1 /* Graphical user interface functions for the Microsoft Windows API.
3 Copyright (C) 1989, 1992-2017 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 */
23 /* Override API version to get the latest functionality. */
25 #define _WIN32_WINNT 0x0600
43 #include "blockinput.h"
46 #include "w32common.h"
51 #endif /* WINDOWSNT */
73 #ifndef FOF_NO_CONNECTED_ELEMENTS
74 #define FOF_NO_CONNECTED_ELEMENTS 0x2000
77 extern int w32_console_toggle_lock_key (int, Lisp_Object
);
78 extern void w32_menu_display_help (HWND
, HMENU
, UINT
, UINT
);
79 extern void w32_free_menu_strings (HWND
);
80 extern const char *map_w32_filename (const char *, const char **);
83 #define IDC_HAND MAKEINTRESOURCE(32649)
86 /* Prefix for system colors. */
87 #define SYSTEM_COLOR_PREFIX "System"
88 #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
90 /* State variables for emulating a three button mouse. */
95 static int button_state
= 0;
96 static W32Msg saved_mouse_button_msg
;
97 static unsigned mouse_button_timer
= 0; /* non-zero when timer is active */
98 static W32Msg saved_mouse_move_msg
;
99 static unsigned mouse_move_timer
= 0;
101 /* Window that is tracking the mouse. */
102 static HWND track_mouse_window
;
104 /* Multi-monitor API definitions that are not pulled from the headers
105 since we are compiling for NT 4. */
106 #ifndef MONITOR_DEFAULT_TO_NEAREST
107 #define MONITOR_DEFAULT_TO_NEAREST 2
109 #ifndef MONITORINFOF_PRIMARY
110 #define MONITORINFOF_PRIMARY 1
112 #ifndef SM_XVIRTUALSCREEN
113 #define SM_XVIRTUALSCREEN 76
115 #ifndef SM_YVIRTUALSCREEN
116 #define SM_YVIRTUALSCREEN 77
118 /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't.
119 To avoid a compile error on one or the other, redefine with a new name. */
128 #if _WIN32_WINDOWS >= 0x0410
129 #define C_CHILDREN_TITLEBAR CCHILDREN_TITLEBAR
130 typedef TITLEBARINFO TITLEBAR_INFO
;
132 #define C_CHILDREN_TITLEBAR 5
137 DWORD rgstate
[C_CHILDREN_TITLEBAR
+1];
138 } TITLEBAR_INFO
, *PTITLEBAR_INFO
;
141 #ifndef CCHDEVICENAME
142 #define CCHDEVICENAME 32
144 struct MONITOR_INFO_EX
150 char szDevice
[CCHDEVICENAME
];
153 /* Reportedly, MSVC does not have this in its headers. */
154 #if defined (_MSC_VER) && _WIN32_WINNT < 0x0500
155 DECLARE_HANDLE(HMONITOR
);
158 typedef BOOL (WINAPI
* TrackMouseEvent_Proc
)
159 (IN OUT LPTRACKMOUSEEVENT lpEventTrack
);
160 typedef LONG (WINAPI
* ImmGetCompositionString_Proc
)
161 (IN HIMC context
, IN DWORD index
, OUT LPVOID buffer
, IN DWORD bufLen
);
162 typedef HIMC (WINAPI
* ImmGetContext_Proc
) (IN HWND window
);
163 typedef BOOL (WINAPI
* ImmReleaseContext_Proc
) (IN HWND wnd
, IN HIMC context
);
164 typedef BOOL (WINAPI
* ImmSetCompositionWindow_Proc
) (IN HIMC context
,
165 IN COMPOSITIONFORM
*form
);
166 typedef HMONITOR (WINAPI
* MonitorFromPoint_Proc
) (IN POINT pt
, IN DWORD flags
);
167 typedef BOOL (WINAPI
* GetMonitorInfo_Proc
)
168 (IN HMONITOR monitor
, OUT
struct MONITOR_INFO
* info
);
169 typedef HMONITOR (WINAPI
* MonitorFromWindow_Proc
)
170 (IN HWND hwnd
, IN DWORD dwFlags
);
171 typedef BOOL
CALLBACK (* MonitorEnum_Proc
)
172 (IN HMONITOR monitor
, IN HDC hdc
, IN RECT
*rcMonitor
, IN LPARAM dwData
);
173 typedef BOOL (WINAPI
* EnumDisplayMonitors_Proc
)
174 (IN HDC hdc
, IN RECT
*rcClip
, IN MonitorEnum_Proc fnEnum
, IN LPARAM dwData
);
175 typedef BOOL (WINAPI
* GetTitleBarInfo_Proc
)
176 (IN HWND hwnd
, OUT TITLEBAR_INFO
* info
);
178 TrackMouseEvent_Proc track_mouse_event_fn
= NULL
;
179 ImmGetCompositionString_Proc get_composition_string_fn
= NULL
;
180 ImmGetContext_Proc get_ime_context_fn
= NULL
;
181 ImmReleaseContext_Proc release_ime_context_fn
= NULL
;
182 ImmSetCompositionWindow_Proc set_ime_composition_window_fn
= NULL
;
183 MonitorFromPoint_Proc monitor_from_point_fn
= NULL
;
184 GetMonitorInfo_Proc get_monitor_info_fn
= NULL
;
185 MonitorFromWindow_Proc monitor_from_window_fn
= NULL
;
186 EnumDisplayMonitors_Proc enum_display_monitors_fn
= NULL
;
187 GetTitleBarInfo_Proc get_title_bar_info_fn
= NULL
;
189 extern AppendMenuW_Proc unicode_append_menu
;
191 /* Flag to selectively ignore WM_IME_CHAR messages. */
192 static int ignore_ime_char
= 0;
194 /* W95 mousewheel handler */
195 unsigned int msh_mousewheel
= 0;
198 #define MOUSE_BUTTON_ID 1
199 #define MOUSE_MOVE_ID 2
200 #define MENU_FREE_ID 3
201 /* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
203 #define MENU_FREE_DELAY 1000
204 static unsigned menu_free_timer
= 0;
207 static ptrdiff_t image_cache_refcount
;
208 static int dpyinfo_refcount
;
211 static HWND w32_visible_system_caret_hwnd
;
213 static int w32_unicode_gui
;
216 int menubar_in_use
= 0;
218 /* From w32uniscribe.c */
219 extern void syms_of_w32uniscribe (void);
220 extern int uniscribe_available
;
223 /* From w32inevt.c */
224 extern int faked_key
;
225 #endif /* WINDOWSNT */
227 /* This gives us the page size and the size of the allocation unit on NT. */
228 SYSTEM_INFO sysinfo_cache
;
230 /* This gives us version, build, and platform identification. */
231 OSVERSIONINFO osinfo_cache
;
233 DWORD_PTR syspage_mask
= 0;
235 /* The major and minor versions of NT. */
236 int w32_major_version
;
237 int w32_minor_version
;
238 int w32_build_number
;
240 /* Distinguish between Windows NT and Windows 95. */
244 HINSTANCE hinst
= NULL
;
247 static unsigned int sound_type
= 0xFFFFFFFF;
248 #define MB_EMACS_SILENT (0xFFFFFFFF - 1)
250 /* Special virtual key code for indicating "any" key. */
253 #ifndef WM_WTSSESSION_CHANGE
254 /* 32-bit MinGW does not define these constants. */
255 # define WM_WTSSESSION_CHANGE 0x02B1
256 # define WTS_SESSION_LOCK 0x7
259 /* Keyboard hook state data. */
262 int hook_count
; /* counter, if several windows are created */
263 HHOOK hook
; /* hook handle */
264 HWND console
; /* console window handle */
266 int lwindown
; /* Left Windows key currently pressed (and hooked) */
267 int rwindown
; /* Right Windows key currently pressed (and hooked) */
268 int winsdown
; /* Number of handled keys currently pressed */
269 int send_win_up
; /* Pass through the keyup for this Windows key press? */
270 int suppress_lone
; /* Suppress simulated Windows keydown-keyup for this press? */
271 int winseen
; /* Windows keys seen during this press? */
273 char alt_hooked
[256]; /* hook Alt+[this key]? */
274 char lwin_hooked
[256]; /* hook left Win+[this key]? */
275 char rwin_hooked
[256]; /* hook right Win+[this key]? */
277 typedef HWND (WINAPI
*GetConsoleWindow_Proc
) (void);
279 typedef BOOL (WINAPI
*IsDebuggerPresent_Proc
) (void);
281 /* stdin, from w32console.c */
282 extern HANDLE keyboard_handle
;
284 /* Let the user specify a display with a frame.
285 nil stands for the selected frame--or, if that is not a w32 frame,
286 the first display on the list. */
288 struct w32_display_info
*
289 check_x_display_info (Lisp_Object object
)
293 struct frame
*sf
= XFRAME (selected_frame
);
295 if (FRAME_W32_P (sf
) && FRAME_LIVE_P (sf
))
296 return FRAME_DISPLAY_INFO (sf
);
298 return &one_w32_display_info
;
300 else if (TERMINALP (object
))
302 struct terminal
*t
= decode_live_terminal (object
);
304 if (t
->type
!= output_w32
)
305 error ("Terminal %d is not a W32 display", t
->id
);
307 return t
->display_info
.w32
;
309 else if (STRINGP (object
))
310 return x_display_info_for_name (object
);
315 CHECK_LIVE_FRAME (object
);
317 if (! FRAME_W32_P (f
))
318 error ("Non-W32 frame used");
319 return FRAME_DISPLAY_INFO (f
);
323 /* Return the Emacs frame-object corresponding to an w32 window.
324 It could be the frame's main window or an icon window. */
327 x_window_to_frame (struct w32_display_info
*dpyinfo
, HWND wdesc
)
329 Lisp_Object tail
, frame
;
332 FOR_EACH_FRAME (tail
, frame
)
335 if (!FRAME_W32_P (f
) || FRAME_DISPLAY_INFO (f
) != dpyinfo
)
338 if (FRAME_W32_WINDOW (f
) == wdesc
)
345 static Lisp_Object
unwind_create_frame (Lisp_Object
);
346 static void unwind_create_tip_frame (Lisp_Object
);
347 static void my_create_window (struct frame
*);
348 static void my_create_tip_window (struct frame
*);
350 /* TODO: Native Input Method support; see x_create_im. */
351 void x_set_foreground_color (struct frame
*, Lisp_Object
, Lisp_Object
);
352 void x_set_background_color (struct frame
*, Lisp_Object
, Lisp_Object
);
353 void x_set_mouse_color (struct frame
*, Lisp_Object
, Lisp_Object
);
354 void x_set_cursor_color (struct frame
*, Lisp_Object
, Lisp_Object
);
355 void x_set_border_color (struct frame
*, Lisp_Object
, Lisp_Object
);
356 void x_set_cursor_type (struct frame
*, Lisp_Object
, Lisp_Object
);
357 void x_set_icon_type (struct frame
*, Lisp_Object
, Lisp_Object
);
358 void x_set_icon_name (struct frame
*, Lisp_Object
, Lisp_Object
);
359 void x_explicitly_set_name (struct frame
*, Lisp_Object
, Lisp_Object
);
360 void x_set_title (struct frame
*, Lisp_Object
, Lisp_Object
);
363 /* Store the screen positions of frame F into XPTR and YPTR.
364 These are the positions of the containing window manager window,
365 not Emacs's own window. */
368 x_real_positions (struct frame
*f
, int *xptr
, int *yptr
)
373 /* Get the bounds of the WM window. */
374 GetWindowRect (FRAME_W32_WINDOW (f
), &rect
);
379 /* Convert (0, 0) in the client area to screen co-ordinates. */
380 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
386 /* Returns the window rectangle appropriate for the given fullscreen mode.
387 The normal rect parameter was the window's rectangle prior to entering
388 fullscreen mode. If multiple monitor support is available, the nearest
389 monitor to the window is chosen. */
392 w32_fullscreen_rect (HWND hwnd
, int fsmode
, RECT normal
, RECT
*rect
)
394 struct MONITOR_INFO mi
= { sizeof(mi
) };
395 if (monitor_from_window_fn
&& get_monitor_info_fn
)
398 monitor_from_window_fn (hwnd
, MONITOR_DEFAULT_TO_NEAREST
);
399 get_monitor_info_fn (monitor
, &mi
);
403 mi
.rcMonitor
.left
= 0;
404 mi
.rcMonitor
.top
= 0;
405 mi
.rcMonitor
.right
= GetSystemMetrics (SM_CXSCREEN
);
406 mi
.rcMonitor
.bottom
= GetSystemMetrics (SM_CYSCREEN
);
409 mi
.rcWork
.right
= GetSystemMetrics (SM_CXMAXIMIZED
);
410 mi
.rcWork
.bottom
= GetSystemMetrics (SM_CYMAXIMIZED
);
415 case FULLSCREEN_BOTH
:
416 rect
->left
= mi
.rcMonitor
.left
;
417 rect
->top
= mi
.rcMonitor
.top
;
418 rect
->right
= mi
.rcMonitor
.right
;
419 rect
->bottom
= mi
.rcMonitor
.bottom
;
421 case FULLSCREEN_WIDTH
:
422 rect
->left
= mi
.rcWork
.left
;
423 rect
->top
= normal
.top
;
424 rect
->right
= mi
.rcWork
.right
;
425 rect
->bottom
= normal
.bottom
;
427 case FULLSCREEN_HEIGHT
:
428 rect
->left
= normal
.left
;
429 rect
->top
= mi
.rcWork
.top
;
430 rect
->right
= normal
.right
;
431 rect
->bottom
= mi
.rcWork
.bottom
;
441 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color
,
442 Sw32_define_rgb_color
, 4, 4, 0,
443 doc
: /* Convert RGB numbers to a Windows color reference and associate with NAME.
444 This adds or updates a named color to `w32-color-map', making it
445 available for use. The original entry's RGB ref is returned, or nil
446 if the entry is new. */)
447 (Lisp_Object red
, Lisp_Object green
, Lisp_Object blue
, Lisp_Object name
)
450 Lisp_Object oldrgb
= Qnil
;
454 CHECK_NUMBER (green
);
458 XSETINT (rgb
, RGB (XUINT (red
), XUINT (green
), XUINT (blue
)));
462 /* replace existing entry in w32-color-map or add new entry. */
463 entry
= Fassoc (name
, Vw32_color_map
);
466 entry
= Fcons (name
, rgb
);
467 Vw32_color_map
= Fcons (entry
, Vw32_color_map
);
471 oldrgb
= Fcdr (entry
);
472 Fsetcdr (entry
, rgb
);
480 /* The default colors for the w32 color map */
481 typedef struct colormap_t
487 colormap_t w32_color_map
[] =
489 {"snow" , PALETTERGB (255,250,250)},
490 {"ghost white" , PALETTERGB (248,248,255)},
491 {"GhostWhite" , PALETTERGB (248,248,255)},
492 {"white smoke" , PALETTERGB (245,245,245)},
493 {"WhiteSmoke" , PALETTERGB (245,245,245)},
494 {"gainsboro" , PALETTERGB (220,220,220)},
495 {"floral white" , PALETTERGB (255,250,240)},
496 {"FloralWhite" , PALETTERGB (255,250,240)},
497 {"old lace" , PALETTERGB (253,245,230)},
498 {"OldLace" , PALETTERGB (253,245,230)},
499 {"linen" , PALETTERGB (250,240,230)},
500 {"antique white" , PALETTERGB (250,235,215)},
501 {"AntiqueWhite" , PALETTERGB (250,235,215)},
502 {"papaya whip" , PALETTERGB (255,239,213)},
503 {"PapayaWhip" , PALETTERGB (255,239,213)},
504 {"blanched almond" , PALETTERGB (255,235,205)},
505 {"BlanchedAlmond" , PALETTERGB (255,235,205)},
506 {"bisque" , PALETTERGB (255,228,196)},
507 {"peach puff" , PALETTERGB (255,218,185)},
508 {"PeachPuff" , PALETTERGB (255,218,185)},
509 {"navajo white" , PALETTERGB (255,222,173)},
510 {"NavajoWhite" , PALETTERGB (255,222,173)},
511 {"moccasin" , PALETTERGB (255,228,181)},
512 {"cornsilk" , PALETTERGB (255,248,220)},
513 {"ivory" , PALETTERGB (255,255,240)},
514 {"lemon chiffon" , PALETTERGB (255,250,205)},
515 {"LemonChiffon" , PALETTERGB (255,250,205)},
516 {"seashell" , PALETTERGB (255,245,238)},
517 {"honeydew" , PALETTERGB (240,255,240)},
518 {"mint cream" , PALETTERGB (245,255,250)},
519 {"MintCream" , PALETTERGB (245,255,250)},
520 {"azure" , PALETTERGB (240,255,255)},
521 {"alice blue" , PALETTERGB (240,248,255)},
522 {"AliceBlue" , PALETTERGB (240,248,255)},
523 {"lavender" , PALETTERGB (230,230,250)},
524 {"lavender blush" , PALETTERGB (255,240,245)},
525 {"LavenderBlush" , PALETTERGB (255,240,245)},
526 {"misty rose" , PALETTERGB (255,228,225)},
527 {"MistyRose" , PALETTERGB (255,228,225)},
528 {"white" , PALETTERGB (255,255,255)},
529 {"black" , PALETTERGB ( 0, 0, 0)},
530 {"dark slate gray" , PALETTERGB ( 47, 79, 79)},
531 {"DarkSlateGray" , PALETTERGB ( 47, 79, 79)},
532 {"dark slate grey" , PALETTERGB ( 47, 79, 79)},
533 {"DarkSlateGrey" , PALETTERGB ( 47, 79, 79)},
534 {"dim gray" , PALETTERGB (105,105,105)},
535 {"DimGray" , PALETTERGB (105,105,105)},
536 {"dim grey" , PALETTERGB (105,105,105)},
537 {"DimGrey" , PALETTERGB (105,105,105)},
538 {"slate gray" , PALETTERGB (112,128,144)},
539 {"SlateGray" , PALETTERGB (112,128,144)},
540 {"slate grey" , PALETTERGB (112,128,144)},
541 {"SlateGrey" , PALETTERGB (112,128,144)},
542 {"light slate gray" , PALETTERGB (119,136,153)},
543 {"LightSlateGray" , PALETTERGB (119,136,153)},
544 {"light slate grey" , PALETTERGB (119,136,153)},
545 {"LightSlateGrey" , PALETTERGB (119,136,153)},
546 {"gray" , PALETTERGB (190,190,190)},
547 {"grey" , PALETTERGB (190,190,190)},
548 {"light grey" , PALETTERGB (211,211,211)},
549 {"LightGrey" , PALETTERGB (211,211,211)},
550 {"light gray" , PALETTERGB (211,211,211)},
551 {"LightGray" , PALETTERGB (211,211,211)},
552 {"midnight blue" , PALETTERGB ( 25, 25,112)},
553 {"MidnightBlue" , PALETTERGB ( 25, 25,112)},
554 {"navy" , PALETTERGB ( 0, 0,128)},
555 {"navy blue" , PALETTERGB ( 0, 0,128)},
556 {"NavyBlue" , PALETTERGB ( 0, 0,128)},
557 {"cornflower blue" , PALETTERGB (100,149,237)},
558 {"CornflowerBlue" , PALETTERGB (100,149,237)},
559 {"dark slate blue" , PALETTERGB ( 72, 61,139)},
560 {"DarkSlateBlue" , PALETTERGB ( 72, 61,139)},
561 {"slate blue" , PALETTERGB (106, 90,205)},
562 {"SlateBlue" , PALETTERGB (106, 90,205)},
563 {"medium slate blue" , PALETTERGB (123,104,238)},
564 {"MediumSlateBlue" , PALETTERGB (123,104,238)},
565 {"light slate blue" , PALETTERGB (132,112,255)},
566 {"LightSlateBlue" , PALETTERGB (132,112,255)},
567 {"medium blue" , PALETTERGB ( 0, 0,205)},
568 {"MediumBlue" , PALETTERGB ( 0, 0,205)},
569 {"royal blue" , PALETTERGB ( 65,105,225)},
570 {"RoyalBlue" , PALETTERGB ( 65,105,225)},
571 {"blue" , PALETTERGB ( 0, 0,255)},
572 {"dodger blue" , PALETTERGB ( 30,144,255)},
573 {"DodgerBlue" , PALETTERGB ( 30,144,255)},
574 {"deep sky blue" , PALETTERGB ( 0,191,255)},
575 {"DeepSkyBlue" , PALETTERGB ( 0,191,255)},
576 {"sky blue" , PALETTERGB (135,206,235)},
577 {"SkyBlue" , PALETTERGB (135,206,235)},
578 {"light sky blue" , PALETTERGB (135,206,250)},
579 {"LightSkyBlue" , PALETTERGB (135,206,250)},
580 {"steel blue" , PALETTERGB ( 70,130,180)},
581 {"SteelBlue" , PALETTERGB ( 70,130,180)},
582 {"light steel blue" , PALETTERGB (176,196,222)},
583 {"LightSteelBlue" , PALETTERGB (176,196,222)},
584 {"light blue" , PALETTERGB (173,216,230)},
585 {"LightBlue" , PALETTERGB (173,216,230)},
586 {"powder blue" , PALETTERGB (176,224,230)},
587 {"PowderBlue" , PALETTERGB (176,224,230)},
588 {"pale turquoise" , PALETTERGB (175,238,238)},
589 {"PaleTurquoise" , PALETTERGB (175,238,238)},
590 {"dark turquoise" , PALETTERGB ( 0,206,209)},
591 {"DarkTurquoise" , PALETTERGB ( 0,206,209)},
592 {"medium turquoise" , PALETTERGB ( 72,209,204)},
593 {"MediumTurquoise" , PALETTERGB ( 72,209,204)},
594 {"turquoise" , PALETTERGB ( 64,224,208)},
595 {"cyan" , PALETTERGB ( 0,255,255)},
596 {"light cyan" , PALETTERGB (224,255,255)},
597 {"LightCyan" , PALETTERGB (224,255,255)},
598 {"cadet blue" , PALETTERGB ( 95,158,160)},
599 {"CadetBlue" , PALETTERGB ( 95,158,160)},
600 {"medium aquamarine" , PALETTERGB (102,205,170)},
601 {"MediumAquamarine" , PALETTERGB (102,205,170)},
602 {"aquamarine" , PALETTERGB (127,255,212)},
603 {"dark green" , PALETTERGB ( 0,100, 0)},
604 {"DarkGreen" , PALETTERGB ( 0,100, 0)},
605 {"dark olive green" , PALETTERGB ( 85,107, 47)},
606 {"DarkOliveGreen" , PALETTERGB ( 85,107, 47)},
607 {"dark sea green" , PALETTERGB (143,188,143)},
608 {"DarkSeaGreen" , PALETTERGB (143,188,143)},
609 {"sea green" , PALETTERGB ( 46,139, 87)},
610 {"SeaGreen" , PALETTERGB ( 46,139, 87)},
611 {"medium sea green" , PALETTERGB ( 60,179,113)},
612 {"MediumSeaGreen" , PALETTERGB ( 60,179,113)},
613 {"light sea green" , PALETTERGB ( 32,178,170)},
614 {"LightSeaGreen" , PALETTERGB ( 32,178,170)},
615 {"pale green" , PALETTERGB (152,251,152)},
616 {"PaleGreen" , PALETTERGB (152,251,152)},
617 {"spring green" , PALETTERGB ( 0,255,127)},
618 {"SpringGreen" , PALETTERGB ( 0,255,127)},
619 {"lawn green" , PALETTERGB (124,252, 0)},
620 {"LawnGreen" , PALETTERGB (124,252, 0)},
621 {"green" , PALETTERGB ( 0,255, 0)},
622 {"chartreuse" , PALETTERGB (127,255, 0)},
623 {"medium spring green" , PALETTERGB ( 0,250,154)},
624 {"MediumSpringGreen" , PALETTERGB ( 0,250,154)},
625 {"green yellow" , PALETTERGB (173,255, 47)},
626 {"GreenYellow" , PALETTERGB (173,255, 47)},
627 {"lime green" , PALETTERGB ( 50,205, 50)},
628 {"LimeGreen" , PALETTERGB ( 50,205, 50)},
629 {"yellow green" , PALETTERGB (154,205, 50)},
630 {"YellowGreen" , PALETTERGB (154,205, 50)},
631 {"forest green" , PALETTERGB ( 34,139, 34)},
632 {"ForestGreen" , PALETTERGB ( 34,139, 34)},
633 {"olive drab" , PALETTERGB (107,142, 35)},
634 {"OliveDrab" , PALETTERGB (107,142, 35)},
635 {"dark khaki" , PALETTERGB (189,183,107)},
636 {"DarkKhaki" , PALETTERGB (189,183,107)},
637 {"khaki" , PALETTERGB (240,230,140)},
638 {"pale goldenrod" , PALETTERGB (238,232,170)},
639 {"PaleGoldenrod" , PALETTERGB (238,232,170)},
640 {"light goldenrod yellow" , PALETTERGB (250,250,210)},
641 {"LightGoldenrodYellow" , PALETTERGB (250,250,210)},
642 {"light yellow" , PALETTERGB (255,255,224)},
643 {"LightYellow" , PALETTERGB (255,255,224)},
644 {"yellow" , PALETTERGB (255,255, 0)},
645 {"gold" , PALETTERGB (255,215, 0)},
646 {"light goldenrod" , PALETTERGB (238,221,130)},
647 {"LightGoldenrod" , PALETTERGB (238,221,130)},
648 {"goldenrod" , PALETTERGB (218,165, 32)},
649 {"dark goldenrod" , PALETTERGB (184,134, 11)},
650 {"DarkGoldenrod" , PALETTERGB (184,134, 11)},
651 {"rosy brown" , PALETTERGB (188,143,143)},
652 {"RosyBrown" , PALETTERGB (188,143,143)},
653 {"indian red" , PALETTERGB (205, 92, 92)},
654 {"IndianRed" , PALETTERGB (205, 92, 92)},
655 {"saddle brown" , PALETTERGB (139, 69, 19)},
656 {"SaddleBrown" , PALETTERGB (139, 69, 19)},
657 {"sienna" , PALETTERGB (160, 82, 45)},
658 {"peru" , PALETTERGB (205,133, 63)},
659 {"burlywood" , PALETTERGB (222,184,135)},
660 {"beige" , PALETTERGB (245,245,220)},
661 {"wheat" , PALETTERGB (245,222,179)},
662 {"sandy brown" , PALETTERGB (244,164, 96)},
663 {"SandyBrown" , PALETTERGB (244,164, 96)},
664 {"tan" , PALETTERGB (210,180,140)},
665 {"chocolate" , PALETTERGB (210,105, 30)},
666 {"firebrick" , PALETTERGB (178,34, 34)},
667 {"brown" , PALETTERGB (165,42, 42)},
668 {"dark salmon" , PALETTERGB (233,150,122)},
669 {"DarkSalmon" , PALETTERGB (233,150,122)},
670 {"salmon" , PALETTERGB (250,128,114)},
671 {"light salmon" , PALETTERGB (255,160,122)},
672 {"LightSalmon" , PALETTERGB (255,160,122)},
673 {"orange" , PALETTERGB (255,165, 0)},
674 {"dark orange" , PALETTERGB (255,140, 0)},
675 {"DarkOrange" , PALETTERGB (255,140, 0)},
676 {"coral" , PALETTERGB (255,127, 80)},
677 {"light coral" , PALETTERGB (240,128,128)},
678 {"LightCoral" , PALETTERGB (240,128,128)},
679 {"tomato" , PALETTERGB (255, 99, 71)},
680 {"orange red" , PALETTERGB (255, 69, 0)},
681 {"OrangeRed" , PALETTERGB (255, 69, 0)},
682 {"red" , PALETTERGB (255, 0, 0)},
683 {"hot pink" , PALETTERGB (255,105,180)},
684 {"HotPink" , PALETTERGB (255,105,180)},
685 {"deep pink" , PALETTERGB (255, 20,147)},
686 {"DeepPink" , PALETTERGB (255, 20,147)},
687 {"pink" , PALETTERGB (255,192,203)},
688 {"light pink" , PALETTERGB (255,182,193)},
689 {"LightPink" , PALETTERGB (255,182,193)},
690 {"pale violet red" , PALETTERGB (219,112,147)},
691 {"PaleVioletRed" , PALETTERGB (219,112,147)},
692 {"maroon" , PALETTERGB (176, 48, 96)},
693 {"medium violet red" , PALETTERGB (199, 21,133)},
694 {"MediumVioletRed" , PALETTERGB (199, 21,133)},
695 {"violet red" , PALETTERGB (208, 32,144)},
696 {"VioletRed" , PALETTERGB (208, 32,144)},
697 {"magenta" , PALETTERGB (255, 0,255)},
698 {"violet" , PALETTERGB (238,130,238)},
699 {"plum" , PALETTERGB (221,160,221)},
700 {"orchid" , PALETTERGB (218,112,214)},
701 {"medium orchid" , PALETTERGB (186, 85,211)},
702 {"MediumOrchid" , PALETTERGB (186, 85,211)},
703 {"dark orchid" , PALETTERGB (153, 50,204)},
704 {"DarkOrchid" , PALETTERGB (153, 50,204)},
705 {"dark violet" , PALETTERGB (148, 0,211)},
706 {"DarkViolet" , PALETTERGB (148, 0,211)},
707 {"blue violet" , PALETTERGB (138, 43,226)},
708 {"BlueViolet" , PALETTERGB (138, 43,226)},
709 {"purple" , PALETTERGB (160, 32,240)},
710 {"medium purple" , PALETTERGB (147,112,219)},
711 {"MediumPurple" , PALETTERGB (147,112,219)},
712 {"thistle" , PALETTERGB (216,191,216)},
713 {"gray0" , PALETTERGB ( 0, 0, 0)},
714 {"grey0" , PALETTERGB ( 0, 0, 0)},
715 {"dark grey" , PALETTERGB (169,169,169)},
716 {"DarkGrey" , PALETTERGB (169,169,169)},
717 {"dark gray" , PALETTERGB (169,169,169)},
718 {"DarkGray" , PALETTERGB (169,169,169)},
719 {"dark blue" , PALETTERGB ( 0, 0,139)},
720 {"DarkBlue" , PALETTERGB ( 0, 0,139)},
721 {"dark cyan" , PALETTERGB ( 0,139,139)},
722 {"DarkCyan" , PALETTERGB ( 0,139,139)},
723 {"dark magenta" , PALETTERGB (139, 0,139)},
724 {"DarkMagenta" , PALETTERGB (139, 0,139)},
725 {"dark red" , PALETTERGB (139, 0, 0)},
726 {"DarkRed" , PALETTERGB (139, 0, 0)},
727 {"light green" , PALETTERGB (144,238,144)},
728 {"LightGreen" , PALETTERGB (144,238,144)},
732 w32_default_color_map (void)
735 colormap_t
*pc
= w32_color_map
;
742 for (i
= 0; i
< ARRAYELTS (w32_color_map
); pc
++, i
++)
743 cmap
= Fcons (Fcons (build_string (pc
->name
),
744 make_number (pc
->colorref
)),
752 DEFUN ("w32-default-color-map", Fw32_default_color_map
, Sw32_default_color_map
,
753 0, 0, 0, doc
: /* Return the default color map. */)
756 return w32_default_color_map ();
760 w32_color_map_lookup (const char *colorname
)
762 Lisp_Object tail
, ret
= Qnil
;
766 for (tail
= Vw32_color_map
; CONSP (tail
); tail
= XCDR (tail
))
768 register Lisp_Object elt
, tem
;
771 if (!CONSP (elt
)) continue;
775 if (lstrcmpi (SSDATA (tem
), colorname
) == 0)
791 add_system_logical_colors_to_map (Lisp_Object
*system_colors
)
795 /* Other registry operations are done with input blocked. */
798 /* Look for "Control Panel/Colors" under User and Machine registry
800 if (RegOpenKeyEx (HKEY_CURRENT_USER
, "Control Panel\\Colors", 0,
801 KEY_READ
, &colors_key
) == ERROR_SUCCESS
802 || RegOpenKeyEx (HKEY_LOCAL_MACHINE
, "Control Panel\\Colors", 0,
803 KEY_READ
, &colors_key
) == ERROR_SUCCESS
)
806 char color_buffer
[64];
807 char full_name_buffer
[MAX_PATH
+ SYSTEM_COLOR_PREFIX_LEN
];
809 DWORD name_size
, color_size
;
810 char *name_buffer
= full_name_buffer
+ SYSTEM_COLOR_PREFIX_LEN
;
812 name_size
= sizeof (full_name_buffer
) - SYSTEM_COLOR_PREFIX_LEN
;
813 color_size
= sizeof (color_buffer
);
815 strcpy (full_name_buffer
, SYSTEM_COLOR_PREFIX
);
817 while (RegEnumValueA (colors_key
, index
, name_buffer
, &name_size
,
818 NULL
, NULL
, (LPBYTE
)color_buffer
, &color_size
)
822 if (sscanf (color_buffer
, " %u %u %u", &r
, &g
, &b
) == 3)
823 *system_colors
= Fcons (Fcons (build_string (full_name_buffer
),
824 make_number (RGB (r
, g
, b
))),
827 name_size
= sizeof (full_name_buffer
) - SYSTEM_COLOR_PREFIX_LEN
;
828 color_size
= sizeof (color_buffer
);
831 RegCloseKey (colors_key
);
839 x_to_w32_color (const char * colorname
)
841 register Lisp_Object ret
= Qnil
;
845 if (colorname
[0] == '#')
847 /* Could be an old-style RGB Device specification. */
848 int size
= strlen (colorname
+ 1);
849 char *color
= alloca (size
+ 1);
851 strcpy (color
, colorname
+ 1);
852 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
860 for (i
= 0; i
< 3; i
++)
866 /* The check for 'x' in the following conditional takes into
867 account the fact that strtol allows a "0x" in front of
868 our numbers, and we don't. */
869 if (!isxdigit (color
[0]) || color
[1] == 'x')
873 value
= strtoul (color
, &end
, 16);
875 if (errno
== ERANGE
|| end
- color
!= size
)
880 value
= value
* 0x10;
891 colorval
|= (value
<< pos
);
896 XSETINT (ret
, colorval
);
903 else if (strnicmp (colorname
, "rgb:", 4) == 0)
911 color
= colorname
+ 4;
912 for (i
= 0; i
< 3; i
++)
917 /* The check for 'x' in the following conditional takes into
918 account the fact that strtol allows a "0x" in front of
919 our numbers, and we don't. */
920 if (!isxdigit (color
[0]) || color
[1] == 'x')
922 value
= strtoul (color
, &end
, 16);
928 value
= value
* 0x10 + value
;
941 if (value
== ULONG_MAX
)
943 colorval
|= (value
<< pos
);
950 XSETINT (ret
, colorval
);
958 else if (strnicmp (colorname
, "rgbi:", 5) == 0)
960 /* This is an RGB Intensity specification. */
967 color
= colorname
+ 5;
968 for (i
= 0; i
< 3; i
++)
974 value
= strtod (color
, &end
);
977 if (value
< 0.0 || value
> 1.0)
979 val
= (UINT
)(0x100 * value
);
980 /* We used 0x100 instead of 0xFF to give a continuous
981 range between 0.0 and 1.0 inclusive. The next statement
982 fixes the 1.0 case. */
985 colorval
|= (val
<< pos
);
992 XSETINT (ret
, colorval
);
1000 /* I am not going to attempt to handle any of the CIE color schemes
1001 or TekHVC, since I don't know the algorithms for conversion to
1004 /* If we fail to lookup the color name in w32_color_map, then check the
1005 colorname to see if it can be crudely approximated: If the X color
1006 ends in a number (e.g., "darkseagreen2"), strip the number and
1007 return the result of looking up the base color name. */
1008 ret
= w32_color_map_lookup (colorname
);
1011 int len
= strlen (colorname
);
1013 if (isdigit (colorname
[len
- 1]))
1015 char *ptr
, *approx
= alloca (len
+ 1);
1017 strcpy (approx
, colorname
);
1018 ptr
= &approx
[len
- 1];
1019 while (ptr
> approx
&& isdigit (*ptr
))
1022 ret
= w32_color_map_lookup (approx
);
1031 w32_regenerate_palette (struct frame
*f
)
1033 struct w32_palette_entry
* list
;
1034 LOGPALETTE
* log_palette
;
1035 HPALETTE new_palette
;
1038 /* don't bother trying to create palette if not supported */
1039 if (! FRAME_DISPLAY_INFO (f
)->has_palette
)
1042 log_palette
= (LOGPALETTE
*)
1043 alloca (sizeof (LOGPALETTE
) +
1044 FRAME_DISPLAY_INFO (f
)->num_colors
* sizeof (PALETTEENTRY
));
1045 log_palette
->palVersion
= 0x300;
1046 log_palette
->palNumEntries
= FRAME_DISPLAY_INFO (f
)->num_colors
;
1048 list
= FRAME_DISPLAY_INFO (f
)->color_list
;
1050 i
< FRAME_DISPLAY_INFO (f
)->num_colors
;
1051 i
++, list
= list
->next
)
1052 log_palette
->palPalEntry
[i
] = list
->entry
;
1054 new_palette
= CreatePalette (log_palette
);
1058 if (FRAME_DISPLAY_INFO (f
)->palette
)
1059 DeleteObject (FRAME_DISPLAY_INFO (f
)->palette
);
1060 FRAME_DISPLAY_INFO (f
)->palette
= new_palette
;
1062 /* Realize display palette and garbage all frames. */
1063 release_frame_dc (f
, get_frame_dc (f
));
1068 #define W32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1069 #define SET_W32_COLOR(pe, color) \
1072 pe.peRed = GetRValue (color); \
1073 pe.peGreen = GetGValue (color); \
1074 pe.peBlue = GetBValue (color); \
1079 /* Keep these around in case we ever want to track color usage. */
1081 w32_map_color (struct frame
*f
, COLORREF color
)
1083 struct w32_palette_entry
* list
= FRAME_DISPLAY_INFO (f
)->color_list
;
1085 if (NILP (Vw32_enable_palette
))
1088 /* check if color is already mapped */
1091 if (W32_COLOR (list
->entry
) == color
)
1099 /* not already mapped, so add to list and recreate Windows palette */
1100 list
= xmalloc (sizeof (struct w32_palette_entry
));
1101 SET_W32_COLOR (list
->entry
, color
);
1103 list
->next
= FRAME_DISPLAY_INFO (f
)->color_list
;
1104 FRAME_DISPLAY_INFO (f
)->color_list
= list
;
1105 FRAME_DISPLAY_INFO (f
)->num_colors
++;
1107 /* set flag that palette must be regenerated */
1108 FRAME_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1112 w32_unmap_color (struct frame
*f
, COLORREF color
)
1114 struct w32_palette_entry
* list
= FRAME_DISPLAY_INFO (f
)->color_list
;
1115 struct w32_palette_entry
**prev
= &FRAME_DISPLAY_INFO (f
)->color_list
;
1117 if (NILP (Vw32_enable_palette
))
1120 /* check if color is already mapped */
1123 if (W32_COLOR (list
->entry
) == color
)
1125 if (--list
->refcount
== 0)
1129 FRAME_DISPLAY_INFO (f
)->num_colors
--;
1139 /* set flag that palette must be regenerated */
1140 FRAME_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1145 /* Gamma-correct COLOR on frame F. */
1148 gamma_correct (struct frame
*f
, COLORREF
*color
)
1152 *color
= PALETTERGB (
1153 pow (GetRValue (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5,
1154 pow (GetGValue (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5,
1155 pow (GetBValue (*color
) / 255.0, f
->gamma
) * 255.0 + 0.5);
1160 /* Decide if color named COLOR is valid for the display associated with
1161 the selected frame; if so, return the rgb values in COLOR_DEF.
1162 If ALLOC is nonzero, allocate a new colormap cell. */
1165 w32_defined_color (struct frame
*f
, const char *color
, XColor
*color_def
,
1168 register Lisp_Object tem
;
1169 COLORREF w32_color_ref
;
1171 tem
= x_to_w32_color (color
);
1177 /* Apply gamma correction. */
1178 w32_color_ref
= XUINT (tem
);
1179 gamma_correct (f
, &w32_color_ref
);
1180 XSETINT (tem
, w32_color_ref
);
1183 /* Map this color to the palette if it is enabled. */
1184 if (!NILP (Vw32_enable_palette
))
1186 struct w32_palette_entry
* entry
=
1187 one_w32_display_info
.color_list
;
1188 struct w32_palette_entry
** prev
=
1189 &one_w32_display_info
.color_list
;
1191 /* check if color is already mapped */
1194 if (W32_COLOR (entry
->entry
) == XUINT (tem
))
1196 prev
= &entry
->next
;
1197 entry
= entry
->next
;
1200 if (entry
== NULL
&& alloc_p
)
1202 /* not already mapped, so add to list */
1203 entry
= xmalloc (sizeof (struct w32_palette_entry
));
1204 SET_W32_COLOR (entry
->entry
, XUINT (tem
));
1207 one_w32_display_info
.num_colors
++;
1209 /* set flag that palette must be regenerated */
1210 one_w32_display_info
.regen_palette
= TRUE
;
1213 /* Ensure COLORREF value is snapped to nearest color in (default)
1214 palette by simulating the PALETTERGB macro. This works whether
1215 or not the display device has a palette. */
1216 w32_color_ref
= XUINT (tem
) | 0x2000000;
1218 color_def
->pixel
= w32_color_ref
;
1219 color_def
->red
= GetRValue (w32_color_ref
) * 256;
1220 color_def
->green
= GetGValue (w32_color_ref
) * 256;
1221 color_def
->blue
= GetBValue (w32_color_ref
) * 256;
1231 /* Given a string ARG naming a color, compute a pixel value from it
1232 suitable for screen F.
1233 If F is not a color screen, return DEF (default) regardless of what
1237 x_decode_color (struct frame
*f
, Lisp_Object arg
, int def
)
1243 if (strcmp (SSDATA (arg
), "black") == 0)
1244 return BLACK_PIX_DEFAULT (f
);
1245 else if (strcmp (SSDATA (arg
), "white") == 0)
1246 return WHITE_PIX_DEFAULT (f
);
1248 if ((FRAME_DISPLAY_INFO (f
)->n_planes
* FRAME_DISPLAY_INFO (f
)->n_cbits
) == 1)
1251 /* w32_defined_color is responsible for coping with failures
1252 by looking for a near-miss. */
1253 if (w32_defined_color (f
, SSDATA (arg
), &cdef
, true))
1256 /* defined_color failed; return an ultimate default. */
1262 /* Functions called only from `x_set_frame_param'
1263 to set individual parameters.
1265 If FRAME_W32_WINDOW (f) is 0,
1266 the frame is being created and its window does not exist yet.
1267 In that case, just record the parameter's new value
1268 in the standard place; do not attempt to change the window. */
1271 x_set_foreground_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1273 struct w32_output
*x
= f
->output_data
.w32
;
1274 PIX_TYPE fg
, old_fg
;
1276 fg
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1277 old_fg
= FRAME_FOREGROUND_PIXEL (f
);
1278 FRAME_FOREGROUND_PIXEL (f
) = fg
;
1280 if (FRAME_W32_WINDOW (f
) != 0)
1282 if (x
->cursor_pixel
== old_fg
)
1284 x
->cursor_pixel
= fg
;
1285 x
->cursor_gc
->background
= fg
;
1288 update_face_from_frame_parameter (f
, Qforeground_color
, arg
);
1289 if (FRAME_VISIBLE_P (f
))
1295 x_set_background_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1297 FRAME_BACKGROUND_PIXEL (f
)
1298 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1300 if (FRAME_W32_WINDOW (f
) != 0)
1302 SetWindowLong (FRAME_W32_WINDOW (f
), WND_BACKGROUND_INDEX
,
1303 FRAME_BACKGROUND_PIXEL (f
));
1305 update_face_from_frame_parameter (f
, Qbackground_color
, arg
);
1307 if (FRAME_VISIBLE_P (f
))
1313 x_set_mouse_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1316 Cursor cursor
, nontext_cursor
, mode_cursor
, hand_cursor
;
1321 if (!EQ (Qnil
, arg
))
1322 f
->output_data
.w32
->mouse_pixel
1323 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1324 mask_color
= FRAME_BACKGROUND_PIXEL (f
);
1326 /* Don't let pointers be invisible. */
1327 if (mask_color
== f
->output_data
.w32
->mouse_pixel
1328 && mask_color
== FRAME_BACKGROUND_PIXEL (f
))
1329 f
->output_data
.w32
->mouse_pixel
= FRAME_FOREGROUND_PIXEL (f
);
1331 #if 0 /* TODO : Mouse cursor customization. */
1334 /* It's not okay to crash if the user selects a screwy cursor. */
1335 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
1337 if (!EQ (Qnil
, Vx_pointer_shape
))
1339 CHECK_NUMBER (Vx_pointer_shape
);
1340 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
1343 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1344 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
1346 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1348 CHECK_NUMBER (Vx_nontext_pointer_shape
);
1349 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1350 XINT (Vx_nontext_pointer_shape
));
1353 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
1354 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1356 if (!EQ (Qnil
, Vx_hourglass_pointer_shape
))
1358 CHECK_NUMBER (Vx_hourglass_pointer_shape
);
1359 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1360 XINT (Vx_hourglass_pointer_shape
));
1363 hourglass_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_watch
);
1364 x_check_errors (FRAME_W32_DISPLAY (f
), "bad busy pointer cursor: %s");
1366 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1367 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1369 CHECK_NUMBER (Vx_mode_pointer_shape
);
1370 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1371 XINT (Vx_mode_pointer_shape
));
1374 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1375 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
1377 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1379 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
);
1381 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1382 XINT (Vx_sensitive_text_pointer_shape
));
1385 hand_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
1387 if (!NILP (Vx_window_horizontal_drag_shape
))
1389 CHECK_NUMBER (Vx_window_horizontal_drag_shape
);
1390 horizontal_drag_cursor
1391 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1392 XINT (Vx_window_horizontal_drag_shape
));
1395 horizontal_drag_cursor
1396 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_h_double_arrow
);
1398 if (!NILP (Vx_window_vertical_drag_shape
))
1400 CHECK_NUMBER (Vx_window_vertical_drag_shape
);
1401 vertical_drag_cursor
1402 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1403 XINT (Vx_window_vertical_drag_shape
));
1406 vertical_drag_cursor
1407 = XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_sb_v_double_arrow
);
1409 /* Check and report errors with the above calls. */
1410 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
1411 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
1414 XColor fore_color
, back_color
;
1416 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
1417 back_color
.pixel
= mask_color
;
1418 XQueryColor (FRAME_W32_DISPLAY (f
),
1419 DefaultColormap (FRAME_W32_DISPLAY (f
),
1420 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1422 XQueryColor (FRAME_W32_DISPLAY (f
),
1423 DefaultColormap (FRAME_W32_DISPLAY (f
),
1424 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1426 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
1427 &fore_color
, &back_color
);
1428 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
1429 &fore_color
, &back_color
);
1430 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
1431 &fore_color
, &back_color
);
1432 XRecolorCursor (FRAME_W32_DISPLAY (f
), hand_cursor
,
1433 &fore_color
, &back_color
);
1434 XRecolorCursor (FRAME_W32_DISPLAY (f
), hourglass_cursor
,
1435 &fore_color
, &back_color
);
1438 if (FRAME_W32_WINDOW (f
) != 0)
1439 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
1441 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
1442 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
1443 f
->output_data
.w32
->text_cursor
= cursor
;
1445 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
1446 && f
->output_data
.w32
->nontext_cursor
!= 0)
1447 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
1448 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
1450 if (hourglass_cursor
!= f
->output_data
.w32
->hourglass_cursor
1451 && f
->output_data
.w32
->hourglass_cursor
!= 0)
1452 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hourglass_cursor
);
1453 f
->output_data
.w32
->hourglass_cursor
= hourglass_cursor
;
1455 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
1456 && f
->output_data
.w32
->modeline_cursor
!= 0)
1457 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
1458 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
1460 if (hand_cursor
!= f
->output_data
.w32
->hand_cursor
1461 && f
->output_data
.w32
->hand_cursor
!= 0)
1462 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->hand_cursor
);
1463 f
->output_data
.w32
->hand_cursor
= hand_cursor
;
1465 XFlush (FRAME_W32_DISPLAY (f
));
1468 update_face_from_frame_parameter (f
, Qmouse_color
, arg
);
1473 x_set_cursor_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1475 unsigned long fore_pixel
, pixel
;
1477 if (!NILP (Vx_cursor_fore_pixel
))
1478 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1479 WHITE_PIX_DEFAULT (f
));
1481 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1483 pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1485 /* Make sure that the cursor color differs from the background color. */
1486 if (pixel
== FRAME_BACKGROUND_PIXEL (f
))
1488 pixel
= f
->output_data
.w32
->mouse_pixel
;
1489 if (pixel
== fore_pixel
)
1490 fore_pixel
= FRAME_BACKGROUND_PIXEL (f
);
1493 f
->output_data
.w32
->cursor_foreground_pixel
= fore_pixel
;
1494 f
->output_data
.w32
->cursor_pixel
= pixel
;
1496 if (FRAME_W32_WINDOW (f
) != 0)
1499 /* Update frame's cursor_gc. */
1500 f
->output_data
.w32
->cursor_gc
->foreground
= fore_pixel
;
1501 f
->output_data
.w32
->cursor_gc
->background
= pixel
;
1505 if (FRAME_VISIBLE_P (f
))
1507 x_update_cursor (f
, 0);
1508 x_update_cursor (f
, 1);
1512 update_face_from_frame_parameter (f
, Qcursor_color
, arg
);
1515 /* Set the border-color of frame F to pixel value PIX.
1516 Note that this does not fully take effect if done before
1520 x_set_border_pixel (struct frame
*f
, int pix
)
1523 f
->output_data
.w32
->border_pixel
= pix
;
1525 if (FRAME_W32_WINDOW (f
) != 0 && f
->border_width
> 0)
1527 if (FRAME_VISIBLE_P (f
))
1532 /* Set the border-color of frame F to value described by ARG.
1533 ARG can be a string naming a color.
1534 The border-color is used for the border that is drawn by the server.
1535 Note that this does not fully take effect if done before
1536 F has a window; it must be redone when the window is created. */
1539 x_set_border_color (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1544 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1545 x_set_border_pixel (f
, pix
);
1546 update_face_from_frame_parameter (f
, Qborder_color
, arg
);
1551 x_set_cursor_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1553 set_frame_cursor_types (f
, arg
);
1557 x_set_icon_type (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1561 if (NILP (arg
) && NILP (oldval
))
1564 if (STRINGP (arg
) && STRINGP (oldval
)
1565 && EQ (Fstring_equal (oldval
, arg
), Qt
))
1568 if (SYMBOLP (arg
) && SYMBOLP (oldval
) && EQ (arg
, oldval
))
1573 result
= x_bitmap_icon (f
, arg
);
1577 error ("No icon window available");
1584 x_set_icon_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1588 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
1591 else if (!NILP (arg
) || NILP (oldval
))
1594 fset_icon_name (f
, arg
);
1597 if (f
->output_data
.w32
->icon_bitmap
!= 0)
1602 result
= x_text_icon (f
,
1603 SSDATA ((!NILP (f
->icon_name
)
1612 error ("No icon window available");
1615 /* If the window was unmapped (and its icon was mapped),
1616 the new icon is not mapped, so map the window in its stead. */
1617 if (FRAME_VISIBLE_P (f
))
1619 #ifdef USE_X_TOOLKIT
1620 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
1622 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
1625 XFlush (FRAME_W32_DISPLAY (f
));
1631 x_clear_under_internal_border (struct frame
*f
)
1633 int border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
1635 /* Clear border if it's larger than before. */
1638 HDC hdc
= get_frame_dc (f
);
1639 int width
= FRAME_PIXEL_WIDTH (f
);
1640 int height
= FRAME_PIXEL_HEIGHT (f
);
1643 w32_clear_area (f
, hdc
, 0, FRAME_TOP_MARGIN_HEIGHT (f
), width
, border
);
1644 w32_clear_area (f
, hdc
, 0, 0, border
, height
);
1645 w32_clear_area (f
, hdc
, width
- border
, 0, border
, height
);
1646 w32_clear_area (f
, hdc
, 0, height
- border
, width
, border
);
1647 release_frame_dc (f
, hdc
);
1654 x_set_internal_border_width (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1658 CHECK_TYPE_RANGED_INTEGER (int, arg
);
1659 border
= max (XINT (arg
), 0);
1661 if (border
!= FRAME_INTERNAL_BORDER_WIDTH (f
))
1663 f
->internal_border_width
= border
;
1665 if (FRAME_X_WINDOW (f
) != 0)
1667 adjust_frame_size (f
, -1, -1, 3, false, Qinternal_border_width
);
1669 if (FRAME_VISIBLE_P (f
))
1670 x_clear_under_internal_border (f
);
1677 x_set_menu_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1681 /* Right now, menu bars don't work properly in minibuf-only frames;
1682 most of the commands try to apply themselves to the minibuffer
1683 frame itself, and get an error because you can't switch buffers
1684 in or split the minibuffer window. */
1685 if (FRAME_MINIBUF_ONLY_P (f
))
1688 if (INTEGERP (value
))
1689 nlines
= XINT (value
);
1693 FRAME_MENU_BAR_LINES (f
) = 0;
1694 FRAME_MENU_BAR_HEIGHT (f
) = 0;
1696 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
1699 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
1700 free_frame_menubar (f
);
1701 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
1703 /* Adjust the frame size so that the client (text) dimensions
1704 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
1705 set correctly. Note that we resize twice: The first time upon
1706 a request from the window manager who wants to keep the height
1707 of the outer rectangle (including decorations) unchanged, and a
1708 second time because we want to keep the height of the inner
1709 rectangle (without the decorations unchanged). */
1710 adjust_frame_size (f
, -1, -1, 2, true, Qmenu_bar_lines
);
1712 /* Not sure whether this is needed. */
1713 x_clear_under_internal_border (f
);
1718 /* Set the number of lines used for the tool bar of frame F to VALUE.
1719 VALUE not an integer, or < 0 means set the lines to zero. OLDVAL is
1720 the old number of tool bar lines (and is unused). This function may
1721 change the height of all windows on frame F to match the new tool bar
1722 height. By design, the frame's height doesn't change (but maybe it
1723 should if we don't get enough space otherwise). */
1726 x_set_tool_bar_lines (struct frame
*f
, Lisp_Object value
, Lisp_Object oldval
)
1730 /* Treat tool bars like menu bars. */
1731 if (FRAME_MINIBUF_ONLY_P (f
))
1734 /* Use VALUE only if an integer >= 0. */
1735 if (INTEGERP (value
) && XINT (value
) >= 0)
1736 nlines
= XFASTINT (value
);
1740 x_change_tool_bar_height (f
, nlines
* FRAME_LINE_HEIGHT (f
));
1744 /* Set the pixel height of the tool bar of frame F to HEIGHT. */
1746 x_change_tool_bar_height (struct frame
*f
, int height
)
1748 int unit
= FRAME_LINE_HEIGHT (f
);
1749 int old_height
= FRAME_TOOL_BAR_HEIGHT (f
);
1750 int lines
= (height
+ unit
- 1) / unit
;
1751 Lisp_Object fullscreen
;
1753 /* Make sure we redisplay all windows in this frame. */
1754 windows_or_buffers_changed
= 23;
1756 /* Recalculate tool bar and frame text sizes. */
1757 FRAME_TOOL_BAR_HEIGHT (f
) = height
;
1758 FRAME_TOOL_BAR_LINES (f
) = lines
;
1759 /* Store `tool-bar-lines' and `height' frame parameters. */
1760 store_frame_param (f
, Qtool_bar_lines
, make_number (lines
));
1761 store_frame_param (f
, Qheight
, make_number (FRAME_LINES (f
)));
1763 if (FRAME_W32_WINDOW (f
) && FRAME_TOOL_BAR_HEIGHT (f
) == 0)
1766 clear_current_matrices (f
);
1769 if ((height
< old_height
) && WINDOWP (f
->tool_bar_window
))
1770 clear_glyph_matrix (XWINDOW (f
->tool_bar_window
)->current_matrix
);
1772 /* Recalculate toolbar height. */
1773 f
->n_tool_bar_rows
= 0;
1775 && (!f
->after_make_frame
1776 || NILP (frame_inhibit_implied_resize
)
1777 || (CONSP (frame_inhibit_implied_resize
)
1778 && NILP (Fmemq (Qtool_bar_lines
, frame_inhibit_implied_resize
)))))
1779 f
->tool_bar_redisplayed
= f
->tool_bar_resized
= false;
1781 adjust_frame_size (f
, -1, -1,
1782 ((!f
->tool_bar_resized
1783 && (NILP (fullscreen
=
1784 get_frame_param (f
, Qfullscreen
))
1785 || EQ (fullscreen
, Qfullwidth
))) ? 1
1786 : (old_height
== 0 || height
== 0) ? 2
1788 false, Qtool_bar_lines
);
1790 f
->tool_bar_resized
= f
->tool_bar_redisplayed
;
1792 /* adjust_frame_size might not have done anything, garbage frame
1794 adjust_frame_glyphs (f
);
1795 SET_FRAME_GARBAGED (f
);
1796 if (FRAME_X_WINDOW (f
))
1797 x_clear_under_internal_border (f
);
1801 w32_set_title_bar_text (struct frame
*f
, Lisp_Object name
)
1803 if (FRAME_W32_WINDOW (f
))
1807 GUI_FN (SetWindowText
) (FRAME_W32_WINDOW (f
),
1808 GUI_SDATA (GUI_ENCODE_SYSTEM (name
)));
1810 /* The frame's title many times shows the name of the file
1811 visited in the selected window's buffer, so it makes sense to
1812 support non-ASCII characters outside of the current system
1813 codepage in the title. */
1814 if (w32_unicode_filenames
)
1816 Lisp_Object encoded_title
= ENCODE_UTF_8 (name
);
1818 int tlen
= pMultiByteToWideChar (CP_UTF8
, 0, SSDATA (encoded_title
),
1823 /* Windows truncates the title text beyond what fits on
1824 a single line, so we can limit the length to some
1825 reasonably large value, and use alloca. */
1828 title_w
= alloca ((tlen
+ 1) * sizeof (wchar_t));
1829 pMultiByteToWideChar (CP_UTF8
, 0, SSDATA (encoded_title
), -1,
1831 title_w
[tlen
] = L
'\0';
1832 SetWindowTextW (FRAME_W32_WINDOW (f
), title_w
);
1834 else /* Conversion to UTF-16 failed, so we punt. */
1835 SetWindowTextA (FRAME_W32_WINDOW (f
),
1836 SSDATA (ENCODE_SYSTEM (name
)));
1839 SetWindowTextA (FRAME_W32_WINDOW (f
), SSDATA (ENCODE_SYSTEM (name
)));
1845 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
1848 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1849 name; if NAME is a string, set F's name to NAME and set
1850 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1852 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1853 suggesting a new name, which lisp code should override; if
1854 F->explicit_name is set, ignore the new name; otherwise, set it. */
1857 x_set_name (struct frame
*f
, Lisp_Object name
, bool explicit)
1859 /* Make sure that requests from lisp code override requests from
1860 Emacs redisplay code. */
1863 /* If we're switching from explicit to implicit, we had better
1864 update the mode lines and thereby update the title. */
1865 if (f
->explicit_name
&& NILP (name
))
1866 update_mode_lines
= 25;
1868 f
->explicit_name
= ! NILP (name
);
1870 else if (f
->explicit_name
)
1873 /* If NAME is nil, set the name to the w32_id_name. */
1876 /* Check for no change needed in this very common case
1877 before we do any consing. */
1878 if (!strcmp (FRAME_DISPLAY_INFO (f
)->w32_id_name
,
1881 name
= build_string (FRAME_DISPLAY_INFO (f
)->w32_id_name
);
1884 CHECK_STRING (name
);
1886 /* Don't change the name if it's already NAME. */
1887 if (! NILP (Fstring_equal (name
, f
->name
)))
1890 fset_name (f
, name
);
1892 /* For setting the frame title, the title parameter should override
1893 the name parameter. */
1894 if (! NILP (f
->title
))
1897 w32_set_title_bar_text (f
, name
);
1900 /* This function should be called when the user's lisp code has
1901 specified a name for the frame; the name will override any set by the
1904 x_explicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1906 x_set_name (f
, arg
, true);
1909 /* This function should be called by Emacs redisplay code to set the
1910 name; names set this way will never override names set by the user's
1913 x_implicitly_set_name (struct frame
*f
, Lisp_Object arg
, Lisp_Object oldval
)
1915 x_set_name (f
, arg
, false);
1918 /* Change the title of frame F to NAME.
1919 If NAME is nil, use the frame name as the title. */
1922 x_set_title (struct frame
*f
, Lisp_Object name
, Lisp_Object old_name
)
1924 /* Don't change the title if it's already NAME. */
1925 if (EQ (name
, f
->title
))
1928 update_mode_lines
= 26;
1930 fset_title (f
, name
);
1935 w32_set_title_bar_text (f
, name
);
1939 x_set_scroll_bar_default_width (struct frame
*f
)
1941 int unit
= FRAME_COLUMN_WIDTH (f
);
1943 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = GetSystemMetrics (SM_CXVSCROLL
);
1944 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
1945 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + unit
- 1) / unit
;
1950 x_set_scroll_bar_default_height (struct frame
*f
)
1952 int unit
= FRAME_LINE_HEIGHT (f
);
1954 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = GetSystemMetrics (SM_CXHSCROLL
);
1955 FRAME_CONFIG_SCROLL_BAR_LINES (f
)
1956 = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) + unit
- 1) / unit
;
1959 /* Subroutines for creating a frame. */
1961 Cursor
w32_load_cursor (LPCTSTR
);
1964 w32_load_cursor (LPCTSTR name
)
1966 /* Try first to load cursor from application resource. */
1967 Cursor cursor
= LoadImage ((HINSTANCE
) GetModuleHandle (NULL
),
1968 name
, IMAGE_CURSOR
, 0, 0,
1969 LR_DEFAULTCOLOR
| LR_DEFAULTSIZE
| LR_SHARED
);
1972 /* Then try to load a shared predefined cursor. */
1973 cursor
= LoadImage (NULL
, name
, IMAGE_CURSOR
, 0, 0,
1974 LR_DEFAULTCOLOR
| LR_DEFAULTSIZE
| LR_SHARED
);
1979 static LRESULT CALLBACK
w32_wnd_proc (HWND
, UINT
, WPARAM
, LPARAM
);
1981 #define INIT_WINDOW_CLASS(WC) \
1982 (WC).style = CS_HREDRAW | CS_VREDRAW; \
1983 (WC).lpfnWndProc = (WNDPROC) w32_wnd_proc; \
1984 (WC).cbClsExtra = 0; \
1985 (WC).cbWndExtra = WND_EXTRA_BYTES; \
1986 (WC).hInstance = hinst; \
1987 (WC).hIcon = LoadIcon (hinst, EMACS_CLASS); \
1988 (WC).hCursor = w32_load_cursor (IDC_ARROW); \
1989 (WC).hbrBackground = NULL; \
1990 (WC).lpszMenuName = NULL; \
1993 w32_init_class (HINSTANCE hinst
)
1995 if (w32_unicode_gui
)
1998 INIT_WINDOW_CLASS(uwc
);
1999 uwc
.lpszClassName
= L
"Emacs";
2001 return RegisterClassW (&uwc
);
2006 INIT_WINDOW_CLASS(wc
);
2007 wc
.lpszClassName
= EMACS_CLASS
;
2009 return RegisterClassA (&wc
);
2014 w32_createvscrollbar (struct frame
*f
, struct scroll_bar
* bar
)
2016 return CreateWindow ("SCROLLBAR", "", SBS_VERT
| WS_CHILD
| WS_VISIBLE
,
2017 /* Position and size of scroll bar. */
2018 bar
->left
, bar
->top
, bar
->width
, bar
->height
,
2019 FRAME_W32_WINDOW (f
), NULL
, hinst
, NULL
);
2023 w32_createhscrollbar (struct frame
*f
, struct scroll_bar
* bar
)
2025 return CreateWindow ("SCROLLBAR", "", SBS_HORZ
| WS_CHILD
| WS_VISIBLE
,
2026 /* Position and size of scroll bar. */
2027 bar
->left
, bar
->top
, bar
->width
, bar
->height
,
2028 FRAME_W32_WINDOW (f
), NULL
, hinst
, NULL
);
2032 w32_createwindow (struct frame
*f
, int *coords
)
2039 rect
.left
= rect
.top
= 0;
2040 rect
.right
= FRAME_PIXEL_WIDTH (f
);
2041 rect
.bottom
= FRAME_PIXEL_HEIGHT (f
);
2043 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
,
2044 FRAME_EXTERNAL_MENU_BAR (f
));
2046 /* Do first time app init */
2048 w32_init_class (hinst
);
2050 if (f
->size_hint_flags
& USPosition
|| f
->size_hint_flags
& PPosition
)
2061 FRAME_W32_WINDOW (f
) = hwnd
2062 = CreateWindow (EMACS_CLASS
,
2064 f
->output_data
.w32
->dwStyle
| WS_CLIPCHILDREN
,
2066 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
2074 SetWindowLong (hwnd
, WND_FONTWIDTH_INDEX
, FRAME_COLUMN_WIDTH (f
));
2075 SetWindowLong (hwnd
, WND_LINEHEIGHT_INDEX
, FRAME_LINE_HEIGHT (f
));
2076 SetWindowLong (hwnd
, WND_BORDER_INDEX
, FRAME_INTERNAL_BORDER_WIDTH (f
));
2077 SetWindowLong (hwnd
, WND_VSCROLLBAR_INDEX
, FRAME_SCROLL_BAR_AREA_WIDTH (f
));
2078 SetWindowLong (hwnd
, WND_HSCROLLBAR_INDEX
, FRAME_SCROLL_BAR_AREA_HEIGHT (f
));
2079 SetWindowLong (hwnd
, WND_BACKGROUND_INDEX
, FRAME_BACKGROUND_PIXEL (f
));
2081 /* Enable drag-n-drop. */
2082 DragAcceptFiles (hwnd
, TRUE
);
2084 /* Do this to discard the default setting specified by our parent. */
2085 ShowWindow (hwnd
, SW_HIDE
);
2087 /* Update frame positions. */
2088 GetWindowRect (hwnd
, &rect
);
2089 f
->left_pos
= rect
.left
;
2090 f
->top_pos
= rect
.top
;
2095 my_post_msg (W32Msg
* wmsg
, HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
2097 wmsg
->msg
.hwnd
= hwnd
;
2098 wmsg
->msg
.message
= msg
;
2099 wmsg
->msg
.wParam
= wParam
;
2100 wmsg
->msg
.lParam
= lParam
;
2101 wmsg
->msg
.time
= GetMessageTime ();
2107 /* The Windows keyboard hook callback. */
2108 static LRESULT CALLBACK
2109 funhook (int code
, WPARAM w
, LPARAM l
)
2112 HWND focus
= GetFocus ();
2114 KBDLLHOOKSTRUCT
const *hs
= (KBDLLHOOKSTRUCT
*)l
;
2116 if (code
< 0 || (hs
->flags
& LLKHF_INJECTED
))
2117 return CallNextHookEx (0, code
, w
, l
);
2119 /* The keyboard hook sees keyboard input on all processes (except
2120 elevated ones, when Emacs itself is not elevated). As such,
2121 care must be taken to only filter out keyboard input when Emacs
2122 itself is on the foreground.
2124 GetFocus returns a non-NULL window if another application is active,
2125 and always for a console Emacs process. For a console Emacs, determine
2126 focus by checking if the current foreground window is the process's
2128 if (focus
== NULL
&& kbdhook
.console
!= NULL
)
2130 if (GetForegroundWindow () == kbdhook
.console
)
2132 focus
= kbdhook
.console
;
2137 /* First, check hooks for the left and right Windows keys. */
2138 if (hs
->vkCode
== VK_LWIN
|| hs
->vkCode
== VK_RWIN
)
2140 if (focus
!= NULL
&& (w
== WM_KEYDOWN
|| w
== WM_SYSKEYDOWN
))
2142 /* The key is being pressed in an Emacs window. */
2143 if (hs
->vkCode
== VK_LWIN
&& !kbdhook
.lwindown
)
2145 kbdhook
.lwindown
= 1;
2146 kbdhook
.winseen
= 1;
2149 else if (hs
->vkCode
== VK_RWIN
&& !kbdhook
.rwindown
)
2151 kbdhook
.rwindown
= 1;
2152 kbdhook
.winseen
= 1;
2155 /* Returning 1 here drops the keypress without further processing.
2156 If the keypress was allowed to go through, the normal Windows
2157 hotkeys would take over. */
2160 else if (kbdhook
.winsdown
> 0 && (w
== WM_KEYUP
|| w
== WM_SYSKEYUP
))
2162 /* A key that has been captured earlier is being released now. */
2163 if (hs
->vkCode
== VK_LWIN
&& kbdhook
.lwindown
)
2165 kbdhook
.lwindown
= 0;
2168 else if (hs
->vkCode
== VK_RWIN
&& kbdhook
.rwindown
)
2170 kbdhook
.rwindown
= 0;
2173 if (kbdhook
.winsdown
== 0 && kbdhook
.winseen
)
2175 if (!kbdhook
.suppress_lone
)
2177 /* The Windows key was pressed, then released,
2178 without any other key pressed simultaneously.
2179 Normally, this opens the Start menu, but the user
2180 can prevent this by setting the
2181 w32-pass-[lr]window-to-system variable to
2183 if ((hs
->vkCode
== VK_LWIN
&& !NILP (Vw32_pass_lwindow_to_system
)) ||
2184 (hs
->vkCode
== VK_RWIN
&& !NILP (Vw32_pass_rwindow_to_system
)))
2186 /* Not prevented - Simulate the keypress to the system. */
2187 memset (inputs
, 0, sizeof (inputs
));
2188 inputs
[0].type
= INPUT_KEYBOARD
;
2189 inputs
[0].ki
.wVk
= hs
->vkCode
;
2190 inputs
[0].ki
.wScan
= hs
->vkCode
;
2191 inputs
[0].ki
.dwFlags
= KEYEVENTF_EXTENDEDKEY
;
2192 inputs
[0].ki
.time
= 0;
2193 inputs
[1].type
= INPUT_KEYBOARD
;
2194 inputs
[1].ki
.wVk
= hs
->vkCode
;
2195 inputs
[1].ki
.wScan
= hs
->vkCode
;
2196 inputs
[1].ki
.dwFlags
2197 = KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
;
2198 inputs
[1].ki
.time
= 0;
2199 SendInput (2, inputs
, sizeof (INPUT
));
2201 else if (focus
!= NULL
)
2203 /* When not passed to system, must simulate privately to Emacs. */
2204 PostMessage (focus
, WM_SYSKEYDOWN
, hs
->vkCode
, 0);
2205 PostMessage (focus
, WM_SYSKEYUP
, hs
->vkCode
, 0);
2209 if (kbdhook
.winsdown
== 0)
2211 /* No Windows keys pressed anymore - clear the state flags. */
2212 kbdhook
.suppress_lone
= 0;
2213 kbdhook
.winseen
= 0;
2215 if (!kbdhook
.send_win_up
)
2217 /* Swallow this release message, as not to confuse
2218 applications who did not get to see the original
2219 WM_KEYDOWN message either. */
2222 kbdhook
.send_win_up
= 0;
2225 else if (kbdhook
.winsdown
> 0)
2227 /* Some other key was pressed while a captured Win key is down.
2228 This is either an Emacs registered hotkey combination, or a
2230 if ((kbdhook
.lwindown
&& kbdhook
.lwin_hooked
[hs
->vkCode
]) ||
2231 (kbdhook
.rwindown
&& kbdhook
.rwin_hooked
[hs
->vkCode
]))
2233 /* Hooked Win-x combination, do not pass the keypress to Windows. */
2234 kbdhook
.suppress_lone
= 1;
2236 else if (!kbdhook
.suppress_lone
)
2238 /* Unhooked S-x combination; simulate the combination now
2239 (will be seen by the system). */
2240 memset (inputs
, 0, sizeof (inputs
));
2241 inputs
[0].type
= INPUT_KEYBOARD
;
2242 inputs
[0].ki
.wVk
= kbdhook
.lwindown
? VK_LWIN
: VK_RWIN
;
2243 inputs
[0].ki
.wScan
= kbdhook
.lwindown
? VK_LWIN
: VK_RWIN
;
2244 inputs
[0].ki
.dwFlags
= KEYEVENTF_EXTENDEDKEY
;
2245 inputs
[0].ki
.time
= 0;
2246 inputs
[1].type
= INPUT_KEYBOARD
;
2247 inputs
[1].ki
.wVk
= hs
->vkCode
;
2248 inputs
[1].ki
.wScan
= hs
->scanCode
;
2249 inputs
[1].ki
.dwFlags
=
2250 (hs
->flags
& LLKHF_EXTENDED
) ? KEYEVENTF_EXTENDEDKEY
: 0;
2251 inputs
[1].ki
.time
= 0;
2252 SendInput (2, inputs
, sizeof (INPUT
));
2253 /* Stop processing of this Win sequence here; the
2254 corresponding keyup messages will come through the normal
2255 channel when the keys are released. */
2256 kbdhook
.suppress_lone
= 1;
2257 kbdhook
.send_win_up
= 1;
2258 /* Swallow the original keypress (as we want the Win key
2259 down message simulated above to precede this real message). */
2264 /* Next, handle the registered Alt-* combinations. */
2265 if ((w
== WM_SYSKEYDOWN
|| w
== WM_KEYDOWN
)
2266 && kbdhook
.alt_hooked
[hs
->vkCode
]
2268 && (GetAsyncKeyState (VK_MENU
) & 0x8000))
2270 /* Prevent the system from getting this Alt-* key - suppress the
2271 message and post as a normal keypress to Emacs. */
2276 rec
.EventType
= KEY_EVENT
;
2277 rec
.Event
.KeyEvent
.bKeyDown
= TRUE
;
2278 rec
.Event
.KeyEvent
.wVirtualKeyCode
= hs
->vkCode
;
2279 rec
.Event
.KeyEvent
.wVirtualScanCode
= hs
->scanCode
;
2280 rec
.Event
.KeyEvent
.uChar
.UnicodeChar
= 0;
2281 rec
.Event
.KeyEvent
.dwControlKeyState
=
2282 ((GetAsyncKeyState (VK_LMENU
) & 0x8000) ? LEFT_ALT_PRESSED
: 0)
2283 | ((GetAsyncKeyState (VK_RMENU
) & 0x8000) ? RIGHT_ALT_PRESSED
: 0)
2284 | ((GetAsyncKeyState (VK_LCONTROL
) & 0x8000) ? LEFT_CTRL_PRESSED
: 0)
2285 | ((GetAsyncKeyState (VK_RCONTROL
) & 0x8000) ? RIGHT_CTRL_PRESSED
: 0)
2286 | ((GetAsyncKeyState (VK_SHIFT
) & 0x8000) ? SHIFT_PRESSED
: 0)
2287 | ((hs
->flags
& LLKHF_EXTENDED
) ? ENHANCED_KEY
: 0);
2288 if (w32_console_unicode_input
)
2289 WriteConsoleInputW (keyboard_handle
, &rec
, 1, &n
);
2291 WriteConsoleInputA (keyboard_handle
, &rec
, 1, &n
);
2294 PostMessage (focus
, w
, hs
->vkCode
, 1 | (1<<29));
2298 /* The normal case - pass the message through. */
2299 return CallNextHookEx (0, code
, w
, l
);
2302 /* Set up the hook; can be called several times, with matching
2303 remove_w32_kbdhook calls. */
2305 setup_w32_kbdhook (void)
2307 kbdhook
.hook_count
++;
2309 /* This hook gets in the way of debugging, since when Emacs stops,
2310 its input thread stops, and there's nothing to process keyboard
2311 events, whereas this hook is global, and is invoked in the
2312 context of the thread that installed it. So we don't install the
2313 hook if the process is being debugged. */
2314 if (w32_kbdhook_active
)
2316 IsDebuggerPresent_Proc is_debugger_present
= (IsDebuggerPresent_Proc
)
2317 GetProcAddress (GetModuleHandle ("kernel32.dll"), "IsDebuggerPresent");
2318 if (is_debugger_present
&& is_debugger_present ())
2322 /* Hooking is only available on NT architecture systems, as
2323 indicated by the w32_kbdhook_active variable. */
2324 if (kbdhook
.hook_count
== 1 && w32_kbdhook_active
)
2326 /* Get the handle of the Emacs console window. As the
2327 GetConsoleWindow function is only available on Win2000+, a
2328 hackish workaround described in Microsoft KB article 124103
2329 (https://support.microsoft.com/en-us/kb/124103) is used for
2331 GetConsoleWindow_Proc get_console
= (GetConsoleWindow_Proc
)
2332 GetProcAddress (GetModuleHandle ("kernel32.dll"), "GetConsoleWindow");
2334 if (get_console
!= NULL
)
2335 kbdhook
.console
= get_console ();
2339 wchar_t *oldTitle
= malloc (1024 * sizeof(wchar_t));
2340 wchar_t newTitle
[64];
2343 CoCreateGuid (&guid
);
2344 StringFromGUID2 (&guid
, newTitle
, 64);
2345 if (newTitle
!= NULL
)
2347 GetConsoleTitleW (oldTitle
, 1024);
2348 SetConsoleTitleW (newTitle
);
2349 for (i
= 0; i
< 25; i
++)
2352 kbdhook
.console
= FindWindowW (NULL
, newTitle
);
2353 if (kbdhook
.console
!= NULL
)
2356 SetConsoleTitleW (oldTitle
);
2362 kbdhook
.hook
= SetWindowsHookEx (WH_KEYBOARD_LL
, funhook
,
2363 GetModuleHandle (NULL
), 0);
2367 /* Remove the hook. */
2369 remove_w32_kbdhook (void)
2371 kbdhook
.hook_count
--;
2372 if (kbdhook
.hook_count
== 0 && w32_kbdhook_active
)
2374 UnhookWindowsHookEx (kbdhook
.hook
);
2375 kbdhook
.hook
= NULL
;
2378 #endif /* WINDOWSNT */
2380 /* Mark a specific key combination as hooked, preventing it to be
2381 handled by the system. */
2383 hook_w32_key (int hook
, int modifier
, int vkey
)
2390 tbl
= kbdhook
.alt_hooked
;
2393 tbl
= kbdhook
.lwin_hooked
;
2396 tbl
= kbdhook
.rwin_hooked
;
2400 if (tbl
!= NULL
&& vkey
>= 0 && vkey
<= 255)
2402 /* VK_ANY hooks all keys for this modifier */
2404 memset (tbl
, (char)hook
, 256);
2406 tbl
[vkey
] = (char)hook
;
2407 /* Alt-<modifier>s should go through */
2408 kbdhook
.alt_hooked
[VK_MENU
] = 0;
2409 kbdhook
.alt_hooked
[VK_LMENU
] = 0;
2410 kbdhook
.alt_hooked
[VK_RMENU
] = 0;
2411 kbdhook
.alt_hooked
[VK_CONTROL
] = 0;
2412 kbdhook
.alt_hooked
[VK_LCONTROL
] = 0;
2413 kbdhook
.alt_hooked
[VK_RCONTROL
] = 0;
2414 kbdhook
.alt_hooked
[VK_SHIFT
] = 0;
2415 kbdhook
.alt_hooked
[VK_LSHIFT
] = 0;
2416 kbdhook
.alt_hooked
[VK_RSHIFT
] = 0;
2421 /* Check the current Win key pressed state. */
2423 check_w32_winkey_state (int vkey
)
2425 /* The hook code handles grabbing of the Windows keys and Alt-* key
2426 combinations reserved by the system. Handling Alt is a bit
2427 easier, as Windows intends Alt-* shortcuts for application use in
2428 Windows; hotkeys such as Alt-tab and Alt-escape are special
2429 cases. Win-* hotkeys, on the other hand, are primarily meant for
2432 As a result, when we want Emacs to be able to grab the Win-*
2433 keys, we must swallow all Win key presses in a low-level keyboard
2434 hook. Unfortunately, this means that the Emacs window procedure
2435 (and console input handler) never see the keypresses either.
2436 Thus, to check the modifier states properly, Emacs code must use
2437 the check_w32_winkey_state function that uses the flags directly
2438 updated by the hook callback. */
2442 return kbdhook
.lwindown
;
2444 return kbdhook
.rwindown
;
2448 #endif /* WINDOWSNT */
2450 /* Reset the keyboard hook state. Locking the workstation with Win-L
2451 leaves the Win key(s) "down" from the hook's point of view - the
2452 keyup event is never seen. Thus, this function must be called when
2453 the system is locked. */
2455 reset_w32_kbdhook_state (void)
2457 kbdhook
.lwindown
= 0;
2458 kbdhook
.rwindown
= 0;
2459 kbdhook
.winsdown
= 0;
2460 kbdhook
.send_win_up
= 0;
2461 kbdhook
.suppress_lone
= 0;
2462 kbdhook
.winseen
= 0;
2465 /* GetKeyState and MapVirtualKey on Windows 95 do not actually distinguish
2466 between left and right keys as advertised. We test for this
2467 support dynamically, and set a flag when the support is absent. If
2468 absent, we keep track of the left and right control and alt keys
2469 ourselves. This is particularly necessary on keyboards that rely
2470 upon the AltGr key, which is represented as having the left control
2471 and right alt keys pressed. For these keyboards, we need to know
2472 when the left alt key has been pressed in addition to the AltGr key
2473 so that we can properly support M-AltGr-key sequences (such as M-@
2474 on Swedish keyboards). */
2476 #define EMACS_LCONTROL 0
2477 #define EMACS_RCONTROL 1
2478 #define EMACS_LMENU 2
2479 #define EMACS_RMENU 3
2481 static int modifiers
[4];
2482 static int modifiers_recorded
;
2483 static int modifier_key_support_tested
;
2486 test_modifier_support (unsigned int wparam
)
2490 if (wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
)
2492 if (wparam
== VK_CONTROL
)
2502 if (!(GetKeyState (l
) & 0x8000) && !(GetKeyState (r
) & 0x8000))
2503 modifiers_recorded
= 1;
2505 modifiers_recorded
= 0;
2506 modifier_key_support_tested
= 1;
2510 record_keydown (unsigned int wparam
, unsigned int lparam
)
2514 if (!modifier_key_support_tested
)
2515 test_modifier_support (wparam
);
2517 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
2520 if (wparam
== VK_CONTROL
)
2521 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
2523 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
2529 record_keyup (unsigned int wparam
, unsigned int lparam
)
2533 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
2536 if (wparam
== VK_CONTROL
)
2537 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
2539 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
2544 /* Emacs can lose focus while a modifier key has been pressed. When
2545 it regains focus, be conservative and clear all modifiers since
2546 we cannot reconstruct the left and right modifier state. */
2548 reset_modifiers (void)
2552 if (GetFocus () == NULL
)
2553 /* Emacs doesn't have keyboard focus. Do nothing. */
2556 ctrl
= GetAsyncKeyState (VK_CONTROL
);
2557 alt
= GetAsyncKeyState (VK_MENU
);
2559 if (!(ctrl
& 0x08000))
2560 /* Clear any recorded control modifier state. */
2561 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
2563 if (!(alt
& 0x08000))
2564 /* Clear any recorded alt modifier state. */
2565 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
2567 /* Update the state of all modifier keys, because modifiers used in
2568 hot-key combinations can get stuck on if Emacs loses focus as a
2569 result of a hot-key being pressed. */
2573 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
2575 memset (keystate
, 0, sizeof (keystate
));
2576 GetKeyboardState (keystate
);
2577 keystate
[VK_SHIFT
] = CURRENT_STATE (VK_SHIFT
);
2578 keystate
[VK_CONTROL
] = CURRENT_STATE (VK_CONTROL
);
2579 keystate
[VK_LCONTROL
] = CURRENT_STATE (VK_LCONTROL
);
2580 keystate
[VK_RCONTROL
] = CURRENT_STATE (VK_RCONTROL
);
2581 keystate
[VK_MENU
] = CURRENT_STATE (VK_MENU
);
2582 keystate
[VK_LMENU
] = CURRENT_STATE (VK_LMENU
);
2583 keystate
[VK_RMENU
] = CURRENT_STATE (VK_RMENU
);
2584 keystate
[VK_LWIN
] = CURRENT_STATE (VK_LWIN
);
2585 keystate
[VK_RWIN
] = CURRENT_STATE (VK_RWIN
);
2586 keystate
[VK_APPS
] = CURRENT_STATE (VK_APPS
);
2587 SetKeyboardState (keystate
);
2591 /* Synchronize modifier state with what is reported with the current
2592 keystroke. Even if we cannot distinguish between left and right
2593 modifier keys, we know that, if no modifiers are set, then neither
2594 the left or right modifier should be set. */
2596 sync_modifiers (void)
2598 if (!modifiers_recorded
)
2601 if (!(GetKeyState (VK_CONTROL
) & 0x8000))
2602 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
2604 if (!(GetKeyState (VK_MENU
) & 0x8000))
2605 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
2609 modifier_set (int vkey
)
2611 /* Warning: The fact that VK_NUMLOCK is not treated as the other 2
2612 toggle keys is not an omission! If you want to add it, you will
2613 have to make changes in the default sub-case of the WM_KEYDOWN
2614 switch, because if the NUMLOCK modifier is set, the code there
2615 will directly convert any key that looks like an ASCII letter,
2616 and also downcase those that look like upper-case ASCII. */
2617 if (vkey
== VK_CAPITAL
)
2619 if (NILP (Vw32_enable_caps_lock
))
2622 return (GetKeyState (vkey
) & 0x1);
2624 if (vkey
== VK_SCROLL
)
2626 if (NILP (Vw32_scroll_lock_modifier
)
2627 /* w32-scroll-lock-modifier can be any non-nil value that is
2628 not one of the modifiers, in which case it shall be ignored. */
2629 || !( EQ (Vw32_scroll_lock_modifier
, Qhyper
)
2630 || EQ (Vw32_scroll_lock_modifier
, Qsuper
)
2631 || EQ (Vw32_scroll_lock_modifier
, Qmeta
)
2632 || EQ (Vw32_scroll_lock_modifier
, Qalt
)
2633 || EQ (Vw32_scroll_lock_modifier
, Qcontrol
)
2634 || EQ (Vw32_scroll_lock_modifier
, Qshift
)))
2637 return (GetKeyState (vkey
) & 0x1);
2640 if (w32_kbdhook_active
&& (vkey
== VK_LWIN
|| vkey
== VK_RWIN
))
2641 return check_w32_winkey_state (vkey
);
2644 if (!modifiers_recorded
)
2645 return (GetKeyState (vkey
) & 0x8000);
2650 return modifiers
[EMACS_LCONTROL
];
2652 return modifiers
[EMACS_RCONTROL
];
2654 return modifiers
[EMACS_LMENU
];
2656 return modifiers
[EMACS_RMENU
];
2658 return (GetKeyState (vkey
) & 0x8000);
2661 /* Convert between the modifier bits W32 uses and the modifier bits
2663 unsigned int w32_key_to_modifier (int);
2666 w32_key_to_modifier (int key
)
2668 Lisp_Object key_mapping
;
2673 key_mapping
= Vw32_lwindow_modifier
;
2676 key_mapping
= Vw32_rwindow_modifier
;
2679 key_mapping
= Vw32_apps_modifier
;
2682 key_mapping
= Vw32_scroll_lock_modifier
;
2688 /* NB. This code runs in the input thread, asynchronously to the lisp
2689 thread, so we must be careful to ensure access to lisp data is
2690 thread-safe. The following code is safe because the modifier
2691 variable values are updated atomically from lisp and symbols are
2692 not relocated by GC. Also, we don't have to worry about seeing GC
2694 if (EQ (key_mapping
, Qhyper
))
2695 return hyper_modifier
;
2696 if (EQ (key_mapping
, Qsuper
))
2697 return super_modifier
;
2698 if (EQ (key_mapping
, Qmeta
))
2699 return meta_modifier
;
2700 if (EQ (key_mapping
, Qalt
))
2701 return alt_modifier
;
2702 if (EQ (key_mapping
, Qctrl
))
2703 return ctrl_modifier
;
2704 if (EQ (key_mapping
, Qcontrol
)) /* synonym for ctrl */
2705 return ctrl_modifier
;
2706 if (EQ (key_mapping
, Qshift
))
2707 return shift_modifier
;
2709 /* Don't generate any modifier if not explicitly requested. */
2714 w32_get_modifiers (void)
2716 return ((modifier_set (VK_SHIFT
) ? shift_modifier
: 0) |
2717 (modifier_set (VK_CONTROL
) ? ctrl_modifier
: 0) |
2718 (modifier_set (VK_LWIN
) ? w32_key_to_modifier (VK_LWIN
) : 0) |
2719 (modifier_set (VK_RWIN
) ? w32_key_to_modifier (VK_RWIN
) : 0) |
2720 (modifier_set (VK_APPS
) ? w32_key_to_modifier (VK_APPS
) : 0) |
2721 (modifier_set (VK_SCROLL
) ? w32_key_to_modifier (VK_SCROLL
) : 0) |
2722 (modifier_set (VK_MENU
) ?
2723 ((NILP (Vw32_alt_is_meta
)) ? alt_modifier
: meta_modifier
) : 0));
2726 /* We map the VK_* modifiers into console modifier constants
2727 so that we can use the same routines to handle both console
2728 and window input. */
2731 construct_console_modifiers (void)
2736 mods
|= (modifier_set (VK_SHIFT
)) ? SHIFT_PRESSED
: 0;
2737 mods
|= (modifier_set (VK_CAPITAL
)) ? CAPSLOCK_ON
: 0;
2738 mods
|= (modifier_set (VK_SCROLL
)) ? SCROLLLOCK_ON
: 0;
2739 mods
|= (modifier_set (VK_NUMLOCK
)) ? NUMLOCK_ON
: 0;
2740 mods
|= (modifier_set (VK_LCONTROL
)) ? LEFT_CTRL_PRESSED
: 0;
2741 mods
|= (modifier_set (VK_RCONTROL
)) ? RIGHT_CTRL_PRESSED
: 0;
2742 mods
|= (modifier_set (VK_LMENU
)) ? LEFT_ALT_PRESSED
: 0;
2743 mods
|= (modifier_set (VK_RMENU
)) ? RIGHT_ALT_PRESSED
: 0;
2744 mods
|= (modifier_set (VK_LWIN
)) ? LEFT_WIN_PRESSED
: 0;
2745 mods
|= (modifier_set (VK_RWIN
)) ? RIGHT_WIN_PRESSED
: 0;
2746 mods
|= (modifier_set (VK_APPS
)) ? APPS_PRESSED
: 0;
2752 w32_get_key_modifiers (unsigned int wparam
, unsigned int lparam
)
2756 /* Convert to emacs modifiers. */
2757 mods
= w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam
);
2762 unsigned int map_keypad_keys (unsigned int, unsigned int);
2765 map_keypad_keys (unsigned int virt_key
, unsigned int extended
)
2767 if (virt_key
< VK_CLEAR
|| virt_key
> VK_DELETE
)
2770 if (virt_key
== VK_RETURN
)
2771 return (extended
? VK_NUMPAD_ENTER
: VK_RETURN
);
2773 if (virt_key
>= VK_PRIOR
&& virt_key
<= VK_DOWN
)
2774 return (!extended
? (VK_NUMPAD_PRIOR
+ (virt_key
- VK_PRIOR
)) : virt_key
);
2776 if (virt_key
== VK_INSERT
|| virt_key
== VK_DELETE
)
2777 return (!extended
? (VK_NUMPAD_INSERT
+ (virt_key
- VK_INSERT
)) : virt_key
);
2779 if (virt_key
== VK_CLEAR
)
2780 return (!extended
? VK_NUMPAD_CLEAR
: virt_key
);
2785 /* List of special key combinations which w32 would normally capture,
2786 but Emacs should grab instead. Not directly visible to lisp, to
2787 simplify synchronization. Each item is an integer encoding a virtual
2788 key code and modifier combination to capture.
2789 Note: This code is not used if keyboard hooks are active
2790 (Windows 2000 and later). */
2791 static Lisp_Object w32_grabbed_keys
;
2793 #define HOTKEY(vk, mods) make_number (((vk) & 255) | ((mods) << 8))
2794 #define HOTKEY_ID(k) (XFASTINT (k) & 0xbfff)
2795 #define HOTKEY_VK_CODE(k) (XFASTINT (k) & 255)
2796 #define HOTKEY_MODIFIERS(k) (XFASTINT (k) >> 8)
2798 #define RAW_HOTKEY_ID(k) ((k) & 0xbfff)
2799 #define RAW_HOTKEY_VK_CODE(k) ((k) & 255)
2800 #define RAW_HOTKEY_MODIFIERS(k) ((k) >> 8)
2802 /* Register hot-keys for reserved key combinations when Emacs has
2803 keyboard focus, since this is the only way Emacs can receive key
2804 combinations like Alt-Tab which are used by the system. */
2807 register_hot_keys (HWND hwnd
)
2809 Lisp_Object keylist
;
2811 /* Use CONSP, since we are called asynchronously. */
2812 for (keylist
= w32_grabbed_keys
; CONSP (keylist
); keylist
= XCDR (keylist
))
2814 Lisp_Object key
= XCAR (keylist
);
2816 /* Deleted entries get set to nil. */
2817 if (!INTEGERP (key
))
2820 RegisterHotKey (hwnd
, HOTKEY_ID (key
),
2821 HOTKEY_MODIFIERS (key
), HOTKEY_VK_CODE (key
));
2826 unregister_hot_keys (HWND hwnd
)
2828 Lisp_Object keylist
;
2830 for (keylist
= w32_grabbed_keys
; CONSP (keylist
); keylist
= XCDR (keylist
))
2832 Lisp_Object key
= XCAR (keylist
);
2834 if (!INTEGERP (key
))
2837 UnregisterHotKey (hwnd
, HOTKEY_ID (key
));
2843 w32_name_of_message (UINT msg
)
2846 static char buf
[64];
2847 static const struct {
2851 #define M(msg) { msg, # msg }
2859 M (WM_EMACS_CREATEWINDOW
),
2861 M (WM_EMACS_CREATEVSCROLLBAR
),
2862 M (WM_EMACS_CREATEHSCROLLBAR
),
2863 M (WM_EMACS_SHOWWINDOW
),
2864 M (WM_EMACS_SETWINDOWPOS
),
2865 M (WM_EMACS_DESTROYWINDOW
),
2866 M (WM_EMACS_TRACKPOPUPMENU
),
2867 M (WM_EMACS_SETFOCUS
),
2868 M (WM_EMACS_SETFOREGROUND
),
2869 M (WM_EMACS_SETLOCALE
),
2870 M (WM_EMACS_SETKEYBOARDLAYOUT
),
2871 M (WM_EMACS_REGISTER_HOT_KEY
),
2872 M (WM_EMACS_UNREGISTER_HOT_KEY
),
2873 M (WM_EMACS_TOGGLE_LOCK_KEY
),
2874 M (WM_EMACS_TRACK_CARET
),
2875 M (WM_EMACS_DESTROY_CARET
),
2876 M (WM_EMACS_SHOW_CARET
),
2877 M (WM_EMACS_HIDE_CARET
),
2878 M (WM_EMACS_SETCURSOR
),
2879 M (WM_EMACS_SHOWCURSOR
),
2886 for (i
= 0; msgnames
[i
].name
; ++i
)
2887 if (msgnames
[i
].msg
== msg
)
2888 return msgnames
[i
].name
;
2890 sprintf (buf
, "message 0x%04x", (unsigned)msg
);
2893 #endif /* EMACSDEBUG */
2895 /* Here's an overview of how Emacs input works in GUI sessions on
2896 MS-Windows. (For description of non-GUI input, see the commentary
2897 before w32_console_read_socket in w32inevt.c.)
2899 System messages are read and processed by w32_msg_pump below. This
2900 function runs in a separate thread. It handles a small number of
2901 custom WM_EMACS_* messages (posted by the main thread, look for
2902 PostMessage calls), and dispatches the rest to w32_wnd_proc, which
2903 is the main window procedure for the entire Emacs application.
2905 w32_wnd_proc also runs in the same separate input thread. It
2906 handles some messages, mostly those that need GDI calls, by itself.
2907 For the others, it calls my_post_msg, which inserts the messages
2908 into the input queue serviced by w32_read_socket.
2910 w32_read_socket runs in the main (a.k.a. "Lisp") thread, and is
2911 called synchronously from keyboard.c when it is known or suspected
2912 that some input is available. w32_read_socket either handles
2913 messages immediately, or converts them into Emacs input events and
2914 stuffs them into kbd_buffer, where kbd_buffer_get_event can get at
2915 them and process them when read_char and its callers require
2918 Under Cygwin with the W32 toolkit, the use of /dev/windows with
2919 select(2) takes the place of w32_read_socket.
2923 /* Main message dispatch loop. */
2926 w32_msg_pump (deferred_msg
* msg_buf
)
2932 msh_mousewheel
= RegisterWindowMessage (MSH_MOUSEWHEEL
);
2934 while ((w32_unicode_gui
? GetMessageW
: GetMessageA
) (&msg
, NULL
, 0, 0))
2937 /* DebPrint (("w32_msg_pump: %s time:%u\n", */
2938 /* w32_name_of_message (msg.message), msg.time)); */
2940 if (msg
.hwnd
== NULL
)
2942 switch (msg
.message
)
2945 /* Produced by complete_deferred_msg; just ignore. */
2947 case WM_EMACS_CREATEWINDOW
:
2948 /* Initialize COM for this window. Even though we don't use it,
2949 some third party shell extensions can cause it to be used in
2950 system dialogs, which causes a crash if it is not initialized.
2951 This is a known bug in Windows, which was fixed long ago, but
2952 the patch for XP is not publicly available until XP SP3,
2953 and older versions will never be patched. */
2954 CoInitialize (NULL
);
2955 w32_createwindow ((struct frame
*) msg
.wParam
,
2956 (int *) msg
.lParam
);
2957 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
2960 case WM_EMACS_SETLOCALE
:
2961 SetThreadLocale (msg
.wParam
);
2962 /* Reply is not expected. */
2964 case WM_EMACS_SETKEYBOARDLAYOUT
:
2965 result
= (WPARAM
) ActivateKeyboardLayout ((HKL
) msg
.wParam
, 0);
2966 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
2970 case WM_EMACS_REGISTER_HOT_KEY
:
2971 focus_window
= GetFocus ();
2972 if (focus_window
!= NULL
)
2973 RegisterHotKey (focus_window
,
2974 RAW_HOTKEY_ID (msg
.wParam
),
2975 RAW_HOTKEY_MODIFIERS (msg
.wParam
),
2976 RAW_HOTKEY_VK_CODE (msg
.wParam
));
2977 /* Reply is not expected. */
2979 case WM_EMACS_UNREGISTER_HOT_KEY
:
2980 focus_window
= GetFocus ();
2981 if (focus_window
!= NULL
)
2982 UnregisterHotKey (focus_window
, RAW_HOTKEY_ID (msg
.wParam
));
2983 /* Mark item as erased. NB: this code must be
2984 thread-safe. The next line is okay because the cons
2985 cell is never made into garbage and is not relocated by
2987 XSETCAR (make_lisp_ptr ((void *)msg
.lParam
, Lisp_Cons
), Qnil
);
2988 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
2991 case WM_EMACS_TOGGLE_LOCK_KEY
:
2993 int vk_code
= (int) msg
.wParam
;
2994 int cur_state
= (GetKeyState (vk_code
) & 1);
2995 int new_state
= msg
.lParam
;
2998 || ((new_state
& 1) != cur_state
))
3000 one_w32_display_info
.faked_key
= vk_code
;
3002 keybd_event ((BYTE
) vk_code
,
3003 (BYTE
) MapVirtualKey (vk_code
, 0),
3004 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3005 keybd_event ((BYTE
) vk_code
,
3006 (BYTE
) MapVirtualKey (vk_code
, 0),
3007 KEYEVENTF_EXTENDEDKEY
| 0, 0);
3008 keybd_event ((BYTE
) vk_code
,
3009 (BYTE
) MapVirtualKey (vk_code
, 0),
3010 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3011 cur_state
= !cur_state
;
3013 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
3019 /* Broadcast messages make it here, so you need to be looking
3020 for something in particular for this to be useful. */
3022 DebPrint (("msg %x not expected by w32_msg_pump\n", msg
.message
));
3028 if (w32_unicode_gui
)
3029 DispatchMessageW (&msg
);
3031 DispatchMessageA (&msg
);
3034 /* Exit nested loop when our deferred message has completed. */
3035 if (msg_buf
->completed
)
3040 deferred_msg
* deferred_msg_head
;
3042 static deferred_msg
*
3043 find_deferred_msg (HWND hwnd
, UINT msg
)
3045 deferred_msg
* item
;
3047 /* Don't actually need synchronization for read access, since
3048 modification of single pointer is always atomic. */
3049 /* enter_crit (); */
3051 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
3052 if (item
->w32msg
.msg
.hwnd
== hwnd
3053 && item
->w32msg
.msg
.message
== msg
)
3056 /* leave_crit (); */
3062 send_deferred_msg (deferred_msg
* msg_buf
,
3068 /* Only input thread can send deferred messages. */
3069 if (GetCurrentThreadId () != dwWindowsThreadId
)
3072 /* It is an error to send a message that is already deferred. */
3073 if (find_deferred_msg (hwnd
, msg
) != NULL
)
3076 /* Enforced synchronization is not needed because this is the only
3077 function that alters deferred_msg_head, and the following critical
3078 section is guaranteed to only be serially reentered (since only the
3079 input thread can call us). */
3081 /* enter_crit (); */
3083 msg_buf
->completed
= 0;
3084 msg_buf
->next
= deferred_msg_head
;
3085 deferred_msg_head
= msg_buf
;
3086 my_post_msg (&msg_buf
->w32msg
, hwnd
, msg
, wParam
, lParam
);
3088 /* leave_crit (); */
3090 /* Start a new nested message loop to process other messages until
3091 this one is completed. */
3092 w32_msg_pump (msg_buf
);
3094 deferred_msg_head
= msg_buf
->next
;
3096 return msg_buf
->result
;
3100 complete_deferred_msg (HWND hwnd
, UINT msg
, LRESULT result
)
3102 deferred_msg
* msg_buf
= find_deferred_msg (hwnd
, msg
);
3104 if (msg_buf
== NULL
)
3105 /* Message may have been canceled, so don't abort. */
3108 msg_buf
->result
= result
;
3109 msg_buf
->completed
= 1;
3111 /* Ensure input thread is woken so it notices the completion. */
3112 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
3116 cancel_all_deferred_msgs (void)
3118 deferred_msg
* item
;
3120 /* Don't actually need synchronization for read access, since
3121 modification of single pointer is always atomic. */
3122 /* enter_crit (); */
3124 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
3127 item
->completed
= 1;
3130 /* leave_crit (); */
3132 /* Ensure input thread is woken so it notices the completion. */
3133 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
3136 DWORD WINAPI
w32_msg_worker (void *);
3139 w32_msg_worker (void *arg
)
3142 deferred_msg dummy_buf
;
3144 /* Ensure our message queue is created */
3146 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
3148 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3151 memset (&dummy_buf
, 0, sizeof (dummy_buf
));
3152 dummy_buf
.w32msg
.msg
.hwnd
= NULL
;
3153 dummy_buf
.w32msg
.msg
.message
= WM_NULL
;
3155 /* This is the initial message loop which should only exit when the
3156 application quits. */
3157 w32_msg_pump (&dummy_buf
);
3163 signal_user_input (void)
3165 /* Interrupt any lisp that wants to be interrupted by input. */
3166 if (!NILP (Vthrow_on_input
))
3168 Vquit_flag
= Vthrow_on_input
;
3169 /* Doing a QUIT from this thread is a bad idea, since this
3170 unwinds the stack of the Lisp thread, and the Windows runtime
3171 rightfully barfs. Disabled. */
3173 /* If we're inside a function that wants immediate quits,
3175 if (immediate_quit
&& NILP (Vinhibit_quit
))
3186 post_character_message (HWND hwnd
, UINT msg
,
3187 WPARAM wParam
, LPARAM lParam
,
3192 wmsg
.dwModifiers
= modifiers
;
3194 /* Detect quit_char and set quit-flag directly. Note that we
3195 still need to post a message to ensure the main thread will be
3196 woken up if blocked in sys_select, but we do NOT want to post
3197 the quit_char message itself (because it will usually be as if
3198 the user had typed quit_char twice). Instead, we post a dummy
3199 message that has no particular effect. */
3202 if (isalpha (c
) && wmsg
.dwModifiers
== ctrl_modifier
)
3203 c
= make_ctrl_char (c
) & 0377;
3205 || (wmsg
.dwModifiers
== 0
3206 && w32_quit_key
&& wParam
== w32_quit_key
))
3210 /* The choice of message is somewhat arbitrary, as long as
3211 the main thread handler just ignores it. */
3214 /* Interrupt any blocking system calls. */
3217 /* As a safety precaution, forcibly complete any deferred
3218 messages. This is a kludge, but I don't see any particularly
3219 clean way to handle the situation where a deferred message is
3220 "dropped" in the lisp thread, and will thus never be
3221 completed, eg. by the user trying to activate the menubar
3222 when the lisp thread is busy, and then typing C-g when the
3223 menubar doesn't open promptly (with the result that the
3224 menubar never responds at all because the deferred
3225 WM_INITMENU message is never completed). Another problem
3226 situation is when the lisp thread calls SendMessage (to send
3227 a window manager command) when a message has been deferred;
3228 the lisp thread gets blocked indefinitely waiting for the
3229 deferred message to be completed, which itself is waiting for
3230 the lisp thread to respond.
3232 Note that we don't want to block the input thread waiting for
3233 a response from the lisp thread (although that would at least
3234 solve the deadlock problem above), because we want to be able
3235 to receive C-g to interrupt the lisp thread. */
3236 cancel_all_deferred_msgs ();
3239 signal_user_input ();
3242 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3246 get_wm_chars (HWND aWnd
, int *buf
, int buflen
, int ignore_ctrl
, int ctrl
,
3247 int *ctrl_cnt
, int *is_dead
, int vk
, int exp
)
3250 /* If doubled is at the end, ignore it. */
3251 int i
= buflen
, doubled
= 0, code_unit
;
3257 eassert (w32_unicode_gui
);
3259 /* Should be called only when w32_unicode_gui: */
3260 && PeekMessageW (&msg
, aWnd
, WM_KEYFIRST
, WM_KEYLAST
,
3261 PM_NOREMOVE
| PM_NOYIELD
)
3262 && (msg
.message
== WM_CHAR
|| msg
.message
== WM_SYSCHAR
3263 || msg
.message
== WM_DEADCHAR
|| msg
.message
== WM_SYSDEADCHAR
3264 || msg
.message
== WM_UNICHAR
))
3266 /* We extract character payload, but in this call we handle only the
3267 characters which come BEFORE the next keyup/keydown message. */
3270 GetMessageW (&msg
, aWnd
, msg
.message
, msg
.message
);
3271 dead
= (msg
.message
== WM_DEADCHAR
|| msg
.message
== WM_SYSDEADCHAR
);
3273 *is_dead
= (dead
? msg
.wParam
: -1);
3276 code_unit
= msg
.wParam
;
3279 /* Had surrogate. */
3280 if (msg
.message
== WM_UNICHAR
3281 || code_unit
< 0xDC00 || code_unit
> 0xDFFF)
3282 { /* Mismatched first surrogate.
3283 Pass both code units as if they were two characters. */
3286 return i
; /* Drop the 2nd char if at the end of the buffer. */
3288 else /* see https://en.wikipedia.org/wiki/UTF-16 */
3289 code_unit
= (doubled
<< 10) + code_unit
- 0x35FDC00;
3292 else if (code_unit
>= 0xD800 && code_unit
<= 0xDBFF)
3294 /* Handle mismatched 2nd surrogate the same as a normal character. */
3295 doubled
= code_unit
;
3299 /* The only "fake" characters delivered by ToUnicode() or
3300 TranslateMessage() are:
3301 0x01 .. 0x1a for Ctrl-letter, Enter, Tab, Ctrl-Break, Esc, Backspace
3302 0x00 and 0x1b .. 0x1f for Control- []\@^_
3303 0x7f for Control-BackSpace
3304 0x20 for Control-Space */
3306 && (code_unit
< 0x20 || code_unit
== 0x7f
3307 || (code_unit
== 0x20 && ctrl
)))
3309 /* Non-character payload in a WM_CHAR
3310 (Ctrl-something pressed, see above). Ignore, and report. */
3315 /* Traditionally, Emacs would ignore the character payload of VK_NUMPAD*
3316 keys, and would treat them later via `function-key-map'. In addition
3317 to usual 102-key NUMPAD keys, this map also treats `kp-'-variants of
3318 space, tab, enter, separator, equal. TAB and EQUAL, apparently,
3319 cannot be generated on Win-GUI branch. ENTER is already handled
3320 by the code above. According to `lispy_function_keys', kp_space is
3321 generated by not-extended VK_CLEAR. (kp-tab != VK_OEM_NEC_EQUAL!).
3323 We do similarly for backward-compatibility, but ignore only the
3324 characters restorable later by `function-key-map'. */
3325 if (code_unit
< 0x7f
3326 && ((vk
>= VK_NUMPAD0
&& vk
<= VK_DIVIDE
)
3327 || (exp
&& ((vk
>= VK_PRIOR
&& vk
<= VK_DOWN
) ||
3328 vk
== VK_INSERT
|| vk
== VK_DELETE
|| vk
== VK_CLEAR
)))
3329 && strchr ("0123456789/*-+.,", code_unit
))
3338 # define FPRINTF_WM_CHARS(ARG) fprintf ARG
3340 # define FPRINTF_WM_CHARS(ARG) (void)0
3343 /* This is a heuristic only. This is supposed to track the state of the
3344 finite automaton in the language environment of Windows.
3346 However, separate windows (if with the same different language
3347 environments!) should have different values. Moreover, switching to a
3348 non-Emacs window with the same language environment, and using (dead)keys
3349 there would change the value stored in the kernel, but not this value. */
3350 /* A layout may emit deadkey=0. It looks like this would reset the state
3351 of the kernel's finite automaton (equivalent to emiting 0-length string,
3352 which is otherwise impossible in the dead-key map of a layout).
3353 Be ready to treat the case when this delivers WM_(SYS)DEADCHAR. */
3354 static int after_deadkey
= -1;
3357 deliver_wm_chars (int do_translate
, HWND hwnd
, UINT msg
, UINT wParam
,
3358 UINT lParam
, int legacy_alt_meta
)
3360 /* An "old style" keyboard description may assign up to 125 UTF-16 code
3361 points to a keypress.
3362 (However, the "old style" TranslateMessage() would deliver at most 16 of
3363 them.) Be on a safe side, and prepare to treat many more. */
3364 int ctrl_cnt
, buf
[1024], count
, is_dead
, after_dead
= (after_deadkey
> 0);
3366 /* Since the keypress processing logic of Windows has a lot of state, it
3367 is important to call TranslateMessage() for every keyup/keydown, AND
3368 do it exactly once. (The actual change of state is done by
3369 ToUnicode[Ex](), which is called by TranslateMessage(). So one can
3370 call ToUnicode[Ex]() instead.)
3372 The "usual" message pump calls TranslateMessage() for EVERY event.
3373 Emacs calls TranslateMessage() very selectively (is it needed for doing
3374 some tricky stuff with Win95??? With newer Windows, selectiveness is,
3375 most probably, not needed -- and harms a lot).
3377 So, with the usual message pump, the following call to TranslateMessage()
3378 is not needed (and is going to be VERY harmful). With Emacs' message
3379 pump, the call is needed. */
3382 MSG windows_msg
= { hwnd
, msg
, wParam
, lParam
, 0, {0,0} };
3384 windows_msg
.time
= GetMessageTime ();
3385 TranslateMessage (&windows_msg
);
3387 count
= get_wm_chars (hwnd
, buf
, sizeof (buf
)/sizeof (*buf
), 1,
3388 /* The message may have been synthesized by
3389 who knows what; be conservative. */
3390 modifier_set (VK_LCONTROL
)
3391 || modifier_set (VK_RCONTROL
)
3392 || modifier_set (VK_CONTROL
),
3393 &ctrl_cnt
, &is_dead
, wParam
,
3394 (lParam
& 0x1000000L
) != 0);
3398 DWORD console_modifiers
= construct_console_modifiers ();
3399 int *b
= buf
, strip_ExtraMods
= 1, hairy
= 0;
3400 const char *type_CtrlAlt
= NULL
;
3402 /* XXXX In fact, there may be another case when we need to do the same:
3403 What happens if the string defined in the LIGATURES has length
3404 0? Probably, we will get count==0, but the state of the finite
3405 automaton would reset to 0??? */
3408 /* wParam is checked when converting CapsLock to Shift; this is a clone
3409 of w32_get_key_modifiers (). */
3410 wmsg
.dwModifiers
= w32_kbd_mods_to_emacs (console_modifiers
, wParam
);
3412 /* What follows is just heuristics; the correct treatement requires
3413 non-destructive ToUnicode():
3414 http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Can_an_application_on_Windows_accept_keyboard_events?_Part_IV:_application-specific_modifiers
3416 What one needs to find is:
3417 * which of the present modifiers AFFECT the resulting char(s)
3418 (so should be stripped, since their EFFECT is "already
3419 taken into account" in the string in buf), and
3420 * which modifiers are not affecting buf, so should be reported to
3421 the application for further treatment.
3423 Example: assume that we know:
3424 (A) lCtrl+rCtrl+rAlt modifiers with VK_A key produce a Latin "f"
3425 ("may be logical" in JCUKEN-flavored Russian keyboard flavors);
3426 (B) removing any of lCtrl, rCtrl, rAlt changes the produced char;
3427 (C) Win-modifier is not affecting the produced character
3428 (this is the common case: happens with all "standard" layouts).
3430 Suppose the user presses Win+lCtrl+rCtrl+rAlt modifiers with VK_A.
3431 What is the intent of the user? We need to guess the intent to decide
3432 which event to deliver to the application.
3434 This looks like a reasonable logic: since Win- modifier doesn't affect
3435 the output string, the user was pressing Win for SOME OTHER purpose.
3436 So the user wanted to generate Win-SOMETHING event. Now, what is
3437 something? If one takes the mantra that "character payload is more
3438 important than the combination of keypresses which resulted in this
3439 payload", then one should ignore lCtrl+rCtrl+rAlt, ignore VK_A, and
3440 assume that the user wanted to generate Win-f.
3442 Unfortunately, without non-destructive ToUnicode(), checking (B),(C)
3443 is out of question. So we use heuristics (hopefully, covering
3444 99.9999% of cases). */
3446 /* Another thing to watch for is a possibility to use AltGr-* and
3447 Ctrl-Alt-* with different semantic.
3449 Background: the layout defining the KLLF_ALTGR bit are treated
3450 specially by the kernel: when VK_RMENU (=rightAlt, =AltGr) is pressed
3451 (released), a press (release) of VK_LCONTROL is emulated (unless Ctrl
3452 is already down). As a result, any press/release of AltGr is seen
3453 by applications as a press/release of lCtrl AND rAlt. This is
3454 applicable, in particular, to ToUnicode[Ex](). (Keyrepeat is covered
3457 NOTE: it IS possible to see bare rAlt even with KLLF_ALTGR; but this
3458 requires a good finger coordination: doing (physically)
3459 Down-lCtrl Down-rAlt Up-lCtrl Down-a
3460 (doing quick enough, so that key repeat of rAlt [which would
3461 generate new "fake" Down-lCtrl events] does not happens before 'a'
3462 is down) results in no "fake" events, so the application will see
3463 only rAlt down when 'a' is pressed. (However, fake Up-lCtrl WILL
3464 be generated when rAlt goes UP.)
3466 In fact, note also that KLLF_ALTGR does not prohibit construction of
3467 rCtrl-rAlt (just press them in this order!).
3469 Moreover: "traditional" layouts do not define distinct modifier-masks
3470 for VK_LMENU and VK_RMENU (same for VK_L/RCONTROL). Instead, they
3471 rely on the KLLF_ALTGR bit to make the behavior of VK_LMENU and
3472 VK_RMENU distinct. As a corollary, for such layouts, the produced
3473 character is the same for AltGr-* (=rAlt-*) and Ctrl-Alt-* (in any
3474 combination of handedness). For description of masks, see
3476 http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Keyboard_input_on_Windows,_Part_I:_what_is_the_kernel_doing?
3478 By default, Emacs was using these coincidences via the following
3479 heuristics: it was treating:
3480 (*) keypresses with lCtrl-rAlt modifiers as if they are carrying
3481 ONLY the character payload (no matter what the actual keyboard
3482 was defining: if lCtrl-lAlt-b was delivering U+05df=beta, then
3483 Emacs saw [beta]; if lCtrl-lAlt-b was undefined in the layout,
3484 the keypress was completely ignored), and
3485 (*) keypresses with the other combinations of handedness of Ctrl-Alt
3486 modifiers (e.g., lCtrl-lAlt) as if they NEVER carry a character
3487 payload (so they were reported "raw": if lCtrl-lAlt-b was
3488 delivering beta, then Emacs saw event [C-A-b], and not [beta]).
3489 This worked good for "traditional" layouts: users could type both
3490 AltGr-x and Ctrl-Alt-x, and one was a character, another a bindable
3493 However, for layouts which deliver different characters for AltGr-x
3494 and lCtrl-lAlt-x, this scheme makes the latter character unaccessible
3495 in Emacs. While it is easy to access functionality of [C-M-x] in
3496 Emacs by other means (for example, by the `controlify' prefix, or
3497 using lCtrl-rCtrl-x, or rCtrl-rAlt-x [in this order]), missing
3498 characters cannot be reconstructed without a tedious manual work. */
3500 /* These two cases are often going to be distinguishable, since at most
3501 one of these character is defined with KBDCTRL | KBDMENU modifier
3502 bitmap. (This heuristic breaks if both lCtrl-lAlt- AND lCtrl-rAlt-
3503 are translated to modifier bitmaps distinct from KBDCTRL | KBDMENU,
3504 or in the cases when lCtrl-lAlt-* and lCtrl-rAlt-* are generally
3505 different, but lCtrl-lAlt-x and lCtrl-rAlt-x happen to deliver the
3508 So we have 2 chunks of info:
3509 (A) is it lCtrl-rAlt-, or lCtrl-lAlt, or some other combination?
3510 (B) is the delivered character defined with KBDCTRL | KBDMENU bits?
3511 Basing on (A) and (B), we should decide whether to ignore the
3512 delivered character. (Before, Emacs was completely ignoring (B), and
3513 was treating the 3-state of (A) as a bit.) This means that we have 6
3514 bits of customization.
3516 Additionally, a presence of two Ctrl down may be AltGr-rCtrl-. */
3518 /* Strip all non-Shift modifiers if:
3519 - more than one UTF-16 code point delivered (can't call VkKeyScanW ())
3520 - or the character is a result of combining with a prefix key. */
3521 if (!after_dead
&& count
== 1 && *b
< 0x10000)
3523 if (console_modifiers
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
)
3524 && console_modifiers
& (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
3526 type_CtrlAlt
= "bB"; /* generic bindable Ctrl-Alt- modifiers */
3527 if ((console_modifiers
& (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
3528 == (LEFT_CTRL_PRESSED
| RIGHT_CTRL_PRESSED
))
3530 e.g. AltGr-rCtrl on some layouts (in this order!) */
3531 type_CtrlAlt
= "dD";
3532 else if ((console_modifiers
3533 & (LEFT_CTRL_PRESSED
| LEFT_ALT_PRESSED
))
3534 == (LEFT_CTRL_PRESSED
| LEFT_ALT_PRESSED
))
3535 type_CtrlAlt
= "lL"; /* Ctrl-Alt- modifiers on the left */
3536 else if (!NILP (Vw32_recognize_altgr
)
3537 && ((console_modifiers
3538 & (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
)))
3539 == (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
))
3540 type_CtrlAlt
= "gG"; /* modifiers as in AltGr */
3542 else if (wmsg
.dwModifiers
& (alt_modifier
| meta_modifier
)
3543 || ((console_modifiers
3544 & (LEFT_WIN_PRESSED
| RIGHT_WIN_PRESSED
3545 | APPS_PRESSED
| SCROLLLOCK_ON
))))
3547 /* Pure Alt (or combination of Alt, Win, APPS, scrolllock. */
3548 type_CtrlAlt
= "aA";
3552 /* Out of bound bitmap: */
3553 SHORT r
= VkKeyScanW (*b
), bitmap
= 0x1FF;
3555 FPRINTF_WM_CHARS((stderr
, "VkKeyScanW %#06x %#04x\n", (int)r
,
3557 if ((r
& 0xFF) == wParam
)
3558 bitmap
= r
>>8; /* *b is reachable via simple interface */
3561 /* VkKeyScanW() (essentially) returns the FIRST key with
3562 the specified character; so here the pressed key is the
3563 SECONDARY key producing the character.
3565 Essentially, we have no information about the "role" of
3566 modifiers on this key: which contribute into the
3567 produced character (so "are consumed"), and which are
3568 "extra" (must attache to bindable events).
3570 The default above would consume ALL modifiers, so the
3571 character is reported "as is". However, on many layouts
3572 the ordering of the keys (in the layout table) is not
3573 thought out well, so the "secondary" keys are often those
3574 which the users would prefer to use with Alt-CHAR.
3575 (Moreover - with e.g. Czech-QWERTY - the ASCII
3576 punctuation is accessible from two equally [nu]preferable
3579 SO: Heuristic: if the reported char is ASCII, AND Meta
3580 modifier is a candidate, behave as if Meta is present
3581 (fallback to the legacy branch; bug#23251).
3583 (This would break layouts
3584 - delivering ASCII characters
3586 - with not Shift/AltGr-like modifier combinations.
3587 All 3 conditions together must be pretty exotic
3588 cases - and a workaround exists: use "primary" keys!) */
3590 && (wmsg
.dwModifiers
3591 & (alt_modifier
| meta_modifier
3592 | super_modifier
| hyper_modifier
)))
3595 if (*type_CtrlAlt
== 'a') /* Simple Alt seen */
3597 if ((bitmap
& ~1) == 0) /* 1: KBDSHIFT */
3599 /* In "traditional" layouts, Alt without Ctrl does not
3600 change the delivered character. This detects this
3601 situation; it is safe to report this as Alt-something
3602 -- as opposed to delivering the reported character
3603 without modifiers. */
3605 && *b
> 0x7f && ('A' <= wParam
&& wParam
<= 'Z'))
3606 /* For backward-compatibility with older Emacsen, let
3607 this be processed by another branch below (which
3608 would convert it to Alt-Latin char via wParam). */
3614 /* Check whether the delivered character(s) is accessible via
3615 KBDCTRL | KBDALT ( | KBDSHIFT ) modifier mask (which is 7). */
3616 else if ((bitmap
& ~1) != 6)
3618 /* The character is not accessible via plain Ctrl-Alt(-Shift)
3619 (which is, probably, same as AltGr) modifiers.
3620 Either it was after a prefix key, or is combined with
3621 modifier keys which we don't see, or there is an asymmetry
3622 between left-hand and right-hand modifiers, or other hairy
3626 /* The best solution is to delegate these tough (but rarely
3627 needed) choices to the user. Temporarily (???), it is
3628 implemented as C macros.
3630 Essentially, there are 3 things to do: return 0 (handle to the
3631 legacy processing code [ignoring the character payload]; keep
3632 some modifiers (so that they will be processed by the binding
3633 system [on top of the character payload]; strip modifiers [so
3634 that `self-insert' is going to be triggered with the character
3637 The default below should cover 99.9999% of cases:
3638 (a) strip Alt- in the hairy case only;
3639 (stripping = not ignoring)
3640 (l) for lAlt-lCtrl, ignore the char in simple cases only;
3641 (g) for what looks like AltGr, ignore the modifiers;
3642 (d) for what looks like lCtrl-rCtrl-Alt (probably
3643 AltGr-rCtrl), ignore the character in simple cases only;
3644 (b) for other cases of Ctrl-Alt, ignore the character in
3647 Essentially, in all hairy cases, and in looks-like-AltGr case,
3648 we keep the character, ignoring the modifiers. In all the
3649 other cases, we ignore the delivered character. */
3650 #define S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD "aldb"
3651 #define S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS ""
3652 if (strchr (S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD
,
3653 type_CtrlAlt
[hairy
]))
3655 /* If in neither list, report all the modifiers we see COMBINED
3656 WITH the reported character. */
3657 if (strchr (S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS
,
3658 type_CtrlAlt
[hairy
]))
3659 strip_ExtraMods
= 0;
3662 if (strip_ExtraMods
)
3663 wmsg
.dwModifiers
= wmsg
.dwModifiers
& shift_modifier
;
3665 signal_user_input ();
3668 FPRINTF_WM_CHARS((stderr
, "unichar %#06x\n", *b
));
3669 my_post_msg (&wmsg
, hwnd
, WM_UNICHAR
, *b
++, lParam
);
3671 if (!ctrl_cnt
) /* Process ALSO as ctrl */
3674 FPRINTF_WM_CHARS((stderr
, "extra ctrl char\n"));
3677 else if (is_dead
>= 0)
3679 FPRINTF_WM_CHARS((stderr
, "dead %#06x\n", is_dead
));
3680 after_deadkey
= is_dead
;
3686 /* Main window procedure */
3688 static LRESULT CALLBACK
3689 w32_wnd_proc (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
3692 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
3694 int windows_translate
;
3697 /* Note that it is okay to call x_window_to_frame, even though we are
3698 not running in the main lisp thread, because frame deletion
3699 requires the lisp thread to synchronize with this thread. Thus, if
3700 a frame struct is returned, it can be used without concern that the
3701 lisp thread might make it disappear while we are using it.
3703 NB. Walking the frame list in this thread is safe (as long as
3704 writes of Lisp_Object slots are atomic, which they are on Windows).
3705 Although delete-frame can destructively modify the frame list while
3706 we are walking it, a garbage collection cannot occur until after
3707 delete-frame has synchronized with this thread.
3709 It is also safe to use functions that make GDI calls, such as
3710 w32_clear_rect, because these functions must obtain a DC handle
3711 from the frame struct using get_frame_dc which is thread-aware. */
3716 f
= x_window_to_frame (dpyinfo
, hwnd
);
3719 HDC hdc
= get_frame_dc (f
);
3720 GetUpdateRect (hwnd
, &wmsg
.rect
, FALSE
);
3721 w32_clear_rect (f
, hdc
, &wmsg
.rect
);
3722 release_frame_dc (f
, hdc
);
3724 #if defined (W32_DEBUG_DISPLAY)
3725 DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
3727 wmsg
.rect
.left
, wmsg
.rect
.top
,
3728 wmsg
.rect
.right
, wmsg
.rect
.bottom
));
3729 #endif /* W32_DEBUG_DISPLAY */
3732 case WM_PALETTECHANGED
:
3733 /* ignore our own changes */
3734 if ((HWND
)wParam
!= hwnd
)
3736 f
= x_window_to_frame (dpyinfo
, hwnd
);
3738 /* get_frame_dc will realize our palette and force all
3739 frames to be redrawn if needed. */
3740 release_frame_dc (f
, get_frame_dc (f
));
3745 PAINTSTRUCT paintStruct
;
3747 memset (&update_rect
, 0, sizeof (update_rect
));
3749 f
= x_window_to_frame (dpyinfo
, hwnd
);
3752 DebPrint (("WM_PAINT received for unknown window %p\n", hwnd
));
3756 /* MSDN Docs say not to call BeginPaint if GetUpdateRect
3757 fails. Apparently this can happen under some
3759 if (GetUpdateRect (hwnd
, &update_rect
, FALSE
) || !w32_strict_painting
)
3762 BeginPaint (hwnd
, &paintStruct
);
3764 /* The rectangles returned by GetUpdateRect and BeginPaint
3765 do not always match. Play it safe by assuming both areas
3767 UnionRect (&(wmsg
.rect
), &update_rect
, &(paintStruct
.rcPaint
));
3769 #if defined (W32_DEBUG_DISPLAY)
3770 DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
3772 wmsg
.rect
.left
, wmsg
.rect
.top
,
3773 wmsg
.rect
.right
, wmsg
.rect
.bottom
));
3774 DebPrint ((" [update region is %d,%d-%d,%d]\n",
3775 update_rect
.left
, update_rect
.top
,
3776 update_rect
.right
, update_rect
.bottom
));
3778 EndPaint (hwnd
, &paintStruct
);
3781 /* Change the message type to prevent Windows from
3782 combining WM_PAINT messages in the Lisp thread's queue,
3783 since Windows assumes that each message queue is
3784 dedicated to one frame and does not bother checking
3785 that hwnd matches before combining them. */
3786 my_post_msg (&wmsg
, hwnd
, WM_EMACS_PAINT
, wParam
, lParam
);
3791 /* If GetUpdateRect returns 0 (meaning there is no update
3792 region), assume the whole window needs to be repainted. */
3793 GetClientRect (hwnd
, &wmsg
.rect
);
3794 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3798 case WM_INPUTLANGCHANGE
:
3799 /* Inform lisp thread of keyboard layout changes. */
3800 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3802 /* The state of the finite automaton is separate per every input
3803 language environment (so it does not change when one switches
3804 to a different window with the same environment). Moreover,
3805 the experiments show that the state is not remembered when
3806 one switches back to the pre-previous environment. */
3809 /* XXXX??? What follows is a COMPLETE misunderstanding of Windows! */
3811 /* Clear dead keys in the keyboard state; for simplicity only
3812 preserve modifier key states. */
3817 GetKeyboardState (keystate
);
3818 for (i
= 0; i
< 256; i
++)
3835 SetKeyboardState (keystate
);
3840 /* Synchronize hot keys with normal input. */
3841 PostMessage (hwnd
, WM_KEYDOWN
, HIWORD (lParam
), 0);
3846 record_keyup (wParam
, lParam
);
3851 /* Ignore keystrokes we fake ourself; see below. */
3852 if (dpyinfo
->faked_key
== wParam
)
3854 dpyinfo
->faked_key
= 0;
3855 /* Make sure TranslateMessage sees them though (as long as
3856 they don't produce WM_CHAR messages). This ensures that
3857 indicator lights are toggled promptly on Windows 9x, for
3859 if (wParam
< 256 && lispy_function_keys
[wParam
])
3861 windows_translate
= 1;
3867 /* Synchronize modifiers with current keystroke. */
3869 record_keydown (wParam
, lParam
);
3870 if (w32_use_fallback_wm_chars_method
)
3871 wParam
= map_keypad_keys (wParam
, (lParam
& 0x1000000L
) != 0);
3873 windows_translate
= 0;
3878 if (!w32_kbdhook_active
&& NILP (Vw32_pass_lwindow_to_system
))
3880 /* Prevent system from acting on keyup (which opens the
3881 Start menu if no other key was pressed) by simulating a
3882 press of Space which we will ignore. */
3883 if (GetAsyncKeyState (wParam
) & 1)
3885 if (NUMBERP (Vw32_phantom_key_code
))
3886 key
= XUINT (Vw32_phantom_key_code
) & 255;
3889 dpyinfo
->faked_key
= key
;
3890 keybd_event (key
, (BYTE
) MapVirtualKey (key
, 0), 0, 0);
3893 if (!NILP (Vw32_lwindow_modifier
))
3897 if (!w32_kbdhook_active
&& NILP (Vw32_pass_rwindow_to_system
))
3899 if (GetAsyncKeyState (wParam
) & 1)
3901 if (NUMBERP (Vw32_phantom_key_code
))
3902 key
= XUINT (Vw32_phantom_key_code
) & 255;
3905 dpyinfo
->faked_key
= key
;
3906 keybd_event (key
, (BYTE
) MapVirtualKey (key
, 0), 0, 0);
3909 if (!NILP (Vw32_rwindow_modifier
))
3913 if (!NILP (Vw32_apps_modifier
))
3917 if (NILP (Vw32_pass_alt_to_system
))
3918 /* Prevent DefWindowProc from activating the menu bar if an
3919 Alt key is pressed and released by itself. */
3921 windows_translate
= 1;
3924 /* Decide whether to treat as modifier or function key. */
3925 if (NILP (Vw32_enable_caps_lock
))
3926 goto disable_lock_key
;
3927 windows_translate
= 1;
3930 /* Decide whether to treat as modifier or function key. */
3931 if (NILP (Vw32_enable_num_lock
))
3932 goto disable_lock_key
;
3933 windows_translate
= 1;
3936 /* Decide whether to treat as modifier or function key. */
3937 if (NILP (Vw32_scroll_lock_modifier
))
3938 goto disable_lock_key
;
3939 windows_translate
= 1;
3942 /* Ensure the appropriate lock key state (and indicator light)
3943 remains in the same state. We do this by faking another
3944 press of the relevant key. Apparently, this really is the
3945 only way to toggle the state of the indicator lights. */
3946 dpyinfo
->faked_key
= wParam
;
3947 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3948 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3949 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3950 KEYEVENTF_EXTENDEDKEY
| 0, 0);
3951 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3952 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3953 /* Ensure indicator lights are updated promptly on Windows 9x
3954 (TranslateMessage apparently does this), after forwarding
3956 post_character_message (hwnd
, msg
, wParam
, lParam
,
3957 w32_get_key_modifiers (wParam
, lParam
));
3958 windows_translate
= 1;
3962 case VK_PROCESSKEY
: /* Generated by IME. */
3963 windows_translate
= 1;
3966 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
3967 which is confusing for purposes of key binding; convert
3968 VK_CANCEL events into VK_PAUSE events. */
3972 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
3973 for purposes of key binding; convert these back into
3974 VK_NUMLOCK events, at least when we want to see NumLock key
3975 presses. (Note that there is never any possibility that
3976 VK_PAUSE with Ctrl really is C-Pause as per above.) */
3977 if (NILP (Vw32_enable_num_lock
) && modifier_set (VK_CONTROL
))
3978 wParam
= VK_NUMLOCK
;
3981 if (w32_unicode_gui
&& !w32_use_fallback_wm_chars_method
)
3983 /* If this event generates characters or deadkeys, do
3984 not interpret it as a "raw combination of modifiers
3985 and keysym". Hide deadkeys, and use the generated
3986 character(s) instead of the keysym. (Backward
3987 compatibility: exceptions for numpad keys generating
3988 0-9 . , / * - +, and for extra-Alt combined with a
3991 Try to not report modifiers which have effect on
3992 which character or deadkey is generated.
3994 Example (contrived): if rightAlt-? generates f (on a
3995 Cyrillic keyboard layout), and Ctrl, leftAlt do not
3996 affect the generated character, one wants to report
3997 Ctrl-leftAlt-f if the user presses
3998 Ctrl-leftAlt-rightAlt-?. */
4001 /* Some of WM_CHAR may be fed to us directly, some are
4002 results of TranslateMessage(). Using 0 as the first
4003 argument (in a separate call) might help us
4004 distinguish these two cases.
4006 However, the keypress feeders would most probably
4007 expect the "standard" message pump, when
4008 TranslateMessage() is called on EVERY KeyDown/KeyUp
4009 event. So they may feed us Down-Ctrl Down-FAKE
4010 Char-o and expect us to recognize it as Ctrl-o.
4011 Using 0 as the first argument would interfere with
4013 deliver_wm_chars (0, hwnd
, msg
, wParam
, lParam
, 1);
4015 /* Processing the generated WM_CHAR messages *WHILE* we
4016 handle KEYDOWN/UP event is the best choice, since
4017 without any fuss, we know all 3 of: scancode, virtual
4018 keycode, and expansion. (Additionally, one knows
4019 boundaries of expansion of different keypresses.) */
4020 res
= deliver_wm_chars (1, hwnd
, msg
, wParam
, lParam
, 1);
4021 windows_translate
= -(res
!= 0);
4022 if (res
> 0) /* Bound to character(s) or a deadkey */
4024 /* deliver_wm_chars may make some branches after this vestigal. */
4026 wParam
= map_keypad_keys (wParam
, (lParam
& 0x1000000L
) != 0);
4027 /* If not defined as a function key, change it to a WM_CHAR message. */
4028 if (wParam
> 255 || !lispy_function_keys
[wParam
])
4030 DWORD modifiers
= construct_console_modifiers ();
4032 if (!NILP (Vw32_recognize_altgr
)
4033 && modifier_set (VK_LCONTROL
) && modifier_set (VK_RMENU
))
4035 /* Always let TranslateMessage handle AltGr key chords;
4036 for some reason, ToAscii doesn't always process AltGr
4037 chords correctly. */
4038 windows_translate
= 1;
4040 else if ((modifiers
& (~SHIFT_PRESSED
& ~CAPSLOCK_ON
)) != 0)
4042 /* Handle key chords including any modifiers other
4043 than shift directly, in order to preserve as much
4044 modifier information as possible. */
4045 if ('A' <= wParam
&& wParam
<= 'Z')
4047 /* Don't translate modified alphabetic keystrokes,
4048 so the user doesn't need to constantly switch
4049 layout to type control or meta keystrokes when
4050 the normal layout translates alphabetic
4051 characters to non-ascii characters. */
4052 if (!modifier_set (VK_SHIFT
))
4053 wParam
+= ('a' - 'A');
4058 /* Try to handle other keystrokes by determining the
4059 base character (ie. translating the base key plus
4062 KEY_EVENT_RECORD key
;
4064 key
.bKeyDown
= TRUE
;
4065 key
.wRepeatCount
= 1;
4066 key
.wVirtualKeyCode
= wParam
;
4067 key
.wVirtualScanCode
= (lParam
& 0xFF0000) >> 16;
4068 key
.uChar
.AsciiChar
= 0;
4069 key
.dwControlKeyState
= modifiers
;
4071 add
= w32_kbd_patch_key (&key
, w32_keyboard_codepage
);
4072 /* 0 means an unrecognized keycode, negative means
4073 dead key. Ignore both. */
4076 /* Forward asciified character sequence. */
4077 post_character_message
4079 (unsigned char) key
.uChar
.AsciiChar
, lParam
,
4080 w32_get_key_modifiers (wParam
, lParam
));
4081 w32_kbd_patch_key (&key
, w32_keyboard_codepage
);
4088 /* Let TranslateMessage handle everything else. */
4089 windows_translate
= 1;
4094 if (windows_translate
== -1)
4097 if (windows_translate
)
4099 MSG windows_msg
= { hwnd
, msg
, wParam
, lParam
, 0, {0,0} };
4100 windows_msg
.time
= GetMessageTime ();
4101 TranslateMessage (&windows_msg
);
4113 wmsg
.dwModifiers
= w32_get_key_modifiers (wParam
, lParam
);
4114 signal_user_input ();
4115 my_post_msg (&wmsg
, hwnd
, WM_UNICHAR
, wParam
, lParam
);
4119 post_character_message (hwnd
, msg
, wParam
, lParam
,
4120 w32_get_key_modifiers (wParam
, lParam
));
4124 /* WM_UNICHAR looks promising from the docs, but the exact
4125 circumstances in which TranslateMessage sends it is one of those
4126 Microsoft secret API things that EU and US courts are supposed
4127 to have put a stop to already. Spy++ shows it being sent to Notepad
4128 and other MS apps, but never to Emacs.
4130 Some third party IMEs send it in accordance with the official
4131 documentation though, so handle it here.
4133 UNICODE_NOCHAR is used to test for support for this message.
4134 TRUE indicates that the message is supported. */
4135 if (wParam
== UNICODE_NOCHAR
)
4140 wmsg
.dwModifiers
= w32_get_key_modifiers (wParam
, lParam
);
4141 signal_user_input ();
4142 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4147 /* If we can't get the IME result as Unicode, use default processing,
4148 which will at least allow characters decodable in the system locale
4150 if (!get_composition_string_fn
)
4153 else if (!ignore_ime_char
)
4158 HIMC context
= get_ime_context_fn (hwnd
);
4159 wmsg
.dwModifiers
= w32_get_key_modifiers (wParam
, lParam
);
4160 /* Get buffer size. */
4161 size
= get_composition_string_fn (context
, GCS_RESULTSTR
, NULL
, 0);
4162 buffer
= alloca (size
);
4163 size
= get_composition_string_fn (context
, GCS_RESULTSTR
,
4165 release_ime_context_fn (hwnd
, context
);
4167 signal_user_input ();
4168 for (i
= 0; i
< size
/ sizeof (wchar_t); i
++)
4170 my_post_msg (&wmsg
, hwnd
, WM_UNICHAR
, (WPARAM
) buffer
[i
],
4173 /* Ignore the messages for the rest of the
4174 characters in the string that was output above. */
4175 ignore_ime_char
= (size
/ sizeof (wchar_t)) - 1;
4182 case WM_IME_STARTCOMPOSITION
:
4183 if (!set_ime_composition_window_fn
)
4187 COMPOSITIONFORM form
;
4191 /* Implementation note: The code below does something that
4192 one shouldn't do: it accesses the window object from a
4193 separate thread, while the main (a.k.a. "Lisp") thread
4194 runs and can legitimately delete and even GC it. That is
4195 why we are extra careful not to futz with a window that
4196 is different from the one recorded when the system caret
4197 coordinates were last modified. That is also why we are
4198 careful not to move the IME window if the window
4199 described by W was deleted, as indicated by its buffer
4200 field being reset to nil. */
4201 f
= x_window_to_frame (dpyinfo
, hwnd
);
4202 if (!(f
&& FRAME_LIVE_P (f
)))
4204 w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
4205 /* Punt if someone changed the frame's selected window
4207 if (w
!= w32_system_caret_window
)
4210 form
.dwStyle
= CFS_RECT
;
4211 form
.ptCurrentPos
.x
= w32_system_caret_x
;
4212 form
.ptCurrentPos
.y
= w32_system_caret_y
;
4214 form
.rcArea
.left
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, 0);
4215 form
.rcArea
.top
= (WINDOW_TOP_EDGE_Y (w
)
4216 + w32_system_caret_hdr_height
);
4217 form
.rcArea
.right
= (WINDOW_BOX_RIGHT_EDGE_X (w
)
4218 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
4219 - WINDOW_RIGHT_FRINGE_WIDTH (w
));
4220 form
.rcArea
.bottom
= (WINDOW_BOTTOM_EDGE_Y (w
)
4221 - WINDOW_BOTTOM_DIVIDER_WIDTH (w
)
4222 - w32_system_caret_mode_height
);
4224 /* Punt if the window was deleted behind our back. */
4225 if (!BUFFERP (w
->contents
))
4228 context
= get_ime_context_fn (hwnd
);
4233 set_ime_composition_window_fn (context
, &form
);
4234 release_ime_context_fn (hwnd
, context
);
4236 /* We should "goto dflt" here to pass WM_IME_STARTCOMPOSITION to
4237 DefWindowProc, so that the composition window will actually
4238 be displayed. But doing so causes trouble with displaying
4239 dialog boxes, such as the file selection dialog or font
4240 selection dialog. So something else is needed to fix the
4241 former without breaking the latter. See bug#11732. */
4244 case WM_IME_ENDCOMPOSITION
:
4245 ignore_ime_char
= 0;
4248 /* Simulate middle mouse button events when left and right buttons
4249 are used together, but only if user has two button mouse. */
4250 case WM_LBUTTONDOWN
:
4251 case WM_RBUTTONDOWN
:
4252 if (w32_num_mouse_buttons
> 2)
4253 goto handle_plain_button
;
4256 int this = (msg
== WM_LBUTTONDOWN
) ? LMOUSE
: RMOUSE
;
4257 int other
= (msg
== WM_LBUTTONDOWN
) ? RMOUSE
: LMOUSE
;
4259 if (button_state
& this)
4262 if (button_state
== 0)
4265 button_state
|= this;
4267 if (button_state
& other
)
4269 if (mouse_button_timer
)
4271 KillTimer (hwnd
, mouse_button_timer
);
4272 mouse_button_timer
= 0;
4274 /* Generate middle mouse event instead. */
4275 msg
= WM_MBUTTONDOWN
;
4276 button_state
|= MMOUSE
;
4278 else if (button_state
& MMOUSE
)
4280 /* Ignore button event if we've already generated a
4281 middle mouse down event. This happens if the
4282 user releases and press one of the two buttons
4283 after we've faked a middle mouse event. */
4288 /* Flush out saved message. */
4289 post_msg (&saved_mouse_button_msg
);
4291 wmsg
.dwModifiers
= w32_get_modifiers ();
4292 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4293 signal_user_input ();
4295 /* Clear message buffer. */
4296 saved_mouse_button_msg
.msg
.hwnd
= 0;
4300 /* Hold onto message for now. */
4301 mouse_button_timer
=
4302 SetTimer (hwnd
, MOUSE_BUTTON_ID
,
4303 w32_mouse_button_tolerance
, NULL
);
4304 saved_mouse_button_msg
.msg
.hwnd
= hwnd
;
4305 saved_mouse_button_msg
.msg
.message
= msg
;
4306 saved_mouse_button_msg
.msg
.wParam
= wParam
;
4307 saved_mouse_button_msg
.msg
.lParam
= lParam
;
4308 saved_mouse_button_msg
.msg
.time
= GetMessageTime ();
4309 saved_mouse_button_msg
.dwModifiers
= w32_get_modifiers ();
4316 if (w32_num_mouse_buttons
> 2)
4317 goto handle_plain_button
;
4320 int this = (msg
== WM_LBUTTONUP
) ? LMOUSE
: RMOUSE
;
4321 int other
= (msg
== WM_LBUTTONUP
) ? RMOUSE
: LMOUSE
;
4323 if ((button_state
& this) == 0)
4326 button_state
&= ~this;
4328 if (button_state
& MMOUSE
)
4330 /* Only generate event when second button is released. */
4331 if ((button_state
& other
) == 0)
4334 button_state
&= ~MMOUSE
;
4336 if (button_state
) emacs_abort ();
4343 /* Flush out saved message if necessary. */
4344 if (saved_mouse_button_msg
.msg
.hwnd
)
4346 post_msg (&saved_mouse_button_msg
);
4349 wmsg
.dwModifiers
= w32_get_modifiers ();
4350 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4351 signal_user_input ();
4353 /* Always clear message buffer and cancel timer. */
4354 saved_mouse_button_msg
.msg
.hwnd
= 0;
4355 KillTimer (hwnd
, mouse_button_timer
);
4356 mouse_button_timer
= 0;
4358 if (button_state
== 0)
4363 case WM_XBUTTONDOWN
:
4365 if (w32_pass_extra_mouse_buttons_to_system
)
4367 /* else fall through and process them. */
4368 case WM_MBUTTONDOWN
:
4370 handle_plain_button
:
4375 /* Ignore middle and extra buttons as long as the menu is active. */
4376 f
= x_window_to_frame (dpyinfo
, hwnd
);
4377 if (f
&& f
->output_data
.w32
->menubar_active
)
4380 if (parse_button (msg
, HIWORD (wParam
), &button
, &up
))
4382 if (up
) ReleaseCapture ();
4383 else SetCapture (hwnd
);
4384 button
= (button
== 0) ? LMOUSE
:
4385 ((button
== 1) ? MMOUSE
: RMOUSE
);
4387 button_state
&= ~button
;
4389 button_state
|= button
;
4393 wmsg
.dwModifiers
= w32_get_modifiers ();
4394 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4395 signal_user_input ();
4397 /* Need to return true for XBUTTON messages, false for others,
4398 to indicate that we processed the message. */
4399 return (msg
== WM_XBUTTONDOWN
|| msg
== WM_XBUTTONUP
);
4402 f
= x_window_to_frame (dpyinfo
, hwnd
);
4405 /* Ignore mouse movements as long as the menu is active.
4406 These movements are processed by the window manager
4407 anyway, and it's wrong to handle them as if they happened
4408 on the underlying frame. */
4409 if (f
->output_data
.w32
->menubar_active
)
4412 /* If the mouse moved, and the mouse pointer is invisible,
4413 make it visible again. We do this here so as to be able
4414 to show the mouse pointer even when the main
4415 (a.k.a. "Lisp") thread is busy doing something. */
4416 static int last_x
, last_y
;
4417 int x
= GET_X_LPARAM (lParam
);
4418 int y
= GET_Y_LPARAM (lParam
);
4420 if (f
->pointer_invisible
4421 && (x
!= last_x
|| y
!= last_y
))
4422 f
->pointer_invisible
= false;
4428 /* If the mouse has just moved into the frame, start tracking
4429 it, so we will be notified when it leaves the frame. Mouse
4430 tracking only works under W98 and NT4 and later. On earlier
4431 versions, there is no way of telling when the mouse leaves the
4432 frame, so we just have to put up with help-echo and mouse
4433 highlighting remaining while the frame is not active. */
4434 if (track_mouse_event_fn
&& !track_mouse_window
4435 /* If the menu bar is active, turning on tracking of mouse
4436 movement events might send these events to the tooltip
4437 frame, if the user happens to move the mouse pointer over
4438 the tooltip. But since we don't process events for
4439 tooltip frames, this causes Windows to present a
4440 hourglass cursor, which is ugly and unexpected. So don't
4441 enable tracking mouse events in this case; they will be
4442 restarted when the menu pops down. (Confusingly, the
4443 menubar_active member of f->output_data.w32, tested
4444 above, is only set when a menu was popped up _not_ from
4445 the frame's menu bar, but via x-popup-menu.) */
4448 TRACKMOUSEEVENT tme
;
4449 tme
.cbSize
= sizeof (tme
);
4450 tme
.dwFlags
= TME_LEAVE
;
4451 tme
.hwndTrack
= hwnd
;
4452 tme
.dwHoverTime
= HOVER_DEFAULT
;
4454 track_mouse_event_fn (&tme
);
4455 track_mouse_window
= hwnd
;
4459 if (w32_mouse_move_interval
<= 0
4460 || (msg
== WM_MOUSEMOVE
&& button_state
== 0))
4462 wmsg
.dwModifiers
= w32_get_modifiers ();
4463 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4467 /* Hang onto mouse move and scroll messages for a bit, to avoid
4468 sending such events to Emacs faster than it can process them.
4469 If we get more events before the timer from the first message
4470 expires, we just replace the first message. */
4472 if (saved_mouse_move_msg
.msg
.hwnd
== 0)
4474 SetTimer (hwnd
, MOUSE_MOVE_ID
,
4475 w32_mouse_move_interval
, NULL
);
4477 /* Hold onto message for now. */
4478 saved_mouse_move_msg
.msg
.hwnd
= hwnd
;
4479 saved_mouse_move_msg
.msg
.message
= msg
;
4480 saved_mouse_move_msg
.msg
.wParam
= wParam
;
4481 saved_mouse_move_msg
.msg
.lParam
= lParam
;
4482 saved_mouse_move_msg
.msg
.time
= GetMessageTime ();
4483 saved_mouse_move_msg
.dwModifiers
= w32_get_modifiers ();
4489 wmsg
.dwModifiers
= w32_get_modifiers ();
4490 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4491 signal_user_input ();
4495 if (w32_pass_multimedia_buttons_to_system
)
4497 /* Otherwise, pass to lisp, the same way we do with mousehwheel. */
4498 case WM_MOUSEHWHEEL
:
4499 wmsg
.dwModifiers
= w32_get_modifiers ();
4500 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4501 signal_user_input ();
4502 /* Non-zero must be returned when WM_MOUSEHWHEEL messages are
4503 handled, to prevent the system trying to handle it by faking
4504 scroll bar events. */
4508 /* Flush out saved messages if necessary. */
4509 if (wParam
== mouse_button_timer
)
4511 if (saved_mouse_button_msg
.msg
.hwnd
)
4513 post_msg (&saved_mouse_button_msg
);
4514 signal_user_input ();
4515 saved_mouse_button_msg
.msg
.hwnd
= 0;
4517 KillTimer (hwnd
, mouse_button_timer
);
4518 mouse_button_timer
= 0;
4520 else if (wParam
== mouse_move_timer
)
4522 if (saved_mouse_move_msg
.msg
.hwnd
)
4524 post_msg (&saved_mouse_move_msg
);
4525 saved_mouse_move_msg
.msg
.hwnd
= 0;
4527 KillTimer (hwnd
, mouse_move_timer
);
4528 mouse_move_timer
= 0;
4530 else if (wParam
== menu_free_timer
)
4532 KillTimer (hwnd
, menu_free_timer
);
4533 menu_free_timer
= 0;
4534 f
= x_window_to_frame (dpyinfo
, hwnd
);
4535 /* If a popup menu is active, don't wipe its strings. */
4537 && current_popup_menu
== NULL
)
4539 /* Free memory used by owner-drawn and help-echo strings. */
4540 w32_free_menu_strings (hwnd
);
4542 f
->output_data
.w32
->menubar_active
= 0;
4549 /* Windows doesn't send us focus messages when putting up and
4550 taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
4551 The only indication we get that something happened is receiving
4552 this message afterwards. So this is a good time to reset our
4553 keyboard modifiers' state. */
4560 /* We must ensure menu bar is fully constructed and up to date
4561 before allowing user interaction with it. To achieve this
4562 we send this message to the lisp thread and wait for a
4563 reply (whose value is not actually needed) to indicate that
4564 the menu bar is now ready for use, so we can now return.
4566 To remain responsive in the meantime, we enter a nested message
4567 loop that can process all other messages.
4569 However, we skip all this if the message results from calling
4570 TrackPopupMenu - in fact, we must NOT attempt to send the lisp
4571 thread a message because it is blocked on us at this point. We
4572 set menubar_active before calling TrackPopupMenu to indicate
4573 this (there is no possibility of confusion with real menubar
4576 f
= x_window_to_frame (dpyinfo
, hwnd
);
4578 && (f
->output_data
.w32
->menubar_active
4579 /* We can receive this message even in the absence of a
4580 menubar (ie. when the system menu is activated) - in this
4581 case we do NOT want to forward the message, otherwise it
4582 will cause the menubar to suddenly appear when the user
4583 had requested it to be turned off! */
4584 || f
->output_data
.w32
->menubar_widget
== NULL
))
4588 deferred_msg msg_buf
;
4590 /* Detect if message has already been deferred; in this case
4591 we cannot return any sensible value to ignore this. */
4592 if (find_deferred_msg (hwnd
, msg
) != NULL
)
4597 return send_deferred_msg (&msg_buf
, hwnd
, msg
, wParam
, lParam
);
4600 case WM_EXITMENULOOP
:
4601 f
= x_window_to_frame (dpyinfo
, hwnd
);
4603 /* If a menu is still active, check again after a short delay,
4604 since Windows often (always?) sends the WM_EXITMENULOOP
4605 before the corresponding WM_COMMAND message.
4606 Don't do this if a popup menu is active, since it is only
4607 menubar menus that require cleaning up in this way.
4609 if (f
&& menubar_in_use
&& current_popup_menu
== NULL
)
4610 menu_free_timer
= SetTimer (hwnd
, MENU_FREE_ID
, MENU_FREE_DELAY
, NULL
);
4612 /* If hourglass cursor should be displayed, display it now. */
4613 if (f
&& f
->output_data
.w32
->hourglass_p
)
4614 SetCursor (f
->output_data
.w32
->hourglass_cursor
);
4619 /* Direct handling of help_echo in menus. Should be safe now
4620 that we generate the help_echo by placing a help event in the
4623 HMENU menu
= (HMENU
) lParam
;
4624 UINT menu_item
= (UINT
) LOWORD (wParam
);
4625 UINT flags
= (UINT
) HIWORD (wParam
);
4627 w32_menu_display_help (hwnd
, menu
, menu_item
, flags
);
4631 case WM_MEASUREITEM
:
4632 f
= x_window_to_frame (dpyinfo
, hwnd
);
4635 MEASUREITEMSTRUCT
* pMis
= (MEASUREITEMSTRUCT
*) lParam
;
4637 if (pMis
->CtlType
== ODT_MENU
)
4639 /* Work out dimensions for popup menu titles. */
4640 char * title
= (char *) pMis
->itemData
;
4641 HDC hdc
= GetDC (hwnd
);
4642 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4643 LOGFONT menu_logfont
;
4647 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4648 menu_logfont
.lfWeight
= FW_BOLD
;
4649 menu_font
= CreateFontIndirect (&menu_logfont
);
4650 old_font
= SelectObject (hdc
, menu_font
);
4652 pMis
->itemHeight
= GetSystemMetrics (SM_CYMENUSIZE
);
4655 if (unicode_append_menu
)
4656 GetTextExtentPoint32W (hdc
, (WCHAR
*) title
,
4657 wcslen ((WCHAR
*) title
),
4660 GetTextExtentPoint32 (hdc
, title
, strlen (title
), &size
);
4662 pMis
->itemWidth
= size
.cx
;
4663 if (pMis
->itemHeight
< size
.cy
)
4664 pMis
->itemHeight
= size
.cy
;
4667 pMis
->itemWidth
= 0;
4669 SelectObject (hdc
, old_font
);
4670 DeleteObject (menu_font
);
4671 ReleaseDC (hwnd
, hdc
);
4678 f
= x_window_to_frame (dpyinfo
, hwnd
);
4681 DRAWITEMSTRUCT
* pDis
= (DRAWITEMSTRUCT
*) lParam
;
4683 if (pDis
->CtlType
== ODT_MENU
)
4685 /* Draw popup menu title. */
4686 char * title
= (char *) pDis
->itemData
;
4689 HDC hdc
= pDis
->hDC
;
4690 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4691 LOGFONT menu_logfont
;
4694 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4695 menu_logfont
.lfWeight
= FW_BOLD
;
4696 menu_font
= CreateFontIndirect (&menu_logfont
);
4697 old_font
= SelectObject (hdc
, menu_font
);
4699 /* Always draw title as if not selected. */
4700 if (unicode_append_menu
)
4703 + GetSystemMetrics (SM_CXMENUCHECK
),
4705 ETO_OPAQUE
, &pDis
->rcItem
,
4707 wcslen ((WCHAR
*) title
), NULL
);
4711 + GetSystemMetrics (SM_CXMENUCHECK
),
4713 ETO_OPAQUE
, &pDis
->rcItem
,
4714 title
, strlen (title
), NULL
);
4716 SelectObject (hdc
, old_font
);
4717 DeleteObject (menu_font
);
4725 /* Still not right - can't distinguish between clicks in the
4726 client area of the frame from clicks forwarded from the scroll
4727 bars - may have to hook WM_NCHITTEST to remember the mouse
4728 position and then check if it is in the client area ourselves. */
4729 case WM_MOUSEACTIVATE
:
4730 /* Discard the mouse click that activates a frame, allowing the
4731 user to click anywhere without changing point (or worse!).
4732 Don't eat mouse clicks on scrollbars though!! */
4733 if (LOWORD (lParam
) == HTCLIENT
)
4734 return MA_ACTIVATEANDEAT
;
4739 /* No longer tracking mouse. */
4740 track_mouse_window
= NULL
;
4742 case WM_ACTIVATEAPP
:
4744 case WM_WINDOWPOSCHANGED
:
4746 /* Inform lisp thread that a frame might have just been obscured
4747 or exposed, so should recheck visibility of all frames. */
4748 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4752 dpyinfo
->faked_key
= 0;
4754 if (!w32_kbdhook_active
)
4755 register_hot_keys (hwnd
);
4758 if (!w32_kbdhook_active
)
4759 unregister_hot_keys (hwnd
);
4762 /* Relinquish the system caret. */
4763 if (w32_system_caret_hwnd
)
4765 w32_visible_system_caret_hwnd
= NULL
;
4766 w32_system_caret_hwnd
= NULL
;
4772 f
= x_window_to_frame (dpyinfo
, hwnd
);
4773 if (f
&& HIWORD (wParam
) == 0)
4775 if (menu_free_timer
)
4777 KillTimer (hwnd
, menu_free_timer
);
4778 menu_free_timer
= 0;
4784 wmsg
.dwModifiers
= w32_get_modifiers ();
4785 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4790 setup_w32_kbdhook ();
4796 remove_w32_kbdhook ();
4801 case WM_WTSSESSION_CHANGE
:
4802 if (wParam
== WTS_SESSION_LOCK
)
4803 reset_w32_kbdhook_state ();
4807 wmsg
.dwModifiers
= w32_get_modifiers ();
4808 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4812 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4813 /* If we return, the process will be terminated immediately. */
4816 case WM_WINDOWPOSCHANGING
:
4817 /* Don't restrict the sizing of any kind of frames. If the window
4818 manager doesn't, there's no reason to do it ourselves. */
4821 case WM_GETMINMAXINFO
:
4822 /* Hack to allow resizing the Emacs frame above the screen size.
4823 Note that Windows 9x limits coordinates to 16-bits. */
4824 ((LPMINMAXINFO
) lParam
)->ptMaxTrackSize
.x
= 32767;
4825 ((LPMINMAXINFO
) lParam
)->ptMaxTrackSize
.y
= 32767;
4829 if (LOWORD (lParam
) == HTCLIENT
)
4831 f
= x_window_to_frame (dpyinfo
, hwnd
);
4834 if (f
->output_data
.w32
->hourglass_p
4835 && !menubar_in_use
&& !current_popup_menu
)
4836 SetCursor (f
->output_data
.w32
->hourglass_cursor
);
4837 else if (f
->pointer_invisible
)
4840 SetCursor (f
->output_data
.w32
->current_cursor
);
4847 case WM_EMACS_SETCURSOR
:
4849 Cursor cursor
= (Cursor
) wParam
;
4850 f
= x_window_to_frame (dpyinfo
, hwnd
);
4853 f
->output_data
.w32
->current_cursor
= cursor
;
4854 /* Don't change the cursor while menu-bar menu is in use. */
4855 if (!f
->output_data
.w32
->menubar_active
4856 && !f
->output_data
.w32
->hourglass_p
)
4858 if (f
->pointer_invisible
)
4867 case WM_EMACS_SHOWCURSOR
:
4869 ShowCursor ((BOOL
) wParam
);
4874 case WM_EMACS_CREATEVSCROLLBAR
:
4875 return (LRESULT
) w32_createvscrollbar ((struct frame
*) wParam
,
4876 (struct scroll_bar
*) lParam
);
4878 case WM_EMACS_CREATEHSCROLLBAR
:
4879 return (LRESULT
) w32_createhscrollbar ((struct frame
*) wParam
,
4880 (struct scroll_bar
*) lParam
);
4882 case WM_EMACS_SHOWWINDOW
:
4883 return ShowWindow ((HWND
) wParam
, (WPARAM
) lParam
);
4885 case WM_EMACS_BRINGTOTOP
:
4886 case WM_EMACS_SETFOREGROUND
:
4888 HWND foreground_window
;
4889 DWORD foreground_thread
, retval
;
4891 /* On NT 5.0, and apparently Windows 98, it is necessary to
4892 attach to the thread that currently has focus in order to
4893 pull the focus away from it. */
4894 foreground_window
= GetForegroundWindow ();
4895 foreground_thread
= GetWindowThreadProcessId (foreground_window
, NULL
);
4896 if (!foreground_window
4897 || foreground_thread
== GetCurrentThreadId ()
4898 || !AttachThreadInput (GetCurrentThreadId (),
4899 foreground_thread
, TRUE
))
4900 foreground_thread
= 0;
4902 retval
= SetForegroundWindow ((HWND
) wParam
);
4903 if (msg
== WM_EMACS_BRINGTOTOP
)
4904 retval
= BringWindowToTop ((HWND
) wParam
);
4906 /* Detach from the previous foreground thread. */
4907 if (foreground_thread
)
4908 AttachThreadInput (GetCurrentThreadId (),
4909 foreground_thread
, FALSE
);
4914 case WM_EMACS_SETWINDOWPOS
:
4916 WINDOWPOS
* pos
= (WINDOWPOS
*) wParam
;
4917 return SetWindowPos (hwnd
, pos
->hwndInsertAfter
,
4918 pos
->x
, pos
->y
, pos
->cx
, pos
->cy
, pos
->flags
);
4921 case WM_EMACS_DESTROYWINDOW
:
4922 DragAcceptFiles ((HWND
) wParam
, FALSE
);
4923 return DestroyWindow ((HWND
) wParam
);
4925 case WM_EMACS_HIDE_CARET
:
4926 return HideCaret (hwnd
);
4928 case WM_EMACS_SHOW_CARET
:
4929 return ShowCaret (hwnd
);
4931 case WM_EMACS_DESTROY_CARET
:
4932 w32_system_caret_hwnd
= NULL
;
4933 w32_visible_system_caret_hwnd
= NULL
;
4934 return DestroyCaret ();
4936 case WM_EMACS_TRACK_CARET
:
4937 /* If there is currently no system caret, create one. */
4938 if (w32_system_caret_hwnd
== NULL
)
4940 /* Use the default caret width, and avoid changing it
4941 unnecessarily, as it confuses screen reader software. */
4942 w32_system_caret_hwnd
= hwnd
;
4943 CreateCaret (hwnd
, NULL
, 0,
4944 w32_system_caret_height
);
4947 if (!SetCaretPos (w32_system_caret_x
, w32_system_caret_y
))
4949 /* Ensure visible caret gets turned on when requested. */
4950 else if (w32_use_visible_system_caret
4951 && w32_visible_system_caret_hwnd
!= hwnd
)
4953 w32_visible_system_caret_hwnd
= hwnd
;
4954 return ShowCaret (hwnd
);
4956 /* Ensure visible caret gets turned off when requested. */
4957 else if (!w32_use_visible_system_caret
4958 && w32_visible_system_caret_hwnd
)
4960 w32_visible_system_caret_hwnd
= NULL
;
4961 return HideCaret (hwnd
);
4966 case WM_EMACS_TRACKPOPUPMENU
:
4971 pos
= (POINT
*)lParam
;
4972 flags
= TPM_CENTERALIGN
;
4973 if (button_state
& LMOUSE
)
4974 flags
|= TPM_LEFTBUTTON
;
4975 else if (button_state
& RMOUSE
)
4976 flags
|= TPM_RIGHTBUTTON
;
4978 /* Remember we did a SetCapture on the initial mouse down event,
4979 so for safety, we make sure the capture is canceled now. */
4983 /* Use menubar_active to indicate that WM_INITMENU is from
4984 TrackPopupMenu below, and should be ignored. */
4985 f
= x_window_to_frame (dpyinfo
, hwnd
);
4987 f
->output_data
.w32
->menubar_active
= 1;
4989 if (TrackPopupMenu ((HMENU
)wParam
, flags
, pos
->x
, pos
->y
,
4993 /* Eat any mouse messages during popupmenu */
4994 while (PeekMessage (&amsg
, hwnd
, WM_MOUSEFIRST
, WM_MOUSELAST
,
4996 /* Get the menu selection, if any */
4997 if (PeekMessage (&amsg
, hwnd
, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
))
4999 retval
= LOWORD (amsg
.wParam
);
5013 case WM_EMACS_FILENOTIFY
:
5014 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
5018 /* Check for messages registered at runtime. */
5019 if (msg
== msh_mousewheel
)
5021 wmsg
.dwModifiers
= w32_get_modifiers ();
5022 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
5023 signal_user_input ();
5028 return (w32_unicode_gui
? DefWindowProcW
: DefWindowProcA
) (hwnd
, msg
, wParam
, lParam
);
5031 /* The most common default return code for handled messages is 0. */
5036 my_create_window (struct frame
* f
)
5039 static int coords
[2];
5040 Lisp_Object left
, top
;
5041 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
5043 /* When called with RES_TYPE_NUMBER, x_get_arg will return zero for
5044 anything that is not a number and is not Qunbound. */
5045 left
= x_get_arg (dpyinfo
, Qnil
, Qleft
, "left", "Left", RES_TYPE_NUMBER
);
5046 top
= x_get_arg (dpyinfo
, Qnil
, Qtop
, "top", "Top", RES_TYPE_NUMBER
);
5047 if (EQ (left
, Qunbound
))
5048 coords
[0] = CW_USEDEFAULT
;
5050 coords
[0] = XINT (left
);
5051 if (EQ (top
, Qunbound
))
5052 coords
[1] = CW_USEDEFAULT
;
5054 coords
[1] = XINT (top
);
5056 if (!PostThreadMessage (dwWindowsThreadId
, WM_EMACS_CREATEWINDOW
,
5057 (WPARAM
)f
, (LPARAM
)coords
))
5059 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
5063 /* Create a tooltip window. Unlike my_create_window, we do not do this
5064 indirectly via the Window thread, as we do not need to process Window
5065 messages for the tooltip. Creating tooltips indirectly also creates
5066 deadlocks when tooltips are created for menu items. */
5068 my_create_tip_window (struct frame
*f
)
5072 rect
.left
= rect
.top
= 0;
5073 rect
.right
= FRAME_PIXEL_WIDTH (f
);
5074 rect
.bottom
= FRAME_PIXEL_HEIGHT (f
);
5076 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
, false);
5078 tip_window
= FRAME_W32_WINDOW (f
)
5079 = CreateWindow (EMACS_CLASS
,
5081 f
->output_data
.w32
->dwStyle
,
5084 rect
.right
- rect
.left
,
5085 rect
.bottom
- rect
.top
,
5086 FRAME_W32_WINDOW (SELECTED_FRAME ()), /* owner */
5093 SetWindowLong (tip_window
, WND_FONTWIDTH_INDEX
, FRAME_COLUMN_WIDTH (f
));
5094 SetWindowLong (tip_window
, WND_LINEHEIGHT_INDEX
, FRAME_LINE_HEIGHT (f
));
5095 SetWindowLong (tip_window
, WND_BORDER_INDEX
, FRAME_INTERNAL_BORDER_WIDTH (f
));
5096 SetWindowLong (tip_window
, WND_BACKGROUND_INDEX
, FRAME_BACKGROUND_PIXEL (f
));
5098 /* Tip frames have no scrollbars. */
5099 SetWindowLong (tip_window
, WND_VSCROLLBAR_INDEX
, 0);
5100 SetWindowLong (tip_window
, WND_HSCROLLBAR_INDEX
, 0);
5102 /* Do this to discard the default setting specified by our parent. */
5103 ShowWindow (tip_window
, SW_HIDE
);
5108 /* Create and set up the w32 window for frame F. */
5111 w32_window (struct frame
*f
, long window_prompting
, bool minibuffer_only
)
5115 /* Use the resource name as the top-level window name
5116 for looking up resources. Make a non-Lisp copy
5117 for the window manager, so GC relocation won't bother it.
5119 Elsewhere we specify the window name for the window manager. */
5120 f
->namebuf
= xlispstrdup (Vx_resource_name
);
5122 my_create_window (f
);
5124 validate_x_resource_name ();
5126 /* x_set_name normally ignores requests to set the name if the
5127 requested name is the same as the current name. This is the one
5128 place where that assumption isn't correct; f->name is set, but
5129 the server hasn't been told. */
5132 int explicit = f
->explicit_name
;
5134 f
->explicit_name
= 0;
5136 fset_name (f
, Qnil
);
5137 x_set_name (f
, name
, explicit);
5142 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
5143 initialize_frame_menubar (f
);
5145 if (FRAME_W32_WINDOW (f
) == 0)
5146 error ("Unable to create window");
5149 /* Handle the icon stuff for this window. Perhaps later we might
5150 want an x_set_icon_position which can be called interactively as
5154 x_icon (struct frame
*f
, Lisp_Object parms
)
5156 Lisp_Object icon_x
, icon_y
;
5157 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
5159 /* Set the position of the icon. Note that Windows 95 groups all
5160 icons in the tray. */
5161 icon_x
= x_get_arg (dpyinfo
, parms
, Qicon_left
, 0, 0, RES_TYPE_NUMBER
);
5162 icon_y
= x_get_arg (dpyinfo
, parms
, Qicon_top
, 0, 0, RES_TYPE_NUMBER
);
5163 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
5165 CHECK_NUMBER (icon_x
);
5166 CHECK_NUMBER (icon_y
);
5168 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
5169 error ("Both left and top icon corners of icon must be specified");
5174 /* Start up iconic or window? */
5175 x_wm_set_window_state
5176 (f
, (EQ (x_get_arg (dpyinfo
, parms
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
), Qicon
)
5180 x_text_icon (f
, SSDATA ((!NILP (f
->icon_name
)
5190 x_make_gc (struct frame
*f
)
5192 XGCValues gc_values
;
5196 /* Create the GC's of this frame.
5197 Note that many default values are used. */
5200 gc_values
.font
= FRAME_FONT (f
);
5202 /* Cursor has cursor-color background, background-color foreground. */
5203 gc_values
.foreground
= FRAME_BACKGROUND_PIXEL (f
);
5204 gc_values
.background
= f
->output_data
.w32
->cursor_pixel
;
5205 f
->output_data
.w32
->cursor_gc
5206 = XCreateGC (NULL
, FRAME_W32_WINDOW (f
),
5207 (GCFont
| GCForeground
| GCBackground
),
5211 f
->output_data
.w32
->white_relief
.gc
= 0;
5212 f
->output_data
.w32
->black_relief
.gc
= 0;
5218 /* Handler for signals raised during x_create_frame and
5219 x_create_tip_frame. FRAME is the frame which is partially
5223 unwind_create_frame (Lisp_Object frame
)
5225 struct frame
*f
= XFRAME (frame
);
5227 /* If frame is ``official'', nothing to do. */
5228 if (NILP (Fmemq (frame
, Vframe_list
)))
5231 struct w32_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
5233 /* If the frame's image cache refcount is still the same as our
5234 private shadow variable, it means we are unwinding a frame
5235 for which we didn't yet call init_frame_faces, where the
5236 refcount is incremented. Therefore, we increment it here, so
5237 that free_frame_faces, called in x_free_frame_resources
5238 below, will not mistakenly decrement the counter that was not
5239 incremented yet to account for this new frame. */
5240 if (FRAME_IMAGE_CACHE (f
) != NULL
5241 && FRAME_IMAGE_CACHE (f
)->refcount
== image_cache_refcount
)
5242 FRAME_IMAGE_CACHE (f
)->refcount
++;
5245 x_free_frame_resources (f
);
5249 /* Check that reference counts are indeed correct. */
5250 eassert (dpyinfo
->reference_count
== dpyinfo_refcount
);
5251 eassert ((dpyinfo
->terminal
->image_cache
== NULL
5252 && image_cache_refcount
== 0)
5253 || (dpyinfo
->terminal
->image_cache
!= NULL
5254 && dpyinfo
->terminal
->image_cache
->refcount
== image_cache_refcount
));
5263 do_unwind_create_frame (Lisp_Object frame
)
5265 unwind_create_frame (frame
);
5269 x_default_font_parameter (struct frame
*f
, Lisp_Object parms
)
5271 struct w32_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
5272 Lisp_Object font_param
= x_get_arg (dpyinfo
, parms
, Qfont
, NULL
, NULL
,
5275 if (EQ (font_param
, Qunbound
))
5277 font
= !NILP (font_param
) ? font_param
5278 : x_get_arg (dpyinfo
, parms
, Qfont
, "font", "Font", RES_TYPE_STRING
);
5280 if (!STRINGP (font
))
5283 static const char *names
[]
5284 = { "Courier New-10",
5285 "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
5286 "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
5290 for (i
= 0; names
[i
]; i
++)
5292 font
= font_open_by_name (f
, build_unibyte_string (names
[i
]));
5297 error ("No suitable font was found");
5299 else if (!NILP (font_param
))
5301 /* Remember the explicit font parameter, so we can re-apply it after
5302 we've applied the `default' face settings. */
5303 x_set_frame_parameters (f
, Fcons (Fcons (Qfont_parameter
, font_param
),
5306 x_default_parameter (f
, parms
, Qfont
, font
, "font", "Font", RES_TYPE_STRING
);
5309 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
5311 doc
: /* Make a new window, which is called a \"frame\" in Emacs terms.
5312 Return an Emacs frame object.
5313 PARAMETERS is an alist of frame parameters.
5314 If the parameters specify that the frame should not have a minibuffer,
5315 and do not specify a specific minibuffer window to use,
5316 then `default-minibuffer-frame' must be a frame whose minibuffer can
5317 be shared by the new frame.
5319 This function is an internal primitive--use `make-frame' instead. */)
5320 (Lisp_Object parameters
)
5323 Lisp_Object frame
, tem
;
5325 bool minibuffer_only
= false;
5326 long window_prompting
= 0;
5327 ptrdiff_t count
= SPECPDL_INDEX ();
5328 Lisp_Object display
;
5329 struct w32_display_info
*dpyinfo
= NULL
;
5332 int x_width
= 0, x_height
= 0;
5334 if (!FRAME_W32_P (SELECTED_FRAME ())
5335 && !FRAME_INITIAL_P (SELECTED_FRAME ()))
5336 error ("Cannot create a GUI frame in a -nw session");
5338 /* Make copy of frame parameters because the original is in pure
5340 parameters
= Fcopy_alist (parameters
);
5342 /* Use this general default value to start with
5343 until we know if this frame has a specified name. */
5344 Vx_resource_name
= Vinvocation_name
;
5346 display
= x_get_arg (dpyinfo
, parameters
, Qterminal
, 0, 0, RES_TYPE_NUMBER
);
5347 if (EQ (display
, Qunbound
))
5348 display
= x_get_arg (dpyinfo
, parameters
, Qdisplay
, 0, 0, RES_TYPE_STRING
);
5349 if (EQ (display
, Qunbound
))
5351 dpyinfo
= check_x_display_info (display
);
5352 kb
= dpyinfo
->terminal
->kboard
;
5354 if (!dpyinfo
->terminal
->name
)
5355 error ("Terminal is not live, can't create new frames on it");
5357 name
= x_get_arg (dpyinfo
, parameters
, Qname
, "name", "Name", RES_TYPE_STRING
);
5359 && ! EQ (name
, Qunbound
)
5361 error ("Invalid frame name--not a string or nil");
5364 Vx_resource_name
= name
;
5366 /* See if parent window is specified. */
5367 parent
= x_get_arg (dpyinfo
, parameters
, Qparent_id
, NULL
, NULL
, RES_TYPE_NUMBER
);
5368 if (EQ (parent
, Qunbound
))
5370 if (! NILP (parent
))
5371 CHECK_NUMBER (parent
);
5373 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
5374 /* No need to protect DISPLAY because that's not used after passing
5375 it to make_frame_without_minibuffer. */
5377 tem
= x_get_arg (dpyinfo
, parameters
, Qminibuffer
, "minibuffer", "Minibuffer",
5379 if (EQ (tem
, Qnone
) || NILP (tem
))
5380 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
5381 else if (EQ (tem
, Qonly
))
5383 f
= make_minibuffer_frame ();
5384 minibuffer_only
= true;
5386 else if (WINDOWP (tem
))
5387 f
= make_frame_without_minibuffer (tem
, kb
, display
);
5389 f
= make_frame (true);
5391 XSETFRAME (frame
, f
);
5393 /* By default, make scrollbars the system standard width and height. */
5394 FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) = GetSystemMetrics (SM_CXVSCROLL
);
5395 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f
) = GetSystemMetrics (SM_CXHSCROLL
);
5397 f
->terminal
= dpyinfo
->terminal
;
5399 f
->output_method
= output_w32
;
5400 f
->output_data
.w32
= xzalloc (sizeof (struct w32_output
));
5401 FRAME_FONTSET (f
) = -1;
5404 (f
, x_get_arg (dpyinfo
, parameters
, Qicon_name
, "iconName", "Title",
5406 if (! STRINGP (f
->icon_name
))
5407 fset_icon_name (f
, Qnil
);
5409 /* FRAME_DISPLAY_INFO (f) = dpyinfo; */
5411 /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
5412 record_unwind_protect (do_unwind_create_frame
, frame
);
5415 image_cache_refcount
=
5416 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
5417 dpyinfo_refcount
= dpyinfo
->reference_count
;
5418 #endif /* GLYPH_DEBUG */
5420 /* Specify the parent under which to make this window. */
5423 /* Cast to UINT_PTR shuts up compiler warnings about cast to
5424 pointer from integer of different size. */
5425 f
->output_data
.w32
->parent_desc
= (Window
) (UINT_PTR
) XFASTINT (parent
);
5426 f
->output_data
.w32
->explicit_parent
= true;
5430 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5431 f
->output_data
.w32
->explicit_parent
= false;
5434 /* Set the name; the functions to which we pass f expect the name to
5436 if (EQ (name
, Qunbound
) || NILP (name
))
5438 fset_name (f
, build_string (dpyinfo
->w32_id_name
));
5439 f
->explicit_name
= false;
5443 fset_name (f
, name
);
5444 f
->explicit_name
= true;
5445 /* Use the frame's title when getting resources for this frame. */
5446 specbind (Qx_resource_name
, name
);
5449 if (uniscribe_available
)
5450 register_font_driver (&uniscribe_font_driver
, f
);
5451 register_font_driver (&w32font_driver
, f
);
5453 x_default_parameter (f
, parameters
, Qfont_backend
, Qnil
,
5454 "fontBackend", "FontBackend", RES_TYPE_STRING
);
5456 /* Extract the window parameters from the supplied values
5457 that are needed to determine window geometry. */
5458 x_default_font_parameter (f
, parameters
);
5460 x_default_parameter (f
, parameters
, Qborder_width
, make_number (2),
5461 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
5463 /* We recognize either internalBorderWidth or internalBorder
5464 (which is what xterm calls it). */
5465 if (NILP (Fassq (Qinternal_border_width
, parameters
)))
5469 value
= x_get_arg (dpyinfo
, parameters
, Qinternal_border_width
,
5470 "internalBorder", "InternalBorder", RES_TYPE_NUMBER
);
5471 if (! EQ (value
, Qunbound
))
5472 parameters
= Fcons (Fcons (Qinternal_border_width
, value
),
5475 /* Default internalBorderWidth to 0 on Windows to match other programs. */
5476 x_default_parameter (f
, parameters
, Qinternal_border_width
, make_number (0),
5477 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER
);
5478 x_default_parameter (f
, parameters
, Qright_divider_width
, make_number (0),
5479 NULL
, NULL
, RES_TYPE_NUMBER
);
5480 x_default_parameter (f
, parameters
, Qbottom_divider_width
, make_number (0),
5481 NULL
, NULL
, RES_TYPE_NUMBER
);
5482 x_default_parameter (f
, parameters
, Qvertical_scroll_bars
, Qright
,
5483 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
5484 x_default_parameter (f
, parameters
, Qhorizontal_scroll_bars
, Qnil
,
5485 "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL
);
5487 /* Also do the stuff which must be set before the window exists. */
5488 x_default_parameter (f
, parameters
, Qforeground_color
, build_string ("black"),
5489 "foreground", "Foreground", RES_TYPE_STRING
);
5490 x_default_parameter (f
, parameters
, Qbackground_color
, build_string ("white"),
5491 "background", "Background", RES_TYPE_STRING
);
5492 x_default_parameter (f
, parameters
, Qmouse_color
, build_string ("black"),
5493 "pointerColor", "Foreground", RES_TYPE_STRING
);
5494 x_default_parameter (f
, parameters
, Qborder_color
, build_string ("black"),
5495 "borderColor", "BorderColor", RES_TYPE_STRING
);
5496 x_default_parameter (f
, parameters
, Qscreen_gamma
, Qnil
,
5497 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT
);
5498 x_default_parameter (f
, parameters
, Qline_spacing
, Qnil
,
5499 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER
);
5500 x_default_parameter (f
, parameters
, Qleft_fringe
, Qnil
,
5501 "leftFringe", "LeftFringe", RES_TYPE_NUMBER
);
5502 x_default_parameter (f
, parameters
, Qright_fringe
, Qnil
,
5503 "rightFringe", "RightFringe", RES_TYPE_NUMBER
);
5504 /* Process alpha here (Bug#16619). */
5505 x_default_parameter (f
, parameters
, Qalpha
, Qnil
,
5506 "alpha", "Alpha", RES_TYPE_NUMBER
);
5508 /* Init faces first since we need the frame's column width/line
5509 height in various occasions. */
5510 init_frame_faces (f
);
5512 /* The following call of change_frame_size is needed since otherwise
5513 x_set_tool_bar_lines will already work with the character sizes
5514 installed by init_frame_faces while the frame's pixel size is
5515 still calculated from a character size of 1 and we subsequently
5516 hit the (height >= 0) assertion in window_box_height.
5518 The non-pixelwise code apparently worked around this because it
5519 had one frame line vs one toolbar line which left us with a zero
5520 root window height which was obviously wrong as well ... */
5521 adjust_frame_size (f
, FRAME_COLS (f
) * FRAME_COLUMN_WIDTH (f
),
5522 FRAME_LINES (f
) * FRAME_LINE_HEIGHT (f
), 5, true,
5525 /* The X resources controlling the menu-bar and tool-bar are
5526 processed specially at startup, and reflected in the mode
5527 variables; ignore them here. */
5528 x_default_parameter (f
, parameters
, Qmenu_bar_lines
,
5529 NILP (Vmenu_bar_mode
)
5530 ? make_number (0) : make_number (1),
5531 NULL
, NULL
, RES_TYPE_NUMBER
);
5532 x_default_parameter (f
, parameters
, Qtool_bar_lines
,
5533 NILP (Vtool_bar_mode
)
5534 ? make_number (0) : make_number (1),
5535 NULL
, NULL
, RES_TYPE_NUMBER
);
5537 x_default_parameter (f
, parameters
, Qbuffer_predicate
, Qnil
,
5538 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL
);
5539 x_default_parameter (f
, parameters
, Qtitle
, Qnil
,
5540 "title", "Title", RES_TYPE_STRING
);
5542 f
->output_data
.w32
->dwStyle
= WS_OVERLAPPEDWINDOW
;
5543 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
5545 f
->output_data
.w32
->text_cursor
= w32_load_cursor (IDC_IBEAM
);
5546 f
->output_data
.w32
->nontext_cursor
= w32_load_cursor (IDC_ARROW
);
5547 f
->output_data
.w32
->modeline_cursor
= w32_load_cursor (IDC_ARROW
);
5548 f
->output_data
.w32
->hand_cursor
= w32_load_cursor (IDC_HAND
);
5549 f
->output_data
.w32
->hourglass_cursor
= w32_load_cursor (IDC_WAIT
);
5550 f
->output_data
.w32
->horizontal_drag_cursor
= w32_load_cursor (IDC_SIZEWE
);
5551 f
->output_data
.w32
->vertical_drag_cursor
= w32_load_cursor (IDC_SIZENS
);
5553 f
->output_data
.w32
->current_cursor
= f
->output_data
.w32
->nontext_cursor
;
5555 window_prompting
= x_figure_window_size (f
, parameters
, true, &x_width
, &x_height
);
5557 tem
= x_get_arg (dpyinfo
, parameters
, Qunsplittable
, 0, 0, RES_TYPE_BOOLEAN
);
5558 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
5560 w32_window (f
, window_prompting
, minibuffer_only
);
5561 x_icon (f
, parameters
);
5565 /* Now consider the frame official. */
5566 f
->terminal
->reference_count
++;
5567 FRAME_DISPLAY_INFO (f
)->reference_count
++;
5568 Vframe_list
= Fcons (frame
, Vframe_list
);
5570 /* We need to do this after creating the window, so that the
5571 icon-creation functions can say whose icon they're describing. */
5572 x_default_parameter (f
, parameters
, Qicon_type
, Qnil
,
5573 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL
);
5575 x_default_parameter (f
, parameters
, Qauto_raise
, Qnil
,
5576 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5577 x_default_parameter (f
, parameters
, Qauto_lower
, Qnil
,
5578 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
5579 x_default_parameter (f
, parameters
, Qcursor_type
, Qbox
,
5580 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
5581 x_default_parameter (f
, parameters
, Qscroll_bar_width
, Qnil
,
5582 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER
);
5583 x_default_parameter (f
, parameters
, Qscroll_bar_height
, Qnil
,
5584 "scrollBarHeight", "ScrollBarHeight", RES_TYPE_NUMBER
);
5586 /* Allow x_set_window_size, now. */
5587 f
->can_x_set_window_size
= true;
5590 SET_FRAME_WIDTH (f
, x_width
);
5592 SET_FRAME_HEIGHT (f
, x_height
);
5594 /* Tell the server what size and position, etc, we want, and how
5595 badly we want them. This should be done after we have the menu
5596 bar so that its size can be taken into account. */
5598 x_wm_set_size_hint (f
, window_prompting
, false);
5601 adjust_frame_size (f
, FRAME_TEXT_WIDTH (f
), FRAME_TEXT_HEIGHT (f
), 0, true,
5604 /* Process fullscreen parameter here in the hope that normalizing a
5605 fullheight/fullwidth frame will produce the size set by the last
5606 adjust_frame_size call. */
5607 x_default_parameter (f
, parameters
, Qfullscreen
, Qnil
,
5608 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL
);
5610 /* Make the window appear on the frame and enable display, unless
5611 the caller says not to. However, with explicit parent, Emacs
5612 cannot control visibility, so don't try. */
5613 if (! f
->output_data
.w32
->explicit_parent
)
5615 Lisp_Object visibility
;
5617 visibility
= x_get_arg (dpyinfo
, parameters
, Qvisibility
, 0, 0, RES_TYPE_SYMBOL
);
5618 if (EQ (visibility
, Qunbound
))
5621 if (EQ (visibility
, Qicon
))
5622 x_iconify_frame (f
);
5623 else if (! NILP (visibility
))
5624 x_make_frame_visible (f
);
5627 /* Must have been Qnil. */
5632 /* Initialize `default-minibuffer-frame' in case this is the first
5633 frame on this terminal. */
5634 if (FRAME_HAS_MINIBUF_P (f
)
5635 && (!FRAMEP (KVAR (kb
, Vdefault_minibuffer_frame
))
5636 || !FRAME_LIVE_P (XFRAME (KVAR (kb
, Vdefault_minibuffer_frame
)))))
5637 kset_default_minibuffer_frame (kb
, frame
);
5639 /* All remaining specified parameters, which have not been "used"
5640 by x_get_arg and friends, now go in the misc. alist of the frame. */
5641 for (tem
= parameters
; CONSP (tem
); tem
= XCDR (tem
))
5642 if (CONSP (XCAR (tem
)) && !NILP (XCAR (XCAR (tem
))))
5643 fset_param_alist (f
, Fcons (XCAR (tem
), f
->param_alist
));
5645 /* Make sure windows on this frame appear in calls to next-window
5646 and similar functions. */
5647 Vwindow_list
= Qnil
;
5649 return unbind_to (count
, frame
);
5652 /* FRAME is used only to get a handle on the X display. We don't pass the
5653 display info directly because we're called from frame.c, which doesn't
5654 know about that structure. */
5656 x_get_focus_frame (struct frame
*frame
)
5658 struct w32_display_info
*dpyinfo
= FRAME_DISPLAY_INFO (frame
);
5660 if (! dpyinfo
->w32_focus_frame
)
5663 XSETFRAME (xfocus
, dpyinfo
->w32_focus_frame
);
5667 DEFUN ("xw-color-defined-p", Fxw_color_defined_p
, Sxw_color_defined_p
, 1, 2, 0,
5668 doc
: /* Internal function called by `color-defined-p', which see.
5669 \(Note that the Nextstep version of this function ignores FRAME.) */)
5670 (Lisp_Object color
, Lisp_Object frame
)
5673 struct frame
*f
= decode_window_system_frame (frame
);
5675 CHECK_STRING (color
);
5677 if (w32_defined_color (f
, SSDATA (color
), &foo
, false))
5683 DEFUN ("xw-color-values", Fxw_color_values
, Sxw_color_values
, 1, 2, 0,
5684 doc
: /* Internal function called by `color-values', which see. */)
5685 (Lisp_Object color
, Lisp_Object frame
)
5688 struct frame
*f
= decode_window_system_frame (frame
);
5690 CHECK_STRING (color
);
5692 if (w32_defined_color (f
, SSDATA (color
), &foo
, false))
5693 return list3i ((GetRValue (foo
.pixel
) << 8) | GetRValue (foo
.pixel
),
5694 (GetGValue (foo
.pixel
) << 8) | GetGValue (foo
.pixel
),
5695 (GetBValue (foo
.pixel
) << 8) | GetBValue (foo
.pixel
));
5700 DEFUN ("xw-display-color-p", Fxw_display_color_p
, Sxw_display_color_p
, 0, 1, 0,
5701 doc
: /* Internal function called by `display-color-p', which see. */)
5702 (Lisp_Object display
)
5704 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5706 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
5712 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
,
5713 Sx_display_grayscale_p
, 0, 1, 0,
5714 doc
: /* Return t if DISPLAY supports shades of gray.
5715 Note that color displays do support shades of gray.
5716 The optional argument DISPLAY specifies which display to ask about.
5717 DISPLAY should be either a frame or a display name (a string).
5718 If omitted or nil, that stands for the selected frame's display. */)
5719 (Lisp_Object display
)
5721 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5723 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
5729 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
,
5730 Sx_display_pixel_width
, 0, 1, 0,
5731 doc
: /* Return the width in pixels of DISPLAY.
5732 The optional argument DISPLAY specifies which display to ask about.
5733 DISPLAY should be either a frame or a display name (a string).
5734 If omitted or nil, that stands for the selected frame's display.
5736 On \"multi-monitor\" setups this refers to the pixel width for all
5737 physical monitors associated with DISPLAY. To get information for
5738 each physical monitor, use `display-monitor-attributes-list'. */)
5739 (Lisp_Object display
)
5741 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5743 return make_number (x_display_pixel_width (dpyinfo
));
5746 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
5747 Sx_display_pixel_height
, 0, 1, 0,
5748 doc
: /* Return the height in pixels of DISPLAY.
5749 The optional argument DISPLAY specifies which display to ask about.
5750 DISPLAY should be either a frame or a display name (a string).
5751 If omitted or nil, that stands for the selected frame's display.
5753 On \"multi-monitor\" setups this refers to the pixel height for all
5754 physical monitors associated with DISPLAY. To get information for
5755 each physical monitor, use `display-monitor-attributes-list'. */)
5756 (Lisp_Object display
)
5758 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5760 return make_number (x_display_pixel_height (dpyinfo
));
5763 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
5765 doc
: /* Return the number of bitplanes of DISPLAY.
5766 The optional argument DISPLAY specifies which display to ask about.
5767 DISPLAY should be either a frame or a display name (a string).
5768 If omitted or nil, that stands for the selected frame's display. */)
5769 (Lisp_Object display
)
5771 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5773 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
5776 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
5778 doc
: /* Return the number of color cells of DISPLAY.
5779 The optional argument DISPLAY specifies which display to ask about.
5780 DISPLAY should be either a frame or a display name (a string).
5781 If omitted or nil, that stands for the selected frame's display. */)
5782 (Lisp_Object display
)
5784 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5787 /* Don't use NCOLORS: it returns incorrect results under remote
5788 * desktop. We force 24+ bit depths to 24-bit, both to prevent an
5789 * overflow and because probably is more meaningful on Windows
5792 cap
= 1 << min (dpyinfo
->n_planes
* dpyinfo
->n_cbits
, 24);
5793 return make_number (cap
);
5796 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
5797 Sx_server_max_request_size
,
5799 doc
: /* Return the maximum request size of the server of DISPLAY.
5800 The optional argument DISPLAY specifies which display to ask about.
5801 DISPLAY should be either a frame or a display name (a string).
5802 If omitted or nil, that stands for the selected frame's display. */)
5803 (Lisp_Object display
)
5805 return make_number (1);
5808 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
5809 doc
: /* Return the "vendor ID" string of the GUI software on TERMINAL.
5811 \(Labeling every distributor as a "vendor" embodies the false assumption
5812 that operating systems cannot be developed and distributed noncommercially.)
5814 For GNU and Unix systems, this queries the X server software; for
5815 MS-Windows, this queries the OS.
5817 The optional argument TERMINAL specifies which display to ask about.
5818 TERMINAL should be a terminal object, a frame or a display name (a string).
5819 If omitted or nil, that stands for the selected frame's display. */)
5820 (Lisp_Object terminal
)
5822 return build_string ("Microsoft Corp.");
5825 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
5826 doc
: /* Return the version numbers of the GUI software on TERMINAL.
5827 The value is a list of three integers specifying the version of the GUI
5830 For GNU and Unix system, the first 2 numbers are the version of the X
5831 Protocol used on TERMINAL and the 3rd number is the distributor-specific
5832 release number. For MS-Windows, the 3 numbers report the version and
5833 the build number of the OS.
5835 See also the function `x-server-vendor'.
5837 The optional argument TERMINAL specifies which display to ask about.
5838 TERMINAL should be a terminal object, a frame or a display name (a string).
5839 If omitted or nil, that stands for the selected frame's display. */)
5840 (Lisp_Object terminal
)
5842 return list3i (w32_major_version
, w32_minor_version
, w32_build_number
);
5845 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
5846 doc
: /* Return the number of screens on the server of DISPLAY.
5847 The optional argument DISPLAY specifies which display to ask about.
5848 DISPLAY should be either a frame or a display name (a string).
5849 If omitted or nil, that stands for the selected frame's display. */)
5850 (Lisp_Object display
)
5852 return make_number (1);
5855 DEFUN ("x-display-mm-height", Fx_display_mm_height
,
5856 Sx_display_mm_height
, 0, 1, 0,
5857 doc
: /* Return the height in millimeters of DISPLAY.
5858 The optional argument DISPLAY specifies which display to ask about.
5859 DISPLAY should be either a frame or a display name (a string).
5860 If omitted or nil, that stands for the selected frame's display.
5862 On \"multi-monitor\" setups this refers to the height in millimeters for
5863 all physical monitors associated with DISPLAY. To get information
5864 for each physical monitor, use `display-monitor-attributes-list'. */)
5865 (Lisp_Object display
)
5867 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5869 double mm_per_pixel
;
5872 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, VERTSIZE
)
5873 / GetDeviceCaps (hdc
, VERTRES
));
5874 ReleaseDC (NULL
, hdc
);
5876 return make_number (x_display_pixel_height (dpyinfo
) * mm_per_pixel
+ 0.5);
5879 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
5880 doc
: /* Return the width in millimeters of DISPLAY.
5881 The optional argument DISPLAY specifies which display to ask about.
5882 DISPLAY should be either a frame or a display name (a string).
5883 If omitted or nil, that stands for the selected frame's display.
5885 On \"multi-monitor\" setups this refers to the width in millimeters for
5886 all physical monitors associated with TERMINAL. To get information
5887 for each physical monitor, use `display-monitor-attributes-list'. */)
5888 (Lisp_Object display
)
5890 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5892 double mm_per_pixel
;
5895 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, HORZSIZE
)
5896 / GetDeviceCaps (hdc
, HORZRES
));
5897 ReleaseDC (NULL
, hdc
);
5899 return make_number (x_display_pixel_width (dpyinfo
) * mm_per_pixel
+ 0.5);
5902 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
5903 Sx_display_backing_store
, 0, 1, 0,
5904 doc
: /* Return an indication of whether DISPLAY does backing store.
5905 The value may be `always', `when-mapped', or `not-useful'.
5906 The optional argument DISPLAY specifies which display to ask about.
5907 DISPLAY should be either a frame or a display name (a string).
5908 If omitted or nil, that stands for the selected frame's display. */)
5909 (Lisp_Object display
)
5911 return intern ("not-useful");
5914 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
5915 Sx_display_visual_class
, 0, 1, 0,
5916 doc
: /* Return the visual class of DISPLAY.
5917 The value is one of the symbols `static-gray', `gray-scale',
5918 `static-color', `pseudo-color', `true-color', or `direct-color'.
5920 The optional argument DISPLAY specifies which display to ask about.
5921 DISPLAY should be either a frame or a display name (a string).
5922 If omitted or nil, that stands for the selected frame's display. */)
5923 (Lisp_Object display
)
5925 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5926 Lisp_Object result
= Qnil
;
5928 if (dpyinfo
->has_palette
)
5929 result
= intern ("pseudo-color");
5930 else if (dpyinfo
->n_planes
* dpyinfo
->n_cbits
== 1)
5931 result
= intern ("static-grey");
5932 else if (dpyinfo
->n_planes
* dpyinfo
->n_cbits
== 4)
5933 result
= intern ("static-color");
5934 else if (dpyinfo
->n_planes
* dpyinfo
->n_cbits
> 8)
5935 result
= intern ("true-color");
5940 DEFUN ("x-display-save-under", Fx_display_save_under
,
5941 Sx_display_save_under
, 0, 1, 0,
5942 doc
: /* Return t if DISPLAY supports the save-under feature.
5943 The optional argument DISPLAY specifies which display to ask about.
5944 DISPLAY should be either a frame or a display name (a string).
5945 If omitted or nil, that stands for the selected frame's display. */)
5946 (Lisp_Object display
)
5951 static BOOL CALLBACK ALIGN_STACK
5952 w32_monitor_enum (HMONITOR monitor
, HDC hdc
, RECT
*rcMonitor
, LPARAM dwData
)
5954 Lisp_Object
*monitor_list
= (Lisp_Object
*) dwData
;
5956 *monitor_list
= Fcons (make_save_ptr (monitor
), *monitor_list
);
5962 w32_display_monitor_attributes_list (void)
5964 Lisp_Object attributes_list
= Qnil
, primary_monitor_attributes
= Qnil
;
5965 Lisp_Object monitor_list
= Qnil
, monitor_frames
, rest
, frame
;
5969 if (!(enum_display_monitors_fn
&& get_monitor_info_fn
5970 && monitor_from_window_fn
))
5973 if (!enum_display_monitors_fn (NULL
, NULL
, w32_monitor_enum
,
5974 (LPARAM
) &monitor_list
)
5975 || NILP (monitor_list
))
5979 for (rest
= monitor_list
; CONSP (rest
); rest
= XCDR (rest
))
5982 monitors
= xmalloc (n_monitors
* sizeof (*monitors
));
5983 for (i
= 0; i
< n_monitors
; i
++)
5985 monitors
[i
] = XSAVE_POINTER (XCAR (monitor_list
), 0);
5986 monitor_list
= XCDR (monitor_list
);
5989 monitor_frames
= Fmake_vector (make_number (n_monitors
), Qnil
);
5990 FOR_EACH_FRAME (rest
, frame
)
5992 struct frame
*f
= XFRAME (frame
);
5994 if (FRAME_W32_P (f
) && !EQ (frame
, tip_frame
))
5997 monitor_from_window_fn (FRAME_W32_WINDOW (f
),
5998 MONITOR_DEFAULT_TO_NEAREST
);
6000 for (i
= 0; i
< n_monitors
; i
++)
6001 if (monitors
[i
] == monitor
)
6005 ASET (monitor_frames
, i
, Fcons (frame
, AREF (monitor_frames
, i
)));
6009 for (i
= 0; i
< n_monitors
; i
++)
6011 Lisp_Object geometry
, workarea
, name
, attributes
= Qnil
;
6013 int width_mm
, height_mm
;
6014 struct MONITOR_INFO_EX mi
;
6016 mi
.cbSize
= sizeof (mi
);
6017 if (!get_monitor_info_fn (monitors
[i
], (struct MONITOR_INFO
*) &mi
))
6020 hdc
= CreateDCA ("DISPLAY", mi
.szDevice
, NULL
, NULL
);
6023 width_mm
= GetDeviceCaps (hdc
, HORZSIZE
);
6024 height_mm
= GetDeviceCaps (hdc
, VERTSIZE
);
6027 attributes
= Fcons (Fcons (Qframes
, AREF (monitor_frames
, i
)),
6030 name
= DECODE_SYSTEM (build_unibyte_string (mi
.szDevice
));
6032 attributes
= Fcons (Fcons (Qname
, name
), attributes
);
6034 attributes
= Fcons (Fcons (Qmm_size
, list2i (width_mm
, height_mm
)),
6037 workarea
= list4i (mi
.rcWork
.left
, mi
.rcWork
.top
,
6038 mi
.rcWork
.right
- mi
.rcWork
.left
,
6039 mi
.rcWork
.bottom
- mi
.rcWork
.top
);
6040 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
6042 geometry
= list4i (mi
.rcMonitor
.left
, mi
.rcMonitor
.top
,
6043 mi
.rcMonitor
.right
- mi
.rcMonitor
.left
,
6044 mi
.rcMonitor
.bottom
- mi
.rcMonitor
.top
);
6045 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
6047 if (mi
.dwFlags
& MONITORINFOF_PRIMARY
)
6048 primary_monitor_attributes
= attributes
;
6050 attributes_list
= Fcons (attributes
, attributes_list
);
6053 if (!NILP (primary_monitor_attributes
))
6054 attributes_list
= Fcons (primary_monitor_attributes
, attributes_list
);
6058 return attributes_list
;
6062 w32_display_monitor_attributes_list_fallback (struct w32_display_info
*dpyinfo
)
6064 Lisp_Object geometry
, workarea
, frames
, rest
, frame
, attributes
= Qnil
;
6066 double mm_per_pixel
;
6067 int pixel_width
, pixel_height
, width_mm
, height_mm
;
6070 /* Fallback: treat (possibly) multiple physical monitors as if they
6071 formed a single monitor as a whole. This should provide a
6072 consistent result at least on single monitor environments. */
6073 attributes
= Fcons (Fcons (Qname
, build_string ("combined screen")),
6077 FOR_EACH_FRAME (rest
, frame
)
6079 struct frame
*f
= XFRAME (frame
);
6081 if (FRAME_W32_P (f
) && !EQ (frame
, tip_frame
))
6082 frames
= Fcons (frame
, frames
);
6084 attributes
= Fcons (Fcons (Qframes
, frames
), attributes
);
6086 pixel_width
= x_display_pixel_width (dpyinfo
);
6087 pixel_height
= x_display_pixel_height (dpyinfo
);
6090 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, HORZSIZE
)
6091 / GetDeviceCaps (hdc
, HORZRES
));
6092 width_mm
= pixel_width
* mm_per_pixel
+ 0.5;
6093 mm_per_pixel
= ((double) GetDeviceCaps (hdc
, VERTSIZE
)
6094 / GetDeviceCaps (hdc
, VERTRES
));
6095 height_mm
= pixel_height
* mm_per_pixel
+ 0.5;
6096 ReleaseDC (NULL
, hdc
);
6097 attributes
= Fcons (Fcons (Qmm_size
, list2i (width_mm
, height_mm
)),
6100 /* GetSystemMetrics below may return 0 for Windows 95 or NT 4.0, but
6102 geometry
= list4i (GetSystemMetrics (SM_XVIRTUALSCREEN
),
6103 GetSystemMetrics (SM_YVIRTUALSCREEN
),
6104 pixel_width
, pixel_height
);
6105 if (SystemParametersInfo (SPI_GETWORKAREA
, 0, &workarea_rect
, 0))
6106 workarea
= list4i (workarea_rect
.left
, workarea_rect
.top
,
6107 workarea_rect
.right
- workarea_rect
.left
,
6108 workarea_rect
.bottom
- workarea_rect
.top
);
6110 workarea
= geometry
;
6111 attributes
= Fcons (Fcons (Qworkarea
, workarea
), attributes
);
6113 attributes
= Fcons (Fcons (Qgeometry
, geometry
), attributes
);
6115 return list1 (attributes
);
6118 DEFUN ("w32-display-monitor-attributes-list", Fw32_display_monitor_attributes_list
,
6119 Sw32_display_monitor_attributes_list
,
6121 doc
: /* Return a list of physical monitor attributes on the W32 display DISPLAY.
6123 The optional argument DISPLAY specifies which display to ask about.
6124 DISPLAY should be either a frame or a display name (a string).
6125 If omitted or nil, that stands for the selected frame's display.
6127 Internal use only, use `display-monitor-attributes-list' instead. */)
6128 (Lisp_Object display
)
6130 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6131 Lisp_Object attributes_list
;
6134 attributes_list
= w32_display_monitor_attributes_list ();
6135 if (NILP (attributes_list
))
6136 attributes_list
= w32_display_monitor_attributes_list_fallback (dpyinfo
);
6139 return attributes_list
;
6142 DEFUN ("set-message-beep", Fset_message_beep
, Sset_message_beep
, 1, 1, 0,
6143 doc
: /* Set the sound generated when the bell is rung.
6144 SOUND is `asterisk', `exclamation', `hand', `question', `ok', or `silent'
6145 to use the corresponding system sound for the bell. The `silent' sound
6146 prevents Emacs from making any sound at all.
6147 SOUND is nil to use the normal beep. */)
6150 CHECK_SYMBOL (sound
);
6153 sound_type
= 0xFFFFFFFF;
6154 else if (EQ (sound
, intern ("asterisk")))
6155 sound_type
= MB_ICONASTERISK
;
6156 else if (EQ (sound
, intern ("exclamation")))
6157 sound_type
= MB_ICONEXCLAMATION
;
6158 else if (EQ (sound
, intern ("hand")))
6159 sound_type
= MB_ICONHAND
;
6160 else if (EQ (sound
, intern ("question")))
6161 sound_type
= MB_ICONQUESTION
;
6162 else if (EQ (sound
, intern ("ok")))
6164 else if (EQ (sound
, intern ("silent")))
6165 sound_type
= MB_EMACS_SILENT
;
6167 sound_type
= 0xFFFFFFFF;
6174 x_screen_planes (register struct frame
*f
)
6176 return FRAME_DISPLAY_INFO (f
)->n_planes
;
6180 /* Return the display structure for the display named NAME.
6181 Open a new connection if necessary. */
6183 struct w32_display_info
*
6184 x_display_info_for_name (Lisp_Object name
)
6186 struct w32_display_info
*dpyinfo
;
6188 CHECK_STRING (name
);
6190 for (dpyinfo
= &one_w32_display_info
; dpyinfo
; dpyinfo
= dpyinfo
->next
)
6191 if (!NILP (Fstring_equal (XCAR (dpyinfo
->name_list_element
), name
)))
6194 /* Use this general default value to start with. */
6195 Vx_resource_name
= Vinvocation_name
;
6197 validate_x_resource_name ();
6199 dpyinfo
= w32_term_init (name
, NULL
, SSDATA (Vx_resource_name
));
6202 error ("Cannot connect to server %s", SDATA (name
));
6204 XSETFASTINT (Vwindow_system_version
, w32_major_version
);
6209 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
6210 1, 3, 0, doc
: /* Open a connection to a display server.
6211 DISPLAY is the name of the display to connect to.
6212 Optional second arg XRM-STRING is a string of resources in xrdb format.
6213 If the optional third arg MUST-SUCCEED is non-nil,
6214 terminate Emacs if we can't open the connection.
6215 \(In the Nextstep version, the last two arguments are currently ignored.) */)
6216 (Lisp_Object display
, Lisp_Object xrm_string
, Lisp_Object must_succeed
)
6219 struct w32_display_info
*dpyinfo
;
6221 CHECK_STRING (display
);
6223 /* Signal an error in order to encourage correct use from callers.
6224 * If we ever support multiple window systems in the same Emacs,
6225 * we'll need callers to be precise about what window system they
6228 if (strcmp (SSDATA (display
), "w32") != 0)
6229 error ("The name of the display in this Emacs must be \"w32\"");
6231 /* If initialization has already been done, return now to avoid
6232 overwriting critical parts of one_w32_display_info. */
6233 if (window_system_available (NULL
))
6236 if (! NILP (xrm_string
))
6237 CHECK_STRING (xrm_string
);
6239 /* Allow color mapping to be defined externally; first look in user's
6240 HOME directory, then in Emacs etc dir for a file called rgb.txt. */
6242 Lisp_Object color_file
;
6244 color_file
= build_string ("~/rgb.txt");
6246 if (NILP (Ffile_readable_p (color_file
)))
6248 Fexpand_file_name (build_string ("rgb.txt"),
6249 Fsymbol_value (intern ("data-directory")));
6251 Vw32_color_map
= Fx_load_color_file (color_file
);
6253 if (NILP (Vw32_color_map
))
6254 Vw32_color_map
= w32_default_color_map ();
6256 /* Merge in system logical colors. */
6257 add_system_logical_colors_to_map (&Vw32_color_map
);
6259 if (! NILP (xrm_string
))
6260 xrm_option
= SSDATA (xrm_string
);
6264 /* Use this general default value to start with. */
6265 /* First remove .exe suffix from invocation-name - it looks ugly. */
6267 char basename
[ MAX_PATH
], *str
;
6269 lispstpcpy (basename
, Vinvocation_name
);
6270 str
= strrchr (basename
, '.');
6272 Vinvocation_name
= build_string (basename
);
6274 Vx_resource_name
= Vinvocation_name
;
6276 validate_x_resource_name ();
6278 /* This is what opens the connection and sets x_current_display.
6279 This also initializes many symbols, such as those used for input. */
6280 dpyinfo
= w32_term_init (display
, xrm_option
, SSDATA (Vx_resource_name
));
6284 if (!NILP (must_succeed
))
6285 fatal ("Cannot connect to server %s.\n",
6288 error ("Cannot connect to server %s", SDATA (display
));
6291 XSETFASTINT (Vwindow_system_version
, w32_major_version
);
6295 DEFUN ("x-close-connection", Fx_close_connection
,
6296 Sx_close_connection
, 1, 1, 0,
6297 doc
: /* Close the connection to DISPLAY's server.
6298 For DISPLAY, specify either a frame or a display name (a string).
6299 If DISPLAY is nil, that stands for the selected frame's display. */)
6300 (Lisp_Object display
)
6302 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6304 if (dpyinfo
->reference_count
> 0)
6305 error ("Display still has frames on it");
6308 x_destroy_all_bitmaps (dpyinfo
);
6310 x_delete_display (dpyinfo
);
6316 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
6317 doc
: /* Return the list of display names that Emacs has connections to. */)
6320 Lisp_Object result
= Qnil
;
6321 struct w32_display_info
*wdi
;
6323 for (wdi
= x_display_list
; wdi
; wdi
= wdi
->next
)
6324 result
= Fcons (XCAR (wdi
->name_list_element
), result
);
6329 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
6330 doc
: /* If ON is non-nil, report X errors as soon as the erring request is made.
6331 This function only has an effect on X Windows. With MS Windows, it is
6332 defined but does nothing.
6334 If ON is nil, allow buffering of requests.
6335 Turning on synchronization prohibits the Xlib routines from buffering
6336 requests and seriously degrades performance, but makes debugging much
6338 The optional second argument TERMINAL specifies which display to act on.
6339 TERMINAL should be a terminal object, a frame or a display name (a string).
6340 If TERMINAL is omitted or nil, that stands for the selected frame's display. */)
6341 (Lisp_Object on
, Lisp_Object display
)
6348 /***********************************************************************
6350 ***********************************************************************/
6352 #if 0 /* TODO : port window properties to W32 */
6354 DEFUN ("x-change-window-property", Fx_change_window_property
,
6355 Sx_change_window_property
, 2, 6, 0,
6356 doc
: /* Change window property PROP to VALUE on the X window of FRAME.
6357 PROP must be a string. VALUE may be a string or a list of conses,
6358 numbers and/or strings. If an element in the list is a string, it is
6359 converted to an atom and the value of the Atom is used. If an element
6360 is a cons, it is converted to a 32 bit number where the car is the 16
6361 top bits and the cdr is the lower 16 bits.
6363 FRAME nil or omitted means use the selected frame.
6364 If TYPE is given and non-nil, it is the name of the type of VALUE.
6365 If TYPE is not given or nil, the type is STRING.
6366 FORMAT gives the size in bits of each element if VALUE is a list.
6367 It must be one of 8, 16 or 32.
6368 If VALUE is a string or FORMAT is nil or not given, FORMAT defaults to 8.
6369 If OUTER-P is non-nil, the property is changed for the outer X window of
6370 FRAME. Default is to change on the edit X window. */)
6371 (Lisp_Object prop
, Lisp_Object value
, Lisp_Object frame
,
6372 Lisp_Object type
, Lisp_Object format
, Lisp_Object outer_p
)
6374 struct frame
*f
= decode_window_system_frame (frame
);
6377 CHECK_STRING (prop
);
6378 CHECK_STRING (value
);
6381 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
6382 XChangeProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
6383 prop_atom
, XA_STRING
, 8, PropModeReplace
,
6384 SDATA (value
), SCHARS (value
));
6386 /* Make sure the property is set when we return. */
6387 XFlush (FRAME_W32_DISPLAY (f
));
6394 DEFUN ("x-delete-window-property", Fx_delete_window_property
,
6395 Sx_delete_window_property
, 1, 2, 0,
6396 doc
: /* Remove window property PROP from X window of FRAME.
6397 FRAME nil or omitted means use the selected frame. Value is PROP. */)
6398 (Lisp_Object prop
, Lisp_Object frame
)
6400 struct frame
*f
= decode_window_system_frame (frame
);
6403 CHECK_STRING (prop
);
6405 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
6406 XDeleteProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), prop_atom
);
6408 /* Make sure the property is removed when we return. */
6409 XFlush (FRAME_W32_DISPLAY (f
));
6416 DEFUN ("x-window-property", Fx_window_property
, Sx_window_property
,
6418 doc
: /* Value is the value of window property PROP on FRAME.
6419 If FRAME is nil or omitted, use the selected frame.
6421 On X Windows, the following optional arguments are also accepted:
6422 If TYPE is nil or omitted, get the property as a string.
6423 Otherwise TYPE is the name of the atom that denotes the type expected.
6424 If SOURCE is non-nil, get the property on that window instead of from
6425 FRAME. The number 0 denotes the root window.
6426 If DELETE-P is non-nil, delete the property after retrieving it.
6427 If VECTOR-RET-P is non-nil, don't return a string but a vector of values.
6429 On MS Windows, this function accepts but ignores those optional arguments.
6431 Value is nil if FRAME hasn't a property with name PROP or if PROP has
6432 no value of TYPE (always string in the MS Windows case). */)
6433 (Lisp_Object prop
, Lisp_Object frame
, Lisp_Object type
,
6434 Lisp_Object source
, Lisp_Object delete_p
, Lisp_Object vector_ret_p
)
6436 struct frame
*f
= decode_window_system_frame (frame
);
6439 Lisp_Object prop_value
= Qnil
;
6440 char *tmp_data
= NULL
;
6443 unsigned long actual_size
, bytes_remaining
;
6445 CHECK_STRING (prop
);
6447 prop_atom
= XInternAtom (FRAME_W32_DISPLAY (f
), SDATA (prop
), False
);
6448 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
6449 prop_atom
, 0, 0, False
, XA_STRING
,
6450 &actual_type
, &actual_format
, &actual_size
,
6451 &bytes_remaining
, (unsigned char **) &tmp_data
);
6454 int size
= bytes_remaining
;
6459 rc
= XGetWindowProperty (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
6460 prop_atom
, 0, bytes_remaining
,
6462 &actual_type
, &actual_format
,
6463 &actual_size
, &bytes_remaining
,
6464 (unsigned char **) &tmp_data
);
6466 prop_value
= make_string (tmp_data
, size
);
6480 /***********************************************************************
6482 ***********************************************************************/
6484 static void compute_tip_xy (struct frame
*, Lisp_Object
, Lisp_Object
,
6485 Lisp_Object
, int, int, int *, int *);
6487 /* The frame of a currently visible tooltip. */
6489 Lisp_Object tip_frame
;
6491 /* If non-nil, a timer started that hides the last tooltip when it
6494 Lisp_Object tip_timer
;
6497 /* If non-nil, a vector of 3 elements containing the last args
6498 with which x-show-tip was called. See there. */
6500 Lisp_Object last_show_tip_args
;
6504 unwind_create_tip_frame (Lisp_Object frame
)
6506 Lisp_Object deleted
;
6508 deleted
= unwind_create_frame (frame
);
6509 if (EQ (deleted
, Qt
))
6517 /* Create a frame for a tooltip on the display described by DPYINFO.
6518 PARMS is a list of frame parameters. Value is the frame.
6520 Note that functions called here, esp. x_default_parameter can
6521 signal errors, for instance when a specified color name is
6522 undefined. We have to make sure that we're in a consistent state
6523 when this happens. */
6526 x_create_tip_frame (struct w32_display_info
*dpyinfo
, Lisp_Object parms
)
6532 ptrdiff_t count
= SPECPDL_INDEX ();
6534 bool face_change_before
= face_change
;
6535 int x_width
= 0, x_height
= 0;
6537 /* Use this general default value to start with until we know if
6538 this frame has a specified name. */
6539 Vx_resource_name
= Vinvocation_name
;
6541 kb
= dpyinfo
->terminal
->kboard
;
6543 /* The calls to x_get_arg remove elements from PARMS, so copy it to
6544 avoid destructive changes behind our caller's back. */
6545 parms
= Fcopy_alist (parms
);
6547 /* Get the name of the frame to use for resource lookup. */
6548 name
= x_get_arg (dpyinfo
, parms
, Qname
, "name", "Name", RES_TYPE_STRING
);
6550 && !EQ (name
, Qunbound
)
6552 error ("Invalid frame name--not a string or nil");
6553 Vx_resource_name
= name
;
6556 /* Make a frame without minibuffer nor mode-line. */
6557 f
= make_frame (false);
6558 f
->wants_modeline
= false;
6559 XSETFRAME (frame
, f
);
6561 record_unwind_protect (unwind_create_tip_frame
, frame
);
6563 /* By setting the output method, we're essentially saying that
6564 the frame is live, as per FRAME_LIVE_P. If we get a signal
6565 from this point on, x_destroy_window might screw up reference
6567 f
->terminal
= dpyinfo
->terminal
;
6568 f
->output_method
= output_w32
;
6569 f
->output_data
.w32
= xzalloc (sizeof (struct w32_output
));
6571 FRAME_FONTSET (f
) = -1;
6572 fset_icon_name (f
, Qnil
);
6575 image_cache_refcount
=
6576 FRAME_IMAGE_CACHE (f
) ? FRAME_IMAGE_CACHE (f
)->refcount
: 0;
6577 dpyinfo_refcount
= dpyinfo
->reference_count
;
6578 #endif /* GLYPH_DEBUG */
6579 FRAME_KBOARD (f
) = kb
;
6580 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
6581 f
->output_data
.w32
->explicit_parent
= false;
6583 /* Set the name; the functions to which we pass f expect the name to
6585 if (EQ (name
, Qunbound
) || NILP (name
))
6587 fset_name (f
, build_string (dpyinfo
->w32_id_name
));
6588 f
->explicit_name
= false;
6592 fset_name (f
, name
);
6593 f
->explicit_name
= true;
6594 /* Use the frame's title when getting resources for this frame. */
6595 specbind (Qx_resource_name
, name
);
6598 if (uniscribe_available
)
6599 register_font_driver (&uniscribe_font_driver
, f
);
6600 register_font_driver (&w32font_driver
, f
);
6602 x_default_parameter (f
, parms
, Qfont_backend
, Qnil
,
6603 "fontBackend", "FontBackend", RES_TYPE_STRING
);
6605 /* Extract the window parameters from the supplied values
6606 that are needed to determine window geometry. */
6607 x_default_font_parameter (f
, parms
);
6609 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
6610 "borderWidth", "BorderWidth", RES_TYPE_NUMBER
);
6611 /* This defaults to 2 in order to match xterm. We recognize either
6612 internalBorderWidth or internalBorder (which is what xterm calls
6614 if (NILP (Fassq (Qinternal_border_width
, parms
)))
6618 value
= x_get_arg (dpyinfo
, parms
, Qinternal_border_width
,
6619 "internalBorder", "internalBorder", RES_TYPE_NUMBER
);
6620 if (! EQ (value
, Qunbound
))
6621 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
6625 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (1),
6626 "internalBorderWidth", "internalBorderWidth",
6628 /* Also do the stuff which must be set before the window exists. */
6629 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
6630 "foreground", "Foreground", RES_TYPE_STRING
);
6631 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
6632 "background", "Background", RES_TYPE_STRING
);
6633 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
6634 "pointerColor", "Foreground", RES_TYPE_STRING
);
6635 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
6636 "cursorColor", "Foreground", RES_TYPE_STRING
);
6637 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
6638 "borderColor", "BorderColor", RES_TYPE_STRING
);
6640 /* Init faces before x_default_parameter is called for the
6641 scroll-bar-width parameter because otherwise we end up in
6642 init_iterator with a null face cache, which should not happen. */
6643 init_frame_faces (f
);
6645 f
->output_data
.w32
->dwStyle
= WS_BORDER
| WS_POPUP
| WS_DISABLED
;
6646 f
->output_data
.w32
->parent_desc
= FRAME_DISPLAY_INFO (f
)->root_window
;
6648 x_figure_window_size (f
, parms
, true, &x_width
, &x_height
);
6650 /* No fringes on tip frame. */
6652 f
->left_fringe_width
= 0;
6653 f
->right_fringe_width
= 0;
6654 /* No dividers on tip frame. */
6655 f
->right_divider_width
= 0;
6656 f
->bottom_divider_width
= 0;
6659 my_create_tip_window (f
);
6664 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
6665 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
6666 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
6667 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN
);
6668 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
6669 "cursorType", "CursorType", RES_TYPE_SYMBOL
);
6670 /* Process alpha here (Bug#17344). */
6671 x_default_parameter (f
, parms
, Qalpha
, Qnil
,
6672 "alpha", "Alpha", RES_TYPE_NUMBER
);
6674 /* Dimensions, especially FRAME_LINES (f), must be done via
6675 change_frame_size. Change will not be effected unless different
6676 from the current FRAME_LINES (f). */
6677 width
= FRAME_COLS (f
);
6678 height
= FRAME_LINES (f
);
6679 SET_FRAME_COLS (f
, 0);
6680 SET_FRAME_LINES (f
, 0);
6681 adjust_frame_size (f
, width
* FRAME_COLUMN_WIDTH (f
),
6682 height
* FRAME_LINE_HEIGHT (f
), 0, true, Qtip_frame
);
6683 /* Add `tooltip' frame parameter's default value. */
6684 if (NILP (Fframe_parameter (frame
, Qtooltip
)))
6685 Fmodify_frame_parameters (frame
, Fcons (Fcons (Qtooltip
, Qt
), Qnil
));
6687 /* Set up faces after all frame parameters are known. This call
6688 also merges in face attributes specified for new frames.
6690 Frame parameters may be changed if .Xdefaults contains
6691 specifications for the default font. For example, if there is an
6692 `Emacs.default.attributeBackground: pink', the `background-color'
6693 attribute of the frame get's set, which let's the internal border
6694 of the tooltip frame appear in pink. Prevent this. */
6696 Lisp_Object bg
= Fframe_parameter (frame
, Qbackground_color
);
6697 Lisp_Object fg
= Fframe_parameter (frame
, Qforeground_color
);
6698 Lisp_Object colors
= Qnil
;
6700 call2 (Qface_set_after_frame_default
, frame
, Qnil
);
6702 if (!EQ (bg
, Fframe_parameter (frame
, Qbackground_color
)))
6703 colors
= Fcons (Fcons (Qbackground_color
, bg
), colors
);
6704 if (!EQ (fg
, Fframe_parameter (frame
, Qforeground_color
)))
6705 colors
= Fcons (Fcons (Qforeground_color
, fg
), colors
);
6708 Fmodify_frame_parameters (frame
, colors
);
6713 /* Now that the frame is official, it counts as a reference to
6715 FRAME_DISPLAY_INFO (f
)->reference_count
++;
6716 f
->terminal
->reference_count
++;
6718 /* It is now ok to make the frame official even if we get an error
6719 below. And the frame needs to be on Vframe_list or making it
6720 visible won't work. */
6721 Vframe_list
= Fcons (frame
, Vframe_list
);
6722 f
->can_x_set_window_size
= true;
6724 /* Setting attributes of faces of the tooltip frame from resources
6725 and similar will set face_change, which leads to the
6726 clearing of all current matrices. Since this isn't necessary
6727 here, avoid it by resetting face_change to the value it
6728 had before we created the tip frame. */
6729 face_change
= face_change_before
;
6731 /* Discard the unwind_protect. */
6732 return unbind_to (count
, frame
);
6736 /* Compute where to display tip frame F. PARMS is the list of frame
6737 parameters for F. DX and DY are specified offsets from the current
6738 location of the mouse. WIDTH and HEIGHT are the width and height
6739 of the tooltip. Return coordinates relative to the root window of
6740 the display in *ROOT_X and *ROOT_Y. */
6743 compute_tip_xy (struct frame
*f
,
6744 Lisp_Object parms
, Lisp_Object dx
, Lisp_Object dy
,
6745 int width
, int height
, int *root_x
, int *root_y
)
6747 Lisp_Object left
, top
, right
, bottom
;
6748 int min_x
, min_y
, max_x
, max_y
;
6750 /* User-specified position? */
6751 left
= Fcdr (Fassq (Qleft
, parms
));
6752 top
= Fcdr (Fassq (Qtop
, parms
));
6753 right
= Fcdr (Fassq (Qright
, parms
));
6754 bottom
= Fcdr (Fassq (Qbottom
, parms
));
6756 /* Move the tooltip window where the mouse pointer is. Resize and
6758 if ((!INTEGERP (left
) && !INTEGERP (right
))
6759 || (!INTEGERP (top
) && !INTEGERP (bottom
)))
6763 /* Default min and max values. */
6766 max_x
= x_display_pixel_width (FRAME_DISPLAY_INFO (f
));
6767 max_y
= x_display_pixel_height (FRAME_DISPLAY_INFO (f
));
6775 /* If multiple monitor support is available, constrain the tip onto
6776 the current monitor. This improves the above by allowing negative
6777 co-ordinates if monitor positions are such that they are valid, and
6778 snaps a tooltip onto a single monitor if we are close to the edge
6779 where it would otherwise flow onto the other monitor (or into
6780 nothingness if there is a gap in the overlap). */
6781 if (monitor_from_point_fn
&& get_monitor_info_fn
)
6783 struct MONITOR_INFO info
;
6785 = monitor_from_point_fn (pt
, MONITOR_DEFAULT_TO_NEAREST
);
6786 info
.cbSize
= sizeof (info
);
6788 if (get_monitor_info_fn (monitor
, &info
))
6790 min_x
= info
.rcWork
.left
;
6791 min_y
= info
.rcWork
.top
;
6792 max_x
= info
.rcWork
.right
;
6793 max_y
= info
.rcWork
.bottom
;
6799 *root_y
= XINT (top
);
6800 else if (INTEGERP (bottom
))
6801 *root_y
= XINT (bottom
) - height
;
6802 else if (*root_y
+ XINT (dy
) <= min_y
)
6803 *root_y
= min_y
; /* Can happen for negative dy */
6804 else if (*root_y
+ XINT (dy
) + height
<= max_y
)
6805 /* It fits below the pointer */
6806 *root_y
+= XINT (dy
);
6807 else if (height
+ XINT (dy
) + min_y
<= *root_y
)
6808 /* It fits above the pointer. */
6809 *root_y
-= height
+ XINT (dy
);
6811 /* Put it on the top. */
6814 if (INTEGERP (left
))
6815 *root_x
= XINT (left
);
6816 else if (INTEGERP (right
))
6817 *root_x
= XINT (right
) - width
;
6818 else if (*root_x
+ XINT (dx
) <= min_x
)
6819 *root_x
= 0; /* Can happen for negative dx */
6820 else if (*root_x
+ XINT (dx
) + width
<= max_x
)
6821 /* It fits to the right of the pointer. */
6822 *root_x
+= XINT (dx
);
6823 else if (width
+ XINT (dx
) + min_x
<= *root_x
)
6824 /* It fits to the left of the pointer. */
6825 *root_x
-= width
+ XINT (dx
);
6827 /* Put it left justified on the screen -- it ought to fit that way. */
6831 /* Hide tooltip. Delete its frame if DELETE is true. */
6833 x_hide_tip (bool delete)
6835 if (!NILP (tip_timer
))
6837 call1 (Qcancel_timer
, tip_timer
);
6841 if (NILP (tip_frame
)
6842 || (!delete && FRAMEP (tip_frame
)
6843 && !FRAME_VISIBLE_P (XFRAME (tip_frame
))))
6848 Lisp_Object was_open
= Qnil
;
6850 count
= SPECPDL_INDEX ();
6851 specbind (Qinhibit_redisplay
, Qt
);
6852 specbind (Qinhibit_quit
, Qt
);
6854 if (FRAMEP (tip_frame
))
6858 delete_frame (tip_frame
, Qnil
);
6862 x_make_frame_invisible (XFRAME (tip_frame
));
6869 return unbind_to (count
, was_open
);
6874 DEFUN ("x-show-tip", Fx_show_tip
, Sx_show_tip
, 1, 6, 0,
6875 doc
: /* Show STRING in a \"tooltip\" window on frame FRAME.
6876 A tooltip window is a small window displaying a string.
6878 This is an internal function; Lisp code should call `tooltip-show'.
6880 FRAME nil or omitted means use the selected frame.
6882 PARMS is an optional list of frame parameters which can be
6883 used to change the tooltip's appearance.
6885 Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
6886 means use the default timeout of 5 seconds.
6888 If the list of frame parameters PARMS contains a `left' parameter,
6889 display the tooltip at that x-position. If the list of frame parameters
6890 PARMS contains no `left' but a `right' parameter, display the tooltip
6891 right-adjusted at that x-position. Otherwise display it at the
6892 x-position of the mouse, with offset DX added (default is 5 if DX isn't
6895 Likewise for the y-position: If a `top' frame parameter is specified, it
6896 determines the position of the upper edge of the tooltip window. If a
6897 `bottom' parameter but no `top' frame parameter is specified, it
6898 determines the position of the lower edge of the tooltip window.
6899 Otherwise display the tooltip window at the y-position of the mouse,
6900 with offset DY added (default is -10).
6902 A tooltip's maximum size is specified by `x-max-tooltip-size'.
6903 Text larger than the specified size is clipped. */)
6904 (Lisp_Object string
, Lisp_Object frame
, Lisp_Object parms
, Lisp_Object timeout
, Lisp_Object dx
, Lisp_Object dy
)
6906 struct frame
*tip_f
;
6909 struct buffer
*old_buffer
;
6910 struct text_pos pos
;
6912 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
6913 ptrdiff_t count
= SPECPDL_INDEX ();
6915 Lisp_Object window
, size
;
6916 AUTO_STRING (tip
, " *tip*");
6918 specbind (Qinhibit_redisplay
, Qt
);
6920 CHECK_STRING (string
);
6921 decode_window_system_frame (frame
);
6923 timeout
= make_number (5);
6925 CHECK_NATNUM (timeout
);
6928 dx
= make_number (5);
6933 dy
= make_number (-10);
6937 if (NILP (last_show_tip_args
))
6938 last_show_tip_args
= Fmake_vector (make_number (3), Qnil
);
6940 if (FRAMEP (tip_frame
) && FRAME_LIVE_P (XFRAME (tip_frame
)))
6942 Lisp_Object last_string
= AREF (last_show_tip_args
, 0);
6943 Lisp_Object last_frame
= AREF (last_show_tip_args
, 1);
6944 Lisp_Object last_parms
= AREF (last_show_tip_args
, 2);
6946 if (FRAME_VISIBLE_P (XFRAME (tip_frame
))
6947 && EQ (frame
, last_frame
)
6948 && !NILP (Fequal_including_properties (last_string
, string
))
6949 && !NILP (Fequal (last_parms
, parms
)))
6951 /* Only DX and DY have changed. */
6952 tip_f
= XFRAME (tip_frame
);
6953 if (!NILP (tip_timer
))
6955 Lisp_Object timer
= tip_timer
;
6958 call1 (Qcancel_timer
, timer
);
6962 compute_tip_xy (tip_f
, parms
, dx
, dy
, FRAME_PIXEL_WIDTH (tip_f
),
6963 FRAME_PIXEL_HEIGHT (tip_f
), &root_x
, &root_y
);
6965 /* Put tooltip in topmost group and in position. */
6966 SetWindowPos (FRAME_W32_WINDOW (tip_f
), HWND_TOPMOST
,
6967 root_x
, root_y
, 0, 0,
6968 SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
6970 /* Ensure tooltip is on top of other topmost windows (eg menus). */
6971 SetWindowPos (FRAME_W32_WINDOW (tip_f
), HWND_TOP
,
6973 SWP_NOMOVE
| SWP_NOSIZE
6974 | SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
6976 /* Let redisplay know that we have made the frame visible already. */
6977 SET_FRAME_VISIBLE (tip_f
, 1);
6978 ShowWindow (FRAME_W32_WINDOW (tip_f
), SW_SHOWNOACTIVATE
);
6983 else if (tooltip_reuse_hidden_frame
&& EQ (frame
, last_frame
))
6985 bool delete = false;
6986 Lisp_Object tail
, elt
, parm
, last
;
6988 /* Check if every parameter in PARMS has the same value in
6989 last_parms. This may destruct last_parms which, however,
6990 will be recreated below. */
6991 for (tail
= parms
; CONSP (tail
); tail
= XCDR (tail
))
6995 /* The left, top, right and bottom parameters are handled
6996 by compute_tip_xy so they can be ignored here. */
6997 if (!EQ (parm
, Qleft
) && !EQ (parm
, Qtop
)
6998 && !EQ (parm
, Qright
) && !EQ (parm
, Qbottom
))
7000 last
= Fassq (parm
, last_parms
);
7001 if (NILP (Fequal (Fcdr (elt
), Fcdr (last
))))
7003 /* We lost, delete the old tooltip. */
7008 last_parms
= call2 (Qassq_delete_all
, parm
, last_parms
);
7011 last_parms
= call2 (Qassq_delete_all
, parm
, last_parms
);
7014 /* Now check if there's a parameter left in last_parms with a
7016 for (tail
= last_parms
; CONSP (tail
); tail
= XCDR (tail
))
7020 if (!EQ (parm
, Qleft
) && !EQ (parm
, Qtop
) && !EQ (parm
, Qright
)
7021 && !EQ (parm
, Qbottom
) && !NILP (Fcdr (elt
)))
7023 /* We lost, delete the old tooltip. */
7029 x_hide_tip (delete);
7037 ASET (last_show_tip_args
, 0, string
);
7038 ASET (last_show_tip_args
, 1, frame
);
7039 ASET (last_show_tip_args
, 2, parms
);
7041 /* Block input until the tip has been fully drawn, to avoid crashes
7042 when drawing tips in menus. */
7045 if (!FRAMEP (tip_frame
) || !FRAME_LIVE_P (XFRAME (tip_frame
)))
7047 /* Add default values to frame parameters. */
7048 if (NILP (Fassq (Qname
, parms
)))
7049 parms
= Fcons (Fcons (Qname
, build_string ("tooltip")), parms
);
7050 if (NILP (Fassq (Qinternal_border_width
, parms
)))
7051 parms
= Fcons (Fcons (Qinternal_border_width
, make_number (3)), parms
);
7052 if (NILP (Fassq (Qborder_width
, parms
)))
7053 parms
= Fcons (Fcons (Qborder_width
, make_number (1)), parms
);
7054 if (NILP (Fassq (Qborder_color
, parms
)))
7055 parms
= Fcons (Fcons (Qborder_color
, build_string ("lightyellow")), parms
);
7056 if (NILP (Fassq (Qbackground_color
, parms
)))
7057 parms
= Fcons (Fcons (Qbackground_color
, build_string ("lightyellow")),
7060 /* Create a frame for the tooltip, and record it in the global
7061 variable tip_frame. */
7062 struct frame
*f
; /* The value is unused. */
7063 if (NILP (tip_frame
= x_create_tip_frame (FRAME_DISPLAY_INFO (f
), parms
)))
7065 /* Creating the tip frame failed. */
7067 return unbind_to (count
, Qnil
);
7071 tip_f
= XFRAME (tip_frame
);
7072 window
= FRAME_ROOT_WINDOW (tip_f
);
7073 set_window_buffer (window
, Fget_buffer_create (tip
), false, false);
7074 w
= XWINDOW (window
);
7075 w
->pseudo_window_p
= true;
7077 /* Set up the frame's root window. Note: The following code does not
7078 try to size the window or its frame correctly. Its only purpose is
7079 to make the subsequent text size calculations work. The right
7080 sizes should get installed when the toolkit gets back to us. */
7086 if (CONSP (Vx_max_tooltip_size
)
7087 && RANGED_INTEGERP (1, XCAR (Vx_max_tooltip_size
), INT_MAX
)
7088 && RANGED_INTEGERP (1, XCDR (Vx_max_tooltip_size
), INT_MAX
))
7090 w
->total_cols
= XFASTINT (XCAR (Vx_max_tooltip_size
));
7091 w
->total_lines
= XFASTINT (XCDR (Vx_max_tooltip_size
));
7096 w
->total_lines
= 40;
7099 w
->pixel_width
= w
->total_cols
* FRAME_COLUMN_WIDTH (tip_f
);
7100 w
->pixel_height
= w
->total_lines
* FRAME_LINE_HEIGHT (tip_f
);
7101 FRAME_TOTAL_COLS (tip_f
) = WINDOW_TOTAL_COLS (w
);
7102 adjust_frame_glyphs (tip_f
);
7104 /* Insert STRING into the root window's buffer and fit the frame to
7106 count_1
= SPECPDL_INDEX ();
7107 old_buffer
= current_buffer
;
7108 set_buffer_internal_1 (XBUFFER (w
->contents
));
7109 bset_truncate_lines (current_buffer
, Qnil
);
7110 specbind (Qinhibit_read_only
, Qt
);
7111 specbind (Qinhibit_modification_hooks
, Qt
);
7112 specbind (Qinhibit_point_motion_hooks
, Qt
);
7114 Finsert (1, &string
);
7115 clear_glyph_matrix (w
->desired_matrix
);
7116 clear_glyph_matrix (w
->current_matrix
);
7117 SET_TEXT_POS (pos
, BEGV
, BEGV_BYTE
);
7118 try_window (window
, pos
, TRY_WINDOW_IGNORE_FONTS_CHANGE
);
7119 /* Calculate size of tooltip window. */
7120 size
= Fwindow_text_pixel_size (window
, Qnil
, Qnil
, Qnil
,
7121 make_number (w
->pixel_height
), Qnil
);
7122 /* Add the frame's internal border to calculated size. */
7123 width
= XINT (Fcar (size
)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f
);
7124 height
= XINT (Fcdr (size
)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f
);
7125 /* Calculate position of tooltip frame. */
7126 compute_tip_xy (tip_f
, parms
, dx
, dy
, width
, height
, &root_x
, &root_y
);
7128 /* Show tooltip frame. */
7131 int pad
= (NUMBERP (Vw32_tooltip_extra_pixels
)
7132 ? max (0, XINT (Vw32_tooltip_extra_pixels
))
7133 : FRAME_COLUMN_WIDTH (tip_f
));
7135 rect
.left
= rect
.top
= 0;
7137 rect
.bottom
= height
;
7138 AdjustWindowRect (&rect
, tip_f
->output_data
.w32
->dwStyle
,
7139 FRAME_EXTERNAL_MENU_BAR (tip_f
));
7141 /* Position and size tooltip and put it in the topmost group. */
7142 SetWindowPos (FRAME_W32_WINDOW (tip_f
), HWND_TOPMOST
,
7144 rect
.right
- rect
.left
+ pad
,
7145 rect
.bottom
- rect
.top
, SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
7147 /* Ensure tooltip is on top of other topmost windows (eg menus). */
7148 SetWindowPos (FRAME_W32_WINDOW (tip_f
), HWND_TOP
,
7150 SWP_NOMOVE
| SWP_NOSIZE
7151 | SWP_NOACTIVATE
| SWP_NOOWNERZORDER
);
7153 /* Let redisplay know that we have made the frame visible already. */
7154 SET_FRAME_VISIBLE (tip_f
, 1);
7156 ShowWindow (FRAME_W32_WINDOW (tip_f
), SW_SHOWNOACTIVATE
);
7159 w
->must_be_updated_p
= true;
7160 update_single_window (w
);
7161 set_buffer_internal_1 (old_buffer
);
7162 unbind_to (count_1
, Qnil
);
7164 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
7167 /* Let the tip disappear after timeout seconds. */
7168 tip_timer
= call3 (intern ("run-at-time"), timeout
, Qnil
,
7169 intern ("x-hide-tip"));
7171 return unbind_to (count
, Qnil
);
7175 DEFUN ("x-hide-tip", Fx_hide_tip
, Sx_hide_tip
, 0, 0, 0,
7176 doc
: /* Hide the current tooltip window, if there is any.
7177 Value is t if tooltip was open, nil otherwise. */)
7180 return x_hide_tip (!tooltip_reuse_hidden_frame
);
7183 /***********************************************************************
7184 File selection dialog
7185 ***********************************************************************/
7187 #define FILE_NAME_TEXT_FIELD edt1
7188 #define FILE_NAME_COMBO_BOX cmb13
7189 #define FILE_NAME_LIST lst1
7191 /* Callback for altering the behavior of the Open File dialog.
7192 Makes the Filename text field contain "Current Directory" and be
7193 read-only when "Directories" is selected in the filter. This
7194 allows us to work around the fact that the standard Open File
7195 dialog does not support directories. */
7196 static UINT_PTR CALLBACK
7197 file_dialog_callback (HWND hwnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
7199 if (msg
== WM_NOTIFY
)
7201 OFNOTIFYW
* notify_w
= (OFNOTIFYW
*)lParam
;
7202 OFNOTIFYA
* notify_a
= (OFNOTIFYA
*)lParam
;
7203 int dropdown_changed
;
7205 #ifdef NTGUI_UNICODE
7206 const int use_unicode
= 1;
7207 #else /* !NTGUI_UNICODE */
7208 int use_unicode
= w32_unicode_filenames
;
7209 #endif /* NTGUI_UNICODE */
7211 /* Detect when the Filter dropdown is changed. */
7214 notify_w
->hdr
.code
== CDN_TYPECHANGE
7215 || notify_w
->hdr
.code
== CDN_INITDONE
;
7218 notify_a
->hdr
.code
== CDN_TYPECHANGE
7219 || notify_a
->hdr
.code
== CDN_INITDONE
;
7220 if (dropdown_changed
)
7222 HWND dialog
= GetParent (hwnd
);
7223 HWND edit_control
= GetDlgItem (dialog
, FILE_NAME_TEXT_FIELD
);
7224 HWND list
= GetDlgItem (dialog
, FILE_NAME_LIST
);
7227 /* At least on Windows 7, the above attempt to get the window handle
7228 to the File Name Text Field fails. The following code does the
7229 job though. Note that this code is based on my examination of the
7230 window hierarchy using Microsoft Spy++. bk */
7231 if (edit_control
== NULL
)
7233 HWND tmp
= GetDlgItem (dialog
, FILE_NAME_COMBO_BOX
);
7236 tmp
= GetWindow (tmp
, GW_CHILD
);
7238 edit_control
= GetWindow (tmp
, GW_CHILD
);
7242 /* Directories is in index 2. */
7245 dir_index
= notify_w
->lpOFN
->nFilterIndex
;
7246 hdr_code
= notify_w
->hdr
.code
;
7250 dir_index
= notify_a
->lpOFN
->nFilterIndex
;
7251 hdr_code
= notify_a
->hdr
.code
;
7256 SendMessageW (dialog
, CDM_SETCONTROLTEXT
, FILE_NAME_TEXT_FIELD
,
7257 (LPARAM
)L
"Current Directory");
7259 SendMessageA (dialog
, CDM_SETCONTROLTEXT
, FILE_NAME_TEXT_FIELD
,
7260 (LPARAM
)"Current Directory");
7261 EnableWindow (edit_control
, FALSE
);
7262 /* Note that at least on Windows 7, the above call to EnableWindow
7263 disables the window that would ordinarily have focus. If we
7264 do not set focus to some other window here, focus will land in
7265 no man's land and the user will be unable to tab through the
7266 dialog box (pressing tab will only result in a beep).
7267 Avoid that problem by setting focus to the list here. */
7268 if (hdr_code
== CDN_INITDONE
)
7273 /* Don't override default filename on init done. */
7274 if (hdr_code
== CDN_TYPECHANGE
)
7277 SendMessageW (dialog
, CDM_SETCONTROLTEXT
,
7278 FILE_NAME_TEXT_FIELD
, (LPARAM
)L
"");
7280 SendMessageA (dialog
, CDM_SETCONTROLTEXT
,
7281 FILE_NAME_TEXT_FIELD
, (LPARAM
)"");
7283 EnableWindow (edit_control
, TRUE
);
7290 DEFUN ("x-file-dialog", Fx_file_dialog
, Sx_file_dialog
, 2, 5, 0,
7291 doc
: /* Read file name, prompting with PROMPT in directory DIR.
7292 Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
7293 selection box, if specified. If MUSTMATCH is non-nil, the returned file
7294 or directory must exist.
7296 This function is only defined on NS, MS Windows, and X Windows with the
7297 Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
7298 Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
7299 On Windows 7 and later, the file selection dialog "remembers" the last
7300 directory where the user selected a file, and will open that directory
7301 instead of DIR on subsequent invocations of this function with the same
7302 value of DIR as in previous invocations; this is standard Windows behavior. */)
7303 (Lisp_Object prompt
, Lisp_Object dir
, Lisp_Object default_filename
, Lisp_Object mustmatch
, Lisp_Object only_dir_p
)
7305 /* Filter index: 1: All Files, 2: Directories only */
7306 static const wchar_t filter_w
[] = L
"All Files (*.*)\0*.*\0Directories\0*|*\0";
7307 #ifndef NTGUI_UNICODE
7308 static const char filter_a
[] = "All Files (*.*)\0*.*\0Directories\0*|*\0";
7311 Lisp_Object filename
= default_filename
;
7312 struct frame
*f
= SELECTED_FRAME ();
7313 BOOL file_opened
= FALSE
;
7314 Lisp_Object orig_dir
= dir
;
7315 Lisp_Object orig_prompt
= prompt
;
7317 /* If we compile with _WIN32_WINNT set to 0x0400 (for NT4
7318 compatibility) we end up with the old file dialogs. Define a big
7319 enough struct for the new dialog to trick GetOpenFileName into
7320 giving us the new dialogs on newer versions of Windows. */
7322 OPENFILENAMEW details
;
7323 #if _WIN32_WINNT < 0x500 /* < win2k */
7327 #endif /* < win2k */
7328 } new_file_details_w
;
7330 #ifdef NTGUI_UNICODE
7331 wchar_t filename_buf_w
[32*1024 + 1]; /* NT kernel maximum */
7332 OPENFILENAMEW
* file_details_w
= &new_file_details_w
.details
;
7333 const int use_unicode
= 1;
7334 #else /* not NTGUI_UNICODE */
7336 OPENFILENAMEA details
;
7337 #if _WIN32_WINNT < 0x500 /* < win2k */
7341 #endif /* < win2k */
7342 } new_file_details_a
;
7343 wchar_t filename_buf_w
[MAX_PATH
+ 1], dir_w
[MAX_PATH
];
7344 char filename_buf_a
[MAX_PATH
+ 1], dir_a
[MAX_PATH
];
7345 OPENFILENAMEW
* file_details_w
= &new_file_details_w
.details
;
7346 OPENFILENAMEA
* file_details_a
= &new_file_details_a
.details
;
7347 int use_unicode
= w32_unicode_filenames
;
7351 char fname_ret
[MAX_UTF8_PATH
];
7352 #endif /* NTGUI_UNICODE */
7355 /* Note: under NTGUI_UNICODE, we do _NOT_ use ENCODE_FILE: the
7356 system file encoding expected by the platform APIs (e.g. Cygwin's
7357 POSIX implementation) may not be the same as the encoding expected
7358 by the Windows "ANSI" APIs! */
7360 CHECK_STRING (prompt
);
7363 dir
= Fexpand_file_name (dir
, Qnil
);
7365 if (STRINGP (filename
))
7366 filename
= Ffile_name_nondirectory (filename
);
7368 filename
= empty_unibyte_string
;
7371 dir
= Fcygwin_convert_file_name_to_windows (dir
, Qt
);
7372 if (SCHARS (filename
) > 0)
7373 filename
= Fcygwin_convert_file_name_to_windows (filename
, Qnil
);
7377 CHECK_STRING (filename
);
7379 /* The code in file_dialog_callback that attempts to set the text
7380 of the file name edit window when handling the CDN_INITDONE
7381 WM_NOTIFY message does not work. Setting filename to "Current
7382 Directory" in the only_dir_p case here does work however. */
7383 if (SCHARS (filename
) == 0 && ! NILP (only_dir_p
))
7384 filename
= build_string ("Current Directory");
7386 /* Convert the values we've computed so far to system form. */
7387 #ifdef NTGUI_UNICODE
7388 to_unicode (prompt
, &prompt
);
7389 to_unicode (dir
, &dir
);
7390 to_unicode (filename
, &filename
);
7391 if (SBYTES (filename
) + 1 > sizeof (filename_buf_w
))
7392 report_file_error ("filename too long", default_filename
);
7394 memcpy (filename_buf_w
, SDATA (filename
), SBYTES (filename
) + 1);
7395 #else /* !NTGUI_UNICODE */
7396 prompt
= ENCODE_FILE (prompt
);
7397 dir
= ENCODE_FILE (dir
);
7398 filename
= ENCODE_FILE (filename
);
7400 /* We modify these in-place, so make copies for safety. */
7401 dir
= Fcopy_sequence (dir
);
7402 unixtodos_filename (SSDATA (dir
));
7403 filename
= Fcopy_sequence (filename
);
7404 unixtodos_filename (SSDATA (filename
));
7405 if (SBYTES (filename
) >= MAX_UTF8_PATH
)
7406 report_file_error ("filename too long", default_filename
);
7407 if (w32_unicode_filenames
)
7409 filename_to_utf16 (SSDATA (dir
), dir_w
);
7410 if (filename_to_utf16 (SSDATA (filename
), filename_buf_w
) != 0)
7412 /* filename_to_utf16 sets errno to ENOENT when the file
7413 name is too long or cannot be converted to UTF-16. */
7414 if (errno
== ENOENT
&& filename_buf_w
[MAX_PATH
- 1] != 0)
7415 report_file_error ("filename too long", default_filename
);
7417 len
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7418 SSDATA (prompt
), -1, NULL
, 0);
7421 prompt_w
= alloca (len
* sizeof (wchar_t));
7422 pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7423 SSDATA (prompt
), -1, prompt_w
, len
);
7427 filename_to_ansi (SSDATA (dir
), dir_a
);
7428 if (filename_to_ansi (SSDATA (filename
), filename_buf_a
) != '\0')
7430 /* filename_to_ansi sets errno to ENOENT when the file
7431 name is too long or cannot be converted to UTF-16. */
7432 if (errno
== ENOENT
&& filename_buf_a
[MAX_PATH
- 1] != 0)
7433 report_file_error ("filename too long", default_filename
);
7435 len
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7436 SSDATA (prompt
), -1, NULL
, 0);
7439 prompt_w
= alloca (len
* sizeof (wchar_t));
7440 pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7441 SSDATA (prompt
), -1, prompt_w
, len
);
7442 len
= pWideCharToMultiByte (CP_ACP
, 0, prompt_w
, -1, NULL
, 0, NULL
, NULL
);
7445 prompt_a
= alloca (len
);
7446 pWideCharToMultiByte (CP_ACP
, 0, prompt_w
, -1, prompt_a
, len
, NULL
, NULL
);
7448 #endif /* NTGUI_UNICODE */
7450 /* Fill in the structure for the call to GetOpenFileName below.
7451 For NTGUI_UNICODE builds (which run only on NT), we just use
7452 the actual size of the structure. For non-NTGUI_UNICODE
7453 builds, we tell the OS we're using an old version of the
7454 structure if the OS isn't new enough to support the newer
7458 memset (&new_file_details_w
, 0, sizeof (new_file_details_w
));
7459 if (w32_major_version
> 4 && w32_major_version
< 95)
7460 file_details_w
->lStructSize
= sizeof (new_file_details_w
);
7462 file_details_w
->lStructSize
= sizeof (*file_details_w
);
7463 /* Set up the inout parameter for the selected file name. */
7464 file_details_w
->lpstrFile
= filename_buf_w
;
7465 file_details_w
->nMaxFile
=
7466 sizeof (filename_buf_w
) / sizeof (*filename_buf_w
);
7467 file_details_w
->hwndOwner
= FRAME_W32_WINDOW (f
);
7468 /* Undocumented Bug in Common File Dialog:
7469 If a filter is not specified, shell links are not resolved. */
7470 file_details_w
->lpstrFilter
= filter_w
;
7471 #ifdef NTGUI_UNICODE
7472 file_details_w
->lpstrInitialDir
= (wchar_t*) SDATA (dir
);
7473 file_details_w
->lpstrTitle
= (guichar_t
*) SDATA (prompt
);
7475 file_details_w
->lpstrInitialDir
= dir_w
;
7476 file_details_w
->lpstrTitle
= prompt_w
;
7478 file_details_w
->nFilterIndex
= NILP (only_dir_p
) ? 1 : 2;
7479 file_details_w
->Flags
= (OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
7480 | OFN_EXPLORER
| OFN_ENABLEHOOK
);
7481 if (!NILP (mustmatch
))
7483 /* Require that the path to the parent directory exists. */
7484 file_details_w
->Flags
|= OFN_PATHMUSTEXIST
;
7485 /* If we are looking for a file, require that it exists. */
7486 if (NILP (only_dir_p
))
7487 file_details_w
->Flags
|= OFN_FILEMUSTEXIST
;
7490 #ifndef NTGUI_UNICODE
7493 memset (&new_file_details_a
, 0, sizeof (new_file_details_a
));
7494 if (w32_major_version
> 4 && w32_major_version
< 95)
7495 file_details_a
->lStructSize
= sizeof (new_file_details_a
);
7497 file_details_a
->lStructSize
= sizeof (*file_details_a
);
7498 file_details_a
->lpstrFile
= filename_buf_a
;
7499 file_details_a
->nMaxFile
=
7500 sizeof (filename_buf_a
) / sizeof (*filename_buf_a
);
7501 file_details_a
->hwndOwner
= FRAME_W32_WINDOW (f
);
7502 file_details_a
->lpstrFilter
= filter_a
;
7503 file_details_a
->lpstrInitialDir
= dir_a
;
7504 file_details_a
->lpstrTitle
= prompt_a
;
7505 file_details_a
->nFilterIndex
= NILP (only_dir_p
) ? 1 : 2;
7506 file_details_a
->Flags
= (OFN_HIDEREADONLY
| OFN_NOCHANGEDIR
7507 | OFN_EXPLORER
| OFN_ENABLEHOOK
);
7508 if (!NILP (mustmatch
))
7510 /* Require that the path to the parent directory exists. */
7511 file_details_a
->Flags
|= OFN_PATHMUSTEXIST
;
7512 /* If we are looking for a file, require that it exists. */
7513 if (NILP (only_dir_p
))
7514 file_details_a
->Flags
|= OFN_FILEMUSTEXIST
;
7517 #endif /* !NTGUI_UNICODE */
7520 int count
= SPECPDL_INDEX ();
7521 /* Prevent redisplay. */
7522 specbind (Qinhibit_redisplay
, Qt
);
7526 file_details_w
->lpfnHook
= file_dialog_callback
;
7528 file_opened
= GetOpenFileNameW (file_details_w
);
7530 #ifndef NTGUI_UNICODE
7533 file_details_a
->lpfnHook
= file_dialog_callback
;
7535 file_opened
= GetOpenFileNameA (file_details_a
);
7537 #endif /* !NTGUI_UNICODE */
7539 unbind_to (count
, Qnil
);
7544 /* Get an Emacs string from the value Windows gave us. */
7545 #ifdef NTGUI_UNICODE
7546 filename
= from_unicode_buffer (filename_buf_w
);
7547 #else /* !NTGUI_UNICODE */
7549 filename_from_utf16 (filename_buf_w
, fname_ret
);
7551 filename_from_ansi (filename_buf_a
, fname_ret
);
7552 dostounix_filename (fname_ret
);
7553 filename
= DECODE_FILE (build_unibyte_string (fname_ret
));
7554 #endif /* NTGUI_UNICODE */
7557 filename
= Fcygwin_convert_file_name_from_windows (filename
, Qt
);
7560 /* Strip the dummy filename off the end of the string if we
7561 added it to select a directory. */
7562 if ((use_unicode
&& file_details_w
->nFilterIndex
== 2)
7563 #ifndef NTGUI_UNICODE
7564 || (!use_unicode
&& file_details_a
->nFilterIndex
== 2)
7567 filename
= Ffile_name_directory (filename
);
7569 /* User canceled the dialog without making a selection. */
7570 else if (!CommDlgExtendedError ())
7572 /* An error occurred, fallback on reading from the mini-buffer. */
7574 filename
= Fcompleting_read (
7576 intern ("read-file-name-internal"),
7585 /* Make "Cancel" equivalent to C-g. */
7586 if (NILP (filename
))
7594 /* Moving files to the system recycle bin.
7595 Used by `move-file-to-trash' instead of the default moving to ~/.Trash */
7596 DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash
,
7597 Ssystem_move_file_to_trash
, 1, 1, 0,
7598 doc
: /* Move file or directory named FILENAME to the recycle bin. */)
7599 (Lisp_Object filename
)
7601 Lisp_Object handler
;
7602 Lisp_Object encoded_file
;
7603 Lisp_Object operation
;
7605 operation
= Qdelete_file
;
7606 if (!NILP (Ffile_directory_p (filename
))
7607 && NILP (Ffile_symlink_p (filename
)))
7609 operation
= intern ("delete-directory");
7610 filename
= Fdirectory_file_name (filename
);
7613 /* Must have fully qualified file names for moving files to Recycle
7615 filename
= Fexpand_file_name (filename
, Qnil
);
7617 handler
= Ffind_file_name_handler (filename
, operation
);
7618 if (!NILP (handler
))
7619 return call2 (handler
, operation
, filename
);
7625 encoded_file
= ENCODE_FILE (filename
);
7627 path
= map_w32_filename (SSDATA (encoded_file
), NULL
);
7629 /* The Unicode version of SHFileOperation is not supported on
7631 if (w32_unicode_filenames
&& os_subtype
!= OS_9X
)
7633 SHFILEOPSTRUCTW file_op_w
;
7634 /* We need one more element beyond MAX_PATH because this is
7635 a list of file names, with the last element double-null
7637 wchar_t tmp_path_w
[MAX_PATH
+ 1];
7639 memset (tmp_path_w
, 0, sizeof (tmp_path_w
));
7640 filename_to_utf16 (path
, tmp_path_w
);
7642 /* On Windows, write permission is required to delete/move files. */
7643 _wchmod (tmp_path_w
, 0666);
7645 memset (&file_op_w
, 0, sizeof (file_op_w
));
7646 file_op_w
.hwnd
= HWND_DESKTOP
;
7647 file_op_w
.wFunc
= FO_DELETE
;
7648 file_op_w
.pFrom
= tmp_path_w
;
7649 file_op_w
.fFlags
= FOF_SILENT
| FOF_NOCONFIRMATION
| FOF_ALLOWUNDO
7650 | FOF_NOERRORUI
| FOF_NO_CONNECTED_ELEMENTS
;
7651 file_op_w
.fAnyOperationsAborted
= FALSE
;
7653 result
= SHFileOperationW (&file_op_w
);
7657 SHFILEOPSTRUCTA file_op_a
;
7658 char tmp_path_a
[MAX_PATH
+ 1];
7660 memset (tmp_path_a
, 0, sizeof (tmp_path_a
));
7661 filename_to_ansi (path
, tmp_path_a
);
7663 /* If a file cannot be represented in ANSI codepage, don't
7664 let them inadvertently delete other files because some
7665 characters are interpreted as a wildcards. */
7666 if (_mbspbrk ((unsigned char *)tmp_path_a
,
7667 (const unsigned char *)"?*"))
7668 result
= ERROR_FILE_NOT_FOUND
;
7671 _chmod (tmp_path_a
, 0666);
7673 memset (&file_op_a
, 0, sizeof (file_op_a
));
7674 file_op_a
.hwnd
= HWND_DESKTOP
;
7675 file_op_a
.wFunc
= FO_DELETE
;
7676 file_op_a
.pFrom
= tmp_path_a
;
7677 file_op_a
.fFlags
= FOF_SILENT
| FOF_NOCONFIRMATION
| FOF_ALLOWUNDO
7678 | FOF_NOERRORUI
| FOF_NO_CONNECTED_ELEMENTS
;
7679 file_op_a
.fAnyOperationsAborted
= FALSE
;
7681 result
= SHFileOperationA (&file_op_a
);
7685 report_file_error ("Removing old name", list1 (filename
));
7690 #endif /* WINDOWSNT */
7693 /***********************************************************************
7694 w32 specialized functions
7695 ***********************************************************************/
7697 DEFUN ("w32-send-sys-command", Fw32_send_sys_command
,
7698 Sw32_send_sys_command
, 1, 2, 0,
7699 doc
: /* Send frame a Windows WM_SYSCOMMAND message of type COMMAND.
7700 Some useful values for COMMAND are #xf030 to maximize frame (#xf020
7701 to minimize), #xf120 to restore frame to original size, and #xf100
7702 to activate the menubar for keyboard access. #xf140 activates the
7703 screen saver if defined.
7705 If optional parameter FRAME is not specified, use selected frame. */)
7706 (Lisp_Object command
, Lisp_Object frame
)
7708 struct frame
*f
= decode_window_system_frame (frame
);
7710 CHECK_NUMBER (command
);
7712 if (FRAME_W32_P (f
))
7713 PostMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, XINT (command
), 0);
7718 DEFUN ("w32-shell-execute", Fw32_shell_execute
, Sw32_shell_execute
, 2, 4, 0,
7719 doc
: /* Get Windows to perform OPERATION on DOCUMENT.
7720 This is a wrapper around the ShellExecute system function, which
7721 invokes the application registered to handle OPERATION for DOCUMENT.
7723 OPERATION is either nil or a string that names a supported operation.
7724 What operations can be used depends on the particular DOCUMENT and its
7725 handler application, but typically it is one of the following common
7728 \"open\" - open DOCUMENT, which could be a file, a directory, or an
7729 executable program (application). If it is an application,
7730 that application is launched in the current buffer's default
7731 directory. Otherwise, the application associated with
7732 DOCUMENT is launched in the buffer's default directory.
7733 \"opennew\" - like \"open\", but instruct the application to open
7734 DOCUMENT in a new window.
7735 \"openas\" - open the \"Open With\" dialog for DOCUMENT.
7736 \"print\" - print DOCUMENT, which must be a file.
7737 \"printto\" - print DOCUMENT, which must be a file, to a specified printer.
7738 The printer should be provided in PARAMETERS, see below.
7739 \"explore\" - start the Windows Explorer on DOCUMENT.
7740 \"edit\" - launch an editor and open DOCUMENT for editing; which
7741 editor is launched depends on the association for the
7743 \"find\" - initiate search starting from DOCUMENT, which must specify
7745 \"delete\" - move DOCUMENT, a file or a directory, to Recycle Bin.
7746 \"copy\" - copy DOCUMENT, which must be a file or a directory, into
7748 \"cut\" - move DOCUMENT, a file or a directory, into the clipboard.
7749 \"paste\" - paste the file whose name is in the clipboard into DOCUMENT,
7750 which must be a directory.
7752 - create a shortcut in DOCUMENT (which must be a directory)
7753 the file or directory whose name is in the clipboard.
7754 \"runas\" - run DOCUMENT, which must be an excutable file, with
7755 elevated privileges (a.k.a. \"as Administrator\").
7757 - open the property sheet dialog for DOCUMENT.
7758 nil - invoke the default OPERATION, or \"open\" if default is
7759 not defined or unavailable.
7761 DOCUMENT is typically the name of a document file or a URL, but can
7762 also be an executable program to run, or a directory to open in the
7763 Windows Explorer. If it is a file or a directory, it must be a local
7764 one; this function does not support remote file names.
7766 If DOCUMENT is an executable program, the optional third arg PARAMETERS
7767 can be a string containing command line parameters, separated by blanks,
7768 that will be passed to the program. Some values of OPERATION also require
7769 parameters (e.g., \"printto\" requires the printer address). Otherwise,
7770 PARAMETERS should be nil or unspecified. Note that double quote characters
7771 in PARAMETERS must each be enclosed in 2 additional quotes, as in \"\"\".
7773 Optional fourth argument SHOW-FLAG can be used to control how the
7774 application will be displayed when it is invoked. If SHOW-FLAG is nil
7775 or unspecified, the application is displayed as if SHOW-FLAG of 10 was
7776 specified, otherwise it is an integer between 0 and 11 representing
7780 1 - start as normal-size window
7781 3 - start in a maximized window
7782 6 - start in a minimized window
7783 10 - start as the application itself specifies; this is the default. */)
7784 (Lisp_Object operation
, Lisp_Object document
, Lisp_Object parameters
, Lisp_Object show_flag
)
7787 Lisp_Object current_dir
= BVAR (current_buffer
, directory
);;
7788 wchar_t *doc_w
= NULL
, *params_w
= NULL
, *ops_w
= NULL
;
7792 int use_unicode
= w32_unicode_filenames
;
7793 char *doc_a
= NULL
, *params_a
= NULL
, *ops_a
= NULL
;
7794 Lisp_Object absdoc
, handler
;
7798 CHECK_STRING (document
);
7801 current_dir
= Fcygwin_convert_file_name_to_windows (current_dir
, Qt
);
7802 document
= Fcygwin_convert_file_name_to_windows (document
, Qt
);
7804 /* Encode filename, current directory and parameters. */
7805 current_dir
= GUI_ENCODE_FILE (current_dir
);
7806 document
= GUI_ENCODE_FILE (document
);
7807 doc_w
= GUI_SDATA (document
);
7808 if (STRINGP (parameters
))
7810 parameters
= GUI_ENCODE_SYSTEM (parameters
);
7811 params_w
= GUI_SDATA (parameters
);
7813 if (STRINGP (operation
))
7815 operation
= GUI_ENCODE_SYSTEM (operation
);
7816 ops_w
= GUI_SDATA (operation
);
7818 result
= (intptr_t) ShellExecuteW (NULL
, ops_w
, doc_w
, params_w
,
7819 GUI_SDATA (current_dir
),
7820 (INTEGERP (show_flag
)
7821 ? XINT (show_flag
) : SW_SHOWDEFAULT
));
7828 case SE_ERR_ACCESSDENIED
:
7829 errstr
= w32_strerror (ERROR_ACCESS_DENIED
);
7831 case SE_ERR_ASSOCINCOMPLETE
:
7832 case SE_ERR_NOASSOC
:
7833 errstr
= w32_strerror (ERROR_NO_ASSOCIATION
);
7835 case SE_ERR_DDEBUSY
:
7836 case SE_ERR_DDEFAIL
:
7837 errstr
= w32_strerror (ERROR_DDE_FAIL
);
7839 case SE_ERR_DDETIMEOUT
:
7840 errstr
= w32_strerror (ERROR_TIMEOUT
);
7842 case SE_ERR_DLLNOTFOUND
:
7843 errstr
= w32_strerror (ERROR_DLL_NOT_FOUND
);
7846 errstr
= w32_strerror (ERROR_FILE_NOT_FOUND
);
7849 errstr
= w32_strerror (ERROR_NOT_ENOUGH_MEMORY
);
7852 errstr
= w32_strerror (ERROR_PATH_NOT_FOUND
);
7855 errstr
= w32_strerror (ERROR_SHARING_VIOLATION
);
7858 errstr
= w32_strerror (0);
7864 const char file_url_str
[] = "file:///";
7865 const int file_url_len
= sizeof (file_url_str
) - 1;
7868 if (strncmp (SSDATA (document
), file_url_str
, file_url_len
) == 0)
7870 /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to
7871 start a thread in some rare system configurations, for
7872 unknown reasons. That thread is started in the context of
7873 the Emacs process, but out of control of our code, and seems
7874 to never exit afterwards. Each such thread reserves 8MB of
7875 stack space (because that's the value recorded in the Emacs
7876 executable at link time: Emacs needs a large stack). So a
7877 large enough number of invocations of w32-shell-execute can
7878 potentially cause the Emacs process to run out of available
7879 address space, which is nasty. To work around this, we
7880 convert such URLs to local file names, which seems to prevent
7881 those threads from starting. See bug #20220. */
7882 char *p
= SSDATA (document
) + file_url_len
;
7884 if (c_isalpha (*p
) && p
[1] == ':' && IS_DIRECTORY_SEP (p
[2]))
7885 document
= Fsubstring_no_properties (document
,
7886 make_number (file_url_len
), Qnil
);
7888 /* We have a situation here. If DOCUMENT is a relative file name,
7889 but its name includes leading directories, i.e. it lives not in
7890 CURRENT_DIR, but in its subdirectory, then ShellExecute below
7891 will fail to find it. So we need to make the file name is
7892 absolute. But DOCUMENT does not have to be a file, it can be a
7893 URL, for example. So we make it absolute only if it is an
7894 existing file; if it is a file that does not exist, tough. */
7895 absdoc
= Fexpand_file_name (document
, Qnil
);
7896 /* Don't call file handlers for file-exists-p, since they might
7897 attempt to access the file, which could fail or produce undesired
7898 consequences, see bug#16558 for an example. */
7899 handler
= Ffind_file_name_handler (absdoc
, Qfile_exists_p
);
7902 Lisp_Object absdoc_encoded
= ENCODE_FILE (absdoc
);
7904 if (faccessat (AT_FDCWD
, SSDATA (absdoc_encoded
), F_OK
, AT_EACCESS
) == 0)
7906 /* ShellExecute fails if DOCUMENT is a UNC with forward
7907 slashes (expand-file-name above converts all backslashes
7908 to forward slashes). Now that we know DOCUMENT is a
7909 file, we can mirror all forward slashes into backslashes. */
7910 unixtodos_filename (SSDATA (absdoc_encoded
));
7911 document
= absdoc_encoded
;
7914 document
= ENCODE_FILE (document
);
7917 document
= ENCODE_FILE (document
);
7919 current_dir
= ENCODE_FILE (current_dir
);
7920 /* Cannot use filename_to_utf16/ansi with DOCUMENT, since it could
7921 be a URL that is not limited to MAX_PATH chararcters. */
7922 doclen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7923 SSDATA (document
), -1, NULL
, 0);
7924 doc_w
= xmalloc (doclen
* sizeof (wchar_t));
7925 pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
7926 SSDATA (document
), -1, doc_w
, doclen
);
7929 wchar_t current_dir_w
[MAX_PATH
];
7930 SHELLEXECUTEINFOW shexinfo_w
;
7932 /* Encode the current directory and parameters, and convert
7933 operation to UTF-16. */
7934 filename_to_utf16 (SSDATA (current_dir
), current_dir_w
);
7935 if (STRINGP (parameters
))
7939 parameters
= ENCODE_SYSTEM (parameters
);
7940 len
= pMultiByteToWideChar (CP_ACP
, multiByteToWideCharFlags
,
7941 SSDATA (parameters
), -1, NULL
, 0);
7944 params_w
= alloca (len
* sizeof (wchar_t));
7945 pMultiByteToWideChar (CP_ACP
, multiByteToWideCharFlags
,
7946 SSDATA (parameters
), -1, params_w
, len
);
7947 params_w
[len
- 1] = 0;
7949 if (STRINGP (operation
))
7951 /* Assume OPERATION is pure ASCII. */
7952 const char *s
= SSDATA (operation
);
7954 int len
= SBYTES (operation
) + 1;
7958 d
= ops_w
= alloca (len
* sizeof (wchar_t));
7959 while (d
< ops_w
+ len
- 1)
7964 /* Using ShellExecuteEx and setting the SEE_MASK_INVOKEIDLIST
7965 flag succeeds with more OPERATIONs (a.k.a. "verbs"), as it is
7966 able to invoke verbs from shortcut menu extensions, not just
7967 static verbs listed in the Registry. */
7968 memset (&shexinfo_w
, 0, sizeof (shexinfo_w
));
7969 shexinfo_w
.cbSize
= sizeof (shexinfo_w
);
7971 SEE_MASK_INVOKEIDLIST
| SEE_MASK_FLAG_DDEWAIT
| SEE_MASK_FLAG_NO_UI
;
7972 shexinfo_w
.hwnd
= NULL
;
7973 shexinfo_w
.lpVerb
= ops_w
;
7974 shexinfo_w
.lpFile
= doc_w
;
7975 shexinfo_w
.lpParameters
= params_w
;
7976 shexinfo_w
.lpDirectory
= current_dir_w
;
7978 (INTEGERP (show_flag
) ? XINT (show_flag
) : SW_SHOWDEFAULT
);
7979 success
= ShellExecuteExW (&shexinfo_w
);
7984 char current_dir_a
[MAX_PATH
];
7985 SHELLEXECUTEINFOA shexinfo_a
;
7986 int codepage
= codepage_for_filenames (NULL
);
7987 int ldoc_a
= pWideCharToMultiByte (codepage
, 0, doc_w
, -1, NULL
, 0,
7990 doc_a
= xmalloc (ldoc_a
);
7991 pWideCharToMultiByte (codepage
, 0, doc_w
, -1, doc_a
, ldoc_a
, NULL
, NULL
);
7992 filename_to_ansi (SSDATA (current_dir
), current_dir_a
);
7993 if (STRINGP (parameters
))
7995 parameters
= ENCODE_SYSTEM (parameters
);
7996 params_a
= SSDATA (parameters
);
7998 if (STRINGP (operation
))
8000 /* Assume OPERATION is pure ASCII. */
8001 ops_a
= SSDATA (operation
);
8003 memset (&shexinfo_a
, 0, sizeof (shexinfo_a
));
8004 shexinfo_a
.cbSize
= sizeof (shexinfo_a
);
8006 SEE_MASK_INVOKEIDLIST
| SEE_MASK_FLAG_DDEWAIT
| SEE_MASK_FLAG_NO_UI
;
8007 shexinfo_a
.hwnd
= NULL
;
8008 shexinfo_a
.lpVerb
= ops_a
;
8009 shexinfo_a
.lpFile
= doc_a
;
8010 shexinfo_a
.lpParameters
= params_a
;
8011 shexinfo_a
.lpDirectory
= current_dir_a
;
8013 (INTEGERP (show_flag
) ? XINT (show_flag
) : SW_SHOWDEFAULT
);
8014 success
= ShellExecuteExA (&shexinfo_a
);
8022 errstr
= w32_strerror (0);
8024 #endif /* !CYGWIN */
8026 /* The error string might be encoded in the locale's encoding. */
8027 if (!NILP (Vlocale_coding_system
))
8029 Lisp_Object decoded
=
8030 code_convert_string_norecord (build_unibyte_string (errstr
),
8031 Vlocale_coding_system
, 0);
8032 errstr
= SSDATA (decoded
);
8034 error ("ShellExecute failed: %s", errstr
);
8037 /* Lookup virtual keycode from string representing the name of a
8038 non-ascii keystroke into the corresponding virtual key, using
8039 lispy_function_keys. */
8041 lookup_vk_code (char *key
)
8045 for (i
= 0; i
< 256; i
++)
8046 if (lispy_function_keys
[i
]
8047 && strcmp (lispy_function_keys
[i
], key
) == 0)
8050 if (w32_kbdhook_active
)
8052 /* Alphanumerics map to themselves. */
8055 if ((key
[0] >= 'A' && key
[0] <= 'Z')
8056 || (key
[0] >= '0' && key
[0] <= '9'))
8058 if (key
[0] >= 'a' && key
[0] <= 'z')
8059 return toupper(key
[0]);
8066 /* Convert a one-element vector style key sequence to a hot key
8069 w32_parse_and_hook_hot_key (Lisp_Object key
, int hook
)
8071 /* Copied from Fdefine_key and store_in_keymap. */
8072 register Lisp_Object c
;
8076 Lisp_Object res
= Qnil
;
8081 if (ASIZE (key
) != 1)
8086 if (CONSP (c
) && lucid_event_type_list_p (c
))
8087 c
= Fevent_convert_list (c
);
8089 if (! INTEGERP (c
) && ! SYMBOLP (c
))
8090 error ("Key definition is invalid");
8092 /* Work out the base key and the modifiers. */
8095 c
= parse_modifiers (c
);
8096 lisp_modifiers
= XINT (Fcar (Fcdr (c
)));
8100 vkname
= SSDATA (SYMBOL_NAME (c
));
8101 /* [s-], [M-], [h-]: Register all keys for this modifier */
8102 if (w32_kbdhook_active
&& vkname
[0] == 0)
8105 vk_code
= lookup_vk_code (vkname
);
8107 else if (INTEGERP (c
))
8109 lisp_modifiers
= XINT (c
) & ~CHARACTERBITS
;
8110 /* Many ascii characters are their own virtual key code. */
8111 vk_code
= XINT (c
) & CHARACTERBITS
;
8114 if (vk_code
< 0 || vk_code
> 255)
8117 if ((lisp_modifiers
& meta_modifier
) != 0
8118 && !NILP (Vw32_alt_is_meta
))
8119 lisp_modifiers
|= alt_modifier
;
8121 /* Supply defs missing from mingw32. */
8123 #define MOD_ALT 0x0001
8124 #define MOD_CONTROL 0x0002
8125 #define MOD_SHIFT 0x0004
8126 #define MOD_WIN 0x0008
8129 if (w32_kbdhook_active
)
8131 /* Register Alt-x combinations. */
8132 if (lisp_modifiers
& alt_modifier
)
8134 hook_w32_key (hook
, VK_MENU
, vk_code
);
8137 /* Register Win-x combinations based on modifier mappings. */
8138 if (((lisp_modifiers
& hyper_modifier
)
8139 && EQ (Vw32_lwindow_modifier
, Qhyper
))
8140 || ((lisp_modifiers
& super_modifier
)
8141 && EQ (Vw32_lwindow_modifier
, Qsuper
)))
8143 hook_w32_key (hook
, VK_LWIN
, vk_code
);
8146 if (((lisp_modifiers
& hyper_modifier
)
8147 && EQ (Vw32_rwindow_modifier
, Qhyper
))
8148 || ((lisp_modifiers
& super_modifier
)
8149 && EQ (Vw32_rwindow_modifier
, Qsuper
)))
8151 hook_w32_key (hook
, VK_RWIN
, vk_code
);
8158 /* Convert lisp modifiers to Windows hot-key form. */
8159 w32_modifiers
= (lisp_modifiers
& hyper_modifier
) ? MOD_WIN
: 0;
8160 w32_modifiers
|= (lisp_modifiers
& alt_modifier
) ? MOD_ALT
: 0;
8161 w32_modifiers
|= (lisp_modifiers
& ctrl_modifier
) ? MOD_CONTROL
: 0;
8162 w32_modifiers
|= (lisp_modifiers
& shift_modifier
) ? MOD_SHIFT
: 0;
8164 return HOTKEY (vk_code
, w32_modifiers
);
8168 DEFUN ("w32-register-hot-key", Fw32_register_hot_key
,
8169 Sw32_register_hot_key
, 1, 1, 0,
8170 doc
: /* Register KEY as a hot-key combination.
8171 Certain key combinations like Alt-Tab and Win-R are reserved for
8172 system use on Windows, and therefore are normally intercepted by the
8173 system. These key combinations can be received by registering them
8174 as hot-keys, except for Win-L which always locks the computer.
8176 On Windows 98 and ME, KEY must be a one element key definition in
8177 vector form that would be acceptable to `define-key' (e.g. [A-tab] for
8178 Alt-Tab). The meta modifier is interpreted as Alt if
8179 `w32-alt-is-meta' is t, and hyper is always interpreted as the Windows
8180 modifier keys. The return value is the hotkey-id if registered, otherwise nil.
8182 On Windows versions since NT, KEY can also be specified as [M-], [s-] or
8183 [h-] to indicate that all combinations of that key should be processed
8184 by Emacs instead of the operating system. The super and hyper
8185 modifiers are interpreted according to the current values of
8186 `w32-lwindow-modifier' and `w32-rwindow-modifier'. For instance,
8187 setting `w32-lwindow-modifier' to `super' and then calling
8188 `(register-hot-key [s-])' grabs all combinations of the left Windows
8189 key to Emacs, but leaves the right Windows key free for the operating
8190 system keyboard shortcuts. The return value is t if the call affected
8191 any key combinations, otherwise nil. */)
8194 key
= w32_parse_and_hook_hot_key (key
, 1);
8196 if (!w32_kbdhook_active
8197 && !NILP (key
) && NILP (Fmemq (key
, w32_grabbed_keys
)))
8199 /* Reuse an empty slot if possible. */
8200 Lisp_Object item
= Fmemq (Qnil
, w32_grabbed_keys
);
8202 /* Safe to add new key to list, even if we have focus. */
8204 w32_grabbed_keys
= Fcons (key
, w32_grabbed_keys
);
8206 XSETCAR (item
, key
);
8208 /* Notify input thread about new hot-key definition, so that it
8209 takes effect without needing to switch focus. */
8210 PostThreadMessage (dwWindowsThreadId
, WM_EMACS_REGISTER_HOT_KEY
,
8211 (WPARAM
) XINT (key
), 0);
8217 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key
,
8218 Sw32_unregister_hot_key
, 1, 1, 0,
8219 doc
: /* Unregister KEY as a hot-key combination. */)
8224 if (!INTEGERP (key
))
8225 key
= w32_parse_and_hook_hot_key (key
, 0);
8227 if (w32_kbdhook_active
)
8230 item
= Fmemq (key
, w32_grabbed_keys
);
8236 eassert (CONSP (item
));
8237 /* Pass the tail of the list as a pointer to a Lisp_Cons cell,
8238 so that it works in a --with-wide-int build as well. */
8239 lparam
= (LPARAM
) XUNTAG (item
, Lisp_Cons
);
8241 /* Notify input thread about hot-key definition being removed, so
8242 that it takes effect without needing focus switch. */
8243 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_UNREGISTER_HOT_KEY
,
8244 (WPARAM
) XINT (XCAR (item
)), lparam
))
8247 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
8254 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys
,
8255 Sw32_registered_hot_keys
, 0, 0, 0,
8256 doc
: /* Return list of registered hot-key IDs. */)
8259 return Fdelq (Qnil
, Fcopy_sequence (w32_grabbed_keys
));
8262 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key
,
8263 Sw32_reconstruct_hot_key
, 1, 1, 0,
8264 doc
: /* Convert hot-key ID to a lisp key combination.
8265 usage: (w32-reconstruct-hot-key ID) */)
8266 (Lisp_Object hotkeyid
)
8268 int vk_code
, w32_modifiers
;
8271 CHECK_NUMBER (hotkeyid
);
8273 vk_code
= HOTKEY_VK_CODE (hotkeyid
);
8274 w32_modifiers
= HOTKEY_MODIFIERS (hotkeyid
);
8276 if (vk_code
< 256 && lispy_function_keys
[vk_code
])
8277 key
= intern (lispy_function_keys
[vk_code
]);
8279 key
= make_number (vk_code
);
8281 key
= Fcons (key
, Qnil
);
8282 if (w32_modifiers
& MOD_SHIFT
)
8283 key
= Fcons (Qshift
, key
);
8284 if (w32_modifiers
& MOD_CONTROL
)
8285 key
= Fcons (Qctrl
, key
);
8286 if (w32_modifiers
& MOD_ALT
)
8287 key
= Fcons (NILP (Vw32_alt_is_meta
) ? Qalt
: Qmeta
, key
);
8288 if (w32_modifiers
& MOD_WIN
)
8289 key
= Fcons (Qhyper
, key
);
8294 DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key
,
8295 Sw32_toggle_lock_key
, 1, 2, 0,
8296 doc
: /* Toggle the state of the lock key KEY.
8297 KEY can be `capslock', `kp-numlock', or `scroll'.
8298 If the optional parameter NEW-STATE is a number, then the state of KEY
8299 is set to off if the low bit of NEW-STATE is zero, otherwise on.
8300 If NEW-STATE is omitted or nil, the function toggles the state,
8302 Value is the new state of the key, or nil if the function failed
8303 to change the state. */)
8304 (Lisp_Object key
, Lisp_Object new_state
)
8309 if (EQ (key
, intern ("capslock")))
8310 vk_code
= VK_CAPITAL
;
8311 else if (EQ (key
, intern ("kp-numlock")))
8312 vk_code
= VK_NUMLOCK
;
8313 else if (EQ (key
, intern ("scroll")))
8314 vk_code
= VK_SCROLL
;
8318 if (!dwWindowsThreadId
)
8319 return make_number (w32_console_toggle_lock_key (vk_code
, new_state
));
8321 if (NILP (new_state
))
8324 lparam
= (XUINT (new_state
)) & 1;
8325 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_TOGGLE_LOCK_KEY
,
8326 (WPARAM
) vk_code
, lparam
))
8329 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
8330 return make_number (msg
.wParam
);
8335 DEFUN ("w32-window-exists-p", Fw32_window_exists_p
, Sw32_window_exists_p
,
8337 doc
: /* Return non-nil if a window exists with the specified CLASS and NAME.
8339 This is a direct interface to the Windows API FindWindow function. */)
8340 (Lisp_Object
class, Lisp_Object name
)
8345 CHECK_STRING (class);
8347 CHECK_STRING (name
);
8349 hnd
= FindWindow (STRINGP (class) ? ((LPCTSTR
) SDATA (class)) : NULL
,
8350 STRINGP (name
) ? ((LPCTSTR
) SDATA (name
)) : NULL
);
8356 DEFUN ("w32-frame-geometry", Fw32_frame_geometry
, Sw32_frame_geometry
, 0, 1, 0,
8357 doc
: /* Return geometric attributes of FRAME.
8358 FRAME must be a live frame and defaults to the selected one. The return
8359 value is an association list of the attributes listed below. All height
8360 and width values are in pixels.
8362 `outer-position' is a cons of the outer left and top edges of FRAME
8363 relative to the origin - the position (0, 0) - of FRAME's display.
8365 `outer-size' is a cons of the outer width and height of FRAME. The
8366 outer size includes the title bar and the external borders as well as
8367 any menu and/or tool bar of frame.
8369 `external-border-size' is a cons of the horizontal and vertical width of
8370 FRAME's external borders as supplied by the window manager.
8372 `title-bar-size' is a cons of the width and height of the title bar of
8373 FRAME as supplied by the window manager. If both of them are zero,
8374 FRAME has no title bar. If only the width is zero, Emacs was not
8375 able to retrieve the width information.
8377 `menu-bar-external', if non-nil, means the menu bar is external (never
8378 included in the inner edges of FRAME).
8380 `menu-bar-size' is a cons of the width and height of the menu bar of
8383 `tool-bar-external', if non-nil, means the tool bar is external (never
8384 included in the inner edges of FRAME).
8386 `tool-bar-position' tells on which side the tool bar on FRAME is and can
8387 be one of `left', `top', `right' or `bottom'. If this is nil, FRAME
8390 `tool-bar-size' is a cons of the width and height of the tool bar of
8393 `internal-border-width' is the width of the internal border of
8397 struct frame
*f
= decode_live_frame (frame
);
8399 MENUBARINFO menu_bar
;
8401 int left
, top
, right
, bottom
;
8402 unsigned int external_border_width
, external_border_height
;
8403 int title_bar_width
= 0, title_bar_height
= 0;
8404 int single_menu_bar_height
, wrapped_menu_bar_height
, menu_bar_height
;
8405 int tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
8406 int internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
8408 if (FRAME_INITIAL_P (f
) || !FRAME_W32_P (f
))
8412 /* Outer rectangle and borders. */
8413 window
.cbSize
= sizeof (window
);
8414 GetWindowInfo (FRAME_W32_WINDOW (f
), &window
);
8415 external_border_width
= window
.cxWindowBorders
;
8416 external_border_height
= window
.cyWindowBorders
;
8418 if (get_title_bar_info_fn
)
8420 TITLEBAR_INFO title_bar
;
8422 title_bar
.cbSize
= sizeof (title_bar
);
8423 title_bar
.rcTitleBar
.left
= title_bar
.rcTitleBar
.right
= 0;
8424 title_bar
.rcTitleBar
.top
= title_bar
.rcTitleBar
.bottom
= 0;
8425 for (int i
= 0; i
< 6; i
++)
8426 title_bar
.rgstate
[i
] = 0;
8427 if (get_title_bar_info_fn (FRAME_W32_WINDOW (f
), &title_bar
)
8428 && !(title_bar
.rgstate
[0] & 0x00008001))
8431 = title_bar
.rcTitleBar
.right
- title_bar
.rcTitleBar
.left
;
8433 = title_bar
.rcTitleBar
.bottom
- title_bar
.rcTitleBar
.top
;
8436 else if ((window
.dwStyle
& WS_CAPTION
) == WS_CAPTION
)
8437 title_bar_height
= GetSystemMetrics (SM_CYCAPTION
);
8439 menu_bar
.cbSize
= sizeof (menu_bar
);
8440 menu_bar
.rcBar
.right
= menu_bar
.rcBar
.left
= 0;
8441 menu_bar
.rcBar
.top
= menu_bar
.rcBar
.bottom
= 0;
8442 GetMenuBarInfo (FRAME_W32_WINDOW (f
), 0xFFFFFFFD, 0, &menu_bar
);
8443 single_menu_bar_height
= GetSystemMetrics (SM_CYMENU
);
8444 wrapped_menu_bar_height
= GetSystemMetrics (SM_CYMENUSIZE
);
8447 left
= window
.rcWindow
.left
;
8448 top
= window
.rcWindow
.top
;
8449 right
= window
.rcWindow
.right
;
8450 bottom
= window
.rcWindow
.bottom
;
8453 menu_bar_height
= menu_bar
.rcBar
.bottom
- menu_bar
.rcBar
.top
;
8454 /* Fix menu bar height reported by GetMenuBarInfo. */
8455 if (menu_bar_height
> single_menu_bar_height
)
8456 /* A wrapped menu bar. */
8457 menu_bar_height
+= single_menu_bar_height
- wrapped_menu_bar_height
;
8458 else if (menu_bar_height
> 0)
8459 /* A single line menu bar. */
8460 menu_bar_height
= single_menu_bar_height
;
8462 return listn (CONSTYPE_HEAP
, 10,
8463 Fcons (Qouter_position
,
8464 Fcons (make_number (left
), make_number (top
))),
8466 Fcons (make_number (right
- left
),
8467 make_number (bottom
- top
))),
8468 Fcons (Qexternal_border_size
,
8469 Fcons (make_number (external_border_width
),
8470 make_number (external_border_height
))),
8471 Fcons (Qtitle_bar_size
,
8472 Fcons (make_number (title_bar_width
),
8473 make_number (title_bar_height
))),
8474 Fcons (Qmenu_bar_external
, Qt
),
8475 Fcons (Qmenu_bar_size
,
8477 (menu_bar
.rcBar
.right
- menu_bar
.rcBar
.left
),
8478 make_number (menu_bar_height
))),
8479 Fcons (Qtool_bar_external
, Qnil
),
8480 Fcons (Qtool_bar_position
, tool_bar_height
? Qtop
: Qnil
),
8481 Fcons (Qtool_bar_size
,
8484 ? (right
- left
- 2 * external_border_width
8485 - 2 * internal_border_width
)
8487 make_number (tool_bar_height
))),
8488 Fcons (Qinternal_border_width
,
8489 make_number (internal_border_width
)));
8492 DEFUN ("w32-frame-edges", Fw32_frame_edges
, Sw32_frame_edges
, 0, 2, 0,
8493 doc
: /* Return edge coordinates of FRAME.
8494 FRAME must be a live frame and defaults to the selected one. The return
8495 value is a list of the form (LEFT, TOP, RIGHT, BOTTOM). All values are
8496 in pixels relative to the origin - the position (0, 0) - of FRAME's
8499 If optional argument TYPE is the symbol `outer-edges', return the outer
8500 edges of FRAME. The outer edges comprise the decorations of the window
8501 manager (like the title bar or external borders) as well as any external
8502 menu or tool bar of FRAME. If optional argument TYPE is the symbol
8503 `native-edges' or nil, return the native edges of FRAME. The native
8504 edges exclude the decorations of the window manager and any external
8505 menu or tool bar of FRAME. If TYPE is the symbol `inner-edges', return
8506 the inner edges of FRAME. These edges exclude title bar, any borders,
8507 menu bar or tool bar of FRAME. */)
8508 (Lisp_Object frame
, Lisp_Object type
)
8510 struct frame
*f
= decode_live_frame (frame
);
8512 if (FRAME_INITIAL_P (f
) || !FRAME_W32_P (f
))
8515 if (EQ (type
, Qouter_edges
))
8520 /* Outer frame rectangle, including outer borders and title bar. */
8521 GetWindowRect (FRAME_W32_WINDOW (f
), &rectangle
);
8524 return list4 (make_number (rectangle
.left
),
8525 make_number (rectangle
.top
),
8526 make_number (rectangle
.right
),
8527 make_number (rectangle
.bottom
));
8533 int left
, top
, right
, bottom
;
8536 /* Inner frame rectangle, excluding borders and title bar. */
8537 GetClientRect (FRAME_W32_WINDOW (f
), &rectangle
);
8538 /* Get top-left corner of native rectangle in screen
8542 ClientToScreen (FRAME_W32_WINDOW (f
), &pt
);
8547 right
= left
+ rectangle
.right
;
8548 bottom
= top
+ rectangle
.bottom
;
8550 if (EQ (type
, Qinner_edges
))
8552 int internal_border_width
= FRAME_INTERNAL_BORDER_WIDTH (f
);
8554 return list4 (make_number (left
+ internal_border_width
),
8556 + FRAME_TOOL_BAR_HEIGHT (f
)
8557 + internal_border_width
),
8558 make_number (right
- internal_border_width
),
8559 make_number (bottom
- internal_border_width
));
8562 return list4 (make_number (left
), make_number (top
),
8563 make_number (right
), make_number (bottom
));
8567 DEFUN ("w32-mouse-absolute-pixel-position", Fw32_mouse_absolute_pixel_position
,
8568 Sw32_mouse_absolute_pixel_position
, 0, 0, 0,
8569 doc
: /* Return absolute position of mouse cursor in pixels.
8570 The position is returned as a cons cell (X . Y) of the coordinates of
8571 the mouse cursor position in pixels relative to a position (0, 0) of the
8572 selected frame's display. */)
8581 return Fcons (make_number (pt
.x
), make_number (pt
.y
));
8584 DEFUN ("w32-set-mouse-absolute-pixel-position", Fw32_set_mouse_absolute_pixel_position
,
8585 Sw32_set_mouse_absolute_pixel_position
, 2, 2, 0,
8586 doc
: /* Move mouse pointer to absolute pixel position (X, Y).
8587 The coordinates X and Y are interpreted in pixels relative to a position
8588 \(0, 0) of the selected frame's display. */)
8589 (Lisp_Object x
, Lisp_Object y
)
8594 CHECK_TYPE_RANGED_INTEGER (int, x
);
8595 CHECK_TYPE_RANGED_INTEGER (int, y
);
8598 /* When "mouse trails" are in effect, moving the mouse cursor
8599 sometimes leaves behind an annoying "ghost" of the pointer.
8600 Avoid that by momentarily switching off mouse trails. */
8601 if (os_subtype
== OS_NT
8602 && w32_major_version
+ w32_minor_version
>= 6)
8603 ret
= SystemParametersInfo (SPI_GETMOUSETRAILS
, 0, &trail_num
, 0);
8604 SetCursorPos (XINT (x
), XINT (y
));
8606 SystemParametersInfo (SPI_SETMOUSETRAILS
, trail_num
, NULL
, 0);
8612 DEFUN ("w32-battery-status", Fw32_battery_status
, Sw32_battery_status
, 0, 0, 0,
8613 doc
: /* Get power status information from Windows system.
8615 The following %-sequences are provided:
8616 %L AC line status (verbose)
8617 %B Battery status (verbose)
8618 %b Battery status, empty means high, `-' means low,
8619 `!' means critical, and `+' means charging
8620 %p Battery load percentage
8621 %s Remaining time (to charge or discharge) in seconds
8622 %m Remaining time (to charge or discharge) in minutes
8623 %h Remaining time (to charge or discharge) in hours
8624 %t Remaining time (to charge or discharge) in the form `h:min' */)
8627 Lisp_Object status
= Qnil
;
8629 SYSTEM_POWER_STATUS system_status
;
8630 if (GetSystemPowerStatus (&system_status
))
8632 Lisp_Object line_status
, battery_status
, battery_status_symbol
;
8633 Lisp_Object load_percentage
, seconds
, minutes
, hours
, remain
;
8635 long seconds_left
= (long) system_status
.BatteryLifeTime
;
8637 if (system_status
.ACLineStatus
== 0)
8638 line_status
= build_string ("off-line");
8639 else if (system_status
.ACLineStatus
== 1)
8640 line_status
= build_string ("on-line");
8642 line_status
= build_string ("N/A");
8644 if (system_status
.BatteryFlag
& 128)
8646 battery_status
= build_string ("N/A");
8647 battery_status_symbol
= empty_unibyte_string
;
8649 else if (system_status
.BatteryFlag
& 8)
8651 battery_status
= build_string ("charging");
8652 battery_status_symbol
= build_string ("+");
8653 if (system_status
.BatteryFullLifeTime
!= -1L)
8654 seconds_left
= system_status
.BatteryFullLifeTime
- seconds_left
;
8656 else if (system_status
.BatteryFlag
& 4)
8658 battery_status
= build_string ("critical");
8659 battery_status_symbol
= build_string ("!");
8661 else if (system_status
.BatteryFlag
& 2)
8663 battery_status
= build_string ("low");
8664 battery_status_symbol
= build_string ("-");
8666 else if (system_status
.BatteryFlag
& 1)
8668 battery_status
= build_string ("high");
8669 battery_status_symbol
= empty_unibyte_string
;
8673 battery_status
= build_string ("medium");
8674 battery_status_symbol
= empty_unibyte_string
;
8677 if (system_status
.BatteryLifePercent
> 100)
8678 load_percentage
= build_string ("N/A");
8682 snprintf (buffer
, 16, "%d", system_status
.BatteryLifePercent
);
8683 load_percentage
= build_string (buffer
);
8686 if (seconds_left
< 0)
8687 seconds
= minutes
= hours
= remain
= build_string ("N/A");
8693 snprintf (buffer
, 16, "%ld", seconds_left
);
8694 seconds
= build_string (buffer
);
8696 m
= seconds_left
/ 60;
8697 snprintf (buffer
, 16, "%ld", m
);
8698 minutes
= build_string (buffer
);
8700 h
= seconds_left
/ 3600.0;
8701 snprintf (buffer
, 16, "%3.1f", h
);
8702 hours
= build_string (buffer
);
8704 snprintf (buffer
, 16, "%ld:%02ld", m
/ 60, m
% 60);
8705 remain
= build_string (buffer
);
8708 status
= listn (CONSTYPE_HEAP
, 8,
8709 Fcons (make_number ('L'), line_status
),
8710 Fcons (make_number ('B'), battery_status
),
8711 Fcons (make_number ('b'), battery_status_symbol
),
8712 Fcons (make_number ('p'), load_percentage
),
8713 Fcons (make_number ('s'), seconds
),
8714 Fcons (make_number ('m'), minutes
),
8715 Fcons (make_number ('h'), hours
),
8716 Fcons (make_number ('t'), remain
));
8723 typedef BOOL (WINAPI
*GetDiskFreeSpaceExW_Proc
)
8724 (LPCWSTR
, PULARGE_INTEGER
, PULARGE_INTEGER
, PULARGE_INTEGER
);
8725 typedef BOOL (WINAPI
*GetDiskFreeSpaceExA_Proc
)
8726 (LPCSTR
, PULARGE_INTEGER
, PULARGE_INTEGER
, PULARGE_INTEGER
);
8728 DEFUN ("file-system-info", Ffile_system_info
, Sfile_system_info
, 1, 1, 0,
8729 doc
: /* Return storage information about the file system FILENAME is on.
8730 Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
8731 storage of the file system, FREE is the free storage, and AVAIL is the
8732 storage available to a non-superuser. All 3 numbers are in bytes.
8733 If the underlying system call fails, value is nil. */)
8734 (Lisp_Object filename
)
8736 Lisp_Object encoded
, value
;
8738 CHECK_STRING (filename
);
8739 filename
= Fexpand_file_name (filename
, Qnil
);
8740 encoded
= ENCODE_FILE (filename
);
8744 /* Determining the required information on Windows turns out, sadly,
8745 to be more involved than one would hope. The original Windows API
8746 call for this will return bogus information on some systems, but we
8747 must dynamically probe for the replacement api, since that was
8748 added rather late on. */
8750 HMODULE hKernel
= GetModuleHandle ("kernel32");
8751 GetDiskFreeSpaceExW_Proc pfn_GetDiskFreeSpaceExW
=
8752 (GetDiskFreeSpaceExW_Proc
) GetProcAddress (hKernel
, "GetDiskFreeSpaceExW");
8753 GetDiskFreeSpaceExA_Proc pfn_GetDiskFreeSpaceExA
=
8754 (GetDiskFreeSpaceExA_Proc
) GetProcAddress (hKernel
, "GetDiskFreeSpaceExA");
8755 bool have_pfn_GetDiskFreeSpaceEx
=
8756 ((w32_unicode_filenames
&& pfn_GetDiskFreeSpaceExW
)
8757 || (!w32_unicode_filenames
&& pfn_GetDiskFreeSpaceExA
));
8759 /* On Windows, we may need to specify the root directory of the
8760 volume holding FILENAME. */
8761 char rootname
[MAX_UTF8_PATH
];
8762 wchar_t rootname_w
[MAX_PATH
];
8763 char rootname_a
[MAX_PATH
];
8764 char *name
= SSDATA (encoded
);
8767 /* find the root name of the volume if given */
8768 if (isalpha (name
[0]) && name
[1] == ':')
8770 rootname
[0] = name
[0];
8771 rootname
[1] = name
[1];
8775 else if (IS_DIRECTORY_SEP (name
[0]) && IS_DIRECTORY_SEP (name
[1]))
8777 char *str
= rootname
;
8781 if (IS_DIRECTORY_SEP (*name
) && --slashes
== 0)
8791 if (w32_unicode_filenames
)
8792 filename_to_utf16 (rootname
, rootname_w
);
8794 filename_to_ansi (rootname
, rootname_a
);
8796 if (have_pfn_GetDiskFreeSpaceEx
)
8798 /* Unsigned large integers cannot be cast to double, so
8799 use signed ones instead. */
8800 LARGE_INTEGER availbytes
;
8801 LARGE_INTEGER freebytes
;
8802 LARGE_INTEGER totalbytes
;
8804 if (w32_unicode_filenames
)
8805 result
= pfn_GetDiskFreeSpaceExW (rootname_w
,
8806 (ULARGE_INTEGER
*)&availbytes
,
8807 (ULARGE_INTEGER
*)&totalbytes
,
8808 (ULARGE_INTEGER
*)&freebytes
);
8810 result
= pfn_GetDiskFreeSpaceExA (rootname_a
,
8811 (ULARGE_INTEGER
*)&availbytes
,
8812 (ULARGE_INTEGER
*)&totalbytes
,
8813 (ULARGE_INTEGER
*)&freebytes
);
8815 value
= list3 (make_float ((double) totalbytes
.QuadPart
),
8816 make_float ((double) freebytes
.QuadPart
),
8817 make_float ((double) availbytes
.QuadPart
));
8821 DWORD sectors_per_cluster
;
8822 DWORD bytes_per_sector
;
8823 DWORD free_clusters
;
8824 DWORD total_clusters
;
8826 if (w32_unicode_filenames
)
8827 result
= GetDiskFreeSpaceW (rootname_w
,
8828 §ors_per_cluster
,
8833 result
= GetDiskFreeSpaceA (rootname_a
,
8834 §ors_per_cluster
,
8839 value
= list3 (make_float ((double) total_clusters
8840 * sectors_per_cluster
* bytes_per_sector
),
8841 make_float ((double) free_clusters
8842 * sectors_per_cluster
* bytes_per_sector
),
8843 make_float ((double) free_clusters
8844 * sectors_per_cluster
* bytes_per_sector
));
8850 #endif /* WINDOWSNT */
8854 DEFUN ("default-printer-name", Fdefault_printer_name
, Sdefault_printer_name
,
8855 0, 0, 0, doc
: /* Return the name of Windows default printer device. */)
8858 static char pname_buf
[256];
8861 PRINTER_INFO_2W
*ppi2w
= NULL
;
8862 PRINTER_INFO_2A
*ppi2a
= NULL
;
8863 DWORD dwNeeded
= 0, dwReturned
= 0;
8864 char server_name
[MAX_UTF8_PATH
], share_name
[MAX_UTF8_PATH
];
8865 char port_name
[MAX_UTF8_PATH
];
8867 /* Retrieve the default string from Win.ini (the registry).
8868 * String will be in form "printername,drivername,portname".
8869 * This is the most portable way to get the default printer. */
8870 if (GetProfileString ("windows", "device", ",,", pname_buf
, sizeof (pname_buf
)) <= 0)
8872 /* printername precedes first "," character */
8873 strtok (pname_buf
, ",");
8874 /* We want to know more than the printer name */
8875 if (!OpenPrinter (pname_buf
, &hPrn
, NULL
))
8877 /* GetPrinterW is not supported by unicows.dll. */
8878 if (w32_unicode_filenames
&& os_subtype
!= OS_9X
)
8879 GetPrinterW (hPrn
, 2, NULL
, 0, &dwNeeded
);
8881 GetPrinterA (hPrn
, 2, NULL
, 0, &dwNeeded
);
8884 ClosePrinter (hPrn
);
8887 /* Call GetPrinter again with big enough memory block. */
8888 if (w32_unicode_filenames
&& os_subtype
!= OS_9X
)
8890 /* Allocate memory for the PRINTER_INFO_2 struct. */
8891 ppi2w
= xmalloc (dwNeeded
);
8892 err
= GetPrinterW (hPrn
, 2, (LPBYTE
)ppi2w
, dwNeeded
, &dwReturned
);
8893 ClosePrinter (hPrn
);
8900 if ((ppi2w
->Attributes
& PRINTER_ATTRIBUTE_SHARED
)
8901 && ppi2w
->pServerName
)
8903 filename_from_utf16 (ppi2w
->pServerName
, server_name
);
8904 filename_from_utf16 (ppi2w
->pShareName
, share_name
);
8908 server_name
[0] = '\0';
8909 filename_from_utf16 (ppi2w
->pPortName
, port_name
);
8914 ppi2a
= xmalloc (dwNeeded
);
8915 err
= GetPrinterA (hPrn
, 2, (LPBYTE
)ppi2a
, dwNeeded
, &dwReturned
);
8916 ClosePrinter (hPrn
);
8923 if ((ppi2a
->Attributes
& PRINTER_ATTRIBUTE_SHARED
)
8924 && ppi2a
->pServerName
)
8926 filename_from_ansi (ppi2a
->pServerName
, server_name
);
8927 filename_from_ansi (ppi2a
->pShareName
, share_name
);
8931 server_name
[0] = '\0';
8932 filename_from_ansi (ppi2a
->pPortName
, port_name
);
8938 /* a remote printer */
8939 if (server_name
[0] == '\\')
8940 snprintf (pname_buf
, sizeof (pname_buf
), "%s\\%s", server_name
,
8943 snprintf (pname_buf
, sizeof (pname_buf
), "\\\\%s\\%s", server_name
,
8945 pname_buf
[sizeof (pname_buf
) - 1] = '\0';
8949 /* a local printer */
8950 strncpy (pname_buf
, port_name
, sizeof (pname_buf
));
8951 pname_buf
[sizeof (pname_buf
) - 1] = '\0';
8952 /* `pPortName' can include several ports, delimited by ','.
8953 * we only use the first one. */
8954 strtok (pname_buf
, ",");
8957 return DECODE_FILE (build_unibyte_string (pname_buf
));
8959 #endif /* WINDOWSNT */
8962 /* Equivalent of strerror for W32 error codes. */
8964 w32_strerror (int error_no
)
8966 static char buf
[500];
8970 error_no
= GetLastError ();
8972 ret
= FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
|
8973 FORMAT_MESSAGE_IGNORE_INSERTS
,
8976 0, /* choose most suitable language */
8977 buf
, sizeof (buf
), NULL
);
8979 while (ret
> 0 && (buf
[ret
- 1] == '\n' ||
8980 buf
[ret
- 1] == '\r' ))
8984 sprintf (buf
, "w32 error %d", error_no
);
8989 /* For convenience when debugging. (You cannot call GetLastError
8990 directly from GDB: it will crash, because it uses the __stdcall
8991 calling convention, not the _cdecl convention assumed by GDB.) */
8992 DWORD
w32_last_error (void);
8995 w32_last_error (void)
8997 return GetLastError ();
9000 /* Cache information describing the NT system for later use. */
9002 cache_system_info (void)
9015 /* Cache the module handle of Emacs itself. */
9016 hinst
= GetModuleHandle (NULL
);
9018 /* Cache the version of the operating system. */
9019 version
.data
= GetVersion ();
9020 w32_major_version
= version
.info
.major
;
9021 w32_minor_version
= version
.info
.minor
;
9023 if (version
.info
.platform
& 0x8000)
9028 /* Cache page size, allocation unit, processor type, etc. */
9029 GetSystemInfo (&sysinfo_cache
);
9030 syspage_mask
= (DWORD_PTR
)sysinfo_cache
.dwPageSize
- 1;
9032 /* Cache os info. */
9033 osinfo_cache
.dwOSVersionInfoSize
= sizeof (OSVERSIONINFO
);
9034 GetVersionEx (&osinfo_cache
);
9036 w32_build_number
= osinfo_cache
.dwBuildNumber
;
9037 if (os_subtype
== OS_9X
)
9038 w32_build_number
&= 0xffff;
9040 w32_num_mouse_buttons
= GetSystemMetrics (SM_CMOUSEBUTTONS
);
9045 _DebPrint (const char *fmt
, ...)
9050 va_start (args
, fmt
);
9051 vsprintf (buf
, fmt
, args
);
9054 fprintf (stderr
, "%s", buf
);
9056 OutputDebugString (buf
);
9061 w32_console_toggle_lock_key (int vk_code
, Lisp_Object new_state
)
9063 int cur_state
= (GetKeyState (vk_code
) & 1);
9065 if (NILP (new_state
)
9066 || (NUMBERP (new_state
)
9067 && ((XUINT (new_state
)) & 1) != cur_state
))
9070 faked_key
= vk_code
;
9071 #endif /* WINDOWSNT */
9073 keybd_event ((BYTE
) vk_code
,
9074 (BYTE
) MapVirtualKey (vk_code
, 0),
9075 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
9076 keybd_event ((BYTE
) vk_code
,
9077 (BYTE
) MapVirtualKey (vk_code
, 0),
9078 KEYEVENTF_EXTENDEDKEY
| 0, 0);
9079 keybd_event ((BYTE
) vk_code
,
9080 (BYTE
) MapVirtualKey (vk_code
, 0),
9081 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
9082 cur_state
= !cur_state
;
9088 /* Translate console modifiers to emacs modifiers.
9089 German keyboard support (Kai Morgan Zeise 2/18/95). */
9091 w32_kbd_mods_to_emacs (DWORD mods
, WORD key
)
9095 /* If we recognize right-alt and left-ctrl as AltGr, and it has been
9096 pressed, first remove those modifiers. */
9097 if (!NILP (Vw32_recognize_altgr
)
9098 && (mods
& (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
))
9099 == (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
))
9100 mods
&= ~ (RIGHT_ALT_PRESSED
| LEFT_CTRL_PRESSED
);
9102 if (mods
& (RIGHT_ALT_PRESSED
| LEFT_ALT_PRESSED
))
9103 retval
= ((NILP (Vw32_alt_is_meta
)) ? alt_modifier
: meta_modifier
);
9105 if (mods
& (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
9107 retval
|= ctrl_modifier
;
9108 if ((mods
& (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
9109 == (RIGHT_CTRL_PRESSED
| LEFT_CTRL_PRESSED
))
9110 retval
|= meta_modifier
;
9113 if (mods
& LEFT_WIN_PRESSED
)
9114 retval
|= w32_key_to_modifier (VK_LWIN
);
9115 if (mods
& RIGHT_WIN_PRESSED
)
9116 retval
|= w32_key_to_modifier (VK_RWIN
);
9117 if (mods
& APPS_PRESSED
)
9118 retval
|= w32_key_to_modifier (VK_APPS
);
9119 if (mods
& SCROLLLOCK_ON
)
9120 retval
|= w32_key_to_modifier (VK_SCROLL
);
9122 /* Just in case someone wanted the original behavior, make it
9123 optional by setting w32-capslock-is-shiftlock to t. */
9124 if (NILP (Vw32_capslock_is_shiftlock
)
9125 /* Keys that should _not_ be affected by CapsLock. */
9126 && ( (key
== VK_BACK
)
9128 || (key
== VK_CLEAR
)
9129 || (key
== VK_RETURN
)
9130 || (key
== VK_ESCAPE
)
9131 || ((key
>= VK_SPACE
) && (key
<= VK_HELP
))
9132 || ((key
>= VK_NUMPAD0
) && (key
<= VK_F24
))
9133 || ((key
>= VK_NUMPAD_CLEAR
) && (key
<= VK_NUMPAD_DELETE
))
9136 /* Only consider shift state. */
9137 if ((mods
& SHIFT_PRESSED
) != 0)
9138 retval
|= shift_modifier
;
9142 /* Ignore CapsLock state if not enabled. */
9143 if (NILP (Vw32_enable_caps_lock
))
9144 mods
&= ~CAPSLOCK_ON
;
9145 if ((mods
& (SHIFT_PRESSED
| CAPSLOCK_ON
)) != 0)
9146 retval
|= shift_modifier
;
9152 /* The return code indicates key code size. cpID is the codepage to
9153 use for translation to Unicode; -1 means use the current console
9156 w32_kbd_patch_key (KEY_EVENT_RECORD
*event
, int cpId
)
9158 unsigned int key_code
= event
->wVirtualKeyCode
;
9159 unsigned int mods
= event
->dwControlKeyState
;
9161 static BYTE ansi_code
[4];
9162 static int isdead
= 0;
9166 event
->uChar
.AsciiChar
= ansi_code
[2];
9170 if (event
->uChar
.AsciiChar
!= 0)
9173 memset (keystate
, 0, sizeof (keystate
));
9174 keystate
[key_code
] = 0x80;
9175 if (mods
& SHIFT_PRESSED
)
9176 keystate
[VK_SHIFT
] = 0x80;
9177 if (mods
& CAPSLOCK_ON
)
9178 keystate
[VK_CAPITAL
] = 1;
9179 /* If we recognize right-alt and left-ctrl as AltGr, set the key
9180 states accordingly before invoking ToAscii. */
9181 if (!NILP (Vw32_recognize_altgr
)
9182 && (mods
& LEFT_CTRL_PRESSED
) && (mods
& RIGHT_ALT_PRESSED
))
9184 keystate
[VK_CONTROL
] = 0x80;
9185 keystate
[VK_LCONTROL
] = 0x80;
9186 keystate
[VK_MENU
] = 0x80;
9187 keystate
[VK_RMENU
] = 0x80;
9191 /* Because of an OS bug, ToAscii corrupts the stack when called to
9192 convert a dead key in console mode on NT4. Unfortunately, trying
9193 to check for dead keys using MapVirtualKey doesn't work either -
9194 these functions apparently use internal information about keyboard
9195 layout which doesn't get properly updated in console programs when
9196 changing layout (though apparently it gets partly updated,
9197 otherwise ToAscii wouldn't crash). */
9198 if (is_dead_key (event
->wVirtualKeyCode
))
9202 /* On NT, call ToUnicode instead and then convert to the current
9203 console input codepage. */
9204 if (os_subtype
== OS_NT
)
9208 isdead
= ToUnicode (event
->wVirtualKeyCode
, event
->wVirtualScanCode
,
9209 keystate
, buf
, 128, 0);
9212 /* When we are called from the GUI message processing code,
9213 we are passed the current keyboard codepage, a positive
9214 number, to use below. */
9216 cpId
= GetConsoleCP ();
9218 event
->uChar
.UnicodeChar
= buf
[isdead
- 1];
9219 isdead
= WideCharToMultiByte (cpId
, 0, buf
, isdead
,
9220 (LPSTR
)ansi_code
, 4, NULL
, NULL
);
9227 isdead
= ToAscii (event
->wVirtualKeyCode
, event
->wVirtualScanCode
,
9228 keystate
, (LPWORD
) ansi_code
, 0);
9233 event
->uChar
.AsciiChar
= ansi_code
[0];
9239 w32_sys_ring_bell (struct frame
*f
)
9241 if (sound_type
== 0xFFFFFFFF)
9245 else if (sound_type
== MB_EMACS_SILENT
)
9250 MessageBeep (sound_type
);
9253 DEFUN ("w32--menu-bar-in-use", Fw32__menu_bar_in_use
, Sw32__menu_bar_in_use
,
9255 doc
: /* Return non-nil when a menu-bar menu is being used.
9256 Internal use only. */)
9259 return menubar_in_use
? Qt
: Qnil
;
9262 #if defined WINDOWSNT && !defined HAVE_DBUS
9264 /***********************************************************************
9266 ***********************************************************************/
9267 /* A private struct declaration to avoid compile-time limits. */
9268 typedef struct MY_NOTIFYICONDATAW
{
9273 UINT uCallbackMessage
;
9279 _ANONYMOUS_UNION
union {
9283 WCHAR szInfoTitle
[64];
9287 } MY_NOTIFYICONDATAW
;
9289 #define MYNOTIFYICONDATAW_V1_SIZE offsetof (MY_NOTIFYICONDATAW, szTip[64])
9290 #define MYNOTIFYICONDATAW_V2_SIZE offsetof (MY_NOTIFYICONDATAW, guidItem)
9291 #define MYNOTIFYICONDATAW_V3_SIZE offsetof (MY_NOTIFYICONDATAW, hBalloonIcon)
9293 # define NIF_INFO 0x00000010
9296 # define NIIF_NONE 0x00000000
9299 # define NIIF_INFO 0x00000001
9301 #ifndef NIIF_WARNING
9302 # define NIIF_WARNING 0x00000002
9305 # define NIIF_ERROR 0x00000003
9309 #define EMACS_TRAY_NOTIFICATION_ID 42 /* arbitrary */
9310 #define EMACS_NOTIFICATION_MSG (WM_APP + 1)
9319 /* Report the version of a DLL given by its name. The return value is
9320 constructed using MAKEDLLVERULL. */
9322 get_dll_version (const char *dll_name
)
9324 ULONGLONG version
= 0;
9325 HINSTANCE hdll
= LoadLibrary (dll_name
);
9329 DLLGETVERSIONPROC pDllGetVersion
9330 = (DLLGETVERSIONPROC
) GetProcAddress (hdll
, "DllGetVersion");
9337 memset (&dvi
, 0, sizeof(dvi
));
9338 dvi
.cbSize
= sizeof(dvi
);
9339 result
= pDllGetVersion (&dvi
);
9340 if (SUCCEEDED (result
))
9341 version
= MAKEDLLVERULL (dvi
.dwMajorVersion
, dvi
.dwMinorVersion
,
9350 /* Return the number of bytes in UTF-8 encoded string STR that
9351 corresponds to at most LIM characters. If STR ends before LIM
9352 characters, return the number of bytes in STR including the
9353 terminating null byte. */
9355 utf8_mbslen_lim (const char *str
, int lim
)
9357 const char *p
= str
;
9358 int mblen
= 0, nchars
= 0;
9360 while (*p
&& nchars
< lim
)
9362 int nbytes
= CHAR_BYTES (*p
);
9369 if (!*p
&& nchars
< lim
)
9375 /* Low-level subroutine to show tray notifications. All strings are
9376 supposed to be unibyte UTF-8 encoded by the caller. */
9378 add_tray_notification (struct frame
*f
, const char *icon
, const char *tip
,
9379 enum NI_Severity severity
, unsigned timeout
,
9380 const char *title
, const char *msg
)
9382 EMACS_INT retval
= EMACS_TRAY_NOTIFICATION_ID
;
9384 if (FRAME_W32_P (f
))
9386 MY_NOTIFYICONDATAW nidw
;
9387 ULONGLONG shell_dll_version
= get_dll_version ("Shell32.dll");
9388 wchar_t tipw
[128], msgw
[256], titlew
[64];
9391 memset (&nidw
, 0, sizeof(nidw
));
9393 /* MSDN says the full struct is supported since Vista, whose
9394 Shell32.dll version is said to be 6.0.6. But DllGetVersion
9395 cannot report the 3rd field value, it reports "build number"
9396 instead, which is something else. So we use the Windows 7's
9397 version 6.1 as cutoff, and Vista loses. (Actually, the loss
9398 is not a real one, since we don't expose the hBalloonIcon
9399 member of the struct to Lisp.) */
9400 if (shell_dll_version
>= MAKEDLLVERULL (6, 1, 0, 0)) /* >= Windows 7 */
9401 nidw
.cbSize
= sizeof (nidw
);
9402 else if (shell_dll_version
>= MAKEDLLVERULL (6, 0, 0, 0)) /* XP */
9403 nidw
.cbSize
= MYNOTIFYICONDATAW_V3_SIZE
;
9404 else if (shell_dll_version
>= MAKEDLLVERULL (5, 0, 0, 0)) /* W2K */
9405 nidw
.cbSize
= MYNOTIFYICONDATAW_V2_SIZE
;
9407 nidw
.cbSize
= MYNOTIFYICONDATAW_V1_SIZE
; /* < W2K */
9408 nidw
.hWnd
= FRAME_W32_WINDOW (f
);
9409 nidw
.uID
= EMACS_TRAY_NOTIFICATION_ID
;
9410 nidw
.uFlags
= NIF_MESSAGE
| NIF_ICON
| NIF_TIP
| NIF_INFO
;
9411 nidw
.uCallbackMessage
= EMACS_NOTIFICATION_MSG
;
9413 nidw
.hIcon
= LoadIcon (hinst
, EMACS_CLASS
);
9416 if (w32_unicode_filenames
)
9418 wchar_t icon_w
[MAX_PATH
];
9420 if (filename_to_utf16 (icon
, icon_w
) != 0)
9425 nidw
.hIcon
= LoadImageW (NULL
, icon_w
, IMAGE_ICON
, 0, 0,
9426 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9430 char icon_a
[MAX_PATH
];
9432 if (filename_to_ansi (icon
, icon_a
) != 0)
9437 nidw
.hIcon
= LoadImageA (NULL
, icon_a
, IMAGE_ICON
, 0, 0,
9438 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
9443 switch (GetLastError ())
9445 case ERROR_FILE_NOT_FOUND
:
9455 /* Windows 9X and NT4 support only 64 characters in the Tip,
9456 later versions support up to 128. */
9457 if (nidw
.cbSize
== MYNOTIFYICONDATAW_V1_SIZE
)
9459 tiplen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9460 tip
, utf8_mbslen_lim (tip
, 63),
9467 tiplen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9468 tip
, utf8_mbslen_lim (tip
, 127),
9479 wcscpy (nidw
.szTip
, tipw
);
9481 /* The rest of the structure is only supported since Windows 2000. */
9482 if (nidw
.cbSize
> MYNOTIFYICONDATAW_V1_SIZE
)
9486 slen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9487 msg
, utf8_mbslen_lim (msg
, 255),
9497 wcscpy (nidw
.szInfo
, msgw
);
9498 nidw
.uTimeout
= timeout
;
9499 slen
= pMultiByteToWideChar (CP_UTF8
, multiByteToWideCharFlags
,
9500 title
, utf8_mbslen_lim (title
, 63),
9510 wcscpy (nidw
.szInfoTitle
, titlew
);
9515 nidw
.dwInfoFlags
= NIIF_NONE
;
9519 nidw
.dwInfoFlags
= NIIF_INFO
;
9522 nidw
.dwInfoFlags
= NIIF_WARNING
;
9525 nidw
.dwInfoFlags
= NIIF_ERROR
;
9530 if (!Shell_NotifyIconW (NIM_ADD
, (PNOTIFYICONDATAW
)&nidw
))
9532 /* GetLastError returns meaningless results when
9533 Shell_NotifyIcon fails. */
9534 DebPrint (("Shell_NotifyIcon ADD failed (err=%d)\n",
9540 if (*icon
&& !DestroyIcon (nidw
.hIcon
))
9541 DebPrint (("DestroyIcon failed (err=%d)\n", GetLastError ()));
9546 /* Low-level subroutine to remove a tray notification. Note: we only
9547 pass the minimum data about the notification: its ID and the handle
9548 of the window to which it sends messages. MSDN doesn't say this is
9549 enough, but it works in practice. This allows us to avoid keeping
9550 the notification data around after we show the notification. */
9552 delete_tray_notification (struct frame
*f
, int id
)
9554 if (FRAME_W32_P (f
))
9556 MY_NOTIFYICONDATAW nidw
;
9558 memset (&nidw
, 0, sizeof(nidw
));
9559 nidw
.hWnd
= FRAME_W32_WINDOW (f
);
9562 if (!Shell_NotifyIconW (NIM_DELETE
, (PNOTIFYICONDATAW
)&nidw
))
9564 /* GetLastError returns meaningless results when
9565 Shell_NotifyIcon fails. */
9566 DebPrint (("Shell_NotifyIcon DELETE failed\n"));
9574 DEFUN ("w32-notification-notify",
9575 Fw32_notification_notify
, Sw32_notification_notify
,
9577 doc
: /* Display an MS-Windows tray notification as specified by PARAMS.
9579 Value is the integer unique ID of the notification that can be used
9580 to remove the notification using `w32-notification-close', which see.
9581 If the function fails, the return value is nil.
9583 Tray notifications, a.k.a. \"taskbar messages\", are messages that
9584 inform the user about events unrelated to the current user activity,
9585 such as a significant system event, by briefly displaying informative
9586 text in a balloon from an icon in the notification area of the taskbar.
9588 Parameters in PARAMS are specified as keyword/value pairs. All the
9589 parameters are optional, but if no parameters are specified, the
9590 function will do nothing and return nil.
9592 The following parameters are supported:
9594 :icon ICON -- Display ICON in the system tray. If ICON is a string,
9595 it should specify a file name from which to load the
9596 icon; the specified file should be a .ico Windows icon
9597 file. If ICON is not a string, or if this parameter
9598 is not specified, the standard Emacs icon will be used.
9600 :tip TIP -- Use TIP as the tooltip for the notification. If TIP
9601 is a string, this is the text of a tooltip that will
9602 be shown when the mouse pointer hovers over the tray
9603 icon added by the notification. If TIP is not a
9604 string, or if this parameter is not specified, the
9605 default tooltip text is \"Emacs notification\". The
9606 tooltip text can be up to 127 characters long (63
9607 on Windows versions before W2K). Longer strings
9610 :level LEVEL -- Notification severity level, one of `info',
9611 `warning', or `error'. If given, the value
9612 determines the icon displayed to the left of the
9613 notification title, but only if the `:title'
9614 parameter (see below) is also specified and is a
9617 :title TITLE -- The title of the notification. If TITLE is a string,
9618 it is displayed in a larger font immediately above
9619 the body text. The title text can be up to 63
9620 characters long; longer text will be truncated.
9622 :body BODY -- The body of the notification. If BODY is a string,
9623 it specifies the text of the notification message.
9624 Use embedded newlines to control how the text is
9625 broken into lines. The body text can be up to 255
9626 characters long, and will be truncated if it's longer.
9628 Note that versions of Windows before W2K support only `:icon' and `:tip'.
9629 You can pass the other parameters, but they will be ignored on those
9632 There can be at most one active notification at any given time. An
9633 active notification must be removed by calling `w32-notification-close'
9634 before a new one can be shown.
9636 usage: (w32-notification-notify &rest PARAMS) */)
9637 (ptrdiff_t nargs
, Lisp_Object
*args
)
9639 struct frame
*f
= SELECTED_FRAME ();
9640 Lisp_Object arg_plist
, lres
;
9642 char *icon
, *tip
, *title
, *msg
;
9643 enum NI_Severity severity
;
9644 unsigned timeout
= 0;
9649 arg_plist
= Flist (nargs
, args
);
9652 lres
= Fplist_get (arg_plist
, QCicon
);
9654 icon
= SSDATA (ENCODE_FILE (Fexpand_file_name (lres
, Qnil
)));
9659 lres
= Fplist_get (arg_plist
, QCtip
);
9661 tip
= SSDATA (code_convert_string_norecord (lres
, Qutf_8
, 1));
9663 tip
= (char *)"Emacs notification";
9666 lres
= Fplist_get (arg_plist
, QClevel
);
9669 else if (EQ (lres
, Qinfo
))
9671 else if (EQ (lres
, Qwarning
))
9673 else if (EQ (lres
, Qerror
))
9679 lres
= Fplist_get (arg_plist
, QCtitle
);
9681 title
= SSDATA (code_convert_string_norecord (lres
, Qutf_8
, 1));
9685 /* Notification body text. */
9686 lres
= Fplist_get (arg_plist
, QCbody
);
9688 msg
= SSDATA (code_convert_string_norecord (lres
, Qutf_8
, 1));
9693 retval
= add_tray_notification (f
, icon
, tip
, severity
, timeout
, title
, msg
);
9694 return (retval
< 0 ? Qnil
: make_number (retval
));
9697 DEFUN ("w32-notification-close",
9698 Fw32_notification_close
, Sw32_notification_close
,
9700 doc
: /* Remove the MS-Windows tray notification specified by its ID. */)
9703 struct frame
*f
= SELECTED_FRAME ();
9706 delete_tray_notification (f
, XINT (id
));
9711 #endif /* WINDOWSNT && !HAVE_DBUS */
9714 /***********************************************************************
9716 ***********************************************************************/
9718 /* Keep this list in the same order as frame_parms in frame.c.
9719 Use 0 for unsupported frame parameters. */
9721 frame_parm_handler w32_frame_parm_handlers
[] =
9725 x_set_background_color
,
9731 x_set_foreground_color
,
9734 x_set_internal_border_width
,
9735 x_set_right_divider_width
,
9736 x_set_bottom_divider_width
,
9737 x_set_menu_bar_lines
,
9739 x_explicitly_set_name
,
9740 x_set_scroll_bar_width
,
9741 x_set_scroll_bar_height
,
9744 x_set_vertical_scroll_bars
,
9745 x_set_horizontal_scroll_bars
,
9747 x_set_tool_bar_lines
,
9748 0, /* x_set_scroll_bar_foreground, */
9749 0, /* x_set_scroll_bar_background, */
9754 0, /* x_set_wait_for_wm, */
9758 0, /* x_set_sticky */
9759 0, /* x_set_tool_bar_position */
9760 0, /* x_set_inhibit_double_buffering */
9764 syms_of_w32fns (void)
9766 globals_of_w32fns ();
9767 track_mouse_window
= NULL
;
9769 w32_visible_system_caret_hwnd
= NULL
;
9771 DEFSYM (Qundefined_color
, "undefined-color");
9772 DEFSYM (Qcancel_timer
, "cancel-timer");
9773 DEFSYM (Qhyper
, "hyper");
9774 DEFSYM (Qsuper
, "super");
9775 DEFSYM (Qmeta
, "meta");
9776 DEFSYM (Qalt
, "alt");
9777 DEFSYM (Qctrl
, "ctrl");
9778 DEFSYM (Qcontrol
, "control");
9779 DEFSYM (Qshift
, "shift");
9780 DEFSYM (Qfont_parameter
, "font-parameter");
9781 DEFSYM (Qgeometry
, "geometry");
9782 DEFSYM (Qworkarea
, "workarea");
9783 DEFSYM (Qmm_size
, "mm-size");
9784 DEFSYM (Qframes
, "frames");
9785 DEFSYM (Qtip_frame
, "tip-frame");
9786 DEFSYM (Qassq_delete_all
, "assq-delete-all");
9787 DEFSYM (Qunicode_sip
, "unicode-sip");
9788 #if defined WINDOWSNT && !defined HAVE_DBUS
9789 DEFSYM (QCicon
, ":icon");
9790 DEFSYM (QCtip
, ":tip");
9791 DEFSYM (QClevel
, ":level");
9792 DEFSYM (Qinfo
, "info");
9793 DEFSYM (Qwarning
, "warning");
9794 DEFSYM (QCtitle
, ":title");
9795 DEFSYM (QCbody
, ":body");
9798 /* Symbols used elsewhere, but only in MS-Windows-specific code. */
9799 DEFSYM (Qgnutls
, "gnutls");
9800 DEFSYM (Qlibxml2
, "libxml2");
9801 DEFSYM (Qserif
, "serif");
9802 DEFSYM (Qzlib
, "zlib");
9804 Fput (Qundefined_color
, Qerror_conditions
,
9805 listn (CONSTYPE_PURE
, 2, Qundefined_color
, Qerror
));
9806 Fput (Qundefined_color
, Qerror_message
,
9807 build_pure_c_string ("Undefined color"));
9809 staticpro (&w32_grabbed_keys
);
9810 w32_grabbed_keys
= Qnil
;
9812 DEFVAR_LISP ("w32-color-map", Vw32_color_map
,
9813 doc
: /* An array of color name mappings for Windows. */);
9814 Vw32_color_map
= Qnil
;
9816 DEFVAR_LISP ("w32-pass-alt-to-system", Vw32_pass_alt_to_system
,
9817 doc
: /* Non-nil if Alt key presses are passed on to Windows.
9818 When non-nil, for example, Alt pressed and released and then space will
9819 open the System menu. When nil, Emacs processes the Alt key events, and
9820 then silently swallows them. */);
9821 Vw32_pass_alt_to_system
= Qnil
;
9823 DEFVAR_LISP ("w32-alt-is-meta", Vw32_alt_is_meta
,
9824 doc
: /* Non-nil if the Alt key is to be considered the same as the META key.
9825 When nil, Emacs will translate the Alt key to the ALT modifier, not to META. */);
9826 Vw32_alt_is_meta
= Qt
;
9828 DEFVAR_INT ("w32-quit-key", w32_quit_key
,
9829 doc
: /* If non-zero, the virtual key code for an alternative quit key. */);
9832 DEFVAR_LISP ("w32-pass-lwindow-to-system",
9833 Vw32_pass_lwindow_to_system
,
9834 doc
: /* If non-nil, the left \"Windows\" key is passed on to Windows.
9836 When non-nil, the Start menu is opened by tapping the key.
9837 If you set this to nil, the left \"Windows\" key is processed by Emacs
9838 according to the value of `w32-lwindow-modifier', which see.
9840 Note that some combinations of the left \"Windows\" key with other
9841 keys are caught by Windows at low level. For example, <lwindow>-r
9842 pops up the Windows Run dialog, <lwindow>-<Pause> pops up the "System
9843 Properties" dialog, etc. On Windows 10, no \"Windows\" key
9844 combinations are normally handed to applications. To enable Emacs to
9845 process \"Windows\" key combinations, use the function
9846 `w32-register-hot-key`.
9848 For Windows 98/ME, see the doc string of `w32-phantom-key-code'. */);
9849 Vw32_pass_lwindow_to_system
= Qt
;
9851 DEFVAR_LISP ("w32-pass-rwindow-to-system",
9852 Vw32_pass_rwindow_to_system
,
9853 doc
: /* If non-nil, the right \"Windows\" key is passed on to Windows.
9855 When non-nil, the Start menu is opened by tapping the key.
9856 If you set this to nil, the right \"Windows\" key is processed by Emacs
9857 according to the value of `w32-rwindow-modifier', which see.
9859 Note that some combinations of the right \"Windows\" key with other
9860 keys are caught by Windows at low level. For example, <rwindow>-r
9861 pops up the Windows Run dialog, <rwindow>-<Pause> pops up the "System
9862 Properties" dialog, etc. On Windows 10, no \"Windows\" key
9863 combinations are normally handed to applications. To enable Emacs to
9864 process \"Windows\" key combinations, use the function
9865 `w32-register-hot-key`.
9867 For Windows 98/ME, see the doc string of `w32-phantom-key-code'. */);
9868 Vw32_pass_rwindow_to_system
= Qt
;
9870 DEFVAR_LISP ("w32-phantom-key-code",
9871 Vw32_phantom_key_code
,
9872 doc
: /* Virtual key code used to generate \"phantom\" key presses.
9873 Value is a number between 0 and 255.
9875 Phantom key presses are generated in order to stop the system from
9876 acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or
9877 `w32-pass-rwindow-to-system' is nil.
9879 This variable is only used on Windows 98 and ME. For other Windows
9880 versions, see the documentation of the `w32-register-hot-key`
9882 /* Although 255 is technically not a valid key code, it works and
9883 means that this hack won't interfere with any real key code. */
9884 XSETINT (Vw32_phantom_key_code
, 255);
9886 DEFVAR_LISP ("w32-enable-num-lock",
9887 Vw32_enable_num_lock
,
9888 doc
: /* If non-nil, the Num Lock key acts normally.
9889 Set to nil to handle Num Lock as the `kp-numlock' key. */);
9890 Vw32_enable_num_lock
= Qt
;
9892 DEFVAR_LISP ("w32-enable-caps-lock",
9893 Vw32_enable_caps_lock
,
9894 doc
: /* If non-nil, the Caps Lock key acts normally.
9895 Set to nil to handle Caps Lock as the `capslock' key. */);
9896 Vw32_enable_caps_lock
= Qt
;
9898 DEFVAR_LISP ("w32-scroll-lock-modifier",
9899 Vw32_scroll_lock_modifier
,
9900 doc
: /* Modifier to use for the Scroll Lock ON state.
9901 The value can be hyper, super, meta, alt, control or shift for the
9902 respective modifier, or nil to handle Scroll Lock as the `scroll' key.
9903 Any other value will cause the Scroll Lock key to be ignored by Emacs,
9904 and it will have the same effect as in other applications. */);
9905 Vw32_scroll_lock_modifier
= Qnil
;
9907 DEFVAR_LISP ("w32-lwindow-modifier",
9908 Vw32_lwindow_modifier
,
9909 doc
: /* Modifier to use for the left \"Windows\" key.
9910 The value can be hyper, super, meta, alt, control or shift for the
9911 respective modifier, or nil to appear as the `lwindow' key.
9912 Any other value will cause the key to be ignored.
9914 Also see the documentation of the `w32-register-hot-key` function. */);
9915 Vw32_lwindow_modifier
= Qnil
;
9917 DEFVAR_LISP ("w32-rwindow-modifier",
9918 Vw32_rwindow_modifier
,
9919 doc
: /* Modifier to use for the right \"Windows\" key.
9920 The value can be hyper, super, meta, alt, control or shift for the
9921 respective modifier, or nil to appear as the `rwindow' key.
9922 Any other value will cause the key to be ignored.
9924 Also see the documentation of the `w32-register-hot-key` function. */);
9925 Vw32_rwindow_modifier
= Qnil
;
9927 DEFVAR_LISP ("w32-apps-modifier",
9929 doc
: /* Modifier to use for the \"Apps\" key.
9930 The value can be hyper, super, meta, alt, control or shift for the
9931 respective modifier, or nil to appear as the `apps' key.
9932 Any other value will cause the key to be ignored. */);
9933 Vw32_apps_modifier
= Qnil
;
9935 DEFVAR_BOOL ("w32-enable-synthesized-fonts", w32_enable_synthesized_fonts
,
9936 doc
: /* Non-nil enables selection of artificially italicized and bold fonts. */);
9937 w32_enable_synthesized_fonts
= 0;
9939 DEFVAR_LISP ("w32-enable-palette", Vw32_enable_palette
,
9940 doc
: /* Non-nil enables Windows palette management to map colors exactly. */);
9941 Vw32_enable_palette
= Qt
;
9943 DEFVAR_INT ("w32-mouse-button-tolerance",
9944 w32_mouse_button_tolerance
,
9945 doc
: /* Analogue of double click interval for faking middle mouse events.
9946 The value is the minimum time in milliseconds that must elapse between
9947 left and right button down events before they are considered distinct events.
9948 If both mouse buttons are depressed within this interval, a middle mouse
9949 button down event is generated instead. */);
9950 w32_mouse_button_tolerance
= GetDoubleClickTime () / 2;
9952 DEFVAR_INT ("w32-mouse-move-interval",
9953 w32_mouse_move_interval
,
9954 doc
: /* Minimum interval between mouse move events.
9955 The value is the minimum time in milliseconds that must elapse between
9956 successive mouse move (or scroll bar drag) events before they are
9957 reported as lisp events. */);
9958 w32_mouse_move_interval
= 0;
9960 DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
9961 w32_pass_extra_mouse_buttons_to_system
,
9962 doc
: /* If non-nil, the fourth and fifth mouse buttons are passed to Windows.
9963 Recent versions of Windows support mice with up to five buttons.
9964 Since most applications don't support these extra buttons, most mouse
9965 drivers will allow you to map them to functions at the system level.
9966 If this variable is non-nil, Emacs will pass them on, allowing the
9967 system to handle them. */);
9968 w32_pass_extra_mouse_buttons_to_system
= 0;
9970 DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
9971 w32_pass_multimedia_buttons_to_system
,
9972 doc
: /* If non-nil, media buttons are passed to Windows.
9973 Some modern keyboards contain buttons for controlling media players, web
9974 browsers and other applications. Generally these buttons are handled on a
9975 system wide basis, but by setting this to nil they are made available
9976 to Emacs for binding. Depending on your keyboard, additional keys that
9977 may be available are:
9979 browser-back, browser-forward, browser-refresh, browser-stop,
9980 browser-search, browser-favorites, browser-home,
9981 mail, mail-reply, mail-forward, mail-send,
9983 help, find, new, open, close, save, print, undo, redo, copy, cut, paste,
9984 spell-check, correction-list, toggle-dictate-command,
9985 media-next, media-previous, media-stop, media-play-pause, media-select,
9986 media-play, media-pause, media-record, media-fast-forward, media-rewind,
9987 media-channel-up, media-channel-down,
9988 volume-mute, volume-up, volume-down,
9989 mic-volume-mute, mic-volume-down, mic-volume-up, mic-toggle,
9990 bass-down, bass-boost, bass-up, treble-down, treble-up */);
9991 w32_pass_multimedia_buttons_to_system
= 1;
9993 #if 0 /* TODO: Mouse cursor customization. */
9994 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape
,
9995 doc
: /* The shape of the pointer when over text.
9996 Changing the value does not affect existing frames
9997 unless you set the mouse color. */);
9998 Vx_pointer_shape
= Qnil
;
10000 Vx_nontext_pointer_shape
= Qnil
;
10002 Vx_mode_pointer_shape
= Qnil
;
10004 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape
,
10005 doc
: /* The shape of the pointer when Emacs is busy.
10006 This variable takes effect when you create a new frame
10007 or when you set the mouse color. */);
10008 Vx_hourglass_pointer_shape
= Qnil
;
10010 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10011 Vx_sensitive_text_pointer_shape
,
10012 doc
: /* The shape of the pointer when over mouse-sensitive text.
10013 This variable takes effect when you create a new frame
10014 or when you set the mouse color. */);
10015 Vx_sensitive_text_pointer_shape
= Qnil
;
10017 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10018 Vx_window_horizontal_drag_shape
,
10019 doc
: /* Pointer shape to use for indicating a window can be dragged horizontally.
10020 This variable takes effect when you create a new frame
10021 or when you set the mouse color. */);
10022 Vx_window_horizontal_drag_shape
= Qnil
;
10024 DEFVAR_LISP ("x-window-vertical-drag-cursor",
10025 Vx_window_vertical_drag_shape
,
10026 doc
: /* Pointer shape to use for indicating a window can be dragged vertically.
10027 This variable takes effect when you create a new frame
10028 or when you set the mouse color. */);
10029 Vx_window_vertical_drag_shape
= Qnil
;
10032 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel
,
10033 doc
: /* A string indicating the foreground color of the cursor box. */);
10034 Vx_cursor_fore_pixel
= Qnil
;
10036 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size
,
10037 doc
: /* Maximum size for tooltips.
10038 Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
10039 Vx_max_tooltip_size
= Fcons (make_number (80), make_number (40));
10041 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager
,
10042 doc
: /* Non-nil if no window manager is in use.
10043 Emacs doesn't try to figure this out; this is always nil
10044 unless you set it to something else. */);
10045 /* We don't have any way to find this out, so set it to nil
10046 and maybe the user would like to set it to t. */
10047 Vx_no_window_manager
= Qnil
;
10049 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10050 Vx_pixel_size_width_font_regexp
,
10051 doc
: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
10053 Since Emacs gets width of a font matching with this regexp from
10054 PIXEL_SIZE field of the name, font finding mechanism gets faster for
10055 such a font. This is especially effective for such large fonts as
10056 Chinese, Japanese, and Korean. */);
10057 Vx_pixel_size_width_font_regexp
= Qnil
;
10059 DEFVAR_LISP ("w32-bdf-filename-alist",
10060 Vw32_bdf_filename_alist
,
10061 doc
: /* List of bdf fonts and their corresponding filenames. */);
10062 Vw32_bdf_filename_alist
= Qnil
;
10064 DEFVAR_BOOL ("w32-strict-fontnames",
10065 w32_strict_fontnames
,
10066 doc
: /* Non-nil means only use fonts that are exact matches for those requested.
10067 Default is nil, which allows old fontnames that are not XLFD compliant,
10068 and allows third-party CJK display to work by specifying false charset
10069 fields to trick Emacs into translating to Big5, SJIS etc.
10070 Setting this to t will prevent wrong fonts being selected when
10071 fontsets are automatically created. */);
10072 w32_strict_fontnames
= 0;
10074 DEFVAR_BOOL ("w32-strict-painting",
10075 w32_strict_painting
,
10076 doc
: /* Non-nil means use strict rules for repainting frames.
10077 Set this to nil to get the old behavior for repainting; this should
10078 only be necessary if the default setting causes problems. */);
10079 w32_strict_painting
= 1;
10081 DEFVAR_BOOL ("w32-use-fallback-wm-chars-method",
10082 w32_use_fallback_wm_chars_method
,
10083 doc
: /* Non-nil means use old method of processing character keys.
10084 This is intended only for debugging of the new processing method.
10087 This variable has effect only on NT family of systems, not on Windows 9X. */);
10088 w32_use_fallback_wm_chars_method
= 0;
10090 DEFVAR_BOOL ("w32-disable-new-uniscribe-apis",
10091 w32_disable_new_uniscribe_apis
,
10092 doc
: /* Non-nil means don't use new Uniscribe APIs.
10093 The new APIs are used to access OTF features supported by fonts.
10094 This is intended only for debugging of the new Uniscribe-related code.
10097 This variable has effect only on Windows Vista and later. */);
10098 w32_disable_new_uniscribe_apis
= 0;
10100 DEFVAR_LISP ("w32-tooltip-extra-pixels",
10101 Vw32_tooltip_extra_pixels
,
10102 doc
: /* Number of pixels added after tooltip text.
10103 On Windows some fonts may cause the last character of a tooltip be
10104 truncated or wrapped around to the next line. Adding some extra space
10105 at the end of the toooltip works around this problem.
10107 This variable specifies the number of pixels that shall be added. The
10108 default value t means to add the width of one canonical character of the
10110 Vw32_tooltip_extra_pixels
= Qt
;
10112 #if 0 /* TODO: Port to W32 */
10113 defsubr (&Sx_change_window_property
);
10114 defsubr (&Sx_delete_window_property
);
10115 defsubr (&Sx_window_property
);
10117 defsubr (&Sxw_display_color_p
);
10118 defsubr (&Sx_display_grayscale_p
);
10119 defsubr (&Sxw_color_defined_p
);
10120 defsubr (&Sxw_color_values
);
10121 defsubr (&Sx_server_max_request_size
);
10122 defsubr (&Sx_server_vendor
);
10123 defsubr (&Sx_server_version
);
10124 defsubr (&Sx_display_pixel_width
);
10125 defsubr (&Sx_display_pixel_height
);
10126 defsubr (&Sx_display_mm_width
);
10127 defsubr (&Sx_display_mm_height
);
10128 defsubr (&Sx_display_screens
);
10129 defsubr (&Sx_display_planes
);
10130 defsubr (&Sx_display_color_cells
);
10131 defsubr (&Sx_display_visual_class
);
10132 defsubr (&Sx_display_backing_store
);
10133 defsubr (&Sx_display_save_under
);
10134 defsubr (&Sx_create_frame
);
10135 defsubr (&Sx_open_connection
);
10136 defsubr (&Sx_close_connection
);
10137 defsubr (&Sx_display_list
);
10138 defsubr (&Sw32_frame_geometry
);
10139 defsubr (&Sw32_frame_edges
);
10140 defsubr (&Sw32_mouse_absolute_pixel_position
);
10141 defsubr (&Sw32_set_mouse_absolute_pixel_position
);
10142 defsubr (&Sx_synchronize
);
10144 /* W32 specific functions */
10146 defsubr (&Sw32_define_rgb_color
);
10147 defsubr (&Sw32_default_color_map
);
10148 defsubr (&Sw32_display_monitor_attributes_list
);
10149 defsubr (&Sw32_send_sys_command
);
10150 defsubr (&Sw32_shell_execute
);
10151 defsubr (&Sw32_register_hot_key
);
10152 defsubr (&Sw32_unregister_hot_key
);
10153 defsubr (&Sw32_registered_hot_keys
);
10154 defsubr (&Sw32_reconstruct_hot_key
);
10155 defsubr (&Sw32_toggle_lock_key
);
10156 defsubr (&Sw32_window_exists_p
);
10157 defsubr (&Sw32_battery_status
);
10158 defsubr (&Sw32__menu_bar_in_use
);
10159 #if defined WINDOWSNT && !defined HAVE_DBUS
10160 defsubr (&Sw32_notification_notify
);
10161 defsubr (&Sw32_notification_close
);
10165 defsubr (&Sfile_system_info
);
10166 defsubr (&Sdefault_printer_name
);
10169 defsubr (&Sset_message_beep
);
10170 defsubr (&Sx_show_tip
);
10171 defsubr (&Sx_hide_tip
);
10173 staticpro (&tip_timer
);
10175 staticpro (&tip_frame
);
10177 last_show_tip_args
= Qnil
;
10178 staticpro (&last_show_tip_args
);
10180 defsubr (&Sx_file_dialog
);
10182 defsubr (&Ssystem_move_file_to_trash
);
10188 /* Crashing and reporting backtrace. */
10191 static LONG CALLBACK
my_exception_handler (EXCEPTION_POINTERS
*);
10192 static LPTOP_LEVEL_EXCEPTION_FILTER prev_exception_handler
;
10194 static DWORD except_code
;
10195 static PVOID except_addr
;
10199 /* Stack overflow recovery. */
10201 /* MinGW headers don't declare this (should be in malloc.h). Also,
10202 the function is not present pre-W2K, so make the call through
10203 a function pointer. */
10204 typedef int (__cdecl
*_resetstkoflw_proc
) (void);
10205 static _resetstkoflw_proc resetstkoflw
;
10207 /* Re-establish the guard page at stack limit. This is needed because
10208 when a stack overflow is detected, Windows removes the guard bit
10209 from the guard page, so if we don't re-establish that protection,
10210 the next stack overflow will cause a crash. */
10212 w32_reset_stack_overflow_guard (void)
10214 if (resetstkoflw
== NULL
)
10216 (_resetstkoflw_proc
)GetProcAddress (GetModuleHandle ("msvcrt.dll"),
10218 /* We ignore the return value. If _resetstkoflw fails, the next
10219 stack overflow will crash the program. */
10220 if (resetstkoflw
!= NULL
)
10221 (void)resetstkoflw ();
10225 stack_overflow_handler (void)
10227 /* Hard GC error may lead to stack overflow caused by
10228 too nested calls to mark_object. No way to survive. */
10229 if (gc_in_progress
)
10230 terminate_due_to_signal (SIGSEGV
, 40);
10232 /* See ms-w32.h: MinGW64's longjmp crashes if invoked in this context. */
10233 __builtin_longjmp (return_to_command_loop
, 1);
10235 sys_longjmp (return_to_command_loop
, 1);
10239 /* This handler records the exception code and the address where it
10240 was triggered so that this info could be included in the backtrace.
10241 Without that, the backtrace in some cases has no information
10242 whatsoever about the offending code, and looks as if the top-level
10243 exception handler in the MinGW startup code was the one that
10244 crashed. We also recover from stack overflow, by calling our stack
10245 overflow handler that jumps back to top level. */
10246 static LONG CALLBACK
10247 my_exception_handler (EXCEPTION_POINTERS
* exception_data
)
10249 except_code
= exception_data
->ExceptionRecord
->ExceptionCode
;
10250 except_addr
= exception_data
->ExceptionRecord
->ExceptionAddress
;
10252 /* If this is a stack overflow exception, attempt to recover. */
10253 if (exception_data
->ExceptionRecord
->ExceptionCode
== EXCEPTION_STACK_OVERFLOW
10254 && exception_data
->ExceptionRecord
->NumberParameters
== 2
10255 /* We can only longjmp to top level from the main thread. */
10256 && GetCurrentThreadId () == dwMainThreadId
)
10258 /* Call stack_overflow_handler (). */
10260 exception_data
->ContextRecord
->Rip
= (DWORD_PTR
) &stack_overflow_handler
;
10262 exception_data
->ContextRecord
->Eip
= (DWORD_PTR
) &stack_overflow_handler
;
10264 /* Zero this out, so the stale address of the stack overflow
10265 exception we handled is not displayed in some future
10266 unrelated crash. */
10268 return EXCEPTION_CONTINUE_EXECUTION
;
10271 if (prev_exception_handler
)
10272 return prev_exception_handler (exception_data
);
10273 return EXCEPTION_EXECUTE_HANDLER
;
10277 typedef USHORT (WINAPI
* CaptureStackBackTrace_proc
) (ULONG
, ULONG
, PVOID
*,
10280 #define BACKTRACE_LIMIT_MAX 62
10283 w32_backtrace (void **buffer
, int limit
)
10285 static CaptureStackBackTrace_proc s_pfn_CaptureStackBackTrace
= NULL
;
10286 HMODULE hm_kernel32
= NULL
;
10288 if (!s_pfn_CaptureStackBackTrace
)
10290 hm_kernel32
= LoadLibrary ("Kernel32.dll");
10291 s_pfn_CaptureStackBackTrace
=
10292 (CaptureStackBackTrace_proc
) GetProcAddress (hm_kernel32
,
10293 "RtlCaptureStackBackTrace");
10295 if (s_pfn_CaptureStackBackTrace
)
10296 return s_pfn_CaptureStackBackTrace (0, min (BACKTRACE_LIMIT_MAX
, limit
),
10305 button
= MessageBox (NULL
,
10306 "A fatal error has occurred!\n\n"
10307 "Would you like to attach a debugger?\n\n"
10309 "YES -- to debug Emacs, or\n"
10310 "NO -- to abort Emacs and produce a backtrace\n"
10311 " (emacs_backtrace.txt in current directory)."
10313 "\n\n(type \"gdb -p <emacs-PID>\" and\n"
10314 "\"continue\" inside GDB before clicking YES.)"
10316 , "Emacs Abort Dialog",
10317 MB_ICONEXCLAMATION
| MB_TASKMODAL
10318 | MB_SETFOREGROUND
| MB_YESNO
);
10323 exit (2); /* tell the compiler we will never return */
10327 void *stack
[BACKTRACE_LIMIT_MAX
+ 1];
10328 int i
= w32_backtrace (stack
, BACKTRACE_LIMIT_MAX
+ 1);
10332 int errfile_fd
= -1;
10334 char buf
[sizeof ("\r\nException at this address:\r\n\r\n")
10335 /* The type below should really be 'void *', but
10336 INT_BUFSIZE_BOUND cannot handle that without
10337 triggering compiler warnings (under certain
10338 pedantic warning switches), it wants an
10340 + 2 * INT_BUFSIZE_BOUND (intptr_t)];
10344 HANDLE errout
= GetStdHandle (STD_ERROR_HANDLE
);
10345 int stderr_fd
= -1;
10347 if (errout
&& errout
!= INVALID_HANDLE_VALUE
)
10348 stderr_fd
= _open_osfhandle ((intptr_t)errout
, O_APPEND
| O_BINARY
);
10351 /* We use %p, not 0x%p, as %p produces a leading "0x" on XP,
10352 but not on Windows 7. addr2line doesn't mind a missing
10353 "0x", but will be confused by an extra one. */
10355 sprintf (buf
, "\r\nException 0x%x at this address:\r\n%p\r\n",
10356 (unsigned int) except_code
, except_addr
);
10357 if (stderr_fd
>= 0)
10360 write (stderr_fd
, buf
, strlen (buf
));
10361 write (stderr_fd
, "\r\nBacktrace:\r\n", 14);
10366 errfile_fd
= _open ("emacs_backtrace.txt", O_RDWR
| O_CREAT
| O_BINARY
, S_IREAD
| S_IWRITE
);
10367 if (errfile_fd
>= 0)
10369 lseek (errfile_fd
, 0L, SEEK_END
);
10371 write (errfile_fd
, buf
, strlen (buf
));
10372 write (errfile_fd
, "\r\nBacktrace:\r\n", 14);
10375 for (j
= 0; j
< i
; j
++)
10377 /* stack[] gives the return addresses, whereas we want
10378 the address of the call, so decrease each address
10379 by approximate size of 1 CALL instruction. */
10380 sprintf (buf
, "%p\r\n", (char *)stack
[j
] - sizeof(void *));
10381 if (stderr_fd
>= 0)
10382 write (stderr_fd
, buf
, strlen (buf
));
10383 if (errfile_fd
>= 0)
10384 write (errfile_fd
, buf
, strlen (buf
));
10386 if (i
== BACKTRACE_LIMIT_MAX
)
10388 if (stderr_fd
>= 0)
10389 write (stderr_fd
, "...\r\n", 5);
10390 if (errfile_fd
>= 0)
10391 write (errfile_fd
, "...\r\n", 5);
10393 if (errfile_fd
>= 0)
10394 close (errfile_fd
);
10404 /* Initialization. */
10407 globals_of_w32fns is used to initialize those global variables that
10408 must always be initialized on startup even when the global variable
10409 initialized is non zero (see the function main in emacs.c).
10410 globals_of_w32fns is called from syms_of_w32fns when the global
10411 variable initialized is 0 and directly from main when initialized
10415 globals_of_w32fns (void)
10417 HMODULE user32_lib
= GetModuleHandle ("user32.dll");
10419 TrackMouseEvent not available in all versions of Windows, so must load
10420 it dynamically. Do it once, here, instead of every time it is used.
10422 track_mouse_event_fn
= (TrackMouseEvent_Proc
)
10423 GetProcAddress (user32_lib
, "TrackMouseEvent");
10425 monitor_from_point_fn
= (MonitorFromPoint_Proc
)
10426 GetProcAddress (user32_lib
, "MonitorFromPoint");
10427 get_monitor_info_fn
= (GetMonitorInfo_Proc
)
10428 GetProcAddress (user32_lib
, "GetMonitorInfoA");
10429 monitor_from_window_fn
= (MonitorFromWindow_Proc
)
10430 GetProcAddress (user32_lib
, "MonitorFromWindow");
10431 enum_display_monitors_fn
= (EnumDisplayMonitors_Proc
)
10432 GetProcAddress (user32_lib
, "EnumDisplayMonitors");
10433 get_title_bar_info_fn
= (GetTitleBarInfo_Proc
)
10434 GetProcAddress (user32_lib
, "GetTitleBarInfo");
10437 HMODULE imm32_lib
= GetModuleHandle ("imm32.dll");
10438 get_composition_string_fn
= (ImmGetCompositionString_Proc
)
10439 GetProcAddress (imm32_lib
, "ImmGetCompositionStringW");
10440 get_ime_context_fn
= (ImmGetContext_Proc
)
10441 GetProcAddress (imm32_lib
, "ImmGetContext");
10442 release_ime_context_fn
= (ImmReleaseContext_Proc
)
10443 GetProcAddress (imm32_lib
, "ImmReleaseContext");
10444 set_ime_composition_window_fn
= (ImmSetCompositionWindow_Proc
)
10445 GetProcAddress (imm32_lib
, "ImmSetCompositionWindow");
10451 prev_exception_handler
= SetUnhandledExceptionFilter (my_exception_handler
);
10452 resetstkoflw
= NULL
;
10455 DEFVAR_INT ("w32-ansi-code-page",
10456 w32_ansi_code_page
,
10457 doc
: /* The ANSI code page used by the system. */);
10458 w32_ansi_code_page
= GetACP ();
10460 if (os_subtype
== OS_NT
)
10461 w32_unicode_gui
= 1;
10463 w32_unicode_gui
= 0;
10465 after_deadkey
= -1;
10467 /* MessageBox does not work without this when linked to comctl32.dll 6.0. */
10468 InitCommonControls ();
10470 syms_of_w32uniscribe ();
10473 #ifdef NTGUI_UNICODE
10476 ntgui_encode_system (Lisp_Object str
)
10478 Lisp_Object encoded
;
10479 to_unicode (str
, &encoded
);
10483 #endif /* NTGUI_UNICODE */