1 /* Graphical user interface functions for the Microsoft W32 API.
   2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
   3                  2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
   4                  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 /* Added by Kevin Gallo */
  22 
  23 #include <config.h>
  24 
  25 #include <signal.h>
  26 #include <stdio.h>
  27 #include <limits.h>
  28 #include <errno.h>
  29 #include <math.h>
  30 #include <setjmp.h>
  31 
  32 #include "lisp.h"
  33 #include "w32term.h"
  34 #include "frame.h"
  35 #include "window.h"
  36 #include "buffer.h"
  37 #include "intervals.h"
  38 #include "dispextern.h"
  39 #include "keyboard.h"
  40 #include "blockinput.h"
  41 #include "epaths.h"
  42 #include "character.h"
  43 #include "charset.h"
  44 #include "coding.h"
  45 #include "ccl.h"
  46 #include "fontset.h"
  47 #include "systime.h"
  48 #include "termhooks.h"
  49 #include "w32heap.h"
  50 #include "w32.h"
  51 
  52 #include "bitmaps/gray.xbm"
  53 
  54 #include <commctrl.h>
  55 #include <commdlg.h>
  56 #include <shellapi.h>
  57 #include <ctype.h>
  58 #include <winspool.h>
  59 #include <objbase.h>
  60 
  61 #include <dlgs.h>
  62 #include <imm.h>
  63 #define FILE_NAME_TEXT_FIELD edt1
  64 
  65 #include "font.h"
  66 #include "w32font.h"
  67 
  68 #ifndef FOF_NO_CONNECTED_ELEMENTS
  69 #define FOF_NO_CONNECTED_ELEMENTS 0x2000
  70 #endif
  71 
  72 void syms_of_w32fns ();
  73 void globals_of_w32fns ();
  74 
  75 extern void free_frame_menubar ();
  76 extern double atof ();
  77 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
  78 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
  79 extern void w32_free_menu_strings P_ ((HWND));
  80 extern const char *map_w32_filename P_ ((const char *, const char **));
  81 
  82 extern int quit_char;
  83 
  84 extern char *lispy_function_keys[];
  85 
  86 /* The colormap for converting color names to RGB values */
  87 Lisp_Object Vw32_color_map;
  88 
  89 /* Non nil if alt key presses are passed on to Windows.  */
  90 Lisp_Object Vw32_pass_alt_to_system;
  91 
  92 /* Non nil if alt key is translated to meta_modifier, nil if it is translated
  93    to alt_modifier.  */
  94 Lisp_Object Vw32_alt_is_meta;
  95 
  96 /* If non-zero, the windows virtual key code for an alternative quit key. */
  97 int w32_quit_key;
  98 
  99 /* Non nil if left window key events are passed on to Windows (this only
 100    affects whether "tapping" the key opens the Start menu).  */
 101 Lisp_Object Vw32_pass_lwindow_to_system;
 102 
 103 /* Non nil if right window key events are passed on to Windows (this
 104    only affects whether "tapping" the key opens the Start menu).  */
 105 Lisp_Object Vw32_pass_rwindow_to_system;
 106 
 107 /* Virtual key code used to generate "phantom" key presses in order
 108    to stop system from acting on Windows key events.  */
 109 Lisp_Object Vw32_phantom_key_code;
 110 
 111 /* Modifier associated with the left "Windows" key, or nil to act as a
 112    normal key.  */
 113 Lisp_Object Vw32_lwindow_modifier;
 114 
 115 /* Modifier associated with the right "Windows" key, or nil to act as a
 116    normal key.  */
 117 Lisp_Object Vw32_rwindow_modifier;
 118 
 119 /* Modifier associated with the "Apps" key, or nil to act as a normal
 120    key.  */
 121 Lisp_Object Vw32_apps_modifier;
 122 
 123 /* Value is nil if Num Lock acts as a function key.  */
 124 Lisp_Object Vw32_enable_num_lock;
 125 
 126 /* Value is nil if Caps Lock acts as a function key.  */
 127 Lisp_Object Vw32_enable_caps_lock;
 128 
 129 /* Modifier associated with Scroll Lock, or nil to act as a normal key.  */
 130 Lisp_Object Vw32_scroll_lock_modifier;
 131 
 132 /* Switch to control whether we inhibit requests for synthesized bold
 133    and italic versions of fonts.  */
 134 int w32_enable_synthesized_fonts;
 135 
 136 /* Enable palette management. */
 137 Lisp_Object Vw32_enable_palette;
 138 
 139 /* Control how close left/right button down events must be to
 140    be converted to a middle button down event. */
 141 int w32_mouse_button_tolerance;
 142 
 143 /* Minimum interval between mouse movement (and scroll bar drag)
 144    events that are passed on to the event loop. */
 145 int w32_mouse_move_interval;
 146 
 147 /* Flag to indicate if XBUTTON events should be passed on to Windows.  */
 148 static int w32_pass_extra_mouse_buttons_to_system;
 149 
 150 /* Flag to indicate if media keys should be passed on to Windows.  */
 151 static int w32_pass_multimedia_buttons_to_system;
 152 
 153 /* Non nil if no window manager is in use.  */
 154 Lisp_Object Vx_no_window_manager;
 155 
 156 /* If non-zero, a w32 timer that, when it expires, displays an
 157    hourglass cursor on all frames.  */
 158 static unsigned hourglass_timer = 0;
 159 static HWND hourglass_hwnd = NULL;
 160 
 161 #if 0 /* TODO: Mouse cursor customization.  */
 162 /* The background and shape of the mouse pointer, and shape when not
 163    over text or in the modeline.  */
 164 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
 165 Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;
 166 
 167 /* The shape when over mouse-sensitive text.  */
 168 
 169 Lisp_Object Vx_sensitive_text_pointer_shape;
 170 #endif
 171 
 172 #ifndef IDC_HAND
 173 #define IDC_HAND MAKEINTRESOURCE(32649)
 174 #endif
 175 
 176 /* Color of chars displayed in cursor box.  */
 177 Lisp_Object Vx_cursor_fore_pixel;
 178 
 179 /* Nonzero if using Windows.  */
 180 
 181 static int w32_in_use;
 182 
 183 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.  */
 184 
 185 Lisp_Object Vx_pixel_size_width_font_regexp;
 186 
 187 /* Alist of bdf fonts and the files that define them.  */
 188 Lisp_Object Vw32_bdf_filename_alist;
 189 
 190 /* A flag to control whether fonts are matched strictly or not.  */
 191 static int w32_strict_fontnames;
 192 
 193 /* A flag to control whether we should only repaint if GetUpdateRect
 194    indicates there is an update region.  */
 195 static int w32_strict_painting;
 196 
 197 Lisp_Object Qnone;
 198 Lisp_Object Qsuppress_icon;
 199 Lisp_Object Qundefined_color;
 200 Lisp_Object Qcancel_timer;
 201 Lisp_Object Qfont_param;
 202 Lisp_Object Qhyper;
 203 Lisp_Object Qsuper;
 204 Lisp_Object Qmeta;
 205 Lisp_Object Qalt;
 206 Lisp_Object Qctrl;
 207 Lisp_Object Qcontrol;
 208 Lisp_Object Qshift;
 209 
 210 
 211 /* The ANSI codepage.  */
 212 int w32_ansi_code_page;
 213 
 214 /* Prefix for system colors.  */
 215 #define SYSTEM_COLOR_PREFIX "System"
 216 #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
 217 
 218 /* State variables for emulating a three button mouse. */
 219 #define LMOUSE 1
 220 #define MMOUSE 2
 221 #define RMOUSE 4
 222 
 223 static int button_state = 0;
 224 static W32Msg saved_mouse_button_msg;
 225 static unsigned mouse_button_timer = 0; /* non-zero when timer is active */
 226 static W32Msg saved_mouse_move_msg;
 227 static unsigned mouse_move_timer = 0;
 228 
 229 /* Window that is tracking the mouse.  */
 230 static HWND track_mouse_window;
 231 
 232 /* Multi-monitor API definitions that are not pulled from the headers
 233    since we are compiling for NT 4.  */
 234 #ifndef MONITOR_DEFAULT_TO_NEAREST
 235 #define MONITOR_DEFAULT_TO_NEAREST 2
 236 #endif
 237 /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't.
 238    To avoid a compile error on one or the other, redefine with a new name.  */
 239 struct MONITOR_INFO
 240 {
 241     DWORD   cbSize;
 242     RECT    rcMonitor;
 243     RECT    rcWork;
 244     DWORD   dwFlags;
 245 };
 246 
 247 /* Reportedly, VS 6 does not have this in its headers.  */
 248 #if defined(_MSC_VER) && _MSC_VER < 1300
 249 DECLARE_HANDLE(HMONITOR);
 250 #endif
 251 
 252 typedef BOOL (WINAPI * TrackMouseEvent_Proc)
 253   (IN OUT LPTRACKMOUSEEVENT lpEventTrack);
 254 typedef LONG (WINAPI * ImmGetCompositionString_Proc)
 255   (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen);
 256 typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window);
 257 typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
 258 typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
 259                                                       IN COMPOSITIONFORM *form);
 260 typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
 261 typedef BOOL (WINAPI * GetMonitorInfo_Proc)
 262   (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
 263 
 264 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 265 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
 266 ImmGetCompositionString_Proc get_composition_string_fn = NULL;
 267 ImmGetContext_Proc get_ime_context_fn = NULL;
 268 ImmReleaseContext_Proc release_ime_context_fn = NULL;
 269 ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
 270 MonitorFromPoint_Proc monitor_from_point_fn = NULL;
 271 GetMonitorInfo_Proc get_monitor_info_fn = NULL;
 272 
 273 extern AppendMenuW_Proc unicode_append_menu;
 274 
 275 /* Flag to selectively ignore WM_IME_CHAR messages.  */
 276 static int ignore_ime_char = 0;
 277 
 278 /* W95 mousewheel handler */
 279 unsigned int msh_mousewheel = 0;
 280 
 281 /* Timers */
 282 #define MOUSE_BUTTON_ID 1
 283 #define MOUSE_MOVE_ID   2
 284 #define MENU_FREE_ID 3
 285 #define HOURGLASS_ID 4
 286 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
 287    is received.  */
 288 #define MENU_FREE_DELAY 1000
 289 static unsigned menu_free_timer = 0;
 290 
 291 /* The below are defined in frame.c.  */
 292 
 293 extern Lisp_Object Vwindow_system_version;
 294 
 295 #ifdef GLYPH_DEBUG
 296 int image_cache_refcount, dpyinfo_refcount;
 297 #endif
 298 
 299 
 300 /* From w32term.c. */
 301 extern int w32_num_mouse_buttons;
 302 extern Lisp_Object Vw32_recognize_altgr;
 303 
 304 extern HWND w32_system_caret_hwnd;
 305 
 306 extern int w32_system_caret_height;
 307 extern int w32_system_caret_x;
 308 extern int w32_system_caret_y;
 309 extern int w32_use_visible_system_caret;
 310 
 311 static HWND w32_visible_system_caret_hwnd;
 312 
 313 /* From w32menu.c  */
 314 extern HMENU current_popup_menu;
 315 static int menubar_in_use = 0;
 316 
 317 /* From w32uniscribe.c  */
 318 extern void syms_of_w32uniscribe ();
 319 extern int uniscribe_available;
 320 
 321 /* Function prototypes for hourglass support.  */
 322 static void w32_show_hourglass P_ ((struct frame *));
 323 static void w32_hide_hourglass P_ ((void));
 324 
 325 
 326 
 327 /* Error if we are not connected to MS-Windows.  */
 328 void
 329 check_w32 ()
 330 {
 331   if (! w32_in_use)
 332     error ("MS-Windows not in use or not initialized");
 333 }
 334 
 335 /* Nonzero if we can use mouse menus.
 336    You should not call this unless HAVE_MENUS is defined.  */
 337 
 338 int
 339 have_menus_p ()
 340 {
 341   return w32_in_use;
 342 }
 343 
 344 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
 345    and checking validity for W32.  */
 346 
 347 FRAME_PTR
 348 check_x_frame (frame)
 349      Lisp_Object frame;
 350 {
 351   FRAME_PTR f;
 352 
 353   if (NILP (frame))
 354     frame = selected_frame;
 355   CHECK_LIVE_FRAME (frame);
 356   f = XFRAME (frame);
 357   if (! FRAME_W32_P (f))
 358     error ("Non-W32 frame used");
 359   return f;
 360 }
 361 
 362 /* Let the user specify a display with a frame.
 363    nil stands for the selected frame--or, if that is not a w32 frame,
 364    the first display on the list.  */
 365 
 366 struct w32_display_info *
 367 check_x_display_info (frame)
 368      Lisp_Object frame;
 369 {
 370   if (NILP (frame))
 371     {
 372       struct frame *sf = XFRAME (selected_frame);
 373 
 374       if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf))
 375         return FRAME_W32_DISPLAY_INFO (sf);
 376       else
 377         return &one_w32_display_info;
 378     }
 379   else if (STRINGP (frame))
 380     return x_display_info_for_name (frame);
 381   else
 382     {
 383       FRAME_PTR f;
 384 
 385       CHECK_LIVE_FRAME (frame);
 386       f = XFRAME (frame);
 387       if (! FRAME_W32_P (f))
 388         error ("Non-W32 frame used");
 389       return FRAME_W32_DISPLAY_INFO (f);
 390     }
 391 }
 392 
 393 /* Return the Emacs frame-object corresponding to an w32 window.
 394    It could be the frame's main window or an icon window.  */
 395 
 396 /* This function can be called during GC, so use GC_xxx type test macros.  */
 397 
 398 struct frame *
 399 x_window_to_frame (dpyinfo, wdesc)
 400      struct w32_display_info *dpyinfo;
 401      HWND wdesc;
 402 {
 403   Lisp_Object tail, frame;
 404   struct frame *f;
 405 
 406   for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
 407     {
 408       frame = XCAR (tail);
 409       if (!FRAMEP (frame))
 410         continue;
 411       f = XFRAME (frame);
 412       if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
 413         continue;
 414 
 415       if (FRAME_W32_WINDOW (f) == wdesc)
 416         return f;
 417     }
 418   return 0;
 419 }
 420 
 421 
 422 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
 423 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
 424 static void my_create_window P_ ((struct frame *));
 425 static void my_create_tip_window P_ ((struct frame *));
 426 
 427 /* TODO: Native Input Method support; see x_create_im.  */
 428 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 429 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 430 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 431 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 432 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
 433 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 434 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
 435 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 436 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
 437 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 438 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
 439 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 440 static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
 441                                   Lisp_Object));
 442 
 443 
 444 
 445 
 446 /* Store the screen positions of frame F into XPTR and YPTR.
 447    These are the positions of the containing window manager window,
 448    not Emacs's own window.  */
 449 
 450 void
 451 x_real_positions (f, xptr, yptr)
 452      FRAME_PTR f;
 453      int *xptr, *yptr;
 454 {
 455   POINT pt;
 456   RECT rect;
 457 
 458   /* Get the bounds of the WM window.  */
 459   GetWindowRect (FRAME_W32_WINDOW (f), &rect);
 460 
 461   pt.x = 0;
 462   pt.y = 0;
 463 
 464   /* Convert (0, 0) in the client area to screen co-ordinates.  */
 465   ClientToScreen (FRAME_W32_WINDOW (f), &pt);
 466 
 467   /* Remember x_pixels_diff and y_pixels_diff.  */
 468   f->x_pixels_diff = pt.x - rect.left;
 469   f->y_pixels_diff = pt.y - rect.top;
 470 
 471   *xptr = rect.left;
 472   *yptr = rect.top;
 473 }
 474 
 475 
 476 
 477 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
 478        Sw32_define_rgb_color, 4, 4, 0,
 479        doc: /* Convert RGB numbers to a Windows color reference and associate with NAME.
 480 This adds or updates a named color to `w32-color-map', making it
 481 available for use.  The original entry's RGB ref is returned, or nil
 482 if the entry is new.  */)
 483     (red, green, blue, name)
 484     Lisp_Object red, green, blue, name;
 485 {
 486   Lisp_Object rgb;
 487   Lisp_Object oldrgb = Qnil;
 488   Lisp_Object entry;
 489 
 490   CHECK_NUMBER (red);
 491   CHECK_NUMBER (green);
 492   CHECK_NUMBER (blue);
 493   CHECK_STRING (name);
 494 
 495   XSETINT (rgb, RGB (XUINT (red), XUINT (green), XUINT (blue)));
 496 
 497   BLOCK_INPUT;
 498 
 499   /* replace existing entry in w32-color-map or add new entry. */
 500   entry = Fassoc (name, Vw32_color_map);
 501   if (NILP (entry))
 502     {
 503       entry = Fcons (name, rgb);
 504       Vw32_color_map = Fcons (entry, Vw32_color_map);
 505     }
 506   else
 507     {
 508       oldrgb = Fcdr (entry);
 509       Fsetcdr (entry, rgb);
 510     }
 511 
 512   UNBLOCK_INPUT;
 513 
 514   return (oldrgb);
 515 }
 516 
 517 /* The default colors for the w32 color map */
 518 typedef struct colormap_t
 519 {
 520   char *name;
 521   COLORREF colorref;
 522 } colormap_t;
 523 
 524 colormap_t w32_color_map[] =
 525 {
 526   {"snow"                      , PALETTERGB (255,250,250)},
 527   {"ghost white"               , PALETTERGB (248,248,255)},
 528   {"GhostWhite"                , PALETTERGB (248,248,255)},
 529   {"white smoke"               , PALETTERGB (245,245,245)},
 530   {"WhiteSmoke"                , PALETTERGB (245,245,245)},
 531   {"gainsboro"                 , PALETTERGB (220,220,220)},
 532   {"floral white"              , PALETTERGB (255,250,240)},
 533   {"FloralWhite"               , PALETTERGB (255,250,240)},
 534   {"old lace"                  , PALETTERGB (253,245,230)},
 535   {"OldLace"                   , PALETTERGB (253,245,230)},
 536   {"linen"                     , PALETTERGB (250,240,230)},
 537   {"antique white"             , PALETTERGB (250,235,215)},
 538   {"AntiqueWhite"              , PALETTERGB (250,235,215)},
 539   {"papaya whip"               , PALETTERGB (255,239,213)},
 540   {"PapayaWhip"                , PALETTERGB (255,239,213)},
 541   {"blanched almond"           , PALETTERGB (255,235,205)},
 542   {"BlanchedAlmond"            , PALETTERGB (255,235,205)},
 543   {"bisque"                    , PALETTERGB (255,228,196)},
 544   {"peach puff"                , PALETTERGB (255,218,185)},
 545   {"PeachPuff"                 , PALETTERGB (255,218,185)},
 546   {"navajo white"              , PALETTERGB (255,222,173)},
 547   {"NavajoWhite"               , PALETTERGB (255,222,173)},
 548   {"moccasin"                  , PALETTERGB (255,228,181)},
 549   {"cornsilk"                  , PALETTERGB (255,248,220)},
 550   {"ivory"                     , PALETTERGB (255,255,240)},
 551   {"lemon chiffon"             , PALETTERGB (255,250,205)},
 552   {"LemonChiffon"              , PALETTERGB (255,250,205)},
 553   {"seashell"                  , PALETTERGB (255,245,238)},
 554   {"honeydew"                  , PALETTERGB (240,255,240)},
 555   {"mint cream"                , PALETTERGB (245,255,250)},
 556   {"MintCream"                 , PALETTERGB (245,255,250)},
 557   {"azure"                     , PALETTERGB (240,255,255)},
 558   {"alice blue"                , PALETTERGB (240,248,255)},
 559   {"AliceBlue"                 , PALETTERGB (240,248,255)},
 560   {"lavender"                  , PALETTERGB (230,230,250)},
 561   {"lavender blush"            , PALETTERGB (255,240,245)},
 562   {"LavenderBlush"             , PALETTERGB (255,240,245)},
 563   {"misty rose"                , PALETTERGB (255,228,225)},
 564   {"MistyRose"                 , PALETTERGB (255,228,225)},
 565   {"white"                     , PALETTERGB (255,255,255)},
 566   {"black"                     , PALETTERGB (  0,  0,  0)},
 567   {"dark slate gray"           , PALETTERGB ( 47, 79, 79)},
 568   {"DarkSlateGray"             , PALETTERGB ( 47, 79, 79)},
 569   {"dark slate grey"           , PALETTERGB ( 47, 79, 79)},
 570   {"DarkSlateGrey"             , PALETTERGB ( 47, 79, 79)},
 571   {"dim gray"                  , PALETTERGB (105,105,105)},
 572   {"DimGray"                   , PALETTERGB (105,105,105)},
 573   {"dim grey"                  , PALETTERGB (105,105,105)},
 574   {"DimGrey"                   , PALETTERGB (105,105,105)},
 575   {"slate gray"                , PALETTERGB (112,128,144)},
 576   {"SlateGray"                 , PALETTERGB (112,128,144)},
 577   {"slate grey"                , PALETTERGB (112,128,144)},
 578   {"SlateGrey"                 , PALETTERGB (112,128,144)},
 579   {"light slate gray"          , PALETTERGB (119,136,153)},
 580   {"LightSlateGray"            , PALETTERGB (119,136,153)},
 581   {"light slate grey"          , PALETTERGB (119,136,153)},
 582   {"LightSlateGrey"            , PALETTERGB (119,136,153)},
 583   {"gray"                      , PALETTERGB (190,190,190)},
 584   {"grey"                      , PALETTERGB (190,190,190)},
 585   {"light grey"                , PALETTERGB (211,211,211)},
 586   {"LightGrey"                 , PALETTERGB (211,211,211)},
 587   {"light gray"                , PALETTERGB (211,211,211)},
 588   {"LightGray"                 , PALETTERGB (211,211,211)},
 589   {"midnight blue"             , PALETTERGB ( 25, 25,112)},
 590   {"MidnightBlue"              , PALETTERGB ( 25, 25,112)},
 591   {"navy"                      , PALETTERGB (  0,  0,128)},
 592   {"navy blue"                 , PALETTERGB (  0,  0,128)},
 593   {"NavyBlue"                  , PALETTERGB (  0,  0,128)},
 594   {"cornflower blue"           , PALETTERGB (100,149,237)},
 595   {"CornflowerBlue"            , PALETTERGB (100,149,237)},
 596   {"dark slate blue"           , PALETTERGB ( 72, 61,139)},
 597   {"DarkSlateBlue"             , PALETTERGB ( 72, 61,139)},
 598   {"slate blue"                , PALETTERGB (106, 90,205)},
 599   {"SlateBlue"                 , PALETTERGB (106, 90,205)},
 600   {"medium slate blue"         , PALETTERGB (123,104,238)},
 601   {"MediumSlateBlue"           , PALETTERGB (123,104,238)},
 602   {"light slate blue"          , PALETTERGB (132,112,255)},
 603   {"LightSlateBlue"            , PALETTERGB (132,112,255)},
 604   {"medium blue"               , PALETTERGB (  0,  0,205)},
 605   {"MediumBlue"                , PALETTERGB (  0,  0,205)},
 606   {"royal blue"                , PALETTERGB ( 65,105,225)},
 607   {"RoyalBlue"                 , PALETTERGB ( 65,105,225)},
 608   {"blue"                      , PALETTERGB (  0,  0,255)},
 609   {"dodger blue"               , PALETTERGB ( 30,144,255)},
 610   {"DodgerBlue"                , PALETTERGB ( 30,144,255)},
 611   {"deep sky blue"             , PALETTERGB (  0,191,255)},
 612   {"DeepSkyBlue"               , PALETTERGB (  0,191,255)},
 613   {"sky blue"                  , PALETTERGB (135,206,235)},
 614   {"SkyBlue"                   , PALETTERGB (135,206,235)},
 615   {"light sky blue"            , PALETTERGB (135,206,250)},
 616   {"LightSkyBlue"              , PALETTERGB (135,206,250)},
 617   {"steel blue"                , PALETTERGB ( 70,130,180)},
 618   {"SteelBlue"                 , PALETTERGB ( 70,130,180)},
 619   {"light steel blue"          , PALETTERGB (176,196,222)},
 620   {"LightSteelBlue"            , PALETTERGB (176,196,222)},
 621   {"light blue"                , PALETTERGB (173,216,230)},
 622   {"LightBlue"                 , PALETTERGB (173,216,230)},
 623   {"powder blue"               , PALETTERGB (176,224,230)},
 624   {"PowderBlue"                , PALETTERGB (176,224,230)},
 625   {"pale turquoise"            , PALETTERGB (175,238,238)},
 626   {"PaleTurquoise"             , PALETTERGB (175,238,238)},
 627   {"dark turquoise"            , PALETTERGB (  0,206,209)},
 628   {"DarkTurquoise"             , PALETTERGB (  0,206,209)},
 629   {"medium turquoise"          , PALETTERGB ( 72,209,204)},
 630   {"MediumTurquoise"           , PALETTERGB ( 72,209,204)},
 631   {"turquoise"                 , PALETTERGB ( 64,224,208)},
 632   {"cyan"                      , PALETTERGB (  0,255,255)},
 633   {"light cyan"                , PALETTERGB (224,255,255)},
 634   {"LightCyan"                 , PALETTERGB (224,255,255)},
 635   {"cadet blue"                , PALETTERGB ( 95,158,160)},
 636   {"CadetBlue"                 , PALETTERGB ( 95,158,160)},
 637   {"medium aquamarine"         , PALETTERGB (102,205,170)},
 638   {"MediumAquamarine"          , PALETTERGB (102,205,170)},
 639   {"aquamarine"                , PALETTERGB (127,255,212)},
 640   {"dark green"                , PALETTERGB (  0,100,  0)},
 641   {"DarkGreen"                 , PALETTERGB (  0,100,  0)},
 642   {"dark olive green"          , PALETTERGB ( 85,107, 47)},
 643   {"DarkOliveGreen"            , PALETTERGB ( 85,107, 47)},
 644   {"dark sea green"            , PALETTERGB (143,188,143)},
 645   {"DarkSeaGreen"              , PALETTERGB (143,188,143)},
 646   {"sea green"                 , PALETTERGB ( 46,139, 87)},
 647   {"SeaGreen"                  , PALETTERGB ( 46,139, 87)},
 648   {"medium sea green"          , PALETTERGB ( 60,179,113)},
 649   {"MediumSeaGreen"            , PALETTERGB ( 60,179,113)},
 650   {"light sea green"           , PALETTERGB ( 32,178,170)},
 651   {"LightSeaGreen"             , PALETTERGB ( 32,178,170)},
 652   {"pale green"                , PALETTERGB (152,251,152)},
 653   {"PaleGreen"                 , PALETTERGB (152,251,152)},
 654   {"spring green"              , PALETTERGB (  0,255,127)},
 655   {"SpringGreen"               , PALETTERGB (  0,255,127)},
 656   {"lawn green"                , PALETTERGB (124,252,  0)},
 657   {"LawnGreen"                 , PALETTERGB (124,252,  0)},
 658   {"green"                     , PALETTERGB (  0,255,  0)},
 659   {"chartreuse"                , PALETTERGB (127,255,  0)},
 660   {"medium spring green"       , PALETTERGB (  0,250,154)},
 661   {"MediumSpringGreen"         , PALETTERGB (  0,250,154)},
 662   {"green yellow"              , PALETTERGB (173,255, 47)},
 663   {"GreenYellow"               , PALETTERGB (173,255, 47)},
 664   {"lime green"                , PALETTERGB ( 50,205, 50)},
 665   {"LimeGreen"                 , PALETTERGB ( 50,205, 50)},
 666   {"yellow green"              , PALETTERGB (154,205, 50)},
 667   {"YellowGreen"               , PALETTERGB (154,205, 50)},
 668   {"forest green"              , PALETTERGB ( 34,139, 34)},
 669   {"ForestGreen"               , PALETTERGB ( 34,139, 34)},
 670   {"olive drab"                , PALETTERGB (107,142, 35)},
 671   {"OliveDrab"                 , PALETTERGB (107,142, 35)},
 672   {"dark khaki"                , PALETTERGB (189,183,107)},
 673   {"DarkKhaki"                 , PALETTERGB (189,183,107)},
 674   {"khaki"                     , PALETTERGB (240,230,140)},
 675   {"pale goldenrod"            , PALETTERGB (238,232,170)},
 676   {"PaleGoldenrod"             , PALETTERGB (238,232,170)},
 677   {"light goldenrod yellow"    , PALETTERGB (250,250,210)},
 678   {"LightGoldenrodYellow"      , PALETTERGB (250,250,210)},
 679   {"light yellow"              , PALETTERGB (255,255,224)},
 680   {"LightYellow"               , PALETTERGB (255,255,224)},
 681   {"yellow"                    , PALETTERGB (255,255,  0)},
 682   {"gold"                      , PALETTERGB (255,215,  0)},
 683   {"light goldenrod"           , PALETTERGB (238,221,130)},
 684   {"LightGoldenrod"            , PALETTERGB (238,221,130)},
 685   {"goldenrod"                 , PALETTERGB (218,165, 32)},
 686   {"dark goldenrod"            , PALETTERGB (184,134, 11)},
 687   {"DarkGoldenrod"             , PALETTERGB (184,134, 11)},
 688   {"rosy brown"                , PALETTERGB (188,143,143)},
 689   {"RosyBrown"                 , PALETTERGB (188,143,143)},
 690   {"indian red"                , PALETTERGB (205, 92, 92)},
 691   {"IndianRed"                 , PALETTERGB (205, 92, 92)},
 692   {"saddle brown"              , PALETTERGB (139, 69, 19)},
 693   {"SaddleBrown"               , PALETTERGB (139, 69, 19)},
 694   {"sienna"                    , PALETTERGB (160, 82, 45)},
 695   {"peru"                      , PALETTERGB (205,133, 63)},
 696   {"burlywood"                 , PALETTERGB (222,184,135)},
 697   {"beige"                     , PALETTERGB (245,245,220)},
 698   {"wheat"                     , PALETTERGB (245,222,179)},
 699   {"sandy brown"               , PALETTERGB (244,164, 96)},
 700   {"SandyBrown"                , PALETTERGB (244,164, 96)},
 701   {"tan"                       , PALETTERGB (210,180,140)},
 702   {"chocolate"                 , PALETTERGB (210,105, 30)},
 703   {"firebrick"                 , PALETTERGB (178,34, 34)},
 704   {"brown"                     , PALETTERGB (165,42, 42)},
 705   {"dark salmon"               , PALETTERGB (233,150,122)},
 706   {"DarkSalmon"                , PALETTERGB (233,150,122)},
 707   {"salmon"                    , PALETTERGB (250,128,114)},
 708   {"light salmon"              , PALETTERGB (255,160,122)},
 709   {"LightSalmon"               , PALETTERGB (255,160,122)},
 710   {"orange"                    , PALETTERGB (255,165,  0)},
 711   {"dark orange"               , PALETTERGB (255,140,  0)},
 712   {"DarkOrange"                , PALETTERGB (255,140,  0)},
 713   {"coral"                     , PALETTERGB (255,127, 80)},
 714   {"light coral"               , PALETTERGB (240,128,128)},
 715   {"LightCoral"                , PALETTERGB (240,128,128)},
 716   {"tomato"                    , PALETTERGB (255, 99, 71)},
 717   {"orange red"                , PALETTERGB (255, 69,  0)},
 718   {"OrangeRed"                 , PALETTERGB (255, 69,  0)},
 719   {"red"                       , PALETTERGB (255,  0,  0)},
 720   {"hot pink"                  , PALETTERGB (255,105,180)},
 721   {"HotPink"                   , PALETTERGB (255,105,180)},
 722   {"deep pink"                 , PALETTERGB (255, 20,147)},
 723   {"DeepPink"                  , PALETTERGB (255, 20,147)},
 724   {"pink"                      , PALETTERGB (255,192,203)},
 725   {"light pink"                , PALETTERGB (255,182,193)},
 726   {"LightPink"                 , PALETTERGB (255,182,193)},
 727   {"pale violet red"           , PALETTERGB (219,112,147)},
 728   {"PaleVioletRed"             , PALETTERGB (219,112,147)},
 729   {"maroon"                    , PALETTERGB (176, 48, 96)},
 730   {"medium violet red"         , PALETTERGB (199, 21,133)},
 731   {"MediumVioletRed"           , PALETTERGB (199, 21,133)},
 732   {"violet red"                , PALETTERGB (208, 32,144)},
 733   {"VioletRed"                 , PALETTERGB (208, 32,144)},
 734   {"magenta"                   , PALETTERGB (255,  0,255)},
 735   {"violet"                    , PALETTERGB (238,130,238)},
 736   {"plum"                      , PALETTERGB (221,160,221)},
 737   {"orchid"                    , PALETTERGB (218,112,214)},
 738   {"medium orchid"             , PALETTERGB (186, 85,211)},
 739   {"MediumOrchid"              , PALETTERGB (186, 85,211)},
 740   {"dark orchid"               , PALETTERGB (153, 50,204)},
 741   {"DarkOrchid"                , PALETTERGB (153, 50,204)},
 742   {"dark violet"               , PALETTERGB (148,  0,211)},
 743   {"DarkViolet"                , PALETTERGB (148,  0,211)},
 744   {"blue violet"               , PALETTERGB (138, 43,226)},
 745   {"BlueViolet"                , PALETTERGB (138, 43,226)},
 746   {"purple"                    , PALETTERGB (160, 32,240)},
 747   {"medium purple"             , PALETTERGB (147,112,219)},
 748   {"MediumPurple"              , PALETTERGB (147,112,219)},
 749   {"thistle"                   , PALETTERGB (216,191,216)},
 750   {"gray0"                     , PALETTERGB (  0,  0,  0)},
 751   {"grey0"                     , PALETTERGB (  0,  0,  0)},
 752   {"dark grey"                 , PALETTERGB (169,169,169)},
 753   {"DarkGrey"                  , PALETTERGB (169,169,169)},
 754   {"dark gray"                 , PALETTERGB (169,169,169)},
 755   {"DarkGray"                  , PALETTERGB (169,169,169)},
 756   {"dark blue"                 , PALETTERGB (  0,  0,139)},
 757   {"DarkBlue"                  , PALETTERGB (  0,  0,139)},
 758   {"dark cyan"                 , PALETTERGB (  0,139,139)},
 759   {"DarkCyan"                  , PALETTERGB (  0,139,139)},
 760   {"dark magenta"              , PALETTERGB (139,  0,139)},
 761   {"DarkMagenta"               , PALETTERGB (139,  0,139)},
 762   {"dark red"                  , PALETTERGB (139,  0,  0)},
 763   {"DarkRed"                   , PALETTERGB (139,  0,  0)},
 764   {"light green"               , PALETTERGB (144,238,144)},
 765   {"LightGreen"                , PALETTERGB (144,238,144)},
 766 };
 767 
 768 DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
 769        0, 0, 0, doc: /* Return the default color map.  */)
 770      ()
 771 {
 772   int i;
 773   colormap_t *pc = w32_color_map;
 774   Lisp_Object cmap;
 775 
 776   BLOCK_INPUT;
 777 
 778   cmap = Qnil;
 779 
 780   for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]);
 781        pc++, i++)
 782     cmap = Fcons (Fcons (build_string (pc->name),
 783                          make_number (pc->colorref)),
 784                   cmap);
 785 
 786   UNBLOCK_INPUT;
 787 
 788   return (cmap);
 789 }
 790 
 791 static Lisp_Object
 792 w32_to_x_color (rgb)
 793      Lisp_Object rgb;
 794 {
 795   Lisp_Object color;
 796 
 797   CHECK_NUMBER (rgb);
 798 
 799   BLOCK_INPUT;
 800 
 801   color = Frassq (rgb, Vw32_color_map);
 802 
 803   UNBLOCK_INPUT;
 804 
 805   if (!NILP (color))
 806     return (Fcar (color));
 807   else
 808     return Qnil;
 809 }
 810 
 811 static Lisp_Object
 812 w32_color_map_lookup (colorname)
 813      char *colorname;
 814 {
 815   Lisp_Object tail, ret = Qnil;
 816 
 817   BLOCK_INPUT;
 818 
 819   for (tail = Vw32_color_map; CONSP (tail); tail = XCDR (tail))
 820     {
 821       register Lisp_Object elt, tem;
 822 
 823       elt = XCAR (tail);
 824       if (!CONSP (elt)) continue;
 825 
 826       tem = Fcar (elt);
 827 
 828       if (lstrcmpi (SDATA (tem), colorname) == 0)
 829         {
 830           ret = Fcdr (elt);
 831           break;
 832         }
 833 
 834       QUIT;
 835     }
 836 
 837 
 838   UNBLOCK_INPUT;
 839 
 840   return ret;
 841 }
 842 
 843 
 844 static void
 845 add_system_logical_colors_to_map (system_colors)
 846      Lisp_Object *system_colors;
 847 {
 848   HKEY colors_key;
 849 
 850   /* Other registry operations are done with input blocked.  */
 851   BLOCK_INPUT;
 852 
 853   /* Look for "Control Panel/Colors" under User and Machine registry
 854      settings.  */
 855   if (RegOpenKeyEx (HKEY_CURRENT_USER, "Control Panel\\Colors", 0,
 856                     KEY_READ, &colors_key) == ERROR_SUCCESS
 857       || RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Control Panel\\Colors", 0,
 858                        KEY_READ, &colors_key) == ERROR_SUCCESS)
 859     {
 860       /* List all keys.  */
 861       char color_buffer[64];
 862       char full_name_buffer[MAX_PATH + SYSTEM_COLOR_PREFIX_LEN];
 863       int index = 0;
 864       DWORD name_size, color_size;
 865       char *name_buffer = full_name_buffer + SYSTEM_COLOR_PREFIX_LEN;
 866 
 867       name_size = sizeof (full_name_buffer) - SYSTEM_COLOR_PREFIX_LEN;
 868       color_size = sizeof (color_buffer);
 869 
 870       strcpy (full_name_buffer, SYSTEM_COLOR_PREFIX);
 871 
 872       while (RegEnumValueA (colors_key, index, name_buffer, &name_size,
 873                             NULL, NULL, color_buffer, &color_size)
 874              == ERROR_SUCCESS)
 875         {
 876           int r, g, b;
 877           if (sscanf (color_buffer, " %u %u %u", &r, &g, &b) == 3)
 878             *system_colors = Fcons (Fcons (build_string (full_name_buffer),
 879                                            make_number (RGB (r, g, b))),
 880                                     *system_colors);
 881 
 882           name_size = sizeof (full_name_buffer) - SYSTEM_COLOR_PREFIX_LEN;
 883           color_size = sizeof (color_buffer);
 884           index++;
 885         }
 886       RegCloseKey (colors_key);
 887     }
 888 
 889   UNBLOCK_INPUT;
 890 }
 891 
 892 
 893 static Lisp_Object
 894 x_to_w32_color (colorname)
 895      char * colorname;
 896 {
 897   register Lisp_Object ret = Qnil;
 898 
 899   BLOCK_INPUT;
 900 
 901   if (colorname[0] == '#')
 902     {
 903       /* Could be an old-style RGB Device specification.  */
 904       char *color;
 905       int size;
 906       color = colorname + 1;
 907 
 908       size = strlen (color);
 909       if (size == 3 || size == 6 || size == 9 || size == 12)
 910         {
 911           UINT colorval;
 912           int i, pos;
 913           pos = 0;
 914           size /= 3;
 915           colorval = 0;
 916 
 917           for (i = 0; i < 3; i++)
 918             {
 919               char *end;
 920               char t;
 921               unsigned long value;
 922 
 923               /* The check for 'x' in the following conditional takes into
 924                  account the fact that strtol allows a "0x" in front of
 925                  our numbers, and we don't.  */
 926               if (!isxdigit (color[0]) || color[1] == 'x')
 927                 break;
 928               t = color[size];
 929               color[size] = '\0';
 930               value = strtoul (color, &end, 16);
 931               color[size] = t;
 932               if (errno == ERANGE || end - color != size)
 933                 break;
 934               switch (size)
 935                 {
 936                 case 1:
 937                   value = value * 0x10;
 938                   break;
 939                 case 2:
 940                   break;
 941                 case 3:
 942                   value /= 0x10;
 943                   break;
 944                 case 4:
 945                   value /= 0x100;
 946                   break;
 947                 }
 948               colorval |= (value << pos);
 949               pos += 0x8;
 950               if (i == 2)
 951                 {
 952                   UNBLOCK_INPUT;
 953                   XSETINT (ret, colorval);
 954                   return ret;
 955                 }
 956               color = end;
 957             }
 958         }
 959     }
 960   else if (strnicmp (colorname, "rgb:", 4) == 0)
 961     {
 962       char *color;
 963       UINT colorval;
 964       int i, pos;
 965       pos = 0;
 966 
 967       colorval = 0;
 968       color = colorname + 4;
 969       for (i = 0; i < 3; i++)
 970         {
 971           char *end;
 972           unsigned long value;
 973 
 974           /* The check for 'x' in the following conditional takes into
 975              account the fact that strtol allows a "0x" in front of
 976              our numbers, and we don't.  */
 977           if (!isxdigit (color[0]) || color[1] == 'x')
 978             break;
 979           value = strtoul (color, &end, 16);
 980           if (errno == ERANGE)
 981             break;
 982           switch (end - color)
 983             {
 984             case 1:
 985               value = value * 0x10 + value;
 986               break;
 987             case 2:
 988               break;
 989             case 3:
 990               value /= 0x10;
 991               break;
 992             case 4:
 993               value /= 0x100;
 994               break;
 995             default:
 996               value = ULONG_MAX;
 997             }
 998           if (value == ULONG_MAX)
 999             break;
1000           colorval |= (value << pos);
1001           pos += 0x8;
1002           if (i == 2)
1003             {
1004               if (*end != '\0')
1005                 break;
1006               UNBLOCK_INPUT;
1007               XSETINT (ret, colorval);
1008               return ret;
1009             }
1010           if (*end != '/')
1011             break;
1012           color = end + 1;
1013         }
1014     }
1015   else if (strnicmp (colorname, "rgbi:", 5) == 0)
1016     {
1017       /* This is an RGB Intensity specification.  */
1018       char *color;
1019       UINT colorval;
1020       int i, pos;
1021       pos = 0;
1022 
1023       colorval = 0;
1024       color = colorname + 5;
1025       for (i = 0; i < 3; i++)
1026         {
1027           char *end;
1028           double value;
1029           UINT val;
1030 
1031           value = strtod (color, &end);
1032           if (errno == ERANGE)
1033             break;
1034           if (value < 0.0 || value > 1.0)
1035             break;
1036           val = (UINT)(0x100 * value);
1037           /* We used 0x100 instead of 0xFF to give a continuous
1038              range between 0.0 and 1.0 inclusive.  The next statement
1039              fixes the 1.0 case.  */
1040           if (val == 0x100)
1041             val = 0xFF;
1042           colorval |= (val << pos);
1043           pos += 0x8;
1044           if (i == 2)
1045             {
1046               if (*end != '\0')
1047                 break;
1048               UNBLOCK_INPUT;
1049               XSETINT (ret, colorval);
1050               return ret;
1051             }
1052           if (*end != '/')
1053             break;
1054           color = end + 1;
1055         }
1056     }
1057   /* I am not going to attempt to handle any of the CIE color schemes
1058      or TekHVC, since I don't know the algorithms for conversion to
1059      RGB.  */
1060 
1061   /* If we fail to lookup the color name in w32_color_map, then check the
1062      colorname to see if it can be crudely approximated: If the X color
1063      ends in a number (e.g., "darkseagreen2"), strip the number and
1064      return the result of looking up the base color name.  */
1065   ret = w32_color_map_lookup (colorname);
1066   if (NILP (ret))
1067     {
1068       int len = strlen (colorname);
1069 
1070       if (isdigit (colorname[len - 1]))
1071         {
1072           char *ptr, *approx = alloca (len + 1);
1073 
1074           strcpy (approx, colorname);
1075           ptr = &approx[len - 1];
1076           while (ptr > approx && isdigit (*ptr))
1077               *ptr-- = '\0';
1078 
1079           ret = w32_color_map_lookup (approx);
1080         }
1081     }
1082 
1083   UNBLOCK_INPUT;
1084   return ret;
1085 }
1086 
1087 void
1088 w32_regenerate_palette (FRAME_PTR f)
1089 {
1090   struct w32_palette_entry * list;
1091   LOGPALETTE *          log_palette;
1092   HPALETTE              new_palette;
1093   int                   i;
1094 
1095   /* don't bother trying to create palette if not supported */
1096   if (! FRAME_W32_DISPLAY_INFO (f)->has_palette)
1097     return;
1098 
1099   log_palette = (LOGPALETTE *)
1100     alloca (sizeof (LOGPALETTE) +
1101              FRAME_W32_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY));
1102   log_palette->palVersion = 0x300;
1103   log_palette->palNumEntries = FRAME_W32_DISPLAY_INFO (f)->num_colors;
1104 
1105   list = FRAME_W32_DISPLAY_INFO (f)->color_list;
1106   for (i = 0;
1107        i < FRAME_W32_DISPLAY_INFO (f)->num_colors;
1108        i++, list = list->next)
1109     log_palette->palPalEntry[i] = list->entry;
1110 
1111   new_palette = CreatePalette (log_palette);
1112 
1113   enter_crit ();
1114 
1115   if (FRAME_W32_DISPLAY_INFO (f)->palette)
1116     DeleteObject (FRAME_W32_DISPLAY_INFO (f)->palette);
1117   FRAME_W32_DISPLAY_INFO (f)->palette = new_palette;
1118 
1119   /* Realize display palette and garbage all frames. */
1120   release_frame_dc (f, get_frame_dc (f));
1121 
1122   leave_crit ();
1123 }
1124 
1125 #define W32_COLOR(pe)  RGB (pe.peRed, pe.peGreen, pe.peBlue)
1126 #define SET_W32_COLOR(pe, color) \
1127   do \
1128     { \
1129       pe.peRed = GetRValue (color); \
1130       pe.peGreen = GetGValue (color); \
1131       pe.peBlue = GetBValue (color); \
1132       pe.peFlags = 0; \
1133     } while (0)
1134 
1135 #if 0
1136 /* Keep these around in case we ever want to track color usage. */
1137 void
1138 w32_map_color (FRAME_PTR f, COLORREF color)
1139 {
1140   struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
1141 
1142   if (NILP (Vw32_enable_palette))
1143     return;
1144 
1145   /* check if color is already mapped */
1146   while (list)
1147     {
1148       if (W32_COLOR (list->entry) == color)
1149         {
1150           ++list->refcount;
1151           return;
1152         }
1153       list = list->next;
1154     }
1155 
1156   /* not already mapped, so add to list and recreate Windows palette */
1157   list = (struct w32_palette_entry *)
1158     xmalloc (sizeof (struct w32_palette_entry));
1159   SET_W32_COLOR (list->entry, color);
1160   list->refcount = 1;
1161   list->next = FRAME_W32_DISPLAY_INFO (f)->color_list;
1162   FRAME_W32_DISPLAY_INFO (f)->color_list = list;
1163   FRAME_W32_DISPLAY_INFO (f)->num_colors++;
1164 
1165   /* set flag that palette must be regenerated */
1166   FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE;
1167 }
1168 
1169 void
1170 w32_unmap_color (FRAME_PTR f, COLORREF color)
1171 {
1172   struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
1173   struct w32_palette_entry **prev = &FRAME_W32_DISPLAY_INFO (f)->color_list;
1174 
1175   if (NILP (Vw32_enable_palette))
1176     return;
1177 
1178   /* check if color is already mapped */
1179   while (list)
1180     {
1181       if (W32_COLOR (list->entry) == color)
1182         {
1183           if (--list->refcount == 0)
1184             {
1185               *prev = list->next;
1186               xfree (list);
1187               FRAME_W32_DISPLAY_INFO (f)->num_colors--;
1188               break;
1189             }
1190           else
1191             return;
1192         }
1193       prev = &list->next;
1194       list = list->next;
1195     }
1196 
1197   /* set flag that palette must be regenerated */
1198   FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE;
1199 }
1200 #endif
1201 
1202 
1203 /* Gamma-correct COLOR on frame F.  */
1204 
1205 void
1206 gamma_correct (f, color)
1207      struct frame *f;
1208      COLORREF *color;
1209 {
1210   if (f->gamma)
1211     {
1212       *color = PALETTERGB (
1213         pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1214         pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1215         pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5);
1216     }
1217 }
1218 
1219 
1220 /* Decide if color named COLOR is valid for the display associated with
1221    the selected frame; if so, return the rgb values in COLOR_DEF.
1222    If ALLOC is nonzero, allocate a new colormap cell.  */
1223 
1224 int
1225 w32_defined_color (f, color, color_def, alloc)
1226      FRAME_PTR f;
1227      char *color;
1228      XColor *color_def;
1229      int alloc;
1230 {
1231   register Lisp_Object tem;
1232   COLORREF w32_color_ref;
1233 
1234   tem = x_to_w32_color (color);
1235 
1236   if (!NILP (tem))
1237     {
1238       if (f)
1239         {
1240           /* Apply gamma correction.  */
1241           w32_color_ref = XUINT (tem);
1242           gamma_correct (f, &w32_color_ref);
1243           XSETINT (tem, w32_color_ref);
1244         }
1245 
1246       /* Map this color to the palette if it is enabled. */
1247       if (!NILP (Vw32_enable_palette))
1248         {
1249           struct w32_palette_entry * entry =
1250             one_w32_display_info.color_list;
1251           struct w32_palette_entry ** prev =
1252             &one_w32_display_info.color_list;
1253 
1254           /* check if color is already mapped */
1255           while (entry)
1256             {
1257               if (W32_COLOR (entry->entry) == XUINT (tem))
1258                 break;
1259               prev = &entry->next;
1260               entry = entry->next;
1261             }
1262 
1263           if (entry == NULL && alloc)
1264             {
1265               /* not already mapped, so add to list */
1266               entry = (struct w32_palette_entry *)
1267                 xmalloc (sizeof (struct w32_palette_entry));
1268               SET_W32_COLOR (entry->entry, XUINT (tem));
1269               entry->next = NULL;
1270               *prev = entry;
1271               one_w32_display_info.num_colors++;
1272 
1273               /* set flag that palette must be regenerated */
1274               one_w32_display_info.regen_palette = TRUE;
1275             }
1276         }
1277       /* Ensure COLORREF value is snapped to nearest color in (default)
1278          palette by simulating the PALETTERGB macro.  This works whether
1279          or not the display device has a palette. */
1280       w32_color_ref = XUINT (tem) | 0x2000000;
1281 
1282       color_def->pixel = w32_color_ref;
1283       color_def->red = GetRValue (w32_color_ref) * 256;
1284       color_def->green = GetGValue (w32_color_ref) * 256;
1285       color_def->blue = GetBValue (w32_color_ref) * 256;
1286 
1287       return 1;
1288     }
1289   else
1290     {
1291       return 0;
1292     }
1293 }
1294 
1295 /* Given a string ARG naming a color, compute a pixel value from it
1296    suitable for screen F.
1297    If F is not a color screen, return DEF (default) regardless of what
1298    ARG says.  */
1299 
1300 int
1301 x_decode_color (f, arg, def)
1302      FRAME_PTR f;
1303      Lisp_Object arg;
1304      int def;
1305 {
1306   XColor cdef;
1307 
1308   CHECK_STRING (arg);
1309 
1310   if (strcmp (SDATA (arg), "black") == 0)
1311     return BLACK_PIX_DEFAULT (f);
1312   else if (strcmp (SDATA (arg), "white") == 0)
1313     return WHITE_PIX_DEFAULT (f);
1314 
1315   if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1)
1316     return def;
1317 
1318   /* w32_defined_color is responsible for coping with failures
1319      by looking for a near-miss.  */
1320   if (w32_defined_color (f, SDATA (arg), &cdef, 1))
1321     return cdef.pixel;
1322 
1323   /* defined_color failed; return an ultimate default.  */
1324   return def;
1325 }
1326 
1327 
1328 
1329 /* Functions called only from `x_set_frame_param'
1330    to set individual parameters.
1331 
1332    If FRAME_W32_WINDOW (f) is 0,
1333    the frame is being created and its window does not exist yet.
1334    In that case, just record the parameter's new value
1335    in the standard place; do not attempt to change the window.  */
1336 
1337 void
1338 x_set_foreground_color (f, arg, oldval)
1339      struct frame *f;
1340      Lisp_Object arg, oldval;
1341 {
1342   struct w32_output *x = f->output_data.w32;
1343   PIX_TYPE fg, old_fg;
1344 
1345   fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1346   old_fg = FRAME_FOREGROUND_PIXEL (f);
1347   FRAME_FOREGROUND_PIXEL (f) = fg;
1348 
1349   if (FRAME_W32_WINDOW (f) != 0)
1350     {
1351       if (x->cursor_pixel == old_fg)
1352         x->cursor_pixel = fg;
1353 
1354       update_face_from_frame_parameter (f, Qforeground_color, arg);
1355       if (FRAME_VISIBLE_P (f))
1356         redraw_frame (f);
1357     }
1358 }
1359 
1360 void
1361 x_set_background_color (f, arg, oldval)
1362      struct frame *f;
1363      Lisp_Object arg, oldval;
1364 {
1365   FRAME_BACKGROUND_PIXEL (f)
1366     = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1367 
1368   if (FRAME_W32_WINDOW (f) != 0)
1369     {
1370       SetWindowLong (FRAME_W32_WINDOW (f), WND_BACKGROUND_INDEX,
1371                      FRAME_BACKGROUND_PIXEL (f));
1372 
1373       update_face_from_frame_parameter (f, Qbackground_color, arg);
1374 
1375       if (FRAME_VISIBLE_P (f))
1376         redraw_frame (f);
1377     }
1378 }
1379 
1380 void
1381 x_set_mouse_color (f, arg, oldval)
1382      struct frame *f;
1383      Lisp_Object arg, oldval;
1384 {
1385   Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1386   int count;
1387   int mask_color;
1388 
1389   if (!EQ (Qnil, arg))
1390     f->output_data.w32->mouse_pixel
1391       = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1392   mask_color = FRAME_BACKGROUND_PIXEL (f);
1393 
1394   /* Don't let pointers be invisible.  */
1395   if (mask_color == f->output_data.w32->mouse_pixel
1396         && mask_color == FRAME_BACKGROUND_PIXEL (f))
1397     f->output_data.w32->mouse_pixel = FRAME_FOREGROUND_PIXEL (f);
1398 
1399 #if 0 /* TODO : Mouse cursor customization.  */
1400   BLOCK_INPUT;
1401 
1402   /* It's not okay to crash if the user selects a screwy cursor.  */
1403   count = x_catch_errors (FRAME_W32_DISPLAY (f));
1404 
1405   if (!EQ (Qnil, Vx_pointer_shape))
1406     {
1407       CHECK_NUMBER (Vx_pointer_shape);
1408       cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XINT (Vx_pointer_shape));
1409     }
1410   else
1411     cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1412   x_check_errors (FRAME_W32_DISPLAY (f), "bad text pointer cursor: %s");
1413 
1414   if (!EQ (Qnil, Vx_nontext_pointer_shape))
1415     {
1416       CHECK_NUMBER (Vx_nontext_pointer_shape);
1417       nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1418                                           XINT (Vx_nontext_pointer_shape));
1419     }
1420   else
1421     nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_left_ptr);
1422   x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1423 
1424   if (!EQ (Qnil, Vx_hourglass_pointer_shape))
1425     {
1426       CHECK_NUMBER (Vx_hourglass_pointer_shape);
1427       hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1428                                             XINT (Vx_hourglass_pointer_shape));
1429     }
1430   else
1431     hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch);
1432   x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s");
1433 
1434   x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1435   if (!EQ (Qnil, Vx_mode_pointer_shape))
1436     {
1437       CHECK_NUMBER (Vx_mode_pointer_shape);
1438       mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1439                                        XINT (Vx_mode_pointer_shape));
1440     }
1441   else
1442     mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1443   x_check_errors (FRAME_W32_DISPLAY (f), "bad modeline pointer cursor: %s");
1444 
1445   if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
1446     {
1447       CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1448       hand_cursor
1449         = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1450                              XINT (Vx_sensitive_text_pointer_shape));
1451     }
1452   else
1453     hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair);
1454 
1455   if (!NILP (Vx_window_horizontal_drag_shape))
1456     {
1457       CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1458       horizontal_drag_cursor
1459         = XCreateFontCursor (FRAME_X_DISPLAY (f),
1460                              XINT (Vx_window_horizontal_drag_shape));
1461     }
1462   else
1463     horizontal_drag_cursor
1464       = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
1465 
1466   /* Check and report errors with the above calls.  */
1467   x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
1468   x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
1469 
1470   {
1471     XColor fore_color, back_color;
1472 
1473     fore_color.pixel = f->output_data.w32->mouse_pixel;
1474     back_color.pixel = mask_color;
1475     XQueryColor (FRAME_W32_DISPLAY (f),
1476                  DefaultColormap (FRAME_W32_DISPLAY (f),
1477                                   DefaultScreen (FRAME_W32_DISPLAY (f))),
1478                  &fore_color);
1479     XQueryColor (FRAME_W32_DISPLAY (f),
1480                  DefaultColormap (FRAME_W32_DISPLAY (f),
1481                                   DefaultScreen (FRAME_W32_DISPLAY (f))),
1482                  &back_color);
1483     XRecolorCursor (FRAME_W32_DISPLAY (f), cursor,
1484                     &fore_color, &back_color);
1485     XRecolorCursor (FRAME_W32_DISPLAY (f), nontext_cursor,
1486                     &fore_color, &back_color);
1487     XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
1488                     &fore_color, &back_color);
1489     XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
1490                     &fore_color, &back_color);
1491     XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
1492                     &fore_color, &back_color);
1493   }
1494 
1495   if (FRAME_W32_WINDOW (f) != 0)
1496     XDefineCursor (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), cursor);
1497 
1498   if (cursor != f->output_data.w32->text_cursor && f->output_data.w32->text_cursor != 0)
1499     XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->text_cursor);
1500   f->output_data.w32->text_cursor = cursor;
1501 
1502   if (nontext_cursor != f->output_data.w32->nontext_cursor
1503       && f->output_data.w32->nontext_cursor != 0)
1504     XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->nontext_cursor);
1505   f->output_data.w32->nontext_cursor = nontext_cursor;
1506 
1507   if (hourglass_cursor != f->output_data.w32->hourglass_cursor
1508       && f->output_data.w32->hourglass_cursor != 0)
1509     XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hourglass_cursor);
1510   f->output_data.w32->hourglass_cursor = hourglass_cursor;
1511 
1512   if (mode_cursor != f->output_data.w32->modeline_cursor
1513       && f->output_data.w32->modeline_cursor != 0)
1514     XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor);
1515   f->output_data.w32->modeline_cursor = mode_cursor;
1516 
1517   if (hand_cursor != f->output_data.w32->hand_cursor
1518       && f->output_data.w32->hand_cursor != 0)
1519     XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor);
1520   f->output_data.w32->hand_cursor = hand_cursor;
1521 
1522   XFlush (FRAME_W32_DISPLAY (f));
1523   UNBLOCK_INPUT;
1524 
1525   update_face_from_frame_parameter (f, Qmouse_color, arg);
1526 #endif /* TODO */
1527 }
1528 
1529 void
1530 x_set_cursor_color (f, arg, oldval)
1531      struct frame *f;
1532      Lisp_Object arg, oldval;
1533 {
1534   unsigned long fore_pixel, pixel;
1535 
1536   if (!NILP (Vx_cursor_fore_pixel))
1537     fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1538                                  WHITE_PIX_DEFAULT (f));
1539   else
1540     fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1541 
1542   pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1543 
1544   /* Make sure that the cursor color differs from the background color.  */
1545   if (pixel == FRAME_BACKGROUND_PIXEL (f))
1546     {
1547       pixel = f->output_data.w32->mouse_pixel;
1548       if (pixel == fore_pixel)
1549         fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1550     }
1551 
1552   f->output_data.w32->cursor_foreground_pixel = fore_pixel;
1553   f->output_data.w32->cursor_pixel = pixel;
1554 
1555   if (FRAME_W32_WINDOW (f) != 0)
1556     {
1557       BLOCK_INPUT;
1558       /* Update frame's cursor_gc.  */
1559       f->output_data.w32->cursor_gc->foreground = fore_pixel;
1560       f->output_data.w32->cursor_gc->background = pixel;
1561 
1562       UNBLOCK_INPUT;
1563 
1564       if (FRAME_VISIBLE_P (f))
1565         {
1566           x_update_cursor (f, 0);
1567           x_update_cursor (f, 1);
1568         }
1569     }
1570 
1571   update_face_from_frame_parameter (f, Qcursor_color, arg);
1572 }
1573 
1574 /* Set the border-color of frame F to pixel value PIX.
1575    Note that this does not fully take effect if done before
1576    F has a window.  */
1577 
1578 void
1579 x_set_border_pixel (f, pix)
1580      struct frame *f;
1581      int pix;
1582 {
1583 
1584   f->output_data.w32->border_pixel = pix;
1585 
1586   if (FRAME_W32_WINDOW (f) != 0 && f->border_width > 0)
1587     {
1588       if (FRAME_VISIBLE_P (f))
1589         redraw_frame (f);
1590     }
1591 }
1592 
1593 /* Set the border-color of frame F to value described by ARG.
1594    ARG can be a string naming a color.
1595    The border-color is used for the border that is drawn by the server.
1596    Note that this does not fully take effect if done before
1597    F has a window; it must be redone when the window is created.  */
1598 
1599 void
1600 x_set_border_color (f, arg, oldval)
1601      struct frame *f;
1602      Lisp_Object arg, oldval;
1603 {
1604   int pix;
1605 
1606   CHECK_STRING (arg);
1607   pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1608   x_set_border_pixel (f, pix);
1609   update_face_from_frame_parameter (f, Qborder_color, arg);
1610 }
1611 
1612 
1613 void
1614 x_set_cursor_type (f, arg, oldval)
1615      FRAME_PTR f;
1616      Lisp_Object arg, oldval;
1617 {
1618   set_frame_cursor_types (f, arg);
1619 
1620   /* Make sure the cursor gets redrawn.  */
1621   cursor_type_changed = 1;
1622 }
1623 
1624 void
1625 x_set_icon_type (f, arg, oldval)
1626      struct frame *f;
1627      Lisp_Object arg, oldval;
1628 {
1629   int result;
1630 
1631   if (NILP (arg) && NILP (oldval))
1632     return;
1633 
1634   if (STRINGP (arg) && STRINGP (oldval)
1635       && EQ (Fstring_equal (oldval, arg), Qt))
1636     return;
1637 
1638   if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1639     return;
1640 
1641   BLOCK_INPUT;
1642 
1643   result = x_bitmap_icon (f, arg);
1644   if (result)
1645     {
1646       UNBLOCK_INPUT;
1647       error ("No icon window available");
1648     }
1649 
1650   UNBLOCK_INPUT;
1651 }
1652 
1653 void
1654 x_set_icon_name (f, arg, oldval)
1655      struct frame *f;
1656      Lisp_Object arg, oldval;
1657 {
1658   if (STRINGP (arg))
1659     {
1660       if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1661         return;
1662     }
1663   else if (!NILP (arg) || NILP (oldval))
1664     return;
1665 
1666   f->icon_name = arg;
1667 
1668 #if 0
1669   if (f->output_data.w32->icon_bitmap != 0)
1670     return;
1671 
1672   BLOCK_INPUT;
1673 
1674   result = x_text_icon (f,
1675                         (char *) SDATA ((!NILP (f->icon_name)
1676                                          ? f->icon_name
1677                                          : !NILP (f->title)
1678                                          ? f->title
1679                                          : f->name)));
1680 
1681   if (result)
1682     {
1683       UNBLOCK_INPUT;
1684       error ("No icon window available");
1685     }
1686 
1687   /* If the window was unmapped (and its icon was mapped),
1688      the new icon is not mapped, so map the window in its stead.  */
1689   if (FRAME_VISIBLE_P (f))
1690     {
1691 #ifdef USE_X_TOOLKIT
1692       XtPopup (f->output_data.w32->widget, XtGrabNone);
1693 #endif
1694       XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1695     }
1696 
1697   XFlush (FRAME_W32_DISPLAY (f));
1698   UNBLOCK_INPUT;
1699 #endif
1700 }
1701 
1702 
1703 void
1704 x_set_menu_bar_lines (f, value, oldval)
1705      struct frame *f;
1706      Lisp_Object value, oldval;
1707 {
1708   int nlines;
1709   int olines = FRAME_MENU_BAR_LINES (f);
1710 
1711   /* Right now, menu bars don't work properly in minibuf-only frames;
1712      most of the commands try to apply themselves to the minibuffer
1713      frame itself, and get an error because you can't switch buffers
1714      in or split the minibuffer window.  */
1715   if (FRAME_MINIBUF_ONLY_P (f))
1716     return;
1717 
1718   if (INTEGERP (value))
1719     nlines = XINT (value);
1720   else
1721     nlines = 0;
1722 
1723   FRAME_MENU_BAR_LINES (f) = 0;
1724   if (nlines)
1725     FRAME_EXTERNAL_MENU_BAR (f) = 1;
1726   else
1727     {
1728       if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1729         free_frame_menubar (f);
1730       FRAME_EXTERNAL_MENU_BAR (f) = 0;
1731 
1732       /* Adjust the frame size so that the client (text) dimensions
1733          remain the same.  This depends on FRAME_EXTERNAL_MENU_BAR being
1734          set correctly.  */
1735       x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
1736       do_pending_window_change (0);
1737     }
1738   adjust_glyphs (f);
1739 }
1740 
1741 
1742 /* Set the number of lines used for the tool bar of frame F to VALUE.
1743    VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
1744    is the old number of tool bar lines.  This function changes the
1745    height of all windows on frame F to match the new tool bar height.
1746    The frame's height doesn't change.  */
1747 
1748 void
1749 x_set_tool_bar_lines (f, value, oldval)
1750      struct frame *f;
1751      Lisp_Object value, oldval;
1752 {
1753   int delta, nlines, root_height;
1754   Lisp_Object root_window;
1755 
1756   /* Treat tool bars like menu bars.  */
1757   if (FRAME_MINIBUF_ONLY_P (f))
1758     return;
1759 
1760   /* Use VALUE only if an integer >= 0.  */
1761   if (INTEGERP (value) && XINT (value) >= 0)
1762     nlines = XFASTINT (value);
1763   else
1764     nlines = 0;
1765 
1766   /* Make sure we redisplay all windows in this frame.  */
1767   ++windows_or_buffers_changed;
1768 
1769   delta = nlines - FRAME_TOOL_BAR_LINES (f);
1770 
1771   /* Don't resize the tool-bar to more than we have room for.  */
1772   root_window = FRAME_ROOT_WINDOW (f);
1773   root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1774   if (root_height - delta < 1)
1775     {
1776       delta = root_height - 1;
1777       nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1778     }
1779 
1780   FRAME_TOOL_BAR_LINES (f) = nlines;
1781   change_window_heights (root_window, delta);
1782   adjust_glyphs (f);
1783 
1784   /* We also have to make sure that the internal border at the top of
1785      the frame, below the menu bar or tool bar, is redrawn when the
1786      tool bar disappears.  This is so because the internal border is
1787      below the tool bar if one is displayed, but is below the menu bar
1788      if there isn't a tool bar.  The tool bar draws into the area
1789      below the menu bar.  */
1790   if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1791     {
1792       clear_frame (f);
1793       clear_current_matrices (f);
1794     }
1795 
1796   /* If the tool bar gets smaller, the internal border below it
1797      has to be cleared.  It was formerly part of the display
1798      of the larger tool bar, and updating windows won't clear it.  */
1799   if (delta < 0)
1800     {
1801       int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1802       int width = FRAME_PIXEL_WIDTH (f);
1803       int y = nlines * FRAME_LINE_HEIGHT (f);
1804 
1805       BLOCK_INPUT;
1806       {
1807         HDC hdc = get_frame_dc (f);
1808         w32_clear_area (f, hdc, 0, y, width, height);
1809         release_frame_dc (f, hdc);
1810       }
1811       UNBLOCK_INPUT;
1812 
1813       if (WINDOWP (f->tool_bar_window))
1814         clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1815     }
1816 }
1817 
1818 
1819 /* Change the name of frame F to NAME.  If NAME is nil, set F's name to
1820        w32_id_name.
1821 
1822    If EXPLICIT is non-zero, that indicates that lisp code is setting the
1823        name; if NAME is a string, set F's name to NAME and set
1824        F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1825 
1826    If EXPLICIT is zero, that indicates that Emacs redisplay code is
1827        suggesting a new name, which lisp code should override; if
1828        F->explicit_name is set, ignore the new name; otherwise, set it.  */
1829 
1830 void
1831 x_set_name (f, name, explicit)
1832      struct frame *f;
1833      Lisp_Object name;
1834      int explicit;
1835 {
1836   /* Make sure that requests from lisp code override requests from
1837      Emacs redisplay code.  */
1838   if (explicit)
1839     {
1840       /* If we're switching from explicit to implicit, we had better
1841          update the mode lines and thereby update the title.  */
1842       if (f->explicit_name && NILP (name))
1843         update_mode_lines = 1;
1844 
1845       f->explicit_name = ! NILP (name);
1846     }
1847   else if (f->explicit_name)
1848     return;
1849 
1850   /* If NAME is nil, set the name to the w32_id_name.  */
1851   if (NILP (name))
1852     {
1853       /* Check for no change needed in this very common case
1854          before we do any consing.  */
1855       if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name,
1856                    SDATA (f->name)))
1857         return;
1858       name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name);
1859     }
1860   else
1861     CHECK_STRING (name);
1862 
1863   /* Don't change the name if it's already NAME.  */
1864   if (! NILP (Fstring_equal (name, f->name)))
1865     return;
1866 
1867   f->name = name;
1868 
1869   /* For setting the frame title, the title parameter should override
1870      the name parameter.  */
1871   if (! NILP (f->title))
1872     name = f->title;
1873 
1874   if (FRAME_W32_WINDOW (f))
1875     {
1876       if (STRING_MULTIBYTE (name))
1877         name = ENCODE_SYSTEM (name);
1878 
1879       BLOCK_INPUT;
1880       SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
1881       UNBLOCK_INPUT;
1882     }
1883 }
1884 
1885 /* This function should be called when the user's lisp code has
1886    specified a name for the frame; the name will override any set by the
1887    redisplay code.  */
1888 void
1889 x_explicitly_set_name (f, arg, oldval)
1890      FRAME_PTR f;
1891      Lisp_Object arg, oldval;
1892 {
1893   x_set_name (f, arg, 1);
1894 }
1895 
1896 /* This function should be called by Emacs redisplay code to set the
1897    name; names set this way will never override names set by the user's
1898    lisp code.  */
1899 void
1900 x_implicitly_set_name (f, arg, oldval)
1901      FRAME_PTR f;
1902      Lisp_Object arg, oldval;
1903 {
1904   x_set_name (f, arg, 0);
1905 }
1906 
1907 /* Change the title of frame F to NAME.
1908    If NAME is nil, use the frame name as the title.  */
1909 
1910 void
1911 x_set_title (f, name, old_name)
1912      struct frame *f;
1913      Lisp_Object name, old_name;
1914 {
1915   /* Don't change the title if it's already NAME.  */
1916   if (EQ (name, f->title))
1917     return;
1918 
1919   update_mode_lines = 1;
1920 
1921   f->title = name;
1922 
1923   if (NILP (name))
1924     name = f->name;
1925 
1926   if (FRAME_W32_WINDOW (f))
1927     {
1928       if (STRING_MULTIBYTE (name))
1929         name = ENCODE_SYSTEM (name);
1930 
1931       BLOCK_INPUT;
1932       SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
1933       UNBLOCK_INPUT;
1934     }
1935 }
1936 
1937 
1938 void x_set_scroll_bar_default_width (f)
1939      struct frame *f;
1940 {
1941   int wid = FRAME_COLUMN_WIDTH (f);
1942 
1943   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
1944   FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
1945                                       wid - 1) / wid;
1946 }
1947 
1948 
1949 /* Subroutines for creating a frame.  */
1950 
1951 Cursor
1952 w32_load_cursor (LPCTSTR name)
1953 {
1954   /* Try first to load cursor from application resource.  */
1955   Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL),
1956                              name, IMAGE_CURSOR, 0, 0,
1957                              LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
1958   if (!cursor)
1959     {
1960       /* Then try to load a shared predefined cursor.  */
1961       cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0,
1962                           LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
1963     }
1964   return cursor;
1965 }
1966 
1967 extern LRESULT CALLBACK w32_wnd_proc ();
1968 
1969 static BOOL
1970 w32_init_class (hinst)
1971      HINSTANCE hinst;
1972 {
1973   WNDCLASS wc;
1974 
1975   wc.style = CS_HREDRAW | CS_VREDRAW;
1976   wc.lpfnWndProc = (WNDPROC) w32_wnd_proc;
1977   wc.cbClsExtra = 0;
1978   wc.cbWndExtra = WND_EXTRA_BYTES;
1979   wc.hInstance = hinst;
1980   wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
1981   wc.hCursor = w32_load_cursor (IDC_ARROW);
1982   wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH);  */
1983   wc.lpszMenuName = NULL;
1984   wc.lpszClassName = EMACS_CLASS;
1985 
1986   return (RegisterClass (&wc));
1987 }
1988 
1989 static HWND
1990 w32_createscrollbar (f, bar)
1991      struct frame *f;
1992      struct scroll_bar * bar;
1993 {
1994   return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
1995                         /* Position and size of scroll bar.  */
1996                         XINT (bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
1997                         XINT (bar->top),
1998                         XINT (bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
1999                         XINT (bar->height),
2000                         FRAME_W32_WINDOW (f),
2001                         NULL,
2002                         hinst,
2003                         NULL));
2004 }
2005 
2006 static void
2007 w32_createwindow (f)
2008      struct frame *f;
2009 {
2010   HWND hwnd;
2011   RECT rect;
2012   Lisp_Object top = Qunbound;
2013   Lisp_Object left = Qunbound;
2014   struct w32_display_info *dpyinfo = &one_w32_display_info;
2015 
2016   rect.left = rect.top = 0;
2017   rect.right = FRAME_PIXEL_WIDTH (f);
2018   rect.bottom = FRAME_PIXEL_HEIGHT (f);
2019 
2020   AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
2021                     FRAME_EXTERNAL_MENU_BAR (f));
2022 
2023   /* Do first time app init */
2024 
2025   if (!hprevinst)
2026     {
2027       w32_init_class (hinst);
2028     }
2029 
2030   if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
2031     {
2032       XSETINT (left, f->left_pos);
2033       XSETINT (top, f->top_pos);
2034     }
2035   else if (EQ (left, Qunbound) && EQ (top, Qunbound))
2036     {
2037       /* When called with RES_TYPE_NUMBER, w32_get_arg will return zero
2038          for anything that is not a number and is not Qunbound.  */
2039       left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
2040       top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
2041     }
2042 
2043   FRAME_W32_WINDOW (f) = hwnd
2044     = CreateWindow (EMACS_CLASS,
2045                     f->namebuf,
2046                     f->output_data.w32->dwStyle | WS_CLIPCHILDREN,
2047                     EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left),
2048                     EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top),
2049                     rect.right - rect.left,
2050                     rect.bottom - rect.top,
2051                     NULL,
2052                     NULL,
2053                     hinst,
2054                     NULL);
2055 
2056   if (hwnd)
2057     {
2058       SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
2059       SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
2060       SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
2061       SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
2062       SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
2063 
2064       /* Enable drag-n-drop.  */
2065       DragAcceptFiles (hwnd, TRUE);
2066 
2067       /* Do this to discard the default setting specified by our parent. */
2068       ShowWindow (hwnd, SW_HIDE);
2069 
2070       /* Update frame positions. */
2071       GetWindowRect (hwnd, &rect);
2072       f->left_pos = rect.left;
2073       f->top_pos = rect.top;
2074     }
2075 }
2076 
2077 static void
2078 my_post_msg (wmsg, hwnd, msg, wParam, lParam)
2079      W32Msg * wmsg;
2080      HWND hwnd;
2081      UINT msg;
2082      WPARAM wParam;
2083      LPARAM lParam;
2084 {
2085   wmsg->msg.hwnd = hwnd;
2086   wmsg->msg.message = msg;
2087   wmsg->msg.wParam = wParam;
2088   wmsg->msg.lParam = lParam;
2089   wmsg->msg.time = GetMessageTime ();
2090 
2091   post_msg (wmsg);
2092 }
2093 
2094 /* GetKeyState and MapVirtualKey on Windows 95 do not actually distinguish
2095    between left and right keys as advertised.  We test for this
2096    support dynamically, and set a flag when the support is absent.  If
2097    absent, we keep track of the left and right control and alt keys
2098    ourselves.  This is particularly necessary on keyboards that rely
2099    upon the AltGr key, which is represented as having the left control
2100    and right alt keys pressed.  For these keyboards, we need to know
2101    when the left alt key has been pressed in addition to the AltGr key
2102    so that we can properly support M-AltGr-key sequences (such as M-@
2103    on Swedish keyboards).  */
2104 
2105 #define EMACS_LCONTROL 0
2106 #define EMACS_RCONTROL 1
2107 #define EMACS_LMENU    2
2108 #define EMACS_RMENU    3
2109 
2110 static int modifiers[4];
2111 static int modifiers_recorded;
2112 static int modifier_key_support_tested;
2113 
2114 static void
2115 test_modifier_support (unsigned int wparam)
2116 {
2117   unsigned int l, r;
2118 
2119   if (wparam != VK_CONTROL && wparam != VK_MENU)
2120     return;
2121   if (wparam == VK_CONTROL)
2122     {
2123       l = VK_LCONTROL;
2124       r = VK_RCONTROL;
2125     }
2126   else
2127     {
2128       l = VK_LMENU;
2129       r = VK_RMENU;
2130     }
2131   if (!(GetKeyState (l) & 0x8000) && !(GetKeyState (r) & 0x8000))
2132     modifiers_recorded = 1;
2133   else
2134     modifiers_recorded = 0;
2135   modifier_key_support_tested = 1;
2136 }
2137 
2138 static void
2139 record_keydown (unsigned int wparam, unsigned int lparam)
2140 {
2141   int i;
2142 
2143   if (!modifier_key_support_tested)
2144     test_modifier_support (wparam);
2145 
2146   if ((wparam != VK_CONTROL && wparam != VK_MENU) || !modifiers_recorded)
2147     return;
2148 
2149   if (wparam == VK_CONTROL)
2150     i = (lparam & 0x1000000) ? EMACS_RCONTROL : EMACS_LCONTROL;
2151   else
2152     i = (lparam & 0x1000000) ? EMACS_RMENU : EMACS_LMENU;
2153 
2154   modifiers[i] = 1;
2155 }
2156 
2157 static void
2158 record_keyup (unsigned int wparam, unsigned int lparam)
2159 {
2160   int i;
2161 
2162   if ((wparam != VK_CONTROL && wparam != VK_MENU) || !modifiers_recorded)
2163     return;
2164 
2165   if (wparam == VK_CONTROL)
2166     i = (lparam & 0x1000000) ? EMACS_RCONTROL : EMACS_LCONTROL;
2167   else
2168     i = (lparam & 0x1000000) ? EMACS_RMENU : EMACS_LMENU;
2169 
2170   modifiers[i] = 0;
2171 }
2172 
2173 /* Emacs can lose focus while a modifier key has been pressed.  When
2174    it regains focus, be conservative and clear all modifiers since
2175    we cannot reconstruct the left and right modifier state.  */
2176 static void
2177 reset_modifiers ()
2178 {
2179   SHORT ctrl, alt;
2180 
2181   if (GetFocus () == NULL)
2182     /* Emacs doesn't have keyboard focus.  Do nothing.  */
2183     return;
2184 
2185   ctrl = GetAsyncKeyState (VK_CONTROL);
2186   alt = GetAsyncKeyState (VK_MENU);
2187 
2188   if (!(ctrl & 0x08000))
2189     /* Clear any recorded control modifier state.  */
2190     modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
2191 
2192   if (!(alt & 0x08000))
2193     /* Clear any recorded alt modifier state.  */
2194     modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
2195 
2196   /* Update the state of all modifier keys, because modifiers used in
2197      hot-key combinations can get stuck on if Emacs loses focus as a
2198      result of a hot-key being pressed.  */
2199   {
2200     BYTE keystate[256];
2201 
2202 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
2203 
2204     GetKeyboardState (keystate);
2205     keystate[VK_SHIFT] = CURRENT_STATE (VK_SHIFT);
2206     keystate[VK_CONTROL] = CURRENT_STATE (VK_CONTROL);
2207     keystate[VK_LCONTROL] = CURRENT_STATE (VK_LCONTROL);
2208     keystate[VK_RCONTROL] = CURRENT_STATE (VK_RCONTROL);
2209     keystate[VK_MENU] = CURRENT_STATE (VK_MENU);
2210     keystate[VK_LMENU] = CURRENT_STATE (VK_LMENU);
2211     keystate[VK_RMENU] = CURRENT_STATE (VK_RMENU);
2212     keystate[VK_LWIN] = CURRENT_STATE (VK_LWIN);
2213     keystate[VK_RWIN] = CURRENT_STATE (VK_RWIN);
2214     keystate[VK_APPS] = CURRENT_STATE (VK_APPS);
2215     SetKeyboardState (keystate);
2216   }
2217 }
2218 
2219 /* Synchronize modifier state with what is reported with the current
2220    keystroke.  Even if we cannot distinguish between left and right
2221    modifier keys, we know that, if no modifiers are set, then neither
2222    the left or right modifier should be set.  */
2223 static void
2224 sync_modifiers ()
2225 {
2226   if (!modifiers_recorded)
2227     return;
2228 
2229   if (!(GetKeyState (VK_CONTROL) & 0x8000))
2230     modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
2231 
2232   if (!(GetKeyState (VK_MENU) & 0x8000))
2233     modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
2234 }
2235 
2236 static int
2237 modifier_set (int vkey)
2238 {
2239   if (vkey == VK_CAPITAL || vkey == VK_SCROLL)
2240     return (GetKeyState (vkey) & 0x1);
2241   if (!modifiers_recorded)
2242     return (GetKeyState (vkey) & 0x8000);
2243 
2244   switch (vkey)
2245     {
2246     case VK_LCONTROL:
2247       return modifiers[EMACS_LCONTROL];
2248     case VK_RCONTROL:
2249       return modifiers[EMACS_RCONTROL];
2250     case VK_LMENU:
2251       return modifiers[EMACS_LMENU];
2252     case VK_RMENU:
2253       return modifiers[EMACS_RMENU];
2254     }
2255   return (GetKeyState (vkey) & 0x8000);
2256 }
2257 
2258 /* Convert between the modifier bits W32 uses and the modifier bits
2259    Emacs uses.  */
2260 
2261 unsigned int
2262 w32_key_to_modifier (int key)
2263 {
2264   Lisp_Object key_mapping;
2265 
2266   switch (key)
2267     {
2268     case VK_LWIN:
2269       key_mapping = Vw32_lwindow_modifier;
2270       break;
2271     case VK_RWIN:
2272       key_mapping = Vw32_rwindow_modifier;
2273       break;
2274     case VK_APPS:
2275       key_mapping = Vw32_apps_modifier;
2276       break;
2277     case VK_SCROLL:
2278       key_mapping = Vw32_scroll_lock_modifier;
2279       break;
2280     default:
2281       key_mapping = Qnil;
2282     }
2283 
2284   /* NB. This code runs in the input thread, asychronously to the lisp
2285      thread, so we must be careful to ensure access to lisp data is
2286      thread-safe.  The following code is safe because the modifier
2287      variable values are updated atomically from lisp and symbols are
2288      not relocated by GC.  Also, we don't have to worry about seeing GC
2289      markbits here.  */
2290   if (EQ (key_mapping, Qhyper))
2291     return hyper_modifier;
2292   if (EQ (key_mapping, Qsuper))
2293     return super_modifier;
2294   if (EQ (key_mapping, Qmeta))
2295     return meta_modifier;
2296   if (EQ (key_mapping, Qalt))
2297     return alt_modifier;
2298   if (EQ (key_mapping, Qctrl))
2299     return ctrl_modifier;
2300   if (EQ (key_mapping, Qcontrol)) /* synonym for ctrl */
2301     return ctrl_modifier;
2302   if (EQ (key_mapping, Qshift))
2303     return shift_modifier;
2304 
2305   /* Don't generate any modifier if not explicitly requested.  */
2306   return 0;
2307 }
2308 
2309 static unsigned int
2310 w32_get_modifiers ()
2311 {
2312   return ((modifier_set (VK_SHIFT)   ? shift_modifier : 0) |
2313           (modifier_set (VK_CONTROL) ? ctrl_modifier  : 0) |
2314           (modifier_set (VK_LWIN)    ? w32_key_to_modifier (VK_LWIN) : 0) |
2315           (modifier_set (VK_RWIN)    ? w32_key_to_modifier (VK_RWIN) : 0) |
2316           (modifier_set (VK_APPS)    ? w32_key_to_modifier (VK_APPS) : 0) |
2317           (modifier_set (VK_SCROLL)  ? w32_key_to_modifier (VK_SCROLL) : 0) |
2318           (modifier_set (VK_MENU)    ?
2319            ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0));
2320 }
2321 
2322 /* We map the VK_* modifiers into console modifier constants
2323    so that we can use the same routines to handle both console
2324    and window input.  */
2325 
2326 static int
2327 construct_console_modifiers ()
2328 {
2329   int mods;
2330 
2331   mods = 0;
2332   mods |= (modifier_set (VK_SHIFT)) ? SHIFT_PRESSED : 0;
2333   mods |= (modifier_set (VK_CAPITAL)) ? CAPSLOCK_ON : 0;
2334   mods |= (modifier_set (VK_SCROLL)) ? SCROLLLOCK_ON : 0;
2335   mods |= (modifier_set (VK_NUMLOCK)) ? NUMLOCK_ON : 0;
2336   mods |= (modifier_set (VK_LCONTROL)) ? LEFT_CTRL_PRESSED : 0;
2337   mods |= (modifier_set (VK_RCONTROL)) ? RIGHT_CTRL_PRESSED : 0;
2338   mods |= (modifier_set (VK_LMENU)) ? LEFT_ALT_PRESSED : 0;
2339   mods |= (modifier_set (VK_RMENU)) ? RIGHT_ALT_PRESSED : 0;
2340   mods |= (modifier_set (VK_LWIN)) ? LEFT_WIN_PRESSED : 0;
2341   mods |= (modifier_set (VK_RWIN)) ? RIGHT_WIN_PRESSED : 0;
2342   mods |= (modifier_set (VK_APPS)) ? APPS_PRESSED : 0;
2343 
2344   return mods;
2345 }
2346 
2347 static int
2348 w32_get_key_modifiers (unsigned int wparam, unsigned int lparam)
2349 {
2350   int mods;
2351 
2352   /* Convert to emacs modifiers.  */
2353   mods = w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam);
2354 
2355   return mods;
2356 }
2357 
2358 unsigned int
2359 map_keypad_keys (unsigned int virt_key, unsigned int extended)
2360 {
2361   if (virt_key < VK_CLEAR || virt_key > VK_DELETE)
2362     return virt_key;
2363 
2364   if (virt_key == VK_RETURN)
2365     return (extended ? VK_NUMPAD_ENTER : VK_RETURN);
2366 
2367   if (virt_key >= VK_PRIOR && virt_key <= VK_DOWN)
2368     return (!extended ? (VK_NUMPAD_PRIOR + (virt_key - VK_PRIOR)) : virt_key);
2369 
2370   if (virt_key == VK_INSERT || virt_key == VK_DELETE)
2371     return (!extended ? (VK_NUMPAD_INSERT + (virt_key - VK_INSERT)) : virt_key);
2372 
2373   if (virt_key == VK_CLEAR)
2374     return (!extended ? VK_NUMPAD_CLEAR : virt_key);
2375 
2376   return virt_key;
2377 }
2378 
2379 /* List of special key combinations which w32 would normally capture,
2380    but Emacs should grab instead.  Not directly visible to lisp, to
2381    simplify synchronization.  Each item is an integer encoding a virtual
2382    key code and modifier combination to capture.  */
2383 static Lisp_Object w32_grabbed_keys;
2384 
2385 #define HOTKEY(vk, mods)      make_number (((vk) & 255) | ((mods) << 8))
2386 #define HOTKEY_ID(k)          (XFASTINT (k) & 0xbfff)
2387 #define HOTKEY_VK_CODE(k)     (XFASTINT (k) & 255)
2388 #define HOTKEY_MODIFIERS(k)   (XFASTINT (k) >> 8)
2389 
2390 #define RAW_HOTKEY_ID(k)        ((k) & 0xbfff)
2391 #define RAW_HOTKEY_VK_CODE(k)   ((k) & 255)
2392 #define RAW_HOTKEY_MODIFIERS(k) ((k) >> 8)
2393 
2394 /* Register hot-keys for reserved key combinations when Emacs has
2395    keyboard focus, since this is the only way Emacs can receive key
2396    combinations like Alt-Tab which are used by the system.  */
2397 
2398 static void
2399 register_hot_keys (hwnd)
2400      HWND hwnd;
2401 {
2402   Lisp_Object keylist;
2403 
2404   /* Use CONSP, since we are called asynchronously.  */
2405   for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
2406     {
2407       Lisp_Object key = XCAR (keylist);
2408 
2409       /* Deleted entries get set to nil.  */
2410       if (!INTEGERP (key))
2411         continue;
2412 
2413       RegisterHotKey (hwnd, HOTKEY_ID (key),
2414                       HOTKEY_MODIFIERS (key), HOTKEY_VK_CODE (key));
2415     }
2416 }
2417 
2418 static void
2419 unregister_hot_keys (hwnd)
2420      HWND hwnd;
2421 {
2422   Lisp_Object keylist;
2423 
2424   for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
2425     {
2426       Lisp_Object key = XCAR (keylist);
2427 
2428       if (!INTEGERP (key))
2429         continue;
2430 
2431       UnregisterHotKey (hwnd, HOTKEY_ID (key));
2432     }
2433 }
2434 
2435 /* Main message dispatch loop. */
2436 
2437 static void
2438 w32_msg_pump (deferred_msg * msg_buf)
2439 {
2440   MSG msg;
2441   int result;
2442   HWND focus_window;
2443 
2444   msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
2445 
2446   while (GetMessage (&msg, NULL, 0, 0))
2447     {
2448       if (msg.hwnd == NULL)
2449         {
2450           switch (msg.message)
2451             {
2452             case WM_NULL:
2453               /* Produced by complete_deferred_msg; just ignore.  */
2454               break;
2455             case WM_EMACS_CREATEWINDOW:
2456               /* Initialize COM for this window. Even though we don't use it,
2457                  some third party shell extensions can cause it to be used in
2458                  system dialogs, which causes a crash if it is not initialized.
2459                  This is a known bug in Windows, which was fixed long ago, but
2460                  the patch for XP is not publically available until XP SP3,
2461                  and older versions will never be patched.  */
2462               CoInitialize (NULL);
2463               w32_createwindow ((struct frame *) msg.wParam);
2464               if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2465                 abort ();
2466               break;
2467             case WM_EMACS_SETLOCALE:
2468               SetThreadLocale (msg.wParam);
2469               /* Reply is not expected.  */
2470               break;
2471             case WM_EMACS_SETKEYBOARDLAYOUT:
2472               result = (int) ActivateKeyboardLayout ((HKL) msg.wParam, 0);
2473               if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
2474                                       result, 0))
2475                 abort ();
2476               break;
2477             case WM_EMACS_REGISTER_HOT_KEY:
2478               focus_window = GetFocus ();
2479               if (focus_window != NULL)
2480                 RegisterHotKey (focus_window,
2481                                 RAW_HOTKEY_ID (msg.wParam),
2482                                 RAW_HOTKEY_MODIFIERS (msg.wParam),
2483                                 RAW_HOTKEY_VK_CODE (msg.wParam));
2484               /* Reply is not expected.  */
2485               break;
2486             case WM_EMACS_UNREGISTER_HOT_KEY:
2487               focus_window = GetFocus ();
2488               if (focus_window != NULL)
2489                 UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam));
2490               /* Mark item as erased.  NB: this code must be
2491                  thread-safe.  The next line is okay because the cons
2492                  cell is never made into garbage and is not relocated by
2493                  GC.  */
2494               XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
2495               if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2496                 abort ();
2497               break;
2498             case WM_EMACS_TOGGLE_LOCK_KEY:
2499               {
2500                 int vk_code = (int) msg.wParam;
2501                 int cur_state = (GetKeyState (vk_code) & 1);
2502                 Lisp_Object new_state = (Lisp_Object) ((EMACS_INT) msg.lParam);
2503 
2504                 /* NB: This code must be thread-safe.  It is safe to
2505                    call NILP because symbols are not relocated by GC,
2506                    and pointer here is not touched by GC (so the markbit
2507                    can't be set).  Numbers are safe because they are
2508                    immediate values.  */
2509                 if (NILP (new_state)
2510                     || (NUMBERP (new_state)
2511                         && ((XUINT (new_state)) & 1) != cur_state))
2512                   {
2513                     one_w32_display_info.faked_key = vk_code;
2514 
2515                     keybd_event ((BYTE) vk_code,
2516                                  (BYTE) MapVirtualKey (vk_code, 0),
2517                                  KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
2518                     keybd_event ((BYTE) vk_code,
2519                                  (BYTE) MapVirtualKey (vk_code, 0),
2520                                  KEYEVENTF_EXTENDEDKEY | 0, 0);
2521                     keybd_event ((BYTE) vk_code,
2522                                  (BYTE) MapVirtualKey (vk_code, 0),
2523                                  KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
2524                     cur_state = !cur_state;
2525                   }
2526                 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
2527                                         cur_state, 0))
2528                   abort ();
2529               }
2530               break;
2531 #ifdef MSG_DEBUG
2532               /* Broadcast messages make it here, so you need to be looking
2533                  for something in particular for this to be useful.  */
2534             default:
2535               DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
2536 #endif
2537             }
2538         }
2539       else
2540         {
2541           DispatchMessage (&msg);
2542         }
2543 
2544       /* Exit nested loop when our deferred message has completed.  */
2545       if (msg_buf->completed)
2546         break;
2547     }
2548 }
2549 
2550 deferred_msg * deferred_msg_head;
2551 
2552 static deferred_msg *
2553 find_deferred_msg (HWND hwnd, UINT msg)
2554 {
2555   deferred_msg * item;
2556 
2557   /* Don't actually need synchronization for read access, since
2558      modification of single pointer is always atomic.  */
2559   /* enter_crit (); */
2560 
2561   for (item = deferred_msg_head; item != NULL; item = item->next)
2562     if (item->w32msg.msg.hwnd == hwnd
2563         && item->w32msg.msg.message == msg)
2564       break;
2565 
2566   /* leave_crit (); */
2567 
2568   return item;
2569 }
2570 
2571 static LRESULT
2572 send_deferred_msg (deferred_msg * msg_buf,
2573                    HWND hwnd,
2574                    UINT msg,
2575                    WPARAM wParam,
2576                    LPARAM lParam)
2577 {
2578   /* Only input thread can send deferred messages.  */
2579   if (GetCurrentThreadId () != dwWindowsThreadId)
2580     abort ();
2581 
2582   /* It is an error to send a message that is already deferred.  */
2583   if (find_deferred_msg (hwnd, msg) != NULL)
2584     abort ();
2585 
2586   /* Enforced synchronization is not needed because this is the only
2587      function that alters deferred_msg_head, and the following critical
2588      section is guaranteed to only be serially reentered (since only the
2589      input thread can call us).  */
2590 
2591   /* enter_crit (); */
2592 
2593   msg_buf->completed = 0;
2594   msg_buf->next = deferred_msg_head;
2595   deferred_msg_head = msg_buf;
2596   my_post_msg (&msg_buf->w32msg, hwnd, msg, wParam, lParam);
2597 
2598   /* leave_crit (); */
2599 
2600   /* Start a new nested message loop to process other messages until
2601      this one is completed.  */
2602   w32_msg_pump (msg_buf);
2603 
2604   deferred_msg_head = msg_buf->next;
2605 
2606   return msg_buf->result;
2607 }
2608 
2609 void
2610 complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result)
2611 {
2612   deferred_msg * msg_buf = find_deferred_msg (hwnd, msg);
2613 
2614   if (msg_buf == NULL)
2615     /* Message may have been cancelled, so don't abort.  */
2616     return;
2617 
2618   msg_buf->result = result;
2619   msg_buf->completed = 1;
2620 
2621   /* Ensure input thread is woken so it notices the completion.  */
2622   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
2623 }
2624 
2625 static void
2626 cancel_all_deferred_msgs ()
2627 {
2628   deferred_msg * item;
2629 
2630   /* Don't actually need synchronization for read access, since
2631      modification of single pointer is always atomic.  */
2632   /* enter_crit (); */
2633 
2634   for (item = deferred_msg_head; item != NULL; item = item->next)
2635     {
2636       item->result = 0;
2637       item->completed = 1;
2638     }
2639 
2640   /* leave_crit (); */
2641 
2642   /* Ensure input thread is woken so it notices the completion.  */
2643   PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
2644 }
2645 
2646 DWORD WINAPI
2647 w32_msg_worker (void *arg)
2648 {
2649   MSG msg;
2650   deferred_msg dummy_buf;
2651 
2652   /* Ensure our message queue is created */
2653 
2654   PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2655 
2656   if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2657     abort ();
2658 
2659   memset (&dummy_buf, 0, sizeof (dummy_buf));
2660   dummy_buf.w32msg.msg.hwnd = NULL;
2661   dummy_buf.w32msg.msg.message = WM_NULL;
2662 
2663   /* This is the initial message loop which should only exit when the
2664      application quits.  */
2665   w32_msg_pump (&dummy_buf);
2666 
2667   return 0;
2668 }
2669 
2670 static void
2671 signal_user_input ()
2672 {
2673   /* Interrupt any lisp that wants to be interrupted by input.  */
2674   if (!NILP (Vthrow_on_input))
2675     {
2676       Vquit_flag = Vthrow_on_input;
2677       /* If we're inside a function that wants immediate quits,
2678          do it now.  */
2679       if (immediate_quit && NILP (Vinhibit_quit))
2680         {
2681           immediate_quit = 0;
2682           QUIT;
2683         }
2684     }
2685 }
2686 
2687 
2688 static void
2689 post_character_message (hwnd, msg, wParam, lParam, modifiers)
2690      HWND hwnd;
2691      UINT msg;
2692      WPARAM wParam;
2693      LPARAM lParam;
2694      DWORD  modifiers;
2695 
2696 {
2697   W32Msg wmsg;
2698 
2699   wmsg.dwModifiers = modifiers;
2700 
2701   /* Detect quit_char and set quit-flag directly.  Note that we
2702      still need to post a message to ensure the main thread will be
2703      woken up if blocked in sys_select, but we do NOT want to post
2704      the quit_char message itself (because it will usually be as if
2705      the user had typed quit_char twice).  Instead, we post a dummy
2706      message that has no particular effect. */
2707   {
2708     int c = wParam;
2709     if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier)
2710       c = make_ctrl_char (c) & 0377;
2711     if (c == quit_char
2712         || (wmsg.dwModifiers == 0 &&
2713             w32_quit_key && wParam == w32_quit_key))
2714       {
2715         Vquit_flag = Qt;
2716 
2717         /* The choice of message is somewhat arbitrary, as long as
2718            the main thread handler just ignores it. */
2719         msg = WM_NULL;
2720 
2721         /* Interrupt any blocking system calls.  */
2722         signal_quit ();
2723 
2724         /* As a safety precaution, forcibly complete any deferred
2725            messages.  This is a kludge, but I don't see any particularly
2726            clean way to handle the situation where a deferred message is
2727            "dropped" in the lisp thread, and will thus never be
2728            completed, eg. by the user trying to activate the menubar
2729            when the lisp thread is busy, and then typing C-g when the
2730            menubar doesn't open promptly (with the result that the
2731            menubar never responds at all because the deferred
2732            WM_INITMENU message is never completed).  Another problem
2733            situation is when the lisp thread calls SendMessage (to send
2734            a window manager command) when a message has been deferred;
2735            the lisp thread gets blocked indefinitely waiting for the
2736            deferred message to be completed, which itself is waiting for
2737            the lisp thread to respond.
2738 
2739            Note that we don't want to block the input thread waiting for
2740            a reponse from the lisp thread (although that would at least
2741            solve the deadlock problem above), because we want to be able
2742            to receive C-g to interrupt the lisp thread.  */
2743         cancel_all_deferred_msgs ();
2744       }
2745     else
2746       signal_user_input ();
2747   }
2748 
2749   my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2750 }
2751 
2752 /* Main window procedure */
2753 
2754 LRESULT CALLBACK
2755 w32_wnd_proc (hwnd, msg, wParam, lParam)
2756      HWND hwnd;
2757      UINT msg;
2758      WPARAM wParam;
2759      LPARAM lParam;
2760 {
2761   struct frame *f;
2762   struct w32_display_info *dpyinfo = &one_w32_display_info;
2763   W32Msg wmsg;
2764   int windows_translate;
2765   int key;
2766 
2767   /* Note that it is okay to call x_window_to_frame, even though we are
2768      not running in the main lisp thread, because frame deletion
2769      requires the lisp thread to synchronize with this thread.  Thus, if
2770      a frame struct is returned, it can be used without concern that the
2771      lisp thread might make it disappear while we are using it.
2772 
2773      NB. Walking the frame list in this thread is safe (as long as
2774      writes of Lisp_Object slots are atomic, which they are on Windows).
2775      Although delete-frame can destructively modify the frame list while
2776      we are walking it, a garbage collection cannot occur until after
2777      delete-frame has synchronized with this thread.
2778 
2779      It is also safe to use functions that make GDI calls, such as
2780      w32_clear_rect, because these functions must obtain a DC handle
2781      from the frame struct using get_frame_dc which is thread-aware.  */
2782 
2783   switch (msg)
2784     {
2785     case WM_ERASEBKGND:
2786       f = x_window_to_frame (dpyinfo, hwnd);
2787       if (f)
2788         {
2789           HDC hdc = get_frame_dc (f);
2790           GetUpdateRect (hwnd, &wmsg.rect, FALSE);
2791           w32_clear_rect (f, hdc, &wmsg.rect);
2792           release_frame_dc (f, hdc);
2793 
2794 #if defined (W32_DEBUG_DISPLAY)
2795           DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
2796                      f,
2797                      wmsg.rect.left, wmsg.rect.top,
2798                      wmsg.rect.right, wmsg.rect.bottom));
2799 #endif /* W32_DEBUG_DISPLAY */
2800         }
2801       return 1;
2802     case WM_PALETTECHANGED:
2803       /* ignore our own changes */
2804       if ((HWND)wParam != hwnd)
2805         {
2806           f = x_window_to_frame (dpyinfo, hwnd);
2807           if (f)
2808             /* get_frame_dc will realize our palette and force all
2809                frames to be redrawn if needed. */
2810             release_frame_dc (f, get_frame_dc (f));
2811         }
2812       return 0;
2813     case WM_PAINT:
2814       {
2815         PAINTSTRUCT paintStruct;
2816         RECT update_rect;
2817         bzero (&update_rect, sizeof (update_rect));
2818 
2819         f = x_window_to_frame (dpyinfo, hwnd);
2820         if (f == 0)
2821           {
2822             DebPrint (("WM_PAINT received for unknown window %p\n", hwnd));
2823             return 0;
2824           }
2825 
2826         /* MSDN Docs say not to call BeginPaint if GetUpdateRect
2827            fails.  Apparently this can happen under some
2828            circumstances.  */
2829         if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
2830           {
2831             enter_crit ();
2832             BeginPaint (hwnd, &paintStruct);
2833 
2834             /* The rectangles returned by GetUpdateRect and BeginPaint
2835                do not always match.  Play it safe by assuming both areas
2836                are invalid.  */
2837             UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint));
2838 
2839 #if defined (W32_DEBUG_DISPLAY)
2840             DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
2841                        f,
2842                        wmsg.rect.left, wmsg.rect.top,
2843                        wmsg.rect.right, wmsg.rect.bottom));
2844             DebPrint (("  [update region is %d,%d-%d,%d]\n",
2845                        update_rect.left, update_rect.top,
2846                        update_rect.right, update_rect.bottom));
2847 #endif
2848             EndPaint (hwnd, &paintStruct);
2849             leave_crit ();
2850 
2851             /* Change the message type to prevent Windows from
2852                combining WM_PAINT messages in the Lisp thread's queue,
2853                since Windows assumes that each message queue is
2854                dedicated to one frame and does not bother checking
2855                that hwnd matches before combining them.  */
2856             my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
2857 
2858             return 0;
2859           }
2860 
2861         /* If GetUpdateRect returns 0 (meaning there is no update
2862            region), assume the whole window needs to be repainted.  */
2863         GetClientRect (hwnd, &wmsg.rect);
2864         my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2865         return 0;
2866       }
2867 
2868     case WM_INPUTLANGCHANGE:
2869       /* Inform lisp thread of keyboard layout changes.  */
2870       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2871 
2872       /* Clear dead keys in the keyboard state; for simplicity only
2873          preserve modifier key states.  */
2874       {
2875         int i;
2876         BYTE keystate[256];
2877 
2878         GetKeyboardState (keystate);
2879         for (i = 0; i < 256; i++)
2880           if (1
2881               && i != VK_SHIFT
2882               && i != VK_LSHIFT
2883               && i != VK_RSHIFT
2884               && i != VK_CAPITAL
2885               && i != VK_NUMLOCK
2886               && i != VK_SCROLL
2887               && i != VK_CONTROL
2888               && i != VK_LCONTROL
2889               && i != VK_RCONTROL
2890               && i != VK_MENU
2891               && i != VK_LMENU
2892               && i != VK_RMENU
2893               && i != VK_LWIN
2894               && i != VK_RWIN)
2895             keystate[i] = 0;
2896         SetKeyboardState (keystate);
2897       }
2898       goto dflt;
2899 
2900     case WM_HOTKEY:
2901       /* Synchronize hot keys with normal input.  */
2902       PostMessage (hwnd, WM_KEYDOWN, HIWORD (lParam), 0);
2903       return (0);
2904 
2905     case WM_KEYUP:
2906     case WM_SYSKEYUP:
2907       record_keyup (wParam, lParam);
2908       goto dflt;
2909 
2910     case WM_KEYDOWN:
2911     case WM_SYSKEYDOWN:
2912       /* Ignore keystrokes we fake ourself; see below.  */
2913       if (dpyinfo->faked_key == wParam)
2914         {
2915           dpyinfo->faked_key = 0;
2916           /* Make sure TranslateMessage sees them though (as long as
2917              they don't produce WM_CHAR messages).  This ensures that
2918              indicator lights are toggled promptly on Windows 9x, for
2919              example.  */
2920           if (wParam < 256 && lispy_function_keys[wParam])
2921             {
2922               windows_translate = 1;
2923               goto translate;
2924             }
2925           return 0;
2926         }
2927 
2928       /* Synchronize modifiers with current keystroke.  */
2929       sync_modifiers ();
2930       record_keydown (wParam, lParam);
2931       wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
2932 
2933       windows_translate = 0;
2934 
2935       switch (wParam)
2936         {
2937         case VK_LWIN:
2938           if (NILP (Vw32_pass_lwindow_to_system))
2939             {
2940               /* Prevent system from acting on keyup (which opens the
2941                  Start menu if no other key was pressed) by simulating a
2942                  press of Space which we will ignore.  */
2943               if (GetAsyncKeyState (wParam) & 1)
2944                 {
2945                   if (NUMBERP (Vw32_phantom_key_code))
2946                     key = XUINT (Vw32_phantom_key_code) & 255;
2947                   else
2948                     key = VK_SPACE;
2949                   dpyinfo->faked_key = key;
2950                   keybd_event (key, (BYTE) MapVirtualKey (key, 0), 0, 0);
2951                 }
2952             }
2953           if (!NILP (Vw32_lwindow_modifier))
2954             return 0;
2955           break;
2956         case VK_RWIN:
2957           if (NILP (Vw32_pass_rwindow_to_system))
2958             {
2959               if (GetAsyncKeyState (wParam) & 1)
2960                 {
2961                   if (NUMBERP (Vw32_phantom_key_code))
2962                     key = XUINT (Vw32_phantom_key_code) & 255;
2963                   else
2964                     key = VK_SPACE;
2965                   dpyinfo->faked_key = key;
2966                   keybd_event (key, (BYTE) MapVirtualKey (key, 0), 0, 0);
2967                 }
2968             }
2969           if (!NILP (Vw32_rwindow_modifier))
2970             return 0;
2971           break;
2972         case VK_APPS:
2973           if (!NILP (Vw32_apps_modifier))
2974             return 0;
2975           break;
2976         case VK_MENU:
2977           if (NILP (Vw32_pass_alt_to_system))
2978             /* Prevent DefWindowProc from activating the menu bar if an
2979                Alt key is pressed and released by itself.  */
2980             return 0;
2981           windows_translate = 1;
2982           break;
2983         case VK_CAPITAL:
2984           /* Decide whether to treat as modifier or function key.  */
2985           if (NILP (Vw32_enable_caps_lock))
2986             goto disable_lock_key;
2987           windows_translate = 1;
2988           break;
2989         case VK_NUMLOCK:
2990           /* Decide whether to treat as modifier or function key.  */
2991           if (NILP (Vw32_enable_num_lock))
2992             goto disable_lock_key;
2993           windows_translate = 1;
2994           break;
2995         case VK_SCROLL:
2996           /* Decide whether to treat as modifier or function key.  */
2997           if (NILP (Vw32_scroll_lock_modifier))
2998             goto disable_lock_key;
2999           windows_translate = 1;
3000           break;
3001         disable_lock_key:
3002           /* Ensure the appropriate lock key state (and indicator light)
3003              remains in the same state. We do this by faking another
3004              press of the relevant key.  Apparently, this really is the
3005              only way to toggle the state of the indicator lights.  */
3006           dpyinfo->faked_key = wParam;
3007           keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3008                        KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3009           keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3010                        KEYEVENTF_EXTENDEDKEY | 0, 0);
3011           keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3012                        KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3013           /* Ensure indicator lights are updated promptly on Windows 9x
3014              (TranslateMessage apparently does this), after forwarding
3015              input event.  */
3016           post_character_message (hwnd, msg, wParam, lParam,
3017                                   w32_get_key_modifiers (wParam, lParam));
3018           windows_translate = 1;
3019           break;
3020         case VK_CONTROL:
3021         case VK_SHIFT:
3022         case VK_PROCESSKEY:  /* Generated by IME.  */
3023           windows_translate = 1;
3024           break;
3025         case VK_CANCEL:
3026           /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
3027              which is confusing for purposes of key binding; convert
3028              VK_CANCEL events into VK_PAUSE events.  */
3029           wParam = VK_PAUSE;
3030           break;
3031         case VK_PAUSE:
3032           /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
3033              for purposes of key binding; convert these back into
3034              VK_NUMLOCK events, at least when we want to see NumLock key
3035              presses.  (Note that there is never any possibility that
3036              VK_PAUSE with Ctrl really is C-Pause as per above.)  */
3037           if (NILP (Vw32_enable_num_lock) && modifier_set (VK_CONTROL))
3038             wParam = VK_NUMLOCK;
3039           break;
3040         default:
3041           /* If not defined as a function key, change it to a WM_CHAR message. */
3042           if (wParam > 255 || !lispy_function_keys[wParam])
3043             {
3044               DWORD modifiers = construct_console_modifiers ();
3045 
3046               if (!NILP (Vw32_recognize_altgr)
3047                   && modifier_set (VK_LCONTROL) && modifier_set (VK_RMENU))
3048                 {
3049                   /* Always let TranslateMessage handle AltGr key chords;
3050                      for some reason, ToAscii doesn't always process AltGr
3051                      chords correctly.  */
3052                   windows_translate = 1;
3053                 }
3054               else if ((modifiers & (~SHIFT_PRESSED & ~CAPSLOCK_ON)) != 0)
3055                 {
3056                   /* Handle key chords including any modifiers other
3057                      than shift directly, in order to preserve as much
3058                      modifier information as possible.  */
3059                   if ('A' <= wParam && wParam <= 'Z')
3060                     {
3061                       /* Don't translate modified alphabetic keystrokes,
3062                          so the user doesn't need to constantly switch
3063                          layout to type control or meta keystrokes when
3064                          the normal layout translates alphabetic
3065                          characters to non-ascii characters.  */
3066                       if (!modifier_set (VK_SHIFT))
3067                         wParam += ('a' - 'A');
3068                       msg = WM_CHAR;
3069                     }
3070                   else
3071                     {
3072                       /* Try to handle other keystrokes by determining the
3073                          base character (ie. translating the base key plus
3074                          shift modifier).  */
3075                       int add;
3076                       int isdead = 0;
3077                       KEY_EVENT_RECORD key;
3078 
3079                       key.bKeyDown = TRUE;
3080                       key.wRepeatCount = 1;
3081                       key.wVirtualKeyCode = wParam;
3082                       key.wVirtualScanCode = (lParam & 0xFF0000) >> 16;
3083                       key.uChar.AsciiChar = 0;
3084                       key.dwControlKeyState = modifiers;
3085 
3086                       add = w32_kbd_patch_key (&key);
3087                       /* 0 means an unrecognised keycode, negative means
3088                          dead key.  Ignore both.  */
3089                       while (--add >= 0)
3090                         {
3091                           /* Forward asciified character sequence.  */
3092                           post_character_message
3093                             (hwnd, WM_CHAR,
3094                              (unsigned char) key.uChar.AsciiChar, lParam,
3095                              w32_get_key_modifiers (wParam, lParam));
3096                           w32_kbd_patch_key (&key);
3097                         }
3098                       return 0;
3099                     }
3100                 }
3101               else
3102                 {
3103                   /* Let TranslateMessage handle everything else.  */
3104                   windows_translate = 1;
3105                 }
3106             }
3107         }
3108 
3109     translate:
3110       if (windows_translate)
3111         {
3112           MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
3113           windows_msg.time = GetMessageTime ();
3114           TranslateMessage (&windows_msg);
3115           goto dflt;
3116         }
3117 
3118       /* Fall through */
3119 
3120     case WM_SYSCHAR:
3121     case WM_CHAR:
3122       post_character_message (hwnd, msg, wParam, lParam,
3123                               w32_get_key_modifiers (wParam, lParam));
3124       break;
3125 
3126     case WM_UNICHAR:
3127       /* WM_UNICHAR looks promising from the docs, but the exact
3128          circumstances in which TranslateMessage sends it is one of those
3129          Microsoft secret API things that EU and US courts are supposed
3130          to have put a stop to already. Spy++ shows it being sent to Notepad
3131          and other MS apps, but never to Emacs.
3132 
3133          Some third party IMEs send it in accordance with the official
3134          documentation though, so handle it here.
3135 
3136          UNICODE_NOCHAR is used to test for support for this message.
3137          TRUE indicates that the message is supported.  */
3138       if (wParam == UNICODE_NOCHAR)
3139         return TRUE;
3140 
3141       {
3142         W32Msg wmsg;
3143         wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3144         signal_user_input ();
3145         my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3146       }
3147       break;
3148 
3149     case WM_IME_CHAR:
3150       /* If we can't get the IME result as unicode, use default processing,
3151          which will at least allow characters decodable in the system locale
3152          get through.  */
3153       if (!get_composition_string_fn)
3154         goto dflt;
3155 
3156       else if (!ignore_ime_char)
3157         {
3158           wchar_t * buffer;
3159           int size, i;
3160           W32Msg wmsg;
3161           HIMC context = get_ime_context_fn (hwnd);
3162           wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3163           /* Get buffer size.  */
3164           size = get_composition_string_fn (context, GCS_RESULTSTR, buffer, 0);
3165           buffer = alloca(size);
3166           size = get_composition_string_fn (context, GCS_RESULTSTR,
3167                                             buffer, size);
3168           release_ime_context_fn (hwnd, context);
3169 
3170           signal_user_input ();
3171           for (i = 0; i < size / sizeof (wchar_t); i++)
3172             {
3173               my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
3174                            lParam);
3175             }
3176           /* Ignore the messages for the rest of the
3177              characters in the string that was output above.  */
3178           ignore_ime_char = (size / sizeof (wchar_t)) - 1;
3179         }
3180       else
3181         ignore_ime_char--;
3182 
3183       break;
3184 
3185     case WM_IME_STARTCOMPOSITION:
3186       if (!set_ime_composition_window_fn)
3187         goto dflt;
3188       else
3189         {
3190           COMPOSITIONFORM form;
3191           HIMC context;
3192           struct window *w;
3193 
3194           if (!context)
3195             break;
3196 
3197           f = x_window_to_frame (dpyinfo, hwnd);
3198           w = XWINDOW (FRAME_SELECTED_WINDOW (f));
3199 
3200           form.dwStyle = CFS_RECT;
3201           form.ptCurrentPos.x = w32_system_caret_x;
3202           form.ptCurrentPos.y = w32_system_caret_y;
3203 
3204           form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
3205           form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
3206                              + WINDOW_HEADER_LINE_HEIGHT (w));
3207           form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
3208                                - WINDOW_RIGHT_MARGIN_WIDTH (w)
3209                                - WINDOW_RIGHT_FRINGE_WIDTH (w));
3210           form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
3211                                 - WINDOW_MODE_LINE_HEIGHT (w));
3212 
3213           context = get_ime_context_fn (hwnd);
3214           set_ime_composition_window_fn (context, &form);
3215           release_ime_context_fn (hwnd, context);
3216         }
3217       break;
3218 
3219     case WM_IME_ENDCOMPOSITION:
3220       ignore_ime_char = 0;
3221       goto dflt;
3222 
3223       /* Simulate middle mouse button events when left and right buttons
3224          are used together, but only if user has two button mouse. */
3225     case WM_LBUTTONDOWN:
3226     case WM_RBUTTONDOWN:
3227       if (w32_num_mouse_buttons > 2)
3228         goto handle_plain_button;
3229 
3230       {
3231         int this = (msg == WM_LBUTTONDOWN) ? LMOUSE : RMOUSE;
3232         int other = (msg == WM_LBUTTONDOWN) ? RMOUSE : LMOUSE;
3233 
3234         if (button_state & this)
3235           return 0;
3236 
3237         if (button_state == 0)
3238           SetCapture (hwnd);
3239 
3240         button_state |= this;
3241 
3242         if (button_state & other)
3243           {
3244             if (mouse_button_timer)
3245               {
3246                 KillTimer (hwnd, mouse_button_timer);
3247                 mouse_button_timer = 0;
3248 
3249                 /* Generate middle mouse event instead. */
3250                 msg = WM_MBUTTONDOWN;
3251                 button_state |= MMOUSE;
3252               }
3253             else if (button_state & MMOUSE)
3254               {
3255                 /* Ignore button event if we've already generated a
3256                    middle mouse down event.  This happens if the
3257                    user releases and press one of the two buttons
3258                    after we've faked a middle mouse event. */
3259                 return 0;
3260               }
3261             else
3262               {
3263                 /* Flush out saved message. */
3264                 post_msg (&saved_mouse_button_msg);
3265               }
3266             wmsg.dwModifiers = w32_get_modifiers ();
3267             my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3268             signal_user_input ();
3269 
3270             /* Clear message buffer. */
3271             saved_mouse_button_msg.msg.hwnd = 0;
3272           }
3273         else
3274           {
3275             /* Hold onto message for now. */
3276             mouse_button_timer =
3277               SetTimer (hwnd, MOUSE_BUTTON_ID,
3278                         w32_mouse_button_tolerance, NULL);
3279             saved_mouse_button_msg.msg.hwnd = hwnd;
3280             saved_mouse_button_msg.msg.message = msg;
3281             saved_mouse_button_msg.msg.wParam = wParam;
3282             saved_mouse_button_msg.msg.lParam = lParam;
3283             saved_mouse_button_msg.msg.time = GetMessageTime ();
3284             saved_mouse_button_msg.dwModifiers = w32_get_modifiers ();
3285           }
3286       }
3287       return 0;
3288 
3289     case WM_LBUTTONUP:
3290     case WM_RBUTTONUP:
3291       if (w32_num_mouse_buttons > 2)
3292         goto handle_plain_button;
3293 
3294       {
3295         int this = (msg == WM_LBUTTONUP) ? LMOUSE : RMOUSE;
3296         int other = (msg == WM_LBUTTONUP) ? RMOUSE : LMOUSE;
3297 
3298         if ((button_state & this) == 0)
3299           return 0;
3300 
3301         button_state &= ~this;
3302 
3303         if (button_state & MMOUSE)
3304           {
3305             /* Only generate event when second button is released. */
3306             if ((button_state & other) == 0)
3307               {
3308                 msg = WM_MBUTTONUP;
3309                 button_state &= ~MMOUSE;
3310 
3311                 if (button_state) abort ();
3312               }
3313             else
3314               return 0;
3315           }
3316         else
3317           {
3318             /* Flush out saved message if necessary. */
3319             if (saved_mouse_button_msg.msg.hwnd)
3320               {
3321                 post_msg (&saved_mouse_button_msg);
3322               }
3323           }
3324         wmsg.dwModifiers = w32_get_modifiers ();
3325         my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3326         signal_user_input ();
3327 
3328         /* Always clear message buffer and cancel timer. */
3329         saved_mouse_button_msg.msg.hwnd = 0;
3330         KillTimer (hwnd, mouse_button_timer);
3331         mouse_button_timer = 0;
3332 
3333         if (button_state == 0)
3334           ReleaseCapture ();
3335       }
3336       return 0;
3337 
3338     case WM_XBUTTONDOWN:
3339     case WM_XBUTTONUP:
3340       if (w32_pass_extra_mouse_buttons_to_system)
3341         goto dflt;
3342       /* else fall through and process them.  */
3343     case WM_MBUTTONDOWN:
3344     case WM_MBUTTONUP:
3345     handle_plain_button:
3346       {
3347         BOOL up;
3348         int button;
3349 
3350         /* Ignore middle and extra buttons as long as the menu is active.  */
3351         f = x_window_to_frame (dpyinfo, hwnd);
3352         if (f && f->output_data.w32->menubar_active)
3353           return 0;
3354 
3355         if (parse_button (msg, HIWORD (wParam), &button, &up))
3356           {
3357             if (up) ReleaseCapture ();
3358             else SetCapture (hwnd);
3359             button = (button == 0) ? LMOUSE :
3360               ((button == 1) ? MMOUSE  : RMOUSE);
3361             if (up)
3362               button_state &= ~button;
3363             else
3364               button_state |= button;
3365           }
3366       }
3367 
3368       wmsg.dwModifiers = w32_get_modifiers ();
3369       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3370       signal_user_input ();
3371 
3372       /* Need to return true for XBUTTON messages, false for others,
3373          to indicate that we processed the message.  */
3374       return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
3375 
3376     case WM_MOUSEMOVE:
3377       /* Ignore mouse movements as long as the menu is active.  These
3378          movements are processed by the window manager anyway, and
3379          it's wrong to handle them as if they happened on the
3380          underlying frame.  */
3381       f = x_window_to_frame (dpyinfo, hwnd);
3382       if (f && f->output_data.w32->menubar_active)
3383         return 0;
3384 
3385       /* If the mouse has just moved into the frame, start tracking
3386          it, so we will be notified when it leaves the frame.  Mouse
3387          tracking only works under W98 and NT4 and later. On earlier
3388          versions, there is no way of telling when the mouse leaves the
3389          frame, so we just have to put up with help-echo and mouse
3390          highlighting remaining while the frame is not active.  */
3391       if (track_mouse_event_fn && !track_mouse_window)
3392         {
3393           TRACKMOUSEEVENT tme;
3394           tme.cbSize = sizeof (tme);
3395           tme.dwFlags = TME_LEAVE;
3396           tme.hwndTrack = hwnd;
3397 
3398           track_mouse_event_fn (&tme);
3399           track_mouse_window = hwnd;
3400         }
3401     case WM_VSCROLL:
3402       if (w32_mouse_move_interval <= 0
3403           || (msg == WM_MOUSEMOVE && button_state == 0))
3404         {
3405           wmsg.dwModifiers = w32_get_modifiers ();
3406           my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3407           return 0;
3408         }
3409 
3410       /* Hang onto mouse move and scroll messages for a bit, to avoid
3411          sending such events to Emacs faster than it can process them.
3412          If we get more events before the timer from the first message
3413          expires, we just replace the first message. */
3414 
3415       if (saved_mouse_move_msg.msg.hwnd == 0)
3416         mouse_move_timer =
3417           SetTimer (hwnd, MOUSE_MOVE_ID,
3418                     w32_mouse_move_interval, NULL);
3419 
3420       /* Hold onto message for now. */
3421       saved_mouse_move_msg.msg.hwnd = hwnd;
3422       saved_mouse_move_msg.msg.message = msg;
3423       saved_mouse_move_msg.msg.wParam = wParam;
3424       saved_mouse_move_msg.msg.lParam = lParam;
3425       saved_mouse_move_msg.msg.time = GetMessageTime ();
3426       saved_mouse_move_msg.dwModifiers = w32_get_modifiers ();
3427 
3428       return 0;
3429 
3430     case WM_MOUSEWHEEL:
3431     case WM_DROPFILES:
3432       wmsg.dwModifiers = w32_get_modifiers ();
3433       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3434       signal_user_input ();
3435       return 0;
3436 
3437     case WM_APPCOMMAND:
3438       if (w32_pass_multimedia_buttons_to_system)
3439         goto dflt;
3440       /* Otherwise, pass to lisp, the same way we do with mousehwheel.  */
3441     case WM_MOUSEHWHEEL:
3442       wmsg.dwModifiers = w32_get_modifiers ();
3443       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3444       signal_user_input ();
3445       /* Non-zero must be returned when WM_MOUSEHWHEEL messages are
3446          handled, to prevent the system trying to handle it by faking
3447          scroll bar events.  */
3448       return 1;
3449 
3450     case WM_TIMER:
3451       /* Flush out saved messages if necessary. */
3452       if (wParam == mouse_button_timer)
3453         {
3454           if (saved_mouse_button_msg.msg.hwnd)
3455             {
3456               post_msg (&saved_mouse_button_msg);
3457               signal_user_input ();
3458               saved_mouse_button_msg.msg.hwnd = 0;
3459             }
3460           KillTimer (hwnd, mouse_button_timer);
3461           mouse_button_timer = 0;
3462         }
3463       else if (wParam == mouse_move_timer)
3464         {
3465           if (saved_mouse_move_msg.msg.hwnd)
3466             {
3467               post_msg (&saved_mouse_move_msg);
3468               saved_mouse_move_msg.msg.hwnd = 0;
3469             }
3470           KillTimer (hwnd, mouse_move_timer);
3471           mouse_move_timer = 0;
3472         }
3473       else if (wParam == menu_free_timer)
3474         {
3475           KillTimer (hwnd, menu_free_timer);
3476           menu_free_timer = 0;
3477           f = x_window_to_frame (dpyinfo, hwnd);
3478           /* If a popup menu is active, don't wipe its strings.  */
3479           if (menubar_in_use
3480               && current_popup_menu == NULL)
3481             {
3482               /* Free memory used by owner-drawn and help-echo strings.  */
3483               w32_free_menu_strings (hwnd);
3484               f->output_data.w32->menubar_active = 0;
3485               menubar_in_use = 0;
3486             }
3487         }
3488       else if (wParam == hourglass_timer)
3489         {
3490           KillTimer (hwnd, hourglass_timer);
3491           hourglass_timer = 0;
3492           w32_show_hourglass (x_window_to_frame (dpyinfo, hwnd));
3493         }
3494       return 0;
3495 
3496     case WM_NCACTIVATE:
3497       /* Windows doesn't send us focus messages when putting up and
3498          taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
3499          The only indication we get that something happened is receiving
3500          this message afterwards.  So this is a good time to reset our
3501          keyboard modifiers' state. */
3502       reset_modifiers ();
3503       goto dflt;
3504 
3505     case WM_INITMENU:
3506       button_state = 0;
3507       ReleaseCapture ();
3508       /* We must ensure menu bar is fully constructed and up to date
3509          before allowing user interaction with it.  To achieve this
3510          we send this message to the lisp thread and wait for a
3511          reply (whose value is not actually needed) to indicate that
3512          the menu bar is now ready for use, so we can now return.
3513 
3514          To remain responsive in the meantime, we enter a nested message
3515          loop that can process all other messages.
3516 
3517          However, we skip all this if the message results from calling
3518          TrackPopupMenu - in fact, we must NOT attempt to send the lisp
3519          thread a message because it is blocked on us at this point.  We
3520          set menubar_active before calling TrackPopupMenu to indicate
3521          this (there is no possibility of confusion with real menubar
3522          being active).  */
3523 
3524       f = x_window_to_frame (dpyinfo, hwnd);
3525       if (f
3526           && (f->output_data.w32->menubar_active
3527               /* We can receive this message even in the absence of a
3528                  menubar (ie. when the system menu is activated) - in this
3529                  case we do NOT want to forward the message, otherwise it
3530                  will cause the menubar to suddenly appear when the user
3531                  had requested it to be turned off!  */
3532               || f->output_data.w32->menubar_widget == NULL))
3533         return 0;
3534 
3535       {
3536         deferred_msg msg_buf;
3537 
3538         /* Detect if message has already been deferred; in this case
3539            we cannot return any sensible value to ignore this.  */
3540         if (find_deferred_msg (hwnd, msg) != NULL)
3541           abort ();
3542 
3543         menubar_in_use = 1;
3544 
3545         return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam);
3546       }
3547 
3548     case WM_EXITMENULOOP:
3549       f = x_window_to_frame (dpyinfo, hwnd);
3550 
3551       /* If a menu is still active, check again after a short delay,
3552          since Windows often (always?) sends the WM_EXITMENULOOP
3553          before the corresponding WM_COMMAND message.
3554          Don't do this if a popup menu is active, since it is only
3555          menubar menus that require cleaning up in this way.
3556       */
3557       if (f && menubar_in_use && current_popup_menu == NULL)
3558         menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
3559 
3560       /* If hourglass cursor should be displayed, display it now.  */
3561       if (f && f->output_data.w32->hourglass_p)
3562         SetCursor (f->output_data.w32->hourglass_cursor);
3563 
3564       goto dflt;
3565 
3566     case WM_MENUSELECT:
3567       /* Direct handling of help_echo in menus.  Should be safe now
3568          that we generate the help_echo by placing a help event in the
3569          keyboard buffer.  */
3570       {
3571         HMENU menu = (HMENU) lParam;
3572         UINT menu_item = (UINT) LOWORD (wParam);
3573         UINT flags = (UINT) HIWORD (wParam);
3574 
3575         w32_menu_display_help (hwnd, menu, menu_item, flags);
3576       }
3577       return 0;
3578 
3579     case WM_MEASUREITEM:
3580       f = x_window_to_frame (dpyinfo, hwnd);
3581       if (f)
3582         {
3583           MEASUREITEMSTRUCT * pMis = (MEASUREITEMSTRUCT *) lParam;
3584 
3585           if (pMis->CtlType == ODT_MENU)
3586             {
3587               /* Work out dimensions for popup menu titles. */
3588               char * title = (char *) pMis->itemData;
3589               HDC hdc = GetDC (hwnd);
3590               HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
3591               LOGFONT menu_logfont;
3592               HFONT old_font;
3593               SIZE size;
3594 
3595               GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
3596               menu_logfont.lfWeight = FW_BOLD;
3597               menu_font = CreateFontIndirect (&menu_logfont);
3598               old_font = SelectObject (hdc, menu_font);
3599 
3600               pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
3601               if (title)
3602                 {
3603                   if (unicode_append_menu)
3604                     GetTextExtentPoint32W (hdc, (WCHAR *) title,
3605                                            wcslen ((WCHAR *) title),
3606                                            &size);
3607                   else
3608                     GetTextExtentPoint32 (hdc, title, strlen (title), &size);
3609 
3610                   pMis->itemWidth = size.cx;
3611                   if (pMis->itemHeight < size.cy)
3612                     pMis->itemHeight = size.cy;
3613                 }
3614               else
3615                 pMis->itemWidth = 0;
3616 
3617               SelectObject (hdc, old_font);
3618               DeleteObject (menu_font);
3619               ReleaseDC (hwnd, hdc);
3620               return TRUE;
3621             }
3622         }
3623       return 0;
3624 
3625     case WM_DRAWITEM:
3626       f = x_window_to_frame (dpyinfo, hwnd);
3627       if (f)
3628         {
3629           DRAWITEMSTRUCT * pDis = (DRAWITEMSTRUCT *) lParam;
3630 
3631           if (pDis->CtlType == ODT_MENU)
3632             {
3633               /* Draw popup menu title. */
3634               char * title = (char *) pDis->itemData;
3635               if (title)
3636                 {
3637                   HDC hdc = pDis->hDC;
3638                   HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
3639                   LOGFONT menu_logfont;
3640                   HFONT old_font;
3641 
3642                   GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
3643                   menu_logfont.lfWeight = FW_BOLD;
3644                   menu_font = CreateFontIndirect (&menu_logfont);
3645                   old_font = SelectObject (hdc, menu_font);
3646 
3647                   /* Always draw title as if not selected.  */
3648                   if (unicode_append_menu)
3649                     ExtTextOutW (hdc,
3650                                  pDis->rcItem.left
3651                                  + GetSystemMetrics (SM_CXMENUCHECK),
3652                                  pDis->rcItem.top,
3653                                  ETO_OPAQUE, &pDis->rcItem,
3654                                  (WCHAR *) title,
3655                                  wcslen ((WCHAR *) title), NULL);
3656                   else
3657                     ExtTextOut (hdc,
3658                                 pDis->rcItem.left
3659                                 + GetSystemMetrics (SM_CXMENUCHECK),
3660                                 pDis->rcItem.top,
3661                                 ETO_OPAQUE, &pDis->rcItem,
3662                                 title, strlen (title), NULL);
3663 
3664                   SelectObject (hdc, old_font);
3665                   DeleteObject (menu_font);
3666                 }
3667               return TRUE;
3668             }
3669         }
3670       return 0;
3671 
3672 #if 0
3673       /* Still not right - can't distinguish between clicks in the
3674          client area of the frame from clicks forwarded from the scroll
3675          bars - may have to hook WM_NCHITTEST to remember the mouse
3676          position and then check if it is in the client area ourselves.  */
3677     case WM_MOUSEACTIVATE:
3678       /* Discard the mouse click that activates a frame, allowing the
3679          user to click anywhere without changing point (or worse!).
3680          Don't eat mouse clicks on scrollbars though!!  */
3681       if (LOWORD (lParam) == HTCLIENT )
3682         return MA_ACTIVATEANDEAT;
3683       goto dflt;
3684 #endif
3685 
3686     case WM_MOUSELEAVE:
3687       /* No longer tracking mouse.  */
3688       track_mouse_window = NULL;
3689 
3690     case WM_ACTIVATEAPP:
3691     case WM_ACTIVATE:
3692     case WM_WINDOWPOSCHANGED:
3693     case WM_SHOWWINDOW:
3694       /* Inform lisp thread that a frame might have just been obscured
3695          or exposed, so should recheck visibility of all frames.  */
3696       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3697       goto dflt;
3698 
3699     case WM_SETFOCUS:
3700       dpyinfo->faked_key = 0;
3701       reset_modifiers ();
3702       register_hot_keys (hwnd);
3703       goto command;
3704     case WM_KILLFOCUS:
3705       unregister_hot_keys (hwnd);
3706       button_state = 0;
3707       ReleaseCapture ();
3708       /* Relinquish the system caret.  */
3709       if (w32_system_caret_hwnd)
3710         {
3711           w32_visible_system_caret_hwnd = NULL;
3712           w32_system_caret_hwnd = NULL;
3713           DestroyCaret ();
3714         }
3715       goto command;
3716     case WM_COMMAND:
3717       menubar_in_use = 0;
3718       f = x_window_to_frame (dpyinfo, hwnd);
3719       if (f && HIWORD (wParam) == 0)
3720         {
3721           if (menu_free_timer)
3722             {
3723               KillTimer (hwnd, menu_free_timer);
3724               menu_free_timer = 0;
3725             }
3726         }
3727     case WM_MOVE:
3728     case WM_SIZE:
3729     command:
3730       wmsg.dwModifiers = w32_get_modifiers ();
3731       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3732       goto dflt;
3733 
3734     case WM_DESTROY:
3735       CoUninitialize ();
3736       return 0;
3737 
3738     case WM_CLOSE:
3739       wmsg.dwModifiers = w32_get_modifiers ();
3740       my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3741       return 0;
3742 
3743     case WM_WINDOWPOSCHANGING:
3744       /* Don't restrict the sizing of tip frames.  */
3745       if (hwnd == tip_window)
3746         return 0;
3747       {
3748         WINDOWPLACEMENT wp;
3749         LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
3750 
3751         wp.length = sizeof (WINDOWPLACEMENT);
3752         GetWindowPlacement (hwnd, &wp);
3753 
3754         if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0)
3755           {
3756             RECT rect;
3757             int wdiff;
3758             int hdiff;
3759             DWORD font_width;
3760             DWORD line_height;
3761             DWORD internal_border;
3762             DWORD scrollbar_extra;
3763             RECT wr;
3764 
3765             wp.length = sizeof (wp);
3766             GetWindowRect (hwnd, &wr);
3767 
3768             enter_crit ();
3769 
3770             font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
3771             line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
3772             internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
3773             scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX);
3774 
3775             leave_crit ();
3776 
3777             memset (&rect, 0, sizeof (rect));
3778             AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
3779                               GetMenu (hwnd) != NULL);
3780 
3781             /* Force width and height of client area to be exact
3782                multiples of the character cell dimensions.  */
3783             wdiff = (lppos->cx - (rect.right - rect.left)
3784                      - 2 * internal_border - scrollbar_extra)
3785               % font_width;
3786             hdiff = (lppos->cy - (rect.bottom - rect.top)
3787                      - 2 * internal_border)
3788               % line_height;
3789 
3790             if (wdiff || hdiff)
3791               {
3792                 /* For right/bottom sizing we can just fix the sizes.
3793                    However for top/left sizing we will need to fix the X
3794                    and Y positions as well.  */
3795 
3796                 int cx_mintrack = GetSystemMetrics (SM_CXMINTRACK);
3797                 int cy_mintrack = GetSystemMetrics (SM_CYMINTRACK);
3798 
3799                 lppos->cx = max (lppos->cx - wdiff, cx_mintrack);
3800                 lppos->cy = max (lppos->cy - hdiff, cy_mintrack);
3801 
3802                 if (wp.showCmd != SW_SHOWMAXIMIZED
3803                     && (lppos->flags & SWP_NOMOVE) == 0)
3804                   {
3805                     if (lppos->x != wr.left || lppos->y != wr.top)
3806                       {
3807                         lppos->x += wdiff;
3808                         lppos->y += hdiff;
3809                       }
3810                     else
3811                       {
3812                         lppos->flags |= SWP_NOMOVE;
3813                       }
3814                   }
3815 
3816                 return 0;
3817               }
3818           }
3819       }
3820 
3821       goto dflt;
3822 
3823     case WM_GETMINMAXINFO:
3824       /* Hack to allow resizing the Emacs frame above the screen size.
3825          Note that Windows 9x limits coordinates to 16-bits.  */
3826       ((LPMINMAXINFO) lParam)->ptMaxTrackSize.x = 32767;
3827       ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;
3828       return 0;
3829 
3830     case WM_SETCURSOR:
3831       if (LOWORD (lParam) == HTCLIENT)
3832         {
3833           f = x_window_to_frame (dpyinfo, hwnd);
3834           if (f->output_data.w32->hourglass_p && !menubar_in_use
3835               && !current_popup_menu)
3836             SetCursor (f->output_data.w32->hourglass_cursor);
3837           else
3838             SetCursor (f->output_data.w32->current_cursor);
3839           return 0;
3840         }
3841       goto dflt;
3842 
3843     case WM_EMACS_SETCURSOR:
3844       {
3845         Cursor cursor = (Cursor) wParam;
3846         f = x_window_to_frame (dpyinfo, hwnd);
3847         if (f && cursor)
3848           {
3849             f->output_data.w32->current_cursor = cursor;
3850             if (!f->output_data.w32->hourglass_p)
3851               SetCursor (cursor);
3852           }
3853         return 0;
3854       }
3855 
3856     case WM_EMACS_CREATESCROLLBAR:
3857       return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
3858                                             (struct scroll_bar *) lParam);
3859 
3860     case WM_EMACS_SHOWWINDOW:
3861       return ShowWindow ((HWND) wParam, (WPARAM) lParam);
3862 
3863     case WM_EMACS_SETFOREGROUND:
3864       {
3865         HWND foreground_window;
3866         DWORD foreground_thread, retval;
3867 
3868         /* On NT 5.0, and apparently Windows 98, it is necessary to
3869            attach to the thread that currently has focus in order to
3870            pull the focus away from it.  */
3871         foreground_window = GetForegroundWindow ();
3872         foreground_thread = GetWindowThreadProcessId (foreground_window, NULL);
3873         if (!foreground_window
3874             || foreground_thread == GetCurrentThreadId ()
3875             || !AttachThreadInput (GetCurrentThreadId (),
3876                                    foreground_thread, TRUE))
3877           foreground_thread = 0;
3878 
3879         retval = SetForegroundWindow ((HWND) wParam);
3880 
3881         /* Detach from the previous foreground thread.  */
3882         if (foreground_thread)
3883           AttachThreadInput (GetCurrentThreadId (),
3884                              foreground_thread, FALSE);
3885 
3886         return retval;
3887       }
3888 
3889     case WM_EMACS_SETWINDOWPOS:
3890       {
3891         WINDOWPOS * pos = (WINDOWPOS *) wParam;
3892         return SetWindowPos (hwnd, pos->hwndInsertAfter,
3893                              pos->x, pos->y, pos->cx, pos->cy, pos->flags);
3894       }
3895 
3896     case WM_EMACS_DESTROYWINDOW:
3897       DragAcceptFiles ((HWND) wParam, FALSE);
3898       return DestroyWindow ((HWND) wParam);
3899 
3900     case WM_EMACS_HIDE_CARET:
3901       return HideCaret (hwnd);
3902 
3903     case WM_EMACS_SHOW_CARET:
3904       return ShowCaret (hwnd);
3905 
3906     case WM_EMACS_DESTROY_CARET:
3907       w32_system_caret_hwnd = NULL;
3908       w32_visible_system_caret_hwnd = NULL;
3909       return DestroyCaret ();
3910 
3911     case WM_EMACS_TRACK_CARET:
3912       /* If there is currently no system caret, create one.  */
3913       if (w32_system_caret_hwnd == NULL)
3914         {
3915           /* Use the default caret width, and avoid changing it
3916              unneccesarily, as it confuses screen reader software.  */
3917           w32_system_caret_hwnd = hwnd;
3918           CreateCaret (hwnd, NULL, 0,
3919                        w32_system_caret_height);
3920         }
3921 
3922       if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y))
3923         return 0;
3924       /* Ensure visible caret gets turned on when requested.  */
3925       else if (w32_use_visible_system_caret
3926                && w32_visible_system_caret_hwnd != hwnd)
3927         {
3928           w32_visible_system_caret_hwnd = hwnd;
3929           return ShowCaret (hwnd);
3930         }
3931       /* Ensure visible caret gets turned off when requested.  */
3932       else if (!w32_use_visible_system_caret
3933                && w32_visible_system_caret_hwnd)
3934         {
3935           w32_visible_system_caret_hwnd = NULL;
3936           return HideCaret (hwnd);
3937         }
3938       else
3939         return 1;
3940 
3941     case WM_EMACS_TRACKPOPUPMENU:
3942       {
3943         UINT flags;
3944         POINT *pos;
3945         int retval;
3946         pos = (POINT *)lParam;
3947         flags = TPM_CENTERALIGN;
3948         if (button_state & LMOUSE)
3949           flags |= TPM_LEFTBUTTON;
3950         else if (button_state & RMOUSE)
3951           flags |= TPM_RIGHTBUTTON;
3952 
3953         /* Remember we did a SetCapture on the initial mouse down event,
3954            so for safety, we make sure the capture is cancelled now.  */
3955         ReleaseCapture ();
3956         button_state = 0;
3957 
3958         /* Use menubar_active to indicate that WM_INITMENU is from
3959            TrackPopupMenu below, and should be ignored.  */
3960         f = x_window_to_frame (dpyinfo, hwnd);
3961         if (f)
3962           f->output_data.w32->menubar_active = 1;
3963 
3964         if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y,
3965                             0, hwnd, NULL))
3966           {
3967             MSG amsg;
3968             /* Eat any mouse messages during popupmenu */
3969             while (PeekMessage (&amsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST,
3970                                 PM_REMOVE));
3971             /* Get the menu selection, if any */
3972             if (PeekMessage (&amsg, hwnd, WM_COMMAND, WM_COMMAND, PM_REMOVE))
3973               {
3974                 retval =  LOWORD (amsg.wParam);
3975               }
3976             else
3977               {
3978                 retval = 0;
3979               }
3980           }
3981         else
3982           {
3983             retval = -1;
3984           }
3985 
3986         return retval;
3987       }
3988 
3989     default:
3990       /* Check for messages registered at runtime. */
3991       if (msg == msh_mousewheel)
3992         {
3993           wmsg.dwModifiers = w32_get_modifiers ();
3994           my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3995           signal_user_input ();
3996           return 0;
3997         }
3998 
3999     dflt:
4000       return DefWindowProc (hwnd, msg, wParam, lParam);
4001     }
4002 
4003 
4004   /* The most common default return code for handled messages is 0.  */
4005   return 0;
4006 }
4007 
4008 static void
4009 my_create_window (f)
4010      struct frame * f;
4011 {
4012   MSG msg;
4013 
4014   if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0))
4015     abort ();
4016   GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
4017 }
4018 
4019 
4020 /* Create a tooltip window. Unlike my_create_window, we do not do this
4021    indirectly via the Window thread, as we do not need to process Window
4022    messages for the tooltip.  Creating tooltips indirectly also creates
4023    deadlocks when tooltips are created for menu items.  */
4024 static void
4025 my_create_tip_window (f)
4026      struct frame *f;
4027 {
4028   RECT rect;
4029 
4030   rect.left = rect.top = 0;
4031   rect.right = FRAME_PIXEL_WIDTH (f);
4032   rect.bottom = FRAME_PIXEL_HEIGHT (f);
4033 
4034   AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
4035                     FRAME_EXTERNAL_MENU_BAR (f));
4036 
4037   tip_window = FRAME_W32_WINDOW (f)
4038     = CreateWindow (EMACS_CLASS,
4039                     f->namebuf,
4040                     f->output_data.w32->dwStyle,
4041                     f->left_pos,
4042                     f->top_pos,
4043                     rect.right - rect.left,
4044                     rect.bottom - rect.top,
4045                     FRAME_W32_WINDOW (SELECTED_FRAME ()), /* owner */
4046                     NULL,
4047                     hinst,
4048                     NULL);
4049 
4050   if (tip_window)
4051     {
4052       SetWindowLong (tip_window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
4053       SetWindowLong (tip_window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
4054       SetWindowLong (tip_window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
4055       SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
4056 
4057       /* Tip frames have no scrollbars.  */
4058       SetWindowLong (tip_window, WND_SCROLLBAR_INDEX, 0);
4059 
4060       /* Do this to discard the default setting specified by our parent. */
4061       ShowWindow (tip_window, SW_HIDE);
4062     }
4063 }
4064 
4065 
4066 /* Create and set up the w32 window for frame F.  */
4067 
4068 static void
4069 w32_window (f, window_prompting, minibuffer_only)
4070      struct frame *f;
4071      long window_prompting;
4072      int minibuffer_only;
4073 {
4074   BLOCK_INPUT;
4075 
4076   /* Use the resource name as the top-level window name
4077      for looking up resources.  Make a non-Lisp copy
4078      for the window manager, so GC relocation won't bother it.
4079 
4080      Elsewhere we specify the window name for the window manager.  */
4081 
4082   {
4083     char *str = (char *) SDATA (Vx_resource_name);
4084     f->namebuf = (char *) xmalloc (strlen (str) + 1);
4085     strcpy (f->namebuf, str);
4086   }
4087 
4088   my_create_window (f);
4089 
4090   validate_x_resource_name ();
4091 
4092   /* x_set_name normally ignores requests to set the name if the
4093      requested name is the same as the current name.  This is the one
4094      place where that assumption isn't correct; f->name is set, but
4095      the server hasn't been told.  */
4096   {
4097     Lisp_Object name;
4098     int explicit = f->explicit_name;
4099 
4100     f->explicit_name = 0;
4101     name = f->name;
4102     f->name = Qnil;
4103     x_set_name (f, name, explicit);
4104   }
4105 
4106   UNBLOCK_INPUT;
4107 
4108   if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
4109     initialize_frame_menubar (f);
4110 
4111   if (FRAME_W32_WINDOW (f) == 0)
4112     error ("Unable to create window");
4113 }
4114 
4115 /* Handle the icon stuff for this window.  Perhaps later we might
4116    want an x_set_icon_position which can be called interactively as
4117    well.  */
4118 
4119 static void
4120 x_icon (f, parms)
4121      struct frame *f;
4122      Lisp_Object parms;
4123 {
4124   Lisp_Object icon_x, icon_y;
4125   struct w32_display_info *dpyinfo = &one_w32_display_info;
4126 
4127   /* Set the position of the icon.  Note that Windows 95 groups all
4128      icons in the tray.  */
4129   icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
4130   icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
4131   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
4132     {
4133       CHECK_NUMBER (icon_x);
4134       CHECK_NUMBER (icon_y);
4135     }
4136   else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
4137     error ("Both left and top icon corners of icon must be specified");
4138 
4139   BLOCK_INPUT;
4140 
4141   if (! EQ (icon_x, Qunbound))
4142     x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
4143 
4144 #if 0 /* TODO */
4145   /* Start up iconic or window? */
4146   x_wm_set_window_state
4147     (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
4148          ? IconicState
4149          : NormalState));
4150 
4151   x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
4152                                      ? f->icon_name
4153                                      : f->name)));
4154 #endif
4155 
4156   UNBLOCK_INPUT;
4157 }
4158 
4159 
4160 static void
4161 x_make_gc (f)
4162      struct frame *f;
4163 {
4164   XGCValues gc_values;
4165 
4166   BLOCK_INPUT;
4167 
4168   /* Create the GC's of this frame.
4169      Note that many default values are used.  */
4170 
4171   /* Normal video */
4172   gc_values.font = FRAME_FONT (f);
4173 
4174   /* Cursor has cursor-color background, background-color foreground.  */
4175   gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
4176   gc_values.background = f->output_data.w32->cursor_pixel;
4177   f->output_data.w32->cursor_gc
4178     = XCreateGC (NULL, FRAME_W32_WINDOW (f),
4179                  (GCFont | GCForeground | GCBackground),
4180                  &gc_values);
4181 
4182   /* Reliefs.  */
4183   f->output_data.w32->white_relief.gc = 0;
4184   f->output_data.w32->black_relief.gc = 0;
4185 
4186   UNBLOCK_INPUT;
4187 }
4188 
4189 
4190 /* Handler for signals raised during x_create_frame and
4191    x_create_top_frame.  FRAME is the frame which is partially
4192    constructed.  */
4193 
4194 static Lisp_Object
4195 unwind_create_frame (frame)
4196      Lisp_Object frame;
4197 {
4198   struct frame *f = XFRAME (frame);
4199 
4200   /* If frame is ``official'', nothing to do.  */
4201   if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
4202     {
4203 #ifdef GLYPH_DEBUG
4204       struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4205 #endif
4206 
4207       x_free_frame_resources (f);
4208 
4209 #if GLYPH_DEBUG
4210       /* Check that reference counts are indeed correct.  */
4211       xassert (dpyinfo->reference_count == dpyinfo_refcount);
4212       xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
4213 #endif
4214       return Qt;
4215     }
4216 
4217   return Qnil;
4218 }
4219 
4220 static void
4221 x_default_font_parameter (f, parms)
4222      struct frame *f;
4223      Lisp_Object parms;
4224 {
4225   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4226   Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
4227                                 RES_TYPE_STRING);
4228   Lisp_Object font;
4229   if (EQ (font_param, Qunbound))
4230     font_param = Qnil;
4231   font = !NILP (font_param) ? font_param
4232     : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
4233 
4234   if (!STRINGP (font))
4235     {
4236       int i;
4237       static char *names[]
4238         = { "Courier New-10",
4239             "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
4240             "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
4241             "Fixedsys",
4242             NULL };
4243 
4244       for (i = 0; names[i]; i++)
4245         {
4246           font = font_open_by_name (f, names[i]);
4247           if (! NILP (font))
4248             break;
4249         }
4250       if (NILP (font))
4251         error ("No suitable font was found");
4252     }
4253   else if (!NILP (font_param))
4254     {
4255       /* Remember the explicit font parameter, so we can re-apply it after
4256          we've applied the `default' face settings.  */
4257       x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
4258     }
4259   x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
4260 }
4261 
4262 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
4263        1, 1, 0,
4264        doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
4265 Return an Emacs frame object.
4266 PARAMETERS is an alist of frame parameters.
4267 If the parameters specify that the frame should not have a minibuffer,
4268 and do not specify a specific minibuffer window to use,
4269 then `default-minibuffer-frame' must be a frame whose minibuffer can
4270 be shared by the new frame.
4271 
4272 This function is an internal primitive--use `make-frame' instead.  */)
4273   (parameters)
4274      Lisp_Object parameters;
4275 {
4276   struct frame *f;
4277   Lisp_Object frame, tem;
4278   Lisp_Object name;
4279   int minibuffer_only = 0;
4280   long window_prompting = 0;
4281   int width, height;
4282   int count = SPECPDL_INDEX ();
4283   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4284   Lisp_Object display;
4285   struct w32_display_info *dpyinfo = NULL;
4286   Lisp_Object parent;
4287   struct kboard *kb;
4288 
4289   /* Make copy of frame parameters because the original is in pure
4290      storage now. */
4291   parameters = Fcopy_alist (parameters);
4292 
4293   /* Use this general default value to start with
4294      until we know if this frame has a specified name.  */
4295   Vx_resource_name = Vinvocation_name;
4296 
4297   display = x_get_arg (dpyinfo, parameters, Qterminal, 0, 0, RES_TYPE_NUMBER);
4298   if (EQ (display, Qunbound))
4299     display = x_get_arg (dpyinfo, parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
4300   if (EQ (display, Qunbound))
4301     display = Qnil;
4302   dpyinfo = check_x_display_info (display);
4303   kb = dpyinfo->terminal->kboard;
4304 
4305   if (!dpyinfo->terminal->name)
4306     error ("Terminal is not live, can't create new frames on it");
4307 
4308   name = x_get_arg (dpyinfo, parameters, Qname, "name", "Name", RES_TYPE_STRING);
4309   if (!STRINGP (name)
4310       && ! EQ (name, Qunbound)
4311       && ! NILP (name))
4312     error ("Invalid frame name--not a string or nil");
4313 
4314   if (STRINGP (name))
4315     Vx_resource_name = name;
4316 
4317   /* See if parent window is specified.  */
4318   parent = x_get_arg (dpyinfo, parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
4319   if (EQ (parent, Qunbound))
4320     parent = Qnil;
4321   if (! NILP (parent))
4322     CHECK_NUMBER (parent);
4323 
4324   /* make_frame_without_minibuffer can run Lisp code and garbage collect.  */
4325   /* No need to protect DISPLAY because that's not used after passing
4326      it to make_frame_without_minibuffer.  */
4327   frame = Qnil;
4328   GCPRO4 (parameters, parent, name, frame);
4329   tem = x_get_arg (dpyinfo, parameters, Qminibuffer, "minibuffer", "Minibuffer",
4330                      RES_TYPE_SYMBOL);
4331   if (EQ (tem, Qnone) || NILP (tem))
4332     f = make_frame_without_minibuffer (Qnil, kb, display);
4333   else if (EQ (tem, Qonly))
4334     {
4335       f = make_minibuffer_frame ();
4336       minibuffer_only = 1;
4337     }
4338   else if (WINDOWP (tem))
4339     f = make_frame_without_minibuffer (tem, kb, display);
4340   else
4341     f = make_frame (1);
4342 
4343   XSETFRAME (frame, f);
4344 
4345   /* Note that Windows does support scroll bars.  */
4346   FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
4347 
4348   /* By default, make scrollbars the system standard width. */
4349   FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
4350 
4351   f->terminal = dpyinfo->terminal;
4352   f->terminal->reference_count++;
4353 
4354   f->output_method = output_w32;
4355   f->output_data.w32 =
4356     (struct w32_output *) xmalloc (sizeof (struct w32_output));
4357   bzero (f->output_data.w32, sizeof (struct w32_output));
4358   FRAME_FONTSET (f) = -1;
4359 
4360   f->icon_name
4361     = x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
4362                    RES_TYPE_STRING);
4363   if (! STRINGP (f->icon_name))
4364     f->icon_name = Qnil;
4365 
4366 /*  FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
4367 
4368   /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe.  */
4369   record_unwind_protect (unwind_create_frame, frame);
4370 #if GLYPH_DEBUG
4371   image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4372   dpyinfo_refcount = dpyinfo->reference_count;
4373 #endif /* GLYPH_DEBUG */
4374 
4375   /* Specify the parent under which to make this window.  */
4376 
4377   if (!NILP (parent))
4378     {
4379       f->output_data.w32->parent_desc = (Window) XFASTINT (parent);
4380       f->output_data.w32->explicit_parent = 1;
4381     }
4382   else
4383     {
4384       f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
4385       f->output_data.w32->explicit_parent = 0;
4386     }
4387 
4388   /* Set the name; the functions to which we pass f expect the name to
4389      be set.  */
4390   if (EQ (name, Qunbound) || NILP (name))
4391     {
4392       f->name = build_string (dpyinfo->w32_id_name);
4393       f->explicit_name = 0;
4394     }
4395   else
4396     {
4397       f->name = name;
4398       f->explicit_name = 1;
4399       /* use the frame's title when getting resources for this frame.  */
4400       specbind (Qx_resource_name, name);
4401     }
4402 
4403   f->resx = dpyinfo->resx;
4404   f->resy = dpyinfo->resy;
4405 
4406   if (uniscribe_available)
4407     register_font_driver (&uniscribe_font_driver, f);
4408   register_font_driver (&w32font_driver, f);
4409 
4410   x_default_parameter (f, parameters, Qfont_backend, Qnil,
4411                        "fontBackend", "FontBackend", RES_TYPE_STRING);
4412   /* Extract the window parameters from the supplied values
4413      that are needed to determine window geometry.  */
4414   x_default_font_parameter (f, parameters);
4415   x_default_parameter (f, parameters, Qborder_width, make_number (2),
4416                        "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4417 
4418   /* We recognize either internalBorderWidth or internalBorder
4419      (which is what xterm calls it).  */
4420   if (NILP (Fassq (Qinternal_border_width, parameters)))
4421     {
4422       Lisp_Object value;
4423 
4424       value = x_get_arg (dpyinfo, parameters, Qinternal_border_width,
4425                            "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
4426       if (! EQ (value, Qunbound))
4427         parameters = Fcons (Fcons (Qinternal_border_width, value),
4428                             parameters);
4429     }
4430   /* Default internalBorderWidth to 0 on Windows to match other programs.  */
4431   x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
4432                        "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
4433   x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
4434                        "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4435 
4436   /* Also do the stuff which must be set before the window exists.  */
4437   x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
4438                        "foreground", "Foreground", RES_TYPE_STRING);
4439   x_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
4440                        "background", "Background", RES_TYPE_STRING);
4441   x_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
4442                        "pointerColor", "Foreground", RES_TYPE_STRING);
4443   x_default_parameter (f, parameters, Qcursor_color, build_string ("black"),
4444                        "cursorColor", "Foreground", RES_TYPE_STRING);
4445   x_default_parameter (f, parameters, Qborder_color, build_string ("black"),
4446                        "borderColor", "BorderColor", RES_TYPE_STRING);
4447   x_default_parameter (f, parameters, Qscreen_gamma, Qnil,
4448                        "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
4449   x_default_parameter (f, parameters, Qline_spacing, Qnil,
4450                        "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
4451   x_default_parameter (f, parameters, Qleft_fringe, Qnil,
4452                        "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
4453   x_default_parameter (f, parameters, Qright_fringe, Qnil,
4454                        "rightFringe", "RightFringe", RES_TYPE_NUMBER);
4455 
4456 
4457   /* Init faces before x_default_parameter is called for scroll-bar
4458      parameters because that function calls x_set_scroll_bar_width,
4459      which calls change_frame_size, which calls Fset_window_buffer,
4460      which runs hooks, which call Fvertical_motion.  At the end, we
4461      end up in init_iterator with a null face cache, which should not
4462      happen.  */
4463   init_frame_faces (f);
4464 
4465   x_default_parameter (f, parameters, Qmenu_bar_lines, make_number (1),
4466                        "menuBar", "MenuBar", RES_TYPE_NUMBER);
4467   x_default_parameter (f, parameters, Qtool_bar_lines, make_number (1),
4468                        "toolBar", "ToolBar", RES_TYPE_NUMBER);
4469 
4470   x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
4471                        "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
4472   x_default_parameter (f, parameters, Qtitle, Qnil,
4473                        "title", "Title", RES_TYPE_STRING);
4474   x_default_parameter (f, parameters, Qfullscreen, Qnil,
4475                        "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4476 
4477   f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
4478   f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
4479 
4480   f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM);
4481   f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
4482   f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW);
4483   f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
4484   f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
4485   f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
4486 
4487   f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
4488 
4489   window_prompting = x_figure_window_size (f, parameters, 1);
4490 
4491   tem = x_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
4492   f->no_split = minibuffer_only || EQ (tem, Qt);
4493 
4494   w32_window (f, window_prompting, minibuffer_only);
4495   x_icon (f, parameters);
4496 
4497   x_make_gc (f);
4498 
4499   /* Now consider the frame official.  */
4500   FRAME_W32_DISPLAY_INFO (f)->reference_count++;
4501   Vframe_list = Fcons (frame, Vframe_list);
4502 
4503   /* We need to do this after creating the window, so that the
4504      icon-creation functions can say whose icon they're describing.  */
4505   x_default_parameter (f, parameters, Qicon_type, Qnil,
4506                        "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
4507 
4508   x_default_parameter (f, parameters, Qauto_raise, Qnil,
4509                        "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4510   x_default_parameter (f, parameters, Qauto_lower, Qnil,
4511                        "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4512   x_default_parameter (f, parameters, Qcursor_type, Qbox,
4513                        "cursorType", "CursorType", RES_TYPE_SYMBOL);
4514   x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
4515                        "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
4516   x_default_parameter (f, parameters, Qalpha, Qnil,
4517                        "alpha", "Alpha", RES_TYPE_NUMBER);
4518 
4519   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
4520      Change will not be effected unless different from the current
4521      FRAME_LINES (f).  */
4522   width = FRAME_COLS (f);
4523   height = FRAME_LINES (f);
4524 
4525   FRAME_LINES (f) = 0;
4526   SET_FRAME_COLS (f, 0);
4527   change_frame_size (f, height, width, 1, 0, 0);
4528 
4529   /* Tell the server what size and position, etc, we want, and how
4530      badly we want them.  This should be done after we have the menu
4531      bar so that its size can be taken into account.  */
4532   BLOCK_INPUT;
4533   x_wm_set_size_hint (f, window_prompting, 0);
4534   UNBLOCK_INPUT;
4535 
4536   /* Make the window appear on the frame and enable display, unless
4537      the caller says not to.  However, with explicit parent, Emacs
4538      cannot control visibility, so don't try.  */
4539   if (! f->output_data.w32->explicit_parent)
4540     {
4541       Lisp_Object visibility;
4542 
4543       visibility = x_get_arg (dpyinfo, parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
4544       if (EQ (visibility, Qunbound))
4545         visibility = Qt;
4546 
4547       if (EQ (visibility, Qicon))
4548         x_iconify_frame (f);
4549       else if (! NILP (visibility))
4550         x_make_frame_visible (f);
4551       else
4552         /* Must have been Qnil.  */
4553         ;
4554     }
4555 
4556   /* Initialize `default-minibuffer-frame' in case this is the first
4557      frame on this terminal.  */
4558   if (FRAME_HAS_MINIBUF_P (f)
4559       && (!FRAMEP (kb->Vdefault_minibuffer_frame)
4560           || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
4561     kb->Vdefault_minibuffer_frame = frame;
4562 
4563   /* All remaining specified parameters, which have not been "used"
4564      by x_get_arg and friends, now go in the misc. alist of the frame.  */
4565   for (tem = parameters; CONSP (tem); tem = XCDR (tem))
4566     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
4567       f->param_alist = Fcons (XCAR (tem), f->param_alist);
4568 
4569   UNGCPRO;
4570 
4571   /* Make sure windows on this frame appear in calls to next-window
4572      and similar functions.  */
4573   Vwindow_list = Qnil;
4574 
4575   return unbind_to (count, frame);
4576 }
4577 
4578 /* FRAME is used only to get a handle on the X display.  We don't pass the
4579    display info directly because we're called from frame.c, which doesn't
4580    know about that structure.  */
4581 Lisp_Object
4582 x_get_focus_frame (frame)
4583      struct frame *frame;
4584 {
4585   struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (frame);
4586   Lisp_Object xfocus;
4587   if (! dpyinfo->w32_focus_frame)
4588     return Qnil;
4589 
4590   XSETFRAME (xfocus, dpyinfo->w32_focus_frame);
4591   return xfocus;
4592 }
4593 
4594 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
4595        doc: /* Give FRAME input focus, raising to foreground if necessary.  */)
4596   (frame)
4597      Lisp_Object frame;
4598 {
4599   x_focus_on_frame (check_x_frame (frame));
4600   return Qnil;
4601 }
4602 
4603 
4604 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
4605        doc: /* Internal function called by `color-defined-p', which see.  */)
4606   (color, frame)
4607      Lisp_Object color, frame;
4608 {
4609   XColor foo;
4610   FRAME_PTR f = check_x_frame (frame);
4611 
4612   CHECK_STRING (color);
4613 
4614   if (w32_defined_color (f, SDATA (color), &foo, 0))
4615     return Qt;
4616   else
4617     return Qnil;
4618 }
4619 
4620 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
4621        doc: /* Internal function called by `color-values', which see.  */)
4622   (color, frame)
4623      Lisp_Object color, frame;
4624 {
4625   XColor foo;
4626   FRAME_PTR f = check_x_frame (frame);
4627 
4628   CHECK_STRING (color);
4629 
4630   if (w32_defined_color (f, SDATA (color), &foo, 0))
4631     return list3 (make_number ((GetRValue (foo.pixel) << 8)
4632                                | GetRValue (foo.pixel)),
4633                   make_number ((GetGValue (foo.pixel) << 8)
4634                                | GetGValue (foo.pixel)),
4635                   make_number ((GetBValue (foo.pixel) << 8)
4636                                | GetBValue (foo.pixel)));
4637   else
4638     return Qnil;
4639 }
4640 
4641 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
4642        doc: /* Internal function called by `display-color-p', which see.  */)
4643   (display)
4644      Lisp_Object display;
4645 {
4646   struct w32_display_info *dpyinfo = check_x_display_info (display);
4647 
4648   if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 2)
4649     return Qnil;
4650 
4651   return Qt;
4652 }
4653 
4654 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
4655        Sx_display_grayscale_p, 0, 1, 0,
4656        doc: /* Return t if DISPLAY supports shades of gray.
4657 Note that color displays do support shades of gray.
4658 The optional argument DISPLAY specifies which display to ask about.
4659 DISPLAY should be either a frame or a display name (a string).
4660 If omitted or nil, that stands for the selected frame's display.  */)
4661   (display)
4662      Lisp_Object display;
4663 {
4664   struct w32_display_info *dpyinfo = check_x_display_info (display);
4665 
4666   if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 1)
4667     return Qnil;
4668 
4669   return Qt;
4670 }
4671 
4672 DEFUN ("x-display-pixel-width", Fx_display_pixel_width,
4673        Sx_display_pixel_width, 0, 1, 0,
4674        doc: /* Return the width in pixels of DISPLAY.
4675 The optional argument DISPLAY specifies which display to ask about.
4676 DISPLAY should be either a frame or a display name (a string).
4677 If omitted or nil, that stands for the selected frame's display.  */)
4678   (display)
4679      Lisp_Object display;
4680 {
4681   struct w32_display_info *dpyinfo = check_x_display_info (display);
4682 
4683   return make_number (x_display_pixel_width (dpyinfo));
4684 }
4685 
4686 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
4687        Sx_display_pixel_height, 0, 1, 0,
4688        doc: /* Return the height in pixels of DISPLAY.
4689 The optional argument DISPLAY specifies which display to ask about.
4690 DISPLAY should be either a frame or a display name (a string).
4691 If omitted or nil, that stands for the selected frame's display.  */)
4692   (display)
4693      Lisp_Object display;
4694 {
4695   struct w32_display_info *dpyinfo = check_x_display_info (display);
4696 
4697   return make_number (x_display_pixel_height (dpyinfo));
4698 }
4699 
4700 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
4701        0, 1, 0,
4702        doc: /* Return the number of bitplanes of DISPLAY.
4703 The optional argument DISPLAY specifies which display to ask about.
4704 DISPLAY should be either a frame or a display name (a string).
4705 If omitted or nil, that stands for the selected frame's display.  */)
4706   (display)
4707      Lisp_Object display;
4708 {
4709   struct w32_display_info *dpyinfo = check_x_display_info (display);
4710 
4711   return make_number (dpyinfo->n_planes * dpyinfo->n_cbits);
4712 }
4713 
4714 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
4715        0, 1, 0,
4716        doc: /* Return the number of color cells of DISPLAY.
4717 The optional argument DISPLAY specifies which display to ask about.
4718 DISPLAY should be either a frame or a display name (a string).
4719 If omitted or nil, that stands for the selected frame's display.  */)
4720   (display)
4721      Lisp_Object display;
4722 {
4723   struct w32_display_info *dpyinfo = check_x_display_info (display);
4724   HDC hdc;
4725   int cap;
4726 
4727   hdc = GetDC (dpyinfo->root_window);
4728   if (dpyinfo->has_palette)
4729     cap = GetDeviceCaps (hdc, SIZEPALETTE);
4730   else
4731     cap = GetDeviceCaps (hdc, NUMCOLORS);
4732 
4733   /* We force 24+ bit depths to 24-bit, both to prevent an overflow
4734      and because probably is more meaningful on Windows anyway */
4735   if (cap < 0)
4736     cap = 1 << min (dpyinfo->n_planes * dpyinfo->n_cbits, 24);
4737 
4738   ReleaseDC (dpyinfo->root_window, hdc);
4739 
4740   return make_number (cap);
4741 }
4742 
4743 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
4744        Sx_server_max_request_size,
4745        0, 1, 0,
4746        doc: /* Return the maximum request size of the server of DISPLAY.
4747 The optional argument DISPLAY specifies which display to ask about.
4748 DISPLAY should be either a frame or a display name (a string).
4749 If omitted or nil, that stands for the selected frame's display.  */)
4750   (display)
4751      Lisp_Object display;
4752 {
4753   struct w32_display_info *dpyinfo = check_x_display_info (display);
4754 
4755   return make_number (1);
4756 }
4757 
4758 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
4759        doc: /* Return the "vendor ID" string of the W32 system (Microsoft).
4760 The optional argument DISPLAY specifies which display to ask about.
4761 DISPLAY should be either a frame or a display name (a string).
4762 If omitted or nil, that stands for the selected frame's display.  */)
4763   (display)
4764      Lisp_Object display;
4765 {
4766   return build_string ("Microsoft Corp.");
4767 }
4768 
4769 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
4770        doc: /* Return the version numbers of the server of DISPLAY.
4771 The value is a list of three integers: the major and minor
4772 version numbers of the X Protocol in use, and the distributor-specific
4773 release number.  See also the function `x-server-vendor'.
4774 
4775 The optional argument DISPLAY specifies which display to ask about.
4776 DISPLAY should be either a frame or a display name (a string).
4777 If omitted or nil, that stands for the selected frame's display.  */)
4778   (display)
4779      Lisp_Object display;
4780 {
4781   return Fcons (make_number (w32_major_version),
4782                 Fcons (make_number (w32_minor_version),
4783                        Fcons (make_number (w32_build_number), Qnil)));
4784 }
4785 
4786 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
4787        doc: /* Return the number of screens on the server of DISPLAY.
4788 The optional argument DISPLAY specifies which display to ask about.
4789 DISPLAY should be either a frame or a display name (a string).
4790 If omitted or nil, that stands for the selected frame's display.  */)
4791   (display)
4792      Lisp_Object display;
4793 {
4794   return make_number (1);
4795 }
4796 
4797 DEFUN ("x-display-mm-height", Fx_display_mm_height,
4798        Sx_display_mm_height, 0, 1, 0,
4799        doc: /* Return the height in millimeters of DISPLAY.
4800 The optional argument DISPLAY specifies which display to ask about.
4801 DISPLAY should be either a frame or a display name (a string).
4802 If omitted or nil, that stands for the selected frame's display.  */)
4803   (display)
4804      Lisp_Object display;
4805 {
4806   struct w32_display_info *dpyinfo = check_x_display_info (display);
4807   HDC hdc;
4808   int cap;
4809 
4810   hdc = GetDC (dpyinfo->root_window);
4811 
4812   cap = GetDeviceCaps (hdc, VERTSIZE);
4813 
4814   ReleaseDC (dpyinfo->root_window, hdc);
4815 
4816   return make_number (cap);
4817 }
4818 
4819 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
4820        doc: /* Return the width in millimeters of DISPLAY.
4821 The optional argument DISPLAY specifies which display to ask about.
4822 DISPLAY should be either a frame or a display name (a string).
4823 If omitted or nil, that stands for the selected frame's display.  */)
4824   (display)
4825      Lisp_Object display;
4826 {
4827   struct w32_display_info *dpyinfo = check_x_display_info (display);
4828 
4829   HDC hdc;
4830   int cap;
4831 
4832   hdc = GetDC (dpyinfo->root_window);
4833 
4834   cap = GetDeviceCaps (hdc, HORZSIZE);
4835 
4836   ReleaseDC (dpyinfo->root_window, hdc);
4837 
4838   return make_number (cap);
4839 }
4840 
4841 DEFUN ("x-display-backing-store", Fx_display_backing_store,
4842        Sx_display_backing_store, 0, 1, 0,
4843        doc: /* Return an indication of whether DISPLAY does backing store.
4844 The value may be `always', `when-mapped', or `not-useful'.
4845 The optional argument DISPLAY specifies which display to ask about.
4846 DISPLAY should be either a frame or a display name (a string).
4847 If omitted or nil, that stands for the selected frame's display.  */)
4848   (display)
4849      Lisp_Object display;
4850 {
4851   return intern ("not-useful");
4852 }
4853 
4854 DEFUN ("x-display-visual-class", Fx_display_visual_class,
4855        Sx_display_visual_class, 0, 1, 0,
4856        doc: /* Return the visual class of DISPLAY.
4857 The value is one of the symbols `static-gray', `gray-scale',
4858 `static-color', `pseudo-color', `true-color', or `direct-color'.
4859 
4860 The optional argument DISPLAY specifies which display to ask about.
4861 DISPLAY should be either a frame or a display name (a string).
4862 If omitted or nil, that stands for the selected frame's display.  */)
4863         (display)
4864      Lisp_Object display;
4865 {
4866   struct w32_display_info *dpyinfo = check_x_display_info (display);
4867   Lisp_Object result = Qnil;
4868 
4869   if (dpyinfo->has_palette)
4870       result = intern ("pseudo-color");
4871   else if (dpyinfo->n_planes * dpyinfo->n_cbits == 1)
4872       result = intern ("static-grey");
4873   else if (dpyinfo->n_planes * dpyinfo->n_cbits == 4)
4874       result = intern ("static-color");
4875   else if (dpyinfo->n_planes * dpyinfo->n_cbits > 8)
4876       result = intern ("true-color");
4877 
4878   return result;
4879 }
4880 
4881 DEFUN ("x-display-save-under", Fx_display_save_under,
4882        Sx_display_save_under, 0, 1, 0,
4883        doc: /* Return t if DISPLAY supports the save-under feature.
4884 The optional argument DISPLAY specifies which display to ask about.
4885 DISPLAY should be either a frame or a display name (a string).
4886 If omitted or nil, that stands for the selected frame's display.  */)
4887   (display)
4888      Lisp_Object display;
4889 {
4890   return Qnil;
4891 }
4892 
4893 int
4894 x_pixel_width (f)
4895      register struct frame *f;
4896 {
4897   return FRAME_PIXEL_WIDTH (f);
4898 }
4899 
4900 int
4901 x_pixel_height (f)
4902      register struct frame *f;
4903 {
4904   return FRAME_PIXEL_HEIGHT (f);
4905 }
4906 
4907 int
4908 x_char_width (f)
4909      register struct frame *f;
4910 {
4911   return FRAME_COLUMN_WIDTH (f);
4912 }
4913 
4914 int
4915 x_char_height (f)
4916      register struct frame *f;
4917 {
4918   return FRAME_LINE_HEIGHT (f);
4919 }
4920 
4921 int
4922 x_screen_planes (f)
4923      register struct frame *f;
4924 {
4925   return FRAME_W32_DISPLAY_INFO (f)->n_planes;
4926 }
4927 
4928 /* Return the display structure for the display named NAME.
4929    Open a new connection if necessary.  */
4930 
4931 struct w32_display_info *
4932 x_display_info_for_name (name)
4933      Lisp_Object name;
4934 {
4935   Lisp_Object names;
4936   struct w32_display_info *dpyinfo;
4937 
4938   CHECK_STRING (name);
4939 
4940   for (dpyinfo = &one_w32_display_info, names = w32_display_name_list;
4941        dpyinfo;
4942        dpyinfo = dpyinfo->next, names = XCDR (names))
4943     {
4944       Lisp_Object tem;
4945       tem = Fstring_equal (XCAR (XCAR (names)), name);
4946       if (!NILP (tem))
4947         return dpyinfo;
4948     }
4949 
4950   /* Use this general default value to start with.  */
4951   Vx_resource_name = Vinvocation_name;
4952 
4953   validate_x_resource_name ();
4954 
4955   dpyinfo = w32_term_init (name, (unsigned char *)0,
4956                              (char *) SDATA (Vx_resource_name));
4957 
4958   if (dpyinfo == 0)
4959     error ("Cannot connect to server %s", SDATA (name));
4960 
4961   w32_in_use = 1;
4962   XSETFASTINT (Vwindow_system_version, w32_major_version);
4963 
4964   return dpyinfo;
4965 }
4966 
4967 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4968        1, 3, 0, doc: /* Open a connection to a server.
4969 DISPLAY is the name of the display to connect to.
4970 Optional second arg XRM-STRING is a string of resources in xrdb format.
4971 If the optional third arg MUST-SUCCEED is non-nil,
4972 terminate Emacs if we can't open the connection.  */)
4973   (display, xrm_string, must_succeed)
4974      Lisp_Object display, xrm_string, must_succeed;
4975 {
4976   unsigned char *xrm_option;
4977   struct w32_display_info *dpyinfo;
4978 
4979   /* If initialization has already been done, return now to avoid
4980      overwriting critical parts of one_w32_display_info.  */
4981   if (w32_in_use)
4982     return Qnil;
4983 
4984   CHECK_STRING (display);
4985   if (! NILP (xrm_string))
4986     CHECK_STRING (xrm_string);
4987 
4988 #if 0
4989   if (! EQ (Vwindow_system, intern ("w32")))
4990     error ("Not using Microsoft Windows");
4991 #endif
4992 
4993   /* Allow color mapping to be defined externally; first look in user's
4994      HOME directory, then in Emacs etc dir for a file called rgb.txt. */
4995   {
4996     Lisp_Object color_file;
4997     struct gcpro gcpro1;
4998 
4999     color_file = build_string ("~/rgb.txt");
5000 
5001     GCPRO1 (color_file);
5002 
5003     if (NILP (Ffile_readable_p (color_file)))
5004       color_file =
5005         Fexpand_file_name (build_string ("rgb.txt"),
5006                            Fsymbol_value (intern ("data-directory")));
5007 
5008     Vw32_color_map = Fx_load_color_file (color_file);
5009 
5010     UNGCPRO;
5011   }
5012   if (NILP (Vw32_color_map))
5013     Vw32_color_map = Fw32_default_color_map ();
5014 
5015   /* Merge in system logical colors.  */
5016   add_system_logical_colors_to_map (&Vw32_color_map);
5017 
5018   if (! NILP (xrm_string))
5019     xrm_option = (unsigned char *) SDATA (xrm_string);
5020   else
5021     xrm_option = (unsigned char *) 0;
5022 
5023   /* Use this general default value to start with.  */
5024   /* First remove .exe suffix from invocation-name - it looks ugly. */
5025   {
5026     char basename[ MAX_PATH ], *str;
5027 
5028     strcpy (basename, SDATA (Vinvocation_name));
5029     str = strrchr (basename, '.');
5030     if (str) *str = 0;
5031     Vinvocation_name = build_string (basename);
5032   }
5033   Vx_resource_name = Vinvocation_name;
5034 
5035   validate_x_resource_name ();
5036 
5037   /* This is what opens the connection and sets x_current_display.
5038      This also initializes many symbols, such as those used for input.  */
5039   dpyinfo = w32_term_init (display, xrm_option,
5040                              (char *) SDATA (Vx_resource_name));
5041 
5042   if (dpyinfo == 0)
5043     {
5044       if (!NILP (must_succeed))
5045         fatal ("Cannot connect to server %s.\n",
5046                SDATA (display));
5047       else
5048         error ("Cannot connect to server %s", SDATA (display));
5049     }
5050 
5051   w32_in_use = 1;
5052 
5053   XSETFASTINT (Vwindow_system_version, w32_major_version);
5054   return Qnil;
5055 }
5056 
5057 DEFUN ("x-close-connection", Fx_close_connection,
5058        Sx_close_connection, 1, 1, 0,
5059        doc: /* Close the connection to DISPLAY's server.
5060 For DISPLAY, specify either a frame or a display name (a string).
5061 If DISPLAY is nil, that stands for the selected frame's display.  */)
5062   (display)
5063   Lisp_Object display;
5064 {
5065   struct w32_display_info *dpyinfo = check_x_display_info (display);
5066   int i;
5067 
5068   if (dpyinfo->reference_count > 0)
5069     error ("Display still has frames on it");
5070 
5071   BLOCK_INPUT;
5072   x_destroy_all_bitmaps (dpyinfo);
5073 
5074   x_delete_display (dpyinfo);
5075   UNBLOCK_INPUT;
5076 
5077   return Qnil;
5078 }
5079 
5080 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
5081        doc: /* Return the list of display names that Emacs has connections to.  */)
5082   ()
5083 {
5084   Lisp_Object tail, result;
5085 
5086   result = Qnil;
5087   for (tail = w32_display_name_list; CONSP (tail); tail = XCDR (tail))
5088     result = Fcons (XCAR (XCAR (tail)), result);
5089 
5090   return result;
5091 }
5092 
5093 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
5094        doc: /* This is a noop on W32 systems.  */)
5095      (on, display)
5096      Lisp_Object display, on;
5097 {
5098   return Qnil;
5099 }
5100 
5101 
5102 
5103 /***********************************************************************
5104                            Window properties
5105  ***********************************************************************/
5106 
5107 DEFUN ("x-change-window-property", Fx_change_window_property,
5108        Sx_change_window_property, 2, 6, 0,
5109        doc: /* Change window property PROP to VALUE on the X window of FRAME.
5110 VALUE may be a string or a list of conses, numbers and/or strings.
5111 If an element in the list is a string, it is converted to
5112 an Atom and the value of the Atom is used.  If an element is a cons,
5113 it is converted to a 32 bit number where the car is the 16 top bits and the
5114 cdr is the lower 16 bits.
5115 FRAME nil or omitted means use the selected frame.
5116 If TYPE is given and non-nil, it is the name of the type of VALUE.
5117 If TYPE is not given or nil, the type is STRING.
5118 FORMAT gives the size in bits of each element if VALUE is a list.
5119 It must be one of 8, 16 or 32.
5120 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
5121 If OUTER_P is non-nil, the property is changed for the outer X window of
5122 FRAME.  Default is to change on the edit X window.
5123 
5124 Value is VALUE.  */)
5125      (prop, value, frame, type, format, outer_p)
5126      Lisp_Object prop, value, frame, type, format, outer_p;
5127 {
5128 #if 0 /* TODO : port window properties to W32 */
5129   struct frame *f = check_x_frame (frame);
5130   Atom prop_atom;
5131 
5132   CHECK_STRING (prop);
5133   CHECK_STRING (value);
5134 
5135   BLOCK_INPUT;
5136   prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
5137   XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
5138                    prop_atom, XA_STRING, 8, PropModeReplace,
5139                    SDATA (value), SCHARS (value));
5140 
5141   /* Make sure the property is set when we return.  */
5142   XFlush (FRAME_W32_DISPLAY (f));
5143   UNBLOCK_INPUT;
5144 
5145 #endif /* TODO */
5146 
5147   return value;
5148 }
5149 
5150 
5151 DEFUN ("x-delete-window-property", Fx_delete_window_property,
5152        Sx_delete_window_property, 1, 2, 0,
5153        doc: /* Remove window property PROP from X window of FRAME.
5154 FRAME nil or omitted means use the selected frame.  Value is PROP.  */)
5155   (prop, frame)
5156      Lisp_Object prop, frame;
5157 {
5158 #if 0 /* TODO : port window properties to W32 */
5159 
5160   struct frame *f = check_x_frame (frame);
5161   Atom prop_atom;
5162 
5163   CHECK_STRING (prop);
5164   BLOCK_INPUT;
5165   prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
5166   XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
5167 
5168   /* Make sure the property is removed when we return.  */
5169   XFlush (FRAME_W32_DISPLAY (f));
5170   UNBLOCK_INPUT;
5171 #endif  /* TODO */
5172 
5173   return prop;
5174 }
5175 
5176 
5177 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
5178        1, 2, 0,
5179        doc: /* Value is the value of window property PROP on FRAME.
5180 If FRAME is nil or omitted, use the selected frame.  Value is nil
5181 if FRAME hasn't a property with name PROP or if PROP has no string
5182 value.  */)
5183   (prop, frame)
5184      Lisp_Object prop, frame;
5185 {
5186 #if 0 /* TODO : port window properties to W32 */
5187 
5188   struct frame *f = check_x_frame (frame);
5189   Atom prop_atom;
5190   int rc;
5191   Lisp_Object prop_value = Qnil;
5192   char *tmp_data = NULL;
5193   Atom actual_type;
5194   int actual_format;
5195   unsigned long actual_size, bytes_remaining;
5196 
5197   CHECK_STRING (prop);
5198   BLOCK_INPUT;
5199   prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
5200   rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
5201                            prop_atom, 0, 0, False, XA_STRING,
5202                            &actual_type, &actual_format, &actual_size,
5203                            &bytes_remaining, (unsigned char **) &tmp_data);
5204   if (rc == Success)
5205     {
5206       int size = bytes_remaining;
5207 
5208       XFree (tmp_data);
5209       tmp_data = NULL;
5210 
5211       rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
5212                                prop_atom, 0, bytes_remaining,
5213                                False, XA_STRING,
5214                                &actual_type, &actual_format,
5215                                &actual_size, &bytes_remaining,
5216                                (unsigned char **) &tmp_data);
5217       if (rc == Success)
5218         prop_value = make_string (tmp_data, size);
5219 
5220       XFree (tmp_data);
5221     }
5222 
5223   UNBLOCK_INPUT;
5224 
5225   return prop_value;
5226 
5227 #endif /* TODO */
5228   return Qnil;
5229 }
5230 
5231 
5232 
5233 /***********************************************************************
5234                                 Busy cursor
5235  ***********************************************************************/
5236 
5237 /* Default number of seconds to wait before displaying an hourglass
5238    cursor.  Duplicated from xdisp.c, but cannot use the version there
5239    due to lack of atimers on w32.  */
5240 #define DEFAULT_HOURGLASS_DELAY 1
5241 extern Lisp_Object Vhourglass_delay;
5242 
5243 /* Return non-zero if houglass timer has been started or hourglass is shown.  */
5244 /* PENDING: if W32 can use atimers (atimer.[hc]) then the common impl in
5245             xdisp.c could be used. */
5246 
5247 int
5248 hourglass_started ()
5249 {
5250   return hourglass_shown_p || hourglass_timer;
5251 }
5252 
5253 /* Cancel a currently active hourglass timer, and start a new one.  */
5254 
5255 void
5256 start_hourglass ()
5257 {
5258   DWORD delay;
5259   int secs, msecs = 0;
5260   struct frame * f = SELECTED_FRAME ();
5261 
5262   /* No cursors on non GUI frames.  */
5263   if (!FRAME_W32_P (f))
5264     return;
5265 
5266   cancel_hourglass ();
5267 
5268   if (INTEGERP (Vhourglass_delay)
5269       && XINT (Vhourglass_delay) > 0)
5270     secs = XFASTINT (Vhourglass_delay);
5271   else if (FLOATP (Vhourglass_delay)
5272            && XFLOAT_DATA (Vhourglass_delay) > 0)
5273     {
5274       Lisp_Object tem;
5275       tem = Ftruncate (Vhourglass_delay, Qnil);
5276       secs = XFASTINT (tem);
5277       msecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000;
5278     }
5279   else
5280     secs = DEFAULT_HOURGLASS_DELAY;
5281 
5282   delay = secs * 1000 + msecs;
5283   hourglass_hwnd = FRAME_W32_WINDOW (f);
5284   hourglass_timer = SetTimer (hourglass_hwnd, HOURGLASS_ID, delay, NULL);
5285 }
5286 
5287 
5288 /* Cancel the hourglass cursor timer if active, hide an hourglass
5289    cursor if shown.  */
5290 
5291 void
5292 cancel_hourglass ()
5293 {
5294   if (hourglass_timer)
5295     {
5296       KillTimer (hourglass_hwnd, hourglass_timer);
5297       hourglass_timer = 0;
5298     }
5299 
5300   if (hourglass_shown_p)
5301     w32_hide_hourglass ();
5302 }
5303 
5304 
5305 /* Timer function of hourglass_timer.
5306 
5307    Display an hourglass cursor.  Set the hourglass_p flag in display info
5308    to indicate that an hourglass cursor is shown.  */
5309 
5310 static void
5311 w32_show_hourglass (f)
5312      struct frame *f;
5313 {
5314   if (!hourglass_shown_p)
5315     {
5316       f->output_data.w32->hourglass_p = 1;
5317       if (!menubar_in_use && !current_popup_menu)
5318         SetCursor (f->output_data.w32->hourglass_cursor);
5319       hourglass_shown_p = 1;
5320     }
5321 }
5322 
5323 
5324 /* Hide the hourglass cursor on all frames, if it is currently shown.  */
5325 
5326 static void
5327 w32_hide_hourglass ()
5328 {
5329   if (hourglass_shown_p)
5330     {
5331       struct frame *f = x_window_to_frame (&one_w32_display_info,
5332                                            hourglass_hwnd);
5333       if (f)
5334         f->output_data.w32->hourglass_p = 0;
5335       else
5336         /* If frame was deleted, restore to selected frame's cursor.  */
5337         f = SELECTED_FRAME ();
5338 
5339       if (FRAME_W32_P (f))
5340         SetCursor (f->output_data.w32->current_cursor);
5341       else
5342         /* No cursors on non GUI frames - restore to stock arrow cursor.  */
5343         SetCursor (w32_load_cursor (IDC_ARROW));
5344 
5345       hourglass_shown_p = 0;
5346     }
5347 }
5348 
5349 
5350 
5351 /***********************************************************************
5352                                 Tool tips
5353  ***********************************************************************/
5354 
5355 static Lisp_Object x_create_tip_frame P_ ((struct w32_display_info *,
5356                                            Lisp_Object, Lisp_Object));
5357 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
5358                                 Lisp_Object, int, int, int *, int *));
5359 
5360 /* The frame of a currently visible tooltip.  */
5361 
5362 Lisp_Object tip_frame;
5363 
5364 /* If non-nil, a timer started that hides the last tooltip when it
5365    fires.  */
5366 
5367 Lisp_Object tip_timer;
5368 Window tip_window;
5369 
5370 /* If non-nil, a vector of 3 elements containing the last args
5371    with which x-show-tip was called.  See there.  */
5372 
5373 Lisp_Object last_show_tip_args;
5374 
5375 /* Maximum size for tooltips; a cons (COLUMNS . ROWS).  */
5376 
5377 Lisp_Object Vx_max_tooltip_size;
5378 
5379 
5380 static Lisp_Object
5381 unwind_create_tip_frame (frame)
5382      Lisp_Object frame;
5383 {
5384   Lisp_Object deleted;
5385 
5386   deleted = unwind_create_frame (frame);
5387   if (EQ (deleted, Qt))
5388     {
5389       tip_window = NULL;
5390       tip_frame = Qnil;
5391     }
5392 
5393   return deleted;
5394 }
5395 
5396 
5397 /* Create a frame for a tooltip on the display described by DPYINFO.
5398    PARMS is a list of frame parameters.  TEXT is the string to
5399    display in the tip frame.  Value is the frame.
5400 
5401    Note that functions called here, esp. x_default_parameter can
5402    signal errors, for instance when a specified color name is
5403    undefined.  We have to make sure that we're in a consistent state
5404    when this happens.  */
5405 
5406 static Lisp_Object
5407 x_create_tip_frame (dpyinfo, parms, text)
5408      struct w32_display_info *dpyinfo;
5409      Lisp_Object parms, text;
5410 {
5411   struct frame *f;
5412   Lisp_Object frame, tem;
5413   Lisp_Object name;
5414   long window_prompting = 0;
5415   int width, height;
5416   int count = SPECPDL_INDEX ();
5417   struct gcpro gcpro1, gcpro2, gcpro3;
5418   struct kboard *kb;
5419   int face_change_count_before = face_change_count;
5420   Lisp_Object buffer;
5421   struct buffer *old_buffer;
5422 
5423   check_w32 ();
5424 
5425   /* Use this general default value to start with until we know if
5426      this frame has a specified name.  */
5427   Vx_resource_name = Vinvocation_name;
5428 
5429   kb = dpyinfo->terminal->kboard;
5430 
5431   /* The calls to x_get_arg remove elements from PARMS, so copy it to
5432      avoid destructive changes behind our caller's back.  */
5433   parms = Fcopy_alist (parms);
5434 
5435   /* Get the name of the frame to use for resource lookup.  */
5436   name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
5437   if (!STRINGP (name)
5438       && !EQ (name, Qunbound)
5439       && !NILP (name))
5440     error ("Invalid frame name--not a string or nil");
5441   Vx_resource_name = name;
5442 
5443   frame = Qnil;
5444   GCPRO3 (parms, name, frame);
5445   /* Make a frame without minibuffer nor mode-line.  */
5446   f = make_frame (0);
5447   f->wants_modeline = 0;
5448   XSETFRAME (frame, f);
5449 
5450   buffer = Fget_buffer_create (build_string (" *tip*"));
5451   Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
5452   old_buffer = current_buffer;
5453   set_buffer_internal_1 (XBUFFER (buffer));
5454   current_buffer->truncate_lines = Qnil;
5455   specbind (Qinhibit_read_only, Qt);
5456   specbind (Qinhibit_modification_hooks, Qt);
5457   Ferase_buffer ();
5458   Finsert (1, &text);
5459   set_buffer_internal_1 (old_buffer);
5460 
5461   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
5462   record_unwind_protect (unwind_create_tip_frame, frame);
5463 
5464   /* By setting the output method, we're essentially saying that
5465      the frame is live, as per FRAME_LIVE_P.  If we get a signal
5466      from this point on, x_destroy_window might screw up reference
5467      counts etc.  */
5468   f->terminal = dpyinfo->terminal;
5469   f->terminal->reference_count++;
5470   f->output_method = output_w32;
5471   f->output_data.w32 =
5472     (struct w32_output *) xmalloc (sizeof (struct w32_output));
5473   bzero (f->output_data.w32, sizeof (struct w32_output));
5474 
5475   FRAME_FONTSET (f)  = -1;
5476   f->icon_name = Qnil;
5477 
5478 #if GLYPH_DEBUG
5479   image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
5480   dpyinfo_refcount = dpyinfo->reference_count;
5481 #endif /* GLYPH_DEBUG */
5482   FRAME_KBOARD (f) = kb;
5483   f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
5484   f->output_data.w32->explicit_parent = 0;
5485 
5486   /* Set the name; the functions to which we pass f expect the name to
5487      be set.  */
5488   if (EQ (name, Qunbound) || NILP (name))
5489     {
5490       f->name = build_string (dpyinfo->w32_id_name);
5491       f->explicit_name = 0;
5492     }
5493   else
5494     {
5495       f->name = name;
5496       f->explicit_name = 1;
5497       /* use the frame's title when getting resources for this frame.  */
5498       specbind (Qx_resource_name, name);
5499     }
5500 
5501   f->resx = dpyinfo->resx;
5502   f->resy = dpyinfo->resy;
5503 
5504   if (uniscribe_available)
5505     register_font_driver (&uniscribe_font_driver, f);
5506   register_font_driver (&w32font_driver, f);
5507 
5508   x_default_parameter (f, parms, Qfont_backend, Qnil,
5509                        "fontBackend", "FontBackend", RES_TYPE_STRING);
5510 
5511   /* Extract the window parameters from the supplied values
5512      that are needed to determine window geometry.  */
5513   x_default_font_parameter (f, parms);
5514 
5515   x_default_parameter (f, parms, Qborder_width, make_number (2),
5516                        "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5517   /* This defaults to 2 in order to match xterm.  We recognize either
5518      internalBorderWidth or internalBorder (which is what xterm calls
5519      it).  */
5520   if (NILP (Fassq (Qinternal_border_width, parms)))
5521     {
5522       Lisp_Object value;
5523 
5524       value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
5525                          "internalBorder", "internalBorder", RES_TYPE_NUMBER);
5526       if (! EQ (value, Qunbound))
5527         parms = Fcons (Fcons (Qinternal_border_width, value),
5528                        parms);
5529     }
5530   x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5531                        "internalBorderWidth", "internalBorderWidth",
5532                        RES_TYPE_NUMBER);
5533 
5534   /* Also do the stuff which must be set before the window exists.  */
5535   x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
5536                        "foreground", "Foreground", RES_TYPE_STRING);
5537   x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
5538                        "background", "Background", RES_TYPE_STRING);
5539   x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
5540                        "pointerColor", "Foreground", RES_TYPE_STRING);
5541   x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
5542                        "cursorColor", "Foreground", RES_TYPE_STRING);
5543   x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5544                        "borderColor", "BorderColor", RES_TYPE_STRING);
5545 
5546   /* Init faces before x_default_parameter is called for scroll-bar
5547      parameters because that function calls x_set_scroll_bar_width,
5548      which calls change_frame_size, which calls Fset_window_buffer,
5549      which runs hooks, which call Fvertical_motion.  At the end, we
5550      end up in init_iterator with a null face cache, which should not
5551      happen.  */
5552   init_frame_faces (f);
5553 
5554   f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
5555   f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
5556 
5557   window_prompting = x_figure_window_size (f, parms, 0);
5558 
5559   /* No fringes on tip frame.  */
5560   f->fringe_cols = 0;
5561   f->left_fringe_width = 0;
5562   f->right_fringe_width = 0;
5563 
5564   BLOCK_INPUT;
5565   my_create_tip_window (f);
5566   UNBLOCK_INPUT;
5567 
5568   x_make_gc (f);
5569 
5570   x_default_parameter (f, parms, Qauto_raise, Qnil,
5571                        "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5572   x_default_parameter (f, parms, Qauto_lower, Qnil,
5573                        "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5574   x_default_parameter (f, parms, Qcursor_type, Qbox,
5575                        "cursorType", "CursorType", RES_TYPE_SYMBOL);
5576 
5577   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
5578