1 /* Implementation of GUI terminal on the Microsoft W32 API.
   2    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998,
   3                  1999, 2000, 2001, 2002, 2003, 2004, 2005,
   4                  2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
   5 
   6 This file is part of GNU Emacs.
   7 
   8 GNU Emacs is free software: you can redistribute it and/or modify
   9 it under the terms of the GNU General Public License as published by
  10 the Free Software Foundation, either version 3 of the License, or
  11 (at your option) any later version.
  12 
  13 GNU Emacs is distributed in the hope that it will be useful,
  14 but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 GNU General Public License for more details.
  17 
  18 You should have received a copy of the GNU General Public License
  19 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
  20 
  21 #include <config.h>
  22 #include <signal.h>
  23 #include <stdio.h>
  24 #include <stdlib.h>
  25 #include <setjmp.h>
  26 #include "lisp.h"
  27 #include "blockinput.h"
  28 #include "w32term.h"
  29 
  30 #include "systty.h"
  31 #include "systime.h"
  32 
  33 #include <ctype.h>
  34 #include <errno.h>
  35 #include <sys/stat.h>
  36 #include <imm.h>
  37 
  38 #include "charset.h"
  39 #include "character.h"
  40 #include "coding.h"
  41 #include "ccl.h"
  42 #include "frame.h"
  43 #include "dispextern.h"
  44 #include "fontset.h"
  45 #include "termhooks.h"
  46 #include "termopts.h"
  47 #include "termchar.h"
  48 #include "disptab.h"
  49 #include "buffer.h"
  50 #include "window.h"
  51 #include "keyboard.h"
  52 #include "intervals.h"
  53 #include "process.h"
  54 #include "atimer.h"
  55 #include "keymap.h"
  56 
  57 #include "w32heap.h"
  58 #include <shellapi.h>
  59 
  60 #include "font.h"
  61 #include "w32font.h"
  62 
  63 /* Fringe bitmaps.  */
  64 
  65 static int max_fringe_bmp = 0;
  66 static HBITMAP *fringe_bmp = 0;
  67 
  68 /* Non-nil means Emacs uses toolkit scroll bars.  */
  69 
  70 Lisp_Object Vx_toolkit_scroll_bars;
  71 
  72 /* Temporary variables for w32_read_socket.  */
  73 
  74 static int last_mousemove_x = 0;
  75 static int last_mousemove_y = 0;
  76 
  77 /* Define GET_WHEEL_DELTA_WPARAM macro if system headers don't.  */
  78 #ifndef GET_WHEEL_DELTA_WPARAM
  79 #define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD (wparam))
  80 #endif
  81 
  82 /* Non-zero means that a HELP_EVENT has been generated since Emacs
  83    start.  */
  84 
  85 static int any_help_event_p;
  86 
  87 /* Last window where we saw the mouse.  Used by mouse-autoselect-window.  */
  88 static Lisp_Object last_window;
  89 
  90 /* Non-zero means make use of UNDERLINE_POSITION font properties.  */
  91 int x_use_underline_position_properties;
  92 
  93 /* Non-zero means to draw the underline at the same place as the descent line.  */
  94 
  95 int x_underline_at_descent_line;
  96 
  97 extern unsigned int msh_mousewheel;
  98 
  99 extern void free_frame_menubar ();
 100 
 101 extern int w32_codepage_for_font (char *fontname);
 102 extern Cursor w32_load_cursor (LPCTSTR name);
 103 
 104 extern Lisp_Object Vwindow_system;
 105 
 106 #define x_any_window_to_frame x_window_to_frame
 107 #define x_top_window_to_frame x_window_to_frame
 108 
 109 
 110 /* This is display since w32 does not support multiple ones.  */
 111 struct w32_display_info one_w32_display_info;
 112 struct w32_display_info *x_display_list;
 113 
 114 /* This is a list of cons cells, each of the form (NAME . FONT-LIST-CACHE),
 115    one for each element of w32_display_list and in the same order.
 116    NAME is the name of the frame.
 117    FONT-LIST-CACHE records previous values returned by x-list-fonts.  */
 118 Lisp_Object w32_display_name_list;
 119 
 120 
 121 #ifndef GLYPHSET
 122 /* Pre Windows 2000, this was not available, but define it here so
 123    that Emacs compiled on such a platform will run on newer versions.  */
 124 
 125 typedef struct tagWCRANGE
 126 {
 127   WCHAR wcLow;
 128   USHORT cGlyphs;
 129 } WCRANGE;
 130 
 131 typedef struct tagGLYPHSET
 132 {
 133   DWORD cbThis;
 134   DWORD flAccel;
 135   DWORD cGlyphsSupported;
 136   DWORD cRanges;
 137   WCRANGE ranges[1];
 138 } GLYPHSET;
 139 
 140 #endif
 141 
 142 /* Dynamic linking to SetLayeredWindowAttribute (only since 2000).  */
 143 BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
 144 
 145 #ifndef LWA_ALPHA
 146 #define LWA_ALPHA 0x02
 147 #endif
 148 /* WS_EX_LAYERED is defined unconditionally by MingW, but only for W2K and
 149    later targets by MSVC headers.  */
 150 #ifndef WS_EX_LAYERED
 151 #define WS_EX_LAYERED 0x80000
 152 #endif
 153 
 154 /* Frame being updated by update_frame.  This is declared in term.c.
 155    This is set by update_begin and looked at by all the
 156    w32 functions.  It is zero while not inside an update.
 157    In that case, the w32 functions assume that `SELECTED_FRAME ()'
 158    is the frame to apply to.  */
 159 extern struct frame *updating_frame;
 160 
 161 /* This is a frame waiting to be autoraised, within w32_read_socket.  */
 162 struct frame *pending_autoraise_frame;
 163 
 164 /* The handle of the frame that currently owns the system caret.  */
 165 HWND w32_system_caret_hwnd;
 166 int w32_system_caret_height;
 167 int w32_system_caret_x;
 168 int w32_system_caret_y;
 169 int w32_use_visible_system_caret;
 170 
 171 DWORD dwWindowsThreadId = 0;
 172 HANDLE hWindowsThread = NULL;
 173 DWORD dwMainThreadId = 0;
 174 HANDLE hMainThread = NULL;
 175 
 176 int vertical_scroll_bar_min_handle;
 177 int vertical_scroll_bar_top_border;
 178 int vertical_scroll_bar_bottom_border;
 179 
 180 int last_scroll_bar_drag_pos;
 181 
 182 /* Mouse movement. */
 183 
 184 /* Where the mouse was last time we reported a mouse event.  */
 185 static RECT last_mouse_glyph;
 186 static FRAME_PTR last_mouse_glyph_frame;
 187 static Lisp_Object last_mouse_press_frame;
 188 
 189 int w32_num_mouse_buttons;
 190 
 191 Lisp_Object Vw32_swap_mouse_buttons;
 192 
 193 /* Control whether x_raise_frame also sets input focus.  */
 194 Lisp_Object Vw32_grab_focus_on_raise;
 195 
 196 /* Control whether Caps Lock affects non-ascii characters.  */
 197 Lisp_Object Vw32_capslock_is_shiftlock;
 198 
 199 /* Control whether right-alt and left-ctrl should be recognized as AltGr.  */
 200 Lisp_Object Vw32_recognize_altgr;
 201 
 202 /* The scroll bar in which the last motion event occurred.
 203 
 204    If the last motion event occurred in a scroll bar, we set this
 205    so w32_mouse_position can know whether to report a scroll bar motion or
 206    an ordinary motion.
 207 
 208    If the last motion event didn't occur in a scroll bar, we set this
 209    to Qnil, to tell w32_mouse_position to return an ordinary motion event.  */
 210 static Lisp_Object last_mouse_scroll_bar;
 211 static int last_mouse_scroll_bar_pos;
 212 
 213 /* This is a hack.  We would really prefer that w32_mouse_position would
 214    return the time associated with the position it returns, but there
 215    doesn't seem to be any way to wrest the time-stamp from the server
 216    along with the position query.  So, we just keep track of the time
 217    of the last movement we received, and return that in hopes that
 218    it's somewhat accurate.  */
 219 static Time last_mouse_movement_time;
 220 
 221 /* Incremented by w32_read_socket whenever it really tries to read
 222    events.  */
 223 #ifdef __STDC__
 224 static int volatile input_signal_count;
 225 #else
 226 static int input_signal_count;
 227 #endif
 228 
 229 extern Lisp_Object Vcommand_line_args, Vsystem_name;
 230 
 231 /* A mask of extra modifier bits to put into every keyboard char.  */
 232 extern EMACS_INT extra_keyboard_modifiers;
 233 
 234 /* Keyboard code page - may be changed by language-change events.  */
 235 static int keyboard_codepage;
 236 
 237 static void x_update_window_end P_ ((struct window *, int, int));
 238 static void w32_handle_tool_bar_click P_ ((struct frame *,
 239                                           struct input_event *));
 240 static void w32_define_cursor P_ ((Window, Cursor));
 241 
 242 void x_lower_frame P_ ((struct frame *));
 243 void x_scroll_bar_clear P_ ((struct frame *));
 244 void x_wm_set_size_hint P_ ((struct frame *, long, int));
 245 void x_raise_frame P_ ((struct frame *));
 246 void x_set_window_size P_ ((struct frame *, int, int, int));
 247 void x_wm_set_window_state P_ ((struct frame *, int));
 248 void x_wm_set_icon_pixmap P_ ((struct frame *, int));
 249 static void w32_initialize P_ ((void));
 250 static void x_update_end P_ ((struct frame *));
 251 static void w32_frame_up_to_date P_ ((struct frame *));
 252 static void w32_set_terminal_modes P_ ((struct terminal *));
 253 static void w32_reset_terminal_modes P_ ((struct terminal *));
 254 static void x_clear_frame P_ ((struct frame *));
 255 static void frame_highlight P_ ((struct frame *));
 256 static void frame_unhighlight P_ ((struct frame *));
 257 static void x_new_focus_frame P_ ((struct w32_display_info *,
 258                                    struct frame *));
 259 static void x_focus_changed P_ ((int, int, struct w32_display_info *,
 260                                   struct frame *, struct input_event *));
 261 static void w32_detect_focus_change P_ ((struct w32_display_info *,
 262                                        W32Msg *, struct input_event *));
 263 static void w32_frame_rehighlight P_ ((struct frame *));
 264 static void x_frame_rehighlight P_ ((struct w32_display_info *));
 265 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
 266 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
 267                                    enum text_cursor_kinds));
 268 static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, int, HDC));
 269 static BOOL my_show_window P_ ((struct frame *, HWND, int));
 270 static void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));
 271 static void my_set_focus P_ ((struct frame *, HWND));
 272 static void my_set_foreground_window P_ ((HWND));
 273 static void my_destroy_window P_ ((struct frame *, HWND));
 274 
 275 static Lisp_Object Qvendor_specific_keysyms;
 276 
 277 
 278 /***********************************************************************
 279                               Debugging
 280  ***********************************************************************/
 281 
 282 #if 0
 283 
 284 /* This is a function useful for recording debugging information about
 285    the sequence of occurrences in this file.  */
 286 
 287 struct record
 288 {
 289   char *locus;
 290   int type;
 291 };
 292 
 293 struct record event_record[100];
 294 
 295 int event_record_index;
 296 
 297 record_event (locus, type)
 298      char *locus;
 299      int type;
 300 {
 301   if (event_record_index == sizeof (event_record) / sizeof (struct record))
 302     event_record_index = 0;
 303 
 304   event_record[event_record_index].locus = locus;
 305   event_record[event_record_index].type = type;
 306   event_record_index++;
 307 }
 308 
 309 #endif /* 0 */
 310 
 311 
 312 void
 313 XChangeGC (void * ignore, XGCValues* gc, unsigned long mask,
 314            XGCValues *xgcv)
 315 {
 316   if (mask & GCForeground)
 317     gc->foreground = xgcv->foreground;
 318   if (mask & GCBackground)
 319     gc->background = xgcv->background;
 320   if (mask & GCFont)
 321     gc->font = xgcv->font;
 322 }
 323 
 324 XGCValues *XCreateGC (void * ignore, Window window, unsigned long mask,
 325                       XGCValues *xgcv)
 326 {
 327   XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
 328   bzero (gc, sizeof (XGCValues));
 329 
 330   XChangeGC (ignore, gc, mask, xgcv);
 331 
 332   return gc;
 333 }
 334 
 335 void
 336 XGetGCValues (void* ignore, XGCValues *gc,
 337                    unsigned long mask, XGCValues *xgcv)
 338 {
 339   XChangeGC (ignore, xgcv, mask, gc);
 340 }
 341 
 342 static void
 343 w32_set_clip_rectangle (HDC hdc, RECT *rect)
 344 {
 345   if (rect)
 346     {
 347       HRGN clip_region = CreateRectRgnIndirect (rect);
 348       SelectClipRgn (hdc, clip_region);
 349       DeleteObject (clip_region);
 350     }
 351   else
 352     SelectClipRgn (hdc, NULL);
 353 }
 354 
 355 
 356 /* Draw a hollow rectangle at the specified position.  */
 357 void
 358 w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y,
 359                     int width, int height)
 360 {
 361   HBRUSH hb, oldhb;
 362   HPEN hp, oldhp;
 363 
 364   hb = CreateSolidBrush (gc->background);
 365   hp = CreatePen (PS_SOLID, 0, gc->foreground);
 366   oldhb = SelectObject (hdc, hb);
 367   oldhp = SelectObject (hdc, hp);
 368 
 369   Rectangle (hdc, x, y, x + width, y + height);
 370 
 371   SelectObject (hdc, oldhb);
 372   SelectObject (hdc, oldhp);
 373   DeleteObject (hb);
 374   DeleteObject (hp);
 375 }
 376 
 377 /* Draw a filled rectangle at the specified position. */
 378 void
 379 w32_fill_rect (f, hdc, pix, lprect)
 380      FRAME_PTR f;
 381      HDC hdc;
 382      COLORREF pix;
 383      RECT * lprect;
 384 {
 385   HBRUSH hb;
 386 
 387   hb = CreateSolidBrush (pix);
 388   FillRect (hdc, lprect, hb);
 389   DeleteObject (hb);
 390 }
 391 
 392 void
 393 w32_clear_window (f)
 394      FRAME_PTR f;
 395 {
 396   RECT rect;
 397   HDC hdc = get_frame_dc (f);
 398 
 399   /* Under certain conditions, this can be called at startup with
 400      a console frame pointer before the GUI frame is created. An HDC
 401      of 0 indicates this. */
 402   if (hdc)
 403     {
 404       GetClientRect (FRAME_W32_WINDOW (f), &rect);
 405       w32_clear_rect (f, hdc, &rect);
 406     }
 407 
 408   release_frame_dc (f, hdc);
 409 }
 410 
 411 #define OPAQUE_FRAME 255
 412 
 413 void
 414 x_set_frame_alpha (f)
 415      struct frame *f;
 416 {
 417   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 418   double alpha = 1.0;
 419   double alpha_min = 1.0;
 420   BYTE opac;
 421   LONG ex_style;
 422   HWND window = FRAME_W32_WINDOW (f);
 423 
 424   /* Older versions of Windows do not support transparency.  */
 425   if (!pfnSetLayeredWindowAttributes)
 426     return;
 427 
 428   if (dpyinfo->x_highlight_frame == f)
 429     alpha = f->alpha[0];
 430   else
 431     alpha = f->alpha[1];
 432 
 433   if (FLOATP (Vframe_alpha_lower_limit))
 434     alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
 435   else if (INTEGERP (Vframe_alpha_lower_limit))
 436     alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
 437 
 438   if (alpha < 0.0)
 439     return;
 440   else if (alpha > 1.0)
 441     alpha = 1.0;
 442   else if (alpha < alpha_min && alpha_min <= 1.0)
 443     alpha = alpha_min;
 444 
 445   opac = alpha * OPAQUE_FRAME;
 446 
 447   ex_style = GetWindowLong (window, GWL_EXSTYLE);
 448 
 449   if (opac == OPAQUE_FRAME)
 450     ex_style &= ~WS_EX_LAYERED;
 451   else
 452     ex_style |= WS_EX_LAYERED;
 453 
 454   SetWindowLong (window, GWL_EXSTYLE, ex_style);
 455 
 456   if (opac != OPAQUE_FRAME)
 457     pfnSetLayeredWindowAttributes (window, 0, opac, LWA_ALPHA);
 458 }
 459 
 460 int
 461 x_display_pixel_height (dpyinfo)
 462      struct w32_display_info *dpyinfo;
 463 {
 464   HDC dc = GetDC (NULL);
 465   int pixels = GetDeviceCaps (dc, VERTRES);
 466   ReleaseDC (NULL, dc);
 467   return pixels;
 468 }
 469 
 470 int
 471 x_display_pixel_width (dpyinfo)
 472      struct w32_display_info *dpyinfo;
 473 {
 474   HDC dc = GetDC (NULL);
 475   int pixels = GetDeviceCaps (dc, HORZRES);
 476   ReleaseDC (NULL, dc);
 477   return pixels;
 478 }
 479 
 480 
 481 /***********************************************************************
 482                     Starting and ending an update
 483  ***********************************************************************/
 484 
 485 /* Start an update of frame F.  This function is installed as a hook
 486    for update_begin, i.e. it is called when update_begin is called.
 487    This function is called prior to calls to x_update_window_begin for
 488    each window being updated.  */
 489 
 490 static void
 491 x_update_begin (f)
 492      struct frame *f;
 493 {
 494   struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
 495 
 496   if (! FRAME_W32_P (f))
 497     return;
 498 
 499   /* Regenerate display palette before drawing if list of requested
 500      colors has changed. */
 501   if (display_info->regen_palette)
 502   {
 503     w32_regenerate_palette (f);
 504     display_info->regen_palette = FALSE;
 505   }
 506 }
 507 
 508 
 509 /* Start update of window W.  Set the global variable updated_window
 510    to the window being updated and set output_cursor to the cursor
 511    position of W.  */
 512 
 513 static void
 514 x_update_window_begin (w)
 515      struct window *w;
 516 {
 517   struct frame *f = XFRAME (WINDOW_FRAME (w));
 518   struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
 519 
 520   /* Hide the system caret during an update.  */
 521   if (w32_use_visible_system_caret && w32_system_caret_hwnd)
 522     {
 523       SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
 524     }
 525 
 526   updated_window = w;
 527   set_output_cursor (&w->cursor);
 528 
 529   BLOCK_INPUT;
 530 
 531   if (f == display_info->mouse_face_mouse_frame)
 532     {
 533       /* Don't do highlighting for mouse motion during the update.  */
 534       display_info->mouse_face_defer = 1;
 535 
 536       /* If F needs to be redrawn, simply forget about any prior mouse
 537          highlighting.  */
 538       if (FRAME_GARBAGED_P (f))
 539         display_info->mouse_face_window = Qnil;
 540 
 541 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
 542          their mouse_face_p flag set, which means that they are always
 543          unequal to rows in a desired matrix which never have that
 544          flag set.  So, rows containing mouse-face glyphs are never
 545          scrolled, and we don't have to switch the mouse highlight off
 546          here to prevent it from being scrolled.  */
 547 
 548       /* Can we tell that this update does not affect the window
 549          where the mouse highlight is?  If so, no need to turn off.
 550          Likewise, don't do anything if the frame is garbaged;
 551          in that case, the frame's current matrix that we would use
 552          is all wrong, and we will redisplay that line anyway.  */
 553       if (!NILP (display_info->mouse_face_window)
 554           && w == XWINDOW (display_info->mouse_face_window))
 555         {
 556           int i;
 557 
 558           for (i = 0; i < w->desired_matrix->nrows; ++i)
 559             if (MATRIX_ROW_ENABLED_P (w->desired_matrix, i))
 560               break;
 561 
 562           if (i < w->desired_matrix->nrows)
 563             clear_mouse_face (display_info);
 564         }
 565 #endif /* 0 */
 566     }
 567 
 568   UNBLOCK_INPUT;
 569 }
 570 
 571 /* Draw a vertical window border from (x,y0) to (x,y1)  */
 572 
 573 static void
 574 w32_draw_vertical_window_border (w, x, y0, y1)
 575      struct window *w;
 576      int x, y0, y1;
 577 {
 578   struct frame *f = XFRAME (WINDOW_FRAME (w));
 579   RECT r;
 580   HDC hdc;
 581   struct face *face;
 582 
 583   r.left = x;
 584   r.right = x + 1;
 585   r.top = y0;
 586   r.bottom = y1;
 587 
 588   hdc = get_frame_dc (f);
 589   face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID);
 590   if (face)
 591     w32_fill_rect (f, hdc, face->foreground, &r);
 592   else
 593     w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
 594 
 595   release_frame_dc (f, hdc);
 596 }
 597 
 598 
 599 /* End update of window W (which is equal to updated_window).
 600 
 601    Draw vertical borders between horizontally adjacent windows, and
 602    display W's cursor if CURSOR_ON_P is non-zero.
 603 
 604    MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
 605    glyphs in mouse-face were overwritten.  In that case we have to
 606    make sure that the mouse-highlight is properly redrawn.
 607 
 608    W may be a menu bar pseudo-window in case we don't have X toolkit
 609    support. Such windows don't have a cursor, so don't display it
 610    here. */
 611 
 612 static void
 613 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
 614      struct window *w;
 615      int cursor_on_p, mouse_face_overwritten_p;
 616 {
 617   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
 618 
 619   if (!w->pseudo_window_p)
 620     {
 621       BLOCK_INPUT;
 622 
 623       if (cursor_on_p)
 624         display_and_set_cursor (w, 1, output_cursor.hpos,
 625                                 output_cursor.vpos,
 626                                 output_cursor.x, output_cursor.y);
 627 
 628       if (draw_window_fringes (w, 1))
 629         x_draw_vertical_border (w);
 630 
 631       UNBLOCK_INPUT;
 632     }
 633 
 634   /* If a row with mouse-face was overwritten, arrange for
 635      XTframe_up_to_date to redisplay the mouse highlight.  */
 636   if (mouse_face_overwritten_p)
 637     {
 638       dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
 639       dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
 640       dpyinfo->mouse_face_window = Qnil;
 641     }
 642 
 643   /* Unhide the caret.  This won't actually show the cursor, unless it
 644      was visible before the corresponding call to HideCaret in
 645      x_update_window_begin.  */
 646   if (w32_use_visible_system_caret && w32_system_caret_hwnd)
 647     {
 648       SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
 649     }
 650 
 651   updated_window = NULL;
 652 }
 653 
 654 
 655 /* End update of frame F.  This function is installed as a hook in
 656    update_end.  */
 657 
 658 static void
 659 x_update_end (f)
 660      struct frame *f;
 661 {
 662   if (! FRAME_W32_P (f))
 663     return;
 664 
 665   /* Mouse highlight may be displayed again.  */
 666   FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
 667 }
 668 
 669 
 670 /* This function is called from various places in xdisp.c whenever a
 671    complete update has been performed.  The global variable
 672    updated_window is not available here.  */
 673 
 674 static void
 675 w32_frame_up_to_date (f)
 676      struct frame *f;
 677 {
 678   if (FRAME_W32_P (f))
 679     {
 680       struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
 681 
 682       if (dpyinfo->mouse_face_deferred_gc
 683           || f == dpyinfo->mouse_face_mouse_frame)
 684         {
 685           BLOCK_INPUT;
 686           if (dpyinfo->mouse_face_mouse_frame)
 687             note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
 688                                   dpyinfo->mouse_face_mouse_x,
 689                                   dpyinfo->mouse_face_mouse_y);
 690           dpyinfo->mouse_face_deferred_gc = 0;
 691           UNBLOCK_INPUT;
 692         }
 693     }
 694 }
 695 
 696 
 697 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
 698    arrow bitmaps, or clear the fringes if no bitmaps are required
 699    before DESIRED_ROW is made current.  The window being updated is
 700    found in updated_window.  This function is called from
 701    update_window_line only if it is known that there are differences
 702    between bitmaps to be drawn between current row and DESIRED_ROW.  */
 703 
 704 static void
 705 x_after_update_window_line (desired_row)
 706      struct glyph_row *desired_row;
 707 {
 708   struct window *w = updated_window;
 709   struct frame *f;
 710   int width, height;
 711 
 712   xassert (w);
 713 
 714   if (!desired_row->mode_line_p && !w->pseudo_window_p)
 715     desired_row->redraw_fringe_bitmaps_p = 1;
 716 
 717   /* When a window has disappeared, make sure that no rest of
 718      full-width rows stays visible in the internal border.  Could
 719      check here if updated_window is the leftmost/rightmost window,
 720      but I guess it's not worth doing since vertically split windows
 721      are almost never used, internal border is rarely set, and the
 722      overhead is very small.  */
 723   if (windows_or_buffers_changed
 724       && desired_row->full_width_p
 725       && (f = XFRAME (w->frame),
 726           width = FRAME_INTERNAL_BORDER_WIDTH (f),
 727           width != 0)
 728       && (height = desired_row->visible_height,
 729           height > 0))
 730     {
 731       int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
 732 
 733       BLOCK_INPUT;
 734       {
 735         HDC hdc = get_frame_dc (f);
 736         w32_clear_area (f, hdc, 0, y, width, height);
 737         w32_clear_area (f, hdc, FRAME_PIXEL_WIDTH (f) - width,
 738                         y, width, height);
 739         release_frame_dc (f, hdc);
 740       }
 741       UNBLOCK_INPUT;
 742     }
 743 }
 744 
 745 
 746 /* Draw the bitmap WHICH in one of the left or right fringes of
 747    window W.  ROW is the glyph row for which to display the bitmap; it
 748    determines the vertical position at which the bitmap has to be
 749    drawn.  */
 750 
 751 static void
 752 w32_draw_fringe_bitmap (w, row, p)
 753      struct window *w;
 754      struct glyph_row *row;
 755      struct draw_fringe_bitmap_params *p;
 756 {
 757   struct frame *f = XFRAME (WINDOW_FRAME (w));
 758   HDC hdc;
 759   struct face *face = p->face;
 760   int rowY;
 761 
 762   hdc = get_frame_dc (f);
 763 
 764   if (!p->overlay_p)
 765     {
 766       int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
 767 
 768       /* If the fringe is adjacent to the left (right) scroll bar of a
 769          leftmost (rightmost, respectively) window, then extend its
 770          background to the gap between the fringe and the bar.  */
 771       if ((WINDOW_LEFTMOST_P (w)
 772            && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
 773           || (WINDOW_RIGHTMOST_P (w)
 774               && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
 775         {
 776           int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
 777 
 778           if (sb_width > 0)
 779             {
 780               int left = WINDOW_SCROLL_BAR_AREA_X (w);
 781               int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
 782                            * FRAME_COLUMN_WIDTH (f));
 783 
 784               if (bx < 0)
 785                 {
 786                   /* Bitmap fills the fringe.  */
 787                   if (left + width == p->x)
 788                     bx = left + sb_width;
 789                   else if (p->x + p->wd == left)
 790                     bx = left;
 791                   if (bx >= 0)
 792                     {
 793                       int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
 794 
 795                       nx = width - sb_width;
 796                       by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
 797                                                             row->y));
 798                       ny = row->visible_height;
 799                     }
 800                 }
 801               else
 802                 {
 803                   if (left + width == bx)
 804                     {
 805                       bx = left + sb_width;
 806                       nx += width - sb_width;
 807                     }
 808                   else if (bx + nx == left)
 809                     nx += width - sb_width;
 810                 }
 811             }
 812         }
 813 
 814       if (bx >= 0 && nx > 0)
 815         w32_fill_area (f, hdc, face->background, bx, by, nx, ny);
 816     }
 817 
 818   /* Must clip because of partially visible lines.  */
 819   rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
 820   if (p->y < rowY)
 821     {
 822       /* Adjust position of "bottom aligned" bitmap on partially
 823          visible last row.  */
 824       int oldY = row->y;
 825       int oldVH = row->visible_height;
 826       row->visible_height = p->h;
 827       row->y -= rowY - p->y;
 828       w32_clip_to_row (w, row, -1, hdc);
 829       row->y = oldY;
 830       row->visible_height = oldVH;
 831     }
 832   else
 833     w32_clip_to_row (w, row, -1, hdc);
 834 
 835   if (p->which && p->which < max_fringe_bmp)
 836     {
 837       HBITMAP pixmap = fringe_bmp[p->which];
 838       HDC compat_hdc;
 839       HANDLE horig_obj;
 840 
 841       compat_hdc = CreateCompatibleDC (hdc);
 842 
 843       SaveDC (hdc);
 844 
 845       horig_obj = SelectObject (compat_hdc, pixmap);
 846 
 847       /* Paint overlays transparently.  */
 848       if (p->overlay_p)
 849         {
 850           HBRUSH h_brush, h_orig_brush;
 851 
 852           SetTextColor (hdc, BLACK_PIX_DEFAULT (f));
 853           SetBkColor (hdc, WHITE_PIX_DEFAULT (f));
 854           h_brush = CreateSolidBrush (face->foreground);
 855           h_orig_brush = SelectObject (hdc, h_brush);
 856 
 857           BitBlt (hdc, p->x, p->y, p->wd, p->h,
 858                   compat_hdc, 0, p->dh,
 859                   DSTINVERT);
 860           BitBlt (hdc, p->x, p->y, p->wd, p->h,
 861                   compat_hdc, 0, p->dh,
 862                   0x2E064A);
 863           BitBlt (hdc, p->x, p->y, p->wd, p->h,
 864                   compat_hdc, 0, p->dh,
 865                   DSTINVERT);
 866 
 867           SelectObject (hdc, h_orig_brush);
 868           DeleteObject (h_brush);
 869         }
 870       else
 871         {
 872           SetTextColor (hdc, face->background);
 873           SetBkColor (hdc, (p->cursor_p
 874                             ? f->output_data.w32->cursor_pixel
 875                             : face->foreground));
 876 
 877           BitBlt (hdc, p->x, p->y, p->wd, p->h,
 878                   compat_hdc, 0, p->dh,
 879                   SRCCOPY);
 880         }
 881 
 882       SelectObject (compat_hdc, horig_obj);
 883       DeleteDC (compat_hdc);
 884       RestoreDC (hdc, -1);
 885     }
 886 
 887   w32_set_clip_rectangle (hdc, NULL);
 888 
 889   release_frame_dc (f, hdc);
 890 }
 891 
 892 static void
 893 w32_define_fringe_bitmap (which, bits, h, wd)
 894      int which;
 895      unsigned short *bits;
 896      int h, wd;
 897 {
 898   if (which >= max_fringe_bmp)
 899     {
 900       int i = max_fringe_bmp;
 901       max_fringe_bmp = which + 20;
 902       fringe_bmp = (HBITMAP *) xrealloc (fringe_bmp, max_fringe_bmp * sizeof (HBITMAP));
 903       while (i < max_fringe_bmp)
 904         fringe_bmp[i++] = 0;
 905     }
 906 
 907   fringe_bmp[which] = CreateBitmap (wd, h, 1, 1, bits);
 908 }
 909 
 910 static void
 911 w32_destroy_fringe_bitmap (which)
 912      int which;
 913 {
 914   if (which >= max_fringe_bmp)
 915     return;
 916 
 917   if (fringe_bmp[which])
 918     DeleteObject (fringe_bmp[which]);
 919   fringe_bmp[which] = 0;
 920 }
 921 
 922 
 923 
 924 /* This is called when starting Emacs and when restarting after
 925    suspend.  When starting Emacs, no window is mapped.  And nothing
 926    must be done to Emacs's own window if it is suspended (though that
 927    rarely happens).  */
 928 
 929 static void
 930 w32_set_terminal_modes (struct terminal *term)
 931 {
 932 }
 933 
 934 /* This is called when exiting or suspending Emacs. Exiting will make
 935    the W32 windows go away, and suspending requires no action. */
 936 
 937 static void
 938 w32_reset_terminal_modes (struct terminal *term)
 939 {
 940 }
 941 
 942 
 943 
 944 /***********************************************************************
 945                            Display Iterator
 946  ***********************************************************************/
 947 
 948 /* Function prototypes of this page.  */
 949 
 950 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
 951 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
 952 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
 953                                                 int));
 954 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
 955 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
 956 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
 957 static void x_draw_glyph_string  P_ ((struct glyph_string *));
 958 static void x_set_cursor_gc P_ ((struct glyph_string *));
 959 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
 960 static void x_set_mouse_face_gc P_ ((struct glyph_string *));
 961 static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int);
 962 static void w32_setup_relief_color P_ ((struct frame *, struct relief *,
 963                                         double, int, COLORREF));
 964 static void x_setup_relief_colors P_ ((struct glyph_string *));
 965 static void x_draw_image_glyph_string P_ ((struct glyph_string *));
 966 static void x_draw_image_relief P_ ((struct glyph_string *));
 967 static void x_draw_image_foreground P_ ((struct glyph_string *));
 968 static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP));
 969 static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int,
 970                                            int, int, int));
 971 static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
 972                                       int, int, int, int, int, int,
 973                                       RECT *));
 974 static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
 975                                  int, int, int, RECT *));
 976 
 977 
 978 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
 979    face.  */
 980 
 981 static void
 982 x_set_cursor_gc (s)
 983      struct glyph_string *s;
 984 {
 985   if (s->font == FRAME_FONT (s->f)
 986       && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
 987       && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
 988       && !s->cmp)
 989     s->gc = s->f->output_data.w32->cursor_gc;
 990   else
 991     {
 992       /* Cursor on non-default face: must merge.  */
 993       XGCValues xgcv;
 994       unsigned long mask;
 995 
 996       xgcv.background = s->f->output_data.w32->cursor_pixel;
 997       xgcv.foreground = s->face->background;
 998 
 999       /* If the glyph would be invisible, try a different foreground.  */
1000       if (xgcv.foreground == xgcv.background)
1001         xgcv.foreground = s->face->foreground;
1002       if (xgcv.foreground == xgcv.background)
1003         xgcv.foreground = s->f->output_data.w32->cursor_foreground_pixel;
1004       if (xgcv.foreground == xgcv.background)
1005         xgcv.foreground = s->face->foreground;
1006 
1007       /* Make sure the cursor is distinct from text in this face.  */
1008       if (xgcv.background == s->face->background
1009           && xgcv.foreground == s->face->foreground)
1010         {
1011           xgcv.background = s->face->foreground;
1012           xgcv.foreground = s->face->background;
1013         }
1014 
1015       IF_DEBUG (x_check_font (s->f, s->font));
1016       xgcv.font = s->font;
1017       mask = GCForeground | GCBackground | GCFont;
1018 
1019       if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1020         XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1021                    mask, &xgcv);
1022       else
1023         FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
1024           = XCreateGC (NULL, s->window, mask, &xgcv);
1025 
1026       s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1027     }
1028 }
1029 
1030 
1031 /* Set up S->gc of glyph string S for drawing text in mouse face.  */
1032 
1033 static void
1034 x_set_mouse_face_gc (s)
1035      struct glyph_string *s;
1036 {
1037   int face_id;
1038   struct face *face;
1039 
1040   /* What face has to be used last for the mouse face?  */
1041   face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
1042   face = FACE_FROM_ID (s->f, face_id);
1043   if (face == NULL)
1044     face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
1045 
1046   if (s->first_glyph->type == CHAR_GLYPH)
1047     face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
1048   else
1049     face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
1050   s->face = FACE_FROM_ID (s->f, face_id);
1051   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
1052 
1053   /* If font in this face is same as S->font, use it.  */
1054   if (s->font == s->face->font)
1055     s->gc = s->face->gc;
1056   else
1057     {
1058       /* Otherwise construct scratch_cursor_gc with values from FACE
1059          but font FONT.  */
1060       XGCValues xgcv;
1061       unsigned long mask;
1062 
1063       xgcv.background = s->face->background;
1064       xgcv.foreground = s->face->foreground;
1065       IF_DEBUG (x_check_font (s->f, s->font));
1066       xgcv.font = s->font;
1067       mask = GCForeground | GCBackground | GCFont;
1068 
1069       if (FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc)
1070         XChangeGC (NULL, FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc,
1071                    mask, &xgcv);
1072       else
1073         FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc
1074           = XCreateGC (NULL, s->window, mask, &xgcv);
1075 
1076       s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
1077     }
1078 
1079   xassert (s->gc != 0);
1080 }
1081 
1082 
1083 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
1084    Faces to use in the mode line have already been computed when the
1085    matrix was built, so there isn't much to do, here.  */
1086 
1087 static INLINE void
1088 x_set_mode_line_face_gc (s)
1089      struct glyph_string *s;
1090 {
1091   s->gc = s->face->gc;
1092 }
1093 
1094 
1095 /* Set S->gc of glyph string S for drawing that glyph string.  Set
1096    S->stippled_p to a non-zero value if the face of S has a stipple
1097    pattern.  */
1098 
1099 static INLINE void
1100 x_set_glyph_string_gc (s)
1101      struct glyph_string *s;
1102 {
1103   PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
1104 
1105   if (s->hl == DRAW_NORMAL_TEXT)
1106     {
1107       s->gc = s->face->gc;
1108       s->stippled_p = s->face->stipple != 0;
1109     }
1110   else if (s->hl == DRAW_INVERSE_VIDEO)
1111     {
1112       x_set_mode_line_face_gc (s);
1113       s->stippled_p = s->face->stipple != 0;
1114     }
1115   else if (s->hl == DRAW_CURSOR)
1116     {
1117       x_set_cursor_gc (s);
1118       s->stippled_p = 0;
1119     }
1120   else if (s->hl == DRAW_MOUSE_FACE)
1121     {
1122       x_set_mouse_face_gc (s);
1123       s->stippled_p = s->face->stipple != 0;
1124     }
1125   else if (s->hl == DRAW_IMAGE_RAISED
1126            || s->hl == DRAW_IMAGE_SUNKEN)
1127     {
1128       s->gc = s->face->gc;
1129       s->stippled_p = s->face->stipple != 0;
1130     }
1131   else
1132     {
1133       s->gc = s->face->gc;
1134       s->stippled_p = s->face->stipple != 0;
1135     }
1136 
1137   /* GC must have been set.  */
1138   xassert (s->gc != 0);
1139 }
1140 
1141 
1142 /* Set clipping for output of glyph string S.  S may be part of a mode
1143    line or menu if we don't have X toolkit support.  */
1144 
1145 static INLINE void
1146 x_set_glyph_string_clipping (s)
1147      struct glyph_string *s;
1148 {
1149   RECT *r = s->clip;
1150   int n = get_glyph_string_clip_rects (s, r, 2);
1151 
1152   if (n == 1)
1153     w32_set_clip_rectangle (s->hdc, r);
1154   else if (n > 1)
1155     {
1156       HRGN full_clip, clip1, clip2;
1157       clip1 = CreateRectRgnIndirect (r);
1158       clip2 = CreateRectRgnIndirect (r + 1);
1159       if (CombineRgn (full_clip, clip1, clip2, RGN_OR) != ERROR)
1160         {
1161           SelectClipRgn (s->hdc, full_clip);
1162         }
1163       DeleteObject (clip1);
1164       DeleteObject (clip2);
1165       DeleteObject (full_clip);
1166     }
1167     s->num_clips = n;
1168 }
1169 
1170 /* Set SRC's clipping for output of glyph string DST.  This is called
1171    when we are drawing DST's left_overhang or right_overhang only in
1172    the area of SRC.  */
1173 
1174 static void
1175 x_set_glyph_string_clipping_exactly (src, dst)
1176      struct glyph_string *src, *dst;
1177 {
1178   RECT r;
1179 
1180   r.left = src->x;
1181   r.right = r.left + src->width;
1182   r.top = src->y;
1183   r.bottom = r.top + src->height;
1184   dst->clip[0] = r;
1185   dst->num_clips = 1;
1186   w32_set_clip_rectangle (dst->hdc, &r);
1187 }
1188 
1189 /* RIF:
1190    Compute left and right overhang of glyph string S.  */
1191 
1192 static void
1193 w32_compute_glyph_string_overhangs (s)
1194      struct glyph_string *s;
1195 {
1196   if (s->cmp == NULL
1197       && s->first_glyph->type == CHAR_GLYPH
1198       && !s->font_not_found_p)
1199     {
1200       unsigned *code = alloca (sizeof (unsigned) * s->nchars);
1201       struct font *font = s->font;
1202       struct font_metrics metrics;
1203       int i;
1204 
1205       for (i = 0; i < s->nchars; i++)
1206         code[i] = s->char2b[i];
1207       font->driver->text_extents (font, code, s->nchars, &metrics);
1208       s->right_overhang = (metrics.rbearing > metrics.width
1209                            ? metrics.rbearing - metrics.width : 0);
1210       s->left_overhang = metrics.lbearing < 0 ? -metrics.lbearing : 0;
1211     }
1212   else if (s->cmp)
1213     {
1214       s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
1215       s->left_overhang = -s->cmp->lbearing;
1216     }
1217 }
1218 
1219 /* Fill rectangle X, Y, W, H with background color of glyph string S.  */
1220 
1221 static INLINE void
1222 x_clear_glyph_string_rect (s, x, y, w, h)
1223      struct glyph_string *s;
1224      int x, y, w, h;
1225 {
1226   int real_x = x;
1227   int real_y = y;
1228   int real_w = w;
1229   int real_h = h;
1230 #if 0
1231   /* Take clipping into account.  */
1232   if (s->gc->clip_mask == Rect)
1233     {
1234       real_x = max (real_x, s->gc->clip_rectangle.left);
1235       real_y = max (real_y, s->gc->clip_rectangle.top);
1236       real_w = min (real_w, s->gc->clip_rectangle.right
1237                     - s->gc->clip_rectangle.left);
1238       real_h = min (real_h, s->gc->clip_rectangle.bottom
1239                     - s->gc->clip_rectangle.top);
1240     }
1241 #endif
1242   w32_fill_area (s->f, s->hdc, s->gc->background, real_x, real_y,
1243                  real_w, real_h);
1244 }
1245 
1246 
1247 /* Draw the background of glyph_string S.  If S->background_filled_p
1248    is non-zero don't draw it.  FORCE_P non-zero means draw the
1249    background even if it wouldn't be drawn normally.  This is used
1250    when a string preceding S draws into the background of S, or S
1251    contains the first component of a composition.  */
1252 
1253 static void
1254 x_draw_glyph_string_background (s, force_p)
1255      struct glyph_string *s;
1256      int force_p;
1257 {
1258   /* Nothing to do if background has already been drawn or if it
1259      shouldn't be drawn in the first place.  */
1260   if (!s->background_filled_p)
1261     {
1262       int box_line_width = max (s->face->box_line_width, 0);
1263 
1264 #if 0 /* TODO: stipple */
1265       if (s->stippled_p)
1266         {
1267           /* Fill background with a stipple pattern.  */
1268           XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
1269           XFillRectangle (s->display, s->window, s->gc, s->x,
1270                           s->y + box_line_width,
1271                           s->background_width,
1272                           s->height - 2 * box_line_width);
1273           XSetFillStyle (s->display, s->gc, FillSolid);
1274           s->background_filled_p = 1;
1275         }
1276       else
1277 #endif
1278         if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width
1279                || s->font_not_found_p
1280                || s->extends_to_end_of_line_p
1281                || force_p)
1282         {
1283           x_clear_glyph_string_rect (s, s->x, s->y + box_line_width,
1284                                      s->background_width,
1285                                      s->height - 2 * box_line_width);
1286           s->background_filled_p = 1;
1287         }
1288     }
1289 }
1290 
1291 
1292 /* Draw the foreground of glyph string S.  */
1293 
1294 static void
1295 x_draw_glyph_string_foreground (s)
1296      struct glyph_string *s;
1297 {
1298   int i, x;
1299 
1300   /* If first glyph of S has a left box line, start drawing the text
1301      of S to the right of that box line.  */
1302   if (s->face->box != FACE_NO_BOX
1303       && s->first_glyph->left_box_line_p)
1304     x = s->x + eabs (s->face->box_line_width);
1305   else
1306     x = s->x;
1307 
1308   SetTextColor (s->hdc, s->gc->foreground);
1309   SetBkColor (s->hdc, s->gc->background);
1310   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1311 
1312   /* Draw characters of S as rectangles if S's font could not be
1313      loaded. */
1314   if (s->font_not_found_p)
1315     {
1316       for (i = 0; i < s->nchars; ++i)
1317         {
1318           struct glyph *g = s->first_glyph + i;
1319 
1320           w32_draw_rectangle (s->hdc, s->gc, x, s->y, g->pixel_width - 1,
1321                               s->height - 1);
1322           x += g->pixel_width;
1323         }
1324     }
1325   else
1326     {
1327       struct font *font = s->font;
1328       int boff = font->baseline_offset;
1329       int y;
1330       HFONT old_font;
1331 
1332       old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1333 
1334       if (font->vertical_centering)
1335         boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff;
1336 
1337       y = s->ybase - boff;
1338       if (s->for_overlaps
1339           || (s->background_filled_p && s->hl != DRAW_CURSOR))
1340         font->driver->draw (s, 0, s->nchars, x, y, 0);
1341       else
1342         font->driver->draw (s, 0, s->nchars, x, y, 1);
1343       if (s->face->overstrike)
1344         font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
1345 
1346       SelectObject (s->hdc, old_font);
1347     }
1348 }
1349 
1350 /* Draw the foreground of composite glyph string S.  */
1351 
1352 static void
1353 x_draw_composite_glyph_string_foreground (s)
1354      struct glyph_string *s;
1355 {
1356   int i, j, x;
1357   struct font *font = s->font;
1358 
1359   /* If first glyph of S has a left box line, start drawing the text
1360      of S to the right of that box line.  */
1361   if (s->face && s->face->box != FACE_NO_BOX
1362       && s->first_glyph->left_box_line_p)
1363     x = s->x + eabs (s->face->box_line_width);
1364   else
1365     x = s->x;
1366 
1367   /* S is a glyph string for a composition.  S->cmp_from is the index
1368      of the first character drawn for glyphs of this composition.
1369      S->cmp_from == 0 means we are drawing the very first character of
1370      this composition.  */
1371 
1372   SetTextColor (s->hdc, s->gc->foreground);
1373   SetBkColor (s->hdc, s->gc->background);
1374   SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
1375 
1376   /* Draw a rectangle for the composition if the font for the very
1377      first character of the composition could not be loaded.  */
1378   if (s->font_not_found_p)
1379     {
1380       if (s->cmp_from == 0)
1381         w32_draw_rectangle (s->hdc, s->gc, x, s->y, s->width - 1,
1382                             s->height - 1);
1383     }
1384   else if (! s->first_glyph->u.cmp.automatic)
1385     {
1386       int y = s->ybase;
1387       int width = 0;
1388       HFONT old_font;
1389 
1390       old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1391 
1392       for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++)
1393         if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
1394           {
1395             int xx = x + s->cmp->offsets[j * 2];
1396             int yy = y - s->cmp->offsets[j * 2 + 1];
1397 
1398             font->driver->draw (s, j, j + 1, xx, yy, 0);
1399             if (s->face->overstrike)
1400               font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
1401           }
1402       SelectObject (s->hdc, old_font);
1403     }
1404   else
1405     {
1406       Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
1407       Lisp_Object glyph;
1408       int y = s->ybase;
1409       int width = 0;
1410       HFONT old_font;
1411 
1412       old_font = SelectObject (s->hdc, FONT_HANDLE (font));
1413 
1414       for (i = j = s->cmp_from; i < s->cmp_to; i++)
1415         {
1416           glyph = LGSTRING_GLYPH (gstring, i);
1417           if (NILP (LGLYPH_ADJUSTMENT (glyph)))
1418             width += LGLYPH_WIDTH (glyph);
1419           else
1420             {
1421               int xoff, yoff, wadjust;
1422 
1423               if (j < i)
1424                 {
1425                   font->driver->draw (s, j, i, x, y, 0);
1426                   x += width;
1427                 }
1428               xoff = LGLYPH_XOFF (glyph);
1429               yoff = LGLYPH_YOFF (glyph);
1430               wadjust = LGLYPH_WADJUST (glyph);
1431               font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
1432               x += wadjust;
1433               j = i + 1;
1434               width = 0;
1435             }
1436         }
1437       if (j < i)
1438         font->driver->draw (s, j, i, x, y, 0);
1439 
1440       SelectObject (s->hdc, old_font);
1441     }
1442 }
1443 
1444 
1445 /* Brightness beyond which a color won't have its highlight brightness
1446    boosted.
1447 
1448    Nominally, highlight colors for `3d' faces are calculated by
1449    brightening an object's color by a constant scale factor, but this
1450    doesn't yield good results for dark colors, so for colors who's
1451    brightness is less than this value (on a scale of 0-255) have to
1452    use an additional additive factor.
1453 
1454    The value here is set so that the default menu-bar/mode-line color
1455    (grey75) will not have its highlights changed at all.  */
1456 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
1457 
1458 
1459 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
1460    or DELTA.  Try a color with RGB values multiplied by FACTOR first.
1461    If this produces the same color as COLOR, try a color where all RGB
1462    values have DELTA added.  Return the allocated color in *COLOR.
1463    DISPLAY is the X display, CMAP is the colormap to operate on.
1464    Value is non-zero if successful.  */
1465 
1466 static int
1467 w32_alloc_lighter_color (f, color, factor, delta)
1468      struct frame *f;
1469      COLORREF *color;
1470      double factor;
1471      int delta;
1472 {
1473   COLORREF new;
1474   long bright;
1475 
1476   /* On Windows, RGB values are 0-255, not 0-65535, so scale delta. */
1477   delta /= 256;
1478 
1479   /* Change RGB values by specified FACTOR.  Avoid overflow!  */
1480   xassert (factor >= 0);
1481   new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
1482                     min (0xff, factor * GetGValue (*color)),
1483                     min (0xff, factor * GetBValue (*color)));
1484 
1485   /* Calculate brightness of COLOR.  */
1486   bright = (2 * GetRValue (*color) + 3 * GetGValue (*color)
1487             + GetBValue (*color)) / 6;
1488 
1489   /* We only boost colors that are darker than
1490      HIGHLIGHT_COLOR_DARK_BOOST_LIMIT.  */
1491   if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
1492     /* Make an additive adjustment to NEW, because it's dark enough so
1493        that scaling by FACTOR alone isn't enough.  */
1494     {
1495       /* How far below the limit this color is (0 - 1, 1 being darker).  */
1496       double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
1497       /* The additive adjustment.  */
1498       int min_delta = delta * dimness * factor / 2;
1499 
1500       if (factor < 1)
1501         new = PALETTERGB (max (0, min (0xff, min_delta - GetRValue (*color))),
1502                           max (0, min (0xff, min_delta - GetGValue (*color))),
1503                           max (0, min (0xff, min_delta - GetBValue (*color))));
1504       else
1505         new = PALETTERGB (max (0, min (0xff, min_delta + GetRValue (*color))),
1506                           max (0, min (0xff, min_delta + GetGValue (*color))),
1507                           max (0, min (0xff, min_delta + GetBValue (*color))));
1508     }
1509 
1510   if (new == *color)
1511     new = PALETTERGB (max (0, min (0xff, delta + GetRValue (*color))),
1512                       max (0, min (0xff, delta + GetGValue (*color))),
1513                       max (0, min (0xff, delta + GetBValue (*color))));
1514 
1515   /* TODO: Map to palette and retry with delta if same? */
1516   /* TODO: Free colors (if using palette)? */
1517 
1518   if (new == *color)
1519     return 0;
1520 
1521   *color = new;
1522 
1523   return 1;
1524 }
1525 
1526 /* On frame F, translate pixel colors to RGB values for the NCOLORS
1527    colors in COLORS.  On W32, we no longer try to map colors to
1528    a palette.  */
1529 void
1530 x_query_colors (f, colors, ncolors)
1531      struct frame *f;
1532      XColor *colors;
1533      int ncolors;
1534 {
1535   int i;
1536 
1537   for (i = 0; i < ncolors; i++)
1538     {
1539       DWORD pixel = colors[i].pixel;
1540       /* Convert to a 16 bit value in range 0 - 0xffff. */
1541       colors[i].red = GetRValue (pixel) * 257;
1542       colors[i].green = GetGValue (pixel) * 257;
1543       colors[i].blue = GetBValue (pixel) * 257;
1544     }
1545 }
1546 
1547 void
1548 x_query_color (f, color)
1549      struct frame *f;
1550      XColor *color;
1551 {
1552   x_query_colors (f, color, 1);
1553 }
1554 
1555 
1556 /* Set up the foreground color for drawing relief lines of glyph
1557    string S.  RELIEF is a pointer to a struct relief containing the GC
1558    with which lines will be drawn.  Use a color that is FACTOR or
1559    DELTA lighter or darker than the relief's background which is found
1560    in S->f->output_data.x->relief_background.  If such a color cannot
1561    be allocated, use DEFAULT_PIXEL, instead.  */
1562 
1563 static void
1564 w32_setup_relief_color (f, relief, factor, delta, default_pixel)
1565      struct frame *f;
1566      struct relief *relief;
1567      double factor;
1568      int delta;
1569      COLORREF default_pixel;
1570 {
1571   XGCValues xgcv;
1572   struct w32_output *di = f->output_data.w32;
1573   unsigned long mask = GCForeground;
1574   COLORREF pixel;
1575   COLORREF background = di->relief_background;
1576   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
1577 
1578   /* TODO: Free colors (if using palette)? */
1579 
1580   /* Allocate new color.  */
1581   xgcv.foreground = default_pixel;
1582   pixel = background;
1583   if (w32_alloc_lighter_color (f, &pixel, factor, delta))
1584     {
1585       relief->allocated_p = 1;
1586       xgcv.foreground = relief->pixel = pixel;
1587     }
1588 
1589   if (relief->gc == 0)
1590     {
1591 #if 0 /* TODO: stipple */
1592       xgcv.stipple = dpyinfo->gray;
1593       mask |= GCStipple;
1594 #endif
1595       relief->gc = XCreateGC (NULL, FRAME_W32_WINDOW (f), mask, &xgcv);
1596     }
1597   else
1598     XChangeGC (NULL, relief->gc, mask, &xgcv);
1599 }
1600 
1601 
1602 /* Set up colors for the relief lines around glyph string S.  */
1603 
1604 static void
1605 x_setup_relief_colors (s)
1606      struct glyph_string *s;
1607 {
1608   struct w32_output *di = s->f->output_data.w32;
1609   COLORREF color;
1610 
1611   if (s->face->use_box_color_for_shadows_p)
1612     color = s->face->box_color;
1613   else if (s->first_glyph->type == IMAGE_GLYPH
1614            && s->img->pixmap
1615            && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
1616     color = IMAGE_BACKGROUND  (s->img, s->f, 0);
1617   else
1618     color = s->gc->background;
1619 
1620   if (di->white_relief.gc == 0
1621       || color != di->relief_background)
1622     {
1623       di->relief_background = color;
1624       w32_setup_relief_color (s->f, &di->white_relief, 1.2, 0x8000,
1625                               WHITE_PIX_DEFAULT (s->f));
1626       w32_setup_relief_color (s->f, &di->black_relief, 0.6, 0x4000,
1627                               BLACK_PIX_DEFAULT (s->f));
1628     }
1629 }
1630 
1631 
1632 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
1633    TOP_Y, RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the relief
1634    to draw, it must be >= 0.  RAISED_P non-zero means draw a raised
1635    relief.  LEFT_P non-zero means draw a relief on the left side of
1636    the rectangle.  RIGHT_P non-zero means draw a relief on the right
1637    side of the rectangle.  CLIP_RECT is the clipping rectangle to use
1638    when drawing.  */
1639 
1640 static void
1641 w32_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
1642                       raised_p, top_p, bot_p, left_p, right_p, clip_rect)
1643      struct frame *f;
1644      int left_x, top_y, right_x, bottom_y, width;
1645      int top_p, bot_p, left_p, right_p, raised_p;
1646      RECT *clip_rect;
1647 {
1648   int i;
1649   XGCValues gc;
1650   HDC hdc = get_frame_dc (f);
1651 
1652   if (raised_p)
1653     gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1654   else
1655     gc.foreground = f->output_data.w32->black_relief.gc->foreground;
1656 
1657   w32_set_clip_rectangle (hdc, clip_rect);
1658 
1659   /* Top.  */
1660   if (top_p)
1661     for (i = 0; i < width; ++i)
1662       w32_fill_area (f, hdc, gc.foreground,
1663                      left_x + i * left_p, top_y + i,
1664                      right_x - left_x - i * (left_p + right_p ) + 1, 1);
1665 
1666   /* Left.  */
1667   if (left_p)
1668     for (i = 0; i < width; ++i)
1669       w32_fill_area (f, hdc, gc.foreground,
1670                      left_x + i, top_y + i, 1,
1671                      bottom_y - top_y - 2 * i + 1);
1672 
1673   if (raised_p)
1674     gc.foreground = f->output_data.w32->black_relief.gc->foreground;
1675   else
1676     gc.foreground = f->output_data.w32->white_relief.gc->foreground;
1677 
1678   /* Bottom.  */
1679   if (bot_p)
1680     for (i = 0; i < width; ++i)
1681       w32_fill_area (f, hdc, gc.foreground,
1682                      left_x + i * left_p, bottom_y - i,
1683                      right_x - left_x - i * (left_p + right_p) + 1, 1);
1684 
1685   /* Right.  */
1686   if (right_p)
1687     for (i = 0; i < width; ++i)
1688       w32_fill_area (f, hdc, gc.foreground,
1689                      right_x - i, top_y + i + 1, 1,
1690                      bottom_y - top_y - 2 * i - 1);
1691 
1692   w32_set_clip_rectangle (hdc, NULL);
1693 
1694   release_frame_dc (f, hdc);
1695 }
1696 
1697 
1698 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
1699    RIGHT_X, and BOTTOM_Y.  WIDTH is the thickness of the lines to
1700    draw, it must be >= 0.  LEFT_P non-zero means draw a line on the
1701    left side of the rectangle.  RIGHT_P non-zero means draw a line
1702    on the right side of the rectangle.  CLIP_RECT is the clipping
1703    rectangle to use when drawing.  */
1704 
1705 static void
1706 w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
1707                    left_p, right_p, clip_rect)
1708      struct glyph_string *s;
1709      int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
1710      RECT *clip_rect;
1711 {
1712   w32_set_clip_rectangle (s->hdc, clip_rect);
1713 
1714   /* Top.  */
1715   w32_fill_area (s->f, s->hdc, s->face->box_color,
1716                   left_x, top_y, right_x - left_x + 1, width);
1717 
1718   /* Left.  */
1719   if (left_p)
1720     {
1721       w32_fill_area (s->f, s->hdc, s->face->box_color,
1722                      left_x, top_y, width, bottom_y - top_y + 1);
1723     }
1724 
1725   /* Bottom.  */
1726   w32_fill_area (s->f, s->hdc, s->face->box_color,
1727                  left_x, bottom_y - width + 1, right_x - left_x + 1, width);
1728 
1729   /* Right.  */
1730   if (right_p)
1731     {
1732       w32_fill_area (s->f, s->hdc, s->face->box_color,
1733                      right_x - width + 1, top_y, width, bottom_y - top_y + 1);
1734     }
1735 
1736   w32_set_clip_rectangle (s->hdc, NULL);
1737 }
1738 
1739 
1740 /* Draw a box around glyph string S.  */
1741 
1742 static void
1743 x_draw_glyph_string_box (s)
1744      struct glyph_string *s;
1745 {
1746   int width, left_x, right_x, top_y, bottom_y, last_x, raised_p;
1747   int left_p, right_p;
1748   struct glyph *last_glyph;
1749   RECT clip_rect;
1750 
1751   last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
1752             ? WINDOW_RIGHT_EDGE_X (s->w)
1753             : window_box_right (s->w, s->area));
1754 
1755   /* The glyph that may have a right box line.  */
1756   last_glyph = (s->cmp || s->img
1757                 ? s->first_glyph
1758                 : s->first_glyph + s->nchars - 1);
1759 
1760   width = eabs (s->face->box_line_width);
1761   raised_p = s->face->box == FACE_RAISED_BOX;
1762   left_x = s->x;
1763   right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p
1764               ? last_x - 1
1765               : min (last_x, s->x + s->background_width) - 1));
1766   top_y = s->y;
1767   bottom_y = top_y + s->height - 1;
1768 
1769   left_p = (s->first_glyph->left_box_line_p
1770             || (s->hl == DRAW_MOUSE_FACE
1771                 && (s->prev == NULL
1772                     || s->prev->hl != s->hl)));
1773   right_p = (last_glyph->right_box_line_p
1774              || (s->hl == DRAW_MOUSE_FACE
1775                  && (s->next == NULL
1776                      || s->next->hl != s->hl)));
1777 
1778   get_glyph_string_clip_rect (s, &clip_rect);
1779 
1780   if (s->face->box == FACE_SIMPLE_BOX)
1781     w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
1782                        left_p, right_p, &clip_rect);
1783   else
1784     {
1785       x_setup_relief_colors (s);
1786       w32_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
1787                             width, raised_p, 1, 1, left_p, right_p, &clip_rect);
1788     }
1789 }
1790 
1791 
1792 /* Draw foreground of image glyph string S.  */
1793 
1794 static void
1795 x_draw_image_foreground (s)
1796      struct glyph_string *s;
1797 {
1798   int x = s->x;
1799   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1800 
1801   /* If first glyph of S has a left box line, start drawing it to the
1802      right of that line.  */
1803   if (s->face->box != FACE_NO_BOX
1804       && s->first_glyph->left_box_line_p
1805       && s->slice.x == 0)
1806     x += eabs (s->face->box_line_width);
1807 
1808   /* If there is a margin around the image, adjust x- and y-position
1809      by that margin.  */
1810   if (s->slice.x == 0)
1811     x += s->img->hmargin;
1812   if (s->slice.y == 0)
1813     y += s->img->vmargin;
1814 
1815   SaveDC (s->hdc);
1816 
1817   if (s->img->pixmap)
1818     {
1819       HDC compat_hdc = CreateCompatibleDC (s->hdc);
1820       HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
1821       HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
1822       HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
1823       SetBkColor (compat_hdc, RGB (255, 255, 255));
1824       SetTextColor (s->hdc, RGB (0, 0, 0));
1825       x_set_glyph_string_clipping (s);
1826 
1827       if (s->img->mask)
1828         {
1829           HDC mask_dc = CreateCompatibleDC (s->hdc);
1830           HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
1831 
1832           SetTextColor (s->hdc, RGB (255, 255, 255));
1833           SetBkColor (s->hdc, RGB (0, 0, 0));
1834 
1835           BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1836                   compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1837           BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1838                   mask_dc, s->slice.x, s->slice.y, SRCAND);
1839           BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1840                   compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1841 
1842           SelectObject (mask_dc, mask_orig_obj);
1843           DeleteDC (mask_dc);
1844         }
1845       else
1846         {
1847           SetTextColor (s->hdc, s->gc->foreground);
1848           SetBkColor (s->hdc, s->gc->background);
1849 
1850           BitBlt (s->hdc, x, y, s->slice.width, s->slice.height,
1851                   compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
1852 
1853           /* When the image has a mask, we can expect that at
1854              least part of a mouse highlight or a block cursor will
1855              be visible.  If the image doesn't have a mask, make
1856              a block cursor visible by drawing a rectangle around
1857              the image.  I believe it's looking better if we do
1858              nothing here for mouse-face.  */
1859           if (s->hl == DRAW_CURSOR)
1860             {
1861               int r = s->img->relief;
1862               if (r < 0) r = -r;
1863               w32_draw_rectangle (s->hdc, s->gc, x - r, y - r ,
1864                                   s->slice.width + r*2 - 1,
1865                                   s->slice.height + r*2 - 1);
1866             }
1867         }
1868 
1869       w32_set_clip_rectangle (s->hdc, NULL);
1870       SelectObject (s->hdc, orig_brush);
1871       DeleteObject (fg_brush);
1872       SelectObject (compat_hdc, orig_obj);
1873       DeleteDC (compat_hdc);
1874     }
1875   else
1876     w32_draw_rectangle (s->hdc, s->gc, x, y,
1877                         s->slice.width - 1, s->slice.height - 1);
1878 
1879   RestoreDC (s->hdc ,-1);
1880 }
1881 
1882 
1883 /* Draw a relief around the image glyph string S.  */
1884 
1885 static void
1886 x_draw_image_relief (s)
1887      struct glyph_string *s;
1888 {
1889   int x0, y0, x1, y1, thick, raised_p;
1890   RECT r;
1891   int x = s->x;
1892   int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
1893 
1894   /* If first glyph of S has a left box line, start drawing it to the
1895      right of that line.  */
1896   if (s->face->box != FACE_NO_BOX
1897       && s->first_glyph->left_box_line_p
1898       && s->slice.x == 0)
1899     x += eabs (s->face->box_line_width);
1900 
1901   /* If there is a margin around the image, adjust x- and y-position
1902      by that margin.  */
1903   if (s->slice.x == 0)
1904     x += s->img->hmargin;
1905   if (s->slice.y == 0)
1906     y += s->img->vmargin;
1907 
1908   if (s->hl == DRAW_IMAGE_SUNKEN
1909       || s->hl == DRAW_IMAGE_RAISED)
1910     {
1911       thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF;
1912       raised_p = s->hl == DRAW_IMAGE_RAISED;
1913     }
1914   else
1915     {
1916       thick = eabs (s->img->relief);
1917       raised_p = s->img->relief > 0;
1918     }
1919 
1920   x0 = x - thick;
1921   y0 = y - thick;
1922   x1 = x + s->slice.width + thick - 1;
1923   y1 = y + s->slice.height + thick - 1;
1924 
1925   x_setup_relief_colors (s);
1926   get_glyph_string_clip_rect (s, &r);
1927   w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
1928                         s->slice.y == 0,
1929                         s->slice.y + s->slice.height == s->img->height,
1930                         s->slice.x == 0,
1931                         s->slice.x + s->slice.width == s->img->width,
1932                         &r);
1933 }
1934 
1935 
1936 /* Draw the foreground of image glyph string S to PIXMAP.  */
1937 
1938 static void
1939 w32_draw_image_foreground_1 (s, pixmap)
1940      struct glyph_string *s;
1941      HBITMAP pixmap;
1942 {
1943   HDC hdc = CreateCompatibleDC (s->hdc);
1944   HGDIOBJ orig_hdc_obj = SelectObject (hdc, pixmap);
1945   int x = 0;
1946   int y = s->ybase - s->y - image_ascent (s->img, s->face, &s->slice);
1947 
1948   /* If first glyph of S has a left box line, start drawing it to the
1949      right of that line.  */
1950   if (s->face->box != FACE_NO_BOX
1951       && s->first_glyph->left_box_line_p
1952       && s->slice.x == 0)
1953     x += eabs (s->face->box_line_width);
1954 
1955   /* If there is a margin around the image, adjust x- and y-position
1956      by that margin.  */
1957   if (s->slice.x == 0)
1958     x += s->img->hmargin;
1959   if (s->slice.y == 0)
1960     y += s->img->vmargin;
1961 
1962   if (s->img->pixmap)
1963     {
1964       HDC compat_hdc = CreateCompatibleDC (hdc);
1965       HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
1966       HBRUSH orig_brush = SelectObject (hdc, fg_brush);
1967       HGDIOBJ orig_obj = SelectObject (compat_hdc, s->img->pixmap);
1968 
1969       if (s->img->mask)
1970         {
1971           HDC mask_dc = CreateCompatibleDC (hdc);
1972           HGDIOBJ mask_orig_obj = SelectObject (mask_dc, s->img->mask);
1973 
1974           SetTextColor (hdc, RGB (0, 0, 0));
1975           SetBkColor (hdc, RGB (255, 255, 255));
1976           BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1977                   compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1978           BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1979                   mask_dc, s->slice.x, s->slice.y, SRCAND);
1980           BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1981                   compat_hdc, s->slice.x, s->slice.y, SRCINVERT);
1982 
1983           SelectObject (mask_dc, mask_orig_obj);
1984           DeleteDC (mask_dc);
1985         }
1986       else
1987         {
1988           SetTextColor (hdc, s->gc->foreground);
1989           SetBkColor (hdc, s->gc->background);
1990 
1991           BitBlt (hdc, x, y, s->slice.width, s->slice.height,
1992                   compat_hdc, s->slice.x, s->slice.y, SRCCOPY);
1993 
1994           /* When the image has a mask, we can expect that at
1995              least part of a mouse highlight or a block cursor will
1996              be visible.  If the image doesn't have a mask, make
1997              a block cursor visible by drawing a rectangle around
1998              the image.  I believe it's looking better if we do
1999              nothing here for mouse-face.  */
2000           if (s->hl == DRAW_CURSOR)
2001             {
2002               int r = s->img->relief;
2003               if (r < 0) r = -r;
2004               w32_draw_rectangle (hdc, s->gc, x - r, y - r,
2005                                   s->slice.width + r*2 - 1,
2006                                   s->slice.height + r*2 - 1);
2007             }
2008         }
2009 
2010       SelectObject (hdc, orig_brush);
2011       DeleteObject (fg_brush);
2012       SelectObject (compat_hdc, orig_obj);
2013       DeleteDC (compat_hdc);
2014     }
2015   else
2016     w32_draw_rectangle (hdc, s->gc, x, y,
2017                         s->slice.width - 1, s->slice.height - 1);
2018 
2019   SelectObject (hdc, orig_hdc_obj);
2020   DeleteDC (hdc);
2021 }
2022 
2023 
2024 /* Draw part of the background of glyph string S.  X, Y, W, and H
2025    give the rectangle to draw.  */
2026 
2027 static void
2028 x_draw_glyph_string_bg_rect (s, x, y, w, h)
2029      struct glyph_string *s;
2030      int x, y, w, h;
2031 {
2032 #if 0 /* TODO: stipple */
2033   if (s->stippled_p)
2034     {
2035       /* Fill background with a stipple pattern.  */
2036       XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2037       XFillRectangle (s->display, s->window, s->gc, x, y, w, h);
2038       XSetFillStyle (s->display, s->gc, FillSolid);
2039     }
2040   else
2041 #endif
2042     x_clear_glyph_string_rect (s, x, y, w, h);
2043 }
2044 
2045 
2046 /* Draw image glyph string S.
2047 
2048             s->y
2049    s->x      +-------------------------
2050              |   s->face->box
2051              |
2052              |     +-------------------------
2053              |     |  s->img->vmargin
2054              |     |
2055              |     |       +-------------------
2056              |     |       |  the image
2057 
2058  */
2059 
2060 static void
2061 x_draw_image_glyph_string (s)
2062      struct glyph_string *s;
2063 {
2064   int x, y;
2065   int box_line_hwidth = eabs (s->face->box_line_width);
2066   int box_line_vwidth = max (s->face->box_line_width, 0);
2067   int height;
2068   HBITMAP pixmap = 0;
2069 
2070   height = s->height - 2 * box_line_vwidth;
2071 
2072   /* Fill background with face under the image.  Do it only if row is
2073      taller than image or if image has a clip mask to reduce
2074      flickering.  */
2075   s->stippled_p = s->face->stipple != 0;
2076   if (height > s->slice.height
2077       || s->img->hmargin
2078       || s->img->vmargin
2079       || s->img->mask
2080       || s->img->pixmap == 0
2081       || s->width != s->background_width)
2082     {
2083       x = s->x;
2084       if (s->first_glyph->left_box_line_p
2085           && s->slice.x == 0)
2086         x += box_line_hwidth;
2087 
2088       y = s->y;
2089       if (s->slice.y == 0)
2090         y += box_line_vwidth;
2091 
2092 #if 0 /* TODO: figure out if we need to do this on Windows.  */
2093       if (s->img->mask)
2094         {
2095           /* Create a pixmap as large as the glyph string.  Fill it
2096              with the background color.  Copy the image to it, using
2097              its mask.  Copy the temporary pixmap to the display.  */
2098           Screen *screen = FRAME_X_SCREEN (s->f);
2099           int depth = DefaultDepthOfScreen (screen);
2100 
2101           /* Create a pixmap as large as the glyph string.  */
2102           pixmap = XCreatePixmap (s->display, s->window,
2103                                   s->background_width,
2104                                   s->height, depth);
2105 
2106           /* Don't clip in the following because we're working on the
2107              pixmap.  */
2108           XSetClipMask (s->display, s->gc, None);
2109 
2110           /* Fill the pixmap with the background color/stipple.  */
2111           if (s->stippled_p)
2112             {
2113               /* Fill background with a stipple pattern.  */
2114               XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2115               XFillRectangle (s->display, pixmap, s->gc,
2116                               0, 0, s->background_width, s->height);
2117               XSetFillStyle (s->display, s->gc, FillSolid);
2118             }
2119           else
2120             {
2121               XGCValues xgcv;
2122               XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
2123                             &xgcv);
2124               XSetForeground (s->display, s->gc, xgcv.background);
2125               XFillRectangle (s->display, pixmap, s->gc,
2126                               0, 0, s->background_width, s->height);
2127               XSetForeground (s->display, s->gc, xgcv.foreground);
2128             }
2129         }
2130       else
2131 #endif
2132         x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
2133 
2134       s->background_filled_p = 1;
2135     }
2136 
2137   /* Draw the foreground.  */
2138   if (pixmap != 0)
2139     {
2140       w32_draw_image_foreground_1 (s, pixmap);
2141       x_set_glyph_string_clipping (s);
2142       {
2143         HDC compat_hdc = CreateCompatibleDC (s->hdc);
2144         HBRUSH fg_brush = CreateSolidBrush (s->gc->foreground);
2145         HBRUSH orig_brush = SelectObject (s->hdc, fg_brush);
2146         HGDIOBJ orig_obj = SelectObject (compat_hdc, pixmap);
2147 
2148         SetTextColor (s->hdc, s->gc->foreground);
2149         SetBkColor (s->hdc, s->gc->background);
2150         BitBlt (s->hdc, s->x, s->y, s->background_width, s->height,
2151                 compat_hdc, 0, 0, SRCCOPY);
2152 
2153         SelectObject (s->hdc, orig_brush);
2154         DeleteObject (fg_brush);
2155         SelectObject (compat_hdc, orig_obj);
2156         DeleteDC (compat_hdc);
2157       }
2158       DeleteObject (pixmap);
2159       pixmap = 0;
2160     }
2161   else
2162     x_draw_image_foreground (s);
2163 
2164   /* If we must draw a relief around the image, do it.  */
2165   if (s->img->relief
2166       || s->hl == DRAW_IMAGE_RAISED
2167       || s->hl == DRAW_IMAGE_SUNKEN)
2168     x_draw_image_relief (s);
2169 }
2170 
2171 
2172 /* Draw stretch glyph string S.  */
2173 
2174 static void
2175 x_draw_stretch_glyph_string (s)
2176      struct glyph_string *s;
2177 {
2178   xassert (s->first_glyph->type == STRETCH_GLYPH);
2179 
2180   if (s->hl == DRAW_CURSOR
2181       && !x_stretch_cursor_p)
2182     {
2183       /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
2184          as wide as the stretch glyph.  */
2185       int width, background_width = s->background_width;
2186       int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
2187 
2188       if (x < left_x)
2189         {
2190           background_width -= left_x - x;
2191           x = left_x;
2192         }
2193       width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
2194 
2195       /* Draw cursor.  */
2196       x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
2197 
2198       /* Clear rest using the GC of the original non-cursor face.  */
2199       if (width < background_width)
2200         {
2201           XGCValues *gc = s->face->gc;
2202           int y = s->y;
2203           int w = background_width - width, h = s->height;
2204           RECT r;
2205           HDC hdc = s->hdc;
2206 
2207           x += width;
2208           if (s->row->mouse_face_p
2209               && cursor_in_mouse_face_p (s->w))
2210             {
2211               x_set_mouse_face_gc (s);
2212               gc = s->gc;
2213             }
2214           else
2215             gc = s->face->gc;
2216 
2217           get_glyph_string_clip_rect (s, &r);
2218           w32_set_clip_rectangle (hdc, &r);
2219 
2220 #if 0 /* TODO: stipple */
2221           if (s->face->stipple)
2222             {
2223               /* Fill background with a stipple pattern.  */
2224               XSetFillStyle (s->display, gc, FillOpaqueStippled);
2225               XFillRectangle (s->display, s->window, gc, x, y, w, h);
2226               XSetFillStyle (s->display, gc, FillSolid);
2227             }
2228           else
2229 #endif
2230             {
2231               w32_fill_area (s->f, s->hdc, gc->background, x, y, w, h);
2232             }
2233         }
2234     }
2235   else if (!s->background_filled_p)
2236     {
2237       int background_width = s->background_width;
2238       int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
2239 
2240       /* Don't draw into left margin, fringe or scrollbar area
2241          except for header line and mode line.  */
2242       if (x < left_x && !s->row->mode_line_p)
2243         {
2244           background_width -= left_x - x;
2245           x = left_x;
2246         }
2247       if (background_width > 0)
2248         x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
2249     }
2250 
2251   s->background_filled_p = 1;
2252 }
2253 
2254 
2255 /* Draw glyph string S.  */
2256 
2257 static void
2258 x_draw_glyph_string (s)
2259      struct glyph_string *s;
2260 {
2261   int relief_drawn_p = 0;
2262 
2263   /* If S draws into the background of its successor, draw the
2264      background of the successor first so that S can draw into it.
2265      This makes S->next use XDrawString instead of XDrawImageString.  */
2266   if (s->next && s->right_overhang && !s->for_overlaps)
2267     {
2268       int width;
2269       struct glyph_string *next;
2270       for (width = 0, next = s->next;
2271            next && width < s->right_overhang;
2272            width += next->width, next = next->next)
2273         if (next->first_glyph->type != IMAGE_GLYPH)
2274           {
2275             x_set_glyph_string_gc (next);
2276             x_set_glyph_string_clipping (next);
2277             if (next->first_glyph->type == STRETCH_GLYPH)
2278               x_draw_stretch_glyph_string (next);
2279             else
2280               x_draw_glyph_string_background (next, 1);
2281             next->num_clips = 0;
2282           }
2283     }
2284 
2285   /* Set up S->gc, set clipping and draw S.  */
2286   x_set_glyph_string_gc (s);
2287 
2288   /* Draw relief (if any) in advance for char/composition so that the
2289      glyph string can be drawn over it.  */
2290   if (!s->for_overlaps
2291       && s->face->box != FACE_NO_BOX
2292       && (s->first_glyph->type == CHAR_GLYPH
2293           || s->first_glyph->type == COMPOSITE_GLYPH))
2294 
2295     {
2296       x_set_glyph_string_clipping (s);
2297       x_draw_glyph_string_background (s, 1);
2298       x_draw_glyph_string_box (s);
2299       x_set_glyph_string_clipping (s);
2300       relief_drawn_p = 1;
2301     }
2302   else if (!s->clip_head /* draw_glyphs didn't specify a clip mask.  */
2303            && !s->clip_tail
2304            && ((s->prev && s->prev->hl != s->hl && s->left_overhang)
2305                || (s->next && s->next->hl != s->hl && s->right_overhang)))
2306     /* We must clip just this glyph.  left_overhang part has already
2307        drawn when s->prev was drawn, and right_overhang part will be
2308        drawn later when s->next is drawn. */
2309     x_set_glyph_string_clipping_exactly (s, s);
2310   else
2311     x_set_glyph_string_clipping (s);
2312 
2313   switch (s->first_glyph->type)
2314     {
2315     case IMAGE_GLYPH:
2316       x_draw_image_glyph_string (s);
2317       break;
2318 
2319     case STRETCH_GLYPH:
2320       x_draw_stretch_glyph_string (s);
2321       break;
2322 
2323     case CHAR_GLYPH:
2324       if (s->for_overlaps)
2325         s->background_filled_p = 1;
2326       else
2327         x_draw_glyph_string_background (s, 0);
2328       x_draw_glyph_string_foreground (s);
2329       break;
2330 
2331     case COMPOSITE_GLYPH:
2332       if (s->for_overlaps || (s->cmp_from > 0
2333                               && ! s->first_glyph->u.cmp.automatic))
2334         s->background_filled_p = 1;
2335       else
2336         x_draw_glyph_string_background (s, 1);
2337       x_draw_composite_glyph_string_foreground (s);
2338       break;
2339 
2340     default:
2341       abort ();
2342     }
2343 
2344   if (!s->for_overlaps)
2345     {
2346       /* Draw underline.  */
2347       if (s->face->underline_p)
2348         {
2349           unsigned long thickness, position;
2350           int y;
2351 
2352           if (s->prev && s->prev->face->underline_p)
2353             {
2354               /* We use the same underline style as the previous one.  */
2355               thickness = s->prev->underline_thickness;
2356               position = s->prev->underline_position;
2357             }
2358           else
2359             {
2360               /* Get the underline thickness.  Default is 1 pixel.  */
2361               if (s->font && s->font->underline_thickness > 0)
2362                 thickness = s->font->underline_thickness;
2363               else
2364                 thickness = 1;
2365               if (x_underline_at_descent_line)
2366                 position = (s->height - thickness) - (s->ybase - s->y);
2367               else
2368                 {
2369                 /* Get the underline position.  This is the recommended
2370                    vertical offset in pixels from the baseline to the top of
2371                    the underline.  This is a signed value according to the
2372                    specs, and its default is
2373 
2374                    ROUND ((maximum_descent) / 2), with
2375                    ROUND (x) = floor (x + 0.5)  */
2376 
2377                 if (x_use_underline_position_properties
2378                     && s->font && s->font->underline_position >= 0)
2379                   position = s->font->underline_position;
2380                 else if (s->font)
2381                   position = (s->font->descent + 1) / 2;
2382                 }
2383               position = max (position, underline_minimum_offset);
2384             }
2385           /* Check the sanity of thickness and position.  We should
2386              avoid drawing underline out of the current line area.  */
2387           if (s->y + s->height <= s->ybase + position)
2388             position = (s->height - 1) - (s->ybase - s->y);
2389           if (s->y + s->height < s->ybase + position + thickness)
2390             thickness = (s->y + s->height) - (s->ybase + position);
2391           s->underline_thickness = thickness;
2392           s->underline_position =position;
2393           y = s->ybase + position;
2394           if (s->face->underline_defaulted_p)
2395             {
2396               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2397                              y, s->width, 1);
2398             }
2399           else
2400             {
2401               w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
2402                              y, s->width, 1);
2403             }
2404         }
2405       /* Draw overline.  */
2406       if (s->face->overline_p)
2407         {
2408           unsigned long dy = 0, h = 1;
2409 
2410           if (s->face->overline_color_defaulted_p)
2411             {
2412               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
2413                              s->y + dy, s->width, h);
2414             }
2415           else
2416             {
2417               w32_fill_area (s->f, s->hdc, s->face->overline_color, s->x,
2418                              s->y + dy, s->width, h);
2419             }
2420         }
2421 
2422       /* Draw strike-through.  */
2423       if (s->face->strike_through_p
2424           && !FONT_TEXTMETRIC(s->font).tmStruckOut)
2425         {
2426           unsigned long h = 1;
2427           unsigned long dy = (s->height - h) / 2;
2428 
2429           if (s->face->strike_through_color_defaulted_p)
2430             {
2431               w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x, s->y + dy,
2432                              s->width, h);
2433             }
2434           else
2435             {
2436               w32_fill_area (s->f, s->hdc, s->face->strike_through_color, s->x,
2437                              s->y + dy, s->width, h);
2438             }
2439         }
2440 
2441       /* Draw relief if not yet drawn.  */
2442       if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
2443         x_draw_glyph_string_box (s);
2444 
2445       if (s->prev)
2446         {
2447           struct glyph_string *prev;
2448 
2449           for (prev = s->prev; prev; prev = prev->prev)
2450             if (prev->hl != s->hl
2451                 && prev->x + prev->width + prev->right_overhang > s->x)
2452               {
2453                 /* As prev was drawn while clipped to its own area, we
2454                    must draw the right_overhang part using s->hl now.  */
2455                 enum draw_glyphs_face save = prev->hl;
2456 
2457                 prev->hl = s->hl;
2458                 x_set_glyph_string_gc (prev);
2459                 x_set_glyph_string_clipping_exactly (s, prev);
2460                 if (prev->first_glyph->type == CHAR_GLYPH)
2461                   x_draw_glyph_string_foreground (prev);
2462                 else
2463                   x_draw_composite_glyph_string_foreground (prev);
2464                 w32_set_clip_rectangle (prev->hdc, NULL);
2465                 prev->hl = save;
2466                 prev->num_clips = 0;
2467               }
2468         }
2469 
2470       if (s->next)
2471         {
2472           struct glyph_string *next;
2473 
2474           for (next = s->next; next; next = next->next)
2475             if (next->hl != s->hl
2476                 && next->x - next->left_overhang < s->x + s->width)
2477               {
2478                 /* As next will be drawn while clipped to its own area,
2479                    we must draw the left_overhang part using s->hl now.  */
2480                 enum draw_glyphs_face save = next->hl;
2481 
2482                 next->hl = s->hl;
2483                 x_set_glyph_string_gc (next);
2484                 x_set_glyph_string_clipping_exactly (s, next);
2485                 if (next->first_glyph->type == CHAR_GLYPH)
2486                   x_draw_glyph_string_foreground (next);
2487                 else
2488                   x_draw_composite_glyph_string_foreground (next);
2489                 w32_set_clip_rectangle (next->hdc, NULL);
2490                 next->hl = save;
2491                 next->num_clips = 0;
2492               }
2493         }
2494     }
2495 
2496   /* Reset clipping.  */
2497   w32_set_clip_rectangle (s->hdc, NULL);
2498   s->num_clips = 0;
2499 }
2500 
2501 
2502 /* Shift display to make room for inserted glyphs.   */
2503 
2504 void
2505 w32_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
2506      struct frame *f;
2507      int x, y, width, height, shift_by;
2508 {
2509   HDC hdc;
2510 
2511   hdc = get_frame_dc (f);
2512   BitBlt (hdc, x + shift_by, y, width, height,
2513           hdc, x, y, SRCCOPY);
2514 
2515   release_frame_dc (f, hdc);
2516 }
2517 
2518 
2519 /* Delete N glyphs at the nominal cursor position.  Not implemented
2520    for X frames.  */
2521 
2522 static void
2523 x_delete_glyphs (f, n)
2524      struct frame *f;
2525      register int n;
2526 {
2527   if (! FRAME_W32_P (f))
2528     return;
2529 
2530   abort ();
2531 }
2532 
2533 
2534 /* Clear entire frame.  If updating_frame is non-null, clear that
2535    frame.  Otherwise clear the selected frame.  */
2536 
2537 static void
2538 x_clear_frame (struct frame *f)
2539 {
2540   if (! FRAME_W32_P (f))
2541     return;
2542 
2543   /* Clearing the frame will erase any cursor, so mark them all as no
2544      longer visible.  */
2545   mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
2546   output_cursor.hpos = output_cursor.vpos = 0;
2547   output_cursor.x = -1;
2548 
2549   /* We don't set the output cursor here because there will always
2550      follow an explicit cursor_to.  */
2551   BLOCK_INPUT;
2552 
2553   w32_clear_window (f);
2554 
2555   /* We have to clear the scroll bars, too.  If we have changed
2556      colors or something like that, then they should be notified.  */
2557   x_scroll_bar_clear (f);
2558 
2559   UNBLOCK_INPUT;
2560 }
2561 
2562 
2563 /* Make audible bell.  */
2564 
2565 static void
2566 w32_ring_bell (struct frame *f)
2567 {
2568   BLOCK_INPUT;
2569 
2570   if (FRAME_W32_P (f) && visible_bell)
2571     {
2572       int i;
2573       HWND hwnd = FRAME_W32_WINDOW (f);
2574 
2575       for (i = 0; i < 5; i++)
2576         {
2577           FlashWindow (hwnd, TRUE);
2578           Sleep (10);
2579         }
2580       FlashWindow (hwnd, FALSE);
2581     }
2582   else
2583       w32_sys_ring_bell (f);
2584 
2585   UNBLOCK_INPUT;
2586 }
2587 
2588 
2589 /* Specify how many text lines, from the top of the window,
2590    should be affected by insert-lines and delete-lines operations.
2591    This, and those operations, are used only within an update
2592    that is bounded by calls to x_update_begin and x_update_end.  */
2593 
2594 static void
2595 w32_set_terminal_window (n)
2596      register int n;
2597 {
2598   /* This function intentionally left blank.  */
2599 }
2600 
2601 
2602 /***********************************************************************
2603                               Line Dance
2604  ***********************************************************************/
2605 
2606 /* Perform an insert-lines or delete-lines operation, inserting N
2607    lines or deleting -N lines at vertical position VPOS.  */
2608 
2609 static void
2610 x_ins_del_lines (f, vpos, n)
2611      struct frame *f;
2612      int vpos, n;
2613 {
2614   if (! FRAME_W32_P (f))
2615     return;
2616 
2617   abort ();
2618 }
2619 
2620 
2621 /* Scroll part of the display as described by RUN.  */
2622 
2623 static void
2624 x_scroll_run (w, run)
2625      struct window *w;
2626      struct run *run;
2627 {
2628   struct frame *f = XFRAME (w->frame);
2629   int x, y, width, height, from_y, to_y, bottom_y;
2630   HWND hwnd = FRAME_W32_WINDOW (f);
2631   HRGN expect_dirty;
2632 
2633   /* Get frame-relative bounding box of the text display area of W,
2634      without mode lines.  Include in this box the left and right
2635      fringes of W.  */
2636   window_box (w, -1, &x, &y, &width, &height);
2637 
2638   from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
2639   to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y);
2640   bottom_y = y + height;
2641 
2642   if (to_y < from_y)
2643     {
2644       /* Scrolling up.  Make sure we don't copy part of the mode
2645          line at the bottom.  */
2646       if (from_y + run->height > bottom_y)
2647         height = bottom_y - from_y;
2648       else
2649         height = run->height;
2650       expect_dirty = CreateRectRgn (x, y + height, x + width, bottom_y);
2651     }
2652   else
2653     {
2654       /* Scolling down.  Make sure we don't copy over the mode line.
2655          at the bottom.  */
2656       if (to_y + run->height > bottom_y)
2657         height = bottom_y - to_y;
2658       else
2659         height = run->height;
2660       expect_dirty = CreateRectRgn (x, y, x + width, to_y);
2661     }
2662 
2663   BLOCK_INPUT;
2664 
2665   /* Cursor off.  Will be switched on again in x_update_window_end.  */
2666   updated_window = w;
2667   x_clear_cursor (w);
2668 
2669   {
2670     RECT from;
2671     RECT to;
2672     HRGN dirty = CreateRectRgn (0, 0, 0, 0);
2673     HRGN combined = CreateRectRgn (0, 0, 0, 0);
2674 
2675     from.left = to.left = x;
2676     from.right = to.right = x + width;
2677     from.top = from_y;
2678     from.bottom = from_y + height;
2679     to.top = y;
2680     to.bottom = bottom_y;
2681 
2682     ScrollWindowEx (hwnd, 0, to_y - from_y, &from, &to, dirty,
2683                     NULL, SW_INVALIDATE);
2684 
2685     /* Combine this with what we expect to be dirty. This covers the
2686        case where not all of the region we expect is actually dirty.  */
2687     CombineRgn (combined, dirty, expect_dirty, RGN_OR);
2688 
2689     /* If the dirty region is not what we expected, redraw the entire frame.  */
2690     if (!EqualRgn (combined, expect_dirty))
2691       SET_FRAME_GARBAGED (f);
2692 
2693     DeleteObject (dirty);
2694     DeleteObject (combined);
2695   }
2696 
2697   UNBLOCK_INPUT;
2698   DeleteObject (expect_dirty);
2699 }
2700 
2701 
2702 
2703 /***********************************************************************
2704                            Exposure Events
2705  ***********************************************************************/
2706 
2707 static void
2708 frame_highlight (f)
2709      struct frame *f;
2710 {
2711   x_update_cursor (f, 1);
2712   x_set_frame_alpha (f);
2713 }
2714 
2715 static void
2716 frame_unhighlight (f)
2717      struct frame *f;
2718 {
2719   x_update_cursor (f, 1);
2720   x_set_frame_alpha (f);
2721 }
2722 
2723 /* The focus has changed.  Update the frames as necessary to reflect
2724    the new situation.  Note that we can't change the selected frame
2725    here, because the Lisp code we are interrupting might become confused.
2726    Each event gets marked with the frame in which it occurred, so the
2727    Lisp code can tell when the switch took place by examining the events.  */
2728 
2729 static void
2730 x_new_focus_frame (dpyinfo, frame)
2731      struct w32_display_info *dpyinfo;
2732      struct frame *frame;
2733 {
2734   struct frame *old_focus = dpyinfo->w32_focus_frame;
2735 
2736   if (frame != dpyinfo->w32_focus_frame)
2737     {
2738       /* Set this before calling other routines, so that they see
2739          the correct value of w32_focus_frame.  */
2740       dpyinfo->w32_focus_frame = frame;
2741 
2742       if (old_focus && old_focus->auto_lower)
2743         x_lower_frame (old_focus);
2744 
2745       if (dpyinfo->w32_focus_frame && dpyinfo->w32_focus_frame->auto_raise)
2746         pending_autoraise_frame = dpyinfo->w32_focus_frame;
2747       else
2748         pending_autoraise_frame = 0;
2749     }
2750 
2751   x_frame_rehighlight (dpyinfo);
2752 }
2753 
2754 
2755 /* Handle FocusIn and FocusOut state changes for FRAME.
2756    If FRAME has focus and there exists more than one frame, puts
2757    a FOCUS_IN_EVENT into *BUFP.  */
2758 
2759 static void
2760 x_focus_changed (type, state, dpyinfo, frame, bufp)
2761      int type;
2762      int state;
2763      struct w32_display_info *dpyinfo;
2764      struct frame *frame;
2765      struct input_event *bufp;
2766 {
2767   if (type == WM_SETFOCUS)
2768     {
2769       if (dpyinfo->w32_focus_event_frame != frame)
2770         {
2771           x_new_focus_frame (dpyinfo, frame);
2772           dpyinfo->w32_focus_event_frame = frame;
2773 
2774           /* Don't stop displaying the initial startup message
2775              for a switch-frame event we don't need.  */
2776           if (NILP (Vterminal_frame)
2777               && CONSP (Vframe_list)
2778               && !NILP (XCDR (Vframe_list)))
2779             {
2780               bufp->kind = FOCUS_IN_EVENT;
2781               XSETFRAME (bufp->frame_or_window, frame);
2782             }
2783         }
2784 
2785       frame->output_data.x->focus_state |= state;
2786 
2787       /* TODO: IME focus?  */
2788     }
2789   else if (type == WM_KILLFOCUS)
2790     {
2791       frame->output_data.x->focus_state &= ~state;
2792 
2793       if (dpyinfo->w32_focus_event_frame == frame)
2794         {
2795           dpyinfo->w32_focus_event_frame = 0;
2796           x_new_focus_frame (dpyinfo, 0);
2797         }
2798 
2799       /* TODO: IME focus?  */
2800     }
2801 }
2802 
2803 
2804 /* The focus may have changed.  Figure out if it is a real focus change,
2805    by checking both FocusIn/Out and Enter/LeaveNotify events.
2806 
2807    Returns FOCUS_IN_EVENT event in *BUFP. */
2808 
2809 static void
2810 w32_detect_focus_change (dpyinfo, event, bufp)
2811      struct w32_display_info *dpyinfo;
2812      W32Msg *event;
2813      struct input_event *bufp;
2814 {
2815   struct frame *frame;
2816 
2817   frame = x_any_window_to_frame (dpyinfo, event->msg.hwnd);
2818   if (! frame)
2819     return;
2820 
2821   /* On w32, this is only called from focus events, so no switch needed.  */
2822   x_focus_changed (event->msg.message,
2823                    (event->msg.message == WM_KILLFOCUS ?
2824                     FOCUS_IMPLICIT : FOCUS_EXPLICIT),
2825                    dpyinfo, frame, bufp);
2826 }
2827 
2828 
2829 /* Handle an event saying the mouse has moved out of an Emacs frame.  */
2830 
2831 void
2832 x_mouse_leave (dpyinfo)
2833      struct w32_display_info *dpyinfo;
2834 {
2835   x_new_focus_frame (dpyinfo, dpyinfo->w32_focus_event_frame);
2836 }
2837 
2838 /* The focus has changed, or we have redirected a frame's focus to
2839    another frame (this happens when a frame uses a surrogate
2840    mini-buffer frame).  Shift the highlight as appropriate.
2841 
2842    The FRAME argument doesn't necessarily have anything to do with which
2843    frame is being highlighted or un-highlighted; we only use it to find
2844    the appropriate X display info.  */
2845 
2846 static void
2847 w32_frame_rehighlight (frame)
2848      struct frame *frame;
2849 {
2850   if (! FRAME_W32_P (frame))
2851     return;
2852   x_frame_rehighlight (FRAME_W32_DISPLAY_INFO (frame));
2853 }
2854 
2855 static void
2856 x_frame_rehighlight (dpyinfo)
2857      struct w32_display_info *dpyinfo;
2858 {
2859   struct frame *old_highlight = dpyinfo->x_highlight_frame;
2860 
2861   if (dpyinfo->w32_focus_frame)
2862     {
2863       dpyinfo->x_highlight_frame
2864         = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame)))
2865            ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame))
2866            : dpyinfo->w32_focus_frame);
2867       if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
2868         {
2869           FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
2870           dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
2871         }
2872     }
2873   else
2874     dpyinfo->x_highlight_frame = 0;
2875 
2876   if (dpyinfo->x_highlight_frame != old_highlight)
2877     {
2878       if (old_highlight)
2879         frame_unhighlight (old_highlight);
2880       if (dpyinfo->x_highlight_frame)
2881         frame_highlight (dpyinfo->x_highlight_frame);
2882     }
2883 }
2884 
2885 /* Keyboard processing - modifier keys, etc. */
2886 
2887 /* Convert a keysym to its name.  */
2888 
2889 char *
2890 x_get_keysym_name (keysym)
2891     int keysym;
2892 {
2893   /* Make static so we can always return it */
2894   static char value[100];
2895 
2896   BLOCK_INPUT;
2897   GetKeyNameText (keysym, value, 100);
2898   UNBLOCK_INPUT;
2899 
2900   return value;
2901 }
2902 
2903 static int codepage_for_locale(LCID locale)
2904 {
2905   char cp[20];
2906 
2907   if (GetLocaleInfo (locale, LOCALE_IDEFAULTANSICODEPAGE, cp, 20) > 0)
2908     return atoi (cp);
2909   else
2910     return CP_ACP;
2911 }
2912 
2913 
2914 /* Mouse clicks and mouse movement.  Rah.  */
2915 
2916 /* Parse a button MESSAGE. The button index is returned in PBUTTON, and
2917    the state in PUP. XBUTTON provides extra information for extended mouse
2918    button messages. Returns FALSE if unable to parse the message.  */
2919 BOOL
2920 parse_button (message, xbutton, pbutton, pup)
2921      int message;
2922      int xbutton;
2923      int * pbutton;
2924      int * pup;
2925 {
2926   int button = 0;
2927   int up = 0;
2928 
2929   switch (message)
2930     {
2931     case WM_LBUTTONDOWN:
2932       button = 0;
2933       up = 0;
2934       break;
2935     case WM_LBUTTONUP:
2936       button = 0;
2937       up = 1;
2938       break;
2939     case WM_MBUTTONDOWN:
2940       if (NILP (Vw32_swap_mouse_buttons))
2941         button = 1;
2942       else
2943         button = 2;
2944       up = 0;
2945       break;
2946     case WM_MBUTTONUP:
2947       if (NILP (Vw32_swap_mouse_buttons))
2948         button = 1;
2949       else
2950         button = 2;
2951       up = 1;
2952       break;
2953     case WM_RBUTTONDOWN:
2954       if (NILP (Vw32_swap_mouse_buttons))
2955         button = 2;
2956       else
2957         button = 1;
2958       up = 0;
2959       break;
2960     case WM_RBUTTONUP:
2961       if (NILP (Vw32_swap_mouse_buttons))
2962         button = 2;
2963       else
2964         button = 1;
2965       up = 1;
2966       break;
2967     case WM_XBUTTONDOWN:
2968       button = xbutton + 2;
2969       up = 0;
2970       break;
2971     case WM_XBUTTONUP:
2972       button = xbutton + 2;
2973       up = 1;
2974       break;
2975     default:
2976       return (FALSE);
2977     }
2978 
2979   if (pup) *pup = up;
2980   if (pbutton) *pbutton = button;
2981 
2982   return (TRUE);
2983 }
2984 
2985 
2986 /* Prepare a mouse-event in *RESULT for placement in the input queue.
2987 
2988    If the event is a button press, then note that we have grabbed
2989    the mouse.  */
2990 
2991 static Lisp_Object
2992 construct_mouse_click (result, msg, f)
2993      struct input_event *result;
2994      W32Msg *msg;
2995      struct frame *f;
2996 {
2997   int button;
2998   int up;
2999 
3000   parse_button (msg->msg.message, HIWORD (msg->msg.wParam),
3001                 &button, &up);
3002 
3003   /* Make the event type NO_EVENT; we'll change that when we decide
3004      otherwise.  */
3005   result->kind = MOUSE_CLICK_EVENT;
3006   result->code = button;
3007   result->timestamp = msg->msg.time;
3008   result->modifiers = (msg->dwModifiers
3009                        | (up
3010                           ? up_modifier
3011                           : down_modifier));
3012 
3013   XSETINT (result->x, LOWORD (msg->msg.lParam));
3014   XSETINT (result->y, HIWORD (msg->msg.lParam));
3015   XSETFRAME (result->frame_or_window, f);
3016   result->arg = Qnil;
3017   return Qnil;
3018 }
3019 
3020 static Lisp_Object
3021 construct_mouse_wheel (result, msg, f)
3022      struct input_event *result;
3023      W32Msg *msg;
3024      struct frame *f;
3025 {
3026   POINT p;
3027   int delta;
3028 
3029   result->kind = msg->msg.message == WM_MOUSEHWHEEL ? HORIZ_WHEEL_EVENT
3030                                                     : WHEEL_EVENT;
3031   result->code = 0;
3032   result->timestamp = msg->msg.time;
3033 
3034   /* A WHEEL_DELTA positive value indicates that the wheel was rotated
3035      forward, away from the user (up); a negative value indicates that
3036      the wheel was rotated backward, toward the user (down).  */
3037   delta = GET_WHEEL_DELTA_WPARAM (msg->msg.wParam);
3038 
3039   /* The up and down modifiers indicate if the wheel was rotated up or
3040      down based on WHEEL_DELTA value.  */
3041   result->modifiers = (msg->dwModifiers
3042                        | ((delta < 0 ) ? down_modifier : up_modifier));
3043 
3044   /* With multiple monitors, we can legitimately get negative
3045      coordinates, so cast to short to interpret them correctly.  */
3046   p.x = (short) LOWORD (msg->msg.lParam);
3047   p.y = (short) HIWORD (msg->msg.lParam);
3048   ScreenToClient (msg->msg.hwnd, &p);
3049   XSETINT (result->x, p.x);
3050   XSETINT (result->y, p.y);
3051   XSETFRAME (result->frame_or_window, f);
3052   result->arg = Qnil;
3053   return Qnil;
3054 }
3055 
3056 static Lisp_Object
3057 construct_drag_n_drop (result, msg, f)
3058      struct input_event *result;
3059      W32Msg *msg;
3060      struct frame *f;
3061 {
3062   Lisp_Object files;
3063   Lisp_Object frame;
3064   HDROP hdrop;
3065   POINT p;
3066   WORD num_files;
3067   char *name;
3068   int i, len;
3069 
3070   result->kind = DRAG_N_DROP_EVENT;
3071   result->code = 0;
3072   result->timestamp = msg->msg.time;
3073   result->modifiers = msg->dwModifiers;
3074 
3075   hdrop = (HDROP) msg->msg.wParam;
3076   DragQueryPoint (hdrop, &p);
3077 
3078 #if 0
3079   p.x = LOWORD (msg->msg.lParam);
3080   p.y = HIWORD (msg->msg.lParam);
3081   ScreenToClient (msg->msg.hwnd, &p);
3082 #endif
3083 
3084   XSETINT (result->x, p.x);
3085   XSETINT (result->y, p.y);
3086 
3087   num_files = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
3088   files = Qnil;
3089 
3090   for (i = 0; i < num_files; i++)
3091     {
3092       len = DragQueryFile (hdrop, i, NULL, 0);
3093       if (len <= 0)
3094         continue;
3095       name = alloca (len + 1);
3096       DragQueryFile (hdrop, i, name, len + 1);
3097       files = Fcons (DECODE_FILE (build_string (name)), files);
3098     }
3099 
3100   DragFinish (hdrop);
3101 
3102   XSETFRAME (frame, f);
3103   result->frame_or_window = frame;
3104   result->arg = files;
3105   return Qnil;
3106 }
3107 
3108 
3109 /* Function to report a mouse movement to the mainstream Emacs code.
3110    The input handler calls this.
3111 
3112    We have received a mouse movement event, which is given in *event.
3113    If the mouse is over a different glyph than it was last time, tell
3114    the mainstream emacs code by setting mouse_moved.  If not, ask for
3115    another motion event, so we can check again the next time it moves.  */
3116 
3117 static MSG last_mouse_motion_event;
3118 static Lisp_Object last_mouse_motion_frame;
3119 
3120 static int
3121 note_mouse_movement (frame, msg)
3122      FRAME_PTR frame;
3123      MSG *msg;
3124 {
3125   int mouse_x = LOWORD (msg->lParam);
3126   int mouse_y = HIWORD (msg->lParam);
3127 
3128   last_mouse_movement_time = msg->time;
3129   memcpy (&last_mouse_motion_event, msg, sizeof (last_mouse_motion_event));
3130   XSETFRAME (last_mouse_motion_frame, frame);
3131 
3132   if (!FRAME_X_OUTPUT (frame))
3133     return 0;
3134 
3135   if (msg->hwnd != FRAME_W32_WINDOW (frame))
3136     {
3137       frame->mouse_moved = 1;
3138       last_mouse_scroll_bar = Qnil;
3139       note_mouse_highlight (frame, -1, -1);
3140       last_mouse_glyph_frame = 0;
3141       return 1;
3142     }
3143 
3144   /* Has the mouse moved off the glyph it was on at the last sighting?  */
3145   if (frame != last_mouse_glyph_frame
3146       || mouse_x < last_mouse_glyph.left
3147       || mouse_x >= last_mouse_glyph.right
3148       || mouse_y < last_mouse_glyph.top
3149       || mouse_y >= last_mouse_glyph.bottom)
3150     {
3151       frame->mouse_moved = 1;
3152       last_mouse_scroll_bar = Qnil;
3153       note_mouse_highlight (frame, mouse_x, mouse_y);
3154       /* Remember the mouse position here, as w32_mouse_position only
3155          gets called when mouse tracking is enabled but we also need
3156          to keep track of the mouse for help_echo and highlighting at
3157          other times.  */
3158       remember_mouse_glyph (frame, mouse_x, mouse_y, &last_mouse_glyph);
3159       last_mouse_glyph_frame = frame;
3160       return 1;
3161     }
3162 
3163   return 0;
3164 }
3165 
3166 
3167 /************************************************************************
3168                               Mouse Face
3169  ************************************************************************/
3170 
3171 static struct scroll_bar *x_window_to_scroll_bar ();
3172 static void x_scroll_bar_report_motion ();
3173 static void x_check_fullscreen P_ ((struct frame *));
3174 
3175 static void
3176 redo_mouse_highlight ()
3177 {
3178   if (!NILP (last_mouse_motion_frame)
3179       && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame)))
3180     note_mouse_highlight (XFRAME (last_mouse_motion_frame),
3181                           LOWORD (last_mouse_motion_event.lParam),
3182                           HIWORD (last_mouse_motion_event.lParam));
3183 }
3184 
3185 static void
3186 w32_define_cursor (window, cursor)
3187      Window window;
3188      Cursor cursor;
3189 {
3190   PostMessage (window, WM_EMACS_SETCURSOR, (WPARAM) cursor, 0);
3191 }
3192 /* Return the current position of the mouse.
3193    *fp should be a frame which indicates which display to ask about.
3194 
3195    If the mouse movement started in a scroll bar, set *fp, *bar_window,
3196    and *part to the frame, window, and scroll bar part that the mouse
3197    is over.  Set *x and *y to the portion and whole of the mouse's
3198    position on the scroll bar.
3199 
3200    If the mouse movement started elsewhere, set *fp to the frame the
3201    mouse is on, *bar_window to nil, and *x and *y to the character cell
3202    the mouse is over.
3203 
3204    Set *time to the server time-stamp for the time at which the mouse
3205    was at this position.
3206 
3207    Don't store anything if we don't have a valid set of values to report.
3208 
3209    This clears the mouse_moved flag, so we can wait for the next mouse
3210    movement.  */
3211 
3212 static void
3213 w32_mouse_position (fp, insist, bar_window, part, x, y, time)
3214      FRAME_PTR *fp;
3215      int insist;
3216      Lisp_Object *bar_window;
3217      enum scroll_bar_part *part;
3218      Lisp_Object *x, *y;
3219      unsigned long *time;
3220 {
3221   FRAME_PTR f1;
3222 
3223   BLOCK_INPUT;
3224 
3225   if (! NILP (last_mouse_scroll_bar) && insist == 0)
3226     x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3227   else
3228     {
3229       POINT pt;
3230 
3231       Lisp_Object frame, tail;
3232 
3233       /* Clear the mouse-moved flag for every frame on this display.  */
3234       FOR_EACH_FRAME (tail, frame)
3235         XFRAME (frame)->mouse_moved = 0;
3236 
3237       last_mouse_scroll_bar = Qnil;
3238 
3239       GetCursorPos (&pt);
3240 
3241       /* Now we have a position on the root; find the innermost window
3242          containing the pointer.  */
3243       {
3244         if (FRAME_W32_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
3245             && FRAME_LIVE_P (last_mouse_frame))
3246           {
3247             /* If mouse was grabbed on a frame, give coords for that frame
3248                even if the mouse is now outside it.  */
3249             f1 = last_mouse_frame;
3250           }
3251         else
3252           {
3253             /* Is window under mouse one of our frames?  */
3254             f1 = x_any_window_to_frame (FRAME_W32_DISPLAY_INFO (*fp),
3255                                     WindowFromPoint (pt));
3256           }
3257 
3258         /* If not, is it one of our scroll bars?  */
3259         if (! f1)
3260           {
3261             struct scroll_bar *bar
3262               = x_window_to_scroll_bar (WindowFromPoint (pt));
3263 
3264             if (bar)
3265               {
3266                 f1 = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3267               }
3268           }
3269 
3270         if (f1 == 0 && insist > 0)
3271           f1 = SELECTED_FRAME ();
3272 
3273         if (f1)
3274           {
3275             /* Ok, we found a frame.  Store all the values.
3276                last_mouse_glyph is a rectangle used to reduce the
3277                generation of mouse events.  To not miss any motion
3278                events, we must divide the frame into rectangles of the
3279                size of the smallest character that could be displayed
3280                on it, i.e. into the same rectangles that matrices on
3281                the frame are divided into.  */
3282 
3283             ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
3284             remember_mouse_glyph (f1, pt.x, pt.y, &last_mouse_glyph);
3285             last_mouse_glyph_frame = f1;
3286 
3287             *bar_window = Qnil;
3288             *part = 0;
3289             *fp = f1;
3290             XSETINT (*x, pt.x);
3291             XSETINT (*y, pt.y);
3292             *time = last_mouse_movement_time;
3293           }
3294       }
3295     }
3296 
3297   UNBLOCK_INPUT;
3298 }
3299 
3300 
3301 /***********************************************************************
3302                                Tool-bars
3303  ***********************************************************************/
3304 
3305 /* Handle mouse button event on the tool-bar of frame F, at
3306    frame-relative coordinates X/Y.  EVENT_TYPE is either ButtionPress
3307    or ButtonRelase.  */
3308 
3309 static void
3310 w32_handle_tool_bar_click (f, button_event)
3311      struct frame *f;
3312      struct input_event *button_event;
3313 {
3314   int x = XFASTINT (button_event->x);
3315   int y = XFASTINT (button_event->y);
3316 
3317   if (button_event->modifiers & down_modifier)
3318     handle_tool_bar_click (f, x, y, 1, 0);
3319   else
3320     handle_tool_bar_click (f, x, y, 0,
3321                            button_event->modifiers & ~up_modifier);
3322 }
3323 
3324 
3325 
3326 /***********************************************************************
3327                                Scroll bars
3328  ***********************************************************************/
3329 
3330 /* Scroll bar support.  */
3331 
3332 /* Given a window ID, find the struct scroll_bar which manages it.
3333    This can be called in GC, so we have to make sure to strip off mark
3334    bits.  */
3335 
3336 static struct scroll_bar *
3337 x_window_to_scroll_bar (window_id)
3338      Window window_id;
3339 {
3340   Lisp_Object tail;
3341 
3342   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
3343     {
3344       Lisp_Object frame, bar, condemned;
3345 
3346       frame = XCAR (tail);
3347       /* All elements of Vframe_list should be frames.  */
3348       if (! FRAMEP (frame))
3349         abort ();
3350 
3351       /* Scan this frame's scroll bar list for a scroll bar with the
3352          right window ID.  */
3353       condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
3354       for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
3355            /* This trick allows us to search both the ordinary and
3356               condemned scroll bar lists with one loop.  */
3357            ! NILP (bar) || (bar = condemned,
3358                                condemned = Qnil,
3359                                ! NILP (bar));
3360            bar = XSCROLL_BAR (bar)->next)
3361         if (SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar)) == window_id)
3362           return XSCROLL_BAR (bar);
3363     }
3364 
3365   return 0;
3366 }
3367 
3368 
3369 
3370 /* Set the thumb size and position of scroll bar BAR.  We are currently
3371    displaying PORTION out of a whole WHOLE, and our position POSITION.  */
3372 
3373 static void
3374 w32_set_scroll_bar_thumb (bar, portion, position, whole)
3375      struct scroll_bar *bar;
3376      int portion, position, whole;
3377 {
3378   Window w = SCROLL_BAR_W32_WINDOW (bar);
3379   /* We use the whole scroll-bar height in the calculations below, to
3380      avoid strange effects like scrolling backwards when just clicking
3381      on the handle (without moving it).  */
3382   double range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height))
3383                  + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3384   int sb_page, sb_pos;
3385   BOOL draggingp = !NILP (bar->dragging) ? TRUE : FALSE;
3386   SCROLLINFO si;
3387 
3388   /* We used to change the nPage setting while dragging the handle,
3389      but that had very strange effects (such as scrolling backwards
3390      while dragging downwards).
3391 
3392      Now, we don't change the nPage setting while dragging unless we
3393      get near to the end of the buffer, in which case we often have to
3394      resize the handle to "go all the way".  */
3395 
3396   if (draggingp)
3397     {
3398       int near_bottom_p;
3399       BLOCK_INPUT;
3400       si.cbSize = sizeof (si);
3401       si.fMask = SIF_POS | SIF_PAGE;
3402       GetScrollInfo(w, SB_CTL, &si);
3403       near_bottom_p = si.nPos + si.nPage >= range;
3404       UNBLOCK_INPUT;
3405       if (!near_bottom_p)
3406         return;
3407     }
3408 
3409   if (whole)
3410     {
3411       /* Position scroll bar at rock bottom if the bottom of the
3412          buffer is visible. This avoids shinking the thumb away
3413          to nothing if it is held at the bottom of the buffer.  */
3414       if (position + portion >= whole && !draggingp)
3415         {
3416           sb_page = range * (whole - position) / whole;
3417           sb_pos = range;
3418         }
3419       else
3420         {
3421           sb_pos = position * range / whole;
3422           sb_page = (min (portion, (whole - position)) * range) / whole;
3423         }
3424     }
3425   else
3426     {
3427       sb_page = range;
3428       sb_pos = 0;
3429     }
3430 
3431   sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
3432 
3433   BLOCK_INPUT;
3434 
3435   si.cbSize = sizeof (si);
3436   si.fMask = SIF_PAGE | SIF_POS;
3437   si.nPage = sb_page;
3438   si.nPos = sb_pos;
3439 
3440   SetScrollInfo (w, SB_CTL, &si, TRUE);
3441 
3442   UNBLOCK_INPUT;
3443 }
3444 
3445 
3446 /************************************************************************
3447                          Scroll bars, general
3448  ************************************************************************/
3449 
3450 static HWND
3451 my_create_scrollbar (f, bar)
3452      struct frame * f;
3453      struct scroll_bar * bar;
3454 {
3455   return (HWND) SendMessage (FRAME_W32_WINDOW (f),
3456                              WM_EMACS_CREATESCROLLBAR, (WPARAM) f,
3457                              (LPARAM) bar);
3458 }
3459 
3460 /*#define ATTACH_THREADS*/
3461 
3462 static BOOL
3463 my_show_window (FRAME_PTR f, HWND hwnd, int how)
3464 {
3465 #ifndef ATTACH_THREADS
3466   return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
3467                       (WPARAM) hwnd, (LPARAM) how);
3468 #else
3469   return ShowWindow (hwnd, how);
3470 #endif
3471 }
3472 
3473 static void
3474 my_set_window_pos (HWND hwnd, HWND hwndAfter,
3475                    int x, int y, int cx, int cy, UINT flags)
3476 {
3477 #ifndef ATTACH_THREADS
3478   WINDOWPOS pos;
3479   pos.hwndInsertAfter = hwndAfter;
3480   pos.x = x;
3481   pos.y = y;
3482   pos.cx = cx;
3483   pos.cy = cy;
3484   pos.flags = flags;
3485   SendMessage (hwnd, WM_EMACS_SETWINDOWPOS, (WPARAM) &pos, 0);
3486 #else
3487   SetWindowPos (hwnd, hwndAfter, x, y, cx, cy, flags);
3488 #endif
3489 }
3490 
3491 static void
3492 my_set_focus (f, hwnd)
3493      struct frame * f;
3494      HWND hwnd;
3495 {
3496   SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SETFOCUS,
3497                (WPARAM) hwnd, 0);
3498 }
3499 
3500 static void
3501 my_set_foreground_window (hwnd)
3502      HWND hwnd;
3503 {
3504   SendMessage (hwnd, WM_EMACS_SETFOREGROUND, (WPARAM) hwnd, 0);
3505 }
3506 
3507 
3508 static void
3509 my_destroy_window (f, hwnd)
3510      struct frame * f;
3511      HWND hwnd;
3512 {
3513   SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_DESTROYWINDOW,
3514                (WPARAM) hwnd, 0);
3515 }
3516 
3517 /* Create a scroll bar and return the scroll bar vector for it.  W is
3518    the Emacs window on which to create the scroll bar. TOP, LEFT,
3519    WIDTH and HEIGHT are.the pixel coordinates and dimensions of the
3520    scroll bar. */
3521 
3522 static struct scroll_bar *
3523 x_scroll_bar_create (w, top, left, width, height)
3524      struct window *w;
3525      int top, left, width, height;
3526 {
3527   struct frame *f = XFRAME (WINDOW_FRAME (w));
3528   HWND hwnd;
3529   SCROLLINFO si;
3530   struct scroll_bar *bar
3531     = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
3532 
3533   BLOCK_INPUT;
3534 
3535   XSETWINDOW (bar->window, w);
3536   XSETINT (bar->top, top);
3537   XSETINT (bar->left, left);
3538   XSETINT (bar->width, width);
3539   XSETINT (bar->height, height);
3540   XSETINT (bar->start, 0);
3541   XSETINT (bar->end, 0);
3542   bar->dragging = Qnil;
3543   bar->fringe_extended_p = Qnil;
3544 
3545   /* Requires geometry to be set before call to create the real window */
3546 
3547   hwnd = my_create_scrollbar (f, bar);
3548 
3549   si.cbSize = sizeof (si);
3550   si.fMask = SIF_ALL;
3551   si.nMin = 0;
3552   si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
3553     + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3554   si.nPage = si.nMax;
3555   si.nPos = 0;
3556 
3557   SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
3558 
3559   SET_SCROLL_BAR_W32_WINDOW (bar, hwnd);
3560 
3561   /* Add bar to its frame's list of scroll bars.  */
3562   bar->next = FRAME_SCROLL_BARS (f);
3563   bar->prev = Qnil;
3564   XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
3565   if (! NILP (bar->next))
3566     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
3567 
3568   UNBLOCK_INPUT;
3569 
3570   return bar;
3571 }
3572 
3573 
3574 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
3575    nil. */
3576 
3577 static void
3578 x_scroll_bar_remove (bar)
3579      struct scroll_bar *bar;
3580 {
3581   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3582 
3583   BLOCK_INPUT;
3584 
3585   /* Destroy the window.  */
3586   my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
3587 
3588   /* Disassociate this scroll bar from its window.  */
3589   XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
3590 
3591   UNBLOCK_INPUT;
3592 }
3593 
3594 /* Set the handle of the vertical scroll bar for WINDOW to indicate
3595    that we are displaying PORTION characters out of a total of WHOLE
3596    characters, starting at POSITION.  If WINDOW has no scroll bar,
3597    create one.  */
3598 static void
3599 w32_set_vertical_scroll_bar (w, portion, whole, position)
3600      struct window *w;
3601      int portion, whole, position;
3602 {
3603   struct frame *f = XFRAME (w->frame);
3604   struct scroll_bar *bar;
3605   int top, height, left, sb_left, width, sb_width;
3606   int window_y, window_height;
3607   int fringe_extended_p;
3608 
3609   /* Get window dimensions.  */
3610   window_box (w, -1, 0, &window_y, 0, &window_height);
3611   top  = window_y;
3612   width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f);
3613   height = window_height;
3614 
3615   /* Compute the left edge of the scroll bar area.  */
3616   left = WINDOW_SCROLL_BAR_AREA_X (w);
3617 
3618   /* Compute the width of the scroll bar which might be less than
3619      the width of the area reserved for the scroll bar.  */
3620   if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) > 0)
3621     sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
3622   else
3623     sb_width = width;
3624 
3625   /* Compute the left edge of the scroll bar.  */
3626   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
3627     sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
3628   else
3629     sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
3630 
3631   if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
3632     fringe_extended_p = (WINDOW_LEFTMOST_P (w)
3633                          && WINDOW_LEFT_FRINGE_WIDTH (w)
3634                          && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
3635                              || WINDOW_LEFT_MARGIN_COLS (w) == 0));
3636   else
3637     fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
3638                          && WINDOW_RIGHT_FRINGE_WIDTH (w)
3639                          && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
3640                              || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
3641 
3642   /* Does the scroll bar exist yet?  */
3643   if (NILP (w->vertical_scroll_bar))
3644     {
3645       HDC hdc;
3646       BLOCK_INPUT;
3647       if (width > 0 && height > 0)
3648         {
3649           hdc = get_frame_dc (f);
3650           if (fringe_extended_p)
3651             w32_clear_area (f, hdc, sb_left, top, sb_width, height);
3652           else
3653             w32_clear_area (f, hdc, left, top, width, height);
3654           release_frame_dc (f, hdc);
3655         }
3656       UNBLOCK_INPUT;
3657 
3658       bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
3659     }
3660   else
3661     {
3662       /* It may just need to be moved and resized.  */
3663       HWND hwnd;
3664 
3665       bar = XSCROLL_BAR (w->vertical_scroll_bar);
3666       hwnd = SCROLL_BAR_W32_WINDOW (bar);
3667 
3668       /* If already correctly positioned, do nothing.  */
3669       if ( XINT (bar->left) == sb_left
3670            && XINT (bar->top) == top
3671            && XINT (bar->width) ==  sb_width
3672            && XINT (bar->height) == height
3673            && !NILP (bar->fringe_extended_p) == fringe_extended_p )
3674         {
3675           /* Redraw after clear_frame. */
3676           if (!my_show_window (f, hwnd, SW_NORMAL))
3677             InvalidateRect (hwnd, NULL, FALSE);
3678         }
3679       else
3680         {
3681           HDC hdc;
3682           SCROLLINFO si;
3683 
3684           BLOCK_INPUT;
3685           if (width && height)
3686             {
3687               hdc = get_frame_dc (f);
3688               /* Since Windows scroll bars are smaller than the space reserved
3689                  for them on the frame, we have to clear "under" them.  */
3690               if (fringe_extended_p)
3691                 w32_clear_area (f, hdc, sb_left, top, sb_width, height);
3692               else
3693                 w32_clear_area (f, hdc, left, top, width, height);
3694               release_frame_dc (f, hdc);
3695             }
3696           /* Make sure scroll bar is "visible" before moving, to ensure the
3697              area of the parent window now exposed will be refreshed.  */
3698           my_show_window (f, hwnd, SW_HIDE);
3699           MoveWindow (hwnd, sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
3700                       top, sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
3701                       max (height, 1), TRUE);
3702 
3703           si.cbSize = sizeof (si);
3704           si.fMask = SIF_RANGE;
3705           si.nMin = 0;
3706           si.nMax = VERTICAL_SCROLL_BAR_TOP_RANGE (f, height)
3707             + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3708 
3709           SetScrollInfo (hwnd, SB_CTL, &si, FALSE);
3710 
3711           my_show_window (f, hwnd, SW_NORMAL);
3712           /* InvalidateRect (w, NULL, FALSE);  */
3713 
3714           /* Remember new settings.  */
3715           XSETINT (bar->left, sb_left);
3716           XSETINT (bar->top, top);
3717           XSETINT (bar->width, sb_width);
3718           XSETINT (bar->height, height);
3719 
3720           UNBLOCK_INPUT;
3721         }
3722     }
3723   bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
3724 
3725   w32_set_scroll_bar_thumb (bar, portion, position, whole);
3726 
3727   XSETVECTOR (w->vertical_scroll_bar, bar);
3728 }
3729 
3730 
3731 /* The following three hooks are used when we're doing a thorough
3732    redisplay of the frame.  We don't explicitly know which scroll bars
3733    are going to be deleted, because keeping track of when windows go
3734    away is a real pain - "Can you say set-window-configuration, boys
3735    and girls?"  Instead, we just assert at the beginning of redisplay
3736    that *all* scroll bars are to be removed, and then save a scroll bar
3737    from the fiery pit when we actually redisplay its window.  */
3738 
3739 /* Arrange for all scroll bars on FRAME to be removed at the next call
3740    to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
3741    `*redeem_scroll_bar_hook' is applied to its window before the judgment.  */
3742 
3743 static void
3744 w32_condemn_scroll_bars (frame)
3745      FRAME_PTR frame;
3746 {
3747   /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS.  */
3748   while (! NILP (FRAME_SCROLL_BARS (frame)))
3749     {
3750       Lisp_Object bar;
3751       bar = FRAME_SCROLL_BARS (frame);
3752       FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
3753       XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
3754       XSCROLL_BAR (bar)->prev = Qnil;
3755       if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
3756         XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
3757       FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
3758     }
3759 }
3760 
3761 
3762 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
3763    Note that WINDOW isn't necessarily condemned at all.  */
3764 
3765 static void
3766 w32_redeem_scroll_bar (window)
3767      struct window *window;
3768 {
3769   struct scroll_bar *bar;
3770   struct frame *f;
3771 
3772   /* We can't redeem this window's scroll bar if it doesn't have one.  */
3773   if (NILP (window->vertical_scroll_bar))
3774     abort ();
3775 
3776   bar = XSCROLL_BAR (window->vertical_scroll_bar);
3777 
3778   /* Unlink it from the condemned list.  */
3779   f = XFRAME (WINDOW_FRAME (window));
3780   if (NILP (bar->prev))
3781     {
3782       /* If the prev pointer is nil, it must be the first in one of
3783          the lists.  */
3784       if (EQ (FRAME_SCROLL_BARS (f), window->vertical_scroll_bar))
3785         /* It's not condemned.  Everything's fine.  */
3786         return;
3787       else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
3788                    window->vertical_scroll_bar))
3789         FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
3790       else
3791         /* If its prev pointer is nil, it must be at the front of
3792            one or the other!  */
3793         abort ();
3794     }
3795   else
3796     XSCROLL_BAR (bar->prev)->next = bar->next;
3797 
3798   if (! NILP (bar->next))
3799     XSCROLL_BAR (bar->next)->prev = bar->prev;
3800 
3801   bar->next = FRAME_SCROLL_BARS (f);
3802   bar->prev = Qnil;
3803   XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
3804   if (! NILP (bar->next))
3805     XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
3806 }
3807 
3808 /* Remove all scroll bars on FRAME that haven't been saved since the
3809    last call to `*condemn_scroll_bars_hook'.  */
3810 
3811 static void
3812 w32_judge_scroll_bars (f)
3813      FRAME_PTR f;
3814 {
3815   Lisp_Object bar, next;
3816 
3817   bar = FRAME_CONDEMNED_SCROLL_BARS (f);
3818 
3819   /* Clear out the condemned list now so we won't try to process any
3820      more events on the hapless scroll bars.  */
3821   FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
3822 
3823   for (; ! NILP (bar); bar = next)
3824     {
3825       struct scroll_bar *b = XSCROLL_BAR (bar);
3826 
3827       x_scroll_bar_remove (b);
3828 
3829       next = b->next;
3830       b->next = b->prev = Qnil;
3831     }
3832 
3833   /* Now there should be no references to the condemned scroll bars,
3834      and they should get garbage-collected.  */
3835 }
3836 
3837 /* Handle a mouse click on the scroll bar BAR.  If *EMACS_EVENT's kind
3838    is set to something other than NO_EVENT, it is enqueued.
3839 
3840    This may be called from a signal handler, so we have to ignore GC
3841    mark bits.  */
3842 
3843 static int
3844 w32_scroll_bar_handle_click (bar, msg, emacs_event)
3845      struct scroll_bar *bar;
3846      W32Msg *msg;
3847      struct input_event *emacs_event;
3848 {
3849   if (! WINDOWP (bar->window))
3850     abort ();
3851 
3852   emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
3853   emacs_event->code = 0;
3854   /* not really meaningful to distinguish up/down */
3855   emacs_event->modifiers = msg->dwModifiers;
3856   emacs_event->frame_or_window = bar->window;
3857   emacs_event->arg = Qnil;
3858   emacs_event->timestamp = msg->msg.time;
3859 
3860   {
3861     int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
3862     int y;
3863     int dragging = !NILP (bar->dragging);
3864     SCROLLINFO si;
3865 
3866     si.cbSize = sizeof (si);
3867     si.fMask = SIF_POS;
3868 
3869     GetScrollInfo ((HWND) msg->msg.lParam, SB_CTL, &si);
3870     y = si.nPos;
3871 
3872     bar->dragging = Qnil;
3873 
3874 
3875     last_mouse_scroll_bar_pos = msg->msg.wParam;
3876 
3877     switch (LOWORD (msg->msg.wParam))
3878       {
3879       case SB_LINEDOWN:
3880         emacs_event->part = scroll_bar_down_arrow;
3881         break;
3882       case SB_LINEUP:
3883         emacs_event->part = scroll_bar_up_arrow;
3884         break;
3885       case SB_PAGEUP:
3886         emacs_event->part = scroll_bar_above_handle;
3887         break;
3888       case SB_PAGEDOWN:
3889         emacs_event->part = scroll_bar_below_handle;
3890         break;
3891       case SB_TOP:
3892         emacs_event->part = scroll_bar_handle;
3893         y = 0;
3894         break;
3895       case SB_BOTTOM:
3896         emacs_event->part = scroll_bar_handle;
3897         y = top_range;
3898         break;
3899       case SB_THUMBTRACK:
3900       case SB_THUMBPOSITION:
3901         if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
3902           y = HIWORD (msg->msg.wParam);
3903         bar->dragging = Qt;
3904         emacs_event->part = scroll_bar_handle;
3905 
3906         /* "Silently" update current position.  */
3907         {
3908           SCROLLINFO si;
3909 
3910           si.cbSize = sizeof (si);
3911           si.fMask = SIF_POS;
3912           si.nPos = y;
3913           /* Remember apparent position (we actually lag behind the real
3914              position, so don't set that directly.  */
3915           last_scroll_bar_drag_pos = y;
3916 
3917           SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, FALSE);
3918         }
3919         break;
3920       case SB_ENDSCROLL:
3921         /* If this is the end of a drag sequence, then reset the scroll
3922            handle size to normal and do a final redraw.  Otherwise do
3923            nothing.  */
3924         if (dragging)
3925           {
3926             SCROLLINFO si;
3927             int start = XINT (bar->start);
3928             int end = XINT (bar->end);
3929 
3930             si.cbSize = sizeof (si);
3931             si.fMask = SIF_PAGE | SIF_POS;
3932             si.nPage = end - start + VERTICAL_SCROLL_BAR_MIN_HANDLE;
3933             si.nPos = last_scroll_bar_drag_pos;
3934             SetScrollInfo (SCROLL_BAR_W32_WINDOW (bar), SB_CTL, &si, TRUE);
3935           }
3936         /* fall through */
3937       default:
3938         emacs_event->kind = NO_EVENT;
3939         return FALSE;
3940       }
3941 
3942     XSETINT (emacs_event->x, y);
3943     XSETINT (emacs_event->y, top_range);
3944 
3945     return TRUE;
3946   }
3947 }
3948 
3949 /* Return information to the user about the current position of the mouse
3950    on the scroll bar.  */
3951 
3952 static void
3953 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time)
3954      FRAME_PTR *fp;
3955      Lisp_Object *bar_window;
3956      enum scroll_bar_part *part;
3957      Lisp_Object *x, *y;
3958      unsigned long *time;
3959 {
3960   struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
3961   Window w = SCROLL_BAR_W32_WINDOW (bar);
3962   FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
3963   int pos;
3964   int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
3965   SCROLLINFO si;
3966 
3967   BLOCK_INPUT;
3968 
3969   *fp = f;
3970   *bar_window = bar->window;
3971 
3972   si.cbSize = sizeof (si);
3973   si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE;
3974 
3975   GetScrollInfo (w, SB_CTL, &si);
3976   pos = si.nPos;
3977   top_range = si.nMax - si.nPage + 1;
3978 
3979   switch (LOWORD (last_mouse_scroll_bar_pos))
3980   {
3981   case SB_THUMBPOSITION:
3982   case SB_THUMBTRACK:
3983       *part = scroll_bar_handle;
3984       if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
3985           pos = HIWORD (last_mouse_scroll_bar_pos);
3986       break;
3987   case SB_LINEDOWN:
3988       *part = scroll_bar_handle;
3989       pos++;
3990       break;
3991   default:
3992       *part = scroll_bar_handle;
3993       break;
3994   }
3995 
3996   XSETINT (*x, pos);
3997   XSETINT (*y, top_range);
3998 
3999   f->mouse_moved = 0;
4000   last_mouse_scroll_bar = Qnil;
4001 
4002   *time = last_mouse_movement_time;
4003 
4004   UNBLOCK_INPUT;
4005 }
4006 
4007 
4008 /* The screen has been cleared so we may have changed foreground or
4009    background colors, and the scroll bars may need to be redrawn.
4010    Clear out the scroll bars, and ask for expose events, so we can
4011    redraw them.  */
4012 
4013 void
4014 x_scroll_bar_clear (f)
4015      FRAME_PTR f;
4016 {
4017   Lisp_Object bar;
4018 
4019   /* We can have scroll bars even if this is 0,
4020      if we just turned off scroll bar mode.
4021      But in that case we should not clear them.  */
4022   if (FRAME_HAS_VERTICAL_SCROLL_BARS (f))
4023     for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar);
4024          bar = XSCROLL_BAR (bar)->next)
4025       {
4026         HWND window = SCROLL_BAR_W32_WINDOW (XSCROLL_BAR (bar));
4027         HDC hdc = GetDC (window);
4028         RECT rect;
4029 
4030         /* Hide scroll bar until ready to repaint.  x_scroll_bar_move
4031            arranges to refresh the scroll bar if hidden.  */
4032         my_show_window (f, window, SW_HIDE);
4033 
4034         GetClientRect (window, &rect);
4035         select_palette (f, hdc);
4036         w32_clear_rect (f, hdc, &rect);
4037         deselect_palette (f, hdc);
4038 
4039         ReleaseDC (window, hdc);
4040       }
4041 }
4042 
4043 
4044 /* The main W32 event-reading loop - w32_read_socket.  */
4045 
4046 /* Record the last 100 characters stored
4047    to help debug the loss-of-chars-during-GC problem.  */
4048 
4049 static int temp_index;
4050 static short temp_buffer[100];
4051 
4052 /* Temporarily store lead byte of DBCS input sequences.  */
4053 static char dbcs_lead = 0;
4054 
4055 /* Read events coming from the W32 shell.
4056    This routine is called by the SIGIO handler.
4057    We return as soon as there are no more events to be read.
4058 
4059    We return the number of characters stored into the buffer,
4060    thus pretending to be `read'.
4061 
4062    EXPECTED is nonzero if the caller knows input is available.
4063 
4064    Some of these messages are reposted back to the message queue since the
4065    system calls the windows proc directly in a context where we cannot return
4066    the data nor can we guarantee the state we are in.  So if we dispatch them
4067    we will get into an infinite loop.  To prevent this from ever happening we
4068    will set a variable to indicate we are in the read_socket call and indicate
4069    which message we are processing since the windows proc gets called
4070    recursively with different messages by the system.
4071 */
4072 
4073 int
4074 w32_read_socket (sd, expected, hold_quit)
4075      register int sd;
4076      int expected;
4077      struct input_event *hold_quit;
4078 {
4079   int count = 0;
4080   int check_visibility = 0;
4081   W32Msg msg;
4082   struct frame *f;
4083   struct w32_display_info *dpyinfo = &one_w32_display_info;
4084 
4085   if (interrupt_input_blocked)
4086     {
4087       interrupt_input_pending = 1;
4088       return -1;
4089     }
4090 
4091   interrupt_input_pending = 0;
4092   BLOCK_INPUT;
4093 
4094   /* So people can tell when we have read the available input.  */
4095   input_signal_count++;
4096 
4097   /* TODO: ghostscript integration. */
4098   while (get_next_msg (&msg, FALSE))
4099     {
4100       struct input_event inev;
4101       int do_help = 0;
4102 
4103       EVENT_INIT (inev);
4104       inev.kind = NO_EVENT;
4105       inev.arg = Qnil;
4106 
4107       switch (msg.msg.message)
4108         {
4109         case WM_EMACS_PAINT:
4110           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4111 
4112           if (f)
4113             {
4114               if (msg.rect.right == msg.rect.left ||
4115                   msg.rect.bottom == msg.rect.top)
4116                 {
4117                   /* We may get paint messages even though the client
4118                      area is clipped - these are not expose events. */
4119                   DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
4120                              SDATA (f->name)));
4121                 }
4122               else if (f->async_visible != 1)
4123                 {
4124                   /* Definitely not obscured, so mark as visible.  */
4125                   f->async_visible = 1;
4126                   f->async_iconified = 0;
4127                   SET_FRAME_GARBAGED (f);
4128                   DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
4129                              SDATA (f->name)));
4130 
4131                   /* WM_PAINT serves as MapNotify as well, so report
4132                      visibility changes properly.  */
4133                   if (f->iconified)
4134                     {
4135                       inev.kind = DEICONIFY_EVENT;
4136                       XSETFRAME (inev.frame_or_window, f);
4137                     }
4138                   else if (! NILP (Vframe_list)
4139                            && ! NILP (XCDR (Vframe_list)))
4140                     /* Force a redisplay sooner or later to update the
4141                        frame titles in case this is the second frame.  */
4142                     record_asynch_buffer_change ();
4143                 }
4144               else
4145                 {
4146                   HDC hdc = get_frame_dc (f);
4147 
4148                   /* Erase background again for safety.  */
4149                   w32_clear_rect (f, hdc, &msg.rect);
4150                   release_frame_dc (f, hdc);
4151                   expose_frame (f,
4152                                 msg.rect.left,
4153                                 msg.rect.top,
4154                                 msg.rect.right - msg.rect.left,
4155                                 msg.rect.bottom - msg.rect.top);
4156                 }
4157             }
4158           break;
4159 
4160         case WM_INPUTLANGCHANGE:
4161           /* Generate a language change event.  */
4162           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4163 
4164           /* lParam contains the input lang ID.  Use it to update our
4165              record of the keyboard codepage.  */
4166           keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
4167                                                           & 0xffff));
4168 
4169           if (f)
4170             {
4171               inev.kind = LANGUAGE_CHANGE_EVENT;
4172               XSETFRAME (inev.frame_or_window, f);
4173               inev.code = msg.msg.wParam;
4174               inev.modifiers = msg.msg.lParam & 0xffff;
4175             }
4176           break;
4177 
4178         case WM_KEYDOWN:
4179         case WM_SYSKEYDOWN:
4180           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4181 
4182           if (f && !f->iconified)
4183             {
4184               if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4185                   && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
4186                 {
4187                   clear_mouse_face (dpyinfo);
4188                   dpyinfo->mouse_face_hidden = 1;
4189                 }
4190 
4191               if (temp_index == sizeof temp_buffer / sizeof (short))
4192                 temp_index = 0;
4193               temp_buffer[temp_index++] = msg.msg.wParam;
4194               inev.kind = NON_ASCII_KEYSTROKE_EVENT;
4195               inev.code = msg.msg.wParam;
4196               inev.modifiers = msg.dwModifiers;
4197               XSETFRAME (inev.frame_or_window, f);
4198               inev.timestamp = msg.msg.time;
4199             }
4200           break;
4201 
4202         case WM_UNICHAR:
4203         case WM_SYSCHAR:
4204         case WM_CHAR:
4205           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4206 
4207           if (f && !f->iconified)
4208             {
4209               if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4210                   && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
4211                 {
4212                   clear_mouse_face (dpyinfo);
4213                   dpyinfo->mouse_face_hidden = 1;
4214                 }
4215 
4216               if (temp_index == sizeof temp_buffer / sizeof (short))
4217                 temp_index = 0;
4218               temp_buffer[temp_index++] = msg.msg.wParam;
4219 
4220               inev.modifiers = msg.dwModifiers;
4221               XSETFRAME (inev.frame_or_window, f);
4222               inev.timestamp = msg.msg.time;
4223 
4224               if (msg.msg.message == WM_UNICHAR)
4225                 {
4226                   inev.code = msg.msg.wParam;
4227                 }
4228               else if (msg.msg.wParam < 256)
4229                 {
4230                   wchar_t code;
4231                   char dbcs[2];
4232                   dbcs[0] = 0;
4233                   dbcs[1] = (char) msg.msg.wParam;
4234 
4235                   if (dbcs_lead)
4236                     {
4237                       dbcs[0] = dbcs_lead;
4238                       dbcs_lead = 0;
4239                       if (!MultiByteToWideChar (keyboard_codepage, 0,
4240                                                 dbcs, 2, &code, 1))
4241                         {
4242                           /* Garbage */
4243                           DebPrint (("Invalid DBCS sequence: %d %d\n",
4244                                      dbcs[0], dbcs[1]));
4245                           inev.kind = NO_EVENT;
4246                           break;
4247                         }
4248                     }
4249                   else if (IsDBCSLeadByteEx (keyboard_codepage,
4250                                              (BYTE) msg.msg.wParam))
4251                     {
4252                       dbcs_lead = (char) msg.msg.wParam;
4253                       inev.kind = NO_EVENT;
4254                       break;
4255                     }
4256                   else
4257                     {
4258                       if (!MultiByteToWideChar (keyboard_codepage, 0,
4259                                                 &dbcs[1], 1, &code, 1))
4260                         {
4261                           /* What to do with garbage? */
4262                           DebPrint (("Invalid character: %d\n", dbcs[1]));
4263                           inev.kind = NO_EVENT;
4264                           break;
4265                         }
4266                     }
4267                   inev.code = code;
4268                 }
4269               else
4270                 {
4271                   /* Windows shouldn't generate WM_CHAR events above 0xFF
4272                      in non-Unicode message handlers.  */
4273                   DebPrint (("Non-byte WM_CHAR: %d\n", msg.msg.wParam));
4274                   inev.kind = NO_EVENT;
4275                   break;
4276                 }
4277               inev.kind = inev.code < 128 ? ASCII_KEYSTROKE_EVENT
4278                                           : MULTIBYTE_CHAR_KEYSTROKE_EVENT;
4279             }
4280           break;
4281 
4282         case WM_APPCOMMAND:
4283           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4284 
4285           if (f && !f->iconified)
4286             {
4287               if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4288                   && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
4289                 {
4290                   clear_mouse_face (dpyinfo);
4291                   dpyinfo->mouse_face_hidden = 1;
4292                 }
4293 
4294               if (temp_index == sizeof temp_buffer / sizeof (short))
4295                 temp_index = 0;
4296               temp_buffer[temp_index++] = msg.msg.wParam;
4297               inev.kind = MULTIMEDIA_KEY_EVENT;
4298               inev.code = GET_APPCOMMAND_LPARAM(msg.msg.lParam);
4299               inev.modifiers = msg.dwModifiers;
4300               XSETFRAME (inev.frame_or_window, f);
4301               inev.timestamp = msg.msg.time;
4302             }
4303           break;
4304 
4305         case WM_MOUSEMOVE:
4306           /* Ignore non-movement.  */
4307           {
4308             int x = LOWORD (msg.msg.lParam);
4309             int y = HIWORD (msg.msg.lParam);
4310             if (x == last_mousemove_x && y == last_mousemove_y)
4311               break;
4312             last_mousemove_x = x;
4313             last_mousemove_y = y;
4314           }
4315 
4316           previous_help_echo_string = help_echo_string;
4317           help_echo_string = Qnil;
4318 
4319           if (dpyinfo->grabbed && last_mouse_frame
4320               && FRAME_LIVE_P (last_mouse_frame))
4321             f = last_mouse_frame;
4322           else
4323             f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4324 
4325           if (dpyinfo->mouse_face_hidden)
4326             {
4327               dpyinfo->mouse_face_hidden = 0;
4328               clear_mouse_face (dpyinfo);
4329             }
4330 
4331           if (f)
4332             {
4333               /* Generate SELECT_WINDOW_EVENTs when needed.  */
4334               if (!NILP (Vmouse_autoselect_window))
4335                 {
4336                   Lisp_Object window;
4337                   int x = LOWORD (msg.msg.lParam);
4338                   int y = HIWORD (msg.msg.lParam);
4339 
4340                   window = window_from_coordinates (f, x, y, 0, 0, 0, 0);
4341 
4342                   /* Window will be selected only when it is not
4343                      selected now and last mouse movement event was
4344                      not in it.  Minibuffer window will be selected
4345                      only when it is active.  */
4346                   if (WINDOWP(window)
4347                       && !EQ (window, last_window)
4348                       && !EQ (window, selected_window)
4349                       /* For click-to-focus window managers
4350                          create event iff we don't leave the
4351                          selected frame.  */
4352                       && (focus_follows_mouse
4353                           || (EQ (XWINDOW (window)->frame,
4354                                   XWINDOW (selected_window)->frame))))
4355                     {
4356                       inev.kind = SELECT_WINDOW_EVENT;
4357                       inev.frame_or_window = window;
4358                     }
4359 
4360                   last_window=window;
4361                 }
4362               if (!note_mouse_movement (f, &msg.msg))
4363                 help_echo_string = previous_help_echo_string;
4364             }
4365           else
4366             {
4367               /* If we move outside the frame, then we're
4368                  certainly no longer on any text in the frame.  */
4369               clear_mouse_face (dpyinfo);
4370             }
4371 
4372           /* If the contents of the global variable help_echo_string
4373              has changed, generate a HELP_EVENT.  */
4374 #if 0 /* The below is an invalid comparison when USE_LISP_UNION_TYPE.
4375          But it was originally changed to this to fix a bug, so I have
4376          not removed it completely in case the bug is still there.  */
4377           if (help_echo_string != previous_help_echo_string ||
4378               (!NILP (help_echo_string) && !STRINGP (help_echo_string) && f->mouse_moved))
4379 #else /* This is what xterm.c does.  */
4380             if (!NILP (help_echo_string)
4381                 || !NILP (previous_help_echo_string))
4382             do_help = 1;
4383 #endif
4384           break;
4385 
4386         case WM_LBUTTONDOWN:
4387         case WM_LBUTTONUP:
4388         case WM_MBUTTONDOWN:
4389         case WM_MBUTTONUP:
4390         case WM_RBUTTONDOWN:
4391         case WM_RBUTTONUP:
4392         case WM_XBUTTONDOWN:
4393         case WM_XBUTTONUP:
4394           {
4395             /* If we decide we want to generate an event to be seen
4396                by the rest of Emacs, we put it here.  */
4397             int tool_bar_p = 0;
4398             int button;
4399             int up;
4400 
4401             if (dpyinfo->grabbed && last_mouse_frame
4402                 && FRAME_LIVE_P (last_mouse_frame))
4403               f = last_mouse_frame;
4404             else
4405               f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4406 
4407             if (f)
4408               {
4409                 construct_mouse_click (&inev, &msg, f);
4410 
4411                 /* Is this in the tool-bar?  */
4412                 if (WINDOWP (f->tool_bar_window)
4413                     && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
4414                   {
4415                     Lisp_Object window;
4416                     int x = XFASTINT (inev.x);
4417                     int y = XFASTINT (inev.y);
4418 
4419                     window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
4420 
4421                     if (EQ (window, f->tool_bar_window))
4422                       {
4423                         w32_handle_tool_bar_click (f, &inev);
4424                         tool_bar_p = 1;
4425                       }
4426                   }
4427 
4428                 if (tool_bar_p
4429                     || (dpyinfo->w32_focus_frame
4430                         && f != dpyinfo->w32_focus_frame))
4431                   inev.kind = NO_EVENT;
4432               }
4433 
4434             parse_button (msg.msg.message, HIWORD (msg.msg.wParam),
4435                           &button, &up);
4436 
4437             if (up)
4438               {
4439                 dpyinfo->grabbed &= ~ (1 << button);
4440               }
4441             else
4442               {
4443                 dpyinfo->grabbed |= (1 << button);
4444                 last_mouse_frame = f;
4445                 /* Ignore any mouse motion that happened
4446                    before this event; any subsequent mouse-movement
4447                    Emacs events should reflect only motion after
4448                    the ButtonPress.  */
4449                 if (f != 0)
4450                   f->mouse_moved = 0;
4451 
4452                 if (!tool_bar_p)
4453                   last_tool_bar_item = -1;
4454               }
4455             break;
4456           }
4457 
4458         case WM_MOUSEWHEEL:
4459         case WM_MOUSEHWHEEL:
4460           {
4461             if (dpyinfo->grabbed && last_mouse_frame
4462                 && FRAME_LIVE_P (last_mouse_frame))
4463               f = last_mouse_frame;
4464             else
4465               f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4466 
4467             if (f)
4468               {
4469 
4470                 if (!dpyinfo->w32_focus_frame
4471                     || f == dpyinfo->w32_focus_frame)
4472                   {
4473                     /* Emit an Emacs wheel-up/down event.  */
4474                     construct_mouse_wheel (&inev, &msg, f);
4475                   }
4476                 /* Ignore any mouse motion that happened before this
4477                    event; any subsequent mouse-movement Emacs events
4478                    should reflect only motion after the
4479                    ButtonPress.  */
4480                 f->mouse_moved = 0;
4481               }
4482             last_mouse_frame = f;
4483             last_tool_bar_item = -1;
4484           }
4485           break;
4486 
4487         case WM_DROPFILES:
4488           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4489 
4490           if (f)
4491             construct_drag_n_drop (&inev, &msg, f);
4492           break;
4493 
4494         case WM_VSCROLL:
4495           {
4496             struct scroll_bar *bar =
4497               x_window_to_scroll_bar ((HWND)msg.msg.lParam);
4498 
4499             if (bar)
4500               w32_scroll_bar_handle_click (bar, &msg, &inev);
4501             break;
4502           }
4503 
4504         case WM_WINDOWPOSCHANGED:
4505           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4506           if (f)
4507             {
4508               if (f->want_fullscreen & FULLSCREEN_WAIT)
4509                 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
4510             }
4511           check_visibility = 1;
4512           break;
4513 
4514         case WM_ACTIVATE:
4515         case WM_ACTIVATEAPP:
4516           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4517           if (f)
4518             x_check_fullscreen (f);
4519           check_visibility = 1;
4520           break;
4521 
4522         case WM_MOVE:
4523           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4524 
4525           if (f && !f->async_iconified)
4526             {
4527               int x, y;
4528 
4529               x_real_positions (f, &x, &y);
4530               f->left_pos = x;
4531               f->top_pos = y;
4532             }
4533 
4534           check_visibility = 1;
4535           break;
4536 
4537         case WM_SHOWWINDOW:
4538           /* wParam non-zero means Window is about to be shown, 0 means
4539              about to be hidden.  */
4540           /* Redo the mouse-highlight after the tooltip has gone.  */
4541           if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
4542             {
4543               tip_window = NULL;
4544               redo_mouse_highlight ();
4545             }
4546 
4547           /* If window has been obscured or exposed by another window
4548              being maximised or minimised/restored, then recheck
4549              visibility of all frames.  Direct changes to our own
4550              windows get handled by WM_SIZE.  */
4551 #if 0
4552           if (msg.msg.lParam != 0)
4553             check_visibility = 1;
4554           else
4555             {
4556               f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4557               f->async_visible = msg.msg.wParam;
4558             }
4559 #endif
4560 
4561           check_visibility = 1;
4562           break;
4563 
4564         case WM_SIZE:
4565           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4566 
4567           /* Inform lisp of whether frame has been iconified etc. */
4568           if (f)
4569             {
4570               switch (msg.msg.wParam)
4571                 {
4572                 case SIZE_MINIMIZED:
4573                   f->async_visible = 0;
4574                   f->async_iconified = 1;
4575 
4576                   inev.kind = ICONIFY_EVENT;
4577                   XSETFRAME (inev.frame_or_window, f);
4578                   break;
4579 
4580                 case SIZE_MAXIMIZED:
4581                 case SIZE_RESTORED:
4582                   f->async_visible = 1;
4583                   f->async_iconified = 0;
4584 
4585                   /* wait_reading_process_output will notice this and update
4586                      the frame's display structures.  */
4587                   SET_FRAME_GARBAGED (f);
4588 
4589                   if (f->iconified)
4590                     {
4591                       int x, y;
4592 
4593                       /* Reset top and left positions of the Window
4594                          here since Windows sends a WM_MOVE message
4595                          BEFORE telling us the Window is minimized
4596                          when the Window is iconified, with 3000,3000
4597                          as the co-ords. */
4598                       x_real_positions (f, &x, &y);
4599                       f->left_pos = x;
4600                       f->top_pos = y;
4601 
4602                       inev.kind = DEICONIFY_EVENT;
4603                       XSETFRAME (inev.frame_or_window, f);
4604                     }
4605                   else if (! NILP (Vframe_list)
4606                            && ! NILP (XCDR (Vframe_list)))
4607                     /* Force a redisplay sooner or later
4608                        to update the frame titles
4609                        in case this is the second frame.  */
4610                     record_asynch_buffer_change ();
4611                   break;
4612                 }
4613             }
4614 
4615           if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
4616             {
4617               RECT rect;
4618               int rows;
4619               int columns;
4620               int width;
4621               int height;
4622 
4623               GetClientRect (msg.msg.hwnd, &rect);
4624 
4625               height = rect.bottom - rect.top;
4626               width = rect.right - rect.left;
4627 
4628               rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, height);
4629               columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, width);
4630 
4631               /* TODO: Clip size to the screen dimensions.  */
4632 
4633               /* Even if the number of character rows and columns has
4634                  not changed, the font size may have changed, so we need
4635                  to check the pixel dimensions as well.  */
4636 
4637               if (columns != FRAME_COLS (f)
4638                   || rows != FRAME_LINES (f)
4639                   || width != FRAME_PIXEL_WIDTH (f)
4640                   || height != FRAME_PIXEL_HEIGHT (f))
4641                 {
4642                   change_frame_size (f, rows, columns, 0, 1, 0);
4643                   SET_FRAME_GARBAGED (f);
4644                   cancel_mouse_face (f);
4645                   FRAME_PIXEL_WIDTH (f) = width;
4646                   FRAME_PIXEL_HEIGHT (f) = height;
4647                   f->win_gravity = NorthWestGravity;
4648                 }
4649             }
4650 
4651           check_visibility = 1;
4652           break;
4653 
4654         case WM_MOUSELEAVE:
4655           f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
4656           if (f)
4657             {
4658               if (f == dpyinfo->mouse_face_mouse_frame)
4659                 {
4660                   /* If we move outside the frame, then we're
4661                      certainly no longer on any text in the frame.  */
4662                   clear_mouse_face (dpyinfo);
4663                   dpyinfo->mouse_face_mouse_frame = 0;
4664                 }
4665 
4666               /* Generate a nil HELP_EVENT to cancel a help-echo.
4667                  Do it only if there's something to cancel.
4668                  Otherwise, the startup message is cleared when
4669                  the mouse leaves the frame.  */
4670               if (any_help_event_p)
4671                 do_help = -1;
4672             }
4673           break;
4674 
4675         case WM_SETFOCUS:
4676           w32_detect_focus_change (dpyinfo, &msg, &inev);
4677 
4678           dpyinfo->grabbed = 0;
4679           check_visibility = 1;
4680           break;
4681 
4682         case WM_KILLFOCUS:
4683           f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
4684 
4685           if (f)
4686             {
4687               if (f == dpyinfo->w32_focus_event_frame)
4688                 dpyinfo->w32_focus_event_frame = 0;
4689 
4690               if (f == dpyinfo->w32_focus_frame)
4691                 x_new_focus_frame (dpyinfo, 0);
4692 
4693               if (f == dpyinfo->mouse_face_mouse_frame)
4694                 {
4695                   /* If we move outside the frame, then we're
4696                      certainly no longer on any text in the frame.  */
4697                   clear_mouse_face (dpyinfo);
4698                   dpyinfo->mouse_face_mouse_frame = 0;
4699                 }
4700 
4701               /* Generate a nil HELP_EVENT to cancel a help-echo.
4702                  Do it only if there's something to cancel.
4703                  Otherwise, the startup message is cleared when
4704                  the mouse leaves the frame.  */
4705               if (any_help_event_p)
4706                 do_help = -1;
4707             }
4708 
4709           dpyinfo->grabbed = 0;
4710           check_visibility = 1;
4711           break;
4712 
4713         case WM_CLOSE:
4714           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4715 
4716           if (f)
4717             {
4718               inev.kind = DELETE_WINDOW_EVENT;
4719               XSETFRAME (inev.frame_or_window, f);
4720             }
4721           break;
4722 
4723         case WM_INITMENU:
4724           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4725 
4726           if (f)
4727             {
4728               inev.kind = MENU_BAR_ACTIVATE_EVENT;
4729               XSETFRAME (inev.frame_or_window, f);
4730             }
4731           break;
4732 
4733         case WM_COMMAND:
4734           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4735 
4736           if (f)
4737             {
4738               extern void menubar_selection_callback
4739                 (FRAME_PTR f, void * client_data);
4740               menubar_selection_callback (f, (void *)msg.msg.wParam);
4741             }
4742 
4743           check_visibility = 1;
4744           break;
4745 
4746         case WM_DISPLAYCHANGE:
4747           f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4748 
4749           if (f)
4750             {
4751               dpyinfo->n_cbits = msg.msg.wParam;
4752               DebPrint (("display change: %d %d\n",
4753                          (short) LOWORD (msg.msg.lParam),
4754                          (short) HIWORD (msg.msg.lParam)));
4755             }
4756 
4757           check_visibility = 1;
4758           break;
4759 
4760         default:
4761           /* Check for messages registered at runtime.  */
4762           if (msg.msg.message == msh_mousewheel)
4763             {
4764               /* Forward MSH_MOUSEWHEEL as WM_MOUSEWHEEL.  */
4765               msg.msg.message = WM_MOUSEWHEEL;
4766               prepend_msg (&msg);
4767             }
4768           break;
4769         }
4770 
4771       if (inev.kind != NO_EVENT)
4772         {
4773           kbd_buffer_store_event_hold (&inev, hold_quit);
4774           count++;
4775         }
4776 
4777       if (do_help
4778           && !(hold_quit && hold_quit->kind != NO_EVENT))
4779         {
4780           Lisp_Object frame;
4781 
4782           if (f)
4783             XSETFRAME (frame, f);
4784           else
4785             frame = Qnil;
4786 
4787           if (do_help > 0)
4788             {
4789               if (NILP (help_echo_string))
4790                 {
4791                   help_echo_object = help_echo_window = Qnil;
4792                   help_echo_pos = -1;
4793                 }
4794 
4795               any_help_event_p = 1;
4796               gen_help_event (help_echo_string, frame, help_echo_window,
4797                               help_echo_object, help_echo_pos);
4798             }
4799           else
4800             {
4801               help_echo_string = Qnil;
4802               gen_help_event (Qnil, frame, Qnil, Qnil, 0);
4803             }
4804           count++;
4805         }
4806     }
4807 
4808   /* If the focus was just given to an autoraising frame,
4809      raise it now.  */
4810   /* ??? This ought to be able to handle more than one such frame.  */
4811   if (pending_autoraise_frame)
4812     {
4813       x_raise_frame (pending_autoraise_frame);
4814       pending_autoraise_frame = 0;
4815     }
4816 
4817   /* Check which frames are still visisble, if we have enqueued any user
4818      events or been notified of events that may affect visibility.  We
4819      do this here because there doesn't seem to be any direct
4820      notification from Windows that the visibility of a window has
4821      changed (at least, not in all cases).  */
4822   if (count > 0 || check_visibility)
4823     {
4824       Lisp_Object tail, frame;
4825 
4826       FOR_EACH_FRAME (tail, frame)
4827       {
4828         FRAME_PTR f = XFRAME (frame);
4829         /* The tooltip has been drawn already.  Avoid the
4830            SET_FRAME_GARBAGED below.  */
4831         if (EQ (frame, tip_frame))
4832           continue;
4833 
4834         /* Check "visible" frames and mark each as obscured or not.
4835            Note that async_visible is nonzero for unobscured and
4836            obscured frames, but zero for hidden and iconified frames.  */
4837         if (FRAME_W32_P (f) && f->async_visible)
4838           {
4839             RECT clipbox;
4840             HDC  hdc;
4841 
4842             enter_crit ();
4843             /* Query clipping rectangle for the entire window area
4844                (GetWindowDC), not just the client portion (GetDC).
4845                Otherwise, the scrollbars and menubar aren't counted as
4846                part of the visible area of the frame, and we may think
4847                the frame is obscured when really a scrollbar is still
4848                visible and gets WM_PAINT messages above.  */
4849             hdc = GetWindowDC (FRAME_W32_WINDOW (f));
4850             GetClipBox (hdc, &clipbox);
4851             ReleaseDC (FRAME_W32_WINDOW (f), hdc);
4852             leave_crit ();
4853 
4854             if (clipbox.right == clipbox.left
4855                 || clipbox.bottom == clipbox.top)
4856               {
4857                 /* Frame has become completely obscured so mark as
4858                    such (we do this by setting async_visible to 2 so
4859                    that FRAME_VISIBLE_P is still true, but redisplay
4860                    will skip it).  */
4861                 f->async_visible = 2;
4862 
4863                 if (!FRAME_OBSCURED_P (f))
4864                   {
4865                     DebPrint (("frame %p (%s) obscured\n", f,
4866                                SDATA (f->name)));
4867                   }
4868               }
4869             else
4870               {
4871                 /* Frame is not obscured, so mark it as such.  */
4872                 f->async_visible = 1;
4873 
4874                 if (FRAME_OBSCURED_P (f))
4875                   {
4876                     SET_FRAME_GARBAGED (f);
4877                     DebPrint (("obscured frame %p (%s) found to be visible\n", f,
4878                                SDATA (f->name)));
4879 
4880                     /* Force a redisplay sooner or later.  */
4881                     record_asynch_buffer_change ();
4882                   }
4883               }
4884           }
4885       }
4886     }
4887 
4888   UNBLOCK_INPUT;
4889   return count;
4890 }
4891 
4892 
4893 
4894 /***********************************************************************
4895                              Text Cursor
4896  ***********************************************************************/
4897 
4898 /* Set clipping for output in glyph row ROW.  W is the window in which
4899    we operate.  GC is the graphics context to set clipping in.
4900 
4901    ROW may be a text row or, e.g., a mode line.  Text rows must be
4902    clipped to the interior of the window dedicated to text display,
4903    mode lines must be clipped to the whole window.  */
4904 
4905 static void
4906 w32_clip_to_row (w, row, area, hdc)
4907      struct window *w;
4908      struct glyph_row *row;
4909      int area;
4910      HDC hdc;
4911 {
4912   struct frame *f = XFRAME (WINDOW_FRAME (w));
4913   RECT clip_rect;
4914   int window_x, window_y, window_width;
4915 
4916   window_box (w, area, &window_x, &window_y, &window_width, 0);
4917 
4918   clip_rect.left = window_x;
4919   clip_rect.top = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
4920   clip_rect.top = max (clip_rect.top, window_y);
4921   clip_rect.right = clip_rect.left + window_width;
4922   clip_rect.bottom = clip_rect.top + row->visible_height;
4923 
4924   w32_set_clip_rectangle (hdc, &clip_rect);
4925 }
4926 
4927 
4928 /* Draw a hollow box cursor on window W in glyph row ROW.  */
4929 
4930 static void
4931 x_draw_hollow_cursor (w, row)
4932      struct window *w;
4933      struct glyph_row *row;
4934 {
4935   struct frame *f = XFRAME (WINDOW_FRAME (w));
4936   HDC hdc;
4937   RECT rect;
4938   int left, top, h;
4939   struct glyph *cursor_glyph;
4940   HBRUSH hb = CreateSolidBrush (f->output_data.w32->cursor_pixel);
4941 
4942   /* Get the glyph the cursor is on.  If we can't tell because
4943      the current matrix is invalid or such, give up.  */
4944   cursor_glyph = get_phys_cursor_glyph (w);
4945   if (cursor_glyph == NULL)
4946     return;
4947 
4948   /* Compute frame-relative coordinates for phys cursor.  */
4949   get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
4950   rect.left = left;
4951   rect.top = top;
4952   rect.bottom = rect.top + h;
4953   rect.right = rect.left + w->phys_cursor_width;
4954 
4955   hdc = get_frame_dc (f);
4956   /* Set clipping, draw the rectangle, and reset clipping again.  */
4957   w32_clip_to_row (w, row, TEXT_AREA, hdc);
4958   FrameRect (hdc, &rect, hb);
4959   DeleteObject (hb);
4960   w32_set_clip_rectangle (hdc, NULL);
4961   release_frame_dc (f, hdc);
4962 }
4963 
4964 
4965 /* Draw a bar cursor on window W in glyph row ROW.
4966 
4967    Implementation note: One would like to draw a bar cursor with an
4968    angle equal to the one given by the font property XA_ITALIC_ANGLE.
4969    Unfortunately, I didn't find a font yet that has this property set.
4970    --gerd.  */
4971 
4972 static void
4973 x_draw_bar_cursor (w, row, width, kind)
4974      struct window *w;
4975      struct glyph_row *row;
4976      int width;
4977      enum text_cursor_kinds kind;
4978 {
4979   struct frame *f = XFRAME (w->frame);
4980   struct glyph *cursor_glyph;
4981 
4982   /* If cursor is out of bounds, don't draw garbage.  This can happen
4983      in mini-buffer windows when switching between echo area glyphs
4984      and mini-buffer.  */
4985   cursor_glyph = get_phys_cursor_glyph (w);
4986   if (cursor_glyph == NULL)
4987     return;
4988 
4989   /* If on an image, draw like a normal cursor.  That's usually better
4990      visible than drawing a bar, esp. if the image is large so that
4991      the bar might not be in the window.  */
4992   if (cursor_glyph->type == IMAGE_GLYPH)
4993     {
4994       struct glyph_row *row;
4995       row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
4996       draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
4997     }
4998   else
4999     {
5000       COLORREF cursor_color = f->output_data.w32->cursor_pixel;
5001       struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
5002       int x;
5003       HDC hdc;
5004 
5005       /* If the glyph's background equals the color we normally draw
5006          the bar cursor in, the bar cursor in its normal color is
5007          invisible.  Use the glyph's foreground color instead in this
5008          case, on the assumption that the glyph's colors are chosen so
5009          that the glyph is legible.  */
5010       if (face->background == cursor_color)
5011         cursor_color = face->foreground;
5012 
5013       x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
5014 
5015       hdc = get_frame_dc (f);
5016       w32_clip_to_row (w, row, TEXT_AREA, hdc);
5017 
5018       if (kind == BAR_CURSOR)
5019         {
5020           if (width < 0)
5021             width = FRAME_CURSOR_WIDTH (f);
5022           width = min (cursor_glyph->pixel_width, width);
5023 
5024           w->phys_cursor_width = width;
5025 
5026           w32_fill_area (f, hdc, cursor_color, x,
5027                          WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
5028                          width, row->height);
5029         }
5030       else
5031         {
5032           int dummy_x, dummy_y, dummy_h;
5033 
5034           if (width < 0)
5035             width = row->height;
5036 
5037           width = min (row->height, width);
5038 
5039           get_phys_cursor_geometry (w, row, cursor_glyph, &dummy_x,
5040                                     &dummy_y, &dummy_h);
5041           w32_fill_area (f, hdc, cursor_color, x,
5042                          WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
5043                                                   row->height - width),
5044                          w->phys_cursor_width, width);
5045         }
5046 
5047       w32_set_clip_rectangle (hdc, NULL);
5048       release_frame_dc (f, hdc);
5049     }
5050 }
5051 
5052 
5053 /* RIF: Define cursor CURSOR on frame F.  */
5054 
5055 static void
5056 w32_define_frame_cursor (f, cursor)
5057      struct frame *f;
5058      Cursor cursor;
5059 {
5060   w32_define_cursor (FRAME_W32_WINDOW (f), cursor);
5061 }
5062 
5063 
5064 /* RIF: Clear area on frame F.  */
5065 
5066 static void
5067 w32_clear_frame_area (f, x, y, width, height)
5068      struct frame *f;
5069      int x, y, width, height;
5070 {
5071   HDC hdc;
5072 
5073   hdc = get_frame_dc (f);
5074   w32_clear_area (f, hdc, x, y, width, height);
5075   release_frame_dc (f, hdc);
5076 }
5077 
5078 /* RIF: Draw or clear cursor on window W.  */
5079 
5080 static void
5081 w32_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, active_p)
5082      struct window *w;
5083      struct glyph_row *glyph_row;
5084      int x, y;
5085      int cursor_type, cursor_width;
5086      int on_p, active_p;
5087 {
5088   if (on_p)
5089     {
5090       /* If the user wants to use the system caret, make sure our own
5091          cursor remains invisible.  */
5092       if (w32_use_visible_system_caret)
5093         {
5094           /* Call to erase_phys_cursor here seems to use the
5095              wrong values of w->phys_cursor, as they have been
5096              overwritten before this function was called. */
5097           if (w->phys_cursor_type != NO_CURSOR)
5098             erase_phys_cursor (w);
5099 
5100           cursor_type = w->phys_cursor_type = NO_CURSOR;
5101           w->phys_cursor_width = -1;
5102         }
5103       else
5104         {
5105           w->phys_cursor_type = cursor_type;
5106         }
5107 
5108       w->phys_cursor_on_p = 1;
5109 
5110       /* If this is the active cursor, we need to track it with the
5111          system caret, so third party software like screen magnifiers
5112          and speech synthesizers can follow the cursor.  */
5113       if (active_p)
5114         {
5115           struct frame *f = XFRAME (WINDOW_FRAME (w));
5116           HWND hwnd = FRAME_W32_WINDOW (f);
5117 
5118           w32_system_caret_x
5119             = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
5120           w32_system_caret_y
5121             = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
5122                + glyph_row->ascent - w->phys_cursor_ascent);
5123 
5124           PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
5125 
5126           /* If the size of the active cursor changed, destroy the old
5127              system caret.  */
5128           if (w32_system_caret_hwnd
5129               && (w32_system_caret_height != w->phys_cursor_height))
5130             PostMessage (hwnd, WM_EMACS_DESTROY_CARET, 0, 0);
5131 
5132           w32_system_caret_height = w->phys_cursor_height;
5133 
5134           /* Move the system caret.  */
5135           PostMessage (hwnd, WM_EMACS_TRACK_CARET, 0, 0);
5136         }
5137 
5138       if (glyph_row->exact_window_width_line_p
5139           && (glyph_row->reversed_p
5140               ? (w->phys_cursor.hpos < 0)
5141               : (w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA])))
5142         {
5143           glyph_row->cursor_in_fringe_p = 1;
5144           draw_fringe_bitmap (w, glyph_row, glyph_row->reversed_p);
5145           return;
5146         }
5147 
5148       switch (cursor_type)
5149         {
5150         case HOLLOW_BOX_CURSOR:
5151           x_draw_hollow_cursor (w, glyph_row);
5152           break;
5153 
5154         case FILLED_BOX_CURSOR:
5155           draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
5156           break;
5157 
5158         case BAR_CURSOR:
5159           x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
5160           break;
5161 
5162         case HBAR_CURSOR:
5163           x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
5164           break;
5165 
5166         case NO_CURSOR:
5167           w->phys_cursor_width = 0;
5168           break;
5169 
5170         default:
5171           abort ();
5172         }
5173     }
5174 }
5175 
5176 
5177 
5178 /* Icons.  */
5179 
5180 int
5181 x_bitmap_icon (f, icon)
5182      struct frame *f;
5183      Lisp_Object icon;
5184 {
5185   HANDLE main_icon;
5186   HANDLE small_icon = NULL;
5187 
5188   if (FRAME_W32_WINDOW (f) == 0)
5189     return 1;
5190 
5191   if (NILP (icon))
5192     main_icon = LoadIcon (hinst, EMACS_CLASS);
5193   else if (STRINGP (icon))
5194     {
5195       /* Load the main icon from the named file.  */
5196       main_icon = LoadImage (NULL, (LPCTSTR) SDATA (icon), IMAGE_ICON, 0, 0,
5197                              LR_DEFAULTSIZE | LR_LOADFROMFILE);
5198       /* Try to load a small icon to go with it.  */
5199       small_icon = LoadImage (NULL, (LPCSTR) SDATA (icon), IMAGE_ICON,
5200                               GetSystemMetrics (SM_CXSMICON),
5201                               GetSystemMetrics (SM_CYSMICON),
5202                               LR_LOADFROMFILE);
5203     }
5204   else if (SYMBOLP (icon))
5205     {
5206       LPCTSTR name;
5207 
5208       if (EQ (icon, intern ("application")))
5209         name = (LPCTSTR) IDI_APPLICATION;
5210       else if (EQ (icon, intern ("hand")))
5211         name = (LPCTSTR) IDI_HAND;
5212       else if (EQ (icon, intern ("question")))
5213         name = (LPCTSTR) IDI_QUESTION;
5214       else if (EQ (icon, intern ("exclamation")))
5215         name = (LPCTSTR) IDI_EXCLAMATION;
5216       else if (EQ (icon, intern ("asterisk")))
5217         name = (LPCTSTR) IDI_ASTERISK;
5218       else if (EQ (icon, intern ("winlogo")))
5219         name = (LPCTSTR) IDI_WINLOGO;
5220       else
5221         return 1;
5222 
5223       main_icon = LoadIcon (NULL, name);
5224     }
5225   else
5226     return 1;
5227 
5228   if (main_icon == NULL)
5229     return 1;
5230 
5231   PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_BIG,
5232                (LPARAM) main_icon);
5233 
5234   /* If there is a small icon that goes with it, set that too.  */
5235   if (small_icon)
5236     PostMessage (FRAME_W32_WINDOW (f), WM_SETICON, (WPARAM) ICON_SMALL,
5237                  (LPARAM) small_icon);
5238 
5239   return 0;
5240 }
5241 
5242 
5243 /************************************************************************
5244                           Handling X errors
5245  ************************************************************************/
5246 
5247 /* Display Error Handling functions not used on W32. Listing them here
5248    helps diff stay in step when comparing w32term.c with xterm.c.
5249 
5250 x_error_catcher (display, error)
5251 x_catch_errors (dpy)
5252 x_catch_errors_unwind (old_val)
5253 x_check_errors (dpy, format)
5254 x_fully_uncatch_errors ()
5255 x_catching_errors ()
5256 x_had_errors_p (dpy)
5257 x_clear_errors (dpy)
5258 x_uncatch_errors (dpy, count)
5259 x_trace_wire ()
5260 x_connection_signal (signalnum)
5261 x_connection_closed (dpy, error_message)
5262 x_error_quitter (display, error)
5263 x_error_handler (display, error)
5264 x_io_error_quitter (display)
5265 
5266  */
5267 
5268 
5269 /* Changing the font of the frame.  */
5270 
5271 Lisp_Object
5272 x_new_font (f, font_object, fontset)
5273      struct frame *f;
5274      Lisp_Object font_object;
5275      int fontset;
5276 {
5277   struct font *font = XFONT_OBJECT (font_object);
5278 
5279   if (fontset < 0)
5280     fontset = fontset_from_font (font_object);
5281   FRAME_FONTSET (f) = fontset;
5282   if (FRAME_FONT (f) == font)
5283     /* This font is already set in frame F.  There's nothing more to
5284        do.  */
5285     return font_object;
5286 
5287   FRAME_FONT (f) = font;
5288   FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
5289   FRAME_COLUMN_WIDTH (f) = font->average_width;
5290   FRAME_SPACE_WIDTH (f) = font->space_width;
5291   FRAME_LINE_HEIGHT (f) = font->height;
5292 
5293   compute_fringe_widths (f, 1);
5294 
5295   /* Compute the scroll bar width in character columns.  */
5296   if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
5297     {
5298       int wid = FRAME_COLUMN_WIDTH (f);
5299       FRAME_CONFIG_SCROLL_BAR_COLS (f)
5300         = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
5301     }
5302   else
5303     {
5304       int wid = FRAME_COLUMN_WIDTH (f);
5305       FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
5306     }
5307 
5308   /* Now make the frame display the given font.  */
5309   if (FRAME_X_WINDOW (f) != 0)
5310     {
5311       /* Don't change the size of a tip frame; there's no point in
5312          doing it because it's done in Fx_show_tip, and it leads to
5313          problems because the tip frame has no widget.  */
5314       if (NILP (tip_frame) || XFRAME (tip_frame) != f)
5315         x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
5316     }
5317 
5318   /* X version sets font of input methods here also.  */
5319 
5320   return font_object;
5321 }
5322 
5323 
5324 /***********************************************************************
5325         TODO: W32 Input Methods
5326  ***********************************************************************/
5327 /* Listing missing functions from xterm.c helps diff stay in step.
5328 
5329 xim_destroy_callback (xim, client_data, call_data)
5330 xim_open_dpy (dpyinfo, resource_name)
5331 struct xim_inst_t
5332 xim_instantiate_callback (display, client_data, call_data)
5333 xim_initialize (dpyinfo, resource_name)
5334 xim_close_dpy (dpyinfo)
5335 
5336  */
5337 
5338 
5339 /* Calculate the absolute position in frame F
5340    from its current recorded position values and gravity.  */
5341 
5342 void
5343 x_calc_absolute_position (f)
5344      struct frame *f;
5345 {
5346   int flags = f->size_hint_flags;
5347 
5348   /* The sum of the widths of the frame's left and right borders, and
5349      the sum of the heights of the frame's top and bottom borders (in
5350      pixels) drawn by Windows.  */
5351   unsigned int left_right_borders_width, top_bottom_borders_height;
5352 
5353   /* Try to get the actual values of these two variables.  We compute
5354      the border width (height) by subtracting the width (height) of
5355      the frame's client area from the width (height) of the frame's
5356      entire window.  */
5357   WINDOWPLACEMENT wp = { 0 };
5358   RECT client_rect = { 0 };
5359 
5360   if (GetWindowPlacement (FRAME_W32_WINDOW (f), &wp)
5361       && GetClientRect (FRAME_W32_WINDOW (f), &client_rect))
5362     {
5363       left_right_borders_width =
5364         (wp.rcNormalPosition.right - wp.rcNormalPosition.left) -
5365         (client_rect.right - client_rect.left);
5366 
5367       top_bottom_borders_height =
5368         (wp.rcNormalPosition.bottom - wp.rcNormalPosition.top) -
5369         (client_rect.bottom - client_rect.top);
5370     }
5371   else
5372     {
5373       /* Use sensible default values.  */
5374       left_right_borders_width = 8;
5375       top_bottom_borders_height = 32;
5376     }
5377 
5378   /* Treat negative positions as relative to the rightmost bottommost
5379      position that fits on the screen.  */
5380   if (flags & XNegative)
5381     f->left_pos = (x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f))
5382                    - FRAME_PIXEL_WIDTH (f)
5383                    + f->left_pos
5384                    - (left_right_borders_width - 1));
5385 
5386   if (flags & YNegative)
5387     f->top_pos = (x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f))
5388                   - FRAME_PIXEL_HEIGHT (f)
5389                   + f->top_pos
5390                   - (top_bottom_borders_height - 1));
5391 
5392   /* The left_pos and top_pos are now relative to the top and left
5393      screen edges, so the flags should correspond.  */
5394   f->size_hint_flags &= ~ (XNegative | YNegative);
5395 }
5396 
5397 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5398    to really change the position, and 0 when calling from
5399    x_make_frame_visible (in that case, XOFF and YOFF are the current
5400    position values).  It is -1 when calling from x_set_frame_parameters,
5401    which means, do adjust for borders but don't change the gravity.  */
5402 
5403 void
5404 x_set_offset (f, xoff, yoff, change_gravity)
5405      struct frame *f;
5406      register int xoff, yoff;
5407      int change_gravity;
5408 {
5409   int modified_top, modified_left;
5410 
5411   if (change_gravity > 0)
5412     {
5413       f->top_pos = yoff;
5414       f->left_pos = xoff;
5415       f->size_hint_flags &= ~ (XNegative | YNegative);
5416       if (xoff < 0)
5417         f->size_hint_flags |= XNegative;
5418       if (yoff < 0)
5419         f->size_hint_flags |= YNegative;
5420       f->win_gravity = NorthWestGravity;
5421     }
5422   x_calc_absolute_position (f);
5423 
5424   BLOCK_INPUT;
5425   x_wm_set_size_hint (f, (long) 0, 0);
5426 
5427   modified_left = f->left_pos;
5428   modified_top = f->top_pos;
5429 
5430   my_set_window_pos (FRAME_W32_WINDOW (f),
5431                      NULL,
5432                      modified_left, modified_top,
5433                      0, 0,
5434                      SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
5435   UNBLOCK_INPUT;
5436 }
5437 
5438 
5439 /* Check if we need to resize the frame due to a fullscreen request.
5440    If so needed, resize the frame. */
5441 static void
5442 x_check_fullscreen (f)
5443      struct frame *f;
5444 {
5445   if (f->want_fullscreen & FULLSCREEN_BOTH)
5446     {
5447       int width, height, ign;
5448 
5449       x_real_positions (f, &f->left_pos, &f->top_pos);
5450 
5451       x_fullscreen_adjust (f, &width, &height, &ign, &ign);
5452 
5453       /* We do not need to move the window, it shall be taken care of
5454          when setting WM manager hints.  */
5455       if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
5456         {
5457           change_frame_size (f, height, width, 0, 1, 0);
5458           SET_FRAME_GARBAGED (f);
5459           cancel_mouse_face (f);
5460 
5461           /* Wait for the change of frame size to occur */
5462           f->want_fullscreen |= FULLSCREEN_WAIT;
5463         }
5464     }
5465 }
5466 
5467 /* Call this to change the size of frame F's x-window.
5468    If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5469    for this size change and subsequent size changes.
5470    Otherwise we leave the window gravity unchanged.  */
5471 
5472 void
5473 x_set_window_size (f, change_gravity, cols, rows)
5474      struct frame *f;
5475      int change_gravity;
5476      int cols, rows;
5477 {
5478   int pixelwidth, pixelheight;
5479 
5480   BLOCK_INPUT;
5481 
5482   check_frame_size (f, &rows, &cols);
5483   f->scroll_bar_actual_width
5484     = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
5485 
5486   compute_fringe_widths (f, 0);
5487 
5488   pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
5489   pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
5490 
5491   f->win_gravity = NorthWestGravity;
5492   x_wm_set_size_hint (f, (long) 0, 0);
5493 
5494   {
5495     RECT rect;
5496 
5497     rect.left = rect.top = 0;
5498     rect.right = pixelwidth;
5499     rect.bottom = pixelheight;
5500 
5501     AdjustWindowRect(&rect, f->output_data.w32->dwStyle,
5502                      FRAME_EXTERNAL_MENU_BAR (f));
5503 
5504     my_set_window_pos (FRAME_W32_WINDOW (f),
5505                        NULL,
5506                        0, 0,
5507                        rect.right - rect.left,
5508                        rect.bottom - rect.top,
5509                        SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
5510   }
5511 
5512 #if 0
5513   /* The following mirrors what is done in xterm.c. It appears to be
5514      for informing lisp of the new size immediately, while the actual
5515      resize will happen asynchronously. But on Windows, the menu bar
5516      automatically wraps when the frame is too narrow to contain it,
5517      and that causes any calculations made here to come out wrong. The
5518      end is some nasty buggy behavior, including the potential loss
5519      of the minibuffer.
5520 
5521      Disabling this code is either not sufficient to fix the problems
5522      completely, or it causes fresh problems, but at least it removes
5523      the most problematic symptom of the minibuffer becoming unusable.
5524 
5525      -----------------------------------------------------------------
5526 
5527      Now, strictly speaking, we can't be sure that this is accurate,
5528      but the window manager will get around to dealing with the size
5529      change request eventually, and we'll hear how it went when the
5530      ConfigureNotify event gets here.
5531 
5532      We could just not bother storing any of this information here,
5533      and let the ConfigureNotify event set everything up, but that
5534      might be kind of confusing to the Lisp code, since size changes
5535      wouldn't be reported in the frame parameters until some random
5536      point in the future when the ConfigureNotify event arrives.
5537 
5538      We pass 1 for DELAY since we can't run Lisp code inside of
5539      a BLOCK_INPUT.  */
5540   change_frame_size (f, rows, cols, 0, 1, 0);
5541   FRAME_PIXEL_WIDTH (f) = pixelwidth;
5542   FRAME_PIXEL_HEIGHT (f) = pixelheight;
5543 
5544   /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
5545      receive in the ConfigureNotify event; if we get what we asked
5546      for, then the event won't cause the screen to become garbaged, so
5547      we have to make sure to do it here.  */
5548   SET_FRAME_GARBAGED (f);
5549 
5550   /* If cursor was outside the new size, mark it as off.  */
5551   mark_window_cursors_off (XWINDOW (f->root_window));
5552 
5553   /* Clear out any recollection of where the mouse highlighting was,
5554      since it might be in a place that's outside the new frame size.
5555      Actually checking whether it is outside is a pain in the neck,
5556      so don't try--just let the highlighting be done afresh with new size.  */
5557   cancel_mouse_face (f);
5558 #endif
5559 
5560   UNBLOCK_INPUT;
5561 }
5562 
5563 /* Mouse warping.  */
5564 
5565 void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
5566 
5567 void
5568 x_set_mouse_position (f, x, y)
5569      struct frame *f;
5570      int x, y;
5571 {
5572   int pix_x, pix_y;
5573 
5574   pix_x = FRAME_COL_TO_PIXEL_X (f, x) + FRAME_COLUMN_WIDTH (f) / 2;
5575   pix_y = FRAME_LINE_TO_PIXEL_Y (f, y) + FRAME_LINE_HEIGHT (f) / 2;
5576 
5577   if (pix_x < 0) pix_x = 0;
5578   if (pix_x > FRAME_PIXEL_WIDTH (f)) pix_x = FRAME_PIXEL_WIDTH (f);
5579 
5580   if (pix_y < 0) pix_y = 0;
5581   if (pix_y > FRAME_PIXEL_HEIGHT (f)) pix_y = FRAME_PIXEL_HEIGHT (f);
5582 
5583   x_set_mouse_pixel_position (f, pix_x, pix_y);
5584 }
5585 
5586 void
5587 x_set_mouse_pixel_position (f, pix_x, pix_y)
5588      struct frame *f;
5589      int pix_x, pix_y;
5590 {
5591   RECT rect;
5592   POINT pt;
5593 
5594   BLOCK_INPUT;
5595 
5596   GetClientRect (FRAME_W32_WINDOW (f), &rect);
5597   pt.x = rect.left + pix_x;
5598   pt.y = rect.top + pix_y;
5599   ClientToScreen (FRAME_W32_WINDOW (f), &pt);
5600 
5601   SetCursorPos (pt.x, pt.y);
5602 
5603   UNBLOCK_INPUT;
5604 }
5605 
5606 
5607 /* focus shifting, raising and lowering.  */
5608 
5609 void
5610 x_focus_on_frame (f)
5611      struct frame *f;
5612 {
5613   struct w32_display_info *dpyinfo = &one_w32_display_info;
5614 
5615   /* Give input focus to frame.  */
5616   BLOCK_INPUT;
5617 #if 0
5618   /* Try not to change its Z-order if possible.  */
5619   if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
5620     my_set_focus (f, FRAME_W32_WINDOW (f));
5621   else
5622 #endif
5623     my_set_foreground_window (FRAME_W32_WINDOW (f));
5624   UNBLOCK_INPUT;
5625 }
5626 
5627 void
5628 x_unfocus_frame (f)
5629      struct frame *f;
5630 {
5631 }
5632 
5633 /* Raise frame F.  */
5634 void
5635 x_raise_frame (f)
5636      struct frame *f;
5637 {
5638   BLOCK_INPUT;
5639 
5640   /* Strictly speaking, raise-frame should only change the frame's Z
5641      order, leaving input focus unchanged.  This is reasonable behavior
5642      on X where the usual policy is point-to-focus.  However, this
5643      behavior would be very odd on Windows where the usual policy is
5644      click-to-focus.
5645 
5646      On X, if the mouse happens to be over the raised frame, it gets
5647      input focus anyway (so the window with focus will never be
5648      completely obscured) - if not, then just moving the mouse over it
5649      is sufficient to give it focus.  On Windows, the user must actually
5650      click on the frame (preferrably the title bar so as not to move
5651      point), which is more awkward.  Also, no other Windows program
5652      raises a window to the top but leaves another window (possibly now
5653      completely obscured) with input focus.
5654 
5655      Because there is a system setting on Windows that allows the user
5656      to choose the point to focus policy, we make the strict semantics
5657      optional, but by default we grab focus when raising.  */
5658 
5659   if (NILP (Vw32_grab_focus_on_raise))
5660     {
5661       /* The obvious call to my_set_window_pos doesn't work if Emacs is
5662          not already the foreground application: the frame is raised
5663          above all other frames belonging to us, but not above the
5664          current top window.  To achieve that, we have to resort to this
5665          more cumbersome method.  */
5666 
5667       HDWP handle = BeginDeferWindowPos (2);
5668       if (handle)
5669         {
5670           DeferWindowPos (handle,
5671                           FRAME_W32_WINDOW (f),
5672                           HWND_TOP,
5673                           0, 0, 0, 0,
5674                           SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
5675 
5676           DeferWindowPos (handle,
5677                           GetForegroundWindow (),
5678                           FRAME_W32_WINDOW (f),
5679                           0, 0, 0, 0,
5680                           SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
5681 
5682           EndDeferWindowPos (handle);
5683         }
5684     }
5685   else
5686     {
5687       my_set_foreground_window (FRAME_W32_WINDOW (f));
5688     }
5689 
5690   UNBLOCK_INPUT;
5691 }
5692 
5693 /* Lower frame F.  */
5694 void
5695 x_lower_frame (f)
5696      struct frame *f;
5697 {
5698   BLOCK_INPUT;
5699   my_set_window_pos (FRAME_W32_WINDOW (f),
5700                      HWND_BOTTOM,
5701                      0, 0, 0, 0,
5702                      SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
5703   UNBLOCK_INPUT;
5704 }
5705 
5706 static void
5707 w32_frame_raise_lower (f, raise_flag)
5708      FRAME_PTR f;
5709      int raise_flag;
5710 {
5711   if (! FRAME_W32_P (f))
5712     return;
5713 
5714   if (raise_flag)
5715     x_raise_frame (f);
5716   else
5717     x_lower_frame (f);
5718 }
5719 
5720 /* Change of visibility.  */
5721 
5722 /* This tries to wait until the frame is really visible.
5723    However, if the window manager asks the user where to position
5724    the frame, this will return before the user finishes doing that.
5725    The frame will not actually be visible at that time,
5726    but it will become visible later when the window manager
5727    finishes with it.  */
5728 
5729 void
5730 x_make_frame_visible (f)
5731      struct frame *f;
5732 {
5733   Lisp_Object type;
5734 
5735   BLOCK_INPUT;
5736 
5737   type = x_icon_type (f);
5738   if (!NILP (type))
5739     x_bitmap_icon (f, type);
5740 
5741   if (! FRAME_VISIBLE_P (f))
5742     {
5743       /* We test FRAME_GARBAGED_P here to make sure we don't
5744          call x_set_offset a second time
5745          if we get to x_make_frame_visible a second time
5746          before the window gets really visible.  */
5747       if (! FRAME_ICONIFIED_P (f)
5748           && ! f->output_data.w32->asked_for_visible)
5749         {
5750           RECT workarea_rect;
5751           RECT window_rect;
5752 
5753           /* Adjust vertical window position in order to avoid being
5754              covered by a task bar placed at the bottom of the desktop. */
5755           SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rect, 0);
5756           GetWindowRect(FRAME_W32_WINDOW(f), &window_rect);
5757           if (window_rect.bottom > workarea_rect.bottom
5758               && window_rect.top > workarea_rect.top)
5759             f->top_pos = max (window_rect.top
5760                               - window_rect.bottom + workarea_rect.bottom,
5761                               workarea_rect.top);
5762 
5763           x_set_offset (f, f->left_pos, f->top_pos, 0);
5764         }
5765 
5766       f->output_data.w32->asked_for_visible = 1;
5767 
5768       /* The first of these seems to give more expected behavior, but
5769          was added as a commented out line in Sept 1997, with the
5770          second version remaining uncommented. There may have been
5771          some problem with it that led to it not being enabled,
5772          so the old version remains commented out below in case we
5773          decide we need to go back to it [23.0.60 2008-06-09].  */
5774       my_show_window (f, FRAME_W32_WINDOW (f),
5775                       f->async_iconified ? SW_RESTORE : SW_SHOW);
5776       /* my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL);  */
5777     }
5778 
5779   /* Synchronize to ensure Emacs knows the frame is visible
5780      before we do anything else.  We do this loop with input not blocked
5781      so that incoming events are handled.  */
5782   {
5783     Lisp_Object frame;
5784     int count;
5785 
5786     /* This must come after we set COUNT.  */
5787     UNBLOCK_INPUT;
5788 
5789     XSETFRAME (frame, f);
5790 
5791     /* Wait until the frame is visible.  Process X events until a
5792        MapNotify event has been seen, or until we think we won't get a
5793        MapNotify at all..  */
5794     for (count = input_signal_count + 10;
5795          input_signal_count < count && !FRAME_VISIBLE_P (f);)
5796       {
5797         /* Force processing of queued events.  */
5798         /* TODO: x_sync equivalent?  */
5799 
5800         /* Machines that do polling rather than SIGIO have been observed
5801            to go into a busy-wait here.  So we'll fake an alarm signal
5802            to let the handler know that there's something to be read.
5803            We used to raise a real alarm, but it seems that the handler
5804            isn't always enabled here.  This is probably a bug.  */
5805         if (input_polling_used ())
5806           {
5807             /* It could be confusing if a real alarm arrives while processing
5808                the fake one.  Turn it off and let the handler reset it.  */
5809             int old_poll_suppress_count = poll_suppress_count;
5810             poll_suppress_count = 1;
5811             poll_for_input_1 ();
5812             poll_suppress_count = old_poll_suppress_count;
5813           }
5814       }
5815     FRAME_SAMPLE_VISIBILITY (f);
5816   }
5817 }
5818 
5819 /* Change from mapped state to withdrawn state. */
5820 
5821 /* Make the frame visible (mapped and not iconified).  */
5822 
5823 x_make_frame_invisible (f)
5824      struct frame *f;
5825 {
5826   /* Don't keep the highlight on an invisible frame.  */
5827   if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
5828     FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
5829 
5830   BLOCK_INPUT;
5831 
5832   my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
5833 
5834   /* We can't distinguish this from iconification
5835      just by the event that we get from the server.
5836      So we can't win using the usual strategy of letting
5837      FRAME_SAMPLE_VISIBILITY set this.  So do it by hand,
5838      and synchronize with the server to make sure we agree.  */
5839   f->visible = 0;
5840   FRAME_ICONIFIED_P (f) = 0;
5841   f->async_visible = 0;
5842   f->async_iconified = 0;
5843 
5844   UNBLOCK_INPUT;
5845 }
5846 
5847 /* Change window state from mapped to iconified. */
5848 
5849 void
5850 x_iconify_frame (f)
5851      struct frame *f;
5852 {
5853   Lisp_Object type;
5854 
5855   /* Don't keep the highlight on an invisible frame.  */
5856   if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
5857     FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
5858 
5859   if (f->async_iconified)
5860     return;
5861 
5862   BLOCK_INPUT;
5863 
5864   type = x_icon_type (f);
5865   if (!NILP (type))
5866     x_bitmap_icon (f, type);
5867 
5868   /* Simulate the user minimizing the frame.  */
5869   SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
5870 
5871   UNBLOCK_INPUT;
5872 }
5873 
5874 
5875 /* Free X resources of frame F.  */
5876 
5877 void
5878 x_free_frame_resources (f)
5879      struct frame *f;
5880 {
5881   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5882 
5883   BLOCK_INPUT;
5884 
5885   /* We must free faces before destroying windows because some
5886      font-driver (e.g. xft) access a window while finishing a
5887      face.  */
5888   if (FRAME_FACE_CACHE (f))
5889     free_frame_faces (f);
5890 
5891   if (FRAME_W32_WINDOW (f))
5892     my_destroy_window (f, FRAME_W32_WINDOW (f));
5893 
5894   free_frame_menubar (f);
5895 
5896   unload_color (f, FRAME_FOREGROUND_PIXEL (f));
5897   unload_color (f, FRAME_BACKGROUND_PIXEL (f));
5898   unload_color (f, f->output_data.w32->cursor_pixel);
5899   unload_color (f, f->output_data.w32->cursor_foreground_pixel);
5900   unload_color (f, f->output_data.w32->border_pixel);
5901   unload_color (f, f->output_data.w32->mouse_pixel);
5902   if (f->output_data.w32->white_relief.allocated_p)
5903     unload_color (f, f->output_data.w32->white_relief.pixel);
5904   if (f->output_data.w32->black_relief.allocated_p)
5905     unload_color (f, f->output_data.w32->black_relief.pixel);
5906 
5907   if (FRAME_FACE_CACHE (f))
5908     free_frame_faces (f);
5909 
5910   xfree (f->output_data.w32);
5911   f->output_data.w32 = NULL;
5912 
5913   if (f == dpyinfo->w32_focus_frame)
5914     dpyinfo->w32_focus_frame = 0;
5915   if (f == dpyinfo->w32_focus_event_frame)
5916     dpyinfo->w32_focus_event_frame = 0;
5917   if (f == dpyinfo->x_highlight_frame)
5918     dpyinfo->x_highlight_frame = 0;
5919 
5920   if (f == dpyinfo->mouse_face_mouse_frame)
5921     {
5922       dpyinfo->mouse_face_beg_row
5923         = dpyinfo->mouse_face_beg_col = -1;
5924       dpyinfo->mouse_face_end_row
5925         = dpyinfo->mouse_face_end_col = -1;
5926       dpyinfo->mouse_face_window = Qnil;
5927       dpyinfo->mouse_face_deferred_gc = 0;
5928       dpyinfo->mouse_face_mouse_frame = 0;
5929     }
5930 
5931   UNBLOCK_INPUT;
5932 }
5933 
5934 
5935 /* Destroy the window of frame F.  */
5936 void
5937 x_destroy_window (f)
5938      struct frame *f;
5939 {
5940   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
5941 
5942   x_free_frame_resources (f);
5943   dpyinfo->reference_count--;
5944 }
5945 
5946 
5947 /* Setting window manager hints.  */
5948 
5949 /* Set the normal size hints for the window manager, for frame F.
5950    FLAGS is the flags word to use--or 0 meaning preserve the flags
5951    that the window now has.
5952    If USER_POSITION is nonzero, we set the USPosition
5953    flag (this is useful when FLAGS is 0).  */
5954 void
5955 x_wm_set_size_hint (f, flags, user_position)
5956      struct frame *f;
5957      long flags;
5958      int user_position;
5959 {
5960   Window window = FRAME_W32_WINDOW (f);
5961 
5962   enter_crit ();
5963 
5964   SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
5965   SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
5966   SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
5967   SetWindowLong (window, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
5968 
5969   leave_crit ();
5970 }
5971 
5972 /* Window manager things */
5973 void
5974 x_wm_set_icon_position (f, icon_x, icon_y)
5975      struct frame *f;
5976      int icon_x, icon_y;
5977 {
5978 #if 0
5979   Window window = FRAME_W32_WINDOW (f);
5980 
5981   f->display.x->wm_hints.flags |= IconPositionHint;
5982   f->display.x->wm_hints.icon_x = icon_x;
5983   f->display.x->wm_hints.icon_y = icon_y;
5984 
5985   XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
5986 #endif
5987 }
5988 
5989 
5990 /***********************************************************************
5991                             Initialization
5992  ***********************************************************************/
5993 
5994 static int w32_initialized = 0;
5995 
5996 void
5997 w32_initialize_display_info (display_name)
5998      Lisp_Object display_name;
5999 {
6000   struct w32_display_info *dpyinfo = &one_w32_display_info;
6001 
6002   bzero (dpyinfo, sizeof (*dpyinfo));
6003 
6004   /* Put it on w32_display_name_list.  */
6005   w32_display_name_list = Fcons (Fcons (display_name, Qnil),
6006                                  w32_display_name_list);
6007   dpyinfo->name_list_element = XCAR (w32_display_name_list);
6008 
6009   dpyinfo->w32_id_name
6010     = (char *) xmalloc (SCHARS (Vinvocation_name)
6011                         + SCHARS (Vsystem_name)
6012                         + 2);
6013   sprintf (dpyinfo->w32_id_name, "%s@%s",
6014            SDATA (Vinvocation_name), SDATA (Vsystem_name));
6015 
6016   /* Default Console mode values - overridden when running in GUI mode
6017      with values obtained from system metrics.  */
6018   dpyinfo->resx = 1;
6019   dpyinfo->resy = 1;
6020   dpyinfo->n_planes = 1;
6021   dpyinfo->n_cbits = 4;
6022   dpyinfo->n_fonts = 0;
6023   dpyinfo->smallest_font_height = 1;
6024   dpyinfo->smallest_char_width = 1;
6025 
6026   dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
6027   dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
6028   dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
6029   dpyinfo->mouse_face_window = Qnil;
6030   dpyinfo->mouse_face_overlay = Qnil;
6031   dpyinfo->mouse_face_hidden = 0;
6032 
6033   dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
6034   /* TODO: dpyinfo->gray */
6035 
6036 }
6037 
6038 /* Create an xrdb-style database of resources to supercede registry settings.
6039    The database is just a concatenation of C strings, finished by an additional
6040    \0.  The strings are submitted to some basic normalization, so
6041 
6042      [ *]option[ *]:[ *]value...
6043 
6044    becomes
6045 
6046      option:value...
6047 
6048    but any whitespace following value is not removed.  */
6049 
6050 static char *
6051 w32_make_rdb (xrm_option)
6052      char *xrm_option;
6053 {
6054   char *buffer = xmalloc (strlen (xrm_option) + 2);
6055   char *current = buffer;
6056   char ch;
6057   int in_option = 1;
6058   int before_value = 0;
6059 
6060   do {
6061     ch = *xrm_option++;
6062 
6063     if (ch == '\n')
6064       {
6065         *current++ = '\0';
6066         in_option = 1;
6067         before_value = 0;
6068       }
6069     else if (ch != ' ')
6070       {
6071         *current++ = ch;
6072         if (in_option && (ch == ':'))
6073           {
6074             in_option = 0;
6075             before_value = 1;
6076           }
6077         else if (before_value)
6078           {
6079             before_value = 0;
6080           }
6081       }
6082     else if (!(in_option || before_value))
6083       {
6084         *current++ = ch;
6085       }
6086   } while (ch);
6087 
6088   *current = '\0';
6089 
6090   return buffer;
6091 }
6092 
6093 void
6094 x_flush (struct frame * f)
6095 { /* Nothing to do */ }
6096 
6097 
6098 extern frame_parm_handler w32_frame_parm_handlers[];
6099 
6100 static struct redisplay_interface w32_redisplay_interface =
6101 {
6102   w32_frame_parm_handlers,
6103   x_produce_glyphs,
6104   x_write_glyphs,
6105   x_insert_glyphs,
6106   x_clear_end_of_line,
6107   x_scroll_run,
6108   x_after_update_window_line,
6109   x_update_window_begin,
6110   x_update_window_end,
6111   x_cursor_to,
6112   x_flush,
6113   0,  /* flush_display_optional */
6114   x_clear_window_mouse_face,
6115   x_get_glyph_overhangs,
6116   x_fix_overlapping_area,
6117   w32_draw_fringe_bitmap,
6118   w32_define_fringe_bitmap,
6119   w32_destroy_fringe_bitmap,
6120   w32_compute_glyph_string_overhangs,
6121   x_draw_glyph_string,
6122   w32_define_frame_cursor,
6123   w32_clear_frame_area,
6124   w32_draw_window_cursor,
6125   w32_draw_vertical_window_border,
6126   w32_shift_glyphs_for_insert
6127 };
6128 
6129 static void x_delete_terminal (struct terminal *term);
6130 
6131 static struct terminal *
6132 w32_create_terminal (struct w32_display_info *dpyinfo)
6133 {
6134   struct terminal *terminal;
6135 
6136   terminal = create_terminal ();
6137 
6138   terminal->type = output_w32;
6139   terminal->display_info.w32 = dpyinfo;
6140   dpyinfo->terminal = terminal;
6141 
6142   /* MSVC does not type K&R functions with no arguments correctly, and
6143      so we must explicitly cast them.  */
6144   terminal->clear_frame_hook = x_clear_frame;
6145   terminal->ins_del_lines_hook = x_ins_del_lines;
6146   terminal->delete_glyphs_hook = x_delete_glyphs;
6147   terminal->ring_bell_hook = w32_ring_bell;
6148   terminal->reset_terminal_modes_hook = w32_reset_terminal_modes;
6149   terminal->set_terminal_modes_hook = w32_set_terminal_modes;
6150   terminal->update_begin_hook = x_update_begin;
6151   terminal->update_end_hook = x_update_end;
6152   terminal->set_terminal_window_hook = w32_set_terminal_window;
6153   terminal->read_socket_hook = w32_read_socket;
6154   terminal->frame_up_to_date_hook = w32_frame_up_to_date;
6155   terminal->mouse_position_hook = w32_mouse_position;
6156   terminal->frame_rehighlight_hook = w32_frame_rehighlight;
6157   terminal->frame_raise_lower_hook = w32_frame_raise_lower;
6158   //  terminal->fullscreen_hook = XTfullscreen_hook;
6159   terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
6160   terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
6161   terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
6162   terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
6163 
6164   terminal->delete_frame_hook = x_destroy_window;
6165   terminal->delete_terminal_hook = x_delete_terminal;
6166 
6167   terminal->rif = &w32_redisplay_interface;
6168   terminal->scroll_region_ok = 1;    /* We'll scroll partial frames. */
6169   terminal->char_ins_del_ok = 1;
6170   terminal->line_ins_del_ok = 1;         /* We'll just blt 'em. */
6171   terminal->fast_clear_end_of_line = 1;  /* X does this well. */
6172   terminal->memory_below_frame = 0;   /* We don't remember what scrolls
6173                                         off the bottom. */
6174 
6175   /* We don't yet support separate terminals on W32, so don't try to share
6176      keyboards between virtual terminals that are on the same physical
6177      terminal like X does.  */
6178   terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
6179   init_kboard (terminal->kboard);
6180   terminal->kboard->Vwindow_system = intern ("w32");
6181   terminal->kboard->next_kboard = all_kboards;
6182   all_kboards = terminal->kboard;
6183   /* Don't let the initial kboard remain current longer than necessary.
6184      That would cause problems if a file loaded on startup tries to
6185      prompt in the mini-buffer.  */
6186   if (current_kboard == initial_kboard)
6187     current_kboard = terminal->kboard;
6188   terminal->kboard->reference_count++;
6189 
6190   return terminal;
6191 }
6192 
6193 static void
6194 x_delete_terminal (struct terminal *terminal)
6195 {
6196   struct w32_display_info *dpyinfo = terminal->display_info.w32;
6197   int i;
6198 
6199   /* Protect against recursive calls.  delete_frame in
6200      delete_terminal calls us back when it deletes our last frame.  */
6201   if (!terminal->name)
6202     return;
6203 
6204   BLOCK_INPUT;
6205 
6206   x_delete_display (dpyinfo);
6207   UNBLOCK_INPUT;
6208 }
6209 
6210 struct w32_display_info *
6211 w32_term_init (display_name, xrm_option, resource_name)
6212      Lisp_Object display_name;
6213      char *xrm_option;
6214      char *resource_name;
6215 {
6216   struct w32_display_info *dpyinfo;
6217   struct terminal *terminal;
6218   HDC hdc;
6219 
6220   BLOCK_INPUT;
6221 
6222   if (!w32_initialized)
6223     {
6224       w32_initialize ();
6225       w32_initialized = 1;
6226     }
6227 
6228   w32_initialize_display_info (display_name);
6229 
6230   dpyinfo = &one_w32_display_info;
6231   terminal = w32_create_terminal (dpyinfo);
6232 
6233   /* Set the name of the terminal. */
6234   terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
6235   strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
6236   terminal->name[SBYTES (display_name)] = 0;
6237 
6238   dpyinfo->xrdb = xrm_option ? w32_make_rdb (xrm_option) : NULL;
6239 
6240   /* Put this display on the chain.  */
6241   dpyinfo->next = x_display_list;
6242   x_display_list = dpyinfo;
6243 
6244   hdc = GetDC (NULL);
6245 
6246   dpyinfo->root_window = GetDesktopWindow ();
6247   dpyinfo->n_planes = GetDeviceCaps (hdc, PLANES);
6248   dpyinfo->n_cbits = GetDeviceCaps (hdc, BITSPIXEL);
6249   dpyinfo->resx = GetDeviceCaps (hdc, LOGPIXELSX);
6250   dpyinfo->resy = GetDeviceCaps (hdc, LOGPIXELSY);
6251   dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
6252   ReleaseDC (NULL, hdc);
6253 
6254   /* initialise palette with white and black */
6255   {
6256     XColor color;
6257     w32_defined_color (0, "white", &color, 1);
6258     w32_defined_color (0, "black", &color, 1);
6259   }
6260 
6261   /* Add the default keyboard.  */
6262   add_keyboard_wait_descriptor (0);
6263 
6264   /* Create Fringe Bitmaps and store them for later use.
6265 
6266      On W32, bitmaps are all unsigned short, as Windows requires
6267      bitmap data to be Word aligned.  For some reason they are
6268      horizontally reflected compared to how they appear on X, so we
6269      need to bitswap and convert to unsigned shorts before creating
6270      the bitmaps.  */
6271   w32_init_fringe (terminal->rif);
6272 
6273 #ifdef F_SETOWN
6274   fcntl (connection, F_SETOWN, getpid ());
6275 #endif /* ! defined (F_SETOWN) */
6276 
6277 #ifdef SIGIO
6278   if (interrupt_input)
6279     init_sigio (connection);
6280 #endif /* ! defined (SIGIO) */
6281 
6282   UNBLOCK_INPUT;
6283 
6284   return dpyinfo;
6285 }
6286 
6287 /* Get rid of display DPYINFO, assuming all frames are already gone.  */
6288 void
6289 x_delete_display (dpyinfo)
6290      struct w32_display_info *dpyinfo;
6291 {
6292   /* Discard this display from w32_display_name_list and w32_display_list.
6293      We can't use Fdelq because that can quit.  */
6294   if (! NILP (w32_display_name_list)
6295       && EQ (XCAR (w32_display_name_list), dpyinfo->name_list_element))
6296     w32_display_name_list = XCDR (w32_display_name_list);
6297   else
6298     {
6299       Lisp_Object tail;
6300 
6301       tail = w32_display_name_list;
6302       while (CONSP (tail) && CONSP (XCDR (tail)))
6303         {
6304           if (EQ (XCAR (XCDR (tail)), dpyinfo->name_list_element))
6305             {
6306               XSETCDR (tail, XCDR (XCDR (tail)));
6307               break;
6308             }
6309           tail = XCDR (tail);
6310         }
6311     }
6312 
6313   /* free palette table */
6314   {
6315     struct w32_palette_entry * plist;
6316 
6317     plist = dpyinfo->color_list;
6318     while (plist)
6319     {
6320       struct w32_palette_entry * pentry = plist;
6321       plist = plist->next;
6322       xfree (pentry);
6323     }
6324     dpyinfo->color_list = NULL;
6325     if (dpyinfo->palette)
6326       DeleteObject(dpyinfo->palette);
6327   }
6328   xfree (dpyinfo->w32_id_name);
6329 
6330   w32_reset_fringes ();
6331 }
6332 
6333 /* Set up use of W32.  */
6334 
6335 DWORD WINAPI w32_msg_worker (void * arg);
6336 
6337 static void
6338 w32_initialize ()
6339 {
6340   HANDLE shell;
6341   HRESULT (WINAPI * set_user_model) (wchar_t * id);
6342 
6343   baud_rate = 19200;
6344 
6345   w32_system_caret_hwnd = NULL;
6346   w32_system_caret_height = 0;
6347   w32_system_caret_x = 0;
6348   w32_system_caret_y = 0;
6349 
6350   /* On Windows 7 and later, we need to set the user model ID
6351      to associate emacsclient launched files with Emacs frames
6352      in the UI.  */
6353   shell = GetModuleHandle ("shell32.dll");
6354   if (shell)
6355     {
6356       set_user_model
6357         = (void *) GetProcAddress (shell,
6358                                    "SetCurrentProcessExplicitAppUserModelID");
6359 
6360       /* If the function is defined, then we are running on Windows 7
6361          or newer, and the UI uses this to group related windows
6362          together.  Since emacs, runemacs, emacsclient are related, we
6363          want them grouped even though the executables are different,
6364          so we need to set a consistent ID between them.  */
6365       if (set_user_model)
6366         set_user_model (L"GNU.Emacs");
6367     }
6368 
6369   /* Initialize w32_use_visible_system_caret based on whether a screen
6370      reader is in use.  */
6371   if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
6372                              &w32_use_visible_system_caret, 0))
6373     w32_use_visible_system_caret = 0;
6374 
6375   last_tool_bar_item = -1;
6376   any_help_event_p = 0;
6377 
6378   /* Initialize input mode: interrupt_input off, no flow control, allow
6379      8 bit character input, standard quit char.  */
6380   Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
6381 
6382   {
6383     DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
6384     keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
6385   }
6386 
6387   /* Create the window thread - it will terminate itself when the app
6388      terminates */
6389   init_crit ();
6390 
6391   dwMainThreadId = GetCurrentThreadId ();
6392   DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
6393                    GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS);
6394 
6395   /* Wait for thread to start */
6396   {
6397     MSG msg;
6398 
6399     PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
6400 
6401     hWindowsThread = CreateThread (NULL, 0,
6402                                    w32_msg_worker,
6403                                    0, 0, &dwWindowsThreadId);
6404 
6405     GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
6406   }
6407 
6408   /* It is desirable that mainThread should have the same notion of
6409      focus window and active window as windowsThread.  Unfortunately, the
6410      following call to AttachThreadInput, which should do precisely what
6411      we need, causes major problems when Emacs is linked as a console
6412      program.  Unfortunately, we have good reasons for doing that, so
6413      instead we need to send messages to windowsThread to make some API
6414      calls for us (ones that affect, or depend on, the active/focus
6415      window state.)  */
6416 #ifdef ATTACH_THREADS
6417   AttachThreadInput (dwMainThreadId, dwWindowsThreadId, TRUE);
6418 #endif
6419 
6420   /* Dynamically link to optional system components.  */
6421   {
6422     HMODULE user_lib = GetModuleHandle ("user32.dll");
6423 
6424 #define LOAD_PROC(lib, fn) pfn##fn = (void *) GetProcAddress (lib, #fn)
6425 
6426     LOAD_PROC (user_lib, SetLayeredWindowAttributes);
6427 
6428 #undef LOAD_PROC
6429 
6430     /* Ensure scrollbar handle is at least 5 pixels.  */
6431     vertical_scroll_bar_min_handle = 5;
6432 
6433     /* For either kind of scroll bar, take account of the arrows; these
6434        effectively form the border of the main scroll bar range.  */
6435     vertical_scroll_bar_top_border = vertical_scroll_bar_bottom_border
6436       = GetSystemMetrics (SM_CYVSCROLL);
6437   }
6438 }
6439 
6440 void
6441 syms_of_w32term ()
6442 {
6443   staticpro (&w32_display_name_list);
6444   w32_display_name_list = Qnil;
6445 
6446   staticpro (&last_mouse_scroll_bar);
6447   last_mouse_scroll_bar = Qnil;
6448 
6449   DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
6450 
6451   DEFVAR_INT ("w32-num-mouse-buttons",
6452               &w32_num_mouse_buttons,
6453               doc: /* Number of physical mouse buttons.  */);
6454   w32_num_mouse_buttons = 2;
6455 
6456   DEFVAR_LISP ("w32-swap-mouse-buttons",
6457               &Vw32_swap_mouse_buttons,
6458                doc: /* Swap the mapping of middle and right mouse buttons.
6459 When nil, middle button is mouse-2 and right button is mouse-3.  */);
6460   Vw32_swap_mouse_buttons = Qnil;
6461 
6462   DEFVAR_LISP ("w32-grab-focus-on-raise",
6463                &Vw32_grab_focus_on_raise,
6464                doc: /* Raised frame grabs input focus.
6465 When t, `raise-frame' grabs input focus as well.  This fits well
6466 with the normal Windows click-to-focus policy, but might not be
6467 desirable when using a point-to-focus policy.  */);
6468   Vw32_grab_focus_on_raise = Qt;
6469 
6470   DEFVAR_LISP ("w32-capslock-is-shiftlock",
6471                &Vw32_capslock_is_shiftlock,
6472                doc: /* Apply CapsLock state to non character input keys.
6473 When nil, CapsLock only affects normal character input keys.  */);
6474   Vw32_capslock_is_shiftlock = Qnil;
6475 
6476   DEFVAR_LISP ("w32-recognize-altgr",
6477                &Vw32_recognize_altgr,
6478                doc: /* Recognize right-alt and left-ctrl as AltGr.
6479 When nil, the right-alt and left-ctrl key combination is
6480 interpreted normally.  */);
6481   Vw32_recognize_altgr = Qt;
6482 
6483   DEFVAR_BOOL ("w32-use-visible-system-caret",
6484                &w32_use_visible_system_caret,
6485                doc: /* Flag to make the system caret visible.
6486 When this is non-nil, Emacs will indicate the position of point by
6487 using the system caret instead of drawing its own cursor.  Some screen
6488 reader software does not track the system cursor properly when it is
6489 invisible, and gets confused by Emacs drawing its own cursor, so this
6490 variable is initialized to t when Emacs detects that screen reader
6491 software is running as it starts up.
6492 
6493 When this variable is set, other variables affecting the appearance of
6494 the cursor have no effect.  */);
6495 
6496   w32_use_visible_system_caret = 0;
6497 
6498   /* We don't yet support this, but defining this here avoids whining
6499      from cus-start.el and other places, like "M-x set-variable".  */
6500   DEFVAR_BOOL ("x-use-underline-position-properties",
6501                &x_use_underline_position_properties,
6502      doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
6503 A value of nil means ignore them.  If you encounter fonts with bogus
6504 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
6505 to 4.1, set this to nil.  */);
6506   x_use_underline_position_properties = 0;
6507 
6508   DEFVAR_BOOL ("x-underline-at-descent-line",
6509                &x_underline_at_descent_line,
6510      doc: /* *Non-nil means to draw the underline at the same place as the descent line.
6511 A value of nil means to draw the underline according to the value of the
6512 variable `x-use-underline-position-properties', which is usually at the
6513 baseline level.  The default value is nil.  */);
6514   x_underline_at_descent_line = 0;
6515 
6516   DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
6517                doc: /* If not nil, Emacs uses toolkit scroll bars.  */);
6518   Vx_toolkit_scroll_bars = Qt;
6519 
6520   staticpro (&last_mouse_motion_frame);
6521   last_mouse_motion_frame = Qnil;
6522 }
6523 
6524 /* arch-tag: 5fa70624-ab86-499c-8a85-473958ee4646
6525    (do not change this comment) */