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