(cvs-enabledp): Ignore errors.
[emacs.git] / src / w32term.c
blob3b64348a6a37b67d31f1d84f6738ab36e1f4b76e
1 /* Implementation of GUI terminal on the Microsoft W32 API.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include <config.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include "lisp.h"
27 #include "charset.h"
28 #include "blockinput.h"
30 #include "w32heap.h"
31 #include "w32term.h"
32 #include "w32bdf.h"
33 #include <shellapi.h>
35 #include "systty.h"
36 #include "systime.h"
37 #include "atimer.h"
39 #include <ctype.h>
40 #include <errno.h>
41 #include <setjmp.h>
42 #include <sys/stat.h>
44 #include "keyboard.h"
45 #include "frame.h"
46 #include "dispextern.h"
47 #include "fontset.h"
48 #include "termhooks.h"
49 #include "termopts.h"
50 #include "termchar.h"
51 #include "gnu.h"
52 #include "disptab.h"
53 #include "buffer.h"
54 #include "window.h"
55 #include "intervals.h"
56 #include "composite.h"
57 #include "coding.h"
59 #undef min
60 #undef max
61 #define min(x, y) (((x) < (y)) ? (x) : (y))
62 #define max(x, y) (((x) > (y)) ? (x) : (y))
64 #define abs(x) ((x) < 0 ? -(x) : (x))
66 #define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
69 /* Bitmaps for truncated lines. */
71 enum bitmap_type
73 NO_BITMAP,
74 LEFT_TRUNCATION_BITMAP,
75 RIGHT_TRUNCATION_BITMAP,
76 OVERLAY_ARROW_BITMAP,
77 CONTINUED_LINE_BITMAP,
78 CONTINUATION_LINE_BITMAP,
79 ZV_LINE_BITMAP
82 /* Bitmaps are all unsigned short, as Windows requires bitmap data to
83 be Word aligned. For some reason they are horizontally reflected
84 compared to how they appear on X, so changes in xterm.c should be
85 reflected here. */
87 /* Bitmap drawn to indicate lines not displaying text if
88 `indicate-empty-lines' is non-nil. */
90 #define zv_width 8
91 #define zv_height 8
92 static unsigned short zv_bits[] = {
93 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00};
94 static HBITMAP zv_bmp;
96 /* An arrow like this: `<-'. */
98 #define left_width 8
99 #define left_height 8
100 static unsigned short left_bits[] = {
101 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
102 static HBITMAP left_bmp;
104 /* Right truncation arrow bitmap `->'. */
106 #define right_width 8
107 #define right_height 8
108 static unsigned short right_bits[] = {
109 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
110 static HBITMAP right_bmp;
112 /* Marker for continued lines. */
114 #define continued_width 8
115 #define continued_height 8
116 static unsigned short continued_bits[] = {
117 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
118 static HBITMAP continued_bmp;
120 /* Marker for continuation lines. */
122 #define continuation_width 8
123 #define continuation_height 8
124 static unsigned short continuation_bits[] = {
125 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
126 static HBITMAP continuation_bmp;
128 /* Overlay arrow bitmap. */
130 #if 0
131 /* A bomb. */
132 #define ov_width 8
133 #define ov_height 8
134 static unsigned short ov_bits[] = {
135 0x0c, 0x10, 0x3c, 0x7e, 0x5e, 0x5e, 0x46, 0x3c};
136 #else
137 /* A triangular arrow. */
138 #define ov_width 8
139 #define ov_height 8
140 static unsigned short ov_bits[] = {
141 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
142 #endif
143 static HBITMAP ov_bmp;
145 extern Lisp_Object Qhelp_echo;
148 /* Non-zero means Emacs uses toolkit scroll bars. */
150 int x_toolkit_scroll_bars_p;
152 /* If a string, w32_read_socket generates an event to display that string.
153 (The display is done in read_char.) */
155 static Lisp_Object help_echo;
156 static Lisp_Object help_echo_window;
157 static Lisp_Object help_echo_object;
158 static int help_echo_pos;
160 /* Temporary variable for w32_read_socket. */
162 static Lisp_Object previous_help_echo;
164 /* Non-zero means that a HELP_EVENT has been generated since Emacs
165 start. */
167 static int any_help_event_p;
169 /* Non-zero means draw block and hollow cursor as wide as the glyph
170 under it. For example, if a block cursor is over a tab, it will be
171 drawn as wide as that tab on the display. */
173 int x_stretch_cursor_p;
175 extern unsigned int msh_mousewheel;
177 extern void free_frame_menubar ();
179 extern void w32_menu_display_help (HMENU menu, UINT menu_item, UINT flags);
181 extern int w32_codepage_for_font (char *fontname);
183 extern glyph_metric *w32_BDF_TextMetric(bdffont *fontp,
184 unsigned char *text, int dim);
185 extern Lisp_Object Vwindow_system;
187 #define x_any_window_to_frame x_window_to_frame
188 #define x_top_window_to_frame x_window_to_frame
191 /* This is display since w32 does not support multiple ones. */
192 struct w32_display_info one_w32_display_info;
194 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
195 one for each element of w32_display_list and in the same order.
196 NAME is the name of the frame.
197 FONT-LIST-CACHE records previous values returned by x-list-fonts. */
198 Lisp_Object w32_display_name_list;
200 /* Frame being updated by update_frame. This is declared in term.c.
201 This is set by update_begin and looked at by all the
202 w32 functions. It is zero while not inside an update.
203 In that case, the w32 functions assume that `SELECTED_FRAME ()'
204 is the frame to apply to. */
205 extern struct frame *updating_frame;
207 /* This is a frame waiting to be autoraised, within w32_read_socket. */
208 struct frame *pending_autoraise_frame;
210 /* Nominal cursor position -- where to draw output.
211 HPOS and VPOS are window relative glyph matrix coordinates.
212 X and Y are window relative pixel coordinates. */
214 struct cursor_pos output_cursor;
216 /* Flag to enable Unicode output in case users wish to use programs
217 like Twinbridge on '95 rather than installed system level support
218 for Far East languages. */
219 int w32_enable_unicode_output;
221 DWORD dwWindowsThreadId = 0;
222 HANDLE hWindowsThread = NULL;
223 DWORD dwMainThreadId = 0;
224 HANDLE hMainThread = NULL;
226 #ifndef SIF_ALL
227 /* These definitions are new with Windows 95. */
228 #define SIF_RANGE 0x0001
229 #define SIF_PAGE 0x0002
230 #define SIF_POS 0x0004
231 #define SIF_DISABLENOSCROLL 0x0008
232 #define SIF_TRACKPOS 0x0010
233 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
235 typedef struct tagSCROLLINFO
237 UINT cbSize;
238 UINT fMask;
239 int nMin;
240 int nMax;
241 UINT nPage;
242 int nPos;
243 int nTrackPos;
244 } SCROLLINFO, FAR *LPSCROLLINFO;
245 typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
246 #endif /* SIF_ALL */
248 /* Dynamic linking to new proportional scroll bar functions. */
249 int (PASCAL *pfnSetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
250 BOOL (PASCAL *pfnGetScrollInfo) (HWND hwnd, int fnBar, LPSCROLLINFO lpsi);
252 int vertical_scroll_bar_min_handle;
253 int vertical_scroll_bar_top_border;
254 int vertical_scroll_bar_bottom_border;
256 int last_scroll_bar_drag_pos;
258 /* Mouse movement. */
260 /* Where the mouse was last time we reported a mouse event. */
262 FRAME_PTR last_mouse_frame;
263 static RECT last_mouse_glyph;
264 static Lisp_Object last_mouse_press_frame;
266 Lisp_Object Vw32_num_mouse_buttons;
268 Lisp_Object Vw32_swap_mouse_buttons;
270 /* Control whether x_raise_frame also sets input focus. */
271 Lisp_Object Vw32_grab_focus_on_raise;
273 /* Control whether Caps Lock affects non-ascii characters. */
274 Lisp_Object Vw32_capslock_is_shiftlock;
276 /* Control whether right-alt and left-ctrl should be recognized as AltGr. */
277 Lisp_Object Vw32_recognize_altgr;
279 /* The scroll bar in which the last motion event occurred.
281 If the last motion event occurred in a scroll bar, we set this
282 so w32_mouse_position can know whether to report a scroll bar motion or
283 an ordinary motion.
285 If the last motion event didn't occur in a scroll bar, we set this
286 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
287 static Lisp_Object last_mouse_scroll_bar;
288 static int last_mouse_scroll_bar_pos;
290 /* This is a hack. We would really prefer that w32_mouse_position would
291 return the time associated with the position it returns, but there
292 doesn't seem to be any way to wrest the time-stamp from the server
293 along with the position query. So, we just keep track of the time
294 of the last movement we received, and return that in hopes that
295 it's somewhat accurate. */
297 static Time last_mouse_movement_time;
299 /* Incremented by w32_read_socket whenever it really tries to read
300 events. */
302 #ifdef __STDC__
303 static int volatile input_signal_count;
304 #else
305 static int input_signal_count;
306 #endif
308 extern Lisp_Object Vcommand_line_args, Vsystem_name;
310 extern Lisp_Object Qface, Qmouse_face;
312 #ifndef USE_CRT_DLL
313 extern int errno;
314 #endif
316 /* A mask of extra modifier bits to put into every keyboard char. */
318 extern int extra_keyboard_modifiers;
320 /* Enumeration for overriding/changing the face to use for drawing
321 glyphs in x_draw_glyphs. */
323 enum draw_glyphs_face
325 DRAW_NORMAL_TEXT,
326 DRAW_INVERSE_VIDEO,
327 DRAW_CURSOR,
328 DRAW_MOUSE_FACE,
329 DRAW_IMAGE_RAISED,
330 DRAW_IMAGE_SUNKEN
333 static void x_update_window_end P_ ((struct window *, int, int));
334 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
335 void w32_delete_display P_ ((struct w32_display_info *));
336 static int fast_find_position P_ ((struct window *, int, int *, int *,
337 int *, int *));
338 static void set_output_cursor P_ ((struct cursor_pos *));
339 static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
340 int *, int *, int *));
341 static void note_mode_line_highlight P_ ((struct window *, int, int));
342 static void x_check_font P_ ((struct frame *, XFontStruct *));
343 static void note_mouse_highlight P_ ((struct frame *, int, int));
344 static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
345 static void w32_handle_tool_bar_click P_ ((struct frame *,
346 struct input_event *));
347 static void show_mouse_face P_ ((struct w32_display_info *,
348 enum draw_glyphs_face));
349 void clear_mouse_face P_ ((struct w32_display_info *));
351 void x_lower_frame P_ ((struct frame *));
352 void x_scroll_bar_clear P_ ((struct frame *));
353 void x_wm_set_size_hint P_ ((struct frame *, long, int));
354 void x_raise_frame P_ ((struct frame *));
355 void x_set_window_size P_ ((struct frame *, int, int, int));
356 void x_wm_set_window_state P_ ((struct frame *, int));
357 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
358 void w32_initialize P_ ((void));
359 static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
360 int x_compute_min_glyph_bounds P_ ((struct frame *));
361 static void x_draw_phys_cursor_glyph P_ ((struct window *,
362 struct glyph_row *,
363 enum draw_glyphs_face));
364 static void x_update_end P_ ((struct frame *));
365 static void w32_frame_up_to_date P_ ((struct frame *));
366 static void w32_reassert_line_highlight P_ ((int, int));
367 static void x_change_line_highlight P_ ((int, int, int, int));
368 static void w32_set_terminal_modes P_ ((void));
369 static void w32_reset_terminal_modes P_ ((void));
370 static void w32_cursor_to P_ ((int, int, int, int));
371 static void x_write_glyphs P_ ((struct glyph *, int));
372 static void x_clear_end_of_line P_ ((int));
373 static void x_clear_frame P_ ((void));
374 static void x_clear_cursor P_ ((struct window *));
375 static void frame_highlight P_ ((struct frame *));
376 static void frame_unhighlight P_ ((struct frame *));
377 static void w32_new_focus_frame P_ ((struct w32_display_info *,
378 struct frame *));
379 static void w32_frame_rehighlight P_ ((struct frame *));
380 static void x_frame_rehighlight P_ ((struct w32_display_info *));
381 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
382 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int));
383 static void expose_frame P_ ((struct frame *, int, int, int, int));
384 static void expose_window_tree P_ ((struct window *, RECT *));
385 static void expose_window P_ ((struct window *, RECT *));
386 static void expose_area P_ ((struct window *, struct glyph_row *,
387 RECT *, enum glyph_row_area));
388 static void expose_line P_ ((struct window *, struct glyph_row *,
389 RECT *));
390 void x_update_cursor P_ ((struct frame *, int));
391 static void x_update_cursor_in_window_tree P_ ((struct window *, int));
392 static void x_update_window_cursor P_ ((struct window *, int));
393 static void x_erase_phys_cursor P_ ((struct window *));
394 void x_display_cursor P_ ((struct window *w, int, int, int, int, int));
395 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
396 static void w32_draw_bitmap P_ ((struct window *, HDC hdc, struct glyph_row *,
397 enum bitmap_type));
398 static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
399 static void x_draw_row_bitmaps P_ ((struct window *, struct glyph_row *));
400 static void note_overwritten_text_cursor P_ ((struct window *, int, int));
401 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
402 HDC, int));
404 static Lisp_Object Qvendor_specific_keysyms;
407 /***********************************************************************
408 Debugging
409 ***********************************************************************/
411 #if 0
413 /* This is a function useful for recording debugging information about
414 the sequence of occurrences in this file. */
416 struct record
418 char *locus;
419 int type;
422 struct record event_record[100];
424 int event_record_index;
426 record_event (locus, type)
427 char *locus;
428 int type;
430 if (event_record_index == sizeof (event_record) / sizeof (struct record))
431 event_record_index = 0;
433 event_record[event_record_index].locus = locus;
434 event_record[event_record_index].type = type;
435 event_record_index++;
438 #endif /* 0 */
441 void XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
442 XGCValues *xgcv)
444 if (mask & GCForeground)
445 gc->foreground = xgcv->foreground;
446 if (mask & GCBackground)
447 gc->background = xgcv->background;
448 if (mask & GCFont)
449 gc->font = xgcv->font;
452 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
453 XGCValues *xgcv)
455 XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
456 bzero (gc, sizeof (XGCValues));
458 XChangeGC (ignore, gc, mask, xgcv);
460 return gc;
463 void XGetGCValues (void* ignore, XGCValues *gc,
464 unsigned long mask, XGCValues *xgcv)
466 XChangeGC (ignore, xgcv, mask, gc);
469 static void
470 w32_set_clip_rectangle (HDC hdc, RECT *rect)
472 if (rect)
474 HRGN clip_region = CreateRectRgnIndirect (rect);
475 SelectClipRgn (hdc, clip_region);
476 DeleteObject (clip_region);
478 else
479 SelectClipRgn (hdc, NULL);
483 /* Draw a hollow rectangle at the specified position. */
484 void
485 w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
486 int width, int height)
488 HBRUSH hb, oldhb;
489 HPEN hp, oldhp;
491 hb = CreateSolidBrush (gc->background);
492 hp = CreatePen (PS_SOLID, 0, gc->foreground);
493 oldhb = SelectObject (hdc, hb);
494 oldhp = SelectObject (hdc, hp);
496 Rectangle (hdc, x, y, x + width, y + height);
498 SelectObject (hdc, oldhb);
499 SelectObject (hdc, oldhp);
500 DeleteObject (hb);
501 DeleteObject (hp);
504 /* Draw a filled rectangle at the specified position. */
505 void
506 w32_fill_rect (f, hdc, pix, lprect)
507 FRAME_PTR f;
508 HDC hdc;
509 COLORREF pix;
510 RECT * lprect;
512 HBRUSH hb;
513 RECT rect;
515 hb = CreateSolidBrush (pix);
516 FillRect (hdc, lprect, hb);
517 DeleteObject (hb);
520 void
521 w32_clear_window (f)
522 FRAME_PTR f;
524 RECT rect;
525 HDC hdc = get_frame_dc (f);
527 GetClientRect (FRAME_W32_WINDOW (f), &rect);
528 w32_clear_rect (f, hdc, &rect);
529 release_frame_dc (f, hdc);
533 /***********************************************************************
534 Starting and ending an update
535 ***********************************************************************/
537 /* Start an update of frame F. This function is installed as a hook
538 for update_begin, i.e. it is called when update_begin is called.
539 This function is called prior to calls to x_update_window_begin for
540 each window being updated. Currently, there is nothing to do here
541 because all interesting stuff is done on a window basis. */
543 static void
544 x_update_begin (f)
545 struct frame *f;
547 /* Nothing to do. We have to do something though, otherwise the
548 function gets optimized away and the hook is no longer valid. */
549 struct frame *cf = f;
553 /* Start update of window W. Set the global variable updated_window
554 to the window being updated and set output_cursor to the cursor
555 position of W. */
557 static void
558 x_update_window_begin (w)
559 struct window *w;
561 struct frame *f = XFRAME (WINDOW_FRAME (w));
562 struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
564 updated_window = w;
565 set_output_cursor (&w->cursor);
567 BLOCK_INPUT;
569 /* Regenerate display palette before drawing if list of requested
570 colors has changed. */
571 if (display_info->regen_palette)
573 w32_regenerate_palette (f);
574 display_info->regen_palette = FALSE;
577 if (f == display_info->mouse_face_mouse_frame)
579 /* Don't do highlighting for mouse motion during the update. */
580 display_info->mouse_face_defer = 1;
582 /* If F needs to be redrawn, simply forget about any prior mouse
583 highlighting. */
584 if (FRAME_GARBAGED_P (f))
585 display_info->mouse_face_window = Qnil;
587 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
588 their mouse_face_p flag set, which means that they are always
589 unequal to rows in a desired matrix which never have that
590 flag set. So, rows containing mouse-face glyphs are never
591 scrolled, and we don't have to switch the mouse highlight off
592 here to prevent it from being scrolled. */
594 /* Can we tell that this update does not affect the window
595 where the mouse highlight is? If so, no need to turn off.
596 Likewise, don't do anything if the frame is garbaged;
597 in that case, the frame's current matrix that we would use
598 is all wrong, and we will redisplay that line anyway. */
599 if (!NILP (display_info->mouse_face_window)
600 && w == XWINDOW (display_info->mouse_face_window))
602 int i;
604 for (i = 0; i < w->desired_matrix->nrows; ++i)
605 if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
606 break;
608 if (i < w->desired_matrix->nrows)
609 clear_mouse_face (display_info);
611 #endif /* 0 */
614 UNBLOCK_INPUT;
618 /* Draw a vertical window border to the right of window W if W doesn't
619 have vertical scroll bars. */
621 static void
622 x_draw_vertical_border (w)
623 struct window *w;
625 struct frame *f = XFRAME (WINDOW_FRAME (w));
627 /* Redraw borders between horizontally adjacent windows. Don't
628 do it for frames with vertical scroll bars because either the
629 right scroll bar of a window, or the left scroll bar of its
630 neighbor will suffice as a border. */
631 if (!WINDOW_RIGHTMOST_P (w)
632 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
634 RECT r;
635 HDC hdc;
637 window_box_edges (w, -1, &r.left, &r.top, &r.right, &r.bottom);
638 r.left = r.right + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f);
639 r.right = r.left + 1;
640 r.bottom -= 1;
642 hdc = get_frame_dc (f);
643 w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), r);
644 release_frame_dc (f, hdc);
649 /* End update of window W (which is equal to updated_window).
651 Draw vertical borders between horizontally adjacent windows, and
652 display W's cursor if CURSOR_ON_P is non-zero.
654 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
655 glyphs in mouse-face were overwritten. In that case we have to
656 make sure that the mouse-highlight is properly redrawn.
658 W may be a menu bar pseudo-window in case we don't have X toolkit
659 support. Such windows don't have a cursor, so don't display it
660 here. */
662 static void
663 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
664 struct window *w;
665 int cursor_on_p, mouse_face_overwritten_p;
667 if (!w->pseudo_window_p)
669 struct w32_display_info *dpyinfo
670 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
672 BLOCK_INPUT;
674 /* If a row with mouse-face was overwritten, arrange for
675 XTframe_up_to_date to redisplay the mouse highlight. */
676 if (mouse_face_overwritten_p)
678 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
679 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
680 dpyinfo->mouse_face_window = Qnil;
683 if (cursor_on_p)
684 x_display_and_set_cursor (w, 1, output_cursor.hpos,
685 output_cursor.vpos,
686 output_cursor.x, output_cursor.y);
687 x_draw_vertical_border (w);
688 UNBLOCK_INPUT;
691 updated_window = NULL;
695 /* End update of frame F. This function is installed as a hook in
696 update_end. */
698 static void
699 x_update_end (f)
700 struct frame *f;
702 /* Mouse highlight may be displayed again. */
703 FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
707 /* This function is called from various places in xdisp.c whenever a
708 complete update has been performed. The global variable
709 updated_window is not available here. */
711 static void
712 w32_frame_up_to_date (f)
713 struct frame *f;
715 if (FRAME_W32_P (f))
717 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
718 if (dpyinfo->mouse_face_deferred_gc
719 || f == dpyinfo->mouse_face_mouse_frame)
721 BLOCK_INPUT;
722 if (dpyinfo->mouse_face_mouse_frame)
723 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
724 dpyinfo->mouse_face_mouse_x,
725 dpyinfo->mouse_face_mouse_y);
726 dpyinfo->mouse_face_deferred_gc = 0;
727 UNBLOCK_INPUT;
733 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
734 arrow bitmaps, or clear the areas where they would be displayed
735 before DESIRED_ROW is made current. The window being updated is
736 found in updated_window. This function It is called from
737 update_window_line only if it is known that there are differences
738 between bitmaps to be drawn between current row and DESIRED_ROW. */
740 static void
741 x_after_update_window_line (desired_row)
742 struct glyph_row *desired_row;
744 struct window *w = updated_window;
746 xassert (w);
748 if (!desired_row->mode_line_p && !w->pseudo_window_p)
750 BLOCK_INPUT;
751 x_draw_row_bitmaps (w, desired_row);
753 /* When a window has disappeared, make sure that no rest of
754 full-width rows stays visible in the internal border. */
755 if (windows_or_buffers_changed)
757 struct frame *f = XFRAME (w->frame);
758 int width = FRAME_INTERNAL_BORDER_WIDTH (f);
759 int height = desired_row->visible_height;
760 int x = (window_box_right (w, -1)
761 + FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f));
762 int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
763 HDC hdc = get_frame_dc (f);
765 w32_clear_area (f, hdc, x, y, width, height);
766 release_frame_dc (f, hdc);
769 UNBLOCK_INPUT;
774 /* Draw the bitmap WHICH in one of the areas to the left or right of
775 window W. ROW is the glyph row for which to display the bitmap; it
776 determines the vertical position at which the bitmap has to be
777 drawn. */
779 static void
780 w32_draw_bitmap (w, hdc, row, which)
781 struct window *w;
782 HDC hdc;
783 struct glyph_row *row;
784 enum bitmap_type which;
786 struct frame *f = XFRAME (WINDOW_FRAME (w));
787 Window window = FRAME_W32_WINDOW (f);
788 HDC compat_hdc;
789 int x, y, wd, h, dy;
790 HBITMAP pixmap;
791 HBRUSH fg_brush, orig_brush;
792 HANDLE horig_obj;
793 struct face *face;
795 /* Must clip because of partially visible lines. */
796 w32_clip_to_row (w, row, hdc, 1);
798 switch (which)
800 case LEFT_TRUNCATION_BITMAP:
801 wd = left_width;
802 h = left_height;
803 pixmap = left_bmp;
804 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
805 - wd
806 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
807 break;
809 case OVERLAY_ARROW_BITMAP:
810 wd = ov_width;
811 h = ov_height;
812 pixmap = ov_bmp;
813 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
814 - wd
815 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
816 break;
818 case RIGHT_TRUNCATION_BITMAP:
819 wd = right_width;
820 h = right_height;
821 pixmap = right_bmp;
822 x = window_box_right (w, -1);
823 x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
824 break;
826 case CONTINUED_LINE_BITMAP:
827 wd = continued_width;
828 h = continued_height;
829 pixmap = continued_bmp;
830 x = window_box_right (w, -1);
831 x += (FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f) - wd) / 2;
832 break;
834 case CONTINUATION_LINE_BITMAP:
835 wd = continuation_width;
836 h = continuation_height;
837 pixmap = continuation_bmp;
838 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
839 - wd
840 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
841 break;
843 case ZV_LINE_BITMAP:
844 wd = zv_width;
845 h = zv_height;
846 pixmap = zv_bmp;
847 x = (WINDOW_TO_FRAME_PIXEL_X (w, 0)
848 - wd
849 - (FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - wd) / 2);
850 break;
852 default:
853 abort ();
856 /* Convert to frame coordinates. Set dy to the offset in the row to
857 start drawing the bitmap. */
858 y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
859 dy = (row->height - h) / 2;
861 /* Draw the bitmap. */
862 face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
864 compat_hdc = CreateCompatibleDC (hdc);
865 SaveDC (hdc);
866 fg_brush = CreateSolidBrush (FRAME_FOREGROUND_PIXEL (f));
867 orig_brush = SelectObject (hdc, fg_brush);
868 horig_obj = SelectObject (compat_hdc, pixmap);
869 SetTextColor (hdc, FRAME_BACKGROUND_PIXEL (f));
870 SetBkColor (hdc, FRAME_FOREGROUND_PIXEL (f));
871 #if 0 /* From w32bdf.c (which is from Meadow). */
872 BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, SRCCOPY);
873 #else
874 BitBlt (hdc, x, y + dy, wd, h, compat_hdc, 0, 0, 0xB8074A);
875 #endif
876 SelectObject (compat_hdc, horig_obj);
877 SelectObject (hdc, orig_brush);
878 DeleteObject (fg_brush);
879 DeleteDC (compat_hdc);
880 RestoreDC (hdc, -1);
884 /* Draw flags bitmaps for glyph row ROW on window W. Call this
885 function with input blocked. */
887 static void
888 x_draw_row_bitmaps (w, row)
889 struct window *w;
890 struct glyph_row *row;
892 struct frame *f = XFRAME (w->frame);
893 enum bitmap_type bitmap;
894 struct face *face;
895 int header_line_height = -1;
896 HDC hdc = get_frame_dc (f);
898 xassert (interrupt_input_blocked);
900 /* If row is completely invisible, because of vscrolling, we
901 don't have to draw anything. */
902 if (row->visible_height <= 0)
903 return;
905 face = FACE_FROM_ID (f, BITMAP_AREA_FACE_ID);
906 PREPARE_FACE_FOR_DISPLAY (f, face);
908 /* Decide which bitmap to draw at the left side. */
909 if (row->overlay_arrow_p)
910 bitmap = OVERLAY_ARROW_BITMAP;
911 else if (row->truncated_on_left_p)
912 bitmap = LEFT_TRUNCATION_BITMAP;
913 else if (MATRIX_ROW_CONTINUATION_LINE_P (row))
914 bitmap = CONTINUATION_LINE_BITMAP;
915 else if (row->indicate_empty_line_p)
916 bitmap = ZV_LINE_BITMAP;
917 else
918 bitmap = NO_BITMAP;
920 /* Clear flags area if no bitmap to draw or if bitmap doesn't fill
921 the flags area. */
922 if (bitmap == NO_BITMAP
923 || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
924 || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
926 /* If W has a vertical border to its left, don't draw over it. */
927 int border = ((XFASTINT (w->left) > 0
928 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
929 ? 1 : 0);
930 int left = window_box_left (w, -1);
932 if (header_line_height < 0)
933 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
935 w32_fill_area (f, hdc, face->background,
936 left - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) + border,
937 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
938 row->y)),
939 FRAME_X_LEFT_FLAGS_AREA_WIDTH (f) - border,
940 row->visible_height);
943 /* Draw the left bitmap. */
944 if (bitmap != NO_BITMAP)
945 w32_draw_bitmap (w, hdc, row, bitmap);
947 /* Decide which bitmap to draw at the right side. */
948 if (row->truncated_on_right_p)
949 bitmap = RIGHT_TRUNCATION_BITMAP;
950 else if (row->continued_p)
951 bitmap = CONTINUED_LINE_BITMAP;
952 else
953 bitmap = NO_BITMAP;
955 /* Clear flags area if no bitmap to draw of if bitmap doesn't fill
956 the flags area. */
957 if (bitmap == NO_BITMAP
958 || FRAME_FLAGS_BITMAP_WIDTH (f) < FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f)
959 || row->height > FRAME_FLAGS_BITMAP_HEIGHT (f))
961 int right = window_box_right (w, -1);
963 if (header_line_height < 0)
964 header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
966 w32_fill_area (f, hdc, face->background,
967 right,
968 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
969 row->y)),
970 FRAME_X_RIGHT_FLAGS_AREA_WIDTH (f),
971 row->visible_height);
974 /* Draw the right bitmap. */
975 if (bitmap != NO_BITMAP)
976 w32_draw_bitmap (w, hdc, row, bitmap);
978 release_frame_dc (f, hdc);
982 /***********************************************************************
983 Line Highlighting
984 ***********************************************************************/
986 /* External interface to control of standout mode. Not used for W32
987 frames. Aborts when called. */
989 static void
990 w32_reassert_line_highlight (new, vpos)
991 int new, vpos;
993 abort ();
996 /* Call this when about to modify line at position VPOS and change
997 whether it is highlighted. Not used for W32 frames. Aborts when
998 called. */
1000 static void
1001 x_change_line_highlight (new_highlight, vpos, y, first_unused_hpos)
1002 int new_highlight, vpos, y, first_unused_hpos;
1004 abort ();
1007 /* This is called when starting Emacs and when restarting after
1008 suspend. When starting Emacs, no window is mapped. And nothing
1009 must be done to Emacs's own window if it is suspended (though that
1010 rarely happens). */
1012 static void
1013 w32_set_terminal_modes (void)
1017 /* This is called when exiting or suspending Emacs. Exiting will make
1018 the W32 windows go away, and suspending requires no action. */
1020 static void
1021 w32_reset_terminal_modes (void)
1027 /***********************************************************************
1028 Output Cursor
1029 ***********************************************************************/
1031 /* Set the global variable output_cursor to CURSOR. All cursor
1032 positions are relative to updated_window. */
1034 static void
1035 set_output_cursor (cursor)
1036 struct cursor_pos *cursor;
1038 output_cursor.hpos = cursor->hpos;
1039 output_cursor.vpos = cursor->vpos;
1040 output_cursor.x = cursor->x;
1041 output_cursor.y = cursor->y;
1045 /* Set a nominal cursor position.
1047 HPOS and VPOS are column/row positions in a window glyph matrix. X
1048 and Y are window text area relative pixel positions.
1050 If this is done during an update, updated_window will contain the
1051 window that is being updated and the position is the future output
1052 cursor position for that window. If updated_window is null, use
1053 selected_window and display the cursor at the given position. */
1055 static void
1056 w32_cursor_to (vpos, hpos, y, x)
1057 int vpos, hpos, y, x;
1059 struct window *w;
1061 /* If updated_window is not set, work on selected_window. */
1062 if (updated_window)
1063 w = updated_window;
1064 else
1065 w = XWINDOW (selected_window);
1067 /* Set the output cursor. */
1068 output_cursor.hpos = hpos;
1069 output_cursor.vpos = vpos;
1070 output_cursor.x = x;
1071 output_cursor.y = y;
1073 /* If not called as part of an update, really display the cursor.
1074 This will also set the cursor position of W. */
1075 if (updated_window == NULL)
1077 BLOCK_INPUT;
1078 x_display_cursor (w, 1, hpos, vpos, x, y);
1079 UNBLOCK_INPUT;
1085 /***********************************************************************
1086 Display Iterator
1087 ***********************************************************************/
1089 /* Function prototypes of this page. */
1091 static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *,
1092 struct glyph *,
1093 wchar_t *,
1094 int *));
1095 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
1096 int, wchar_t *, int));
1097 static XCharStruct *w32_per_char_metric P_ ((XFontStruct *,
1098 wchar_t *,
1099 enum w32_char_font_type));
1100 static enum w32_char_font_type
1101 w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *));
1102 static void x_append_glyph P_ ((struct it *));
1103 static void x_append_composite_glyph P_ ((struct it *));
1104 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
1105 int, int, double));
1106 static void x_produce_glyphs P_ ((struct it *));
1107 static void x_produce_image_glyph P_ ((struct it *it));
1110 /* Dealing with bits of wchar_t as if they were an XChar2B. */
1111 #define BUILD_WCHAR_T(byte1, byte2) \
1112 ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff)))
1115 #define BYTE1(ch) \
1116 (((ch) & 0xff00) >> 8)
1118 #define BYTE2(ch) \
1119 ((ch) & 0x00ff)
1122 /* Get metrics of character CHAR2B in FONT. Value is always non-null.
1123 If CHAR2B is not contained in FONT, the font's default character
1124 metric is returned. */
1126 static int
1127 w32_bdf_per_char_metric (font, char2b, dim, pcm)
1128 XFontStruct *font;
1129 wchar_t *char2b;
1130 int dim;
1131 XCharStruct * pcm;
1133 glyph_metric * bdf_metric;
1134 char buf[2];
1136 if (dim == 1)
1137 buf[0] = (char)char2b;
1138 else
1140 buf[0] = BYTE1 (*char2b);
1141 buf[1] = BYTE2 (*char2b);
1144 bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
1146 if (bdf_metric)
1148 pcm->width = bdf_metric->dwidth;
1149 pcm->lbearing = bdf_metric->bbox;
1150 pcm->rbearing = bdf_metric->dwidth
1151 - (bdf_metric->bbox + bdf_metric->bbw);
1152 pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
1153 pcm->descent = -bdf_metric->bboy;
1155 return 1;
1157 return 0;
1161 static int
1162 w32_native_per_char_metric (font, char2b, font_type, pcm)
1163 XFontStruct *font;
1164 wchar_t *char2b;
1165 enum w32_char_font_type font_type;
1166 XCharStruct * pcm;
1168 HDC hdc = GetDC (NULL);
1169 HFONT old_font;
1170 BOOL retval = FALSE;
1172 xassert (font && char2b);
1173 xassert (font->hfont);
1174 xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
1176 old_font = SelectObject (hdc, font->hfont);
1178 if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
1180 ABC char_widths;
1182 if (font_type == UNICODE_FONT)
1183 retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
1184 else
1185 retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
1187 if (retval)
1189 pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
1190 pcm->lbearing = char_widths.abcA;
1191 pcm->rbearing = pcm->width - char_widths.abcC;
1192 pcm->ascent = FONT_BASE (font);
1193 pcm->descent = FONT_DESCENT (font);
1197 if (!retval)
1199 /* Either font is not a True-type font, or GetCharABCWidthsW
1200 failed (it is not supported on Windows 9x for instance), so we
1201 can't determine the full info we would like. All is not lost
1202 though - we can call GetTextExtentPoint32 to get rbearing and
1203 deduce width based on the font's per-string overhang. lbearing
1204 is assumed to be zero. */
1206 /* TODO: Some Thai characters (and other composites if Windows
1207 supports them) do have lbearing, and report their total width
1208 as zero. Need some way of handling them when
1209 GetCharABCWidthsW fails. */
1210 SIZE sz;
1212 if (font_type == UNICODE_FONT)
1213 retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
1214 else
1215 retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
1217 if (retval)
1219 pcm->width = sz.cx - font->tm.tmOverhang;
1220 pcm->rbearing = sz.cx;
1221 pcm->lbearing = 0;
1222 pcm->ascent = FONT_BASE (font);
1223 pcm->descent = FONT_DESCENT (font);
1228 if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
1230 retval = FALSE;
1233 SelectObject (hdc, old_font);
1234 ReleaseDC (NULL, hdc);
1236 return retval;
1240 static XCharStruct *
1241 w32_per_char_metric (font, char2b, font_type)
1242 XFontStruct *font;
1243 wchar_t *char2b;
1244 enum w32_char_font_type font_type;
1246 /* The result metric information. */
1247 XCharStruct *pcm;
1248 BOOL retval;
1250 xassert (font && char2b);
1251 xassert (font_type != UNKNOWN_FONT);
1253 /* Handle the common cases quickly. */
1254 if (font->per_char == NULL)
1255 /* TODO: determine whether char2b exists in font? */
1256 return &font->max_bounds;
1257 else if (*char2b < 128)
1258 return &font->per_char[*char2b];
1260 pcm = &font->scratch;
1262 if (font_type == BDF_1D_FONT)
1263 retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
1264 else if (font_type == BDF_2D_FONT)
1265 retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
1266 else
1267 retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
1269 if (retval)
1270 return pcm;
1272 return NULL;
1275 void
1276 w32_cache_char_metrics (font)
1277 XFontStruct *font;
1279 wchar_t char2b = L'x';
1281 /* Cache char metrics for the common cases. */
1282 if (font->bdf)
1284 /* TODO: determine whether font is fixed-pitch. */
1285 if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
1287 /* Use the font width and height as max bounds, as not all BDF
1288 fonts contain the letter 'x'. */
1289 font->max_bounds.width = FONT_MAX_WIDTH (font);
1290 font->max_bounds.lbearing = -font->bdf->llx;
1291 font->max_bounds.rbearing = FONT_MAX_WIDTH (font) - font->bdf->urx;
1292 font->max_bounds.ascent = FONT_BASE (font);
1293 font->max_bounds.descent = FONT_DESCENT (font);
1296 else
1298 if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
1299 /* Some fonts (eg DBCS fonts) are marked as fixed width even
1300 though they contain characters of different widths. */
1301 || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
1303 /* Font is not fixed pitch, so cache per_char info for the
1304 ASCII characters. It would be much more work, and probably
1305 not worth it, to cache other chars, since we may change
1306 between using Unicode and ANSI text drawing functions at
1307 run-time. */
1308 int i;
1310 font->per_char = xmalloc (128 * sizeof(XCharStruct));
1311 for (i = 0; i < 128; i++)
1313 char2b = i;
1314 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1315 &font->per_char[i]);
1318 else
1319 w32_native_per_char_metric (font, &char2b, ANSI_FONT,
1320 &font->max_bounds);
1325 /* Determine if a font is double byte. */
1326 int w32_font_is_double_byte (XFontStruct *font)
1328 return font->double_byte_p;
1332 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
1333 the two-byte form of C. Encoding is returned in *CHAR2B. */
1335 static INLINE enum w32_char_font_type
1336 w32_encode_char (c, char2b, font_info, two_byte_p)
1337 int c;
1338 wchar_t *char2b;
1339 struct font_info *font_info;
1340 int * two_byte_p;
1342 int charset = CHAR_CHARSET (c);
1343 int codepage;
1344 int unicode_p = 0;
1346 XFontStruct *font = font_info->font;
1348 xassert (two_byte_p);
1350 *two_byte_p = w32_font_is_double_byte (font);
1352 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
1353 This may be either a program in a special encoder language or a
1354 fixed encoding. */
1355 if (font_info->font_encoder)
1357 /* It's a program. */
1358 struct ccl_program *ccl = font_info->font_encoder;
1360 if (CHARSET_DIMENSION (charset) == 1)
1362 ccl->reg[0] = charset;
1363 ccl->reg[1] = BYTE2 (*char2b);
1365 else
1367 ccl->reg[0] = charset;
1368 ccl->reg[1] = BYTE1 (*char2b);
1369 ccl->reg[2] = BYTE2 (*char2b);
1372 ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
1374 /* We assume that MSBs are appropriately set/reset by CCL
1375 program. */
1376 if (!*two_byte_p) /* 1-byte font */
1377 *char2b = BUILD_WCHAR_T (0, ccl->reg[1]);
1378 else
1379 *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]);
1381 else if (font_info->encoding[charset])
1383 /* Fixed encoding scheme. See fontset.h for the meaning of the
1384 encoding numbers. */
1385 int enc = font_info->encoding[charset];
1387 if ((enc == 1 || enc == 2)
1388 && CHARSET_DIMENSION (charset) == 2)
1389 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b));
1391 if (enc == 1 || enc == 3
1392 || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
1393 *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80);
1394 else if (enc == 4)
1396 int sjis1, sjis2;
1398 ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b),
1399 sjis1, sjis2);
1400 *char2b = BUILD_WCHAR_T (sjis1, sjis2);
1403 codepage = w32_codepage_for_font (font_info->name);
1405 /* If charset is not ASCII or Latin-1, may need to move it into
1406 Unicode space. */
1407 if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
1408 && charset != CHARSET_ASCII && charset != charset_latin_iso8859_1)
1410 char temp[3];
1411 temp[0] = BYTE1 (*char2b);
1412 temp[1] = BYTE2 (*char2b);
1413 temp[2] = '\0';
1414 if (temp[0])
1415 MultiByteToWideChar (codepage, 0, temp, 2, char2b, 1);
1416 else
1417 MultiByteToWideChar (codepage, 0, temp+1, 1, char2b, 1);
1418 unicode_p = 1;
1419 *two_byte_p = 1;
1421 if (!font)
1422 return UNKNOWN_FONT;
1423 else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
1424 return BDF_1D_FONT;
1425 else if (font->bdf)
1426 return BDF_2D_FONT;
1427 else if (unicode_p)
1428 return UNICODE_FONT;
1429 else
1430 return ANSI_FONT;
1434 /* Get face and two-byte form of character C in face FACE_ID on frame
1435 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
1436 means we want to display multibyte text. Value is a pointer to a
1437 realized face that is ready for display. */
1439 static INLINE struct face *
1440 x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p)
1441 struct frame *f;
1442 int c, face_id;
1443 wchar_t *char2b;
1444 int multibyte_p;
1446 struct face *face = FACE_FROM_ID (f, face_id);
1448 if (!multibyte_p)
1450 /* Unibyte case. We don't have to encode, but we have to make
1451 sure to use a face suitable for unibyte. */
1452 *char2b = BUILD_WCHAR_T (0, c);
1453 face_id = FACE_FOR_CHAR (f, face, c);
1454 face = FACE_FROM_ID (f, face_id);
1456 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
1458 /* Case of ASCII in a face known to fit ASCII. */
1459 *char2b = BUILD_WCHAR_T (0, c);
1461 else
1463 int c1, c2, charset;
1465 /* Split characters into bytes. If c2 is -1 afterwards, C is
1466 really a one-byte character so that byte1 is zero. */
1467 SPLIT_CHAR (c, charset, c1, c2);
1468 if (c2 > 0)
1469 *char2b = BUILD_WCHAR_T (c1, c2);
1470 else
1471 *char2b = BUILD_WCHAR_T (0, c1);
1473 /* Maybe encode the character in *CHAR2B. */
1474 if (face->font != NULL)
1476 struct font_info *font_info
1477 = FONT_INFO_FROM_ID (f, face->font_info_id);
1478 if (font_info)
1479 w32_encode_char (c, char2b, font_info, &multibyte_p);
1483 /* Make sure X resources of the face are allocated. */
1484 xassert (face != NULL);
1485 PREPARE_FACE_FOR_DISPLAY (f, face);
1487 return face;
1491 /* Get face and two-byte form of character glyph GLYPH on frame F.
1492 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
1493 a pointer to a realized face that is ready for display. */
1495 static INLINE struct face *
1496 x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
1497 struct frame *f;
1498 struct glyph *glyph;
1499 wchar_t *char2b;
1500 int *two_byte_p;
1502 struct face *face;
1503 int dummy = 0;
1505 xassert (glyph->type == CHAR_GLYPH);
1506 face = FACE_FROM_ID (f, glyph->face_id);
1508 if (two_byte_p)
1509 *two_byte_p = 0;
1510 else
1511 two_byte_p = &dummy;
1513 if (!glyph->multibyte_p)
1515 /* Unibyte case. We don't have to encode, but we have to make
1516 sure to use a face suitable for unibyte. */
1517 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1519 else if (glyph->u.ch < 128
1520 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
1522 /* Case of ASCII in a face known to fit ASCII. */
1523 *char2b = BUILD_WCHAR_T (0, glyph->u.ch);
1525 else
1527 int c1, c2, charset;
1529 /* Split characters into bytes. If c2 is -1 afterwards, C is
1530 really a one-byte character so that byte1 is zero. */
1531 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
1532 if (c2 > 0)
1533 *char2b = BUILD_WCHAR_T (c1, c2);
1534 else
1535 *char2b = BUILD_WCHAR_T (0, c1);
1537 /* Maybe encode the character in *CHAR2B. */
1538 if (charset != CHARSET_ASCII)
1540 struct font_info *font_info
1541 = FONT_INFO_FROM_ID (f, face->font_info_id);
1542 if (font_info)
1544 glyph->w32_font_type
1545 = w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
1550 /* Make sure X resources of the face are allocated. */
1551 xassert (face != NULL);
1552 PREPARE_FACE_FOR_DISPLAY (f, face);
1553 return face;
1557 /* Store one glyph for IT->char_to_display in IT->glyph_row.
1558 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1560 static INLINE void
1561 x_append_glyph (it)
1562 struct it *it;
1564 struct glyph *glyph;
1565 enum glyph_row_area area = it->area;
1567 xassert (it->glyph_row);
1568 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
1570 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1571 if (glyph < it->glyph_row->glyphs[area + 1])
1573 glyph->charpos = CHARPOS (it->position);
1574 glyph->object = it->object;
1575 glyph->pixel_width = it->pixel_width;
1576 glyph->voffset = it->voffset;
1577 glyph->type = CHAR_GLYPH;
1578 glyph->multibyte_p = it->multibyte_p;
1579 glyph->left_box_line_p = it->start_of_box_run_p;
1580 glyph->right_box_line_p = it->end_of_box_run_p;
1581 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1582 || it->phys_descent > it->descent);
1583 glyph->padding_p = 0;
1584 glyph->glyph_not_available_p = it->glyph_not_available_p;
1585 glyph->face_id = it->face_id;
1586 glyph->u.ch = it->char_to_display;
1587 glyph->w32_font_type = UNKNOWN_FONT;
1588 ++it->glyph_row->used[area];
1592 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1593 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1595 static INLINE void
1596 x_append_composite_glyph (it)
1597 struct it *it;
1599 struct glyph *glyph;
1600 enum glyph_row_area area = it->area;
1602 xassert (it->glyph_row);
1604 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1605 if (glyph < it->glyph_row->glyphs[area + 1])
1607 glyph->charpos = CHARPOS (it->position);
1608 glyph->object = it->object;
1609 glyph->pixel_width = it->pixel_width;
1610 glyph->voffset = it->voffset;
1611 glyph->type = COMPOSITE_GLYPH;
1612 glyph->multibyte_p = it->multibyte_p;
1613 glyph->left_box_line_p = it->start_of_box_run_p;
1614 glyph->right_box_line_p = it->end_of_box_run_p;
1615 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1616 || it->phys_descent > it->descent);
1617 glyph->padding_p = 0;
1618 glyph->glyph_not_available_p = 0;
1619 glyph->face_id = it->face_id;
1620 glyph->u.cmp_id = it->cmp_id;
1621 glyph->w32_font_type = UNKNOWN_FONT;
1622 ++it->glyph_row->used[area];
1627 /* Change IT->ascent and IT->height according to the setting of
1628 IT->voffset. */
1630 static INLINE void
1631 take_vertical_position_into_account (it)
1632 struct it *it;
1634 if (it->voffset)
1636 if (it->voffset < 0)
1637 /* Increase the ascent so that we can display the text higher
1638 in the line. */
1639 it->ascent += abs (it->voffset);
1640 else
1641 /* Increase the descent so that we can display the text lower
1642 in the line. */
1643 it->descent += it->voffset;
1648 /* Produce glyphs/get display metrics for the image IT is loaded with.
1649 See the description of struct display_iterator in dispextern.h for
1650 an overview of struct display_iterator. */
1652 static void
1653 x_produce_image_glyph (it)
1654 struct it *it;
1656 struct image *img;
1657 struct face *face;
1659 xassert (it->what == IT_IMAGE);
1661 face = FACE_FROM_ID (it->f, it->face_id);
1662 img = IMAGE_FROM_ID (it->f, it->image_id);
1663 xassert (img);
1665 /* Make sure X resources of the face and image are loaded. */
1666 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1667 prepare_image_for_display (it->f, img);
1669 it->ascent = it->phys_ascent = image_ascent (img, face);
1670 it->descent = it->phys_descent = img->height + 2 * img->margin - it->ascent;
1671 it->pixel_width = img->width + 2 * img->margin;
1673 it->nglyphs = 1;
1675 if (face->box != FACE_NO_BOX)
1677 it->ascent += face->box_line_width;
1678 it->descent += face->box_line_width;
1680 if (it->start_of_box_run_p)
1681 it->pixel_width += face->box_line_width;
1682 if (it->end_of_box_run_p)
1683 it->pixel_width += face->box_line_width;
1686 take_vertical_position_into_account (it);
1688 if (it->glyph_row)
1690 struct glyph *glyph;
1691 enum glyph_row_area area = it->area;
1693 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1694 if (glyph < it->glyph_row->glyphs[area + 1])
1696 glyph->charpos = CHARPOS (it->position);
1697 glyph->object = it->object;
1698 glyph->pixel_width = it->pixel_width;
1699 glyph->voffset = it->voffset;
1700 glyph->type = IMAGE_GLYPH;
1701 glyph->multibyte_p = it->multibyte_p;
1702 glyph->left_box_line_p = it->start_of_box_run_p;
1703 glyph->right_box_line_p = it->end_of_box_run_p;
1704 glyph->overlaps_vertically_p = 0;
1705 glyph->padding_p = 0;
1706 glyph->glyph_not_available_p = 0;
1707 glyph->face_id = it->face_id;
1708 glyph->u.img_id = img->id;
1709 glyph->w32_font_type = UNKNOWN_FONT;
1710 ++it->glyph_row->used[area];
1716 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
1717 of the glyph, WIDTH and HEIGHT are the width and height of the
1718 stretch. ASCENT is the percentage/100 of HEIGHT to use for the
1719 ascent of the glyph (0 <= ASCENT <= 1). */
1721 static void
1722 x_append_stretch_glyph (it, object, width, height, ascent)
1723 struct it *it;
1724 Lisp_Object object;
1725 int width, height;
1726 double ascent;
1728 struct glyph *glyph;
1729 enum glyph_row_area area = it->area;
1731 xassert (ascent >= 0 && ascent <= 1);
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 = object;
1738 glyph->pixel_width = width;
1739 glyph->voffset = it->voffset;
1740 glyph->type = STRETCH_GLYPH;
1741 glyph->multibyte_p = it->multibyte_p;
1742 glyph->left_box_line_p = it->start_of_box_run_p;
1743 glyph->right_box_line_p = it->end_of_box_run_p;
1744 glyph->overlaps_vertically_p = 0;
1745 glyph->padding_p = 0;
1746 glyph->glyph_not_available_p = 0;
1747 glyph->face_id = it->face_id;
1748 glyph->u.stretch.ascent = height * ascent;
1749 glyph->u.stretch.height = height;
1750 glyph->w32_font_type = UNKNOWN_FONT;
1751 ++it->glyph_row->used[area];
1756 /* Produce a stretch glyph for iterator IT. IT->object is the value
1757 of the glyph property displayed. The value must be a list
1758 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1759 being recognized:
1761 1. `:width WIDTH' specifies that the space should be WIDTH *
1762 canonical char width wide. WIDTH may be an integer or floating
1763 point number.
1765 2. `:relative-width FACTOR' specifies that the width of the stretch
1766 should be computed from the width of the first character having the
1767 `glyph' property, and should be FACTOR times that width.
1769 3. `:align-to HPOS' specifies that the space should be wide enough
1770 to reach HPOS, a value in canonical character units.
1772 Exactly one of the above pairs must be present.
1774 4. `:height HEIGHT' specifies that the height of the stretch produced
1775 should be HEIGHT, measured in canonical character units.
1777 5. `:relative-height FACTOR' specifies that the height of the the
1778 stretch should be FACTOR times the height of the characters having
1779 the glyph property.
1781 Either none or exactly one of 4 or 5 must be present.
1783 6. `:ascent ASCENT' specifies that ASCENT percent of the height
1784 of the stretch should be used for the ascent of the stretch.
1785 ASCENT must be in the range 0 <= ASCENT <= 100. */
1787 #define NUMVAL(X) \
1788 ((INTEGERP (X) || FLOATP (X)) \
1789 ? XFLOATINT (X) \
1790 : - 1)
1793 static void
1794 x_produce_stretch_glyph (it)
1795 struct it *it;
1797 /* (space :width WIDTH :height HEIGHT. */
1798 extern Lisp_Object QCwidth, QCheight, QCascent, Qspace;
1799 extern Lisp_Object QCrelative_width, QCrelative_height;
1800 extern Lisp_Object QCalign_to;
1801 Lisp_Object prop, plist;
1802 double width = 0, height = 0, ascent = 0;
1803 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1804 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
1806 PREPARE_FACE_FOR_DISPLAY (it->f, face);
1808 /* List should start with `space'. */
1809 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1810 plist = XCDR (it->object);
1812 /* Compute the width of the stretch. */
1813 if (prop = Fplist_get (plist, QCwidth),
1814 NUMVAL (prop) > 0)
1815 /* Absolute width `:width WIDTH' specified and valid. */
1816 width = NUMVAL (prop) * CANON_X_UNIT (it->f);
1817 else if (prop = Fplist_get (plist, QCrelative_width),
1818 NUMVAL (prop) > 0)
1820 /* Relative width `:relative-width FACTOR' specified and valid.
1821 Compute the width of the characters having the `glyph'
1822 property. */
1823 struct it it2;
1824 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
1826 it2 = *it;
1827 if (it->multibyte_p)
1829 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
1830 - IT_BYTEPOS (*it));
1831 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
1833 else
1834 it2.c = *p, it2.len = 1;
1836 it2.glyph_row = NULL;
1837 it2.what = IT_CHARACTER;
1838 x_produce_glyphs (&it2);
1839 width = NUMVAL (prop) * it2.pixel_width;
1841 else if (prop = Fplist_get (plist, QCalign_to),
1842 NUMVAL (prop) > 0)
1843 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x;
1844 else
1845 /* Nothing specified -> width defaults to canonical char width. */
1846 width = CANON_X_UNIT (it->f);
1848 /* Compute height. */
1849 if (prop = Fplist_get (plist, QCheight),
1850 NUMVAL (prop) > 0)
1851 height = NUMVAL (prop) * CANON_Y_UNIT (it->f);
1852 else if (prop = Fplist_get (plist, QCrelative_height),
1853 NUMVAL (prop) > 0)
1854 height = FONT_HEIGHT (font) * NUMVAL (prop);
1855 else
1856 height = FONT_HEIGHT (font);
1858 /* Compute percentage of height used for ascent. If
1859 `:ascent ASCENT' is present and valid, use that. Otherwise,
1860 derive the ascent from the font in use. */
1861 if (prop = Fplist_get (plist, QCascent),
1862 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
1863 ascent = NUMVAL (prop) / 100.0;
1864 else
1865 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font);
1867 if (width <= 0)
1868 width = 1;
1869 if (height <= 0)
1870 height = 1;
1872 if (it->glyph_row)
1874 Lisp_Object object = it->stack[it->sp - 1].string;
1875 if (!STRINGP (object))
1876 object = it->w->buffer;
1877 x_append_stretch_glyph (it, object, width, height, ascent);
1880 it->pixel_width = width;
1881 it->ascent = it->phys_ascent = height * ascent;
1882 it->descent = it->phys_descent = height - it->ascent;
1883 it->nglyphs = 1;
1885 if (face->box != FACE_NO_BOX)
1887 it->ascent += face->box_line_width;
1888 it->descent += face->box_line_width;
1890 if (it->start_of_box_run_p)
1891 it->pixel_width += face->box_line_width;
1892 if (it->end_of_box_run_p)
1893 it->pixel_width += face->box_line_width;
1896 take_vertical_position_into_account (it);
1899 /* Return proper value to be used as baseline offset of font that has
1900 ASCENT and DESCENT to draw characters by the font at the vertical
1901 center of the line of frame F.
1903 Here, out task is to find the value of BOFF in the following figure;
1905 -------------------------+-----------+-
1906 -+-+---------+-+ | |
1907 | | | | | |
1908 | | | | F_ASCENT F_HEIGHT
1909 | | | ASCENT | |
1910 HEIGHT | | | | |
1911 | | |-|-+------+-----------|------- baseline
1912 | | | | BOFF | |
1913 | |---------|-+-+ | |
1914 | | | DESCENT | |
1915 -+-+---------+-+ F_DESCENT |
1916 -------------------------+-----------+-
1918 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1919 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1920 DESCENT = FONT->descent
1921 HEIGHT = FONT_HEIGHT (FONT)
1922 F_DESCENT = (F->output_data.x->font->descent
1923 - F->output_data.x->baseline_offset)
1924 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1927 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1928 (FONT_DESCENT (FONT) \
1929 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \
1930 + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \
1931 - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F)))
1933 /* Produce glyphs/get display metrics for the display element IT is
1934 loaded with. See the description of struct display_iterator in
1935 dispextern.h for an overview of struct display_iterator. */
1937 static void
1938 x_produce_glyphs (it)
1939 struct it *it;
1941 it->glyph_not_available_p = 0;
1943 if (it->what == IT_CHARACTER)
1945 wchar_t char2b;
1946 XFontStruct *font;
1947 struct face *face = FACE_FROM_ID (it->f, it->face_id);
1948 XCharStruct *pcm;
1949 int font_not_found_p;
1950 struct font_info *font_info;
1951 int boff; /* baseline offset */
1952 /* We may change it->multibyte_p upon unibyte<->multibyte
1953 conversion. So, save the current value now and restore it
1954 later.
1956 Note: It seems that we don't have to record multibyte_p in
1957 struct glyph because the character code itself tells if or
1958 not the character is multibyte. Thus, in the future, we must
1959 consider eliminating the field `multibyte_p' in the struct
1960 glyph.
1962 int saved_multibyte_p = it->multibyte_p;
1964 /* Maybe translate single-byte characters to multibyte, or the
1965 other way. */
1966 it->char_to_display = it->c;
1967 if (!ASCII_BYTE_P (it->c))
1969 if (unibyte_display_via_language_environment
1970 && SINGLE_BYTE_CHAR_P (it->c)
1971 && (it->c >= 0240
1972 || !NILP (Vnonascii_translation_table)))
1974 it->char_to_display = unibyte_char_to_multibyte (it->c);
1975 it->multibyte_p = 1;
1976 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
1977 face = FACE_FROM_ID (it->f, it->face_id);
1979 else if (!SINGLE_BYTE_CHAR_P (it->c)
1980 && !it->multibyte_p)
1982 it->char_to_display = multibyte_char_to_unibyte (it->c, Qnil);
1983 it->multibyte_p = 0;
1984 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
1985 face = FACE_FROM_ID (it->f, it->face_id);
1989 /* Get font to use. Encode IT->char_to_display. */
1990 x_get_char_face_and_encoding (it->f, it->char_to_display,
1991 it->face_id, &char2b,
1992 it->multibyte_p);
1993 font = face->font;
1995 /* When no suitable font found, use the default font. */
1996 font_not_found_p = font == NULL;
1997 if (font_not_found_p)
1999 font = FRAME_FONT (it->f);
2000 boff = it->f->output_data.w32->baseline_offset;
2001 font_info = NULL;
2003 else
2005 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2006 boff = font_info->baseline_offset;
2007 if (font_info->vertical_centering)
2008 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2011 if (it->char_to_display >= ' '
2012 && (!it->multibyte_p || it->char_to_display < 128))
2014 /* Either unibyte or ASCII. */
2015 int stretched_p;
2017 it->nglyphs = 1;
2019 pcm = w32_per_char_metric (font, &char2b,
2020 font->bdf ? BDF_1D_FONT : ANSI_FONT);
2021 it->ascent = FONT_BASE (font) + boff;
2022 it->descent = FONT_DESCENT (font) - boff;
2024 if (pcm)
2026 it->phys_ascent = pcm->ascent + boff;
2027 it->phys_descent = pcm->descent - boff;
2028 it->pixel_width = pcm->width;
2030 else
2032 it->glyph_not_available_p = 1;
2033 it->phys_ascent = FONT_BASE (font) + boff;
2034 it->phys_descent = FONT_DESCENT (font) - boff;
2035 it->pixel_width = FONT_WIDTH (font);
2038 /* If this is a space inside a region of text with
2039 `space-width' property, change its width. */
2040 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
2041 if (stretched_p)
2042 it->pixel_width *= XFLOATINT (it->space_width);
2044 /* If face has a box, add the box thickness to the character
2045 height. If character has a box line to the left and/or
2046 right, add the box line width to the character's width. */
2047 if (face->box != FACE_NO_BOX)
2049 int thick = face->box_line_width;
2051 it->ascent += thick;
2052 it->descent += thick;
2054 if (it->start_of_box_run_p)
2055 it->pixel_width += thick;
2056 if (it->end_of_box_run_p)
2057 it->pixel_width += thick;
2060 /* If face has an overline, add the height of the overline
2061 (1 pixel) and a 1 pixel margin to the character height. */
2062 if (face->overline_p)
2063 it->ascent += 2;
2065 take_vertical_position_into_account (it);
2067 /* If we have to actually produce glyphs, do it. */
2068 if (it->glyph_row)
2070 if (stretched_p)
2072 /* Translate a space with a `space-width' property
2073 into a stretch glyph. */
2074 double ascent = (double) FONT_BASE (font)
2075 / FONT_HEIGHT (font);
2076 x_append_stretch_glyph (it, it->object, it->pixel_width,
2077 it->ascent + it->descent, ascent);
2079 else
2080 x_append_glyph (it);
2082 /* If characters with lbearing or rbearing are displayed
2083 in this line, record that fact in a flag of the
2084 glyph row. This is used to optimize X output code. */
2085 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
2086 it->glyph_row->contains_overlapping_glyphs_p = 1;
2089 else if (it->char_to_display == '\n')
2091 /* A newline has no width but we need the height of the line. */
2092 it->pixel_width = 0;
2093 it->nglyphs = 0;
2094 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2095 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2097 if (face->box != FACE_NO_BOX)
2099 int thick = face->box_line_width;
2100 it->ascent += thick;
2101 it->descent += thick;
2104 else if (it->char_to_display == '\t')
2106 int tab_width = it->tab_width * CANON_X_UNIT (it->f);
2107 int x = it->current_x + it->continuation_lines_width;
2108 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
2110 /* If the distance from the current position to the next tab
2111 stop is less than a canonical character width, use the
2112 tab stop after that. */
2113 if (next_tab_x - x < CANON_X_UNIT (it->f))
2114 next_tab_x += tab_width;
2116 it->pixel_width = next_tab_x - x;
2117 it->nglyphs = 1;
2118 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
2119 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
2121 if (it->glyph_row)
2123 double ascent = (double) it->ascent / (it->ascent + it->descent);
2124 x_append_stretch_glyph (it, it->object, it->pixel_width,
2125 it->ascent + it->descent, ascent);
2128 else
2130 /* A multi-byte character.
2131 If we found a font, this font should give us the right
2132 metrics. If we didn't find a font, use the frame's
2133 default font and calculate the width of the character
2134 from the charset width; this is what old redisplay code
2135 did. */
2136 enum w32_char_font_type type;
2138 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2139 type = BDF_1D_FONT;
2140 else if (font->bdf)
2141 type = BDF_2D_FONT;
2142 else
2143 type = UNICODE_FONT;
2145 pcm = w32_per_char_metric (font, &char2b, type);
2147 if (font_not_found_p || !pcm)
2149 int charset = CHAR_CHARSET (it->char_to_display);
2151 it->glyph_not_available_p = 1;
2152 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f))
2153 * CHARSET_WIDTH (charset));
2154 it->phys_ascent = FONT_BASE (font) + boff;
2155 it->phys_descent = FONT_DESCENT (font) - boff;
2157 else
2159 it->pixel_width = pcm->width;
2160 it->phys_ascent = pcm->ascent + boff;
2161 it->phys_descent = pcm->descent - boff;
2162 if (it->glyph_row
2163 && (pcm->lbearing < 0
2164 || pcm->rbearing > pcm->width))
2165 it->glyph_row->contains_overlapping_glyphs_p = 1;
2167 it->nglyphs = 1;
2168 it->ascent = FONT_BASE (font) + boff;
2169 it->descent = FONT_DESCENT (font) - boff;
2171 if (face->box != FACE_NO_BOX)
2173 int thick = face->box_line_width;
2174 it->ascent += thick;
2175 it->descent += thick;
2177 if (it->start_of_box_run_p)
2178 it->pixel_width += thick;
2179 if (it->end_of_box_run_p)
2180 it->pixel_width += thick;
2183 /* If face has an overline, add the height of the overline
2184 (1 pixel) and a 1 pixel margin to the character height. */
2185 if (face->overline_p)
2186 it->ascent += 2;
2188 take_vertical_position_into_account (it);
2190 if (it->glyph_row)
2191 x_append_glyph (it);
2193 it->multibyte_p = saved_multibyte_p;
2195 else if (it->what == IT_COMPOSITION)
2197 /* Note: A composition is represented as one glyph in the
2198 glyph matrix. There are no padding glyphs. */
2199 wchar_t char2b;
2200 XFontStruct *font;
2201 struct face *face = FACE_FROM_ID (it->f, it->face_id);
2202 XCharStruct *pcm;
2203 int font_not_found_p;
2204 struct font_info *font_info;
2205 int boff; /* baseline offset */
2206 struct composition *cmp = composition_table[it->cmp_id];
2208 /* Maybe translate single-byte characters to multibyte. */
2209 it->char_to_display = it->c;
2210 if (unibyte_display_via_language_environment
2211 && SINGLE_BYTE_CHAR_P (it->c)
2212 && (it->c >= 0240
2213 || (it->c >= 0200
2214 && !NILP (Vnonascii_translation_table))))
2216 it->char_to_display = unibyte_char_to_multibyte (it->c);
2219 /* Get face and font to use. Encode IT->char_to_display. */
2220 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
2221 face = FACE_FROM_ID (it->f, it->face_id);
2222 x_get_char_face_and_encoding (it->f, it->char_to_display,
2223 it->face_id, &char2b, it->multibyte_p);
2224 font = face->font;
2226 /* When no suitable font found, use the default font. */
2227 font_not_found_p = font == NULL;
2228 if (font_not_found_p)
2230 font = FRAME_FONT (it->f);
2231 boff = it->f->output_data.w32->baseline_offset;
2232 font_info = NULL;
2234 else
2236 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2237 boff = font_info->baseline_offset;
2238 if (font_info->vertical_centering)
2239 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2242 /* There are no padding glyphs, so there is only one glyph to
2243 produce for the composition. Important is that pixel_width,
2244 ascent and descent are the values of what is drawn by
2245 draw_glyphs (i.e. the values of the overall glyphs composed). */
2246 it->nglyphs = 1;
2248 /* If we have not yet calculated pixel size data of glyphs of
2249 the composition for the current face font, calculate them
2250 now. Theoretically, we have to check all fonts for the
2251 glyphs, but that requires much time and memory space. So,
2252 here we check only the font of the first glyph. This leads
2253 to incorrect display very rarely, and C-l (recenter) can
2254 correct the display anyway. */
2255 if (cmp->font != (void *) font)
2257 /* Ascent and descent of the font of the first character of
2258 this composition (adjusted by baseline offset). Ascent
2259 and descent of overall glyphs should not be less than
2260 them respectively. */
2261 int font_ascent = FONT_BASE (font) + boff;
2262 int font_descent = FONT_DESCENT (font) - boff;
2263 /* Bounding box of the overall glyphs. */
2264 int leftmost, rightmost, lowest, highest;
2265 int i, width, ascent, descent;
2266 enum w32_char_font_type font_type;
2268 cmp->font = (void *) font;
2270 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1)
2271 font_type = BDF_1D_FONT;
2272 else if (font->bdf)
2273 font_type = BDF_2D_FONT;
2274 else
2275 font_type = UNICODE_FONT;
2277 /* Initialize the bounding box. */
2278 pcm = w32_per_char_metric (font, &char2b, font_type);
2279 if (pcm)
2281 width = pcm->width;
2282 ascent = pcm->ascent;
2283 descent = pcm->descent;
2285 else
2287 width = FONT_WIDTH (font);
2288 ascent = FONT_BASE (font);
2289 descent = FONT_DESCENT (font);
2292 rightmost = width;
2293 lowest = - descent + boff;
2294 highest = ascent + boff;
2295 leftmost = 0;
2297 if (font_info
2298 && font_info->default_ascent
2299 && CHAR_TABLE_P (Vuse_default_ascent)
2300 && !NILP (Faref (Vuse_default_ascent,
2301 make_number (it->char_to_display))))
2302 highest = font_info->default_ascent + boff;
2304 /* Draw the first glyph at the normal position. It may be
2305 shifted to right later if some other glyphs are drawn at
2306 the left. */
2307 cmp->offsets[0] = 0;
2308 cmp->offsets[1] = boff;
2310 /* Set cmp->offsets for the remaining glyphs. */
2311 for (i = 1; i < cmp->glyph_len; i++)
2313 int left, right, btm, top;
2314 int ch = COMPOSITION_GLYPH (cmp, i);
2315 int face_id = FACE_FOR_CHAR (it->f, face, ch);
2317 face = FACE_FROM_ID (it->f, face_id);
2318 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b,
2319 it->multibyte_p);
2320 font = face->font;
2321 if (font == NULL)
2323 font = FRAME_FONT (it->f);
2324 boff = it->f->output_data.w32->baseline_offset;
2325 font_info = NULL;
2327 else
2329 font_info
2330 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2331 boff = font_info->baseline_offset;
2332 if (font_info->vertical_centering)
2333 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2336 if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1)
2337 font_type = BDF_1D_FONT;
2338 else if (font->bdf)
2339 font_type = BDF_2D_FONT;
2340 else
2341 font_type = UNICODE_FONT;
2343 pcm = w32_per_char_metric (font, &char2b, font_type);
2344 if (pcm)
2346 width = pcm->width;
2347 ascent = pcm->ascent;
2348 descent = pcm->descent;
2350 else
2352 width = FONT_WIDTH (font);
2353 ascent = FONT_BASE (font);
2354 descent = FONT_DESCENT (font);
2357 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
2359 /* Relative composition with or without
2360 alternate chars. */
2361 left = (leftmost + rightmost - width) / 2;
2362 btm = - descent + boff;
2363 if (font_info && font_info->relative_compose
2364 && (! CHAR_TABLE_P (Vignore_relative_composition)
2365 || NILP (Faref (Vignore_relative_composition,
2366 make_number (ch)))))
2369 if (- descent >= font_info->relative_compose)
2370 /* One extra pixel between two glyphs. */
2371 btm = highest + 1;
2372 else if (ascent <= 0)
2373 /* One extra pixel between two glyphs. */
2374 btm = lowest - 1 - ascent - descent;
2377 else
2379 /* A composition rule is specified by an integer
2380 value that encodes global and new reference
2381 points (GREF and NREF). GREF and NREF are
2382 specified by numbers as below:
2384 0---1---2 -- ascent
2388 9--10--11 -- center
2390 ---3---4---5--- baseline
2392 6---7---8 -- descent
2394 int rule = COMPOSITION_RULE (cmp, i);
2395 int gref, nref, grefx, grefy, nrefx, nrefy;
2397 COMPOSITION_DECODE_RULE (rule, gref, nref);
2398 grefx = gref % 3, nrefx = nref % 3;
2399 grefy = gref / 3, nrefy = nref / 3;
2401 left = (leftmost
2402 + grefx * (rightmost - leftmost) / 2
2403 - nrefx * width / 2);
2404 btm = ((grefy == 0 ? highest
2405 : grefy == 1 ? 0
2406 : grefy == 2 ? lowest
2407 : (highest + lowest) / 2)
2408 - (nrefy == 0 ? ascent + descent
2409 : nrefy == 1 ? descent - boff
2410 : nrefy == 2 ? 0
2411 : (ascent + descent) / 2));
2414 cmp->offsets[i * 2] = left;
2415 cmp->offsets[i * 2 + 1] = btm + descent;
2417 /* Update the bounding box of the overall glyphs. */
2418 right = left + width;
2419 top = btm + descent + ascent;
2420 if (left < leftmost)
2421 leftmost = left;
2422 if (right > rightmost)
2423 rightmost = right;
2424 if (top > highest)
2425 highest = top;
2426 if (btm < lowest)
2427 lowest = btm;
2430 /* If there are glyphs whose x-offsets are negative,
2431 shift all glyphs to the right and make all x-offsets
2432 non-negative. */
2433 if (leftmost < 0)
2435 for (i = 0; i < cmp->glyph_len; i++)
2436 cmp->offsets[i * 2] -= leftmost;
2437 rightmost -= leftmost;
2440 cmp->pixel_width = rightmost;
2441 cmp->ascent = highest;
2442 cmp->descent = - lowest;
2443 if (cmp->ascent < font_ascent)
2444 cmp->ascent = font_ascent;
2445 if (cmp->descent < font_descent)
2446 cmp->descent = font_descent;
2449 it->pixel_width = cmp->pixel_width;
2450 it->ascent = it->phys_ascent = cmp->ascent;
2451 it->descent = it->phys_descent = cmp->descent;
2453 if (face->box != FACE_NO_BOX)
2455 int thick = face->box_line_width;
2456 it->ascent += thick;
2457 it->descent += thick;
2459 if (it->start_of_box_run_p)
2460 it->pixel_width += thick;
2461 if (it->end_of_box_run_p)
2462 it->pixel_width += thick;
2465 /* If face has an overline, add the height of the overline
2466 (1 pixel) and a 1 pixel margin to the character height. */
2467 if (face->overline_p)
2468 it->ascent += 2;
2470 take_vertical_position_into_account (it);
2472 if (it->glyph_row)
2473 x_append_composite_glyph (it);
2475 else if (it->what == IT_IMAGE)
2476 x_produce_image_glyph (it);
2477 else if (it->what == IT_STRETCH)
2478 x_produce_stretch_glyph (it);
2480 /* Accumulate dimensions. */
2481 xassert (it->ascent >= 0 && it->descent > 0);
2482 if (it->area == TEXT_AREA)
2483 it->current_x += it->pixel_width;
2485 it->descent += it->extra_line_spacing;
2487 it->max_ascent = max (it->max_ascent, it->ascent);
2488 it->max_descent = max (it->max_descent, it->descent);
2489 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
2490 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
2494 /* Estimate the pixel height of the mode or top line on frame F.
2495 FACE_ID specifies what line's height to estimate. */
2498 x_estimate_mode_line_height (f, face_id)
2499 struct frame *f;
2500 enum face_id face_id;
2502 int height = 1;
2504 /* This function is called so early when Emacs starts that the face
2505 cache and mode line face are not yet initialized. */
2506 if (FRAME_FACE_CACHE (f))
2508 struct face *face = FACE_FROM_ID (f, face_id);
2509 if (face)
2510 height = FONT_HEIGHT (face->font) + 2 * face->box_line_width;
2513 return height;
2518 BOOL
2519 w32_use_unicode_for_codepage (codepage)
2520 int codepage;
2522 /* If the current codepage is supported, use Unicode for output. */
2523 return (w32_enable_unicode_output
2524 && codepage != CP_DEFAULT && IsValidCodePage (codepage));
2528 /***********************************************************************
2529 Glyph display
2530 ***********************************************************************/
2532 /* A sequence of glyphs to be drawn in the same face.
2534 This data structure is not really completely X specific, so it
2535 could possibly, at least partially, be useful for other systems. It
2536 is currently not part of the external redisplay interface because
2537 it's not clear what other systems will need. */
2539 struct glyph_string
2541 /* X-origin of the string. */
2542 int x;
2544 /* Y-origin and y-position of the base line of this string. */
2545 int y, ybase;
2547 /* The width of the string, not including a face extension. */
2548 int width;
2550 /* The width of the string, including a face extension. */
2551 int background_width;
2553 /* The height of this string. This is the height of the line this
2554 string is drawn in, and can be different from the height of the
2555 font the string is drawn in. */
2556 int height;
2558 /* Number of pixels this string overwrites in front of its x-origin.
2559 This number is zero if the string has an lbearing >= 0; it is
2560 -lbearing, if the string has an lbearing < 0. */
2561 int left_overhang;
2563 /* Number of pixels this string overwrites past its right-most
2564 nominal x-position, i.e. x + width. Zero if the string's
2565 rbearing is <= its nominal width, rbearing - width otherwise. */
2566 int right_overhang;
2568 /* The frame on which the glyph string is drawn. */
2569 struct frame *f;
2571 /* The window on which the glyph string is drawn. */
2572 struct window *w;
2574 /* X display and window for convenience. */
2575 Window window;
2577 /* The glyph row for which this string was built. It determines the
2578 y-origin and height of the string. */
2579 struct glyph_row *row;
2581 /* The area within row. */
2582 enum glyph_row_area area;
2584 /* Characters to be drawn, and number of characters. */
2585 wchar_t *char2b;
2586 int nchars;
2588 /* A face-override for drawing cursors, mouse face and similar. */
2589 enum draw_glyphs_face hl;
2591 /* Face in which this string is to be drawn. */
2592 struct face *face;
2594 /* Font in which this string is to be drawn. */
2595 XFontStruct *font;
2597 /* Font info for this string. */
2598 struct font_info *font_info;
2600 /* Non-null means this string describes (part of) a composition.
2601 All characters from char2b are drawn composed. */
2602 struct composition *cmp;
2604 /* Index of this glyph string's first character in the glyph
2605 definition of CMP. If this is zero, this glyph string describes
2606 the first character of a composition. */
2607 int gidx;
2609 /* 1 means this glyph strings face has to be drawn to the right end
2610 of the window's drawing area. */
2611 unsigned extends_to_end_of_line_p : 1;
2613 /* 1 means the background of this string has been drawn. */
2614 unsigned background_filled_p : 1;
2616 /* 1 means glyph string must be drawn with 16-bit functions. */
2617 unsigned two_byte_p : 1;
2619 /* 1 means that the original font determined for drawing this glyph
2620 string could not be loaded. The member `font' has been set to
2621 the frame's default font in this case. */
2622 unsigned font_not_found_p : 1;
2624 /* 1 means that the face in which this glyph string is drawn has a
2625 stipple pattern. */
2626 unsigned stippled_p : 1;
2628 /* 1 means only the foreground of this glyph string must be drawn,
2629 and we should use the physical height of the line this glyph
2630 string appears in as clip rect. */
2631 unsigned for_overlaps_p : 1;
2633 /* The GC to use for drawing this glyph string. */
2634 XGCValues *gc;
2636 HDC hdc;
2638 /* A pointer to the first glyph in the string. This glyph
2639 corresponds to char2b[0]. Needed to draw rectangles if
2640 font_not_found_p is 1. */
2641 struct glyph *first_glyph;
2643 /* Image, if any. */
2644 struct image *img;
2646 struct glyph_string *next, *prev;
2650 /* Encapsulate the different ways of displaying text under W32. */
2652 void W32_TEXTOUT (s, x, y,chars,nchars)
2653 struct glyph_string * s;
2654 int x, y;
2655 wchar_t * chars;
2656 int nchars;
2658 int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1;
2659 if (s->gc->font->bdf)
2660 w32_BDF_TextOut (s->gc->font->bdf, s->hdc,
2661 x, y, (char *) chars, charset_dim,
2662 nchars * charset_dim, 0);
2663 else if (s->first_glyph->w32_font_type == UNICODE_FONT)
2664 ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
2665 else
2666 ExtTextOut (s->hdc, x, y, 0, NULL, (char *) chars,
2667 nchars * charset_dim, NULL);
2670 #if 0
2672 static void
2673 x_dump_glyph_string (s)
2674 struct glyph_string *s;
2676 fprintf (stderr, "glyph string\n");
2677 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
2678 s->x, s->y, s->width, s->height);
2679 fprintf (stderr, " ybase = %d\n", s->ybase);
2680 fprintf (stderr, " hl = %d\n", s->hl);
2681 fprintf (stderr, " left overhang = %d, right = %d\n",
2682 s->left_overhang, s->right_overhang);
2683 fprintf (stderr, " nchars = %d\n", s->nchars);
2684 fprintf (stderr, " extends to end of line = %d\n",
2685 s->extends_to_end_of_line_p);
2686 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
2687 fprintf (stderr, " bg width = %d\n", s->background_width);
2690 #endif /* GLYPH_DEBUG */
2694 static void x_append_glyph_string_lists P_ ((struct glyph_string **,
2695 struct glyph_string **,
2696 struct glyph_string *,
2697 struct glyph_string *));
2698 static void x_prepend_glyph_string_lists P_ ((struct glyph_string **,
2699 struct glyph_string **,
2700 struct glyph_string *,
2701 struct glyph_string *));
2702 static void x_append_glyph_string P_ ((struct glyph_string **,
2703 struct glyph_string **,
2704 struct glyph_string *));
2705 static int x_left_overwritten P_ ((struct glyph_string *));
2706 static int x_left_overwriting P_ ((struct glyph_string *));
2707 static int x_right_overwritten P_ ((struct glyph_string *));
2708 static int x_right_overwriting P_ ((struct glyph_string *));
2709 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int,
2710 int, int));
2711 static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc,
2712 wchar_t *, struct window *,
2713 struct glyph_row *,
2714 enum glyph_row_area, int,
2715 enum draw_glyphs_face));
2716 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
2717 enum glyph_row_area, int, int,
2718 enum draw_glyphs_face, int *, int *, int));
2719 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2720 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2721 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2722 int));
2723 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
2724 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
2725 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
2726 static void x_draw_glyph_string P_ ((struct glyph_string *));
2727 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
2728 static void x_set_cursor_gc P_ ((struct glyph_string *));
2729 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
2730 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
2731 static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *,
2732 struct frame *,
2733 int *, int *));
2734 static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int));
2735 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
2736 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
2737 double, int, COLORREF));
2738 static void x_setup_relief_colors P_ ((struct glyph_string *));
2739 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
2740 static void x_draw_image_relief P_ ((struct glyph_string *));
2741 static void x_draw_image_foreground P_ ((struct glyph_string *));
2742 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
2743 static void x_fill_image_glyph_string P_ ((struct glyph_string *));
2744 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
2745 int, int, int));
2746 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
2747 int, int, int, int, RECT *));
2748 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
2749 int, int, int, RECT *));
2750 static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
2751 enum glyph_row_area));
2754 /* Append the list of glyph strings with head H and tail T to the list
2755 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
2757 static INLINE void
2758 x_append_glyph_string_lists (head, tail, h, t)
2759 struct glyph_string **head, **tail;
2760 struct glyph_string *h, *t;
2762 if (h)
2764 if (*head)
2765 (*tail)->next = h;
2766 else
2767 *head = h;
2768 h->prev = *tail;
2769 *tail = t;
2774 /* Prepend the list of glyph strings with head H and tail T to the
2775 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
2776 result. */
2778 static INLINE void
2779 x_prepend_glyph_string_lists (head, tail, h, t)
2780 struct glyph_string **head, **tail;
2781 struct glyph_string *h, *t;
2783 if (h)
2785 if (*head)
2786 (*head)->prev = t;
2787 else
2788 *tail = t;
2789 t->next = *head;
2790 *head = h;
2795 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
2796 Set *HEAD and *TAIL to the resulting list. */
2798 static INLINE void
2799 x_append_glyph_string (head, tail, s)
2800 struct glyph_string **head, **tail;
2801 struct glyph_string *s;
2803 s->next = s->prev = NULL;
2804 x_append_glyph_string_lists (head, tail, s, s);
2808 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2809 face. */
2811 static void
2812 x_set_cursor_gc (s)
2813 struct glyph_string *s;
2815 if (s->font == FRAME_FONT (s->f)
2816 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
2817 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
2818 && !s->cmp)
2819 s->gc = s->f->output_data.w32->cursor_gc;
2820 else
2822 /* Cursor on non-default face: must merge. */
2823 XGCValues xgcv;
2824 unsigned long mask;
2826 xgcv.background = s->f->output_data.w32->cursor_pixel;
2827 xgcv.foreground = s->face->background;
2829 /* If the glyph would be invisible, try a different foreground. */
2830 if (xgcv.foreground == xgcv.background)
2831 xgcv.foreground = s->face->foreground;
2832 if (xgcv.foreground == xgcv.background)
2833 xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
2834 if (xgcv.foreground == xgcv.background)
2835 xgcv.foreground = s->face->foreground;
2837 /* Make sure the cursor is distinct from text in this face. */
2838 if (xgcv.background == s->face->background
2839 && xgcv.foreground == s->face->foreground)
2841 xgcv.background = s->face->foreground;
2842 xgcv.foreground = s->face->background;
2845 IF_DEBUG (x_check_font (s->f, s->font));
2846 xgcv.font = s->font;
2847 mask = GCForeground | GCBackground | GCFont;
2849 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2850 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2851 mask, &xgcv);
2852 else
2853 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2854 = XCreateGC (NULL, s->window, mask, &xgcv);
2856 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2861 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2863 static void
2864 x_set_mouse_face_gc (s)
2865 struct glyph_string *s;
2867 int face_id;
2868 struct face *face;
2870 /* What face has to be used for the mouse face? */
2871 face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
2872 face = FACE_FROM_ID (s->f, face_id);
2873 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
2874 s->face = FACE_FROM_ID (s->f, face_id);
2875 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2877 /* If font in this face is same as S->font, use it. */
2878 if (s->font == s->face->font)
2879 s->gc = s->face->gc;
2880 else
2882 /* Otherwise construct scratch_cursor_gc with values from FACE
2883 but font FONT. */
2884 XGCValues xgcv;
2885 unsigned long mask;
2887 xgcv.background = s->face->background;
2888 xgcv.foreground = s->face->foreground;
2889 IF_DEBUG (x_check_font (s->f, s->font));
2890 xgcv.font = s->font;
2891 mask = GCForeground | GCBackground | GCFont;
2893 if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
2894 XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
2895 mask, &xgcv);
2896 else
2897 FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
2898 = XCreateGC (NULL, s->window, mask, &xgcv);
2900 s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
2903 xassert (s->gc != 0);
2907 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2908 Faces to use in the mode line have already been computed when the
2909 matrix was built, so there isn't much to do, here. */
2911 static INLINE void
2912 x_set_mode_line_face_gc (s)
2913 struct glyph_string *s;
2915 s->gc = s->face->gc;
2919 /* Set S->gc of glyph string S for drawing that glyph string. Set
2920 S->stippled_p to a non-zero value if the face of S has a stipple
2921 pattern. */
2923 static INLINE void
2924 x_set_glyph_string_gc (s)
2925 struct glyph_string *s;
2927 PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
2929 if (s->hl == DRAW_NORMAL_TEXT)
2931 s->gc = s->face->gc;
2932 s->stippled_p = s->face->stipple != 0;
2934 else if (s->hl == DRAW_INVERSE_VIDEO)
2936 x_set_mode_line_face_gc (s);
2937 s->stippled_p = s->face->stipple != 0;
2939 else if (s->hl == DRAW_CURSOR)
2941 x_set_cursor_gc (s);
2942 s->stippled_p = 0;
2944 else if (s->hl == DRAW_MOUSE_FACE)
2946 x_set_mouse_face_gc (s);
2947 s->stippled_p = s->face->stipple != 0;
2949 else if (s->hl == DRAW_IMAGE_RAISED
2950 || s->hl == DRAW_IMAGE_SUNKEN)
2952 s->gc = s->face->gc;
2953 s->stippled_p = s->face->stipple != 0;
2955 else
2957 s->gc = s->face->gc;
2958 s->stippled_p = s->face->stipple != 0;
2961 /* GC must have been set. */
2962 xassert (s->gc != 0);
2966 /* Return in *R the clipping rectangle for glyph string S. */
2968 static void
2969 w32_get_glyph_string_clip_rect (s, r)
2970 struct glyph_string *s;
2971 RECT *r;
2973 int r_height, r_width;
2975 if (s->row->full_width_p)
2977 /* Draw full-width. X coordinates are relative to S->w->left. */
2978 int canon_x = CANON_X_UNIT (s->f);
2980 r->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
2981 r_width = XFASTINT (s->w->width) * canon_x;
2983 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
2985 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
2986 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
2987 r->left -= width;
2990 r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
2992 /* Unless displaying a mode or menu bar line, which are always
2993 fully visible, clip to the visible part of the row. */
2994 if (s->w->pseudo_window_p)
2995 r_height = s->row->visible_height;
2996 else
2997 r_height = s->height;
2999 else
3001 /* This is a text line that may be partially visible. */
3002 r->left = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
3003 r_width = window_box_width (s->w, s->area);
3004 r_height = s->row->visible_height;
3007 /* Don't use S->y for clipping because it doesn't take partially
3008 visible lines into account. For example, it can be negative for
3009 partially visible lines at the top of a window. */
3010 if (!s->row->full_width_p
3011 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
3012 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3013 else
3014 r->top = max (0, s->row->y);
3016 /* If drawing a tool-bar window, draw it over the internal border
3017 at the top of the window. */
3018 if (s->w == XWINDOW (s->f->tool_bar_window))
3019 r->top -= s->f->output_data.w32->internal_border_width;
3021 /* If S draws overlapping rows, it's sufficient to use the top and
3022 bottom of the window for clipping because this glyph string
3023 intentionally draws over other lines. */
3024 if (s->for_overlaps_p)
3026 r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
3027 r_height = window_text_bottom_y (s->w) - r->top;
3030 r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
3032 r->bottom = r->top + r_height;
3033 r->right = r->left + r_width;
3037 /* Set clipping for output of glyph string S. S may be part of a mode
3038 line or menu if we don't have X toolkit support. */
3040 static INLINE void
3041 x_set_glyph_string_clipping (s)
3042 struct glyph_string *s;
3044 RECT r;
3045 w32_get_glyph_string_clip_rect (s, &r);
3046 w32_set_clip_rectangle (s->hdc, &r);
3050 /* Compute left and right overhang of glyph string S. If S is a glyph
3051 string for a composition, assume overhangs don't exist. */
3053 static INLINE void
3054 x_compute_glyph_string_overhangs (s)
3055 struct glyph_string *s;
3057 /* TODO: Windows does not appear to have a method for
3058 getting this info without getting the ABC widths for each
3059 individual character and working it out manually. */
3063 /* Compute overhangs and x-positions for glyph string S and its
3064 predecessors, or successors. X is the starting x-position for S.
3065 BACKWARD_P non-zero means process predecessors. */
3067 static void
3068 x_compute_overhangs_and_x (s, x, backward_p)
3069 struct glyph_string *s;
3070 int x;
3071 int backward_p;
3073 if (backward_p)
3075 while (s)
3077 x_compute_glyph_string_overhangs (s);
3078 x -= s->width;
3079 s->x = x;
3080 s = s->prev;
3083 else
3085 while (s)
3087 x_compute_glyph_string_overhangs (s);
3088 s->x = x;
3089 x += s->width;
3090 s = s->next;
3096 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
3097 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
3098 assumed to be zero. */
3100 static void
3101 w32_get_glyph_overhangs (hdc, glyph, f, left, right)
3102 HDC hdc;
3103 struct glyph *glyph;
3104 struct frame *f;
3105 int *left, *right;
3107 int c;
3109 *left = *right = 0;
3111 if (glyph->type == CHAR_GLYPH)
3113 XFontStruct *font;
3114 struct face *face;
3115 wchar_t char2b;
3116 XCharStruct *pcm;
3118 face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
3119 font = face->font;
3121 if (font
3122 && (pcm = w32_per_char_metric (font, &char2b,
3123 glyph->w32_font_type)))
3125 if (pcm->rbearing > pcm->width)
3126 *right = pcm->rbearing - pcm->width;
3127 if (pcm->lbearing < 0)
3128 *left = -pcm->lbearing;
3134 static void
3135 x_get_glyph_overhangs (glyph, f, left, right)
3136 struct glyph *glyph;
3137 struct frame *f;
3138 int *left, *right;
3140 HDC hdc = get_frame_dc (f);
3141 /* Convert to unicode! */
3142 w32_get_glyph_overhangs (hdc, glyph, f, left, right);
3143 release_frame_dc (f, hdc);
3147 /* Return the index of the first glyph preceding glyph string S that
3148 is overwritten by S because of S's left overhang. Value is -1
3149 if no glyphs are overwritten. */
3151 static int
3152 x_left_overwritten (s)
3153 struct glyph_string *s;
3155 int k;
3157 if (s->left_overhang)
3159 int x = 0, i;
3160 struct glyph *glyphs = s->row->glyphs[s->area];
3161 int first = s->first_glyph - glyphs;
3163 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
3164 x -= glyphs[i].pixel_width;
3166 k = i + 1;
3168 else
3169 k = -1;
3171 return k;
3175 /* Return the index of the first glyph preceding glyph string S that
3176 is overwriting S because of its right overhang. Value is -1 if no
3177 glyph in front of S overwrites S. */
3179 static int
3180 x_left_overwriting (s)
3181 struct glyph_string *s;
3183 int i, k, x;
3184 struct glyph *glyphs = s->row->glyphs[s->area];
3185 int first = s->first_glyph - glyphs;
3187 k = -1;
3188 x = 0;
3189 for (i = first - 1; i >= 0; --i)
3191 int left, right;
3192 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3193 if (x + right > 0)
3194 k = i;
3195 x -= glyphs[i].pixel_width;
3198 return k;
3202 /* Return the index of the last glyph following glyph string S that is
3203 not overwritten by S because of S's right overhang. Value is -1 if
3204 no such glyph is found. */
3206 static int
3207 x_right_overwritten (s)
3208 struct glyph_string *s;
3210 int k = -1;
3212 if (s->right_overhang)
3214 int x = 0, i;
3215 struct glyph *glyphs = s->row->glyphs[s->area];
3216 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3217 int end = s->row->used[s->area];
3219 for (i = first; i < end && s->right_overhang > x; ++i)
3220 x += glyphs[i].pixel_width;
3222 k = i;
3225 return k;
3229 /* Return the index of the last glyph following glyph string S that
3230 overwrites S because of its left overhang. Value is negative
3231 if no such glyph is found. */
3233 static int
3234 x_right_overwriting (s)
3235 struct glyph_string *s;
3237 int i, k, x;
3238 int end = s->row->used[s->area];
3239 struct glyph *glyphs = s->row->glyphs[s->area];
3240 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
3242 k = -1;
3243 x = 0;
3244 for (i = first; i < end; ++i)
3246 int left, right;
3247 w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right);
3248 if (x - left < 0)
3249 k = i;
3250 x += glyphs[i].pixel_width;
3253 return k;
3257 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
3259 static INLINE void
3260 x_clear_glyph_string_rect (s, x, y, w, h)
3261 struct glyph_string *s;
3262 int x, y, w, h;
3264 int real_x = x;
3265 int real_y = y;
3266 int real_w = w;
3267 int real_h = h;
3268 #if 0
3269 /* Take clipping into account. */
3270 if (s->gc->clip_mask == Rect)
3272 real_x = max (real_x, s->gc->clip_rectangle.left);
3273 real_y = max (real_y, s->gc->clip_rectangle.top);
3274 real_w = min (real_w, s->gc->clip_rectangle.right
3275 - s->gc->clip_rectangle.left);
3276 real_h = min (real_h, s->gc->clip_rectangle.bottom
3277 - s->gc->clip_rectangle.top);
3279 #endif
3280 w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
3281 real_w, real_h);
3285 /* Draw the background of glyph_string S. If S->background_filled_p
3286 is non-zero don't draw it. FORCE_P non-zero means draw the
3287 background even if it wouldn't be drawn normally. This is used
3288 when a string preceding S draws into the background of S, or S
3289 contains the first component of a composition. */
3291 static void
3292 x_draw_glyph_string_background (s, force_p)
3293 struct glyph_string *s;
3294 int force_p;
3296 /* Nothing to do if background has already been drawn or if it
3297 shouldn't be drawn in the first place. */
3298 if (!s->background_filled_p)
3300 #if 0 /* TODO: stipple */
3301 if (s->stippled_p)
3303 /* Fill background with a stipple pattern. */
3304 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3305 XFillRectangle (s->display, s->window, s->gc, s->x,
3306 s->y + s->face->box_line_width,
3307 s->background_width,
3308 s->height - 2 * s->face->box_line_width);
3309 XSetFillStyle (s->display, s->gc, FillSolid);
3310 s->background_filled_p = 1;
3312 else
3313 #endif
3314 if (FONT_HEIGHT (s->font) < s->height - 2 * s->face->box_line_width
3315 || s->font_not_found_p
3316 || s->extends_to_end_of_line_p
3317 || s->font->bdf
3318 || force_p)
3320 x_clear_glyph_string_rect (s, s->x, s->y + s->face->box_line_width,
3321 s->background_width,
3322 s->height - 2 * s->face->box_line_width);
3323 s->background_filled_p = 1;
3329 /* Draw the foreground of glyph string S. */
3331 static void
3332 x_draw_glyph_string_foreground (s)
3333 struct glyph_string *s;
3335 int i, x;
3336 HFONT old_font;
3338 /* If first glyph of S has a left box line, start drawing the text
3339 of S to the right of that box line. */
3340 if (s->face->box != FACE_NO_BOX
3341 && s->first_glyph->left_box_line_p)
3342 x = s->x + s->face->box_line_width;
3343 else
3344 x = s->x;
3346 if (s->for_overlaps_p || (s->background_filled_p && s->hl != DRAW_CURSOR))
3347 SetBkMode (s->hdc, TRANSPARENT);
3348 else
3349 SetBkMode (s->hdc, OPAQUE);
3351 SetTextColor (s->hdc, s->gc->foreground);
3352 SetBkColor (s->hdc, s->gc->background);
3353 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3355 if (s->font && s->font->hfont)
3356 old_font = SelectObject (s->hdc, s->font->hfont);
3358 /* Draw characters of S as rectangles if S's font could not be
3359 loaded. */
3360 if (s->font_not_found_p)
3362 for (i = 0; i < s->nchars; ++i)
3364 struct glyph *g = s->first_glyph + i;
3366 w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
3367 s->height - 1);
3368 x += g->pixel_width;
3371 else
3373 char *char1b = (char *) s->char2b;
3374 int boff = s->font_info->baseline_offset;
3376 if (s->font_info->vertical_centering)
3377 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
3379 /* If we can use 8-bit functions, condense S->char2b. */
3380 if (!s->two_byte_p)
3381 for (i = 0; i < s->nchars; ++i)
3382 char1b[i] = BYTE2 (s->char2b[i]);
3384 /* Draw text with TextOut and friends. */
3385 W32_TEXTOUT (s, x, s->ybase - boff, s->char2b, s->nchars);
3387 if (s->font && s->font->hfont)
3388 SelectObject (s->hdc, old_font);
3391 /* Draw the foreground of composite glyph string S. */
3393 static void
3394 x_draw_composite_glyph_string_foreground (s)
3395 struct glyph_string *s;
3397 int i, x;
3398 HFONT old_font;
3400 /* If first glyph of S has a left box line, start drawing the text
3401 of S to the right of that box line. */
3402 if (s->face->box != FACE_NO_BOX
3403 && s->first_glyph->left_box_line_p)
3404 x = s->x + s->face->box_line_width;
3405 else
3406 x = s->x;
3408 /* S is a glyph string for a composition. S->gidx is the index of
3409 the first character drawn for glyphs of this composition.
3410 S->gidx == 0 means we are drawing the very first character of
3411 this composition. */
3413 SetTextColor (s->hdc, s->gc->foreground);
3414 SetBkColor (s->hdc, s->gc->background);
3415 SetBkMode (s->hdc, TRANSPARENT);
3416 SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
3418 if (s->font && s->font->hfont)
3419 old_font = SelectObject (s->hdc, s->font->hfont);
3421 /* Draw a rectangle for the composition if the font for the very
3422 first character of the composition could not be loaded. */
3423 if (s->font_not_found_p)
3425 if (s->gidx == 0)
3426 w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
3427 s->height - 1);
3429 else
3431 for (i = 0; i < s->nchars; i++, ++s->gidx)
3432 W32_TEXTOUT (s, x + s->cmp->offsets[s->gidx * 2],
3433 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
3434 s->char2b + i, 1);
3436 if (s->font && s->font->hfont)
3437 SelectObject (s->hdc, old_font);
3440 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3441 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3442 If this produces the same color as COLOR, try a color where all RGB
3443 values have DELTA added. Return the allocated color in *COLOR.
3444 DISPLAY is the X display, CMAP is the colormap to operate on.
3445 Value is non-zero if successful. */
3447 static int
3448 w32_alloc_lighter_color (f, color, factor, delta)
3449 struct frame *f;
3450 COLORREF *color;
3451 double factor;
3452 int delta;
3454 COLORREF new;
3456 /* Change RGB values by specified FACTOR. Avoid overflow! */
3457 xassert (factor >= 0);
3458 new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
3459 min (0xff, factor * GetGValue (*color)),
3460 min (0xff, factor * GetBValue (*color)));
3461 if (new == *color)
3462 new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
3463 max (0, min (0xff, delta + GetGValue (*color))),
3464 max (0, min (0xff, delta + GetBValue (*color))));
3466 /* TODO: Map to palette and retry with delta if same? */
3467 /* TODO: Free colors (if using palette)? */
3469 if (new == *color)
3470 return 0;
3472 *color = new;
3474 return 1;
3478 /* Set up the foreground color for drawing relief lines of glyph
3479 string S. RELIEF is a pointer to a struct relief containing the GC
3480 with which lines will be drawn. Use a color that is FACTOR or
3481 DELTA lighter or darker than the relief's background which is found
3482 in S->f->output_data.x->relief_background. If such a color cannot
3483 be allocated, use DEFAULT_PIXEL, instead. */
3485 static void
3486 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
3487 struct frame *f;
3488 struct relief *relief;
3489 double factor;
3490 int delta;
3491 COLORREF default_pixel;
3493 XGCValues xgcv;
3494 struct w32_output *di = f->output_data.w32;
3495 unsigned long mask = GCForeground;
3496 COLORREF pixel;
3497 COLORREF background = di->relief_background;
3498 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
3500 /* TODO: Free colors (if using palette)? */
3502 /* Allocate new color. */
3503 xgcv.foreground = default_pixel;
3504 pixel = background;
3505 if (w32_alloc_lighter_color (f, &pixel, factor, delta))
3507 relief->allocated_p = 1;
3508 xgcv.foreground = relief->pixel = pixel;
3511 if (relief->gc == 0)
3513 #if 0 /* TODO: stipple */
3514 xgcv.stipple = dpyinfo->gray;
3515 mask |= GCStipple;
3516 #endif
3517 relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
3519 else
3520 XChangeGC (NULL, relief->gc, mask, &xgcv);
3524 /* Set up colors for the relief lines around glyph string S. */
3526 static void
3527 x_setup_relief_colors (s)
3528 struct glyph_string *s;
3530 struct w32_output *di = s->f->output_data.w32;
3531 COLORREF color;
3533 if (s->face->use_box_color_for_shadows_p)
3534 color = s->face->box_color;
3535 else
3536 color = s->gc->background;
3538 if (di->white_relief.gc == 0
3539 || color != di->relief_background)
3541 di->relief_background = color;
3542 w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
3543 WHITE_PIX_DEFAULT (s->f));
3544 w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
3545 BLACK_PIX_DEFAULT (s->f));
3550 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3551 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3552 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3553 relief. LEFT_P non-zero means draw a relief on the left side of
3554 the rectangle. RIGHT_P non-zero means draw a relief on the right
3555 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3556 when drawing. */
3558 static void
3559 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
3560 raised_p, left_p, right_p, clip_rect)
3561 struct frame *f;
3562 int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p;
3563 RECT *clip_rect;
3565 int i;
3566 XGCValues gc;
3567 HDC hdc = get_frame_dc (f);
3569 if (raised_p)
3570 gc.foreground = PALETTERGB (255, 255, 255);
3571 else
3572 gc.foreground = PALETTERGB (0, 0, 0);
3574 w32_set_clip_rectangle (hdc, clip_rect);
3576 /* Top. */
3577 for (i = 0; i < width; ++i)
3579 w32_fill_area (f, hdc, gc.foreground,
3580 left_x + i * left_p, top_y + i,
3581 (right_x + 1 - i * right_p) - (left_x + i * left_p), 1);
3584 /* Left. */
3585 if (left_p)
3586 for (i = 0; i < width; ++i)
3588 w32_fill_area (f, hdc, gc.foreground,
3589 left_x + i, top_y + i, 1,
3590 (bottom_y - i) - (top_y + i));
3593 w32_set_clip_rectangle (hdc, NULL);
3595 if (raised_p)
3596 gc.foreground = PALETTERGB (0, 0, 0);
3597 else
3598 gc.foreground = PALETTERGB (255, 255, 255);
3600 w32_set_clip_rectangle (hdc, clip_rect);
3602 /* Bottom. */
3603 for (i = 0; i < width; ++i)
3605 w32_fill_area (f, hdc, gc.foreground,
3606 left_x + i * left_p, bottom_y - i,
3607 (right_x + 1 - i * right_p) - left_x + i * left_p, 1);
3610 /* Right. */
3611 if (right_p)
3612 for (i = 0; i < width; ++i)
3614 w32_fill_area (f, hdc, gc.foreground,
3615 right_x - i, top_y + i + 1, 1,
3616 (bottom_y - i) - (top_y + i + 1));
3619 w32_set_clip_rectangle (hdc, NULL);
3621 release_frame_dc (f, hdc);
3625 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3626 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3627 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3628 left side of the rectangle. RIGHT_P non-zero means draw a line
3629 on the right side of the rectangle. CLIP_RECT is the clipping
3630 rectangle to use when drawing. */
3632 static void
3633 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3634 left_p, right_p, clip_rect)
3635 struct glyph_string *s;
3636 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
3637 RECT *clip_rect;
3639 w32_set_clip_rectangle (s->hdc, clip_rect);
3641 /* Top. */
3642 w32_fill_area (s->f, s->hdc, s->face->box_color,
3643 left_x, top_y, right_x - left_x + 1, width);
3645 /* Left. */
3646 if (left_p)
3648 w32_fill_area (s->f, s->hdc, s->face->box_color,
3649 left_x, top_y, width, bottom_y - top_y + 1);
3652 /* Bottom. */
3653 w32_fill_area (s->f, s->hdc, s->face->box_color,
3654 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
3656 /* Right. */
3657 if (right_p)
3659 w32_fill_area (s->f, s->hdc, s->face->box_color,
3660 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
3663 w32_set_clip_rectangle (s->hdc, NULL);
3667 /* Draw a box around glyph string S. */
3669 static void
3670 x_draw_glyph_string_box (s)
3671 struct glyph_string *s;
3673 int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
3674 int left_p, right_p;
3675 struct glyph *last_glyph;
3676 RECT clip_rect;
3678 last_x = window_box_right (s->w, s->area);
3679 if (s->row->full_width_p
3680 && !s->w->pseudo_window_p)
3682 last_x += FRAME_X_RIGHT_FLAGS_AREA_WIDTH (s->f);
3683 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
3684 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
3687 /* The glyph that may have a right box line. */
3688 last_glyph = (s->cmp || s->img
3689 ? s->first_glyph
3690 : s->first_glyph + s->nchars - 1);
3692 width = s->face->box_line_width;
3693 raised_p = s->face->box == FACE_RAISED_BOX;
3694 left_x = s->x;
3695 right_x = ((s->row->full_width_p
3696 ? last_x - 1
3697 : min (last_x, s->x + s->background_width) - 1));
3698 top_y = s->y;
3699 bottom_y = top_y + s->height - 1;
3701 left_p = (s->first_glyph->left_box_line_p
3702 || (s->hl == DRAW_MOUSE_FACE
3703 && (s->prev == NULL
3704 || s->prev->hl != s->hl)));
3705 right_p = (last_glyph->right_box_line_p
3706 || (s->hl == DRAW_MOUSE_FACE
3707 && (s->next == NULL
3708 || s->next->hl != s->hl)));
3710 w32_get_glyph_string_clip_rect (s, &clip_rect);
3712 if (s->face->box == FACE_SIMPLE_BOX)
3713 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
3714 left_p, right_p, &clip_rect);
3715 else
3717 x_setup_relief_colors (s);
3718 w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
3719 width, raised_p, left_p, right_p, &clip_rect);
3724 /* Draw foreground of image glyph string S. */
3726 static void
3727 x_draw_image_foreground (s)
3728 struct glyph_string *s;
3730 int x;
3731 int y = s->ybase - image_ascent (s->img, s->face);
3733 /* If first glyph of S has a left box line, start drawing it to the
3734 right of that line. */
3735 if (s->face->box != FACE_NO_BOX
3736 && s->first_glyph->left_box_line_p)
3737 x = s->x + s->face->box_line_width;
3738 else
3739 x = s->x;
3741 /* If there is a margin around the image, adjust x- and y-position
3742 by that margin. */
3743 if (s->img->margin)
3745 x += s->img->margin;
3746 y += s->img->margin;
3749 SaveDC (s->hdc);
3751 if (s->img->pixmap)
3753 #if 0 /* TODO: image mask */
3754 if (s->img->mask)
3756 /* We can't set both a clip mask and use XSetClipRectangles
3757 because the latter also sets a clip mask. We also can't
3758 trust on the shape extension to be available
3759 (XShapeCombineRegion). So, compute the rectangle to draw
3760 manually. */
3761 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3762 | GCFunction);
3763 XGCValues xgcv;
3764 XRectangle clip_rect, image_rect, r;
3766 xgcv.clip_mask = s->img->mask;
3767 xgcv.clip_x_origin = x;
3768 xgcv.clip_y_origin = y;
3769 xgcv.function = GXcopy;
3770 XChangeGC (s->display, s->gc, mask, &xgcv);
3772 w32_get_glyph_string_clip_rect (s, &clip_rect);
3773 image_rect.x = x;
3774 image_rect.y = y;
3775 image_rect.width = s->img->width;
3776 image_rect.height = s->img->height;
3777 if (IntersectRect (&r, &clip_rect, &image_rect))
3778 XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
3779 r.x - x, r.y - y, r.width, r.height, r.x, r.y);
3781 else
3782 #endif
3784 HDC compat_hdc = CreateCompatibleDC (s->hdc);
3785 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3786 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
3787 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3788 x_set_glyph_string_clipping (s);
3790 SetTextColor (s->hdc, s->gc->foreground);
3791 SetBkColor (s->hdc, s->gc->background);
3792 #if 0 /* From w32bdf.c (which is from Meadow). */
3793 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3794 compat_hdc, 0, 0, SRCCOPY);
3795 #else
3796 BitBlt (s->hdc, x, y, s->img->width, s->img->height,
3797 compat_hdc, 0, 0, 0xB8074A);
3798 #endif
3799 SelectObject (s->hdc, orig_brush);
3800 DeleteObject (fg_brush);
3801 SelectObject (compat_hdc, orig_obj);
3802 DeleteDC (compat_hdc);
3804 /* When the image has a mask, we can expect that at
3805 least part of a mouse highlight or a block cursor will
3806 be visible. If the image doesn't have a mask, make
3807 a block cursor visible by drawing a rectangle around
3808 the image. I believe it's looking better if we do
3809 nothing here for mouse-face. */
3810 if (s->hl == DRAW_CURSOR)
3811 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width - 1,
3812 s->img->height - 1);
3813 w32_set_clip_rectangle (s->hdc, NULL);
3816 else
3817 w32_draw_rectangle (s->hdc, s->gc, x, y, s->img->width -1,
3818 s->img->height - 1);
3820 RestoreDC (s->hdc ,-1);
3825 /* Draw a relief around the image glyph string S. */
3827 static void
3828 x_draw_image_relief (s)
3829 struct glyph_string *s;
3831 int x0, y0, x1, y1, thick, raised_p;
3832 RECT r;
3833 int x;
3834 int y = s->ybase - image_ascent (s->img, s->face);
3836 /* If first glyph of S has a left box line, start drawing it to the
3837 right of that line. */
3838 if (s->face->box != FACE_NO_BOX
3839 && s->first_glyph->left_box_line_p)
3840 x = s->x + s->face->box_line_width;
3841 else
3842 x = s->x;
3844 /* If there is a margin around the image, adjust x- and y-position
3845 by that margin. */
3846 if (s->img->margin)
3848 x += s->img->margin;
3849 y += s->img->margin;
3852 if (s->hl == DRAW_IMAGE_SUNKEN
3853 || s->hl == DRAW_IMAGE_RAISED)
3855 thick = tool_bar_button_relief > 0 ? tool_bar_button_relief : 3;
3856 raised_p = s->hl == DRAW_IMAGE_RAISED;
3858 else
3860 thick = abs (s->img->relief);
3861 raised_p = s->img->relief > 0;
3864 x0 = x - thick;
3865 y0 = y - thick;
3866 x1 = x + s->img->width + thick - 1;
3867 y1 = y + s->img->height + thick - 1;
3869 x_setup_relief_colors (s);
3870 w32_get_glyph_string_clip_rect (s, &r);
3871 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
3875 /* Draw the foreground of image glyph string S to PIXMAP. */
3877 static void
3878 w32_draw_image_foreground_1 (s, pixmap)
3879 struct glyph_string *s;
3880 HBITMAP pixmap;
3882 HDC hdc = CreateCompatibleDC (s->hdc);
3883 HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
3884 int x;
3885 int y = s->ybase - s->y - image_ascent (s->img, s->face);
3887 /* If first glyph of S has a left box line, start drawing it to the
3888 right of that line. */
3889 if (s->face->box != FACE_NO_BOX
3890 && s->first_glyph->left_box_line_p)
3891 x = s->face->box_line_width;
3892 else
3893 x = 0;
3895 /* If there is a margin around the image, adjust x- and y-position
3896 by that margin. */
3897 if (s->img->margin)
3899 x += s->img->margin;
3900 y += s->img->margin;
3903 if (s->img->pixmap)
3905 #if 0 /* TODO: image mask */
3906 if (s->img->mask)
3908 /* We can't set both a clip mask and use XSetClipRectangles
3909 because the latter also sets a clip mask. We also can't
3910 trust on the shape extension to be available
3911 (XShapeCombineRegion). So, compute the rectangle to draw
3912 manually. */
3913 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
3914 | GCFunction);
3915 XGCValues xgcv;
3917 xgcv.clip_mask = s->img->mask;
3918 xgcv.clip_x_origin = x;
3919 xgcv.clip_y_origin = y;
3920 xgcv.function = GXcopy;
3921 XChangeGC (s->display, s->gc, mask, &xgcv);
3923 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
3924 0, 0, s->img->width, s->img->height, x, y);
3925 XSetClipMask (s->display, s->gc, None);
3927 else
3928 #endif
3930 HDC compat_hdc = CreateCompatibleDC (hdc);
3931 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
3932 HBRUSH orig_brush = SelectObject (hdc, fg_brush);
3933 HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
3935 SetTextColor (hdc, s->gc->foreground);
3936 SetBkColor (hdc, s->gc->background);
3937 #if 0 /* From w32bdf.c (which is from Meadow). */
3938 BitBlt (hdc, x, y, s->img->width, s->img->height,
3939 compat_hdc, 0, 0, SRCCOPY);
3940 #else
3941 BitBlt (hdc, x, y, s->img->width, s->img->height,
3942 compat_hdc, 0, 0, 0xB8074A);
3943 #endif
3944 SelectObject (hdc, orig_brush);
3945 DeleteObject (fg_brush);
3946 SelectObject (compat_hdc, orig_obj);
3947 DeleteDC (compat_hdc);
3949 /* When the image has a mask, we can expect that at
3950 least part of a mouse highlight or a block cursor will
3951 be visible. If the image doesn't have a mask, make
3952 a block cursor visible by drawing a rectangle around
3953 the image. I believe it's looking better if we do
3954 nothing here for mouse-face. */
3955 if (s->hl == DRAW_CURSOR)
3956 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
3957 s->img->height - 1);
3960 else
3961 w32_draw_rectangle (hdc, s->gc, x, y, s->img->width - 1,
3962 s->img->height - 1);
3964 SelectObject (hdc, orig_hdc_obj);
3965 DeleteDC (hdc);
3969 /* Draw part of the background of glyph string S. X, Y, W, and H
3970 give the rectangle to draw. */
3972 static void
3973 x_draw_glyph_string_bg_rect (s, x, y, w, h)
3974 struct glyph_string *s;
3975 int x, y, w, h;
3977 #if 0 /* TODO: stipple */
3978 if (s->stippled_p)
3980 /* Fill background with a stipple pattern. */
3981 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
3982 XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
3983 XSetFillStyle (s->display, s->gc, FillSolid);
3985 else
3986 #endif
3987 x_clear_glyph_string_rect (s, x, y, w, h);
3991 /* Draw image glyph string S.
3993 s->y
3994 s->x +-------------------------
3995 | s->face->box
3997 | +-------------------------
3998 | | s->img->margin
4000 | | +-------------------
4001 | | | the image
4005 static void
4006 x_draw_image_glyph_string (s)
4007 struct glyph_string *s;
4009 int x, y;
4010 int box_line_width = s->face->box_line_width;
4011 int margin = s->img->margin;
4012 int height;
4013 HBITMAP pixmap = 0;
4015 height = s->height - 2 * box_line_width;
4017 /* Fill background with face under the image. Do it only if row is
4018 taller than image or if image has a clip mask to reduce
4019 flickering. */
4020 s->stippled_p = s->face->stipple != 0;
4021 if (height > s->img->height
4022 || margin
4023 #if 0 /* TODO: image mask */
4024 || s->img->mask
4025 #endif
4026 || s->img->pixmap == 0
4027 || s->width != s->background_width)
4029 if (box_line_width && s->first_glyph->left_box_line_p)
4030 x = s->x + box_line_width;
4031 else
4032 x = s->x;
4034 y = s->y + box_line_width;
4035 #if 0 /* TODO: image mask */
4036 if (s->img->mask)
4038 /* Create a pixmap as large as the glyph string Fill it with
4039 the background color. Copy the image to it, using its
4040 mask. Copy the temporary pixmap to the display. */
4041 Screen *screen = FRAME_X_SCREEN (s->f);
4042 int depth = DefaultDepthOfScreen (screen);
4044 /* Create a pixmap as large as the glyph string. */
4045 pixmap = XCreatePixmap (s->display, s->window,
4046 s->background_width,
4047 s->height, depth);
4049 /* Don't clip in the following because we're working on the
4050 pixmap. */
4051 XSetClipMask (s->display, s->gc, None);
4053 /* Fill the pixmap with the background color/stipple. */
4054 if (s->stippled_p)
4056 /* Fill background with a stipple pattern. */
4057 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
4058 XFillRectangle (s->display, pixmap, s->gc,
4059 0, 0, s->background_width, s->height);
4060 XSetFillStyle (s->display, s->gc, FillSolid);
4062 else
4064 XGCValues xgcv;
4065 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
4066 &xgcv);
4067 XSetForeground (s->display, s->gc, xgcv.background);
4068 XFillRectangle (s->display, pixmap, s->gc,
4069 0, 0, s->background_width, s->height);
4070 XSetForeground (s->display, s->gc, xgcv.foreground);
4073 else
4074 #endif
4075 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
4077 s->background_filled_p = 1;
4080 /* Draw the foreground. */
4081 if (pixmap != 0)
4083 w32_draw_image_foreground_1 (s, pixmap);
4084 x_set_glyph_string_clipping (s);
4086 HDC compat_hdc = CreateCompatibleDC (s->hdc);
4087 HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
4088 HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
4089 HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
4091 SetTextColor (s->hdc, s->gc->foreground);
4092 SetBkColor (s->hdc, s->gc->background);
4093 #if 0 /* From w32bdf.c (which is from Meadow). */
4094 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4095 compat_hdc, 0, 0, SRCCOPY);
4096 #else
4097 BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
4098 compat_hdc, 0, 0, 0xB8074A);
4099 #endif
4100 SelectObject (s->hdc, orig_brush);
4101 DeleteObject (fg_brush);
4102 SelectObject (compat_hdc, orig_obj);
4103 DeleteDC (compat_hdc);
4105 DeleteObject (pixmap);
4106 pixmap = 0;
4108 else
4109 x_draw_image_foreground (s);
4111 /* If we must draw a relief around the image, do it. */
4112 if (s->img->relief
4113 || s->hl == DRAW_IMAGE_RAISED
4114 || s->hl == DRAW_IMAGE_SUNKEN)
4115 x_draw_image_relief (s);
4119 /* Draw stretch glyph string S. */
4121 static void
4122 x_draw_stretch_glyph_string (s)
4123 struct glyph_string *s;
4125 xassert (s->first_glyph->type == STRETCH_GLYPH);
4126 s->stippled_p = s->face->stipple != 0;
4128 if (s->hl == DRAW_CURSOR
4129 && !x_stretch_cursor_p)
4131 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
4132 as wide as the stretch glyph. */
4133 int width = min (CANON_X_UNIT (s->f), s->background_width);
4135 /* Draw cursor. */
4136 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
4138 /* Clear rest using the GC of the original non-cursor face. */
4139 if (width < s->background_width)
4141 XGCValues *gc = s->face->gc;
4142 int x = s->x + width, y = s->y;
4143 int w = s->background_width - width, h = s->height;
4144 RECT r;
4145 HDC hdc = s->hdc;
4146 w32_get_glyph_string_clip_rect (s, &r);
4147 w32_set_clip_rectangle (hdc, &r);
4149 #if 0 /* TODO: stipple */
4150 if (s->face->stipple)
4152 /* Fill background with a stipple pattern. */
4153 XSetFillStyle (s->display, gc, FillOpaqueStippled);
4154 XFillRectangle (s->display, s->window, gc, x, y, w, h);
4155 XSetFillStyle (s->display, gc, FillSolid);
4157 else
4158 #endif
4160 w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
4164 else
4165 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
4166 s->height);
4168 s->background_filled_p = 1;
4172 /* Draw glyph string S. */
4174 static void
4175 x_draw_glyph_string (s)
4176 struct glyph_string *s;
4178 /* If S draws into the background of its successor, draw the
4179 background of the successor first so that S can draw into it.
4180 This makes S->next use XDrawString instead of XDrawImageString. */
4181 if (s->next && s->right_overhang && !s->for_overlaps_p)
4183 xassert (s->next->img == NULL);
4184 x_set_glyph_string_gc (s->next);
4185 x_set_glyph_string_clipping (s->next);
4186 x_draw_glyph_string_background (s->next, 1);
4189 /* Set up S->gc, set clipping and draw S. */
4190 x_set_glyph_string_gc (s);
4191 x_set_glyph_string_clipping (s);
4193 switch (s->first_glyph->type)
4195 case IMAGE_GLYPH:
4196 x_draw_image_glyph_string (s);
4197 break;
4199 case STRETCH_GLYPH:
4200 x_draw_stretch_glyph_string (s);
4201 break;
4203 case CHAR_GLYPH:
4204 if (s->for_overlaps_p)
4205 s->background_filled_p = 1;
4206 else
4207 x_draw_glyph_string_background (s, 0);
4208 x_draw_glyph_string_foreground (s);
4209 break;
4211 case COMPOSITE_GLYPH:
4212 if (s->for_overlaps_p || s->gidx > 0)
4213 s->background_filled_p = 1;
4214 else
4215 x_draw_glyph_string_background (s, 1);
4216 x_draw_composite_glyph_string_foreground (s);
4217 break;
4219 default:
4220 abort ();
4223 if (!s->for_overlaps_p)
4225 /* Draw underline. */
4226 if (s->face->underline_p
4227 && (s->font->bdf || !s->font->tm.tmUnderlined))
4229 unsigned long h = 1;
4230 unsigned long dy = s->height - h;
4232 if (s->face->underline_defaulted_p)
4234 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4235 s->y + dy, s->width, 1);
4237 else
4239 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4240 s->y + dy, s->width, 1);
4244 /* Draw overline. */
4245 if (s->face->overline_p)
4247 unsigned long dy = 0, h = 1;
4249 if (s->face->overline_color_defaulted_p)
4251 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
4252 s->y + dy, s->width, h);
4254 else
4256 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4257 s->y + dy, s->width, h);
4261 /* Draw strike-through. */
4262 if (s->face->strike_through_p
4263 && (s->font->bdf || !s->font->tm.tmStruckOut))
4265 unsigned long h = 1;
4266 unsigned long dy = (s->height - h) / 2;
4268 if (s->face->strike_through_color_defaulted_p)
4270 w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
4271 s->width, h);
4273 else
4275 w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
4276 s->y + dy, s->width, h);
4280 /* Draw relief. */
4281 if (s->face->box != FACE_NO_BOX)
4282 x_draw_glyph_string_box (s);
4285 /* Reset clipping. */
4286 w32_set_clip_rectangle (s->hdc, NULL);
4290 static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
4291 struct face **, int));
4294 /* Load glyph string S with a composition components specified by S->cmp.
4295 FACES is an array of faces for all components of this composition.
4296 S->gidx is the index of the first component for S.
4297 OVERLAPS_P non-zero means S should draw the foreground only, and
4298 use its lines physical height for clipping.
4300 Value is the index of a component not in S. */
4302 static int
4303 x_fill_composite_glyph_string (s, faces, overlaps_p)
4304 struct glyph_string *s;
4305 struct face **faces;
4306 int overlaps_p;
4308 int i;
4310 xassert (s);
4312 s->for_overlaps_p = overlaps_p;
4314 s->face = faces[s->gidx];
4315 s->font = s->face->font;
4316 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4318 /* For all glyphs of this composition, starting at the offset
4319 S->gidx, until we reach the end of the definition or encounter a
4320 glyph that requires the different face, add it to S. */
4321 ++s->nchars;
4322 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
4323 ++s->nchars;
4325 /* All glyph strings for the same composition has the same width,
4326 i.e. the width set for the first component of the composition. */
4328 s->width = s->first_glyph->pixel_width;
4330 /* If the specified font could not be loaded, use the frame's
4331 default font, but record the fact that we couldn't load it in
4332 the glyph string so that we can draw rectangles for the
4333 characters of the glyph string. */
4334 if (s->font == NULL)
4336 s->font_not_found_p = 1;
4337 s->font = FRAME_FONT (s->f);
4340 /* Adjust base line for subscript/superscript text. */
4341 s->ybase += s->first_glyph->voffset;
4343 xassert (s->face && s->face->gc);
4345 /* This glyph string must always be drawn with 16-bit functions. */
4346 s->two_byte_p = 1;
4348 return s->gidx + s->nchars;
4352 /* Load glyph string S with a sequence of characters.
4353 FACE_ID is the face id of the string. START is the index of the
4354 first glyph to consider, END is the index of the last + 1.
4355 OVERLAPS_P non-zero means S should draw the foreground only, and
4356 use its lines physical height for clipping.
4358 Value is the index of the first glyph not in S. */
4360 static int
4361 x_fill_glyph_string (s, face_id, start, end, overlaps_p)
4362 struct glyph_string *s;
4363 int face_id;
4364 int start, end, overlaps_p;
4366 struct glyph *glyph, *last;
4367 int voffset;
4368 int glyph_not_available_p;
4370 xassert (s->f == XFRAME (s->w->frame));
4371 xassert (s->nchars == 0);
4372 xassert (start >= 0 && end > start);
4374 s->for_overlaps_p = overlaps_p;
4375 glyph = s->row->glyphs[s->area] + start;
4376 last = s->row->glyphs[s->area] + end;
4377 voffset = glyph->voffset;
4379 glyph_not_available_p = glyph->glyph_not_available_p;
4381 while (glyph < last
4382 && glyph->type == CHAR_GLYPH
4383 && glyph->voffset == voffset
4384 /* Same face id implies same font, nowadays. */
4385 && glyph->face_id == face_id
4386 && glyph->glyph_not_available_p == glyph_not_available_p)
4388 int two_byte_p;
4390 s->face = x_get_glyph_face_and_encoding (s->f, glyph,
4391 s->char2b + s->nchars,
4392 &two_byte_p);
4393 s->two_byte_p = two_byte_p;
4394 ++s->nchars;
4395 xassert (s->nchars <= end - start);
4396 s->width += glyph->pixel_width;
4397 ++glyph;
4400 s->font = s->face->font;
4401 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4403 /* If the specified font could not be loaded, use the frame's font,
4404 but record the fact that we couldn't load it in
4405 S->font_not_found_p so that we can draw rectangles for the
4406 characters of the glyph string. */
4407 if (s->font == NULL || glyph_not_available_p)
4409 s->font_not_found_p = 1;
4410 s->font = FRAME_FONT (s->f);
4413 /* Adjust base line for subscript/superscript text. */
4414 s->ybase += voffset;
4416 xassert (s->face && s->face->gc);
4417 return glyph - s->row->glyphs[s->area];
4421 /* Fill glyph string S from image glyph S->first_glyph. */
4423 static void
4424 x_fill_image_glyph_string (s)
4425 struct glyph_string *s;
4427 xassert (s->first_glyph->type == IMAGE_GLYPH);
4428 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
4429 xassert (s->img);
4430 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4431 s->font = s->face->font;
4432 s->width = s->first_glyph->pixel_width;
4434 /* Adjust base line for subscript/superscript text. */
4435 s->ybase += s->first_glyph->voffset;
4439 /* Fill glyph string S from a sequence of stretch glyphs.
4441 ROW is the glyph row in which the glyphs are found, AREA is the
4442 area within the row. START is the index of the first glyph to
4443 consider, END is the index of the last + 1.
4445 Value is the index of the first glyph not in S. */
4447 static int
4448 x_fill_stretch_glyph_string (s, row, area, start, end)
4449 struct glyph_string *s;
4450 struct glyph_row *row;
4451 enum glyph_row_area area;
4452 int start, end;
4454 struct glyph *glyph, *last;
4455 int voffset, face_id;
4457 xassert (s->first_glyph->type == STRETCH_GLYPH);
4459 glyph = s->row->glyphs[s->area] + start;
4460 last = s->row->glyphs[s->area] + end;
4461 face_id = glyph->face_id;
4462 s->face = FACE_FROM_ID (s->f, face_id);
4463 s->font = s->face->font;
4464 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
4465 s->width = glyph->pixel_width;
4466 voffset = glyph->voffset;
4468 for (++glyph;
4469 (glyph < last
4470 && glyph->type == STRETCH_GLYPH
4471 && glyph->voffset == voffset
4472 && glyph->face_id == face_id);
4473 ++glyph)
4474 s->width += glyph->pixel_width;
4476 /* Adjust base line for subscript/superscript text. */
4477 s->ybase += voffset;
4479 xassert (s->face && s->face->gc);
4480 return glyph - s->row->glyphs[s->area];
4484 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
4485 of XChar2b structures for S; it can't be allocated in
4486 x_init_glyph_string because it must be allocated via `alloca'. W
4487 is the window on which S is drawn. ROW and AREA are the glyph row
4488 and area within the row from which S is constructed. START is the
4489 index of the first glyph structure covered by S. HL is a
4490 face-override for drawing S. */
4492 static void
4493 w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
4494 struct glyph_string *s;
4495 HDC hdc;
4496 wchar_t *char2b;
4497 struct window *w;
4498 struct glyph_row *row;
4499 enum glyph_row_area area;
4500 int start;
4501 enum draw_glyphs_face hl;
4503 bzero (s, sizeof *s);
4504 s->w = w;
4505 s->f = XFRAME (w->frame);
4506 s->hdc = hdc;
4507 s->window = FRAME_W32_WINDOW (s->f);
4508 s->char2b = char2b;
4509 s->hl = hl;
4510 s->row = row;
4511 s->area = area;
4512 s->first_glyph = row->glyphs[area] + start;
4513 s->height = row->height;
4514 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4516 /* Display the internal border below the tool-bar window. */
4517 if (s->w == XWINDOW (s->f->tool_bar_window))
4518 s->y -= s->f->output_data.w32->internal_border_width;
4520 s->ybase = s->y + row->ascent;
4524 /* Set background width of glyph string S. START is the index of the
4525 first glyph following S. LAST_X is the right-most x-position + 1
4526 in the drawing area. */
4528 static INLINE void
4529 x_set_glyph_string_background_width (s, start, last_x)
4530 struct glyph_string *s;
4531 int start;
4532 int last_x;
4534 /* If the face of this glyph string has to be drawn to the end of
4535 the drawing area, set S->extends_to_end_of_line_p. */
4536 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
4538 if (start == s->row->used[s->area]
4539 && s->hl == DRAW_NORMAL_TEXT
4540 && ((s->area == TEXT_AREA && s->row->fill_line_p)
4541 || s->face->background != default_face->background
4542 || s->face->stipple != default_face->stipple))
4543 s->extends_to_end_of_line_p = 1;
4545 /* If S extends its face to the end of the line, set its
4546 background_width to the distance to the right edge of the drawing
4547 area. */
4548 if (s->extends_to_end_of_line_p)
4549 s->background_width = last_x - s->x + 1;
4550 else
4551 s->background_width = s->width;
4555 /* Add a glyph string for a stretch glyph to the list of strings
4556 between HEAD and TAIL. START is the index of the stretch glyph in
4557 row area AREA of glyph row ROW. END is the index of the last glyph
4558 in that glyph row area. X is the current output position assigned
4559 to the new glyph string constructed. HL overrides that face of the
4560 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4561 is the right-most x-position of the drawing area. */
4563 #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4564 do \
4566 s = (struct glyph_string *) alloca (sizeof *s); \
4567 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4568 START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \
4569 x_append_glyph_string (&HEAD, &TAIL, s); \
4570 s->x = (X); \
4572 while (0)
4575 /* Add a glyph string for an image glyph to the list of strings
4576 between HEAD and TAIL. START is the index of the image glyph in
4577 row area AREA of glyph row ROW. END is the index of the last glyph
4578 in that glyph row area. X is the current output position assigned
4579 to the new glyph string constructed. HL overrides that face of the
4580 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
4581 is the right-most x-position of the drawing area. */
4583 #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \
4584 do \
4586 s = (struct glyph_string *) alloca (sizeof *s); \
4587 w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \
4588 x_fill_image_glyph_string (s); \
4589 x_append_glyph_string (&HEAD, &TAIL, s); \
4590 ++START; \
4591 s->x = (X); \
4593 while (0)
4596 /* Add a glyph string for a sequence of character glyphs to the list
4597 of strings between HEAD and TAIL. START is the index of the first
4598 glyph in row area AREA of glyph row ROW that is part of the new
4599 glyph string. END is the index of the last glyph in that glyph row
4600 area. X is the current output position assigned to the new glyph
4601 string constructed. HL overrides that face of the glyph; e.g. it
4602 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
4603 right-most x-position of the drawing area. */
4605 #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4606 do \
4608 int c, face_id; \
4609 wchar_t *char2b; \
4611 c = (ROW)->glyphs[AREA][START].u.ch; \
4612 face_id = (ROW)->glyphs[AREA][START].face_id; \
4614 s = (struct glyph_string *) alloca (sizeof *s); \
4615 char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \
4616 w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \
4617 x_append_glyph_string (&HEAD, &TAIL, s); \
4618 s->x = (X); \
4619 START = x_fill_glyph_string (s, face_id, START, END, \
4620 OVERLAPS_P); \
4622 while (0)
4625 /* Add a glyph string for a composite sequence to the list of strings
4626 between HEAD and TAIL. START is the index of the first glyph in
4627 row area AREA of glyph row ROW that is part of the new glyph
4628 string. END is the index of the last glyph in that glyph row area.
4629 X is the current output position assigned to the new glyph string
4630 constructed. HL overrides that face of the glyph; e.g. it is
4631 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4632 x-position of the drawing area. */
4634 #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4635 do { \
4636 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \
4637 int face_id = (ROW)->glyphs[AREA][START].face_id; \
4638 struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \
4639 struct composition *cmp = composition_table[cmp_id]; \
4640 int glyph_len = cmp->glyph_len; \
4641 wchar_t *char2b; \
4642 struct face **faces; \
4643 struct glyph_string *first_s = NULL; \
4644 int n; \
4646 base_face = base_face->ascii_face; \
4647 char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \
4648 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4649 /* At first, fill in `char2b' and `faces'. */ \
4650 for (n = 0; n < glyph_len; n++) \
4652 int c = COMPOSITION_GLYPH (cmp, n); \
4653 int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \
4654 faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \
4655 x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4656 this_face_id, char2b + n, 1); \
4659 /* Make glyph_strings for each glyph sequence that is drawable by \
4660 the same face, and append them to HEAD/TAIL. */ \
4661 for (n = 0; n < cmp->glyph_len;) \
4663 s = (struct glyph_string *) alloca (sizeof *s); \
4664 w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \
4665 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4666 s->cmp = cmp; \
4667 s->gidx = n; \
4668 s->x = (X); \
4670 if (n == 0) \
4671 first_s = s; \
4673 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4676 ++START; \
4677 s = first_s; \
4678 } while (0)
4681 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4682 of AREA of glyph row ROW on window W between indices START and END.
4683 HL overrides the face for drawing glyph strings, e.g. it is
4684 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4685 x-positions of the drawing area.
4687 This is an ugly monster macro construct because we must use alloca
4688 to allocate glyph strings (because x_draw_glyphs can be called
4689 asynchronously). */
4691 #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \
4692 do \
4694 HEAD = TAIL = NULL; \
4695 while (START < END) \
4697 struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \
4698 switch (first_glyph->type) \
4700 case CHAR_GLYPH: \
4701 BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \
4702 HEAD, TAIL, HL, X, LAST_X, \
4703 OVERLAPS_P); \
4704 break; \
4706 case COMPOSITE_GLYPH: \
4707 BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \
4708 END, HEAD, TAIL, HL, X, \
4709 LAST_X, OVERLAPS_P); \
4710 break; \
4712 case STRETCH_GLYPH: \
4713 BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\
4714 HEAD, TAIL, HL, X, LAST_X); \
4715 break; \
4717 case IMAGE_GLYPH: \
4718 BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \
4719 HEAD, TAIL, HL, X, LAST_X); \
4720 break; \
4722 default: \
4723 abort (); \
4726 x_set_glyph_string_background_width (s, START, LAST_X); \
4727 (X) += s->width; \
4730 while (0)
4733 /* Draw glyphs between START and END in AREA of ROW on window W,
4734 starting at x-position X. X is relative to AREA in W. HL is a
4735 face-override with the following meaning:
4737 DRAW_NORMAL_TEXT draw normally
4738 DRAW_CURSOR draw in cursor face
4739 DRAW_MOUSE_FACE draw in mouse face.
4740 DRAW_INVERSE_VIDEO draw in mode line face
4741 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
4742 DRAW_IMAGE_RAISED draw an image with a raised relief around it
4744 If REAL_START is non-null, return in *REAL_START the real starting
4745 position for display. This can be different from START in case
4746 overlapping glyphs must be displayed. If REAL_END is non-null,
4747 return in *REAL_END the real end position for display. This can be
4748 different from END in case overlapping glyphs must be displayed.
4750 If OVERLAPS_P is non-zero, draw only the foreground of characters
4751 and clip to the physical height of ROW.
4753 Value is the x-position reached, relative to AREA of W. */
4755 static int
4756 x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end,
4757 overlaps_p)
4758 struct window *w;
4759 int x;
4760 struct glyph_row *row;
4761 enum glyph_row_area area;
4762 int start, end;
4763 enum draw_glyphs_face hl;
4764 int *real_start, *real_end;
4765 int overlaps_p;
4767 struct glyph_string *head, *tail;
4768 struct glyph_string *s;
4769 int last_x, area_width;
4770 int x_reached;
4771 int i, j;
4772 HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w)));
4774 /* Let's rather be paranoid than getting a SEGV. */
4775 end = min (end, row->used[area]);
4776 start = max (0, start);
4777 start = min (end, start);
4779 if (real_start)
4780 *real_start = start;
4781 if (real_end)
4782 *real_end = end;
4784 /* Translate X to frame coordinates. Set last_x to the right
4785 end of the drawing area. */
4786 if (row->full_width_p)
4788 /* X is relative to the left edge of W, without scroll bars
4789 or flag areas. */
4790 struct frame *f = XFRAME (WINDOW_FRAME (w));
4791 /* int width = FRAME_FLAGS_AREA_WIDTH (f); */
4792 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f);
4794 x += window_left_x;
4795 area_width = XFASTINT (w->width) * CANON_X_UNIT (f);
4796 last_x = window_left_x + area_width;
4798 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4800 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
4801 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
4802 last_x += width;
4803 else
4804 x -= width;
4807 x += FRAME_INTERNAL_BORDER_WIDTH (f);
4808 last_x -= FRAME_INTERNAL_BORDER_WIDTH (f);
4810 else
4812 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x);
4813 area_width = window_box_width (w, area);
4814 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width);
4817 /* Build a doubly-linked list of glyph_string structures between
4818 head and tail from what we have to draw. Note that the macro
4819 BUILD_GLYPH_STRINGS will modify its start parameter. That's
4820 the reason we use a separate variable `i'. */
4821 i = start;
4822 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x,
4823 overlaps_p);
4824 if (tail)
4825 x_reached = tail->x + tail->background_width;
4826 else
4827 x_reached = x;
4829 /* If there are any glyphs with lbearing < 0 or rbearing > width in
4830 the row, redraw some glyphs in front or following the glyph
4831 strings built above. */
4832 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
4834 int dummy_x = 0;
4835 struct glyph_string *h, *t;
4837 /* Compute overhangs for all glyph strings. */
4838 for (s = head; s; s = s->next)
4839 x_compute_glyph_string_overhangs (s);
4841 /* Prepend glyph strings for glyphs in front of the first glyph
4842 string that are overwritten because of the first glyph
4843 string's left overhang. The background of all strings
4844 prepended must be drawn because the first glyph string
4845 draws over it. */
4846 i = x_left_overwritten (head);
4847 if (i >= 0)
4849 j = i;
4850 BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t,
4851 DRAW_NORMAL_TEXT, dummy_x, last_x,
4852 overlaps_p);
4853 start = i;
4854 if (real_start)
4855 *real_start = start;
4856 x_compute_overhangs_and_x (t, head->x, 1);
4857 x_prepend_glyph_string_lists (&head, &tail, h, t);
4860 /* Prepend glyph strings for glyphs in front of the first glyph
4861 string that overwrite that glyph string because of their
4862 right overhang. For these strings, only the foreground must
4863 be drawn, because it draws over the glyph string at `head'.
4864 The background must not be drawn because this would overwrite
4865 right overhangs of preceding glyphs for which no glyph
4866 strings exist. */
4867 i = x_left_overwriting (head);
4868 if (i >= 0)
4870 BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t,
4871 DRAW_NORMAL_TEXT, dummy_x, last_x,
4872 overlaps_p);
4873 for (s = h; s; s = s->next)
4874 s->background_filled_p = 1;
4875 if (real_start)
4876 *real_start = i;
4877 x_compute_overhangs_and_x (t, head->x, 1);
4878 x_prepend_glyph_string_lists (&head, &tail, h, t);
4881 /* Append glyphs strings for glyphs following the last glyph
4882 string tail that are overwritten by tail. The background of
4883 these strings has to be drawn because tail's foreground draws
4884 over it. */
4885 i = x_right_overwritten (tail);
4886 if (i >= 0)
4888 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4889 DRAW_NORMAL_TEXT, x, last_x,
4890 overlaps_p);
4891 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4892 x_append_glyph_string_lists (&head, &tail, h, t);
4893 if (real_end)
4894 *real_end = i;
4897 /* Append glyph strings for glyphs following the last glyph
4898 string tail that overwrite tail. The foreground of such
4899 glyphs has to be drawn because it writes into the background
4900 of tail. The background must not be drawn because it could
4901 paint over the foreground of following glyphs. */
4902 i = x_right_overwriting (tail);
4903 if (i >= 0)
4905 BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t,
4906 DRAW_NORMAL_TEXT, x, last_x,
4907 overlaps_p);
4908 for (s = h; s; s = s->next)
4909 s->background_filled_p = 1;
4910 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
4911 x_append_glyph_string_lists (&head, &tail, h, t);
4912 if (real_end)
4913 *real_end = i;
4917 /* Draw all strings. */
4918 for (s = head; s; s = s->next)
4919 x_draw_glyph_string (s);
4921 /* Value is the x-position up to which drawn, relative to AREA of W.
4922 This doesn't include parts drawn because of overhangs. */
4923 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
4924 if (!row->full_width_p)
4926 if (area > LEFT_MARGIN_AREA)
4927 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
4928 if (area > TEXT_AREA)
4929 x_reached -= window_box_width (w, TEXT_AREA);
4932 release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc);
4934 return x_reached;
4938 /* Fix the display of area AREA of overlapping row ROW in window W. */
4940 static void
4941 x_fix_overlapping_area (w, row, area)
4942 struct window *w;
4943 struct glyph_row *row;
4944 enum glyph_row_area area;
4946 int i, x;
4948 BLOCK_INPUT;
4950 if (area == LEFT_MARGIN_AREA)
4951 x = 0;
4952 else if (area == TEXT_AREA)
4953 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
4954 else
4955 x = (window_box_width (w, LEFT_MARGIN_AREA)
4956 + window_box_width (w, TEXT_AREA));
4958 for (i = 0; i < row->used[area];)
4960 if (row->glyphs[area][i].overlaps_vertically_p)
4962 int start = i, start_x = x;
4966 x += row->glyphs[area][i].pixel_width;
4967 ++i;
4969 while (i < row->used[area]
4970 && row->glyphs[area][i].overlaps_vertically_p);
4972 x_draw_glyphs (w, start_x, row, area, start, i,
4973 (row->inverse_p
4974 ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
4975 NULL, NULL, 1);
4977 else
4979 x += row->glyphs[area][i].pixel_width;
4980 ++i;
4984 UNBLOCK_INPUT;
4988 /* Output LEN glyphs starting at START at the nominal cursor position.
4989 Advance the nominal cursor over the text. The global variable
4990 updated_window contains the window being updated, updated_row is
4991 the glyph row being updated, and updated_area is the area of that
4992 row being updated. */
4994 static void
4995 x_write_glyphs (start, len)
4996 struct glyph *start;
4997 int len;
4999 int x, hpos, real_start, real_end;
5001 xassert (updated_window && updated_row);
5002 BLOCK_INPUT;
5004 /* Write glyphs. */
5006 hpos = start - updated_row->glyphs[updated_area];
5007 x = x_draw_glyphs (updated_window, output_cursor.x,
5008 updated_row, updated_area,
5009 hpos, hpos + len,
5010 (updated_row->inverse_p
5011 ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT),
5012 &real_start, &real_end, 0);
5014 /* If we drew over the cursor, note that it is not visible any more. */
5015 note_overwritten_text_cursor (updated_window, real_start,
5016 real_end - real_start);
5018 UNBLOCK_INPUT;
5020 /* Advance the output cursor. */
5021 output_cursor.hpos += len;
5022 output_cursor.x = x;
5026 /* Insert LEN glyphs from START at the nominal cursor position. */
5028 static void
5029 x_insert_glyphs (start, len)
5030 struct glyph *start;
5031 register int len;
5033 struct frame *f;
5034 struct window *w;
5035 int line_height, shift_by_width, shifted_region_width;
5036 struct glyph_row *row;
5037 struct glyph *glyph;
5038 int frame_x, frame_y, hpos, real_start, real_end;
5039 HDC hdc;
5041 xassert (updated_window && updated_row);
5042 BLOCK_INPUT;
5043 w = updated_window;
5044 f = XFRAME (WINDOW_FRAME (w));
5045 hdc = get_frame_dc (f);
5047 /* Get the height of the line we are in. */
5048 row = updated_row;
5049 line_height = row->height;
5051 /* Get the width of the glyphs to insert. */
5052 shift_by_width = 0;
5053 for (glyph = start; glyph < start + len; ++glyph)
5054 shift_by_width += glyph->pixel_width;
5056 /* Get the width of the region to shift right. */
5057 shifted_region_width = (window_box_width (w, updated_area)
5058 - output_cursor.x
5059 - shift_by_width);
5061 /* Shift right. */
5062 frame_x = WINDOW_TO_FRAME_PIXEL_X (w, output_cursor.x);
5063 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
5064 BitBlt (hdc, frame_x + shift_by_width, frame_y,
5065 shifted_region_width, line_height,
5066 hdc, frame_x, frame_y, SRCCOPY);
5068 /* Write the glyphs. */
5069 hpos = start - row->glyphs[updated_area];
5070 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
5071 DRAW_NORMAL_TEXT, &real_start, &real_end, 0);
5072 note_overwritten_text_cursor (w, real_start, real_end - real_start);
5074 /* Advance the output cursor. */
5075 output_cursor.hpos += len;
5076 output_cursor.x += shift_by_width;
5077 release_frame_dc (f, hdc);
5079 UNBLOCK_INPUT;
5083 /* Delete N glyphs at the nominal cursor position. Not implemented
5084 for X frames. */
5086 static void
5087 x_delete_glyphs (n)
5088 register int n;
5090 abort ();
5094 /* Erase the current text line from the nominal cursor position
5095 (inclusive) to pixel column TO_X (exclusive). The idea is that
5096 everything from TO_X onward is already erased.
5098 TO_X is a pixel position relative to updated_area of
5099 updated_window. TO_X == -1 means clear to the end of this area. */
5101 static void
5102 x_clear_end_of_line (to_x)
5103 int to_x;
5105 struct frame *f;
5106 struct window *w = updated_window;
5107 int max_x, min_y, max_y;
5108 int from_x, from_y, to_y;
5110 xassert (updated_window && updated_row);
5111 f = XFRAME (w->frame);
5113 if (updated_row->full_width_p)
5115 max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
5116 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
5117 && !w->pseudo_window_p)
5118 max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
5120 else
5121 max_x = window_box_width (w, updated_area);
5122 max_y = window_text_bottom_y (w);
5124 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
5125 of window. For TO_X > 0, truncate to end of drawing area. */
5126 if (to_x == 0)
5127 return;
5128 else if (to_x < 0)
5129 to_x = max_x;
5130 else
5131 to_x = min (to_x, max_x);
5133 to_y = min (max_y, output_cursor.y + updated_row->height);
5135 /* Notice if the cursor will be cleared by this operation. */
5136 if (!updated_row->full_width_p)
5137 note_overwritten_text_cursor (w, output_cursor.hpos, -1);
5139 from_x = output_cursor.x;
5141 /* Translate to frame coordinates. */
5142 if (updated_row->full_width_p)
5144 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
5145 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
5147 else
5149 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
5150 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
5153 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
5154 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
5155 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
5157 /* Prevent inadvertently clearing to end of the X window. */
5158 if (to_x > from_x && to_y > from_y)
5160 HDC hdc;
5161 BLOCK_INPUT;
5162 hdc = get_frame_dc (f);
5164 w32_clear_area (f, hdc, from_x, from_y, to_x - from_x, to_y - from_y);
5165 release_frame_dc (f, hdc);
5166 UNBLOCK_INPUT;
5171 /* Clear entire frame. If updating_frame is non-null, clear that
5172 frame. Otherwise clear the selected frame. */
5174 static void
5175 x_clear_frame ()
5177 struct frame *f;
5179 if (updating_frame)
5180 f = updating_frame;
5181 else
5182 f = SELECTED_FRAME ();
5184 /* Clearing the frame will erase any cursor, so mark them all as no
5185 longer visible. */
5186 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
5187 output_cursor.hpos = output_cursor.vpos = 0;
5188 output_cursor.x = -1;
5190 /* We don't set the output cursor here because there will always
5191 follow an explicit cursor_to. */
5192 BLOCK_INPUT;
5194 w32_clear_window (f);
5196 /* We have to clear the scroll bars, too. If we have changed
5197 colors or something like that, then they should be notified. */
5198 x_scroll_bar_clear (f);
5200 UNBLOCK_INPUT;
5204 /* Make audible bell. */
5206 static void
5207 w32_ring_bell (void)
5209 BLOCK_INPUT;
5211 if (visible_bell)
5213 int i;
5214 HWND hwnd = FRAME_W32_WINDOW (SELECTED_FRAME ());
5216 for (i = 0; i < 5; i++)
5218 FlashWindow (hwnd, TRUE);
5219 Sleep (10);
5221 FlashWindow (hwnd, FALSE);
5223 else
5224 w32_sys_ring_bell ();
5226 UNBLOCK_INPUT;
5230 /* Specify how many text lines, from the top of the window,
5231 should be affected by insert-lines and delete-lines operations.
5232 This, and those operations, are used only within an update
5233 that is bounded by calls to x_update_begin and x_update_end. */
5235 static void
5236 w32_set_terminal_window (n)
5237 register int n;
5239 /* This function intentionally left blank. */
5244 /***********************************************************************
5245 Line Dance
5246 ***********************************************************************/
5248 /* Perform an insert-lines or delete-lines operation, inserting N
5249 lines or deleting -N lines at vertical position VPOS. */
5251 static void
5252 x_ins_del_lines (vpos, n)
5253 int vpos, n;
5255 abort ();
5259 /* Scroll part of the display as described by RUN. */
5261 static void
5262 x_scroll_run (w, run)
5263 struct window *w;
5264 struct run *run;
5266 struct frame *f = XFRAME (w->frame);
5267 int x, y, width, height, from_y, to_y, bottom_y;
5268 HDC hdc = get_frame_dc (f);
5270 /* Get frame-relative bounding box of the text display area of W,
5271 without mode lines. Include in this box the flags areas to the
5272 left and right of W. */
5273 window_box (w, -1, &x, &y, &width, &height);
5274 width += FRAME_X_FLAGS_AREA_WIDTH (f);
5275 x -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
5277 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
5278 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
5279 bottom_y = y + height;
5281 if (to_y < from_y)
5283 /* Scrolling up. Make sure we don't copy part of the mode
5284 line at the bottom. */
5285 if (from_y + run->height > bottom_y)
5286 height = bottom_y - from_y;
5287 else
5288 height = run->height;
5290 else
5292 /* Scolling down. Make sure we don't copy over the mode line.
5293 at the bottom. */
5294 if (to_y + run->height > bottom_y)
5295 height = bottom_y - to_y;
5296 else
5297 height = run->height;
5300 BLOCK_INPUT;
5302 /* Cursor off. Will be switched on again in x_update_window_end. */
5303 updated_window = w;
5304 x_clear_cursor (w);
5306 BitBlt (hdc, x, to_y, width, height, hdc, x, from_y, SRCCOPY);
5308 UNBLOCK_INPUT;
5309 release_frame_dc (f, hdc);
5314 /***********************************************************************
5315 Exposure Events
5316 ***********************************************************************/
5318 /* Redisplay an exposed area of frame F. X and Y are the upper-left
5319 corner of the exposed rectangle. W and H are width and height of
5320 the exposed area. All are pixel values. W or H zero means redraw
5321 the entire frame. */
5323 static void
5324 expose_frame (f, x, y, w, h)
5325 struct frame *f;
5326 int x, y, w, h;
5328 RECT r;
5330 TRACE ((stderr, "expose_frame "));
5332 /* No need to redraw if frame will be redrawn soon. */
5333 if (FRAME_GARBAGED_P (f))
5335 TRACE ((stderr, " garbaged\n"));
5336 return;
5339 /* If basic faces haven't been realized yet, there is no point in
5340 trying to redraw anything. This can happen when we get an expose
5341 event while Emacs is starting, e.g. by moving another window. */
5342 if (FRAME_FACE_CACHE (f) == NULL
5343 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
5345 TRACE ((stderr, " no faces\n"));
5346 return;
5349 if (w == 0 || h == 0)
5351 r.left = r.top = 0;
5352 r.right = CANON_X_UNIT (f) * f->width;
5353 r.bottom = CANON_Y_UNIT (f) * f->height;
5355 else
5357 r.left = x;
5358 r.top = y;
5359 r.right = x + w;
5360 r.bottom = y + h;
5363 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.left, r.top, r.right, r.bottom));
5364 expose_window_tree (XWINDOW (f->root_window), &r);
5366 if (WINDOWP (f->tool_bar_window))
5368 struct window *w = XWINDOW (f->tool_bar_window);
5369 RECT window_rect;
5370 RECT intersection_rect;
5371 int window_x, window_y, window_width, window_height;
5373 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
5374 window_rect.left = window_x;
5375 window_rect.top = window_y;
5376 window_rect.right = window_x + window_width;
5377 window_rect.bottom = window_y + window_height;
5379 if (IntersectRect (&intersection_rect, &r, &window_rect))
5380 expose_window (w, &intersection_rect);
5385 /* Redraw (parts) of all windows in the window tree rooted at W that
5386 intersect R. R contains frame pixel coordinates. */
5388 static void
5389 expose_window_tree (w, r)
5390 struct window *w;
5391 RECT *r;
5393 while (w)
5395 if (!NILP (w->hchild))
5396 expose_window_tree (XWINDOW (w->hchild), r);
5397 else if (!NILP (w->vchild))
5398 expose_window_tree (XWINDOW (w->vchild), r);
5399 else
5401 RECT window_rect;
5402 RECT intersection_rect;
5403 struct frame *f = XFRAME (w->frame);
5404 int window_x, window_y, window_width, window_height;
5406 /* Frame-relative pixel rectangle of W. */
5407 window_box (w, -1, &window_x, &window_y, &window_width,
5408 &window_height);
5409 window_rect.left
5410 = (window_x
5411 - FRAME_X_LEFT_FLAGS_AREA_WIDTH (f)
5412 - FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_Y_UNIT (f));
5413 window_rect.top = window_y;
5414 window_rect.right = window_rect.left
5415 + (window_width
5416 + FRAME_X_FLAGS_AREA_WIDTH (f)
5417 + FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f));
5418 window_rect.bottom = window_rect.top
5419 + window_height + CURRENT_MODE_LINE_HEIGHT (w);
5421 if (IntersectRect (&intersection_rect, r, &window_rect))
5422 expose_window (w, &intersection_rect);
5425 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5430 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
5431 which intersects rectangle R. R is in window-relative coordinates. */
5433 static void
5434 expose_area (w, row, r, area)
5435 struct window *w;
5436 struct glyph_row *row;
5437 RECT *r;
5438 enum glyph_row_area area;
5440 int x;
5441 struct glyph *first = row->glyphs[area];
5442 struct glyph *end = row->glyphs[area] + row->used[area];
5443 struct glyph *last;
5444 int first_x;
5446 /* Set x to the window-relative start position for drawing glyphs of
5447 AREA. The first glyph of the text area can be partially visible.
5448 The first glyphs of other areas cannot. */
5449 if (area == LEFT_MARGIN_AREA)
5450 x = 0;
5451 else if (area == TEXT_AREA)
5452 x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
5453 else
5454 x = (window_box_width (w, LEFT_MARGIN_AREA)
5455 + window_box_width (w, TEXT_AREA));
5457 if (area == TEXT_AREA && row->fill_line_p)
5458 /* If row extends face to end of line write the whole line. */
5459 x_draw_glyphs (w, x, row, area,
5460 0, row->used[area],
5461 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5462 NULL, NULL, 0);
5463 else
5465 /* Find the first glyph that must be redrawn. */
5466 while (first < end
5467 && x + first->pixel_width < r->left)
5469 x += first->pixel_width;
5470 ++first;
5473 /* Find the last one. */
5474 last = first;
5475 first_x = x;
5476 while (last < end
5477 && x < r->right)
5479 x += last->pixel_width;
5480 ++last;
5483 /* Repaint. */
5484 if (last > first)
5485 x_draw_glyphs (w, first_x, row, area,
5486 first - row->glyphs[area],
5487 last - row->glyphs[area],
5488 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5489 NULL, NULL, 0);
5494 /* Redraw the parts of the glyph row ROW on window W intersecting
5495 rectangle R. R is in window-relative coordinates. */
5497 static void
5498 expose_line (w, row, r)
5499 struct window *w;
5500 struct glyph_row *row;
5501 RECT *r;
5503 xassert (row->enabled_p);
5505 if (row->mode_line_p || w->pseudo_window_p)
5506 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
5507 row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
5508 NULL, NULL, 0);
5509 else
5511 if (row->used[LEFT_MARGIN_AREA])
5512 expose_area (w, row, r, LEFT_MARGIN_AREA);
5513 if (row->used[TEXT_AREA])
5514 expose_area (w, row, r, TEXT_AREA);
5515 if (row->used[RIGHT_MARGIN_AREA])
5516 expose_area (w, row, r, RIGHT_MARGIN_AREA);
5517 x_draw_row_bitmaps (w, row);
5522 /* Return non-zero if W's cursor intersects rectangle R. */
5524 static int
5525 x_phys_cursor_in_rect_p (w, r)
5526 struct window *w;
5527 RECT *r;
5529 RECT cr, result;
5530 struct glyph *cursor_glyph;
5532 cursor_glyph = get_phys_cursor_glyph (w);
5533 if (cursor_glyph)
5535 cr.left = w->phys_cursor.x;
5536 cr.top = w->phys_cursor.y;
5537 cr.right = cr.left + cursor_glyph->pixel_width;
5538 cr.bottom = cr.top + w->phys_cursor_height;
5539 return IntersectRect (&result, &cr, r);
5541 else
5542 return 0;
5546 /* Redraw a rectangle of window W. R is a rectangle in window
5547 relative coordinates. Call this function with input blocked. */
5549 static void
5550 expose_window (w, r)
5551 struct window *w;
5552 RECT *r;
5554 struct glyph_row *row;
5555 int y;
5556 int yb = window_text_bottom_y (w);
5557 int cursor_cleared_p;
5559 /* If window is not yet fully initialized, do nothing. This can
5560 happen when toolkit scroll bars are used and a window is split.
5561 Reconfiguring the scroll bar will generate an expose for a newly
5562 created window. */
5563 if (w->current_matrix == NULL)
5564 return;
5566 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
5567 r->left, r->top, r->right, r->bottom));
5569 /* Convert to window coordinates. */
5570 r->left = FRAME_TO_WINDOW_PIXEL_X (w, r->left);
5571 r->top = FRAME_TO_WINDOW_PIXEL_Y (w, r->top);
5572 r->right = FRAME_TO_WINDOW_PIXEL_X (w, r->right);
5573 r->bottom = FRAME_TO_WINDOW_PIXEL_Y (w, r->bottom);
5575 /* Turn off the cursor. */
5576 if (!w->pseudo_window_p
5577 && x_phys_cursor_in_rect_p (w, r))
5579 x_clear_cursor (w);
5580 cursor_cleared_p = 1;
5582 else
5583 cursor_cleared_p = 0;
5585 /* Find the first row intersecting the rectangle R. */
5586 row = w->current_matrix->rows;
5587 y = 0;
5588 while (row->enabled_p
5589 && y < yb
5590 && y + row->height < r->top)
5592 y += row->height;
5593 ++row;
5596 /* Display the text in the rectangle, one text line at a time. */
5597 while (row->enabled_p
5598 && y < yb
5599 && y < r->bottom)
5601 expose_line (w, row, r);
5602 y += row->height;
5603 ++row;
5606 /* Display the mode line if there is one. */
5607 if (WINDOW_WANTS_MODELINE_P (w)
5608 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
5609 row->enabled_p)
5610 && row->y < r->bottom)
5611 expose_line (w, row, r);
5613 if (!w->pseudo_window_p)
5615 /* Draw border between windows. */
5616 x_draw_vertical_border (w);
5618 /* Turn the cursor on again. */
5619 if (cursor_cleared_p)
5620 x_update_window_cursor (w, 1);
5625 static void
5626 frame_highlight (f)
5627 struct frame *f;
5629 x_update_cursor (f, 1);
5632 static void
5633 frame_unhighlight (f)
5634 struct frame *f;
5636 x_update_cursor (f, 1);
5639 /* The focus has changed. Update the frames as necessary to reflect
5640 the new situation. Note that we can't change the selected frame
5641 here, because the Lisp code we are interrupting might become confused.
5642 Each event gets marked with the frame in which it occurred, so the
5643 Lisp code can tell when the switch took place by examining the events. */
5645 static void
5646 x_new_focus_frame (dpyinfo, frame)
5647 struct w32_display_info *dpyinfo;
5648 struct frame *frame;
5650 struct frame *old_focus = dpyinfo->w32_focus_frame;
5652 if (frame != dpyinfo->w32_focus_frame)
5654 /* Set this before calling other routines, so that they see
5655 the correct value of w32_focus_frame. */
5656 dpyinfo->w32_focus_frame = frame;
5658 if (old_focus && old_focus->auto_lower)
5659 x_lower_frame (old_focus);
5661 if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
5662 pending_autoraise_frame = dpyinfo->w32_focus_frame;
5663 else
5664 pending_autoraise_frame = 0;
5667 x_frame_rehighlight (dpyinfo);
5670 /* Handle an event saying the mouse has moved out of an Emacs frame. */
5672 void
5673 x_mouse_leave (dpyinfo)
5674 struct w32_display_info *dpyinfo;
5676 x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
5679 /* The focus has changed, or we have redirected a frame's focus to
5680 another frame (this happens when a frame uses a surrogate
5681 mini-buffer frame). Shift the highlight as appropriate.
5683 The FRAME argument doesn't necessarily have anything to do with which
5684 frame is being highlighted or un-highlighted; we only use it to find
5685 the appropriate X display info. */
5687 static void
5688 w32_frame_rehighlight (frame)
5689 struct frame *frame;
5691 x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
5694 static void
5695 x_frame_rehighlight (dpyinfo)
5696 struct w32_display_info *dpyinfo;
5698 struct frame *old_highlight = dpyinfo->w32_highlight_frame;
5700 if (dpyinfo->w32_focus_frame)
5702 dpyinfo->w32_highlight_frame
5703 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
5704 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
5705 : dpyinfo->w32_focus_frame);
5706 if (! FRAME_LIVE_P (dpyinfo->w32_highlight_frame))
5708 FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
5709 dpyinfo->w32_highlight_frame = dpyinfo->w32_focus_frame;
5712 else
5713 dpyinfo->w32_highlight_frame = 0;
5715 if (dpyinfo->w32_highlight_frame != old_highlight)
5717 if (old_highlight)
5718 frame_unhighlight (old_highlight);
5719 if (dpyinfo->w32_highlight_frame)
5720 frame_highlight (dpyinfo->w32_highlight_frame);
5724 /* Keyboard processing - modifier keys, etc. */
5726 /* Convert a keysym to its name. */
5728 char *
5729 x_get_keysym_name (keysym)
5730 int keysym;
5732 /* Make static so we can always return it */
5733 static char value[100];
5735 BLOCK_INPUT;
5736 GetKeyNameText (keysym, value, 100);
5737 UNBLOCK_INPUT;
5739 return value;
5744 /* Mouse clicks and mouse movement. Rah. */
5746 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
5747 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
5748 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
5749 not force the value into range. */
5751 void
5752 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
5753 FRAME_PTR f;
5754 register int pix_x, pix_y;
5755 register int *x, *y;
5756 RECT *bounds;
5757 int noclip;
5759 /* Support tty mode: if Vwindow_system is nil, behave correctly. */
5760 if (NILP (Vwindow_system))
5762 *x = pix_x;
5763 *y = pix_y;
5764 return;
5767 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to round down
5768 even for negative values. */
5769 if (pix_x < 0)
5770 pix_x -= FONT_WIDTH (FRAME_FONT (f)) - 1;
5771 if (pix_y < 0)
5772 pix_y -= (f)->output_data.w32->line_height - 1;
5774 pix_x = PIXEL_TO_CHAR_COL (f, pix_x);
5775 pix_y = PIXEL_TO_CHAR_ROW (f, pix_y);
5777 if (bounds)
5779 bounds->left = CHAR_TO_PIXEL_COL (f, pix_x);
5780 bounds->top = CHAR_TO_PIXEL_ROW (f, pix_y);
5781 bounds->right = bounds->left + FONT_WIDTH (FRAME_FONT (f)) - 1;
5782 bounds->bottom = bounds->top + f->output_data.w32->line_height - 1;
5785 if (!noclip)
5787 if (pix_x < 0)
5788 pix_x = 0;
5789 else if (pix_x > FRAME_WINDOW_WIDTH (f))
5790 pix_x = FRAME_WINDOW_WIDTH (f);
5792 if (pix_y < 0)
5793 pix_y = 0;
5794 else if (pix_y > f->height)
5795 pix_y = f->height;
5798 *x = pix_x;
5799 *y = pix_y;
5803 /* Given HPOS/VPOS in the current matrix of W, return corresponding
5804 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
5805 can't tell the positions because W's display is not up to date,
5806 return 0. */
5809 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
5810 struct window *w;
5811 int hpos, vpos;
5812 int *frame_x, *frame_y;
5814 int success_p;
5816 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
5817 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
5819 if (display_completed)
5821 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
5822 struct glyph *glyph = row->glyphs[TEXT_AREA];
5823 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
5825 *frame_y = row->y;
5826 *frame_x = row->x;
5827 while (glyph < end)
5829 *frame_x += glyph->pixel_width;
5830 ++glyph;
5833 success_p = 1;
5835 else
5837 *frame_y = *frame_x = 0;
5838 success_p = 0;
5841 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, *frame_y);
5842 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, *frame_x);
5843 return success_p;
5846 BOOL
5847 parse_button (message, pbutton, pup)
5848 int message;
5849 int * pbutton;
5850 int * pup;
5852 int button = 0;
5853 int up = 0;
5855 switch (message)
5857 case WM_LBUTTONDOWN:
5858 button = 0;
5859 up = 0;
5860 break;
5861 case WM_LBUTTONUP:
5862 button = 0;
5863 up = 1;
5864 break;
5865 case WM_MBUTTONDOWN:
5866 if (NILP (Vw32_swap_mouse_buttons))
5867 button = 1;
5868 else
5869 button = 2;
5870 up = 0;
5871 break;
5872 case WM_MBUTTONUP:
5873 if (NILP (Vw32_swap_mouse_buttons))
5874 button = 1;
5875 else
5876 button = 2;
5877 up = 1;
5878 break;
5879 case WM_RBUTTONDOWN:
5880 if (NILP (Vw32_swap_mouse_buttons))
5881 button = 2;
5882 else
5883 button = 1;
5884 up = 0;
5885 break;
5886 case WM_RBUTTONUP:
5887 if (NILP (Vw32_swap_mouse_buttons))
5888 button = 2;
5889 else
5890 button = 1;
5891 up = 1;
5892 break;
5893 default:
5894 return (FALSE);
5897 if (pup) *pup = up;
5898 if (pbutton) *pbutton = button;
5900 return (TRUE);
5904 /* Prepare a mouse-event in *RESULT for placement in the input queue.
5906 If the event is a button press, then note that we have grabbed
5907 the mouse. */
5909 static Lisp_Object
5910 construct_mouse_click (result, msg, f)
5911 struct input_event *result;
5912 W32Msg *msg;
5913 struct frame *f;
5915 int button;
5916 int up;
5918 parse_button (msg->msg.message, &button, &up);
5920 /* Make the event type no_event; we'll change that when we decide
5921 otherwise. */
5922 result->kind = mouse_click;
5923 result->code = button;
5924 result->timestamp = msg->msg.time;
5925 result->modifiers = (msg->dwModifiers
5926 | (up
5927 ? up_modifier
5928 : down_modifier));
5930 XSETINT (result->x, LOWORD (msg->msg.lParam));
5931 XSETINT (result->y, HIWORD (msg->msg.lParam));
5932 XSETFRAME (result->frame_or_window, f);
5933 result->arg = Qnil;
5934 return Qnil;
5937 static Lisp_Object
5938 construct_mouse_wheel (result, msg, f)
5939 struct input_event *result;
5940 W32Msg *msg;
5941 struct frame *f;
5943 POINT p;
5944 result->kind = mouse_wheel;
5945 result->code = (short) HIWORD (msg->msg.wParam);
5946 result->timestamp = msg->msg.time;
5947 result->modifiers = msg->dwModifiers;
5948 p.x = LOWORD (msg->msg.lParam);
5949 p.y = HIWORD (msg->msg.lParam);
5950 ScreenToClient (msg->msg.hwnd, &p);
5951 XSETINT (result->x, p.x);
5952 XSETINT (result->y, p.y);
5953 XSETFRAME (result->frame_or_window, f);
5954 result->arg = Qnil;
5955 return Qnil;
5958 static Lisp_Object
5959 construct_drag_n_drop (result, msg, f)
5960 struct input_event *result;
5961 W32Msg *msg;
5962 struct frame *f;
5964 Lisp_Object files;
5965 Lisp_Object frame;
5966 HDROP hdrop;
5967 POINT p;
5968 WORD num_files;
5969 char *name;
5970 int i, len;
5972 result->kind = drag_n_drop;
5973 result->code = 0;
5974 result->timestamp = msg->msg.time;
5975 result->modifiers = msg->dwModifiers;
5977 hdrop = (HDROP) msg->msg.wParam;
5978 DragQueryPoint (hdrop, &p);
5980 #if 0
5981 p.x = LOWORD (msg->msg.lParam);
5982 p.y = HIWORD (msg->msg.lParam);
5983 ScreenToClient (msg->msg.hwnd, &p);
5984 #endif
5986 XSETINT (result->x, p.x);
5987 XSETINT (result->y, p.y);
5989 num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
5990 files = Qnil;
5992 for (i = 0; i < num_files; i++)
5994 len = DragQueryFile (hdrop, i, NULL, 0);
5995 if (len <= 0)
5996 continue;
5997 name = alloca (len + 1);
5998 DragQueryFile (hdrop, i, name, len + 1);
5999 files = Fcons (build_string (name), files);
6002 DragFinish (hdrop);
6004 XSETFRAME (frame, f);
6005 result->frame_or_window = Fcons (frame, files);
6006 result->arg = Qnil;
6007 return Qnil;
6011 /* Function to report a mouse movement to the mainstream Emacs code.
6012 The input handler calls this.
6014 We have received a mouse movement event, which is given in *event.
6015 If the mouse is over a different glyph than it was last time, tell
6016 the mainstream emacs code by setting mouse_moved. If not, ask for
6017 another motion event, so we can check again the next time it moves. */
6019 static MSG last_mouse_motion_event;
6020 static Lisp_Object last_mouse_motion_frame;
6022 static void
6023 note_mouse_movement (frame, msg)
6024 FRAME_PTR frame;
6025 MSG *msg;
6027 last_mouse_movement_time = msg->time;
6028 memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
6029 XSETFRAME (last_mouse_motion_frame, frame);
6031 if (msg->hwnd != FRAME_W32_WINDOW (frame))
6033 frame->mouse_moved = 1;
6034 last_mouse_scroll_bar = Qnil;
6035 note_mouse_highlight (frame, -1, -1);
6038 /* Has the mouse moved off the glyph it was on at the last sighting? */
6039 else if (LOWORD (msg->lParam) < last_mouse_glyph.left
6040 || LOWORD (msg->lParam) > last_mouse_glyph.right
6041 || HIWORD (msg->lParam) < last_mouse_glyph.top
6042 || HIWORD (msg->lParam) > last_mouse_glyph.bottom)
6044 frame->mouse_moved = 1;
6045 last_mouse_scroll_bar = Qnil;
6047 note_mouse_highlight (frame, LOWORD (msg->lParam), HIWORD (msg->lParam));
6051 /* This is used for debugging, to turn off note_mouse_highlight. */
6053 int disable_mouse_highlight;
6057 /************************************************************************
6058 Mouse Face
6059 ************************************************************************/
6061 /* Find the glyph under window-relative coordinates X/Y in window W.
6062 Consider only glyphs from buffer text, i.e. no glyphs from overlay
6063 strings. Return in *HPOS and *VPOS the row and column number of
6064 the glyph found. Return in *AREA the glyph area containing X.
6065 Value is a pointer to the glyph found or null if X/Y is not on
6066 text, or we can't tell because W's current matrix is not up to
6067 date. */
6069 static struct glyph *
6070 x_y_to_hpos_vpos (w, x, y, hpos, vpos, area)
6071 struct window *w;
6072 int x, y;
6073 int *hpos, *vpos, *area;
6075 struct glyph *glyph, *end;
6076 struct glyph_row *row = NULL;
6077 int x0, i, left_area_width;
6079 /* Find row containing Y. Give up if some row is not enabled. */
6080 for (i = 0; i < w->current_matrix->nrows; ++i)
6082 row = MATRIX_ROW (w->current_matrix, i);
6083 if (!row->enabled_p)
6084 return NULL;
6085 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
6086 break;
6089 *vpos = i;
6090 *hpos = 0;
6092 /* Give up if Y is not in the window. */
6093 if (i == w->current_matrix->nrows)
6094 return NULL;
6096 /* Get the glyph area containing X. */
6097 if (w->pseudo_window_p)
6099 *area = TEXT_AREA;
6100 x0 = 0;
6102 else
6104 left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
6105 if (x < left_area_width)
6107 *area = LEFT_MARGIN_AREA;
6108 x0 = 0;
6110 else if (x < left_area_width + window_box_width (w, TEXT_AREA))
6112 *area = TEXT_AREA;
6113 x0 = row->x + left_area_width;
6115 else
6117 *area = RIGHT_MARGIN_AREA;
6118 x0 = left_area_width + window_box_width (w, TEXT_AREA);
6122 /* Find glyph containing X. */
6123 glyph = row->glyphs[*area];
6124 end = glyph + row->used[*area];
6125 while (glyph < end)
6127 if (x < x0 + glyph->pixel_width)
6129 if (w->pseudo_window_p)
6130 break;
6131 else if (BUFFERP (glyph->object))
6132 break;
6135 x0 += glyph->pixel_width;
6136 ++glyph;
6139 if (glyph == end)
6140 return NULL;
6142 *hpos = glyph - row->glyphs[*area];
6143 return glyph;
6147 /* Convert frame-relative x/y to coordinates relative to window W.
6148 Takes pseudo-windows into account. */
6150 static void
6151 frame_to_window_pixel_xy (w, x, y)
6152 struct window *w;
6153 int *x, *y;
6155 if (w->pseudo_window_p)
6157 /* A pseudo-window is always full-width, and starts at the
6158 left edge of the frame, plus a frame border. */
6159 struct frame *f = XFRAME (w->frame);
6160 *x -= FRAME_INTERNAL_BORDER_WIDTH_SAFE (f);
6161 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6163 else
6165 *x = FRAME_TO_WINDOW_PIXEL_X (w, *x);
6166 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
6171 /* Take proper action when mouse has moved to the mode or top line of
6172 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
6173 mode line. X is relative to the start of the text display area of
6174 W, so the width of bitmap areas and scroll bars must be subtracted
6175 to get a position relative to the start of the mode line. */
6177 static void
6178 note_mode_line_highlight (w, x, mode_line_p)
6179 struct window *w;
6180 int x, mode_line_p;
6182 struct frame *f = XFRAME (w->frame);
6183 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6184 Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
6185 struct glyph_row *row;
6187 if (mode_line_p)
6188 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
6189 else
6190 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
6192 if (row->enabled_p)
6194 struct glyph *glyph, *end;
6195 Lisp_Object help, map;
6196 int x0;
6198 /* Find the glyph under X. */
6199 glyph = row->glyphs[TEXT_AREA];
6200 end = glyph + row->used[TEXT_AREA];
6201 x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f)
6202 + FRAME_X_LEFT_FLAGS_AREA_WIDTH (f));
6203 while (glyph < end
6204 && x >= x0 + glyph->pixel_width)
6206 x0 += glyph->pixel_width;
6207 ++glyph;
6210 if (glyph < end
6211 && STRINGP (glyph->object)
6212 && XSTRING (glyph->object)->intervals
6213 && glyph->charpos >= 0
6214 && glyph->charpos < XSTRING (glyph->object)->size)
6216 /* If we're on a string with `help-echo' text property,
6217 arrange for the help to be displayed. This is done by
6218 setting the global variable help_echo to the help string. */
6219 help = Fget_text_property (make_number (glyph->charpos),
6220 Qhelp_echo, glyph->object);
6221 if (!NILP (help))
6223 help_echo = help;
6224 XSETWINDOW (help_echo_window, w);
6225 help_echo_object = glyph->object;
6226 help_echo_pos = glyph->charpos;
6229 /* Change the mouse pointer according to what is under X/Y. */
6230 map = Fget_text_property (make_number (glyph->charpos),
6231 Qlocal_map, glyph->object);
6232 if (KEYMAPP (map))
6233 cursor = f->output_data.w32->nontext_cursor;
6237 #if 0 /* TODO: mouse cursor */
6238 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor);
6239 #endif
6243 /* Take proper action when the mouse has moved to position X, Y on
6244 frame F as regards highlighting characters that have mouse-face
6245 properties. Also de-highlighting chars where the mouse was before.
6246 X and Y can be negative or out of range. */
6248 static void
6249 note_mouse_highlight (f, x, y)
6250 struct frame *f;
6251 int x, y;
6253 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6254 int portion;
6255 Lisp_Object window;
6256 struct window *w;
6258 /* When a menu is active, don't highlight because this looks odd. */
6259 if (popup_activated ())
6260 return;
6262 if (disable_mouse_highlight
6263 || !f->glyphs_initialized_p)
6264 return;
6266 dpyinfo->mouse_face_mouse_x = x;
6267 dpyinfo->mouse_face_mouse_y = y;
6268 dpyinfo->mouse_face_mouse_frame = f;
6270 if (dpyinfo->mouse_face_defer)
6271 return;
6273 if (gc_in_progress)
6275 dpyinfo->mouse_face_deferred_gc = 1;
6276 return;
6279 /* Which window is that in? */
6280 window = window_from_coordinates (f, x, y, &portion, 1);
6282 /* If we were displaying active text in another window, clear that. */
6283 if (! EQ (window, dpyinfo->mouse_face_window))
6284 clear_mouse_face (dpyinfo);
6286 /* Not on a window -> return. */
6287 if (!WINDOWP (window))
6288 return;
6290 /* Convert to window-relative pixel coordinates. */
6291 w = XWINDOW (window);
6292 frame_to_window_pixel_xy (w, &x, &y);
6294 /* Handle tool-bar window differently since it doesn't display a
6295 buffer. */
6296 if (EQ (window, f->tool_bar_window))
6298 note_tool_bar_highlight (f, x, y);
6299 return;
6302 if (portion == 1 || portion == 3)
6304 /* Mouse is on the mode or top line. */
6305 note_mode_line_highlight (w, x, portion == 1);
6306 return;
6308 #if 0 /* TODO: mouse cursor */
6309 else
6310 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6311 f->output_data.x->text_cursor);
6312 #endif
6314 /* Are we in a window whose display is up to date?
6315 And verify the buffer's text has not changed. */
6316 if (/* Within text portion of the window. */
6317 portion == 0
6318 && EQ (w->window_end_valid, w->buffer)
6319 && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
6320 && (XFASTINT (w->last_overlay_modified)
6321 == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
6323 int hpos, vpos, pos, i, area;
6324 struct glyph *glyph;
6326 /* Find the glyph under X/Y. */
6327 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &area);
6329 /* Clear mouse face if X/Y not over text. */
6330 if (glyph == NULL
6331 || area != TEXT_AREA
6332 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
6334 clear_mouse_face (dpyinfo);
6335 return;
6338 pos = glyph->charpos;
6339 xassert (w->pseudo_window_p || BUFFERP (glyph->object));
6341 /* Check for mouse-face and help-echo. */
6343 Lisp_Object mouse_face, overlay, position;
6344 Lisp_Object *overlay_vec;
6345 int len, noverlays;
6346 struct buffer *obuf;
6347 int obegv, ozv;
6349 /* If we get an out-of-range value, return now; avoid an error. */
6350 if (pos > BUF_Z (XBUFFER (w->buffer)))
6351 return;
6353 /* Make the window's buffer temporarily current for
6354 overlays_at and compute_char_face. */
6355 obuf = current_buffer;
6356 current_buffer = XBUFFER (w->buffer);
6357 obegv = BEGV;
6358 ozv = ZV;
6359 BEGV = BEG;
6360 ZV = Z;
6362 /* Is this char mouse-active or does it have help-echo? */
6363 XSETINT (position, pos);
6365 /* Put all the overlays we want in a vector in overlay_vec.
6366 Store the length in len. If there are more than 10, make
6367 enough space for all, and try again. */
6368 len = 10;
6369 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6370 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
6371 if (noverlays > len)
6373 len = noverlays;
6374 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
6375 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
6378 /* Sort overlays into increasing priority order. */
6379 noverlays = sort_overlays (overlay_vec, noverlays, w);
6381 /* Check mouse-face highlighting. */
6382 if (! (EQ (window, dpyinfo->mouse_face_window)
6383 && vpos >= dpyinfo->mouse_face_beg_row
6384 && vpos <= dpyinfo->mouse_face_end_row
6385 && (vpos > dpyinfo->mouse_face_beg_row
6386 || hpos >= dpyinfo->mouse_face_beg_col)
6387 && (vpos < dpyinfo->mouse_face_end_row
6388 || hpos < dpyinfo->mouse_face_end_col
6389 || dpyinfo->mouse_face_past_end)))
6391 /* Clear the display of the old active region, if any. */
6392 clear_mouse_face (dpyinfo);
6394 /* Find the highest priority overlay that has a mouse-face prop. */
6395 overlay = Qnil;
6396 for (i = noverlays - 1; i >= 0; --i)
6398 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
6399 if (!NILP (mouse_face))
6401 overlay = overlay_vec[i];
6402 break;
6406 /* If no overlay applies, get a text property. */
6407 if (NILP (overlay))
6408 mouse_face = Fget_text_property (position, Qmouse_face, w->buffer);
6410 /* Handle the overlay case. */
6411 if (! NILP (overlay))
6413 /* Find the range of text around this char that
6414 should be active. */
6415 Lisp_Object before, after;
6416 int ignore;
6418 before = Foverlay_start (overlay);
6419 after = Foverlay_end (overlay);
6420 /* Record this as the current active region. */
6421 fast_find_position (w, XFASTINT (before),
6422 &dpyinfo->mouse_face_beg_col,
6423 &dpyinfo->mouse_face_beg_row,
6424 &dpyinfo->mouse_face_beg_x,
6425 &dpyinfo->mouse_face_beg_y);
6426 dpyinfo->mouse_face_past_end
6427 = !fast_find_position (w, XFASTINT (after),
6428 &dpyinfo->mouse_face_end_col,
6429 &dpyinfo->mouse_face_end_row,
6430 &dpyinfo->mouse_face_end_x,
6431 &dpyinfo->mouse_face_end_y);
6432 dpyinfo->mouse_face_window = window;
6433 dpyinfo->mouse_face_face_id
6434 = face_at_buffer_position (w, pos, 0, 0,
6435 &ignore, pos + 1, 1);
6437 /* Display it as active. */
6438 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6440 /* Handle the text property case. */
6441 else if (! NILP (mouse_face))
6443 /* Find the range of text around this char that
6444 should be active. */
6445 Lisp_Object before, after, beginning, end;
6446 int ignore;
6448 beginning = Fmarker_position (w->start);
6449 XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
6450 - XFASTINT (w->window_end_pos)));
6451 before
6452 = Fprevious_single_property_change (make_number (pos + 1),
6453 Qmouse_face,
6454 w->buffer, beginning);
6455 after
6456 = Fnext_single_property_change (position, Qmouse_face,
6457 w->buffer, end);
6458 /* Record this as the current active region. */
6459 fast_find_position (w, XFASTINT (before),
6460 &dpyinfo->mouse_face_beg_col,
6461 &dpyinfo->mouse_face_beg_row,
6462 &dpyinfo->mouse_face_beg_x,
6463 &dpyinfo->mouse_face_beg_y);
6464 dpyinfo->mouse_face_past_end
6465 = !fast_find_position (w, XFASTINT (after),
6466 &dpyinfo->mouse_face_end_col,
6467 &dpyinfo->mouse_face_end_row,
6468 &dpyinfo->mouse_face_end_x,
6469 &dpyinfo->mouse_face_end_y);
6470 dpyinfo->mouse_face_window = window;
6471 dpyinfo->mouse_face_face_id
6472 = face_at_buffer_position (w, pos, 0, 0,
6473 &ignore, pos + 1, 1);
6475 /* Display it as active. */
6476 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
6480 /* Look for a `help-echo' property. */
6482 Lisp_Object help, overlay;
6484 /* Check overlays first. */
6485 help = Qnil;
6486 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
6488 overlay = overlay_vec[i];
6489 help = Foverlay_get (overlay, Qhelp_echo);
6492 if (!NILP (help))
6494 help_echo = help;
6495 help_echo_window = window;
6496 help_echo_object = overlay;
6497 help_echo_pos = pos;
6499 else
6501 /* Try text properties. */
6502 if ((STRINGP (glyph->object)
6503 && glyph->charpos >= 0
6504 && glyph->charpos < XSTRING (glyph->object)->size)
6505 || (BUFFERP (glyph->object)
6506 && glyph->charpos >= BEGV
6507 && glyph->charpos < ZV))
6508 help = Fget_text_property (make_number (glyph->charpos),
6509 Qhelp_echo, glyph->object);
6511 if (!NILP (help))
6513 help_echo = help;
6514 help_echo_window = window;
6515 help_echo_object = glyph->object;
6516 help_echo_pos = glyph->charpos;
6521 BEGV = obegv;
6522 ZV = ozv;
6523 current_buffer = obuf;
6528 static void
6529 redo_mouse_highlight ()
6531 if (!NILP (last_mouse_motion_frame)
6532 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
6533 note_mouse_highlight (XFRAME (last_mouse_motion_frame),
6534 LOWORD (last_mouse_motion_event.lParam),
6535 HIWORD (last_mouse_motion_event.lParam));
6540 /***********************************************************************
6541 Tool-bars
6542 ***********************************************************************/
6544 static int x_tool_bar_item P_ ((struct frame *, int, int,
6545 struct glyph **, int *, int *, int *));
6547 /* Tool-bar item index of the item on which a mouse button was pressed
6548 or -1. */
6550 static int last_tool_bar_item;
6553 /* Get information about the tool-bar item at position X/Y on frame F.
6554 Return in *GLYPH a pointer to the glyph of the tool-bar item in
6555 the current matrix of the tool-bar window of F, or NULL if not
6556 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
6557 item in F->current_tool_bar_items. Value is
6559 -1 if X/Y is not on a tool-bar item
6560 0 if X/Y is on the same item that was highlighted before.
6561 1 otherwise. */
6563 static int
6564 x_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
6565 struct frame *f;
6566 int x, y;
6567 struct glyph **glyph;
6568 int *hpos, *vpos, *prop_idx;
6570 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6571 struct window *w = XWINDOW (f->tool_bar_window);
6572 int area;
6574 /* Find the glyph under X/Y. */
6575 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, &area);
6576 if (*glyph == NULL)
6577 return -1;
6579 /* Get the start of this tool-bar item's properties in
6580 f->current_tool_bar_items. */
6581 if (!tool_bar_item_info (f, *glyph, prop_idx))
6582 return -1;
6584 /* Is mouse on the highlighted item? */
6585 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
6586 && *vpos >= dpyinfo->mouse_face_beg_row
6587 && *vpos <= dpyinfo->mouse_face_end_row
6588 && (*vpos > dpyinfo->mouse_face_beg_row
6589 || *hpos >= dpyinfo->mouse_face_beg_col)
6590 && (*vpos < dpyinfo->mouse_face_end_row
6591 || *hpos < dpyinfo->mouse_face_end_col
6592 || dpyinfo->mouse_face_past_end))
6593 return 0;
6595 return 1;
6599 /* Handle mouse button event on the tool-bar of frame F, at
6600 frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
6601 or ButtonRelase. */
6603 static void
6604 w32_handle_tool_bar_click (f, button_event)
6605 struct frame *f;
6606 struct input_event *button_event;
6608 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6609 struct window *w = XWINDOW (f->tool_bar_window);
6610 int hpos, vpos, prop_idx;
6611 struct glyph *glyph;
6612 Lisp_Object enabled_p;
6613 int x = XFASTINT (button_event->x);
6614 int y = XFASTINT (button_event->y);
6616 /* If not on the highlighted tool-bar item, return. */
6617 frame_to_window_pixel_xy (w, &x, &y);
6618 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
6619 return;
6621 /* If item is disabled, do nothing. */
6622 enabled_p = (XVECTOR (f->current_tool_bar_items)
6623 ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
6624 if (NILP (enabled_p))
6625 return;
6627 if (button_event->kind == mouse_click)
6629 /* Show item in pressed state. */
6630 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
6631 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
6632 last_tool_bar_item = prop_idx;
6634 else
6636 Lisp_Object key, frame;
6637 struct input_event event;
6639 /* Show item in released state. */
6640 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
6641 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
6643 key = (XVECTOR (f->current_tool_bar_items)
6644 ->contents[prop_idx + TOOL_BAR_ITEM_KEY]);
6646 XSETFRAME (frame, f);
6647 event.kind = TOOL_BAR_EVENT;
6648 event.frame_or_window = frame;
6649 event.arg = frame;
6650 kbd_buffer_store_event (&event);
6652 event.kind = TOOL_BAR_EVENT;
6653 event.frame_or_window = frame;
6654 event.arg = key;
6655 event.modifiers = button_event->modifiers;
6656 kbd_buffer_store_event (&event);
6657 last_tool_bar_item = -1;
6662 /* Possibly highlight a tool-bar item on frame F when mouse moves to
6663 tool-bar window-relative coordinates X/Y. Called from
6664 note_mouse_highlight. */
6666 static void
6667 note_tool_bar_highlight (f, x, y)
6668 struct frame *f;
6669 int x, y;
6671 Lisp_Object window = f->tool_bar_window;
6672 struct window *w = XWINDOW (window);
6673 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
6674 int hpos, vpos;
6675 struct glyph *glyph;
6676 struct glyph_row *row;
6677 int i;
6678 Lisp_Object enabled_p;
6679 int prop_idx;
6680 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
6681 int mouse_down_p, rc;
6683 /* Function note_mouse_highlight is called with negative x(y
6684 values when mouse moves outside of the frame. */
6685 if (x <= 0 || y <= 0)
6687 clear_mouse_face (dpyinfo);
6688 return;
6691 rc = x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
6692 if (rc < 0)
6694 /* Not on tool-bar item. */
6695 clear_mouse_face (dpyinfo);
6696 return;
6698 else if (rc == 0)
6699 /* On same tool-bar item as before. */
6700 goto set_help_echo;
6702 clear_mouse_face (dpyinfo);
6704 /* Mouse is down, but on different tool-bar item? */
6705 mouse_down_p = (dpyinfo->grabbed
6706 && f == last_mouse_frame
6707 && FRAME_LIVE_P (f));
6708 if (mouse_down_p
6709 && last_tool_bar_item != prop_idx)
6710 return;
6712 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
6713 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
6715 /* If tool-bar item is not enabled, don't highlight it. */
6716 enabled_p = (XVECTOR (f->current_tool_bar_items)
6717 ->contents[prop_idx + TOOL_BAR_ITEM_ENABLED_P]);
6718 if (!NILP (enabled_p))
6720 /* Compute the x-position of the glyph. In front and past the
6721 image is a space. We include this is the highlighted area. */
6722 row = MATRIX_ROW (w->current_matrix, vpos);
6723 for (i = x = 0; i < hpos; ++i)
6724 x += row->glyphs[TEXT_AREA][i].pixel_width;
6726 /* Record this as the current active region. */
6727 dpyinfo->mouse_face_beg_col = hpos;
6728 dpyinfo->mouse_face_beg_row = vpos;
6729 dpyinfo->mouse_face_beg_x = x;
6730 dpyinfo->mouse_face_beg_y = row->y;
6731 dpyinfo->mouse_face_past_end = 0;
6733 dpyinfo->mouse_face_end_col = hpos + 1;
6734 dpyinfo->mouse_face_end_row = vpos;
6735 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
6736 dpyinfo->mouse_face_end_y = row->y;
6737 dpyinfo->mouse_face_window = window;
6738 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
6740 /* Display it as active. */
6741 show_mouse_face (dpyinfo, draw);
6742 dpyinfo->mouse_face_image_state = draw;
6745 set_help_echo:
6747 /* Set help_echo to a help string.to display for this tool-bar item.
6748 w32_read_socket does the rest. */
6749 help_echo_object = help_echo_window = Qnil;
6750 help_echo_pos = -1;
6751 help_echo = (XVECTOR (f->current_tool_bar_items)
6752 ->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
6753 if (NILP (help_echo))
6754 help_echo = (XVECTOR (f->current_tool_bar_items)
6755 ->contents[prop_idx + TOOL_BAR_ITEM_CAPTION]);
6760 /* Find the glyph matrix position of buffer position POS in window W.
6761 *HPOS, *VPOS, *X, and *Y are set to the positions found. W's
6762 current glyphs must be up to date. If POS is above window start
6763 return (0, 0, 0, 0). If POS is after end of W, return end of
6764 last line in W. */
6766 static int
6767 fast_find_position (w, pos, hpos, vpos, x, y)
6768 struct window *w;
6769 int pos;
6770 int *hpos, *vpos, *x, *y;
6772 int i;
6773 int lastcol;
6774 int maybe_next_line_p = 0;
6775 int line_start_position;
6776 int yb = window_text_bottom_y (w);
6777 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0);
6778 struct glyph_row *best_row = row;
6779 int row_vpos = 0, best_row_vpos = 0;
6780 int current_x;
6782 while (row->y < yb)
6784 if (row->used[TEXT_AREA])
6785 line_start_position = row->glyphs[TEXT_AREA]->charpos;
6786 else
6787 line_start_position = 0;
6789 if (line_start_position > pos)
6790 break;
6791 /* If the position sought is the end of the buffer,
6792 don't include the blank lines at the bottom of the window. */
6793 else if (line_start_position == pos
6794 && pos == BUF_ZV (XBUFFER (w->buffer)))
6796 maybe_next_line_p = 1;
6797 break;
6799 else if (line_start_position > 0)
6801 best_row = row;
6802 best_row_vpos = row_vpos;
6805 if (row->y + row->height >= yb)
6806 break;
6808 ++row;
6809 ++row_vpos;
6812 /* Find the right column within BEST_ROW. */
6813 lastcol = 0;
6814 current_x = best_row->x;
6815 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
6817 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
6818 int charpos;
6820 charpos = glyph->charpos;
6821 if (charpos == pos)
6823 *hpos = i;
6824 *vpos = best_row_vpos;
6825 *x = current_x;
6826 *y = best_row->y;
6827 return 1;
6829 else if (charpos > pos)
6830 break;
6831 else if (charpos > 0)
6832 lastcol = i;
6834 current_x += glyph->pixel_width;
6837 /* If we're looking for the end of the buffer,
6838 and we didn't find it in the line we scanned,
6839 use the start of the following line. */
6840 if (maybe_next_line_p)
6842 ++best_row;
6843 ++best_row_vpos;
6844 lastcol = 0;
6845 current_x = best_row->x;
6848 *vpos = best_row_vpos;
6849 *hpos = lastcol + 1;
6850 *x = current_x;
6851 *y = best_row->y;
6852 return 0;
6856 /* Display the active region described by mouse_face_*
6857 in its mouse-face if HL > 0, in its normal face if HL = 0. */
6859 static void
6860 show_mouse_face (dpyinfo, draw)
6861 struct w32_display_info *dpyinfo;
6862 enum draw_glyphs_face draw;
6864 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
6865 struct frame *f = XFRAME (WINDOW_FRAME (w));
6866 int i;
6867 int cursor_off_p = 0;
6868 struct cursor_pos saved_cursor;
6870 saved_cursor = output_cursor;
6872 /* If window is in the process of being destroyed, don't bother
6873 to do anything. */
6874 if (w->current_matrix == NULL)
6875 goto set_x_cursor;
6877 /* Recognize when we are called to operate on rows that don't exist
6878 anymore. This can happen when a window is split. */
6879 if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
6880 goto set_x_cursor;
6882 set_output_cursor (&w->phys_cursor);
6884 /* Note that mouse_face_beg_row etc. are window relative. */
6885 for (i = dpyinfo->mouse_face_beg_row;
6886 i <= dpyinfo->mouse_face_end_row;
6887 i++)
6889 int start_hpos, end_hpos, start_x;
6890 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
6892 /* Don't do anything if row doesn't have valid contents. */
6893 if (!row->enabled_p)
6894 continue;
6896 /* For all but the first row, the highlight starts at column 0. */
6897 if (i == dpyinfo->mouse_face_beg_row)
6899 start_hpos = dpyinfo->mouse_face_beg_col;
6900 start_x = dpyinfo->mouse_face_beg_x;
6902 else
6904 start_hpos = 0;
6905 start_x = 0;
6908 if (i == dpyinfo->mouse_face_end_row)
6909 end_hpos = dpyinfo->mouse_face_end_col;
6910 else
6911 end_hpos = row->used[TEXT_AREA];
6913 /* If the cursor's in the text we are about to rewrite, turn the
6914 cursor off. */
6915 if (!w->pseudo_window_p
6916 && i == output_cursor.vpos
6917 && output_cursor.hpos >= start_hpos - 1
6918 && output_cursor.hpos <= end_hpos)
6920 x_update_window_cursor (w, 0);
6921 cursor_off_p = 1;
6924 if (end_hpos > start_hpos)
6926 row->mouse_face_p = draw == DRAW_MOUSE_FACE;
6927 x_draw_glyphs (w, start_x, row, TEXT_AREA,
6928 start_hpos, end_hpos, draw, NULL, NULL, 0);
6932 /* If we turned the cursor off, turn it back on. */
6933 if (cursor_off_p)
6934 x_display_cursor (w, 1,
6935 output_cursor.hpos, output_cursor.vpos,
6936 output_cursor.x, output_cursor.y);
6938 output_cursor = saved_cursor;
6940 set_x_cursor:
6941 #if 0 /* TODO: mouse cursor */
6942 /* Change the mouse cursor. */
6943 if (draw == DRAW_NORMAL_TEXT)
6944 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6945 f->output_data.x->text_cursor);
6946 else if (draw == DRAW_MOUSE_FACE)
6947 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6948 f->output_data.x->cross_cursor);
6949 else
6950 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
6951 f->output_data.x->nontext_cursor);
6952 #endif
6956 /* Clear out the mouse-highlighted active region.
6957 Redraw it un-highlighted first. */
6959 void
6960 clear_mouse_face (dpyinfo)
6961 struct w32_display_info *dpyinfo;
6963 if (tip_frame)
6964 return;
6966 if (! NILP (dpyinfo->mouse_face_window))
6967 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
6969 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
6970 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
6971 dpyinfo->mouse_face_window = Qnil;
6975 /* Clear any mouse-face on window W. This function is part of the
6976 redisplay interface, and is called from try_window_id and similar
6977 functions to ensure the mouse-highlight is off. */
6979 static void
6980 x_clear_mouse_face (w)
6981 struct window *w;
6983 struct w32_display_info *dpyinfo
6984 = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
6985 Lisp_Object window;
6987 BLOCK_INPUT;
6988 XSETWINDOW (window, w);
6989 if (EQ (window, dpyinfo->mouse_face_window))
6990 clear_mouse_face (dpyinfo);
6991 UNBLOCK_INPUT;
6995 /* Just discard the mouse face information for frame F, if any.
6996 This is used when the size of F is changed. */
6998 void
6999 cancel_mouse_face (f)
7000 FRAME_PTR f;
7002 Lisp_Object window;
7003 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
7005 window = dpyinfo->mouse_face_window;
7006 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
7008 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
7009 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
7010 dpyinfo->mouse_face_window = Qnil;
7014 static struct scroll_bar *x_window_to_scroll_bar ();
7015 static void x_scroll_bar_report_motion ();
7017 /* Return the current position of the mouse.
7018 *fp should be a frame which indicates which display to ask about.
7020 If the mouse movement started in a scroll bar, set *fp, *bar_window,
7021 and *part to the frame, window, and scroll bar part that the mouse
7022 is over. Set *x and *y to the portion and whole of the mouse's
7023 position on the scroll bar.
7025 If the mouse movement started elsewhere, set *fp to the frame the
7026 mouse is on, *bar_window to nil, and *x and *y to the character cell
7027 the mouse is over.
7029 Set *time to the server time-stamp for the time at which the mouse
7030 was at this position.
7032 Don't store anything if we don't have a valid set of values to report.
7034 This clears the mouse_moved flag, so we can wait for the next mouse
7035 movement. */
7037 static void
7038 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
7039 FRAME_PTR *fp;
7040 int insist;
7041 Lisp_Object *bar_window;
7042 enum scroll_bar_part *part;
7043 Lisp_Object *x, *y;
7044 unsigned long *time;
7046 FRAME_PTR f1;
7048 BLOCK_INPUT;
7050 if (! NILP (last_mouse_scroll_bar) && insist == 0)
7051 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
7052 else
7054 POINT pt;
7056 Lisp_Object frame, tail;
7058 /* Clear the mouse-moved flag for every frame on this display. */
7059 FOR_EACH_FRAME (tail, frame)
7060 XFRAME (frame)->mouse_moved = 0;
7062 last_mouse_scroll_bar = Qnil;
7064 GetCursorPos (&pt);
7066 /* Now we have a position on the root; find the innermost window
7067 containing the pointer. */
7069 if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
7070 && FRAME_LIVE_P (last_mouse_frame))
7072 /* If mouse was grabbed on a frame, give coords for that frame
7073 even if the mouse is now outside it. */
7074 f1 = last_mouse_frame;
7076 else
7078 /* Is window under mouse one of our frames? */
7079 f1 = x_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
7080 WindowFromPoint (pt));
7083 /* If not, is it one of our scroll bars? */
7084 if (! f1)
7086 struct scroll_bar *bar
7087 = x_window_to_scroll_bar (WindowFromPoint (pt));
7089 if (bar)
7091 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7095 if (f1 == 0 && insist > 0)
7096 f1 = SELECTED_FRAME ();
7098 if (f1)
7100 /* Ok, we found a frame. Store all the values.
7101 last_mouse_glyph is a rectangle used to reduce the
7102 generation of mouse events. To not miss any motion
7103 events, we must divide the frame into rectangles of the
7104 size of the smallest character that could be displayed
7105 on it, i.e. into the same rectangles that matrices on
7106 the frame are divided into. */
7108 #if OLD_REDISPLAY_CODE
7109 int ignore1, ignore2;
7111 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7113 pixel_to_glyph_coords (f1, pt.x, pt.y, &ignore1, &ignore2,
7114 &last_mouse_glyph,
7115 FRAME_W32_DISPLAY_INFO (f1)->grabbed
7116 || insist);
7117 #else
7118 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
7120 int width = FRAME_SMALLEST_CHAR_WIDTH (f1);
7121 int height = FRAME_SMALLEST_FONT_HEIGHT (f1);
7122 int x = pt.x;
7123 int y = pt.y;
7125 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to
7126 round down even for negative values. */
7127 if (x < 0)
7128 x -= width - 1;
7129 if (y < 0)
7130 y -= height - 1;
7132 last_mouse_glyph.left = (x + width - 1) / width * width;
7133 last_mouse_glyph.top = (y + height - 1) / height * height;
7134 last_mouse_glyph.right = last_mouse_glyph.left + width;
7135 last_mouse_glyph.bottom = last_mouse_glyph.top + height;
7137 #endif
7139 *bar_window = Qnil;
7140 *part = 0;
7141 *fp = f1;
7142 XSETINT (*x, pt.x);
7143 XSETINT (*y, pt.y);
7144 *time = last_mouse_movement_time;
7149 UNBLOCK_INPUT;
7153 /* Scroll bar support. */
7155 /* Given a window ID, find the struct scroll_bar which manages it.
7156 This can be called in GC, so we have to make sure to strip off mark
7157 bits. */
7159 static struct scroll_bar *
7160 x_window_to_scroll_bar (window_id)
7161 Window window_id;
7163 Lisp_Object tail;
7165 for (tail = Vframe_list;
7166 XGCTYPE (tail) == Lisp_Cons;
7167 tail = XCDR (tail))
7169 Lisp_Object frame, bar, condemned;
7171 frame = XCAR (tail);
7172 /* All elements of Vframe_list should be frames. */
7173 if (! GC_FRAMEP (frame))
7174 abort ();
7176 /* Scan this frame's scroll bar list for a scroll bar with the
7177 right window ID. */
7178 condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
7179 for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
7180 /* This trick allows us to search both the ordinary and
7181 condemned scroll bar lists with one loop. */
7182 ! GC_NILP (bar) || (bar = condemned,
7183 condemned = Qnil,
7184 ! GC_NILP (bar));
7185 bar = XSCROLL_BAR (bar)->next)
7186 if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
7187 return XSCROLL_BAR (bar);
7190 return 0;
7195 /* Set the thumb size and position of scroll bar BAR. We are currently
7196 displaying PORTION out of a whole WHOLE, and our position POSITION. */
7198 static void
7199 w32_set_scroll_bar_thumb (bar, portion, position, whole)
7200 struct scroll_bar *bar;
7201 int portion, position, whole;
7203 Window w = SCROLL_BAR_W32_WINDOW (bar);
7204 int range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7205 int sb_page, sb_pos;
7206 BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
7208 if (whole)
7210 /* Position scroll bar at rock bottom if the bottom of the
7211 buffer is visible. This avoids shinking the thumb away
7212 to nothing if it is held at the bottom of the buffer. */
7213 if (position + portion >= whole)
7215 sb_page = range * (whole - position) / whole
7216 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7217 sb_pos = range;
7220 sb_page = portion * range / whole + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7221 sb_pos = position * range / whole;
7223 else
7225 sb_page = range;
7226 sb_pos = 0;
7229 BLOCK_INPUT;
7231 if (pfnSetScrollInfo)
7233 SCROLLINFO si;
7235 si.cbSize = sizeof (si);
7236 /* Only update page size if currently dragging, to reduce
7237 flicker effects. */
7238 if (draggingp)
7239 si.fMask = SIF_PAGE;
7240 else
7241 si.fMask = SIF_PAGE | SIF_POS;
7242 si.nPage = sb_page;
7243 si.nPos = sb_pos;
7245 pfnSetScrollInfo (w, SB_CTL, &si, !draggingp);
7247 else
7248 SetScrollPos (w, SB_CTL, sb_pos, !draggingp);
7250 UNBLOCK_INPUT;
7254 /************************************************************************
7255 Scroll bars, general
7256 ************************************************************************/
7258 HWND
7259 my_create_scrollbar (f, bar)
7260 struct frame * f;
7261 struct scroll_bar * bar;
7263 return (HWND) SendMessage (FRAME_W32_WINDOW (f),
7264 WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
7265 (LPARAM) bar);
7268 //#define ATTACH_THREADS
7270 BOOL
7271 my_show_window (FRAME_PTR f, HWND hwnd, int how)
7273 #ifndef ATTACH_THREADS
7274 return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
7275 (WPARAM) hwnd, (LPARAM) how);
7276 #else
7277 return ShowWindow (hwnd, how);
7278 #endif
7281 void
7282 my_set_window_pos (HWND hwnd, HWND hwndAfter,
7283 int x, int y, int cx, int cy, UINT flags)
7285 #ifndef ATTACH_THREADS
7286 WINDOWPOS pos;
7287 pos.hwndInsertAfter = hwndAfter;
7288 pos.x = x;
7289 pos.y = y;
7290 pos.cx = cx;
7291 pos.cy = cy;
7292 pos.flags = flags;
7293 SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
7294 #else
7295 SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
7296 #endif
7299 void
7300 my_set_focus (f, hwnd)
7301 struct frame * f;
7302 HWND hwnd;
7304 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
7305 (WPARAM) hwnd, 0);
7308 void
7309 my_set_foreground_window (hwnd)
7310 HWND hwnd;
7312 SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
7315 void
7316 my_destroy_window (f, hwnd)
7317 struct frame * f;
7318 HWND hwnd;
7320 SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
7321 (WPARAM) hwnd, 0);
7324 /* Create a scroll bar and return the scroll bar vector for it. W is
7325 the Emacs window on which to create the scroll bar. TOP, LEFT,
7326 WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
7327 scroll bar. */
7329 static struct scroll_bar *
7330 x_scroll_bar_create (w, top, left, width, height)
7331 struct window *w;
7332 int top, left, width, height;
7334 struct frame *f = XFRAME (WINDOW_FRAME (w));
7335 HWND hwnd;
7336 struct scroll_bar *bar
7337 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
7339 BLOCK_INPUT;
7341 XSETWINDOW (bar->window, w);
7342 XSETINT (bar->top, top);
7343 XSETINT (bar->left, left);
7344 XSETINT (bar->width, width);
7345 XSETINT (bar->height, height);
7346 XSETINT (bar->start, 0);
7347 XSETINT (bar->end, 0);
7348 bar->dragging = Qnil;
7350 /* Requires geometry to be set before call to create the real window */
7352 hwnd = my_create_scrollbar (f, bar);
7354 if (pfnSetScrollInfo)
7356 SCROLLINFO si;
7358 si.cbSize = sizeof (si);
7359 si.fMask = SIF_ALL;
7360 si.nMin = 0;
7361 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7362 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7363 si.nPage = si.nMax;
7364 si.nPos = 0;
7366 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7368 else
7370 SetScrollRange (hwnd, SB_CTL, 0,
7371 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7372 SetScrollPos (hwnd, SB_CTL, 0, FALSE);
7375 SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
7377 /* Add bar to its frame's list of scroll bars. */
7378 bar->next = FRAME_SCROLL_BARS (f);
7379 bar->prev = Qnil;
7380 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7381 if (! NILP (bar->next))
7382 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7384 UNBLOCK_INPUT;
7386 return bar;
7390 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
7391 nil. */
7393 static void
7394 x_scroll_bar_remove (bar)
7395 struct scroll_bar *bar;
7397 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7399 BLOCK_INPUT;
7401 /* Destroy the window. */
7402 my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
7404 /* Disassociate this scroll bar from its window. */
7405 XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
7407 UNBLOCK_INPUT;
7410 /* Set the handle of the vertical scroll bar for WINDOW to indicate
7411 that we are displaying PORTION characters out of a total of WHOLE
7412 characters, starting at POSITION. If WINDOW has no scroll bar,
7413 create one. */
7414 static void
7415 w32_set_vertical_scroll_bar (w, portion, whole, position)
7416 struct window *w;
7417 int portion, whole, position;
7419 struct frame *f = XFRAME (w->frame);
7420 struct scroll_bar *bar;
7421 int top, height, left, sb_left, width, sb_width;
7422 int window_x, window_y, window_width, window_height;
7424 /* Get window dimensions. */
7425 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
7426 top = window_y;
7427 width = FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
7428 height = window_height;
7430 /* Compute the left edge of the scroll bar area. */
7431 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7432 left = XINT (w->left) + XINT (w->width) - FRAME_SCROLL_BAR_COLS (f);
7433 else
7434 left = XFASTINT (w->left);
7435 left *= CANON_X_UNIT (f);
7436 left += FRAME_INTERNAL_BORDER_WIDTH (f);
7438 /* Compute the width of the scroll bar which might be less than
7439 the width of the area reserved for the scroll bar. */
7440 if (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0)
7441 sb_width = FRAME_SCROLL_BAR_PIXEL_WIDTH (f);
7442 else
7443 sb_width = width;
7445 /* Compute the left edge of the scroll bar. */
7446 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
7447 sb_left = left + width - sb_width - (width - sb_width) / 2;
7448 else
7449 sb_left = left + (width - sb_width) / 2;
7451 /* Does the scroll bar exist yet? */
7452 if (NILP (w->vertical_scroll_bar))
7454 HDC hdc;
7455 BLOCK_INPUT;
7456 hdc = get_frame_dc (f);
7457 w32_clear_area (f, hdc, left, top, width, height);
7458 release_frame_dc (f, hdc);
7459 UNBLOCK_INPUT;
7461 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
7463 else
7465 /* It may just need to be moved and resized. */
7466 HWND hwnd;
7468 bar = XSCROLL_BAR (w->vertical_scroll_bar);
7469 hwnd = SCROLL_BAR_W32_WINDOW (bar);
7471 /* If already correctly positioned, do nothing. */
7472 if ( XINT (bar->left) == sb_left
7473 && XINT (bar->top) == top
7474 && XINT (bar->width) == sb_width
7475 && XINT (bar->height) == height )
7477 /* Redraw after clear_frame. */
7478 if (!my_show_window (f, hwnd, SW_NORMAL))
7479 InvalidateRect (hwnd, NULL, FALSE);
7481 else
7483 HDC hdc;
7484 BLOCK_INPUT;
7486 hdc = get_frame_dc (f);
7487 /* Since Windows scroll bars are smaller than the space reserved
7488 for them on the frame, we have to clear "under" them. */
7489 w32_clear_area (f, hdc,
7490 left,
7491 top,
7492 width,
7493 height);
7494 release_frame_dc (f, hdc);
7496 /* Make sure scroll bar is "visible" before moving, to ensure the
7497 area of the parent window now exposed will be refreshed. */
7498 my_show_window (f, hwnd, SW_HIDE);
7499 MoveWindow (hwnd, sb_left, top,
7500 sb_width, height, TRUE);
7501 if (pfnSetScrollInfo)
7503 SCROLLINFO si;
7505 si.cbSize = sizeof (si);
7506 si.fMask = SIF_RANGE;
7507 si.nMin = 0;
7508 si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
7509 + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7511 pfnSetScrollInfo (hwnd, SB_CTL, &si, FALSE);
7513 else
7514 SetScrollRange (hwnd, SB_CTL, 0,
7515 VERTICAL_SCROLL_BAR_TOP_RANGE (f, height), FALSE);
7516 my_show_window (f, hwnd, SW_NORMAL);
7517 // InvalidateRect (w, NULL, FALSE);
7519 /* Remember new settings. */
7520 XSETINT (bar->left, sb_left);
7521 XSETINT (bar->top, top);
7522 XSETINT (bar->width, sb_width);
7523 XSETINT (bar->height, height);
7525 UNBLOCK_INPUT;
7528 w32_set_scroll_bar_thumb (bar, portion, position, whole);
7530 XSETVECTOR (w->vertical_scroll_bar, bar);
7534 /* The following three hooks are used when we're doing a thorough
7535 redisplay of the frame. We don't explicitly know which scroll bars
7536 are going to be deleted, because keeping track of when windows go
7537 away is a real pain - "Can you say set-window-configuration, boys
7538 and girls?" Instead, we just assert at the beginning of redisplay
7539 that *all* scroll bars are to be removed, and then save a scroll bar
7540 from the fiery pit when we actually redisplay its window. */
7542 /* Arrange for all scroll bars on FRAME to be removed at the next call
7543 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
7544 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
7546 static void
7547 w32_condemn_scroll_bars (frame)
7548 FRAME_PTR frame;
7550 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
7551 while (! NILP (FRAME_SCROLL_BARS (frame)))
7553 Lisp_Object bar;
7554 bar = FRAME_SCROLL_BARS (frame);
7555 FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
7556 XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
7557 XSCROLL_BAR (bar)->prev = Qnil;
7558 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
7559 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
7560 FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
7564 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
7565 Note that WINDOW isn't necessarily condemned at all. */
7566 static void
7567 w32_redeem_scroll_bar (window)
7568 struct window *window;
7570 struct scroll_bar *bar;
7572 /* We can't redeem this window's scroll bar if it doesn't have one. */
7573 if (NILP (window->vertical_scroll_bar))
7574 abort ();
7576 bar = XSCROLL_BAR (window->vertical_scroll_bar);
7578 /* Unlink it from the condemned list. */
7580 FRAME_PTR f = XFRAME (WINDOW_FRAME (window));
7582 if (NILP (bar->prev))
7584 /* If the prev pointer is nil, it must be the first in one of
7585 the lists. */
7586 if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
7587 /* It's not condemned. Everything's fine. */
7588 return;
7589 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
7590 window->vertical_scroll_bar))
7591 FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
7592 else
7593 /* If its prev pointer is nil, it must be at the front of
7594 one or the other! */
7595 abort ();
7597 else
7598 XSCROLL_BAR (bar->prev)->next = bar->next;
7600 if (! NILP (bar->next))
7601 XSCROLL_BAR (bar->next)->prev = bar->prev;
7603 bar->next = FRAME_SCROLL_BARS (f);
7604 bar->prev = Qnil;
7605 XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
7606 if (! NILP (bar->next))
7607 XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
7611 /* Remove all scroll bars on FRAME that haven't been saved since the
7612 last call to `*condemn_scroll_bars_hook'. */
7614 static void
7615 w32_judge_scroll_bars (f)
7616 FRAME_PTR f;
7618 Lisp_Object bar, next;
7620 bar = FRAME_CONDEMNED_SCROLL_BARS (f);
7622 /* Clear out the condemned list now so we won't try to process any
7623 more events on the hapless scroll bars. */
7624 FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
7626 for (; ! NILP (bar); bar = next)
7628 struct scroll_bar *b = XSCROLL_BAR (bar);
7630 x_scroll_bar_remove (b);
7632 next = b->next;
7633 b->next = b->prev = Qnil;
7636 /* Now there should be no references to the condemned scroll bars,
7637 and they should get garbage-collected. */
7640 /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
7641 is set to something other than no_event, it is enqueued.
7643 This may be called from a signal handler, so we have to ignore GC
7644 mark bits. */
7646 static int
7647 x_scroll_bar_handle_click (bar, msg, emacs_event)
7648 struct scroll_bar *bar;
7649 W32Msg *msg;
7650 struct input_event *emacs_event;
7652 if (! GC_WINDOWP (bar->window))
7653 abort ();
7655 emacs_event->kind = w32_scroll_bar_click;
7656 emacs_event->code = 0;
7657 /* not really meaningful to distinguish up/down */
7658 emacs_event->modifiers = msg->dwModifiers;
7659 emacs_event->frame_or_window = bar->window;
7660 emacs_event->arg = Qnil;
7661 emacs_event->timestamp = msg->msg.time;
7664 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7665 int y;
7666 int dragging = !NILP (bar->dragging);
7668 if (pfnGetScrollInfo)
7670 SCROLLINFO si;
7672 si.cbSize = sizeof (si);
7673 si.fMask = SIF_POS;
7675 pfnGetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
7676 y = si.nPos;
7678 else
7679 y = GetScrollPos ((HWND) msg->msg.lParam, SB_CTL);
7681 bar->dragging = Qnil;
7684 last_mouse_scroll_bar_pos = msg->msg.wParam;
7686 switch (LOWORD (msg->msg.wParam))
7688 case SB_LINEDOWN:
7689 emacs_event->part = scroll_bar_down_arrow;
7690 break;
7691 case SB_LINEUP:
7692 emacs_event->part = scroll_bar_up_arrow;
7693 break;
7694 case SB_PAGEUP:
7695 emacs_event->part = scroll_bar_above_handle;
7696 break;
7697 case SB_PAGEDOWN:
7698 emacs_event->part = scroll_bar_below_handle;
7699 break;
7700 case SB_TOP:
7701 emacs_event->part = scroll_bar_handle;
7702 y = 0;
7703 break;
7704 case SB_BOTTOM:
7705 emacs_event->part = scroll_bar_handle;
7706 y = top_range;
7707 break;
7708 case SB_THUMBTRACK:
7709 case SB_THUMBPOSITION:
7710 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
7711 y = HIWORD (msg->msg.wParam);
7712 bar->dragging = Qt;
7713 emacs_event->part = scroll_bar_handle;
7715 /* "Silently" update current position. */
7716 if (pfnSetScrollInfo)
7718 SCROLLINFO si;
7720 si.cbSize = sizeof (si);
7721 si.fMask = SIF_POS;
7722 si.nPos = y;
7723 /* Remember apparent position (we actually lag behind the real
7724 position, so don't set that directly. */
7725 last_scroll_bar_drag_pos = y;
7727 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
7729 else
7730 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, FALSE);
7731 break;
7732 case SB_ENDSCROLL:
7733 /* If this is the end of a drag sequence, then reset the scroll
7734 handle size to normal and do a final redraw. Otherwise do
7735 nothing. */
7736 if (dragging)
7738 if (pfnSetScrollInfo)
7740 SCROLLINFO si;
7741 int start = XINT (bar->start);
7742 int end = XINT (bar->end);
7744 si.cbSize = sizeof (si);
7745 si.fMask = SIF_PAGE | SIF_POS;
7746 si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
7747 si.nPos = last_scroll_bar_drag_pos;
7748 pfnSetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
7750 else
7751 SetScrollPos (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, y, TRUE);
7753 /* fall through */
7754 default:
7755 emacs_event->kind = no_event;
7756 return FALSE;
7759 XSETINT (emacs_event->x, y);
7760 XSETINT (emacs_event->y, top_range);
7762 return TRUE;
7766 /* Return information to the user about the current position of the mouse
7767 on the scroll bar. */
7769 static void
7770 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
7771 FRAME_PTR *fp;
7772 Lisp_Object *bar_window;
7773 enum scroll_bar_part *part;
7774 Lisp_Object *x, *y;
7775 unsigned long *time;
7777 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
7778 Window w = SCROLL_BAR_W32_WINDOW (bar);
7779 FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
7780 int pos;
7781 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
7783 BLOCK_INPUT;
7785 *fp = f;
7786 *bar_window = bar->window;
7788 if (pfnGetScrollInfo)
7790 SCROLLINFO si;
7792 si.cbSize = sizeof (si);
7793 si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
7795 pfnGetScrollInfo (w, SB_CTL, &si);
7796 pos = si.nPos;
7797 top_range = si.nMax - si.nPage + 1;
7799 else
7800 pos = GetScrollPos (w, SB_CTL);
7802 switch (LOWORD (last_mouse_scroll_bar_pos))
7804 case SB_THUMBPOSITION:
7805 case SB_THUMBTRACK:
7806 *part = scroll_bar_handle;
7807 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
7808 pos = HIWORD (last_mouse_scroll_bar_pos);
7809 break;
7810 case SB_LINEDOWN:
7811 *part = scroll_bar_handle;
7812 pos++;
7813 break;
7814 default:
7815 *part = scroll_bar_handle;
7816 break;
7819 XSETINT (*x, pos);
7820 XSETINT (*y, top_range);
7822 f->mouse_moved = 0;
7823 last_mouse_scroll_bar = Qnil;
7825 *time = last_mouse_movement_time;
7827 UNBLOCK_INPUT;
7831 /* The screen has been cleared so we may have changed foreground or
7832 background colors, and the scroll bars may need to be redrawn.
7833 Clear out the scroll bars, and ask for expose events, so we can
7834 redraw them. */
7836 void
7837 x_scroll_bar_clear (f)
7838 FRAME_PTR f;
7840 Lisp_Object bar;
7842 /* We can have scroll bars even if this is 0,
7843 if we just turned off scroll bar mode.
7844 But in that case we should not clear them. */
7845 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
7846 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
7847 bar = XSCROLL_BAR (bar)->next)
7849 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
7850 HDC hdc = GetDC (window);
7851 RECT rect;
7853 /* Hide scroll bar until ready to repaint. x_scroll_bar_move
7854 arranges to refresh the scroll bar if hidden. */
7855 my_show_window (f, window, SW_HIDE);
7857 GetClientRect (window, &rect);
7858 select_palette (f, hdc);
7859 w32_clear_rect (f, hdc, &rect);
7860 deselect_palette (f, hdc);
7862 ReleaseDC (window, hdc);
7866 show_scroll_bars (f, how)
7867 FRAME_PTR f;
7868 int how;
7870 Lisp_Object bar;
7872 for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
7873 bar = XSCROLL_BAR (bar)->next)
7875 HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
7876 my_show_window (f, window, how);
7881 /* The main W32 event-reading loop - w32_read_socket. */
7883 /* Time stamp of enter window event. This is only used by w32_read_socket,
7884 but we have to put it out here, since static variables within functions
7885 sometimes don't work. */
7887 static Time enter_timestamp;
7889 /* Record the last 100 characters stored
7890 to help debug the loss-of-chars-during-GC problem. */
7892 static int temp_index;
7893 static short temp_buffer[100];
7896 /* Read events coming from the W32 shell.
7897 This routine is called by the SIGIO handler.
7898 We return as soon as there are no more events to be read.
7900 Events representing keys are stored in buffer BUFP,
7901 which can hold up to NUMCHARS characters.
7902 We return the number of characters stored into the buffer,
7903 thus pretending to be `read'.
7905 EXPECTED is nonzero if the caller knows input is available.
7907 Some of these messages are reposted back to the message queue since the
7908 system calls the windows proc directly in a context where we cannot return
7909 the data nor can we guarantee the state we are in. So if we dispatch them
7910 we will get into an infinite loop. To prevent this from ever happening we
7911 will set a variable to indicate we are in the read_socket call and indicate
7912 which message we are processing since the windows proc gets called
7913 recursively with different messages by the system.
7917 w32_read_socket (sd, bufp, numchars, expected)
7918 register int sd;
7919 /* register */ struct input_event *bufp;
7920 /* register */ int numchars;
7921 int expected;
7923 int count = 0;
7924 int check_visibility = 0;
7925 W32Msg msg;
7926 struct frame *f;
7927 struct w32_display_info *dpyinfo = &one_w32_display_info;
7929 if (interrupt_input_blocked)
7931 interrupt_input_pending = 1;
7932 return -1;
7935 interrupt_input_pending = 0;
7936 BLOCK_INPUT;
7938 /* So people can tell when we have read the available input. */
7939 input_signal_count++;
7941 if (numchars <= 0)
7942 abort (); /* Don't think this happens. */
7944 /* TODO: tooltips, tool-bars, ghostscript integration, mouse
7945 cursors. */
7946 while (get_next_msg (&msg, FALSE))
7948 switch (msg.msg.message)
7950 case WM_PAINT:
7951 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
7953 if (f)
7955 if (msg.rect.right == msg.rect.left ||
7956 msg.rect.bottom == msg.rect.top)
7958 /* We may get paint messages even though the client
7959 area is clipped - these are not expose events. */
7960 DebPrint (("clipped frame %04x (%s) got WM_PAINT\n", f,
7961 XSTRING (f->name)->data));
7963 else if (f->async_visible != 1)
7965 /* Definitely not obscured, so mark as visible. */
7966 f->async_visible = 1;
7967 f->async_iconified = 0;
7968 SET_FRAME_GARBAGED (f);
7969 DebPrint (("frame %04x (%s) reexposed\n", f,
7970 XSTRING (f->name)->data));
7972 /* WM_PAINT serves as MapNotify as well, so report
7973 visibility changes properly. */
7974 if (f->iconified)
7976 bufp->kind = deiconify_event;
7977 XSETFRAME (bufp->frame_or_window, f);
7978 bufp->arg = Qnil;
7979 bufp++;
7980 count++;
7981 numchars--;
7983 else if (! NILP (Vframe_list)
7984 && ! NILP (XCDR (Vframe_list)))
7985 /* Force a redisplay sooner or later to update the
7986 frame titles in case this is the second frame. */
7987 record_asynch_buffer_change ();
7989 else
7991 HDC hdc = get_frame_dc (f);
7993 /* Erase background again for safety. */
7994 w32_clear_rect (f, hdc, &msg.rect);
7995 release_frame_dc (f, hdc);
7996 expose_frame (f,
7997 msg.rect.left,
7998 msg.rect.top,
7999 msg.rect.right - msg.rect.left,
8000 msg.rect.bottom - msg.rect.top);
8003 break;
8005 case WM_INPUTLANGCHANGE:
8006 /* Generate a language change event. */
8007 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8009 if (f)
8011 if (numchars == 0)
8012 abort ();
8014 bufp->kind = language_change_event;
8015 XSETFRAME (bufp->frame_or_window, f);
8016 bufp->arg = Qnil;
8017 bufp->code = msg.msg.wParam;
8018 bufp->modifiers = msg.msg.lParam & 0xffff;
8019 bufp++;
8020 count++;
8021 numchars--;
8023 break;
8025 case WM_KEYDOWN:
8026 case WM_SYSKEYDOWN:
8027 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8029 if (f && !f->iconified)
8031 if (temp_index == sizeof temp_buffer / sizeof (short))
8032 temp_index = 0;
8033 temp_buffer[temp_index++] = msg.msg.wParam;
8034 bufp->kind = non_ascii_keystroke;
8035 bufp->code = msg.msg.wParam;
8036 bufp->modifiers = msg.dwModifiers;
8037 XSETFRAME (bufp->frame_or_window, f);
8038 bufp->arg = Qnil;
8039 bufp->timestamp = msg.msg.time;
8040 bufp++;
8041 numchars--;
8042 count++;
8044 break;
8046 case WM_SYSCHAR:
8047 case WM_CHAR:
8048 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8050 if (f && !f->iconified)
8052 if (temp_index == sizeof temp_buffer / sizeof (short))
8053 temp_index = 0;
8054 temp_buffer[temp_index++] = msg.msg.wParam;
8055 bufp->kind = ascii_keystroke;
8056 bufp->code = msg.msg.wParam;
8057 bufp->modifiers = msg.dwModifiers;
8058 XSETFRAME (bufp->frame_or_window, f);
8059 bufp->arg = Qnil;
8060 bufp->timestamp = msg.msg.time;
8061 bufp++;
8062 numchars--;
8063 count++;
8065 break;
8067 case WM_MOUSEMOVE:
8068 previous_help_echo = help_echo;
8069 help_echo = help_echo_object = help_echo_window = Qnil;
8070 help_echo_pos = -1;
8072 if (dpyinfo->grabbed && last_mouse_frame
8073 && FRAME_LIVE_P (last_mouse_frame))
8074 f = last_mouse_frame;
8075 else
8076 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8078 if (f)
8079 note_mouse_movement (f, &msg.msg);
8080 else
8082 /* If we move outside the frame, then we're
8083 certainly no longer on any text in the frame. */
8084 clear_mouse_face (FRAME_W32_DISPLAY_INFO (f));
8087 /* If the contents of the global variable help_echo
8088 has changed, generate a HELP_EVENT. */
8089 if (!NILP (help_echo)
8090 || !NILP (previous_help_echo))
8092 Lisp_Object frame;
8093 int n;
8095 if (f)
8096 XSETFRAME (frame, f);
8097 else
8098 frame = Qnil;
8100 any_help_event_p = 1;
8101 n = gen_help_event (bufp, numchars, help_echo, frame,
8102 help_echo_window, help_echo_object,
8103 help_echo_pos);
8104 bufp += n, count += n, numchars -= n;
8106 break;
8108 case WM_LBUTTONDOWN:
8109 case WM_LBUTTONUP:
8110 case WM_MBUTTONDOWN:
8111 case WM_MBUTTONUP:
8112 case WM_RBUTTONDOWN:
8113 case WM_RBUTTONUP:
8115 /* If we decide we want to generate an event to be seen
8116 by the rest of Emacs, we put it here. */
8117 struct input_event emacs_event;
8118 int tool_bar_p = 0;
8119 int button;
8120 int up;
8122 emacs_event.kind = no_event;
8124 if (dpyinfo->grabbed && last_mouse_frame
8125 && FRAME_LIVE_P (last_mouse_frame))
8126 f = last_mouse_frame;
8127 else
8128 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8130 if (f)
8132 construct_mouse_click (&emacs_event, &msg, f);
8134 /* Is this in the tool-bar? */
8135 if (WINDOWP (f->tool_bar_window)
8136 && XFASTINT (XWINDOW (f->tool_bar_window)->height))
8138 Lisp_Object window;
8139 int p, x, y;
8141 /* Set x and y. */
8142 window = window_from_coordinates (f,
8143 emacs_event.x,
8144 emacs_event.y,
8145 &p, 1);
8146 if (EQ (window, f->tool_bar_window))
8148 w32_handle_tool_bar_click (f, &emacs_event);
8149 tool_bar_p = 1;
8153 if (!tool_bar_p)
8154 if (!dpyinfo->w32_focus_frame
8155 || f == dpyinfo->w32_focus_frame
8156 && (numchars >= 1))
8158 construct_mouse_click (bufp, &msg, f);
8159 bufp++;
8160 count++;
8161 numchars--;
8165 parse_button (msg.msg.message, &button, &up);
8167 if (up)
8169 dpyinfo->grabbed &= ~ (1 << button);
8171 else
8173 dpyinfo->grabbed |= (1 << button);
8174 last_mouse_frame = f;
8175 /* Ignore any mouse motion that happened
8176 before this event; any subsequent mouse-movement
8177 Emacs events should reflect only motion after
8178 the ButtonPress. */
8179 if (f != 0)
8180 f->mouse_moved = 0;
8182 if (!tool_bar_p)
8183 last_tool_bar_item = -1;
8185 break;
8188 case WM_MOUSEWHEEL:
8189 if (dpyinfo->grabbed && last_mouse_frame
8190 && FRAME_LIVE_P (last_mouse_frame))
8191 f = last_mouse_frame;
8192 else
8193 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8195 if (f)
8197 if ((!dpyinfo->w32_focus_frame
8198 || f == dpyinfo->w32_focus_frame)
8199 && (numchars >= 1))
8201 construct_mouse_wheel (bufp, &msg, f);
8202 bufp++;
8203 count++;
8204 numchars--;
8207 break;
8209 case WM_MENUSELECT:
8211 HMENU menu = (HMENU) msg.msg.lParam;
8212 UINT menu_item = (UINT) LOWORD (msg.msg.wParam);
8213 UINT flags = (UINT) HIWORD (msg.msg.wParam);
8215 w32_menu_display_help (menu, menu_item, flags);
8217 break;
8219 case WM_DROPFILES:
8220 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8222 if (f)
8224 construct_drag_n_drop (bufp, &msg, f);
8225 bufp++;
8226 count++;
8227 numchars--;
8229 break;
8231 case WM_VSCROLL:
8233 struct scroll_bar *bar =
8234 x_window_to_scroll_bar ((HWND)msg.msg.lParam);
8236 if (bar && numchars >= 1)
8238 if (x_scroll_bar_handle_click (bar, &msg, bufp))
8240 bufp++;
8241 count++;
8242 numchars--;
8245 break;
8248 case WM_WINDOWPOSCHANGED:
8249 case WM_ACTIVATE:
8250 case WM_ACTIVATEAPP:
8251 check_visibility = 1;
8252 break;
8254 case WM_MOVE:
8255 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8257 if (f && !f->async_iconified)
8259 int x, y;
8261 x_real_positions (f, &x, &y);
8262 f->output_data.w32->left_pos = x;
8263 f->output_data.w32->top_pos = y;
8266 check_visibility = 1;
8267 break;
8269 case WM_SHOWWINDOW:
8270 /* If window has been obscured or exposed by another window
8271 being maximised or minimised/restored, then recheck
8272 visibility of all frames. Direct changes to our own
8273 windows get handled by WM_SIZE. */
8274 #if 0
8275 if (msg.msg.lParam != 0)
8276 check_visibility = 1;
8277 else
8279 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8280 f->async_visible = msg.msg.wParam;
8282 #endif
8284 check_visibility = 1;
8285 break;
8287 case WM_SIZE:
8288 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8290 /* Inform lisp of whether frame has been iconified etc. */
8291 if (f)
8293 switch (msg.msg.wParam)
8295 case SIZE_MINIMIZED:
8296 f->async_visible = 0;
8297 f->async_iconified = 1;
8299 bufp->kind = iconify_event;
8300 XSETFRAME (bufp->frame_or_window, f);
8301 bufp->arg = Qnil;
8302 bufp++;
8303 count++;
8304 numchars--;
8305 break;
8307 case SIZE_MAXIMIZED:
8308 case SIZE_RESTORED:
8309 f->async_visible = 1;
8310 f->async_iconified = 0;
8312 /* wait_reading_process_input will notice this and update
8313 the frame's display structures. */
8314 SET_FRAME_GARBAGED (f);
8316 if (f->iconified)
8318 int x, y;
8320 /* Reset top and left positions of the Window
8321 here since Windows sends a WM_MOVE message
8322 BEFORE telling us the Window is minimized
8323 when the Window is iconified, with 3000,3000
8324 as the co-ords. */
8325 x_real_positions (f, &x, &y);
8326 f->output_data.w32->left_pos = x;
8327 f->output_data.w32->top_pos = y;
8329 bufp->kind = deiconify_event;
8330 XSETFRAME (bufp->frame_or_window, f);
8331 bufp->arg = Qnil;
8332 bufp++;
8333 count++;
8334 numchars--;
8336 else if (! NILP (Vframe_list)
8337 && ! NILP (XCDR (Vframe_list)))
8338 /* Force a redisplay sooner or later
8339 to update the frame titles
8340 in case this is the second frame. */
8341 record_asynch_buffer_change ();
8342 break;
8346 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
8348 RECT rect;
8349 int rows;
8350 int columns;
8351 int width;
8352 int height;
8354 GetClientRect (msg.msg.hwnd, &rect);
8356 height = rect.bottom - rect.top;
8357 width = rect.right - rect.left;
8359 rows = PIXEL_TO_CHAR_HEIGHT (f, height);
8360 columns = PIXEL_TO_CHAR_WIDTH (f, width);
8362 /* TODO: Clip size to the screen dimensions. */
8364 /* Even if the number of character rows and columns has
8365 not changed, the font size may have changed, so we need
8366 to check the pixel dimensions as well. */
8368 if (columns != f->width
8369 || rows != f->height
8370 || width != f->output_data.w32->pixel_width
8371 || height != f->output_data.w32->pixel_height)
8373 change_frame_size (f, rows, columns, 0, 1, 0);
8374 SET_FRAME_GARBAGED (f);
8375 cancel_mouse_face (f);
8376 f->output_data.w32->pixel_width = width;
8377 f->output_data.w32->pixel_height = height;
8378 f->output_data.w32->win_gravity = NorthWestGravity;
8382 check_visibility = 1;
8383 break;
8385 case WM_SETFOCUS:
8386 f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
8388 dpyinfo->w32_focus_event_frame = f;
8390 if (f)
8391 x_new_focus_frame (dpyinfo, f);
8394 dpyinfo->grabbed = 0;
8395 check_visibility = 1;
8396 break;
8398 case WM_KILLFOCUS:
8399 /* TODO: some of this belongs in MOUSE_LEAVE */
8400 f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
8402 if (f)
8404 Lisp_Object frame;
8406 if (f == dpyinfo->w32_focus_event_frame)
8407 dpyinfo->w32_focus_event_frame = 0;
8409 if (f == dpyinfo->w32_focus_frame)
8410 x_new_focus_frame (dpyinfo, 0);
8412 if (f == dpyinfo->mouse_face_mouse_frame)
8414 /* If we move outside the frame, then we're
8415 certainly no longer on any text in the frame. */
8416 clear_mouse_face (dpyinfo);
8417 dpyinfo->mouse_face_mouse_frame = 0;
8420 /* Generate a nil HELP_EVENT to cancel a help-echo.
8421 Do it only if there's something to cancel.
8422 Otherwise, the startup message is cleared when
8423 the mouse leaves the frame. */
8424 if (any_help_event_p)
8426 int n;
8428 XSETFRAME (frame, f);
8429 n = gen_help_event (bufp, numchars, Qnil, frame,
8430 Qnil, Qnil, 0);
8431 bufp += n, count += n, numchars -=n;
8435 dpyinfo->grabbed = 0;
8436 check_visibility = 1;
8437 break;
8439 case WM_CLOSE:
8440 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8442 if (f)
8444 if (numchars == 0)
8445 abort ();
8447 bufp->kind = delete_window_event;
8448 XSETFRAME (bufp->frame_or_window, f);
8449 bufp->arg = Qnil;
8450 bufp++;
8451 count++;
8452 numchars--;
8454 break;
8456 case WM_INITMENU:
8457 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8459 if (f)
8461 if (numchars == 0)
8462 abort ();
8464 bufp->kind = menu_bar_activate_event;
8465 XSETFRAME (bufp->frame_or_window, f);
8466 bufp->arg = Qnil;
8467 bufp++;
8468 count++;
8469 numchars--;
8471 break;
8473 case WM_COMMAND:
8474 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8476 if (f)
8478 extern void menubar_selection_callback
8479 (FRAME_PTR f, void * client_data);
8480 menubar_selection_callback (f, (void *)msg.msg.wParam);
8483 check_visibility = 1;
8484 break;
8486 case WM_DISPLAYCHANGE:
8487 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8489 if (f)
8491 dpyinfo->width = (short) LOWORD (msg.msg.lParam);
8492 dpyinfo->height = (short) HIWORD (msg.msg.lParam);
8493 dpyinfo->n_cbits = msg.msg.wParam;
8494 DebPrint (("display change: %d %d\n", dpyinfo->width,
8495 dpyinfo->height));
8498 check_visibility = 1;
8499 break;
8501 default:
8502 /* Check for messages registered at runtime. */
8503 if (msg.msg.message == msh_mousewheel)
8505 if (dpyinfo->grabbed && last_mouse_frame
8506 && FRAME_LIVE_P (last_mouse_frame))
8507 f = last_mouse_frame;
8508 else
8509 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
8511 if (f)
8513 if ((!dpyinfo->w32_focus_frame
8514 || f == dpyinfo->w32_focus_frame)
8515 && (numchars >= 1))
8517 construct_mouse_wheel (bufp, &msg, f);
8518 bufp++;
8519 count++;
8520 numchars--;
8524 break;
8528 /* If the focus was just given to an autoraising frame,
8529 raise it now. */
8530 /* ??? This ought to be able to handle more than one such frame. */
8531 if (pending_autoraise_frame)
8533 x_raise_frame (pending_autoraise_frame);
8534 pending_autoraise_frame = 0;
8537 /* Check which frames are still visisble, if we have enqueued any user
8538 events or been notified of events that may affect visibility. We
8539 do this here because there doesn't seem to be any direct
8540 notification from Windows that the visibility of a window has
8541 changed (at least, not in all cases). */
8542 if (count > 0 || check_visibility)
8544 Lisp_Object tail, frame;
8546 FOR_EACH_FRAME (tail, frame)
8548 FRAME_PTR f = XFRAME (frame);
8549 /* Check "visible" frames and mark each as obscured or not.
8550 Note that async_visible is nonzero for unobscured and
8551 obscured frames, but zero for hidden and iconified frames. */
8552 if (FRAME_W32_P (f) && f->async_visible)
8554 RECT clipbox;
8555 HDC hdc = get_frame_dc (f);
8556 GetClipBox (hdc, &clipbox);
8557 release_frame_dc (f, hdc);
8559 if (clipbox.right == clipbox.left
8560 || clipbox.bottom == clipbox.top)
8562 /* Frame has become completely obscured so mark as
8563 such (we do this by setting async_visible to 2 so
8564 that FRAME_VISIBLE_P is still true, but redisplay
8565 will skip it). */
8566 f->async_visible = 2;
8568 if (!FRAME_OBSCURED_P (f))
8570 DebPrint (("frame %04x (%s) obscured\n", f,
8571 XSTRING (f->name)->data));
8574 else
8576 /* Frame is not obscured, so mark it as such. */
8577 f->async_visible = 1;
8579 if (FRAME_OBSCURED_P (f))
8581 SET_FRAME_GARBAGED (f);
8582 DebPrint (("frame %04x (%s) reexposed\n", f,
8583 XSTRING (f->name)->data));
8585 /* Force a redisplay sooner or later. */
8586 record_asynch_buffer_change ();
8593 UNBLOCK_INPUT;
8594 return count;
8600 /***********************************************************************
8601 Text Cursor
8602 ***********************************************************************/
8604 /* Note if the text cursor of window W has been overwritten by a
8605 drawing operation that outputs N glyphs starting at HPOS in the
8606 line given by output_cursor.vpos. N < 0 means all the rest of the
8607 line after HPOS has been written. */
8609 static void
8610 note_overwritten_text_cursor (w, hpos, n)
8611 struct window *w;
8612 int hpos, n;
8614 if (updated_area == TEXT_AREA
8615 && output_cursor.vpos == w->phys_cursor.vpos
8616 && hpos <= w->phys_cursor.hpos
8617 && (n < 0
8618 || hpos + n > w->phys_cursor.hpos))
8619 w->phys_cursor_on_p = 0;
8623 /* Set clipping for output in glyph row ROW. W is the window in which
8624 we operate. GC is the graphics context to set clipping in.
8625 WHOLE_LINE_P non-zero means include the areas used for truncation
8626 mark display and alike in the clipping rectangle.
8628 ROW may be a text row or, e.g., a mode line. Text rows must be
8629 clipped to the interior of the window dedicated to text display,
8630 mode lines must be clipped to the whole window. */
8632 static void
8633 w32_clip_to_row (w, row, hdc, whole_line_p)
8634 struct window *w;
8635 struct glyph_row *row;
8636 HDC hdc;
8637 int whole_line_p;
8639 struct frame *f = XFRAME (WINDOW_FRAME (w));
8640 RECT clip_rect;
8641 int window_x, window_y, window_width, window_height;
8643 window_box (w, -1, &window_x, &window_y, &window_width, &window_height);
8645 clip_rect.left = WINDOW_TO_FRAME_PIXEL_X (w, 0);
8646 clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
8647 clip_rect.top = max (clip_rect.top, window_y);
8648 clip_rect.right = clip_rect.left + window_width;
8649 clip_rect.bottom = clip_rect.top + row->visible_height;
8651 /* If clipping to the whole line, including trunc marks, extend
8652 the rectangle to the left and increase its width. */
8653 if (whole_line_p)
8655 clip_rect.left -= FRAME_X_LEFT_FLAGS_AREA_WIDTH (f);
8656 clip_rect.right += FRAME_X_FLAGS_AREA_WIDTH (f);
8659 w32_set_clip_rectangle (hdc, &clip_rect);
8663 /* Draw a hollow box cursor on window W in glyph row ROW. */
8665 static void
8666 x_draw_hollow_cursor (w, row)
8667 struct window *w;
8668 struct glyph_row *row;
8670 struct frame *f = XFRAME (WINDOW_FRAME (w));
8671 HDC hdc = get_frame_dc (f);
8672 RECT rect;
8673 int wd;
8674 struct glyph *cursor_glyph;
8675 HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
8677 /* Compute frame-relative coordinates from window-relative
8678 coordinates. */
8679 rect.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8680 rect.top = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
8681 + row->ascent - w->phys_cursor_ascent);
8682 rect.bottom = rect.top + row->height - 1;
8684 /* Get the glyph the cursor is on. If we can't tell because
8685 the current matrix is invalid or such, give up. */
8686 cursor_glyph = get_phys_cursor_glyph (w);
8687 if (cursor_glyph == NULL)
8688 return;
8690 /* Compute the width of the rectangle to draw. If on a stretch
8691 glyph, and `x-stretch-block-cursor' is nil, don't draw a
8692 rectangle as wide as the glyph, but use a canonical character
8693 width instead. */
8694 wd = cursor_glyph->pixel_width - 1;
8695 if (cursor_glyph->type == STRETCH_GLYPH
8696 && !x_stretch_cursor_p)
8697 wd = min (CANON_X_UNIT (f), wd);
8699 rect.right = rect.left + wd;
8701 FrameRect (hdc, &rect, hb);
8702 DeleteObject (hb);
8704 release_frame_dc (f, hdc);
8708 /* Draw a bar cursor on window W in glyph row ROW.
8710 Implementation note: One would like to draw a bar cursor with an
8711 angle equal to the one given by the font property XA_ITALIC_ANGLE.
8712 Unfortunately, I didn't find a font yet that has this property set.
8713 --gerd. */
8715 static void
8716 x_draw_bar_cursor (w, row, width)
8717 struct window *w;
8718 struct glyph_row *row;
8719 int width;
8721 /* If cursor hpos is out of bounds, don't draw garbage. This can
8722 happen in mini-buffer windows when switching between echo area
8723 glyphs and mini-buffer. */
8724 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
8726 struct frame *f = XFRAME (w->frame);
8727 struct glyph *cursor_glyph;
8728 int x;
8729 HDC hdc;
8731 cursor_glyph = get_phys_cursor_glyph (w);
8732 if (cursor_glyph == NULL)
8733 return;
8735 /* If on an image, draw like a normal cursor. That's usually better
8736 visible than drawing a bar, esp. if the image is large so that
8737 the bar might not be in the window. */
8738 if (cursor_glyph->type == IMAGE_GLYPH)
8740 struct glyph_row *row;
8741 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
8742 x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
8744 else
8747 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8749 if (width < 0)
8750 width = f->output_data.w32->cursor_width;
8752 hdc = get_frame_dc (f);
8753 w32_fill_area (f, hdc, f->output_data.w32->cursor_pixel,
8755 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
8756 min (cursor_glyph->pixel_width, width),
8757 row->height);
8758 release_frame_dc (f, hdc);
8764 /* Clear the cursor of window W to background color, and mark the
8765 cursor as not shown. This is used when the text where the cursor
8766 is is about to be rewritten. */
8768 static void
8769 x_clear_cursor (w)
8770 struct window *w;
8772 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
8773 x_update_window_cursor (w, 0);
8777 /* Draw the cursor glyph of window W in glyph row ROW. See the
8778 comment of x_draw_glyphs for the meaning of HL. */
8780 static void
8781 x_draw_phys_cursor_glyph (w, row, hl)
8782 struct window *w;
8783 struct glyph_row *row;
8784 enum draw_glyphs_face hl;
8786 /* If cursor hpos is out of bounds, don't draw garbage. This can
8787 happen in mini-buffer windows when switching between echo area
8788 glyphs and mini-buffer. */
8789 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
8791 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
8792 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
8793 hl, 0, 0, 0);
8795 /* When we erase the cursor, and ROW is overlapped by other
8796 rows, make sure that these overlapping parts of other rows
8797 are redrawn. */
8798 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
8800 if (row > w->current_matrix->rows
8801 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
8802 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
8804 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
8805 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
8806 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
8812 /* Erase the image of a cursor of window W from the screen. */
8814 static void
8815 x_erase_phys_cursor (w)
8816 struct window *w;
8818 struct frame *f = XFRAME (w->frame);
8819 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
8820 int hpos = w->phys_cursor.hpos;
8821 int vpos = w->phys_cursor.vpos;
8822 int mouse_face_here_p = 0;
8823 struct glyph_matrix *active_glyphs = w->current_matrix;
8824 struct glyph_row *cursor_row;
8825 struct glyph *cursor_glyph;
8826 enum draw_glyphs_face hl;
8828 /* No cursor displayed or row invalidated => nothing to do on the
8829 screen. */
8830 if (w->phys_cursor_type == NO_CURSOR)
8831 goto mark_cursor_off;
8833 /* VPOS >= active_glyphs->nrows means that window has been resized.
8834 Don't bother to erase the cursor. */
8835 if (vpos >= active_glyphs->nrows)
8836 goto mark_cursor_off;
8838 /* If row containing cursor is marked invalid, there is nothing we
8839 can do. */
8840 cursor_row = MATRIX_ROW (active_glyphs, vpos);
8841 if (!cursor_row->enabled_p)
8842 goto mark_cursor_off;
8844 /* This can happen when the new row is shorter than the old one.
8845 In this case, either x_draw_glyphs or clear_end_of_line
8846 should have cleared the cursor. Note that we wouldn't be
8847 able to erase the cursor in this case because we don't have a
8848 cursor glyph at hand. */
8849 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
8850 goto mark_cursor_off;
8852 /* If the cursor is in the mouse face area, redisplay that when
8853 we clear the cursor. */
8854 if (w == XWINDOW (dpyinfo->mouse_face_window)
8855 && (vpos > dpyinfo->mouse_face_beg_row
8856 || (vpos == dpyinfo->mouse_face_beg_row
8857 && hpos >= dpyinfo->mouse_face_beg_col))
8858 && (vpos < dpyinfo->mouse_face_end_row
8859 || (vpos == dpyinfo->mouse_face_end_row
8860 && hpos < dpyinfo->mouse_face_end_col))
8861 /* Don't redraw the cursor's spot in mouse face if it is at the
8862 end of a line (on a newline). The cursor appears there, but
8863 mouse highlighting does not. */
8864 && cursor_row->used[TEXT_AREA] > hpos)
8865 mouse_face_here_p = 1;
8867 /* Maybe clear the display under the cursor. */
8868 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
8870 int x;
8871 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w);
8872 HDC hdc;
8874 cursor_glyph = get_phys_cursor_glyph (w);
8875 if (cursor_glyph == NULL)
8876 goto mark_cursor_off;
8878 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
8880 hdc = get_frame_dc (f);
8881 w32_clear_area (f, hdc, x,
8882 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
8883 cursor_row->y)),
8884 cursor_glyph->pixel_width,
8885 cursor_row->visible_height);
8886 release_frame_dc (f, hdc);
8889 /* Erase the cursor by redrawing the character underneath it. */
8890 if (mouse_face_here_p)
8891 hl = DRAW_MOUSE_FACE;
8892 else if (cursor_row->inverse_p)
8893 hl = DRAW_INVERSE_VIDEO;
8894 else
8895 hl = DRAW_NORMAL_TEXT;
8896 x_draw_phys_cursor_glyph (w, cursor_row, hl);
8898 mark_cursor_off:
8899 w->phys_cursor_on_p = 0;
8900 w->phys_cursor_type = NO_CURSOR;
8904 /* Display or clear cursor of window W. If ON is zero, clear the
8905 cursor. If it is non-zero, display the cursor. If ON is nonzero,
8906 where to put the cursor is specified by HPOS, VPOS, X and Y. */
8908 void
8909 x_display_and_set_cursor (w, on, hpos, vpos, x, y)
8910 struct window *w;
8911 int on, hpos, vpos, x, y;
8913 struct frame *f = XFRAME (w->frame);
8914 int new_cursor_type;
8915 int new_cursor_width;
8916 struct glyph_matrix *current_glyphs;
8917 struct glyph_row *glyph_row;
8918 struct glyph *glyph;
8920 /* This is pointless on invisible frames, and dangerous on garbaged
8921 windows and frames; in the latter case, the frame or window may
8922 be in the midst of changing its size, and x and y may be off the
8923 window. */
8924 if (! FRAME_VISIBLE_P (f)
8925 || FRAME_GARBAGED_P (f)
8926 || vpos >= w->current_matrix->nrows
8927 || hpos >= w->current_matrix->matrix_w)
8928 return;
8930 /* If cursor is off and we want it off, return quickly. */
8931 if (!on && !w->phys_cursor_on_p)
8932 return;
8934 current_glyphs = w->current_matrix;
8935 glyph_row = MATRIX_ROW (current_glyphs, vpos);
8936 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
8938 /* If cursor row is not enabled, we don't really know where to
8939 display the cursor. */
8940 if (!glyph_row->enabled_p)
8942 w->phys_cursor_on_p = 0;
8943 return;
8946 xassert (interrupt_input_blocked);
8948 /* Set new_cursor_type to the cursor we want to be displayed. In a
8949 mini-buffer window, we want the cursor only to appear if we are
8950 reading input from this window. For the selected window, we want
8951 the cursor type given by the frame parameter. If explicitly
8952 marked off, draw no cursor. In all other cases, we want a hollow
8953 box cursor. */
8954 new_cursor_width = -1;
8955 if (cursor_in_echo_area
8956 && FRAME_HAS_MINIBUF_P (f)
8957 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
8959 if (w == XWINDOW (echo_area_window))
8960 new_cursor_type = FRAME_DESIRED_CURSOR (f);
8961 else
8962 new_cursor_type = HOLLOW_BOX_CURSOR;
8964 else
8966 if (w != XWINDOW (selected_window)
8967 || f != FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame)
8969 extern int cursor_in_non_selected_windows;
8971 if (MINI_WINDOW_P (w)
8972 || !cursor_in_non_selected_windows
8973 || NILP (XBUFFER (w->buffer)->cursor_type))
8974 new_cursor_type = NO_CURSOR;
8975 else
8976 new_cursor_type = HOLLOW_BOX_CURSOR;
8978 else if (w->cursor_off_p)
8979 new_cursor_type = NO_CURSOR;
8980 else
8982 struct buffer *b = XBUFFER (w->buffer);
8984 if (EQ (b->cursor_type, Qt))
8985 new_cursor_type = FRAME_DESIRED_CURSOR (f);
8986 else
8987 new_cursor_type = x_specified_cursor_type (b->cursor_type,
8988 &new_cursor_width);
8992 /* If cursor is currently being shown and we don't want it to be or
8993 it is in the wrong place, or the cursor type is not what we want,
8994 erase it. */
8995 if (w->phys_cursor_on_p
8996 && (!on
8997 || w->phys_cursor.x != x
8998 || w->phys_cursor.y != y
8999 || new_cursor_type != w->phys_cursor_type))
9000 x_erase_phys_cursor (w);
9002 /* If the cursor is now invisible and we want it to be visible,
9003 display it. */
9004 if (on && !w->phys_cursor_on_p)
9006 w->phys_cursor_ascent = glyph_row->ascent;
9007 w->phys_cursor_height = glyph_row->height;
9009 /* Set phys_cursor_.* before x_draw_.* is called because some
9010 of them may need the information. */
9011 w->phys_cursor.x = x;
9012 w->phys_cursor.y = glyph_row->y;
9013 w->phys_cursor.hpos = hpos;
9014 w->phys_cursor.vpos = vpos;
9015 w->phys_cursor_type = new_cursor_type;
9016 w->phys_cursor_on_p = 1;
9018 switch (new_cursor_type)
9020 case HOLLOW_BOX_CURSOR:
9021 x_draw_hollow_cursor (w, glyph_row);
9022 break;
9024 case FILLED_BOX_CURSOR:
9025 x_draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
9026 break;
9028 case BAR_CURSOR:
9029 x_draw_bar_cursor (w, glyph_row, new_cursor_width);
9030 break;
9032 case NO_CURSOR:
9033 break;
9035 default:
9036 abort ();
9042 /* Display the cursor on window W, or clear it. X and Y are window
9043 relative pixel coordinates. HPOS and VPOS are glyph matrix
9044 positions. If W is not the selected window, display a hollow
9045 cursor. ON non-zero means display the cursor at X, Y which
9046 correspond to HPOS, VPOS, otherwise it is cleared. */
9048 void
9049 x_display_cursor (w, on, hpos, vpos, x, y)
9050 struct window *w;
9051 int on, hpos, vpos, x, y;
9053 BLOCK_INPUT;
9054 x_display_and_set_cursor (w, on, hpos, vpos, x, y);
9055 UNBLOCK_INPUT;
9059 /* Display the cursor on window W, or clear it, according to ON_P.
9060 Don't change the cursor's position. */
9062 void
9063 x_update_cursor (f, on_p)
9064 struct frame *f;
9065 int on_p;
9067 x_update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
9071 /* Call x_update_window_cursor with parameter ON_P on all leaf windows
9072 in the window tree rooted at W. */
9074 static void
9075 x_update_cursor_in_window_tree (w, on_p)
9076 struct window *w;
9077 int on_p;
9079 while (w)
9081 if (!NILP (w->hchild))
9082 x_update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
9083 else if (!NILP (w->vchild))
9084 x_update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
9085 else
9086 x_update_window_cursor (w, on_p);
9088 w = NILP (w->next) ? 0 : XWINDOW (w->next);
9093 /* Switch the display of W's cursor on or off, according to the value
9094 of ON. */
9096 static void
9097 x_update_window_cursor (w, on)
9098 struct window *w;
9099 int on;
9101 /* Don't update cursor in windows whose frame is in the process
9102 of being deleted. */
9103 if (w->current_matrix)
9105 BLOCK_INPUT;
9106 x_display_and_set_cursor (w, on, w->phys_cursor.hpos,
9107 w->phys_cursor.vpos, w->phys_cursor.x,
9108 w->phys_cursor.y);
9109 UNBLOCK_INPUT;
9116 /* Icons. */
9119 x_bitmap_icon (f, icon)
9120 struct frame *f;
9121 Lisp_Object icon;
9123 int mask, bitmap_id;
9124 Window icon_window;
9125 HANDLE hicon;
9127 if (FRAME_W32_WINDOW (f) == 0)
9128 return 1;
9130 if (NILP (icon))
9131 hicon = LoadIcon (hinst, EMACS_CLASS);
9132 else if (STRINGP (icon))
9133 hicon = LoadImage (NULL, (LPCTSTR) XSTRING (icon)->data, IMAGE_ICON, 0, 0,
9134 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9135 else if (SYMBOLP (icon))
9137 LPCTSTR name;
9139 if (EQ (icon, intern ("application")))
9140 name = (LPCTSTR) IDI_APPLICATION;
9141 else if (EQ (icon, intern ("hand")))
9142 name = (LPCTSTR) IDI_HAND;
9143 else if (EQ (icon, intern ("question")))
9144 name = (LPCTSTR) IDI_QUESTION;
9145 else if (EQ (icon, intern ("exclamation")))
9146 name = (LPCTSTR) IDI_EXCLAMATION;
9147 else if (EQ (icon, intern ("asterisk")))
9148 name = (LPCTSTR) IDI_ASTERISK;
9149 else if (EQ (icon, intern ("winlogo")))
9150 name = (LPCTSTR) IDI_WINLOGO;
9151 else
9152 return 1;
9154 hicon = LoadIcon (NULL, name);
9156 else
9157 return 1;
9159 if (hicon == NULL)
9160 return 1;
9162 PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
9163 (LPARAM) hicon);
9165 return 0;
9169 /* Changing the font of the frame. */
9171 /* Give frame F the font named FONTNAME as its default font, and
9172 return the full name of that font. FONTNAME may be a wildcard
9173 pattern; in that case, we choose some font that fits the pattern.
9174 The return value shows which font we chose. */
9176 Lisp_Object
9177 x_new_font (f, fontname)
9178 struct frame *f;
9179 register char *fontname;
9181 struct font_info *fontp
9182 = FS_LOAD_FONT (f, 0, fontname, -1);
9184 if (!fontp)
9185 return Qnil;
9187 FRAME_FONT (f) = (XFontStruct *) (fontp->font);
9188 FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
9189 FRAME_FONTSET (f) = -1;
9191 /* Compute the scroll bar width in character columns. */
9192 if (f->scroll_bar_pixel_width > 0)
9194 int wid = FONT_WIDTH (FRAME_FONT (f));
9195 f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
9197 else
9199 int wid = FONT_WIDTH (FRAME_FONT (f));
9200 f->scroll_bar_cols = (14 + wid - 1) / wid;
9203 /* Now make the frame display the given font. */
9204 if (FRAME_W32_WINDOW (f) != 0)
9206 frame_update_line_height (f);
9207 x_set_window_size (f, 0, f->width, f->height);
9209 else
9210 /* If we are setting a new frame's font for the first time,
9211 there are no faces yet, so this font's height is the line height. */
9212 f->output_data.w32->line_height = FONT_HEIGHT (FRAME_FONT (f));
9214 return build_string (fontp->full_name);
9217 /* Give frame F the fontset named FONTSETNAME as its default font, and
9218 return the full name of that fontset. FONTSETNAME may be a wildcard
9219 pattern; in that case, we choose some fontset that fits the pattern.
9220 The return value shows which fontset we chose. */
9222 Lisp_Object
9223 x_new_fontset (f, fontsetname)
9224 struct frame *f;
9225 char *fontsetname;
9227 int fontset = fs_query_fontset (build_string (fontsetname), 0);
9228 Lisp_Object result;
9229 char *fontname;
9231 if (fontset < 0)
9232 return Qnil;
9234 if (FRAME_FONTSET (f) == fontset)
9235 /* This fontset is already set in frame F. There's nothing more
9236 to do. */
9237 return fontset_name (fontset);
9239 result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
9241 if (!STRINGP (result))
9242 /* Can't load ASCII font. */
9243 return Qnil;
9245 /* Since x_new_font doesn't update any fontset information, do it now. */
9246 FRAME_FONTSET(f) = fontset;
9248 return build_string (fontsetname);
9252 #if GLYPH_DEBUG
9254 /* Check that FONT is valid on frame F. It is if it can be found in F's
9255 font table. */
9257 static void
9258 x_check_font (f, font)
9259 struct frame *f;
9260 XFontStruct *font;
9262 int i;
9263 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9265 xassert (font != NULL);
9267 for (i = 0; i < dpyinfo->n_fonts; i++)
9268 if (dpyinfo->font_table[i].name
9269 && font == dpyinfo->font_table[i].font)
9270 break;
9272 xassert (i < dpyinfo->n_fonts);
9275 #endif /* GLYPH_DEBUG != 0 */
9277 /* Set *W to the minimum width, *H to the minimum font height of FONT.
9278 Note: There are (broken) X fonts out there with invalid XFontStruct
9279 min_bounds contents. For example, handa@etl.go.jp reports that
9280 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
9281 have font->min_bounds.width == 0. */
9283 static INLINE void
9284 x_font_min_bounds (font, w, h)
9285 XFontStruct *font;
9286 int *w, *h;
9289 * TODO: Windows does not appear to offer min bound, only
9290 * average and maximum width, and maximum height.
9292 *h = FONT_HEIGHT (font);
9293 *w = FONT_WIDTH (font);
9297 /* Compute the smallest character width and smallest font height over
9298 all fonts available on frame F. Set the members smallest_char_width
9299 and smallest_font_height in F's x_display_info structure to
9300 the values computed. Value is non-zero if smallest_font_height or
9301 smallest_char_width become smaller than they were before. */
9304 x_compute_min_glyph_bounds (f)
9305 struct frame *f;
9307 int i;
9308 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9309 XFontStruct *font;
9310 int old_width = dpyinfo->smallest_char_width;
9311 int old_height = dpyinfo->smallest_font_height;
9313 dpyinfo->smallest_font_height = 100000;
9314 dpyinfo->smallest_char_width = 100000;
9316 for (i = 0; i < dpyinfo->n_fonts; ++i)
9317 if (dpyinfo->font_table[i].name)
9319 struct font_info *fontp = dpyinfo->font_table + i;
9320 int w, h;
9322 font = (XFontStruct *) fontp->font;
9323 xassert (font != (XFontStruct *) ~0);
9324 x_font_min_bounds (font, &w, &h);
9326 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h);
9327 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w);
9330 xassert (dpyinfo->smallest_char_width > 0
9331 && dpyinfo->smallest_font_height > 0);
9333 return (dpyinfo->n_fonts == 1
9334 || dpyinfo->smallest_char_width < old_width
9335 || dpyinfo->smallest_font_height < old_height);
9339 /* Calculate the absolute position in frame F
9340 from its current recorded position values and gravity. */
9342 void
9343 x_calc_absolute_position (f)
9344 struct frame *f;
9346 Window child;
9347 POINT pt;
9348 int flags = f->output_data.w32->size_hint_flags;
9350 pt.x = pt.y = 0;
9352 /* Find the position of the outside upper-left corner of
9353 the inner window, with respect to the outer window. */
9354 if (f->output_data.w32->parent_desc != FRAME_W32_DISPLAY_INFO (f)->root_window)
9356 BLOCK_INPUT;
9357 MapWindowPoints (FRAME_W32_WINDOW (f),
9358 f->output_data.w32->parent_desc,
9359 &pt, 1);
9360 UNBLOCK_INPUT;
9364 RECT rt;
9365 rt.left = rt.right = rt.top = rt.bottom = 0;
9367 BLOCK_INPUT;
9368 AdjustWindowRect(&rt, f->output_data.w32->dwStyle,
9369 FRAME_EXTERNAL_MENU_BAR (f));
9370 UNBLOCK_INPUT;
9372 pt.x += (rt.right - rt.left);
9373 pt.y += (rt.bottom - rt.top);
9376 /* Treat negative positions as relative to the leftmost bottommost
9377 position that fits on the screen. */
9378 if (flags & XNegative)
9379 f->output_data.w32->left_pos = (FRAME_W32_DISPLAY_INFO (f)->width
9380 - 2 * f->output_data.w32->border_width - pt.x
9381 - PIXEL_WIDTH (f)
9382 + f->output_data.w32->left_pos);
9384 if (flags & YNegative)
9385 f->output_data.w32->top_pos = (FRAME_W32_DISPLAY_INFO (f)->height
9386 - 2 * f->output_data.w32->border_width - pt.y
9387 - PIXEL_HEIGHT (f)
9388 + f->output_data.w32->top_pos);
9389 /* The left_pos and top_pos
9390 are now relative to the top and left screen edges,
9391 so the flags should correspond. */
9392 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
9395 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
9396 to really change the position, and 0 when calling from
9397 x_make_frame_visible (in that case, XOFF and YOFF are the current
9398 position values). It is -1 when calling from x_set_frame_parameters,
9399 which means, do adjust for borders but don't change the gravity. */
9401 void
9402 x_set_offset (f, xoff, yoff, change_gravity)
9403 struct frame *f;
9404 register int xoff, yoff;
9405 int change_gravity;
9407 int modified_top, modified_left;
9409 if (change_gravity > 0)
9411 f->output_data.w32->top_pos = yoff;
9412 f->output_data.w32->left_pos = xoff;
9413 f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative);
9414 if (xoff < 0)
9415 f->output_data.w32->size_hint_flags |= XNegative;
9416 if (yoff < 0)
9417 f->output_data.w32->size_hint_flags |= YNegative;
9418 f->output_data.w32->win_gravity = NorthWestGravity;
9420 x_calc_absolute_position (f);
9422 BLOCK_INPUT;
9423 x_wm_set_size_hint (f, (long) 0, 0);
9425 modified_left = f->output_data.w32->left_pos;
9426 modified_top = f->output_data.w32->top_pos;
9428 my_set_window_pos (FRAME_W32_WINDOW (f),
9429 NULL,
9430 modified_left, modified_top,
9431 0, 0,
9432 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
9433 UNBLOCK_INPUT;
9436 /* Call this to change the size of frame F's x-window.
9437 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
9438 for this size change and subsequent size changes.
9439 Otherwise we leave the window gravity unchanged. */
9440 void
9441 x_set_window_size (f, change_gravity, cols, rows)
9442 struct frame *f;
9443 int change_gravity;
9444 int cols, rows;
9446 int pixelwidth, pixelheight;
9448 BLOCK_INPUT;
9450 check_frame_size (f, &rows, &cols);
9451 f->output_data.w32->vertical_scroll_bar_extra
9452 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
9454 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font)));
9455 f->output_data.w32->flags_areas_extra
9456 = FRAME_FLAGS_AREA_WIDTH (f);
9457 pixelwidth = CHAR_TO_PIXEL_WIDTH (f, cols);
9458 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
9460 f->output_data.w32->win_gravity = NorthWestGravity;
9461 x_wm_set_size_hint (f, (long) 0, 0);
9464 RECT rect;
9466 rect.left = rect.top = 0;
9467 rect.right = pixelwidth;
9468 rect.bottom = pixelheight;
9470 AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
9471 FRAME_EXTERNAL_MENU_BAR (f));
9473 my_set_window_pos (FRAME_W32_WINDOW (f),
9474 NULL,
9475 0, 0,
9476 rect.right - rect.left,
9477 rect.bottom - rect.top,
9478 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
9481 /* Now, strictly speaking, we can't be sure that this is accurate,
9482 but the window manager will get around to dealing with the size
9483 change request eventually, and we'll hear how it went when the
9484 ConfigureNotify event gets here.
9486 We could just not bother storing any of this information here,
9487 and let the ConfigureNotify event set everything up, but that
9488 might be kind of confusing to the Lisp code, since size changes
9489 wouldn't be reported in the frame parameters until some random
9490 point in the future when the ConfigureNotify event arrives.
9492 We pass 1 for DELAY since we can't run Lisp code inside of
9493 a BLOCK_INPUT. */
9494 change_frame_size (f, rows, cols, 0, 1, 0);
9495 PIXEL_WIDTH (f) = pixelwidth;
9496 PIXEL_HEIGHT (f) = pixelheight;
9498 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
9499 receive in the ConfigureNotify event; if we get what we asked
9500 for, then the event won't cause the screen to become garbaged, so
9501 we have to make sure to do it here. */
9502 SET_FRAME_GARBAGED (f);
9504 /* If cursor was outside the new size, mark it as off. */
9505 mark_window_cursors_off (XWINDOW (f->root_window));
9507 /* Clear out any recollection of where the mouse highlighting was,
9508 since it might be in a place that's outside the new frame size.
9509 Actually checking whether it is outside is a pain in the neck,
9510 so don't try--just let the highlighting be done afresh with new size. */
9511 cancel_mouse_face (f);
9513 UNBLOCK_INPUT;
9516 /* Mouse warping. */
9518 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
9520 void
9521 x_set_mouse_position (f, x, y)
9522 struct frame *f;
9523 int x, y;
9525 int pix_x, pix_y;
9527 pix_x = CHAR_TO_PIXEL_COL (f, x) + FONT_WIDTH (f->output_data.w32->font) / 2;
9528 pix_y = CHAR_TO_PIXEL_ROW (f, y) + f->output_data.w32->line_height / 2;
9530 if (pix_x < 0) pix_x = 0;
9531 if (pix_x > PIXEL_WIDTH (f)) pix_x = PIXEL_WIDTH (f);
9533 if (pix_y < 0) pix_y = 0;
9534 if (pix_y > PIXEL_HEIGHT (f)) pix_y = PIXEL_HEIGHT (f);
9536 x_set_mouse_pixel_position (f, pix_x, pix_y);
9539 void
9540 x_set_mouse_pixel_position (f, pix_x, pix_y)
9541 struct frame *f;
9542 int pix_x, pix_y;
9544 RECT rect;
9545 POINT pt;
9547 BLOCK_INPUT;
9549 GetClientRect (FRAME_W32_WINDOW (f), &rect);
9550 pt.x = rect.left + pix_x;
9551 pt.y = rect.top + pix_y;
9552 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
9554 SetCursorPos (pt.x, pt.y);
9556 UNBLOCK_INPUT;
9560 /* focus shifting, raising and lowering. */
9562 void
9563 x_focus_on_frame (f)
9564 struct frame *f;
9566 struct w32_display_info *dpyinfo = &one_w32_display_info;
9568 /* Give input focus to frame. */
9569 BLOCK_INPUT;
9570 #if 0
9571 /* Try not to change its Z-order if possible. */
9572 if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
9573 my_set_focus (f, FRAME_W32_WINDOW (f));
9574 else
9575 #endif
9576 my_set_foreground_window (FRAME_W32_WINDOW (f));
9577 UNBLOCK_INPUT;
9580 void
9581 x_unfocus_frame (f)
9582 struct frame *f;
9586 /* Raise frame F. */
9587 void
9588 x_raise_frame (f)
9589 struct frame *f;
9591 BLOCK_INPUT;
9593 /* Strictly speaking, raise-frame should only change the frame's Z
9594 order, leaving input focus unchanged. This is reasonable behaviour
9595 on X where the usual policy is point-to-focus. However, this
9596 behaviour would be very odd on Windows where the usual policy is
9597 click-to-focus.
9599 On X, if the mouse happens to be over the raised frame, it gets
9600 input focus anyway (so the window with focus will never be
9601 completely obscured) - if not, then just moving the mouse over it
9602 is sufficient to give it focus. On Windows, the user must actually
9603 click on the frame (preferrably the title bar so as not to move
9604 point), which is more awkward. Also, no other Windows program
9605 raises a window to the top but leaves another window (possibly now
9606 completely obscured) with input focus.
9608 Because there is a system setting on Windows that allows the user
9609 to choose the point to focus policy, we make the strict semantics
9610 optional, but by default we grab focus when raising. */
9612 if (NILP (Vw32_grab_focus_on_raise))
9614 /* The obvious call to my_set_window_pos doesn't work if Emacs is
9615 not already the foreground application: the frame is raised
9616 above all other frames belonging to us, but not above the
9617 current top window. To achieve that, we have to resort to this
9618 more cumbersome method. */
9620 HDWP handle = BeginDeferWindowPos (2);
9621 if (handle)
9623 DeferWindowPos (handle,
9624 FRAME_W32_WINDOW (f),
9625 HWND_TOP,
9626 0, 0, 0, 0,
9627 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9629 DeferWindowPos (handle,
9630 GetForegroundWindow (),
9631 FRAME_W32_WINDOW (f),
9632 0, 0, 0, 0,
9633 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9635 EndDeferWindowPos (handle);
9638 else
9640 my_set_foreground_window (FRAME_W32_WINDOW (f));
9643 UNBLOCK_INPUT;
9646 /* Lower frame F. */
9647 void
9648 x_lower_frame (f)
9649 struct frame *f;
9651 BLOCK_INPUT;
9652 my_set_window_pos (FRAME_W32_WINDOW (f),
9653 HWND_BOTTOM,
9654 0, 0, 0, 0,
9655 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
9656 UNBLOCK_INPUT;
9659 static void
9660 w32_frame_raise_lower (f, raise_flag)
9661 FRAME_PTR f;
9662 int raise_flag;
9664 if (raise_flag)
9665 x_raise_frame (f);
9666 else
9667 x_lower_frame (f);
9670 /* Change of visibility. */
9672 /* This tries to wait until the frame is really visible.
9673 However, if the window manager asks the user where to position
9674 the frame, this will return before the user finishes doing that.
9675 The frame will not actually be visible at that time,
9676 but it will become visible later when the window manager
9677 finishes with it. */
9679 void
9680 x_make_frame_visible (f)
9681 struct frame *f;
9683 Lisp_Object type;
9685 BLOCK_INPUT;
9687 type = x_icon_type (f);
9688 if (!NILP (type))
9689 x_bitmap_icon (f, type);
9691 if (! FRAME_VISIBLE_P (f))
9693 /* We test FRAME_GARBAGED_P here to make sure we don't
9694 call x_set_offset a second time
9695 if we get to x_make_frame_visible a second time
9696 before the window gets really visible. */
9697 if (! FRAME_ICONIFIED_P (f)
9698 && ! f->output_data.w32->asked_for_visible)
9699 x_set_offset (f, f->output_data.w32->left_pos, f->output_data.w32->top_pos, 0);
9701 f->output_data.w32->asked_for_visible = 1;
9703 // my_show_window (f, FRAME_W32_WINDOW (f), f->async_iconified ? SW_RESTORE : SW_SHOW);
9704 my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);
9707 /* Synchronize to ensure Emacs knows the frame is visible
9708 before we do anything else. We do this loop with input not blocked
9709 so that incoming events are handled. */
9711 Lisp_Object frame;
9712 int count;
9714 /* This must come after we set COUNT. */
9715 UNBLOCK_INPUT;
9717 XSETFRAME (frame, f);
9719 /* Wait until the frame is visible. Process X events until a
9720 MapNotify event has been seen, or until we think we won't get a
9721 MapNotify at all.. */
9722 for (count = input_signal_count + 10;
9723 input_signal_count < count && !FRAME_VISIBLE_P (f);)
9725 /* Force processing of queued events. */
9726 /* TODO: x_sync equivalent? */
9728 /* Machines that do polling rather than SIGIO have been observed
9729 to go into a busy-wait here. So we'll fake an alarm signal
9730 to let the handler know that there's something to be read.
9731 We used to raise a real alarm, but it seems that the handler
9732 isn't always enabled here. This is probably a bug. */
9733 if (input_polling_used ())
9735 /* It could be confusing if a real alarm arrives while processing
9736 the fake one. Turn it off and let the handler reset it. */
9737 int old_poll_suppress_count = poll_suppress_count;
9738 poll_suppress_count = 1;
9739 poll_for_input_1 ();
9740 poll_suppress_count = old_poll_suppress_count;
9743 FRAME_SAMPLE_VISIBILITY (f);
9747 /* Change from mapped state to withdrawn state. */
9749 /* Make the frame visible (mapped and not iconified). */
9751 x_make_frame_invisible (f)
9752 struct frame *f;
9754 /* Don't keep the highlight on an invisible frame. */
9755 if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
9756 FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
9758 BLOCK_INPUT;
9760 my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
9762 /* We can't distinguish this from iconification
9763 just by the event that we get from the server.
9764 So we can't win using the usual strategy of letting
9765 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
9766 and synchronize with the server to make sure we agree. */
9767 f->visible = 0;
9768 FRAME_ICONIFIED_P (f) = 0;
9769 f->async_visible = 0;
9770 f->async_iconified = 0;
9772 UNBLOCK_INPUT;
9775 /* Change window state from mapped to iconified. */
9777 void
9778 x_iconify_frame (f)
9779 struct frame *f;
9781 int result;
9782 Lisp_Object type;
9784 /* Don't keep the highlight on an invisible frame. */
9785 if (FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame == f)
9786 FRAME_W32_DISPLAY_INFO (f)->w32_highlight_frame = 0;
9788 if (f->async_iconified)
9789 return;
9791 BLOCK_INPUT;
9793 type = x_icon_type (f);
9794 if (!NILP (type))
9795 x_bitmap_icon (f, type);
9797 /* Simulate the user minimizing the frame. */
9798 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
9800 UNBLOCK_INPUT;
9803 /* Destroy the window of frame F. */
9805 x_destroy_window (f)
9806 struct frame *f;
9808 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
9810 BLOCK_INPUT;
9812 my_destroy_window (f, FRAME_W32_WINDOW (f));
9813 free_frame_menubar (f);
9814 free_frame_faces (f);
9816 xfree (f->output_data.w32);
9817 f->output_data.w32 = 0;
9818 if (f == dpyinfo->w32_focus_frame)
9819 dpyinfo->w32_focus_frame = 0;
9820 if (f == dpyinfo->w32_focus_event_frame)
9821 dpyinfo->w32_focus_event_frame = 0;
9822 if (f == dpyinfo->w32_highlight_frame)
9823 dpyinfo->w32_highlight_frame = 0;
9825 dpyinfo->reference_count--;
9827 if (f == dpyinfo->mouse_face_mouse_frame)
9829 dpyinfo->mouse_face_beg_row
9830 = dpyinfo->mouse_face_beg_col = -1;
9831 dpyinfo->mouse_face_end_row
9832 = dpyinfo->mouse_face_end_col = -1;
9833 dpyinfo->mouse_face_window = Qnil;
9836 UNBLOCK_INPUT;
9839 /* Setting window manager hints. */
9841 /* Set the normal size hints for the window manager, for frame F.
9842 FLAGS is the flags word to use--or 0 meaning preserve the flags
9843 that the window now has.
9844 If USER_POSITION is nonzero, we set the USPosition
9845 flag (this is useful when FLAGS is 0). */
9846 void
9847 x_wm_set_size_hint (f, flags, user_position)
9848 struct frame *f;
9849 long flags;
9850 int user_position;
9852 Window window = FRAME_W32_WINDOW (f);
9854 enter_crit ();
9856 SetWindowLong (window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
9857 SetWindowLong (window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
9858 SetWindowLong (window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
9859 SetWindowLong (window, WND_SCROLLBAR_INDEX, f->output_data.w32->vertical_scroll_bar_extra);
9861 leave_crit ();
9864 /* Window manager things */
9865 x_wm_set_icon_position (f, icon_x, icon_y)
9866 struct frame *f;
9867 int icon_x, icon_y;
9869 #if 0
9870 Window window = FRAME_W32_WINDOW (f);
9872 f->display.x->wm_hints.flags |= IconPositionHint;
9873 f->display.x->wm_hints.icon_x = icon_x;
9874 f->display.x->wm_hints.icon_y = icon_y;
9876 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
9877 #endif
9882 /***********************************************************************
9883 Initialization
9884 ***********************************************************************/
9886 static int w32_initialized = 0;
9888 void
9889 w32_initialize_display_info (display_name)
9890 Lisp_Object display_name;
9892 struct w32_display_info *dpyinfo = &one_w32_display_info;
9894 bzero (dpyinfo, sizeof (*dpyinfo));
9896 /* Put it on w32_display_name_list. */
9897 w32_display_name_list = Fcons (Fcons (display_name, Qnil),
9898 w32_display_name_list);
9899 dpyinfo->name_list_element = XCAR (w32_display_name_list);
9901 dpyinfo->w32_id_name
9902 = (char *) xmalloc (XSTRING (Vinvocation_name)->size
9903 + XSTRING (Vsystem_name)->size
9904 + 2);
9905 sprintf (dpyinfo->w32_id_name, "%s@%s",
9906 XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
9908 /* Default Console mode values - overridden when running in GUI mode
9909 with values obtained from system metrics. */
9910 dpyinfo->resx = 1;
9911 dpyinfo->resy = 1;
9912 dpyinfo->height_in = 1;
9913 dpyinfo->width_in = 1;
9914 dpyinfo->n_planes = 1;
9915 dpyinfo->n_cbits = 4;
9916 dpyinfo->n_fonts = 0;
9917 dpyinfo->smallest_font_height = 1;
9918 dpyinfo->smallest_char_width = 1;
9920 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
9921 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
9922 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
9923 dpyinfo->mouse_face_window = Qnil;
9925 /* TODO: dpyinfo->gray */
9929 struct w32_display_info *
9930 w32_term_init (display_name, xrm_option, resource_name)
9931 Lisp_Object display_name;
9932 char *xrm_option;
9933 char *resource_name;
9935 struct w32_display_info *dpyinfo;
9936 HDC hdc;
9938 BLOCK_INPUT;
9940 if (!w32_initialized)
9942 w32_initialize ();
9943 w32_initialized = 1;
9947 int argc = 0;
9948 char *argv[3];
9950 argv[0] = "";
9951 argc = 1;
9952 if (xrm_option)
9954 argv[argc++] = "-xrm";
9955 argv[argc++] = xrm_option;
9959 w32_initialize_display_info (display_name);
9961 dpyinfo = &one_w32_display_info;
9963 hdc = GetDC (GetDesktopWindow ());
9965 dpyinfo->height = GetDeviceCaps (hdc, VERTRES);
9966 dpyinfo->width = GetDeviceCaps (hdc, HORZRES);
9967 dpyinfo->root_window = GetDesktopWindow ();
9968 dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
9969 dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
9970 dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
9971 dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
9972 dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
9973 dpyinfo->image_cache = make_image_cache ();
9974 dpyinfo->height_in = dpyinfo->height / dpyinfo->resx;
9975 dpyinfo->width_in = dpyinfo->width / dpyinfo->resy;
9976 ReleaseDC (GetDesktopWindow (), hdc);
9978 /* initialise palette with white and black */
9980 COLORREF color;
9981 w32_defined_color (0, "white", &color, 1);
9982 w32_defined_color (0, "black", &color, 1);
9985 /* Create Row Bitmaps and store them for later use. */
9986 left_bmp = CreateBitmap (left_width, left_height, 1, 1, left_bits);
9987 ov_bmp = CreateBitmap (ov_width, ov_height, 1, 1, ov_bits);
9988 right_bmp = CreateBitmap (right_width, right_height, 1, 1, right_bits);
9989 continued_bmp = CreateBitmap (continued_width, continued_height, 1,
9990 1, continued_bits);
9991 continuation_bmp = CreateBitmap (continuation_width, continuation_height,
9992 1, 1, continuation_bits);
9993 zv_bmp = CreateBitmap (zv_width, zv_height, 1, 1, zv_bits);
9995 #ifndef F_SETOWN_BUG
9996 #ifdef F_SETOWN
9997 #ifdef F_SETOWN_SOCK_NEG
9998 /* stdin is a socket here */
9999 fcntl (connection, F_SETOWN, -getpid ());
10000 #else /* ! defined (F_SETOWN_SOCK_NEG) */
10001 fcntl (connection, F_SETOWN, getpid ());
10002 #endif /* ! defined (F_SETOWN_SOCK_NEG) */
10003 #endif /* ! defined (F_SETOWN) */
10004 #endif /* F_SETOWN_BUG */
10006 #ifdef SIGIO
10007 if (interrupt_input)
10008 init_sigio (connection);
10009 #endif /* ! defined (SIGIO) */
10011 UNBLOCK_INPUT;
10013 return dpyinfo;
10016 /* Get rid of display DPYINFO, assuming all frames are already gone. */
10018 void
10019 x_delete_display (dpyinfo)
10020 struct w32_display_info *dpyinfo;
10022 /* Discard this display from w32_display_name_list and w32_display_list.
10023 We can't use Fdelq because that can quit. */
10024 if (! NILP (w32_display_name_list)
10025 && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
10026 w32_display_name_list = XCDR (w32_display_name_list);
10027 else
10029 Lisp_Object tail;
10031 tail = w32_display_name_list;
10032 while (CONSP (tail) && CONSP (XCDR (tail)))
10034 if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
10036 XCDR (tail) = XCDR (XCDR (tail));
10037 break;
10039 tail = XCDR (tail);
10043 /* free palette table */
10045 struct w32_palette_entry * plist;
10047 plist = dpyinfo->color_list;
10048 while (plist)
10050 struct w32_palette_entry * pentry = plist;
10051 plist = plist->next;
10052 xfree (pentry);
10054 dpyinfo->color_list = NULL;
10055 if (dpyinfo->palette)
10056 DeleteObject(dpyinfo->palette);
10058 xfree (dpyinfo->font_table);
10059 xfree (dpyinfo->w32_id_name);
10061 /* Destroy row bitmaps. */
10062 DeleteObject (left_bmp);
10063 DeleteObject (ov_bmp);
10064 DeleteObject (right_bmp);
10065 DeleteObject (continued_bmp);
10066 DeleteObject (continuation_bmp);
10067 DeleteObject (zv_bmp);
10070 /* Set up use of W32. */
10072 DWORD w32_msg_worker ();
10074 void
10075 x_flush (struct frame * f)
10076 { /* Nothing to do */ }
10078 static struct redisplay_interface w32_redisplay_interface =
10080 x_produce_glyphs,
10081 x_write_glyphs,
10082 x_insert_glyphs,
10083 x_clear_end_of_line,
10084 x_scroll_run,
10085 x_after_update_window_line,
10086 x_update_window_begin,
10087 x_update_window_end,
10088 w32_cursor_to,
10089 x_flush,
10090 x_clear_mouse_face,
10091 x_get_glyph_overhangs,
10092 x_fix_overlapping_area
10095 void
10096 w32_initialize ()
10098 rif = &w32_redisplay_interface;
10100 /* MSVC does not type K&R functions with no arguments correctly, and
10101 so we must explicitly cast them. */
10102 clear_frame_hook = (void (*)(void)) x_clear_frame;
10103 ins_del_lines_hook = x_ins_del_lines;
10104 change_line_highlight_hook = x_change_line_highlight;
10105 delete_glyphs_hook = x_delete_glyphs;
10106 ring_bell_hook = (void (*)(void)) w32_ring_bell;
10107 reset_terminal_modes_hook = (void (*)(void)) w32_reset_terminal_modes;
10108 set_terminal_modes_hook = (void (*)(void)) w32_set_terminal_modes;
10109 update_begin_hook = x_update_begin;
10110 update_end_hook = x_update_end;
10111 set_terminal_window_hook = w32_set_terminal_window;
10112 read_socket_hook = w32_read_socket;
10113 frame_up_to_date_hook = w32_frame_up_to_date;
10114 reassert_line_highlight_hook = w32_reassert_line_highlight;
10115 mouse_position_hook = w32_mouse_position;
10116 frame_rehighlight_hook = w32_frame_rehighlight;
10117 frame_raise_lower_hook = w32_frame_raise_lower;
10118 set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
10119 condemn_scroll_bars_hook = w32_condemn_scroll_bars;
10120 redeem_scroll_bar_hook = w32_redeem_scroll_bar;
10121 judge_scroll_bars_hook = w32_judge_scroll_bars;
10122 estimate_mode_line_height_hook = x_estimate_mode_line_height;
10124 scroll_region_ok = 1; /* we'll scroll partial frames */
10125 char_ins_del_ok = 0; /* just as fast to write the line */
10126 line_ins_del_ok = 1; /* we'll just blt 'em */
10127 fast_clear_end_of_line = 1; /* X does this well */
10128 memory_below_frame = 0; /* we don't remember what scrolls
10129 off the bottom */
10130 baud_rate = 19200;
10132 last_tool_bar_item = -1;
10133 any_help_event_p = 0;
10135 /* Initialize input mode: interrupt_input off, no flow control, allow
10136 8 bit character input, standard quit char. */
10137 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
10139 /* Create the window thread - it will terminate itself or when the app terminates */
10141 init_crit ();
10143 dwMainThreadId = GetCurrentThreadId ();
10144 DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
10145 GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
10147 /* Wait for thread to start */
10150 MSG msg;
10152 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
10154 hWindowsThread = CreateThread (NULL, 0,
10155 (LPTHREAD_START_ROUTINE) w32_msg_worker,
10156 0, 0, &dwWindowsThreadId);
10158 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
10161 /* It is desirable that mainThread should have the same notion of
10162 focus window and active window as windowsThread. Unfortunately, the
10163 following call to AttachThreadInput, which should do precisely what
10164 we need, causes major problems when Emacs is linked as a console
10165 program. Unfortunately, we have good reasons for doing that, so
10166 instead we need to send messages to windowsThread to make some API
10167 calls for us (ones that affect, or depend on, the active/focus
10168 window state. */
10169 #ifdef ATTACH_THREADS
10170 AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
10171 #endif
10173 /* Dynamically link to optional system components. */
10175 HANDLE user_lib = LoadLibrary ("user32.dll");
10177 #define LOAD_PROC(fn) pfn##fn = (void *) GetProcAddress (user_lib, #fn)
10179 /* New proportional scroll bar functions. */
10180 LOAD_PROC (SetScrollInfo);
10181 LOAD_PROC (GetScrollInfo);
10183 #undef LOAD_PROC
10185 FreeLibrary (user_lib);
10187 /* If using proportional scroll bars, ensure handle is at least 5 pixels;
10188 otherwise use the fixed height. */
10189 vertical_scroll_bar_min_handle = (pfnSetScrollInfo != NULL) ? 5 :
10190 GetSystemMetrics (SM_CYVTHUMB);
10192 /* For either kind of scroll bar, take account of the arrows; these
10193 effectively form the border of the main scroll bar range. */
10194 vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
10195 = GetSystemMetrics (SM_CYVSCROLL);
10199 void
10200 syms_of_w32term ()
10202 Lisp_Object codepage;
10204 staticpro (&w32_display_name_list);
10205 w32_display_name_list = Qnil;
10207 staticpro (&last_mouse_scroll_bar);
10208 last_mouse_scroll_bar = Qnil;
10210 staticpro (&Qvendor_specific_keysyms);
10211 Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
10213 DEFVAR_INT ("w32-num-mouse-buttons",
10214 &Vw32_num_mouse_buttons,
10215 "Number of physical mouse buttons.");
10216 Vw32_num_mouse_buttons = Qnil;
10218 DEFVAR_LISP ("w32-swap-mouse-buttons",
10219 &Vw32_swap_mouse_buttons,
10220 "Swap the mapping of middle and right mouse buttons.\n\
10221 When nil, middle button is mouse-2 and right button is mouse-3.");
10222 Vw32_swap_mouse_buttons = Qnil;
10224 DEFVAR_LISP ("w32-grab-focus-on-raise",
10225 &Vw32_grab_focus_on_raise,
10226 "Raised frame grabs input focus.\n\
10227 When t, `raise-frame' grabs input focus as well. This fits well\n\
10228 with the normal Windows click-to-focus policy, but might not be\n\
10229 desirable when using a point-to-focus policy.");
10230 Vw32_grab_focus_on_raise = Qt;
10232 DEFVAR_LISP ("w32-capslock-is-shiftlock",
10233 &Vw32_capslock_is_shiftlock,
10234 "Apply CapsLock state to non character input keys.\n\
10235 When nil, CapsLock only affects normal character input keys.");
10236 Vw32_capslock_is_shiftlock = Qnil;
10238 DEFVAR_LISP ("w32-recognize-altgr",
10239 &Vw32_recognize_altgr,
10240 "Recognize right-alt and left-ctrl as AltGr.\n\
10241 When nil, the right-alt and left-ctrl key combination is\n\
10242 interpreted normally.");
10243 Vw32_recognize_altgr = Qt;
10245 DEFVAR_BOOL ("w32-enable-unicode-output",
10246 &w32_enable_unicode_output,
10247 "Enable the use of Unicode for text output if non-nil.\n\
10248 Unicode output may prevent some third party applications for displaying\n\
10249 Far-East Languages on Windows 95/98 from working properly.\n\
10250 NT uses Unicode internally anyway, so this flag will probably have no\n\
10251 affect on NT machines.");
10252 w32_enable_unicode_output = 1;
10254 help_echo = Qnil;
10255 staticpro (&help_echo);
10256 help_echo_object = Qnil;
10257 staticpro (&help_echo_object);
10258 help_echo_window = Qnil;
10259 staticpro (&help_echo_window);
10260 previous_help_echo = Qnil;
10261 staticpro (&previous_help_echo);
10262 help_echo_pos = -1;
10264 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
10265 "*Non-nil means draw block cursor as wide as the glyph under it.\n\
10266 For example, if a block cursor is over a tab, it will be drawn as\n\
10267 wide as that tab on the display.");
10268 x_stretch_cursor_p = 0;
10270 DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p,
10271 "If not nil, Emacs uses toolkit scroll bars.");
10272 x_toolkit_scroll_bars_p = 1;
10274 staticpro (&last_mouse_motion_frame);
10275 last_mouse_motion_frame = Qnil;