1 /* Graphical user interface functions for the Microsoft Windows API.
3 Copyright (C) 1989, 1992-2016 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or (at
10 your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 /* Added by Kevin Gallo */
40 #include "blockinput.h"
43 #include "w32common.h"
47 #endif /* WINDOWSNT */
67 #ifndef FOF_NO_CONNECTED_ELEMENTS
68 #define FOF_NO_CONNECTED_ELEMENTS 0x2000
71 void syms_of_w32fns (void);
72 void globals_of_w32fns (void);
74 extern void free_frame_menubar (struct frame
*);
75 extern int w32_console_toggle_lock_key (int, Lisp_Object
);
76 extern void w32_menu_display_help (HWND
, HMENU
, UINT
, UINT
);
77 extern void w32_free_menu_strings (HWND
);
78 extern const char *map_w32_filename (const char *, const char **);
79 extern char * w32_strerror (int error_no
);
82 #define IDC_HAND MAKEINTRESOURCE(32649)
85 /* Prefix for system colors. */
86 #define SYSTEM_COLOR_PREFIX "System"
87 #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
89 /* State variables for emulating a three button mouse. */
94 static int button_state
= 0;
95 static W32Msg saved_mouse_button_msg
;
96 static unsigned mouse_button_timer
= 0; /* non-zero when timer is active */
97 static W32Msg saved_mouse_move_msg
;
98 static unsigned mouse_move_timer
= 0;
100 /* Window that is tracking the mouse. */
101 static HWND track_mouse_window
;
103 /* Multi-monitor API definitions that are not pulled from the headers
104 since we are compiling for NT 4. */
105 #ifndef MONITOR_DEFAULT_TO_NEAREST
106 #define MONITOR_DEFAULT_TO_NEAREST 2
108 #ifndef MONITORINFOF_PRIMARY
109 #define MONITORINFOF_PRIMARY 1
111 #ifndef SM_XVIRTUALSCREEN
112 #define SM_XVIRTUALSCREEN 76
114 #ifndef SM_YVIRTUALSCREEN
115 #define SM_YVIRTUALSCREEN 77
117 /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't.
118 To avoid a compile error on one or the other, redefine with a new name. */
127 #if _WIN32_WINDOWS >= 0x0410
128 #define C_CHILDREN_TITLEBAR CCHILDREN_TITLEBAR
129 typedef TITLEBARINFO TITLEBAR_INFO
;
131 #define C_CHILDREN_TITLEBAR 5
136 DWORD rgstate
[C_CHILDREN_TITLEBAR
+1];
137 } TITLEBAR_INFO
, *PTITLEBAR_INFO
;
140 #ifndef CCHDEVICENAME
141 #define CCHDEVICENAME 32
143 struct MONITOR_INFO_EX
149 char szDevice
[CCHDEVICENAME
];
152 /* Reportedly, MSVC does not have this in its headers. */
153 #if defined (_MSC_VER) && _WIN32_WINNT < 0x0500
154 DECLARE_HANDLE(HMONITOR
);
157 typedef BOOL (WINAPI
* TrackMouseEvent_Proc
)
158 (IN OUT LPTRACKMOUSEEVENT lpEventTrack
);
159 typedef LONG (WINAPI
* ImmGetCompositionString_Proc
)
160 (IN HIMC context
, IN DWORD index
, OUT LPVOID buffer
, IN DWORD bufLen
);
161 typedef HIMC (WINAPI
* ImmGetContext_Proc
) (IN HWND window
);
162 typedef BOOL (WINAPI
* ImmReleaseContext_Proc
) (IN HWND wnd
, IN HIMC context
);
163 typedef BOOL (WINAPI
* ImmSetCompositionWindow_Proc
) (IN HIMC context
,
164 IN COMPOSITIONFORM
*form
);
165 typedef HMONITOR (WINAPI
* MonitorFromPoint_Proc
) (IN POINT pt
, IN DWORD flags
);
166 typedef BOOL (WINAPI
* GetMonitorInfo_Proc
)
167 (IN HMONITOR monitor
, OUT
struct MONITOR_INFO
* info
);
168 typedef HMONITOR (WINAPI
* MonitorFromWindow_Proc
)
169 (IN HWND hwnd
, IN DWORD dwFlags
);
170 typedef BOOL
CALLBACK (* MonitorEnum_Proc
)
171 (IN HMONITOR monitor
, IN HDC hdc
, IN RECT
*rcMonitor
, IN LPARAM dwData
);
172 typedef BOOL (WINAPI
* EnumDisplayMonitors_Proc
)
173 (IN HDC hdc
, IN RECT
*rcClip
, IN MonitorEnum_Proc fnEnum
, IN LPARAM dwData
);
174 typedef BOOL (WINAPI
* GetTitleBarInfo_Proc
)
175 (IN HWND hwnd
, OUT TITLEBAR_INFO
* info
);
177 TrackMouseEvent_Proc track_mouse_event_fn
= NULL
;
178 ImmGetCompositionString_Proc get_composition_string_fn
= NULL
;
179 ImmGetContext_Proc get_ime_context_fn
= NULL
;
180 ImmReleaseContext_Proc release_ime_context_fn
= NULL
;
181 ImmSetCompositionWindow_Proc set_ime_composition_window_fn
= NULL
;
182 MonitorFromPoint_Proc monitor_from_point_fn
= NULL
;
183 GetMonitorInfo_Proc get_monitor_info_fn
= NULL
;
184 MonitorFromWindow_Proc monitor_from_window_fn
= NULL
;
185 EnumDisplayMonitors_Proc enum_display_monitors_fn
= NULL
;
186 GetTitleBarInfo_Proc get_title_bar_info_fn
= NULL
;
189 #define unicode_append_menu AppendMenuW
190 #else /* !NTGUI_UNICODE */
191 extern AppendMenuW_Proc unicode_append_menu
;
192 #endif /* NTGUI_UNICODE */
194 /* Flag to selectively ignore WM_IME_CHAR messages. */
195 static int ignore_ime_char
= 0;
197 /* W95 mousewheel handler */
198 unsigned int msh_mousewheel
= 0;
201 #define MOUSE_BUTTON_ID 1
202 #define MOUSE_MOVE_ID 2
203 #define MENU_FREE_ID 3
204 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
206 #define MENU_FREE_DELAY 1000
207 static unsigned menu_free_timer
= 0;
210 static ptrdiff_t image_cache_refcount
;
211 static int dpyinfo_refcount
;
214 static HWND w32_visible_system_caret_hwnd
;
216 static int w32_unicode_gui
;
219 extern HMENU current_popup_menu
;
220 int menubar_in_use
= 0;
222 /* From w32uniscribe.c */
223 extern void syms_of_w32uniscribe (void);
224 extern int uniscribe_available
;
227 /* From w32inevt.c */
228 extern int faked_key
;
229 #endif /* WINDOWSNT */
231 /* This gives us the page size and the size of the allocation unit on NT. */
232 SYSTEM_INFO sysinfo_cache
;
234 /* This gives us version, build, and platform identification. */
235 OSVERSIONINFO osinfo_cache
;
237 DWORD_PTR syspage_mask
= 0;
239 /* The major and minor versions of NT. */
240 int w32_major_version
;
241 int w32_minor_version
;
242 int w32_build_number
;
244 /* Distinguish between Windows NT and Windows 95. */
248 HINSTANCE hinst
= NULL
;
251 static unsigned int sound_type
= 0xFFFFFFFF;
252 #define MB_EMACS_SILENT (0xFFFFFFFF - 1)
254 /* Let the user specify a display with a frame.
255 nil stands for the selected frame--or, if that is not a w32 frame,
256 the first display on the list. */
258 struct w32_display_info
*
259 check_x_display_info (Lisp_Object object
)
263 struct frame
*sf
= XFRAME (selected_frame
);
265 if (FRAME_W32_P (sf
) && FRAME_LIVE_P (sf
))
266 return FRAME_DISPLAY_INFO (sf
);
268 return &one_w32_display_info
;
270 else if (TERMINALP (object
))
272 struct terminal
*t
= decode_live_terminal (object
);
274 if (t
->type
!= output_w32
)
275 error ("Terminal %d is not a W32 display", t
->id
);
277 return t
->display_info
.w32
;
279 else if (STRINGP (object
))
280 return x_display_info_for_name (object
);
285 CHECK_LIVE_FRAME (object
);
287 if (! FRAME_W32_P (f
))
288 error ("Non-W32 frame used");
289 return FRAME_DISPLAY_INFO (f
);
293 /* Return the Emacs frame-object corresponding to an w32 window.
294 It could be the frame's main window or an icon window. */
297 x_window_to_frame (struct w32_display_info
*dpyinfo
, HWND wdesc
)
299 Lisp_Object tail
, frame
;
302 FOR_EACH_FRAME (tail
, frame
)
305 if (!FRAME_W32_P (f
) || FRAME_DISPLAY_INFO (f
) != dpyinfo
)
308 if (FRAME_W32_WINDOW (f
) == wdesc
)
315 static Lisp_Object
unwind_create_frame (Lisp_Object
);
316 static void unwind_create_tip_frame (Lisp_Object
);
317 static void my_create_window (struct frame
*);
318 static void my_create_tip_window (struct frame
*);
320 /* TODO: Native Input Method support; see x_create_im. */
321 void x_set_foreground_color (struct frame
*, Lisp_Object
, Lisp_Object
);
322 void x_set_background_color (struct frame
*, Lisp_Object
, Lisp_Object
);
323 void x_set_mouse_color (struct frame
*, Lisp_Object
, Lisp_Object
);
324 void x_set_cursor_color (struct frame
*, Lisp_Object
, Lisp_Object
);
325 void x_set_border_color (struct frame
*, Lisp_Object
, Lisp_Object
);
326 void x_set_cursor_type (struct frame
*, Lisp_Object
, Lisp_Object
);
327 void x_set_icon_type (struct frame
*, Lisp_Object
, Lisp_Object
);
328 void x_set_icon_name (struct frame
*, Lisp_Object
, Lisp_Object
);
329 void x_explicitly_set_name (struct frame
*, Lisp_Object
, Lisp_Object
);
330 void x_set_menu_bar_lines (struct frame
*, Lisp_Object
, Lisp_Object
);
331 void x_set_title (struct frame
*, Lisp_Object
, Lisp_Object
);
332 void x_set_tool_bar_lines (struct frame
*, Lisp_Object
, Lisp_Object
);
333 void x_set_internal_border_width (struct frame
*f
, Lisp_Object
, Lisp_Object
);
336 /* Store the screen positions of frame F into XPTR and YPTR.
337 These are the positions of the containing window manager window,
338 not Emacs's own window. */
341 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
346 /* Get the bounds of the WM window. */
347 GetWindowRect (FRAME_W32_WINDOW (f
), &rect
);
352 /* Convert (0, 0) in the client area to screen co-ordinates. */
353 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
359 /* Returns the window rectangle appropriate for the given fullscreen mode.
360 The normal rect parameter was the window's rectangle prior to entering
361 fullscreen mode. If multiple monitor support is available, the nearest
362 monitor to the window is chosen. */
365 w32_fullscreen_rect (HWND hwnd
, int fsmode
, RECT normal
, RECT
*rect
)
367 struct MONITOR_INFO mi
= { sizeof(mi
) };
368 if (monitor_from_window_fn
&& get_monitor_info_fn
)
371 monitor_from_window_fn (hwnd
, MONITOR_DEFAULT_TO_NEAREST
);
372 get_monitor_info_fn (monitor
, &mi
);
376 mi
.rcMonitor
.left
= 0;
377 mi
.rcMonitor
.top
= 0;
378 mi
.rcMonitor
.right
= GetSystemMetrics (SM_CXSCREEN
);
379 mi
.rcMonitor
.bottom
= GetSystemMetrics (SM_CYSCREEN
);
382 mi
.rcWork
.right
= GetSystemMetrics (SM_CXMAXIMIZED
);
383 mi
.rcWork
.bottom
= GetSystemMetrics (SM_CYMAXIMIZED
);
388 case FULLSCREEN_BOTH
:
389 rect
->left
= mi
.rcMonitor
.left
;
390 rect
->top
= mi
.rcMonitor
.top
;
391 rect
->right
= mi
.rcMonitor
.right
;
392 rect
->bottom
= mi
.rcMonitor
.bottom
;
394 case FULLSCREEN_WIDTH
:
395 rect
->left
= mi
.rcWork
.left
;
396 rect
->top
= normal
.top
;
397 rect
->right
= mi
.rcWork
.right
;
398 rect
->bottom
= normal
.bottom
;
400 case FULLSCREEN_HEIGHT
:
401 rect
->left
= normal
.left
;
402 rect
->top
= mi
.rcWork
.top
;
403 rect
->right
= normal
.right
;
404 rect
->bottom
= mi
.rcWork
.bottom
;
414 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color
,
415 Sw32_define_rgb_color
, 4, 4, 0,
416 doc
: /* Convert RGB numbers to a Windows color reference and associate with NAME.
417 This adds or updates a named color to `w32-color-map', making it
418 available for use. The original entry's RGB ref is returned, or nil
419 if the entry is new. */)
420 (Lisp_Object red
, Lisp_Object green
, Lisp_Object blue
, Lisp_Object name
)
423 Lisp_Object oldrgb
= Qnil
;
427 CHECK_NUMBER (green
);
431 XSETINT (rgb
, RGB (XUINT (red
), XUINT (green
), XUINT (blue
)));
435 /* replace existing entry in w32-color-map or add new entry. */
436 entry
= Fassoc (name
, Vw32_color_map
);
439 entry
= Fcons (name
, rgb
);
440 Vw32_color_map
= Fcons (entry
, Vw32_color_map
);
444 oldrgb
= Fcdr (entry
);
445 Fsetcdr (entry
, rgb
);
453 /* The default colors for the w32 color map */
454 typedef struct colormap_t
460 colormap_t w32_color_map
[] =
462 {"snow" , PALETTERGB (255,250,250)},
463 {"ghost white" , PALETTERGB (248,248,255)},
464 {"GhostWhite" , PALETTERGB (248,248,255)},
465 {"white smoke" , PALETTERGB (245,245,245)},
466 {"WhiteSmoke" , PALETTERGB (245,245,245)},
467 {"gainsboro" , PALETTERGB (220,220,220)},
468 {"floral white" , PALETTERGB (255,250,240)},
469 {"FloralWhite" , PALETTERGB (255,250,240)},
470 {"old lace" , PALETTERGB (253,245,230)},
471 {"OldLace" , PALETTERGB (253,245,230)},
472 {"linen" , PALETTERGB (250,240,230)},
473 {"antique white" , PALETTERGB (250,235,215)},
474 {"AntiqueWhite" , PALETTERGB (250,235,215)},
475 {"papaya whip" , PALETTERGB (255,239,213)},
476 {"PapayaWhip" , PALETTERGB (255,239,213)},
477 {"blanched almond" , PALETTERGB (255,235,205)},
478 {"BlanchedAlmond" , PALETTERGB (255,235,205)},
479 {"bisque" , PALETTERGB (255,228,196)},
480 {"peach puff" , PALETTERGB (255,218,185)},
481 {"PeachPuff" , PALETTERGB (255,218,185)},
482 {"navajo white" , PALETTERGB (255,222,173)},
483 {"NavajoWhite" , PALETTERGB (255,222,173)},
484 {"moccasin" , PALETTERGB (255,228,181)},
485 {"cornsilk" , PALETTERGB (255,248,220)},
486 {"ivory" , PALETTERGB (255,255,240)},
487 {"lemon chiffon" , PALETTERGB (255,250,205)},
488 {"LemonChiffon" , PALETTERGB (255,250,205)},
489 {"seashell" , PALETTERGB (255,245,238)},
490 {"honeydew" , PALETTERGB (240,255,240)},
491 {"mint cream" , PALETTERGB (245,255,250)},
492 {"MintCream" , PALETTERGB (245,255,250)},
493 {"azure" , PALETTERGB (240,255,255)},
494 {"alice blue" , PALETTERGB (240,248,255)},
495 {"AliceBlue" , PALETTERGB (240,248,255)},
496 {"lavender" , PALETTERGB (230,230,250)},
497 {"lavender blush" , PALETTERGB (255,240,245)},
498 {"LavenderBlush" , PALETTERGB (255,240,245)},
499 {"misty rose" , PALETTERGB (255,228,225)},
500 {"MistyRose" , PALETTERGB (255,228,225)},
501 {"white" , PALETTERGB (255,255,255)},
502 {"black" , PALETTERGB ( 0, 0, 0)},
503 {"dark slate gray" , PALETTERGB ( 47, 79, 79)},
504 {"DarkSlateGray" , PALETTERGB ( 47, 79, 79)},
505 {"dark slate grey" , PALETTERGB ( 47, 79, 79)},
506 {"DarkSlateGrey" , PALETTERGB ( 47, 79, 79)},
507 {"dim gray" , PALETTERGB (105,105,105)},
508 {"DimGray" , PALETTERGB (105,105,105)},
509 {"dim grey" , PALETTERGB (105,105,105)},
510 {"DimGrey" , PALETTERGB (105,105,105)},
511 {"slate gray" , PALETTERGB (112,128,144)},
512 {"SlateGray" , PALETTERGB (112,128,144)},
513 {"slate grey" , PALETTERGB (112,128,144)},
514 {"SlateGrey" , PALETTERGB (112,128,144)},
515 {"light slate gray" , PALETTERGB (119,136,153)},
516 {"LightSlateGray" , PALETTERGB (119,136,153)},
517 {"light slate grey" , PALETTERGB (119,136,153)},
518 {"LightSlateGrey" , PALETTERGB (119,136,153)},
519 {"gray" , PALETTERGB (190,190,190)},
520 {"grey" , PALETTERGB (190,190,190)},
521 {"light grey" , PALETTERGB (211,211,211)},
522 {"LightGrey" , PALETTERGB (211,211,211)},
523 {"light gray" , PALETTERGB (211,211,211)},
524 {"LightGray" , PALETTERGB (211,211,211)},
525 {"midnight blue" , PALETTERGB ( 25, 25,112)},
526 {"MidnightBlue" , PALETTERGB ( 25, 25,112)},
527 {"navy" , PALETTERGB ( 0, 0,128)},
528 {"navy blue" , PALETTERGB ( 0, 0,128)},
529 {"NavyBlue" , PALETTERGB ( 0, 0,128)},
530 {"cornflower blue" , PALETTERGB (100,149,237)},
531 {"CornflowerBlue" , PALETTERGB (100,149,237)},
532 {"dark slate blue" , PALETTERGB ( 72, 61,139)},
533 {"DarkSlateBlue" , PALETTERGB ( 72, 61,139)},
534 {"slate blue" , PALETTERGB (106, 90,205)},
535 {"SlateBlue" , PALETTERGB (106, 90,205)},
536 {"medium slate blue" , PALETTERGB (123,104,238)},
537 {"MediumSlateBlue" , PALETTERGB (123,104,238)},
538 {"light slate blue" , PALETTERGB (132,112,255)},
539 {"LightSlateBlue" , PALETTERGB (132,112,255)},
540 {"medium blue" , PALETTERGB ( 0, 0,205)},
541 {"MediumBlue" , PALETTERGB ( 0, 0,205)},
542 {"royal blue" , PALETTERGB ( 65,105,225)},
543 {"RoyalBlue" , PALETTERGB ( 65,105,225)},
544 {"blue" , PALETTERGB ( 0, 0,255)},
545 {"dodger blue" , PALETTERGB ( 30,144,255)},
546 {"DodgerBlue" , PALETTERGB ( 30,144,255)},
547 {"deep sky blue" , PALETTERGB ( 0,191,255)},
548 {"DeepSkyBlue" , PALETTERGB ( 0,191,255)},
549 {"sky blue" , PALETTERGB (135,206,235)},
550 {"SkyBlue" , PALETTERGB (135,206,235)},
551 {"light sky blue" , PALETTERGB (135,206,250)},
552 {"LightSkyBlue" , PALETTERGB (135,206,250)},
553 {"steel blue" , PALETTERGB ( 70,130,180)},
554 {"SteelBlue" , PALETTERGB ( 70,130,180)},
555 {"light steel blue" , PALETTERGB (176,196,222)},
556 {"LightSteelBlue" , PALETTERGB (176,196,222)},
557 {"light blue" , PALETTERGB (173,216,230)},
558 {"LightBlue" , PALETTERGB (173,216,230)},
559 {"powder blue" , PALETTERGB (176,224,230)},
560 {"PowderBlue" , PALETTERGB (176,224,230)},
561 {"pale turquoise" , PALETTERGB (175,238,238)},
562 {"PaleTurquoise" , PALETTERGB (175,238,238)},
563 {"dark turquoise" , PALETTERGB ( 0,206,209)},
564 {"DarkTurquoise" , PALETTERGB ( 0,206,209)},
565 {"medium turquoise" , PALETTERGB ( 72,209,204)},
566 {"MediumTurquoise" , PALETTERGB ( 72,209,204)},
567 {"turquoise" , PALETTERGB ( 64,224,208)},
568 {"cyan" , PALETTERGB ( 0,255,255)},
569 {"light cyan" , PALETTERGB (224,255,255)},
570 {"LightCyan" , PALETTERGB (224,255,255)},
571 {"cadet blue" , PALETTERGB ( 95,158,160)},
572 {"CadetBlue" , PALETTERGB ( 95,158,160)},
573 {"medium aquamarine" , PALETTERGB (102,205,170)},
574 {"MediumAquamarine" , PALETTERGB (102,205,170)},
575 {"aquamarine" , PALETTERGB (127,255,212)},
576 {"dark green" , PALETTERGB ( 0,100, 0)},
577 {"DarkGreen" , PALETTERGB ( 0,100, 0)},
578 {"dark olive green" , PALETTERGB ( 85,107, 47)},
579 {"DarkOliveGreen" , PALETTERGB ( 85,107, 47)},
580 {"dark sea green" , PALETTERGB (143,188,143)},
581 {"DarkSeaGreen" , PALETTERGB (143,188,143)},
582 {"sea green" , PALETTERGB ( 46,139, 87)},
583 {"SeaGreen" , PALETTERGB ( 46,139, 87)},
584 {"medium sea green" , PALETTERGB ( 60,179,113)},
585 {"MediumSeaGreen" , PALETTERGB ( 60,179,113)},
586 {"light sea green" , PALETTERGB ( 32,178,170)},
587 {"LightSeaGreen" , PALETTERGB ( 32,178,170)},
588 {"pale green" , PALETTERGB (152,251,152)},
589 {"PaleGreen" , PALETTERGB (152,251,152)},
590 {"spring green" , PALETTERGB ( 0,255,127)},
591 {"SpringGreen" , PALETTERGB ( 0,255,127)},
592 {"lawn green" , PALETTERGB (124,252, 0)},
593 {"LawnGreen" , PALETTERGB (124,252, 0)},
594 {"green" , PALETTERGB ( 0,255, 0)},
595 {"chartreuse" , PALETTERGB (127,255, 0)},
596 {"medium spring green" , PALETTERGB ( 0,250,154)},
597 {"MediumSpringGreen" , PALETTERGB ( 0,250,154)},
598 {"green yellow" , PALETTERGB (173,255, 47)},
599 {"GreenYellow" , PALETTERGB (173,255, 47)},
600 {"lime green" , PALETTERGB ( 50,205, 50)},
601 {"LimeGreen" , PALETTERGB ( 50,205, 50)},
602 {"yellow green" , PALETTERGB (154,205, 50)},
603 {"YellowGreen" , PALETTERGB (154,205, 50)},
604 {"forest green" , PALETTERGB ( 34,139, 34)},
605 {"ForestGreen" , PALETTERGB ( 34,139, 34)},
606 {"olive drab" , PALETTERGB (107,142, 35)},
607 {"OliveDrab" , PALETTERGB (107,142, 35)},
608 {"dark khaki" , PALETTERGB (189,183,107)},
609 {"DarkKhaki" , PALETTERGB (189,183,107)},
610 {"khaki" , PALETTERGB (240,230,140)},
611 {"pale goldenrod" , PALETTERGB (238,232,170)},
612 {"PaleGoldenrod" , PALETTERGB (238,232,170)},
613 {"light goldenrod yellow" , PALETTERGB (250,250,210)},
614 {"LightGoldenrodYellow" , PALETTERGB (250,250,210)},
615 {"light yellow" , PALETTERGB (255,255,224)},
616 {"LightYellow" , PALETTERGB (255,255,224)},
617 {"yellow" , PALETTERGB (255,255, 0)},
618 {"gold" , PALETTERGB (255,215, 0)},
619 {"light goldenrod" , PALETTERGB (238,221,130)},
620 {"LightGoldenrod" , PALETTERGB (238,221,130)},
621 {"goldenrod" , PALETTERGB (218,165, 32)},
622 {"dark goldenrod" , PALETTERGB (184,134, 11)},
623 {"DarkGoldenrod" , PALETTERGB (184,134, 11)},
624 {"rosy brown" , PALETTERGB (188,143,143)},
625 {"RosyBrown" , PALETTERGB (188,143,143)},
626 {"indian red" , PALETTERGB (205, 92, 92)},
627 {"IndianRed" , PALETTERGB (205, 92, 92)},
628 {"saddle brown" , PALETTERGB (139, 69, 19)},
629 {"SaddleBrown" , PALETTERGB (139, 69, 19)},
630 {"sienna" , PALETTERGB (160, 82, 45)},
631 {"peru" , PALETTERGB (205,133, 63)},
632 {"burlywood" , PALETTERGB (222,184,135)},
633 {"beige" , PALETTERGB (245,245,220)},
634 {"wheat" , PALETTERGB (245,222,179)},
635 {"sandy brown" , PALETTERGB (244,164, 96)},
636 {"SandyBrown" , PALETTERGB (244,164, 96)},
637 {"tan" , PALETTERGB (210,180,140)},
638 {"chocolate" , PALETTERGB (210,105, 30)},
639 {"firebrick" , PALETTERGB (178,34, 34)},
640 {"brown" , PALETTERGB (165,42, 42)},
641 {"dark salmon" , PALETTERGB (233,150,122)},
642 {"DarkSalmon" , PALETTERGB (233,150,122)},
643 {"salmon" , PALETTERGB (250,128,114)},
644 {"light salmon" , PALETTERGB (255,160,122)},
645 {"LightSalmon" , PALETTERGB (255,160,122)},
646 {"orange" , PALETTERGB (255,165, 0)},
647 {"dark orange" , PALETTERGB (255,140, 0)},
648 {"DarkOrange" , PALETTERGB (255,140, 0)},
649 {"coral" , PALETTERGB (255,127, 80)},
650 {"light coral" , PALETTERGB (240,128,128)},
651 {"LightCoral" , PALETTERGB (240,128,128)},
652 {"tomato" , PALETTERGB (255, 99, 71)},
653 {"orange red" , PALETTERGB (255, 69, 0)},
654 {"OrangeRed" , PALETTERGB (255, 69, 0)},
655 {"red" , PALETTERGB (255, 0, 0)},
656 {"hot pink" , PALETTERGB (255,105,180)},
657 {"HotPink" , PALETTERGB (255,105,180)},
658 {"deep pink" , PALETTERGB (255, 20,147)},
659 {"DeepPink" , PALETTERGB (255, 20,147)},
660 {"pink" , PALETTERGB (255,192,203)},
661 {"light pink" , PALETTERGB (255,182,193)},
662 {"LightPink" , PALETTERGB (255,182,193)},
663 {"pale violet red" , PALETTERGB (219,112,147)},
664 {"PaleVioletRed" , PALETTERGB (219,112,147)},
665 {"maroon" , PALETTERGB (176, 48, 96)},
666 {"medium violet red" , PALETTERGB (199, 21,133)},
667 {"MediumVioletRed" , PALETTERGB (199, 21,133)},
668 {"violet red" , PALETTERGB (208, 32,144)},
669 {"VioletRed" , PALETTERGB (208, 32,144)},
670 {"magenta" , PALETTERGB (255, 0,255)},
671 {"violet" , PALETTERGB (238,130,238)},
672 {"plum" , PALETTERGB (221,160,221)},
673 {"orchid" , PALETTERGB (218,112,214)},
674 {"medium orchid" , PALETTERGB (186, 85,211)},
675 {"MediumOrchid" , PALETTERGB (186, 85,211)},
676 {"dark orchid" , PALETTERGB (153, 50,204)},
677 {"DarkOrchid" , PALETTERGB (153, 50,204)},
678 {"dark violet" , PALETTERGB (148, 0,211)},
679 {"DarkViolet" , PALETTERGB (148, 0,211)},
680 {"blue violet" , PALETTERGB (138, 43,226)},
681 {"BlueViolet" , PALETTERGB (138, 43,226)},
682 {"purple" , PALETTERGB (160, 32,240)},
683 {"medium purple" , PALETTERGB (147,112,219)},
684 {"MediumPurple" , PALETTERGB (147,112,219)},
685 {"thistle" , PALETTERGB (216,191,216)},
686 {"gray0" , PALETTERGB ( 0, 0, 0)},
687 {"grey0" , PALETTERGB ( 0, 0, 0)},
688 {"dark grey" , PALETTERGB (169,169,169)},
689 {"DarkGrey" , PALETTERGB (169,169,169)},
690 {"dark gray" , PALETTERGB (169,169,169)},
691 {"DarkGray" , PALETTERGB (169,169,169)},
692 {"dark blue" , PALETTERGB ( 0, 0,139)},
693 {"DarkBlue" , PALETTERGB ( 0, 0,139)},
694 {"dark cyan" , PALETTERGB ( 0,139,139)},
695 {"DarkCyan" , PALETTERGB ( 0,139,139)},
696 {"dark magenta" , PALETTERGB (139, 0,139)},
697 {"DarkMagenta" , PALETTERGB (139, 0,139)},
698 {"dark red" , PALETTERGB (139, 0, 0)},
699 {"DarkRed" , PALETTERGB (139, 0, 0)},
700 {"light green" , PALETTERGB (144,238,144)},
701 {"LightGreen" , PALETTERGB (144,238,144)},
705 w32_default_color_map (void)
708 colormap_t
*pc
= w32_color_map
;
715 for (i
= 0; i
< ARRAYELTS (w32_color_map
); pc
++, i
++)
716 cmap
= Fcons (Fcons (build_string (pc
->name
),
717 make_number (pc
->colorref
)),
725 DEFUN ("w32-default-color-map", Fw32_default_color_map
, Sw32_default_color_map
,
726 0, 0, 0, doc
: /* Return the default color map. */)
729 return w32_default_color_map ();
733 w32_color_map_lookup (const char *colorname
)
735 Lisp_Object tail
, ret
= Qnil
;
739 for (tail
= Vw32_color_map
; CONSP (tail
); tail
= XCDR (tail
))
741 register Lisp_Object elt
, tem
;
744 if (!CONSP (elt
)) continue;
748 if (lstrcmpi (SSDATA (tem
), colorname
) == 0)
764 add_system_logical_colors_to_map (Lisp_Object
*system_colors
)
768 /* Other registry operations are done with input blocked. */
771 /* Look for "Control Panel/Colors" under User and Machine registry
773 if (RegOpenKeyEx (HKEY_CURRENT_USER
, "Control Panel\\Colors", 0,
774 KEY_READ
, &colors_key
) == ERROR_SUCCESS
775 || RegOpenKeyEx (HKEY_LOCAL_MACHINE
, "Control Panel\\Colors", 0,
776 KEY_READ
, &colors_key
) == ERROR_SUCCESS
)
779 char color_buffer
[64];
780 char full_name_buffer
[MAX_PATH
+ SYSTEM_COLOR_PREFIX_LEN
];
782 DWORD name_size
, color_size
;
783 char *name_buffer
= full_name_buffer
+ SYSTEM_COLOR_PREFIX_LEN
;
785 name_size
= sizeof (full_name_buffer
) - SYSTEM_COLOR_PREFIX_LEN
;
786 color_size
= sizeof (color_buffer
);
788 strcpy (full_name_buffer
, SYSTEM_COLOR_PREFIX
);
790 while (RegEnumValueA (colors_key
, index
, name_buffer
, &name_size
,
791 NULL
, NULL
, (LPBYTE
)color_buffer
, &color_size
)
795 if (sscanf (color_buffer
, " %u %u %u", &r
, &g
, &b
) == 3)
796 *system_colors
= Fcons (Fcons (build_string (full_name_buffer
),
797 make_number (RGB (r
, g
, b
))),
800 name_size
= sizeof (full_name_buffer
) - SYSTEM_COLOR_PREFIX_LEN
;
801 color_size
= sizeof (color_buffer
);
804 RegCloseKey (colors_key
);
812 x_to_w32_color (const char * colorname
)
814 register Lisp_Object ret
= Qnil
;
818 if (colorname
[0] == '#')
820 /* Could be an old-style RGB Device specification. */
821 int size
= strlen (colorname
+ 1);
822 char *color
= alloca (size
+ 1);
824 strcpy (color
, colorname
+ 1);
825 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
833 for (i
= 0; i
< 3; i
++)
839 /* The check for 'x' in the following conditional takes into
840 account the fact that strtol allows a "0x" in front of
841 our numbers, and we don't. */
842 if (!isxdigit (color
[0]) || color
[1] == 'x')
846 value
= strtoul (color
, &end
, 16);
848 if (errno
== ERANGE
|| end
- color
!= size
)
853 value
= value
* 0x10;
864 colorval
|= (value
<< pos
);
869 XSETINT (ret
, colorval
);
876 else if (strnicmp (colorname
, "rgb:", 4) == 0)
884 color
= colorname
+ 4;
885 for (i
= 0; i
< 3; i
++)
890 /* The check for 'x' in the following conditional takes into
891 account the fact that strtol allows a "0x" in front of
892 our numbers, and we don't. */
893 if (!isxdigit (color
[0]) || color
[1] == 'x')
895 value
= strtoul (color
, &end
, 16);
901 value
= value
* 0x10 + value
;
914 if (value
== ULONG_MAX
)
916 colorval
|= (value
<< pos
);
923 XSETINT (ret
, colorval
);
931 else if (strnicmp (colorname
, "rgbi:", 5) == 0)
933 /* This is an RGB Intensity specification. */
940 color
= colorname
+ 5;
941 for (i
= 0; i
< 3; i
++)
947 value
= strtod (color
, &end
);
950 if (value
< 0.0 || value
> 1.0)
952 val
= (UINT
)(0x100 * value
);
953 /* We used 0x100 instead of 0xFF to give a continuous
954 range between 0.0 and 1.0 inclusive. The next statement
955 fixes the 1.0 case. */
958 colorval
|= (val
<< pos
);
965 XSETINT (ret
, colorval
);
973 /* I am not going to attempt to handle any of the CIE color schemes
974 or TekHVC, since I don't know the algorithms for conversion to
977 /* If we fail to lookup the color name in w32_color_map, then check the
978 colorname to see if it can be crudely approximated: If the X color
979 ends in a number (e.g., "darkseagreen2"), strip the number and
980 return the result of looking up the base color name. */
981 ret
= w32_color_map_lookup (colorname
);
984 int len
= strlen (colorname
);
986 if (isdigit (colorname
[len
- 1]))
988 char *ptr
, *approx
= alloca (len
+ 1);
990 strcpy (approx
, colorname
);
991 ptr
= &approx
[len
- 1];
992 while (ptr
> approx
&& isdigit (*ptr
))
995 ret
= w32_color_map_lookup (approx
);
1004 w32_regenerate_palette (struct frame
*f
)
1006 struct w32_palette_entry
* list
;
1007 LOGPALETTE
* log_palette
;
1008 HPALETTE new_palette
;
1011 /* don't bother trying to create palette if not supported */
1012 if (! FRAME_DISPLAY_INFO (f
)->has_palette
)
1015 log_palette
= (LOGPALETTE
*)
1016 alloca (sizeof (LOGPALETTE
) +
1017 FRAME_DISPLAY_INFO (f
)->num_colors
* sizeof (PALETTEENTRY
));
1018 log_palette
->palVersion
= 0x300;
1019 log_palette
->palNumEntries
= FRAME_DISPLAY_INFO (f
)->num_colors
;
1021 list
= FRAME_DISPLAY_INFO (f
)->color_list
;
1023 i
< FRAME_DISPLAY_INFO (f
)->num_colors
;
1024 i
++, list
= list
->next
)
1025 log_palette
->palPalEntry
[i
] = list
->entry
;
1027 new_palette
= CreatePalette (log_palette
);
1031 if (FRAME_DISPLAY_INFO (f
)->palette
)
1032 DeleteObject (FRAME_DISPLAY_INFO (f
)->palette
);
1033 FRAME_DISPLAY_INFO (f
)->palette
= new_palette
;
1035 /* Realize display palette and garbage all frames. */
1036 release_frame_dc (f
, get_frame_dc (f
));
1041 #define W32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1042 #define SET_W32_COLOR(pe, color) \
1045 pe.peRed = GetRValue (color); \
1046 pe.peGreen = GetGValue (color); \
1047 pe.peBlue = GetBValue (color); \
1052 /* Keep these around in case we ever want to track color usage. */
1054 w32_map_color (struct frame
*f
, COLORREF color
)
1056 struct w32_palette_entry
* list
= FRAME_DISPLAY_INFO (f
)->color_list
;
1058 if (NILP (Vw32_enable_palette
))
1061 /* check if color is already mapped */
1064 if (W32_COLOR (list
->entry
) == color
)
1072 /* not already mapped, so add to list and recreate Windows palette */
1073 list
= xmalloc (sizeof (struct w32_palette_entry
));
1074 SET_W32_COLOR (list
->entry
, color
);
1076 list
->next
= FRAME_DISPLAY_INFO (f
)->color_list
;
1077 FRAME_DISPLAY_INFO (f
)->color_list
= list
;
1078 FRAME_DISPLAY_INFO (f
)->num_colors
++;
1080 /* set flag that palette must be regenerated */
1081 FRAME_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1085 w32_unmap_color (struct frame
*f
, COLORREF color
)
1087 struct w32_palette_entry
* list
= FRAME_DISPLAY_INFO (f
)->color_list
;
1088 struct w32_palette_entry
**prev
= &FRAME_DISPLAY_INFO (f
)->color_list
;
1090 if (NILP (Vw32_enable_palette
))
1093 /* check if color is already mapped */
1096 if (W32_COLOR (list
->entry
) == color
)
1098 if (--list
->refcount
== 0)
1102 FRAME_DISPLAY_INFO (f
)->num_colors
--;
1112 /* set flag that palette must be regenerated */
1113 FRAME_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1118 /* Gamma-correct COLOR on frame F. */
1121 gamma_correct (struct frame
*f
, COLORREF
*color
)
1125 *color
= PALETTERGB (
1126 pow (GetRValue (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5,
1127 pow (GetGValue (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5,
1128 pow (GetBValue (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5);
1133 /* Decide if color named COLOR is valid for the display associated with
1134 the selected frame; if so, return the rgb values in COLOR_DEF.
1135 If ALLOC is nonzero, allocate a new colormap cell. */
1138 w32_defined_color (struct frame
*f
, const char *color
, XColor
*color_def
,
1141 register Lisp_Object tem
;
1142 COLORREF w32_color_ref
;
1144 tem
= x_to_w32_color (color
);
1150 /* Apply gamma correction. */
1151 w32_color_ref
= XUINT (tem
);
1152 gamma_correct (f
, &w32_color_ref
);
1153 XSETINT (tem
, w32_color_ref
);
1156 /* Map this color to the palette if it is enabled. */
1157 if (!NILP (Vw32_enable_palette
))
1159 struct w32_palette_entry
* entry
=
1160 one_w32_display_info
.color_list
;
1161 struct w32_palette_entry
** prev
=
1162 &one_w32_display_info
.color_list
;
1164 /* check if color is already mapped */
1167 if (W32_COLOR (entry
->entry
) == XUINT (tem
))
1169 prev
= &entry
->next
;
1170 entry
= entry
->next
;
1173 if (entry
== NULL
&& alloc_p
)
1175 /* not already mapped, so add to list */
1176 entry
= xmalloc (sizeof (struct w32_palette_entry
));
1177 SET_W32_COLOR (entry
->entry
, XUINT (tem
));
1180 one_w32_display_info
.num_colors
++;
1182 /* set flag that palette must be regenerated */
1183 one_w32_display_info
.regen_palette
= TRUE
;
1186 /* Ensure COLORREF value is snapped to nearest color in (default)
1187 palette by simulating the PALETTERGB macro. This works whether
1188 or not the display device has a palette. */
1189 w32_color_ref
= XUINT (tem
) | 0x2000000;
1191 color_def
->pixel
= w32_color_ref
;
1192 color_def
->red
= GetRValue (w32_color_ref
) * 256;
1193 color_def
->green
= GetGValue (w32_color_ref
) * 256;
1194 color_def
->blue
= GetBValue (w32_color_ref
) * 256;
1204 /* Given a string ARG naming a color, compute a pixel value from it
1205 suitable for screen F.
1206 If F is not a color screen, return DEF (default) regardless of what
1210 x_decode_color (struct frame
*f
, Lisp_Object arg
, int def
)
1216 if (strcmp (SSDATA (arg
), "black") == 0)
1217 return BLACK_PIX_DEFAULT (f
);
1218 else if (strcmp (SSDATA (arg
), "white") == 0)
1219 return WHITE_PIX_DEFAULT (f
);
1221 if ((FRAME_DISPLAY_INFO (f
)->n_planes
* FRAME_DISPLAY_INFO (f
)->n_cbits
) == 1)
1224 /* w32_defined_color is responsible for coping with failures
1225 by looking for a near-miss. */
1226 if (w32_defined_color (f
, SSDATA (arg
), &cdef
, true))
1229 /* defined_color failed; return an ultimate default. */
1235 /* Functions called only from `x_set_frame_param'
1236 to set individual parameters.
1238 If FRAME_W32_WINDOW (f) is 0,
1239 the frame is being created and its window does not exist yet.
1240 In that case, just record the parameter's new value
1241 in the standard place; do not attempt to change the window. */
1244 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1246 struct w32_output
*x
= f
->output_data
.w32
;
1247 PIX_TYPE fg
, old_fg
;
1249 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1250 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
1251 FRAME_FOREGROUND_PIXEL (f
) = fg
;
1253 if (FRAME_W32_WINDOW (f
) != 0)
1255 if (x
->cursor_pixel
== old_fg
)
1257 x
->cursor_pixel
= fg
;
1258 x
->cursor_gc
->background
= fg
;
1261 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1262 if (FRAME_VISIBLE_P (f
))
1268 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1270 FRAME_BACKGROUND_PIXEL (f
)
1271 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1273 if (FRAME_W32_WINDOW (f
) != 0)
1275 SetWindowLong (FRAME_W32_WINDOW (f
), WND_BACKGROUND_INDEX
,
1276 FRAME_BACKGROUND_PIXEL (f
));
1278 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1280 if (FRAME_VISIBLE_P (f
))
1286 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1289 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1294 if (!EQ (Qnil
, arg
))
1295 f
->output_data
.w32
->mouse_pixel
1296 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1297 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
1299 /* Don't let pointers be invisible. */
1300 if (mask_color
== f
->output_data
.w32
->mouse_pixel
1301 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
1302 f
->output_data
.w32
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
1304 #if 0 /* TODO : Mouse cursor customization. */
1307 /* It's not okay to crash if the user selects a screwy cursor. */
1308 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
1310 if (!EQ (Qnil
, Vx_pointer_shape
))
1312 CHECK_NUMBER (Vx_pointer_shape
);
1313 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
1316 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1317 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
1319 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1321 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1322 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1323 XINT (Vx_nontext_pointer_shape
));
1326 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
1327 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1329 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
1331 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1332 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1333 XINT (Vx_hourglass_pointer_shape
));
1336 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
1337 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
1339 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1340 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1342 CHECK_NUMBER (Vx_mode_pointer_shape
);
1343 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1344 XINT (Vx_mode_pointer_shape
));
1347 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1348 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
1350 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1352 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1354 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1355 XINT (Vx_sensitive_text_pointer_shape
));
1358 hand_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
1360 if (!NILP (Vx_window_horizontal_drag_shape
))
1362 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1363 horizontal_drag_cursor
1364 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1365 XINT (Vx_window_horizontal_drag_shape
));
1368 horizontal_drag_cursor
1369 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
1371 if (!NILP (Vx_window_vertical_drag_shape
))
1373 CHECK_NUMBER (Vx_window_vertical_drag_shape
);
1374 vertical_drag_cursor
1375 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1376 XINT (Vx_window_vertical_drag_shape
));
1379 vertical_drag_cursor
1380 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_v_double_arrow
);
1382 /* Check and report errors with the above calls. */
1383 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
1384 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
1387 XColor fore_color
, back_color
;
1389 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
1390 back_color
.pixel
= mask_color
;
1391 XQueryColor (FRAME_W32_DISPLAY (f
),
1392 DefaultColormap (FRAME_W32_DISPLAY (f
),
1393 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1395 XQueryColor (FRAME_W32_DISPLAY (f
),
1396 DefaultColormap (FRAME_W32_DISPLAY (f
),
1397 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1399 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
1400 &fore_color
, &back_color
);
1401 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
1402 &fore_color
, &back_color
);
1403 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
1404 &fore_color
, &back_color
);
1405 XRecolorCursor (FRAME_W32_DISPLAY (f
), hand_cursor
,
1406 &fore_color
, &back_color
);
1407 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
1408 &fore_color
, &back_color
);
1411 if (FRAME_W32_WINDOW (f
) != 0)
1412 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
1414 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
1415 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
1416 f
->output_data
.w32
->text_cursor
= cursor
;
1418 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
1419 && f
->output_data
.w32
->nontext_cursor
!= 0)
1420 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
1421 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
1423 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
1424 && f
->output_data
.w32
->hourglass_cursor
!= 0)
1425 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
1426 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
1428 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
1429 && f
->output_data
.w32
->modeline_cursor
!= 0)
1430 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
1431 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
1433 if (hand_cursor
!= f
->output_data
.w32
->hand_cursor
1434 && f
->output_data
.w32
->hand_cursor
!= 0)
1435 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hand_cursor
);
1436 f
->output_data
.w32
->hand_cursor
= hand_cursor
;
1438 XFlush (FRAME_W32_DISPLAY (f
));
1441 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1446 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1448 unsigned long fore_pixel
, pixel
;
1450 if (!NILP (Vx_cursor_fore_pixel
))
1451 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1452 WHITE_PIX_DEFAULT (f
));
1454 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1456 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1458 /* Make sure that the cursor color differs from the background color. */
1459 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
1461 pixel
= f
->output_data
.w32
->mouse_pixel
;
1462 if (pixel
== fore_pixel
)
1463 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1466 f
->output_data
.w32
->cursor_foreground_pixel
= fore_pixel
;
1467 f
->output_data
.w32
->cursor_pixel
= pixel
;
1469 if (FRAME_W32_WINDOW (f
) != 0)
1472 /* Update frame's cursor_gc. */
1473 f
->output_data
.w32
->cursor_gc
->foreground
= fore_pixel
;
1474 f
->output_data
.w32
->cursor_gc
->background
= pixel
;
1478 if (FRAME_VISIBLE_P (f
))
1480 x_update_cursor (f
, 0);
1481 x_update_cursor (f
, 1);
1485 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1488 /* Set the border-color of frame F to pixel value PIX.
1489 Note that this does not fully take effect if done before
1493 x_set_border_pixel (struct frame
*f
, int pix
)
1496 f
->output_data
.w32
->border_pixel
= pix
;
1498 if (FRAME_W32_WINDOW (f
) != 0 && f
->border_width
> 0)
1500 if (FRAME_VISIBLE_P (f
))
1505 /* Set the border-color of frame F to value described by ARG.
1506 ARG can be a string naming a color.
1507 The border-color is used for the border that is drawn by the server.
1508 Note that this does not fully take effect if done before
1509 F has a window; it must be redone when the window is created. */
1512 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1517 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1518 x_set_border_pixel (f
, pix
);
1519 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1524 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1526 set_frame_cursor_types (f
, arg
);
1530 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1534 if (NILP (arg
) && NILP (oldval
))
1537 if (STRINGP (arg
) && STRINGP (oldval
)
1538 && EQ (Fstring_equal (oldval
, arg
), Qt
))
1541 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
1546 result
= x_bitmap_icon (f
, arg
);
1550 error ("No icon window available");
1557 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1561 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1564 else if (!NILP (arg
) || NILP (oldval
))
1567 fset_icon_name (f
, arg
);
1570 if (f
->output_data
.w32
->icon_bitmap
!= 0)
1575 result
= x_text_icon (f
,
1576 SSDATA ((!NILP (f
->icon_name
)
1585 error ("No icon window available");
1588 /* If the window was unmapped (and its icon was mapped),
1589 the new icon is not mapped, so map the window in its stead. */
1590 if (FRAME_VISIBLE_P (f
))
1592 #ifdef USE_X_TOOLKIT
1593 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
1595 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
1598 XFlush (FRAME_W32_DISPLAY (f
));
1604 x_clear_under_internal_border (struct frame
*f
)
1606 int border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1608 /* Clear border if it's larger than before. */
1611 HDC hdc
= get_frame_dc (f
);
1612 int width
= FRAME_PIXEL_WIDTH (f
);
1613 int height
= FRAME_PIXEL_HEIGHT (f
);
1616 w32_clear_area (f
, hdc
, 0, FRAME_TOP_MARGIN_HEIGHT (f
), width
, border
);
1617 w32_clear_area (f
, hdc
, 0, 0, border
, height
);
1618 w32_clear_area (f
, hdc
, width
- border
, 0, border
, height
);
1619 w32_clear_area (f
, hdc
, 0, height
- border
, width
, border
);
1620 release_frame_dc (f
, hdc
);
1627 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1631 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1632 border
= max (XINT (arg
), 0);
1634 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1636 FRAME_INTERNAL_BORDER_WIDTH (f
) = border
;
1638 if (FRAME_X_WINDOW (f
) != 0)
1640 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1642 if (FRAME_VISIBLE_P (f
))
1643 x_clear_under_internal_border (f
);
1650 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1654 /* Right now, menu bars don't work properly in minibuf-only frames;
1655 most of the commands try to apply themselves to the minibuffer
1656 frame itself, and get an error because you can't switch buffers
1657 in or split the minibuffer window. */
1658 if (FRAME_MINIBUF_ONLY_P (f
))
1661 if (INTEGERP (value
))
1662 nlines
= XINT (value
);
1666 FRAME_MENU_BAR_LINES (f
) = 0;
1667 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1669 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1672 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1673 free_frame_menubar (f
);
1674 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1676 /* Adjust the frame size so that the client (text) dimensions
1677 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1678 set correctly. Note that we resize twice: The first time upon
1679 a request from the window manager who wants to keep the height
1680 of the outer rectangle (including decorations) unchanged, and a
1681 second time because we want to keep the height of the inner
1682 rectangle (without the decorations unchanged). */
1683 adjust_frame_size (f
, -1, -1, 2, true, Qmenu_bar_lines
);
1685 /* Not sure whether this is needed. */
1686 x_clear_under_internal_border (f
);
1691 /* Set the number of lines used for the tool bar of frame F to VALUE.
1692 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL is
1693 the old number of tool bar lines (and is unused). This function may
1694 change the height of all windows on frame F to match the new tool bar
1695 height. By design, the frame's height doesn't change (but maybe it
1696 should if we don't get enough space otherwise). */
1699 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1703 /* Treat tool bars like menu bars. */
1704 if (FRAME_MINIBUF_ONLY_P (f
))
1707 /* Use VALUE only if an integer >= 0. */
1708 if (INTEGERP (value
) && XINT (value
) >= 0)
1709 nlines
= XFASTINT (value
);
1713 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1717 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1719 x_change_tool_bar_height (struct frame
*f
, int height
)
1721 int unit
= FRAME_LINE_HEIGHT (f
);
1722 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1723 int lines
= (height
+ unit
- 1) / unit
;
1724 Lisp_Object fullscreen
;
1726 /* Make sure we redisplay all windows in this frame. */
1727 windows_or_buffers_changed
= 23;
1729 /* Recalculate tool bar and frame text sizes. */
1730 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1731 FRAME_TOOL_BAR_LINES (f
) = lines
;
1732 /* Store `tool-bar-lines' and `height' frame parameters. */
1733 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1734 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1736 if (FRAME_W32_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1739 clear_current_matrices (f
);
1742 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1743 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1745 /* Recalculate toolbar height. */
1746 f
->n_tool_bar_rows
= 0;
1748 && (!f
->after_make_frame
1749 || NILP (frame_inhibit_implied_resize
)
1750 || (CONSP (frame_inhibit_implied_resize
)
1751 && NILP (Fmemq (Qtool_bar_lines
, frame_inhibit_implied_resize
)))))
1752 f
->tool_bar_redisplayed
= f
->tool_bar_resized
= false;
1754 adjust_frame_size (f
, -1, -1,
1755 ((!f
->tool_bar_resized
1756 && (NILP (fullscreen
=
1757 get_frame_param (f
, Qfullscreen
))
1758 || EQ (fullscreen
, Qfullwidth
))) ? 1
1759 : (old_height
== 0 || height
== 0) ? 2
1761 false, Qtool_bar_lines
);
1763 f
->tool_bar_resized
= f
->tool_bar_redisplayed
;
1765 /* adjust_frame_size might not have done anything, garbage frame
1767 adjust_frame_glyphs (f
);
1768 SET_FRAME_GARBAGED (f
);
1769 if (FRAME_X_WINDOW (f
))
1770 x_clear_under_internal_border (f
);
1774 w32_set_title_bar_text (struct frame
*f
, Lisp_Object name
)
1776 if (FRAME_W32_WINDOW (f
))
1780 GUI_FN (SetWindowText
) (FRAME_W32_WINDOW (f
),
1781 GUI_SDATA (GUI_ENCODE_SYSTEM (name
)));
1783 /* The frame's title many times shows the name of the file
1784 visited in the selected window's buffer, so it makes sense to
1785 support non-ASCII characters outside of the current system
1786 codepage in the title. */
1787 if (w32_unicode_filenames
)
1789 Lisp_Object encoded_title
= ENCODE_UTF_8 (name
);
1791 int tlen
= pMultiByteToWideChar (CP_UTF8
, 0, SSDATA (encoded_title
),
1796 /* Windows truncates the title text beyond what fits on
1797 a single line, so we can limit the length to some
1798 reasonably large value, and use alloca. */
1801 title_w
= alloca ((tlen
+ 1) * sizeof (wchar_t));
1802 pMultiByteToWideChar (CP_UTF8
, 0, SSDATA (encoded_title
), -1,
1804 title_w
[tlen
] = L
'\0';
1805 SetWindowTextW (FRAME_W32_WINDOW (f
), title_w
);
1807 else /* Conversion to UTF-16 failed, so we punt. */
1808 SetWindowTextA (FRAME_W32_WINDOW (f
),
1809 SSDATA (ENCODE_SYSTEM (name
)));
1812 SetWindowTextA (FRAME_W32_WINDOW (f
), SSDATA (ENCODE_SYSTEM (name
)));
1818 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1821 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1822 name; if NAME is a string, set F's name to NAME and set
1823 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1825 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1826 suggesting a new name, which lisp code should override; if
1827 F->explicit_name is set, ignore the new name; otherwise, set it. */
1830 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1832 /* Make sure that requests from lisp code override requests from
1833 Emacs redisplay code. */
1836 /* If we're switching from explicit to implicit, we had better
1837 update the mode lines and thereby update the title. */
1838 if (f
->explicit_name
&& NILP (name
))
1839 update_mode_lines
= 25;
1841 f
->explicit_name
= ! NILP (name
);
1843 else if (f
->explicit_name
)
1846 /* If NAME is nil, set the name to the w32_id_name. */
1849 /* Check for no change needed in this very common case
1850 before we do any consing. */
1851 if (!strcmp (FRAME_DISPLAY_INFO (f
)->w32_id_name
,
1854 name
= build_string (FRAME_DISPLAY_INFO (f
)->w32_id_name
);
1857 CHECK_STRING (name
);
1859 /* Don't change the name if it's already NAME. */
1860 if (! NILP (Fstring_equal (name
, f
->name
)))
1863 fset_name (f
, name
);
1865 /* For setting the frame title, the title parameter should override
1866 the name parameter. */
1867 if (! NILP (f
->title
))
1870 w32_set_title_bar_text (f
, name
);
1873 /* This function should be called when the user's lisp code has
1874 specified a name for the frame; the name will override any set by the
1877 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1879 x_set_name (f
, arg
, true);
1882 /* This function should be called by Emacs redisplay code to set the
1883 name; names set this way will never override names set by the user's
1886 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1888 x_set_name (f
, arg
, false);
1891 /* Change the title of frame F to NAME.
1892 If NAME is nil, use the frame name as the title. */
1895 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1897 /* Don't change the title if it's already NAME. */
1898 if (EQ (name
, f
->title
))
1901 update_mode_lines
= 26;
1903 fset_title (f
, name
);
1908 w32_set_title_bar_text (f
, name
);
1912 x_set_scroll_bar_default_width (struct frame
*f
)
1914 int unit
= FRAME_COLUMN_WIDTH (f
);
1916 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = GetSystemMetrics (SM_CXVSCROLL
);
1917 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
1918 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + unit
- 1) / unit
;
1923 x_set_scroll_bar_default_height (struct frame
*f
)
1925 int unit
= FRAME_LINE_HEIGHT (f
);
1927 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = GetSystemMetrics (SM_CXHSCROLL
);
1928 FRAME_CONFIG_SCROLL_BAR_LINES (f
)
1929 = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) + unit
- 1) / unit
;
1932 /* Subroutines for creating a frame. */
1935 w32_load_cursor (LPCTSTR name
)
1937 /* Try first to load cursor from application resource. */
1938 Cursor cursor
= LoadImage ((HINSTANCE
) GetModuleHandle (NULL
),
1939 name
, IMAGE_CURSOR
, 0, 0,
1940 LR_DEFAULTCOLOR
| LR_DEFAULTSIZE
| LR_SHARED
);
1943 /* Then try to load a shared predefined cursor. */
1944 cursor
= LoadImage (NULL
, name
, IMAGE_CURSOR
, 0, 0,
1945 LR_DEFAULTCOLOR
| LR_DEFAULTSIZE
| LR_SHARED
);
1950 static LRESULT CALLBACK
w32_wnd_proc (HWND
, UINT
, WPARAM
, LPARAM
);
1952 #define INIT_WINDOW_CLASS(WC) \
1953 (WC).style = CS_HREDRAW | CS_VREDRAW; \
1954 (WC).lpfnWndProc = (WNDPROC) w32_wnd_proc; \
1955 (WC).cbClsExtra = 0; \
1956 (WC).cbWndExtra = WND_EXTRA_BYTES; \
1957 (WC).hInstance = hinst; \
1958 (WC).hIcon = LoadIcon (hinst, EMACS_CLASS); \
1959 (WC).hCursor = w32_load_cursor (IDC_ARROW); \
1960 (WC).hbrBackground = NULL; \
1961 (WC).lpszMenuName = NULL; \
1964 w32_init_class (HINSTANCE hinst
)
1966 if (w32_unicode_gui
)
1969 INIT_WINDOW_CLASS(uwc
);
1970 uwc
.lpszClassName
= L
"Emacs";
1972 return RegisterClassW (&uwc
);
1977 INIT_WINDOW_CLASS(wc
);
1978 wc
.lpszClassName
= EMACS_CLASS
;
1980 return RegisterClassA (&wc
);
1985 w32_createvscrollbar (struct frame
*f
, struct scroll_bar
* bar
)
1987 return CreateWindow ("SCROLLBAR", "", SBS_VERT
| WS_CHILD
| WS_VISIBLE
,
1988 /* Position and size of scroll bar. */
1989 bar
->left
, bar
->top
, bar
->width
, bar
->height
,
1990 FRAME_W32_WINDOW (f
), NULL
, hinst
, NULL
);
1994 w32_createhscrollbar (struct frame
*f
, struct scroll_bar
* bar
)
1996 return CreateWindow ("SCROLLBAR", "", SBS_HORZ
| WS_CHILD
| WS_VISIBLE
,
1997 /* Position and size of scroll bar. */
1998 bar
->left
, bar
->top
, bar
->width
, bar
->height
,
1999 FRAME_W32_WINDOW (f
), NULL
, hinst
, NULL
);
2003 w32_createwindow (struct frame
*f
, int *coords
)
2010 rect
.left
= rect
.top
= 0;
2011 rect
.right
= FRAME_PIXEL_WIDTH (f
);
2012 rect
.bottom
= FRAME_PIXEL_HEIGHT (f
);
2014 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
,
2015 FRAME_EXTERNAL_MENU_BAR (f
));
2017 /* Do first time app init */
2019 w32_init_class (hinst
);
2021 if (f
->size_hint_flags
& USPosition
|| f
->size_hint_flags
& PPosition
)
2032 FRAME_W32_WINDOW (f
) = hwnd
2033 = CreateWindow (EMACS_CLASS
,
2035 f
->output_data
.w32
->dwStyle
| WS_CLIPCHILDREN
,
2037 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
2045 SetWindowLong (hwnd
, WND_FONTWIDTH_INDEX
, FRAME_COLUMN_WIDTH (f
));
2046 SetWindowLong (hwnd
, WND_LINEHEIGHT_INDEX
, FRAME_LINE_HEIGHT (f
));
2047 SetWindowLong (hwnd
, WND_BORDER_INDEX
, FRAME_INTERNAL_BORDER_WIDTH (f
));
2048 SetWindowLong (hwnd
, WND_VSCROLLBAR_INDEX
, FRAME_SCROLL_BAR_AREA_WIDTH (f
));
2049 SetWindowLong (hwnd
, WND_HSCROLLBAR_INDEX
, FRAME_SCROLL_BAR_AREA_HEIGHT (f
));
2050 SetWindowLong (hwnd
, WND_BACKGROUND_INDEX
, FRAME_BACKGROUND_PIXEL (f
));
2052 /* Enable drag-n-drop. */
2053 DragAcceptFiles (hwnd
, TRUE
);
2055 /* Do this to discard the default setting specified by our parent. */
2056 ShowWindow (hwnd
, SW_HIDE
);
2058 /* Update frame positions. */
2059 GetWindowRect (hwnd
, &rect
);
2060 f
->left_pos
= rect
.left
;
2061 f
->top_pos
= rect
.top
;
2066 my_post_msg (W32Msg
* wmsg
, HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2068 wmsg
->msg
.hwnd
= hwnd
;
2069 wmsg
->msg
.message
= msg
;
2070 wmsg
->msg
.wParam
= wParam
;
2071 wmsg
->msg
.lParam
= lParam
;
2072 wmsg
->msg
.time
= GetMessageTime ();
2077 /* GetKeyState and MapVirtualKey on Windows 95 do not actually distinguish
2078 between left and right keys as advertised. We test for this
2079 support dynamically, and set a flag when the support is absent. If
2080 absent, we keep track of the left and right control and alt keys
2081 ourselves. This is particularly necessary on keyboards that rely
2082 upon the AltGr key, which is represented as having the left control
2083 and right alt keys pressed. For these keyboards, we need to know
2084 when the left alt key has been pressed in addition to the AltGr key
2085 so that we can properly support M-AltGr-key sequences (such as M-@
2086 on Swedish keyboards). */
2088 #define EMACS_LCONTROL 0
2089 #define EMACS_RCONTROL 1
2090 #define EMACS_LMENU 2
2091 #define EMACS_RMENU 3
2093 static int modifiers
[4];
2094 static int modifiers_recorded
;
2095 static int modifier_key_support_tested
;
2098 test_modifier_support (unsigned int wparam
)
2102 if (wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
)
2104 if (wparam
== VK_CONTROL
)
2114 if (!(GetKeyState (l
) & 0x8000) && !(GetKeyState (r
) & 0x8000))
2115 modifiers_recorded
= 1;
2117 modifiers_recorded
= 0;
2118 modifier_key_support_tested
= 1;
2122 record_keydown (unsigned int wparam
, unsigned int lparam
)
2126 if (!modifier_key_support_tested
)
2127 test_modifier_support (wparam
);
2129 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
2132 if (wparam
== VK_CONTROL
)
2133 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
2135 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
2141 record_keyup (unsigned int wparam
, unsigned int lparam
)
2145 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
2148 if (wparam
== VK_CONTROL
)
2149 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
2151 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
2156 /* Emacs can lose focus while a modifier key has been pressed. When
2157 it regains focus, be conservative and clear all modifiers since
2158 we cannot reconstruct the left and right modifier state. */
2160 reset_modifiers (void)
2164 if (GetFocus () == NULL
)
2165 /* Emacs doesn't have keyboard focus. Do nothing. */
2168 ctrl
= GetAsyncKeyState (VK_CONTROL
);
2169 alt
= GetAsyncKeyState (VK_MENU
);
2171 if (!(ctrl
& 0x08000))
2172 /* Clear any recorded control modifier state. */
2173 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
2175 if (!(alt
& 0x08000))
2176 /* Clear any recorded alt modifier state. */
2177 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
2179 /* Update the state of all modifier keys, because modifiers used in
2180 hot-key combinations can get stuck on if Emacs loses focus as a
2181 result of a hot-key being pressed. */
2185 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
2187 memset (keystate
, 0, sizeof (keystate
));
2188 GetKeyboardState (keystate
);
2189 keystate
[VK_SHIFT
] = CURRENT_STATE (VK_SHIFT
);
2190 keystate
[VK_CONTROL
] = CURRENT_STATE (VK_CONTROL
);
2191 keystate
[VK_LCONTROL
] = CURRENT_STATE (VK_LCONTROL
);
2192 keystate
[VK_RCONTROL
] = CURRENT_STATE (VK_RCONTROL
);
2193 keystate
[VK_MENU
] = CURRENT_STATE (VK_MENU
);
2194 keystate
[VK_LMENU
] = CURRENT_STATE (VK_LMENU
);
2195 keystate
[VK_RMENU
] = CURRENT_STATE (VK_RMENU
);
2196 keystate
[VK_LWIN
] = CURRENT_STATE (VK_LWIN
);
2197 keystate
[VK_RWIN
] = CURRENT_STATE (VK_RWIN
);
2198 keystate
[VK_APPS
] = CURRENT_STATE (VK_APPS
);
2199 SetKeyboardState (keystate
);
2203 /* Synchronize modifier state with what is reported with the current
2204 keystroke. Even if we cannot distinguish between left and right
2205 modifier keys, we know that, if no modifiers are set, then neither
2206 the left or right modifier should be set. */
2208 sync_modifiers (void)
2210 if (!modifiers_recorded
)
2213 if (!(GetKeyState (VK_CONTROL
) & 0x8000))
2214 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
2216 if (!(GetKeyState (VK_MENU
) & 0x8000))
2217 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
2221 modifier_set (int vkey
)
2223 /* Warning: The fact that VK_NUMLOCK is not treated as the other 2
2224 toggle keys is not an omission! If you want to add it, you will
2225 have to make changes in the default sub-case of the WM_KEYDOWN
2226 switch, because if the NUMLOCK modifier is set, the code there
2227 will directly convert any key that looks like an ASCII letter,
2228 and also downcase those that look like upper-case ASCII. */
2229 if (vkey
== VK_CAPITAL
)
2231 if (NILP (Vw32_enable_caps_lock
))
2234 return (GetKeyState (vkey
) & 0x1);
2236 if (vkey
== VK_SCROLL
)
2238 if (NILP (Vw32_scroll_lock_modifier
)
2239 /* w32-scroll-lock-modifier can be any non-nil value that is
2240 not one of the modifiers, in which case it shall be ignored. */
2241 || !( EQ (Vw32_scroll_lock_modifier
, Qhyper
)
2242 || EQ (Vw32_scroll_lock_modifier
, Qsuper
)
2243 || EQ (Vw32_scroll_lock_modifier
, Qmeta
)
2244 || EQ (Vw32_scroll_lock_modifier
, Qalt
)
2245 || EQ (Vw32_scroll_lock_modifier
, Qcontrol
)
2246 || EQ (Vw32_scroll_lock_modifier
, Qshift
)))
2249 return (GetKeyState (vkey
) & 0x1);
2252 if (!modifiers_recorded
)
2253 return (GetKeyState (vkey
) & 0x8000);
2258 return modifiers
[EMACS_LCONTROL
];
2260 return modifiers
[EMACS_RCONTROL
];
2262 return modifiers
[EMACS_LMENU
];
2264 return modifiers
[EMACS_RMENU
];
2266 return (GetKeyState (vkey
) & 0x8000);
2269 /* Convert between the modifier bits W32 uses and the modifier bits
2273 w32_key_to_modifier (int key
)
2275 Lisp_Object key_mapping
;
2280 key_mapping
= Vw32_lwindow_modifier
;
2283 key_mapping
= Vw32_rwindow_modifier
;
2286 key_mapping
= Vw32_apps_modifier
;
2289 key_mapping
= Vw32_scroll_lock_modifier
;
2295 /* NB. This code runs in the input thread, asynchronously to the lisp
2296 thread, so we must be careful to ensure access to lisp data is
2297 thread-safe. The following code is safe because the modifier
2298 variable values are updated atomically from lisp and symbols are
2299 not relocated by GC. Also, we don't have to worry about seeing GC
2301 if (EQ (key_mapping
, Qhyper
))
2302 return hyper_modifier
;
2303 if (EQ (key_mapping
, Qsuper
))
2304 return super_modifier
;
2305 if (EQ (key_mapping
, Qmeta
))
2306 return meta_modifier
;
2307 if (EQ (key_mapping
, Qalt
))
2308 return alt_modifier
;
2309 if (EQ (key_mapping
, Qctrl
))
2310 return ctrl_modifier
;
2311 if (EQ (key_mapping
, Qcontrol
)) /* synonym for ctrl */
2312 return ctrl_modifier
;
2313 if (EQ (key_mapping
, Qshift
))
2314 return shift_modifier
;
2316 /* Don't generate any modifier if not explicitly requested. */
2321 w32_get_modifiers (void)
2323 return ((modifier_set (VK_SHIFT
) ? shift_modifier
: 0) |
2324 (modifier_set (VK_CONTROL
) ? ctrl_modifier
: 0) |
2325 (modifier_set (VK_LWIN
) ? w32_key_to_modifier (VK_LWIN
) : 0) |
2326 (modifier_set (VK_RWIN
) ? w32_key_to_modifier (VK_RWIN
) : 0) |
2327 (modifier_set (VK_APPS
) ? w32_key_to_modifier (VK_APPS
) : 0) |
2328 (modifier_set (VK_SCROLL
) ? w32_key_to_modifier (VK_SCROLL
) : 0) |
2329 (modifier_set (VK_MENU
) ?
2330 ((NILP (Vw32_alt_is_meta
)) ? alt_modifier
: meta_modifier
) : 0));
2333 /* We map the VK_* modifiers into console modifier constants
2334 so that we can use the same routines to handle both console
2335 and window input. */
2338 construct_console_modifiers (void)
2343 mods
|= (modifier_set (VK_SHIFT
)) ? SHIFT_PRESSED
: 0;
2344 mods
|= (modifier_set (VK_CAPITAL
)) ? CAPSLOCK_ON
: 0;
2345 mods
|= (modifier_set (VK_SCROLL
)) ? SCROLLLOCK_ON
: 0;
2346 mods
|= (modifier_set (VK_NUMLOCK
)) ? NUMLOCK_ON
: 0;
2347 mods
|= (modifier_set (VK_LCONTROL
)) ? LEFT_CTRL_PRESSED
: 0;
2348 mods
|= (modifier_set (VK_RCONTROL
)) ? RIGHT_CTRL_PRESSED
: 0;
2349 mods
|= (modifier_set (VK_LMENU
)) ? LEFT_ALT_PRESSED
: 0;
2350 mods
|= (modifier_set (VK_RMENU
)) ? RIGHT_ALT_PRESSED
: 0;
2351 mods
|= (modifier_set (VK_LWIN
)) ? LEFT_WIN_PRESSED
: 0;
2352 mods
|= (modifier_set (VK_RWIN
)) ? RIGHT_WIN_PRESSED
: 0;
2353 mods
|= (modifier_set (VK_APPS
)) ? APPS_PRESSED
: 0;
2359 w32_get_key_modifiers (unsigned int wparam
, unsigned int lparam
)
2363 /* Convert to emacs modifiers. */
2364 mods
= w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam
);
2370 map_keypad_keys (unsigned int virt_key
, unsigned int extended
)
2372 if (virt_key
< VK_CLEAR
|| virt_key
> VK_DELETE
)
2375 if (virt_key
== VK_RETURN
)
2376 return (extended
? VK_NUMPAD_ENTER
: VK_RETURN
);
2378 if (virt_key
>= VK_PRIOR
&& virt_key
<= VK_DOWN
)
2379 return (!extended
? (VK_NUMPAD_PRIOR
+ (virt_key
- VK_PRIOR
)) : virt_key
);
2381 if (virt_key
== VK_INSERT
|| virt_key
== VK_DELETE
)
2382 return (!extended
? (VK_NUMPAD_INSERT
+ (virt_key
- VK_INSERT
)) : virt_key
);
2384 if (virt_key
== VK_CLEAR
)
2385 return (!extended
? VK_NUMPAD_CLEAR
: virt_key
);
2390 /* List of special key combinations which w32 would normally capture,
2391 but Emacs should grab instead. Not directly visible to lisp, to
2392 simplify synchronization. Each item is an integer encoding a virtual
2393 key code and modifier combination to capture. */
2394 static Lisp_Object w32_grabbed_keys
;
2396 #define HOTKEY(vk, mods) make_number (((vk) & 255) | ((mods) << 8))
2397 #define HOTKEY_ID(k) (XFASTINT (k) & 0xbfff)
2398 #define HOTKEY_VK_CODE(k) (XFASTINT (k) & 255)
2399 #define HOTKEY_MODIFIERS(k) (XFASTINT (k) >> 8)
2401 #define RAW_HOTKEY_ID(k) ((k) & 0xbfff)
2402 #define RAW_HOTKEY_VK_CODE(k) ((k) & 255)
2403 #define RAW_HOTKEY_MODIFIERS(k) ((k) >> 8)
2405 /* Register hot-keys for reserved key combinations when Emacs has
2406 keyboard focus, since this is the only way Emacs can receive key
2407 combinations like Alt-Tab which are used by the system. */
2410 register_hot_keys (HWND hwnd
)
2412 Lisp_Object keylist
;
2414 /* Use CONSP, since we are called asynchronously. */
2415 for (keylist
= w32_grabbed_keys
; CONSP (keylist
); keylist
= XCDR (keylist
))
2417 Lisp_Object key
= XCAR (keylist
);
2419 /* Deleted entries get set to nil. */
2420 if (!INTEGERP (key
))
2423 RegisterHotKey (hwnd
, HOTKEY_ID (key
),
2424 HOTKEY_MODIFIERS (key
), HOTKEY_VK_CODE (key
));
2429 unregister_hot_keys (HWND hwnd
)
2431 Lisp_Object keylist
;
2433 for (keylist
= w32_grabbed_keys
; CONSP (keylist
); keylist
= XCDR (keylist
))
2435 Lisp_Object key
= XCAR (keylist
);
2437 if (!INTEGERP (key
))
2440 UnregisterHotKey (hwnd
, HOTKEY_ID (key
));
2446 w32_name_of_message (UINT msg
)
2449 static char buf
[64];
2450 static const struct {
2454 #define M(msg) { msg, # msg }
2462 M (WM_EMACS_CREATEWINDOW
),
2464 M (WM_EMACS_CREATEVSCROLLBAR
),
2465 M (WM_EMACS_CREATEHSCROLLBAR
),
2466 M (WM_EMACS_SHOWWINDOW
),
2467 M (WM_EMACS_SETWINDOWPOS
),
2468 M (WM_EMACS_DESTROYWINDOW
),
2469 M (WM_EMACS_TRACKPOPUPMENU
),
2470 M (WM_EMACS_SETFOCUS
),
2471 M (WM_EMACS_SETFOREGROUND
),
2472 M (WM_EMACS_SETLOCALE
),
2473 M (WM_EMACS_SETKEYBOARDLAYOUT
),
2474 M (WM_EMACS_REGISTER_HOT_KEY
),
2475 M (WM_EMACS_UNREGISTER_HOT_KEY
),
2476 M (WM_EMACS_TOGGLE_LOCK_KEY
),
2477 M (WM_EMACS_TRACK_CARET
),
2478 M (WM_EMACS_DESTROY_CARET
),
2479 M (WM_EMACS_SHOW_CARET
),
2480 M (WM_EMACS_HIDE_CARET
),
2481 M (WM_EMACS_SETCURSOR
),
2482 M (WM_EMACS_SHOWCURSOR
),
2489 for (i
= 0; msgnames
[i
].name
; ++i
)
2490 if (msgnames
[i
].msg
== msg
)
2491 return msgnames
[i
].name
;
2493 sprintf (buf
, "message 0x%04x", (unsigned)msg
);
2496 #endif /* EMACSDEBUG */
2498 /* Here's an overview of how Emacs input works in GUI sessions on
2499 MS-Windows. (For description of non-GUI input, see the commentary
2500 before w32_console_read_socket in w32inevt.c.)
2502 System messages are read and processed by w32_msg_pump below. This
2503 function runs in a separate thread. It handles a small number of
2504 custom WM_EMACS_* messages (posted by the main thread, look for
2505 PostMessage calls), and dispatches the rest to w32_wnd_proc, which
2506 is the main window procedure for the entire Emacs application.
2508 w32_wnd_proc also runs in the same separate input thread. It
2509 handles some messages, mostly those that need GDI calls, by itself.
2510 For the others, it calls my_post_msg, which inserts the messages
2511 into the input queue serviced by w32_read_socket.
2513 w32_read_socket runs in the main (a.k.a. "Lisp") thread, and is
2514 called synchronously from keyboard.c when it is known or suspected
2515 that some input is available. w32_read_socket either handles
2516 messages immediately, or converts them into Emacs input events and
2517 stuffs them into kbd_buffer, where kbd_buffer_get_event can get at
2518 them and process them when read_char and its callers require
2521 Under Cygwin with the W32 toolkit, the use of /dev/windows with
2522 select(2) takes the place of w32_read_socket.
2526 /* Main message dispatch loop. */
2529 w32_msg_pump (deferred_msg
* msg_buf
)
2535 msh_mousewheel
= RegisterWindowMessage (MSH_MOUSEWHEEL
);
2537 while ((w32_unicode_gui
? GetMessageW
: GetMessageA
) (&msg
, NULL
, 0, 0))
2540 /* DebPrint (("w32_msg_pump: %s time:%u\n", */
2541 /* w32_name_of_message (msg.message), msg.time)); */
2543 if (msg
.hwnd
== NULL
)
2545 switch (msg
.message
)
2548 /* Produced by complete_deferred_msg; just ignore. */
2550 case WM_EMACS_CREATEWINDOW
:
2551 /* Initialize COM for this window. Even though we don't use it,
2552 some third party shell extensions can cause it to be used in
2553 system dialogs, which causes a crash if it is not initialized.
2554 This is a known bug in Windows, which was fixed long ago, but
2555 the patch for XP is not publicly available until XP SP3,
2556 and older versions will never be patched. */
2557 CoInitialize (NULL
);
2558 w32_createwindow ((struct frame
*) msg
.wParam
,
2559 (int *) msg
.lParam
);
2560 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
2563 case WM_EMACS_SETLOCALE
:
2564 SetThreadLocale (msg
.wParam
);
2565 /* Reply is not expected. */
2567 case WM_EMACS_SETKEYBOARDLAYOUT
:
2568 result
= (WPARAM
) ActivateKeyboardLayout ((HKL
) msg
.wParam
, 0);
2569 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
2573 case WM_EMACS_REGISTER_HOT_KEY
:
2574 focus_window
= GetFocus ();
2575 if (focus_window
!= NULL
)
2576 RegisterHotKey (focus_window
,
2577 RAW_HOTKEY_ID (msg
.wParam
),
2578 RAW_HOTKEY_MODIFIERS (msg
.wParam
),
2579 RAW_HOTKEY_VK_CODE (msg
.wParam
));
2580 /* Reply is not expected. */
2582 case WM_EMACS_UNREGISTER_HOT_KEY
:
2583 focus_window
= GetFocus ();
2584 if (focus_window
!= NULL
)
2585 UnregisterHotKey (focus_window
, RAW_HOTKEY_ID (msg
.wParam
));
2586 /* Mark item as erased. NB: this code must be
2587 thread-safe. The next line is okay because the cons
2588 cell is never made into garbage and is not relocated by
2590 XSETCAR (make_lisp_ptr ((void *)msg
.lParam
, Lisp_Cons
), Qnil
);
2591 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
2594 case WM_EMACS_TOGGLE_LOCK_KEY
:
2596 int vk_code
= (int) msg
.wParam
;
2597 int cur_state
= (GetKeyState (vk_code
) & 1);
2598 int new_state
= msg
.lParam
;
2601 || ((new_state
& 1) != cur_state
))
2603 one_w32_display_info
.faked_key
= vk_code
;
2605 keybd_event ((BYTE
) vk_code
,
2606 (BYTE
) MapVirtualKey (vk_code
, 0),
2607 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
2608 keybd_event ((BYTE
) vk_code
,
2609 (BYTE
) MapVirtualKey (vk_code
, 0),
2610 KEYEVENTF_EXTENDEDKEY
| 0, 0);
2611 keybd_event ((BYTE
) vk_code
,
2612 (BYTE
) MapVirtualKey (vk_code
, 0),
2613 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
2614 cur_state
= !cur_state
;
2616 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
2622 /* Broadcast messages make it here, so you need to be looking
2623 for something in particular for this to be useful. */
2625 DebPrint (("msg %x not expected by w32_msg_pump\n", msg
.message
));
2631 if (w32_unicode_gui
)
2632 DispatchMessageW (&msg
);
2634 DispatchMessageA (&msg
);
2637 /* Exit nested loop when our deferred message has completed. */
2638 if (msg_buf
->completed
)
2643 deferred_msg
* deferred_msg_head
;
2645 static deferred_msg
*
2646 find_deferred_msg (HWND hwnd
, UINT msg
)
2648 deferred_msg
* item
;
2650 /* Don't actually need synchronization for read access, since
2651 modification of single pointer is always atomic. */
2652 /* enter_crit (); */
2654 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
2655 if (item
->w32msg
.msg
.hwnd
== hwnd
2656 && item
->w32msg
.msg
.message
== msg
)
2659 /* leave_crit (); */
2665 send_deferred_msg (deferred_msg
* msg_buf
,
2671 /* Only input thread can send deferred messages. */
2672 if (GetCurrentThreadId () != dwWindowsThreadId
)
2675 /* It is an error to send a message that is already deferred. */
2676 if (find_deferred_msg (hwnd
, msg
) != NULL
)
2679 /* Enforced synchronization is not needed because this is the only
2680 function that alters deferred_msg_head, and the following critical
2681 section is guaranteed to only be serially reentered (since only the
2682 input thread can call us). */
2684 /* enter_crit (); */
2686 msg_buf
->completed
= 0;
2687 msg_buf
->next
= deferred_msg_head
;
2688 deferred_msg_head
= msg_buf
;
2689 my_post_msg (&msg_buf
->w32msg
, hwnd
, msg
, wParam
, lParam
);
2691 /* leave_crit (); */
2693 /* Start a new nested message loop to process other messages until
2694 this one is completed. */
2695 w32_msg_pump (msg_buf
);
2697 deferred_msg_head
= msg_buf
->next
;
2699 return msg_buf
->result
;
2703 complete_deferred_msg (HWND hwnd
, UINT msg
, LRESULT result
)
2705 deferred_msg
* msg_buf
= find_deferred_msg (hwnd
, msg
);
2707 if (msg_buf
== NULL
)
2708 /* Message may have been canceled, so don't abort. */
2711 msg_buf
->result
= result
;
2712 msg_buf
->completed
= 1;
2714 /* Ensure input thread is woken so it notices the completion. */
2715 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
2719 cancel_all_deferred_msgs (void)
2721 deferred_msg
* item
;
2723 /* Don't actually need synchronization for read access, since
2724 modification of single pointer is always atomic. */
2725 /* enter_crit (); */
2727 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
2730 item
->completed
= 1;
2733 /* leave_crit (); */
2735 /* Ensure input thread is woken so it notices the completion. */
2736 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
2740 w32_msg_worker (void *arg
)
2743 deferred_msg dummy_buf
;
2745 /* Ensure our message queue is created */
2747 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
2749 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
2752 memset (&dummy_buf
, 0, sizeof (dummy_buf
));
2753 dummy_buf
.w32msg
.msg
.hwnd
= NULL
;
2754 dummy_buf
.w32msg
.msg
.message
= WM_NULL
;
2756 /* This is the initial message loop which should only exit when the
2757 application quits. */
2758 w32_msg_pump (&dummy_buf
);
2764 signal_user_input (void)
2766 /* Interrupt any lisp that wants to be interrupted by input. */
2767 if (!NILP (Vthrow_on_input
))
2769 Vquit_flag
= Vthrow_on_input
;
2770 /* Doing a QUIT from this thread is a bad idea, since this
2771 unwinds the stack of the Lisp thread, and the Windows runtime
2772 rightfully barfs. Disabled. */
2774 /* If we're inside a function that wants immediate quits,
2776 if (immediate_quit
&& NILP (Vinhibit_quit
))
2787 post_character_message (HWND hwnd
, UINT msg
,
2788 WPARAM wParam
, LPARAM lParam
,
2793 wmsg
.dwModifiers
= modifiers
;
2795 /* Detect quit_char and set quit-flag directly. Note that we
2796 still need to post a message to ensure the main thread will be
2797 woken up if blocked in sys_select, but we do NOT want to post
2798 the quit_char message itself (because it will usually be as if
2799 the user had typed quit_char twice). Instead, we post a dummy
2800 message that has no particular effect. */
2803 if (isalpha (c
) && wmsg
.dwModifiers
== ctrl_modifier
)
2804 c
= make_ctrl_char (c
) & 0377;
2806 || (wmsg
.dwModifiers
== 0
2807 && w32_quit_key
&& wParam
== w32_quit_key
))
2811 /* The choice of message is somewhat arbitrary, as long as
2812 the main thread handler just ignores it. */
2815 /* Interrupt any blocking system calls. */
2818 /* As a safety precaution, forcibly complete any deferred
2819 messages. This is a kludge, but I don't see any particularly
2820 clean way to handle the situation where a deferred message is
2821 "dropped" in the lisp thread, and will thus never be
2822 completed, eg. by the user trying to activate the menubar
2823 when the lisp thread is busy, and then typing C-g when the
2824 menubar doesn't open promptly (with the result that the
2825 menubar never responds at all because the deferred
2826 WM_INITMENU message is never completed). Another problem
2827 situation is when the lisp thread calls SendMessage (to send
2828 a window manager command) when a message has been deferred;
2829 the lisp thread gets blocked indefinitely waiting for the
2830 deferred message to be completed, which itself is waiting for
2831 the lisp thread to respond.
2833 Note that we don't want to block the input thread waiting for
2834 a response from the lisp thread (although that would at least
2835 solve the deadlock problem above), because we want to be able
2836 to receive C-g to interrupt the lisp thread. */
2837 cancel_all_deferred_msgs ();
2840 signal_user_input ();
2843 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
2847 get_wm_chars (HWND aWnd
, int *buf
, int buflen
, int ignore_ctrl
, int ctrl
,
2848 int *ctrl_cnt
, int *is_dead
, int vk
, int exp
)
2851 /* If doubled is at the end, ignore it. */
2852 int i
= buflen
, doubled
= 0, code_unit
;
2858 eassert (w32_unicode_gui
);
2860 /* Should be called only when w32_unicode_gui: */
2861 && PeekMessageW (&msg
, aWnd
, WM_KEYFIRST
, WM_KEYLAST
,
2862 PM_NOREMOVE
| PM_NOYIELD
)
2863 && (msg
.message
== WM_CHAR
|| msg
.message
== WM_SYSCHAR
2864 || msg
.message
== WM_DEADCHAR
|| msg
.message
== WM_SYSDEADCHAR
2865 || msg
.message
== WM_UNICHAR
))
2867 /* We extract character payload, but in this call we handle only the
2868 characters which come BEFORE the next keyup/keydown message. */
2871 GetMessageW (&msg
, aWnd
, msg
.message
, msg
.message
);
2872 dead
= (msg
.message
== WM_DEADCHAR
|| msg
.message
== WM_SYSDEADCHAR
);
2874 *is_dead
= (dead
? msg
.wParam
: -1);
2877 code_unit
= msg
.wParam
;
2880 /* Had surrogate. */
2881 if (msg
.message
== WM_UNICHAR
2882 || code_unit
< 0xDC00 || code_unit
> 0xDFFF)
2883 { /* Mismatched first surrogate.
2884 Pass both code units as if they were two characters. */
2887 return i
; /* Drop the 2nd char if at the end of the buffer. */
2889 else /* see https://en.wikipedia.org/wiki/UTF-16 */
2890 code_unit
= (doubled
<< 10) + code_unit
- 0x35FDC00;
2893 else if (code_unit
>= 0xD800 && code_unit
<= 0xDBFF)
2895 /* Handle mismatched 2nd surrogate the same as a normal character. */
2896 doubled
= code_unit
;
2900 /* The only "fake" characters delivered by ToUnicode() or
2901 TranslateMessage() are:
2902 0x01 .. 0x1a for Ctrl-letter, Enter, Tab, Ctrl-Break, Esc, Backspace
2903 0x00 and 0x1b .. 0x1f for Control- []\@^_
2904 0x7f for Control-BackSpace
2905 0x20 for Control-Space */
2907 && (code_unit
< 0x20 || code_unit
== 0x7f
2908 || (code_unit
== 0x20 && ctrl
)))
2910 /* Non-character payload in a WM_CHAR
2911 (Ctrl-something pressed, see above). Ignore, and report. */
2916 /* Traditionally, Emacs would ignore the character payload of VK_NUMPAD*
2917 keys, and would treat them later via `function-key-map'. In addition
2918 to usual 102-key NUMPAD keys, this map also treats `kp-'-variants of
2919 space, tab, enter, separator, equal. TAB and EQUAL, apparently,
2920 cannot be generated on Win-GUI branch. ENTER is already handled
2921 by the code above. According to `lispy_function_keys', kp_space is
2922 generated by not-extended VK_CLEAR. (kp-tab != VK_OEM_NEC_EQUAL!).
2924 We do similarly for backward-compatibility, but ignore only the
2925 characters restorable later by `function-key-map'. */
2926 if (code_unit
< 0x7f
2927 && ((vk
>= VK_NUMPAD0
&& vk
<= VK_DIVIDE
)
2928 || (exp
&& ((vk
>= VK_PRIOR
&& vk
<= VK_DOWN
) ||
2929 vk
== VK_INSERT
|| vk
== VK_DELETE
|| vk
== VK_CLEAR
)))
2930 && strchr ("0123456789/*-+.,", code_unit
))
2939 # define FPRINTF_WM_CHARS(ARG) fprintf ARG
2941 # define FPRINTF_WM_CHARS(ARG) (void)0
2944 /* This is a heuristic only. This is supposed to track the state of the
2945 finite automaton in the language environment of Windows.
2947 However, separate windows (if with the same different language
2948 environments!) should have different values. Moreover, switching to a
2949 non-Emacs window with the same language environment, and using (dead)keys
2950 there would change the value stored in the kernel, but not this value. */
2951 /* A layout may emit deadkey=0. It looks like this would reset the state
2952 of the kernel's finite automaton (equivalent to emiting 0-length string,
2953 which is otherwise impossible in the dead-key map of a layout).
2954 Be ready to treat the case when this delivers WM_(SYS)DEADCHAR. */
2955 static int after_deadkey
= -1;
2958 deliver_wm_chars (int do_translate
, HWND hwnd
, UINT msg
, UINT wParam
,
2959 UINT lParam
, int legacy_alt_meta
)
2961 /* An "old style" keyboard description may assign up to 125 UTF-16 code
2962 points to a keypress.
2963 (However, the "old style" TranslateMessage() would deliver at most 16 of
2964 them.) Be on a safe side, and prepare to treat many more. */
2965 int ctrl_cnt
, buf
[1024], count
, is_dead
, after_dead
= (after_deadkey
> 0);
2967 /* Since the keypress processing logic of Windows has a lot of state, it
2968 is important to call TranslateMessage() for every keyup/keydown, AND
2969 do it exactly once. (The actual change of state is done by
2970 ToUnicode[Ex](), which is called by TranslateMessage(). So one can
2971 call ToUnicode[Ex]() instead.)
2973 The "usual" message pump calls TranslateMessage() for EVERY event.
2974 Emacs calls TranslateMessage() very selectively (is it needed for doing
2975 some tricky stuff with Win95??? With newer Windows, selectiveness is,
2976 most probably, not needed -- and harms a lot).
2978 So, with the usual message pump, the following call to TranslateMessage()
2979 is not needed (and is going to be VERY harmful). With Emacs' message
2980 pump, the call is needed. */
2983 MSG windows_msg
= { hwnd
, msg
, wParam
, lParam
, 0, {0,0} };
2985 windows_msg
.time
= GetMessageTime ();
2986 TranslateMessage (&windows_msg
);
2988 count
= get_wm_chars (hwnd
, buf
, sizeof (buf
)/sizeof (*buf
), 1,
2989 /* The message may have been synthesized by
2990 who knows what; be conservative. */
2991 modifier_set (VK_LCONTROL
)
2992 || modifier_set (VK_RCONTROL
)
2993 || modifier_set (VK_CONTROL
),
2994 &ctrl_cnt
, &is_dead
, wParam
,
2995 (lParam
& 0x1000000L
) != 0);
2999 DWORD console_modifiers
= construct_console_modifiers ();
3000 int *b
= buf
, strip_ExtraMods
= 1, hairy
= 0;
3001 char *type_CtrlAlt
= NULL
;
3003 /* XXXX In fact, there may be another case when we need to do the same:
3004 What happens if the string defined in the LIGATURES has length
3005 0? Probably, we will get count==0, but the state of the finite
3006 automaton would reset to 0??? */
3009 /* wParam is checked when converting CapsLock to Shift; this is a clone
3010 of w32_get_key_modifiers (). */
3011 wmsg
.dwModifiers
= w32_kbd_mods_to_emacs (console_modifiers
, wParam
);
3013 /* What follows is just heuristics; the correct treatement requires
3014 non-destructive ToUnicode():
3015 http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Can_an_application_on_Windows_accept_keyboard_events?_Part_IV:_application-specific_modifiers
3017 What one needs to find is:
3018 * which of the present modifiers AFFECT the resulting char(s)
3019 (so should be stripped, since their EFFECT is "already
3020 taken into account" in the string in buf), and
3021 * which modifiers are not affecting buf, so should be reported to
3022 the application for further treatment.
3024 Example: assume that we know:
3025 (A) lCtrl+rCtrl+rAlt modifiers with VK_A key produce a Latin "f"
3026 ("may be logical" in JCUKEN-flavored Russian keyboard flavors);
3027 (B) removing any of lCtrl, rCtrl, rAlt changes the produced char;
3028 (C) Win-modifier is not affecting the produced character
3029 (this is the common case: happens with all "standard" layouts).
3031 Suppose the user presses Win+lCtrl+rCtrl+rAlt modifiers with VK_A.
3032 What is the intent of the user? We need to guess the intent to decide
3033 which event to deliver to the application.
3035 This looks like a reasonable logic: since Win- modifier doesn't affect
3036 the output string, the user was pressing Win for SOME OTHER purpose.
3037 So the user wanted to generate Win-SOMETHING event. Now, what is
3038 something? If one takes the mantra that "character payload is more
3039 important than the combination of keypresses which resulted in this
3040 payload", then one should ignore lCtrl+rCtrl+rAlt, ignore VK_A, and
3041 assume that the user wanted to generate Win-f.
3043 Unfortunately, without non-destructive ToUnicode(), checking (B),(C)
3044 is out of question. So we use heuristics (hopefully, covering
3045 99.9999% of cases). */
3047 /* Another thing to watch for is a possibility to use AltGr-* and
3048 Ctrl-Alt-* with different semantic.
3050 Background: the layout defining the KLLF_ALTGR bit are treated
3051 specially by the kernel: when VK_RMENU (=rightAlt, =AltGr) is pressed
3052 (released), a press (release) of VK_LCONTROL is emulated (unless Ctrl
3053 is already down). As a result, any press/release of AltGr is seen
3054 by applications as a press/release of lCtrl AND rAlt. This is
3055 applicable, in particular, to ToUnicode[Ex](). (Keyrepeat is covered
3058 NOTE: it IS possible to see bare rAlt even with KLLF_ALTGR; but this
3059 requires a good finger coordination: doing (physically)
3060 Down-lCtrl Down-rAlt Up-lCtrl Down-a
3061 (doing quick enough, so that key repeat of rAlt [which would
3062 generate new "fake" Down-lCtrl events] does not happens before 'a'
3063 is down) results in no "fake" events, so the application will see
3064 only rAlt down when 'a' is pressed. (However, fake Up-lCtrl WILL
3065 be generated when rAlt goes UP.)
3067 In fact, note also that KLLF_ALTGR does not prohibit construction of
3068 rCtrl-rAlt (just press them in this order!).
3070 Moreover: "traditional" layouts do not define distinct modifier-masks
3071 for VK_LMENU and VK_RMENU (same for VK_L/RCONTROL). Instead, they
3072 rely on the KLLF_ALTGR bit to make the behavior of VK_LMENU and
3073 VK_RMENU distinct. As a corollary, for such layouts, the produced
3074 character is the same for AltGr-* (=rAlt-*) and Ctrl-Alt-* (in any
3075 combination of handedness). For description of masks, see
3077 http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Keyboard_input_on_Windows,_Part_I:_what_is_the_kernel_doing?
3079 By default, Emacs was using these coincidences via the following
3080 heuristics: it was treating:
3081 (*) keypresses with lCtrl-rAlt modifiers as if they are carrying
3082 ONLY the character payload (no matter what the actual keyboard
3083 was defining: if lCtrl-lAlt-b was delivering U+05df=beta, then
3084 Emacs saw [beta]; if lCtrl-lAlt-b was undefined in the layout,
3085 the keypress was completely ignored), and
3086 (*) keypresses with the other combinations of handedness of Ctrl-Alt
3087 modifiers (e.g., lCtrl-lAlt) as if they NEVER carry a character
3088 payload (so they were reported "raw": if lCtrl-lAlt-b was
3089 delivering beta, then Emacs saw event [C-A-b], and not [beta]).
3090 This worked good for "traditional" layouts: users could type both
3091 AltGr-x and Ctrl-Alt-x, and one was a character, another a bindable
3094 However, for layouts which deliver different characters for AltGr-x
3095 and lCtrl-lAlt-x, this scheme makes the latter character unaccessible
3096 in Emacs. While it is easy to access functionality of [C-M-x] in
3097 Emacs by other means (for example, by the `controlify' prefix, or
3098 using lCtrl-rCtrl-x, or rCtrl-rAlt-x [in this order]), missing
3099 characters cannot be reconstructed without a tedious manual work. */
3101 /* These two cases are often going to be distinguishable, since at most
3102 one of these character is defined with KBDCTRL | KBDMENU modifier
3103 bitmap. (This heuristic breaks if both lCtrl-lAlt- AND lCtrl-rAlt-
3104 are translated to modifier bitmaps distinct from KBDCTRL | KBDMENU,
3105 or in the cases when lCtrl-lAlt-* and lCtrl-rAlt-* are generally
3106 different, but lCtrl-lAlt-x and lCtrl-rAlt-x happen to deliver the
3109 So we have 2 chunks of info:
3110 (A) is it lCtrl-rAlt-, or lCtrl-lAlt, or some other combination?
3111 (B) is the delivered character defined with KBDCTRL | KBDMENU bits?
3112 Basing on (A) and (B), we should decide whether to ignore the
3113 delivered character. (Before, Emacs was completely ignoring (B), and
3114 was treating the 3-state of (A) as a bit.) This means that we have 6
3115 bits of customization.
3117 Additionally, a presence of two Ctrl down may be AltGr-rCtrl-. */
3119 /* Strip all non-Shift modifiers if:
3120 - more than one UTF-16 code point delivered (can't call VkKeyScanW ())
3121 - or the character is a result of combining with a prefix key. */
3122 if (!after_dead
&& count
== 1 && *b
< 0x10000)
3124 if (console_modifiers
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
)
3125 && console_modifiers
& (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
3127 type_CtrlAlt
= "bB"; /* generic bindable Ctrl-Alt- modifiers */
3128 if ((console_modifiers
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
3129 == (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
3131 e.g. AltGr-rCtrl on some layouts (in this order!) */
3132 type_CtrlAlt
= "dD";
3133 else if ((console_modifiers
3134 & (LEFT_CTRL_PRESSED
| LEFT_ALT_PRESSED
))
3135 == (LEFT_CTRL_PRESSED
| LEFT_ALT_PRESSED
))
3136 type_CtrlAlt
= "lL"; /* Ctrl-Alt- modifiers on the left */
3137 else if (!NILP (Vw32_recognize_altgr
)
3138 && ((console_modifiers
3139 & (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
)))
3140 == (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
))
3141 type_CtrlAlt
= "gG"; /* modifiers as in AltGr */
3143 else if (wmsg
.dwModifiers
& (alt_modifier
| meta_modifier
)
3144 || ((console_modifiers
3145 & (LEFT_WIN_PRESSED
| RIGHT_WIN_PRESSED
3146 | APPS_PRESSED
| SCROLLLOCK_ON
))))
3148 /* Pure Alt (or combination of Alt, Win, APPS, scrolllock. */
3149 type_CtrlAlt
= "aA";
3153 /* Out of bound bitmap: */
3154 SHORT r
= VkKeyScanW (*b
), bitmap
= 0x1FF;
3156 FPRINTF_WM_CHARS((stderr
, "VkKeyScanW %#06x %#04x\n", (int)r
,
3158 if ((r
& 0xFF) == wParam
)
3159 bitmap
= r
>>8; /* *b is reachable via simple interface */
3162 /* VkKeyScanW() (essentially) returns the FIRST key with
3163 the specified character; so here the pressed key is the
3164 SECONDARY key producing the character.
3166 Essentially, we have no information about the "role" of
3167 modifiers on this key: which contribute into the
3168 produced character (so "are consumed"), and which are
3169 "extra" (must attache to bindable events).
3171 The default above would consume ALL modifiers, so the
3172 character is reported "as is". However, on many layouts
3173 the ordering of the keys (in the layout table) is not
3174 thought out well, so the "secondary" keys are often those
3175 which the users would prefer to use with Alt-CHAR.
3176 (Moreover - with e.g. Czech-QWERTY - the ASCII
3177 punctuation is accessible from two equally [nu]preferable
3180 SO: Heuristic: if the reported char is ASCII, AND Meta
3181 modifier is a candidate, behave as if Meta is present
3182 (fallback to the legacy branch; bug#23251).
3184 (This would break layouts
3185 - delivering ASCII characters
3187 - with not Shift/AltGr-like modifier combinations.
3188 All 3 conditions together must be pretty exotic
3189 cases - and a workaround exists: use "primary" keys!) */
3191 && (wmsg
.dwModifiers
3192 & (alt_modifier
| meta_modifier
3193 | super_modifier
| hyper_modifier
)))
3196 if (*type_CtrlAlt
== 'a') /* Simple Alt seen */
3198 if ((bitmap
& ~1) == 0) /* 1: KBDSHIFT */
3200 /* In "traditional" layouts, Alt without Ctrl does not
3201 change the delivered character. This detects this
3202 situation; it is safe to report this as Alt-something
3203 -- as opposed to delivering the reported character
3204 without modifiers. */
3206 && *b
> 0x7f && ('A' <= wParam
&& wParam
<= 'Z'))
3207 /* For backward-compatibility with older Emacsen, let
3208 this be processed by another branch below (which
3209 would convert it to Alt-Latin char via wParam). */
3215 /* Check whether the delivered character(s) is accessible via
3216 KBDCTRL | KBDALT ( | KBDSHIFT ) modifier mask (which is 7). */
3217 else if ((bitmap
& ~1) != 6)
3219 /* The character is not accessible via plain Ctrl-Alt(-Shift)
3220 (which is, probably, same as AltGr) modifiers.
3221 Either it was after a prefix key, or is combined with
3222 modifier keys which we don't see, or there is an asymmetry
3223 between left-hand and right-hand modifiers, or other hairy
3227 /* The best solution is to delegate these tough (but rarely
3228 needed) choices to the user. Temporarily (???), it is
3229 implemented as C macros.
3231 Essentially, there are 3 things to do: return 0 (handle to the
3232 legacy processing code [ignoring the character payload]; keep
3233 some modifiers (so that they will be processed by the binding
3234 system [on top of the character payload]; strip modifiers [so
3235 that `self-insert' is going to be triggered with the character
3238 The default below should cover 99.9999% of cases:
3239 (a) strip Alt- in the hairy case only;
3240 (stripping = not ignoring)
3241 (l) for lAlt-lCtrl, ignore the char in simple cases only;
3242 (g) for what looks like AltGr, ignore the modifiers;
3243 (d) for what looks like lCtrl-rCtrl-Alt (probably
3244 AltGr-rCtrl), ignore the character in simple cases only;
3245 (b) for other cases of Ctrl-Alt, ignore the character in
3248 Essentially, in all hairy cases, and in looks-like-AltGr case,
3249 we keep the character, ignoring the modifiers. In all the
3250 other cases, we ignore the delivered character. */
3251 #define S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD "aldb"
3252 #define S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS ""
3253 if (strchr (S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD
,
3254 type_CtrlAlt
[hairy
]))
3256 /* If in neither list, report all the modifiers we see COMBINED
3257 WITH the reported character. */
3258 if (strchr (S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS
,
3259 type_CtrlAlt
[hairy
]))
3260 strip_ExtraMods
= 0;
3263 if (strip_ExtraMods
)
3264 wmsg
.dwModifiers
= wmsg
.dwModifiers
& shift_modifier
;
3266 signal_user_input ();
3269 FPRINTF_WM_CHARS((stderr
, "unichar %#06x\n", *b
));
3270 my_post_msg (&wmsg
, hwnd
, WM_UNICHAR
, *b
++, lParam
);
3272 if (!ctrl_cnt
) /* Process ALSO as ctrl */
3275 FPRINTF_WM_CHARS((stderr
, "extra ctrl char\n"));
3278 else if (is_dead
>= 0)
3280 FPRINTF_WM_CHARS((stderr
, "dead %#06x\n", is_dead
));
3281 after_deadkey
= is_dead
;
3287 /* Main window procedure */
3289 static LRESULT CALLBACK
3290 w32_wnd_proc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
3293 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
3295 int windows_translate
;
3298 /* Note that it is okay to call x_window_to_frame, even though we are
3299 not running in the main lisp thread, because frame deletion
3300 requires the lisp thread to synchronize with this thread. Thus, if
3301 a frame struct is returned, it can be used without concern that the
3302 lisp thread might make it disappear while we are using it.
3304 NB. Walking the frame list in this thread is safe (as long as
3305 writes of Lisp_Object slots are atomic, which they are on Windows).
3306 Although delete-frame can destructively modify the frame list while
3307 we are walking it, a garbage collection cannot occur until after
3308 delete-frame has synchronized with this thread.
3310 It is also safe to use functions that make GDI calls, such as
3311 w32_clear_rect, because these functions must obtain a DC handle
3312 from the frame struct using get_frame_dc which is thread-aware. */
3317 f
= x_window_to_frame (dpyinfo
, hwnd
);
3320 HDC hdc
= get_frame_dc (f
);
3321 GetUpdateRect (hwnd
, &wmsg
.rect
, FALSE
);
3322 w32_clear_rect (f
, hdc
, &wmsg
.rect
);
3323 release_frame_dc (f
, hdc
);
3325 #if defined (W32_DEBUG_DISPLAY)
3326 DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
3328 wmsg
.rect
.left
, wmsg
.rect
.top
,
3329 wmsg
.rect
.right
, wmsg
.rect
.bottom
));
3330 #endif /* W32_DEBUG_DISPLAY */
3333 case WM_PALETTECHANGED
:
3334 /* ignore our own changes */
3335 if ((HWND
)wParam
!= hwnd
)
3337 f
= x_window_to_frame (dpyinfo
, hwnd
);
3339 /* get_frame_dc will realize our palette and force all
3340 frames to be redrawn if needed. */
3341 release_frame_dc (f
, get_frame_dc (f
));
3346 PAINTSTRUCT paintStruct
;
3348 memset (&update_rect
, 0, sizeof (update_rect
));
3350 f
= x_window_to_frame (dpyinfo
, hwnd
);
3353 DebPrint (("WM_PAINT received for unknown window %p\n", hwnd
));
3357 /* MSDN Docs say not to call BeginPaint if GetUpdateRect
3358 fails. Apparently this can happen under some
3360 if (GetUpdateRect (hwnd
, &update_rect
, FALSE
) || !w32_strict_painting
)
3363 BeginPaint (hwnd
, &paintStruct
);
3365 /* The rectangles returned by GetUpdateRect and BeginPaint
3366 do not always match. Play it safe by assuming both areas
3368 UnionRect (&(wmsg
.rect
), &update_rect
, &(paintStruct
.rcPaint
));
3370 #if defined (W32_DEBUG_DISPLAY)
3371 DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
3373 wmsg
.rect
.left
, wmsg
.rect
.top
,
3374 wmsg
.rect
.right
, wmsg
.rect
.bottom
));
3375 DebPrint ((" [update region is %d,%d-%d,%d]\n",
3376 update_rect
.left
, update_rect
.top
,
3377 update_rect
.right
, update_rect
.bottom
));
3379 EndPaint (hwnd
, &paintStruct
);
3382 /* Change the message type to prevent Windows from
3383 combining WM_PAINT messages in the Lisp thread's queue,
3384 since Windows assumes that each message queue is
3385 dedicated to one frame and does not bother checking
3386 that hwnd matches before combining them. */
3387 my_post_msg (&wmsg
, hwnd
, WM_EMACS_PAINT
, wParam
, lParam
);
3392 /* If GetUpdateRect returns 0 (meaning there is no update
3393 region), assume the whole window needs to be repainted. */
3394 GetClientRect (hwnd
, &wmsg
.rect
);
3395 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3399 case WM_INPUTLANGCHANGE
:
3400 /* Inform lisp thread of keyboard layout changes. */
3401 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3403 /* The state of the finite automaton is separate per every input
3404 language environment (so it does not change when one switches
3405 to a different window with the same environment). Moreover,
3406 the experiments show that the state is not remembered when
3407 one switches back to the pre-previous environment. */
3410 /* XXXX??? What follows is a COMPLETE misunderstanding of Windows! */
3412 /* Clear dead keys in the keyboard state; for simplicity only
3413 preserve modifier key states. */
3418 GetKeyboardState (keystate
);
3419 for (i
= 0; i
< 256; i
++)
3436 SetKeyboardState (keystate
);
3441 /* Synchronize hot keys with normal input. */
3442 PostMessage (hwnd
, WM_KEYDOWN
, HIWORD (lParam
), 0);
3447 record_keyup (wParam
, lParam
);
3452 /* Ignore keystrokes we fake ourself; see below. */
3453 if (dpyinfo
->faked_key
== wParam
)
3455 dpyinfo
->faked_key
= 0;
3456 /* Make sure TranslateMessage sees them though (as long as
3457 they don't produce WM_CHAR messages). This ensures that
3458 indicator lights are toggled promptly on Windows 9x, for
3460 if (wParam
< 256 && lispy_function_keys
[wParam
])
3462 windows_translate
= 1;
3468 /* Synchronize modifiers with current keystroke. */
3470 record_keydown (wParam
, lParam
);
3471 if (w32_use_fallback_wm_chars_method
)
3472 wParam
= map_keypad_keys (wParam
, (lParam
& 0x1000000L
) != 0);
3474 windows_translate
= 0;
3479 if (NILP (Vw32_pass_lwindow_to_system
))
3481 /* Prevent system from acting on keyup (which opens the
3482 Start menu if no other key was pressed) by simulating a
3483 press of Space which we will ignore. */
3484 if (GetAsyncKeyState (wParam
) & 1)
3486 if (NUMBERP (Vw32_phantom_key_code
))
3487 key
= XUINT (Vw32_phantom_key_code
) & 255;
3490 dpyinfo
->faked_key
= key
;
3491 keybd_event (key
, (BYTE
) MapVirtualKey (key
, 0), 0, 0);
3494 if (!NILP (Vw32_lwindow_modifier
))
3498 if (NILP (Vw32_pass_rwindow_to_system
))
3500 if (GetAsyncKeyState (wParam
) & 1)
3502 if (NUMBERP (Vw32_phantom_key_code
))
3503 key
= XUINT (Vw32_phantom_key_code
) & 255;
3506 dpyinfo
->faked_key
= key
;
3507 keybd_event (key
, (BYTE
) MapVirtualKey (key
, 0), 0, 0);
3510 if (!NILP (Vw32_rwindow_modifier
))
3514 if (!NILP (Vw32_apps_modifier
))
3518 if (NILP (Vw32_pass_alt_to_system
))
3519 /* Prevent DefWindowProc from activating the menu bar if an
3520 Alt key is pressed and released by itself. */
3522 windows_translate
= 1;
3525 /* Decide whether to treat as modifier or function key. */
3526 if (NILP (Vw32_enable_caps_lock
))
3527 goto disable_lock_key
;
3528 windows_translate
= 1;
3531 /* Decide whether to treat as modifier or function key. */
3532 if (NILP (Vw32_enable_num_lock
))
3533 goto disable_lock_key
;
3534 windows_translate
= 1;
3537 /* Decide whether to treat as modifier or function key. */
3538 if (NILP (Vw32_scroll_lock_modifier
))
3539 goto disable_lock_key
;
3540 windows_translate
= 1;
3543 /* Ensure the appropriate lock key state (and indicator light)
3544 remains in the same state. We do this by faking another
3545 press of the relevant key. Apparently, this really is the
3546 only way to toggle the state of the indicator lights. */
3547 dpyinfo
->faked_key
= wParam
;
3548 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3549 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3550 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3551 KEYEVENTF_EXTENDEDKEY
| 0, 0);
3552 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3553 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3554 /* Ensure indicator lights are updated promptly on Windows 9x
3555 (TranslateMessage apparently does this), after forwarding
3557 post_character_message (hwnd
, msg
, wParam
, lParam
,
3558 w32_get_key_modifiers (wParam
, lParam
));
3559 windows_translate
= 1;
3563 case VK_PROCESSKEY
: /* Generated by IME. */
3564 windows_translate
= 1;
3567 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
3568 which is confusing for purposes of key binding; convert
3569 VK_CANCEL events into VK_PAUSE events. */
3573 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
3574 for purposes of key binding; convert these back into
3575 VK_NUMLOCK events, at least when we want to see NumLock key
3576 presses. (Note that there is never any possibility that
3577 VK_PAUSE with Ctrl really is C-Pause as per above.) */
3578 if (NILP (Vw32_enable_num_lock
) && modifier_set (VK_CONTROL
))
3579 wParam
= VK_NUMLOCK
;
3582 if (w32_unicode_gui
&& !w32_use_fallback_wm_chars_method
)
3584 /* If this event generates characters or deadkeys, do
3585 not interpret it as a "raw combination of modifiers
3586 and keysym". Hide deadkeys, and use the generated
3587 character(s) instead of the keysym. (Backward
3588 compatibility: exceptions for numpad keys generating
3589 0-9 . , / * - +, and for extra-Alt combined with a
3592 Try to not report modifiers which have effect on
3593 which character or deadkey is generated.
3595 Example (contrived): if rightAlt-? generates f (on a
3596 Cyrillic keyboard layout), and Ctrl, leftAlt do not
3597 affect the generated character, one wants to report
3598 Ctrl-leftAlt-f if the user presses
3599 Ctrl-leftAlt-rightAlt-?. */
3602 /* Some of WM_CHAR may be fed to us directly, some are
3603 results of TranslateMessage(). Using 0 as the first
3604 argument (in a separate call) might help us
3605 distinguish these two cases.
3607 However, the keypress feeders would most probably
3608 expect the "standard" message pump, when
3609 TranslateMessage() is called on EVERY KeyDown/KeyUp
3610 event. So they may feed us Down-Ctrl Down-FAKE
3611 Char-o and expect us to recognize it as Ctrl-o.
3612 Using 0 as the first argument would interfere with
3614 deliver_wm_chars (0, hwnd
, msg
, wParam
, lParam
, 1);
3616 /* Processing the generated WM_CHAR messages *WHILE* we
3617 handle KEYDOWN/UP event is the best choice, since
3618 without any fuss, we know all 3 of: scancode, virtual
3619 keycode, and expansion. (Additionally, one knows
3620 boundaries of expansion of different keypresses.) */
3621 res
= deliver_wm_chars (1, hwnd
, msg
, wParam
, lParam
, 1);
3622 windows_translate
= -(res
!= 0);
3623 if (res
> 0) /* Bound to character(s) or a deadkey */
3625 /* deliver_wm_chars may make some branches after this vestigal. */
3627 wParam
= map_keypad_keys (wParam
, (lParam
& 0x1000000L
) != 0);
3628 /* If not defined as a function key, change it to a WM_CHAR message. */
3629 if (wParam
> 255 || !lispy_function_keys
[wParam
])
3631 DWORD modifiers
= construct_console_modifiers ();
3633 if (!NILP (Vw32_recognize_altgr
)
3634 && modifier_set (VK_LCONTROL
) && modifier_set (VK_RMENU
))
3636 /* Always let TranslateMessage handle AltGr key chords;
3637 for some reason, ToAscii doesn't always process AltGr
3638 chords correctly. */
3639 windows_translate
= 1;
3641 else if ((modifiers
& (~SHIFT_PRESSED
& ~CAPSLOCK_ON
)) != 0)
3643 /* Handle key chords including any modifiers other
3644 than shift directly, in order to preserve as much
3645 modifier information as possible. */
3646 if ('A' <= wParam
&& wParam
<= 'Z')
3648 /* Don't translate modified alphabetic keystrokes,
3649 so the user doesn't need to constantly switch
3650 layout to type control or meta keystrokes when
3651 the normal layout translates alphabetic
3652 characters to non-ascii characters. */
3653 if (!modifier_set (VK_SHIFT
))
3654 wParam
+= ('a' - 'A');
3659 /* Try to handle other keystrokes by determining the
3660 base character (ie. translating the base key plus
3663 KEY_EVENT_RECORD key
;
3665 key
.bKeyDown
= TRUE
;
3666 key
.wRepeatCount
= 1;
3667 key
.wVirtualKeyCode
= wParam
;
3668 key
.wVirtualScanCode
= (lParam
& 0xFF0000) >> 16;
3669 key
.uChar
.AsciiChar
= 0;
3670 key
.dwControlKeyState
= modifiers
;
3672 add
= w32_kbd_patch_key (&key
, w32_keyboard_codepage
);
3673 /* 0 means an unrecognized keycode, negative means
3674 dead key. Ignore both. */
3677 /* Forward asciified character sequence. */
3678 post_character_message
3680 (unsigned char) key
.uChar
.AsciiChar
, lParam
,
3681 w32_get_key_modifiers (wParam
, lParam
));
3682 w32_kbd_patch_key (&key
, w32_keyboard_codepage
);
3689 /* Let TranslateMessage handle everything else. */
3690 windows_translate
= 1;
3695 if (windows_translate
== -1)
3698 if (windows_translate
)
3700 MSG windows_msg
= { hwnd
, msg
, wParam
, lParam
, 0, {0,0} };
3701 windows_msg
.time
= GetMessageTime ();
3702 TranslateMessage (&windows_msg
);
3714 wmsg
.dwModifiers
= w32_get_key_modifiers (wParam
, lParam
);
3715 signal_user_input ();
3716 my_post_msg (&wmsg
, hwnd
, WM_UNICHAR
, wParam
, lParam
);
3720 post_character_message (hwnd
, msg
, wParam
, lParam
,
3721 w32_get_key_modifiers (wParam
, lParam
));
3725 /* WM_UNICHAR looks promising from the docs, but the exact
3726 circumstances in which TranslateMessage sends it is one of those
3727 Microsoft secret API things that EU and US courts are supposed
3728 to have put a stop to already. Spy++ shows it being sent to Notepad
3729 and other MS apps, but never to Emacs.
3731 Some third party IMEs send it in accordance with the official
3732 documentation though, so handle it here.
3734 UNICODE_NOCHAR is used to test for support for this message.
3735 TRUE indicates that the message is supported. */
3736 if (wParam
== UNICODE_NOCHAR
)
3741 wmsg
.dwModifiers
= w32_get_key_modifiers (wParam
, lParam
);
3742 signal_user_input ();
3743 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3748 /* If we can't get the IME result as Unicode, use default processing,
3749 which will at least allow characters decodable in the system locale
3751 if (!get_composition_string_fn
)
3754 else if (!ignore_ime_char
)
3759 HIMC context
= get_ime_context_fn (hwnd
);
3760 wmsg
.dwModifiers
= w32_get_key_modifiers (wParam
, lParam
);
3761 /* Get buffer size. */
3762 size
= get_composition_string_fn (context
, GCS_RESULTSTR
, NULL
, 0);
3763 buffer
= alloca (size
);
3764 size
= get_composition_string_fn (context
, GCS_RESULTSTR
,
3766 release_ime_context_fn (hwnd
, context
);
3768 signal_user_input ();
3769 for (i
= 0; i
< size
/ sizeof (wchar_t); i
++)
3771 my_post_msg (&wmsg
, hwnd
, WM_UNICHAR
, (WPARAM
) buffer
[i
],
3774 /* Ignore the messages for the rest of the
3775 characters in the string that was output above. */
3776 ignore_ime_char
= (size
/ sizeof (wchar_t)) - 1;
3783 case WM_IME_STARTCOMPOSITION
:
3784 if (!set_ime_composition_window_fn
)
3788 COMPOSITIONFORM form
;
3792 /* Implementation note: The code below does something that
3793 one shouldn't do: it accesses the window object from a
3794 separate thread, while the main (a.k.a. "Lisp") thread
3795 runs and can legitimately delete and even GC it. That is
3796 why we are extra careful not to futz with a window that
3797 is different from the one recorded when the system caret
3798 coordinates were last modified. That is also why we are
3799 careful not to move the IME window if the window
3800 described by W was deleted, as indicated by its buffer
3801 field being reset to nil. */
3802 f
= x_window_to_frame (dpyinfo
, hwnd
);
3803 if (!(f
&& FRAME_LIVE_P (f
)))
3805 w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
3806 /* Punt if someone changed the frame's selected window
3808 if (w
!= w32_system_caret_window
)
3811 form
.dwStyle
= CFS_RECT
;
3812 form
.ptCurrentPos
.x
= w32_system_caret_x
;
3813 form
.ptCurrentPos
.y
= w32_system_caret_y
;
3815 form
.rcArea
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, 0);
3816 form
.rcArea
.top
= (WINDOW_TOP_EDGE_Y (w
)
3817 + w32_system_caret_hdr_height
);
3818 form
.rcArea
.right
= (WINDOW_BOX_RIGHT_EDGE_X (w
)
3819 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
3820 - WINDOW_RIGHT_FRINGE_WIDTH (w
));
3821 form
.rcArea
.bottom
= (WINDOW_BOTTOM_EDGE_Y (w
)
3822 - WINDOW_BOTTOM_DIVIDER_WIDTH (w
)
3823 - w32_system_caret_mode_height
);
3825 /* Punt if the window was deleted behind our back. */
3826 if (!BUFFERP (w
->contents
))
3829 context
= get_ime_context_fn (hwnd
);
3834 set_ime_composition_window_fn (context
, &form
);
3835 release_ime_context_fn (hwnd
, context
);
3837 /* We should "goto dflt" here to pass WM_IME_STARTCOMPOSITION to
3838 DefWindowProc, so that the composition window will actually
3839 be displayed. But doing so causes trouble with displaying
3840 dialog boxes, such as the file selection dialog or font
3841 selection dialog. So something else is needed to fix the
3842 former without breaking the latter. See bug#11732. */
3845 case WM_IME_ENDCOMPOSITION
:
3846 ignore_ime_char
= 0;
3849 /* Simulate middle mouse button events when left and right buttons
3850 are used together, but only if user has two button mouse. */
3851 case WM_LBUTTONDOWN
:
3852 case WM_RBUTTONDOWN
:
3853 if (w32_num_mouse_buttons
> 2)
3854 goto handle_plain_button
;
3857 int this = (msg
== WM_LBUTTONDOWN
) ? LMOUSE
: RMOUSE
;
3858 int other
= (msg
== WM_LBUTTONDOWN
) ? RMOUSE
: LMOUSE
;
3860 if (button_state
& this)
3863 if (button_state
== 0)
3866 button_state
|= this;
3868 if (button_state
& other
)
3870 if (mouse_button_timer
)
3872 KillTimer (hwnd
, mouse_button_timer
);
3873 mouse_button_timer
= 0;
3875 /* Generate middle mouse event instead. */
3876 msg
= WM_MBUTTONDOWN
;
3877 button_state
|= MMOUSE
;
3879 else if (button_state
& MMOUSE
)
3881 /* Ignore button event if we've already generated a
3882 middle mouse down event. This happens if the
3883 user releases and press one of the two buttons
3884 after we've faked a middle mouse event. */
3889 /* Flush out saved message. */
3890 post_msg (&saved_mouse_button_msg
);
3892 wmsg
.dwModifiers
= w32_get_modifiers ();
3893 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3894 signal_user_input ();
3896 /* Clear message buffer. */
3897 saved_mouse_button_msg
.msg
.hwnd
= 0;
3901 /* Hold onto message for now. */
3902 mouse_button_timer
=
3903 SetTimer (hwnd
, MOUSE_BUTTON_ID
,
3904 w32_mouse_button_tolerance
, NULL
);
3905 saved_mouse_button_msg
.msg
.hwnd
= hwnd
;
3906 saved_mouse_button_msg
.msg
.message
= msg
;
3907 saved_mouse_button_msg
.msg
.wParam
= wParam
;
3908 saved_mouse_button_msg
.msg
.lParam
= lParam
;
3909 saved_mouse_button_msg
.msg
.time
= GetMessageTime ();
3910 saved_mouse_button_msg
.dwModifiers
= w32_get_modifiers ();
3917 if (w32_num_mouse_buttons
> 2)
3918 goto handle_plain_button
;
3921 int this = (msg
== WM_LBUTTONUP
) ? LMOUSE
: RMOUSE
;
3922 int other
= (msg
== WM_LBUTTONUP
) ? RMOUSE
: LMOUSE
;
3924 if ((button_state
& this) == 0)
3927 button_state
&= ~this;
3929 if (button_state
& MMOUSE
)
3931 /* Only generate event when second button is released. */
3932 if ((button_state
& other
) == 0)
3935 button_state
&= ~MMOUSE
;
3937 if (button_state
) emacs_abort ();
3944 /* Flush out saved message if necessary. */
3945 if (saved_mouse_button_msg
.msg
.hwnd
)
3947 post_msg (&saved_mouse_button_msg
);
3950 wmsg
.dwModifiers
= w32_get_modifiers ();
3951 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3952 signal_user_input ();
3954 /* Always clear message buffer and cancel timer. */
3955 saved_mouse_button_msg
.msg
.hwnd
= 0;
3956 KillTimer (hwnd
, mouse_button_timer
);
3957 mouse_button_timer
= 0;
3959 if (button_state
== 0)
3964 case WM_XBUTTONDOWN
:
3966 if (w32_pass_extra_mouse_buttons_to_system
)
3968 /* else fall through and process them. */
3969 case WM_MBUTTONDOWN
:
3971 handle_plain_button
:
3976 /* Ignore middle and extra buttons as long as the menu is active. */
3977 f
= x_window_to_frame (dpyinfo
, hwnd
);
3978 if (f
&& f
->output_data
.w32
->menubar_active
)
3981 if (parse_button (msg
, HIWORD (wParam
), &button
, &up
))
3983 if (up
) ReleaseCapture ();
3984 else SetCapture (hwnd
);
3985 button
= (button
== 0) ? LMOUSE
:
3986 ((button
== 1) ? MMOUSE
: RMOUSE
);
3988 button_state
&= ~button
;
3990 button_state
|= button
;
3994 wmsg
.dwModifiers
= w32_get_modifiers ();
3995 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3996 signal_user_input ();
3998 /* Need to return true for XBUTTON messages, false for others,
3999 to indicate that we processed the message. */
4000 return (msg
== WM_XBUTTONDOWN
|| msg
== WM_XBUTTONUP
);
4003 f
= x_window_to_frame (dpyinfo
, hwnd
);
4006 /* Ignore mouse movements as long as the menu is active.
4007 These movements are processed by the window manager
4008 anyway, and it's wrong to handle them as if they happened
4009 on the underlying frame. */
4010 if (f
->output_data
.w32
->menubar_active
)
4013 /* If the mouse moved, and the mouse pointer is invisible,
4014 make it visible again. We do this here so as to be able
4015 to show the mouse pointer even when the main
4016 (a.k.a. "Lisp") thread is busy doing something. */
4017 static int last_x
, last_y
;
4018 int x
= GET_X_LPARAM (lParam
);
4019 int y
= GET_Y_LPARAM (lParam
);
4021 if (f
->pointer_invisible
4022 && (x
!= last_x
|| y
!= last_y
))
4023 f
->pointer_invisible
= false;
4029 /* If the mouse has just moved into the frame, start tracking
4030 it, so we will be notified when it leaves the frame. Mouse
4031 tracking only works under W98 and NT4 and later. On earlier
4032 versions, there is no way of telling when the mouse leaves the
4033 frame, so we just have to put up with help-echo and mouse
4034 highlighting remaining while the frame is not active. */
4035 if (track_mouse_event_fn
&& !track_mouse_window
4036 /* If the menu bar is active, turning on tracking of mouse
4037 movement events might send these events to the tooltip
4038 frame, if the user happens to move the mouse pointer over
4039 the tooltip. But since we don't process events for
4040 tooltip frames, this causes Windows to present a
4041 hourglass cursor, which is ugly and unexpected. So don't
4042 enable tracking mouse events in this case; they will be
4043 restarted when the menu pops down. (Confusingly, the
4044 menubar_active member of f->output_data.w32, tested
4045 above, is only set when a menu was popped up _not_ from
4046 the frame's menu bar, but via x-popup-menu.) */
4049 TRACKMOUSEEVENT tme
;
4050 tme
.cbSize
= sizeof (tme
);
4051 tme
.dwFlags
= TME_LEAVE
;
4052 tme
.hwndTrack
= hwnd
;
4053 tme
.dwHoverTime
= HOVER_DEFAULT
;
4055 track_mouse_event_fn (&tme
);
4056 track_mouse_window
= hwnd
;
4060 if (w32_mouse_move_interval
<= 0
4061 || (msg
== WM_MOUSEMOVE
&& button_state
== 0))
4063 wmsg
.dwModifiers
= w32_get_modifiers ();
4064 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4068 /* Hang onto mouse move and scroll messages for a bit, to avoid
4069 sending such events to Emacs faster than it can process them.
4070 If we get more events before the timer from the first message
4071 expires, we just replace the first message. */
4073 if (saved_mouse_move_msg
.msg
.hwnd
== 0)
4075 SetTimer (hwnd
, MOUSE_MOVE_ID
,
4076 w32_mouse_move_interval
, NULL
);
4078 /* Hold onto message for now. */
4079 saved_mouse_move_msg
.msg
.hwnd
= hwnd
;
4080 saved_mouse_move_msg
.msg
.message
= msg
;
4081 saved_mouse_move_msg
.msg
.wParam
= wParam
;
4082 saved_mouse_move_msg
.msg
.lParam
= lParam
;
4083 saved_mouse_move_msg
.msg
.time
= GetMessageTime ();
4084 saved_mouse_move_msg
.dwModifiers
= w32_get_modifiers ();
4090 wmsg
.dwModifiers
= w32_get_modifiers ();
4091 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4092 signal_user_input ();
4096 if (w32_pass_multimedia_buttons_to_system
)
4098 /* Otherwise, pass to lisp, the same way we do with mousehwheel. */
4099 case WM_MOUSEHWHEEL
:
4100 wmsg
.dwModifiers
= w32_get_modifiers ();
4101 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4102 signal_user_input ();
4103 /* Non-zero must be returned when WM_MOUSEHWHEEL messages are
4104 handled, to prevent the system trying to handle it by faking
4105 scroll bar events. */
4109 /* Flush out saved messages if necessary. */
4110 if (wParam
== mouse_button_timer
)
4112 if (saved_mouse_button_msg
.msg
.hwnd
)
4114 post_msg (&saved_mouse_button_msg
);
4115 signal_user_input ();
4116 saved_mouse_button_msg
.msg
.hwnd
= 0;
4118 KillTimer (hwnd
, mouse_button_timer
);
4119 mouse_button_timer
= 0;
4121 else if (wParam
== mouse_move_timer
)
4123 if (saved_mouse_move_msg
.msg
.hwnd
)
4125 post_msg (&saved_mouse_move_msg
);
4126 saved_mouse_move_msg
.msg
.hwnd
= 0;
4128 KillTimer (hwnd
, mouse_move_timer
);
4129 mouse_move_timer
= 0;
4131 else if (wParam
== menu_free_timer
)
4133 KillTimer (hwnd
, menu_free_timer
);
4134 menu_free_timer
= 0;
4135 f
= x_window_to_frame (dpyinfo
, hwnd
);
4136 /* If a popup menu is active, don't wipe its strings. */
4138 && current_popup_menu
== NULL
)
4140 /* Free memory used by owner-drawn and help-echo strings. */
4141 w32_free_menu_strings (hwnd
);
4143 f
->output_data
.w32
->menubar_active
= 0;
4150 /* Windows doesn't send us focus messages when putting up and
4151 taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
4152 The only indication we get that something happened is receiving
4153 this message afterwards. So this is a good time to reset our
4154 keyboard modifiers' state. */
4161 /* We must ensure menu bar is fully constructed and up to date
4162 before allowing user interaction with it. To achieve this
4163 we send this message to the lisp thread and wait for a
4164 reply (whose value is not actually needed) to indicate that
4165 the menu bar is now ready for use, so we can now return.
4167 To remain responsive in the meantime, we enter a nested message
4168 loop that can process all other messages.
4170 However, we skip all this if the message results from calling
4171 TrackPopupMenu - in fact, we must NOT attempt to send the lisp
4172 thread a message because it is blocked on us at this point. We
4173 set menubar_active before calling TrackPopupMenu to indicate
4174 this (there is no possibility of confusion with real menubar
4177 f
= x_window_to_frame (dpyinfo
, hwnd
);
4179 && (f
->output_data
.w32
->menubar_active
4180 /* We can receive this message even in the absence of a
4181 menubar (ie. when the system menu is activated) - in this
4182 case we do NOT want to forward the message, otherwise it
4183 will cause the menubar to suddenly appear when the user
4184 had requested it to be turned off! */
4185 || f
->output_data
.w32
->menubar_widget
== NULL
))
4189 deferred_msg msg_buf
;
4191 /* Detect if message has already been deferred; in this case
4192 we cannot return any sensible value to ignore this. */
4193 if (find_deferred_msg (hwnd
, msg
) != NULL
)
4198 return send_deferred_msg (&msg_buf
, hwnd
, msg
, wParam
, lParam
);
4201 case WM_EXITMENULOOP
:
4202 f
= x_window_to_frame (dpyinfo
, hwnd
);
4204 /* If a menu is still active, check again after a short delay,
4205 since Windows often (always?) sends the WM_EXITMENULOOP
4206 before the corresponding WM_COMMAND message.
4207 Don't do this if a popup menu is active, since it is only
4208 menubar menus that require cleaning up in this way.
4210 if (f
&& menubar_in_use
&& current_popup_menu
== NULL
)
4211 menu_free_timer
= SetTimer (hwnd
, MENU_FREE_ID
, MENU_FREE_DELAY
, NULL
);
4213 /* If hourglass cursor should be displayed, display it now. */
4214 if (f
&& f
->output_data
.w32
->hourglass_p
)
4215 SetCursor (f
->output_data
.w32
->hourglass_cursor
);
4220 /* Direct handling of help_echo in menus. Should be safe now
4221 that we generate the help_echo by placing a help event in the
4224 HMENU menu
= (HMENU
) lParam
;
4225 UINT menu_item
= (UINT
) LOWORD (wParam
);
4226 UINT flags
= (UINT
) HIWORD (wParam
);
4228 w32_menu_display_help (hwnd
, menu
, menu_item
, flags
);
4232 case WM_MEASUREITEM
:
4233 f
= x_window_to_frame (dpyinfo
, hwnd
);
4236 MEASUREITEMSTRUCT
* pMis
= (MEASUREITEMSTRUCT
*) lParam
;
4238 if (pMis
->CtlType
== ODT_MENU
)
4240 /* Work out dimensions for popup menu titles. */
4241 char * title
= (char *) pMis
->itemData
;
4242 HDC hdc
= GetDC (hwnd
);
4243 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4244 LOGFONT menu_logfont
;
4248 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4249 menu_logfont
.lfWeight
= FW_BOLD
;
4250 menu_font
= CreateFontIndirect (&menu_logfont
);
4251 old_font
= SelectObject (hdc
, menu_font
);
4253 pMis
->itemHeight
= GetSystemMetrics (SM_CYMENUSIZE
);
4256 if (unicode_append_menu
)
4257 GetTextExtentPoint32W (hdc
, (WCHAR
*) title
,
4258 wcslen ((WCHAR
*) title
),
4261 GetTextExtentPoint32 (hdc
, title
, strlen (title
), &size
);
4263 pMis
->itemWidth
= size
.cx
;
4264 if (pMis
->itemHeight
< size
.cy
)
4265 pMis
->itemHeight
= size
.cy
;
4268 pMis
->itemWidth
= 0;
4270 SelectObject (hdc
, old_font
);
4271 DeleteObject (menu_font
);
4272 ReleaseDC (hwnd
, hdc
);
4279 f
= x_window_to_frame (dpyinfo
, hwnd
);
4282 DRAWITEMSTRUCT
* pDis
= (DRAWITEMSTRUCT
*) lParam
;
4284 if (pDis
->CtlType
== ODT_MENU
)
4286 /* Draw popup menu title. */
4287 char * title
= (char *) pDis
->itemData
;
4290 HDC hdc
= pDis
->hDC
;
4291 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4292 LOGFONT menu_logfont
;
4295 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4296 menu_logfont
.lfWeight
= FW_BOLD
;
4297 menu_font
= CreateFontIndirect (&menu_logfont
);
4298 old_font
= SelectObject (hdc
, menu_font
);
4300 /* Always draw title as if not selected. */
4301 if (unicode_append_menu
)
4304 + GetSystemMetrics (SM_CXMENUCHECK
),
4306 ETO_OPAQUE
, &pDis
->rcItem
,
4308 wcslen ((WCHAR
*) title
), NULL
);
4312 + GetSystemMetrics (SM_CXMENUCHECK
),
4314 ETO_OPAQUE
, &pDis
->rcItem
,
4315 title
, strlen (title
), NULL
);
4317 SelectObject (hdc
, old_font
);
4318 DeleteObject (menu_font
);
4326 /* Still not right - can't distinguish between clicks in the
4327 client area of the frame from clicks forwarded from the scroll
4328 bars - may have to hook WM_NCHITTEST to remember the mouse
4329 position and then check if it is in the client area ourselves. */
4330 case WM_MOUSEACTIVATE
:
4331 /* Discard the mouse click that activates a frame, allowing the
4332 user to click anywhere without changing point (or worse!).
4333 Don't eat mouse clicks on scrollbars though!! */
4334 if (LOWORD (lParam
) == HTCLIENT
)
4335 return MA_ACTIVATEANDEAT
;
4340 /* No longer tracking mouse. */
4341 track_mouse_window
= NULL
;
4343 case WM_ACTIVATEAPP
:
4345 case WM_WINDOWPOSCHANGED
:
4347 /* Inform lisp thread that a frame might have just been obscured
4348 or exposed, so should recheck visibility of all frames. */
4349 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4353 dpyinfo
->faked_key
= 0;
4355 register_hot_keys (hwnd
);
4358 unregister_hot_keys (hwnd
);
4361 /* Relinquish the system caret. */
4362 if (w32_system_caret_hwnd
)
4364 w32_visible_system_caret_hwnd
= NULL
;
4365 w32_system_caret_hwnd
= NULL
;
4371 f
= x_window_to_frame (dpyinfo
, hwnd
);
4372 if (f
&& HIWORD (wParam
) == 0)
4374 if (menu_free_timer
)
4376 KillTimer (hwnd
, menu_free_timer
);
4377 menu_free_timer
= 0;
4383 wmsg
.dwModifiers
= w32_get_modifiers ();
4384 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4392 wmsg
.dwModifiers
= w32_get_modifiers ();
4393 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4396 case WM_WINDOWPOSCHANGING
:
4397 /* Don't restrict the sizing of any kind of frames. If the window
4398 manager doesn't, there's no reason to do it ourselves. */
4401 case WM_GETMINMAXINFO
:
4402 /* Hack to allow resizing the Emacs frame above the screen size.
4403 Note that Windows 9x limits coordinates to 16-bits. */
4404 ((LPMINMAXINFO
) lParam
)->ptMaxTrackSize
.x
= 32767;
4405 ((LPMINMAXINFO
) lParam
)->ptMaxTrackSize
.y
= 32767;
4409 if (LOWORD (lParam
) == HTCLIENT
)
4411 f
= x_window_to_frame (dpyinfo
, hwnd
);
4414 if (f
->output_data
.w32
->hourglass_p
4415 && !menubar_in_use
&& !current_popup_menu
)
4416 SetCursor (f
->output_data
.w32
->hourglass_cursor
);
4417 else if (f
->pointer_invisible
)
4420 SetCursor (f
->output_data
.w32
->current_cursor
);
4427 case WM_EMACS_SETCURSOR
:
4429 Cursor cursor
= (Cursor
) wParam
;
4430 f
= x_window_to_frame (dpyinfo
, hwnd
);
4433 f
->output_data
.w32
->current_cursor
= cursor
;
4434 /* Don't change the cursor while menu-bar menu is in use. */
4435 if (!f
->output_data
.w32
->menubar_active
4436 && !f
->output_data
.w32
->hourglass_p
)
4438 if (f
->pointer_invisible
)
4447 case WM_EMACS_SHOWCURSOR
:
4449 ShowCursor ((BOOL
) wParam
);
4454 case WM_EMACS_CREATEVSCROLLBAR
:
4455 return (LRESULT
) w32_createvscrollbar ((struct frame
*) wParam
,
4456 (struct scroll_bar
*) lParam
);
4458 case WM_EMACS_CREATEHSCROLLBAR
:
4459 return (LRESULT
) w32_createhscrollbar ((struct frame
*) wParam
,
4460 (struct scroll_bar
*) lParam
);
4462 case WM_EMACS_SHOWWINDOW
:
4463 return ShowWindow ((HWND
) wParam
, (WPARAM
) lParam
);
4465 case WM_EMACS_BRINGTOTOP
:
4466 case WM_EMACS_SETFOREGROUND
:
4468 HWND foreground_window
;
4469 DWORD foreground_thread
, retval
;
4471 /* On NT 5.0, and apparently Windows 98, it is necessary to
4472 attach to the thread that currently has focus in order to
4473 pull the focus away from it. */
4474 foreground_window
= GetForegroundWindow ();
4475 foreground_thread
= GetWindowThreadProcessId (foreground_window
, NULL
);
4476 if (!foreground_window
4477 || foreground_thread
== GetCurrentThreadId ()
4478 || !AttachThreadInput (GetCurrentThreadId (),
4479 foreground_thread
, TRUE
))
4480 foreground_thread
= 0;
4482 retval
= SetForegroundWindow ((HWND
) wParam
);
4483 if (msg
== WM_EMACS_BRINGTOTOP
)
4484 retval
= BringWindowToTop ((HWND
) wParam
);
4486 /* Detach from the previous foreground thread. */
4487 if (foreground_thread
)
4488 AttachThreadInput (GetCurrentThreadId (),
4489 foreground_thread
, FALSE
);
4494 case WM_EMACS_SETWINDOWPOS
:
4496 WINDOWPOS
* pos
= (WINDOWPOS
*) wParam
;
4497 return SetWindowPos (hwnd
, pos
->hwndInsertAfter
,
4498 pos
->x
, pos
->y
, pos
->cx
, pos
->cy
, pos
->flags
);
4501 case WM_EMACS_DESTROYWINDOW
:
4502 DragAcceptFiles ((HWND
) wParam
, FALSE
);
4503 return DestroyWindow ((HWND
) wParam
);
4505 case WM_EMACS_HIDE_CARET
:
4506 return HideCaret (hwnd
);
4508 case WM_EMACS_SHOW_CARET
:
4509 return ShowCaret (hwnd
);
4511 case WM_EMACS_DESTROY_CARET
:
4512 w32_system_caret_hwnd
= NULL
;
4513 w32_visible_system_caret_hwnd
= NULL
;
4514 return DestroyCaret ();
4516 case WM_EMACS_TRACK_CARET
:
4517 /* If there is currently no system caret, create one. */
4518 if (w32_system_caret_hwnd
== NULL
)
4520 /* Use the default caret width, and avoid changing it
4521 unnecessarily, as it confuses screen reader software. */
4522 w32_system_caret_hwnd
= hwnd
;
4523 CreateCaret (hwnd
, NULL
, 0,
4524 w32_system_caret_height
);
4527 if (!SetCaretPos (w32_system_caret_x
, w32_system_caret_y
))
4529 /* Ensure visible caret gets turned on when requested. */
4530 else if (w32_use_visible_system_caret
4531 && w32_visible_system_caret_hwnd
!= hwnd
)
4533 w32_visible_system_caret_hwnd
= hwnd
;
4534 return ShowCaret (hwnd
);
4536 /* Ensure visible caret gets turned off when requested. */
4537 else if (!w32_use_visible_system_caret
4538 && w32_visible_system_caret_hwnd
)
4540 w32_visible_system_caret_hwnd
= NULL
;
4541 return HideCaret (hwnd
);
4546 case WM_EMACS_TRACKPOPUPMENU
:
4551 pos
= (POINT
*)lParam
;
4552 flags
= TPM_CENTERALIGN
;
4553 if (button_state
& LMOUSE
)
4554 flags
|= TPM_LEFTBUTTON
;
4555 else if (button_state
& RMOUSE
)
4556 flags
|= TPM_RIGHTBUTTON
;
4558 /* Remember we did a SetCapture on the initial mouse down event,
4559 so for safety, we make sure the capture is canceled now. */
4563 /* Use menubar_active to indicate that WM_INITMENU is from
4564 TrackPopupMenu below, and should be ignored. */
4565 f
= x_window_to_frame (dpyinfo
, hwnd
);
4567 f
->output_data
.w32
->menubar_active
= 1;
4569 if (TrackPopupMenu ((HMENU
)wParam
, flags
, pos
->x
, pos
->y
,
4573 /* Eat any mouse messages during popupmenu */
4574 while (PeekMessage (&amsg
, hwnd
, WM_MOUSEFIRST
, WM_MOUSELAST
,
4576 /* Get the menu selection, if any */
4577 if (PeekMessage (&amsg
, hwnd
, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
))
4579 retval
= LOWORD (amsg
.wParam
);
4593 case WM_EMACS_FILENOTIFY
:
4594 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4598 /* Check for messages registered at runtime. */
4599 if (msg
== msh_mousewheel
)
4601 wmsg
.dwModifiers
= w32_get_modifiers ();
4602 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4603 signal_user_input ();
4608 return (w32_unicode_gui
? DefWindowProcW
: DefWindowProcA
) (hwnd
, msg
, wParam
, lParam
);
4611 /* The most common default return code for handled messages is 0. */
4616 my_create_window (struct frame
* f
)
4619 static int coords
[2];
4620 Lisp_Object left
, top
;
4621 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
4623 /* When called with RES_TYPE_NUMBER, x_get_arg will return zero for
4624 anything that is not a number and is not Qunbound. */
4625 left
= x_get_arg (dpyinfo
, Qnil
, Qleft
, "left", "Left", RES_TYPE_NUMBER
);
4626 top
= x_get_arg (dpyinfo
, Qnil
, Qtop
, "top", "Top", RES_TYPE_NUMBER
);
4627 if (EQ (left
, Qunbound
))
4628 coords
[0] = CW_USEDEFAULT
;
4630 coords
[0] = XINT (left
);
4631 if (EQ (top
, Qunbound
))
4632 coords
[1] = CW_USEDEFAULT
;
4634 coords
[1] = XINT (top
);
4636 if (!PostThreadMessage (dwWindowsThreadId
, WM_EMACS_CREATEWINDOW
,
4637 (WPARAM
)f
, (LPARAM
)coords
))
4639 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
4643 /* Create a tooltip window. Unlike my_create_window, we do not do this
4644 indirectly via the Window thread, as we do not need to process Window
4645 messages for the tooltip. Creating tooltips indirectly also creates
4646 deadlocks when tooltips are created for menu items. */
4648 my_create_tip_window (struct frame
*f
)
4652 rect
.left
= rect
.top
= 0;
4653 rect
.right
= FRAME_PIXEL_WIDTH (f
);
4654 rect
.bottom
= FRAME_PIXEL_HEIGHT (f
);
4656 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
, false);
4658 tip_window
= FRAME_W32_WINDOW (f
)
4659 = CreateWindow (EMACS_CLASS
,
4661 f
->output_data
.w32
->dwStyle
,
4664 rect
.right
- rect
.left
,
4665 rect
.bottom
- rect
.top
,
4666 FRAME_W32_WINDOW (SELECTED_FRAME ()), /* owner */
4673 SetWindowLong (tip_window
, WND_FONTWIDTH_INDEX
, FRAME_COLUMN_WIDTH (f
));
4674 SetWindowLong (tip_window
, WND_LINEHEIGHT_INDEX
, FRAME_LINE_HEIGHT (f
));
4675 SetWindowLong (tip_window
, WND_BORDER_INDEX
, FRAME_INTERNAL_BORDER_WIDTH (f
));
4676 SetWindowLong (tip_window
, WND_BACKGROUND_INDEX
, FRAME_BACKGROUND_PIXEL (f
));
4678 /* Tip frames have no scrollbars. */
4679 SetWindowLong (tip_window
, WND_VSCROLLBAR_INDEX
, 0);
4680 SetWindowLong (tip_window
, WND_HSCROLLBAR_INDEX
, 0);
4682 /* Do this to discard the default setting specified by our parent. */
4683 ShowWindow (tip_window
, SW_HIDE
);
4688 /* Create and set up the w32 window for frame F. */
4691 w32_window (struct frame
*f
, long window_prompting
, bool minibuffer_only
)
4695 /* Use the resource name as the top-level window name
4696 for looking up resources. Make a non-Lisp copy
4697 for the window manager, so GC relocation won't bother it.
4699 Elsewhere we specify the window name for the window manager. */
4700 f
->namebuf
= xlispstrdup (Vx_resource_name
);
4702 my_create_window (f
);
4704 validate_x_resource_name ();
4706 /* x_set_name normally ignores requests to set the name if the
4707 requested name is the same as the current name. This is the one
4708 place where that assumption isn't correct; f->name is set, but
4709 the server hasn't been told. */
4712 int explicit = f
->explicit_name
;
4714 f
->explicit_name
= 0;
4716 fset_name (f
, Qnil
);
4717 x_set_name (f
, name
, explicit);
4722 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
4723 initialize_frame_menubar (f
);
4725 if (FRAME_W32_WINDOW (f
) == 0)
4726 error ("Unable to create window");
4729 /* Handle the icon stuff for this window. Perhaps later we might
4730 want an x_set_icon_position which can be called interactively as
4734 x_icon (struct frame
*f
, Lisp_Object parms
)
4736 Lisp_Object icon_x
, icon_y
;
4737 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
4739 /* Set the position of the icon. Note that Windows 95 groups all
4740 icons in the tray. */
4741 icon_x
= x_get_arg (dpyinfo
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
4742 icon_y
= x_get_arg (dpyinfo
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
4743 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
4745 CHECK_NUMBER (icon_x
);
4746 CHECK_NUMBER (icon_y
);
4748 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
4749 error ("Both left and top icon corners of icon must be specified");
4754 /* Start up iconic or window? */
4755 x_wm_set_window_state
4756 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
4760 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
4770 x_make_gc (struct frame
*f
)
4772 XGCValues gc_values
;
4776 /* Create the GC's of this frame.
4777 Note that many default values are used. */
4780 gc_values
.font
= FRAME_FONT (f
);
4782 /* Cursor has cursor-color background, background-color foreground. */
4783 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
4784 gc_values
.background
= f
->output_data
.w32
->cursor_pixel
;
4785 f
->output_data
.w32
->cursor_gc
4786 = XCreateGC (NULL
, FRAME_W32_WINDOW (f
),
4787 (GCFont
| GCForeground
| GCBackground
),
4791 f
->output_data
.w32
->white_relief
.gc
= 0;
4792 f
->output_data
.w32
->black_relief
.gc
= 0;
4798 /* Handler for signals raised during x_create_frame and
4799 x_create_tip_frame. FRAME is the frame which is partially
4803 unwind_create_frame (Lisp_Object frame
)
4805 struct frame
*f
= XFRAME (frame
);
4807 /* If frame is ``official'', nothing to do. */
4808 if (NILP (Fmemq (frame
, Vframe_list
)))
4811 struct w32_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
4813 /* If the frame's image cache refcount is still the same as our
4814 private shadow variable, it means we are unwinding a frame
4815 for which we didn't yet call init_frame_faces, where the
4816 refcount is incremented. Therefore, we increment it here, so
4817 that free_frame_faces, called in x_free_frame_resources
4818 below, will not mistakenly decrement the counter that was not
4819 incremented yet to account for this new frame. */
4820 if (FRAME_IMAGE_CACHE (f
) != NULL
4821 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
4822 FRAME_IMAGE_CACHE (f
)->refcount
++;
4825 x_free_frame_resources (f
);
4829 /* Check that reference counts are indeed correct. */
4830 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
4831 eassert ((dpyinfo
->terminal
->image_cache
== NULL
4832 && image_cache_refcount
== 0)
4833 || (dpyinfo
->terminal
->image_cache
!= NULL
4834 && dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
));
4843 do_unwind_create_frame (Lisp_Object frame
)
4845 unwind_create_frame (frame
);
4849 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
4851 struct w32_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
4852 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
4855 if (EQ (font_param
, Qunbound
))
4857 font
= !NILP (font_param
) ? font_param
4858 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
4860 if (!STRINGP (font
))
4863 static char *names
[]
4864 = { "Courier New-10",
4865 "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
4866 "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
4870 for (i
= 0; names
[i
]; i
++)
4872 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
4877 error ("No suitable font was found");
4879 else if (!NILP (font_param
))
4881 /* Remember the explicit font parameter, so we can re-apply it after
4882 we've applied the `default' face settings. */
4883 x_set_frame_parameters (f
, Fcons (Fcons (Qfont_param
, font_param
), Qnil
));
4885 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
4888 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
4890 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
4891 Return an Emacs frame object.
4892 PARAMETERS is an alist of frame parameters.
4893 If the parameters specify that the frame should not have a minibuffer,
4894 and do not specify a specific minibuffer window to use,
4895 then `default-minibuffer-frame' must be a frame whose minibuffer can
4896 be shared by the new frame.
4898 This function is an internal primitive--use `make-frame' instead. */)
4899 (Lisp_Object parameters
)
4902 Lisp_Object frame
, tem
;
4904 bool minibuffer_only
= false;
4905 long window_prompting
= 0;
4906 ptrdiff_t count
= SPECPDL_INDEX ();
4907 Lisp_Object display
;
4908 struct w32_display_info
*dpyinfo
= NULL
;
4911 int x_width
= 0, x_height
= 0;
4913 if (!FRAME_W32_P (SELECTED_FRAME ())
4914 && !FRAME_INITIAL_P (SELECTED_FRAME ()))
4915 error ("Cannot create a GUI frame in a -nw session");
4917 /* Make copy of frame parameters because the original is in pure
4919 parameters
= Fcopy_alist (parameters
);
4921 /* Use this general default value to start with
4922 until we know if this frame has a specified name. */
4923 Vx_resource_name
= Vinvocation_name
;
4925 display
= x_get_arg (dpyinfo
, parameters
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
4926 if (EQ (display
, Qunbound
))
4927 display
= x_get_arg (dpyinfo
, parameters
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
4928 if (EQ (display
, Qunbound
))
4930 dpyinfo
= check_x_display_info (display
);
4931 kb
= dpyinfo
->terminal
->kboard
;
4933 if (!dpyinfo
->terminal
->name
)
4934 error ("Terminal is not live, can't create new frames on it");
4936 name
= x_get_arg (dpyinfo
, parameters
, Qname
, "name", "Name", RES_TYPE_STRING
);
4938 && ! EQ (name
, Qunbound
)
4940 error ("Invalid frame name--not a string or nil");
4943 Vx_resource_name
= name
;
4945 /* See if parent window is specified. */
4946 parent
= x_get_arg (dpyinfo
, parameters
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
4947 if (EQ (parent
, Qunbound
))
4949 if (! NILP (parent
))
4950 CHECK_NUMBER (parent
);
4952 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
4953 /* No need to protect DISPLAY because that's not used after passing
4954 it to make_frame_without_minibuffer. */
4956 tem
= x_get_arg (dpyinfo
, parameters
, Qminibuffer
, "minibuffer", "Minibuffer",
4958 if (EQ (tem
, Qnone
) || NILP (tem
))
4959 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
4960 else if (EQ (tem
, Qonly
))
4962 f
= make_minibuffer_frame ();
4963 minibuffer_only
= true;
4965 else if (WINDOWP (tem
))
4966 f
= make_frame_without_minibuffer (tem
, kb
, display
);
4968 f
= make_frame (true);
4970 XSETFRAME (frame
, f
);
4972 /* By default, make scrollbars the system standard width and height. */
4973 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = GetSystemMetrics (SM_CXVSCROLL
);
4974 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = GetSystemMetrics (SM_CXHSCROLL
);
4976 f
->terminal
= dpyinfo
->terminal
;
4978 f
->output_method
= output_w32
;
4979 f
->output_data
.w32
= xzalloc (sizeof (struct w32_output
));
4980 FRAME_FONTSET (f
) = -1;
4983 (f
, x_get_arg (dpyinfo
, parameters
, Qicon_name
, "iconName", "Title",
4985 if (! STRINGP (f
->icon_name
))
4986 fset_icon_name (f
, Qnil
);
4988 /* FRAME_DISPLAY_INFO (f) = dpyinfo; */
4990 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
4991 record_unwind_protect (do_unwind_create_frame
, frame
);
4994 image_cache_refcount
=
4995 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
4996 dpyinfo_refcount
= dpyinfo
->reference_count
;
4997 #endif /* GLYPH_DEBUG */
4999 /* Specify the parent under which to make this window. */
5002 /* Cast to UINT_PTR shuts up compiler warnings about cast to
5003 pointer from integer of different size. */
5004 f
->output_data
.w32
->parent_desc
= (Window
) (UINT_PTR
) XFASTINT (parent
);
5005 f
->output_data
.w32
->explicit_parent
= true;
5009 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5010 f
->output_data
.w32
->explicit_parent
= false;
5013 /* Set the name; the functions to which we pass f expect the name to
5015 if (EQ (name
, Qunbound
) || NILP (name
))
5017 fset_name (f
, build_string (dpyinfo
->w32_id_name
));
5018 f
->explicit_name
= false;
5022 fset_name (f
, name
);
5023 f
->explicit_name
= true;
5024 /* Use the frame's title when getting resources for this frame. */
5025 specbind (Qx_resource_name
, name
);
5028 if (uniscribe_available
)
5029 register_font_driver (&uniscribe_font_driver
, f
);
5030 register_font_driver (&w32font_driver
, f
);
5032 x_default_parameter (f
, parameters
, Qfont_backend
, Qnil
,
5033 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5035 /* Extract the window parameters from the supplied values
5036 that are needed to determine window geometry. */
5037 x_default_font_parameter (f
, parameters
);
5039 x_default_parameter (f
, parameters
, Qborder_width
, make_number (2),
5040 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5042 /* We recognize either internalBorderWidth or internalBorder
5043 (which is what xterm calls it). */
5044 if (NILP (Fassq (Qinternal_border_width
, parameters
)))
5048 value
= x_get_arg (dpyinfo
, parameters
, Qinternal_border_width
,
5049 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
5050 if (! EQ (value
, Qunbound
))
5051 parameters
= Fcons (Fcons (Qinternal_border_width
, value
),
5054 /* Default internalBorderWidth to 0 on Windows to match other programs. */
5055 x_default_parameter (f
, parameters
, Qinternal_border_width
, make_number (0),
5056 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
5057 x_default_parameter (f
, parameters
, Qright_divider_width
, make_number (0),
5058 NULL
, NULL
, RES_TYPE_NUMBER
);
5059 x_default_parameter (f
, parameters
, Qbottom_divider_width
, make_number (0),
5060 NULL
, NULL
, RES_TYPE_NUMBER
);
5061 x_default_parameter (f
, parameters
, Qvertical_scroll_bars
, Qright
,
5062 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
5063 x_default_parameter (f
, parameters
, Qhorizontal_scroll_bars
, Qnil
,
5064 "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
5066 /* Also do the stuff which must be set before the window exists. */
5067 x_default_parameter (f
, parameters
, Qforeground_color
, build_string ("black"),
5068 "foreground", "Foreground", RES_TYPE_STRING
);
5069 x_default_parameter (f
, parameters
, Qbackground_color
, build_string ("white"),
5070 "background", "Background", RES_TYPE_STRING
);
5071 x_default_parameter (f
, parameters
, Qmouse_color
, build_string ("black"),
5072 "pointerColor", "Foreground", RES_TYPE_STRING
);
5073 x_default_parameter (f
, parameters
, Qborder_color
, build_string ("black"),
5074 "borderColor", "BorderColor", RES_TYPE_STRING
);
5075 x_default_parameter (f
, parameters
, Qscreen_gamma
, Qnil
,
5076 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
5077 x_default_parameter (f
, parameters
, Qline_spacing
, Qnil
,
5078 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
5079 x_default_parameter (f
, parameters
, Qleft_fringe
, Qnil
,
5080 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
5081 x_default_parameter (f
, parameters
, Qright_fringe
, Qnil
,
5082 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
5083 /* Process alpha here (Bug#16619). */
5084 x_default_parameter (f
, parameters
, Qalpha
, Qnil
,
5085 "alpha", "Alpha", RES_TYPE_NUMBER
);
5087 /* Init faces first since we need the frame's column width/line
5088 height in various occasions. */
5089 init_frame_faces (f
);
5091 /* The following call of change_frame_size is needed since otherwise
5092 x_set_tool_bar_lines will already work with the character sizes
5093 installed by init_frame_faces while the frame's pixel size is
5094 still calculated from a character size of 1 and we subsequently
5095 hit the (height >= 0) assertion in window_box_height.
5097 The non-pixelwise code apparently worked around this because it
5098 had one frame line vs one toolbar line which left us with a zero
5099 root window height which was obviously wrong as well ... */
5100 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
5101 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
5104 /* The X resources controlling the menu-bar and tool-bar are
5105 processed specially at startup, and reflected in the mode
5106 variables; ignore them here. */
5107 x_default_parameter (f
, parameters
, Qmenu_bar_lines
,
5108 NILP (Vmenu_bar_mode
)
5109 ? make_number (0) : make_number (1),
5110 NULL
, NULL
, RES_TYPE_NUMBER
);
5111 x_default_parameter (f
, parameters
, Qtool_bar_lines
,
5112 NILP (Vtool_bar_mode
)
5113 ? make_number (0) : make_number (1),
5114 NULL
, NULL
, RES_TYPE_NUMBER
);
5116 x_default_parameter (f
, parameters
, Qbuffer_predicate
, Qnil
,
5117 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
5118 x_default_parameter (f
, parameters
, Qtitle
, Qnil
,
5119 "title", "Title", RES_TYPE_STRING
);
5121 f
->output_data
.w32
->dwStyle
= WS_OVERLAPPEDWINDOW
;
5122 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5124 f
->output_data
.w32
->text_cursor
= w32_load_cursor (IDC_IBEAM
);
5125 f
->output_data
.w32
->nontext_cursor
= w32_load_cursor (IDC_ARROW
);
5126 f
->output_data
.w32
->modeline_cursor
= w32_load_cursor (IDC_ARROW
);
5127 f
->output_data
.w32
->hand_cursor
= w32_load_cursor (IDC_HAND
);
5128 f
->output_data
.w32
->hourglass_cursor
= w32_load_cursor (IDC_WAIT
);
5129 f
->output_data
.w32
->horizontal_drag_cursor
= w32_load_cursor (IDC_SIZEWE
);
5130 f
->output_data
.w32
->vertical_drag_cursor
= w32_load_cursor (IDC_SIZENS
);
5132 f
->output_data
.w32
->current_cursor
= f
->output_data
.w32
->nontext_cursor
;
5134 window_prompting
= x_figure_window_size (f
, parameters
, true, &x_width
, &x_height
);
5136 tem
= x_get_arg (dpyinfo
, parameters
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
5137 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
5139 w32_window (f
, window_prompting
, minibuffer_only
);
5140 x_icon (f
, parameters
);
5144 /* Now consider the frame official. */
5145 f
->terminal
->reference_count
++;
5146 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5147 Vframe_list
= Fcons (frame
, Vframe_list
);
5149 /* We need to do this after creating the window, so that the
5150 icon-creation functions can say whose icon they're describing. */
5151 x_default_parameter (f
, parameters
, Qicon_type
, Qnil
,
5152 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
5154 x_default_parameter (f
, parameters
, Qauto_raise
, Qnil
,
5155 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5156 x_default_parameter (f
, parameters
, Qauto_lower
, Qnil
,
5157 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5158 x_default_parameter (f
, parameters
, Qcursor_type
, Qbox
,
5159 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5160 x_default_parameter (f
, parameters
, Qscroll_bar_width
, Qnil
,
5161 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
5162 x_default_parameter (f
, parameters
, Qscroll_bar_height
, Qnil
,
5163 "scrollBarHeight", "ScrollBarHeight", RES_TYPE_NUMBER
);
5165 /* Allow x_set_window_size, now. */
5166 f
->can_x_set_window_size
= true;
5169 SET_FRAME_WIDTH (f
, x_width
);
5171 SET_FRAME_HEIGHT (f
, x_height
);
5173 /* Tell the server what size and position, etc, we want, and how
5174 badly we want them. This should be done after we have the menu
5175 bar so that its size can be taken into account. */
5177 x_wm_set_size_hint (f
, window_prompting
, false);
5180 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
), 0, true,
5183 /* Process fullscreen parameter here in the hope that normalizing a
5184 fullheight/fullwidth frame will produce the size set by the last
5185 adjust_frame_size call. */
5186 x_default_parameter (f
, parameters
, Qfullscreen
, Qnil
,
5187 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
5189 /* Make the window appear on the frame and enable display, unless
5190 the caller says not to. However, with explicit parent, Emacs
5191 cannot control visibility, so don't try. */
5192 if (! f
->output_data
.w32
->explicit_parent
)
5194 Lisp_Object visibility
;
5196 visibility
= x_get_arg (dpyinfo
, parameters
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
5197 if (EQ (visibility
, Qunbound
))
5200 if (EQ (visibility
, Qicon
))
5201 x_iconify_frame (f
);
5202 else if (! NILP (visibility
))
5203 x_make_frame_visible (f
);
5205 /* Must have been Qnil. */
5209 /* Initialize `default-minibuffer-frame' in case this is the first
5210 frame on this terminal. */
5211 if (FRAME_HAS_MINIBUF_P (f
)
5212 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
5213 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
5214 kset_default_minibuffer_frame (kb
, frame
);
5216 /* All remaining specified parameters, which have not been "used"
5217 by x_get_arg and friends, now go in the misc. alist of the frame. */
5218 for (tem
= parameters
; CONSP (tem
); tem
= XCDR (tem
))
5219 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
5220 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
5222 /* Make sure windows on this frame appear in calls to next-window
5223 and similar functions. */
5224 Vwindow_list
= Qnil
;
5226 return unbind_to (count
, frame
);
5229 /* FRAME is used only to get a handle on the X display. We don't pass the
5230 display info directly because we're called from frame.c, which doesn't
5231 know about that structure. */
5233 x_get_focus_frame (struct frame
*frame
)
5235 struct w32_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
5237 if (! dpyinfo
->w32_focus_frame
)
5240 XSETFRAME (xfocus
, dpyinfo
->w32_focus_frame
);
5244 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
5245 doc
: /* Internal function called by `color-defined-p', which see.
5246 \(Note that the Nextstep version of this function ignores FRAME.) */)
5247 (Lisp_Object color
, Lisp_Object frame
)
5250 struct frame
*f
= decode_window_system_frame (frame
);
5252 CHECK_STRING (color
);
5254 if (w32_defined_color (f
, SSDATA (color
), &foo
, false))
5260 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
5261 doc
: /* Internal function called by `color-values', which see. */)
5262 (Lisp_Object color
, Lisp_Object frame
)
5265 struct frame
*f
= decode_window_system_frame (frame
);
5267 CHECK_STRING (color
);
5269 if (w32_defined_color (f
, SSDATA (color
), &foo
, false))
5270 return list3i ((GetRValue (foo
.pixel
) << 8) | GetRValue (foo
.pixel
),
5271 (GetGValue (foo
.pixel
) << 8) | GetGValue (foo
.pixel
),
5272 (GetBValue (foo
.pixel
) << 8) | GetBValue (foo
.pixel
));
5277 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
5278 doc
: /* Internal function called by `display-color-p', which see. */)
5279 (Lisp_Object display
)
5281 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5283 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
5289 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
,
5290 Sx_display_grayscale_p
, 0, 1, 0,
5291 doc
: /* Return t if DISPLAY supports shades of gray.
5292 Note that color displays do support shades of gray.
5293 The optional argument DISPLAY specifies which display to ask about.
5294 DISPLAY should be either a frame or a display name (a string).
5295 If omitted or nil, that stands for the selected frame's display. */)
5296 (Lisp_Object display
)
5298 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5300 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
5306 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
,
5307 Sx_display_pixel_width
, 0, 1, 0,
5308 doc
: /* Return the width in pixels of DISPLAY.
5309 The optional argument DISPLAY specifies which display to ask about.
5310 DISPLAY should be either a frame or a display name (a string).
5311 If omitted or nil, that stands for the selected frame's display.
5313 On \"multi-monitor\" setups this refers to the pixel width for all
5314 physical monitors associated with DISPLAY. To get information for
5315 each physical monitor, use `display-monitor-attributes-list'. */)
5316 (Lisp_Object display
)
5318 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5320 return make_number (x_display_pixel_width (dpyinfo
));
5323 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
5324 Sx_display_pixel_height
, 0, 1, 0,
5325 doc
: /* Return the height in pixels of DISPLAY.
5326 The optional argument DISPLAY specifies which display to ask about.
5327 DISPLAY should be either a frame or a display name (a string).
5328 If omitted or nil, that stands for the selected frame's display.
5330 On \"multi-monitor\" setups this refers to the pixel height for all
5331 physical monitors associated with DISPLAY. To get information for
5332 each physical monitor, use `display-monitor-attributes-list'. */)
5333 (Lisp_Object display
)
5335 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5337 return make_number (x_display_pixel_height (dpyinfo
));
5340 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
5342 doc
: /* Return the number of bitplanes of DISPLAY.
5343 The optional argument DISPLAY specifies which display to ask about.
5344 DISPLAY should be either a frame or a display name (a string).
5345 If omitted or nil, that stands for the selected frame's display. */)
5346 (Lisp_Object display
)
5348 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5350 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
5353 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
5355 doc
: /* Return the number of color cells of DISPLAY.
5356 The optional argument DISPLAY specifies which display to ask about.
5357 DISPLAY should be either a frame or a display name (a string).
5358 If omitted or nil, that stands for the selected frame's display. */)
5359 (Lisp_Object display
)
5361 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5364 /* Don't use NCOLORS: it returns incorrect results under remote
5365 * desktop. We force 24+ bit depths to 24-bit, both to prevent an
5366 * overflow and because probably is more meaningful on Windows
5369 cap
= 1 << min (dpyinfo
->n_planes
* dpyinfo
->n_cbits
, 24);
5370 return make_number (cap
);
5373 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
5374 Sx_server_max_request_size
,
5376 doc
: /* Return the maximum request size of the server of DISPLAY.
5377 The optional argument DISPLAY specifies which display to ask about.
5378 DISPLAY should be either a frame or a display name (a string).
5379 If omitted or nil, that stands for the selected frame's display. */)
5380 (Lisp_Object display
)
5382 return make_number (1);
5385 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
5386 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
5388 \(Labeling every distributor as a "vendor" embodies the false assumption
5389 that operating systems cannot be developed and distributed noncommercially.)
5391 For GNU and Unix systems, this queries the X server software; for
5392 MS-Windows, this queries the OS.
5394 The optional argument TERMINAL specifies which display to ask about.
5395 TERMINAL should be a terminal object, a frame or a display name (a string).
5396 If omitted or nil, that stands for the selected frame's display. */)
5397 (Lisp_Object terminal
)
5399 return build_string ("Microsoft Corp.");
5402 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
5403 doc
: /* Return the version numbers of the GUI software on TERMINAL.
5404 The value is a list of three integers specifying the version of the GUI
5407 For GNU and Unix system, the first 2 numbers are the version of the X
5408 Protocol used on TERMINAL and the 3rd number is the distributor-specific
5409 release number. For MS-Windows, the 3 numbers report the version and
5410 the build number of the OS.
5412 See also the function `x-server-vendor'.
5414 The optional argument TERMINAL specifies which display to ask about.
5415 TERMINAL should be a terminal object, a frame or a display name (a string).
5416 If omitted or nil, that stands for the selected frame's display. */)
5417 (Lisp_Object terminal
)
5419 return list3i (w32_major_version
, w32_minor_version
, w32_build_number
);
5422 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
5423 doc
: /* Return the number of screens on the server of DISPLAY.
5424 The optional argument DISPLAY specifies which display to ask about.
5425 DISPLAY should be either a frame or a display name (a string).
5426 If omitted or nil, that stands for the selected frame's display. */)
5427 (Lisp_Object display
)
5429 return make_number (1);
5432 DEFUN ("x-display-mm-height", Fx_display_mm_height
,
5433 Sx_display_mm_height
, 0, 1, 0,
5434 doc
: /* Return the height in millimeters of DISPLAY.
5435 The optional argument DISPLAY specifies which display to ask about.
5436 DISPLAY should be either a frame or a display name (a string).
5437 If omitted or nil, that stands for the selected frame's display.
5439 On \"multi-monitor\" setups this refers to the height in millimeters for
5440 all physical monitors associated with DISPLAY. To get information
5441 for each physical monitor, use `display-monitor-attributes-list'. */)
5442 (Lisp_Object display
)
5444 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5446 double mm_per_pixel
;
5449 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, VERTSIZE
)
5450 / GetDeviceCaps (hdc
, VERTRES
));
5451 ReleaseDC (NULL
, hdc
);
5453 return make_number (x_display_pixel_height (dpyinfo
) * mm_per_pixel
+ 0.5);
5456 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
5457 doc
: /* Return the width in millimeters of DISPLAY.
5458 The optional argument DISPLAY specifies which display to ask about.
5459 DISPLAY should be either a frame or a display name (a string).
5460 If omitted or nil, that stands for the selected frame's display.
5462 On \"multi-monitor\" setups this refers to the width in millimeters for
5463 all physical monitors associated with TERMINAL. To get information
5464 for each physical monitor, use `display-monitor-attributes-list'. */)
5465 (Lisp_Object display
)
5467 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5469 double mm_per_pixel
;
5472 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, HORZSIZE
)
5473 / GetDeviceCaps (hdc
, HORZRES
));
5474 ReleaseDC (NULL
, hdc
);
5476 return make_number (x_display_pixel_width (dpyinfo
) * mm_per_pixel
+ 0.5);
5479 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
5480 Sx_display_backing_store
, 0, 1, 0,
5481 doc
: /* Return an indication of whether DISPLAY does backing store.
5482 The value may be `always', `when-mapped', or `not-useful'.
5483 The optional argument DISPLAY specifies which display to ask about.
5484 DISPLAY should be either a frame or a display name (a string).
5485 If omitted or nil, that stands for the selected frame's display. */)
5486 (Lisp_Object display
)
5488 return intern ("not-useful");
5491 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
5492 Sx_display_visual_class
, 0, 1, 0,
5493 doc
: /* Return the visual class of DISPLAY.
5494 The value is one of the symbols `static-gray', `gray-scale',
5495 `static-color', `pseudo-color', `true-color', or `direct-color'.
5497 The optional argument DISPLAY specifies which display to ask about.
5498 DISPLAY should be either a frame or a display name (a string).
5499 If omitted or nil, that stands for the selected frame's display. */)
5500 (Lisp_Object display
)
5502 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5503 Lisp_Object result
= Qnil
;
5505 if (dpyinfo
->has_palette
)
5506 result
= intern ("pseudo-color");
5507 else if (dpyinfo
->n_planes
* dpyinfo
->n_cbits
== 1)
5508 result
= intern ("static-grey");
5509 else if (dpyinfo
->n_planes
* dpyinfo
->n_cbits
== 4)
5510 result
= intern ("static-color");
5511 else if (dpyinfo
->n_planes
* dpyinfo
->n_cbits
> 8)
5512 result
= intern ("true-color");
5517 DEFUN ("x-display-save-under", Fx_display_save_under
,
5518 Sx_display_save_under
, 0, 1, 0,
5519 doc
: /* Return t if DISPLAY supports the save-under feature.
5520 The optional argument DISPLAY specifies which display to ask about.
5521 DISPLAY should be either a frame or a display name (a string).
5522 If omitted or nil, that stands for the selected frame's display. */)
5523 (Lisp_Object display
)
5528 static BOOL CALLBACK ALIGN_STACK
5529 w32_monitor_enum (HMONITOR monitor
, HDC hdc
, RECT
*rcMonitor
, LPARAM dwData
)
5531 Lisp_Object
*monitor_list
= (Lisp_Object
*) dwData
;
5533 *monitor_list
= Fcons (make_save_ptr (monitor
), *monitor_list
);
5539 w32_display_monitor_attributes_list (void)
5541 Lisp_Object attributes_list
= Qnil
, primary_monitor_attributes
= Qnil
;
5542 Lisp_Object monitor_list
= Qnil
, monitor_frames
, rest
, frame
;
5546 if (!(enum_display_monitors_fn
&& get_monitor_info_fn
5547 && monitor_from_window_fn
))
5550 if (!enum_display_monitors_fn (NULL
, NULL
, w32_monitor_enum
,
5551 (LPARAM
) &monitor_list
)
5552 || NILP (monitor_list
))
5556 for (rest
= monitor_list
; CONSP (rest
); rest
= XCDR (rest
))
5559 monitors
= xmalloc (n_monitors
* sizeof (*monitors
));
5560 for (i
= 0; i
< n_monitors
; i
++)
5562 monitors
[i
] = XSAVE_POINTER (XCAR (monitor_list
), 0);
5563 monitor_list
= XCDR (monitor_list
);
5566 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
5567 FOR_EACH_FRAME (rest
, frame
)
5569 struct frame
*f
= XFRAME (frame
);
5571 if (FRAME_W32_P (f
) && !EQ (frame
, tip_frame
))
5574 monitor_from_window_fn (FRAME_W32_WINDOW (f
),
5575 MONITOR_DEFAULT_TO_NEAREST
);
5577 for (i
= 0; i
< n_monitors
; i
++)
5578 if (monitors
[i
] == monitor
)
5582 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
5586 for (i
= 0; i
< n_monitors
; i
++)
5588 Lisp_Object geometry
, workarea
, name
, attributes
= Qnil
;
5590 int width_mm
, height_mm
;
5591 struct MONITOR_INFO_EX mi
;
5593 mi
.cbSize
= sizeof (mi
);
5594 if (!get_monitor_info_fn (monitors
[i
], (struct MONITOR_INFO
*) &mi
))
5597 hdc
= CreateDCA ("DISPLAY", mi
.szDevice
, NULL
, NULL
);
5600 width_mm
= GetDeviceCaps (hdc
, HORZSIZE
);
5601 height_mm
= GetDeviceCaps (hdc
, VERTSIZE
);
5604 attributes
= Fcons (Fcons (Qframes
, AREF (monitor_frames
, i
)),
5607 name
= DECODE_SYSTEM (build_unibyte_string (mi
.szDevice
));
5609 attributes
= Fcons (Fcons (Qname
, name
), attributes
);
5611 attributes
= Fcons (Fcons (Qmm_size
, list2i (width_mm
, height_mm
)),
5614 workarea
= list4i (mi
.rcWork
.left
, mi
.rcWork
.top
,
5615 mi
.rcWork
.right
- mi
.rcWork
.left
,
5616 mi
.rcWork
.bottom
- mi
.rcWork
.top
);
5617 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
5619 geometry
= list4i (mi
.rcMonitor
.left
, mi
.rcMonitor
.top
,
5620 mi
.rcMonitor
.right
- mi
.rcMonitor
.left
,
5621 mi
.rcMonitor
.bottom
- mi
.rcMonitor
.top
);
5622 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
5624 if (mi
.dwFlags
& MONITORINFOF_PRIMARY
)
5625 primary_monitor_attributes
= attributes
;
5627 attributes_list
= Fcons (attributes
, attributes_list
);
5630 if (!NILP (primary_monitor_attributes
))
5631 attributes_list
= Fcons (primary_monitor_attributes
, attributes_list
);
5635 return attributes_list
;
5639 w32_display_monitor_attributes_list_fallback (struct w32_display_info
*dpyinfo
)
5641 Lisp_Object geometry
, workarea
, frames
, rest
, frame
, attributes
= Qnil
;
5643 double mm_per_pixel
;
5644 int pixel_width
, pixel_height
, width_mm
, height_mm
;
5647 /* Fallback: treat (possibly) multiple physical monitors as if they
5648 formed a single monitor as a whole. This should provide a
5649 consistent result at least on single monitor environments. */
5650 attributes
= Fcons (Fcons (Qname
, build_string ("combined screen")),
5654 FOR_EACH_FRAME (rest
, frame
)
5656 struct frame
*f
= XFRAME (frame
);
5658 if (FRAME_W32_P (f
) && !EQ (frame
, tip_frame
))
5659 frames
= Fcons (frame
, frames
);
5661 attributes
= Fcons (Fcons (Qframes
, frames
), attributes
);
5663 pixel_width
= x_display_pixel_width (dpyinfo
);
5664 pixel_height
= x_display_pixel_height (dpyinfo
);
5667 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, HORZSIZE
)
5668 / GetDeviceCaps (hdc
, HORZRES
));
5669 width_mm
= pixel_width
* mm_per_pixel
+ 0.5;
5670 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, VERTSIZE
)
5671 / GetDeviceCaps (hdc
, VERTRES
));
5672 height_mm
= pixel_height
* mm_per_pixel
+ 0.5;
5673 ReleaseDC (NULL
, hdc
);
5674 attributes
= Fcons (Fcons (Qmm_size
, list2i (width_mm
, height_mm
)),
5677 /* GetSystemMetrics below may return 0 for Windows 95 or NT 4.0, but
5679 geometry
= list4i (GetSystemMetrics (SM_XVIRTUALSCREEN
),
5680 GetSystemMetrics (SM_YVIRTUALSCREEN
),
5681 pixel_width
, pixel_height
);
5682 if (SystemParametersInfo (SPI_GETWORKAREA
, 0, &workarea_rect
, 0))
5683 workarea
= list4i (workarea_rect
.left
, workarea_rect
.top
,
5684 workarea_rect
.right
- workarea_rect
.left
,
5685 workarea_rect
.bottom
- workarea_rect
.top
);
5687 workarea
= geometry
;
5688 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
5690 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
5692 return list1 (attributes
);
5695 DEFUN ("w32-display-monitor-attributes-list", Fw32_display_monitor_attributes_list
,
5696 Sw32_display_monitor_attributes_list
,
5698 doc
: /* Return a list of physical monitor attributes on the W32 display DISPLAY.
5700 The optional argument DISPLAY specifies which display to ask about.
5701 DISPLAY should be either a frame or a display name (a string).
5702 If omitted or nil, that stands for the selected frame's display.
5704 Internal use only, use `display-monitor-attributes-list' instead. */)
5705 (Lisp_Object display
)
5707 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5708 Lisp_Object attributes_list
;
5711 attributes_list
= w32_display_monitor_attributes_list ();
5712 if (NILP (attributes_list
))
5713 attributes_list
= w32_display_monitor_attributes_list_fallback (dpyinfo
);
5716 return attributes_list
;
5719 DEFUN ("set-message-beep", Fset_message_beep
, Sset_message_beep
, 1, 1, 0,
5720 doc
: /* Set the sound generated when the bell is rung.
5721 SOUND is `asterisk', `exclamation', `hand', `question', `ok', or `silent'
5722 to use the corresponding system sound for the bell. The `silent' sound
5723 prevents Emacs from making any sound at all.
5724 SOUND is nil to use the normal beep. */)
5727 CHECK_SYMBOL (sound
);
5730 sound_type
= 0xFFFFFFFF;
5731 else if (EQ (sound
, intern ("asterisk")))
5732 sound_type
= MB_ICONASTERISK
;
5733 else if (EQ (sound
, intern ("exclamation")))
5734 sound_type
= MB_ICONEXCLAMATION
;
5735 else if (EQ (sound
, intern ("hand")))
5736 sound_type
= MB_ICONHAND
;
5737 else if (EQ (sound
, intern ("question")))
5738 sound_type
= MB_ICONQUESTION
;
5739 else if (EQ (sound
, intern ("ok")))
5741 else if (EQ (sound
, intern ("silent")))
5742 sound_type
= MB_EMACS_SILENT
;
5744 sound_type
= 0xFFFFFFFF;
5750 x_screen_planes (register struct frame
*f
)
5752 return FRAME_DISPLAY_INFO (f
)->n_planes
;
5755 /* Return the display structure for the display named NAME.
5756 Open a new connection if necessary. */
5758 struct w32_display_info
*
5759 x_display_info_for_name (Lisp_Object name
)
5761 struct w32_display_info
*dpyinfo
;
5763 CHECK_STRING (name
);
5765 for (dpyinfo
= &one_w32_display_info
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
5766 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
5769 /* Use this general default value to start with. */
5770 Vx_resource_name
= Vinvocation_name
;
5772 validate_x_resource_name ();
5774 dpyinfo
= w32_term_init (name
, NULL
, SSDATA (Vx_resource_name
));
5777 error ("Cannot connect to server %s", SDATA (name
));
5779 XSETFASTINT (Vwindow_system_version
, w32_major_version
);
5784 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
5785 1, 3, 0, doc
: /* Open a connection to a display server.
5786 DISPLAY is the name of the display to connect to.
5787 Optional second arg XRM-STRING is a string of resources in xrdb format.
5788 If the optional third arg MUST-SUCCEED is non-nil,
5789 terminate Emacs if we can't open the connection.
5790 \(In the Nextstep version, the last two arguments are currently ignored.) */)
5791 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
5794 struct w32_display_info
*dpyinfo
;
5796 CHECK_STRING (display
);
5798 /* Signal an error in order to encourage correct use from callers.
5799 * If we ever support multiple window systems in the same Emacs,
5800 * we'll need callers to be precise about what window system they
5803 if (strcmp (SSDATA (display
), "w32") != 0)
5804 error ("The name of the display in this Emacs must be \"w32\"");
5806 /* If initialization has already been done, return now to avoid
5807 overwriting critical parts of one_w32_display_info. */
5808 if (window_system_available (NULL
))
5811 if (! NILP (xrm_string
))
5812 CHECK_STRING (xrm_string
);
5814 /* Allow color mapping to be defined externally; first look in user's
5815 HOME directory, then in Emacs etc dir for a file called rgb.txt. */
5817 Lisp_Object color_file
;
5819 color_file
= build_string ("~/rgb.txt");
5821 if (NILP (Ffile_readable_p (color_file
)))
5823 Fexpand_file_name (build_string ("rgb.txt"),
5824 Fsymbol_value (intern ("data-directory")));
5826 Vw32_color_map
= Fx_load_color_file (color_file
);
5828 if (NILP (Vw32_color_map
))
5829 Vw32_color_map
= w32_default_color_map ();
5831 /* Merge in system logical colors. */
5832 add_system_logical_colors_to_map (&Vw32_color_map
);
5834 if (! NILP (xrm_string
))
5835 xrm_option
= SSDATA (xrm_string
);
5839 /* Use this general default value to start with. */
5840 /* First remove .exe suffix from invocation-name - it looks ugly. */
5842 char basename
[ MAX_PATH
], *str
;
5844 lispstpcpy (basename
, Vinvocation_name
);
5845 str
= strrchr (basename
, '.');
5847 Vinvocation_name
= build_string (basename
);
5849 Vx_resource_name
= Vinvocation_name
;
5851 validate_x_resource_name ();
5853 /* This is what opens the connection and sets x_current_display.
5854 This also initializes many symbols, such as those used for input. */
5855 dpyinfo
= w32_term_init (display
, xrm_option
, SSDATA (Vx_resource_name
));
5859 if (!NILP (must_succeed
))
5860 fatal ("Cannot connect to server %s.\n",
5863 error ("Cannot connect to server %s", SDATA (display
));
5866 XSETFASTINT (Vwindow_system_version
, w32_major_version
);
5870 DEFUN ("x-close-connection", Fx_close_connection
,
5871 Sx_close_connection
, 1, 1, 0,
5872 doc
: /* Close the connection to DISPLAY's server.
5873 For DISPLAY, specify either a frame or a display name (a string).
5874 If DISPLAY is nil, that stands for the selected frame's display. */)
5875 (Lisp_Object display
)
5877 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5879 if (dpyinfo
->reference_count
> 0)
5880 error ("Display still has frames on it");
5883 x_destroy_all_bitmaps (dpyinfo
);
5885 x_delete_display (dpyinfo
);
5891 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
5892 doc
: /* Return the list of display names that Emacs has connections to. */)
5895 Lisp_Object result
= Qnil
;
5896 struct w32_display_info
*wdi
;
5898 for (wdi
= x_display_list
; wdi
; wdi
= wdi
->next
)
5899 result
= Fcons (XCAR (wdi
->name_list_element
), result
);
5904 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
5905 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
5906 This function only has an effect on X Windows. With MS Windows, it is
5907 defined but does nothing.
5909 If ON is nil, allow buffering of requests.
5910 Turning on synchronization prohibits the Xlib routines from buffering
5911 requests and seriously degrades performance, but makes debugging much
5913 The optional second argument TERMINAL specifies which display to act on.
5914 TERMINAL should be a terminal object, a frame or a display name (a string).
5915 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
5916 (Lisp_Object on
, Lisp_Object display
)
5923 /***********************************************************************
5925 ***********************************************************************/
5927 #if 0 /* TODO : port window properties to W32 */
5929 DEFUN ("x-change-window-property", Fx_change_window_property
,
5930 Sx_change_window_property
, 2, 6, 0,
5931 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
5932 PROP must be a string. VALUE may be a string or a list of conses,
5933 numbers and/or strings. If an element in the list is a string, it is
5934 converted to an atom and the value of the Atom is used. If an element
5935 is a cons, it is converted to a 32 bit number where the car is the 16
5936 top bits and the cdr is the lower 16 bits.
5938 FRAME nil or omitted means use the selected frame.
5939 If TYPE is given and non-nil, it is the name of the type of VALUE.
5940 If TYPE is not given or nil, the type is STRING.
5941 FORMAT gives the size in bits of each element if VALUE is a list.
5942 It must be one of 8, 16 or 32.
5943 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
5944 If OUTER-P is non-nil, the property is changed for the outer X window of
5945 FRAME. Default is to change on the edit X window. */)
5946 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
5947 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
5949 struct frame
*f
= decode_window_system_frame (frame
);
5952 CHECK_STRING (prop
);
5953 CHECK_STRING (value
);
5956 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
5957 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
5958 prop_atom
, XA_STRING
, 8, PropModeReplace
,
5959 SDATA (value
), SCHARS (value
));
5961 /* Make sure the property is set when we return. */
5962 XFlush (FRAME_W32_DISPLAY (f
));
5969 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
5970 Sx_delete_window_property
, 1, 2, 0,
5971 doc
: /* Remove window property PROP from X window of FRAME.
5972 FRAME nil or omitted means use the selected frame. Value is PROP. */)
5973 (Lisp_Object prop
, Lisp_Object frame
)
5975 struct frame
*f
= decode_window_system_frame (frame
);
5978 CHECK_STRING (prop
);
5980 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
5981 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
5983 /* Make sure the property is removed when we return. */
5984 XFlush (FRAME_W32_DISPLAY (f
));
5991 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
5993 doc
: /* Value is the value of window property PROP on FRAME.
5994 If FRAME is nil or omitted, use the selected frame.
5996 On X Windows, the following optional arguments are also accepted:
5997 If TYPE is nil or omitted, get the property as a string.
5998 Otherwise TYPE is the name of the atom that denotes the type expected.
5999 If SOURCE is non-nil, get the property on that window instead of from
6000 FRAME. The number 0 denotes the root window.
6001 If DELETE-P is non-nil, delete the property after retrieving it.
6002 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
6004 On MS Windows, this function accepts but ignores those optional arguments.
6006 Value is nil if FRAME hasn't a property with name PROP or if PROP has
6007 no value of TYPE (always string in the MS Windows case). */)
6008 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
6009 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
6011 struct frame
*f
= decode_window_system_frame (frame
);
6014 Lisp_Object prop_value
= Qnil
;
6015 char *tmp_data
= NULL
;
6018 unsigned long actual_size
, bytes_remaining
;
6020 CHECK_STRING (prop
);
6022 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
6023 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
6024 prop_atom
, 0, 0, False
, XA_STRING
,
6025 &actual_type
, &actual_format
, &actual_size
,
6026 &bytes_remaining
, (unsigned char **) &tmp_data
);
6029 int size
= bytes_remaining
;
6034 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
6035 prop_atom
, 0, bytes_remaining
,
6037 &actual_type
, &actual_format
,
6038 &actual_size
, &bytes_remaining
,
6039 (unsigned char **) &tmp_data
);
6041 prop_value
= make_string (tmp_data
, size
);
6055 /***********************************************************************
6057 ***********************************************************************/
6059 static Lisp_Object
x_create_tip_frame (struct w32_display_info
*,
6060 Lisp_Object
, Lisp_Object
);
6061 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
6062 Lisp_Object
, int, int, int *, int *);
6064 /* The frame of a currently visible tooltip. */
6066 Lisp_Object tip_frame
;
6068 /* If non-nil, a timer started that hides the last tooltip when it
6071 Lisp_Object tip_timer
;
6074 /* If non-nil, a vector of 3 elements containing the last args
6075 with which x-show-tip was called. See there. */
6077 Lisp_Object last_show_tip_args
;
6081 unwind_create_tip_frame (Lisp_Object frame
)
6083 Lisp_Object deleted
;
6085 deleted
= unwind_create_frame (frame
);
6086 if (EQ (deleted
, Qt
))
6094 /* Create a frame for a tooltip on the display described by DPYINFO.
6095 PARMS is a list of frame parameters. TEXT is the string to
6096 display in the tip frame. Value is the frame.
6098 Note that functions called here, esp. x_default_parameter can
6099 signal errors, for instance when a specified color name is
6100 undefined. We have to make sure that we're in a consistent state
6101 when this happens. */
6104 x_create_tip_frame (struct w32_display_info
*dpyinfo
,
6105 Lisp_Object parms
, Lisp_Object text
)
6111 ptrdiff_t count
= SPECPDL_INDEX ();
6113 bool face_change_before
= face_change
;
6115 struct buffer
*old_buffer
;
6116 int x_width
= 0, x_height
= 0;
6118 /* Use this general default value to start with until we know if
6119 this frame has a specified name. */
6120 Vx_resource_name
= Vinvocation_name
;
6122 kb
= dpyinfo
->terminal
->kboard
;
6124 /* The calls to x_get_arg remove elements from PARMS, so copy it to
6125 avoid destructive changes behind our caller's back. */
6126 parms
= Fcopy_alist (parms
);
6128 /* Get the name of the frame to use for resource lookup. */
6129 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
6131 && !EQ (name
, Qunbound
)
6133 error ("Invalid frame name--not a string or nil");
6134 Vx_resource_name
= name
;
6137 /* Make a frame without minibuffer nor mode-line. */
6138 f
= make_frame (false);
6139 f
->wants_modeline
= 0;
6140 XSETFRAME (frame
, f
);
6142 AUTO_STRING (tip
, " *tip*");
6143 buffer
= Fget_buffer_create (tip
);
6144 /* Use set_window_buffer instead of Fset_window_buffer (see
6145 discussion of bug#11984, bug#12025, bug#12026). */
6146 set_window_buffer (FRAME_ROOT_WINDOW (f
), buffer
, false, false);
6147 old_buffer
= current_buffer
;
6148 set_buffer_internal_1 (XBUFFER (buffer
));
6149 bset_truncate_lines (current_buffer
, Qnil
);
6150 specbind (Qinhibit_read_only
, Qt
);
6151 specbind (Qinhibit_modification_hooks
, Qt
);
6154 set_buffer_internal_1 (old_buffer
);
6156 record_unwind_protect (unwind_create_tip_frame
, frame
);
6158 /* By setting the output method, we're essentially saying that
6159 the frame is live, as per FRAME_LIVE_P. If we get a signal
6160 from this point on, x_destroy_window might screw up reference
6162 f
->terminal
= dpyinfo
->terminal
;
6163 f
->output_method
= output_w32
;
6164 f
->output_data
.w32
= xzalloc (sizeof (struct w32_output
));
6166 FRAME_FONTSET (f
) = -1;
6167 fset_icon_name (f
, Qnil
);
6170 image_cache_refcount
=
6171 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
6172 dpyinfo_refcount
= dpyinfo
->reference_count
;
6173 #endif /* GLYPH_DEBUG */
6174 FRAME_KBOARD (f
) = kb
;
6175 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
6176 f
->output_data
.w32
->explicit_parent
= false;
6178 /* Set the name; the functions to which we pass f expect the name to
6180 if (EQ (name
, Qunbound
) || NILP (name
))
6182 fset_name (f
, build_string (dpyinfo
->w32_id_name
));
6183 f
->explicit_name
= false;
6187 fset_name (f
, name
);
6188 f
->explicit_name
= true;
6189 /* use the frame's title when getting resources for this frame. */
6190 specbind (Qx_resource_name
, name
);
6193 if (uniscribe_available
)
6194 register_font_driver (&uniscribe_font_driver
, f
);
6195 register_font_driver (&w32font_driver
, f
);
6197 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
6198 "fontBackend", "FontBackend", RES_TYPE_STRING
);
6200 /* Extract the window parameters from the supplied values
6201 that are needed to determine window geometry. */
6202 x_default_font_parameter (f
, parms
);
6204 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
6205 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
6206 /* This defaults to 2 in order to match xterm. We recognize either
6207 internalBorderWidth or internalBorder (which is what xterm calls
6209 if (NILP (Fassq (Qinternal_border_width
, parms
)))
6213 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
6214 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
6215 if (! EQ (value
, Qunbound
))
6216 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
6219 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
6220 "internalBorderWidth", "internalBorderWidth",
6222 x_default_parameter (f
, parms
, Qright_divider_width
, make_number (0),
6223 NULL
, NULL
, RES_TYPE_NUMBER
);
6224 x_default_parameter (f
, parms
, Qbottom_divider_width
, make_number (0),
6225 NULL
, NULL
, RES_TYPE_NUMBER
);
6227 /* Also do the stuff which must be set before the window exists. */
6228 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
6229 "foreground", "Foreground", RES_TYPE_STRING
);
6230 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
6231 "background", "Background", RES_TYPE_STRING
);
6232 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
6233 "pointerColor", "Foreground", RES_TYPE_STRING
);
6234 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
6235 "cursorColor", "Foreground", RES_TYPE_STRING
);
6236 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
6237 "borderColor", "BorderColor", RES_TYPE_STRING
);
6239 /* Init faces before x_default_parameter is called for the
6240 scroll-bar-width parameter because otherwise we end up in
6241 init_iterator with a null face cache, which should not happen. */
6242 init_frame_faces (f
);
6244 f
->output_data
.w32
->dwStyle
= WS_BORDER
| WS_POPUP
| WS_DISABLED
;
6245 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
6247 x_figure_window_size (f
, parms
, true, &x_width
, &x_height
);
6249 /* No fringes on tip frame. */
6251 f
->left_fringe_width
= 0;
6252 f
->right_fringe_width
= 0;
6255 my_create_tip_window (f
);
6260 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
6261 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
6262 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
6263 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
6264 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
6265 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
6266 /* Process alpha here (Bug#17344). */
6267 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
6268 "alpha", "Alpha", RES_TYPE_NUMBER
);
6270 /* Dimensions, especially FRAME_LINES (f), must be done via
6271 change_frame_size. Change will not be effected unless different
6272 from the current FRAME_LINES (f). */
6273 width
= FRAME_COLS (f
);
6274 height
= FRAME_LINES (f
);
6275 SET_FRAME_COLS (f
, 0);
6276 SET_FRAME_LINES (f
, 0);
6277 adjust_frame_size (f
, width
* FRAME_COLUMN_WIDTH (f
),
6278 height
* FRAME_LINE_HEIGHT (f
), 0, true, Qtip_frame
);
6280 /* Add `tooltip' frame parameter's default value. */
6281 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
6282 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qtooltip
, Qt
), Qnil
));
6284 /* Set up faces after all frame parameters are known. This call
6285 also merges in face attributes specified for new frames.
6287 Frame parameters may be changed if .Xdefaults contains
6288 specifications for the default font. For example, if there is an
6289 `Emacs.default.attributeBackground: pink', the `background-color'
6290 attribute of the frame get's set, which let's the internal border
6291 of the tooltip frame appear in pink. Prevent this. */
6293 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
6294 Lisp_Object fg
= Fframe_parameter (frame
, Qforeground_color
);
6295 Lisp_Object colors
= Qnil
;
6297 /* Set tip_frame here, so that */
6299 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
6301 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
6302 colors
= Fcons (Fcons (Qbackground_color
, bg
), colors
);
6303 if (!EQ (fg
, Fframe_parameter (frame
, Qforeground_color
)))
6304 colors
= Fcons (Fcons (Qforeground_color
, fg
), colors
);
6307 Fmodify_frame_parameters (frame
, colors
);
6312 /* Now that the frame is official, it counts as a reference to
6314 FRAME_DISPLAY_INFO (f
)->reference_count
++;
6315 f
->terminal
->reference_count
++;
6317 /* It is now ok to make the frame official even if we get an error
6318 below. And the frame needs to be on Vframe_list or making it
6319 visible won't work. */
6320 Vframe_list
= Fcons (frame
, Vframe_list
);
6321 f
->can_x_set_window_size
= true;
6323 /* Setting attributes of faces of the tooltip frame from resources
6324 and similar will set face_change, which leads to the
6325 clearing of all current matrices. Since this isn't necessary
6326 here, avoid it by resetting face_change to the value it
6327 had before we created the tip frame. */
6328 face_change
= face_change_before
;
6330 /* Discard the unwind_protect. */
6331 return unbind_to (count
, frame
);
6335 /* Compute where to display tip frame F. PARMS is the list of frame
6336 parameters for F. DX and DY are specified offsets from the current
6337 location of the mouse. WIDTH and HEIGHT are the width and height
6338 of the tooltip. Return coordinates relative to the root window of
6339 the display in *ROOT_X and *ROOT_Y. */
6342 compute_tip_xy (struct frame
*f
,
6343 Lisp_Object parms
, Lisp_Object dx
, Lisp_Object dy
,
6344 int width
, int height
, int *root_x
, int *root_y
)
6346 Lisp_Object left
, top
, right
, bottom
;
6347 int min_x
, min_y
, max_x
, max_y
;
6349 /* User-specified position? */
6350 left
= Fcdr (Fassq (Qleft
, parms
));
6351 top
= Fcdr (Fassq (Qtop
, parms
));
6352 right
= Fcdr (Fassq (Qright
, parms
));
6353 bottom
= Fcdr (Fassq (Qbottom
, parms
));
6355 /* Move the tooltip window where the mouse pointer is. Resize and
6357 if ((!INTEGERP (left
) && !INTEGERP (right
))
6358 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
6362 /* Default min and max values. */
6365 max_x
= x_display_pixel_width (FRAME_DISPLAY_INFO (f
));
6366 max_y
= x_display_pixel_height (FRAME_DISPLAY_INFO (f
));
6374 /* If multiple monitor support is available, constrain the tip onto
6375 the current monitor. This improves the above by allowing negative
6376 co-ordinates if monitor positions are such that they are valid, and
6377 snaps a tooltip onto a single monitor if we are close to the edge
6378 where it would otherwise flow onto the other monitor (or into
6379 nothingness if there is a gap in the overlap). */
6380 if (monitor_from_point_fn
&& get_monitor_info_fn
)
6382 struct MONITOR_INFO info
;
6384 = monitor_from_point_fn (pt
, MONITOR_DEFAULT_TO_NEAREST
);
6385 info
.cbSize
= sizeof (info
);
6387 if (get_monitor_info_fn (monitor
, &info
))
6389 min_x
= info
.rcWork
.left
;
6390 min_y
= info
.rcWork
.top
;
6391 max_x
= info
.rcWork
.right
;
6392 max_y
= info
.rcWork
.bottom
;
6398 *root_y
= XINT (top
);
6399 else if (INTEGERP (bottom
))
6400 *root_y
= XINT (bottom
) - height
;
6401 else if (*root_y
+ XINT (dy
) <= min_y
)
6402 *root_y
= min_y
; /* Can happen for negative dy */
6403 else if (*root_y
+ XINT (dy
) + height
<= max_y
)
6404 /* It fits below the pointer */
6405 *root_y
+= XINT (dy
);
6406 else if (height
+ XINT (dy
) + min_y
<= *root_y
)
6407 /* It fits above the pointer. */
6408 *root_y
-= height
+ XINT (dy
);
6410 /* Put it on the top. */
6413 if (INTEGERP (left
))
6414 *root_x
= XINT (left
);
6415 else if (INTEGERP (right
))
6416 *root_x
= XINT (right
) - width
;
6417 else if (*root_x
+ XINT (dx
) <= min_x
)
6418 *root_x
= 0; /* Can happen for negative dx */
6419 else if (*root_x
+ XINT (dx
) + width
<= max_x
)
6420 /* It fits to the right of the pointer. */
6421 *root_x
+= XINT (dx
);
6422 else if (width
+ XINT (dx
) + min_x
<= *root_x
)
6423 /* It fits to the left of the pointer. */
6424 *root_x
-= width
+ XINT (dx
);
6426 /* Put it left justified on the screen -- it ought to fit that way. */
6431 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
6432 doc
: /* Show STRING in a \"tooltip\" window on frame FRAME.
6433 A tooltip window is a small window displaying a string.
6435 This is an internal function; Lisp code should call `tooltip-show'.
6437 FRAME nil or omitted means use the selected frame.
6439 PARMS is an optional list of frame parameters which can be
6440 used to change the tooltip's appearance.
6442 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
6443 means use the default timeout of 5 seconds.
6445 If the list of frame parameters PARMS contains a `left' parameter,
6446 display the tooltip at that x-position. If the list of frame parameters
6447 PARMS contains no `left' but a `right' parameter, display the tooltip
6448 right-adjusted at that x-position. Otherwise display it at the
6449 x-position of the mouse, with offset DX added (default is 5 if DX isn't
6452 Likewise for the y-position: If a `top' frame parameter is specified, it
6453 determines the position of the upper edge of the tooltip window. If a
6454 `bottom' parameter but no `top' frame parameter is specified, it
6455 determines the position of the lower edge of the tooltip window.
6456 Otherwise display the tooltip window at the y-position of the mouse,
6457 with offset DY added (default is -10).
6459 A tooltip's maximum size is specified by `x-max-tooltip-size'.
6460 Text larger than the specified size is clipped. */)
6461 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
6466 struct buffer
*old_buffer
;
6467 struct text_pos pos
;
6468 int i
, width
, height
;
6469 bool seen_reversed_p
;
6470 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6471 ptrdiff_t count
= SPECPDL_INDEX ();
6473 specbind (Qinhibit_redisplay
, Qt
);
6475 CHECK_STRING (string
);
6476 f
= decode_window_system_frame (frame
);
6478 timeout
= make_number (5);
6480 CHECK_NATNUM (timeout
);
6483 dx
= make_number (5);
6488 dy
= make_number (-10);
6492 if (NILP (last_show_tip_args
))
6493 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
6495 if (!NILP (tip_frame
))
6497 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
6498 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
6499 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
6501 if (EQ (frame
, last_frame
)
6502 && !NILP (Fequal (last_string
, string
))
6503 && !NILP (Fequal (last_parms
, parms
)))
6505 struct frame
*f
= XFRAME (tip_frame
);
6507 /* Only DX and DY have changed. */
6508 if (!NILP (tip_timer
))
6510 Lisp_Object timer
= tip_timer
;
6512 call1 (Qcancel_timer
, timer
);
6516 compute_tip_xy (f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (f
),
6517 FRAME_PIXEL_HEIGHT (f
), &root_x
, &root_y
);
6519 /* Put tooltip in topmost group and in position. */
6520 SetWindowPos (FRAME_W32_WINDOW (f
), HWND_TOPMOST
,
6521 root_x
, root_y
, 0, 0,
6522 SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
6524 /* Ensure tooltip is on top of other topmost windows (eg menus). */
6525 SetWindowPos (FRAME_W32_WINDOW (f
), HWND_TOP
,
6527 SWP_NOMOVE
| SWP_NOSIZE
6528 | SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
6535 /* Hide a previous tip, if any. */
6538 ASET (last_show_tip_args
, 0, string
);
6539 ASET (last_show_tip_args
, 1, frame
);
6540 ASET (last_show_tip_args
, 2, parms
);
6542 /* Add default values to frame parameters. */
6543 if (NILP (Fassq (Qname
, parms
)))
6544 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
6545 if (NILP (Fassq (Qinternal_border_width
, parms
)))
6546 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
6547 if (NILP (Fassq (Qright_divider_width
, parms
)))
6548 parms
= Fcons (Fcons (Qright_divider_width
, make_number (0)), parms
);
6549 if (NILP (Fassq (Qbottom_divider_width
, parms
)))
6550 parms
= Fcons (Fcons (Qbottom_divider_width
, make_number (0)), parms
);
6551 if (NILP (Fassq (Qborder_width
, parms
)))
6552 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
6553 if (NILP (Fassq (Qborder_color
, parms
)))
6554 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
6555 if (NILP (Fassq (Qbackground_color
, parms
)))
6556 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
6559 /* Block input until the tip has been fully drawn, to avoid crashes
6560 when drawing tips in menus. */
6563 /* Create a frame for the tooltip, and record it in the global
6564 variable tip_frame. */
6565 frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
, string
);
6568 /* Set up the frame's root window. */
6569 w
= XWINDOW (FRAME_ROOT_WINDOW (f
));
6575 if (CONSP (Vx_max_tooltip_size
)
6576 && INTEGERP (XCAR (Vx_max_tooltip_size
))
6577 && XINT (XCAR (Vx_max_tooltip_size
)) > 0
6578 && INTEGERP (XCDR (Vx_max_tooltip_size
))
6579 && XINT (XCDR (Vx_max_tooltip_size
)) > 0)
6581 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
6582 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
6587 w
->total_lines
= 40;
6590 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (f
);
6591 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (f
);
6593 FRAME_TOTAL_COLS (f
) = WINDOW_TOTAL_COLS (w
);
6594 adjust_frame_glyphs (f
);
6595 w
->pseudo_window_p
= true;
6597 /* Display the tooltip text in a temporary buffer. */
6598 old_buffer
= current_buffer
;
6599 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f
))->contents
));
6600 bset_truncate_lines (current_buffer
, Qnil
);
6601 clear_glyph_matrix (w
->desired_matrix
);
6602 clear_glyph_matrix (w
->current_matrix
);
6603 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
6604 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
6606 /* Compute width and height of the tooltip. */
6608 seen_reversed_p
= false;
6609 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
6611 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
6615 /* Stop at the first empty row at the end. */
6616 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
6619 /* Let the row go over the full width of the frame. */
6620 row
->full_width_p
= true;
6622 row_width
= row
->pixel_width
;
6623 if (row
->used
[TEXT_AREA
])
6625 if (!row
->reversed_p
)
6627 /* There's a glyph at the end of rows that is used to
6628 place the cursor there. Don't include the width of
6630 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
6631 if (NILP (last
->object
))
6632 row_width
-= last
->pixel_width
;
6636 /* There could be a stretch glyph at the beginning of R2L
6637 rows that is produced by extend_face_to_end_of_line.
6638 Don't count that glyph. */
6639 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
6641 if (g
->type
== STRETCH_GLYPH
&& NILP (g
->object
))
6643 row_width
-= g
->pixel_width
;
6644 seen_reversed_p
= true;
6649 height
+= row
->height
;
6650 width
= max (width
, row_width
);
6653 /* If we've seen partial-length R2L rows, we need to re-adjust the
6654 tool-tip frame width and redisplay it again, to avoid over-wide
6655 tips due to the stretch glyph that extends R2L lines to full
6656 width of the frame. */
6657 if (seen_reversed_p
)
6659 /* PXW: Why do we do the pixel-to-cols conversion only if
6660 seen_reversed_p holds? Don't we have to set other fields of
6661 the window/frame structure?
6663 w->total_cols and FRAME_TOTAL_COLS want the width in columns,
6665 w
->pixel_width
= width
;
6666 width
/= WINDOW_FRAME_COLUMN_WIDTH (w
);
6667 w
->total_cols
= width
;
6668 FRAME_TOTAL_COLS (f
) = width
;
6669 SET_FRAME_WIDTH (f
, width
);
6670 adjust_frame_glyphs (f
);
6671 w
->pseudo_window_p
= 1;
6672 clear_glyph_matrix (w
->desired_matrix
);
6673 clear_glyph_matrix (w
->current_matrix
);
6674 try_window (FRAME_ROOT_WINDOW (f
), pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
6676 /* Recompute width and height of the tooltip. */
6677 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
6679 struct glyph_row
*row
= &w
->desired_matrix
->rows
[i
];
6683 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
6685 row
->full_width_p
= true;
6686 row_width
= row
->pixel_width
;
6687 if (row
->used
[TEXT_AREA
] && !row
->reversed_p
)
6689 last
= &row
->glyphs
[TEXT_AREA
][row
->used
[TEXT_AREA
] - 1];
6690 if (NILP (last
->object
))
6691 row_width
-= last
->pixel_width
;
6694 height
+= row
->height
;
6695 width
= max (width
, row_width
);
6699 /* Add the frame's internal border to the width and height the w32
6700 window should have. */
6701 height
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
6702 width
+= 2 * FRAME_INTERNAL_BORDER_WIDTH (f
);
6704 /* Move the tooltip window where the mouse pointer is. Resize and
6707 PXW: This should use the frame's pixel coordinates. */
6708 compute_tip_xy (f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
6711 /* Adjust Window size to take border into account. */
6713 rect
.left
= rect
.top
= 0;
6715 rect
.bottom
= height
;
6716 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
, false);
6718 /* Position and size tooltip, and put it in the topmost group.
6719 The add-on of FRAME_COLUMN_WIDTH to the 5th argument is a
6720 peculiarity of w32 display: without it, some fonts cause the
6721 last character of the tip to be truncated or wrapped around to
6723 SetWindowPos (FRAME_W32_WINDOW (f
), HWND_TOPMOST
,
6725 rect
.right
- rect
.left
+ FRAME_COLUMN_WIDTH (f
),
6726 rect
.bottom
- rect
.top
, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
6728 /* Ensure tooltip is on top of other topmost windows (eg menus). */
6729 SetWindowPos (FRAME_W32_WINDOW (f
), HWND_TOP
,
6731 SWP_NOMOVE
| SWP_NOSIZE
6732 | SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
6734 /* Let redisplay know that we have made the frame visible already. */
6735 SET_FRAME_VISIBLE (f
, 1);
6737 ShowWindow (FRAME_W32_WINDOW (f
), SW_SHOWNOACTIVATE
);
6740 /* Draw into the window. */
6741 w
->must_be_updated_p
= true;
6742 update_single_window (w
);
6746 /* Restore original current buffer. */
6747 set_buffer_internal_1 (old_buffer
);
6748 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
6751 /* Let the tip disappear after timeout seconds. */
6752 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
6753 intern ("x-hide-tip"));
6755 return unbind_to (count
, Qnil
);
6759 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
6760 doc
: /* Hide the current tooltip window, if there is any.
6761 Value is t if tooltip was open, nil otherwise. */)
6765 Lisp_Object deleted
, frame
, timer
;
6767 /* Return quickly if nothing to do. */
6768 if (NILP (tip_timer
) && NILP (tip_frame
))
6773 tip_frame
= tip_timer
= deleted
= Qnil
;
6775 count
= SPECPDL_INDEX ();
6776 specbind (Qinhibit_redisplay
, Qt
);
6777 specbind (Qinhibit_quit
, Qt
);
6780 call1 (Qcancel_timer
, timer
);
6784 delete_frame (frame
, Qnil
);
6788 return unbind_to (count
, deleted
);
6791 /***********************************************************************
6792 File selection dialog
6793 ***********************************************************************/
6795 #define FILE_NAME_TEXT_FIELD edt1
6796 #define FILE_NAME_COMBO_BOX cmb13
6797 #define FILE_NAME_LIST lst1
6799 /* Callback for altering the behavior of the Open File dialog.
6800 Makes the Filename text field contain "Current Directory" and be
6801 read-only when "Directories" is selected in the filter. This
6802 allows us to work around the fact that the standard Open File
6803 dialog does not support directories. */
6804 static UINT_PTR CALLBACK
6805 file_dialog_callback (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
6807 if (msg
== WM_NOTIFY
)
6809 OFNOTIFYW
* notify_w
= (OFNOTIFYW
*)lParam
;
6810 OFNOTIFYA
* notify_a
= (OFNOTIFYA
*)lParam
;
6811 int dropdown_changed
;
6813 #ifdef NTGUI_UNICODE
6814 const int use_unicode
= 1;
6815 #else /* !NTGUI_UNICODE */
6816 int use_unicode
= w32_unicode_filenames
;
6817 #endif /* NTGUI_UNICODE */
6819 /* Detect when the Filter dropdown is changed. */
6822 notify_w
->hdr
.code
== CDN_TYPECHANGE
6823 || notify_w
->hdr
.code
== CDN_INITDONE
;
6826 notify_a
->hdr
.code
== CDN_TYPECHANGE
6827 || notify_a
->hdr
.code
== CDN_INITDONE
;
6828 if (dropdown_changed
)
6830 HWND dialog
= GetParent (hwnd
);
6831 HWND edit_control
= GetDlgItem (dialog
, FILE_NAME_TEXT_FIELD
);
6832 HWND list
= GetDlgItem (dialog
, FILE_NAME_LIST
);
6835 /* At least on Windows 7, the above attempt to get the window handle
6836 to the File Name Text Field fails. The following code does the
6837 job though. Note that this code is based on my examination of the
6838 window hierarchy using Microsoft Spy++. bk */
6839 if (edit_control
== NULL
)
6841 HWND tmp
= GetDlgItem (dialog
, FILE_NAME_COMBO_BOX
);
6844 tmp
= GetWindow (tmp
, GW_CHILD
);
6846 edit_control
= GetWindow (tmp
, GW_CHILD
);
6850 /* Directories is in index 2. */
6853 dir_index
= notify_w
->lpOFN
->nFilterIndex
;
6854 hdr_code
= notify_w
->hdr
.code
;
6858 dir_index
= notify_a
->lpOFN
->nFilterIndex
;
6859 hdr_code
= notify_a
->hdr
.code
;
6864 SendMessageW (dialog
, CDM_SETCONTROLTEXT
, FILE_NAME_TEXT_FIELD
,
6865 (LPARAM
)L
"Current Directory");
6867 SendMessageA (dialog
, CDM_SETCONTROLTEXT
, FILE_NAME_TEXT_FIELD
,
6868 (LPARAM
)"Current Directory");
6869 EnableWindow (edit_control
, FALSE
);
6870 /* Note that at least on Windows 7, the above call to EnableWindow
6871 disables the window that would ordinarily have focus. If we
6872 do not set focus to some other window here, focus will land in
6873 no man's land and the user will be unable to tab through the
6874 dialog box (pressing tab will only result in a beep).
6875 Avoid that problem by setting focus to the list here. */
6876 if (hdr_code
== CDN_INITDONE
)
6881 /* Don't override default filename on init done. */
6882 if (hdr_code
== CDN_TYPECHANGE
)
6885 SendMessageW (dialog
, CDM_SETCONTROLTEXT
,
6886 FILE_NAME_TEXT_FIELD
, (LPARAM
)L
"");
6888 SendMessageA (dialog
, CDM_SETCONTROLTEXT
,
6889 FILE_NAME_TEXT_FIELD
, (LPARAM
)"");
6891 EnableWindow (edit_control
, TRUE
);
6898 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
6899 doc
: /* Read file name, prompting with PROMPT in directory DIR.
6900 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
6901 selection box, if specified. If MUSTMATCH is non-nil, the returned file
6902 or directory must exist.
6904 This function is only defined on NS, MS Windows, and X Windows with the
6905 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
6906 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
6907 On Windows 7 and later, the file selection dialog "remembers" the last
6908 directory where the user selected a file, and will open that directory
6909 instead of DIR on subsequent invocations of this function with the same
6910 value of DIR as in previous invocations; this is standard Windows behavior. */)
6911 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
6913 /* Filter index: 1: All Files, 2: Directories only */
6914 static const wchar_t filter_w
[] = L
"All Files (*.*)\0*.*\0Directories\0*|*\0";
6915 static const char filter_a
[] = "All Files (*.*)\0*.*\0Directories\0*|*\0";
6917 Lisp_Object filename
= default_filename
;
6918 struct frame
*f
= SELECTED_FRAME ();
6919 BOOL file_opened
= FALSE
;
6920 Lisp_Object orig_dir
= dir
;
6921 Lisp_Object orig_prompt
= prompt
;
6923 /* If we compile with _WIN32_WINNT set to 0x0400 (for NT4
6924 compatibility) we end up with the old file dialogs. Define a big
6925 enough struct for the new dialog to trick GetOpenFileName into
6926 giving us the new dialogs on newer versions of Windows. */
6928 OPENFILENAMEW details
;
6929 #if _WIN32_WINNT < 0x500 /* < win2k */
6933 #endif /* < win2k */
6934 } new_file_details_w
;
6936 #ifdef NTGUI_UNICODE
6937 wchar_t filename_buf_w
[32*1024 + 1]; /* NT kernel maximum */
6938 OPENFILENAMEW
* file_details_w
= &new_file_details_w
.details
;
6939 const int use_unicode
= 1;
6940 #else /* not NTGUI_UNICODE */
6942 OPENFILENAMEA details
;
6943 #if _WIN32_WINNT < 0x500 /* < win2k */
6947 #endif /* < win2k */
6948 } new_file_details_a
;
6949 wchar_t filename_buf_w
[MAX_PATH
+ 1], dir_w
[MAX_PATH
];
6950 char filename_buf_a
[MAX_PATH
+ 1], dir_a
[MAX_PATH
];
6951 OPENFILENAMEW
* file_details_w
= &new_file_details_w
.details
;
6952 OPENFILENAMEA
* file_details_a
= &new_file_details_a
.details
;
6953 int use_unicode
= w32_unicode_filenames
;
6957 char fname_ret
[MAX_UTF8_PATH
];
6958 #endif /* NTGUI_UNICODE */
6961 /* Note: under NTGUI_UNICODE, we do _NOT_ use ENCODE_FILE: the
6962 system file encoding expected by the platform APIs (e.g. Cygwin's
6963 POSIX implementation) may not be the same as the encoding expected
6964 by the Windows "ANSI" APIs! */
6966 CHECK_STRING (prompt
);
6969 dir
= Fexpand_file_name (dir
, Qnil
);
6971 if (STRINGP (filename
))
6972 filename
= Ffile_name_nondirectory (filename
);
6974 filename
= empty_unibyte_string
;
6977 dir
= Fcygwin_convert_file_name_to_windows (dir
, Qt
);
6978 if (SCHARS (filename
) > 0)
6979 filename
= Fcygwin_convert_file_name_to_windows (filename
, Qnil
);
6983 CHECK_STRING (filename
);
6985 /* The code in file_dialog_callback that attempts to set the text
6986 of the file name edit window when handling the CDN_INITDONE
6987 WM_NOTIFY message does not work. Setting filename to "Current
6988 Directory" in the only_dir_p case here does work however. */
6989 if (SCHARS (filename
) == 0 && ! NILP (only_dir_p
))
6990 filename
= build_string ("Current Directory");
6992 /* Convert the values we've computed so far to system form. */
6993 #ifdef NTGUI_UNICODE
6994 to_unicode (prompt
, &prompt
);
6995 to_unicode (dir
, &dir
);
6996 to_unicode (filename
, &filename
);
6997 if (SBYTES (filename
) + 1 > sizeof (filename_buf_w
))
6998 report_file_error ("filename too long", default_filename
);
7000 memcpy (filename_buf_w
, SDATA (filename
), SBYTES (filename
) + 1);
7001 #else /* !NTGUI_UNICODE */
7002 prompt
= ENCODE_FILE (prompt
);
7003 dir
= ENCODE_FILE (dir
);
7004 filename
= ENCODE_FILE (filename
);
7006 /* We modify these in-place, so make copies for safety. */
7007 dir
= Fcopy_sequence (dir
);
7008 unixtodos_filename (SSDATA (dir
));
7009 filename
= Fcopy_sequence (filename
);
7010 unixtodos_filename (SSDATA (filename
));
7011 if (SBYTES (filename
) >= MAX_UTF8_PATH
)
7012 report_file_error ("filename too long", default_filename
);
7013 if (w32_unicode_filenames
)
7015 filename_to_utf16 (SSDATA (dir
), dir_w
);
7016 if (filename_to_utf16 (SSDATA (filename
), filename_buf_w
) != 0)
7018 /* filename_to_utf16 sets errno to ENOENT when the file
7019 name is too long or cannot be converted to UTF-16. */
7020 if (errno
== ENOENT
&& filename_buf_w
[MAX_PATH
- 1] != 0)
7021 report_file_error ("filename too long", default_filename
);
7023 len
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7024 SSDATA (prompt
), -1, NULL
, 0);
7027 prompt_w
= alloca (len
* sizeof (wchar_t));
7028 pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7029 SSDATA (prompt
), -1, prompt_w
, len
);
7033 filename_to_ansi (SSDATA (dir
), dir_a
);
7034 if (filename_to_ansi (SSDATA (filename
), filename_buf_a
) != '\0')
7036 /* filename_to_ansi sets errno to ENOENT when the file
7037 name is too long or cannot be converted to UTF-16. */
7038 if (errno
== ENOENT
&& filename_buf_a
[MAX_PATH
- 1] != 0)
7039 report_file_error ("filename too long", default_filename
);
7041 len
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7042 SSDATA (prompt
), -1, NULL
, 0);
7045 prompt_w
= alloca (len
* sizeof (wchar_t));
7046 pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7047 SSDATA (prompt
), -1, prompt_w
, len
);
7048 len
= pWideCharToMultiByte (CP_ACP
, 0, prompt_w
, -1, NULL
, 0, NULL
, NULL
);
7051 prompt_a
= alloca (len
);
7052 pWideCharToMultiByte (CP_ACP
, 0, prompt_w
, -1, prompt_a
, len
, NULL
, NULL
);
7054 #endif /* NTGUI_UNICODE */
7056 /* Fill in the structure for the call to GetOpenFileName below.
7057 For NTGUI_UNICODE builds (which run only on NT), we just use
7058 the actual size of the structure. For non-NTGUI_UNICODE
7059 builds, we tell the OS we're using an old version of the
7060 structure if the OS isn't new enough to support the newer
7064 memset (&new_file_details_w
, 0, sizeof (new_file_details_w
));
7065 if (w32_major_version
> 4 && w32_major_version
< 95)
7066 file_details_w
->lStructSize
= sizeof (new_file_details_w
);
7068 file_details_w
->lStructSize
= sizeof (*file_details_w
);
7069 /* Set up the inout parameter for the selected file name. */
7070 file_details_w
->lpstrFile
= filename_buf_w
;
7071 file_details_w
->nMaxFile
=
7072 sizeof (filename_buf_w
) / sizeof (*filename_buf_w
);
7073 file_details_w
->hwndOwner
= FRAME_W32_WINDOW (f
);
7074 /* Undocumented Bug in Common File Dialog:
7075 If a filter is not specified, shell links are not resolved. */
7076 file_details_w
->lpstrFilter
= filter_w
;
7077 #ifdef NTGUI_UNICODE
7078 file_details_w
->lpstrInitialDir
= (wchar_t*) SDATA (dir
);
7079 file_details_w
->lpstrTitle
= (guichar_t
*) SDATA (prompt
);
7081 file_details_w
->lpstrInitialDir
= dir_w
;
7082 file_details_w
->lpstrTitle
= prompt_w
;
7084 file_details_w
->nFilterIndex
= NILP (only_dir_p
) ? 1 : 2;
7085 file_details_w
->Flags
= (OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
7086 | OFN_EXPLORER
| OFN_ENABLEHOOK
);
7087 if (!NILP (mustmatch
))
7089 /* Require that the path to the parent directory exists. */
7090 file_details_w
->Flags
|= OFN_PATHMUSTEXIST
;
7091 /* If we are looking for a file, require that it exists. */
7092 if (NILP (only_dir_p
))
7093 file_details_w
->Flags
|= OFN_FILEMUSTEXIST
;
7096 #ifndef NTGUI_UNICODE
7099 memset (&new_file_details_a
, 0, sizeof (new_file_details_a
));
7100 if (w32_major_version
> 4 && w32_major_version
< 95)
7101 file_details_a
->lStructSize
= sizeof (new_file_details_a
);
7103 file_details_a
->lStructSize
= sizeof (*file_details_a
);
7104 file_details_a
->lpstrFile
= filename_buf_a
;
7105 file_details_a
->nMaxFile
=
7106 sizeof (filename_buf_a
) / sizeof (*filename_buf_a
);
7107 file_details_a
->hwndOwner
= FRAME_W32_WINDOW (f
);
7108 file_details_a
->lpstrFilter
= filter_a
;
7109 file_details_a
->lpstrInitialDir
= dir_a
;
7110 file_details_a
->lpstrTitle
= prompt_a
;
7111 file_details_a
->nFilterIndex
= NILP (only_dir_p
) ? 1 : 2;
7112 file_details_a
->Flags
= (OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
7113 | OFN_EXPLORER
| OFN_ENABLEHOOK
);
7114 if (!NILP (mustmatch
))
7116 /* Require that the path to the parent directory exists. */
7117 file_details_a
->Flags
|= OFN_PATHMUSTEXIST
;
7118 /* If we are looking for a file, require that it exists. */
7119 if (NILP (only_dir_p
))
7120 file_details_a
->Flags
|= OFN_FILEMUSTEXIST
;
7123 #endif /* !NTGUI_UNICODE */
7126 int count
= SPECPDL_INDEX ();
7127 /* Prevent redisplay. */
7128 specbind (Qinhibit_redisplay
, Qt
);
7132 file_details_w
->lpfnHook
= file_dialog_callback
;
7134 file_opened
= GetOpenFileNameW (file_details_w
);
7136 #ifndef NTGUI_UNICODE
7139 file_details_a
->lpfnHook
= file_dialog_callback
;
7141 file_opened
= GetOpenFileNameA (file_details_a
);
7143 #endif /* !NTGUI_UNICODE */
7145 unbind_to (count
, Qnil
);
7150 /* Get an Emacs string from the value Windows gave us. */
7151 #ifdef NTGUI_UNICODE
7152 filename
= from_unicode_buffer (filename_buf_w
);
7153 #else /* !NTGUI_UNICODE */
7155 filename_from_utf16 (filename_buf_w
, fname_ret
);
7157 filename_from_ansi (filename_buf_a
, fname_ret
);
7158 dostounix_filename (fname_ret
);
7159 filename
= DECODE_FILE (build_unibyte_string (fname_ret
));
7160 #endif /* NTGUI_UNICODE */
7163 filename
= Fcygwin_convert_file_name_from_windows (filename
, Qt
);
7166 /* Strip the dummy filename off the end of the string if we
7167 added it to select a directory. */
7168 if ((use_unicode
&& file_details_w
->nFilterIndex
== 2)
7169 #ifndef NTGUI_UNICODE
7170 || (!use_unicode
&& file_details_a
->nFilterIndex
== 2)
7173 filename
= Ffile_name_directory (filename
);
7175 /* User canceled the dialog without making a selection. */
7176 else if (!CommDlgExtendedError ())
7178 /* An error occurred, fallback on reading from the mini-buffer. */
7180 filename
= Fcompleting_read (
7182 intern ("read-file-name-internal"),
7191 /* Make "Cancel" equivalent to C-g. */
7192 if (NILP (filename
))
7193 Fsignal (Qquit
, Qnil
);
7200 /* Moving files to the system recycle bin.
7201 Used by `move-file-to-trash' instead of the default moving to ~/.Trash */
7202 DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash
,
7203 Ssystem_move_file_to_trash
, 1, 1, 0,
7204 doc
: /* Move file or directory named FILENAME to the recycle bin. */)
7205 (Lisp_Object filename
)
7207 Lisp_Object handler
;
7208 Lisp_Object encoded_file
;
7209 Lisp_Object operation
;
7211 operation
= Qdelete_file
;
7212 if (!NILP (Ffile_directory_p (filename
))
7213 && NILP (Ffile_symlink_p (filename
)))
7215 operation
= intern ("delete-directory");
7216 filename
= Fdirectory_file_name (filename
);
7219 /* Must have fully qualified file names for moving files to Recycle
7221 filename
= Fexpand_file_name (filename
, Qnil
);
7223 handler
= Ffind_file_name_handler (filename
, operation
);
7224 if (!NILP (handler
))
7225 return call2 (handler
, operation
, filename
);
7231 encoded_file
= ENCODE_FILE (filename
);
7233 path
= map_w32_filename (SSDATA (encoded_file
), NULL
);
7235 /* The Unicode version of SHFileOperation is not supported on
7237 if (w32_unicode_filenames
&& os_subtype
!= OS_9X
)
7239 SHFILEOPSTRUCTW file_op_w
;
7240 /* We need one more element beyond MAX_PATH because this is
7241 a list of file names, with the last element double-null
7243 wchar_t tmp_path_w
[MAX_PATH
+ 1];
7245 memset (tmp_path_w
, 0, sizeof (tmp_path_w
));
7246 filename_to_utf16 (path
, tmp_path_w
);
7248 /* On Windows, write permission is required to delete/move files. */
7249 _wchmod (tmp_path_w
, 0666);
7251 memset (&file_op_w
, 0, sizeof (file_op_w
));
7252 file_op_w
.hwnd
= HWND_DESKTOP
;
7253 file_op_w
.wFunc
= FO_DELETE
;
7254 file_op_w
.pFrom
= tmp_path_w
;
7255 file_op_w
.fFlags
= FOF_SILENT
| FOF_NOCONFIRMATION
| FOF_ALLOWUNDO
7256 | FOF_NOERRORUI
| FOF_NO_CONNECTED_ELEMENTS
;
7257 file_op_w
.fAnyOperationsAborted
= FALSE
;
7259 result
= SHFileOperationW (&file_op_w
);
7263 SHFILEOPSTRUCTA file_op_a
;
7264 char tmp_path_a
[MAX_PATH
+ 1];
7266 memset (tmp_path_a
, 0, sizeof (tmp_path_a
));
7267 filename_to_ansi (path
, tmp_path_a
);
7269 /* If a file cannot be represented in ANSI codepage, don't
7270 let them inadvertently delete other files because some
7271 characters are interpreted as a wildcards. */
7272 if (_mbspbrk ((unsigned char *)tmp_path_a
,
7273 (const unsigned char *)"?*"))
7274 result
= ERROR_FILE_NOT_FOUND
;
7277 _chmod (tmp_path_a
, 0666);
7279 memset (&file_op_a
, 0, sizeof (file_op_a
));
7280 file_op_a
.hwnd
= HWND_DESKTOP
;
7281 file_op_a
.wFunc
= FO_DELETE
;
7282 file_op_a
.pFrom
= tmp_path_a
;
7283 file_op_a
.fFlags
= FOF_SILENT
| FOF_NOCONFIRMATION
| FOF_ALLOWUNDO
7284 | FOF_NOERRORUI
| FOF_NO_CONNECTED_ELEMENTS
;
7285 file_op_a
.fAnyOperationsAborted
= FALSE
;
7287 result
= SHFileOperationA (&file_op_a
);
7291 report_file_error ("Removing old name", list1 (filename
));
7296 #endif /* WINDOWSNT */
7299 /***********************************************************************
7300 w32 specialized functions
7301 ***********************************************************************/
7303 DEFUN ("w32-send-sys-command", Fw32_send_sys_command
,
7304 Sw32_send_sys_command
, 1, 2, 0,
7305 doc
: /* Send frame a Windows WM_SYSCOMMAND message of type COMMAND.
7306 Some useful values for COMMAND are #xf030 to maximize frame (#xf020
7307 to minimize), #xf120 to restore frame to original size, and #xf100
7308 to activate the menubar for keyboard access. #xf140 activates the
7309 screen saver if defined.
7311 If optional parameter FRAME is not specified, use selected frame. */)
7312 (Lisp_Object command
, Lisp_Object frame
)
7314 struct frame
*f
= decode_window_system_frame (frame
);
7316 CHECK_NUMBER (command
);
7318 if (FRAME_W32_P (f
))
7319 PostMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, XINT (command
), 0);
7324 DEFUN ("w32-shell-execute", Fw32_shell_execute
, Sw32_shell_execute
, 2, 4, 0,
7325 doc
: /* Get Windows to perform OPERATION on DOCUMENT.
7326 This is a wrapper around the ShellExecute system function, which
7327 invokes the application registered to handle OPERATION for DOCUMENT.
7329 OPERATION is either nil or a string that names a supported operation.
7330 What operations can be used depends on the particular DOCUMENT and its
7331 handler application, but typically it is one of the following common
7334 \"open\" - open DOCUMENT, which could be a file, a directory, or an
7335 executable program (application). If it is an application,
7336 that application is launched in the current buffer's default
7337 directory. Otherwise, the application associated with
7338 DOCUMENT is launched in the buffer's default directory.
7339 \"opennew\" - like \"open\", but instruct the application to open
7340 DOCUMENT in a new window.
7341 \"openas\" - open the \"Open With\" dialog for DOCUMENT.
7342 \"print\" - print DOCUMENT, which must be a file.
7343 \"printto\" - print DOCUMENT, which must be a file, to a specified printer.
7344 The printer should be provided in PARAMETERS, see below.
7345 \"explore\" - start the Windows Explorer on DOCUMENT.
7346 \"edit\" - launch an editor and open DOCUMENT for editing; which
7347 editor is launched depends on the association for the
7349 \"find\" - initiate search starting from DOCUMENT, which must specify
7351 \"delete\" - move DOCUMENT, a file or a directory, to Recycle Bin.
7352 \"copy\" - copy DOCUMENT, which must be a file or a directory, into
7354 \"cut\" - move DOCUMENT, a file or a directory, into the clipboard.
7355 \"paste\" - paste the file whose name is in the clipboard into DOCUMENT,
7356 which must be a directory.
7358 - create a shortcut in DOCUMENT (which must be a directory)
7359 the file or directory whose name is in the clipboard.
7360 \"runas\" - run DOCUMENT, which must be an excutable file, with
7361 elevated privileges (a.k.a. \"as Administrator\").
7363 - open the property sheet dialog for DOCUMENT.
7364 nil - invoke the default OPERATION, or \"open\" if default is
7365 not defined or unavailable.
7367 DOCUMENT is typically the name of a document file or a URL, but can
7368 also be an executable program to run, or a directory to open in the
7369 Windows Explorer. If it is a file or a directory, it must be a local
7370 one; this function does not support remote file names.
7372 If DOCUMENT is an executable program, the optional third arg PARAMETERS
7373 can be a string containing command line parameters, separated by blanks,
7374 that will be passed to the program. Some values of OPERATION also require
7375 parameters (e.g., \"printto\" requires the printer address). Otherwise,
7376 PARAMETERS should be nil or unspecified. Note that double quote characters
7377 in PARAMETERS must each be enclosed in 2 additional quotes, as in \"\"\".
7379 Optional fourth argument SHOW-FLAG can be used to control how the
7380 application will be displayed when it is invoked. If SHOW-FLAG is nil
7381 or unspecified, the application is displayed as if SHOW-FLAG of 10 was
7382 specified, otherwise it is an integer between 0 and 11 representing
7386 1 - start as normal-size window
7387 3 - start in a maximized window
7388 6 - start in a minimized window
7389 10 - start as the application itself specifies; this is the default. */)
7390 (Lisp_Object operation
, Lisp_Object document
, Lisp_Object parameters
, Lisp_Object show_flag
)
7393 Lisp_Object current_dir
= BVAR (current_buffer
, directory
);;
7394 wchar_t *doc_w
= NULL
, *params_w
= NULL
, *ops_w
= NULL
;
7398 int use_unicode
= w32_unicode_filenames
;
7399 char *doc_a
= NULL
, *params_a
= NULL
, *ops_a
= NULL
;
7400 Lisp_Object absdoc
, handler
;
7404 CHECK_STRING (document
);
7407 current_dir
= Fcygwin_convert_file_name_to_windows (current_dir
, Qt
);
7408 document
= Fcygwin_convert_file_name_to_windows (document
, Qt
);
7410 /* Encode filename, current directory and parameters. */
7411 current_dir
= GUI_ENCODE_FILE (current_dir
);
7412 document
= GUI_ENCODE_FILE (document
);
7413 doc_w
= GUI_SDATA (document
);
7414 if (STRINGP (parameters
))
7416 parameters
= GUI_ENCODE_SYSTEM (parameters
);
7417 params_w
= GUI_SDATA (parameters
);
7419 if (STRINGP (operation
))
7421 operation
= GUI_ENCODE_SYSTEM (operation
);
7422 ops_w
= GUI_SDATA (operation
);
7424 result
= (intptr_t) ShellExecuteW (NULL
, ops_w
, doc_w
, params_w
,
7425 GUI_SDATA (current_dir
),
7426 (INTEGERP (show_flag
)
7427 ? XINT (show_flag
) : SW_SHOWDEFAULT
));
7434 case SE_ERR_ACCESSDENIED
:
7435 errstr
= w32_strerror (ERROR_ACCESS_DENIED
);
7437 case SE_ERR_ASSOCINCOMPLETE
:
7438 case SE_ERR_NOASSOC
:
7439 errstr
= w32_strerror (ERROR_NO_ASSOCIATION
);
7441 case SE_ERR_DDEBUSY
:
7442 case SE_ERR_DDEFAIL
:
7443 errstr
= w32_strerror (ERROR_DDE_FAIL
);
7445 case SE_ERR_DDETIMEOUT
:
7446 errstr
= w32_strerror (ERROR_TIMEOUT
);
7448 case SE_ERR_DLLNOTFOUND
:
7449 errstr
= w32_strerror (ERROR_DLL_NOT_FOUND
);
7452 errstr
= w32_strerror (ERROR_FILE_NOT_FOUND
);
7455 errstr
= w32_strerror (ERROR_NOT_ENOUGH_MEMORY
);
7458 errstr
= w32_strerror (ERROR_PATH_NOT_FOUND
);
7461 errstr
= w32_strerror (ERROR_SHARING_VIOLATION
);
7464 errstr
= w32_strerror (0);
7470 const char file_url_str
[] = "file:///";
7471 const int file_url_len
= sizeof (file_url_str
) - 1;
7474 if (strncmp (SSDATA (document
), file_url_str
, file_url_len
) == 0)
7476 /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to
7477 start a thread in some rare system configurations, for
7478 unknown reasons. That thread is started in the context of
7479 the Emacs process, but out of control of our code, and seems
7480 to never exit afterwards. Each such thread reserves 8MB of
7481 stack space (because that's the value recorded in the Emacs
7482 executable at link time: Emacs needs a large stack). So a
7483 large enough number of invocations of w32-shell-execute can
7484 potentially cause the Emacs process to run out of available
7485 address space, which is nasty. To work around this, we
7486 convert such URLs to local file names, which seems to prevent
7487 those threads from starting. See bug #20220. */
7488 char *p
= SSDATA (document
) + file_url_len
;
7490 if (c_isalpha (*p
) && p
[1] == ':' && IS_DIRECTORY_SEP (p
[2]))
7491 document
= Fsubstring_no_properties (document
,
7492 make_number (file_url_len
), Qnil
);
7494 /* We have a situation here. If DOCUMENT is a relative file name,
7495 but its name includes leading directories, i.e. it lives not in
7496 CURRENT_DIR, but in its subdirectory, then ShellExecute below
7497 will fail to find it. So we need to make the file name is
7498 absolute. But DOCUMENT does not have to be a file, it can be a
7499 URL, for example. So we make it absolute only if it is an
7500 existing file; if it is a file that does not exist, tough. */
7501 absdoc
= Fexpand_file_name (document
, Qnil
);
7502 /* Don't call file handlers for file-exists-p, since they might
7503 attempt to access the file, which could fail or produce undesired
7504 consequences, see bug#16558 for an example. */
7505 handler
= Ffind_file_name_handler (absdoc
, Qfile_exists_p
);
7508 Lisp_Object absdoc_encoded
= ENCODE_FILE (absdoc
);
7510 if (faccessat (AT_FDCWD
, SSDATA (absdoc_encoded
), F_OK
, AT_EACCESS
) == 0)
7512 /* ShellExecute fails if DOCUMENT is a UNC with forward
7513 slashes (expand-file-name above converts all backslashes
7514 to forward slashes). Now that we know DOCUMENT is a
7515 file, we can mirror all forward slashes into backslashes. */
7516 unixtodos_filename (SSDATA (absdoc_encoded
));
7517 document
= absdoc_encoded
;
7520 document
= ENCODE_FILE (document
);
7523 document
= ENCODE_FILE (document
);
7525 current_dir
= ENCODE_FILE (current_dir
);
7526 /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could
7527 be a URL that is not limited to MAX_PATH chararcters. */
7528 doclen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7529 SSDATA (document
), -1, NULL
, 0);
7530 doc_w
= xmalloc (doclen
* sizeof (wchar_t));
7531 pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7532 SSDATA (document
), -1, doc_w
, doclen
);
7535 wchar_t current_dir_w
[MAX_PATH
];
7536 SHELLEXECUTEINFOW shexinfo_w
;
7538 /* Encode the current directory and parameters, and convert
7539 operation to UTF-16. */
7540 filename_to_utf16 (SSDATA (current_dir
), current_dir_w
);
7541 if (STRINGP (parameters
))
7545 parameters
= ENCODE_SYSTEM (parameters
);
7546 len
= pMultiByteToWideChar (CP_ACP
, multiByteToWideCharFlags
,
7547 SSDATA (parameters
), -1, NULL
, 0);
7550 params_w
= alloca (len
* sizeof (wchar_t));
7551 pMultiByteToWideChar (CP_ACP
, multiByteToWideCharFlags
,
7552 SSDATA (parameters
), -1, params_w
, len
);
7553 params_w
[len
- 1] = 0;
7555 if (STRINGP (operation
))
7557 /* Assume OPERATION is pure ASCII. */
7558 const char *s
= SSDATA (operation
);
7560 int len
= SBYTES (operation
) + 1;
7564 d
= ops_w
= alloca (len
* sizeof (wchar_t));
7565 while (d
< ops_w
+ len
- 1)
7570 /* Using ShellExecuteEx and setting the SEE_MASK_INVOKEIDLIST
7571 flag succeeds with more OPERATIONs (a.k.a. "verbs"), as it is
7572 able to invoke verbs from shortcut menu extensions, not just
7573 static verbs listed in the Registry. */
7574 memset (&shexinfo_w
, 0, sizeof (shexinfo_w
));
7575 shexinfo_w
.cbSize
= sizeof (shexinfo_w
);
7577 SEE_MASK_INVOKEIDLIST
| SEE_MASK_FLAG_DDEWAIT
| SEE_MASK_FLAG_NO_UI
;
7578 shexinfo_w
.hwnd
= NULL
;
7579 shexinfo_w
.lpVerb
= ops_w
;
7580 shexinfo_w
.lpFile
= doc_w
;
7581 shexinfo_w
.lpParameters
= params_w
;
7582 shexinfo_w
.lpDirectory
= current_dir_w
;
7584 (INTEGERP (show_flag
) ? XINT (show_flag
) : SW_SHOWDEFAULT
);
7585 success
= ShellExecuteExW (&shexinfo_w
);
7590 char current_dir_a
[MAX_PATH
];
7591 SHELLEXECUTEINFOA shexinfo_a
;
7592 int codepage
= codepage_for_filenames (NULL
);
7593 int ldoc_a
= pWideCharToMultiByte (codepage
, 0, doc_w
, -1, NULL
, 0,
7596 doc_a
= xmalloc (ldoc_a
);
7597 pWideCharToMultiByte (codepage
, 0, doc_w
, -1, doc_a
, ldoc_a
, NULL
, NULL
);
7598 filename_to_ansi (SSDATA (current_dir
), current_dir_a
);
7599 if (STRINGP (parameters
))
7601 parameters
= ENCODE_SYSTEM (parameters
);
7602 params_a
= SSDATA (parameters
);
7604 if (STRINGP (operation
))
7606 /* Assume OPERATION is pure ASCII. */
7607 ops_a
= SSDATA (operation
);
7609 memset (&shexinfo_a
, 0, sizeof (shexinfo_a
));
7610 shexinfo_a
.cbSize
= sizeof (shexinfo_a
);
7612 SEE_MASK_INVOKEIDLIST
| SEE_MASK_FLAG_DDEWAIT
| SEE_MASK_FLAG_NO_UI
;
7613 shexinfo_a
.hwnd
= NULL
;
7614 shexinfo_a
.lpVerb
= ops_a
;
7615 shexinfo_a
.lpFile
= doc_a
;
7616 shexinfo_a
.lpParameters
= params_a
;
7617 shexinfo_a
.lpDirectory
= current_dir_a
;
7619 (INTEGERP (show_flag
) ? XINT (show_flag
) : SW_SHOWDEFAULT
);
7620 success
= ShellExecuteExA (&shexinfo_a
);
7628 errstr
= w32_strerror (0);
7630 #endif /* !CYGWIN */
7632 /* The error string might be encoded in the locale's encoding. */
7633 if (!NILP (Vlocale_coding_system
))
7635 Lisp_Object decoded
=
7636 code_convert_string_norecord (build_unibyte_string (errstr
),
7637 Vlocale_coding_system
, 0);
7638 errstr
= SSDATA (decoded
);
7640 error ("ShellExecute failed: %s", errstr
);
7643 /* Lookup virtual keycode from string representing the name of a
7644 non-ascii keystroke into the corresponding virtual key, using
7645 lispy_function_keys. */
7647 lookup_vk_code (char *key
)
7651 for (i
= 0; i
< 256; i
++)
7652 if (lispy_function_keys
[i
]
7653 && strcmp (lispy_function_keys
[i
], key
) == 0)
7659 /* Convert a one-element vector style key sequence to a hot key
7662 w32_parse_hot_key (Lisp_Object key
)
7664 /* Copied from Fdefine_key and store_in_keymap. */
7665 register Lisp_Object c
;
7672 if (ASIZE (key
) != 1)
7677 if (CONSP (c
) && lucid_event_type_list_p (c
))
7678 c
= Fevent_convert_list (c
);
7680 if (! INTEGERP (c
) && ! SYMBOLP (c
))
7681 error ("Key definition is invalid");
7683 /* Work out the base key and the modifiers. */
7686 c
= parse_modifiers (c
);
7687 lisp_modifiers
= XINT (Fcar (Fcdr (c
)));
7691 vk_code
= lookup_vk_code (SSDATA (SYMBOL_NAME (c
)));
7693 else if (INTEGERP (c
))
7695 lisp_modifiers
= XINT (c
) & ~CHARACTERBITS
;
7696 /* Many ascii characters are their own virtual key code. */
7697 vk_code
= XINT (c
) & CHARACTERBITS
;
7700 if (vk_code
< 0 || vk_code
> 255)
7703 if ((lisp_modifiers
& meta_modifier
) != 0
7704 && !NILP (Vw32_alt_is_meta
))
7705 lisp_modifiers
|= alt_modifier
;
7707 /* Supply defs missing from mingw32. */
7709 #define MOD_ALT 0x0001
7710 #define MOD_CONTROL 0x0002
7711 #define MOD_SHIFT 0x0004
7712 #define MOD_WIN 0x0008
7715 /* Convert lisp modifiers to Windows hot-key form. */
7716 w32_modifiers
= (lisp_modifiers
& hyper_modifier
) ? MOD_WIN
: 0;
7717 w32_modifiers
|= (lisp_modifiers
& alt_modifier
) ? MOD_ALT
: 0;
7718 w32_modifiers
|= (lisp_modifiers
& ctrl_modifier
) ? MOD_CONTROL
: 0;
7719 w32_modifiers
|= (lisp_modifiers
& shift_modifier
) ? MOD_SHIFT
: 0;
7721 return HOTKEY (vk_code
, w32_modifiers
);
7724 DEFUN ("w32-register-hot-key", Fw32_register_hot_key
,
7725 Sw32_register_hot_key
, 1, 1, 0,
7726 doc
: /* Register KEY as a hot-key combination.
7727 Certain key combinations like Alt-Tab are reserved for system use on
7728 Windows, and therefore are normally intercepted by the system. However,
7729 most of these key combinations can be received by registering them as
7730 hot-keys, overriding their special meaning.
7732 KEY must be a one element key definition in vector form that would be
7733 acceptable to `define-key' (e.g. [A-tab] for Alt-Tab). The meta
7734 modifier is interpreted as Alt if `w32-alt-is-meta' is t, and hyper
7735 is always interpreted as the Windows modifier keys.
7737 The return value is the hotkey-id if registered, otherwise nil. */)
7740 key
= w32_parse_hot_key (key
);
7742 if (!NILP (key
) && NILP (Fmemq (key
, w32_grabbed_keys
)))
7744 /* Reuse an empty slot if possible. */
7745 Lisp_Object item
= Fmemq (Qnil
, w32_grabbed_keys
);
7747 /* Safe to add new key to list, even if we have focus. */
7749 w32_grabbed_keys
= Fcons (key
, w32_grabbed_keys
);
7751 XSETCAR (item
, key
);
7753 /* Notify input thread about new hot-key definition, so that it
7754 takes effect without needing to switch focus. */
7755 PostThreadMessage (dwWindowsThreadId
, WM_EMACS_REGISTER_HOT_KEY
,
7756 (WPARAM
) XINT (key
), 0);
7762 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key
,
7763 Sw32_unregister_hot_key
, 1, 1, 0,
7764 doc
: /* Unregister KEY as a hot-key combination. */)
7769 if (!INTEGERP (key
))
7770 key
= w32_parse_hot_key (key
);
7772 item
= Fmemq (key
, w32_grabbed_keys
);
7778 eassert (CONSP (item
));
7779 /* Pass the tail of the list as a pointer to a Lisp_Cons cell,
7780 so that it works in a --with-wide-int build as well. */
7781 lparam
= (LPARAM
) XUNTAG (item
, Lisp_Cons
);
7783 /* Notify input thread about hot-key definition being removed, so
7784 that it takes effect without needing focus switch. */
7785 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_UNREGISTER_HOT_KEY
,
7786 (WPARAM
) XINT (XCAR (item
)), lparam
))
7789 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
7796 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys
,
7797 Sw32_registered_hot_keys
, 0, 0, 0,
7798 doc
: /* Return list of registered hot-key IDs. */)
7801 return Fdelq (Qnil
, Fcopy_sequence (w32_grabbed_keys
));
7804 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key
,
7805 Sw32_reconstruct_hot_key
, 1, 1, 0,
7806 doc
: /* Convert hot-key ID to a lisp key combination.
7807 usage: (w32-reconstruct-hot-key ID) */)
7808 (Lisp_Object hotkeyid
)
7810 int vk_code
, w32_modifiers
;
7813 CHECK_NUMBER (hotkeyid
);
7815 vk_code
= HOTKEY_VK_CODE (hotkeyid
);
7816 w32_modifiers
= HOTKEY_MODIFIERS (hotkeyid
);
7818 if (vk_code
< 256 && lispy_function_keys
[vk_code
])
7819 key
= intern (lispy_function_keys
[vk_code
]);
7821 key
= make_number (vk_code
);
7823 key
= Fcons (key
, Qnil
);
7824 if (w32_modifiers
& MOD_SHIFT
)
7825 key
= Fcons (Qshift
, key
);
7826 if (w32_modifiers
& MOD_CONTROL
)
7827 key
= Fcons (Qctrl
, key
);
7828 if (w32_modifiers
& MOD_ALT
)
7829 key
= Fcons (NILP (Vw32_alt_is_meta
) ? Qalt
: Qmeta
, key
);
7830 if (w32_modifiers
& MOD_WIN
)
7831 key
= Fcons (Qhyper
, key
);
7836 DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key
,
7837 Sw32_toggle_lock_key
, 1, 2, 0,
7838 doc
: /* Toggle the state of the lock key KEY.
7839 KEY can be `capslock', `kp-numlock', or `scroll'.
7840 If the optional parameter NEW-STATE is a number, then the state of KEY
7841 is set to off if the low bit of NEW-STATE is zero, otherwise on.
7842 If NEW-STATE is omitted or nil, the function toggles the state,
7844 Value is the new state of the key, or nil if the function failed
7845 to change the state. */)
7846 (Lisp_Object key
, Lisp_Object new_state
)
7851 if (EQ (key
, intern ("capslock")))
7852 vk_code
= VK_CAPITAL
;
7853 else if (EQ (key
, intern ("kp-numlock")))
7854 vk_code
= VK_NUMLOCK
;
7855 else if (EQ (key
, intern ("scroll")))
7856 vk_code
= VK_SCROLL
;
7860 if (!dwWindowsThreadId
)
7861 return make_number (w32_console_toggle_lock_key (vk_code
, new_state
));
7863 if (NILP (new_state
))
7866 lparam
= (XUINT (new_state
)) & 1;
7867 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_TOGGLE_LOCK_KEY
,
7868 (WPARAM
) vk_code
, lparam
))
7871 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
7872 return make_number (msg
.wParam
);
7877 DEFUN ("w32-window-exists-p", Fw32_window_exists_p
, Sw32_window_exists_p
,
7879 doc
: /* Return non-nil if a window exists with the specified CLASS and NAME.
7881 This is a direct interface to the Windows API FindWindow function. */)
7882 (Lisp_Object
class, Lisp_Object name
)
7887 CHECK_STRING (class);
7889 CHECK_STRING (name
);
7891 hnd
= FindWindow (STRINGP (class) ? ((LPCTSTR
) SDATA (class)) : NULL
,
7892 STRINGP (name
) ? ((LPCTSTR
) SDATA (name
)) : NULL
);
7898 DEFUN ("w32-frame-geometry", Fw32_frame_geometry
, Sw32_frame_geometry
, 0, 1, 0,
7899 doc
: /* Return geometric attributes of FRAME.
7900 FRAME must be a live frame and defaults to the selected one. The return
7901 value is an association list of the attributes listed below. All height
7902 and width values are in pixels.
7904 `outer-position' is a cons of the outer left and top edges of FRAME
7905 relative to the origin - the position (0, 0) - of FRAME's display.
7907 `outer-size' is a cons of the outer width and height of FRAME. The
7908 outer size includes the title bar and the external borders as well as
7909 any menu and/or tool bar of frame.
7911 `external-border-size' is a cons of the horizontal and vertical width of
7912 FRAME's external borders as supplied by the window manager.
7914 `title-bar-size' is a cons of the width and height of the title bar of
7915 FRAME as supplied by the window manager. If both of them are zero,
7916 FRAME has no title bar. If only the width is zero, Emacs was not
7917 able to retrieve the width information.
7919 `menu-bar-external', if non-nil, means the menu bar is external (never
7920 included in the inner edges of FRAME).
7922 `menu-bar-size' is a cons of the width and height of the menu bar of
7925 `tool-bar-external', if non-nil, means the tool bar is external (never
7926 included in the inner edges of FRAME).
7928 `tool-bar-position' tells on which side the tool bar on FRAME is and can
7929 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
7932 `tool-bar-size' is a cons of the width and height of the tool bar of
7935 `internal-border-width' is the width of the internal border of
7939 struct frame
*f
= decode_live_frame (frame
);
7941 MENUBARINFO menu_bar
;
7943 int left
, top
, right
, bottom
;
7944 unsigned int external_border_width
, external_border_height
;
7945 int title_bar_width
= 0, title_bar_height
= 0;
7946 int single_menu_bar_height
, wrapped_menu_bar_height
, menu_bar_height
;
7947 int tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
7948 int internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
7950 if (FRAME_INITIAL_P (f
) || !FRAME_W32_P (f
))
7954 /* Outer rectangle and borders. */
7955 window
.cbSize
= sizeof (window
);
7956 GetWindowInfo (FRAME_W32_WINDOW (f
), &window
);
7957 external_border_width
= window
.cxWindowBorders
;
7958 external_border_height
= window
.cyWindowBorders
;
7960 if (get_title_bar_info_fn
)
7962 TITLEBAR_INFO title_bar
;
7964 title_bar
.cbSize
= sizeof (title_bar
);
7965 title_bar
.rcTitleBar
.left
= title_bar
.rcTitleBar
.right
= 0;
7966 title_bar
.rcTitleBar
.top
= title_bar
.rcTitleBar
.bottom
= 0;
7967 for (int i
= 0; i
< 6; i
++)
7968 title_bar
.rgstate
[i
] = 0;
7969 if (get_title_bar_info_fn (FRAME_W32_WINDOW (f
), &title_bar
)
7970 && !(title_bar
.rgstate
[0] & 0x00008001))
7973 = title_bar
.rcTitleBar
.right
- title_bar
.rcTitleBar
.left
;
7975 = title_bar
.rcTitleBar
.bottom
- title_bar
.rcTitleBar
.top
;
7978 else if ((window
.dwStyle
& WS_CAPTION
) == WS_CAPTION
)
7979 title_bar_height
= GetSystemMetrics (SM_CYCAPTION
);
7981 menu_bar
.cbSize
= sizeof (menu_bar
);
7982 menu_bar
.rcBar
.right
= menu_bar
.rcBar
.left
= 0;
7983 menu_bar
.rcBar
.top
= menu_bar
.rcBar
.bottom
= 0;
7984 GetMenuBarInfo (FRAME_W32_WINDOW (f
), 0xFFFFFFFD, 0, &menu_bar
);
7985 single_menu_bar_height
= GetSystemMetrics (SM_CYMENU
);
7986 wrapped_menu_bar_height
= GetSystemMetrics (SM_CYMENUSIZE
);
7989 left
= window
.rcWindow
.left
;
7990 top
= window
.rcWindow
.top
;
7991 right
= window
.rcWindow
.right
;
7992 bottom
= window
.rcWindow
.bottom
;
7995 menu_bar_height
= menu_bar
.rcBar
.bottom
- menu_bar
.rcBar
.top
;
7996 /* Fix menu bar height reported by GetMenuBarInfo. */
7997 if (menu_bar_height
> single_menu_bar_height
)
7998 /* A wrapped menu bar. */
7999 menu_bar_height
+= single_menu_bar_height
- wrapped_menu_bar_height
;
8000 else if (menu_bar_height
> 0)
8001 /* A single line menu bar. */
8002 menu_bar_height
= single_menu_bar_height
;
8004 return listn (CONSTYPE_HEAP
, 10,
8005 Fcons (Qouter_position
,
8006 Fcons (make_number (left
), make_number (top
))),
8008 Fcons (make_number (right
- left
),
8009 make_number (bottom
- top
))),
8010 Fcons (Qexternal_border_size
,
8011 Fcons (make_number (external_border_width
),
8012 make_number (external_border_height
))),
8013 Fcons (Qtitle_bar_size
,
8014 Fcons (make_number (title_bar_width
),
8015 make_number (title_bar_height
))),
8016 Fcons (Qmenu_bar_external
, Qt
),
8017 Fcons (Qmenu_bar_size
,
8019 (menu_bar
.rcBar
.right
- menu_bar
.rcBar
.left
),
8020 make_number (menu_bar_height
))),
8021 Fcons (Qtool_bar_external
, Qnil
),
8022 Fcons (Qtool_bar_position
, tool_bar_height
? Qtop
: Qnil
),
8023 Fcons (Qtool_bar_size
,
8026 ? right
- left
- 2 * internal_border_width
8028 make_number (tool_bar_height
))),
8029 Fcons (Qinternal_border_width
,
8030 make_number (internal_border_width
)));
8033 DEFUN ("w32-frame-edges", Fw32_frame_edges
, Sw32_frame_edges
, 0, 2, 0,
8034 doc
: /* Return edge coordinates of FRAME.
8035 FRAME must be a live frame and defaults to the selected one. The return
8036 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
8037 in pixels relative to the origin - the position (0, 0) - of FRAME's
8040 If optional argument TYPE is the symbol `outer-edges', return the outer
8041 edges of FRAME. The outer edges comprise the decorations of the window
8042 manager (like the title bar or external borders) as well as any external
8043 menu or tool bar of FRAME. If optional argument TYPE is the symbol
8044 `native-edges' or nil, return the native edges of FRAME. The native
8045 edges exclude the decorations of the window manager and any external
8046 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
8047 the inner edges of FRAME. These edges exclude title bar, any borders,
8048 menu bar or tool bar of FRAME. */)
8049 (Lisp_Object frame
, Lisp_Object type
)
8051 struct frame
*f
= decode_live_frame (frame
);
8053 if (FRAME_INITIAL_P (f
) || !FRAME_W32_P (f
))
8056 if (EQ (type
, Qouter_edges
))
8061 /* Outer frame rectangle, including outer borders and title bar. */
8062 GetWindowRect (FRAME_W32_WINDOW (f
), &rectangle
);
8065 return list4 (make_number (rectangle
.left
),
8066 make_number (rectangle
.top
),
8067 make_number (rectangle
.right
),
8068 make_number (rectangle
.bottom
));
8074 int left
, top
, right
, bottom
;
8077 /* Inner frame rectangle, excluding borders and title bar. */
8078 GetClientRect (FRAME_W32_WINDOW (f
), &rectangle
);
8079 /* Get top-left corner of native rectangle in screen
8083 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
8088 right
= left
+ rectangle
.right
;
8089 bottom
= top
+ rectangle
.bottom
;
8091 if (EQ (type
, Qinner_edges
))
8093 int internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
8095 return list4 (make_number (left
+ internal_border_width
),
8097 + FRAME_TOOL_BAR_HEIGHT (f
)
8098 + internal_border_width
),
8099 make_number (right
- internal_border_width
),
8100 make_number (bottom
- internal_border_width
));
8103 return list4 (make_number (left
), make_number (top
),
8104 make_number (right
), make_number (bottom
));
8108 DEFUN ("w32-mouse-absolute-pixel-position", Fw32_mouse_absolute_pixel_position
,
8109 Sw32_mouse_absolute_pixel_position
, 0, 0, 0,
8110 doc
: /* Return absolute position of mouse cursor in pixels.
8111 The position is returned as a cons cell (X . Y) of the coordinates of
8112 the mouse cursor position in pixels relative to a position (0, 0) of the
8113 selected frame's display. */)
8122 return Fcons (make_number (pt
.x
), make_number (pt
.y
));
8125 DEFUN ("w32-set-mouse-absolute-pixel-position", Fw32_set_mouse_absolute_pixel_position
,
8126 Sw32_set_mouse_absolute_pixel_position
, 2, 2, 0,
8127 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
8128 The coordinates X and Y are interpreted in pixels relative to a position
8129 \(0, 0) of the selected frame's display. */)
8130 (Lisp_Object x
, Lisp_Object y
)
8135 CHECK_TYPE_RANGED_INTEGER (int, x
);
8136 CHECK_TYPE_RANGED_INTEGER (int, y
);
8139 /* When "mouse trails" are in effect, moving the mouse cursor
8140 sometimes leaves behind an annoying "ghost" of the pointer.
8141 Avoid that by momentarily switching off mouse trails. */
8142 if (os_subtype
== OS_NT
8143 && w32_major_version
+ w32_minor_version
>= 6)
8144 ret
= SystemParametersInfo (SPI_GETMOUSETRAILS
, 0, &trail_num
, 0);
8145 SetCursorPos (XINT (x
), XINT (y
));
8147 SystemParametersInfo (SPI_SETMOUSETRAILS
, trail_num
, NULL
, 0);
8153 DEFUN ("w32-battery-status", Fw32_battery_status
, Sw32_battery_status
, 0, 0, 0,
8154 doc
: /* Get power status information from Windows system.
8156 The following %-sequences are provided:
8157 %L AC line status (verbose)
8158 %B Battery status (verbose)
8159 %b Battery status, empty means high, `-' means low,
8160 `!' means critical, and `+' means charging
8161 %p Battery load percentage
8162 %s Remaining time (to charge or discharge) in seconds
8163 %m Remaining time (to charge or discharge) in minutes
8164 %h Remaining time (to charge or discharge) in hours
8165 %t Remaining time (to charge or discharge) in the form `h:min' */)
8168 Lisp_Object status
= Qnil
;
8170 SYSTEM_POWER_STATUS system_status
;
8171 if (GetSystemPowerStatus (&system_status
))
8173 Lisp_Object line_status
, battery_status
, battery_status_symbol
;
8174 Lisp_Object load_percentage
, seconds
, minutes
, hours
, remain
;
8176 long seconds_left
= (long) system_status
.BatteryLifeTime
;
8178 if (system_status
.ACLineStatus
== 0)
8179 line_status
= build_string ("off-line");
8180 else if (system_status
.ACLineStatus
== 1)
8181 line_status
= build_string ("on-line");
8183 line_status
= build_string ("N/A");
8185 if (system_status
.BatteryFlag
& 128)
8187 battery_status
= build_string ("N/A");
8188 battery_status_symbol
= empty_unibyte_string
;
8190 else if (system_status
.BatteryFlag
& 8)
8192 battery_status
= build_string ("charging");
8193 battery_status_symbol
= build_string ("+");
8194 if (system_status
.BatteryFullLifeTime
!= -1L)
8195 seconds_left
= system_status
.BatteryFullLifeTime
- seconds_left
;
8197 else if (system_status
.BatteryFlag
& 4)
8199 battery_status
= build_string ("critical");
8200 battery_status_symbol
= build_string ("!");
8202 else if (system_status
.BatteryFlag
& 2)
8204 battery_status
= build_string ("low");
8205 battery_status_symbol
= build_string ("-");
8207 else if (system_status
.BatteryFlag
& 1)
8209 battery_status
= build_string ("high");
8210 battery_status_symbol
= empty_unibyte_string
;
8214 battery_status
= build_string ("medium");
8215 battery_status_symbol
= empty_unibyte_string
;
8218 if (system_status
.BatteryLifePercent
> 100)
8219 load_percentage
= build_string ("N/A");
8223 snprintf (buffer
, 16, "%d", system_status
.BatteryLifePercent
);
8224 load_percentage
= build_string (buffer
);
8227 if (seconds_left
< 0)
8228 seconds
= minutes
= hours
= remain
= build_string ("N/A");
8234 snprintf (buffer
, 16, "%ld", seconds_left
);
8235 seconds
= build_string (buffer
);
8237 m
= seconds_left
/ 60;
8238 snprintf (buffer
, 16, "%ld", m
);
8239 minutes
= build_string (buffer
);
8241 h
= seconds_left
/ 3600.0;
8242 snprintf (buffer
, 16, "%3.1f", h
);
8243 hours
= build_string (buffer
);
8245 snprintf (buffer
, 16, "%ld:%02ld", m
/ 60, m
% 60);
8246 remain
= build_string (buffer
);
8249 status
= listn (CONSTYPE_HEAP
, 8,
8250 Fcons (make_number ('L'), line_status
),
8251 Fcons (make_number ('B'), battery_status
),
8252 Fcons (make_number ('b'), battery_status_symbol
),
8253 Fcons (make_number ('p'), load_percentage
),
8254 Fcons (make_number ('s'), seconds
),
8255 Fcons (make_number ('m'), minutes
),
8256 Fcons (make_number ('h'), hours
),
8257 Fcons (make_number ('t'), remain
));
8264 typedef BOOL (WINAPI
*GetDiskFreeSpaceExW_Proc
)
8265 (LPCWSTR
, PULARGE_INTEGER
, PULARGE_INTEGER
, PULARGE_INTEGER
);
8266 typedef BOOL (WINAPI
*GetDiskFreeSpaceExA_Proc
)
8267 (LPCSTR
, PULARGE_INTEGER
, PULARGE_INTEGER
, PULARGE_INTEGER
);
8269 DEFUN ("file-system-info", Ffile_system_info
, Sfile_system_info
, 1, 1, 0,
8270 doc
: /* Return storage information about the file system FILENAME is on.
8271 Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
8272 storage of the file system, FREE is the free storage, and AVAIL is the
8273 storage available to a non-superuser. All 3 numbers are in bytes.
8274 If the underlying system call fails, value is nil. */)
8275 (Lisp_Object filename
)
8277 Lisp_Object encoded
, value
;
8279 CHECK_STRING (filename
);
8280 filename
= Fexpand_file_name (filename
, Qnil
);
8281 encoded
= ENCODE_FILE (filename
);
8285 /* Determining the required information on Windows turns out, sadly,
8286 to be more involved than one would hope. The original Windows API
8287 call for this will return bogus information on some systems, but we
8288 must dynamically probe for the replacement api, since that was
8289 added rather late on. */
8291 HMODULE hKernel
= GetModuleHandle ("kernel32");
8292 GetDiskFreeSpaceExW_Proc pfn_GetDiskFreeSpaceExW
=
8293 (GetDiskFreeSpaceExW_Proc
) GetProcAddress (hKernel
, "GetDiskFreeSpaceExW");
8294 GetDiskFreeSpaceExA_Proc pfn_GetDiskFreeSpaceExA
=
8295 (GetDiskFreeSpaceExA_Proc
) GetProcAddress (hKernel
, "GetDiskFreeSpaceExA");
8296 bool have_pfn_GetDiskFreeSpaceEx
=
8297 ((w32_unicode_filenames
&& pfn_GetDiskFreeSpaceExW
)
8298 || (!w32_unicode_filenames
&& pfn_GetDiskFreeSpaceExA
));
8300 /* On Windows, we may need to specify the root directory of the
8301 volume holding FILENAME. */
8302 char rootname
[MAX_UTF8_PATH
];
8303 wchar_t rootname_w
[MAX_PATH
];
8304 char rootname_a
[MAX_PATH
];
8305 char *name
= SSDATA (encoded
);
8308 /* find the root name of the volume if given */
8309 if (isalpha (name
[0]) && name
[1] == ':')
8311 rootname
[0] = name
[0];
8312 rootname
[1] = name
[1];
8316 else if (IS_DIRECTORY_SEP (name
[0]) && IS_DIRECTORY_SEP (name
[1]))
8318 char *str
= rootname
;
8322 if (IS_DIRECTORY_SEP (*name
) && --slashes
== 0)
8332 if (w32_unicode_filenames
)
8333 filename_to_utf16 (rootname
, rootname_w
);
8335 filename_to_ansi (rootname
, rootname_a
);
8337 if (have_pfn_GetDiskFreeSpaceEx
)
8339 /* Unsigned large integers cannot be cast to double, so
8340 use signed ones instead. */
8341 LARGE_INTEGER availbytes
;
8342 LARGE_INTEGER freebytes
;
8343 LARGE_INTEGER totalbytes
;
8345 if (w32_unicode_filenames
)
8346 result
= pfn_GetDiskFreeSpaceExW (rootname_w
,
8347 (ULARGE_INTEGER
*)&availbytes
,
8348 (ULARGE_INTEGER
*)&totalbytes
,
8349 (ULARGE_INTEGER
*)&freebytes
);
8351 result
= pfn_GetDiskFreeSpaceExA (rootname_a
,
8352 (ULARGE_INTEGER
*)&availbytes
,
8353 (ULARGE_INTEGER
*)&totalbytes
,
8354 (ULARGE_INTEGER
*)&freebytes
);
8356 value
= list3 (make_float ((double) totalbytes
.QuadPart
),
8357 make_float ((double) freebytes
.QuadPart
),
8358 make_float ((double) availbytes
.QuadPart
));
8362 DWORD sectors_per_cluster
;
8363 DWORD bytes_per_sector
;
8364 DWORD free_clusters
;
8365 DWORD total_clusters
;
8367 if (w32_unicode_filenames
)
8368 result
= GetDiskFreeSpaceW (rootname_w
,
8369 §ors_per_cluster
,
8374 result
= GetDiskFreeSpaceA (rootname_a
,
8375 §ors_per_cluster
,
8380 value
= list3 (make_float ((double) total_clusters
8381 * sectors_per_cluster
* bytes_per_sector
),
8382 make_float ((double) free_clusters
8383 * sectors_per_cluster
* bytes_per_sector
),
8384 make_float ((double) free_clusters
8385 * sectors_per_cluster
* bytes_per_sector
));
8391 #endif /* WINDOWSNT */
8395 DEFUN ("default-printer-name", Fdefault_printer_name
, Sdefault_printer_name
,
8396 0, 0, 0, doc
: /* Return the name of Windows default printer device. */)
8399 static char pname_buf
[256];
8402 PRINTER_INFO_2W
*ppi2w
= NULL
;
8403 PRINTER_INFO_2A
*ppi2a
= NULL
;
8404 DWORD dwNeeded
= 0, dwReturned
= 0;
8405 char server_name
[MAX_UTF8_PATH
], share_name
[MAX_UTF8_PATH
];
8406 char port_name
[MAX_UTF8_PATH
];
8408 /* Retrieve the default string from Win.ini (the registry).
8409 * String will be in form "printername,drivername,portname".
8410 * This is the most portable way to get the default printer. */
8411 if (GetProfileString ("windows", "device", ",,", pname_buf
, sizeof (pname_buf
)) <= 0)
8413 /* printername precedes first "," character */
8414 strtok (pname_buf
, ",");
8415 /* We want to know more than the printer name */
8416 if (!OpenPrinter (pname_buf
, &hPrn
, NULL
))
8418 /* GetPrinterW is not supported by unicows.dll. */
8419 if (w32_unicode_filenames
&& os_subtype
!= OS_9X
)
8420 GetPrinterW (hPrn
, 2, NULL
, 0, &dwNeeded
);
8422 GetPrinterA (hPrn
, 2, NULL
, 0, &dwNeeded
);
8425 ClosePrinter (hPrn
);
8428 /* Call GetPrinter again with big enough memory block. */
8429 if (w32_unicode_filenames
&& os_subtype
!= OS_9X
)
8431 /* Allocate memory for the PRINTER_INFO_2 struct. */
8432 ppi2w
= xmalloc (dwNeeded
);
8433 err
= GetPrinterW (hPrn
, 2, (LPBYTE
)ppi2w
, dwNeeded
, &dwReturned
);
8434 ClosePrinter (hPrn
);
8441 if ((ppi2w
->Attributes
& PRINTER_ATTRIBUTE_SHARED
)
8442 && ppi2w
->pServerName
)
8444 filename_from_utf16 (ppi2w
->pServerName
, server_name
);
8445 filename_from_utf16 (ppi2w
->pShareName
, share_name
);
8449 server_name
[0] = '\0';
8450 filename_from_utf16 (ppi2w
->pPortName
, port_name
);
8455 ppi2a
= xmalloc (dwNeeded
);
8456 err
= GetPrinterA (hPrn
, 2, (LPBYTE
)ppi2a
, dwNeeded
, &dwReturned
);
8457 ClosePrinter (hPrn
);
8464 if ((ppi2a
->Attributes
& PRINTER_ATTRIBUTE_SHARED
)
8465 && ppi2a
->pServerName
)
8467 filename_from_ansi (ppi2a
->pServerName
, server_name
);
8468 filename_from_ansi (ppi2a
->pShareName
, share_name
);
8472 server_name
[0] = '\0';
8473 filename_from_ansi (ppi2a
->pPortName
, port_name
);
8479 /* a remote printer */
8480 if (server_name
[0] == '\\')
8481 snprintf (pname_buf
, sizeof (pname_buf
), "%s\\%s", server_name
,
8484 snprintf (pname_buf
, sizeof (pname_buf
), "\\\\%s\\%s", server_name
,
8486 pname_buf
[sizeof (pname_buf
) - 1] = '\0';
8490 /* a local printer */
8491 strncpy (pname_buf
, port_name
, sizeof (pname_buf
));
8492 pname_buf
[sizeof (pname_buf
) - 1] = '\0';
8493 /* `pPortName' can include several ports, delimited by ','.
8494 * we only use the first one. */
8495 strtok (pname_buf
, ",");
8498 return DECODE_FILE (build_unibyte_string (pname_buf
));
8500 #endif /* WINDOWSNT */
8503 /* Equivalent of strerror for W32 error codes. */
8505 w32_strerror (int error_no
)
8507 static char buf
[500];
8511 error_no
= GetLastError ();
8513 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
8514 FORMAT_MESSAGE_IGNORE_INSERTS
,
8517 0, /* choose most suitable language */
8518 buf
, sizeof (buf
), NULL
);
8520 while (ret
> 0 && (buf
[ret
- 1] == '\n' ||
8521 buf
[ret
- 1] == '\r' ))
8525 sprintf (buf
, "w32 error %u", error_no
);
8530 /* For convenience when debugging. (You cannot call GetLastError
8531 directly from GDB: it will crash, because it uses the __stdcall
8532 calling convention, not the _cdecl convention assumed by GDB.) */
8534 w32_last_error (void)
8536 return GetLastError ();
8539 /* Cache information describing the NT system for later use. */
8541 cache_system_info (void)
8554 /* Cache the module handle of Emacs itself. */
8555 hinst
= GetModuleHandle (NULL
);
8557 /* Cache the version of the operating system. */
8558 version
.data
= GetVersion ();
8559 w32_major_version
= version
.info
.major
;
8560 w32_minor_version
= version
.info
.minor
;
8562 if (version
.info
.platform
& 0x8000)
8567 /* Cache page size, allocation unit, processor type, etc. */
8568 GetSystemInfo (&sysinfo_cache
);
8569 syspage_mask
= (DWORD_PTR
)sysinfo_cache
.dwPageSize
- 1;
8571 /* Cache os info. */
8572 osinfo_cache
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFO
);
8573 GetVersionEx (&osinfo_cache
);
8575 w32_build_number
= osinfo_cache
.dwBuildNumber
;
8576 if (os_subtype
== OS_9X
)
8577 w32_build_number
&= 0xffff;
8579 w32_num_mouse_buttons
= GetSystemMetrics (SM_CMOUSEBUTTONS
);
8584 _DebPrint (const char *fmt
, ...)
8589 va_start (args
, fmt
);
8590 vsprintf (buf
, fmt
, args
);
8593 fprintf (stderr
, "%s", buf
);
8595 OutputDebugString (buf
);
8600 w32_console_toggle_lock_key (int vk_code
, Lisp_Object new_state
)
8602 int cur_state
= (GetKeyState (vk_code
) & 1);
8604 if (NILP (new_state
)
8605 || (NUMBERP (new_state
)
8606 && ((XUINT (new_state
)) & 1) != cur_state
))
8609 faked_key
= vk_code
;
8610 #endif /* WINDOWSNT */
8612 keybd_event ((BYTE
) vk_code
,
8613 (BYTE
) MapVirtualKey (vk_code
, 0),
8614 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
8615 keybd_event ((BYTE
) vk_code
,
8616 (BYTE
) MapVirtualKey (vk_code
, 0),
8617 KEYEVENTF_EXTENDEDKEY
| 0, 0);
8618 keybd_event ((BYTE
) vk_code
,
8619 (BYTE
) MapVirtualKey (vk_code
, 0),
8620 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
8621 cur_state
= !cur_state
;
8627 /* Translate console modifiers to emacs modifiers.
8628 German keyboard support (Kai Morgan Zeise 2/18/95). */
8630 w32_kbd_mods_to_emacs (DWORD mods
, WORD key
)
8634 /* If we recognize right-alt and left-ctrl as AltGr, and it has been
8635 pressed, first remove those modifiers. */
8636 if (!NILP (Vw32_recognize_altgr
)
8637 && (mods
& (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
))
8638 == (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
))
8639 mods
&= ~ (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
);
8641 if (mods
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
))
8642 retval
= ((NILP (Vw32_alt_is_meta
)) ? alt_modifier
: meta_modifier
);
8644 if (mods
& (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
8646 retval
|= ctrl_modifier
;
8647 if ((mods
& (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
8648 == (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
8649 retval
|= meta_modifier
;
8652 if (mods
& LEFT_WIN_PRESSED
)
8653 retval
|= w32_key_to_modifier (VK_LWIN
);
8654 if (mods
& RIGHT_WIN_PRESSED
)
8655 retval
|= w32_key_to_modifier (VK_RWIN
);
8656 if (mods
& APPS_PRESSED
)
8657 retval
|= w32_key_to_modifier (VK_APPS
);
8658 if (mods
& SCROLLLOCK_ON
)
8659 retval
|= w32_key_to_modifier (VK_SCROLL
);
8661 /* Just in case someone wanted the original behavior, make it
8662 optional by setting w32-capslock-is-shiftlock to t. */
8663 if (NILP (Vw32_capslock_is_shiftlock
)
8664 /* Keys that should _not_ be affected by CapsLock. */
8665 && ( (key
== VK_BACK
)
8667 || (key
== VK_CLEAR
)
8668 || (key
== VK_RETURN
)
8669 || (key
== VK_ESCAPE
)
8670 || ((key
>= VK_SPACE
) && (key
<= VK_HELP
))
8671 || ((key
>= VK_NUMPAD0
) && (key
<= VK_F24
))
8672 || ((key
>= VK_NUMPAD_CLEAR
) && (key
<= VK_NUMPAD_DELETE
))
8675 /* Only consider shift state. */
8676 if ((mods
& SHIFT_PRESSED
) != 0)
8677 retval
|= shift_modifier
;
8681 /* Ignore CapsLock state if not enabled. */
8682 if (NILP (Vw32_enable_caps_lock
))
8683 mods
&= ~CAPSLOCK_ON
;
8684 if ((mods
& (SHIFT_PRESSED
| CAPSLOCK_ON
)) != 0)
8685 retval
|= shift_modifier
;
8691 /* The return code indicates key code size. cpID is the codepage to
8692 use for translation to Unicode; -1 means use the current console
8695 w32_kbd_patch_key (KEY_EVENT_RECORD
*event
, int cpId
)
8697 unsigned int key_code
= event
->wVirtualKeyCode
;
8698 unsigned int mods
= event
->dwControlKeyState
;
8700 static BYTE ansi_code
[4];
8701 static int isdead
= 0;
8705 event
->uChar
.AsciiChar
= ansi_code
[2];
8709 if (event
->uChar
.AsciiChar
!= 0)
8712 memset (keystate
, 0, sizeof (keystate
));
8713 keystate
[key_code
] = 0x80;
8714 if (mods
& SHIFT_PRESSED
)
8715 keystate
[VK_SHIFT
] = 0x80;
8716 if (mods
& CAPSLOCK_ON
)
8717 keystate
[VK_CAPITAL
] = 1;
8718 /* If we recognize right-alt and left-ctrl as AltGr, set the key
8719 states accordingly before invoking ToAscii. */
8720 if (!NILP (Vw32_recognize_altgr
)
8721 && (mods
& LEFT_CTRL_PRESSED
) && (mods
& RIGHT_ALT_PRESSED
))
8723 keystate
[VK_CONTROL
] = 0x80;
8724 keystate
[VK_LCONTROL
] = 0x80;
8725 keystate
[VK_MENU
] = 0x80;
8726 keystate
[VK_RMENU
] = 0x80;
8730 /* Because of an OS bug, ToAscii corrupts the stack when called to
8731 convert a dead key in console mode on NT4. Unfortunately, trying
8732 to check for dead keys using MapVirtualKey doesn't work either -
8733 these functions apparently use internal information about keyboard
8734 layout which doesn't get properly updated in console programs when
8735 changing layout (though apparently it gets partly updated,
8736 otherwise ToAscii wouldn't crash). */
8737 if (is_dead_key (event
->wVirtualKeyCode
))
8741 /* On NT, call ToUnicode instead and then convert to the current
8742 console input codepage. */
8743 if (os_subtype
== OS_NT
)
8747 isdead
= ToUnicode (event
->wVirtualKeyCode
, event
->wVirtualScanCode
,
8748 keystate
, buf
, 128, 0);
8751 /* When we are called from the GUI message processing code,
8752 we are passed the current keyboard codepage, a positive
8753 number, to use below. */
8755 cpId
= GetConsoleCP ();
8757 event
->uChar
.UnicodeChar
= buf
[isdead
- 1];
8758 isdead
= WideCharToMultiByte (cpId
, 0, buf
, isdead
,
8759 (LPSTR
)ansi_code
, 4, NULL
, NULL
);
8766 isdead
= ToAscii (event
->wVirtualKeyCode
, event
->wVirtualScanCode
,
8767 keystate
, (LPWORD
) ansi_code
, 0);
8772 event
->uChar
.AsciiChar
= ansi_code
[0];
8778 w32_sys_ring_bell (struct frame
*f
)
8780 if (sound_type
== 0xFFFFFFFF)
8784 else if (sound_type
== MB_EMACS_SILENT
)
8789 MessageBeep (sound_type
);
8792 DEFUN ("w32--menu-bar-in-use", Fw32__menu_bar_in_use
, Sw32__menu_bar_in_use
,
8794 doc
: /* Return non-nil when a menu-bar menu is being used.
8795 Internal use only. */)
8798 return menubar_in_use
? Qt
: Qnil
;
8801 #if defined WINDOWSNT && !defined HAVE_DBUS
8803 /***********************************************************************
8805 ***********************************************************************/
8806 /* A private struct declaration to avoid compile-time limits. */
8807 typedef struct MY_NOTIFYICONDATAW
{
8812 UINT uCallbackMessage
;
8818 _ANONYMOUS_UNION
union {
8822 WCHAR szInfoTitle
[64];
8826 } MY_NOTIFYICONDATAW
;
8828 #define MYNOTIFYICONDATAW_V1_SIZE offsetof (MY_NOTIFYICONDATAW, szTip[64])
8829 #define MYNOTIFYICONDATAW_V2_SIZE offsetof (MY_NOTIFYICONDATAW, guidItem)
8830 #define MYNOTIFYICONDATAW_V3_SIZE offsetof (MY_NOTIFYICONDATAW, hBalloonIcon)
8832 # define NIF_INFO 0x00000010
8835 # define NIIF_NONE 0x00000000
8838 # define NIIF_INFO 0x00000001
8840 #ifndef NIIF_WARNING
8841 # define NIIF_WARNING 0x00000002
8844 # define NIIF_ERROR 0x00000003
8848 #define EMACS_TRAY_NOTIFICATION_ID 42 /* arbitrary */
8849 #define EMACS_NOTIFICATION_MSG (WM_APP + 1)
8858 /* Report the version of a DLL given by its name. The return value is
8859 constructed using MAKEDLLVERULL. */
8861 get_dll_version (const char *dll_name
)
8863 ULONGLONG version
= 0;
8864 HINSTANCE hdll
= LoadLibrary (dll_name
);
8868 DLLGETVERSIONPROC pDllGetVersion
8869 = (DLLGETVERSIONPROC
) GetProcAddress (hdll
, "DllGetVersion");
8876 memset (&dvi
, 0, sizeof(dvi
));
8877 dvi
.cbSize
= sizeof(dvi
);
8878 result
= pDllGetVersion (&dvi
);
8879 if (SUCCEEDED (result
))
8880 version
= MAKEDLLVERULL (dvi
.dwMajorVersion
, dvi
.dwMinorVersion
,
8889 /* Return the number of bytes in UTF-8 encoded string STR that
8890 corresponds to at most LIM characters. If STR ends before LIM
8891 characters, return the number of bytes in STR including the
8892 terminating null byte. */
8894 utf8_mbslen_lim (const char *str
, int lim
)
8896 const char *p
= str
;
8897 int mblen
= 0, nchars
= 0;
8899 while (*p
&& nchars
< lim
)
8901 int nbytes
= CHAR_BYTES (*p
);
8908 if (!*p
&& nchars
< lim
)
8914 /* Low-level subroutine to show tray notifications. All strings are
8915 supposed to be unibyte UTF-8 encoded by the caller. */
8917 add_tray_notification (struct frame
*f
, const char *icon
, const char *tip
,
8918 enum NI_Severity severity
, unsigned timeout
,
8919 const char *title
, const char *msg
)
8921 EMACS_INT retval
= EMACS_TRAY_NOTIFICATION_ID
;
8923 if (FRAME_W32_P (f
))
8925 MY_NOTIFYICONDATAW nidw
;
8926 ULONGLONG shell_dll_version
= get_dll_version ("Shell32.dll");
8927 wchar_t tipw
[128], msgw
[256], titlew
[64];
8930 memset (&nidw
, 0, sizeof(nidw
));
8932 /* MSDN says the full struct is supported since Vista, whose
8933 Shell32.dll version is said to be 6.0.6. But DllGetVersion
8934 cannot report the 3rd field value, it reports "build number"
8935 instead, which is something else. So we use the Windows 7's
8936 version 6.1 as cutoff, and Vista loses. (Actually, the loss
8937 is not a real one, since we don't expose the hBalloonIcon
8938 member of the struct to Lisp.) */
8939 if (shell_dll_version
>= MAKEDLLVERULL (6, 1, 0, 0)) /* >= Windows 7 */
8940 nidw
.cbSize
= sizeof (nidw
);
8941 else if (shell_dll_version
>= MAKEDLLVERULL (6, 0, 0, 0)) /* XP */
8942 nidw
.cbSize
= MYNOTIFYICONDATAW_V3_SIZE
;
8943 else if (shell_dll_version
>= MAKEDLLVERULL (5, 0, 0, 0)) /* W2K */
8944 nidw
.cbSize
= MYNOTIFYICONDATAW_V2_SIZE
;
8946 nidw
.cbSize
= MYNOTIFYICONDATAW_V1_SIZE
; /* < W2K */
8947 nidw
.hWnd
= FRAME_W32_WINDOW (f
);
8948 nidw
.uID
= EMACS_TRAY_NOTIFICATION_ID
;
8949 nidw
.uFlags
= NIF_MESSAGE
| NIF_ICON
| NIF_TIP
| NIF_INFO
;
8950 nidw
.uCallbackMessage
= EMACS_NOTIFICATION_MSG
;
8952 nidw
.hIcon
= LoadIcon (hinst
, EMACS_CLASS
);
8955 if (w32_unicode_filenames
)
8957 wchar_t icon_w
[MAX_PATH
];
8959 if (filename_to_utf16 (icon
, icon_w
) != 0)
8964 nidw
.hIcon
= LoadImageW (NULL
, icon_w
, IMAGE_ICON
, 0, 0,
8965 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8969 char icon_a
[MAX_PATH
];
8971 if (filename_to_ansi (icon
, icon_a
) != 0)
8976 nidw
.hIcon
= LoadImageA (NULL
, icon_a
, IMAGE_ICON
, 0, 0,
8977 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
8982 switch (GetLastError ())
8984 case ERROR_FILE_NOT_FOUND
:
8994 /* Windows 9X and NT4 support only 64 characters in the Tip,
8995 later versions support up to 128. */
8996 if (nidw
.cbSize
== MYNOTIFYICONDATAW_V1_SIZE
)
8998 tiplen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
8999 tip
, utf8_mbslen_lim (tip
, 63),
9006 tiplen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9007 tip
, utf8_mbslen_lim (tip
, 127),
9018 wcscpy (nidw
.szTip
, tipw
);
9020 /* The rest of the structure is only supported since Windows 2000. */
9021 if (nidw
.cbSize
> MYNOTIFYICONDATAW_V1_SIZE
)
9025 slen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9026 msg
, utf8_mbslen_lim (msg
, 255),
9036 wcscpy (nidw
.szInfo
, msgw
);
9037 nidw
.uTimeout
= timeout
;
9038 slen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9039 title
, utf8_mbslen_lim (title
, 63),
9049 wcscpy (nidw
.szInfoTitle
, titlew
);
9054 nidw
.dwInfoFlags
= NIIF_NONE
;
9058 nidw
.dwInfoFlags
= NIIF_INFO
;
9061 nidw
.dwInfoFlags
= NIIF_WARNING
;
9064 nidw
.dwInfoFlags
= NIIF_ERROR
;
9069 if (!Shell_NotifyIconW (NIM_ADD
, (PNOTIFYICONDATAW
)&nidw
))
9071 /* GetLastError returns meaningless results when
9072 Shell_NotifyIcon fails. */
9073 DebPrint (("Shell_NotifyIcon ADD failed (err=%d)\n",
9079 if (*icon
&& !DestroyIcon (nidw
.hIcon
))
9080 DebPrint (("DestroyIcon failed (err=%d)\n", GetLastError ()));
9085 /* Low-level subroutine to remove a tray notification. Note: we only
9086 pass the minimum data about the notification: its ID and the handle
9087 of the window to which it sends messages. MSDN doesn't say this is
9088 enough, but it works in practice. This allows us to avoid keeping
9089 the notification data around after we show the notification. */
9091 delete_tray_notification (struct frame
*f
, int id
)
9093 if (FRAME_W32_P (f
))
9095 MY_NOTIFYICONDATAW nidw
;
9097 memset (&nidw
, 0, sizeof(nidw
));
9098 nidw
.hWnd
= FRAME_W32_WINDOW (f
);
9101 if (!Shell_NotifyIconW (NIM_DELETE
, (PNOTIFYICONDATAW
)&nidw
))
9103 /* GetLastError returns meaningless results when
9104 Shell_NotifyIcon fails. */
9105 DebPrint (("Shell_NotifyIcon DELETE failed\n"));
9113 DEFUN ("w32-notification-notify",
9114 Fw32_notification_notify
, Sw32_notification_notify
,
9116 doc
: /* Display an MS-Windows tray notification as specified by PARAMS.
9118 Value is the integer unique ID of the notification that can be used
9119 to remove the notification using `w32-notification-close', which see.
9120 If the function fails, the return value is nil.
9122 Tray notifications, a.k.a. \"taskbar messages\", are messages that
9123 inform the user about events unrelated to the current user activity,
9124 such as a significant system event, by briefly displaying informative
9125 text in a balloon from an icon in the notification area of the taskbar.
9127 Parameters in PARAMS are specified as keyword/value pairs. All the
9128 parameters are optional, but if no parameters are specified, the
9129 function will do nothing and return nil.
9131 The following parameters are supported:
9133 :icon ICON -- Display ICON in the system tray. If ICON is a string,
9134 it should specify a file name from which to load the
9135 icon; the specified file should be a .ico Windows icon
9136 file. If ICON is not a string, or if this parameter
9137 is not specified, the standard Emacs icon will be used.
9139 :tip TIP -- Use TIP as the tooltip for the notification. If TIP
9140 is a string, this is the text of a tooltip that will
9141 be shown when the mouse pointer hovers over the tray
9142 icon added by the notification. If TIP is not a
9143 string, or if this parameter is not specified, the
9144 default tooltip text is \"Emacs notification\". The
9145 tooltip text can be up to 127 characters long (63
9146 on Windows versions before W2K). Longer strings
9149 :level LEVEL -- Notification severity level, one of `info',
9150 `warning', or `error'. If given, the value
9151 determines the icon displayed to the left of the
9152 notification title, but only if the `:title'
9153 parameter (see below) is also specified and is a
9156 :title TITLE -- The title of the notification. If TITLE is a string,
9157 it is displayed in a larger font immediately above
9158 the body text. The title text can be up to 63
9159 characters long; longer text will be truncated.
9161 :body BODY -- The body of the notification. If BODY is a string,
9162 it specifies the text of the notification message.
9163 Use embedded newlines to control how the text is
9164 broken into lines. The body text can be up to 255
9165 characters long, and will be truncated if it's longer.
9167 Note that versions of Windows before W2K support only `:icon' and `:tip'.
9168 You can pass the other parameters, but they will be ignored on those
9171 There can be at most one active notification at any given time. An
9172 active notification must be removed by calling `w32-notification-close'
9173 before a new one can be shown.
9175 usage: (w32-notification-notify &rest PARAMS) */)
9176 (ptrdiff_t nargs
, Lisp_Object
*args
)
9178 struct frame
*f
= SELECTED_FRAME ();
9179 Lisp_Object arg_plist
, lres
;
9181 char *icon
, *tip
, *title
, *msg
;
9182 enum NI_Severity severity
;
9188 arg_plist
= Flist (nargs
, args
);
9191 lres
= Fplist_get (arg_plist
, QCicon
);
9193 icon
= SSDATA (ENCODE_FILE (Fexpand_file_name (lres
, Qnil
)));
9198 lres
= Fplist_get (arg_plist
, QCtip
);
9200 tip
= SSDATA (code_convert_string_norecord (lres
, Qutf_8
, 1));
9202 tip
= "Emacs notification";
9205 lres
= Fplist_get (arg_plist
, QClevel
);
9208 else if (EQ (lres
, Qinfo
))
9210 else if (EQ (lres
, Qwarning
))
9212 else if (EQ (lres
, Qerror
))
9218 lres
= Fplist_get (arg_plist
, QCtitle
);
9220 title
= SSDATA (code_convert_string_norecord (lres
, Qutf_8
, 1));
9224 /* Notification body text. */
9225 lres
= Fplist_get (arg_plist
, QCbody
);
9227 msg
= SSDATA (code_convert_string_norecord (lres
, Qutf_8
, 1));
9232 retval
= add_tray_notification (f
, icon
, tip
, severity
, timeout
, title
, msg
);
9233 return (retval
< 0 ? Qnil
: make_number (retval
));
9236 DEFUN ("w32-notification-close",
9237 Fw32_notification_close
, Sw32_notification_close
,
9239 doc
: /* Remove the MS-Windows tray notification specified by its ID. */)
9242 struct frame
*f
= SELECTED_FRAME ();
9245 delete_tray_notification (f
, XINT (id
));
9250 #endif /* WINDOWSNT && !HAVE_DBUS */
9253 /***********************************************************************
9255 ***********************************************************************/
9257 /* Keep this list in the same order as frame_parms in frame.c.
9258 Use 0 for unsupported frame parameters. */
9260 frame_parm_handler w32_frame_parm_handlers
[] =
9264 x_set_background_color
,
9270 x_set_foreground_color
,
9273 x_set_internal_border_width
,
9274 x_set_right_divider_width
,
9275 x_set_bottom_divider_width
,
9276 x_set_menu_bar_lines
,
9278 x_explicitly_set_name
,
9279 x_set_scroll_bar_width
,
9280 x_set_scroll_bar_height
,
9283 x_set_vertical_scroll_bars
,
9284 x_set_horizontal_scroll_bars
,
9286 x_set_tool_bar_lines
,
9287 0, /* x_set_scroll_bar_foreground, */
9288 0, /* x_set_scroll_bar_background, */
9293 0, /* x_set_wait_for_wm, */
9297 0, /* x_set_sticky */
9298 0, /* x_set_tool_bar_position */
9302 syms_of_w32fns (void)
9304 globals_of_w32fns ();
9305 track_mouse_window
= NULL
;
9307 w32_visible_system_caret_hwnd
= NULL
;
9309 DEFSYM (Qundefined_color
, "undefined-color");
9310 DEFSYM (Qcancel_timer
, "cancel-timer");
9311 DEFSYM (Qhyper
, "hyper");
9312 DEFSYM (Qsuper
, "super");
9313 DEFSYM (Qmeta
, "meta");
9314 DEFSYM (Qalt
, "alt");
9315 DEFSYM (Qctrl
, "ctrl");
9316 DEFSYM (Qcontrol
, "control");
9317 DEFSYM (Qshift
, "shift");
9318 DEFSYM (Qfont_param
, "font-parameter");
9319 DEFSYM (Qgeometry
, "geometry");
9320 DEFSYM (Qworkarea
, "workarea");
9321 DEFSYM (Qmm_size
, "mm-size");
9322 DEFSYM (Qframes
, "frames");
9323 DEFSYM (Qtip_frame
, "tip-frame");
9324 DEFSYM (Qunicode_sip
, "unicode-sip");
9325 #if defined WINDOWSNT && !defined HAVE_DBUS
9326 DEFSYM (QCicon
, ":icon");
9327 DEFSYM (QCtip
, ":tip");
9328 DEFSYM (QClevel
, ":level");
9329 DEFSYM (Qinfo
, "info");
9330 DEFSYM (Qwarning
, "warning");
9331 DEFSYM (QCtitle
, ":title");
9332 DEFSYM (QCbody
, ":body");
9335 /* Symbols used elsewhere, but only in MS-Windows-specific code. */
9336 DEFSYM (Qgnutls_dll
, "gnutls");
9337 DEFSYM (Qlibxml2_dll
, "libxml2");
9338 DEFSYM (Qserif
, "serif");
9339 DEFSYM (Qzlib_dll
, "zlib");
9341 Fput (Qundefined_color
, Qerror_conditions
,
9342 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
9343 Fput (Qundefined_color
, Qerror_message
,
9344 build_pure_c_string ("Undefined color"));
9346 staticpro (&w32_grabbed_keys
);
9347 w32_grabbed_keys
= Qnil
;
9349 DEFVAR_LISP ("w32-color-map", Vw32_color_map
,
9350 doc
: /* An array of color name mappings for Windows. */);
9351 Vw32_color_map
= Qnil
;
9353 DEFVAR_LISP ("w32-pass-alt-to-system", Vw32_pass_alt_to_system
,
9354 doc
: /* Non-nil if Alt key presses are passed on to Windows.
9355 When non-nil, for example, Alt pressed and released and then space will
9356 open the System menu. When nil, Emacs processes the Alt key events, and
9357 then silently swallows them. */);
9358 Vw32_pass_alt_to_system
= Qnil
;
9360 DEFVAR_LISP ("w32-alt-is-meta", Vw32_alt_is_meta
,
9361 doc
: /* Non-nil if the Alt key is to be considered the same as the META key.
9362 When nil, Emacs will translate the Alt key to the ALT modifier, not to META. */);
9363 Vw32_alt_is_meta
= Qt
;
9365 DEFVAR_INT ("w32-quit-key", w32_quit_key
,
9366 doc
: /* If non-zero, the virtual key code for an alternative quit key. */);
9369 DEFVAR_LISP ("w32-pass-lwindow-to-system",
9370 Vw32_pass_lwindow_to_system
,
9371 doc
: /* If non-nil, the left \"Windows\" key is passed on to Windows.
9373 When non-nil, the Start menu is opened by tapping the key.
9374 If you set this to nil, the left \"Windows\" key is processed by Emacs
9375 according to the value of `w32-lwindow-modifier', which see.
9377 Note that some combinations of the left \"Windows\" key with other keys are
9378 caught by Windows at low level, and so binding them in Emacs will have no
9379 effect. For example, <lwindow>-r always pops up the Windows Run dialog,
9380 <lwindow>-<Pause> pops up the "System Properties" dialog, etc. However, see
9381 the doc string of `w32-phantom-key-code'. */);
9382 Vw32_pass_lwindow_to_system
= Qt
;
9384 DEFVAR_LISP ("w32-pass-rwindow-to-system",
9385 Vw32_pass_rwindow_to_system
,
9386 doc
: /* If non-nil, the right \"Windows\" key is passed on to Windows.
9388 When non-nil, the Start menu is opened by tapping the key.
9389 If you set this to nil, the right \"Windows\" key is processed by Emacs
9390 according to the value of `w32-rwindow-modifier', which see.
9392 Note that some combinations of the right \"Windows\" key with other keys are
9393 caught by Windows at low level, and so binding them in Emacs will have no
9394 effect. For example, <rwindow>-r always pops up the Windows Run dialog,
9395 <rwindow>-<Pause> pops up the "System Properties" dialog, etc. However, see
9396 the doc string of `w32-phantom-key-code'. */);
9397 Vw32_pass_rwindow_to_system
= Qt
;
9399 DEFVAR_LISP ("w32-phantom-key-code",
9400 Vw32_phantom_key_code
,
9401 doc
: /* Virtual key code used to generate \"phantom\" key presses.
9402 Value is a number between 0 and 255.
9404 Phantom key presses are generated in order to stop the system from
9405 acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or
9406 `w32-pass-rwindow-to-system' is nil. */);
9407 /* Although 255 is technically not a valid key code, it works and
9408 means that this hack won't interfere with any real key code. */
9409 XSETINT (Vw32_phantom_key_code
, 255);
9411 DEFVAR_LISP ("w32-enable-num-lock",
9412 Vw32_enable_num_lock
,
9413 doc
: /* If non-nil, the Num Lock key acts normally.
9414 Set to nil to handle Num Lock as the `kp-numlock' key. */);
9415 Vw32_enable_num_lock
= Qt
;
9417 DEFVAR_LISP ("w32-enable-caps-lock",
9418 Vw32_enable_caps_lock
,
9419 doc
: /* If non-nil, the Caps Lock key acts normally.
9420 Set to nil to handle Caps Lock as the `capslock' key. */);
9421 Vw32_enable_caps_lock
= Qt
;
9423 DEFVAR_LISP ("w32-scroll-lock-modifier",
9424 Vw32_scroll_lock_modifier
,
9425 doc
: /* Modifier to use for the Scroll Lock ON state.
9426 The value can be hyper, super, meta, alt, control or shift for the
9427 respective modifier, or nil to handle Scroll Lock as the `scroll' key.
9428 Any other value will cause the Scroll Lock key to be ignored. */);
9429 Vw32_scroll_lock_modifier
= Qnil
;
9431 DEFVAR_LISP ("w32-lwindow-modifier",
9432 Vw32_lwindow_modifier
,
9433 doc
: /* Modifier to use for the left \"Windows\" key.
9434 The value can be hyper, super, meta, alt, control or shift for the
9435 respective modifier, or nil to appear as the `lwindow' key.
9436 Any other value will cause the key to be ignored. */);
9437 Vw32_lwindow_modifier
= Qnil
;
9439 DEFVAR_LISP ("w32-rwindow-modifier",
9440 Vw32_rwindow_modifier
,
9441 doc
: /* Modifier to use for the right \"Windows\" key.
9442 The value can be hyper, super, meta, alt, control or shift for the
9443 respective modifier, or nil to appear as the `rwindow' key.
9444 Any other value will cause the key to be ignored. */);
9445 Vw32_rwindow_modifier
= Qnil
;
9447 DEFVAR_LISP ("w32-apps-modifier",
9449 doc
: /* Modifier to use for the \"Apps\" key.
9450 The value can be hyper, super, meta, alt, control or shift for the
9451 respective modifier, or nil to appear as the `apps' key.
9452 Any other value will cause the key to be ignored. */);
9453 Vw32_apps_modifier
= Qnil
;
9455 DEFVAR_BOOL ("w32-enable-synthesized-fonts", w32_enable_synthesized_fonts
,
9456 doc
: /* Non-nil enables selection of artificially italicized and bold fonts. */);
9457 w32_enable_synthesized_fonts
= 0;
9459 DEFVAR_LISP ("w32-enable-palette", Vw32_enable_palette
,
9460 doc
: /* Non-nil enables Windows palette management to map colors exactly. */);
9461 Vw32_enable_palette
= Qt
;
9463 DEFVAR_INT ("w32-mouse-button-tolerance",
9464 w32_mouse_button_tolerance
,
9465 doc
: /* Analogue of double click interval for faking middle mouse events.
9466 The value is the minimum time in milliseconds that must elapse between
9467 left and right button down events before they are considered distinct events.
9468 If both mouse buttons are depressed within this interval, a middle mouse
9469 button down event is generated instead. */);
9470 w32_mouse_button_tolerance
= GetDoubleClickTime () / 2;
9472 DEFVAR_INT ("w32-mouse-move-interval",
9473 w32_mouse_move_interval
,
9474 doc
: /* Minimum interval between mouse move events.
9475 The value is the minimum time in milliseconds that must elapse between
9476 successive mouse move (or scroll bar drag) events before they are
9477 reported as lisp events. */);
9478 w32_mouse_move_interval
= 0;
9480 DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
9481 w32_pass_extra_mouse_buttons_to_system
,
9482 doc
: /* If non-nil, the fourth and fifth mouse buttons are passed to Windows.
9483 Recent versions of Windows support mice with up to five buttons.
9484 Since most applications don't support these extra buttons, most mouse
9485 drivers will allow you to map them to functions at the system level.
9486 If this variable is non-nil, Emacs will pass them on, allowing the
9487 system to handle them. */);
9488 w32_pass_extra_mouse_buttons_to_system
= 0;
9490 DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
9491 w32_pass_multimedia_buttons_to_system
,
9492 doc
: /* If non-nil, media buttons are passed to Windows.
9493 Some modern keyboards contain buttons for controlling media players, web
9494 browsers and other applications. Generally these buttons are handled on a
9495 system wide basis, but by setting this to nil they are made available
9496 to Emacs for binding. Depending on your keyboard, additional keys that
9497 may be available are:
9499 browser-back, browser-forward, browser-refresh, browser-stop,
9500 browser-search, browser-favorites, browser-home,
9501 mail, mail-reply, mail-forward, mail-send,
9503 help, find, new, open, close, save, print, undo, redo, copy, cut, paste,
9504 spell-check, correction-list, toggle-dictate-command,
9505 media-next, media-previous, media-stop, media-play-pause, media-select,
9506 media-play, media-pause, media-record, media-fast-forward, media-rewind,
9507 media-channel-up, media-channel-down,
9508 volume-mute, volume-up, volume-down,
9509 mic-volume-mute, mic-volume-down, mic-volume-up, mic-toggle,
9510 bass-down, bass-boost, bass-up, treble-down, treble-up */);
9511 w32_pass_multimedia_buttons_to_system
= 1;
9513 #if 0 /* TODO: Mouse cursor customization. */
9514 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
9515 doc
: /* The shape of the pointer when over text.
9516 Changing the value does not affect existing frames
9517 unless you set the mouse color. */);
9518 Vx_pointer_shape
= Qnil
;
9520 Vx_nontext_pointer_shape
= Qnil
;
9522 Vx_mode_pointer_shape
= Qnil
;
9524 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
9525 doc
: /* The shape of the pointer when Emacs is busy.
9526 This variable takes effect when you create a new frame
9527 or when you set the mouse color. */);
9528 Vx_hourglass_pointer_shape
= Qnil
;
9530 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
9531 Vx_sensitive_text_pointer_shape
,
9532 doc
: /* The shape of the pointer when over mouse-sensitive text.
9533 This variable takes effect when you create a new frame
9534 or when you set the mouse color. */);
9535 Vx_sensitive_text_pointer_shape
= Qnil
;
9537 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
9538 Vx_window_horizontal_drag_shape
,
9539 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
9540 This variable takes effect when you create a new frame
9541 or when you set the mouse color. */);
9542 Vx_window_horizontal_drag_shape
= Qnil
;
9544 DEFVAR_LISP ("x-window-vertical-drag-cursor",
9545 Vx_window_vertical_drag_shape
,
9546 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
9547 This variable takes effect when you create a new frame
9548 or when you set the mouse color. */);
9549 Vx_window_vertical_drag_shape
= Qnil
;
9552 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
9553 doc
: /* A string indicating the foreground color of the cursor box. */);
9554 Vx_cursor_fore_pixel
= Qnil
;
9556 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
9557 doc
: /* Maximum size for tooltips.
9558 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
9559 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
9561 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
9562 doc
: /* Non-nil if no window manager is in use.
9563 Emacs doesn't try to figure this out; this is always nil
9564 unless you set it to something else. */);
9565 /* We don't have any way to find this out, so set it to nil
9566 and maybe the user would like to set it to t. */
9567 Vx_no_window_manager
= Qnil
;
9569 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
9570 Vx_pixel_size_width_font_regexp
,
9571 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
9573 Since Emacs gets width of a font matching with this regexp from
9574 PIXEL_SIZE field of the name, font finding mechanism gets faster for
9575 such a font. This is especially effective for such large fonts as
9576 Chinese, Japanese, and Korean. */);
9577 Vx_pixel_size_width_font_regexp
= Qnil
;
9579 DEFVAR_LISP ("w32-bdf-filename-alist",
9580 Vw32_bdf_filename_alist
,
9581 doc
: /* List of bdf fonts and their corresponding filenames. */);
9582 Vw32_bdf_filename_alist
= Qnil
;
9584 DEFVAR_BOOL ("w32-strict-fontnames",
9585 w32_strict_fontnames
,
9586 doc
: /* Non-nil means only use fonts that are exact matches for those requested.
9587 Default is nil, which allows old fontnames that are not XLFD compliant,
9588 and allows third-party CJK display to work by specifying false charset
9589 fields to trick Emacs into translating to Big5, SJIS etc.
9590 Setting this to t will prevent wrong fonts being selected when
9591 fontsets are automatically created. */);
9592 w32_strict_fontnames
= 0;
9594 DEFVAR_BOOL ("w32-strict-painting",
9595 w32_strict_painting
,
9596 doc
: /* Non-nil means use strict rules for repainting frames.
9597 Set this to nil to get the old behavior for repainting; this should
9598 only be necessary if the default setting causes problems. */);
9599 w32_strict_painting
= 1;
9601 DEFVAR_BOOL ("w32-use-fallback-wm-chars-method",
9602 w32_use_fallback_wm_chars_method
,
9603 doc
: /* Non-nil means use old method of processing character keys.
9604 This is intended only for debugging of the new processing method.
9607 This variable has effect only on NT family of systems, not on Windows 9X. */);
9608 w32_use_fallback_wm_chars_method
= 0;
9610 DEFVAR_BOOL ("w32-disable-new-uniscribe-apis",
9611 w32_disable_new_uniscribe_apis
,
9612 doc
: /* Non-nil means don't use new Uniscribe APIs.
9613 The new APIs are used to access OTF features supported by fonts.
9614 This is intended only for debugging of the new Uniscribe-related code.
9617 This variable has effect only on Windows Vista and later. */);
9618 w32_disable_new_uniscribe_apis
= 0;
9620 #if 0 /* TODO: Port to W32 */
9621 defsubr (&Sx_change_window_property
);
9622 defsubr (&Sx_delete_window_property
);
9623 defsubr (&Sx_window_property
);
9625 defsubr (&Sxw_display_color_p
);
9626 defsubr (&Sx_display_grayscale_p
);
9627 defsubr (&Sxw_color_defined_p
);
9628 defsubr (&Sxw_color_values
);
9629 defsubr (&Sx_server_max_request_size
);
9630 defsubr (&Sx_server_vendor
);
9631 defsubr (&Sx_server_version
);
9632 defsubr (&Sx_display_pixel_width
);
9633 defsubr (&Sx_display_pixel_height
);
9634 defsubr (&Sx_display_mm_width
);
9635 defsubr (&Sx_display_mm_height
);
9636 defsubr (&Sx_display_screens
);
9637 defsubr (&Sx_display_planes
);
9638 defsubr (&Sx_display_color_cells
);
9639 defsubr (&Sx_display_visual_class
);
9640 defsubr (&Sx_display_backing_store
);
9641 defsubr (&Sx_display_save_under
);
9642 defsubr (&Sx_create_frame
);
9643 defsubr (&Sx_open_connection
);
9644 defsubr (&Sx_close_connection
);
9645 defsubr (&Sx_display_list
);
9646 defsubr (&Sw32_frame_geometry
);
9647 defsubr (&Sw32_frame_edges
);
9648 defsubr (&Sw32_mouse_absolute_pixel_position
);
9649 defsubr (&Sw32_set_mouse_absolute_pixel_position
);
9650 defsubr (&Sx_synchronize
);
9652 /* W32 specific functions */
9654 defsubr (&Sw32_define_rgb_color
);
9655 defsubr (&Sw32_default_color_map
);
9656 defsubr (&Sw32_display_monitor_attributes_list
);
9657 defsubr (&Sw32_send_sys_command
);
9658 defsubr (&Sw32_shell_execute
);
9659 defsubr (&Sw32_register_hot_key
);
9660 defsubr (&Sw32_unregister_hot_key
);
9661 defsubr (&Sw32_registered_hot_keys
);
9662 defsubr (&Sw32_reconstruct_hot_key
);
9663 defsubr (&Sw32_toggle_lock_key
);
9664 defsubr (&Sw32_window_exists_p
);
9665 defsubr (&Sw32_battery_status
);
9666 defsubr (&Sw32__menu_bar_in_use
);
9667 #if defined WINDOWSNT && !defined HAVE_DBUS
9668 defsubr (&Sw32_notification_notify
);
9669 defsubr (&Sw32_notification_close
);
9673 defsubr (&Sfile_system_info
);
9674 defsubr (&Sdefault_printer_name
);
9677 defsubr (&Sset_message_beep
);
9678 defsubr (&Sx_show_tip
);
9679 defsubr (&Sx_hide_tip
);
9681 staticpro (&tip_timer
);
9683 staticpro (&tip_frame
);
9685 last_show_tip_args
= Qnil
;
9686 staticpro (&last_show_tip_args
);
9688 defsubr (&Sx_file_dialog
);
9690 defsubr (&Ssystem_move_file_to_trash
);
9696 /* Crashing and reporting backtrace. */
9699 static LONG CALLBACK
my_exception_handler (EXCEPTION_POINTERS
*);
9700 static LPTOP_LEVEL_EXCEPTION_FILTER prev_exception_handler
;
9702 static DWORD except_code
;
9703 static PVOID except_addr
;
9707 /* Stack overflow recovery. */
9709 /* MinGW headers don't declare this (should be in malloc.h). Also,
9710 the function is not present pre-W2K, so make the call through
9711 a function pointer. */
9712 typedef int (__cdecl
*_resetstkoflw_proc
) (void);
9713 static _resetstkoflw_proc resetstkoflw
;
9715 /* Re-establish the guard page at stack limit. This is needed because
9716 when a stack overflow is detected, Windows removes the guard bit
9717 from the guard page, so if we don't re-establish that protection,
9718 the next stack overflow will cause a crash. */
9720 w32_reset_stack_overflow_guard (void)
9722 if (resetstkoflw
== NULL
)
9724 (_resetstkoflw_proc
)GetProcAddress (GetModuleHandle ("msvcrt.dll"),
9726 /* We ignore the return value. If _resetstkoflw fails, the next
9727 stack overflow will crash the program. */
9728 if (resetstkoflw
!= NULL
)
9729 (void)resetstkoflw ();
9733 stack_overflow_handler (void)
9735 /* Hard GC error may lead to stack overflow caused by
9736 too nested calls to mark_object. No way to survive. */
9738 terminate_due_to_signal (SIGSEGV
, 40);
9740 /* See ms-w32.h: MinGW64's longjmp crashes if invoked in this context. */
9741 __builtin_longjmp (return_to_command_loop
, 1);
9743 sys_longjmp (return_to_command_loop
, 1);
9747 /* This handler records the exception code and the address where it
9748 was triggered so that this info could be included in the backtrace.
9749 Without that, the backtrace in some cases has no information
9750 whatsoever about the offending code, and looks as if the top-level
9751 exception handler in the MinGW startup code was the one that
9752 crashed. We also recover from stack overflow, by calling our stack
9753 overflow handler that jumps back to top level. */
9754 static LONG CALLBACK
9755 my_exception_handler (EXCEPTION_POINTERS
* exception_data
)
9757 except_code
= exception_data
->ExceptionRecord
->ExceptionCode
;
9758 except_addr
= exception_data
->ExceptionRecord
->ExceptionAddress
;
9760 /* If this is a stack overflow exception, attempt to recover. */
9761 if (exception_data
->ExceptionRecord
->ExceptionCode
== EXCEPTION_STACK_OVERFLOW
9762 && exception_data
->ExceptionRecord
->NumberParameters
== 2
9763 /* We can only longjmp to top level from the main thread. */
9764 && GetCurrentThreadId () == dwMainThreadId
)
9766 /* Call stack_overflow_handler (). */
9768 exception_data
->ContextRecord
->Rip
= (DWORD_PTR
) &stack_overflow_handler
;
9770 exception_data
->ContextRecord
->Eip
= (DWORD_PTR
) &stack_overflow_handler
;
9772 /* Zero this out, so the stale address of the stack overflow
9773 exception we handled is not displayed in some future
9776 return EXCEPTION_CONTINUE_EXECUTION
;
9779 if (prev_exception_handler
)
9780 return prev_exception_handler (exception_data
);
9781 return EXCEPTION_EXECUTE_HANDLER
;
9785 typedef USHORT (WINAPI
* CaptureStackBackTrace_proc
) (ULONG
, ULONG
, PVOID
*,
9788 #define BACKTRACE_LIMIT_MAX 62
9791 w32_backtrace (void **buffer
, int limit
)
9793 static CaptureStackBackTrace_proc s_pfn_CaptureStackBackTrace
= NULL
;
9794 HMODULE hm_kernel32
= NULL
;
9796 if (!s_pfn_CaptureStackBackTrace
)
9798 hm_kernel32
= LoadLibrary ("Kernel32.dll");
9799 s_pfn_CaptureStackBackTrace
=
9800 (CaptureStackBackTrace_proc
) GetProcAddress (hm_kernel32
,
9801 "RtlCaptureStackBackTrace");
9803 if (s_pfn_CaptureStackBackTrace
)
9804 return s_pfn_CaptureStackBackTrace (0, min (BACKTRACE_LIMIT_MAX
, limit
),
9813 button
= MessageBox (NULL
,
9814 "A fatal error has occurred!\n\n"
9815 "Would you like to attach a debugger?\n\n"
9817 "YES -- to debug Emacs, or\n"
9818 "NO -- to abort Emacs and produce a backtrace\n"
9819 " (emacs_backtrace.txt in current directory)."
9821 "\n\n(type \"gdb -p <emacs-PID>\" and\n"
9822 "\"continue\" inside GDB before clicking YES.)"
9824 , "Emacs Abort Dialog",
9825 MB_ICONEXCLAMATION
| MB_TASKMODAL
9826 | MB_SETFOREGROUND
| MB_YESNO
);
9831 exit (2); /* tell the compiler we will never return */
9835 void *stack
[BACKTRACE_LIMIT_MAX
+ 1];
9836 int i
= w32_backtrace (stack
, BACKTRACE_LIMIT_MAX
+ 1);
9840 int errfile_fd
= -1;
9842 char buf
[sizeof ("\r\nException at this address:\r\n\r\n")
9843 /* The type below should really be 'void *', but
9844 INT_BUFSIZE_BOUND cannot handle that without
9845 triggering compiler warnings (under certain
9846 pedantic warning switches), it wants an
9848 + 2 * INT_BUFSIZE_BOUND (intptr_t)];
9852 HANDLE errout
= GetStdHandle (STD_ERROR_HANDLE
);
9855 if (errout
&& errout
!= INVALID_HANDLE_VALUE
)
9856 stderr_fd
= _open_osfhandle ((intptr_t)errout
, O_APPEND
| O_BINARY
);
9859 /* We use %p, not 0x%p, as %p produces a leading "0x" on XP,
9860 but not on Windows 7. addr2line doesn't mind a missing
9861 "0x", but will be confused by an extra one. */
9863 sprintf (buf
, "\r\nException 0x%lx at this address:\r\n%p\r\n",
9864 except_code
, except_addr
);
9868 write (stderr_fd
, buf
, strlen (buf
));
9869 write (stderr_fd
, "\r\nBacktrace:\r\n", 14);
9874 errfile_fd
= _open ("emacs_backtrace.txt", O_RDWR
| O_CREAT
| O_BINARY
, S_IREAD
| S_IWRITE
);
9875 if (errfile_fd
>= 0)
9877 lseek (errfile_fd
, 0L, SEEK_END
);
9879 write (errfile_fd
, buf
, strlen (buf
));
9880 write (errfile_fd
, "\r\nBacktrace:\r\n", 14);
9883 for (j
= 0; j
< i
; j
++)
9885 /* stack[] gives the return addresses, whereas we want
9886 the address of the call, so decrease each address
9887 by approximate size of 1 CALL instruction. */
9888 sprintf (buf
, "%p\r\n", (char *)stack
[j
] - sizeof(void *));
9890 write (stderr_fd
, buf
, strlen (buf
));
9891 if (errfile_fd
>= 0)
9892 write (errfile_fd
, buf
, strlen (buf
));
9894 if (i
== BACKTRACE_LIMIT_MAX
)
9897 write (stderr_fd
, "...\r\n", 5);
9898 if (errfile_fd
>= 0)
9899 write (errfile_fd
, "...\r\n", 5);
9901 if (errfile_fd
>= 0)
9912 /* Initialization. */
9915 globals_of_w32fns is used to initialize those global variables that
9916 must always be initialized on startup even when the global variable
9917 initialized is non zero (see the function main in emacs.c).
9918 globals_of_w32fns is called from syms_of_w32fns when the global
9919 variable initialized is 0 and directly from main when initialized
9923 globals_of_w32fns (void)
9925 HMODULE user32_lib
= GetModuleHandle ("user32.dll");
9927 TrackMouseEvent not available in all versions of Windows, so must load
9928 it dynamically. Do it once, here, instead of every time it is used.
9930 track_mouse_event_fn
= (TrackMouseEvent_Proc
)
9931 GetProcAddress (user32_lib
, "TrackMouseEvent");
9933 monitor_from_point_fn
= (MonitorFromPoint_Proc
)
9934 GetProcAddress (user32_lib
, "MonitorFromPoint");
9935 get_monitor_info_fn
= (GetMonitorInfo_Proc
)
9936 GetProcAddress (user32_lib
, "GetMonitorInfoA");
9937 monitor_from_window_fn
= (MonitorFromWindow_Proc
)
9938 GetProcAddress (user32_lib
, "MonitorFromWindow");
9939 enum_display_monitors_fn
= (EnumDisplayMonitors_Proc
)
9940 GetProcAddress (user32_lib
, "EnumDisplayMonitors");
9941 get_title_bar_info_fn
= (GetTitleBarInfo_Proc
)
9942 GetProcAddress (user32_lib
, "GetTitleBarInfo");
9945 HMODULE imm32_lib
= GetModuleHandle ("imm32.dll");
9946 get_composition_string_fn
= (ImmGetCompositionString_Proc
)
9947 GetProcAddress (imm32_lib
, "ImmGetCompositionStringW");
9948 get_ime_context_fn
= (ImmGetContext_Proc
)
9949 GetProcAddress (imm32_lib
, "ImmGetContext");
9950 release_ime_context_fn
= (ImmReleaseContext_Proc
)
9951 GetProcAddress (imm32_lib
, "ImmReleaseContext");
9952 set_ime_composition_window_fn
= (ImmSetCompositionWindow_Proc
)
9953 GetProcAddress (imm32_lib
, "ImmSetCompositionWindow");
9959 prev_exception_handler
= SetUnhandledExceptionFilter (my_exception_handler
);
9960 resetstkoflw
= NULL
;
9963 DEFVAR_INT ("w32-ansi-code-page",
9965 doc
: /* The ANSI code page used by the system. */);
9966 w32_ansi_code_page
= GetACP ();
9968 if (os_subtype
== OS_NT
)
9969 w32_unicode_gui
= 1;
9971 w32_unicode_gui
= 0;
9975 /* MessageBox does not work without this when linked to comctl32.dll 6.0. */
9976 InitCommonControls ();
9978 syms_of_w32uniscribe ();
9981 #ifdef NTGUI_UNICODE
9984 ntgui_encode_system (Lisp_Object str
)
9986 Lisp_Object encoded
;
9987 to_unicode (str
, &encoded
);
9991 #endif /* NTGUI_UNICODE */