This source file includes following definitions.
- check_x_display_info
- w32_window_to_frame
- w32_real_positions
- w32_fullscreen_rect
- w32_default_color_map
- w32_color_map_lookup
- add_system_logical_colors_to_map
- x_to_w32_color
- w32_regenerate_palette
- w32_map_color
- w32_unmap_color
- gamma_correct
- w32_defined_color
- w32_decode_color
- w32_set_foreground_color
- w32_set_background_color
- w32_set_mouse_color
- w32_set_cursor_color
- w32_set_border_pixel
- w32_set_border_color
- w32_set_cursor_type
- w32_set_icon_type
- w32_set_icon_name
- w32_clear_under_internal_border
- w32_set_child_frame_border_width
- w32_set_internal_border_width
- w32_set_menu_bar_lines
- w32_set_tab_bar_lines
- w32_change_tab_bar_height
- w32_set_tool_bar_lines
- w32_set_inhibit_double_buffering
- w32_change_tool_bar_height
- w32_set_title_bar_text
- w32_set_name
- w32_explicitly_set_name
- w32_implicitly_set_name
- w32_set_title
- w32_set_scroll_bar_default_width
- w32_set_scroll_bar_default_height
- w32_set_undecorated
- w32_set_parent_frame
- w32_set_skip_taskbar
- w32_set_no_focus_on_map
- w32_set_no_accept_focus
- w32_set_z_group
- w32_load_cursor
- w32_init_class
- w32_applytheme
- w32_createvscrollbar
- w32_createhscrollbar
- w32_createwindow
- my_post_msg
- funhook
- setup_w32_kbdhook
- remove_w32_kbdhook
- hook_w32_key
- check_w32_winkey_state
- reset_w32_kbdhook_state
- test_modifier_support
- record_keydown
- record_keyup
- reset_modifiers
- sync_modifiers
- modifier_set
- w32_key_to_modifier
- w32_get_modifiers
- w32_construct_console_modifiers
- w32_get_key_modifiers
- map_keypad_keys
- register_hot_keys
- unregister_hot_keys
- w32_name_of_message
- w32_msg_pump
- find_deferred_msg
- send_deferred_msg
- complete_deferred_msg
- cancel_all_deferred_msgs
- w32_msg_worker
- signal_user_input
- post_character_message
- get_wm_chars
- deliver_wm_chars
- w32_wnd_proc
- my_create_window
- my_create_tip_window
- w32_window
- w32_icon
- w32_make_gc
- unwind_create_frame
- do_unwind_create_frame
- w32_default_font_parameter
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- w32_monitor_enum
- w32_display_monitor_attributes_list
- w32_display_monitor_attributes_list_fallback
- DEFUN
- DEFUN
- w32_display_info_for_name
- DEFUN
- DEFUN
- unwind_create_tip_frame
- w32_create_tip_frame
- compute_tip_xy
- w32_hide_tip
- DEFUN
- file_dialog_callback
- w32_dialog_in_progress
- DEFUN
- lookup_vk_code
- w32_parse_and_hook_hot_key
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- w32_frame_list_z_order
- DEFUN
- w32_frame_restack
- DEFUN
- DEFUN
- DEFUN
- w32_strerror
- w32_last_error
- cache_system_info
- w32_version_string
- _DebPrint
- w32_console_toggle_lock_key
- w32_kbd_mods_to_emacs
- w32_kbd_patch_key
- w32_sys_ring_bell
- DEFUN
- get_dll_version
- utf8_mbslen_lim
- add_tray_notification
- delete_tray_notification
- DEFUN
- DEFUN
- DEFUN
- w32_get_resource
- DEFUN
- syms_of_w32fns
- w32_reset_stack_overflow_guard
- stack_overflow_handler
- my_exception_handler
- w32_backtrace
- emacs_abort
- globals_of_w32fns
- ntgui_encode_system
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #undef _WIN32_WINNT
25 #define _WIN32_WINNT 0x0600
26
27 #include <signal.h>
28 #include <stdio.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include <math.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34
35 #include <c-ctype.h>
36
37 #include "lisp.h"
38 #include "w32term.h"
39 #include "frame.h"
40 #include "window.h"
41 #include "buffer.h"
42 #include "keyboard.h"
43 #include "blockinput.h"
44 #include "coding.h"
45
46 #include "w32common.h"
47 #include "w32inevt.h"
48
49 #ifdef WINDOWSNT
50 #include <mbstring.h>
51 #include <mbctype.h>
52 #endif
53
54 #if CYGWIN
55 #include "cygw32.h"
56 #else
57 #include "w32.h"
58 #endif
59
60 #include "pdumper.h"
61
62 #include <basetyps.h>
63 #include <unknwn.h>
64 #include <commctrl.h>
65 #include <commdlg.h>
66 #include <shellapi.h>
67 #include <shlwapi.h>
68 #include <ctype.h>
69 #include <winspool.h>
70 #include <objbase.h>
71
72 #include <dlgs.h>
73 #include <imm.h>
74 #include <windowsx.h>
75
76
77
78
79
80 #define DARK_MODE_APP_NAME L"DarkMode_Explorer"
81
82 #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE_OLD
83 #define DWMWA_USE_IMMERSIVE_DARK_MODE_OLD 19
84 #endif
85
86 #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
87 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20
88 #endif
89
90 #ifndef FOF_NO_CONNECTED_ELEMENTS
91 #define FOF_NO_CONNECTED_ELEMENTS 0x2000
92 #endif
93
94 extern int w32_console_toggle_lock_key (int, Lisp_Object);
95 extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
96 extern void w32_free_menu_strings (HWND);
97
98 #ifndef IDC_HAND
99 #define IDC_HAND MAKEINTRESOURCE(32649)
100 #endif
101
102
103 #define SYSTEM_COLOR_PREFIX "System"
104 #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
105
106
107 #define LMOUSE 1
108 #define MMOUSE 2
109 #define RMOUSE 4
110
111 static int button_state = 0;
112 static W32Msg saved_mouse_button_msg;
113 static unsigned mouse_button_timer = 0;
114 static W32Msg saved_mouse_move_msg;
115 static unsigned mouse_move_timer = 0;
116
117
118 static HWND track_mouse_window;
119
120
121
122 #ifndef MONITOR_DEFAULT_TO_NEAREST
123 #define MONITOR_DEFAULT_TO_NEAREST 2
124 #endif
125 #ifndef MONITORINFOF_PRIMARY
126 #define MONITORINFOF_PRIMARY 1
127 #endif
128 #ifndef SM_XVIRTUALSCREEN
129 #define SM_XVIRTUALSCREEN 76
130 #endif
131 #ifndef SM_YVIRTUALSCREEN
132 #define SM_YVIRTUALSCREEN 77
133 #endif
134
135
136 struct MONITOR_INFO
137 {
138 DWORD cbSize;
139 RECT rcMonitor;
140 RECT rcWork;
141 DWORD dwFlags;
142 };
143
144 #if _WIN32_WINDOWS >= 0x0410
145 #define C_CHILDREN_TITLEBAR CCHILDREN_TITLEBAR
146 typedef TITLEBARINFO TITLEBAR_INFO;
147 #else
148 #define C_CHILDREN_TITLEBAR 5
149 typedef struct
150 {
151 DWORD cbSize;
152 RECT rcTitleBar;
153 DWORD rgstate[C_CHILDREN_TITLEBAR+1];
154 } TITLEBAR_INFO, *PTITLEBAR_INFO;
155 #endif
156
157 #ifndef CCHDEVICENAME
158 #define CCHDEVICENAME 32
159 #endif
160 struct MONITOR_INFO_EX
161 {
162 DWORD cbSize;
163 RECT rcMonitor;
164 RECT rcWork;
165 DWORD dwFlags;
166 char szDevice[CCHDEVICENAME];
167 };
168
169
170 #if defined (_MSC_VER) && _WIN32_WINNT < 0x0500
171 DECLARE_HANDLE(HMONITOR);
172 #endif
173
174 typedef BOOL (WINAPI * TrackMouseEvent_Proc)
175 (IN OUT LPTRACKMOUSEEVENT lpEventTrack);
176 typedef LONG (WINAPI * ImmGetCompositionString_Proc)
177 (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen);
178 typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window);
179 typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
180 typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
181 IN COMPOSITIONFORM *form);
182
183 typedef BOOL (WINAPI * ImmGetOpenStatus_Proc) (IN HIMC);
184 typedef BOOL (WINAPI * ImmSetOpenStatus_Proc) (IN HIMC, IN BOOL);
185
186 typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
187 typedef BOOL (WINAPI * GetMonitorInfo_Proc)
188 (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
189 typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
190 (IN HWND hwnd, IN DWORD dwFlags);
191 typedef BOOL CALLBACK (* MonitorEnum_Proc)
192 (IN HMONITOR monitor, IN HDC hdc, IN RECT *rcMonitor, IN LPARAM dwData);
193 typedef BOOL (WINAPI * EnumDisplayMonitors_Proc)
194 (IN HDC hdc, IN RECT *rcClip, IN MonitorEnum_Proc fnEnum, IN LPARAM dwData);
195 typedef BOOL (WINAPI * GetTitleBarInfo_Proc)
196 (IN HWND hwnd, OUT TITLEBAR_INFO* info);
197
198 typedef BOOL (WINAPI *IsDebuggerPresent_Proc) (void);
199 typedef HRESULT (WINAPI *SetThreadDescription_Proc)
200 (HANDLE hThread, PCWSTR lpThreadDescription);
201
202 typedef HRESULT (WINAPI * SetWindowTheme_Proc)
203 (IN HWND hwnd, IN LPCWSTR pszSubAppName, IN LPCWSTR pszSubIdList);
204 typedef HRESULT (WINAPI * DwmSetWindowAttribute_Proc)
205 (HWND hwnd, DWORD dwAttribute, IN LPCVOID pvAttribute, DWORD cbAttribute);
206
207 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
208 ImmGetCompositionString_Proc get_composition_string_fn = NULL;
209 ImmGetContext_Proc get_ime_context_fn = NULL;
210 ImmGetOpenStatus_Proc get_ime_open_status_fn = NULL;
211 ImmSetOpenStatus_Proc set_ime_open_status_fn = NULL;
212 ImmReleaseContext_Proc release_ime_context_fn = NULL;
213 ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
214 MonitorFromPoint_Proc monitor_from_point_fn = NULL;
215 GetMonitorInfo_Proc get_monitor_info_fn = NULL;
216 MonitorFromWindow_Proc monitor_from_window_fn = NULL;
217 EnumDisplayMonitors_Proc enum_display_monitors_fn = NULL;
218 GetTitleBarInfo_Proc get_title_bar_info_fn = NULL;
219 IsDebuggerPresent_Proc is_debugger_present = NULL;
220 SetThreadDescription_Proc set_thread_description = NULL;
221 SetWindowTheme_Proc SetWindowTheme_fn = NULL;
222 DwmSetWindowAttribute_Proc DwmSetWindowAttribute_fn = NULL;
223
224 extern AppendMenuW_Proc unicode_append_menu;
225
226
227 static int ignore_ime_char = 0;
228
229
230 unsigned int msh_mousewheel = 0;
231
232
233 #define MOUSE_BUTTON_ID 1
234 #define MOUSE_MOVE_ID 2
235 #define MENU_FREE_ID 3
236
237
238 #define MENU_FREE_DELAY 1000
239 static unsigned menu_free_timer = 0;
240
241 #ifdef GLYPH_DEBUG
242 static ptrdiff_t image_cache_refcount;
243 static int dpyinfo_refcount;
244 #endif
245
246 static HWND w32_visible_system_caret_hwnd;
247
248 static int w32_unicode_gui;
249
250 static bool w32_selection_dialog_open;
251
252
253 int menubar_in_use = 0;
254
255
256 extern void syms_of_w32uniscribe (void);
257 extern int uniscribe_available;
258 extern int harfbuzz_available;
259
260 #ifdef WINDOWSNT
261
262 extern int faked_key;
263 #endif
264
265
266 SYSTEM_INFO sysinfo_cache;
267
268
269 OSVERSIONINFO osinfo_cache;
270
271 DWORD_PTR syspage_mask = 0;
272
273
274 int w32_major_version;
275 int w32_minor_version;
276 int w32_build_number;
277
278
279 BOOL w32_darkmode = FALSE;
280
281
282 int os_subtype;
283
284 #ifdef HAVE_NTGUI
285 HINSTANCE hinst = NULL;
286 #endif
287
288 static unsigned int sound_type = 0xFFFFFFFF;
289 #define MB_EMACS_SILENT (0xFFFFFFFF - 1)
290
291
292 #define VK_ANY 0xFF
293
294 #ifndef WM_WTSSESSION_CHANGE
295
296 # define WM_WTSSESSION_CHANGE 0x02B1
297 # define WTS_SESSION_LOCK 0x7
298 #endif
299
300 #ifndef WS_EX_NOACTIVATE
301 #define WS_EX_NOACTIVATE 0x08000000L
302 #endif
303
304
305 static struct
306 {
307 int hook_count;
308 HHOOK hook;
309 HWND console;
310
311 int lwindown;
312 int rwindown;
313 int winsdown;
314 int send_win_up;
315 int suppress_lone;
316 int winseen;
317
318 char alt_hooked[256];
319 char lwin_hooked[256];
320 char rwin_hooked[256];
321 } kbdhook;
322 typedef HWND (WINAPI *GetConsoleWindow_Proc) (void);
323
324
325 extern HANDLE keyboard_handle;
326
327 static struct w32_display_info *w32_display_info_for_name (Lisp_Object);
328
329
330
331
332
333 struct w32_display_info *
334 check_x_display_info (Lisp_Object object)
335 {
336 if (NILP (object))
337 {
338 struct frame *sf = XFRAME (selected_frame);
339
340 if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf))
341 return FRAME_DISPLAY_INFO (sf);
342 else
343 return &one_w32_display_info;
344 }
345 else if (TERMINALP (object))
346 {
347 struct terminal *t = decode_live_terminal (object);
348
349 if (t->type != output_w32)
350 error ("Terminal %d is not a W32 display", t->id);
351
352 return t->display_info.w32;
353 }
354 else if (STRINGP (object))
355 return w32_display_info_for_name (object);
356 else
357 {
358 struct frame *f;
359
360 CHECK_LIVE_FRAME (object);
361 f = XFRAME (object);
362 if (! FRAME_W32_P (f))
363 error ("Non-W32 frame used");
364 return FRAME_DISPLAY_INFO (f);
365 }
366 }
367
368
369
370
371 struct frame *
372 w32_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
373 {
374 Lisp_Object tail, frame;
375 struct frame *f;
376
377 FOR_EACH_FRAME (tail, frame)
378 {
379 f = XFRAME (frame);
380 if (!FRAME_W32_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
381 continue;
382
383 if (FRAME_W32_WINDOW (f) == wdesc)
384 return f;
385 }
386 return 0;
387 }
388
389
390 static Lisp_Object unwind_create_frame (Lisp_Object);
391 static void unwind_create_tip_frame (Lisp_Object);
392 static void my_create_window (struct frame *);
393 static void my_create_tip_window (struct frame *);
394
395
396 static void w32_set_foreground_color (struct frame *, Lisp_Object, Lisp_Object);
397 static void w32_set_background_color (struct frame *, Lisp_Object, Lisp_Object);
398 static void w32_set_mouse_color (struct frame *, Lisp_Object, Lisp_Object);
399 static void w32_set_border_color (struct frame *, Lisp_Object, Lisp_Object);
400 static void w32_set_cursor_color (struct frame *, Lisp_Object, Lisp_Object);
401 static void w32_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
402 static void w32_set_icon_type (struct frame *, Lisp_Object, Lisp_Object);
403 static void w32_set_icon_name (struct frame *, Lisp_Object, Lisp_Object);
404 static void w32_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
405 static void w32_set_title (struct frame *, Lisp_Object, Lisp_Object);
406
407
408
409
410
411
412 void
413 w32_real_positions (struct frame *f, int *xptr, int *yptr)
414 {
415 RECT rect;
416
417
418 GetWindowRect (FRAME_W32_WINDOW (f), &rect);
419
420 if (FRAME_PARENT_FRAME (f))
421 {
422
423
424 HWND parent_hwnd = FRAME_W32_WINDOW (FRAME_PARENT_FRAME (f));
425
426 if (parent_hwnd)
427 MapWindowPoints (HWND_DESKTOP, parent_hwnd, (LPPOINT) &rect, 2);
428 }
429
430 *xptr = rect.left;
431 *yptr = rect.top;
432 }
433
434
435
436
437
438
439 void
440 w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect)
441 {
442 struct MONITOR_INFO mi = { sizeof(mi) };
443 if (monitor_from_window_fn && get_monitor_info_fn)
444 {
445 HMONITOR monitor =
446 monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
447 get_monitor_info_fn (monitor, &mi);
448 }
449 else
450 {
451 mi.rcMonitor.left = 0;
452 mi.rcMonitor.top = 0;
453 mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN);
454 mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN);
455 mi.rcWork.left = 0;
456 mi.rcWork.top = 0;
457 mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED);
458 mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED);
459 }
460
461 switch (fsmode)
462 {
463 case FULLSCREEN_BOTH:
464 rect->left = mi.rcMonitor.left;
465 rect->top = mi.rcMonitor.top;
466 rect->right = mi.rcMonitor.right;
467 rect->bottom = mi.rcMonitor.bottom;
468 break;
469 case FULLSCREEN_WIDTH:
470 rect->left = mi.rcWork.left;
471 rect->top = normal.top;
472 rect->right = mi.rcWork.right;
473 rect->bottom = normal.bottom;
474 break;
475 case FULLSCREEN_HEIGHT:
476 rect->left = normal.left;
477 rect->top = mi.rcWork.top;
478 rect->right = normal.right;
479 rect->bottom = mi.rcWork.bottom;
480 break;
481 default:
482 *rect = normal;
483 break;
484 }
485 }
486
487
488
489 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
490 Sw32_define_rgb_color, 4, 4, 0,
491 doc:
492
493
494 )
495 (Lisp_Object red, Lisp_Object green, Lisp_Object blue, Lisp_Object name)
496 {
497 Lisp_Object rgb;
498 Lisp_Object oldrgb = Qnil;
499 Lisp_Object entry;
500
501 CHECK_FIXNUM (red);
502 CHECK_FIXNUM (green);
503 CHECK_FIXNUM (blue);
504 CHECK_STRING (name);
505
506 XSETINT (rgb, RGB (XUFIXNUM (red), XUFIXNUM (green), XUFIXNUM (blue)));
507
508 block_input ();
509
510
511 entry = Fassoc (name, Vw32_color_map, Qnil);
512 if (NILP (entry))
513 {
514 entry = Fcons (name, rgb);
515 Vw32_color_map = Fcons (entry, Vw32_color_map);
516 }
517 else
518 {
519 oldrgb = Fcdr (entry);
520 Fsetcdr (entry, rgb);
521 }
522
523 unblock_input ();
524
525 return (oldrgb);
526 }
527
528
529 typedef struct colormap_t
530 {
531 const char *name;
532 COLORREF colorref;
533 } colormap_t;
534
535 colormap_t w32_color_map[] =
536 {
537 {"snow" , PALETTERGB (255,250,250)},
538 {"ghost white" , PALETTERGB (248,248,255)},
539 {"GhostWhite" , PALETTERGB (248,248,255)},
540 {"white smoke" , PALETTERGB (245,245,245)},
541 {"WhiteSmoke" , PALETTERGB (245,245,245)},
542 {"gainsboro" , PALETTERGB (220,220,220)},
543 {"floral white" , PALETTERGB (255,250,240)},
544 {"FloralWhite" , PALETTERGB (255,250,240)},
545 {"old lace" , PALETTERGB (253,245,230)},
546 {"OldLace" , PALETTERGB (253,245,230)},
547 {"linen" , PALETTERGB (250,240,230)},
548 {"antique white" , PALETTERGB (250,235,215)},
549 {"AntiqueWhite" , PALETTERGB (250,235,215)},
550 {"papaya whip" , PALETTERGB (255,239,213)},
551 {"PapayaWhip" , PALETTERGB (255,239,213)},
552 {"blanched almond" , PALETTERGB (255,235,205)},
553 {"BlanchedAlmond" , PALETTERGB (255,235,205)},
554 {"bisque" , PALETTERGB (255,228,196)},
555 {"peach puff" , PALETTERGB (255,218,185)},
556 {"PeachPuff" , PALETTERGB (255,218,185)},
557 {"navajo white" , PALETTERGB (255,222,173)},
558 {"NavajoWhite" , PALETTERGB (255,222,173)},
559 {"moccasin" , PALETTERGB (255,228,181)},
560 {"cornsilk" , PALETTERGB (255,248,220)},
561 {"ivory" , PALETTERGB (255,255,240)},
562 {"lemon chiffon" , PALETTERGB (255,250,205)},
563 {"LemonChiffon" , PALETTERGB (255,250,205)},
564 {"seashell" , PALETTERGB (255,245,238)},
565 {"honeydew" , PALETTERGB (240,255,240)},
566 {"mint cream" , PALETTERGB (245,255,250)},
567 {"MintCream" , PALETTERGB (245,255,250)},
568 {"azure" , PALETTERGB (240,255,255)},
569 {"alice blue" , PALETTERGB (240,248,255)},
570 {"AliceBlue" , PALETTERGB (240,248,255)},
571 {"lavender" , PALETTERGB (230,230,250)},
572 {"lavender blush" , PALETTERGB (255,240,245)},
573 {"LavenderBlush" , PALETTERGB (255,240,245)},
574 {"misty rose" , PALETTERGB (255,228,225)},
575 {"MistyRose" , PALETTERGB (255,228,225)},
576 {"white" , PALETTERGB (255,255,255)},
577 {"black" , PALETTERGB ( 0, 0, 0)},
578 {"dark slate gray" , PALETTERGB ( 47, 79, 79)},
579 {"DarkSlateGray" , PALETTERGB ( 47, 79, 79)},
580 {"dark slate grey" , PALETTERGB ( 47, 79, 79)},
581 {"DarkSlateGrey" , PALETTERGB ( 47, 79, 79)},
582 {"dim gray" , PALETTERGB (105,105,105)},
583 {"DimGray" , PALETTERGB (105,105,105)},
584 {"dim grey" , PALETTERGB (105,105,105)},
585 {"DimGrey" , PALETTERGB (105,105,105)},
586 {"slate gray" , PALETTERGB (112,128,144)},
587 {"SlateGray" , PALETTERGB (112,128,144)},
588 {"slate grey" , PALETTERGB (112,128,144)},
589 {"SlateGrey" , PALETTERGB (112,128,144)},
590 {"light slate gray" , PALETTERGB (119,136,153)},
591 {"LightSlateGray" , PALETTERGB (119,136,153)},
592 {"light slate grey" , PALETTERGB (119,136,153)},
593 {"LightSlateGrey" , PALETTERGB (119,136,153)},
594 {"gray" , PALETTERGB (190,190,190)},
595 {"grey" , PALETTERGB (190,190,190)},
596 {"light grey" , PALETTERGB (211,211,211)},
597 {"LightGrey" , PALETTERGB (211,211,211)},
598 {"light gray" , PALETTERGB (211,211,211)},
599 {"LightGray" , PALETTERGB (211,211,211)},
600 {"midnight blue" , PALETTERGB ( 25, 25,112)},
601 {"MidnightBlue" , PALETTERGB ( 25, 25,112)},
602 {"navy" , PALETTERGB ( 0, 0,128)},
603 {"navy blue" , PALETTERGB ( 0, 0,128)},
604 {"NavyBlue" , PALETTERGB ( 0, 0,128)},
605 {"cornflower blue" , PALETTERGB (100,149,237)},
606 {"CornflowerBlue" , PALETTERGB (100,149,237)},
607 {"dark slate blue" , PALETTERGB ( 72, 61,139)},
608 {"DarkSlateBlue" , PALETTERGB ( 72, 61,139)},
609 {"slate blue" , PALETTERGB (106, 90,205)},
610 {"SlateBlue" , PALETTERGB (106, 90,205)},
611 {"medium slate blue" , PALETTERGB (123,104,238)},
612 {"MediumSlateBlue" , PALETTERGB (123,104,238)},
613 {"light slate blue" , PALETTERGB (132,112,255)},
614 {"LightSlateBlue" , PALETTERGB (132,112,255)},
615 {"medium blue" , PALETTERGB ( 0, 0,205)},
616 {"MediumBlue" , PALETTERGB ( 0, 0,205)},
617 {"royal blue" , PALETTERGB ( 65,105,225)},
618 {"RoyalBlue" , PALETTERGB ( 65,105,225)},
619 {"blue" , PALETTERGB ( 0, 0,255)},
620 {"dodger blue" , PALETTERGB ( 30,144,255)},
621 {"DodgerBlue" , PALETTERGB ( 30,144,255)},
622 {"deep sky blue" , PALETTERGB ( 0,191,255)},
623 {"DeepSkyBlue" , PALETTERGB ( 0,191,255)},
624 {"sky blue" , PALETTERGB (135,206,235)},
625 {"SkyBlue" , PALETTERGB (135,206,235)},
626 {"light sky blue" , PALETTERGB (135,206,250)},
627 {"LightSkyBlue" , PALETTERGB (135,206,250)},
628 {"steel blue" , PALETTERGB ( 70,130,180)},
629 {"SteelBlue" , PALETTERGB ( 70,130,180)},
630 {"light steel blue" , PALETTERGB (176,196,222)},
631 {"LightSteelBlue" , PALETTERGB (176,196,222)},
632 {"light blue" , PALETTERGB (173,216,230)},
633 {"LightBlue" , PALETTERGB (173,216,230)},
634 {"powder blue" , PALETTERGB (176,224,230)},
635 {"PowderBlue" , PALETTERGB (176,224,230)},
636 {"pale turquoise" , PALETTERGB (175,238,238)},
637 {"PaleTurquoise" , PALETTERGB (175,238,238)},
638 {"dark turquoise" , PALETTERGB ( 0,206,209)},
639 {"DarkTurquoise" , PALETTERGB ( 0,206,209)},
640 {"medium turquoise" , PALETTERGB ( 72,209,204)},
641 {"MediumTurquoise" , PALETTERGB ( 72,209,204)},
642 {"turquoise" , PALETTERGB ( 64,224,208)},
643 {"cyan" , PALETTERGB ( 0,255,255)},
644 {"light cyan" , PALETTERGB (224,255,255)},
645 {"LightCyan" , PALETTERGB (224,255,255)},
646 {"cadet blue" , PALETTERGB ( 95,158,160)},
647 {"CadetBlue" , PALETTERGB ( 95,158,160)},
648 {"medium aquamarine" , PALETTERGB (102,205,170)},
649 {"MediumAquamarine" , PALETTERGB (102,205,170)},
650 {"aquamarine" , PALETTERGB (127,255,212)},
651 {"dark green" , PALETTERGB ( 0,100, 0)},
652 {"DarkGreen" , PALETTERGB ( 0,100, 0)},
653 {"dark olive green" , PALETTERGB ( 85,107, 47)},
654 {"DarkOliveGreen" , PALETTERGB ( 85,107, 47)},
655 {"dark sea green" , PALETTERGB (143,188,143)},
656 {"DarkSeaGreen" , PALETTERGB (143,188,143)},
657 {"sea green" , PALETTERGB ( 46,139, 87)},
658 {"SeaGreen" , PALETTERGB ( 46,139, 87)},
659 {"medium sea green" , PALETTERGB ( 60,179,113)},
660 {"MediumSeaGreen" , PALETTERGB ( 60,179,113)},
661 {"light sea green" , PALETTERGB ( 32,178,170)},
662 {"LightSeaGreen" , PALETTERGB ( 32,178,170)},
663 {"pale green" , PALETTERGB (152,251,152)},
664 {"PaleGreen" , PALETTERGB (152,251,152)},
665 {"spring green" , PALETTERGB ( 0,255,127)},
666 {"SpringGreen" , PALETTERGB ( 0,255,127)},
667 {"lawn green" , PALETTERGB (124,252, 0)},
668 {"LawnGreen" , PALETTERGB (124,252, 0)},
669 {"green" , PALETTERGB ( 0,255, 0)},
670 {"chartreuse" , PALETTERGB (127,255, 0)},
671 {"medium spring green" , PALETTERGB ( 0,250,154)},
672 {"MediumSpringGreen" , PALETTERGB ( 0,250,154)},
673 {"green yellow" , PALETTERGB (173,255, 47)},
674 {"GreenYellow" , PALETTERGB (173,255, 47)},
675 {"lime green" , PALETTERGB ( 50,205, 50)},
676 {"LimeGreen" , PALETTERGB ( 50,205, 50)},
677 {"yellow green" , PALETTERGB (154,205, 50)},
678 {"YellowGreen" , PALETTERGB (154,205, 50)},
679 {"forest green" , PALETTERGB ( 34,139, 34)},
680 {"ForestGreen" , PALETTERGB ( 34,139, 34)},
681 {"olive drab" , PALETTERGB (107,142, 35)},
682 {"OliveDrab" , PALETTERGB (107,142, 35)},
683 {"dark khaki" , PALETTERGB (189,183,107)},
684 {"DarkKhaki" , PALETTERGB (189,183,107)},
685 {"khaki" , PALETTERGB (240,230,140)},
686 {"pale goldenrod" , PALETTERGB (238,232,170)},
687 {"PaleGoldenrod" , PALETTERGB (238,232,170)},
688 {"light goldenrod yellow" , PALETTERGB (250,250,210)},
689 {"LightGoldenrodYellow" , PALETTERGB (250,250,210)},
690 {"light yellow" , PALETTERGB (255,255,224)},
691 {"LightYellow" , PALETTERGB (255,255,224)},
692 {"yellow" , PALETTERGB (255,255, 0)},
693 {"gold" , PALETTERGB (255,215, 0)},
694 {"light goldenrod" , PALETTERGB (238,221,130)},
695 {"LightGoldenrod" , PALETTERGB (238,221,130)},
696 {"goldenrod" , PALETTERGB (218,165, 32)},
697 {"dark goldenrod" , PALETTERGB (184,134, 11)},
698 {"DarkGoldenrod" , PALETTERGB (184,134, 11)},
699 {"rosy brown" , PALETTERGB (188,143,143)},
700 {"RosyBrown" , PALETTERGB (188,143,143)},
701 {"indian red" , PALETTERGB (205, 92, 92)},
702 {"IndianRed" , PALETTERGB (205, 92, 92)},
703 {"saddle brown" , PALETTERGB (139, 69, 19)},
704 {"SaddleBrown" , PALETTERGB (139, 69, 19)},
705 {"sienna" , PALETTERGB (160, 82, 45)},
706 {"peru" , PALETTERGB (205,133, 63)},
707 {"burlywood" , PALETTERGB (222,184,135)},
708 {"beige" , PALETTERGB (245,245,220)},
709 {"wheat" , PALETTERGB (245,222,179)},
710 {"sandy brown" , PALETTERGB (244,164, 96)},
711 {"SandyBrown" , PALETTERGB (244,164, 96)},
712 {"tan" , PALETTERGB (210,180,140)},
713 {"chocolate" , PALETTERGB (210,105, 30)},
714 {"firebrick" , PALETTERGB (178,34, 34)},
715 {"brown" , PALETTERGB (165,42, 42)},
716 {"dark salmon" , PALETTERGB (233,150,122)},
717 {"DarkSalmon" , PALETTERGB (233,150,122)},
718 {"salmon" , PALETTERGB (250,128,114)},
719 {"light salmon" , PALETTERGB (255,160,122)},
720 {"LightSalmon" , PALETTERGB (255,160,122)},
721 {"orange" , PALETTERGB (255,165, 0)},
722 {"dark orange" , PALETTERGB (255,140, 0)},
723 {"DarkOrange" , PALETTERGB (255,140, 0)},
724 {"coral" , PALETTERGB (255,127, 80)},
725 {"light coral" , PALETTERGB (240,128,128)},
726 {"LightCoral" , PALETTERGB (240,128,128)},
727 {"tomato" , PALETTERGB (255, 99, 71)},
728 {"orange red" , PALETTERGB (255, 69, 0)},
729 {"OrangeRed" , PALETTERGB (255, 69, 0)},
730 {"red" , PALETTERGB (255, 0, 0)},
731 {"hot pink" , PALETTERGB (255,105,180)},
732 {"HotPink" , PALETTERGB (255,105,180)},
733 {"deep pink" , PALETTERGB (255, 20,147)},
734 {"DeepPink" , PALETTERGB (255, 20,147)},
735 {"pink" , PALETTERGB (255,192,203)},
736 {"light pink" , PALETTERGB (255,182,193)},
737 {"LightPink" , PALETTERGB (255,182,193)},
738 {"pale violet red" , PALETTERGB (219,112,147)},
739 {"PaleVioletRed" , PALETTERGB (219,112,147)},
740 {"maroon" , PALETTERGB (176, 48, 96)},
741 {"medium violet red" , PALETTERGB (199, 21,133)},
742 {"MediumVioletRed" , PALETTERGB (199, 21,133)},
743 {"violet red" , PALETTERGB (208, 32,144)},
744 {"VioletRed" , PALETTERGB (208, 32,144)},
745 {"magenta" , PALETTERGB (255, 0,255)},
746 {"violet" , PALETTERGB (238,130,238)},
747 {"plum" , PALETTERGB (221,160,221)},
748 {"orchid" , PALETTERGB (218,112,214)},
749 {"medium orchid" , PALETTERGB (186, 85,211)},
750 {"MediumOrchid" , PALETTERGB (186, 85,211)},
751 {"dark orchid" , PALETTERGB (153, 50,204)},
752 {"DarkOrchid" , PALETTERGB (153, 50,204)},
753 {"dark violet" , PALETTERGB (148, 0,211)},
754 {"DarkViolet" , PALETTERGB (148, 0,211)},
755 {"blue violet" , PALETTERGB (138, 43,226)},
756 {"BlueViolet" , PALETTERGB (138, 43,226)},
757 {"purple" , PALETTERGB (160, 32,240)},
758 {"medium purple" , PALETTERGB (147,112,219)},
759 {"MediumPurple" , PALETTERGB (147,112,219)},
760 {"thistle" , PALETTERGB (216,191,216)},
761 {"gray0" , PALETTERGB ( 0, 0, 0)},
762 {"grey0" , PALETTERGB ( 0, 0, 0)},
763 {"dark grey" , PALETTERGB (169,169,169)},
764 {"DarkGrey" , PALETTERGB (169,169,169)},
765 {"dark gray" , PALETTERGB (169,169,169)},
766 {"DarkGray" , PALETTERGB (169,169,169)},
767 {"dark blue" , PALETTERGB ( 0, 0,139)},
768 {"DarkBlue" , PALETTERGB ( 0, 0,139)},
769 {"dark cyan" , PALETTERGB ( 0,139,139)},
770 {"DarkCyan" , PALETTERGB ( 0,139,139)},
771 {"dark magenta" , PALETTERGB (139, 0,139)},
772 {"DarkMagenta" , PALETTERGB (139, 0,139)},
773 {"dark red" , PALETTERGB (139, 0, 0)},
774 {"DarkRed" , PALETTERGB (139, 0, 0)},
775 {"light green" , PALETTERGB (144,238,144)},
776 {"LightGreen" , PALETTERGB (144,238,144)},
777 };
778
779 static Lisp_Object
780 w32_default_color_map (void)
781 {
782 int i;
783 colormap_t *pc = w32_color_map;
784 Lisp_Object cmap;
785
786 block_input ();
787
788 cmap = Qnil;
789
790 for (i = 0; i < ARRAYELTS (w32_color_map); pc++, i++)
791 cmap = Fcons (Fcons (build_string (pc->name),
792 make_fixnum (pc->colorref)),
793 cmap);
794
795 unblock_input ();
796
797 return (cmap);
798 }
799
800 static Lisp_Object
801 w32_color_map_lookup (const char *colorname)
802 {
803 Lisp_Object tail, ret = Qnil;
804
805 block_input ();
806
807 for (tail = Vw32_color_map; CONSP (tail); tail = XCDR (tail))
808 {
809 register Lisp_Object elt, tem;
810
811 elt = XCAR (tail);
812 if (!CONSP (elt)) continue;
813
814 tem = XCAR (elt);
815
816 if (lstrcmpi (SSDATA (tem), colorname) == 0)
817 {
818 ret = Fcdr (elt);
819 break;
820 }
821
822 maybe_quit ();
823 }
824
825 unblock_input ();
826
827 return ret;
828 }
829
830
831 static void
832 add_system_logical_colors_to_map (Lisp_Object *system_colors)
833 {
834 HKEY colors_key;
835
836
837 block_input ();
838
839
840
841 if (RegOpenKeyEx (HKEY_CURRENT_USER, "Control Panel\\Colors", 0,
842 KEY_READ, &colors_key) == ERROR_SUCCESS
843 || RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Control Panel\\Colors", 0,
844 KEY_READ, &colors_key) == ERROR_SUCCESS)
845 {
846
847 char color_buffer[64];
848 char full_name_buffer[MAX_PATH + SYSTEM_COLOR_PREFIX_LEN];
849 int index = 0;
850 DWORD name_size, color_size;
851 char *name_buffer = full_name_buffer + SYSTEM_COLOR_PREFIX_LEN;
852
853 name_size = sizeof (full_name_buffer) - SYSTEM_COLOR_PREFIX_LEN;
854 color_size = sizeof (color_buffer);
855
856 strcpy (full_name_buffer, SYSTEM_COLOR_PREFIX);
857
858 while (RegEnumValueA (colors_key, index, name_buffer, &name_size,
859 NULL, NULL, (LPBYTE)color_buffer, &color_size)
860 == ERROR_SUCCESS)
861 {
862 unsigned r, g, b;
863 if (sscanf (color_buffer, " %u %u %u", &r, &g, &b) == 3)
864 *system_colors = Fcons (Fcons (build_string (full_name_buffer),
865 make_fixnum (RGB (r, g, b))),
866 *system_colors);
867
868 name_size = sizeof (full_name_buffer) - SYSTEM_COLOR_PREFIX_LEN;
869 color_size = sizeof (color_buffer);
870 index++;
871 }
872 RegCloseKey (colors_key);
873 }
874
875 unblock_input ();
876 }
877
878
879 static Lisp_Object
880 x_to_w32_color (const char * colorname)
881 {
882 register Lisp_Object ret = Qnil;
883
884 block_input ();
885
886 unsigned short r, g, b;
887 if (parse_color_spec (colorname, &r, &g, &b))
888 {
889 unblock_input ();
890
891 return make_fixnum ((b & 0xff00) << 8 | (g & 0xff00) | r >> 8);
892 }
893
894
895
896
897
898
899
900
901
902 ret = w32_color_map_lookup (colorname);
903 if (NILP (ret))
904 {
905 int len = strlen (colorname);
906
907 if (isdigit (colorname[len - 1]))
908 {
909 char *ptr, *approx = alloca (len + 1);
910
911 strcpy (approx, colorname);
912 ptr = &approx[len - 1];
913 while (ptr > approx && isdigit (*ptr))
914 *ptr-- = '\0';
915
916 ret = w32_color_map_lookup (approx);
917 }
918 }
919
920 unblock_input ();
921 return ret;
922 }
923
924 void
925 w32_regenerate_palette (struct frame *f)
926 {
927 struct w32_palette_entry * list;
928 LOGPALETTE * log_palette;
929 HPALETTE new_palette;
930 int i;
931
932
933 if (! FRAME_DISPLAY_INFO (f)->has_palette)
934 return;
935
936 log_palette = (LOGPALETTE *)
937 alloca (sizeof (LOGPALETTE) +
938 FRAME_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY));
939 log_palette->palVersion = 0x300;
940 log_palette->palNumEntries = FRAME_DISPLAY_INFO (f)->num_colors;
941
942 list = FRAME_DISPLAY_INFO (f)->color_list;
943 for (i = 0;
944 i < FRAME_DISPLAY_INFO (f)->num_colors;
945 i++, list = list->next)
946 log_palette->palPalEntry[i] = list->entry;
947
948 new_palette = CreatePalette (log_palette);
949
950 enter_crit ();
951
952 if (FRAME_DISPLAY_INFO (f)->palette)
953 DeleteObject (FRAME_DISPLAY_INFO (f)->palette);
954 FRAME_DISPLAY_INFO (f)->palette = new_palette;
955
956
957 release_frame_dc (f, get_frame_dc (f));
958
959 leave_crit ();
960 }
961
962 #define W32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
963 #define SET_W32_COLOR(pe, color) \
964 do \
965 { \
966 pe.peRed = GetRValue (color); \
967 pe.peGreen = GetGValue (color); \
968 pe.peBlue = GetBValue (color); \
969 pe.peFlags = 0; \
970 } while (0)
971
972 #if 0
973
974 void
975 w32_map_color (struct frame *f, COLORREF color)
976 {
977 struct w32_palette_entry * list = FRAME_DISPLAY_INFO (f)->color_list;
978
979 if (NILP (Vw32_enable_palette))
980 return;
981
982
983 while (list)
984 {
985 if (W32_COLOR (list->entry) == color)
986 {
987 ++list->refcount;
988 return;
989 }
990 list = list->next;
991 }
992
993
994 list = xmalloc (sizeof (struct w32_palette_entry));
995 SET_W32_COLOR (list->entry, color);
996 list->refcount = 1;
997 list->next = FRAME_DISPLAY_INFO (f)->color_list;
998 FRAME_DISPLAY_INFO (f)->color_list = list;
999 FRAME_DISPLAY_INFO (f)->num_colors++;
1000
1001
1002 FRAME_DISPLAY_INFO (f)->regen_palette = TRUE;
1003 }
1004
1005 void
1006 w32_unmap_color (struct frame *f, COLORREF color)
1007 {
1008 struct w32_palette_entry * list = FRAME_DISPLAY_INFO (f)->color_list;
1009 struct w32_palette_entry **prev = &FRAME_DISPLAY_INFO (f)->color_list;
1010
1011 if (NILP (Vw32_enable_palette))
1012 return;
1013
1014
1015 while (list)
1016 {
1017 if (W32_COLOR (list->entry) == color)
1018 {
1019 if (--list->refcount == 0)
1020 {
1021 *prev = list->next;
1022 xfree (list);
1023 FRAME_DISPLAY_INFO (f)->num_colors--;
1024 break;
1025 }
1026 else
1027 return;
1028 }
1029 prev = &list->next;
1030 list = list->next;
1031 }
1032
1033
1034 FRAME_DISPLAY_INFO (f)->regen_palette = TRUE;
1035 }
1036 #endif
1037
1038
1039
1040
1041 void
1042 gamma_correct (struct frame *f, COLORREF *color)
1043 {
1044 if (f->gamma)
1045 {
1046 *color = PALETTERGB (
1047 pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1048 pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1049 pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5);
1050 }
1051 }
1052
1053
1054
1055
1056
1057
1058 bool
1059 w32_defined_color (struct frame *f, const char *color, Emacs_Color *color_def,
1060 bool alloc_p, bool _makeIndex)
1061 {
1062 register Lisp_Object tem;
1063 COLORREF w32_color_ref;
1064
1065 tem = x_to_w32_color (color);
1066
1067 if (!NILP (tem))
1068 {
1069 if (f)
1070 {
1071
1072 w32_color_ref = XUFIXNUM (tem);
1073 gamma_correct (f, &w32_color_ref);
1074 XSETINT (tem, w32_color_ref);
1075 }
1076
1077
1078 if (!NILP (Vw32_enable_palette))
1079 {
1080 struct w32_palette_entry * entry =
1081 one_w32_display_info.color_list;
1082 struct w32_palette_entry ** prev =
1083 &one_w32_display_info.color_list;
1084
1085
1086 while (entry)
1087 {
1088 if (W32_COLOR (entry->entry) == XUFIXNUM (tem))
1089 break;
1090 prev = &entry->next;
1091 entry = entry->next;
1092 }
1093
1094 if (entry == NULL && alloc_p)
1095 {
1096
1097 entry = xmalloc (sizeof (struct w32_palette_entry));
1098 SET_W32_COLOR (entry->entry, XUFIXNUM (tem));
1099 entry->next = NULL;
1100 *prev = entry;
1101 one_w32_display_info.num_colors++;
1102
1103
1104 one_w32_display_info.regen_palette = TRUE;
1105 }
1106 }
1107
1108
1109
1110 w32_color_ref = XUFIXNUM (tem) | 0x2000000;
1111
1112 color_def->pixel = w32_color_ref;
1113 color_def->red = GetRValue (w32_color_ref) * 256;
1114 color_def->green = GetGValue (w32_color_ref) * 256;
1115 color_def->blue = GetBValue (w32_color_ref) * 256;
1116
1117 return 1;
1118 }
1119 else
1120 {
1121 return 0;
1122 }
1123 }
1124
1125
1126
1127
1128
1129
1130 static int
1131 w32_decode_color (struct frame *f, Lisp_Object arg, int def)
1132 {
1133 Emacs_Color cdef;
1134
1135 CHECK_STRING (arg);
1136
1137 if (strcmp (SSDATA (arg), "black") == 0)
1138 return BLACK_PIX_DEFAULT (f);
1139 else if (strcmp (SSDATA (arg), "white") == 0)
1140 return WHITE_PIX_DEFAULT (f);
1141
1142 if ((FRAME_DISPLAY_INFO (f)->n_planes * FRAME_DISPLAY_INFO (f)->n_cbits) == 1)
1143 return def;
1144
1145
1146
1147 if (w32_defined_color (f, SSDATA (arg), &cdef, true, false))
1148 return cdef.pixel;
1149
1150
1151 return def;
1152 }
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164 static void
1165 w32_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1166 {
1167 struct w32_output *x = f->output_data.w32;
1168 PIX_TYPE fg, old_fg;
1169
1170 fg = w32_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1171 old_fg = FRAME_FOREGROUND_PIXEL (f);
1172 FRAME_FOREGROUND_PIXEL (f) = fg;
1173
1174 if (FRAME_W32_WINDOW (f) != 0)
1175 {
1176 if (x->cursor_pixel == old_fg)
1177 {
1178 x->cursor_pixel = fg;
1179 x->cursor_gc->background = fg;
1180 }
1181
1182 update_face_from_frame_parameter (f, Qforeground_color, arg);
1183 if (FRAME_VISIBLE_P (f))
1184 redraw_frame (f);
1185 }
1186 }
1187
1188 static void
1189 w32_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1190 {
1191 FRAME_BACKGROUND_PIXEL (f)
1192 = w32_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1193
1194 if (FRAME_W32_WINDOW (f) != 0)
1195 {
1196 SetWindowLong (FRAME_W32_WINDOW (f), WND_BACKGROUND_INDEX,
1197 FRAME_BACKGROUND_PIXEL (f));
1198
1199 update_face_from_frame_parameter (f, Qbackground_color, arg);
1200
1201 if (FRAME_VISIBLE_P (f))
1202 redraw_frame (f);
1203 }
1204 }
1205
1206 static void
1207 w32_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1208 {
1209 #if 0
1210 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1211 int count;
1212 #endif
1213 int mask_color;
1214
1215 if (!NILP (arg))
1216 f->output_data.w32->mouse_pixel
1217 = w32_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1218 mask_color = FRAME_BACKGROUND_PIXEL (f);
1219
1220
1221 if (mask_color == f->output_data.w32->mouse_pixel
1222 && mask_color == FRAME_BACKGROUND_PIXEL (f))
1223 f->output_data.w32->mouse_pixel = FRAME_FOREGROUND_PIXEL (f);
1224
1225 #if 0
1226 block_input ();
1227
1228
1229 count = x_catch_errors (FRAME_W32_DISPLAY (f));
1230
1231 if (!NILP (Vx_pointer_shape))
1232 {
1233 CHECK_FIXNUM (Vx_pointer_shape);
1234 cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XFIXNUM (Vx_pointer_shape));
1235 }
1236 else
1237 cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1238 x_check_errors (FRAME_W32_DISPLAY (f), "bad text pointer cursor: %s");
1239
1240 if (!NILP (Vx_nontext_pointer_shape))
1241 {
1242 CHECK_FIXNUM (Vx_nontext_pointer_shape);
1243 nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1244 XFIXNUM (Vx_nontext_pointer_shape));
1245 }
1246 else
1247 nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_left_ptr);
1248 x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1249
1250 if (!NILP (Vx_hourglass_pointer_shape))
1251 {
1252 CHECK_FIXNUM (Vx_hourglass_pointer_shape);
1253 hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1254 XFIXNUM (Vx_hourglass_pointer_shape));
1255 }
1256 else
1257 hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch);
1258 x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s");
1259
1260 x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1261 if (!NILP (Vx_mode_pointer_shape))
1262 {
1263 CHECK_FIXNUM (Vx_mode_pointer_shape);
1264 mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1265 XFIXNUM (Vx_mode_pointer_shape));
1266 }
1267 else
1268 mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1269 x_check_errors (FRAME_W32_DISPLAY (f), "bad modeline pointer cursor: %s");
1270
1271 if (!NILP (Vx_sensitive_text_pointer_shape))
1272 {
1273 CHECK_FIXNUM (Vx_sensitive_text_pointer_shape);
1274 hand_cursor
1275 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1276 XFIXNUM (Vx_sensitive_text_pointer_shape));
1277 }
1278 else
1279 hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair);
1280
1281 if (!NILP (Vx_window_horizontal_drag_shape))
1282 {
1283 CHECK_FIXNUM (Vx_window_horizontal_drag_shape);
1284 horizontal_drag_cursor
1285 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1286 XFIXNUM (Vx_window_horizontal_drag_shape));
1287 }
1288 else
1289 horizontal_drag_cursor
1290 = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_h_double_arrow);
1291
1292 if (!NILP (Vx_window_vertical_drag_shape))
1293 {
1294 CHECK_FIXNUM (Vx_window_vertical_drag_shape);
1295 vertical_drag_cursor
1296 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1297 XFIXNUM (Vx_window_vertical_drag_shape));
1298 }
1299 else
1300 vertical_drag_cursor
1301 = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_v_double_arrow);
1302
1303
1304 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
1305 x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
1306
1307 {
1308 XColor fore_color, back_color;
1309
1310 fore_color.pixel = f->output_data.w32->mouse_pixel;
1311 back_color.pixel = mask_color;
1312 XQueryColor (FRAME_W32_DISPLAY (f),
1313 DefaultColormap (FRAME_W32_DISPLAY (f),
1314 DefaultScreen (FRAME_W32_DISPLAY (f))),
1315 &fore_color);
1316 XQueryColor (FRAME_W32_DISPLAY (f),
1317 DefaultColormap (FRAME_W32_DISPLAY (f),
1318 DefaultScreen (FRAME_W32_DISPLAY (f))),
1319 &back_color);
1320 XRecolorCursor (FRAME_W32_DISPLAY (f), cursor,
1321 &fore_color, &back_color);
1322 XRecolorCursor (FRAME_W32_DISPLAY (f), nontext_cursor,
1323 &fore_color, &back_color);
1324 XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
1325 &fore_color, &back_color);
1326 XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
1327 &fore_color, &back_color);
1328 XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
1329 &fore_color, &back_color);
1330 }
1331
1332 if (FRAME_W32_WINDOW (f) != 0)
1333 XDefineCursor (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), cursor);
1334
1335 if (cursor != f->output_data.w32->text_cursor && f->output_data.w32->text_cursor != 0)
1336 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->text_cursor);
1337 f->output_data.w32->text_cursor = cursor;
1338
1339 if (nontext_cursor != f->output_data.w32->nontext_cursor
1340 && f->output_data.w32->nontext_cursor != 0)
1341 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->nontext_cursor);
1342 f->output_data.w32->nontext_cursor = nontext_cursor;
1343
1344 if (hourglass_cursor != f->output_data.w32->hourglass_cursor
1345 && f->output_data.w32->hourglass_cursor != 0)
1346 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hourglass_cursor);
1347 f->output_data.w32->hourglass_cursor = hourglass_cursor;
1348
1349 if (mode_cursor != f->output_data.w32->modeline_cursor
1350 && f->output_data.w32->modeline_cursor != 0)
1351 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor);
1352 f->output_data.w32->modeline_cursor = mode_cursor;
1353
1354 if (hand_cursor != f->output_data.w32->hand_cursor
1355 && f->output_data.w32->hand_cursor != 0)
1356 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor);
1357 f->output_data.w32->hand_cursor = hand_cursor;
1358
1359 XFlush (FRAME_W32_DISPLAY (f));
1360 unblock_input ();
1361
1362 update_face_from_frame_parameter (f, Qmouse_color, arg);
1363 #endif
1364 }
1365
1366 static void
1367 w32_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1368 {
1369 unsigned long fore_pixel, pixel;
1370
1371 if (!NILP (Vx_cursor_fore_pixel))
1372 fore_pixel = w32_decode_color (f, Vx_cursor_fore_pixel,
1373 WHITE_PIX_DEFAULT (f));
1374 else
1375 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1376
1377 pixel = w32_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1378
1379
1380 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1381 {
1382 pixel = f->output_data.w32->mouse_pixel;
1383 if (pixel == fore_pixel)
1384 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1385 }
1386
1387 f->output_data.w32->cursor_foreground_pixel = fore_pixel;
1388 f->output_data.w32->cursor_pixel = pixel;
1389
1390 if (FRAME_W32_WINDOW (f) != 0)
1391 {
1392 block_input ();
1393
1394 f->output_data.w32->cursor_gc->foreground = fore_pixel;
1395 f->output_data.w32->cursor_gc->background = pixel;
1396
1397 unblock_input ();
1398
1399 if (FRAME_VISIBLE_P (f))
1400 {
1401 gui_update_cursor (f, 0);
1402 gui_update_cursor (f, 1);
1403 }
1404 }
1405
1406 update_face_from_frame_parameter (f, Qcursor_color, arg);
1407 }
1408
1409
1410
1411
1412
1413 static void
1414 w32_set_border_pixel (struct frame *f, int pix)
1415 {
1416
1417 f->output_data.w32->border_pixel = pix;
1418
1419 if (FRAME_W32_WINDOW (f) != 0 && f->border_width > 0)
1420 {
1421 if (FRAME_VISIBLE_P (f))
1422 redraw_frame (f);
1423 }
1424 }
1425
1426
1427
1428
1429
1430
1431
1432 static void
1433 w32_set_border_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1434 {
1435 int pix;
1436
1437 CHECK_STRING (arg);
1438 pix = w32_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1439 w32_set_border_pixel (f, pix);
1440 update_face_from_frame_parameter (f, Qborder_color, arg);
1441 }
1442
1443
1444 static void
1445 w32_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1446 {
1447 set_frame_cursor_types (f, arg);
1448 }
1449
1450 static void
1451 w32_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1452 {
1453 bool result;
1454
1455 if (NILP (arg) && NILP (oldval))
1456 return;
1457
1458 if (STRINGP (arg) && STRINGP (oldval)
1459 && BASE_EQ (Fstring_equal (oldval, arg), Qt))
1460 return;
1461
1462 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1463 return;
1464
1465 block_input ();
1466
1467 result = FRAME_TERMINAL (f)->set_bitmap_icon_hook (f, arg);
1468 if (result)
1469 {
1470 unblock_input ();
1471 error ("No icon window available");
1472 }
1473
1474 unblock_input ();
1475 }
1476
1477 static void
1478 w32_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1479 {
1480 if (STRINGP (arg))
1481 {
1482 if (STRINGP (oldval) && BASE_EQ (Fstring_equal (oldval, arg), Qt))
1483 return;
1484 }
1485 else if (!NILP (arg) || NILP (oldval))
1486 return;
1487
1488 fset_icon_name (f, arg);
1489
1490 #if 0
1491 if (f->output_data.w32->icon_bitmap != 0)
1492 return;
1493
1494 block_input ();
1495
1496 result = x_text_icon (f,
1497 SSDATA ((!NILP (f->icon_name)
1498 ? f->icon_name
1499 : !NILP (f->title)
1500 ? f->title
1501 : f->name)));
1502
1503 if (result)
1504 {
1505 unblock_input ();
1506 error ("No icon window available");
1507 }
1508
1509
1510
1511 if (FRAME_VISIBLE_P (f))
1512 {
1513 #ifdef USE_X_TOOLKIT
1514 XtPopup (f->output_data.w32->widget, XtGrabNone);
1515 #endif
1516 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1517 }
1518
1519 XFlush (FRAME_W32_DISPLAY (f));
1520 unblock_input ();
1521 #endif
1522 }
1523
1524
1525
1526
1527
1528
1529
1530 void
1531 w32_clear_under_internal_border (struct frame *f)
1532 {
1533 int border = FRAME_INTERNAL_BORDER_WIDTH (f);
1534
1535
1536 if (border != 0)
1537 {
1538 int width = FRAME_PIXEL_WIDTH (f);
1539 int height = FRAME_PIXEL_HEIGHT (f);
1540 int face_id =
1541 (FRAME_PARENT_FRAME (f)
1542 ? (!NILP (Vface_remapping_alist)
1543 ? lookup_basic_face (NULL, f, CHILD_FRAME_BORDER_FACE_ID)
1544 : CHILD_FRAME_BORDER_FACE_ID)
1545 : (!NILP (Vface_remapping_alist)
1546 ? lookup_basic_face (NULL, f, INTERNAL_BORDER_FACE_ID)
1547 : INTERNAL_BORDER_FACE_ID));
1548 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1549
1550 block_input ();
1551 HDC hdc = get_frame_dc (f);
1552 if (face)
1553 {
1554
1555 unsigned long color = face->background;
1556
1557 w32_fill_area (f, hdc, color, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
1558 w32_fill_area (f, hdc, color, 0, 0, border, height);
1559 w32_fill_area (f, hdc, color, width - border, 0, border, height);
1560 w32_fill_area (f, hdc, color, 0, height - border, width, border);
1561 }
1562 else
1563 {
1564 w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
1565 w32_clear_area (f, hdc, 0, 0, border, height);
1566 w32_clear_area (f, hdc, width - border, 0, border, height);
1567 w32_clear_area (f, hdc, 0, height - border, width, border);
1568 }
1569 release_frame_dc (f, hdc);
1570 unblock_input ();
1571 }
1572 }
1573
1574
1575
1576
1577
1578
1579
1580 static void
1581 w32_set_child_frame_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1582 {
1583 int border;
1584
1585 if (NILP (arg))
1586 border = -1;
1587 else if (RANGED_FIXNUMP (0, arg, INT_MAX))
1588 border = XFIXNAT (arg);
1589 else
1590 signal_error ("Invalid child frame border width", arg);
1591
1592 if (border != FRAME_CHILD_FRAME_BORDER_WIDTH (f))
1593 {
1594 f->child_frame_border_width = border;
1595
1596 if (FRAME_NATIVE_WINDOW (f) != 0)
1597 {
1598 adjust_frame_size (f, -1, -1, 3, false, Qchild_frame_border_width);
1599
1600 if (FRAME_VISIBLE_P (f))
1601 w32_clear_under_internal_border (f);
1602 }
1603 }
1604 }
1605
1606
1607
1608
1609
1610
1611
1612
1613 static void
1614 w32_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1615 {
1616 int argval = check_integer_range (arg, INT_MIN, INT_MAX);
1617 int border = max (argval, 0);
1618
1619 if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
1620 {
1621 f->internal_border_width = border;
1622
1623 if (FRAME_NATIVE_WINDOW (f) != 0)
1624 {
1625 adjust_frame_size (f, -1, -1, 3, false, Qinternal_border_width);
1626
1627 if (FRAME_VISIBLE_P (f))
1628 w32_clear_under_internal_border (f);
1629 }
1630 }
1631 }
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642 static void
1643 w32_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1644 {
1645
1646
1647
1648
1649
1650 if (!FRAME_MINIBUF_ONLY_P (f) && !FRAME_PARENT_FRAME (f))
1651 {
1652 boolean old = FRAME_EXTERNAL_MENU_BAR (f);
1653 boolean new = (FIXNUMP (value) && XFIXNUM (value) > 0) ? true : false;
1654
1655 FRAME_MENU_BAR_LINES (f) = 0;
1656 FRAME_MENU_BAR_HEIGHT (f) = 0;
1657
1658 if (old != new)
1659 {
1660 FRAME_EXTERNAL_MENU_BAR (f) = new;
1661
1662 if (!old)
1663
1664
1665 set_frame_menubar (f, true);
1666 else
1667 {
1668
1669 free_frame_menubar (f);
1670
1671
1672
1673
1674
1675
1676
1677
1678 adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
1679 }
1680
1681 if (FRAME_W32_WINDOW (f))
1682 w32_clear_under_internal_border (f);
1683
1684
1685 store_frame_param (f, Qmenu_bar_lines, make_fixnum (new ? 1 : 0));
1686 }
1687 }
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697 static void
1698 w32_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1699 {
1700 int nlines;
1701
1702
1703 if (FRAME_MINIBUF_ONLY_P (f))
1704 return;
1705
1706
1707 if (RANGED_FIXNUMP (0, value, INT_MAX))
1708 nlines = XFIXNAT (value);
1709 else
1710 nlines = 0;
1711
1712 w32_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1713 }
1714
1715
1716
1717 void
1718 w32_change_tab_bar_height (struct frame *f, int height)
1719 {
1720 int unit = FRAME_LINE_HEIGHT (f);
1721 int old_height = FRAME_TAB_BAR_HEIGHT (f);
1722
1723
1724
1725
1726
1727
1728 int lines = height / unit;
1729 if (lines == 0 && height != 0)
1730 lines = 1;
1731
1732
1733 fset_redisplay (f);
1734
1735
1736 FRAME_TAB_BAR_HEIGHT (f) = height;
1737 FRAME_TAB_BAR_LINES (f) = lines;
1738
1739 store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
1740 store_frame_param (f, Qheight, make_fixnum (FRAME_LINES (f)));
1741
1742
1743
1744
1745
1746
1747
1748 if (FRAME_W32_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
1749 {
1750 clear_frame (f);
1751 clear_current_matrices (f);
1752 }
1753
1754 if ((height < old_height) && WINDOWP (f->tab_bar_window))
1755 clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
1756
1757 if (!f->tab_bar_resized)
1758 {
1759 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
1760
1761
1762
1763 if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
1764 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
1765 1, false, Qtab_bar_lines);
1766 else
1767 adjust_frame_size (f, -1, -1, 4, false, Qtab_bar_lines);
1768
1769 f->tab_bar_resized = f->tab_bar_redisplayed;
1770 }
1771 else
1772
1773 adjust_frame_size (f, -1, -1, 3, false, Qtab_bar_lines);
1774
1775
1776
1777 adjust_frame_glyphs (f);
1778 SET_FRAME_GARBAGED (f);
1779 if (FRAME_W32_WINDOW (f))
1780 w32_clear_under_internal_border (f);
1781 }
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791 static void
1792 w32_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1793 {
1794 int nlines;
1795
1796
1797 if (FRAME_MINIBUF_ONLY_P (f))
1798 return;
1799
1800
1801 if (FIXNUMP (value) && XFIXNUM (value) >= 0)
1802 nlines = XFIXNAT (value);
1803 else
1804 nlines = 0;
1805
1806 w32_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
1807 }
1808
1809
1810
1811
1812
1813
1814
1815 static void
1816 w32_set_inhibit_double_buffering (struct frame *f,
1817 Lisp_Object new_value,
1818
1819 Lisp_Object old_value)
1820 {
1821 block_input ();
1822
1823 if (NILP (new_value))
1824 FRAME_OUTPUT_DATA (f)->want_paint_buffer = 1;
1825 else
1826 {
1827 FRAME_OUTPUT_DATA (f)->want_paint_buffer = 0;
1828 w32_release_paint_buffer (f);
1829
1830 SET_FRAME_GARBAGED (f);
1831 }
1832
1833 unblock_input ();
1834 }
1835
1836
1837 void
1838 w32_change_tool_bar_height (struct frame *f, int height)
1839 {
1840 int unit = FRAME_LINE_HEIGHT (f);
1841 int old_height = FRAME_TOOL_BAR_HEIGHT (f);
1842 int lines = (height + unit - 1) / unit;
1843 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
1844
1845
1846 windows_or_buffers_changed = 23;
1847
1848
1849 FRAME_TOOL_BAR_HEIGHT (f) = height;
1850 FRAME_TOOL_BAR_LINES (f) = lines;
1851
1852 store_frame_param (f, Qtool_bar_lines, make_fixnum (lines));
1853 store_frame_param (f, Qheight, make_fixnum (FRAME_LINES (f)));
1854
1855 if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
1856 {
1857 clear_frame (f);
1858 clear_current_matrices (f);
1859 }
1860
1861 if ((height < old_height) && WINDOWP (f->tool_bar_window))
1862 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1863
1864 if (!f->tool_bar_resized)
1865 {
1866
1867
1868 if (NILP (fullscreen) || EQ (fullscreen, Qfullwidth))
1869 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
1870 1, false, Qtool_bar_lines);
1871 else
1872 adjust_frame_size (f, -1, -1, 4, false, Qtool_bar_lines);
1873
1874 f->tool_bar_resized = f->tool_bar_redisplayed;
1875 }
1876 else
1877
1878 adjust_frame_size (f, -1, -1, 3, false, Qtool_bar_lines);
1879
1880
1881
1882 adjust_frame_glyphs (f);
1883 SET_FRAME_GARBAGED (f);
1884 if (FRAME_W32_WINDOW (f))
1885 w32_clear_under_internal_border (f);
1886 }
1887
1888 static void
1889 w32_set_title_bar_text (struct frame *f, Lisp_Object name)
1890 {
1891 if (FRAME_W32_WINDOW (f))
1892 {
1893 block_input ();
1894 #ifdef __CYGWIN__
1895 GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f),
1896 GUI_SDATA (GUI_ENCODE_SYSTEM (name)));
1897 #else
1898
1899
1900
1901
1902 if (w32_unicode_filenames)
1903 {
1904 Lisp_Object encoded_title = ENCODE_UTF_8 (name);
1905 wchar_t *title_w;
1906 int tlen = pMultiByteToWideChar (CP_UTF8, 0, SSDATA (encoded_title),
1907 -1, NULL, 0);
1908
1909 if (tlen > 0)
1910 {
1911
1912
1913
1914 if (tlen > 10000)
1915 tlen = 10000;
1916 title_w = alloca ((tlen + 1) * sizeof (wchar_t));
1917 pMultiByteToWideChar (CP_UTF8, 0, SSDATA (encoded_title), -1,
1918 title_w, tlen);
1919 title_w[tlen] = L'\0';
1920 SetWindowTextW (FRAME_W32_WINDOW (f), title_w);
1921 }
1922 else
1923 SetWindowTextA (FRAME_W32_WINDOW (f),
1924 SSDATA (ENCODE_SYSTEM (name)));
1925 }
1926 else
1927 SetWindowTextA (FRAME_W32_WINDOW (f), SSDATA (ENCODE_SYSTEM (name)));
1928 #endif
1929 unblock_input ();
1930 }
1931 }
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944 static void
1945 w32_set_name (struct frame *f, Lisp_Object name, bool explicit)
1946 {
1947
1948
1949 if (explicit)
1950 {
1951
1952
1953 if (f->explicit_name && NILP (name))
1954 update_mode_lines = 25;
1955
1956 f->explicit_name = ! NILP (name);
1957 }
1958 else if (f->explicit_name)
1959 return;
1960
1961
1962 if (NILP (name))
1963 {
1964
1965
1966 if (!strcmp (FRAME_DISPLAY_INFO (f)->w32_id_name,
1967 SSDATA (f->name)))
1968 return;
1969 name = build_string (FRAME_DISPLAY_INFO (f)->w32_id_name);
1970 }
1971 else
1972 CHECK_STRING (name);
1973
1974
1975 if (! NILP (Fstring_equal (name, f->name)))
1976 return;
1977
1978 fset_name (f, name);
1979
1980
1981
1982 if (! NILP (f->title))
1983 name = f->title;
1984
1985 w32_set_title_bar_text (f, name);
1986 }
1987
1988
1989
1990
1991 static void
1992 w32_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1993 {
1994 w32_set_name (f, arg, true);
1995 }
1996
1997
1998
1999
2000 void
2001 w32_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
2002 {
2003 w32_set_name (f, arg, false);
2004 }
2005
2006
2007
2008
2009 static void
2010 w32_set_title (struct frame *f, Lisp_Object name, Lisp_Object old_name)
2011 {
2012
2013 if (EQ (name, f->title))
2014 return;
2015
2016 update_mode_lines = 26;
2017
2018 fset_title (f, name);
2019
2020 if (NILP (name))
2021 name = f->name;
2022
2023 w32_set_title_bar_text (f, name);
2024 }
2025
2026 void
2027 w32_set_scroll_bar_default_width (struct frame *f)
2028 {
2029 int unit = FRAME_COLUMN_WIDTH (f);
2030
2031 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
2032 FRAME_CONFIG_SCROLL_BAR_COLS (f)
2033 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
2034 }
2035
2036
2037 void
2038 w32_set_scroll_bar_default_height (struct frame *f)
2039 {
2040 int unit = FRAME_LINE_HEIGHT (f);
2041
2042 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL);
2043 FRAME_CONFIG_SCROLL_BAR_LINES (f)
2044 = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + unit - 1) / unit;
2045 }
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059 static void
2060 w32_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2061 {
2062 HWND hwnd = FRAME_W32_WINDOW (f);
2063 DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
2064 Lisp_Object border_width = Fcdr (Fassq (Qborder_width, f->param_alist));
2065
2066 block_input ();
2067 if (!NILP (new_value) && !FRAME_UNDECORATED (f))
2068 {
2069 dwStyle = ((dwStyle & ~WS_THICKFRAME & ~WS_CAPTION)
2070 | ((FIXNUMP (border_width) && (XFIXNUM (border_width) > 0))
2071 ? WS_BORDER : false));
2072 SetWindowLong (hwnd, GWL_STYLE, dwStyle);
2073 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
2074 SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
2075 | SWP_FRAMECHANGED);
2076 FRAME_UNDECORATED (f) = true;
2077 }
2078 else if (NILP (new_value) && FRAME_UNDECORATED (f))
2079 {
2080 SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_THICKFRAME | WS_CAPTION
2081 | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU);
2082 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0,
2083 SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
2084 | SWP_FRAMECHANGED);
2085 FRAME_UNDECORATED (f) = false;
2086 }
2087
2088 f->output_data.w32->dwStyle = GetWindowLong (hwnd, GWL_STYLE);
2089
2090 unblock_input ();
2091 }
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121 static void
2122 w32_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2123 {
2124 struct frame *p = NULL;
2125
2126 if (!NILP (new_value)
2127 && (!FRAMEP (new_value)
2128 || !FRAME_LIVE_P (p = XFRAME (new_value))
2129 || !FRAME_W32_P (p)))
2130 {
2131 store_frame_param (f, Qparent_frame, old_value);
2132 error ("Invalid specification of `parent-frame'");
2133 }
2134
2135 if (p != FRAME_PARENT_FRAME (f))
2136 {
2137 HWND hwnd = FRAME_W32_WINDOW (f);
2138 HWND hwnd_parent = p ? FRAME_W32_WINDOW (p) : NULL;
2139 HWND hwnd_value;
2140
2141 block_input ();
2142 hwnd_value = SetParent (hwnd, hwnd_parent);
2143 unblock_input ();
2144
2145 if (hwnd_value)
2146 fset_parent_frame (f, new_value);
2147 else
2148 {
2149 store_frame_param (f, Qparent_frame, old_value);
2150 error ("Reparenting frame failed");
2151 }
2152 }
2153 }
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166 static void
2167 w32_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2168 {
2169 if (!EQ (new_value, old_value))
2170 {
2171 HWND hwnd = FRAME_W32_WINDOW (f);
2172 DWORD exStyle = GetWindowLong (hwnd, GWL_EXSTYLE);
2173
2174 block_input ();
2175
2176
2177 ShowWindow (hwnd, SW_HIDE);
2178 if (!NILP (new_value))
2179 SetWindowLong (hwnd, GWL_EXSTYLE, exStyle | WS_EX_NOACTIVATE);
2180 else
2181 SetWindowLong (hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_NOACTIVATE);
2182 ShowWindow (hwnd, SW_SHOWNOACTIVATE);
2183 unblock_input ();
2184
2185 FRAME_SKIP_TASKBAR (f) = !NILP (new_value);
2186 }
2187 }
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200 static void
2201 w32_set_no_focus_on_map (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2202 {
2203 if (!EQ (new_value, old_value))
2204 FRAME_NO_FOCUS_ON_MAP (f) = !NILP (new_value);
2205 }
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219 static void
2220 w32_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2221 {
2222 if (!EQ (new_value, old_value))
2223 FRAME_NO_ACCEPT_FOCUS (f) = !NILP (new_value);
2224 }
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244 static void
2245 w32_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
2246 {
2247 HWND hwnd = FRAME_W32_WINDOW (f);
2248
2249 if (NILP (new_value))
2250 {
2251 block_input ();
2252 SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
2253 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE
2254 | SWP_NOOWNERZORDER);
2255 unblock_input ();
2256 FRAME_Z_GROUP (f) = z_group_none;
2257 }
2258 else if (EQ (new_value, Qabove))
2259 {
2260 block_input ();
2261 SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0,
2262 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE
2263 | SWP_NOOWNERZORDER);
2264 unblock_input ();
2265 FRAME_Z_GROUP (f) = z_group_above;
2266 }
2267 else if (EQ (new_value, Qabove_suspended))
2268 {
2269 block_input ();
2270 SetWindowPos (hwnd, HWND_NOTOPMOST, 0, 0, 0, 0,
2271 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE
2272 | SWP_NOOWNERZORDER);
2273 unblock_input ();
2274 FRAME_Z_GROUP (f) = z_group_above_suspended;
2275 }
2276 else if (EQ (new_value, Qbelow))
2277 error ("Value `below' for z-group is not supported on Windows");
2278 else
2279 error ("Invalid z-group specification");
2280 }
2281
2282
2283
2284 HCURSOR w32_load_cursor (LPCTSTR);
2285
2286 HCURSOR
2287 w32_load_cursor (LPCTSTR name)
2288 {
2289
2290 HCURSOR cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL),
2291 name, IMAGE_CURSOR, 0, 0,
2292 LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
2293 if (!cursor)
2294 {
2295
2296 cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0,
2297 LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
2298 }
2299 return cursor;
2300 }
2301
2302 static LRESULT CALLBACK w32_wnd_proc (HWND, UINT, WPARAM, LPARAM);
2303
2304 #define INIT_WINDOW_CLASS(WC) \
2305 (WC).style = CS_HREDRAW | CS_VREDRAW; \
2306 (WC).lpfnWndProc = (WNDPROC) w32_wnd_proc; \
2307 (WC).cbClsExtra = 0; \
2308 (WC).cbWndExtra = WND_EXTRA_BYTES; \
2309 (WC).hInstance = hinst; \
2310 (WC).hIcon = LoadIcon (hinst, EMACS_CLASS); \
2311 (WC).hCursor = w32_load_cursor (IDC_ARROW); \
2312 (WC).hbrBackground = NULL; \
2313 (WC).lpszMenuName = NULL; \
2314
2315 static BOOL
2316 w32_init_class (HINSTANCE hinst)
2317 {
2318 if (w32_unicode_gui)
2319 {
2320 WNDCLASSW uwc;
2321 INIT_WINDOW_CLASS(uwc);
2322 uwc.lpszClassName = L"Emacs";
2323
2324 return RegisterClassW (&uwc);
2325 }
2326 else
2327 {
2328 WNDCLASS wc;
2329 INIT_WINDOW_CLASS(wc);
2330 wc.lpszClassName = EMACS_CLASS;
2331
2332 return RegisterClassA (&wc);
2333 }
2334 }
2335
2336
2337
2338 static void
2339 w32_applytheme (HWND hwnd)
2340 {
2341 if (w32_darkmode)
2342 {
2343
2344
2345 if (SetWindowTheme_fn)
2346 SetWindowTheme_fn (hwnd, DARK_MODE_APP_NAME, NULL);
2347
2348
2349 if (DwmSetWindowAttribute_fn)
2350 {
2351
2352 DWORD attr = DWMWA_USE_IMMERSIVE_DARK_MODE;
2353
2354 if (w32_build_number < 19041)
2355 attr = DWMWA_USE_IMMERSIVE_DARK_MODE_OLD;
2356 DwmSetWindowAttribute_fn (hwnd, attr,
2357 &w32_darkmode, sizeof (w32_darkmode));
2358 }
2359 }
2360 }
2361
2362 static HWND
2363 w32_createvscrollbar (struct frame *f, struct scroll_bar * bar)
2364 {
2365 HWND hwnd = CreateWindow ("SCROLLBAR", "",
2366
2367
2368
2369
2370 SBS_VERT | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
2371
2372 bar->left, bar->top, bar->width, bar->height,
2373 FRAME_W32_WINDOW (f), NULL, hinst, NULL);
2374 if (hwnd)
2375 w32_applytheme (hwnd);
2376 return hwnd;
2377 }
2378
2379 static HWND
2380 w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
2381 {
2382 HWND hwnd = CreateWindow ("SCROLLBAR", "",
2383
2384
2385
2386
2387 SBS_HORZ | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS,
2388
2389 bar->left, bar->top, bar->width, bar->height,
2390 FRAME_W32_WINDOW (f), NULL, hinst, NULL);
2391 if (hwnd)
2392 w32_applytheme (hwnd);
2393 return hwnd;
2394 }
2395
2396 static void
2397 w32_createwindow (struct frame *f, int *coords)
2398 {
2399 HWND hwnd = NULL, parent_hwnd = NULL;
2400 RECT rect;
2401 int top, left;
2402 Lisp_Object border_width = Fcdr (Fassq (Qborder_width, f->param_alist));
2403
2404 if (FRAME_PARENT_FRAME (f) && FRAME_W32_P (FRAME_PARENT_FRAME (f)))
2405 {
2406 parent_hwnd = FRAME_W32_WINDOW (FRAME_PARENT_FRAME (f));
2407 f->output_data.w32->dwStyle = WS_CHILD | WS_CLIPSIBLINGS;
2408
2409 if (FRAME_UNDECORATED (f))
2410 {
2411
2412 if (FIXNUMP (border_width) && (XFIXNUM (border_width) > 0))
2413 f->output_data.w32->dwStyle |= WS_BORDER;
2414 }
2415 else
2416
2417 f->output_data.w32->dwStyle |= (WS_THICKFRAME | WS_CAPTION
2418 | WS_MAXIMIZEBOX | WS_MINIMIZEBOX
2419 | WS_SYSMENU);
2420 }
2421 else if (FRAME_UNDECORATED (f))
2422 {
2423
2424
2425 f->output_data.w32->dwStyle = WS_POPUP;
2426
2427
2428 if (FIXNUMP (border_width) && (XFIXNUM (border_width) > 0))
2429 f->output_data.w32->dwStyle |= WS_BORDER;
2430 }
2431 else
2432 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
2433
2434
2435 f->output_data.w32->dwStyle |= WS_CLIPCHILDREN;
2436
2437 rect.left = rect.top = 0;
2438 rect.right = FRAME_PIXEL_WIDTH (f);
2439 rect.bottom = FRAME_PIXEL_HEIGHT (f);
2440
2441 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
2442 FRAME_EXTERNAL_MENU_BAR (f) && !parent_hwnd);
2443
2444
2445 w32_init_class (hinst);
2446
2447 if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
2448 {
2449 left = f->left_pos;
2450 top = f->top_pos;
2451 }
2452 else
2453 {
2454 left = coords[0];
2455 top = coords[1];
2456 }
2457
2458 FRAME_W32_WINDOW (f) = hwnd
2459 = CreateWindow (EMACS_CLASS, f->namebuf, f->output_data.w32->dwStyle,
2460 left, top, rect.right - rect.left, rect.bottom - rect.top,
2461 parent_hwnd, NULL, hinst, NULL);
2462
2463 if (hwnd)
2464 {
2465 if (FRAME_SKIP_TASKBAR (f))
2466 SetWindowLong (hwnd, GWL_EXSTYLE,
2467 GetWindowLong (hwnd, GWL_EXSTYLE) | WS_EX_NOACTIVATE);
2468
2469 SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
2470 SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
2471 SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
2472 SetWindowLong (hwnd, WND_VSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
2473 SetWindowLong (hwnd, WND_HSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_HEIGHT (f));
2474 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
2475
2476
2477 DragAcceptFiles (hwnd, TRUE);
2478
2479
2480 w32_applytheme (hwnd);
2481
2482
2483 ShowWindow (hwnd, SW_HIDE);
2484
2485
2486 GetWindowRect (hwnd, &rect);
2487
2488 if (parent_hwnd)
2489
2490
2491 MapWindowPoints (HWND_DESKTOP, parent_hwnd, (LPPOINT) &rect, 2);
2492
2493 f->left_pos = rect.left;
2494 f->top_pos = rect.top;
2495 }
2496 }
2497
2498 static void
2499 my_post_msg (W32Msg * wmsg, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2500 {
2501 wmsg->msg.hwnd = hwnd;
2502 wmsg->msg.message = msg;
2503 wmsg->msg.wParam = wParam;
2504 wmsg->msg.lParam = lParam;
2505 wmsg->msg.time = GetMessageTime ();
2506
2507 post_msg (wmsg);
2508 }
2509
2510 #ifdef WINDOWSNT
2511
2512 static LRESULT CALLBACK
2513 funhook (int code, WPARAM w, LPARAM l)
2514 {
2515 INPUT inputs[2];
2516 HWND focus = GetFocus ();
2517 int console = 0;
2518 KBDLLHOOKSTRUCT const *hs = (KBDLLHOOKSTRUCT*)l;
2519
2520 if (code < 0 || (hs->flags & LLKHF_INJECTED))
2521 return CallNextHookEx (0, code, w, l);
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532 if (focus == NULL && kbdhook.console != NULL)
2533 {
2534 if (GetForegroundWindow () == kbdhook.console)
2535 {
2536 focus = kbdhook.console;
2537 console = 1;
2538 }
2539 }
2540
2541
2542 if (hs->vkCode == VK_LWIN || hs->vkCode == VK_RWIN)
2543 {
2544 if (focus != NULL && (w == WM_KEYDOWN || w == WM_SYSKEYDOWN))
2545 {
2546
2547 if (hs->vkCode == VK_LWIN && !kbdhook.lwindown)
2548 {
2549 kbdhook.lwindown = 1;
2550 kbdhook.winseen = 1;
2551 kbdhook.winsdown++;
2552 }
2553 else if (hs->vkCode == VK_RWIN && !kbdhook.rwindown)
2554 {
2555 kbdhook.rwindown = 1;
2556 kbdhook.winseen = 1;
2557 kbdhook.winsdown++;
2558 }
2559
2560
2561
2562 return 1;
2563 }
2564 else if (kbdhook.winsdown > 0 && (w == WM_KEYUP || w == WM_SYSKEYUP))
2565 {
2566
2567 if (hs->vkCode == VK_LWIN && kbdhook.lwindown)
2568 {
2569 kbdhook.lwindown = 0;
2570 kbdhook.winsdown--;
2571 }
2572 else if (hs->vkCode == VK_RWIN && kbdhook.rwindown)
2573 {
2574 kbdhook.rwindown = 0;
2575 kbdhook.winsdown--;
2576 }
2577 if (kbdhook.winsdown == 0 && kbdhook.winseen)
2578 {
2579 if (!kbdhook.suppress_lone)
2580 {
2581
2582
2583
2584
2585
2586
2587 if ((hs->vkCode == VK_LWIN && !NILP (Vw32_pass_lwindow_to_system)) ||
2588 (hs->vkCode == VK_RWIN && !NILP (Vw32_pass_rwindow_to_system)))
2589 {
2590
2591 memset (inputs, 0, sizeof (inputs));
2592 inputs[0].type = INPUT_KEYBOARD;
2593 inputs[0].ki.wVk = hs->vkCode;
2594 inputs[0].ki.wScan = hs->vkCode;
2595 inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
2596 inputs[0].ki.time = 0;
2597 inputs[1].type = INPUT_KEYBOARD;
2598 inputs[1].ki.wVk = hs->vkCode;
2599 inputs[1].ki.wScan = hs->vkCode;
2600 inputs[1].ki.dwFlags
2601 = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
2602 inputs[1].ki.time = 0;
2603 SendInput (2, inputs, sizeof (INPUT));
2604 }
2605 else if (focus != NULL)
2606 {
2607
2608 PostMessage (focus, WM_SYSKEYDOWN, hs->vkCode, 0);
2609 PostMessage (focus, WM_SYSKEYUP, hs->vkCode, 0);
2610 }
2611 }
2612 }
2613 if (kbdhook.winsdown == 0)
2614 {
2615
2616 kbdhook.suppress_lone = 0;
2617 kbdhook.winseen = 0;
2618 }
2619 if (!kbdhook.send_win_up)
2620 {
2621
2622
2623
2624 return 1;
2625 }
2626 kbdhook.send_win_up = 0;
2627 }
2628 }
2629 else if (kbdhook.winsdown > 0)
2630 {
2631
2632
2633
2634 if ((kbdhook.lwindown && kbdhook.lwin_hooked[hs->vkCode]) ||
2635 (kbdhook.rwindown && kbdhook.rwin_hooked[hs->vkCode]))
2636 {
2637
2638 kbdhook.suppress_lone = 1;
2639 }
2640 else if (!kbdhook.suppress_lone)
2641 {
2642
2643
2644 memset (inputs, 0, sizeof (inputs));
2645 inputs[0].type = INPUT_KEYBOARD;
2646 inputs[0].ki.wVk = kbdhook.lwindown ? VK_LWIN : VK_RWIN;
2647 inputs[0].ki.wScan = kbdhook.lwindown ? VK_LWIN : VK_RWIN;
2648 inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
2649 inputs[0].ki.time = 0;
2650 inputs[1].type = INPUT_KEYBOARD;
2651 inputs[1].ki.wVk = hs->vkCode;
2652 inputs[1].ki.wScan = hs->scanCode;
2653 inputs[1].ki.dwFlags =
2654 (hs->flags & LLKHF_EXTENDED) ? KEYEVENTF_EXTENDEDKEY : 0;
2655 inputs[1].ki.time = 0;
2656 SendInput (2, inputs, sizeof (INPUT));
2657
2658
2659
2660 kbdhook.suppress_lone = 1;
2661 kbdhook.send_win_up = 1;
2662
2663
2664 return 1;
2665 }
2666 }
2667
2668
2669 if ((w == WM_SYSKEYDOWN || w == WM_KEYDOWN)
2670 && kbdhook.alt_hooked[hs->vkCode]
2671 && focus != NULL
2672 && (GetAsyncKeyState (VK_MENU) & 0x8000))
2673 {
2674
2675
2676 if (console)
2677 {
2678 INPUT_RECORD rec;
2679 DWORD n;
2680 rec.EventType = KEY_EVENT;
2681 rec.Event.KeyEvent.bKeyDown = TRUE;
2682 rec.Event.KeyEvent.wVirtualKeyCode = hs->vkCode;
2683 rec.Event.KeyEvent.wVirtualScanCode = hs->scanCode;
2684 rec.Event.KeyEvent.uChar.UnicodeChar = 0;
2685 rec.Event.KeyEvent.dwControlKeyState =
2686 ((GetAsyncKeyState (VK_LMENU) & 0x8000) ? LEFT_ALT_PRESSED : 0)
2687 | ((GetAsyncKeyState (VK_RMENU) & 0x8000) ? RIGHT_ALT_PRESSED : 0)
2688 | ((GetAsyncKeyState (VK_LCONTROL) & 0x8000) ? LEFT_CTRL_PRESSED : 0)
2689 | ((GetAsyncKeyState (VK_RCONTROL) & 0x8000) ? RIGHT_CTRL_PRESSED : 0)
2690 | ((GetAsyncKeyState (VK_SHIFT) & 0x8000) ? SHIFT_PRESSED : 0)
2691 | ((hs->flags & LLKHF_EXTENDED) ? ENHANCED_KEY : 0);
2692 if (w32_console_unicode_input)
2693 WriteConsoleInputW (keyboard_handle, &rec, 1, &n);
2694 else
2695 WriteConsoleInputA (keyboard_handle, &rec, 1, &n);
2696 }
2697 else
2698 PostMessage (focus, w, hs->vkCode, 1 | (1<<29));
2699 return 1;
2700 }
2701
2702
2703 return CallNextHookEx (0, code, w, l);
2704 }
2705
2706
2707
2708 void
2709 setup_w32_kbdhook (void)
2710 {
2711 kbdhook.hook_count++;
2712
2713
2714
2715
2716
2717
2718 if (w32_kbdhook_active)
2719 {
2720 if (is_debugger_present && is_debugger_present ())
2721 return;
2722 }
2723
2724
2725
2726 if (kbdhook.hook_count == 1 && w32_kbdhook_active)
2727 {
2728
2729
2730
2731
2732
2733 GetConsoleWindow_Proc get_console = (GetConsoleWindow_Proc)
2734 get_proc_addr (GetModuleHandle ("kernel32.dll"), "GetConsoleWindow");
2735
2736 if (get_console != NULL)
2737 kbdhook.console = get_console ();
2738 else
2739 {
2740 GUID guid;
2741 wchar_t *oldTitle = malloc (1024 * sizeof(wchar_t));
2742 wchar_t newTitle[64];
2743 int i;
2744
2745 CoCreateGuid (&guid);
2746 if (oldTitle != NULL && StringFromGUID2 (&guid, newTitle, 64))
2747 {
2748 GetConsoleTitleW (oldTitle, 1024);
2749 SetConsoleTitleW (newTitle);
2750 for (i = 0; i < 25; i++)
2751 {
2752 Sleep (40);
2753 kbdhook.console = FindWindowW (NULL, newTitle);
2754 if (kbdhook.console != NULL)
2755 break;
2756 }
2757 SetConsoleTitleW (oldTitle);
2758 }
2759 free (oldTitle);
2760 }
2761
2762
2763 kbdhook.hook = SetWindowsHookEx (WH_KEYBOARD_LL, funhook,
2764 GetModuleHandle (NULL), 0);
2765 }
2766 }
2767
2768
2769 void
2770 remove_w32_kbdhook (void)
2771 {
2772 kbdhook.hook_count--;
2773 if (kbdhook.hook_count == 0 && w32_kbdhook_active)
2774 {
2775 UnhookWindowsHookEx (kbdhook.hook);
2776 kbdhook.hook = NULL;
2777 }
2778 }
2779 #endif
2780
2781
2782
2783 static void
2784 hook_w32_key (int hook, int modifier, int vkey)
2785 {
2786 char *tbl = NULL;
2787
2788 switch (modifier)
2789 {
2790 case VK_MENU:
2791 tbl = kbdhook.alt_hooked;
2792 break;
2793 case VK_LWIN:
2794 tbl = kbdhook.lwin_hooked;
2795 break;
2796 case VK_RWIN:
2797 tbl = kbdhook.rwin_hooked;
2798 break;
2799 }
2800
2801 if (tbl != NULL && vkey >= 0 && vkey <= 255)
2802 {
2803
2804 if (vkey == VK_ANY)
2805 memset (tbl, (char)hook, 256);
2806 else
2807 tbl[vkey] = (char)hook;
2808
2809 kbdhook.alt_hooked[VK_MENU] = 0;
2810 kbdhook.alt_hooked[VK_LMENU] = 0;
2811 kbdhook.alt_hooked[VK_RMENU] = 0;
2812 kbdhook.alt_hooked[VK_CONTROL] = 0;
2813 kbdhook.alt_hooked[VK_LCONTROL] = 0;
2814 kbdhook.alt_hooked[VK_RCONTROL] = 0;
2815 kbdhook.alt_hooked[VK_SHIFT] = 0;
2816 kbdhook.alt_hooked[VK_LSHIFT] = 0;
2817 kbdhook.alt_hooked[VK_RSHIFT] = 0;
2818 }
2819 }
2820
2821 #ifdef WINDOWSNT
2822
2823 int
2824 check_w32_winkey_state (int vkey)
2825 {
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840 switch (vkey)
2841 {
2842 case VK_LWIN:
2843 return kbdhook.lwindown;
2844 case VK_RWIN:
2845 return kbdhook.rwindown;
2846 }
2847 return 0;
2848 }
2849 #endif
2850
2851
2852
2853
2854
2855 static void
2856 reset_w32_kbdhook_state (void)
2857 {
2858 kbdhook.lwindown = 0;
2859 kbdhook.rwindown = 0;
2860 kbdhook.winsdown = 0;
2861 kbdhook.send_win_up = 0;
2862 kbdhook.suppress_lone = 0;
2863 kbdhook.winseen = 0;
2864 }
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877 #define EMACS_LCONTROL 0
2878 #define EMACS_RCONTROL 1
2879 #define EMACS_LMENU 2
2880 #define EMACS_RMENU 3
2881
2882 static int modifiers[4];
2883 static int modifiers_recorded;
2884 static int modifier_key_support_tested;
2885
2886 static void
2887 test_modifier_support (unsigned int wparam)
2888 {
2889 unsigned int l, r;
2890
2891 if (wparam != VK_CONTROL && wparam != VK_MENU)
2892 return;
2893 if (wparam == VK_CONTROL)
2894 {
2895 l = VK_LCONTROL;
2896 r = VK_RCONTROL;
2897 }
2898 else
2899 {
2900 l = VK_LMENU;
2901 r = VK_RMENU;
2902 }
2903 if (!(GetKeyState (l) & 0x8000) && !(GetKeyState (r) & 0x8000))
2904 modifiers_recorded = 1;
2905 else
2906 modifiers_recorded = 0;
2907 modifier_key_support_tested = 1;
2908 }
2909
2910 static void
2911 record_keydown (unsigned int wparam, unsigned int lparam)
2912 {
2913 int i;
2914
2915 if (!modifier_key_support_tested)
2916 test_modifier_support (wparam);
2917
2918 if ((wparam != VK_CONTROL && wparam != VK_MENU) || !modifiers_recorded)
2919 return;
2920
2921 if (wparam == VK_CONTROL)
2922 i = (lparam & 0x1000000) ? EMACS_RCONTROL : EMACS_LCONTROL;
2923 else
2924 i = (lparam & 0x1000000) ? EMACS_RMENU : EMACS_LMENU;
2925
2926 modifiers[i] = 1;
2927 }
2928
2929 static void
2930 record_keyup (unsigned int wparam, unsigned int lparam)
2931 {
2932 int i;
2933
2934 if ((wparam != VK_CONTROL && wparam != VK_MENU) || !modifiers_recorded)
2935 return;
2936
2937 if (wparam == VK_CONTROL)
2938 i = (lparam & 0x1000000) ? EMACS_RCONTROL : EMACS_LCONTROL;
2939 else
2940 i = (lparam & 0x1000000) ? EMACS_RMENU : EMACS_LMENU;
2941
2942 modifiers[i] = 0;
2943 }
2944
2945
2946
2947
2948 static void
2949 reset_modifiers (void)
2950 {
2951 SHORT ctrl, alt;
2952
2953 if (GetFocus () == NULL)
2954
2955 return;
2956
2957 ctrl = GetAsyncKeyState (VK_CONTROL);
2958 alt = GetAsyncKeyState (VK_MENU);
2959
2960 if (!(ctrl & 0x08000))
2961
2962 modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
2963
2964 if (!(alt & 0x08000))
2965
2966 modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
2967
2968
2969
2970
2971 {
2972 BYTE keystate[256];
2973
2974 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
2975
2976 memset (keystate, 0, sizeof (keystate));
2977 GetKeyboardState (keystate);
2978 keystate[VK_SHIFT] = CURRENT_STATE (VK_SHIFT);
2979 keystate[VK_CONTROL] = CURRENT_STATE (VK_CONTROL);
2980 keystate[VK_LCONTROL] = CURRENT_STATE (VK_LCONTROL);
2981 keystate[VK_RCONTROL] = CURRENT_STATE (VK_RCONTROL);
2982 keystate[VK_MENU] = CURRENT_STATE (VK_MENU);
2983 keystate[VK_LMENU] = CURRENT_STATE (VK_LMENU);
2984 keystate[VK_RMENU] = CURRENT_STATE (VK_RMENU);
2985 keystate[VK_LWIN] = CURRENT_STATE (VK_LWIN);
2986 keystate[VK_RWIN] = CURRENT_STATE (VK_RWIN);
2987 keystate[VK_APPS] = CURRENT_STATE (VK_APPS);
2988 SetKeyboardState (keystate);
2989 }
2990 }
2991
2992
2993
2994
2995
2996 static void
2997 sync_modifiers (void)
2998 {
2999 if (!modifiers_recorded)
3000 return;
3001
3002 if (!(GetKeyState (VK_CONTROL) & 0x8000))
3003 modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
3004
3005 if (!(GetKeyState (VK_MENU) & 0x8000))
3006 modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
3007 }
3008
3009 static int
3010 modifier_set (int vkey)
3011 {
3012
3013
3014
3015
3016
3017
3018 if (vkey == VK_CAPITAL)
3019 {
3020 if (NILP (Vw32_enable_caps_lock))
3021 return 0;
3022 else
3023 return (GetKeyState (vkey) & 0x1);
3024 }
3025 if (vkey == VK_SCROLL)
3026 {
3027 if (NILP (Vw32_scroll_lock_modifier)
3028
3029
3030 || !( EQ (Vw32_scroll_lock_modifier, Qhyper)
3031 || EQ (Vw32_scroll_lock_modifier, Qsuper)
3032 || EQ (Vw32_scroll_lock_modifier, Qmeta)
3033 || EQ (Vw32_scroll_lock_modifier, Qalt)
3034 || EQ (Vw32_scroll_lock_modifier, Qcontrol)
3035 || EQ (Vw32_scroll_lock_modifier, Qshift)))
3036 return 0;
3037 else
3038 return (GetKeyState (vkey) & 0x1);
3039 }
3040 #ifdef WINDOWSNT
3041 if (w32_kbdhook_active && (vkey == VK_LWIN || vkey == VK_RWIN))
3042 return check_w32_winkey_state (vkey);
3043 #endif
3044
3045 if (!modifiers_recorded)
3046 return (GetKeyState (vkey) & 0x8000);
3047
3048 switch (vkey)
3049 {
3050 case VK_LCONTROL:
3051 return modifiers[EMACS_LCONTROL];
3052 case VK_RCONTROL:
3053 return modifiers[EMACS_RCONTROL];
3054 case VK_LMENU:
3055 return modifiers[EMACS_LMENU];
3056 case VK_RMENU:
3057 return modifiers[EMACS_RMENU];
3058 }
3059 return (GetKeyState (vkey) & 0x8000);
3060 }
3061
3062
3063
3064 unsigned int w32_key_to_modifier (int);
3065
3066 unsigned int
3067 w32_key_to_modifier (int key)
3068 {
3069 Lisp_Object key_mapping;
3070
3071 switch (key)
3072 {
3073 case VK_LWIN:
3074 key_mapping = Vw32_lwindow_modifier;
3075 break;
3076 case VK_RWIN:
3077 key_mapping = Vw32_rwindow_modifier;
3078 break;
3079 case VK_APPS:
3080 key_mapping = Vw32_apps_modifier;
3081 break;
3082 case VK_SCROLL:
3083 key_mapping = Vw32_scroll_lock_modifier;
3084 break;
3085 default:
3086 key_mapping = Qnil;
3087 }
3088
3089
3090
3091
3092
3093
3094
3095 if (EQ (key_mapping, Qhyper))
3096 return hyper_modifier;
3097 if (EQ (key_mapping, Qsuper))
3098 return super_modifier;
3099 if (EQ (key_mapping, Qmeta))
3100 return meta_modifier;
3101 if (EQ (key_mapping, Qalt))
3102 return alt_modifier;
3103 if (EQ (key_mapping, Qctrl))
3104 return ctrl_modifier;
3105 if (EQ (key_mapping, Qcontrol))
3106 return ctrl_modifier;
3107 if (EQ (key_mapping, Qshift))
3108 return shift_modifier;
3109
3110
3111 return 0;
3112 }
3113
3114 static unsigned int
3115 w32_get_modifiers (void)
3116 {
3117 return ((modifier_set (VK_SHIFT) ? shift_modifier : 0) |
3118 (modifier_set (VK_CONTROL) ? ctrl_modifier : 0) |
3119 (modifier_set (VK_LWIN) ? w32_key_to_modifier (VK_LWIN) : 0) |
3120 (modifier_set (VK_RWIN) ? w32_key_to_modifier (VK_RWIN) : 0) |
3121 (modifier_set (VK_APPS) ? w32_key_to_modifier (VK_APPS) : 0) |
3122 (modifier_set (VK_SCROLL) ? w32_key_to_modifier (VK_SCROLL) : 0) |
3123 (modifier_set (VK_MENU) ?
3124 ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0));
3125 }
3126
3127
3128
3129
3130
3131 static int
3132 w32_construct_console_modifiers (void)
3133 {
3134 int mods;
3135
3136 mods = 0;
3137 mods |= (modifier_set (VK_SHIFT)) ? SHIFT_PRESSED : 0;
3138 mods |= (modifier_set (VK_CAPITAL)) ? CAPSLOCK_ON : 0;
3139 mods |= (modifier_set (VK_SCROLL)) ? SCROLLLOCK_ON : 0;
3140 mods |= (modifier_set (VK_NUMLOCK)) ? NUMLOCK_ON : 0;
3141 mods |= (modifier_set (VK_LCONTROL)) ? LEFT_CTRL_PRESSED : 0;
3142 mods |= (modifier_set (VK_RCONTROL)) ? RIGHT_CTRL_PRESSED : 0;
3143 mods |= (modifier_set (VK_LMENU)) ? LEFT_ALT_PRESSED : 0;
3144 mods |= (modifier_set (VK_RMENU)) ? RIGHT_ALT_PRESSED : 0;
3145 mods |= (modifier_set (VK_LWIN)) ? LEFT_WIN_PRESSED : 0;
3146 mods |= (modifier_set (VK_RWIN)) ? RIGHT_WIN_PRESSED : 0;
3147 mods |= (modifier_set (VK_APPS)) ? APPS_PRESSED : 0;
3148
3149 return mods;
3150 }
3151
3152 static int
3153 w32_get_key_modifiers (unsigned int wparam, unsigned int lparam)
3154 {
3155 int mods;
3156
3157
3158 mods = w32_kbd_mods_to_emacs (w32_construct_console_modifiers (), wparam);
3159
3160 return mods;
3161 }
3162
3163 unsigned int map_keypad_keys (unsigned int, unsigned int);
3164
3165 unsigned int
3166 map_keypad_keys (unsigned int virt_key, unsigned int extended)
3167 {
3168 if (virt_key < VK_CLEAR || virt_key > VK_DELETE)
3169 return virt_key;
3170
3171 if (virt_key == VK_RETURN)
3172 return (extended ? VK_NUMPAD_ENTER : VK_RETURN);
3173
3174 if (virt_key >= VK_PRIOR && virt_key <= VK_DOWN)
3175 return (!extended ? (VK_NUMPAD_PRIOR + (virt_key - VK_PRIOR)) : virt_key);
3176
3177 if (virt_key == VK_INSERT || virt_key == VK_DELETE)
3178 return (!extended ? (VK_NUMPAD_INSERT + (virt_key - VK_INSERT)) : virt_key);
3179
3180 if (virt_key == VK_CLEAR)
3181 return (!extended ? VK_NUMPAD_CLEAR : virt_key);
3182
3183 return virt_key;
3184 }
3185
3186
3187
3188
3189
3190
3191
3192 static Lisp_Object w32_grabbed_keys;
3193
3194 #define HOTKEY(vk, mods) make_fixnum (((vk) & 255) | ((mods) << 8))
3195 #define HOTKEY_ID(k) (XFIXNAT (k) & 0xbfff)
3196 #define HOTKEY_VK_CODE(k) (XFIXNAT (k) & 255)
3197 #define HOTKEY_MODIFIERS(k) (XFIXNAT (k) >> 8)
3198
3199 #define RAW_HOTKEY_ID(k) ((k) & 0xbfff)
3200 #define RAW_HOTKEY_VK_CODE(k) ((k) & 255)
3201 #define RAW_HOTKEY_MODIFIERS(k) ((k) >> 8)
3202
3203
3204
3205
3206
3207 static void
3208 register_hot_keys (HWND hwnd)
3209 {
3210 Lisp_Object keylist;
3211
3212
3213 for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
3214 {
3215 Lisp_Object key = XCAR (keylist);
3216
3217
3218 if (!FIXNUMP (key))
3219 continue;
3220
3221 RegisterHotKey (hwnd, HOTKEY_ID (key),
3222 HOTKEY_MODIFIERS (key), HOTKEY_VK_CODE (key));
3223 }
3224 }
3225
3226 static void
3227 unregister_hot_keys (HWND hwnd)
3228 {
3229 Lisp_Object keylist;
3230
3231 for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
3232 {
3233 Lisp_Object key = XCAR (keylist);
3234
3235 if (!FIXNUMP (key))
3236 continue;
3237
3238 UnregisterHotKey (hwnd, HOTKEY_ID (key));
3239 }
3240 }
3241
3242 #if EMACSDEBUG
3243 const char*
3244 w32_name_of_message (UINT msg)
3245 {
3246 unsigned i;
3247 static char buf[64];
3248 static const struct {
3249 UINT msg;
3250 const char* name;
3251 } msgnames[] = {
3252 #define M(msg) { msg, # msg }
3253 M (WM_PAINT),
3254 M (WM_TIMER),
3255 M (WM_USER),
3256 M (WM_MOUSEMOVE),
3257 M (WM_LBUTTONUP),
3258 M (WM_KEYDOWN),
3259 M (WM_EMACS_KILL),
3260 M (WM_EMACS_CREATEWINDOW),
3261 M (WM_EMACS_DONE),
3262 M (WM_EMACS_CREATEVSCROLLBAR),
3263 M (WM_EMACS_CREATEHSCROLLBAR),
3264 M (WM_EMACS_SHOWWINDOW),
3265 M (WM_EMACS_SETWINDOWPOS),
3266 M (WM_EMACS_DESTROYWINDOW),
3267 M (WM_EMACS_TRACKPOPUPMENU),
3268 M (WM_EMACS_SETFOCUS),
3269 M (WM_EMACS_SETFOREGROUND),
3270 M (WM_EMACS_SETLOCALE),
3271 M (WM_EMACS_SETKEYBOARDLAYOUT),
3272 M (WM_EMACS_REGISTER_HOT_KEY),
3273 M (WM_EMACS_UNREGISTER_HOT_KEY),
3274 M (WM_EMACS_TOGGLE_LOCK_KEY),
3275 M (WM_EMACS_TRACK_CARET),
3276 M (WM_EMACS_DESTROY_CARET),
3277 M (WM_EMACS_SHOW_CARET),
3278 M (WM_EMACS_HIDE_CARET),
3279 M (WM_EMACS_SETCURSOR),
3280 M (WM_EMACS_SHOWCURSOR),
3281 M (WM_EMACS_PAINT),
3282 M (WM_EMACS_IME_STATUS),
3283 M (WM_CHAR),
3284 #undef M
3285 { 0, 0 }
3286 };
3287
3288 for (i = 0; msgnames[i].name; ++i)
3289 if (msgnames[i].msg == msg)
3290 return msgnames[i].name;
3291
3292 sprintf (buf, "message 0x%04x", (unsigned)msg);
3293 return buf;
3294 }
3295 #endif
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327 static void
3328 w32_msg_pump (deferred_msg * msg_buf)
3329 {
3330 MSG msg;
3331 WPARAM result;
3332 HWND focus_window;
3333
3334 msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
3335
3336 while ((w32_unicode_gui ? GetMessageW : GetMessageA) (&msg, NULL, 0, 0))
3337 {
3338
3339
3340
3341
3342 if (msg.hwnd == NULL)
3343 {
3344 switch (msg.message)
3345 {
3346 case WM_NULL:
3347
3348 break;
3349 case WM_EMACS_CREATEWINDOW:
3350
3351
3352
3353
3354
3355
3356 CoInitialize (NULL);
3357 w32_createwindow ((struct frame *) msg.wParam,
3358 (int *) msg.lParam);
3359 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
3360 emacs_abort ();
3361 break;
3362 case WM_EMACS_SETLOCALE:
3363 SetThreadLocale (msg.wParam);
3364
3365 break;
3366 case WM_EMACS_SETKEYBOARDLAYOUT:
3367 result = (WPARAM) ActivateKeyboardLayout ((HKL) msg.wParam, 0);
3368 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
3369 result, 0))
3370 emacs_abort ();
3371 break;
3372 case WM_EMACS_REGISTER_HOT_KEY:
3373 focus_window = GetFocus ();
3374 if (focus_window != NULL)
3375 RegisterHotKey (focus_window,
3376 RAW_HOTKEY_ID (msg.wParam),
3377 RAW_HOTKEY_MODIFIERS (msg.wParam),
3378 RAW_HOTKEY_VK_CODE (msg.wParam));
3379
3380 break;
3381 case WM_EMACS_UNREGISTER_HOT_KEY:
3382 focus_window = GetFocus ();
3383 if (focus_window != NULL)
3384 UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam));
3385
3386
3387
3388
3389 XSETCAR (make_lisp_ptr ((void *)msg.lParam, Lisp_Cons), Qnil);
3390 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
3391 emacs_abort ();
3392 break;
3393 case WM_EMACS_TOGGLE_LOCK_KEY:
3394 {
3395 int vk_code = (int) msg.wParam;
3396 int cur_state = (GetKeyState (vk_code) & 1);
3397 int new_state = msg.lParam;
3398
3399 if (new_state == -1
3400 || ((new_state & 1) != cur_state))
3401 {
3402 one_w32_display_info.faked_key = vk_code;
3403
3404 keybd_event ((BYTE) vk_code,
3405 (BYTE) MapVirtualKey (vk_code, 0),
3406 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3407 keybd_event ((BYTE) vk_code,
3408 (BYTE) MapVirtualKey (vk_code, 0),
3409 KEYEVENTF_EXTENDEDKEY | 0, 0);
3410 keybd_event ((BYTE) vk_code,
3411 (BYTE) MapVirtualKey (vk_code, 0),
3412 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3413 cur_state = !cur_state;
3414 }
3415 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
3416 cur_state, 0))
3417 emacs_abort ();
3418 }
3419 break;
3420 case WM_EMACS_IME_STATUS:
3421 {
3422 focus_window = GetFocus ();
3423 if (!set_ime_open_status_fn || !focus_window)
3424 break;
3425
3426 HIMC context = get_ime_context_fn (focus_window);
3427 if (!context)
3428 break;
3429
3430 set_ime_open_status_fn (context, msg.wParam != 0);
3431 release_ime_context_fn (focus_window, context);
3432 break;
3433 }
3434
3435 #ifdef MSG_DEBUG
3436
3437
3438 default:
3439 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
3440 #endif
3441 }
3442 }
3443 else
3444 {
3445 if (w32_unicode_gui)
3446 DispatchMessageW (&msg);
3447 else
3448 DispatchMessageA (&msg);
3449 }
3450
3451
3452 if (msg_buf->completed)
3453 break;
3454 }
3455 }
3456
3457 deferred_msg * deferred_msg_head;
3458
3459 static deferred_msg *
3460 find_deferred_msg (HWND hwnd, UINT msg)
3461 {
3462 deferred_msg * item;
3463
3464
3465
3466
3467
3468 for (item = deferred_msg_head; item != NULL; item = item->next)
3469 if (item->w32msg.msg.hwnd == hwnd
3470 && item->w32msg.msg.message == msg)
3471 break;
3472
3473
3474
3475 return item;
3476 }
3477
3478 static LRESULT
3479 send_deferred_msg (deferred_msg * msg_buf,
3480 HWND hwnd,
3481 UINT msg,
3482 WPARAM wParam,
3483 LPARAM lParam)
3484 {
3485
3486 if (GetCurrentThreadId () != dwWindowsThreadId)
3487 emacs_abort ();
3488
3489
3490 if (find_deferred_msg (hwnd, msg) != NULL)
3491 emacs_abort ();
3492
3493
3494
3495
3496
3497
3498
3499
3500 msg_buf->completed = 0;
3501 msg_buf->next = deferred_msg_head;
3502 deferred_msg_head = msg_buf;
3503 my_post_msg (&msg_buf->w32msg, hwnd, msg, wParam, lParam);
3504
3505
3506
3507
3508
3509 w32_msg_pump (msg_buf);
3510
3511 deferred_msg_head = msg_buf->next;
3512
3513 return msg_buf->result;
3514 }
3515
3516 void
3517 complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result)
3518 {
3519 deferred_msg * msg_buf = find_deferred_msg (hwnd, msg);
3520
3521 if (msg_buf == NULL)
3522
3523 return;
3524
3525 msg_buf->result = result;
3526 msg_buf->completed = 1;
3527
3528
3529 PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
3530 }
3531
3532 static void
3533 cancel_all_deferred_msgs (void)
3534 {
3535 deferred_msg * item;
3536
3537
3538
3539
3540
3541 for (item = deferred_msg_head; item != NULL; item = item->next)
3542 {
3543 item->result = 0;
3544 item->completed = 1;
3545 }
3546
3547
3548
3549
3550 PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
3551 }
3552
3553 DWORD WINAPI w32_msg_worker (void *);
3554
3555 DWORD WINAPI
3556 w32_msg_worker (void *arg)
3557 {
3558 MSG msg;
3559 deferred_msg dummy_buf;
3560
3561
3562
3563 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
3564
3565 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
3566 emacs_abort ();
3567
3568 memset (&dummy_buf, 0, sizeof (dummy_buf));
3569 dummy_buf.w32msg.msg.hwnd = NULL;
3570 dummy_buf.w32msg.msg.message = WM_NULL;
3571
3572
3573
3574 w32_msg_pump (&dummy_buf);
3575
3576 return 0;
3577 }
3578
3579 static void
3580 signal_user_input (void)
3581 {
3582
3583 if (!NILP (Vthrow_on_input))
3584 {
3585 Vquit_flag = Vthrow_on_input;
3586
3587
3588
3589 }
3590 }
3591
3592
3593 static void
3594 post_character_message (HWND hwnd, UINT msg,
3595 WPARAM wParam, LPARAM lParam,
3596 DWORD modifiers)
3597 {
3598 W32Msg wmsg;
3599
3600 wmsg.dwModifiers = modifiers;
3601
3602
3603
3604
3605
3606
3607
3608 {
3609 int c = wParam;
3610 if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier)
3611 c = make_ctrl_char (c) & 0377;
3612 if (c == quit_char
3613 || (wmsg.dwModifiers == 0
3614 && w32_quit_key && wParam == w32_quit_key))
3615 {
3616 Vquit_flag = Qt;
3617
3618
3619
3620 msg = WM_NULL;
3621
3622
3623 signal_quit ();
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644 cancel_all_deferred_msgs ();
3645 }
3646 else
3647 signal_user_input ();
3648 }
3649
3650 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3651 }
3652
3653 static int
3654 get_wm_chars (HWND aWnd, int *buf, int buflen, int ignore_ctrl, int ctrl,
3655 int *ctrl_cnt, int *is_dead, int vk, int exp)
3656 {
3657 MSG msg;
3658
3659 int i = buflen, doubled = 0, code_unit;
3660
3661 if (ctrl_cnt)
3662 *ctrl_cnt = 0;
3663 if (is_dead)
3664 *is_dead = -1;
3665 eassert (w32_unicode_gui);
3666 while (buflen
3667
3668 && PeekMessageW (&msg, aWnd, WM_KEYFIRST, WM_KEYLAST,
3669 PM_NOREMOVE | PM_NOYIELD)
3670 && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR
3671 || msg.message == WM_DEADCHAR || msg.message == WM_SYSDEADCHAR
3672 || msg.message == WM_UNICHAR))
3673 {
3674
3675
3676 int dead;
3677
3678 GetMessageW (&msg, aWnd, msg.message, msg.message);
3679 dead = (msg.message == WM_DEADCHAR || msg.message == WM_SYSDEADCHAR);
3680 if (is_dead)
3681 *is_dead = (dead ? msg.wParam : -1);
3682 if (dead)
3683 continue;
3684 code_unit = msg.wParam;
3685 if (doubled)
3686 {
3687
3688 if (msg.message == WM_UNICHAR
3689 || code_unit < 0xDC00 || code_unit > 0xDFFF)
3690 {
3691
3692 *buf++ = doubled;
3693 if (!--buflen)
3694 return i;
3695 }
3696 else
3697 code_unit = (doubled << 10) + code_unit - 0x35FDC00;
3698 doubled = 0;
3699 }
3700 else if (code_unit >= 0xD800 && code_unit <= 0xDBFF)
3701 {
3702
3703 doubled = code_unit;
3704 continue;
3705 }
3706
3707
3708
3709
3710
3711
3712
3713 if (ignore_ctrl
3714 && (code_unit < 0x20 || code_unit == 0x7f
3715 || (code_unit == 0x20 && ctrl)))
3716 {
3717
3718
3719 if (ctrl_cnt)
3720 (*ctrl_cnt)++;
3721 continue;
3722 }
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733 if (code_unit < 0x7f
3734 && ((vk >= VK_NUMPAD0 && vk <= VK_DIVIDE)
3735 || (exp && ((vk >= VK_PRIOR && vk <= VK_DOWN) ||
3736 vk == VK_INSERT || vk == VK_DELETE || vk == VK_CLEAR)))
3737 && strchr ("0123456789/*-+.,", code_unit))
3738 continue;
3739 *buf++ = code_unit;
3740 buflen--;
3741 }
3742 return i - buflen;
3743 }
3744
3745 #ifdef DBG_WM_CHARS
3746 # define FPRINTF_WM_CHARS(ARG) fprintf ARG
3747 #else
3748 # define FPRINTF_WM_CHARS(ARG) (void)0
3749 #endif
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762 static int after_deadkey = -1;
3763
3764 static int
3765 deliver_wm_chars (int do_translate, HWND hwnd, UINT msg, UINT wParam,
3766 UINT lParam, int legacy_alt_meta)
3767 {
3768
3769
3770
3771
3772 int ctrl_cnt, buf[1024], count, is_dead, after_dead = (after_deadkey > 0);
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788 if (do_translate)
3789 {
3790 MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
3791
3792 windows_msg.time = GetMessageTime ();
3793 TranslateMessage (&windows_msg);
3794 }
3795 count = get_wm_chars (hwnd, buf, sizeof (buf)/sizeof (*buf), 1,
3796
3797
3798 modifier_set (VK_LCONTROL)
3799 || modifier_set (VK_RCONTROL)
3800 || modifier_set (VK_CONTROL),
3801 &ctrl_cnt, &is_dead, wParam,
3802 (lParam & 0x1000000L) != 0);
3803 if (count)
3804 {
3805 W32Msg wmsg;
3806 DWORD console_modifiers = w32_construct_console_modifiers ();
3807 int *b = buf, strip_ExtraMods = 1, hairy = 0;
3808 const char *type_CtrlAlt = NULL;
3809
3810
3811
3812
3813
3814 after_deadkey = -1;
3815
3816
3817
3818 wmsg.dwModifiers = w32_kbd_mods_to_emacs (console_modifiers, wParam);
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929 if (!after_dead && count == 1 && *b < 0x10000)
3930 {
3931 if (console_modifiers & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
3932 && console_modifiers & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
3933 {
3934 type_CtrlAlt = "bB";
3935 if ((console_modifiers & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
3936 == (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
3937
3938
3939 type_CtrlAlt = "dD";
3940 else if ((console_modifiers
3941 & (LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED))
3942 == (LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED))
3943 type_CtrlAlt = "lL";
3944 else if (!NILP (Vw32_recognize_altgr)
3945 && ((console_modifiers
3946 & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED)))
3947 == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
3948 type_CtrlAlt = "gG";
3949 }
3950 else if (wmsg.dwModifiers & (alt_modifier | meta_modifier)
3951 || ((console_modifiers
3952 & (LEFT_WIN_PRESSED | RIGHT_WIN_PRESSED
3953 | APPS_PRESSED | SCROLLLOCK_ON))))
3954 {
3955
3956 type_CtrlAlt = "aA";
3957 }
3958 if (type_CtrlAlt)
3959 {
3960
3961 SHORT r = VkKeyScanW (*b), bitmap = 0x1FF;
3962
3963 FPRINTF_WM_CHARS((stderr, "VkKeyScanW %#06x %#04x\n", (int)r,
3964 wParam));
3965 if ((r & 0xFF) == wParam)
3966 bitmap = r>>8;
3967 else
3968 {
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997 if (*b < 0x80
3998 && (wmsg.dwModifiers
3999 & (alt_modifier | meta_modifier
4000 | super_modifier | hyper_modifier)))
4001 return 0;
4002 }
4003 if (*type_CtrlAlt == 'a')
4004 {
4005 if ((bitmap & ~1) == 0)
4006 {
4007
4008
4009
4010
4011
4012 if (legacy_alt_meta
4013 && *b > 0x7f && ('A' <= wParam && wParam <= 'Z'))
4014
4015
4016
4017 return 0;
4018 }
4019 else
4020 hairy = 1;
4021 }
4022
4023
4024 else if ((bitmap & ~1) != 6)
4025 {
4026
4027
4028
4029
4030
4031
4032 hairy = 1;
4033 }
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058 #define S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD "aldb"
4059 #define S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS ""
4060 if (strchr (S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD,
4061 type_CtrlAlt[hairy]))
4062 return 0;
4063
4064
4065 if (strchr (S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS,
4066 type_CtrlAlt[hairy]))
4067 strip_ExtraMods = 0;
4068 }
4069 }
4070 if (strip_ExtraMods)
4071 wmsg.dwModifiers = wmsg.dwModifiers & shift_modifier;
4072
4073 signal_user_input ();
4074 while (count--)
4075 {
4076 FPRINTF_WM_CHARS((stderr, "unichar %#06x\n", *b));
4077 my_post_msg (&wmsg, hwnd, WM_UNICHAR, *b++, lParam);
4078 }
4079 if (!ctrl_cnt)
4080 return 1;
4081 else
4082 FPRINTF_WM_CHARS((stderr, "extra ctrl char\n"));
4083 return -1;
4084 }
4085 else if (is_dead >= 0)
4086 {
4087 FPRINTF_WM_CHARS((stderr, "dead %#06x\n", is_dead));
4088 after_deadkey = is_dead;
4089 return 1;
4090 }
4091 return 0;
4092 }
4093
4094
4095
4096 static LRESULT CALLBACK
4097 w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
4098 {
4099 struct frame *f;
4100 struct w32_display_info *dpyinfo = &one_w32_display_info;
4101 W32Msg wmsg;
4102 int windows_translate;
4103 int key;
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121 switch (msg)
4122 {
4123 case WM_ERASEBKGND:
4124 f = w32_window_to_frame (dpyinfo, hwnd);
4125
4126 enter_crit ();
4127 if (f && (w32_disable_double_buffering
4128 || !FRAME_OUTPUT_DATA (f)->paint_buffer))
4129 {
4130 HDC hdc = get_frame_dc (f);
4131 GetUpdateRect (hwnd, &wmsg.rect, FALSE);
4132 w32_clear_rect (f, hdc, &wmsg.rect);
4133 release_frame_dc (f, hdc);
4134
4135 #if defined (W32_DEBUG_DISPLAY)
4136 DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
4137 f,
4138 wmsg.rect.left, wmsg.rect.top,
4139 wmsg.rect.right, wmsg.rect.bottom));
4140 #endif
4141 }
4142 leave_crit ();
4143 return 1;
4144 case WM_PALETTECHANGED:
4145
4146 if ((HWND)wParam != hwnd)
4147 {
4148 f = w32_window_to_frame (dpyinfo, hwnd);
4149 if (f)
4150
4151
4152 release_frame_dc (f, get_frame_dc (f));
4153 }
4154 return 0;
4155 case WM_PAINT:
4156 {
4157 PAINTSTRUCT paintStruct;
4158 RECT update_rect;
4159 memset (&update_rect, 0, sizeof (update_rect));
4160
4161 f = w32_window_to_frame (dpyinfo, hwnd);
4162 if (f == 0)
4163 {
4164 DebPrint (("WM_PAINT received for unknown window %p\n", hwnd));
4165 return 0;
4166 }
4167
4168
4169
4170
4171 if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
4172 {
4173 enter_crit ();
4174 BeginPaint (hwnd, &paintStruct);
4175
4176
4177
4178
4179 UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint));
4180
4181 #if defined (W32_DEBUG_DISPLAY)
4182 DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
4183 f,
4184 wmsg.rect.left, wmsg.rect.top,
4185 wmsg.rect.right, wmsg.rect.bottom));
4186 DebPrint ((" [update region is %d,%d-%d,%d]\n",
4187 update_rect.left, update_rect.top,
4188 update_rect.right, update_rect.bottom));
4189 #endif
4190
4191
4192
4193 if (w32_selection_dialog_open
4194 && !w32_disable_double_buffering
4195 && FRAME_OUTPUT_DATA (f)->paint_dc)
4196 BitBlt (FRAME_OUTPUT_DATA (f)->paint_buffer_handle,
4197 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
4198 FRAME_OUTPUT_DATA (f)->paint_dc, 0, 0, SRCCOPY);
4199
4200 EndPaint (hwnd, &paintStruct);
4201 leave_crit ();
4202
4203
4204
4205
4206
4207
4208 my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
4209
4210 return 0;
4211 }
4212
4213
4214
4215 GetClientRect (hwnd, &wmsg.rect);
4216 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4217 return 0;
4218 }
4219
4220 case WM_INPUTLANGCHANGE:
4221
4222 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4223
4224
4225
4226
4227
4228
4229 after_deadkey = -1;
4230
4231
4232
4233
4234
4235 {
4236 int i;
4237 BYTE keystate[256];
4238
4239 GetKeyboardState (keystate);
4240 for (i = 0; i < 256; i++)
4241 if (1
4242 && i != VK_SHIFT
4243 && i != VK_LSHIFT
4244 && i != VK_RSHIFT
4245 && i != VK_CAPITAL
4246 && i != VK_NUMLOCK
4247 && i != VK_SCROLL
4248 && i != VK_CONTROL
4249 && i != VK_LCONTROL
4250 && i != VK_RCONTROL
4251 && i != VK_MENU
4252 && i != VK_LMENU
4253 && i != VK_RMENU
4254 && i != VK_LWIN
4255 && i != VK_RWIN)
4256 keystate[i] = 0;
4257 SetKeyboardState (keystate);
4258 }
4259 goto dflt;
4260
4261 case WM_HOTKEY:
4262
4263 PostMessage (hwnd, WM_KEYDOWN, HIWORD (lParam), 0);
4264 return (0);
4265
4266 case WM_KEYUP:
4267 case WM_SYSKEYUP:
4268 record_keyup (wParam, lParam);
4269 goto dflt;
4270
4271 case WM_KEYDOWN:
4272 case WM_SYSKEYDOWN:
4273
4274 if (dpyinfo->faked_key == wParam)
4275 {
4276 dpyinfo->faked_key = 0;
4277
4278
4279
4280
4281 if (wParam < 256 && lispy_function_keys[wParam])
4282 {
4283 windows_translate = 1;
4284 goto translate;
4285 }
4286 return 0;
4287 }
4288
4289
4290 sync_modifiers ();
4291 record_keydown (wParam, lParam);
4292 if (w32_use_fallback_wm_chars_method)
4293 wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
4294
4295 windows_translate = 0;
4296
4297 switch (wParam)
4298 {
4299 case VK_LWIN:
4300 if (!w32_kbdhook_active && NILP (Vw32_pass_lwindow_to_system))
4301 {
4302
4303
4304
4305 if (GetAsyncKeyState (wParam) & 1)
4306 {
4307 if (FIXNUMP (Vw32_phantom_key_code))
4308 key = XUFIXNUM (Vw32_phantom_key_code) & 255;
4309 else
4310 key = VK_SPACE;
4311 dpyinfo->faked_key = key;
4312 keybd_event (key, (BYTE) MapVirtualKey (key, 0), 0, 0);
4313 }
4314 }
4315 if (!NILP (Vw32_lwindow_modifier))
4316 return 0;
4317 break;
4318 case VK_RWIN:
4319 if (!w32_kbdhook_active && NILP (Vw32_pass_rwindow_to_system))
4320 {
4321 if (GetAsyncKeyState (wParam) & 1)
4322 {
4323 if (FIXNUMP (Vw32_phantom_key_code))
4324 key = XUFIXNUM (Vw32_phantom_key_code) & 255;
4325 else
4326 key = VK_SPACE;
4327 dpyinfo->faked_key = key;
4328 keybd_event (key, (BYTE) MapVirtualKey (key, 0), 0, 0);
4329 }
4330 }
4331 if (!NILP (Vw32_rwindow_modifier))
4332 return 0;
4333 break;
4334 case VK_APPS:
4335 if (!NILP (Vw32_apps_modifier))
4336 return 0;
4337 break;
4338 case VK_MENU:
4339 if (NILP (Vw32_pass_alt_to_system))
4340
4341
4342 return 0;
4343 windows_translate = 1;
4344 break;
4345 case VK_CAPITAL:
4346
4347 if (NILP (Vw32_enable_caps_lock))
4348 goto disable_lock_key;
4349 windows_translate = 1;
4350 break;
4351 case VK_NUMLOCK:
4352
4353 if (NILP (Vw32_enable_num_lock))
4354 goto disable_lock_key;
4355 windows_translate = 1;
4356 break;
4357 case VK_SCROLL:
4358
4359 if (NILP (Vw32_scroll_lock_modifier))
4360 goto disable_lock_key;
4361 windows_translate = 1;
4362 break;
4363 disable_lock_key:
4364
4365
4366
4367
4368 dpyinfo->faked_key = wParam;
4369 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
4370 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
4371 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
4372 KEYEVENTF_EXTENDEDKEY | 0, 0);
4373 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
4374 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
4375
4376
4377
4378 post_character_message (hwnd, msg, wParam, lParam,
4379 w32_get_key_modifiers (wParam, lParam));
4380 windows_translate = 1;
4381 break;
4382 case VK_CONTROL:
4383 case VK_SHIFT:
4384 case VK_PROCESSKEY:
4385 windows_translate = 1;
4386 break;
4387 case VK_CANCEL:
4388
4389
4390
4391 wParam = VK_PAUSE;
4392 break;
4393 case VK_PAUSE:
4394
4395
4396
4397
4398
4399 if (NILP (Vw32_enable_num_lock) && modifier_set (VK_CONTROL))
4400 wParam = VK_NUMLOCK;
4401 break;
4402 default:
4403 if (w32_unicode_gui && !w32_use_fallback_wm_chars_method)
4404 {
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421 int res;
4422 #if 0
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435 deliver_wm_chars (0, hwnd, msg, wParam, lParam, 1);
4436 #endif
4437
4438
4439
4440
4441
4442 res = deliver_wm_chars (1, hwnd, msg, wParam, lParam, 1);
4443 windows_translate = -(res != 0);
4444 if (res > 0)
4445 break;
4446
4447 }
4448 wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
4449
4450 if (wParam > 255 || !lispy_function_keys[wParam])
4451 {
4452 DWORD modifiers = w32_construct_console_modifiers ();
4453
4454 if (!NILP (Vw32_recognize_altgr)
4455 && modifier_set (VK_LCONTROL) && modifier_set (VK_RMENU))
4456 {
4457
4458
4459
4460 windows_translate = 1;
4461 }
4462 else if ((modifiers & (~SHIFT_PRESSED & ~CAPSLOCK_ON)) != 0)
4463 {
4464
4465
4466
4467 if ('A' <= wParam && wParam <= 'Z')
4468 {
4469
4470
4471
4472
4473
4474 if (!modifier_set (VK_SHIFT))
4475 wParam += ('a' - 'A');
4476 msg = WM_CHAR;
4477 }
4478 else
4479 {
4480
4481
4482
4483 int add;
4484 KEY_EVENT_RECORD key;
4485
4486 key.bKeyDown = TRUE;
4487 key.wRepeatCount = 1;
4488 key.wVirtualKeyCode = wParam;
4489 key.wVirtualScanCode = (lParam & 0xFF0000) >> 16;
4490 key.uChar.AsciiChar = 0;
4491 key.dwControlKeyState = modifiers;
4492
4493 add = w32_kbd_patch_key (&key, w32_keyboard_codepage);
4494
4495
4496 while (--add >= 0)
4497 {
4498
4499 post_character_message
4500 (hwnd, WM_CHAR,
4501 (unsigned char) key.uChar.AsciiChar, lParam,
4502 w32_get_key_modifiers (wParam, lParam));
4503 w32_kbd_patch_key (&key, w32_keyboard_codepage);
4504 }
4505 return 0;
4506 }
4507 }
4508 else
4509 {
4510
4511 windows_translate = 1;
4512 }
4513 }
4514 }
4515
4516 if (windows_translate == -1)
4517 break;
4518 translate:
4519 if (windows_translate)
4520 {
4521 MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
4522 windows_msg.time = GetMessageTime ();
4523 TranslateMessage (&windows_msg);
4524 goto dflt;
4525 }
4526
4527 FALLTHROUGH;
4528
4529 case WM_SYSCHAR:
4530 case WM_CHAR:
4531 if (wParam > 255 )
4532 {
4533 W32Msg wmsg;
4534
4535 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
4536 signal_user_input ();
4537 my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam);
4538
4539 }
4540 else
4541 post_character_message (hwnd, msg, wParam, lParam,
4542 w32_get_key_modifiers (wParam, lParam));
4543 break;
4544
4545 case WM_UNICHAR:
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557 if (wParam == UNICODE_NOCHAR)
4558 return TRUE;
4559
4560 {
4561 W32Msg wmsg;
4562 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
4563 signal_user_input ();
4564 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4565 }
4566 break;
4567
4568 case WM_IME_CHAR:
4569
4570
4571
4572 if (!get_composition_string_fn)
4573 goto dflt;
4574
4575 else if (!ignore_ime_char)
4576 {
4577 wchar_t * buffer;
4578 int size, i;
4579 W32Msg wmsg;
4580 HIMC context = get_ime_context_fn (hwnd);
4581 wmsg.dwModifiers =
4582 w32_ignore_modifiers_on_IME_input
4583 ? 0
4584 : w32_get_key_modifiers (wParam, lParam);
4585
4586 size = get_composition_string_fn (context, GCS_RESULTSTR, NULL, 0);
4587 buffer = alloca (size);
4588 size = get_composition_string_fn (context, GCS_RESULTSTR,
4589 buffer, size);
4590 release_ime_context_fn (hwnd, context);
4591
4592 signal_user_input ();
4593 for (i = 0; i < size / sizeof (wchar_t); i++)
4594 {
4595 my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
4596 lParam);
4597 }
4598
4599
4600 ignore_ime_char = (size / sizeof (wchar_t)) - 1;
4601 }
4602 else
4603 ignore_ime_char--;
4604
4605 break;
4606
4607 case WM_IME_STARTCOMPOSITION:
4608 if (!set_ime_composition_window_fn)
4609 goto dflt;
4610 else
4611 {
4612 COMPOSITIONFORM form;
4613 HIMC context;
4614 struct window *w;
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626 f = w32_window_to_frame (dpyinfo, hwnd);
4627 if (!(f && FRAME_LIVE_P (f)))
4628 goto dflt;
4629 w = XWINDOW (FRAME_SELECTED_WINDOW (f));
4630
4631
4632 if (w != w32_system_caret_window)
4633 goto dflt;
4634
4635 form.dwStyle = CFS_RECT;
4636 form.ptCurrentPos.x = w32_system_caret_x;
4637 form.ptCurrentPos.y = w32_system_caret_y;
4638
4639 form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
4640 form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
4641 + w32_system_caret_hdr_height);
4642 form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
4643 - WINDOW_RIGHT_MARGIN_WIDTH (w)
4644 - WINDOW_RIGHT_FRINGE_WIDTH (w));
4645 form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
4646 - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
4647 - w32_system_caret_mode_height);
4648
4649
4650 if (!BUFFERP (w->contents))
4651 goto dflt;
4652
4653 context = get_ime_context_fn (hwnd);
4654
4655 if (!context)
4656 goto dflt;
4657
4658 set_ime_composition_window_fn (context, &form);
4659 release_ime_context_fn (hwnd, context);
4660 }
4661
4662
4663
4664
4665
4666
4667 goto dflt;
4668
4669 case WM_IME_ENDCOMPOSITION:
4670 ignore_ime_char = 0;
4671 goto dflt;
4672
4673
4674
4675 case WM_LBUTTONDOWN:
4676 case WM_RBUTTONDOWN:
4677 if (w32_num_mouse_buttons > 2)
4678 goto handle_plain_button;
4679
4680 {
4681 int this = (msg == WM_LBUTTONDOWN) ? LMOUSE : RMOUSE;
4682 int other = (msg == WM_LBUTTONDOWN) ? RMOUSE : LMOUSE;
4683
4684 if (button_state & this)
4685 return 0;
4686
4687
4688 if (button_state == 0 && !EQ (track_mouse, Qdropping))
4689 SetCapture (hwnd);
4690
4691 button_state |= this;
4692
4693 if (button_state & other)
4694 {
4695 if (mouse_button_timer)
4696 {
4697 KillTimer (hwnd, mouse_button_timer);
4698 mouse_button_timer = 0;
4699
4700
4701 msg = WM_MBUTTONDOWN;
4702 button_state |= MMOUSE;
4703 }
4704 else if (button_state & MMOUSE)
4705 {
4706
4707
4708
4709
4710 return 0;
4711 }
4712 else
4713 {
4714
4715 post_msg (&saved_mouse_button_msg);
4716 }
4717 wmsg.dwModifiers = w32_get_modifiers ();
4718 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4719 signal_user_input ();
4720
4721
4722 saved_mouse_button_msg.msg.hwnd = 0;
4723 }
4724 else
4725 {
4726
4727 mouse_button_timer =
4728 SetTimer (hwnd, MOUSE_BUTTON_ID,
4729 w32_mouse_button_tolerance, NULL);
4730 saved_mouse_button_msg.msg.hwnd = hwnd;
4731 saved_mouse_button_msg.msg.message = msg;
4732 saved_mouse_button_msg.msg.wParam = wParam;
4733 saved_mouse_button_msg.msg.lParam = lParam;
4734 saved_mouse_button_msg.msg.time = GetMessageTime ();
4735 saved_mouse_button_msg.dwModifiers = w32_get_modifiers ();
4736 }
4737 }
4738 return 0;
4739
4740 case WM_LBUTTONUP:
4741 case WM_RBUTTONUP:
4742 if (w32_num_mouse_buttons > 2)
4743 goto handle_plain_button;
4744
4745 {
4746 int this = (msg == WM_LBUTTONUP) ? LMOUSE : RMOUSE;
4747 int other = (msg == WM_LBUTTONUP) ? RMOUSE : LMOUSE;
4748
4749 if ((button_state & this) == 0)
4750 return 0;
4751
4752 button_state &= ~this;
4753
4754 if (button_state & MMOUSE)
4755 {
4756
4757 if ((button_state & other) == 0)
4758 {
4759 msg = WM_MBUTTONUP;
4760 button_state &= ~MMOUSE;
4761
4762 if (button_state) emacs_abort ();
4763 }
4764 else
4765 return 0;
4766 }
4767 else
4768 {
4769
4770 if (saved_mouse_button_msg.msg.hwnd)
4771 {
4772 post_msg (&saved_mouse_button_msg);
4773 }
4774 }
4775 wmsg.dwModifiers = w32_get_modifiers ();
4776 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4777 signal_user_input ();
4778
4779
4780 saved_mouse_button_msg.msg.hwnd = 0;
4781 KillTimer (hwnd, mouse_button_timer);
4782 mouse_button_timer = 0;
4783
4784 if (button_state == 0)
4785 ReleaseCapture ();
4786 }
4787 return 0;
4788
4789 case WM_XBUTTONDOWN:
4790 case WM_XBUTTONUP:
4791 if (w32_pass_extra_mouse_buttons_to_system)
4792 goto dflt;
4793
4794 FALLTHROUGH;
4795 case WM_MBUTTONDOWN:
4796 case WM_MBUTTONUP:
4797 handle_plain_button:
4798 {
4799 BOOL up;
4800 int button;
4801
4802
4803 f = w32_window_to_frame (dpyinfo, hwnd);
4804 if (f && f->output_data.w32->menubar_active)
4805 return 0;
4806
4807 if (parse_button (msg, HIWORD (wParam), &button, &up))
4808 {
4809 if (up)
4810 ReleaseCapture ();
4811
4812 else if (!EQ (track_mouse, Qdropping))
4813 SetCapture (hwnd);
4814 button = (button == 0) ? LMOUSE :
4815 ((button == 1) ? MMOUSE : RMOUSE);
4816 if (up)
4817 button_state &= ~button;
4818 else
4819 button_state |= button;
4820 }
4821 }
4822
4823 if (f && (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN
4824 || msg == WM_MBUTTONDOWN ||msg == WM_XBUTTONDOWN)
4825 && !FRAME_NO_ACCEPT_FOCUS (f))
4826
4827
4828
4829 {
4830 struct frame *p = FRAME_PARENT_FRAME (XFRAME (selected_frame));
4831
4832 if (FRAME_PARENT_FRAME (f) || f == p)
4833 {
4834 SetFocus (hwnd);
4835 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
4836 }
4837 }
4838
4839 wmsg.dwModifiers = w32_get_modifiers ();
4840 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4841 signal_user_input ();
4842
4843
4844
4845 return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
4846
4847 case WM_MOUSEMOVE:
4848 f = w32_window_to_frame (dpyinfo, hwnd);
4849 if (f)
4850 {
4851
4852
4853
4854
4855 if (f->output_data.w32->menubar_active)
4856 return 0;
4857
4858
4859
4860
4861
4862 static int last_x, last_y;
4863 int x = GET_X_LPARAM (lParam);
4864 int y = GET_Y_LPARAM (lParam);
4865
4866 if (f->pointer_invisible
4867 && (x != last_x || y != last_y))
4868 f->pointer_invisible = false;
4869
4870 last_x = x;
4871 last_y = y;
4872 }
4873
4874
4875
4876
4877
4878
4879
4880 if (track_mouse_event_fn && !track_mouse_window
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892 && !menubar_in_use)
4893 {
4894 TRACKMOUSEEVENT tme;
4895 tme.cbSize = sizeof (tme);
4896 tme.dwFlags = TME_LEAVE;
4897 tme.hwndTrack = hwnd;
4898 tme.dwHoverTime = HOVER_DEFAULT;
4899
4900 track_mouse_event_fn (&tme);
4901 track_mouse_window = hwnd;
4902 }
4903 FALLTHROUGH;
4904 case WM_HSCROLL:
4905 case WM_VSCROLL:
4906 if (w32_mouse_move_interval <= 0
4907 || (msg == WM_MOUSEMOVE && button_state == 0))
4908 {
4909 wmsg.dwModifiers = w32_get_modifiers ();
4910 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4911 return 0;
4912 }
4913
4914
4915
4916
4917
4918
4919 if (saved_mouse_move_msg.msg.hwnd == 0)
4920 mouse_move_timer =
4921 SetTimer (hwnd, MOUSE_MOVE_ID,
4922 w32_mouse_move_interval, NULL);
4923
4924
4925 saved_mouse_move_msg.msg.hwnd = hwnd;
4926 saved_mouse_move_msg.msg.message = msg;
4927 saved_mouse_move_msg.msg.wParam = wParam;
4928 saved_mouse_move_msg.msg.lParam = lParam;
4929 saved_mouse_move_msg.msg.time = GetMessageTime ();
4930 saved_mouse_move_msg.dwModifiers = w32_get_modifiers ();
4931
4932 return 0;
4933
4934 case WM_MOUSEWHEEL:
4935 case WM_DROPFILES:
4936 wmsg.dwModifiers = w32_get_modifiers ();
4937 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4938 signal_user_input ();
4939 return 0;
4940
4941 case WM_APPCOMMAND:
4942 if (w32_pass_multimedia_buttons_to_system)
4943 goto dflt;
4944
4945 FALLTHROUGH;
4946
4947
4948
4949
4950 case WM_MOUSEHWHEEL:
4951 wmsg.dwModifiers = w32_get_modifiers ();
4952 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
4953 signal_user_input ();
4954
4955
4956
4957 return 1;
4958
4959 case WM_TIMER:
4960
4961 if (wParam == mouse_button_timer)
4962 {
4963 if (saved_mouse_button_msg.msg.hwnd)
4964 {
4965 post_msg (&saved_mouse_button_msg);
4966 signal_user_input ();
4967 saved_mouse_button_msg.msg.hwnd = 0;
4968 }
4969 KillTimer (hwnd, mouse_button_timer);
4970 mouse_button_timer = 0;
4971 }
4972 else if (wParam == mouse_move_timer)
4973 {
4974 if (saved_mouse_move_msg.msg.hwnd)
4975 {
4976 post_msg (&saved_mouse_move_msg);
4977 saved_mouse_move_msg.msg.hwnd = 0;
4978 }
4979 KillTimer (hwnd, mouse_move_timer);
4980 mouse_move_timer = 0;
4981 }
4982 else if (wParam == menu_free_timer)
4983 {
4984 KillTimer (hwnd, menu_free_timer);
4985 menu_free_timer = 0;
4986 f = w32_window_to_frame (dpyinfo, hwnd);
4987
4988 if (menubar_in_use
4989 && current_popup_menu == NULL)
4990 {
4991
4992 w32_free_menu_strings (hwnd);
4993 if (f)
4994 f->output_data.w32->menubar_active = 0;
4995 menubar_in_use = 0;
4996 }
4997 }
4998 return 0;
4999
5000 case WM_NCACTIVATE:
5001
5002
5003
5004
5005
5006 reset_modifiers ();
5007 goto dflt;
5008
5009 case WM_INITMENU:
5010 button_state = 0;
5011 ReleaseCapture ();
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028 f = w32_window_to_frame (dpyinfo, hwnd);
5029 if (f
5030 && (f->output_data.w32->menubar_active
5031
5032
5033
5034
5035
5036 || f->output_data.w32->menubar_widget == NULL))
5037 return 0;
5038
5039 {
5040 deferred_msg msg_buf;
5041
5042
5043
5044 if (find_deferred_msg (hwnd, msg) != NULL)
5045 emacs_abort ();
5046
5047 menubar_in_use = 1;
5048
5049 return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam);
5050 }
5051
5052 case WM_EXITMENULOOP:
5053 f = w32_window_to_frame (dpyinfo, hwnd);
5054
5055
5056
5057
5058
5059
5060
5061 if (f && menubar_in_use && current_popup_menu == NULL)
5062 menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
5063
5064
5065 if (f && f->output_data.w32->hourglass_p)
5066 SetCursor (f->output_data.w32->hourglass_cursor);
5067
5068 goto dflt;
5069
5070 case WM_MENUSELECT:
5071
5072
5073
5074 {
5075 HMENU menu = (HMENU) lParam;
5076 UINT menu_item = (UINT) LOWORD (wParam);
5077 UINT flags = (UINT) HIWORD (wParam);
5078
5079 w32_menu_display_help (hwnd, menu, menu_item, flags);
5080 }
5081 return 0;
5082
5083 case WM_MEASUREITEM:
5084 f = w32_window_to_frame (dpyinfo, hwnd);
5085 if (f)
5086 {
5087 MEASUREITEMSTRUCT * pMis = (MEASUREITEMSTRUCT *) lParam;
5088
5089 if (pMis->CtlType == ODT_MENU)
5090 {
5091
5092 char * title = (char *) pMis->itemData;
5093 HDC hdc = GetDC (hwnd);
5094 HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
5095 LOGFONT menu_logfont;
5096 HFONT old_font;
5097 SIZE size;
5098
5099 GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
5100 menu_logfont.lfWeight = FW_BOLD;
5101 menu_font = CreateFontIndirect (&menu_logfont);
5102 old_font = SelectObject (hdc, menu_font);
5103
5104 pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
5105 if (title)
5106 {
5107 if (unicode_append_menu)
5108 GetTextExtentPoint32W (hdc, (WCHAR *) title,
5109 wcslen ((WCHAR *) title),
5110 &size);
5111 else
5112 GetTextExtentPoint32 (hdc, title, strlen (title), &size);
5113
5114 pMis->itemWidth = size.cx;
5115 if (pMis->itemHeight < size.cy)
5116 pMis->itemHeight = size.cy;
5117 }
5118 else
5119 pMis->itemWidth = 0;
5120
5121 SelectObject (hdc, old_font);
5122 DeleteObject (menu_font);
5123 ReleaseDC (hwnd, hdc);
5124 return TRUE;
5125 }
5126 }
5127 return 0;
5128
5129 case WM_DRAWITEM:
5130 f = w32_window_to_frame (dpyinfo, hwnd);
5131 if (f)
5132 {
5133 DRAWITEMSTRUCT * pDis = (DRAWITEMSTRUCT *) lParam;
5134
5135 if (pDis->CtlType == ODT_MENU)
5136 {
5137
5138 char * title = (char *) pDis->itemData;
5139 if (title)
5140 {
5141 HDC hdc = pDis->hDC;
5142 HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
5143 LOGFONT menu_logfont;
5144 HFONT old_font;
5145
5146 GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
5147 menu_logfont.lfWeight = FW_BOLD;
5148 menu_font = CreateFontIndirect (&menu_logfont);
5149 old_font = SelectObject (hdc, menu_font);
5150
5151
5152 if (unicode_append_menu)
5153 ExtTextOutW (hdc,
5154 pDis->rcItem.left
5155 + GetSystemMetrics (SM_CXMENUCHECK),
5156 pDis->rcItem.top,
5157 ETO_OPAQUE, &pDis->rcItem,
5158 (WCHAR *) title,
5159 wcslen ((WCHAR *) title), NULL);
5160 else
5161 ExtTextOut (hdc,
5162 pDis->rcItem.left
5163 + GetSystemMetrics (SM_CXMENUCHECK),
5164 pDis->rcItem.top,
5165 ETO_OPAQUE, &pDis->rcItem,
5166 title, strlen (title), NULL);
5167
5168 SelectObject (hdc, old_font);
5169 DeleteObject (menu_font);
5170 }
5171 return TRUE;
5172 }
5173 }
5174 return 0;
5175
5176 case WM_MOUSEACTIVATE:
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191 if ((f = w32_window_to_frame (dpyinfo, hwnd))
5192 && FRAME_NO_ACCEPT_FOCUS (f)
5193
5194 && !FRAME_PARENT_FRAME (f))
5195 {
5196 Lisp_Object frame;
5197
5198 XSETFRAME (frame, f);
5199 if (!EQ (selected_frame, frame))
5200
5201 return MA_NOACTIVATE;
5202 }
5203 goto dflt;
5204
5205 case WM_MOUSELEAVE:
5206
5207 track_mouse_window = NULL;
5208 FALLTHROUGH;
5209
5210 case WM_ACTIVATEAPP:
5211 case WM_ACTIVATE:
5212 case WM_WINDOWPOSCHANGED:
5213 case WM_SHOWWINDOW:
5214
5215
5216 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5217 goto dflt;
5218
5219 case WM_SETTINGCHANGE:
5220
5221
5222
5223 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5224 goto dflt;
5225
5226 case WM_SETFOCUS:
5227 dpyinfo->faked_key = 0;
5228 reset_modifiers ();
5229 if (!w32_kbdhook_active)
5230 register_hot_keys (hwnd);
5231 goto command;
5232 case WM_KILLFOCUS:
5233 if (!w32_kbdhook_active)
5234 unregister_hot_keys (hwnd);
5235 button_state = 0;
5236 ReleaseCapture ();
5237
5238 if (w32_system_caret_hwnd)
5239 {
5240 w32_visible_system_caret_hwnd = NULL;
5241 w32_system_caret_hwnd = NULL;
5242 DestroyCaret ();
5243 }
5244 goto command;
5245 case WM_COMMAND:
5246 menubar_in_use = 0;
5247 f = w32_window_to_frame (dpyinfo, hwnd);
5248 if (f && HIWORD (wParam) == 0)
5249 {
5250 if (menu_free_timer)
5251 {
5252 KillTimer (hwnd, menu_free_timer);
5253 menu_free_timer = 0;
5254 }
5255 }
5256 FALLTHROUGH;
5257 case WM_MOVE:
5258 case WM_SIZE:
5259 command:
5260 wmsg.dwModifiers = w32_get_modifiers ();
5261 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5262 goto dflt;
5263
5264 #ifdef WINDOWSNT
5265 case WM_CREATE:
5266 setup_w32_kbdhook ();
5267 goto dflt;
5268 #endif
5269
5270 case WM_DESTROY:
5271 #ifdef WINDOWSNT
5272 remove_w32_kbdhook ();
5273 #endif
5274 CoUninitialize ();
5275 return 0;
5276
5277 case WM_WTSSESSION_CHANGE:
5278 if (wParam == WTS_SESSION_LOCK)
5279 reset_w32_kbdhook_state ();
5280 goto dflt;
5281
5282 case WM_CLOSE:
5283 wmsg.dwModifiers = w32_get_modifiers ();
5284 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5285 return 0;
5286
5287 case WM_ENDSESSION:
5288 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5289
5290
5291
5292
5293
5294 sleep (1000);
5295 FALLTHROUGH;
5296
5297 case WM_WINDOWPOSCHANGING:
5298
5299
5300 return 0;
5301
5302 case WM_GETMINMAXINFO:
5303
5304
5305 ((LPMINMAXINFO) lParam)->ptMaxTrackSize.x = 32767;
5306 ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;
5307 return 0;
5308
5309 case WM_SETCURSOR:
5310 if (LOWORD (lParam) == HTCLIENT)
5311 {
5312 f = w32_window_to_frame (dpyinfo, hwnd);
5313 if (f)
5314 {
5315 if (f->output_data.w32->hourglass_p
5316 && !menubar_in_use && !current_popup_menu)
5317 SetCursor (f->output_data.w32->hourglass_cursor);
5318 else if (f->pointer_invisible)
5319 SetCursor (NULL);
5320 else
5321 SetCursor (f->output_data.w32->current_cursor);
5322 }
5323
5324 return 0;
5325 }
5326 goto dflt;
5327
5328 case WM_EMACS_SETCURSOR:
5329 {
5330 HCURSOR cursor = (HCURSOR) wParam;
5331 f = w32_window_to_frame (dpyinfo, hwnd);
5332 if (f && cursor)
5333 {
5334 f->output_data.w32->current_cursor = cursor;
5335
5336 if (!f->output_data.w32->menubar_active
5337 && !f->output_data.w32->hourglass_p)
5338 {
5339 if (f->pointer_invisible)
5340 SetCursor (NULL);
5341 else
5342 SetCursor (cursor);
5343 }
5344 }
5345 return 0;
5346 }
5347
5348 case WM_EMACS_SHOWCURSOR:
5349 {
5350 ShowCursor ((BOOL) wParam);
5351
5352 return 0;
5353 }
5354
5355 case WM_EMACS_CREATEVSCROLLBAR:
5356 return (LRESULT) w32_createvscrollbar ((struct frame *) wParam,
5357 (struct scroll_bar *) lParam);
5358
5359 case WM_EMACS_CREATEHSCROLLBAR:
5360 return (LRESULT) w32_createhscrollbar ((struct frame *) wParam,
5361 (struct scroll_bar *) lParam);
5362
5363 case WM_EMACS_SHOWWINDOW:
5364 return ShowWindow ((HWND) wParam, (WPARAM) lParam);
5365
5366 case WM_EMACS_BRINGTOTOP:
5367 case WM_EMACS_SETFOREGROUND:
5368 {
5369 HWND foreground_window;
5370 DWORD foreground_thread, retval;
5371
5372
5373
5374
5375 foreground_window = GetForegroundWindow ();
5376 foreground_thread = GetWindowThreadProcessId (foreground_window, NULL);
5377 if (!foreground_window
5378 || foreground_thread == GetCurrentThreadId ()
5379 || !AttachThreadInput (GetCurrentThreadId (),
5380 foreground_thread, TRUE))
5381 foreground_thread = 0;
5382
5383 retval = SetForegroundWindow ((HWND) wParam);
5384 if (msg == WM_EMACS_BRINGTOTOP)
5385 retval = BringWindowToTop ((HWND) wParam);
5386
5387
5388 if (foreground_thread)
5389 AttachThreadInput (GetCurrentThreadId (),
5390 foreground_thread, FALSE);
5391
5392
5393 if (msg == WM_EMACS_SETFOREGROUND)
5394 SetFocus ((HWND) wParam);
5395
5396 return retval;
5397 }
5398
5399 case WM_EMACS_SETWINDOWPOS:
5400 {
5401 WINDOWPOS * pos = (WINDOWPOS *) wParam;
5402 return SetWindowPos (hwnd, pos->hwndInsertAfter,
5403 pos->x, pos->y, pos->cx, pos->cy, pos->flags);
5404 }
5405
5406 case WM_EMACS_DESTROYWINDOW:
5407 DragAcceptFiles ((HWND) wParam, FALSE);
5408 return DestroyWindow ((HWND) wParam);
5409
5410 case WM_EMACS_HIDE_CARET:
5411 return HideCaret (hwnd);
5412
5413 case WM_EMACS_SHOW_CARET:
5414 return ShowCaret (hwnd);
5415
5416 case WM_EMACS_DESTROY_CARET:
5417 w32_system_caret_hwnd = NULL;
5418 w32_visible_system_caret_hwnd = NULL;
5419 return DestroyCaret ();
5420
5421 case WM_EMACS_TRACK_CARET:
5422
5423 if (w32_system_caret_hwnd == NULL)
5424 {
5425
5426
5427 w32_system_caret_hwnd = hwnd;
5428 CreateCaret (hwnd, NULL, 0,
5429 w32_system_caret_height);
5430 }
5431
5432 if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y))
5433 return 0;
5434
5435 else if (w32_use_visible_system_caret
5436 && w32_visible_system_caret_hwnd != hwnd)
5437 {
5438 w32_visible_system_caret_hwnd = hwnd;
5439 return ShowCaret (hwnd);
5440 }
5441
5442 else if (!w32_use_visible_system_caret
5443 && w32_visible_system_caret_hwnd)
5444 {
5445 w32_visible_system_caret_hwnd = NULL;
5446 return HideCaret (hwnd);
5447 }
5448 else
5449 return 1;
5450
5451 case WM_EMACS_TRACKPOPUPMENU:
5452 {
5453 UINT flags;
5454 POINT *pos;
5455 int retval;
5456 pos = (POINT *)lParam;
5457 flags = TPM_CENTERALIGN;
5458 if (button_state & LMOUSE)
5459 flags |= TPM_LEFTBUTTON;
5460 else if (button_state & RMOUSE)
5461 flags |= TPM_RIGHTBUTTON;
5462
5463
5464
5465
5466 ReleaseCapture ();
5467 button_state = 0;
5468
5469
5470
5471 f = w32_window_to_frame (dpyinfo, hwnd);
5472 if (f)
5473 f->output_data.w32->menubar_active = 1;
5474
5475 if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y,
5476 0, hwnd, NULL))
5477 {
5478 MSG amsg;
5479
5480 while (PeekMessage (&amsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST,
5481 PM_REMOVE));
5482
5483 if (PeekMessage (&amsg, hwnd, WM_COMMAND, WM_COMMAND, PM_REMOVE))
5484 {
5485 retval = LOWORD (amsg.wParam);
5486 }
5487 else
5488 {
5489 retval = 0;
5490 }
5491 }
5492 else
5493 {
5494 retval = -1;
5495 }
5496
5497 return retval;
5498 }
5499 case WM_EMACS_FILENOTIFY:
5500 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5501 return 1;
5502
5503 default:
5504
5505 if (msg == msh_mousewheel)
5506 {
5507 wmsg.dwModifiers = w32_get_modifiers ();
5508 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
5509 signal_user_input ();
5510 return 0;
5511 }
5512
5513 dflt:
5514 return (w32_unicode_gui ? DefWindowProcW : DefWindowProcA) (hwnd, msg, wParam, lParam);
5515 }
5516
5517
5518 return 0;
5519 }
5520
5521
5522
5523
5524
5525
5526 static void
5527 my_create_window (struct frame * f)
5528 {
5529 MSG msg;
5530 static int coords[2];
5531 Lisp_Object left, top;
5532 struct w32_display_info *dpyinfo = &one_w32_display_info;
5533
5534
5535
5536
5537
5538
5539 if (!(f->size_hint_flags & USPosition || f->size_hint_flags & PPosition))
5540 {
5541
5542
5543
5544
5545
5546
5547
5548 left = gui_display_get_arg (dpyinfo, Qnil, Qleft, "left", "Left",
5549 RES_TYPE_NUMBER);
5550 top = gui_display_get_arg (dpyinfo, Qnil, Qtop, "top", "Top",
5551 RES_TYPE_NUMBER);
5552 if (BASE_EQ (left, Qunbound))
5553 coords[0] = CW_USEDEFAULT;
5554 else
5555 coords[0] = XFIXNUM (left);
5556 if (BASE_EQ (top, Qunbound))
5557 coords[1] = CW_USEDEFAULT;
5558 else
5559 coords[1] = XFIXNUM (top);
5560 }
5561
5562 if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW,
5563 (WPARAM)f, (LPARAM)coords))
5564 emacs_abort ();
5565 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
5566 }
5567
5568
5569
5570
5571
5572
5573 static void
5574 my_create_tip_window (struct frame *f)
5575 {
5576 RECT rect;
5577
5578 rect.left = rect.top = 0;
5579 rect.right = FRAME_PIXEL_WIDTH (f);
5580 rect.bottom = FRAME_PIXEL_HEIGHT (f);
5581
5582 AdjustWindowRect (&rect, f->output_data.w32->dwStyle, false);
5583
5584 tip_window = FRAME_W32_WINDOW (f)
5585 = CreateWindow (EMACS_CLASS,
5586 f->namebuf,
5587 f->output_data.w32->dwStyle,
5588 f->left_pos,
5589 f->top_pos,
5590 rect.right - rect.left,
5591 rect.bottom - rect.top,
5592 FRAME_W32_WINDOW (SELECTED_FRAME ()),
5593 NULL,
5594 hinst,
5595 NULL);
5596
5597 if (tip_window)
5598 {
5599 SetWindowLong (tip_window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
5600 SetWindowLong (tip_window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
5601 SetWindowLong (tip_window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
5602 SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
5603
5604
5605 SetWindowLong (tip_window, WND_VSCROLLBAR_INDEX, 0);
5606 SetWindowLong (tip_window, WND_HSCROLLBAR_INDEX, 0);
5607
5608
5609 ShowWindow (tip_window, SW_HIDE);
5610 }
5611 }
5612
5613
5614
5615
5616 static void
5617 w32_window (struct frame *f, long window_prompting, bool minibuffer_only)
5618 {
5619 block_input ();
5620
5621
5622
5623
5624
5625
5626 f->namebuf = xlispstrdup (Vx_resource_name);
5627
5628 my_create_window (f);
5629
5630 validate_x_resource_name ();
5631
5632
5633
5634
5635
5636 {
5637 Lisp_Object name;
5638 int explicit = f->explicit_name;
5639
5640 f->explicit_name = 0;
5641 name = f->name;
5642 fset_name (f, Qnil);
5643 w32_set_name (f, name, explicit);
5644 }
5645
5646 unblock_input ();
5647
5648 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f)
5649 && !FRAME_PARENT_FRAME (f))
5650 initialize_frame_menubar (f);
5651
5652 if (FRAME_W32_WINDOW (f) == 0)
5653 error ("Unable to create window");
5654 }
5655
5656
5657
5658
5659
5660 static void
5661 w32_icon (struct frame *f, Lisp_Object parms)
5662 {
5663 Lisp_Object icon_x, icon_y;
5664 struct w32_display_info *dpyinfo = &one_w32_display_info;
5665
5666
5667
5668 icon_x = gui_display_get_arg (dpyinfo, parms, Qicon_left, 0, 0,
5669 RES_TYPE_NUMBER);
5670 icon_y = gui_display_get_arg (dpyinfo, parms, Qicon_top, 0, 0,
5671 RES_TYPE_NUMBER);
5672 if (!BASE_EQ (icon_x, Qunbound) && !BASE_EQ (icon_y, Qunbound))
5673 {
5674 CHECK_FIXNUM (icon_x);
5675 CHECK_FIXNUM (icon_y);
5676 }
5677 else if (!BASE_EQ (icon_x, Qunbound) || !BASE_EQ (icon_y, Qunbound))
5678 error ("Both left and top icon corners of icon must be specified");
5679
5680 block_input ();
5681
5682
5683
5684 unblock_input ();
5685 }
5686
5687
5688 static void
5689 w32_make_gc (struct frame *f)
5690 {
5691 Emacs_GC gc_values;
5692
5693 block_input ();
5694
5695
5696
5697
5698
5699 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
5700 gc_values.background = f->output_data.w32->cursor_pixel;
5701 f->output_data.w32->cursor_gc
5702 = XCreateGC (NULL, FRAME_W32_WINDOW (f),
5703 (GCForeground | GCBackground),
5704 &gc_values);
5705
5706
5707 f->output_data.w32->white_relief.gc = 0;
5708 f->output_data.w32->black_relief.gc = 0;
5709
5710 unblock_input ();
5711 }
5712
5713
5714
5715
5716
5717
5718 static Lisp_Object
5719 unwind_create_frame (Lisp_Object frame)
5720 {
5721 struct frame *f = XFRAME (frame);
5722
5723
5724 if (NILP (Fmemq (frame, Vframe_list)))
5725 {
5726 #ifdef GLYPH_DEBUG
5727 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
5728
5729
5730
5731
5732
5733
5734
5735
5736 if (FRAME_IMAGE_CACHE (f) != NULL
5737 && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount)
5738 FRAME_IMAGE_CACHE (f)->refcount++;
5739 #endif
5740
5741 w32_free_frame_resources (f);
5742 free_glyphs (f);
5743
5744 #ifdef GLYPH_DEBUG
5745
5746 eassert (dpyinfo->reference_count == dpyinfo_refcount);
5747 eassert ((dpyinfo->terminal->image_cache == NULL
5748 && image_cache_refcount == 0)
5749 || (dpyinfo->terminal->image_cache != NULL
5750 && dpyinfo->terminal->image_cache->refcount == image_cache_refcount));
5751 #endif
5752 return Qt;
5753 }
5754
5755 return Qnil;
5756 }
5757
5758 static void
5759 do_unwind_create_frame (Lisp_Object frame)
5760 {
5761 unwind_create_frame (frame);
5762 }
5763
5764 void
5765 w32_default_font_parameter (struct frame *f, Lisp_Object parms)
5766 {
5767 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
5768 Lisp_Object font_param = gui_display_get_arg (dpyinfo,
5769 parms, Qfont, NULL, NULL,
5770 RES_TYPE_STRING);
5771 Lisp_Object font;
5772 if (BASE_EQ (font_param, Qunbound))
5773 font_param = Qnil;
5774 font = !NILP (font_param) ? font_param
5775 : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font",
5776 RES_TYPE_STRING);
5777
5778 if (!STRINGP (font))
5779 {
5780 int i;
5781 static const char *names[]
5782 = { "Courier New-10",
5783 "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
5784 "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
5785 "Fixedsys",
5786 NULL };
5787
5788 for (i = 0; names[i]; i++)
5789 {
5790 font = font_open_by_name (f, build_unibyte_string (names[i]));
5791 if (! NILP (font))
5792 break;
5793 }
5794 if (NILP (font))
5795 error ("No suitable font was found");
5796 }
5797
5798 gui_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
5799 }
5800
5801 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
5802 1, 1, 0,
5803 doc: )
5804 (Lisp_Object parameters)
5805 {
5806 struct frame *f;
5807 Lisp_Object frame, tem;
5808 Lisp_Object name;
5809 bool minibuffer_only = false;
5810 long window_prompting = 0;
5811 specpdl_ref count = SPECPDL_INDEX ();
5812 Lisp_Object display;
5813 struct w32_display_info *dpyinfo = NULL;
5814 Lisp_Object parent, parent_frame;
5815 struct kboard *kb;
5816
5817 if (!FRAME_W32_P (SELECTED_FRAME ())
5818 && !FRAME_INITIAL_P (SELECTED_FRAME ()))
5819 error ("Cannot create a GUI frame in a -nw session");
5820
5821
5822
5823 parameters = Fcopy_alist (parameters);
5824
5825
5826
5827 Vx_resource_name = Vinvocation_name;
5828
5829 display = gui_display_get_arg (dpyinfo, parameters, Qterminal, 0, 0,
5830 RES_TYPE_NUMBER);
5831 if (BASE_EQ (display, Qunbound))
5832 display = gui_display_get_arg (dpyinfo, parameters, Qdisplay, 0, 0,
5833 RES_TYPE_STRING);
5834 if (BASE_EQ (display, Qunbound))
5835 display = Qnil;
5836 dpyinfo = check_x_display_info (display);
5837 kb = dpyinfo->terminal->kboard;
5838
5839 if (!dpyinfo->terminal->name)
5840 error ("Terminal is not live, can't create new frames on it");
5841
5842 name = gui_display_get_arg (dpyinfo, parameters, Qname, "name", "Name",
5843 RES_TYPE_STRING);
5844 if (!STRINGP (name)
5845 && ! BASE_EQ (name, Qunbound)
5846 && ! NILP (name))
5847 error ("Invalid frame name--not a string or nil");
5848
5849 if (STRINGP (name))
5850 Vx_resource_name = name;
5851
5852
5853 parent = gui_display_get_arg (dpyinfo, parameters, Qparent_id, NULL, NULL,
5854 RES_TYPE_NUMBER);
5855 if (BASE_EQ (parent, Qunbound))
5856 parent = Qnil;
5857 else if (!NILP (parent))
5858 CHECK_FIXNUM (parent);
5859
5860
5861
5862
5863 frame = Qnil;
5864 tem = gui_display_get_arg (dpyinfo, parameters, Qminibuffer,
5865 "minibuffer", "Minibuffer",
5866 RES_TYPE_SYMBOL);
5867 if (EQ (tem, Qnone) || NILP (tem))
5868 f = make_frame_without_minibuffer (Qnil, kb, display);
5869 else if (EQ (tem, Qonly))
5870 {
5871 f = make_minibuffer_frame ();
5872 minibuffer_only = true;
5873 }
5874 else if (WINDOWP (tem))
5875 f = make_frame_without_minibuffer (tem, kb, display);
5876 else
5877 f = make_frame (true);
5878
5879 XSETFRAME (frame, f);
5880
5881 parent_frame = gui_display_get_arg (dpyinfo, parameters, Qparent_frame,
5882 NULL, NULL,
5883 RES_TYPE_SYMBOL);
5884
5885
5886 if (!NILP (parent_frame)
5887 && (!NILP (parent)
5888 || !FRAMEP (parent_frame)
5889 || !FRAME_LIVE_P (XFRAME (parent_frame))
5890 || !FRAME_W32_P (XFRAME (parent_frame))))
5891 parent_frame = Qnil;
5892
5893 fset_parent_frame (f, parent_frame);
5894 store_frame_param (f, Qparent_frame, parent_frame);
5895
5896 tem = gui_display_get_arg (dpyinfo, parameters, Qundecorated, NULL, NULL,
5897 RES_TYPE_BOOLEAN);
5898 FRAME_UNDECORATED (f) = !NILP (tem) && !BASE_EQ (tem, Qunbound);
5899 store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil);
5900
5901 tem = gui_display_get_arg (dpyinfo, parameters, Qskip_taskbar, NULL, NULL,
5902 RES_TYPE_BOOLEAN);
5903 FRAME_SKIP_TASKBAR (f) = !NILP (tem) && !BASE_EQ (tem, Qunbound);
5904 store_frame_param (f, Qskip_taskbar,
5905 (NILP (tem) || BASE_EQ (tem, Qunbound)) ? Qnil : Qt);
5906
5907
5908 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
5909 FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL);
5910
5911 f->terminal = dpyinfo->terminal;
5912
5913 f->output_method = output_w32;
5914 f->output_data.w32 = xzalloc (sizeof (struct w32_output));
5915 FRAME_FONTSET (f) = -1;
5916
5917
5918
5919
5920 if (!f->terminal->reference_count)
5921 gui_init_fringe (f->terminal->rif);
5922
5923 fset_icon_name (f, gui_display_get_arg (dpyinfo,
5924 parameters,
5925 Qicon_name,
5926 "iconName",
5927 "Title",
5928 RES_TYPE_STRING));
5929 if (! STRINGP (f->icon_name))
5930 fset_icon_name (f, Qnil);
5931
5932
5933
5934
5935 record_unwind_protect (do_unwind_create_frame, frame);
5936
5937 #ifdef GLYPH_DEBUG
5938 image_cache_refcount =
5939 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
5940 dpyinfo_refcount = dpyinfo->reference_count;
5941 #endif
5942
5943
5944
5945
5946 if (!NILP (parent))
5947 {
5948
5949
5950 f->output_data.w32->parent_desc = (Window) (UINT_PTR) XFIXNAT (parent);
5951 f->output_data.w32->explicit_parent = true;
5952 }
5953 else
5954 {
5955 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
5956 f->output_data.w32->explicit_parent = false;
5957 }
5958
5959
5960
5961 if (BASE_EQ (name, Qunbound) || NILP (name))
5962 {
5963 fset_name (f, build_string (dpyinfo->w32_id_name));
5964 f->explicit_name = false;
5965 }
5966 else
5967 {
5968 fset_name (f, name);
5969 f->explicit_name = true;
5970
5971 specbind (Qx_resource_name, name);
5972 }
5973
5974 #ifdef HAVE_HARFBUZZ
5975 if (harfbuzz_available)
5976 register_font_driver (&harfbuzz_font_driver, f);
5977 #endif
5978 register_font_driver (&uniscribe_font_driver, f);
5979 register_font_driver (&w32font_driver, f);
5980
5981 gui_default_parameter (f, parameters, Qfont_backend, Qnil,
5982 "fontBackend", "FontBackend", RES_TYPE_STRING);
5983
5984
5985
5986 w32_default_font_parameter (f, parameters);
5987
5988
5989 gui_default_parameter (f, parameters, Qborder_width, make_fixnum (0),
5990 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5991
5992
5993
5994 if (NILP (Fassq (Qinternal_border_width, parameters)))
5995 {
5996 Lisp_Object value;
5997
5998 value = gui_display_get_arg (dpyinfo, parameters, Qinternal_border_width,
5999 "internalBorder", "internalBorder",
6000 RES_TYPE_NUMBER);
6001 if (! BASE_EQ (value, Qunbound))
6002 parameters = Fcons (Fcons (Qinternal_border_width, value),
6003 parameters);
6004 }
6005
6006 gui_default_parameter (f, parameters, Qinternal_border_width, make_fixnum (0),
6007 "internalBorderWidth", "internalBorderWidth",
6008 RES_TYPE_NUMBER);
6009
6010
6011 if (NILP (Fassq (Qchild_frame_border_width, parameters)))
6012 {
6013 Lisp_Object value;
6014
6015 value = gui_display_get_arg (dpyinfo, parameters, Qchild_frame_border_width,
6016 "childFrameBorder", "childFrameBorder",
6017 RES_TYPE_NUMBER);
6018 if (!BASE_EQ (value, Qunbound))
6019 parameters = Fcons (Fcons (Qchild_frame_border_width, value),
6020 parameters);
6021 }
6022
6023 gui_default_parameter (f, parameters, Qchild_frame_border_width, Qnil,
6024 "childFrameBorderWidth", "childFrameBorderWidth",
6025 RES_TYPE_NUMBER);
6026 gui_default_parameter (f, parameters, Qright_divider_width, make_fixnum (0),
6027 NULL, NULL, RES_TYPE_NUMBER);
6028 gui_default_parameter (f, parameters, Qbottom_divider_width, make_fixnum (0),
6029 NULL, NULL, RES_TYPE_NUMBER);
6030 gui_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
6031 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
6032 gui_default_parameter (f, parameters, Qhorizontal_scroll_bars, Qnil,
6033 "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
6034
6035
6036 gui_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
6037 "foreground", "Foreground", RES_TYPE_STRING);
6038 gui_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
6039 "background", "Background", RES_TYPE_STRING);
6040 gui_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
6041 "pointerColor", "Foreground", RES_TYPE_STRING);
6042 gui_default_parameter (f, parameters, Qborder_color, build_string ("black"),
6043 "borderColor", "BorderColor", RES_TYPE_STRING);
6044 gui_default_parameter (f, parameters, Qscreen_gamma, Qnil,
6045 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
6046 gui_default_parameter (f, parameters, Qline_spacing, Qnil,
6047 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
6048 gui_default_parameter (f, parameters, Qleft_fringe, Qnil,
6049 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
6050 gui_default_parameter (f, parameters, Qright_fringe, Qnil,
6051 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
6052 gui_default_parameter (f, parameters, Qno_focus_on_map, Qnil,
6053 NULL, NULL, RES_TYPE_BOOLEAN);
6054 gui_default_parameter (f, parameters, Qno_accept_focus, Qnil,
6055 NULL, NULL, RES_TYPE_BOOLEAN);
6056 gui_default_parameter (f, parameters, Qno_special_glyphs, Qnil,
6057 NULL, NULL, RES_TYPE_BOOLEAN);
6058 gui_default_parameter (f, parameters, Qalpha_background, Qnil,
6059 "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
6060
6061
6062
6063
6064 if (!FRAME_NO_FOCUS_ON_MAP (f))
6065 gui_default_parameter (f, parameters, Qalpha, Qnil,
6066 "alpha", "Alpha", RES_TYPE_NUMBER);
6067
6068
6069
6070 init_frame_faces (f);
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084 tem = gui_display_get_arg (dpyinfo, parameters, Qmin_width, NULL, NULL,
6085 RES_TYPE_NUMBER);
6086 if (FIXNUMP (tem))
6087 store_frame_param (f, Qmin_width, tem);
6088 tem = gui_display_get_arg (dpyinfo, parameters, Qmin_height, NULL, NULL,
6089 RES_TYPE_NUMBER);
6090 if (FIXNUMP (tem))
6091 store_frame_param (f, Qmin_height, tem);
6092 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
6093 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, true,
6094 Qx_create_frame_1);
6095
6096
6097
6098
6099 if (NILP (parent_frame))
6100 {
6101 gui_default_parameter (f, parameters, Qmenu_bar_lines,
6102 NILP (Vmenu_bar_mode)
6103 ? make_fixnum (0) : make_fixnum (1),
6104 NULL, NULL, RES_TYPE_NUMBER);
6105 }
6106 else
6107
6108 store_frame_param (f, Qmenu_bar_lines, make_fixnum (0));
6109
6110 gui_default_parameter (f, parameters, Qtab_bar_lines,
6111 NILP (Vtab_bar_mode)
6112 ? make_fixnum (0) : make_fixnum (1),
6113 NULL, NULL, RES_TYPE_NUMBER);
6114
6115 gui_default_parameter (f, parameters, Qtool_bar_lines,
6116 NILP (Vtool_bar_mode)
6117 ? make_fixnum (0) : make_fixnum (1),
6118 NULL, NULL, RES_TYPE_NUMBER);
6119
6120 gui_default_parameter (f, parameters, Qinhibit_double_buffering, Qnil,
6121 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
6122 RES_TYPE_BOOLEAN);
6123
6124 gui_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
6125 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
6126 gui_default_parameter (f, parameters, Qtitle, Qnil,
6127 "title", "Title", RES_TYPE_STRING);
6128
6129 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
6130 f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM);
6131 f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
6132 f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW);
6133 f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
6134 f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
6135 f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
6136 f->output_data.w32->vertical_drag_cursor = w32_load_cursor (IDC_SIZENS);
6137 f->output_data.w32->left_edge_cursor = w32_load_cursor (IDC_SIZEWE);
6138 f->output_data.w32->top_left_corner_cursor = w32_load_cursor (IDC_SIZENWSE);
6139 f->output_data.w32->top_edge_cursor = w32_load_cursor (IDC_SIZENS);
6140 f->output_data.w32->top_right_corner_cursor = w32_load_cursor (IDC_SIZENESW);
6141 f->output_data.w32->right_edge_cursor = w32_load_cursor (IDC_SIZEWE);
6142 f->output_data.w32->bottom_right_corner_cursor = w32_load_cursor (IDC_SIZENWSE);
6143 f->output_data.w32->bottom_edge_cursor = w32_load_cursor (IDC_SIZENS);
6144 f->output_data.w32->bottom_left_corner_cursor = w32_load_cursor (IDC_SIZENESW);
6145
6146 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
6147
6148 window_prompting = gui_figure_window_size (f, parameters, true, true);
6149
6150 tem = gui_display_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0,
6151 RES_TYPE_BOOLEAN);
6152 f->no_split = minibuffer_only || EQ (tem, Qt);
6153
6154 w32_window (f, window_prompting, minibuffer_only);
6155 w32_icon (f, parameters);
6156
6157 w32_make_gc (f);
6158
6159
6160 f->terminal->reference_count++;
6161 FRAME_DISPLAY_INFO (f)->reference_count++;
6162 Vframe_list = Fcons (frame, Vframe_list);
6163
6164
6165
6166 gui_default_parameter (f, parameters, Qicon_type, Qnil,
6167 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
6168
6169 gui_default_parameter (f, parameters, Qauto_raise, Qnil,
6170 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
6171 gui_default_parameter (f, parameters, Qauto_lower, Qnil,
6172 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
6173 gui_default_parameter (f, parameters, Qcursor_type, Qbox,
6174 "cursorType", "CursorType", RES_TYPE_SYMBOL);
6175 gui_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
6176 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
6177 gui_default_parameter (f, parameters, Qscroll_bar_height, Qnil,
6178 "scrollBarHeight", "ScrollBarHeight", RES_TYPE_NUMBER);
6179
6180
6181 f->can_set_window_size = true;
6182
6183
6184
6185
6186 block_input ();
6187 w32_wm_set_size_hint (f, window_prompting, false);
6188 unblock_input ();
6189
6190 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
6191 0, true, Qx_create_frame_2);
6192
6193
6194
6195
6196 gui_default_parameter (f, parameters, Qfullscreen, Qnil,
6197 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
6198 gui_default_parameter (f, parameters, Qz_group, Qnil,
6199 NULL, NULL, RES_TYPE_SYMBOL);
6200
6201 gui_default_parameter (f, parameters, Qalpha_background, Qnil,
6202 "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
6203
6204
6205
6206
6207 if (!f->output_data.w32->explicit_parent)
6208 {
6209 Lisp_Object visibility
6210 = gui_display_get_arg (dpyinfo, parameters, Qvisibility, 0, 0,
6211 RES_TYPE_SYMBOL);
6212
6213 if (EQ (visibility, Qicon))
6214 w32_iconify_frame (f);
6215 else
6216 {
6217 if (BASE_EQ (visibility, Qunbound))
6218 visibility = Qt;
6219
6220 if (!NILP (visibility))
6221 w32_make_frame_visible (f);
6222 else
6223 f->was_invisible = true;
6224 }
6225
6226 store_frame_param (f, Qvisibility, visibility);
6227 }
6228
6229
6230 if (FRAME_NO_FOCUS_ON_MAP (f))
6231 gui_default_parameter (f, parameters, Qalpha, Qnil,
6232 "alpha", "Alpha", RES_TYPE_NUMBER);
6233
6234
6235
6236 if (FRAME_HAS_MINIBUF_P (f)
6237 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
6238 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
6239 kset_default_minibuffer_frame (kb, frame);
6240
6241
6242
6243
6244 for (tem = parameters; CONSP (tem); tem = XCDR (tem))
6245 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
6246 fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
6247
6248
6249
6250 Vwindow_list = Qnil;
6251
6252 return unbind_to (count, frame);
6253 }
6254
6255 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
6256 doc: )
6257 (Lisp_Object color, Lisp_Object frame)
6258 {
6259 Emacs_Color foo;
6260 struct frame *f = decode_window_system_frame (frame);
6261
6262 CHECK_STRING (color);
6263
6264 if (w32_defined_color (f, SSDATA (color), &foo, false, false))
6265 return Qt;
6266 else
6267 return Qnil;
6268 }
6269
6270 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
6271 doc: )
6272 (Lisp_Object color, Lisp_Object frame)
6273 {
6274 Emacs_Color foo;
6275 struct frame *f = decode_window_system_frame (frame);
6276
6277 CHECK_STRING (color);
6278
6279 if (w32_defined_color (f, SSDATA (color), &foo, false, false))
6280 return list3i ((GetRValue (foo.pixel) << 8) | GetRValue (foo.pixel),
6281 (GetGValue (foo.pixel) << 8) | GetGValue (foo.pixel),
6282 (GetBValue (foo.pixel) << 8) | GetBValue (foo.pixel));
6283 else
6284 return Qnil;
6285 }
6286
6287 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
6288 doc: )
6289 (Lisp_Object display)
6290 {
6291 struct w32_display_info *dpyinfo = check_x_display_info (display);
6292
6293 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 2)
6294 return Qnil;
6295
6296 return Qt;
6297 }
6298
6299 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
6300 Sx_display_grayscale_p, 0, 1, 0,
6301 doc: )
6302 (Lisp_Object display)
6303 {
6304 struct w32_display_info *dpyinfo = check_x_display_info (display);
6305
6306 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 1)
6307 return Qnil;
6308
6309 return Qt;
6310 }
6311
6312 DEFUN ("x-display-pixel-width", Fx_display_pixel_width,
6313 Sx_display_pixel_width, 0, 1, 0,
6314 doc: )
6315 (Lisp_Object display)
6316 {
6317 struct w32_display_info *dpyinfo = check_x_display_info (display);
6318
6319 return make_fixnum (w32_display_pixel_width (dpyinfo));
6320 }
6321
6322 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
6323 Sx_display_pixel_height, 0, 1, 0,
6324 doc: )
6325 (Lisp_Object display)
6326 {
6327 struct w32_display_info *dpyinfo = check_x_display_info (display);
6328
6329 return make_fixnum (w32_display_pixel_height (dpyinfo));
6330 }
6331
6332 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
6333 0, 1, 0,
6334 doc: )
6335 (Lisp_Object display)
6336 {
6337 struct w32_display_info *dpyinfo = check_x_display_info (display);
6338
6339 return make_fixnum (dpyinfo->n_planes * dpyinfo->n_cbits);
6340 }
6341
6342 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
6343 0, 1, 0,
6344 doc: )
6345 (Lisp_Object display)
6346 {
6347 struct w32_display_info *dpyinfo = check_x_display_info (display);
6348 int cap;
6349
6350
6351
6352
6353
6354
6355 cap = 1 << min (dpyinfo->n_planes * dpyinfo->n_cbits, 24);
6356 return make_fixnum (cap);
6357 }
6358
6359 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
6360 Sx_server_max_request_size,
6361 0, 1, 0,
6362 doc: )
6363 (Lisp_Object display)
6364 {
6365 return make_fixnum (1);
6366 }
6367
6368 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
6369 doc: )
6370 (Lisp_Object terminal)
6371 {
6372 return build_string ("Microsoft Corp.");
6373 }
6374
6375 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
6376 doc: )
6377 (Lisp_Object terminal)
6378 {
6379 return list3i (w32_major_version, w32_minor_version, w32_build_number);
6380 }
6381
6382 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
6383 doc: )
6384 (Lisp_Object display)
6385 {
6386 return make_fixnum (1);
6387 }
6388
6389 DEFUN ("x-display-mm-height", Fx_display_mm_height,
6390 Sx_display_mm_height, 0, 1, 0,
6391 doc: )
6392 (Lisp_Object display)
6393 {
6394 struct w32_display_info *dpyinfo = check_x_display_info (display);
6395 HDC hdc;
6396 double mm_per_pixel;
6397
6398 hdc = GetDC (NULL);
6399 mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE)
6400 / GetDeviceCaps (hdc, VERTRES));
6401 ReleaseDC (NULL, hdc);
6402
6403 return make_fixnum (w32_display_pixel_height (dpyinfo) * mm_per_pixel + 0.5);
6404 }
6405
6406 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
6407 doc: )
6408 (Lisp_Object display)
6409 {
6410 struct w32_display_info *dpyinfo = check_x_display_info (display);
6411 HDC hdc;
6412 double mm_per_pixel;
6413
6414 hdc = GetDC (NULL);
6415 mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE)
6416 / GetDeviceCaps (hdc, HORZRES));
6417 ReleaseDC (NULL, hdc);
6418
6419 return make_fixnum (w32_display_pixel_width (dpyinfo) * mm_per_pixel + 0.5);
6420 }
6421
6422 DEFUN ("x-display-backing-store", Fx_display_backing_store,
6423 Sx_display_backing_store, 0, 1, 0,
6424 doc: )
6425 (Lisp_Object display)
6426 {
6427 return intern ("not-useful");
6428 }
6429
6430 DEFUN ("x-display-visual-class", Fx_display_visual_class,
6431 Sx_display_visual_class, 0, 1, 0,
6432 doc: )
6433 (Lisp_Object display)
6434 {
6435 struct w32_display_info *dpyinfo = check_x_display_info (display);
6436 Lisp_Object result = Qnil;
6437
6438 if (dpyinfo->has_palette)
6439 result = intern ("pseudo-color");
6440 else if (dpyinfo->n_planes * dpyinfo->n_cbits == 1)
6441 result = intern ("static-gray");
6442 else if (dpyinfo->n_planes * dpyinfo->n_cbits == 4)
6443 result = intern ("static-color");
6444 else if (dpyinfo->n_planes * dpyinfo->n_cbits > 8)
6445 result = intern ("true-color");
6446
6447 return result;
6448 }
6449
6450 DEFUN ("x-display-save-under", Fx_display_save_under,
6451 Sx_display_save_under, 0, 1, 0,
6452 doc: )
6453 (Lisp_Object display)
6454 {
6455 return Qnil;
6456 }
6457
6458 static BOOL CALLBACK ALIGN_STACK
6459 w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
6460 {
6461 Lisp_Object *monitor_list = (Lisp_Object *) dwData;
6462
6463 *monitor_list = Fcons (make_mint_ptr (monitor), *monitor_list);
6464
6465 return TRUE;
6466 }
6467
6468 static Lisp_Object
6469 w32_display_monitor_attributes_list (void)
6470 {
6471 Lisp_Object attributes_list = Qnil, primary_monitor_attributes = Qnil;
6472 Lisp_Object monitor_list = Qnil, monitor_frames, rest, frame;
6473 int i, n_monitors;
6474 HMONITOR *monitors;
6475
6476 if (!(enum_display_monitors_fn && get_monitor_info_fn
6477 && monitor_from_window_fn))
6478 return Qnil;
6479
6480 if (!enum_display_monitors_fn (NULL, NULL, w32_monitor_enum,
6481 (LPARAM) &monitor_list)
6482 || NILP (monitor_list))
6483 return Qnil;
6484
6485 n_monitors = 0;
6486 for (rest = monitor_list; CONSP (rest); rest = XCDR (rest))
6487 n_monitors++;
6488
6489 monitors = xmalloc (n_monitors * sizeof (*monitors));
6490 for (i = 0; i < n_monitors; i++)
6491 {
6492 monitors[i] = xmint_pointer (XCAR (monitor_list));
6493 monitor_list = XCDR (monitor_list);
6494 }
6495
6496 monitor_frames = Fmake_vector (make_fixnum (n_monitors), Qnil);
6497 FOR_EACH_FRAME (rest, frame)
6498 {
6499 struct frame *f = XFRAME (frame);
6500
6501 if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
6502 {
6503 HMONITOR monitor =
6504 monitor_from_window_fn (FRAME_W32_WINDOW (f),
6505 MONITOR_DEFAULT_TO_NEAREST);
6506
6507 for (i = 0; i < n_monitors; i++)
6508 if (monitors[i] == monitor)
6509 break;
6510
6511 if (i < n_monitors)
6512 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
6513 }
6514 }
6515
6516 for (i = 0; i < n_monitors; i++)
6517 {
6518 Lisp_Object geometry, workarea, name, attributes = Qnil;
6519 HDC hdc;
6520 int width_mm, height_mm;
6521 struct MONITOR_INFO_EX mi;
6522
6523 mi.cbSize = sizeof (mi);
6524 if (!get_monitor_info_fn (monitors[i], (struct MONITOR_INFO *) &mi))
6525 continue;
6526
6527 hdc = CreateDCA ("DISPLAY", mi.szDevice, NULL, NULL);
6528 if (hdc == NULL)
6529 continue;
6530 width_mm = GetDeviceCaps (hdc, HORZSIZE);
6531 height_mm = GetDeviceCaps (hdc, VERTSIZE);
6532 DeleteDC (hdc);
6533
6534 attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
6535 attributes);
6536
6537 name = DECODE_SYSTEM (build_unibyte_string (mi.szDevice));
6538
6539 attributes = Fcons (Fcons (Qname, name), attributes);
6540
6541 attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)),
6542 attributes);
6543
6544 workarea = list4i (mi.rcWork.left, mi.rcWork.top,
6545 mi.rcWork.right - mi.rcWork.left,
6546 mi.rcWork.bottom - mi.rcWork.top);
6547 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
6548
6549 geometry = list4i (mi.rcMonitor.left, mi.rcMonitor.top,
6550 mi.rcMonitor.right - mi.rcMonitor.left,
6551 mi.rcMonitor.bottom - mi.rcMonitor.top);
6552 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
6553
6554 if (mi.dwFlags & MONITORINFOF_PRIMARY)
6555 primary_monitor_attributes = attributes;
6556 else
6557 attributes_list = Fcons (attributes, attributes_list);
6558 }
6559
6560 if (!NILP (primary_monitor_attributes))
6561 attributes_list = Fcons (primary_monitor_attributes, attributes_list);
6562
6563 xfree (monitors);
6564
6565 return attributes_list;
6566 }
6567
6568 static Lisp_Object
6569 w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo)
6570 {
6571 Lisp_Object geometry, workarea, frames, rest, frame, attributes = Qnil;
6572 HDC hdc;
6573 double mm_per_pixel;
6574 int pixel_width, pixel_height, width_mm, height_mm;
6575 RECT workarea_rect;
6576
6577
6578
6579
6580 attributes = Fcons (Fcons (Qname, build_string ("combined screen")),
6581 attributes);
6582
6583 frames = Qnil;
6584 FOR_EACH_FRAME (rest, frame)
6585 {
6586 struct frame *f = XFRAME (frame);
6587
6588 if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
6589 frames = Fcons (frame, frames);
6590 }
6591 attributes = Fcons (Fcons (Qframes, frames), attributes);
6592
6593 pixel_width = w32_display_pixel_width (dpyinfo);
6594 pixel_height = w32_display_pixel_height (dpyinfo);
6595
6596 hdc = GetDC (NULL);
6597 mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE)
6598 / GetDeviceCaps (hdc, HORZRES));
6599 width_mm = pixel_width * mm_per_pixel + 0.5;
6600 mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE)
6601 / GetDeviceCaps (hdc, VERTRES));
6602 height_mm = pixel_height * mm_per_pixel + 0.5;
6603 ReleaseDC (NULL, hdc);
6604 attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)),
6605 attributes);
6606
6607
6608
6609 geometry = list4i (GetSystemMetrics (SM_XVIRTUALSCREEN),
6610 GetSystemMetrics (SM_YVIRTUALSCREEN),
6611 pixel_width, pixel_height);
6612 if (SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0))
6613 workarea = list4i (workarea_rect.left, workarea_rect.top,
6614 workarea_rect.right - workarea_rect.left,
6615 workarea_rect.bottom - workarea_rect.top);
6616 else
6617 workarea = geometry;
6618 attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
6619
6620 attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
6621
6622 return list1 (attributes);
6623 }
6624
6625 DEFUN ("w32-display-monitor-attributes-list", Fw32_display_monitor_attributes_list,
6626 Sw32_display_monitor_attributes_list,
6627 0, 1, 0,
6628 doc:
6629
6630
6631
6632
6633
6634 )
6635 (Lisp_Object display)
6636 {
6637 struct w32_display_info *dpyinfo = check_x_display_info (display);
6638 Lisp_Object attributes_list;
6639
6640 block_input ();
6641 attributes_list = w32_display_monitor_attributes_list ();
6642 if (NILP (attributes_list))
6643 attributes_list = w32_display_monitor_attributes_list_fallback (dpyinfo);
6644 unblock_input ();
6645
6646 return attributes_list;
6647 }
6648
6649 DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
6650 doc:
6651
6652
6653
6654 )
6655 (Lisp_Object sound)
6656 {
6657 CHECK_SYMBOL (sound);
6658
6659 if (NILP (sound))
6660 sound_type = 0xFFFFFFFF;
6661 else if (EQ (sound, intern ("asterisk")))
6662 sound_type = MB_ICONASTERISK;
6663 else if (EQ (sound, intern ("exclamation")))
6664 sound_type = MB_ICONEXCLAMATION;
6665 else if (EQ (sound, intern ("hand")))
6666 sound_type = MB_ICONHAND;
6667 else if (EQ (sound, intern ("question")))
6668 sound_type = MB_ICONQUESTION;
6669 else if (EQ (sound, intern ("ok")))
6670 sound_type = MB_OK;
6671 else if (EQ (sound, intern ("silent")))
6672 sound_type = MB_EMACS_SILENT;
6673 else
6674 sound_type = 0xFFFFFFFF;
6675
6676 return sound;
6677 }
6678
6679
6680
6681
6682
6683 static struct w32_display_info *
6684 w32_display_info_for_name (Lisp_Object name)
6685 {
6686 struct w32_display_info *dpyinfo;
6687
6688 CHECK_STRING (name);
6689
6690 for (dpyinfo = &one_w32_display_info; dpyinfo; dpyinfo = dpyinfo->next)
6691 if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
6692 return dpyinfo;
6693
6694
6695 Vx_resource_name = Vinvocation_name;
6696
6697 validate_x_resource_name ();
6698
6699 dpyinfo = w32_term_init (name, NULL, SSDATA (Vx_resource_name));
6700
6701 if (dpyinfo == 0)
6702 error ("Cannot connect to server %s", SDATA (name));
6703
6704 return dpyinfo;
6705 }
6706
6707 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
6708 1, 3, 0, doc: )
6709 (Lisp_Object display, Lisp_Object xrm_string, Lisp_Object must_succeed)
6710 {
6711 char *xrm_option;
6712 struct w32_display_info *dpyinfo;
6713
6714 CHECK_STRING (display);
6715
6716
6717
6718
6719
6720
6721 if (strcmp (SSDATA (display), "w32") != 0)
6722 error ("The name of the display in this Emacs must be \"w32\"");
6723
6724
6725
6726 if (window_system_available (NULL))
6727 return Qnil;
6728
6729 if (! NILP (xrm_string))
6730 CHECK_STRING (xrm_string);
6731
6732
6733
6734 {
6735 Lisp_Object color_file;
6736
6737 color_file = build_string ("~/rgb.txt");
6738
6739 if (NILP (Ffile_readable_p (color_file)))
6740 color_file =
6741 Fexpand_file_name (build_string ("rgb.txt"),
6742 Fsymbol_value (intern ("data-directory")));
6743
6744 Vw32_color_map = Fx_load_color_file (color_file);
6745 }
6746 if (NILP (Vw32_color_map))
6747 Vw32_color_map = w32_default_color_map ();
6748
6749
6750 add_system_logical_colors_to_map (&Vw32_color_map);
6751
6752 if (! NILP (xrm_string))
6753 xrm_option = SSDATA (xrm_string);
6754 else
6755 xrm_option = NULL;
6756
6757
6758
6759 {
6760 char basename[ MAX_PATH ], *str;
6761
6762 lispstpcpy (basename, Vinvocation_name);
6763 str = strrchr (basename, '.');
6764 if (str) *str = 0;
6765 Vinvocation_name = build_string (basename);
6766 }
6767 Vx_resource_name = Vinvocation_name;
6768
6769 validate_x_resource_name ();
6770
6771
6772
6773 dpyinfo = w32_term_init (display, xrm_option, SSDATA (Vx_resource_name));
6774
6775 if (dpyinfo == 0)
6776 {
6777 if (!NILP (must_succeed))
6778 fatal ("Cannot connect to server %s.\n",
6779 SDATA (display));
6780 else
6781 error ("Cannot connect to server %s", SDATA (display));
6782 }
6783
6784 return Qnil;
6785 }
6786
6787 DEFUN ("x-close-connection", Fx_close_connection,
6788 Sx_close_connection, 1, 1, 0,
6789 doc: )
6790 (Lisp_Object display)
6791 {
6792 struct w32_display_info *dpyinfo = check_x_display_info (display);
6793
6794 if (dpyinfo->reference_count > 0)
6795 error ("Display still has frames on it");
6796
6797 block_input ();
6798 image_destroy_all_bitmaps (dpyinfo);
6799
6800 w32_delete_display (dpyinfo);
6801 unblock_input ();
6802
6803 return Qnil;
6804 }
6805
6806 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
6807 doc: )
6808 (void)
6809 {
6810 Lisp_Object result = Qnil;
6811 struct w32_display_info *wdi;
6812
6813 for (wdi = x_display_list; wdi; wdi = wdi->next)
6814 result = Fcons (XCAR (wdi->name_list_element), result);
6815
6816 return result;
6817 }
6818
6819 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
6820 doc: )
6821 (Lisp_Object on, Lisp_Object display)
6822 {
6823 return Qnil;
6824 }
6825
6826
6827
6828
6829
6830
6831
6832 #if 0
6833
6834 DEFUN ("x-change-window-property", Fx_change_window_property,
6835 Sx_change_window_property, 2, 6, 0,
6836 doc: )
6837 (Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
6838 Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
6839 {
6840 struct frame *f = decode_window_system_frame (frame);
6841 Atom prop_atom;
6842
6843 CHECK_STRING (prop);
6844 CHECK_STRING (value);
6845
6846 block_input ();
6847 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
6848 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
6849 prop_atom, XA_STRING, 8, PropModeReplace,
6850 SDATA (value), SCHARS (value));
6851
6852
6853 XFlush (FRAME_W32_DISPLAY (f));
6854 unblock_input ();
6855
6856 return value;
6857 }
6858
6859
6860 DEFUN ("x-delete-window-property", Fx_delete_window_property,
6861 Sx_delete_window_property, 1, 2, 0,
6862 doc: )
6863 (Lisp_Object prop, Lisp_Object frame)
6864 {
6865 struct frame *f = decode_window_system_frame (frame);
6866 Atom prop_atom;
6867
6868 CHECK_STRING (prop);
6869 block_input ();
6870 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
6871 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
6872
6873
6874 XFlush (FRAME_W32_DISPLAY (f));
6875 unblock_input ();
6876
6877 return prop;
6878 }
6879
6880
6881 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
6882 1, 6, 0,
6883 doc: )
6884 (Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
6885 Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
6886 {
6887 struct frame *f = decode_window_system_frame (frame);
6888 Atom prop_atom;
6889 int rc;
6890 Lisp_Object prop_value = Qnil;
6891 char *tmp_data = NULL;
6892 Atom actual_type;
6893 int actual_format;
6894 unsigned long actual_size, bytes_remaining;
6895
6896 CHECK_STRING (prop);
6897 block_input ();
6898 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
6899 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
6900 prop_atom, 0, 0, False, XA_STRING,
6901 &actual_type, &actual_format, &actual_size,
6902 &bytes_remaining, (unsigned char **) &tmp_data);
6903 if (rc == Success)
6904 {
6905 int size = bytes_remaining;
6906
6907 XFree (tmp_data);
6908 tmp_data = NULL;
6909
6910 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
6911 prop_atom, 0, bytes_remaining,
6912 False, XA_STRING,
6913 &actual_type, &actual_format,
6914 &actual_size, &bytes_remaining,
6915 (unsigned char **) &tmp_data);
6916 if (rc == Success)
6917 prop_value = make_string (tmp_data, size);
6918
6919 XFree (tmp_data);
6920 }
6921
6922 unblock_input ();
6923
6924 return prop_value;
6925
6926 return Qnil;
6927 }
6928
6929 #endif
6930
6931
6932
6933
6934
6935 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
6936 Lisp_Object, int, int, int *, int *);
6937
6938
6939 Lisp_Object tip_frame;
6940
6941
6942
6943 Window tip_window;
6944
6945
6946
6947 Lisp_Object tip_timer;
6948
6949
6950 Lisp_Object tip_last_string;
6951
6952
6953 Lisp_Object tip_last_frame;
6954
6955
6956 Lisp_Object tip_last_parms;
6957
6958
6959 static void
6960 unwind_create_tip_frame (Lisp_Object frame)
6961 {
6962 Lisp_Object deleted;
6963
6964 deleted = unwind_create_frame (frame);
6965 if (EQ (deleted, Qt))
6966 {
6967 tip_window = NULL;
6968 tip_frame = Qnil;
6969 }
6970 }
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981 static Lisp_Object
6982 w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
6983 {
6984 struct frame *f;
6985 Lisp_Object frame;
6986 Lisp_Object name;
6987 specpdl_ref count = SPECPDL_INDEX ();
6988 struct kboard *kb;
6989 bool face_change_before = face_change;
6990
6991
6992
6993 Vx_resource_name = Vinvocation_name;
6994
6995 kb = dpyinfo->terminal->kboard;
6996
6997
6998
6999
7000 parms = Fcopy_alist (parms);
7001
7002
7003 name = gui_display_get_arg (dpyinfo, parms, Qname, "name", "Name",
7004 RES_TYPE_STRING);
7005 if (!STRINGP (name)
7006 && !BASE_EQ (name, Qunbound)
7007 && !NILP (name))
7008 error ("Invalid frame name--not a string or nil");
7009 Vx_resource_name = name;
7010
7011 frame = Qnil;
7012
7013 f = make_frame (false);
7014 f->wants_modeline = false;
7015 XSETFRAME (frame, f);
7016
7017 record_unwind_protect (unwind_create_tip_frame, frame);
7018
7019
7020
7021
7022
7023 f->terminal = dpyinfo->terminal;
7024 f->output_method = output_w32;
7025 f->output_data.w32 = xzalloc (sizeof (struct w32_output));
7026
7027 FRAME_FONTSET (f) = -1;
7028 fset_icon_name (f, Qnil);
7029 f->tooltip = true;
7030
7031 #ifdef GLYPH_DEBUG
7032 image_cache_refcount =
7033 FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
7034 dpyinfo_refcount = dpyinfo->reference_count;
7035 #endif
7036 FRAME_KBOARD (f) = kb;
7037
7038
7039
7040 if (BASE_EQ (name, Qunbound) || NILP (name))
7041 {
7042 fset_name (f, build_string (dpyinfo->w32_id_name));
7043 f->explicit_name = false;
7044 }
7045 else
7046 {
7047 fset_name (f, name);
7048 f->explicit_name = true;
7049
7050 specbind (Qx_resource_name, name);
7051 }
7052
7053 #ifdef HAVE_HARFBUZZ
7054 if (harfbuzz_available)
7055 register_font_driver (&harfbuzz_font_driver, f);
7056 #endif
7057 register_font_driver (&uniscribe_font_driver, f);
7058 register_font_driver (&w32font_driver, f);
7059
7060 gui_default_parameter (f, parms, Qfont_backend, Qnil,
7061 "fontBackend", "FontBackend", RES_TYPE_STRING);
7062
7063
7064
7065 w32_default_font_parameter (f, parms);
7066
7067 gui_default_parameter (f, parms, Qborder_width, make_fixnum (2),
7068 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
7069
7070
7071
7072 if (NILP (Fassq (Qinternal_border_width, parms)))
7073 {
7074 Lisp_Object value;
7075
7076 value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
7077 "internalBorder", "internalBorder",
7078 RES_TYPE_NUMBER);
7079 if (! BASE_EQ (value, Qunbound))
7080 parms = Fcons (Fcons (Qinternal_border_width, value),
7081 parms);
7082 }
7083
7084 gui_default_parameter (f, parms, Qinternal_border_width, make_fixnum (1),
7085 "internalBorderWidth", "internalBorderWidth",
7086 RES_TYPE_NUMBER);
7087
7088 gui_default_parameter (f, parms, Qforeground_color, build_string ("black"),
7089 "foreground", "Foreground", RES_TYPE_STRING);
7090 gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
7091 "background", "Background", RES_TYPE_STRING);
7092 gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
7093 "pointerColor", "Foreground", RES_TYPE_STRING);
7094 gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
7095 "cursorColor", "Foreground", RES_TYPE_STRING);
7096 gui_default_parameter (f, parms, Qborder_color, build_string ("black"),
7097 "borderColor", "BorderColor", RES_TYPE_STRING);
7098 gui_default_parameter (f, parms, Qno_special_glyphs, Qt,
7099 NULL, NULL, RES_TYPE_BOOLEAN);
7100
7101
7102
7103
7104 init_frame_faces (f);
7105
7106 f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
7107 f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
7108 f->output_data.w32->explicit_parent = false;
7109
7110 gui_figure_window_size (f, parms, true, true);
7111
7112
7113 f->fringe_cols = 0;
7114 f->left_fringe_width = 0;
7115 f->right_fringe_width = 0;
7116
7117 f->right_divider_width = 0;
7118 f->bottom_divider_width = 0;
7119
7120 block_input ();
7121 my_create_tip_window (f);
7122 unblock_input ();
7123
7124 w32_make_gc (f);
7125
7126 gui_default_parameter (f, parms, Qauto_raise, Qnil,
7127 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
7128 gui_default_parameter (f, parms, Qauto_lower, Qnil,
7129 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
7130 gui_default_parameter (f, parms, Qcursor_type, Qbox,
7131 "cursorType", "CursorType", RES_TYPE_SYMBOL);
7132
7133 gui_default_parameter (f, parms, Qalpha, Qnil,
7134 "alpha", "Alpha", RES_TYPE_NUMBER);
7135 gui_default_parameter (f, parms, Qalpha_background, Qnil,
7136 "alphaBackground", "AlphaBackground", RES_TYPE_NUMBER);
7137 gui_default_parameter (f, parms, Qinhibit_double_buffering, Qnil,
7138 "inhibitDoubleBuffering", "InhibitDoubleBuffering",
7139 RES_TYPE_BOOLEAN);
7140
7141
7142 if (NILP (Fframe_parameter (frame, Qtooltip)))
7143 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153 {
7154 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
7155 Lisp_Object fg = Fframe_parameter (frame, Qforeground_color);
7156 Lisp_Object colors = Qnil;
7157
7158 call2 (Qface_set_after_frame_default, frame, Qnil);
7159
7160 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
7161 colors = Fcons (Fcons (Qbackground_color, bg), colors);
7162 if (!EQ (fg, Fframe_parameter (frame, Qforeground_color)))
7163 colors = Fcons (Fcons (Qforeground_color, fg), colors);
7164
7165 if (!NILP (colors))
7166 Fmodify_frame_parameters (frame, colors);
7167 }
7168
7169 f->no_split = true;
7170
7171
7172
7173 FRAME_DISPLAY_INFO (f)->reference_count++;
7174 f->terminal->reference_count++;
7175
7176
7177
7178
7179 Vframe_list = Fcons (frame, Vframe_list);
7180 f->can_set_window_size = true;
7181 adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
7182 0, true, Qtip_frame);
7183
7184
7185
7186
7187
7188
7189 face_change = face_change_before;
7190
7191
7192 return unbind_to (count, frame);
7193 }
7194
7195
7196
7197
7198
7199
7200
7201
7202 static void
7203 compute_tip_xy (struct frame *f,
7204 Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
7205 int width, int height, int *root_x, int *root_y)
7206 {
7207 Lisp_Object left, top, right, bottom;
7208 int min_x = 0, min_y = 0, max_x = 0, max_y = 0;
7209
7210
7211 left = Fcdr (Fassq (Qleft, parms));
7212 top = Fcdr (Fassq (Qtop, parms));
7213 right = Fcdr (Fassq (Qright, parms));
7214 bottom = Fcdr (Fassq (Qbottom, parms));
7215
7216
7217
7218 if ((!FIXNUMP (left) && !FIXNUMP (right))
7219 || (!FIXNUMP (top) && !FIXNUMP (bottom)))
7220 {
7221 POINT pt;
7222
7223
7224 min_x = 0;
7225 min_y = 0;
7226 max_x = w32_display_pixel_width (FRAME_DISPLAY_INFO (f));
7227 max_y = w32_display_pixel_height (FRAME_DISPLAY_INFO (f));
7228
7229 block_input ();
7230 GetCursorPos (&pt);
7231 *root_x = pt.x;
7232 *root_y = pt.y;
7233 unblock_input ();
7234
7235
7236
7237
7238
7239
7240
7241 if (monitor_from_point_fn && get_monitor_info_fn)
7242 {
7243 struct MONITOR_INFO info;
7244 HMONITOR monitor
7245 = monitor_from_point_fn (pt, MONITOR_DEFAULT_TO_NEAREST);
7246 info.cbSize = sizeof (info);
7247
7248 if (get_monitor_info_fn (monitor, &info))
7249 {
7250 min_x = info.rcWork.left;
7251 min_y = info.rcWork.top;
7252 max_x = info.rcWork.right;
7253 max_y = info.rcWork.bottom;
7254 }
7255 }
7256 }
7257
7258 if (FIXNUMP (top))
7259 *root_y = XFIXNUM (top);
7260 else if (FIXNUMP (bottom))
7261 *root_y = XFIXNUM (bottom) - height;
7262 else if (*root_y + XFIXNUM (dy) <= min_y)
7263 *root_y = min_y;
7264 else if (*root_y + XFIXNUM (dy) + height <= max_y)
7265
7266 *root_y += XFIXNUM (dy);
7267 else if (height + XFIXNUM (dy) + min_y <= *root_y)
7268
7269 *root_y -= height + XFIXNUM (dy);
7270 else
7271
7272 *root_y = min_y;
7273
7274 if (FIXNUMP (left))
7275 *root_x = XFIXNUM (left);
7276 else if (FIXNUMP (right))
7277 *root_x = XFIXNUM (right) - width;
7278 else if (*root_x + XFIXNUM (dx) <= min_x)
7279 *root_x = 0;
7280 else if (*root_x + XFIXNUM (dx) + width <= max_x)
7281
7282 *root_x += XFIXNUM (dx);
7283 else if (width + XFIXNUM (dx) + min_x <= *root_x)
7284
7285 *root_x -= width + XFIXNUM (dx);
7286 else
7287
7288 *root_x = min_x;
7289 }
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302 static Lisp_Object
7303 w32_hide_tip (bool delete)
7304 {
7305 if (!NILP (tip_timer))
7306 {
7307 call1 (Qcancel_timer, tip_timer);
7308 tip_timer = Qnil;
7309 }
7310
7311 if (NILP (tip_frame)
7312 || (!delete && FRAMEP (tip_frame)
7313 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
7314 return Qnil;
7315 else
7316 {
7317 Lisp_Object was_open = Qnil;
7318
7319 specpdl_ref count = SPECPDL_INDEX ();
7320 specbind (Qinhibit_redisplay, Qt);
7321 specbind (Qinhibit_quit, Qt);
7322
7323 if (FRAMEP (tip_frame))
7324 {
7325 if (FRAME_LIVE_P (XFRAME (tip_frame)))
7326 {
7327 if (delete)
7328 {
7329 delete_frame (tip_frame, Qnil);
7330 tip_frame = Qnil;
7331 }
7332 else
7333 w32_make_frame_invisible (XFRAME (tip_frame));
7334
7335 was_open = Qt;
7336 }
7337 else
7338 tip_frame = Qnil;
7339 }
7340 else
7341 tip_frame = Qnil;
7342
7343 return unbind_to (count, was_open);
7344 }
7345 }
7346
7347
7348 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
7349 doc: )
7350 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
7351 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
7352 {
7353 struct frame *tip_f;
7354 struct window *w;
7355 int root_x, root_y;
7356 struct buffer *old_buffer;
7357 struct text_pos pos;
7358 int width, height;
7359 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7360 specpdl_ref count = SPECPDL_INDEX ();
7361 Lisp_Object window, size, tip_buf;
7362 AUTO_STRING (tip, " *tip*");
7363
7364 specbind (Qinhibit_redisplay, Qt);
7365
7366 CHECK_STRING (string);
7367
7368 if (NILP (frame))
7369 frame = selected_frame;
7370 decode_window_system_frame (frame);
7371
7372 if (NILP (timeout))
7373 timeout = Vx_show_tooltip_timeout;
7374 CHECK_FIXNAT (timeout);
7375
7376 if (NILP (dx))
7377 dx = make_fixnum (5);
7378 else
7379 CHECK_FIXNUM (dx);
7380
7381 if (NILP (dy))
7382 dy = make_fixnum (-10);
7383 else
7384 CHECK_FIXNUM (dy);
7385
7386 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
7387 {
7388 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
7389 && EQ (frame, tip_last_frame)
7390 && !NILP (Fequal_including_properties (string, tip_last_string))
7391 && !NILP (Fequal (parms, tip_last_parms)))
7392 {
7393
7394 tip_f = XFRAME (tip_frame);
7395 if (!NILP (tip_timer))
7396 {
7397 Lisp_Object timer = tip_timer;
7398
7399 tip_timer = Qnil;
7400 call1 (Qcancel_timer, timer);
7401 }
7402
7403 block_input ();
7404 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
7405 FRAME_PIXEL_HEIGHT (tip_f), &root_x, &root_y);
7406
7407
7408 SetWindowPos (FRAME_W32_WINDOW (tip_f), HWND_TOPMOST,
7409 root_x, root_y, 0, 0,
7410 SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
7411
7412
7413 SetWindowPos (FRAME_W32_WINDOW (tip_f), HWND_TOP,
7414 0, 0, 0, 0,
7415 SWP_NOMOVE | SWP_NOSIZE
7416 | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
7417
7418
7419 SET_FRAME_VISIBLE (tip_f, 1);
7420 ShowWindow (FRAME_W32_WINDOW (tip_f), SW_SHOWNOACTIVATE);
7421 unblock_input ();
7422
7423 goto start_timer;
7424 }
7425 else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
7426 {
7427 bool delete = false;
7428 Lisp_Object tail, elt, parm, last;
7429
7430
7431
7432
7433 for (tail = parms; CONSP (tail); tail = XCDR (tail))
7434 {
7435 elt = XCAR (tail);
7436 parm = Fcar (elt);
7437
7438
7439 if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
7440 && !EQ (parm, Qright) && !EQ (parm, Qbottom))
7441 {
7442 last = Fassq (parm, tip_last_parms);
7443 if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
7444 {
7445
7446 delete = true;
7447 break;
7448 }
7449 else
7450 tip_last_parms =
7451 call2 (Qassq_delete_all, parm, tip_last_parms);
7452 }
7453 else
7454 tip_last_parms =
7455 call2 (Qassq_delete_all, parm, tip_last_parms);
7456 }
7457
7458
7459
7460 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
7461 {
7462 elt = XCAR (tail);
7463 parm = Fcar (elt);
7464 if (!EQ (parm, Qleft) && !EQ (parm, Qtop) && !EQ (parm, Qright)
7465 && !EQ (parm, Qbottom) && !NILP (Fcdr (elt)))
7466 {
7467
7468 delete = true;
7469 break;
7470 }
7471 }
7472
7473 w32_hide_tip (delete);
7474 }
7475 else
7476 w32_hide_tip (true);
7477 }
7478 else
7479 w32_hide_tip (true);
7480
7481 tip_last_frame = frame;
7482 tip_last_string = string;
7483 tip_last_parms = parms;
7484
7485
7486
7487 block_input ();
7488
7489 if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
7490 {
7491
7492 if (NILP (Fassq (Qname, parms)))
7493 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
7494 if (NILP (Fassq (Qinternal_border_width, parms)))
7495 parms = Fcons (Fcons (Qinternal_border_width, make_fixnum (3)), parms);
7496 if (NILP (Fassq (Qborder_width, parms)))
7497 parms = Fcons (Fcons (Qborder_width, make_fixnum (1)), parms);
7498 if (NILP (Fassq (Qborder_color, parms)))
7499 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
7500 parms);
7501 if (NILP (Fassq (Qbackground_color, parms)))
7502 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
7503 parms);
7504
7505
7506
7507 struct frame *f;
7508 if (NILP (tip_frame = w32_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
7509 {
7510
7511 unblock_input ();
7512 return unbind_to (count, Qnil);
7513 }
7514 }
7515
7516 tip_f = XFRAME (tip_frame);
7517 window = FRAME_ROOT_WINDOW (tip_f);
7518 tip_buf = Fget_buffer_create (tip, Qnil);
7519
7520
7521 bset_left_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
7522 bset_right_margin_cols (XBUFFER (tip_buf), make_fixnum (0));
7523 set_window_buffer (window, tip_buf, false, false);
7524 w = XWINDOW (window);
7525 w->pseudo_window_p = true;
7526
7527 Fset_window_parameter (window, Qno_other_window, Qt);
7528
7529
7530
7531
7532
7533 w->left_col = 0;
7534 w->top_line = 0;
7535 w->pixel_left = 0;
7536 w->pixel_top = 0;
7537
7538 if (CONSP (Vx_max_tooltip_size)
7539 && RANGED_FIXNUMP (1, XCAR (Vx_max_tooltip_size), INT_MAX)
7540 && RANGED_FIXNUMP (1, XCDR (Vx_max_tooltip_size), INT_MAX))
7541 {
7542 w->total_cols = XFIXNAT (XCAR (Vx_max_tooltip_size));
7543 w->total_lines = XFIXNAT (XCDR (Vx_max_tooltip_size));
7544 }
7545 else
7546 {
7547 w->total_cols = 80;
7548 w->total_lines = 40;
7549 }
7550
7551 w->pixel_width = w->total_cols * FRAME_COLUMN_WIDTH (tip_f);
7552 w->pixel_height = w->total_lines * FRAME_LINE_HEIGHT (tip_f);
7553 FRAME_TOTAL_COLS (tip_f) = WINDOW_TOTAL_COLS (w);
7554 adjust_frame_glyphs (tip_f);
7555
7556
7557
7558 specpdl_ref count_1 = SPECPDL_INDEX ();
7559 old_buffer = current_buffer;
7560 set_buffer_internal_1 (XBUFFER (w->contents));
7561 bset_truncate_lines (current_buffer, Qnil);
7562 specbind (Qinhibit_read_only, Qt);
7563 specbind (Qinhibit_modification_hooks, Qt);
7564 specbind (Qinhibit_point_motion_hooks, Qt);
7565 Ferase_buffer ();
7566 Finsert (1, &string);
7567 clear_glyph_matrix (w->desired_matrix);
7568 clear_glyph_matrix (w->current_matrix);
7569 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
7570 bool displayed = try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
7571 if (!displayed && NILP (Vx_max_tooltip_size))
7572 {
7573 #ifdef ENABLE_CHECKING
7574 struct glyph_row *row = w->desired_matrix->rows;
7575 struct glyph_row *end =
7576 w->desired_matrix->rows + w->desired_matrix->nrows;
7577 while (row < end)
7578 {
7579 if (!row->displays_text_p
7580 || row->ends_at_zv_p)
7581 break;
7582 ++row;
7583 }
7584 eassert (row < end && row->ends_at_zv_p);
7585 #endif
7586 }
7587
7588 size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
7589 make_fixnum (w->pixel_height), Qnil,
7590 Qnil);
7591
7592 width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
7593 height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
7594
7595 compute_tip_xy (tip_f, parms, dx, dy, width, height, &root_x, &root_y);
7596
7597
7598 {
7599 RECT rect;
7600 int pad = (FIXNUMP (Vw32_tooltip_extra_pixels)
7601 ? max (0, XFIXNUM (Vw32_tooltip_extra_pixels))
7602 : FRAME_COLUMN_WIDTH (tip_f));
7603
7604 rect.left = rect.top = 0;
7605 rect.right = width;
7606 rect.bottom = height;
7607 AdjustWindowRect (&rect, tip_f->output_data.w32->dwStyle,
7608 FRAME_EXTERNAL_MENU_BAR (tip_f));
7609
7610
7611 SetWindowPos (FRAME_W32_WINDOW (tip_f), HWND_TOPMOST,
7612 root_x, root_y,
7613 rect.right - rect.left + pad,
7614 rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER);
7615
7616
7617 SetWindowPos (FRAME_W32_WINDOW (tip_f), HWND_TOP,
7618 0, 0, 0, 0,
7619 SWP_NOMOVE | SWP_NOSIZE
7620 | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
7621
7622
7623 SET_FRAME_VISIBLE (tip_f, 1);
7624
7625 ShowWindow (FRAME_W32_WINDOW (tip_f), SW_SHOWNOACTIVATE);
7626 }
7627
7628 w->must_be_updated_p = true;
7629 update_single_window (w);
7630 set_buffer_internal_1 (old_buffer);
7631 unbind_to (count_1, Qnil);
7632 unblock_input ();
7633 windows_or_buffers_changed = old_windows_or_buffers_changed;
7634
7635 start_timer:
7636
7637 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
7638 intern ("x-hide-tip"));
7639
7640 return unbind_to (count, Qnil);
7641 }
7642
7643
7644 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
7645 doc: )
7646 (void)
7647 {
7648 return w32_hide_tip (!tooltip_reuse_hidden_frame);
7649 }
7650
7651
7652
7653
7654
7655 #define FILE_NAME_TEXT_FIELD edt1
7656 #define FILE_NAME_COMBO_BOX cmb13
7657 #define FILE_NAME_LIST lst1
7658
7659
7660
7661
7662
7663
7664 static UINT_PTR CALLBACK
7665 file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
7666 {
7667 if (msg == WM_NOTIFY)
7668 {
7669 OFNOTIFYW * notify_w = (OFNOTIFYW *)lParam;
7670 OFNOTIFYA * notify_a = (OFNOTIFYA *)lParam;
7671 int dropdown_changed;
7672 int dir_index;
7673 #ifdef NTGUI_UNICODE
7674 const int use_unicode = 1;
7675 #else
7676 int use_unicode = w32_unicode_filenames;
7677 #endif
7678
7679
7680 if (use_unicode)
7681 dropdown_changed =
7682 notify_w->hdr.code == CDN_TYPECHANGE
7683 || notify_w->hdr.code == CDN_INITDONE;
7684 else
7685 dropdown_changed =
7686 notify_a->hdr.code == CDN_TYPECHANGE
7687 || notify_a->hdr.code == CDN_INITDONE;
7688 if (dropdown_changed)
7689 {
7690 HWND dialog = GetParent (hwnd);
7691 HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
7692 HWND list = GetDlgItem (dialog, FILE_NAME_LIST);
7693 int hdr_code;
7694
7695
7696
7697
7698
7699 if (edit_control == NULL)
7700 {
7701 HWND tmp = GetDlgItem (dialog, FILE_NAME_COMBO_BOX);
7702 if (tmp)
7703 {
7704 tmp = GetWindow (tmp, GW_CHILD);
7705 if (tmp)
7706 edit_control = GetWindow (tmp, GW_CHILD);
7707 }
7708 }
7709
7710
7711 if (use_unicode)
7712 {
7713 dir_index = notify_w->lpOFN->nFilterIndex;
7714 hdr_code = notify_w->hdr.code;
7715 }
7716 else
7717 {
7718 dir_index = notify_a->lpOFN->nFilterIndex;
7719 hdr_code = notify_a->hdr.code;
7720 }
7721 if (dir_index == 2)
7722 {
7723 if (use_unicode)
7724 SendMessageW (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD,
7725 (LPARAM)L"Current Directory");
7726 else
7727 SendMessageA (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD,
7728 (LPARAM)"Current Directory");
7729 EnableWindow (edit_control, FALSE);
7730
7731
7732
7733
7734
7735
7736 if (hdr_code == CDN_INITDONE)
7737 SetFocus (list);
7738 }
7739 else
7740 {
7741
7742 if (hdr_code == CDN_TYPECHANGE)
7743 {
7744 if (use_unicode)
7745 SendMessageW (dialog, CDM_SETCONTROLTEXT,
7746 FILE_NAME_TEXT_FIELD, (LPARAM)L"");
7747 else
7748 SendMessageA (dialog, CDM_SETCONTROLTEXT,
7749 FILE_NAME_TEXT_FIELD, (LPARAM)"");
7750 }
7751 EnableWindow (edit_control, TRUE);
7752 }
7753 }
7754 }
7755 return 0;
7756 }
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773 void
7774 w32_dialog_in_progress (Lisp_Object in_progress)
7775 {
7776 Lisp_Object frames, frame;
7777
7778
7779
7780 if (!w32_disable_double_buffering)
7781 {
7782 enter_crit ();
7783 w32_selection_dialog_open = !NILP (in_progress);
7784 leave_crit ();
7785 }
7786
7787
7788 FOR_EACH_FRAME (frames, frame)
7789 {
7790 struct frame *f = XFRAME (frame);
7791
7792 if (!NILP (in_progress) && FRAME_Z_GROUP_ABOVE (f))
7793 w32_set_z_group (f, Qabove_suspended, Qabove);
7794 else if (NILP (in_progress) && FRAME_Z_GROUP_ABOVE_SUSPENDED (f))
7795 w32_set_z_group (f, Qabove, Qabove_suspended);
7796 }
7797 }
7798
7799 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
7800 doc: )
7801 (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
7802 {
7803
7804 static const wchar_t filter_w[] = L"All Files (*.*)\0*.*\0Directories\0*|*\0";
7805 #ifndef NTGUI_UNICODE
7806 static const char filter_a[] = "All Files (*.*)\0*.*\0Directories\0*|*\0";
7807 #endif
7808
7809 Lisp_Object filename = default_filename;
7810 struct frame *f = SELECTED_FRAME ();
7811 BOOL file_opened = FALSE;
7812 Lisp_Object orig_dir = dir;
7813 Lisp_Object orig_prompt = prompt;
7814
7815
7816
7817
7818
7819 struct {
7820 OPENFILENAMEW details;
7821 #if _WIN32_WINNT < 0x500
7822 PVOID pvReserved;
7823 DWORD dwReserved;
7824 DWORD FlagsEx;
7825 #endif
7826 } new_file_details_w;
7827
7828 #ifdef NTGUI_UNICODE
7829 wchar_t filename_buf_w[32*1024 + 1];
7830 OPENFILENAMEW * file_details_w = &new_file_details_w.details;
7831 const int use_unicode = 1;
7832 #else
7833 struct {
7834 OPENFILENAMEA details;
7835 #if _WIN32_WINNT < 0x500
7836 PVOID pvReserved;
7837 DWORD dwReserved;
7838 DWORD FlagsEx;
7839 #endif
7840 } new_file_details_a;
7841 wchar_t filename_buf_w[MAX_PATH + 1], dir_w[MAX_PATH];
7842 char filename_buf_a[MAX_PATH + 1], dir_a[MAX_PATH];
7843 OPENFILENAMEW * file_details_w = &new_file_details_w.details;
7844 OPENFILENAMEA * file_details_a = &new_file_details_a.details;
7845 int use_unicode = w32_unicode_filenames;
7846 wchar_t *prompt_w;
7847 char *prompt_a UNINIT;
7848 int len;
7849 char fname_ret[MAX_UTF8_PATH];
7850 #endif
7851
7852 {
7853
7854
7855
7856
7857
7858 CHECK_STRING (prompt);
7859 CHECK_STRING (dir);
7860
7861 dir = Fexpand_file_name (dir, Qnil);
7862
7863 if (STRINGP (filename))
7864 filename = Ffile_name_nondirectory (filename);
7865 else
7866 filename = empty_unibyte_string;
7867
7868 #ifdef CYGWIN
7869 dir = Fcygwin_convert_file_name_to_windows (dir, Qt);
7870 if (SCHARS (filename) > 0)
7871 filename = Fcygwin_convert_file_name_to_windows (filename, Qnil);
7872 #endif
7873
7874 CHECK_STRING (dir);
7875 CHECK_STRING (filename);
7876
7877
7878
7879
7880
7881 if (SCHARS (filename) == 0 && ! NILP (only_dir_p))
7882 filename = build_string ("Current Directory");
7883
7884
7885 #ifdef NTGUI_UNICODE
7886 to_unicode (prompt, &prompt);
7887 to_unicode (dir, &dir);
7888 to_unicode (filename, &filename);
7889 if (SBYTES (filename) + 1 > sizeof (filename_buf_w))
7890 report_file_error ("filename too long", default_filename);
7891
7892 memcpy (filename_buf_w, SDATA (filename), SBYTES (filename) + 1);
7893 #else
7894 prompt = ENCODE_FILE (prompt);
7895 dir = ENCODE_FILE (dir);
7896 filename = ENCODE_FILE (filename);
7897
7898
7899 dir = Fcopy_sequence (dir);
7900 unixtodos_filename (SSDATA (dir));
7901 filename = Fcopy_sequence (filename);
7902 unixtodos_filename (SSDATA (filename));
7903 if (SBYTES (filename) >= MAX_UTF8_PATH)
7904 report_file_error ("filename too long", default_filename);
7905 if (w32_unicode_filenames)
7906 {
7907 filename_to_utf16 (SSDATA (dir), dir_w);
7908 if (filename_to_utf16 (SSDATA (filename), filename_buf_w) != 0)
7909 {
7910
7911
7912 if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0)
7913 report_file_error ("filename too long", default_filename);
7914 }
7915 len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
7916 SSDATA (prompt), -1, NULL, 0);
7917 if (len > 32768)
7918 len = 32768;
7919 prompt_w = alloca (len * sizeof (wchar_t));
7920 pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
7921 SSDATA (prompt), -1, prompt_w, len);
7922 }
7923 else
7924 {
7925 filename_to_ansi (SSDATA (dir), dir_a);
7926 if (filename_to_ansi (SSDATA (filename), filename_buf_a) != '\0')
7927 {
7928
7929
7930 if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0)
7931 report_file_error ("filename too long", default_filename);
7932 }
7933 len = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
7934 SSDATA (prompt), -1, NULL, 0);
7935 if (len > 32768)
7936 len = 32768;
7937 prompt_w = alloca (len * sizeof (wchar_t));
7938 pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
7939 SSDATA (prompt), -1, prompt_w, len);
7940 len = pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL);
7941 if (len > 32768)
7942 len = 32768;
7943 prompt_a = alloca (len);
7944 pWideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL);
7945 }
7946 #endif
7947
7948
7949
7950
7951
7952
7953
7954 if (use_unicode)
7955 {
7956 memset (&new_file_details_w, 0, sizeof (new_file_details_w));
7957 if (w32_major_version > 4 && w32_major_version < 95)
7958 file_details_w->lStructSize = sizeof (new_file_details_w);
7959 else
7960 file_details_w->lStructSize = sizeof (*file_details_w);
7961
7962 file_details_w->lpstrFile = filename_buf_w;
7963 file_details_w->nMaxFile =
7964 sizeof (filename_buf_w) / sizeof (*filename_buf_w);
7965 file_details_w->hwndOwner = FRAME_W32_WINDOW (f);
7966
7967
7968 file_details_w->lpstrFilter = filter_w;
7969 #ifdef NTGUI_UNICODE
7970 file_details_w->lpstrInitialDir = (wchar_t*) SDATA (dir);
7971 file_details_w->lpstrTitle = (guichar_t*) SDATA (prompt);
7972 #else
7973 file_details_w->lpstrInitialDir = dir_w;
7974 file_details_w->lpstrTitle = prompt_w;
7975 #endif
7976 file_details_w->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
7977 file_details_w->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
7978 | OFN_EXPLORER | OFN_ENABLEHOOK);
7979 if (!NILP (mustmatch))
7980 {
7981
7982 file_details_w->Flags |= OFN_PATHMUSTEXIST;
7983
7984 if (NILP (only_dir_p))
7985 file_details_w->Flags |= OFN_FILEMUSTEXIST;
7986 }
7987 }
7988 #ifndef NTGUI_UNICODE
7989 else
7990 {
7991 memset (&new_file_details_a, 0, sizeof (new_file_details_a));
7992 if (w32_major_version > 4 && w32_major_version < 95)
7993 file_details_a->lStructSize = sizeof (new_file_details_a);
7994 else
7995 file_details_a->lStructSize = sizeof (*file_details_a);
7996 file_details_a->lpstrFile = filename_buf_a;
7997 file_details_a->nMaxFile =
7998 sizeof (filename_buf_a) / sizeof (*filename_buf_a);
7999 file_details_a->hwndOwner = FRAME_W32_WINDOW (f);
8000 file_details_a->lpstrFilter = filter_a;
8001 file_details_a->lpstrInitialDir = dir_a;
8002 file_details_a->lpstrTitle = prompt_a;
8003 file_details_a->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
8004 file_details_a->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
8005 | OFN_EXPLORER | OFN_ENABLEHOOK);
8006 if (!NILP (mustmatch))
8007 {
8008
8009 file_details_a->Flags |= OFN_PATHMUSTEXIST;
8010
8011 if (NILP (only_dir_p))
8012 file_details_a->Flags |= OFN_FILEMUSTEXIST;
8013 }
8014 }
8015 #endif
8016
8017 {
8018 specpdl_ref count = SPECPDL_INDEX ();
8019
8020 w32_dialog_in_progress (Qt);
8021
8022
8023 specbind (Qinhibit_redisplay, Qt);
8024 record_unwind_protect (w32_dialog_in_progress, Qnil);
8025 block_input ();
8026 if (use_unicode)
8027 {
8028 file_details_w->lpfnHook = file_dialog_callback;
8029
8030 file_opened = GetOpenFileNameW (file_details_w);
8031 }
8032 #ifndef NTGUI_UNICODE
8033 else
8034 {
8035 file_details_a->lpfnHook = file_dialog_callback;
8036
8037 file_opened = GetOpenFileNameA (file_details_a);
8038 }
8039 #endif
8040 unblock_input ();
8041 unbind_to (count, Qnil);
8042 }
8043
8044 if (file_opened)
8045 {
8046
8047 #ifdef NTGUI_UNICODE
8048 filename = from_unicode_buffer (filename_buf_w);
8049 #else
8050 if (use_unicode)
8051 filename_from_utf16 (filename_buf_w, fname_ret);
8052 else
8053 filename_from_ansi (filename_buf_a, fname_ret);
8054 dostounix_filename (fname_ret);
8055 filename = DECODE_FILE (build_unibyte_string (fname_ret));
8056 #endif
8057
8058 #ifdef CYGWIN
8059 filename = Fcygwin_convert_file_name_from_windows (filename, Qt);
8060 #endif
8061
8062
8063
8064 if ((use_unicode && file_details_w->nFilterIndex == 2)
8065 #ifndef NTGUI_UNICODE
8066 || (!use_unicode && file_details_a->nFilterIndex == 2)
8067 #endif
8068 )
8069 filename = Ffile_name_directory (filename);
8070 }
8071
8072 else if (!CommDlgExtendedError ())
8073 filename = Qnil;
8074
8075 else
8076 filename = Fcompleting_read (
8077 orig_prompt,
8078 intern ("read-file-name-internal"),
8079 orig_dir,
8080 mustmatch,
8081 orig_dir,
8082 Qfile_name_history,
8083 default_filename,
8084 Qnil);
8085 }
8086
8087
8088 if (NILP (filename))
8089 quit ();
8090
8091 return filename;
8092 }
8093
8094
8095 #ifdef WINDOWSNT
8096
8097
8098 DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
8099 Ssystem_move_file_to_trash, 1, 1, 0,
8100 doc: )
8101 (Lisp_Object filename)
8102 {
8103 Lisp_Object handler;
8104 Lisp_Object encoded_file;
8105 Lisp_Object operation;
8106
8107 operation = Qdelete_file;
8108 if (!NILP (Ffile_directory_p (filename))
8109 && NILP (Ffile_symlink_p (filename)))
8110 {
8111 operation = intern ("delete-directory");
8112 filename = Fdirectory_file_name (filename);
8113 }
8114
8115
8116
8117 filename = Fexpand_file_name (filename, Qnil);
8118
8119 handler = Ffind_file_name_handler (filename, operation);
8120 if (!NILP (handler))
8121 return call2 (handler, operation, filename);
8122 else
8123 {
8124 const char * path;
8125 int result;
8126
8127 encoded_file = ENCODE_FILE (filename);
8128
8129 path = map_w32_filename (SSDATA (encoded_file), NULL);
8130
8131
8132
8133 if (w32_unicode_filenames && os_subtype != OS_SUBTYPE_9X)
8134 {
8135 SHFILEOPSTRUCTW file_op_w;
8136
8137
8138
8139 wchar_t tmp_path_w[MAX_PATH + 1];
8140
8141 memset (tmp_path_w, 0, sizeof (tmp_path_w));
8142 filename_to_utf16 (path, tmp_path_w);
8143
8144
8145 _wchmod (tmp_path_w, 0666);
8146
8147 memset (&file_op_w, 0, sizeof (file_op_w));
8148 file_op_w.hwnd = HWND_DESKTOP;
8149 file_op_w.wFunc = FO_DELETE;
8150 file_op_w.pFrom = tmp_path_w;
8151 file_op_w.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO
8152 | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
8153 file_op_w.fAnyOperationsAborted = FALSE;
8154
8155 result = SHFileOperationW (&file_op_w);
8156 }
8157 else
8158 {
8159 SHFILEOPSTRUCTA file_op_a;
8160 char tmp_path_a[MAX_PATH + 1];
8161
8162 memset (tmp_path_a, 0, sizeof (tmp_path_a));
8163 filename_to_ansi (path, tmp_path_a);
8164
8165
8166
8167
8168 if (_mbspbrk ((unsigned char *)tmp_path_a,
8169 (const unsigned char *)"?*"))
8170 result = ERROR_FILE_NOT_FOUND;
8171 else
8172 {
8173 _chmod (tmp_path_a, 0666);
8174
8175 memset (&file_op_a, 0, sizeof (file_op_a));
8176 file_op_a.hwnd = HWND_DESKTOP;
8177 file_op_a.wFunc = FO_DELETE;
8178 file_op_a.pFrom = tmp_path_a;
8179 file_op_a.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO
8180 | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
8181 file_op_a.fAnyOperationsAborted = FALSE;
8182
8183 result = SHFileOperationA (&file_op_a);
8184 }
8185 }
8186 if (result != 0)
8187 report_file_error ("Removing old name", list1 (filename));
8188 }
8189 return Qnil;
8190 }
8191
8192 #endif
8193
8194
8195
8196
8197
8198
8199 DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
8200 Sw32_send_sys_command, 1, 2, 0,
8201 doc:
8202
8203
8204
8205
8206
8207 )
8208 (Lisp_Object command, Lisp_Object frame)
8209 {
8210 struct frame *f = decode_window_system_frame (frame);
8211
8212 CHECK_FIXNUM (command);
8213
8214 if (FRAME_W32_P (f))
8215 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XFIXNUM (command), 0);
8216
8217 return Qnil;
8218 }
8219
8220 DEFUN ("w32-shell-execute", Fw32_shell_execute, Sw32_shell_execute, 2, 4, 0,
8221 doc:
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285 )
8286 (Lisp_Object operation, Lisp_Object document, Lisp_Object parameters, Lisp_Object show_flag)
8287 {
8288 char *errstr;
8289 Lisp_Object current_dir = BVAR (current_buffer, directory);;
8290 wchar_t *doc_w = NULL, *params_w = NULL, *ops_w = NULL;
8291 #ifdef CYGWIN
8292 intptr_t result;
8293 #else
8294 int use_unicode = w32_unicode_filenames;
8295 char *doc_a = NULL, *params_a = NULL, *ops_a = NULL;
8296 Lisp_Object absdoc, handler;
8297 BOOL success;
8298 #endif
8299
8300 CHECK_STRING (document);
8301
8302 #ifdef CYGWIN
8303 current_dir = Fcygwin_convert_file_name_to_windows (current_dir, Qt);
8304 document = Fcygwin_convert_file_name_to_windows (document, Qt);
8305
8306
8307 current_dir = GUI_ENCODE_FILE (current_dir);
8308 document = GUI_ENCODE_FILE (document);
8309 if (STRINGP (parameters))
8310 {
8311 parameters = GUI_ENCODE_SYSTEM (parameters);
8312 params_w = GUI_SDATA (parameters);
8313 }
8314 if (STRINGP (operation))
8315 {
8316 operation = GUI_ENCODE_SYSTEM (operation);
8317 ops_w = GUI_SDATA (operation);
8318 }
8319 doc_w = GUI_SDATA (document);
8320 result = (intptr_t) ShellExecuteW (NULL, ops_w, doc_w, params_w,
8321 GUI_SDATA (current_dir),
8322 (FIXNUMP (show_flag)
8323 ? XFIXNUM (show_flag) : SW_SHOWDEFAULT));
8324
8325 if (result > 32)
8326 return Qt;
8327
8328 switch (result)
8329 {
8330 case SE_ERR_ACCESSDENIED:
8331 errstr = w32_strerror (ERROR_ACCESS_DENIED);
8332 break;
8333 case SE_ERR_ASSOCINCOMPLETE:
8334 case SE_ERR_NOASSOC:
8335 errstr = w32_strerror (ERROR_NO_ASSOCIATION);
8336 break;
8337 case SE_ERR_DDEBUSY:
8338 case SE_ERR_DDEFAIL:
8339 errstr = w32_strerror (ERROR_DDE_FAIL);
8340 break;
8341 case SE_ERR_DDETIMEOUT:
8342 errstr = w32_strerror (ERROR_TIMEOUT);
8343 break;
8344 case SE_ERR_DLLNOTFOUND:
8345 errstr = w32_strerror (ERROR_DLL_NOT_FOUND);
8346 break;
8347 case SE_ERR_FNF:
8348 errstr = w32_strerror (ERROR_FILE_NOT_FOUND);
8349 break;
8350 case SE_ERR_OOM:
8351 errstr = w32_strerror (ERROR_NOT_ENOUGH_MEMORY);
8352 break;
8353 case SE_ERR_PNF:
8354 errstr = w32_strerror (ERROR_PATH_NOT_FOUND);
8355 break;
8356 case SE_ERR_SHARE:
8357 errstr = w32_strerror (ERROR_SHARING_VIOLATION);
8358 break;
8359 default:
8360 errstr = w32_strerror (0);
8361 break;
8362 }
8363
8364 #else
8365
8366 const char file_url_str[] = "file:///";
8367 const int file_url_len = sizeof (file_url_str) - 1;
8368 int doclen;
8369
8370 if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0)
8371 {
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384 char *p = SSDATA (document) + file_url_len;
8385
8386 if (c_isalpha (*p) && p[1] == ':' && IS_DIRECTORY_SEP (p[2]))
8387 document = Fsubstring_no_properties (document,
8388 make_fixnum (file_url_len), Qnil);
8389 }
8390
8391
8392
8393
8394
8395
8396
8397 absdoc = Fexpand_file_name (document, Qnil);
8398
8399
8400
8401 handler = Ffind_file_name_handler (absdoc, Qfile_exists_p);
8402 if (NILP (handler))
8403 {
8404 Lisp_Object absdoc_encoded = Fcopy_sequence (ENCODE_FILE (absdoc));
8405
8406 if (faccessat (AT_FDCWD, SSDATA (absdoc_encoded), F_OK, AT_EACCESS) == 0)
8407 {
8408
8409
8410
8411
8412 unixtodos_filename (SSDATA (absdoc_encoded));
8413 document = absdoc_encoded;
8414 }
8415 else
8416 document = ENCODE_FILE (document);
8417 }
8418 else
8419 document = ENCODE_FILE (document);
8420
8421 current_dir = ENCODE_FILE (current_dir);
8422
8423
8424 doclen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
8425 SSDATA (document), -1, NULL, 0);
8426 doc_w = xmalloc (doclen * sizeof (wchar_t));
8427 pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
8428 SSDATA (document), -1, doc_w, doclen);
8429 if (use_unicode)
8430 {
8431 wchar_t current_dir_w[MAX_PATH];
8432 SHELLEXECUTEINFOW shexinfo_w;
8433
8434
8435
8436 filename_to_utf16 (SSDATA (current_dir), current_dir_w);
8437 if (STRINGP (parameters))
8438 {
8439 int len;
8440
8441 parameters = ENCODE_SYSTEM (parameters);
8442 len = pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags,
8443 SSDATA (parameters), -1, NULL, 0);
8444 if (len > 32768)
8445 len = 32768;
8446 params_w = alloca (len * sizeof (wchar_t));
8447 pMultiByteToWideChar (CP_ACP, multiByteToWideCharFlags,
8448 SSDATA (parameters), -1, params_w, len);
8449 params_w[len - 1] = 0;
8450 }
8451 if (STRINGP (operation))
8452 {
8453
8454 const char *s = SSDATA (operation);
8455 wchar_t *d;
8456 int len = SBYTES (operation) + 1;
8457
8458 if (len > 32768)
8459 len = 32768;
8460 d = ops_w = alloca (len * sizeof (wchar_t));
8461 while (d < ops_w + len - 1)
8462 *d++ = *s++;
8463 *d = 0;
8464 }
8465
8466
8467
8468
8469
8470 memset (&shexinfo_w, 0, sizeof (shexinfo_w));
8471 shexinfo_w.cbSize = sizeof (shexinfo_w);
8472 shexinfo_w.fMask =
8473 SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
8474 shexinfo_w.hwnd = NULL;
8475 shexinfo_w.lpVerb = ops_w;
8476 shexinfo_w.lpFile = doc_w;
8477 shexinfo_w.lpParameters = params_w;
8478 shexinfo_w.lpDirectory = current_dir_w;
8479 shexinfo_w.nShow =
8480 (FIXNUMP (show_flag) ? XFIXNUM (show_flag) : SW_SHOWDEFAULT);
8481 success = ShellExecuteExW (&shexinfo_w);
8482 xfree (doc_w);
8483 }
8484 else
8485 {
8486 char current_dir_a[MAX_PATH];
8487 SHELLEXECUTEINFOA shexinfo_a;
8488 int codepage = codepage_for_filenames (NULL);
8489 int ldoc_a = pWideCharToMultiByte (codepage, 0, doc_w, -1, NULL, 0,
8490 NULL, NULL);
8491
8492 doc_a = xmalloc (ldoc_a);
8493 pWideCharToMultiByte (codepage, 0, doc_w, -1, doc_a, ldoc_a, NULL, NULL);
8494 filename_to_ansi (SSDATA (current_dir), current_dir_a);
8495 if (STRINGP (parameters))
8496 {
8497 parameters = ENCODE_SYSTEM (parameters);
8498 params_a = SSDATA (parameters);
8499 }
8500 if (STRINGP (operation))
8501 {
8502
8503 ops_a = SSDATA (operation);
8504 }
8505 memset (&shexinfo_a, 0, sizeof (shexinfo_a));
8506 shexinfo_a.cbSize = sizeof (shexinfo_a);
8507 shexinfo_a.fMask =
8508 SEE_MASK_INVOKEIDLIST | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
8509 shexinfo_a.hwnd = NULL;
8510 shexinfo_a.lpVerb = ops_a;
8511 shexinfo_a.lpFile = doc_a;
8512 shexinfo_a.lpParameters = params_a;
8513 shexinfo_a.lpDirectory = current_dir_a;
8514 shexinfo_a.nShow =
8515 (FIXNUMP (show_flag) ? XFIXNUM (show_flag) : SW_SHOWDEFAULT);
8516 success = ShellExecuteExA (&shexinfo_a);
8517 xfree (doc_w);
8518 xfree (doc_a);
8519 }
8520
8521 if (success)
8522 return Qt;
8523
8524 errstr = w32_strerror (0);
8525
8526 #endif
8527
8528
8529 if (!NILP (Vlocale_coding_system))
8530 {
8531 Lisp_Object decoded =
8532 code_convert_string_norecord (build_unibyte_string (errstr),
8533 Vlocale_coding_system, 0);
8534 errstr = SSDATA (decoded);
8535 }
8536 error ("ShellExecute failed: %s", errstr);
8537 }
8538
8539
8540
8541
8542 static int
8543 lookup_vk_code (char *key)
8544 {
8545 int i;
8546
8547 for (i = 0; i < 256; i++)
8548 if (lispy_function_keys[i]
8549 && strcmp (lispy_function_keys[i], key) == 0)
8550 return i;
8551
8552 if (w32_kbdhook_active)
8553 {
8554
8555 if (key[1] == 0)
8556 {
8557 if ((key[0] >= 'A' && key[0] <= 'Z')
8558 || (key[0] >= '0' && key[0] <= '9'))
8559 return key[0];
8560 if (key[0] >= 'a' && key[0] <= 'z')
8561 return toupper(key[0]);
8562 }
8563 }
8564
8565 return -1;
8566 }
8567
8568
8569
8570 static Lisp_Object
8571 w32_parse_and_hook_hot_key (Lisp_Object key, int hook)
8572 {
8573
8574 register Lisp_Object c;
8575 int vk_code = 0;
8576 int lisp_modifiers = 0;
8577 int w32_modifiers;
8578 Lisp_Object res = Qnil;
8579 char* vkname;
8580
8581 CHECK_VECTOR (key);
8582
8583 if (ASIZE (key) != 1)
8584 return Qnil;
8585
8586 c = AREF (key, 0);
8587
8588 if (CONSP (c) && lucid_event_type_list_p (c))
8589 c = Fevent_convert_list (c);
8590
8591 if (! FIXNUMP (c) && ! SYMBOLP (c))
8592 error ("Key definition is invalid");
8593
8594
8595 if (SYMBOLP (c))
8596 {
8597 c = parse_modifiers (c);
8598 lisp_modifiers = XFIXNUM (Fcar (Fcdr (c)));
8599 c = Fcar (c);
8600 if (!SYMBOLP (c))
8601 emacs_abort ();
8602 vkname = SSDATA (SYMBOL_NAME (c));
8603
8604 if (w32_kbdhook_active && vkname[0] == 0)
8605 vk_code = VK_ANY;
8606 else
8607 vk_code = lookup_vk_code (vkname);
8608 }
8609 else if (FIXNUMP (c))
8610 {
8611 lisp_modifiers = XFIXNUM (c) & ~CHARACTERBITS;
8612
8613 vk_code = XFIXNUM (c) & CHARACTERBITS;
8614 }
8615
8616 if (vk_code < 0 || vk_code > 255)
8617 return Qnil;
8618
8619 if ((lisp_modifiers & meta_modifier) != 0
8620 && !NILP (Vw32_alt_is_meta))
8621 lisp_modifiers |= alt_modifier;
8622
8623
8624 #ifndef MOD_ALT
8625 #define MOD_ALT 0x0001
8626 #define MOD_CONTROL 0x0002
8627 #define MOD_SHIFT 0x0004
8628 #define MOD_WIN 0x0008
8629 #endif
8630
8631 if (w32_kbdhook_active)
8632 {
8633
8634 if (lisp_modifiers & alt_modifier)
8635 {
8636 hook_w32_key (hook, VK_MENU, vk_code);
8637 res = Qt;
8638 }
8639
8640 if (((lisp_modifiers & hyper_modifier)
8641 && EQ (Vw32_lwindow_modifier, Qhyper))
8642 || ((lisp_modifiers & super_modifier)
8643 && EQ (Vw32_lwindow_modifier, Qsuper)))
8644 {
8645 hook_w32_key (hook, VK_LWIN, vk_code);
8646 res = Qt;
8647 }
8648 if (((lisp_modifiers & hyper_modifier)
8649 && EQ (Vw32_rwindow_modifier, Qhyper))
8650 || ((lisp_modifiers & super_modifier)
8651 && EQ (Vw32_rwindow_modifier, Qsuper)))
8652 {
8653 hook_w32_key (hook, VK_RWIN, vk_code);
8654 res = Qt;
8655 }
8656 return res;
8657 }
8658 else
8659 {
8660
8661 w32_modifiers = (lisp_modifiers & hyper_modifier) ? MOD_WIN : 0;
8662 w32_modifiers |= (lisp_modifiers & alt_modifier) ? MOD_ALT : 0;
8663 w32_modifiers |= (lisp_modifiers & ctrl_modifier) ? MOD_CONTROL : 0;
8664 w32_modifiers |= (lisp_modifiers & shift_modifier) ? MOD_SHIFT : 0;
8665
8666 return HOTKEY (vk_code, w32_modifiers);
8667 }
8668 }
8669
8670 DEFUN ("w32-register-hot-key", Fw32_register_hot_key,
8671 Sw32_register_hot_key, 1, 1, 0,
8672 doc:
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697 )
8698 (Lisp_Object key)
8699 {
8700 key = w32_parse_and_hook_hot_key (key, 1);
8701
8702 if (!w32_kbdhook_active
8703 && !NILP (key) && NILP (Fmemq (key, w32_grabbed_keys)))
8704 {
8705
8706 Lisp_Object item = Fmemq (Qnil, w32_grabbed_keys);
8707
8708
8709 if (NILP (item))
8710 w32_grabbed_keys = Fcons (key, w32_grabbed_keys);
8711 else
8712 XSETCAR (item, key);
8713
8714
8715
8716 PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
8717 (WPARAM) XFIXNUM (key), 0);
8718 }
8719
8720 return key;
8721 }
8722
8723 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
8724 Sw32_unregister_hot_key, 1, 1, 0,
8725 doc: )
8726 (Lisp_Object key)
8727 {
8728 Lisp_Object item;
8729
8730 if (!FIXNUMP (key))
8731 key = w32_parse_and_hook_hot_key (key, 0);
8732
8733 if (w32_kbdhook_active)
8734 return key;
8735
8736 item = Fmemq (key, w32_grabbed_keys);
8737
8738 if (!NILP (item))
8739 {
8740 LPARAM lparam;
8741
8742 eassert (CONSP (item));
8743
8744
8745 lparam = (LPARAM) XUNTAG (item, Lisp_Cons, struct Lisp_Cons);
8746
8747
8748
8749 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
8750 (WPARAM) XFIXNUM (XCAR (item)), lparam))
8751 {
8752 MSG msg;
8753 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
8754 }
8755 return Qt;
8756 }
8757 return Qnil;
8758 }
8759
8760 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys,
8761 Sw32_registered_hot_keys, 0, 0, 0,
8762 doc: )
8763 (void)
8764 {
8765 return Fdelq (Qnil, Fcopy_sequence (w32_grabbed_keys));
8766 }
8767
8768 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key,
8769 Sw32_reconstruct_hot_key, 1, 1, 0,
8770 doc:
8771 )
8772 (Lisp_Object hotkeyid)
8773 {
8774 int vk_code, w32_modifiers;
8775 Lisp_Object key;
8776
8777 CHECK_FIXNUM (hotkeyid);
8778
8779 vk_code = HOTKEY_VK_CODE (hotkeyid);
8780 w32_modifiers = HOTKEY_MODIFIERS (hotkeyid);
8781
8782 if (vk_code < 256 && lispy_function_keys[vk_code])
8783 key = intern (lispy_function_keys[vk_code]);
8784 else
8785 key = make_fixnum (vk_code);
8786
8787 key = Fcons (key, Qnil);
8788 if (w32_modifiers & MOD_SHIFT)
8789 key = Fcons (Qshift, key);
8790 if (w32_modifiers & MOD_CONTROL)
8791 key = Fcons (Qctrl, key);
8792 if (w32_modifiers & MOD_ALT)
8793 key = Fcons (NILP (Vw32_alt_is_meta) ? Qalt : Qmeta, key);
8794 if (w32_modifiers & MOD_WIN)
8795 key = Fcons (Qhyper, key);
8796
8797 return key;
8798 }
8799
8800 DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key,
8801 Sw32_toggle_lock_key, 1, 2, 0,
8802 doc:
8803
8804
8805
8806
8807
8808
8809 )
8810 (Lisp_Object key, Lisp_Object new_state)
8811 {
8812 int vk_code;
8813 LPARAM lparam;
8814
8815 if (EQ (key, intern ("capslock")))
8816 vk_code = VK_CAPITAL;
8817 else if (EQ (key, intern ("kp-numlock")))
8818 vk_code = VK_NUMLOCK;
8819 else if (EQ (key, intern ("scroll")))
8820 vk_code = VK_SCROLL;
8821 else
8822 return Qnil;
8823
8824 if (!dwWindowsThreadId)
8825 return make_fixnum (w32_console_toggle_lock_key (vk_code, new_state));
8826
8827 if (NILP (new_state))
8828 lparam = -1;
8829 else
8830 lparam = (XUFIXNUM (new_state)) & 1;
8831 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
8832 (WPARAM) vk_code, lparam))
8833 {
8834 MSG msg;
8835 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
8836 return make_fixnum (msg.wParam);
8837 }
8838 return Qnil;
8839 }
8840
8841 DEFUN ("w32-window-exists-p", Fw32_window_exists_p, Sw32_window_exists_p,
8842 2, 2, 0,
8843 doc:
8844
8845 )
8846 (Lisp_Object class, Lisp_Object name)
8847 {
8848 HWND hnd;
8849
8850 if (!NILP (class))
8851 CHECK_STRING (class);
8852 if (!NILP (name))
8853 CHECK_STRING (name);
8854
8855 hnd = FindWindow (STRINGP (class) ? ((LPCTSTR) SDATA (class)) : NULL,
8856 STRINGP (name) ? ((LPCTSTR) SDATA (name)) : NULL);
8857 if (!hnd)
8858 return Qnil;
8859 return Qt;
8860 }
8861
8862 DEFUN ("w32-frame-geometry", Fw32_frame_geometry, Sw32_frame_geometry, 0, 1, 0,
8863 doc:
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903 )
8904 (Lisp_Object frame)
8905 {
8906 struct frame *f = decode_live_frame (frame);
8907
8908 MENUBARINFO menu_bar;
8909 WINDOWINFO window;
8910 int left, top, right, bottom;
8911 unsigned int external_border_width, external_border_height;
8912 int title_bar_width = 0, title_bar_height = 0;
8913 int single_menu_bar_height, wrapped_menu_bar_height, menu_bar_height;
8914 int tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
8915 int tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
8916 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
8917
8918 if (FRAME_INITIAL_P (f) || !FRAME_W32_P (f))
8919 return Qnil;
8920
8921 block_input ();
8922
8923 window.cbSize = sizeof (window);
8924 GetWindowInfo (FRAME_W32_WINDOW (f), &window);
8925 external_border_width = window.cxWindowBorders;
8926 external_border_height = window.cyWindowBorders;
8927
8928 if (get_title_bar_info_fn)
8929 {
8930 TITLEBAR_INFO title_bar;
8931
8932 title_bar.cbSize = sizeof (title_bar);
8933 title_bar.rcTitleBar.left = title_bar.rcTitleBar.right = 0;
8934 title_bar.rcTitleBar.top = title_bar.rcTitleBar.bottom = 0;
8935 for (int i = 0; i < 6; i++)
8936 title_bar.rgstate[i] = 0;
8937 if (get_title_bar_info_fn (FRAME_W32_WINDOW (f), &title_bar)
8938 && !(title_bar.rgstate[0] & 0x00008001))
8939 {
8940 title_bar_width
8941 = title_bar.rcTitleBar.right - title_bar.rcTitleBar.left;
8942 title_bar_height
8943 = title_bar.rcTitleBar.bottom - title_bar.rcTitleBar.top;
8944 }
8945 }
8946 else if ((window.dwStyle & WS_CAPTION) == WS_CAPTION)
8947 title_bar_height = GetSystemMetrics (SM_CYCAPTION);
8948
8949 menu_bar.cbSize = sizeof (menu_bar);
8950 menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
8951 menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
8952 GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
8953 single_menu_bar_height = GetSystemMetrics (SM_CYMENU);
8954 wrapped_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
8955 unblock_input ();
8956
8957 left = window.rcWindow.left;
8958 top = window.rcWindow.top;
8959 right = window.rcWindow.right;
8960 bottom = window.rcWindow.bottom;
8961
8962
8963 menu_bar_height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
8964
8965 if (menu_bar_height > single_menu_bar_height)
8966
8967 menu_bar_height += single_menu_bar_height - wrapped_menu_bar_height;
8968 else if (menu_bar_height > 0)
8969
8970 menu_bar_height = single_menu_bar_height;
8971
8972 return list (Fcons (Qouter_position,
8973 Fcons (make_fixnum (left), make_fixnum (top))),
8974 Fcons (Qouter_size,
8975 Fcons (make_fixnum (right - left),
8976 make_fixnum (bottom - top))),
8977 Fcons (Qexternal_border_size,
8978 Fcons (make_fixnum (external_border_width),
8979 make_fixnum (external_border_height))),
8980 Fcons (Qtitle_bar_size,
8981 Fcons (make_fixnum (title_bar_width),
8982 make_fixnum (title_bar_height))),
8983 Fcons (Qmenu_bar_external, Qt),
8984 Fcons (Qmenu_bar_size,
8985 Fcons (make_fixnum
8986 (menu_bar.rcBar.right - menu_bar.rcBar.left),
8987 make_fixnum (menu_bar_height))),
8988 Fcons (Qtab_bar_size,
8989 Fcons (make_fixnum
8990 (tab_bar_height
8991 ? (right - left - 2 * external_border_width
8992 - 2 * internal_border_width)
8993 : 0),
8994 make_fixnum (tab_bar_height))),
8995 Fcons (Qtool_bar_external, Qnil),
8996 Fcons (Qtool_bar_position, tool_bar_height ? Qtop : Qnil),
8997 Fcons (Qtool_bar_size,
8998 Fcons (make_fixnum
8999 (tool_bar_height
9000 ? (right - left - 2 * external_border_width
9001 - 2 * internal_border_width)
9002 : 0),
9003 make_fixnum (tool_bar_height))),
9004 Fcons (Qinternal_border_width,
9005 make_fixnum (internal_border_width)));
9006 }
9007
9008 DEFUN ("w32-frame-edges", Fw32_frame_edges, Sw32_frame_edges, 0, 2, 0,
9009 doc:
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023 )
9024 (Lisp_Object frame, Lisp_Object type)
9025 {
9026 struct frame *f = decode_live_frame (frame);
9027
9028 if (FRAME_INITIAL_P (f) || !FRAME_W32_P (f))
9029 return Qnil;
9030
9031 if (EQ (type, Qouter_edges))
9032 {
9033 RECT rectangle;
9034 BOOL success = false;
9035
9036 block_input ();
9037
9038 success = GetWindowRect (FRAME_W32_WINDOW (f), &rectangle);
9039 unblock_input ();
9040
9041 if (success)
9042 return list4 (make_fixnum (rectangle.left),
9043 make_fixnum (rectangle.top),
9044 make_fixnum (rectangle.right),
9045 make_fixnum (rectangle.bottom));
9046 else
9047 return Qnil;
9048 }
9049 else
9050 {
9051 RECT rectangle;
9052 POINT pt;
9053 int left, top, right, bottom;
9054 BOOL success;
9055
9056 block_input ();
9057
9058 success = GetClientRect (FRAME_W32_WINDOW (f), &rectangle);
9059
9060
9061 if (!success)
9062 {
9063 unblock_input ();
9064 return Qnil;
9065 }
9066
9067 pt.x = 0;
9068 pt.y = 0;
9069 success = ClientToScreen (FRAME_W32_WINDOW (f), &pt);
9070 unblock_input ();
9071
9072 if (!success)
9073 return Qnil;
9074
9075 left = pt.x;
9076 top = pt.y;
9077 right = left + rectangle.right;
9078 bottom = top + rectangle.bottom;
9079
9080 if (EQ (type, Qinner_edges))
9081 {
9082 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
9083
9084 return list4 (make_fixnum (left + internal_border_width),
9085 make_fixnum (top
9086 + FRAME_TAB_BAR_HEIGHT (f)
9087 + FRAME_TOOL_BAR_HEIGHT (f)
9088 + internal_border_width),
9089 make_fixnum (right - internal_border_width),
9090 make_fixnum (bottom - internal_border_width));
9091 }
9092 else
9093 return list4 (make_fixnum (left), make_fixnum (top),
9094 make_fixnum (right), make_fixnum (bottom));
9095 }
9096 }
9097
9098
9099
9100
9101
9102
9103
9104
9105 static Lisp_Object
9106 w32_frame_list_z_order (struct w32_display_info *dpyinfo, HWND window)
9107 {
9108 Lisp_Object frame, frames = Qnil;
9109
9110 while (window)
9111 {
9112 struct frame *f = w32_window_to_frame (dpyinfo, window);
9113
9114 if (f)
9115 {
9116 XSETFRAME (frame, f);
9117 frames = Fcons (frame, frames);
9118 }
9119
9120 block_input ();
9121 window = GetNextWindow (window, GW_HWNDNEXT);
9122 unblock_input ();
9123 }
9124
9125 return Fnreverse (frames);
9126 }
9127
9128 DEFUN ("w32-frame-list-z-order", Fw32_frame_list_z_order,
9129 Sw32_frame_list_z_order, 0, 1, 0,
9130 doc:
9131
9132
9133
9134
9135
9136
9137
9138 )
9139 (Lisp_Object display)
9140 {
9141 struct w32_display_info *dpyinfo = check_x_display_info (display);
9142 HWND window;
9143
9144 block_input ();
9145 if (FRAMEP (display) && FRAME_LIVE_P (XFRAME (display)))
9146 window = GetWindow (FRAME_W32_WINDOW (XFRAME (display)), GW_CHILD);
9147 else
9148 window = GetTopWindow (NULL);
9149 unblock_input ();
9150
9151 return w32_frame_list_z_order (dpyinfo, window);
9152 }
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162 static void
9163 w32_frame_restack (struct frame *f1, struct frame *f2, bool above_flag)
9164 {
9165 HWND hwnd1 = FRAME_W32_WINDOW (f1);
9166 HWND hwnd2 = FRAME_W32_WINDOW (f2);
9167
9168 block_input ();
9169 if (above_flag)
9170
9171 {
9172 if (GetNextWindow (hwnd1, GW_HWNDNEXT) != hwnd2)
9173 {
9174
9175
9176
9177 if (GetNextWindow (hwnd2, GW_HWNDNEXT) != hwnd1)
9178 SetWindowPos (hwnd1, hwnd2, 0, 0, 0, 0,
9179 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE
9180 | SWP_FRAMECHANGED);
9181
9182 SetWindowPos (hwnd2, hwnd1, 0, 0, 0, 0,
9183 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE
9184 | SWP_FRAMECHANGED);
9185 }
9186 }
9187 else if (GetNextWindow (hwnd2, GW_HWNDNEXT) != hwnd1)
9188
9189 SetWindowPos (hwnd1, hwnd2, 0, 0, 0, 0,
9190 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE
9191 | SWP_FRAMECHANGED);
9192 unblock_input ();
9193 }
9194
9195 DEFUN ("w32-frame-restack", Fw32_frame_restack, Sw32_frame_restack, 2, 3, 0,
9196 doc:
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210 )
9211 (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
9212 {
9213 struct frame *f1 = decode_live_frame (frame1);
9214 struct frame *f2 = decode_live_frame (frame2);
9215
9216 if (FRAME_W32_P (f1) && FRAME_W32_P (f2))
9217 {
9218 w32_frame_restack (f1, f2, !NILP (above));
9219 return Qt;
9220 }
9221 else
9222 {
9223 error ("Cannot restack frames");
9224 return Qnil;
9225 }
9226 }
9227
9228 DEFUN ("w32-mouse-absolute-pixel-position", Fw32_mouse_absolute_pixel_position,
9229 Sw32_mouse_absolute_pixel_position, 0, 0, 0,
9230 doc:
9231
9232
9233 )
9234 (void)
9235 {
9236 POINT pt;
9237
9238 block_input ();
9239 GetCursorPos (&pt);
9240 unblock_input ();
9241
9242 return Fcons (make_fixnum (pt.x), make_fixnum (pt.y));
9243 }
9244
9245 DEFUN ("w32-set-mouse-absolute-pixel-position", Fw32_set_mouse_absolute_pixel_position,
9246 Sw32_set_mouse_absolute_pixel_position, 2, 2, 0,
9247 doc:
9248
9249 )
9250 (Lisp_Object x, Lisp_Object y)
9251 {
9252 UINT trail_num = 0;
9253 BOOL ret = false;
9254
9255 int xval = check_integer_range (x, INT_MIN, INT_MAX);
9256 int yval = check_integer_range (y, INT_MIN, INT_MAX);
9257
9258 block_input ();
9259
9260
9261
9262 if (os_subtype == OS_SUBTYPE_NT
9263 && w32_major_version + w32_minor_version >= 6)
9264 ret = SystemParametersInfo (SPI_GETMOUSETRAILS, 0, &trail_num, 0);
9265 SetCursorPos (xval, yval);
9266 if (ret)
9267 SystemParametersInfo (SPI_SETMOUSETRAILS, trail_num, NULL, 0);
9268 unblock_input ();
9269
9270 return Qnil;
9271 }
9272
9273
9274 #ifdef WINDOWSNT
9275 typedef BOOL (WINAPI *GetDiskFreeSpaceExW_Proc)
9276 (LPCWSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
9277 typedef BOOL (WINAPI *GetDiskFreeSpaceExA_Proc)
9278 (LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
9279
9280 DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
9281 doc: )
9282 (Lisp_Object filename)
9283 {
9284 Lisp_Object encoded, value;
9285
9286 CHECK_STRING (filename);
9287 filename = Fexpand_file_name (filename, Qnil);
9288 encoded = ENCODE_FILE (filename);
9289
9290
9291
9292 Lisp_Object handler = Ffind_file_name_handler (encoded, Qfile_system_info);
9293 if (!NILP (handler))
9294 {
9295 value = call2 (handler, Qfile_system_info, encoded);
9296 if (CONSP (value) || NILP (value))
9297 return value;
9298 error ("Invalid handler in `file-name-handler-alist'");
9299 }
9300
9301 value = Qnil;
9302
9303
9304
9305
9306
9307
9308 {
9309 HMODULE hKernel = GetModuleHandle ("kernel32");
9310 GetDiskFreeSpaceExW_Proc pfn_GetDiskFreeSpaceExW =
9311 (GetDiskFreeSpaceExW_Proc) get_proc_addr (hKernel, "GetDiskFreeSpaceExW");
9312 GetDiskFreeSpaceExA_Proc pfn_GetDiskFreeSpaceExA =
9313 (GetDiskFreeSpaceExA_Proc) get_proc_addr (hKernel, "GetDiskFreeSpaceExA");
9314 bool have_pfn_GetDiskFreeSpaceEx =
9315 ((w32_unicode_filenames && pfn_GetDiskFreeSpaceExW)
9316 || (!w32_unicode_filenames && pfn_GetDiskFreeSpaceExA));
9317
9318
9319
9320 char rootname[MAX_UTF8_PATH];
9321 wchar_t rootname_w[MAX_PATH];
9322 char rootname_a[MAX_PATH];
9323 char *name = SSDATA (encoded);
9324 BOOL result;
9325
9326
9327 if (isalpha (name[0]) && name[1] == ':')
9328 {
9329 rootname[0] = name[0];
9330 rootname[1] = name[1];
9331 rootname[2] = '\\';
9332 rootname[3] = 0;
9333 }
9334 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
9335 {
9336 char *str = rootname;
9337 int slashes = 4;
9338 do
9339 {
9340 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
9341 break;
9342 *str++ = *name++;
9343 }
9344 while ( *name );
9345
9346 *str++ = '\\';
9347 *str = 0;
9348 }
9349
9350 if (w32_unicode_filenames)
9351 filename_to_utf16 (rootname, rootname_w);
9352 else
9353 filename_to_ansi (rootname, rootname_a);
9354
9355 if (have_pfn_GetDiskFreeSpaceEx)
9356 {
9357
9358
9359 LARGE_INTEGER availbytes;
9360 LARGE_INTEGER freebytes;
9361 LARGE_INTEGER totalbytes;
9362
9363 if (w32_unicode_filenames)
9364 result = pfn_GetDiskFreeSpaceExW (rootname_w,
9365 (ULARGE_INTEGER *)&availbytes,
9366 (ULARGE_INTEGER *)&totalbytes,
9367 (ULARGE_INTEGER *)&freebytes);
9368 else
9369 result = pfn_GetDiskFreeSpaceExA (rootname_a,
9370 (ULARGE_INTEGER *)&availbytes,
9371 (ULARGE_INTEGER *)&totalbytes,
9372 (ULARGE_INTEGER *)&freebytes);
9373 if (result)
9374 value = list3 (make_float ((double) totalbytes.QuadPart),
9375 make_float ((double) freebytes.QuadPart),
9376 make_float ((double) availbytes.QuadPart));
9377 }
9378 else
9379 {
9380 DWORD sectors_per_cluster;
9381 DWORD bytes_per_sector;
9382 DWORD free_clusters;
9383 DWORD total_clusters;
9384
9385 if (w32_unicode_filenames)
9386 result = GetDiskFreeSpaceW (rootname_w,
9387 §ors_per_cluster,
9388 &bytes_per_sector,
9389 &free_clusters,
9390 &total_clusters);
9391 else
9392 result = GetDiskFreeSpaceA (rootname_a,
9393 §ors_per_cluster,
9394 &bytes_per_sector,
9395 &free_clusters,
9396 &total_clusters);
9397 if (result)
9398 value = list3 (make_float ((double) total_clusters
9399 * sectors_per_cluster * bytes_per_sector),
9400 make_float ((double) free_clusters
9401 * sectors_per_cluster * bytes_per_sector),
9402 make_float ((double) free_clusters
9403 * sectors_per_cluster * bytes_per_sector));
9404 }
9405 }
9406
9407 return value;
9408 }
9409 #endif
9410
9411
9412 #ifdef WINDOWSNT
9413 DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
9414 0, 0, 0, doc: )
9415 (void)
9416 {
9417 static char pname_buf[2 * MAX_UTF8_PATH + 3 - 1];
9418 int err;
9419 HANDLE hPrn;
9420 PRINTER_INFO_2W *ppi2w = NULL;
9421 PRINTER_INFO_2A *ppi2a = NULL;
9422 DWORD dwNeeded = 0, dwReturned = 0;
9423 char server_name[MAX_UTF8_PATH], share_name[MAX_UTF8_PATH];
9424 char port_name[MAX_UTF8_PATH];
9425
9426
9427
9428
9429 if (GetProfileString ("windows", "device", ",,", pname_buf, sizeof (pname_buf)) <= 0)
9430 return Qnil;
9431
9432 strtok (pname_buf, ",");
9433
9434 if (!OpenPrinter (pname_buf, &hPrn, NULL))
9435 return Qnil;
9436
9437 if (w32_unicode_filenames && os_subtype != OS_SUBTYPE_9X)
9438 GetPrinterW (hPrn, 2, NULL, 0, &dwNeeded);
9439 else
9440 GetPrinterA (hPrn, 2, NULL, 0, &dwNeeded);
9441 if (dwNeeded == 0)
9442 {
9443 ClosePrinter (hPrn);
9444 return Qnil;
9445 }
9446
9447 if (w32_unicode_filenames && os_subtype != OS_SUBTYPE_9X)
9448 {
9449
9450 ppi2w = xmalloc (dwNeeded);
9451 err = GetPrinterW (hPrn, 2, (LPBYTE)ppi2w, dwNeeded, &dwReturned);
9452 ClosePrinter (hPrn);
9453 if (!err)
9454 {
9455 xfree (ppi2w);
9456 return Qnil;
9457 }
9458
9459 if ((ppi2w->Attributes & PRINTER_ATTRIBUTE_SHARED)
9460 && ppi2w->pServerName)
9461 {
9462 filename_from_utf16 (ppi2w->pServerName, server_name);
9463 filename_from_utf16 (ppi2w->pShareName, share_name);
9464 }
9465 else
9466 {
9467 server_name[0] = '\0';
9468 filename_from_utf16 (ppi2w->pPortName, port_name);
9469 }
9470 }
9471 else
9472 {
9473 ppi2a = xmalloc (dwNeeded);
9474 err = GetPrinterA (hPrn, 2, (LPBYTE)ppi2a, dwNeeded, &dwReturned);
9475 ClosePrinter (hPrn);
9476 if (!err)
9477 {
9478 xfree (ppi2a);
9479 return Qnil;
9480 }
9481
9482 if ((ppi2a->Attributes & PRINTER_ATTRIBUTE_SHARED)
9483 && ppi2a->pServerName)
9484 {
9485 filename_from_ansi (ppi2a->pServerName, server_name);
9486 filename_from_ansi (ppi2a->pShareName, share_name);
9487 }
9488 else
9489 {
9490 server_name[0] = '\0';
9491 filename_from_ansi (ppi2a->pPortName, port_name);
9492 }
9493 }
9494
9495 if (server_name[0])
9496 {
9497
9498 if (server_name[0] == '\\')
9499 snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", server_name,
9500 share_name);
9501 else
9502 snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", server_name,
9503 share_name);
9504 pname_buf[sizeof (pname_buf) - 1] = '\0';
9505 }
9506 else
9507 {
9508
9509 strncpy (pname_buf, port_name, sizeof (pname_buf));
9510 pname_buf[sizeof (pname_buf) - 1] = '\0';
9511
9512
9513 strtok (pname_buf, ",");
9514 }
9515
9516 return DECODE_FILE (build_unibyte_string (pname_buf));
9517 }
9518 #endif
9519
9520
9521
9522 char *
9523 w32_strerror (int error_no)
9524 {
9525 static char buf[500];
9526 DWORD ret;
9527
9528 if (error_no == 0)
9529 error_no = GetLastError ();
9530
9531 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
9532 FORMAT_MESSAGE_IGNORE_INSERTS,
9533 NULL,
9534 error_no,
9535 0,
9536 buf, sizeof (buf), NULL);
9537
9538 while (ret > 0 && (buf[ret - 1] == '\n' ||
9539 buf[ret - 1] == '\r' ))
9540 --ret;
9541 buf[ret] = '\0';
9542 if (!ret)
9543 sprintf (buf, "w32 error %d", error_no);
9544
9545 return buf;
9546 }
9547
9548
9549
9550
9551 DWORD w32_last_error (void);
9552
9553 DWORD
9554 w32_last_error (void)
9555 {
9556 return GetLastError ();
9557 }
9558
9559
9560 void
9561 cache_system_info (void)
9562 {
9563 union
9564 {
9565 struct info
9566 {
9567 char major;
9568 char minor;
9569 short platform;
9570 } info;
9571 DWORD data;
9572 } version;
9573
9574
9575 hinst = GetModuleHandle (NULL);
9576
9577
9578 version.data = GetVersion ();
9579 w32_major_version = version.info.major;
9580 w32_minor_version = version.info.minor;
9581
9582 if (version.info.platform & 0x8000)
9583 os_subtype = OS_SUBTYPE_9X;
9584 else
9585 os_subtype = OS_SUBTYPE_NT;
9586
9587
9588 GetSystemInfo (&sysinfo_cache);
9589 syspage_mask = (DWORD_PTR)sysinfo_cache.dwPageSize - 1;
9590
9591
9592 osinfo_cache.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
9593 GetVersionEx (&osinfo_cache);
9594
9595 w32_build_number = osinfo_cache.dwBuildNumber;
9596 if (os_subtype == OS_SUBTYPE_9X)
9597 w32_build_number &= 0xffff;
9598
9599 w32_num_mouse_buttons = GetSystemMetrics (SM_CMOUSEBUTTONS);
9600 }
9601
9602 #ifdef WINDOWSNT
9603 char *
9604 w32_version_string (void)
9605 {
9606
9607 static char version_string[3 + 1 + 3 + 1 + 10 + 1];
9608 _snprintf (version_string, sizeof version_string, "%d.%d.%d",
9609 w32_major_version, w32_minor_version, w32_build_number);
9610 return version_string;
9611 }
9612 #endif
9613
9614 #ifdef EMACSDEBUG
9615 void
9616 _DebPrint (const char *fmt, ...)
9617 {
9618 char buf[1024];
9619 va_list args;
9620
9621 va_start (args, fmt);
9622 vsprintf (buf, fmt, args);
9623 va_end (args);
9624 #if CYGWIN
9625 fprintf (stderr, "%s", buf);
9626 #endif
9627 OutputDebugString (buf);
9628 }
9629 #endif
9630
9631 int
9632 w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
9633 {
9634 int cur_state = (GetKeyState (vk_code) & 1);
9635
9636 if (NILP (new_state)
9637 || (FIXNUMP (new_state)
9638 && ((XUFIXNUM (new_state)) & 1) != cur_state))
9639 {
9640 #ifdef WINDOWSNT
9641 faked_key = vk_code;
9642 #endif
9643
9644 keybd_event ((BYTE) vk_code,
9645 (BYTE) MapVirtualKey (vk_code, 0),
9646 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
9647 keybd_event ((BYTE) vk_code,
9648 (BYTE) MapVirtualKey (vk_code, 0),
9649 KEYEVENTF_EXTENDEDKEY | 0, 0);
9650 keybd_event ((BYTE) vk_code,
9651 (BYTE) MapVirtualKey (vk_code, 0),
9652 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
9653 cur_state = !cur_state;
9654 }
9655
9656 return cur_state;
9657 }
9658
9659
9660
9661 int
9662 w32_kbd_mods_to_emacs (DWORD mods, WORD key)
9663 {
9664 int retval = 0;
9665
9666
9667
9668 if (!NILP (Vw32_recognize_altgr)
9669 && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
9670 == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
9671 mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
9672
9673 if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
9674 retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
9675
9676 if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
9677 {
9678 retval |= ctrl_modifier;
9679 if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
9680 == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
9681 retval |= meta_modifier;
9682 }
9683
9684 if (mods & LEFT_WIN_PRESSED)
9685 retval |= w32_key_to_modifier (VK_LWIN);
9686 if (mods & RIGHT_WIN_PRESSED)
9687 retval |= w32_key_to_modifier (VK_RWIN);
9688 if (mods & APPS_PRESSED)
9689 retval |= w32_key_to_modifier (VK_APPS);
9690 if (mods & SCROLLLOCK_ON)
9691 retval |= w32_key_to_modifier (VK_SCROLL);
9692
9693
9694
9695 if (NILP (Vw32_capslock_is_shiftlock)
9696
9697 && ( (key == VK_BACK)
9698 || (key == VK_TAB)
9699 || (key == VK_CLEAR)
9700 || (key == VK_RETURN)
9701 || (key == VK_ESCAPE)
9702 || ((key >= VK_SPACE) && (key <= VK_HELP))
9703 || ((key >= VK_NUMPAD0) && (key <= VK_F24))
9704 || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
9705 ))
9706 {
9707
9708 if ((mods & SHIFT_PRESSED) != 0)
9709 retval |= shift_modifier;
9710 }
9711 else
9712 {
9713
9714 if (NILP (Vw32_enable_caps_lock))
9715 mods &= ~CAPSLOCK_ON;
9716 if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
9717 retval |= shift_modifier;
9718 }
9719
9720 return retval;
9721 }
9722
9723
9724
9725
9726 int
9727 w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId)
9728 {
9729 unsigned int key_code = event->wVirtualKeyCode;
9730 unsigned int mods = event->dwControlKeyState;
9731 BYTE keystate[256];
9732 static BYTE ansi_code[4];
9733 static int isdead = 0;
9734
9735 if (isdead == 2)
9736 {
9737 event->uChar.AsciiChar = ansi_code[2];
9738 isdead = 0;
9739 return 1;
9740 }
9741 if (event->uChar.AsciiChar != 0)
9742 return 1;
9743
9744 memset (keystate, 0, sizeof (keystate));
9745 keystate[key_code] = 0x80;
9746 if (mods & SHIFT_PRESSED)
9747 keystate[VK_SHIFT] = 0x80;
9748 if (mods & CAPSLOCK_ON)
9749 keystate[VK_CAPITAL] = 1;
9750
9751
9752 if (!NILP (Vw32_recognize_altgr)
9753 && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
9754 {
9755 keystate[VK_CONTROL] = 0x80;
9756 keystate[VK_LCONTROL] = 0x80;
9757 keystate[VK_MENU] = 0x80;
9758 keystate[VK_RMENU] = 0x80;
9759 }
9760
9761 #if 0
9762
9763
9764
9765
9766
9767
9768
9769 if (is_dead_key (event->wVirtualKeyCode))
9770 return 0;
9771 #endif
9772
9773
9774
9775 if (os_subtype == OS_SUBTYPE_NT)
9776 {
9777 WCHAR buf[128];
9778
9779 isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
9780 keystate, buf, 128, 0);
9781 if (isdead > 0)
9782 {
9783
9784
9785
9786 if (cpId == -1)
9787 cpId = GetConsoleCP ();
9788
9789 event->uChar.UnicodeChar = buf[isdead - 1];
9790 isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
9791 (LPSTR)ansi_code, 4, NULL, NULL);
9792 }
9793 else
9794 isdead = 0;
9795 }
9796 else
9797 {
9798 isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
9799 keystate, (LPWORD) ansi_code, 0);
9800 }
9801
9802 if (isdead == 0)
9803 return 0;
9804 event->uChar.AsciiChar = ansi_code[0];
9805 return isdead;
9806 }
9807
9808
9809 void
9810 w32_sys_ring_bell (struct frame *f)
9811 {
9812 if (sound_type == 0xFFFFFFFF)
9813 {
9814 Beep (666, 100);
9815 }
9816 else if (sound_type == MB_EMACS_SILENT)
9817 {
9818
9819 }
9820 else
9821 MessageBeep (sound_type);
9822 }
9823
9824 DEFUN ("w32--menu-bar-in-use", Fw32__menu_bar_in_use, Sw32__menu_bar_in_use,
9825 0, 0, 0,
9826 doc:
9827 )
9828 (void)
9829 {
9830 return menubar_in_use ? Qt : Qnil;
9831 }
9832
9833 #if defined WINDOWSNT && !defined HAVE_DBUS
9834
9835
9836
9837
9838
9839 typedef struct MY_NOTIFYICONDATAW {
9840 DWORD cbSize;
9841 HWND hWnd;
9842 UINT uID;
9843 UINT uFlags;
9844 UINT uCallbackMessage;
9845 HICON hIcon;
9846 WCHAR szTip[128];
9847 DWORD dwState;
9848 DWORD dwStateMask;
9849 WCHAR szInfo[256];
9850 _ANONYMOUS_UNION union {
9851 UINT uTimeout;
9852 UINT uVersion;
9853 } DUMMYUNIONNAME;
9854 WCHAR szInfoTitle[64];
9855 DWORD dwInfoFlags;
9856 GUID guidItem;
9857 HICON hBalloonIcon;
9858 } MY_NOTIFYICONDATAW;
9859
9860 #define MYNOTIFYICONDATAW_V1_SIZE offsetof (MY_NOTIFYICONDATAW, szTip[64])
9861 #define MYNOTIFYICONDATAW_V2_SIZE offsetof (MY_NOTIFYICONDATAW, guidItem)
9862 #define MYNOTIFYICONDATAW_V3_SIZE offsetof (MY_NOTIFYICONDATAW, hBalloonIcon)
9863 #ifndef NIF_INFO
9864 # define NIF_INFO 0x00000010
9865 #endif
9866 #ifndef NIIF_NONE
9867 # define NIIF_NONE 0x00000000
9868 #endif
9869 #ifndef NIIF_INFO
9870 # define NIIF_INFO 0x00000001
9871 #endif
9872 #ifndef NIIF_WARNING
9873 # define NIIF_WARNING 0x00000002
9874 #endif
9875 #ifndef NIIF_ERROR
9876 # define NIIF_ERROR 0x00000003
9877 #endif
9878
9879
9880 #define EMACS_TRAY_NOTIFICATION_ID 42
9881 #define EMACS_NOTIFICATION_MSG (WM_APP + 1)
9882
9883 enum NI_Severity {
9884 Ni_None,
9885 Ni_Info,
9886 Ni_Warn,
9887 Ni_Err
9888 };
9889
9890
9891
9892 static ULONGLONG
9893 get_dll_version (const char *dll_name)
9894 {
9895 ULONGLONG version = 0;
9896 HINSTANCE hdll = LoadLibrary (dll_name);
9897
9898 if (hdll)
9899 {
9900 DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)
9901 get_proc_addr (hdll, "DllGetVersion");
9902
9903 if (pDllGetVersion)
9904 {
9905 DLLVERSIONINFO dvi;
9906 HRESULT result;
9907
9908 memset (&dvi, 0, sizeof(dvi));
9909 dvi.cbSize = sizeof(dvi);
9910 result = pDllGetVersion (&dvi);
9911 if (SUCCEEDED (result))
9912 version = MAKEDLLVERULL (dvi.dwMajorVersion, dvi.dwMinorVersion,
9913 0, 0);
9914 }
9915 FreeLibrary (hdll);
9916 }
9917
9918 return version;
9919 }
9920
9921
9922
9923
9924
9925 static int
9926 utf8_mbslen_lim (const char *str, int lim)
9927 {
9928 const char *p = str;
9929 int mblen = 0, nchars = 0;
9930
9931 while (*p && nchars < lim)
9932 {
9933 int nbytes = CHAR_BYTES (*p);
9934
9935 mblen += nbytes;
9936 nchars++;
9937 p += nbytes;
9938 }
9939
9940 if (!*p && nchars < lim)
9941 mblen++;
9942
9943 return mblen;
9944 }
9945
9946
9947
9948 static EMACS_INT
9949 add_tray_notification (struct frame *f, const char *icon, const char *tip,
9950 enum NI_Severity severity, unsigned timeout,
9951 const char *title, const char *msg)
9952 {
9953 EMACS_INT retval = EMACS_TRAY_NOTIFICATION_ID;
9954
9955 if (FRAME_W32_P (f))
9956 {
9957 MY_NOTIFYICONDATAW nidw;
9958 ULONGLONG shell_dll_version = get_dll_version ("Shell32.dll");
9959 wchar_t tipw[128], msgw[256], titlew[64];
9960 int tiplen;
9961
9962 memset (&nidw, 0, sizeof(nidw));
9963
9964
9965
9966
9967
9968
9969
9970
9971 if (shell_dll_version >= MAKEDLLVERULL (6, 1, 0, 0))
9972 nidw.cbSize = sizeof (nidw);
9973 else if (shell_dll_version >= MAKEDLLVERULL (6, 0, 0, 0))
9974 nidw.cbSize = MYNOTIFYICONDATAW_V3_SIZE;
9975 else if (shell_dll_version >= MAKEDLLVERULL (5, 0, 0, 0))
9976 nidw.cbSize = MYNOTIFYICONDATAW_V2_SIZE;
9977 else
9978 nidw.cbSize = MYNOTIFYICONDATAW_V1_SIZE;
9979 nidw.hWnd = FRAME_W32_WINDOW (f);
9980 nidw.uID = EMACS_TRAY_NOTIFICATION_ID;
9981 nidw.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
9982 nidw.uCallbackMessage = EMACS_NOTIFICATION_MSG;
9983 if (!*icon)
9984 nidw.hIcon = LoadIcon (hinst, EMACS_CLASS);
9985 else
9986 {
9987 if (w32_unicode_filenames)
9988 {
9989 wchar_t icon_w[MAX_PATH];
9990
9991 if (filename_to_utf16 (icon, icon_w) != 0)
9992 {
9993 errno = ENOENT;
9994 return -1;
9995 }
9996 nidw.hIcon = LoadImageW (NULL, icon_w, IMAGE_ICON, 0, 0,
9997 LR_DEFAULTSIZE | LR_LOADFROMFILE);
9998 }
9999 else
10000 {
10001 char icon_a[MAX_PATH];
10002
10003 if (filename_to_ansi (icon, icon_a) != 0)
10004 {
10005 errno = ENOENT;
10006 return -1;
10007 }
10008 nidw.hIcon = LoadImageA (NULL, icon_a, IMAGE_ICON, 0, 0,
10009 LR_DEFAULTSIZE | LR_LOADFROMFILE);
10010 }
10011 }
10012 if (!nidw.hIcon)
10013 {
10014 switch (GetLastError ())
10015 {
10016 case ERROR_FILE_NOT_FOUND:
10017 errno = ENOENT;
10018 break;
10019 default:
10020 errno = ENOMEM;
10021 break;
10022 }
10023 return -1;
10024 }
10025
10026
10027
10028 if (nidw.cbSize == MYNOTIFYICONDATAW_V1_SIZE)
10029 {
10030 tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
10031 tip, utf8_mbslen_lim (tip, 63),
10032 tipw, 64);
10033 if (tiplen >= 63)
10034 tipw[63] = 0;
10035 }
10036 else
10037 {
10038 tiplen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
10039 tip, utf8_mbslen_lim (tip, 127),
10040 tipw, 128);
10041 if (tiplen >= 127)
10042 tipw[127] = 0;
10043 }
10044 if (tiplen == 0)
10045 {
10046 errno = EINVAL;
10047 retval = -1;
10048 goto done;
10049 }
10050 wcscpy (nidw.szTip, tipw);
10051
10052
10053 if (nidw.cbSize > MYNOTIFYICONDATAW_V1_SIZE)
10054 {
10055 int slen;
10056
10057 slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
10058 msg, utf8_mbslen_lim (msg, 255),
10059 msgw, 256);
10060 if (slen >= 255)
10061 msgw[255] = 0;
10062 else if (slen == 0)
10063 {
10064 errno = EINVAL;
10065 retval = -1;
10066 goto done;
10067 }
10068 wcscpy (nidw.szInfo, msgw);
10069 nidw.uTimeout = timeout;
10070 slen = pMultiByteToWideChar (CP_UTF8, multiByteToWideCharFlags,
10071 title, utf8_mbslen_lim (title, 63),
10072 titlew, 64);
10073 if (slen >= 63)
10074 titlew[63] = 0;
10075 else if (slen == 0)
10076 {
10077 errno = EINVAL;
10078 retval = -1;
10079 goto done;
10080 }
10081 wcscpy (nidw.szInfoTitle, titlew);
10082
10083 switch (severity)
10084 {
10085 case Ni_None:
10086 nidw.dwInfoFlags = NIIF_NONE;
10087 break;
10088 case Ni_Info:
10089 default:
10090 nidw.dwInfoFlags = NIIF_INFO;
10091 break;
10092 case Ni_Warn:
10093 nidw.dwInfoFlags = NIIF_WARNING;
10094 break;
10095 case Ni_Err:
10096 nidw.dwInfoFlags = NIIF_ERROR;
10097 break;
10098 }
10099 }
10100
10101 if (!Shell_NotifyIconW (NIM_ADD, (PNOTIFYICONDATAW)&nidw))
10102 {
10103
10104
10105 DebPrint (("Shell_NotifyIcon ADD failed (err=%d)\n",
10106 GetLastError ()));
10107 errno = EINVAL;
10108 retval = -1;
10109 }
10110 done:
10111 if (*icon && !DestroyIcon (nidw.hIcon))
10112 DebPrint (("DestroyIcon failed (err=%d)\n", GetLastError ()));
10113 }
10114 return retval;
10115 }
10116
10117
10118
10119
10120
10121
10122 static void
10123 delete_tray_notification (struct frame *f, int id)
10124 {
10125 if (FRAME_W32_P (f))
10126 {
10127 MY_NOTIFYICONDATAW nidw;
10128
10129 memset (&nidw, 0, sizeof(nidw));
10130 nidw.hWnd = FRAME_W32_WINDOW (f);
10131 nidw.uID = id;
10132
10133 if (!Shell_NotifyIconW (NIM_DELETE, (PNOTIFYICONDATAW)&nidw))
10134 {
10135
10136
10137 DebPrint (("Shell_NotifyIcon DELETE failed\n"));
10138 errno = EINVAL;
10139 return;
10140 }
10141 }
10142 return;
10143 }
10144
10145 DEFUN ("w32-notification-notify",
10146 Fw32_notification_notify, Sw32_notification_notify,
10147 0, MANY, 0,
10148 doc:
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207 )
10208 (ptrdiff_t nargs, Lisp_Object *args)
10209 {
10210 struct frame *f = SELECTED_FRAME ();
10211 Lisp_Object arg_plist, lres;
10212 EMACS_INT retval;
10213 char *icon, *tip, *title, *msg;
10214 enum NI_Severity severity;
10215 unsigned timeout = 0;
10216
10217 if (nargs == 0)
10218 return Qnil;
10219
10220 arg_plist = Flist (nargs, args);
10221
10222
10223 lres = plist_get (arg_plist, QCicon);
10224 if (STRINGP (lres))
10225 icon = SSDATA (ENCODE_FILE (Fexpand_file_name (lres, Qnil)));
10226 else
10227 icon = (char *)"";
10228
10229
10230 lres = plist_get (arg_plist, QCtip);
10231 if (STRINGP (lres))
10232 tip = SSDATA (code_convert_string_norecord (lres, Qutf_8, 1));
10233 else
10234 tip = (char *)"Emacs notification";
10235
10236
10237 lres = plist_get (arg_plist, QClevel);
10238 if (NILP (lres))
10239 severity = Ni_None;
10240 else if (EQ (lres, Qinfo))
10241 severity = Ni_Info;
10242 else if (EQ (lres, Qwarning))
10243 severity = Ni_Warn;
10244 else if (EQ (lres, Qerror))
10245 severity = Ni_Err;
10246 else
10247 severity = Ni_Info;
10248
10249
10250 lres = plist_get (arg_plist, QCtitle);
10251 if (STRINGP (lres))
10252 title = SSDATA (code_convert_string_norecord (lres, Qutf_8, 1));
10253 else
10254 title = (char *)"";
10255
10256
10257 lres = plist_get (arg_plist, QCbody);
10258 if (STRINGP (lres))
10259 msg = SSDATA (code_convert_string_norecord (lres, Qutf_8, 1));
10260 else
10261 msg = (char *)"";
10262
10263
10264 retval = add_tray_notification (f, icon, tip, severity, timeout, title, msg);
10265 return (retval < 0 ? Qnil : make_fixnum (retval));
10266 }
10267
10268 DEFUN ("w32-notification-close",
10269 Fw32_notification_close, Sw32_notification_close,
10270 1, 1, 0,
10271 doc: )
10272 (Lisp_Object id)
10273 {
10274 struct frame *f = SELECTED_FRAME ();
10275
10276 if (FIXNUMP (id))
10277 delete_tray_notification (f, XFIXNUM (id));
10278
10279 return Qnil;
10280 }
10281
10282 #endif
10283
10284 DEFUN ("w32-get-ime-open-status",
10285 Fw32_get_ime_open_status, Sw32_get_ime_open_status,
10286 0, 0, 0,
10287 doc:
10288
10289
10290 )
10291 (void)
10292 {
10293 struct frame *sf =
10294 FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame))
10295 ? XFRAME (selected_frame)
10296 : NULL;
10297
10298 if (sf)
10299 {
10300 HWND current_window = FRAME_W32_WINDOW (sf);
10301 HIMC context = get_ime_context_fn (current_window);
10302 if (context)
10303 {
10304 BOOL retval = get_ime_open_status_fn (context);
10305 release_ime_context_fn (current_window, context);
10306
10307 return retval ? Qt : Qnil;
10308 }
10309 }
10310
10311 return Qnil;
10312 }
10313
10314 DEFUN ("w32-set-ime-open-status",
10315 Fw32_set_ime_open_status, Sw32_set_ime_open_status,
10316 1, 1, 0,
10317 doc:
10318
10319
10320 )
10321 (Lisp_Object status)
10322 {
10323 unsigned ime_status = NILP (status) ? 0 : 1;
10324
10325 PostThreadMessage (dwWindowsThreadId, WM_EMACS_IME_STATUS, ime_status, 0);
10326 return Qnil;
10327 }
10328
10329
10330 #ifdef WINDOWSNT
10331
10332
10333
10334 DEFUN ("w32-read-registry",
10335 Fw32_read_registry, Sw32_read_registry,
10336 3, 3, 0,
10337 doc:
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368 )
10369 (Lisp_Object root, Lisp_Object key, Lisp_Object name)
10370 {
10371 CHECK_SYMBOL (root);
10372 CHECK_STRING (key);
10373 CHECK_STRING (name);
10374
10375 HKEY rootkey = HKEY_CURRENT_USER;
10376 if (EQ (root, QHKCR))
10377 rootkey = HKEY_CLASSES_ROOT;
10378 else if (EQ (root, QHKCU))
10379 rootkey = HKEY_CURRENT_USER;
10380 else if (EQ (root, QHKLM))
10381 rootkey = HKEY_LOCAL_MACHINE;
10382 else if (EQ (root, QHKU))
10383 rootkey = HKEY_USERS;
10384 else if (EQ (root, QHKCC))
10385 rootkey = HKEY_CURRENT_CONFIG;
10386 else if (!NILP (root))
10387 error ("unknown root key: %s", SDATA (SYMBOL_NAME (root)));
10388
10389 Lisp_Object val = w32_read_registry (rootkey, key, name);
10390 if (NILP (val) && NILP (root))
10391 val = w32_read_registry (HKEY_LOCAL_MACHINE, key, name);
10392
10393 return val;
10394 }
10395
10396 #endif
10397
10398
10399
10400
10401
10402
10403
10404
10405 LPBYTE
10406 w32_get_resource (const char *key, const char *name, LPDWORD lpdwtype)
10407 {
10408 LPBYTE lpvalue;
10409 HKEY hrootkey = NULL;
10410 DWORD cbData;
10411
10412
10413
10414
10415 if (RegOpenKeyEx (HKEY_CURRENT_USER, key, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
10416 {
10417 lpvalue = NULL;
10418
10419 if (RegQueryValueEx (hrootkey, name, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
10420 && (lpvalue = xmalloc (cbData)) != NULL
10421 && RegQueryValueEx (hrootkey, name, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
10422 {
10423 RegCloseKey (hrootkey);
10424 return (lpvalue);
10425 }
10426
10427 xfree (lpvalue);
10428
10429 RegCloseKey (hrootkey);
10430 }
10431
10432 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
10433 {
10434 lpvalue = NULL;
10435
10436 if (RegQueryValueEx (hrootkey, name, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
10437 && (lpvalue = xmalloc (cbData)) != NULL
10438 && RegQueryValueEx (hrootkey, name, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
10439 {
10440 RegCloseKey (hrootkey);
10441 return (lpvalue);
10442 }
10443
10444 xfree (lpvalue);
10445
10446 RegCloseKey (hrootkey);
10447 }
10448
10449 return (NULL);
10450 }
10451
10452 #ifdef WINDOWSNT
10453
10454
10455
10456
10457
10458 typedef BOOL (WINAPI * SystemParametersInfoW_Proc) (UINT,UINT,PVOID,UINT);
10459 SystemParametersInfoW_Proc system_parameters_info_w_fn = NULL;
10460
10461 DEFUN ("w32-set-wallpaper", Fw32_set_wallpaper, Sw32_set_wallpaper, 1, 1, 0,
10462 doc: )
10463 (Lisp_Object image_file)
10464 {
10465 Lisp_Object encoded = ENCODE_FILE (Fexpand_file_name (image_file, Qnil));
10466 char *fname = SSDATA (encoded);
10467 BOOL result = false;
10468 DWORD err = 0;
10469
10470
10471
10472
10473
10474 if (w32_unicode_filenames && system_parameters_info_w_fn)
10475 {
10476 wchar_t fname_w[MAX_PATH];
10477
10478 if (filename_to_utf16 (fname, fname_w) != 0)
10479 err = ERROR_FILE_NOT_FOUND;
10480 else
10481 result = SystemParametersInfoW (SPI_SETDESKWALLPAPER, 0, fname_w,
10482 SPIF_SENDCHANGE);
10483 }
10484 else
10485 {
10486 char fname_a[MAX_PATH];
10487
10488 if (filename_to_ansi (fname, fname_a) != 0)
10489 err = ERROR_FILE_NOT_FOUND;
10490 else
10491 result = SystemParametersInfoA (SPI_SETDESKWALLPAPER, 0, fname_a,
10492 SPIF_SENDCHANGE);
10493 }
10494 if (!result)
10495 {
10496 if (err == ERROR_FILE_NOT_FOUND)
10497 error ("Wallpaper file %s does not exist or cannot be accessed", fname);
10498 else
10499 {
10500 err = GetLastError ();
10501 if (err)
10502 error ("Could not set desktop wallpaper: %s", w32_strerror (err));
10503 else
10504 error ("Could not set desktop wallpaper (wrong image type?)");
10505 }
10506 }
10507
10508 return Qnil;
10509 }
10510 #endif
10511
10512
10513
10514
10515
10516
10517
10518
10519 frame_parm_handler w32_frame_parm_handlers[] =
10520 {
10521 gui_set_autoraise,
10522 gui_set_autolower,
10523 w32_set_background_color,
10524 w32_set_border_color,
10525 gui_set_border_width,
10526 w32_set_cursor_color,
10527 w32_set_cursor_type,
10528 gui_set_font,
10529 w32_set_foreground_color,
10530 w32_set_icon_name,
10531 w32_set_icon_type,
10532 w32_set_child_frame_border_width,
10533 w32_set_internal_border_width,
10534 gui_set_right_divider_width,
10535 gui_set_bottom_divider_width,
10536 w32_set_menu_bar_lines,
10537 w32_set_mouse_color,
10538 w32_explicitly_set_name,
10539 gui_set_scroll_bar_width,
10540 gui_set_scroll_bar_height,
10541 w32_set_title,
10542 gui_set_unsplittable,
10543 gui_set_vertical_scroll_bars,
10544 gui_set_horizontal_scroll_bars,
10545 gui_set_visibility,
10546 w32_set_tab_bar_lines,
10547 w32_set_tool_bar_lines,
10548 0,
10549 0,
10550 gui_set_screen_gamma,
10551 gui_set_line_spacing,
10552 gui_set_left_fringe,
10553 gui_set_right_fringe,
10554 0,
10555 gui_set_fullscreen,
10556 gui_set_font_backend,
10557 gui_set_alpha,
10558 0,
10559 0,
10560 w32_set_inhibit_double_buffering,
10561 w32_set_undecorated,
10562 w32_set_parent_frame,
10563 w32_set_skip_taskbar,
10564 w32_set_no_focus_on_map,
10565 w32_set_no_accept_focus,
10566 w32_set_z_group,
10567 0,
10568 gui_set_no_special_glyphs,
10569 gui_set_alpha_background,
10570 0,
10571 };
10572
10573 void
10574 syms_of_w32fns (void)
10575 {
10576 globals_of_w32fns ();
10577 track_mouse_window = NULL;
10578
10579 w32_visible_system_caret_hwnd = NULL;
10580 PDUMPER_IGNORE (w32_visible_system_caret_hwnd);
10581
10582 DEFSYM (Qundefined_color, "undefined-color");
10583 DEFSYM (Qcancel_timer, "cancel-timer");
10584 DEFSYM (Qhyper, "hyper");
10585 DEFSYM (Qsuper, "super");
10586 DEFSYM (Qmeta, "meta");
10587 DEFSYM (Qalt, "alt");
10588 DEFSYM (Qctrl, "ctrl");
10589 DEFSYM (Qcontrol, "control");
10590 DEFSYM (Qshift, "shift");
10591 DEFSYM (Qfont_parameter, "font-parameter");
10592 DEFSYM (Qgeometry, "geometry");
10593 DEFSYM (Qworkarea, "workarea");
10594 DEFSYM (Qmm_size, "mm-size");
10595 DEFSYM (Qframes, "frames");
10596 DEFSYM (Qtip_frame, "tip-frame");
10597 DEFSYM (Qassq_delete_all, "assq-delete-all");
10598 DEFSYM (Qunicode_sip, "unicode-sip");
10599 #if defined WINDOWSNT && !defined HAVE_DBUS
10600 DEFSYM (QCicon, ":icon");
10601 DEFSYM (QCtip, ":tip");
10602 DEFSYM (QClevel, ":level");
10603 DEFSYM (Qinfo, "info");
10604 DEFSYM (Qwarning, "warning");
10605 DEFSYM (QCtitle, ":title");
10606 DEFSYM (QCbody, ":body");
10607 #endif
10608
10609 #ifdef WINDOWSNT
10610 DEFSYM (QHKCR, "HKCR");
10611 DEFSYM (QHKCU, "HKCU");
10612 DEFSYM (QHKLM, "HKLM");
10613 DEFSYM (QHKU, "HKU");
10614 DEFSYM (QHKCC, "HKCC");
10615 #endif
10616
10617
10618 DEFSYM (Qgnutls, "gnutls");
10619 DEFSYM (Qlibxml2, "libxml2");
10620 DEFSYM (Qserif, "serif");
10621 DEFSYM (Qzlib, "zlib");
10622 DEFSYM (Qlcms2, "lcms2");
10623 DEFSYM (Qjson, "json");
10624
10625 Fput (Qundefined_color, Qerror_conditions,
10626 pure_list (Qundefined_color, Qerror));
10627 Fput (Qundefined_color, Qerror_message,
10628 build_pure_c_string ("Undefined color"));
10629
10630 staticpro (&w32_grabbed_keys);
10631 w32_grabbed_keys = Qnil;
10632
10633 DEFVAR_LISP ("w32-color-map", Vw32_color_map,
10634 doc: );
10635 Vw32_color_map = Qnil;
10636
10637 DEFVAR_LISP ("w32-pass-alt-to-system", Vw32_pass_alt_to_system,
10638 doc:
10639
10640
10641 );
10642 Vw32_pass_alt_to_system = Qnil;
10643
10644 DEFVAR_LISP ("w32-alt-is-meta", Vw32_alt_is_meta,
10645 doc:
10646 );
10647 Vw32_alt_is_meta = Qt;
10648
10649 DEFVAR_INT ("w32-quit-key", w32_quit_key,
10650 doc: );
10651 w32_quit_key = 0;
10652
10653 DEFVAR_LISP ("w32-pass-lwindow-to-system",
10654 Vw32_pass_lwindow_to_system,
10655 doc:
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669 );
10670 Vw32_pass_lwindow_to_system = Qt;
10671
10672 DEFVAR_LISP ("w32-pass-rwindow-to-system",
10673 Vw32_pass_rwindow_to_system,
10674 doc:
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688 );
10689 Vw32_pass_rwindow_to_system = Qt;
10690
10691 DEFVAR_LISP ("w32-phantom-key-code",
10692 Vw32_phantom_key_code,
10693 doc:
10694
10695
10696
10697
10698
10699
10700
10701
10702 );
10703
10704
10705 XSETINT (Vw32_phantom_key_code, 255);
10706
10707 DEFVAR_LISP ("w32-enable-num-lock",
10708 Vw32_enable_num_lock,
10709 doc:
10710 );
10711 Vw32_enable_num_lock = Qt;
10712
10713 DEFVAR_LISP ("w32-enable-caps-lock",
10714 Vw32_enable_caps_lock,
10715 doc:
10716 );
10717 Vw32_enable_caps_lock = Qt;
10718
10719 DEFVAR_LISP ("w32-scroll-lock-modifier",
10720 Vw32_scroll_lock_modifier,
10721 doc:
10722
10723
10724
10725 );
10726 Vw32_scroll_lock_modifier = Qnil;
10727
10728 DEFVAR_LISP ("w32-lwindow-modifier",
10729 Vw32_lwindow_modifier,
10730 doc:
10731
10732
10733
10734
10735 );
10736 Vw32_lwindow_modifier = Qnil;
10737
10738 DEFVAR_LISP ("w32-rwindow-modifier",
10739 Vw32_rwindow_modifier,
10740 doc:
10741
10742
10743
10744
10745 );
10746 Vw32_rwindow_modifier = Qnil;
10747
10748 DEFVAR_LISP ("w32-apps-modifier",
10749 Vw32_apps_modifier,
10750 doc:
10751
10752
10753 );
10754 Vw32_apps_modifier = Qnil;
10755
10756 DEFVAR_BOOL ("w32-enable-synthesized-fonts", w32_enable_synthesized_fonts,
10757 doc: );
10758 w32_enable_synthesized_fonts = 0;
10759
10760 DEFVAR_LISP ("w32-enable-palette", Vw32_enable_palette,
10761 doc: );
10762 Vw32_enable_palette = Qt;
10763
10764 DEFVAR_INT ("w32-mouse-button-tolerance",
10765 w32_mouse_button_tolerance,
10766 doc:
10767
10768
10769
10770 );
10771 w32_mouse_button_tolerance = GetDoubleClickTime () / 2;
10772
10773 DEFVAR_INT ("w32-mouse-move-interval",
10774 w32_mouse_move_interval,
10775 doc:
10776
10777
10778 );
10779 w32_mouse_move_interval = 0;
10780
10781 DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
10782 w32_pass_extra_mouse_buttons_to_system,
10783 doc:
10784
10785
10786
10787
10788 );
10789 w32_pass_extra_mouse_buttons_to_system = 0;
10790
10791 DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
10792 w32_pass_multimedia_buttons_to_system,
10793 doc:
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811 );
10812 w32_pass_multimedia_buttons_to_system = 1;
10813
10814 #if 0
10815 DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
10816 doc: );
10817 Vx_pointer_shape = Qnil;
10818
10819 Vx_nontext_pointer_shape = Qnil;
10820
10821 Vx_mode_pointer_shape = Qnil;
10822
10823 DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
10824 doc: );
10825 Vx_hourglass_pointer_shape = Qnil;
10826
10827 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
10828 Vx_sensitive_text_pointer_shape,
10829 doc: );
10830 Vx_sensitive_text_pointer_shape = Qnil;
10831
10832 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
10833 Vx_window_horizontal_drag_shape,
10834 doc: );
10835 Vx_window_horizontal_drag_shape = Qnil;
10836
10837 DEFVAR_LISP ("x-window-vertical-drag-cursor",
10838 Vx_window_vertical_drag_shape,
10839 doc: );
10840 Vx_window_vertical_drag_shape = Qnil;
10841 #endif
10842
10843 DEFVAR_LISP ("x-cursor-fore-pixel", Vx_cursor_fore_pixel,
10844 doc: );
10845 Vx_cursor_fore_pixel = Qnil;
10846
10847 DEFVAR_LISP ("x-max-tooltip-size", Vx_max_tooltip_size,
10848 doc: );
10849 Vx_max_tooltip_size = Qnil;
10850
10851 DEFVAR_LISP ("x-no-window-manager", Vx_no_window_manager,
10852 doc: );
10853
10854
10855 Vx_no_window_manager = Qnil;
10856
10857 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
10858 Vx_pixel_size_width_font_regexp,
10859 doc: );
10860 Vx_pixel_size_width_font_regexp = Qnil;
10861
10862 DEFVAR_BOOL ("w32-strict-painting",
10863 w32_strict_painting,
10864 doc:
10865
10866 );
10867 w32_strict_painting = 1;
10868
10869 DEFVAR_BOOL ("w32-use-fallback-wm-chars-method",
10870 w32_use_fallback_wm_chars_method,
10871 doc:
10872
10873
10874
10875 );
10876 w32_use_fallback_wm_chars_method = 0;
10877
10878 DEFVAR_BOOL ("w32-disable-new-uniscribe-apis",
10879 w32_disable_new_uniscribe_apis,
10880 doc:
10881
10882
10883
10884
10885 );
10886 w32_disable_new_uniscribe_apis = 0;
10887
10888 DEFVAR_LISP ("w32-tooltip-extra-pixels",
10889 Vw32_tooltip_extra_pixels,
10890 doc:
10891
10892
10893
10894
10895
10896
10897 );
10898 Vw32_tooltip_extra_pixels = Qt;
10899
10900 DEFVAR_BOOL ("w32-disable-abort-dialog",
10901 w32_disable_abort_dialog,
10902 doc: );
10903 w32_disable_abort_dialog = 0;
10904
10905 DEFVAR_BOOL ("w32-ignore-modifiers-on-IME-input",
10906 w32_ignore_modifiers_on_IME_input,
10907 doc:
10908
10909
10910
10911 );
10912 w32_ignore_modifiers_on_IME_input = true;
10913
10914 #if 0
10915 defsubr (&Sx_change_window_property);
10916 defsubr (&Sx_delete_window_property);
10917 defsubr (&Sx_window_property);
10918 #endif
10919 defsubr (&Sxw_display_color_p);
10920 defsubr (&Sx_display_grayscale_p);
10921 defsubr (&Sxw_color_defined_p);
10922 defsubr (&Sxw_color_values);
10923 defsubr (&Sx_server_max_request_size);
10924 defsubr (&Sx_server_vendor);
10925 defsubr (&Sx_server_version);
10926 defsubr (&Sx_display_pixel_width);
10927 defsubr (&Sx_display_pixel_height);
10928 defsubr (&Sx_display_mm_width);
10929 defsubr (&Sx_display_mm_height);
10930 defsubr (&Sx_display_screens);
10931 defsubr (&Sx_display_planes);
10932 defsubr (&Sx_display_color_cells);
10933 defsubr (&Sx_display_visual_class);
10934 defsubr (&Sx_display_backing_store);
10935 defsubr (&Sx_display_save_under);
10936 defsubr (&Sx_create_frame);
10937 defsubr (&Sx_open_connection);
10938 defsubr (&Sx_close_connection);
10939 defsubr (&Sx_display_list);
10940 defsubr (&Sw32_frame_geometry);
10941 defsubr (&Sw32_frame_edges);
10942 defsubr (&Sw32_frame_list_z_order);
10943 defsubr (&Sw32_frame_restack);
10944 defsubr (&Sw32_mouse_absolute_pixel_position);
10945 defsubr (&Sw32_set_mouse_absolute_pixel_position);
10946 defsubr (&Sx_synchronize);
10947
10948
10949
10950 defsubr (&Sw32_define_rgb_color);
10951 defsubr (&Sw32_display_monitor_attributes_list);
10952 defsubr (&Sw32_send_sys_command);
10953 defsubr (&Sw32_shell_execute);
10954 defsubr (&Sw32_register_hot_key);
10955 defsubr (&Sw32_unregister_hot_key);
10956 defsubr (&Sw32_registered_hot_keys);
10957 defsubr (&Sw32_reconstruct_hot_key);
10958 defsubr (&Sw32_toggle_lock_key);
10959 defsubr (&Sw32_window_exists_p);
10960 defsubr (&Sw32__menu_bar_in_use);
10961 #if defined WINDOWSNT && !defined HAVE_DBUS
10962 defsubr (&Sw32_notification_notify);
10963 defsubr (&Sw32_notification_close);
10964 #endif
10965 defsubr (&Sw32_get_ime_open_status);
10966 defsubr (&Sw32_set_ime_open_status);
10967
10968 #ifdef WINDOWSNT
10969 defsubr (&Sw32_read_registry);
10970 defsubr (&Sfile_system_info);
10971 defsubr (&Sdefault_printer_name);
10972 #endif
10973
10974 defsubr (&Sset_message_beep);
10975 defsubr (&Sx_show_tip);
10976 defsubr (&Sx_hide_tip);
10977 tip_timer = Qnil;
10978 staticpro (&tip_timer);
10979 tip_frame = Qnil;
10980 staticpro (&tip_frame);
10981 tip_last_frame = Qnil;
10982 staticpro (&tip_last_frame);
10983 tip_last_string = Qnil;
10984 staticpro (&tip_last_string);
10985 tip_last_parms = Qnil;
10986 staticpro (&tip_last_parms);
10987
10988 defsubr (&Sx_file_dialog);
10989 #ifdef WINDOWSNT
10990 defsubr (&Ssystem_move_file_to_trash);
10991 defsubr (&Sw32_set_wallpaper);
10992 #endif
10993 }
10994
10995
10996
10997
10998
10999 #ifndef CYGWIN
11000 static LONG CALLBACK my_exception_handler (EXCEPTION_POINTERS *);
11001 static LPTOP_LEVEL_EXCEPTION_FILTER prev_exception_handler;
11002 #endif
11003 static DWORD except_code;
11004 static PVOID except_addr;
11005
11006 #ifndef CYGWIN
11007
11008
11009
11010
11011
11012
11013 typedef int (__cdecl *_resetstkoflw_proc) (void);
11014 static _resetstkoflw_proc resetstkoflw;
11015
11016
11017
11018
11019
11020 void
11021 w32_reset_stack_overflow_guard (void)
11022 {
11023 if (resetstkoflw == NULL)
11024 resetstkoflw = (_resetstkoflw_proc)
11025 get_proc_addr (GetModuleHandle ("msvcrt.dll"), "_resetstkoflw");
11026
11027
11028 if (resetstkoflw != NULL)
11029 (void)resetstkoflw ();
11030 }
11031
11032 static void
11033 stack_overflow_handler (void)
11034 {
11035
11036
11037 if (gc_in_progress)
11038 terminate_due_to_signal (SIGSEGV, 40);
11039 #ifdef _WIN64
11040
11041 __builtin_longjmp (return_to_command_loop, 1);
11042 #else
11043 sys_longjmp (return_to_command_loop, 1);
11044 #endif
11045 }
11046
11047
11048
11049
11050
11051
11052
11053
11054 static LONG CALLBACK
11055 my_exception_handler (EXCEPTION_POINTERS * exception_data)
11056 {
11057 except_code = exception_data->ExceptionRecord->ExceptionCode;
11058 except_addr = exception_data->ExceptionRecord->ExceptionAddress;
11059
11060
11061 if (exception_data->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW
11062 && exception_data->ExceptionRecord->NumberParameters == 2
11063
11064 && GetCurrentThreadId () == dwMainThreadId)
11065 {
11066
11067 #ifdef _WIN64
11068 exception_data->ContextRecord->Rip = (DWORD_PTR) &stack_overflow_handler;
11069 #else
11070 exception_data->ContextRecord->Eip = (DWORD_PTR) &stack_overflow_handler;
11071 #endif
11072
11073
11074
11075 except_addr = 0;
11076 return EXCEPTION_CONTINUE_EXECUTION;
11077 }
11078
11079 if (prev_exception_handler)
11080 return prev_exception_handler (exception_data);
11081 return EXCEPTION_EXECUTE_HANDLER;
11082 }
11083 #endif
11084
11085 typedef USHORT (WINAPI * CaptureStackBackTrace_proc) (ULONG, ULONG, PVOID *,
11086 PULONG);
11087
11088 #define BACKTRACE_LIMIT_MAX 62
11089
11090 static int
11091 w32_backtrace (void **buffer, int limit)
11092 {
11093 static CaptureStackBackTrace_proc s_pfn_CaptureStackBackTrace = NULL;
11094 HMODULE hm_kernel32 = NULL;
11095
11096 if (!s_pfn_CaptureStackBackTrace)
11097 {
11098 hm_kernel32 = LoadLibrary ("Kernel32.dll");
11099 s_pfn_CaptureStackBackTrace = (CaptureStackBackTrace_proc)
11100 get_proc_addr (hm_kernel32, "RtlCaptureStackBackTrace");
11101 }
11102 if (s_pfn_CaptureStackBackTrace)
11103 return s_pfn_CaptureStackBackTrace (0, min (BACKTRACE_LIMIT_MAX, limit),
11104 buffer, NULL);
11105 return 0;
11106 }
11107
11108 void
11109 emacs_abort (void)
11110 {
11111 if (w32_disable_abort_dialog)
11112 abort ();
11113
11114 int button;
11115
11116 if (noninteractive)
11117 button = IDNO;
11118 else
11119 button = MessageBox (NULL,
11120 "A fatal error has occurred!\n\n"
11121 "Would you like to attach a debugger?\n\n"
11122 "Select:\n"
11123 "YES -- to debug Emacs, or\n"
11124 "NO -- to abort Emacs and produce a backtrace\n"
11125 " (emacs_backtrace.txt in current directory)."
11126 #if __GNUC__
11127 "\n\n(Before clicking YES, type\n"
11128 "\"gdb -p <emacs-PID>\", then \"continue\" inside GDB.)"
11129 #endif
11130 , "Emacs Abort Dialog",
11131 MB_ICONEXCLAMATION | MB_TASKMODAL
11132 | MB_SETFOREGROUND | MB_YESNO);
11133 switch (button)
11134 {
11135 case IDYES:
11136 DebugBreak ();
11137 exit (2);
11138 case IDNO:
11139 default:
11140 {
11141 void *stack[BACKTRACE_LIMIT_MAX + 1];
11142 int i = w32_backtrace (stack, BACKTRACE_LIMIT_MAX + 1);
11143
11144 if (i)
11145 {
11146 int errfile_fd = -1;
11147 int j;
11148 char buf[sizeof ("\r\nException at this address:\r\n\r\n")
11149
11150
11151
11152
11153
11154 + 2 * INT_BUFSIZE_BOUND (intptr_t)];
11155 #ifdef CYGWIN
11156 int stderr_fd = 2;
11157 #else
11158 HANDLE errout = GetStdHandle (STD_ERROR_HANDLE);
11159 int stderr_fd = -1;
11160
11161 if (errout && errout != INVALID_HANDLE_VALUE)
11162 stderr_fd = _open_osfhandle ((intptr_t)errout, O_APPEND | O_BINARY);
11163 #endif
11164
11165
11166
11167
11168 if (except_addr)
11169 sprintf (buf, "\r\nException 0x%x at this address:\r\n%p\r\n",
11170 (unsigned int) except_code, except_addr);
11171 if (stderr_fd >= 0)
11172 {
11173 if (except_addr)
11174 write (stderr_fd, buf, strlen (buf));
11175 write (stderr_fd, "\r\nBacktrace:\r\n", 14);
11176 }
11177 #ifdef CYGWIN
11178 #define _open open
11179 #endif
11180 errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
11181 if (errfile_fd >= 0)
11182 {
11183 lseek (errfile_fd, 0L, SEEK_END);
11184 if (except_addr)
11185 write (errfile_fd, buf, strlen (buf));
11186 write (errfile_fd, "\r\nBacktrace:\r\n", 14);
11187 }
11188
11189 for (j = 0; j < i; j++)
11190 {
11191
11192
11193
11194 sprintf (buf, "%p\r\n", (char *)stack[j] - sizeof(void *));
11195 if (stderr_fd >= 0)
11196 write (stderr_fd, buf, strlen (buf));
11197 if (errfile_fd >= 0)
11198 write (errfile_fd, buf, strlen (buf));
11199 }
11200 if (i == BACKTRACE_LIMIT_MAX)
11201 {
11202 if (stderr_fd >= 0)
11203 write (stderr_fd, "...\r\n", 5);
11204 if (errfile_fd >= 0)
11205 write (errfile_fd, "...\r\n", 5);
11206 }
11207 if (errfile_fd >= 0)
11208 close (errfile_fd);
11209 }
11210 abort ();
11211 break;
11212 }
11213 }
11214 }
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228 void
11229 globals_of_w32fns (void)
11230 {
11231 HMODULE user32_lib = GetModuleHandle ("user32.dll");
11232
11233
11234
11235
11236 track_mouse_event_fn = (TrackMouseEvent_Proc)
11237 get_proc_addr (user32_lib, "TrackMouseEvent");
11238
11239 monitor_from_point_fn = (MonitorFromPoint_Proc)
11240 get_proc_addr (user32_lib, "MonitorFromPoint");
11241 get_monitor_info_fn = (GetMonitorInfo_Proc)
11242 get_proc_addr (user32_lib, "GetMonitorInfoA");
11243 monitor_from_window_fn = (MonitorFromWindow_Proc)
11244 get_proc_addr (user32_lib, "MonitorFromWindow");
11245 enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
11246 get_proc_addr (user32_lib, "EnumDisplayMonitors");
11247 get_title_bar_info_fn = (GetTitleBarInfo_Proc)
11248 get_proc_addr (user32_lib, "GetTitleBarInfo");
11249 #ifndef CYGWIN
11250 system_parameters_info_w_fn = (SystemParametersInfoW_Proc)
11251 get_proc_addr (user32_lib, "SystemParametersInfoW");
11252 #endif
11253
11254 {
11255 HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
11256 get_composition_string_fn = (ImmGetCompositionString_Proc)
11257 get_proc_addr (imm32_lib, "ImmGetCompositionStringW");
11258 get_ime_context_fn = (ImmGetContext_Proc)
11259 get_proc_addr (imm32_lib, "ImmGetContext");
11260 release_ime_context_fn = (ImmReleaseContext_Proc)
11261 get_proc_addr (imm32_lib, "ImmReleaseContext");
11262 set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
11263 get_proc_addr (imm32_lib, "ImmSetCompositionWindow");
11264
11265 get_ime_open_status_fn = (ImmGetOpenStatus_Proc)
11266 get_proc_addr (imm32_lib, "ImmGetOpenStatus");
11267 set_ime_open_status_fn = (ImmSetOpenStatus_Proc)
11268 get_proc_addr (imm32_lib, "ImmSetOpenStatus");
11269 }
11270
11271 HMODULE hm_kernel32 = GetModuleHandle ("kernel32.dll");
11272 is_debugger_present = (IsDebuggerPresent_Proc)
11273 get_proc_addr (hm_kernel32, "IsDebuggerPresent");
11274 set_thread_description = (SetThreadDescription_Proc)
11275 get_proc_addr (hm_kernel32, "SetThreadDescription");
11276
11277
11278
11279
11280
11281
11282 if (os_subtype == OS_SUBTYPE_NT
11283 && w32_major_version >= 10 && w32_build_number >= 17763)
11284 {
11285
11286
11287 HMODULE dwmapi_lib = LoadLibrary("dwmapi.dll");
11288 DwmSetWindowAttribute_fn = (DwmSetWindowAttribute_Proc)
11289 get_proc_addr (dwmapi_lib, "DwmSetWindowAttribute");
11290 HMODULE uxtheme_lib = LoadLibrary("uxtheme.dll");
11291 SetWindowTheme_fn = (SetWindowTheme_Proc)
11292 get_proc_addr (uxtheme_lib, "SetWindowTheme");
11293
11294
11295
11296
11297
11298
11299
11300 LPBYTE val =
11301 w32_get_resource ("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
11302 "AppsUseLightTheme",
11303 NULL);
11304 if (val && *val == 0)
11305 w32_darkmode = TRUE;
11306 }
11307
11308 except_code = 0;
11309 except_addr = 0;
11310 #ifndef CYGWIN
11311 prev_exception_handler = SetUnhandledExceptionFilter (my_exception_handler);
11312 resetstkoflw = NULL;
11313 #endif
11314
11315 DEFVAR_INT ("w32-ansi-code-page",
11316 w32_ansi_code_page,
11317 doc: );
11318 w32_ansi_code_page = GetACP ();
11319
11320 #ifndef CYGWIN
11321 DEFVAR_INT ("w32-multibyte-code-page",
11322 w32_multibyte_code_page,
11323 doc:
11324
11325 );
11326 w32_multibyte_code_page = _getmbcp ();
11327 #endif
11328
11329 DEFVAR_BOOL ("w32-disable-double-buffering", w32_disable_double_buffering,
11330 doc:
11331
11332 );
11333 w32_disable_double_buffering = false;
11334
11335 if (os_subtype == OS_SUBTYPE_NT)
11336 w32_unicode_gui = 1;
11337 else
11338 w32_unicode_gui = 0;
11339
11340 after_deadkey = -1;
11341
11342
11343 InitCommonControls ();
11344
11345 syms_of_w32uniscribe ();
11346 }
11347
11348 #ifdef NTGUI_UNICODE
11349
11350 Lisp_Object
11351 ntgui_encode_system (Lisp_Object str)
11352 {
11353 Lisp_Object encoded;
11354 to_unicode (str, &encoded);
11355 return encoded;
11356 }
11357
11358 #endif