1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20
21
22
23 #include <config.h>
24
25 #include <signal.h>
26 #include <stdio.h>
27 #include <limits.h>
28 #include <errno.h>
29 #include <math.h>
30 #include <setjmp.h>
31
32 #include "lisp.h"
33 #include "w32term.h"
34 #include "frame.h"
35 #include "window.h"
36 #include "buffer.h"
37 #include "intervals.h"
38 #include "dispextern.h"
39 #include "keyboard.h"
40 #include "blockinput.h"
41 #include "epaths.h"
42 #include "character.h"
43 #include "charset.h"
44 #include "coding.h"
45 #include "ccl.h"
46 #include "fontset.h"
47 #include "systime.h"
48 #include "termhooks.h"
49 #include "w32heap.h"
50 #include "w32.h"
51
52 #include "bitmaps/gray.xbm"
53
54 #include <commctrl.h>
55 #include <commdlg.h>
56 #include <shellapi.h>
57 #include <ctype.h>
58 #include <winspool.h>
59 #include <objbase.h>
60
61 #include <dlgs.h>
62 #include <imm.h>
63 #define FILE_NAME_TEXT_FIELD edt1
64
65 #include "font.h"
66 #include "w32font.h"
67
68 #ifndef FOF_NO_CONNECTED_ELEMENTS
69 #define FOF_NO_CONNECTED_ELEMENTS 0x2000
70 #endif
71
72 void syms_of_w32fns ();
73 void globals_of_w32fns ();
74
75 extern void free_frame_menubar ();
76 extern double atof ();
77 extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
78 extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
79 extern void w32_free_menu_strings P_ ((HWND));
80 extern const char *map_w32_filename P_ ((const char *, const char **));
81
82 extern int quit_char;
83
84 extern char *lispy_function_keys[];
85
86
87 Lisp_Object Vw32_color_map;
88
89
90 Lisp_Object Vw32_pass_alt_to_system;
91
92 93
94 Lisp_Object Vw32_alt_is_meta;
95
96
97 int w32_quit_key;
98
99 100
101 Lisp_Object Vw32_pass_lwindow_to_system;
102
103 104
105 Lisp_Object Vw32_pass_rwindow_to_system;
106
107 108
109 Lisp_Object Vw32_phantom_key_code;
110
111 112
113 Lisp_Object Vw32_lwindow_modifier;
114
115 116
117 Lisp_Object Vw32_rwindow_modifier;
118
119 120
121 Lisp_Object Vw32_apps_modifier;
122
123
124 Lisp_Object Vw32_enable_num_lock;
125
126
127 Lisp_Object Vw32_enable_caps_lock;
128
129
130 Lisp_Object Vw32_scroll_lock_modifier;
131
132 133
134 int w32_enable_synthesized_fonts;
135
136
137 Lisp_Object Vw32_enable_palette;
138
139 140
141 int w32_mouse_button_tolerance;
142
143 144
145 int w32_mouse_move_interval;
146
147
148 static int w32_pass_extra_mouse_buttons_to_system;
149
150
151 static int w32_pass_multimedia_buttons_to_system;
152
153
154 Lisp_Object Vx_no_window_manager;
155
156 157
158 static unsigned hourglass_timer = 0;
159 static HWND hourglass_hwnd = NULL;
160
161 #if 0
162 163
164 Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
165 Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;
166
167
168
169 Lisp_Object Vx_sensitive_text_pointer_shape;
170 #endif
171
172 #ifndef IDC_HAND
173 #define IDC_HAND MAKEINTRESOURCE(32649)
174 #endif
175
176
177 Lisp_Object Vx_cursor_fore_pixel;
178
179
180
181 static int w32_in_use;
182
183
184
185 Lisp_Object Vx_pixel_size_width_font_regexp;
186
187
188 Lisp_Object Vw32_bdf_filename_alist;
189
190
191 static int w32_strict_fontnames;
192
193 194
195 static int w32_strict_painting;
196
197 Lisp_Object Qnone;
198 Lisp_Object Qsuppress_icon;
199 Lisp_Object Qundefined_color;
200 Lisp_Object Qcancel_timer;
201 Lisp_Object Qfont_param;
202 Lisp_Object Qhyper;
203 Lisp_Object Qsuper;
204 Lisp_Object Qmeta;
205 Lisp_Object Qalt;
206 Lisp_Object Qctrl;
207 Lisp_Object Qcontrol;
208 Lisp_Object Qshift;
209
210
211
212 int w32_ansi_code_page;
213
214
215 #define SYSTEM_COLOR_PREFIX "System"
216 #define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
217
218
219 #define LMOUSE 1
220 #define MMOUSE 2
221 #define RMOUSE 4
222
223 static int button_state = 0;
224 static W32Msg saved_mouse_button_msg;
225 static unsigned mouse_button_timer = 0;
226 static W32Msg saved_mouse_move_msg;
227 static unsigned mouse_move_timer = 0;
228
229
230 static HWND track_mouse_window;
231
232 233
234 #ifndef MONITOR_DEFAULT_TO_NEAREST
235 #define MONITOR_DEFAULT_TO_NEAREST 2
236 #endif
237 238
239 struct MONITOR_INFO
240 {
241 DWORD cbSize;
242 RECT rcMonitor;
243 RECT rcWork;
244 DWORD dwFlags;
245 };
246
247
248 #if defined(_MSC_VER) && _MSC_VER < 1300
249 DECLARE_HANDLE(HMONITOR);
250 #endif
251
252 typedef BOOL (WINAPI * TrackMouseEvent_Proc)
253 (IN OUT LPTRACKMOUSEEVENT lpEventTrack);
254 typedef LONG (WINAPI * ImmGetCompositionString_Proc)
255 (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen);
256 typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window);
257 typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context);
258 typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context,
259 IN COMPOSITIONFORM *form);
260 typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
261 typedef BOOL (WINAPI * GetMonitorInfo_Proc)
262 (IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
263
264 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
265 ClipboardSequence_Proc clipboard_sequence_fn = NULL;
266 ImmGetCompositionString_Proc get_composition_string_fn = NULL;
267 ImmGetContext_Proc get_ime_context_fn = NULL;
268 ImmReleaseContext_Proc release_ime_context_fn = NULL;
269 ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
270 MonitorFromPoint_Proc monitor_from_point_fn = NULL;
271 GetMonitorInfo_Proc get_monitor_info_fn = NULL;
272
273 extern AppendMenuW_Proc unicode_append_menu;
274
275
276 static int ignore_ime_char = 0;
277
278
279 unsigned int msh_mousewheel = 0;
280
281
282 #define MOUSE_BUTTON_ID 1
283 #define MOUSE_MOVE_ID 2
284 #define MENU_FREE_ID 3
285 #define HOURGLASS_ID 4
286 287
288 #define MENU_FREE_DELAY 1000
289 static unsigned menu_free_timer = 0;
290
291
292
293 extern Lisp_Object Vwindow_system_version;
294
295 #ifdef GLYPH_DEBUG
296 int image_cache_refcount, dpyinfo_refcount;
297 #endif
298
299
300
301 extern int w32_num_mouse_buttons;
302 extern Lisp_Object Vw32_recognize_altgr;
303
304 extern HWND w32_system_caret_hwnd;
305
306 extern int w32_system_caret_height;
307 extern int w32_system_caret_x;
308 extern int w32_system_caret_y;
309 extern int w32_use_visible_system_caret;
310
311 static HWND w32_visible_system_caret_hwnd;
312
313
314 extern HMENU current_popup_menu;
315 static int menubar_in_use = 0;
316
317
318 extern void syms_of_w32uniscribe ();
319 extern int uniscribe_available;
320
321
322 static void w32_show_hourglass P_ ((struct frame *));
323 static void w32_hide_hourglass P_ ((void));
324
325
326
327
328 void
329 check_w32 ()
330 {
331 if (! w32_in_use)
332 error ("MS-Windows not in use or not initialized");
333 }
334
335 336
337
338 int
339 have_menus_p ()
340 {
341 return w32_in_use;
342 }
343
344 345
346
347 FRAME_PTR
348 check_x_frame (frame)
349 Lisp_Object frame;
350 {
351 FRAME_PTR f;
352
353 if (NILP (frame))
354 frame = selected_frame;
355 CHECK_LIVE_FRAME (frame);
356 f = XFRAME (frame);
357 if (! FRAME_W32_P (f))
358 error ("Non-W32 frame used");
359 return f;
360 }
361
362 363 364
365
366 struct w32_display_info *
367 check_x_display_info (frame)
368 Lisp_Object frame;
369 {
370 if (NILP (frame))
371 {
372 struct frame *sf = XFRAME (selected_frame);
373
374 if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf))
375 return FRAME_W32_DISPLAY_INFO (sf);
376 else
377 return &one_w32_display_info;
378 }
379 else if (STRINGP (frame))
380 return x_display_info_for_name (frame);
381 else
382 {
383 FRAME_PTR f;
384
385 CHECK_LIVE_FRAME (frame);
386 f = XFRAME (frame);
387 if (! FRAME_W32_P (f))
388 error ("Non-W32 frame used");
389 return FRAME_W32_DISPLAY_INFO (f);
390 }
391 }
392
393 394
395
396
397
398 struct frame *
399 x_window_to_frame (dpyinfo, wdesc)
400 struct w32_display_info *dpyinfo;
401 HWND wdesc;
402 {
403 Lisp_Object tail, frame;
404 struct frame *f;
405
406 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
407 {
408 frame = XCAR (tail);
409 if (!FRAMEP (frame))
410 continue;
411 f = XFRAME (frame);
412 if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
413 continue;
414
415 if (FRAME_W32_WINDOW (f) == wdesc)
416 return f;
417 }
418 return 0;
419 }
420
421
422 static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
423 static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
424 static void my_create_window P_ ((struct frame *));
425 static void my_create_tip_window P_ ((struct frame *));
426
427
428 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
429 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
430 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
431 void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
432 void x_set_border_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
433 void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
434 void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object));
435 void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
436 void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object));
437 void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
438 void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object));
439 void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
440 static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
441 Lisp_Object));
442
443
444
445
446 447 448
449
450 void
451 x_real_positions (f, xptr, yptr)
452 FRAME_PTR f;
453 int *xptr, *yptr;
454 {
455 POINT pt;
456 RECT rect;
457
458
459 GetWindowRect (FRAME_W32_WINDOW (f), &rect);
460
461 pt.x = 0;
462 pt.y = 0;
463
464
465 ClientToScreen (FRAME_W32_WINDOW (f), &pt);
466
467
468 f->x_pixels_diff = pt.x - rect.left;
469 f->y_pixels_diff = pt.y - rect.top;
470
471 *xptr = rect.left;
472 *yptr = rect.top;
473 }
474
475
476
477 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
478 Sw32_define_rgb_color, 4, 4, 0,
479 doc: 480 481 482 )
483 (red, green, blue, name)
484 Lisp_Object red, green, blue, name;
485 {
486 Lisp_Object rgb;
487 Lisp_Object oldrgb = Qnil;
488 Lisp_Object entry;
489
490 CHECK_NUMBER (red);
491 CHECK_NUMBER (green);
492 CHECK_NUMBER (blue);
493 CHECK_STRING (name);
494
495 XSETINT (rgb, RGB (XUINT (red), XUINT (green), XUINT (blue)));
496
497 BLOCK_INPUT;
498
499
500 entry = Fassoc (name, Vw32_color_map);
501 if (NILP (entry))
502 {
503 entry = Fcons (name, rgb);
504 Vw32_color_map = Fcons (entry, Vw32_color_map);
505 }
506 else
507 {
508 oldrgb = Fcdr (entry);
509 Fsetcdr (entry, rgb);
510 }
511
512 UNBLOCK_INPUT;
513
514 return (oldrgb);
515 }
516
517
518 typedef struct colormap_t
519 {
520 char *name;
521 COLORREF colorref;
522 } colormap_t;
523
524 colormap_t w32_color_map[] =
525 {
526 {"snow" , PALETTERGB (255,250,250)},
527 {"ghost white" , PALETTERGB (248,248,255)},
528 {"GhostWhite" , PALETTERGB (248,248,255)},
529 {"white smoke" , PALETTERGB (245,245,245)},
530 {"WhiteSmoke" , PALETTERGB (245,245,245)},
531 {"gainsboro" , PALETTERGB (220,220,220)},
532 {"floral white" , PALETTERGB (255,250,240)},
533 {"FloralWhite" , PALETTERGB (255,250,240)},
534 {"old lace" , PALETTERGB (253,245,230)},
535 {"OldLace" , PALETTERGB (253,245,230)},
536 {"linen" , PALETTERGB (250,240,230)},
537 {"antique white" , PALETTERGB (250,235,215)},
538 {"AntiqueWhite" , PALETTERGB (250,235,215)},
539 {"papaya whip" , PALETTERGB (255,239,213)},
540 {"PapayaWhip" , PALETTERGB (255,239,213)},
541 {"blanched almond" , PALETTERGB (255,235,205)},
542 {"BlanchedAlmond" , PALETTERGB (255,235,205)},
543 {"bisque" , PALETTERGB (255,228,196)},
544 {"peach puff" , PALETTERGB (255,218,185)},
545 {"PeachPuff" , PALETTERGB (255,218,185)},
546 {"navajo white" , PALETTERGB (255,222,173)},
547 {"NavajoWhite" , PALETTERGB (255,222,173)},
548 {"moccasin" , PALETTERGB (255,228,181)},
549 {"cornsilk" , PALETTERGB (255,248,220)},
550 {"ivory" , PALETTERGB (255,255,240)},
551 {"lemon chiffon" , PALETTERGB (255,250,205)},
552 {"LemonChiffon" , PALETTERGB (255,250,205)},
553 {"seashell" , PALETTERGB (255,245,238)},
554 {"honeydew" , PALETTERGB (240,255,240)},
555 {"mint cream" , PALETTERGB (245,255,250)},
556 {"MintCream" , PALETTERGB (245,255,250)},
557 {"azure" , PALETTERGB (240,255,255)},
558 {"alice blue" , PALETTERGB (240,248,255)},
559 {"AliceBlue" , PALETTERGB (240,248,255)},
560 {"lavender" , PALETTERGB (230,230,250)},
561 {"lavender blush" , PALETTERGB (255,240,245)},
562 {"LavenderBlush" , PALETTERGB (255,240,245)},
563 {"misty rose" , PALETTERGB (255,228,225)},
564 {"MistyRose" , PALETTERGB (255,228,225)},
565 {"white" , PALETTERGB (255,255,255)},
566 {"black" , PALETTERGB ( 0, 0, 0)},
567 {"dark slate gray" , PALETTERGB ( 47, 79, 79)},
568 {"DarkSlateGray" , PALETTERGB ( 47, 79, 79)},
569 {"dark slate grey" , PALETTERGB ( 47, 79, 79)},
570 {"DarkSlateGrey" , PALETTERGB ( 47, 79, 79)},
571 {"dim gray" , PALETTERGB (105,105,105)},
572 {"DimGray" , PALETTERGB (105,105,105)},
573 {"dim grey" , PALETTERGB (105,105,105)},
574 {"DimGrey" , PALETTERGB (105,105,105)},
575 {"slate gray" , PALETTERGB (112,128,144)},
576 {"SlateGray" , PALETTERGB (112,128,144)},
577 {"slate grey" , PALETTERGB (112,128,144)},
578 {"SlateGrey" , PALETTERGB (112,128,144)},
579 {"light slate gray" , PALETTERGB (119,136,153)},
580 {"LightSlateGray" , PALETTERGB (119,136,153)},
581 {"light slate grey" , PALETTERGB (119,136,153)},
582 {"LightSlateGrey" , PALETTERGB (119,136,153)},
583 {"gray" , PALETTERGB (190,190,190)},
584 {"grey" , PALETTERGB (190,190,190)},
585 {"light grey" , PALETTERGB (211,211,211)},
586 {"LightGrey" , PALETTERGB (211,211,211)},
587 {"light gray" , PALETTERGB (211,211,211)},
588 {"LightGray" , PALETTERGB (211,211,211)},
589 {"midnight blue" , PALETTERGB ( 25, 25,112)},
590 {"MidnightBlue" , PALETTERGB ( 25, 25,112)},
591 {"navy" , PALETTERGB ( 0, 0,128)},
592 {"navy blue" , PALETTERGB ( 0, 0,128)},
593 {"NavyBlue" , PALETTERGB ( 0, 0,128)},
594 {"cornflower blue" , PALETTERGB (100,149,237)},
595 {"CornflowerBlue" , PALETTERGB (100,149,237)},
596 {"dark slate blue" , PALETTERGB ( 72, 61,139)},
597 {"DarkSlateBlue" , PALETTERGB ( 72, 61,139)},
598 {"slate blue" , PALETTERGB (106, 90,205)},
599 {"SlateBlue" , PALETTERGB (106, 90,205)},
600 {"medium slate blue" , PALETTERGB (123,104,238)},
601 {"MediumSlateBlue" , PALETTERGB (123,104,238)},
602 {"light slate blue" , PALETTERGB (132,112,255)},
603 {"LightSlateBlue" , PALETTERGB (132,112,255)},
604 {"medium blue" , PALETTERGB ( 0, 0,205)},
605 {"MediumBlue" , PALETTERGB ( 0, 0,205)},
606 {"royal blue" , PALETTERGB ( 65,105,225)},
607 {"RoyalBlue" , PALETTERGB ( 65,105,225)},
608 {"blue" , PALETTERGB ( 0, 0,255)},
609 {"dodger blue" , PALETTERGB ( 30,144,255)},
610 {"DodgerBlue" , PALETTERGB ( 30,144,255)},
611 {"deep sky blue" , PALETTERGB ( 0,191,255)},
612 {"DeepSkyBlue" , PALETTERGB ( 0,191,255)},
613 {"sky blue" , PALETTERGB (135,206,235)},
614 {"SkyBlue" , PALETTERGB (135,206,235)},
615 {"light sky blue" , PALETTERGB (135,206,250)},
616 {"LightSkyBlue" , PALETTERGB (135,206,250)},
617 {"steel blue" , PALETTERGB ( 70,130,180)},
618 {"SteelBlue" , PALETTERGB ( 70,130,180)},
619 {"light steel blue" , PALETTERGB (176,196,222)},
620 {"LightSteelBlue" , PALETTERGB (176,196,222)},
621 {"light blue" , PALETTERGB (173,216,230)},
622 {"LightBlue" , PALETTERGB (173,216,230)},
623 {"powder blue" , PALETTERGB (176,224,230)},
624 {"PowderBlue" , PALETTERGB (176,224,230)},
625 {"pale turquoise" , PALETTERGB (175,238,238)},
626 {"PaleTurquoise" , PALETTERGB (175,238,238)},
627 {"dark turquoise" , PALETTERGB ( 0,206,209)},
628 {"DarkTurquoise" , PALETTERGB ( 0,206,209)},
629 {"medium turquoise" , PALETTERGB ( 72,209,204)},
630 {"MediumTurquoise" , PALETTERGB ( 72,209,204)},
631 {"turquoise" , PALETTERGB ( 64,224,208)},
632 {"cyan" , PALETTERGB ( 0,255,255)},
633 {"light cyan" , PALETTERGB (224,255,255)},
634 {"LightCyan" , PALETTERGB (224,255,255)},
635 {"cadet blue" , PALETTERGB ( 95,158,160)},
636 {"CadetBlue" , PALETTERGB ( 95,158,160)},
637 {"medium aquamarine" , PALETTERGB (102,205,170)},
638 {"MediumAquamarine" , PALETTERGB (102,205,170)},
639 {"aquamarine" , PALETTERGB (127,255,212)},
640 {"dark green" , PALETTERGB ( 0,100, 0)},
641 {"DarkGreen" , PALETTERGB ( 0,100, 0)},
642 {"dark olive green" , PALETTERGB ( 85,107, 47)},
643 {"DarkOliveGreen" , PALETTERGB ( 85,107, 47)},
644 {"dark sea green" , PALETTERGB (143,188,143)},
645 {"DarkSeaGreen" , PALETTERGB (143,188,143)},
646 {"sea green" , PALETTERGB ( 46,139, 87)},
647 {"SeaGreen" , PALETTERGB ( 46,139, 87)},
648 {"medium sea green" , PALETTERGB ( 60,179,113)},
649 {"MediumSeaGreen" , PALETTERGB ( 60,179,113)},
650 {"light sea green" , PALETTERGB ( 32,178,170)},
651 {"LightSeaGreen" , PALETTERGB ( 32,178,170)},
652 {"pale green" , PALETTERGB (152,251,152)},
653 {"PaleGreen" , PALETTERGB (152,251,152)},
654 {"spring green" , PALETTERGB ( 0,255,127)},
655 {"SpringGreen" , PALETTERGB ( 0,255,127)},
656 {"lawn green" , PALETTERGB (124,252, 0)},
657 {"LawnGreen" , PALETTERGB (124,252, 0)},
658 {"green" , PALETTERGB ( 0,255, 0)},
659 {"chartreuse" , PALETTERGB (127,255, 0)},
660 {"medium spring green" , PALETTERGB ( 0,250,154)},
661 {"MediumSpringGreen" , PALETTERGB ( 0,250,154)},
662 {"green yellow" , PALETTERGB (173,255, 47)},
663 {"GreenYellow" , PALETTERGB (173,255, 47)},
664 {"lime green" , PALETTERGB ( 50,205, 50)},
665 {"LimeGreen" , PALETTERGB ( 50,205, 50)},
666 {"yellow green" , PALETTERGB (154,205, 50)},
667 {"YellowGreen" , PALETTERGB (154,205, 50)},
668 {"forest green" , PALETTERGB ( 34,139, 34)},
669 {"ForestGreen" , PALETTERGB ( 34,139, 34)},
670 {"olive drab" , PALETTERGB (107,142, 35)},
671 {"OliveDrab" , PALETTERGB (107,142, 35)},
672 {"dark khaki" , PALETTERGB (189,183,107)},
673 {"DarkKhaki" , PALETTERGB (189,183,107)},
674 {"khaki" , PALETTERGB (240,230,140)},
675 {"pale goldenrod" , PALETTERGB (238,232,170)},
676 {"PaleGoldenrod" , PALETTERGB (238,232,170)},
677 {"light goldenrod yellow" , PALETTERGB (250,250,210)},
678 {"LightGoldenrodYellow" , PALETTERGB (250,250,210)},
679 {"light yellow" , PALETTERGB (255,255,224)},
680 {"LightYellow" , PALETTERGB (255,255,224)},
681 {"yellow" , PALETTERGB (255,255, 0)},
682 {"gold" , PALETTERGB (255,215, 0)},
683 {"light goldenrod" , PALETTERGB (238,221,130)},
684 {"LightGoldenrod" , PALETTERGB (238,221,130)},
685 {"goldenrod" , PALETTERGB (218,165, 32)},
686 {"dark goldenrod" , PALETTERGB (184,134, 11)},
687 {"DarkGoldenrod" , PALETTERGB (184,134, 11)},
688 {"rosy brown" , PALETTERGB (188,143,143)},
689 {"RosyBrown" , PALETTERGB (188,143,143)},
690 {"indian red" , PALETTERGB (205, 92, 92)},
691 {"IndianRed" , PALETTERGB (205, 92, 92)},
692 {"saddle brown" , PALETTERGB (139, 69, 19)},
693 {"SaddleBrown" , PALETTERGB (139, 69, 19)},
694 {"sienna" , PALETTERGB (160, 82, 45)},
695 {"peru" , PALETTERGB (205,133, 63)},
696 {"burlywood" , PALETTERGB (222,184,135)},
697 {"beige" , PALETTERGB (245,245,220)},
698 {"wheat" , PALETTERGB (245,222,179)},
699 {"sandy brown" , PALETTERGB (244,164, 96)},
700 {"SandyBrown" , PALETTERGB (244,164, 96)},
701 {"tan" , PALETTERGB (210,180,140)},
702 {"chocolate" , PALETTERGB (210,105, 30)},
703 {"firebrick" , PALETTERGB (178,34, 34)},
704 {"brown" , PALETTERGB (165,42, 42)},
705 {"dark salmon" , PALETTERGB (233,150,122)},
706 {"DarkSalmon" , PALETTERGB (233,150,122)},
707 {"salmon" , PALETTERGB (250,128,114)},
708 {"light salmon" , PALETTERGB (255,160,122)},
709 {"LightSalmon" , PALETTERGB (255,160,122)},
710 {"orange" , PALETTERGB (255,165, 0)},
711 {"dark orange" , PALETTERGB (255,140, 0)},
712 {"DarkOrange" , PALETTERGB (255,140, 0)},
713 {"coral" , PALETTERGB (255,127, 80)},
714 {"light coral" , PALETTERGB (240,128,128)},
715 {"LightCoral" , PALETTERGB (240,128,128)},
716 {"tomato" , PALETTERGB (255, 99, 71)},
717 {"orange red" , PALETTERGB (255, 69, 0)},
718 {"OrangeRed" , PALETTERGB (255, 69, 0)},
719 {"red" , PALETTERGB (255, 0, 0)},
720 {"hot pink" , PALETTERGB (255,105,180)},
721 {"HotPink" , PALETTERGB (255,105,180)},
722 {"deep pink" , PALETTERGB (255, 20,147)},
723 {"DeepPink" , PALETTERGB (255, 20,147)},
724 {"pink" , PALETTERGB (255,192,203)},
725 {"light pink" , PALETTERGB (255,182,193)},
726 {"LightPink" , PALETTERGB (255,182,193)},
727 {"pale violet red" , PALETTERGB (219,112,147)},
728 {"PaleVioletRed" , PALETTERGB (219,112,147)},
729 {"maroon" , PALETTERGB (176, 48, 96)},
730 {"medium violet red" , PALETTERGB (199, 21,133)},
731 {"MediumVioletRed" , PALETTERGB (199, 21,133)},
732 {"violet red" , PALETTERGB (208, 32,144)},
733 {"VioletRed" , PALETTERGB (208, 32,144)},
734 {"magenta" , PALETTERGB (255, 0,255)},
735 {"violet" , PALETTERGB (238,130,238)},
736 {"plum" , PALETTERGB (221,160,221)},
737 {"orchid" , PALETTERGB (218,112,214)},
738 {"medium orchid" , PALETTERGB (186, 85,211)},
739 {"MediumOrchid" , PALETTERGB (186, 85,211)},
740 {"dark orchid" , PALETTERGB (153, 50,204)},
741 {"DarkOrchid" , PALETTERGB (153, 50,204)},
742 {"dark violet" , PALETTERGB (148, 0,211)},
743 {"DarkViolet" , PALETTERGB (148, 0,211)},
744 {"blue violet" , PALETTERGB (138, 43,226)},
745 {"BlueViolet" , PALETTERGB (138, 43,226)},
746 {"purple" , PALETTERGB (160, 32,240)},
747 {"medium purple" , PALETTERGB (147,112,219)},
748 {"MediumPurple" , PALETTERGB (147,112,219)},
749 {"thistle" , PALETTERGB (216,191,216)},
750 {"gray0" , PALETTERGB ( 0, 0, 0)},
751 {"grey0" , PALETTERGB ( 0, 0, 0)},
752 {"dark grey" , PALETTERGB (169,169,169)},
753 {"DarkGrey" , PALETTERGB (169,169,169)},
754 {"dark gray" , PALETTERGB (169,169,169)},
755 {"DarkGray" , PALETTERGB (169,169,169)},
756 {"dark blue" , PALETTERGB ( 0, 0,139)},
757 {"DarkBlue" , PALETTERGB ( 0, 0,139)},
758 {"dark cyan" , PALETTERGB ( 0,139,139)},
759 {"DarkCyan" , PALETTERGB ( 0,139,139)},
760 {"dark magenta" , PALETTERGB (139, 0,139)},
761 {"DarkMagenta" , PALETTERGB (139, 0,139)},
762 {"dark red" , PALETTERGB (139, 0, 0)},
763 {"DarkRed" , PALETTERGB (139, 0, 0)},
764 {"light green" , PALETTERGB (144,238,144)},
765 {"LightGreen" , PALETTERGB (144,238,144)},
766 };
767
768 DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
769 0, 0, 0, doc: )
770 ()
771 {
772 int i;
773 colormap_t *pc = w32_color_map;
774 Lisp_Object cmap;
775
776 BLOCK_INPUT;
777
778 cmap = Qnil;
779
780 for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]);
781 pc++, i++)
782 cmap = Fcons (Fcons (build_string (pc->name),
783 make_number (pc->colorref)),
784 cmap);
785
786 UNBLOCK_INPUT;
787
788 return (cmap);
789 }
790
791 static Lisp_Object
792 w32_to_x_color (rgb)
793 Lisp_Object rgb;
794 {
795 Lisp_Object color;
796
797 CHECK_NUMBER (rgb);
798
799 BLOCK_INPUT;
800
801 color = Frassq (rgb, Vw32_color_map);
802
803 UNBLOCK_INPUT;
804
805 if (!NILP (color))
806 return (Fcar (color));
807 else
808 return Qnil;
809 }
810
811 static Lisp_Object
812 w32_color_map_lookup (colorname)
813 char *colorname;
814 {
815 Lisp_Object tail, ret = Qnil;
816
817 BLOCK_INPUT;
818
819 for (tail = Vw32_color_map; CONSP (tail); tail = XCDR (tail))
820 {
821 register Lisp_Object elt, tem;
822
823 elt = XCAR (tail);
824 if (!CONSP (elt)) continue;
825
826 tem = Fcar (elt);
827
828 if (lstrcmpi (SDATA (tem), colorname) == 0)
829 {
830 ret = Fcdr (elt);
831 break;
832 }
833
834 QUIT;
835 }
836
837
838 UNBLOCK_INPUT;
839
840 return ret;
841 }
842
843
844 static void
845 add_system_logical_colors_to_map (system_colors)
846 Lisp_Object *system_colors;
847 {
848 HKEY colors_key;
849
850
851 BLOCK_INPUT;
852
853 854
855 if (RegOpenKeyEx (HKEY_CURRENT_USER, "Control Panel\\Colors", 0,
856 KEY_READ, &colors_key) == ERROR_SUCCESS
857 || RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Control Panel\\Colors", 0,
858 KEY_READ, &colors_key) == ERROR_SUCCESS)
859 {
860
861 char color_buffer[64];
862 char full_name_buffer[MAX_PATH + SYSTEM_COLOR_PREFIX_LEN];
863 int index = 0;
864 DWORD name_size, color_size;
865 char *name_buffer = full_name_buffer + SYSTEM_COLOR_PREFIX_LEN;
866
867 name_size = sizeof (full_name_buffer) - SYSTEM_COLOR_PREFIX_LEN;
868 color_size = sizeof (color_buffer);
869
870 strcpy (full_name_buffer, SYSTEM_COLOR_PREFIX);
871
872 while (RegEnumValueA (colors_key, index, name_buffer, &name_size,
873 NULL, NULL, color_buffer, &color_size)
874 == ERROR_SUCCESS)
875 {
876 int r, g, b;
877 if (sscanf (color_buffer, " %u %u %u", &r, &g, &b) == 3)
878 *system_colors = Fcons (Fcons (build_string (full_name_buffer),
879 make_number (RGB (r, g, b))),
880 *system_colors);
881
882 name_size = sizeof (full_name_buffer) - SYSTEM_COLOR_PREFIX_LEN;
883 color_size = sizeof (color_buffer);
884 index++;
885 }
886 RegCloseKey (colors_key);
887 }
888
889 UNBLOCK_INPUT;
890 }
891
892
893 static Lisp_Object
894 x_to_w32_color (colorname)
895 char * colorname;
896 {
897 register Lisp_Object ret = Qnil;
898
899 BLOCK_INPUT;
900
901 if (colorname[0] == '#')
902 {
903
904 char *color;
905 int size;
906 color = colorname + 1;
907
908 size = strlen (color);
909 if (size == 3 || size == 6 || size == 9 || size == 12)
910 {
911 UINT colorval;
912 int i, pos;
913 pos = 0;
914 size /= 3;
915 colorval = 0;
916
917 for (i = 0; i < 3; i++)
918 {
919 char *end;
920 char t;
921 unsigned long value;
922
923 924 925
926 if (!isxdigit (color[0]) || color[1] == 'x')
927 break;
928 t = color[size];
929 color[size] = '\0';
930 value = strtoul (color, &end, 16);
931 color[size] = t;
932 if (errno == ERANGE || end - color != size)
933 break;
934 switch (size)
935 {
936 case 1:
937 value = value * 0x10;
938 break;
939 case 2:
940 break;
941 case 3:
942 value /= 0x10;
943 break;
944 case 4:
945 value /= 0x100;
946 break;
947 }
948 colorval |= (value << pos);
949 pos += 0x8;
950 if (i == 2)
951 {
952 UNBLOCK_INPUT;
953 XSETINT (ret, colorval);
954 return ret;
955 }
956 color = end;
957 }
958 }
959 }
960 else if (strnicmp (colorname, "rgb:", 4) == 0)
961 {
962 char *color;
963 UINT colorval;
964 int i, pos;
965 pos = 0;
966
967 colorval = 0;
968 color = colorname + 4;
969 for (i = 0; i < 3; i++)
970 {
971 char *end;
972 unsigned long value;
973
974 975 976
977 if (!isxdigit (color[0]) || color[1] == 'x')
978 break;
979 value = strtoul (color, &end, 16);
980 if (errno == ERANGE)
981 break;
982 switch (end - color)
983 {
984 case 1:
985 value = value * 0x10 + value;
986 break;
987 case 2:
988 break;
989 case 3:
990 value /= 0x10;
991 break;
992 case 4:
993 value /= 0x100;
994 break;
995 default:
996 value = ULONG_MAX;
997 }
998 if (value == ULONG_MAX)
999 break;
1000 colorval |= (value << pos);
1001 pos += 0x8;
1002 if (i == 2)
1003 {
1004 if (*end != '\0')
1005 break;
1006 UNBLOCK_INPUT;
1007 XSETINT (ret, colorval);
1008 return ret;
1009 }
1010 if (*end != '/')
1011 break;
1012 color = end + 1;
1013 }
1014 }
1015 else if (strnicmp (colorname, "rgbi:", 5) == 0)
1016 {
1017
1018 char *color;
1019 UINT colorval;
1020 int i, pos;
1021 pos = 0;
1022
1023 colorval = 0;
1024 color = colorname + 5;
1025 for (i = 0; i < 3; i++)
1026 {
1027 char *end;
1028 double value;
1029 UINT val;
1030
1031 value = strtod (color, &end);
1032 if (errno == ERANGE)
1033 break;
1034 if (value < 0.0 || value > 1.0)
1035 break;
1036 val = (UINT)(0x100 * value);
1037 1038 1039
1040 if (val == 0x100)
1041 val = 0xFF;
1042 colorval |= (val << pos);
1043 pos += 0x8;
1044 if (i == 2)
1045 {
1046 if (*end != '\0')
1047 break;
1048 UNBLOCK_INPUT;
1049 XSETINT (ret, colorval);
1050 return ret;
1051 }
1052 if (*end != '/')
1053 break;
1054 color = end + 1;
1055 }
1056 }
1057 1058 1059
1060
1061 1062 1063 1064
1065 ret = w32_color_map_lookup (colorname);
1066 if (NILP (ret))
1067 {
1068 int len = strlen (colorname);
1069
1070 if (isdigit (colorname[len - 1]))
1071 {
1072 char *ptr, *approx = alloca (len + 1);
1073
1074 strcpy (approx, colorname);
1075 ptr = &approx[len - 1];
1076 while (ptr > approx && isdigit (*ptr))
1077 *ptr-- = '\0';
1078
1079 ret = w32_color_map_lookup (approx);
1080 }
1081 }
1082
1083 UNBLOCK_INPUT;
1084 return ret;
1085 }
1086
1087 void
1088 w32_regenerate_palette (FRAME_PTR f)
1089 {
1090 struct w32_palette_entry * list;
1091 LOGPALETTE * log_palette;
1092 HPALETTE new_palette;
1093 int i;
1094
1095
1096 if (! FRAME_W32_DISPLAY_INFO (f)->has_palette)
1097 return;
1098
1099 log_palette = (LOGPALETTE *)
1100 alloca (sizeof (LOGPALETTE) +
1101 FRAME_W32_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY));
1102 log_palette->palVersion = 0x300;
1103 log_palette->palNumEntries = FRAME_W32_DISPLAY_INFO (f)->num_colors;
1104
1105 list = FRAME_W32_DISPLAY_INFO (f)->color_list;
1106 for (i = 0;
1107 i < FRAME_W32_DISPLAY_INFO (f)->num_colors;
1108 i++, list = list->next)
1109 log_palette->palPalEntry[i] = list->entry;
1110
1111 new_palette = CreatePalette (log_palette);
1112
1113 enter_crit ();
1114
1115 if (FRAME_W32_DISPLAY_INFO (f)->palette)
1116 DeleteObject (FRAME_W32_DISPLAY_INFO (f)->palette);
1117 FRAME_W32_DISPLAY_INFO (f)->palette = new_palette;
1118
1119
1120 release_frame_dc (f, get_frame_dc (f));
1121
1122 leave_crit ();
1123 }
1124
1125 #define W32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1126 #define SET_W32_COLOR(pe, color) \
1127 do \
1128 { \
1129 pe.peRed = GetRValue (color); \
1130 pe.peGreen = GetGValue (color); \
1131 pe.peBlue = GetBValue (color); \
1132 pe.peFlags = 0; \
1133 } while (0)
1134
1135 #if 0
1136
1137 void
1138 w32_map_color (FRAME_PTR f, COLORREF color)
1139 {
1140 struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
1141
1142 if (NILP (Vw32_enable_palette))
1143 return;
1144
1145
1146 while (list)
1147 {
1148 if (W32_COLOR (list->entry) == color)
1149 {
1150 ++list->refcount;
1151 return;
1152 }
1153 list = list->next;
1154 }
1155
1156
1157 list = (struct w32_palette_entry *)
1158 xmalloc (sizeof (struct w32_palette_entry));
1159 SET_W32_COLOR (list->entry, color);
1160 list->refcount = 1;
1161 list->next = FRAME_W32_DISPLAY_INFO (f)->color_list;
1162 FRAME_W32_DISPLAY_INFO (f)->color_list = list;
1163 FRAME_W32_DISPLAY_INFO (f)->num_colors++;
1164
1165
1166 FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE;
1167 }
1168
1169 void
1170 w32_unmap_color (FRAME_PTR f, COLORREF color)
1171 {
1172 struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
1173 struct w32_palette_entry **prev = &FRAME_W32_DISPLAY_INFO (f)->color_list;
1174
1175 if (NILP (Vw32_enable_palette))
1176 return;
1177
1178
1179 while (list)
1180 {
1181 if (W32_COLOR (list->entry) == color)
1182 {
1183 if (--list->refcount == 0)
1184 {
1185 *prev = list->next;
1186 xfree (list);
1187 FRAME_W32_DISPLAY_INFO (f)->num_colors--;
1188 break;
1189 }
1190 else
1191 return;
1192 }
1193 prev = &list->next;
1194 list = list->next;
1195 }
1196
1197
1198 FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE;
1199 }
1200 #endif
1201
1202
1203
1204
1205 void
1206 gamma_correct (f, color)
1207 struct frame *f;
1208 COLORREF *color;
1209 {
1210 if (f->gamma)
1211 {
1212 *color = PALETTERGB (
1213 pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1214 pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1215 pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5);
1216 }
1217 }
1218
1219
1220 1221 1222
1223
1224 int
1225 w32_defined_color (f, color, color_def, alloc)
1226 FRAME_PTR f;
1227 char *color;
1228 XColor *color_def;
1229 int alloc;
1230 {
1231 register Lisp_Object tem;
1232 COLORREF w32_color_ref;
1233
1234 tem = x_to_w32_color (color);
1235
1236 if (!NILP (tem))
1237 {
1238 if (f)
1239 {
1240
1241 w32_color_ref = XUINT (tem);
1242 gamma_correct (f, &w32_color_ref);
1243 XSETINT (tem, w32_color_ref);
1244 }
1245
1246
1247 if (!NILP (Vw32_enable_palette))
1248 {
1249 struct w32_palette_entry * entry =
1250 one_w32_display_info.color_list;
1251 struct w32_palette_entry ** prev =
1252 &one_w32_display_info.color_list;
1253
1254
1255 while (entry)
1256 {
1257 if (W32_COLOR (entry->entry) == XUINT (tem))
1258 break;
1259 prev = &entry->next;
1260 entry = entry->next;
1261 }
1262
1263 if (entry == NULL && alloc)
1264 {
1265
1266 entry = (struct w32_palette_entry *)
1267 xmalloc (sizeof (struct w32_palette_entry));
1268 SET_W32_COLOR (entry->entry, XUINT (tem));
1269 entry->next = NULL;
1270 *prev = entry;
1271 one_w32_display_info.num_colors++;
1272
1273
1274 one_w32_display_info.regen_palette = TRUE;
1275 }
1276 }
1277 1278 1279
1280 w32_color_ref = XUINT (tem) | 0x2000000;
1281
1282 color_def->pixel = w32_color_ref;
1283 color_def->red = GetRValue (w32_color_ref) * 256;
1284 color_def->green = GetGValue (w32_color_ref) * 256;
1285 color_def->blue = GetBValue (w32_color_ref) * 256;
1286
1287 return 1;
1288 }
1289 else
1290 {
1291 return 0;
1292 }
1293 }
1294
1295 1296 1297 1298
1299
1300 int
1301 x_decode_color (f, arg, def)
1302 FRAME_PTR f;
1303 Lisp_Object arg;
1304 int def;
1305 {
1306 XColor cdef;
1307
1308 CHECK_STRING (arg);
1309
1310 if (strcmp (SDATA (arg), "black") == 0)
1311 return BLACK_PIX_DEFAULT (f);
1312 else if (strcmp (SDATA (arg), "white") == 0)
1313 return WHITE_PIX_DEFAULT (f);
1314
1315 if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1)
1316 return def;
1317
1318 1319
1320 if (w32_defined_color (f, SDATA (arg), &cdef, 1))
1321 return cdef.pixel;
1322
1323
1324 return def;
1325 }
1326
1327
1328
1329 1330 1331 1332 1333 1334 1335
1336
1337 void
1338 x_set_foreground_color (f, arg, oldval)
1339 struct frame *f;
1340 Lisp_Object arg, oldval;
1341 {
1342 struct w32_output *x = f->output_data.w32;
1343 PIX_TYPE fg, old_fg;
1344
1345 fg = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1346 old_fg = FRAME_FOREGROUND_PIXEL (f);
1347 FRAME_FOREGROUND_PIXEL (f) = fg;
1348
1349 if (FRAME_W32_WINDOW (f) != 0)
1350 {
1351 if (x->cursor_pixel == old_fg)
1352 x->cursor_pixel = fg;
1353
1354 update_face_from_frame_parameter (f, Qforeground_color, arg);
1355 if (FRAME_VISIBLE_P (f))
1356 redraw_frame (f);
1357 }
1358 }
1359
1360 void
1361 x_set_background_color (f, arg, oldval)
1362 struct frame *f;
1363 Lisp_Object arg, oldval;
1364 {
1365 FRAME_BACKGROUND_PIXEL (f)
1366 = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1367
1368 if (FRAME_W32_WINDOW (f) != 0)
1369 {
1370 SetWindowLong (FRAME_W32_WINDOW (f), WND_BACKGROUND_INDEX,
1371 FRAME_BACKGROUND_PIXEL (f));
1372
1373 update_face_from_frame_parameter (f, Qbackground_color, arg);
1374
1375 if (FRAME_VISIBLE_P (f))
1376 redraw_frame (f);
1377 }
1378 }
1379
1380 void
1381 x_set_mouse_color (f, arg, oldval)
1382 struct frame *f;
1383 Lisp_Object arg, oldval;
1384 {
1385 Cursor cursor, nontext_cursor, mode_cursor, hand_cursor;
1386 int count;
1387 int mask_color;
1388
1389 if (!EQ (Qnil, arg))
1390 f->output_data.w32->mouse_pixel
1391 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1392 mask_color = FRAME_BACKGROUND_PIXEL (f);
1393
1394
1395 if (mask_color == f->output_data.w32->mouse_pixel
1396 && mask_color == FRAME_BACKGROUND_PIXEL (f))
1397 f->output_data.w32->mouse_pixel = FRAME_FOREGROUND_PIXEL (f);
1398
1399 #if 0
1400 BLOCK_INPUT;
1401
1402
1403 count = x_catch_errors (FRAME_W32_DISPLAY (f));
1404
1405 if (!EQ (Qnil, Vx_pointer_shape))
1406 {
1407 CHECK_NUMBER (Vx_pointer_shape);
1408 cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XINT (Vx_pointer_shape));
1409 }
1410 else
1411 cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1412 x_check_errors (FRAME_W32_DISPLAY (f), "bad text pointer cursor: %s");
1413
1414 if (!EQ (Qnil, Vx_nontext_pointer_shape))
1415 {
1416 CHECK_NUMBER (Vx_nontext_pointer_shape);
1417 nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1418 XINT (Vx_nontext_pointer_shape));
1419 }
1420 else
1421 nontext_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_left_ptr);
1422 x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1423
1424 if (!EQ (Qnil, Vx_hourglass_pointer_shape))
1425 {
1426 CHECK_NUMBER (Vx_hourglass_pointer_shape);
1427 hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1428 XINT (Vx_hourglass_pointer_shape));
1429 }
1430 else
1431 hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch);
1432 x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s");
1433
1434 x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s");
1435 if (!EQ (Qnil, Vx_mode_pointer_shape))
1436 {
1437 CHECK_NUMBER (Vx_mode_pointer_shape);
1438 mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1439 XINT (Vx_mode_pointer_shape));
1440 }
1441 else
1442 mode_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_xterm);
1443 x_check_errors (FRAME_W32_DISPLAY (f), "bad modeline pointer cursor: %s");
1444
1445 if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
1446 {
1447 CHECK_NUMBER (Vx_sensitive_text_pointer_shape);
1448 hand_cursor
1449 = XCreateFontCursor (FRAME_W32_DISPLAY (f),
1450 XINT (Vx_sensitive_text_pointer_shape));
1451 }
1452 else
1453 hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair);
1454
1455 if (!NILP (Vx_window_horizontal_drag_shape))
1456 {
1457 CHECK_NUMBER (Vx_window_horizontal_drag_shape);
1458 horizontal_drag_cursor
1459 = XCreateFontCursor (FRAME_X_DISPLAY (f),
1460 XINT (Vx_window_horizontal_drag_shape));
1461 }
1462 else
1463 horizontal_drag_cursor
1464 = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
1465
1466
1467 x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
1468 x_uncatch_errors (FRAME_W32_DISPLAY (f), count);
1469
1470 {
1471 XColor fore_color, back_color;
1472
1473 fore_color.pixel = f->output_data.w32->mouse_pixel;
1474 back_color.pixel = mask_color;
1475 XQueryColor (FRAME_W32_DISPLAY (f),
1476 DefaultColormap (FRAME_W32_DISPLAY (f),
1477 DefaultScreen (FRAME_W32_DISPLAY (f))),
1478 &fore_color);
1479 XQueryColor (FRAME_W32_DISPLAY (f),
1480 DefaultColormap (FRAME_W32_DISPLAY (f),
1481 DefaultScreen (FRAME_W32_DISPLAY (f))),
1482 &back_color);
1483 XRecolorCursor (FRAME_W32_DISPLAY (f), cursor,
1484 &fore_color, &back_color);
1485 XRecolorCursor (FRAME_W32_DISPLAY (f), nontext_cursor,
1486 &fore_color, &back_color);
1487 XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
1488 &fore_color, &back_color);
1489 XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
1490 &fore_color, &back_color);
1491 XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
1492 &fore_color, &back_color);
1493 }
1494
1495 if (FRAME_W32_WINDOW (f) != 0)
1496 XDefineCursor (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), cursor);
1497
1498 if (cursor != f->output_data.w32->text_cursor && f->output_data.w32->text_cursor != 0)
1499 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->text_cursor);
1500 f->output_data.w32->text_cursor = cursor;
1501
1502 if (nontext_cursor != f->output_data.w32->nontext_cursor
1503 && f->output_data.w32->nontext_cursor != 0)
1504 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->nontext_cursor);
1505 f->output_data.w32->nontext_cursor = nontext_cursor;
1506
1507 if (hourglass_cursor != f->output_data.w32->hourglass_cursor
1508 && f->output_data.w32->hourglass_cursor != 0)
1509 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hourglass_cursor);
1510 f->output_data.w32->hourglass_cursor = hourglass_cursor;
1511
1512 if (mode_cursor != f->output_data.w32->modeline_cursor
1513 && f->output_data.w32->modeline_cursor != 0)
1514 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor);
1515 f->output_data.w32->modeline_cursor = mode_cursor;
1516
1517 if (hand_cursor != f->output_data.w32->hand_cursor
1518 && f->output_data.w32->hand_cursor != 0)
1519 XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor);
1520 f->output_data.w32->hand_cursor = hand_cursor;
1521
1522 XFlush (FRAME_W32_DISPLAY (f));
1523 UNBLOCK_INPUT;
1524
1525 update_face_from_frame_parameter (f, Qmouse_color, arg);
1526 #endif
1527 }
1528
1529 void
1530 x_set_cursor_color (f, arg, oldval)
1531 struct frame *f;
1532 Lisp_Object arg, oldval;
1533 {
1534 unsigned long fore_pixel, pixel;
1535
1536 if (!NILP (Vx_cursor_fore_pixel))
1537 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1538 WHITE_PIX_DEFAULT (f));
1539 else
1540 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1541
1542 pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1543
1544
1545 if (pixel == FRAME_BACKGROUND_PIXEL (f))
1546 {
1547 pixel = f->output_data.w32->mouse_pixel;
1548 if (pixel == fore_pixel)
1549 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1550 }
1551
1552 f->output_data.w32->cursor_foreground_pixel = fore_pixel;
1553 f->output_data.w32->cursor_pixel = pixel;
1554
1555 if (FRAME_W32_WINDOW (f) != 0)
1556 {
1557 BLOCK_INPUT;
1558
1559 f->output_data.w32->cursor_gc->foreground = fore_pixel;
1560 f->output_data.w32->cursor_gc->background = pixel;
1561
1562 UNBLOCK_INPUT;
1563
1564 if (FRAME_VISIBLE_P (f))
1565 {
1566 x_update_cursor (f, 0);
1567 x_update_cursor (f, 1);
1568 }
1569 }
1570
1571 update_face_from_frame_parameter (f, Qcursor_color, arg);
1572 }
1573
1574 1575 1576
1577
1578 void
1579 x_set_border_pixel (f, pix)
1580 struct frame *f;
1581 int pix;
1582 {
1583
1584 f->output_data.w32->border_pixel = pix;
1585
1586 if (FRAME_W32_WINDOW (f) != 0 && f->border_width > 0)
1587 {
1588 if (FRAME_VISIBLE_P (f))
1589 redraw_frame (f);
1590 }
1591 }
1592
1593 1594 1595 1596 1597
1598
1599 void
1600 x_set_border_color (f, arg, oldval)
1601 struct frame *f;
1602 Lisp_Object arg, oldval;
1603 {
1604 int pix;
1605
1606 CHECK_STRING (arg);
1607 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1608 x_set_border_pixel (f, pix);
1609 update_face_from_frame_parameter (f, Qborder_color, arg);
1610 }
1611
1612
1613 void
1614 x_set_cursor_type (f, arg, oldval)
1615 FRAME_PTR f;
1616 Lisp_Object arg, oldval;
1617 {
1618 set_frame_cursor_types (f, arg);
1619
1620
1621 cursor_type_changed = 1;
1622 }
1623
1624 void
1625 x_set_icon_type (f, arg, oldval)
1626 struct frame *f;
1627 Lisp_Object arg, oldval;
1628 {
1629 int result;
1630
1631 if (NILP (arg) && NILP (oldval))
1632 return;
1633
1634 if (STRINGP (arg) && STRINGP (oldval)
1635 && EQ (Fstring_equal (oldval, arg), Qt))
1636 return;
1637
1638 if (SYMBOLP (arg) && SYMBOLP (oldval) && EQ (arg, oldval))
1639 return;
1640
1641 BLOCK_INPUT;
1642
1643 result = x_bitmap_icon (f, arg);
1644 if (result)
1645 {
1646 UNBLOCK_INPUT;
1647 error ("No icon window available");
1648 }
1649
1650 UNBLOCK_INPUT;
1651 }
1652
1653 void
1654 x_set_icon_name (f, arg, oldval)
1655 struct frame *f;
1656 Lisp_Object arg, oldval;
1657 {
1658 if (STRINGP (arg))
1659 {
1660 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1661 return;
1662 }
1663 else if (!NILP (arg) || NILP (oldval))
1664 return;
1665
1666 f->icon_name = arg;
1667
1668 #if 0
1669 if (f->output_data.w32->icon_bitmap != 0)
1670 return;
1671
1672 BLOCK_INPUT;
1673
1674 result = x_text_icon (f,
1675 (char *) SDATA ((!NILP (f->icon_name)
1676 ? f->icon_name
1677 : !NILP (f->title)
1678 ? f->title
1679 : f->name)));
1680
1681 if (result)
1682 {
1683 UNBLOCK_INPUT;
1684 error ("No icon window available");
1685 }
1686
1687 1688
1689 if (FRAME_VISIBLE_P (f))
1690 {
1691 #ifdef USE_X_TOOLKIT
1692 XtPopup (f->output_data.w32->widget, XtGrabNone);
1693 #endif
1694 XMapWindow (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f));
1695 }
1696
1697 XFlush (FRAME_W32_DISPLAY (f));
1698 UNBLOCK_INPUT;
1699 #endif
1700 }
1701
1702
1703 void
1704 x_set_menu_bar_lines (f, value, oldval)
1705 struct frame *f;
1706 Lisp_Object value, oldval;
1707 {
1708 int nlines;
1709 int olines = FRAME_MENU_BAR_LINES (f);
1710
1711 1712 1713 1714
1715 if (FRAME_MINIBUF_ONLY_P (f))
1716 return;
1717
1718 if (INTEGERP (value))
1719 nlines = XINT (value);
1720 else
1721 nlines = 0;
1722
1723 FRAME_MENU_BAR_LINES (f) = 0;
1724 if (nlines)
1725 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1726 else
1727 {
1728 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1729 free_frame_menubar (f);
1730 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1731
1732 1733 1734
1735 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
1736 do_pending_window_change (0);
1737 }
1738 adjust_glyphs (f);
1739 }
1740
1741
1742 1743 1744 1745 1746
1747
1748 void
1749 x_set_tool_bar_lines (f, value, oldval)
1750 struct frame *f;
1751 Lisp_Object value, oldval;
1752 {
1753 int delta, nlines, root_height;
1754 Lisp_Object root_window;
1755
1756
1757 if (FRAME_MINIBUF_ONLY_P (f))
1758 return;
1759
1760
1761 if (INTEGERP (value) && XINT (value) >= 0)
1762 nlines = XFASTINT (value);
1763 else
1764 nlines = 0;
1765
1766
1767 ++windows_or_buffers_changed;
1768
1769 delta = nlines - FRAME_TOOL_BAR_LINES (f);
1770
1771
1772 root_window = FRAME_ROOT_WINDOW (f);
1773 root_height = WINDOW_TOTAL_LINES (XWINDOW (root_window));
1774 if (root_height - delta < 1)
1775 {
1776 delta = root_height - 1;
1777 nlines = FRAME_TOOL_BAR_LINES (f) + delta;
1778 }
1779
1780 FRAME_TOOL_BAR_LINES (f) = nlines;
1781 change_window_heights (root_window, delta);
1782 adjust_glyphs (f);
1783
1784 1785 1786 1787 1788 1789
1790 if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_LINES (f) == 0)
1791 {
1792 clear_frame (f);
1793 clear_current_matrices (f);
1794 }
1795
1796 1797 1798
1799 if (delta < 0)
1800 {
1801 int height = FRAME_INTERNAL_BORDER_WIDTH (f);
1802 int width = FRAME_PIXEL_WIDTH (f);
1803 int y = nlines * FRAME_LINE_HEIGHT (f);
1804
1805 BLOCK_INPUT;
1806 {
1807 HDC hdc = get_frame_dc (f);
1808 w32_clear_area (f, hdc, 0, y, width, height);
1809 release_frame_dc (f, hdc);
1810 }
1811 UNBLOCK_INPUT;
1812
1813 if (WINDOWP (f->tool_bar_window))
1814 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1815 }
1816 }
1817
1818
1819 1820 1821 1822 1823 1824 1825 1826 1827 1828
1829
1830 void
1831 x_set_name (f, name, explicit)
1832 struct frame *f;
1833 Lisp_Object name;
1834 int explicit;
1835 {
1836 1837
1838 if (explicit)
1839 {
1840 1841
1842 if (f->explicit_name && NILP (name))
1843 update_mode_lines = 1;
1844
1845 f->explicit_name = ! NILP (name);
1846 }
1847 else if (f->explicit_name)
1848 return;
1849
1850
1851 if (NILP (name))
1852 {
1853 1854
1855 if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name,
1856 SDATA (f->name)))
1857 return;
1858 name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name);
1859 }
1860 else
1861 CHECK_STRING (name);
1862
1863
1864 if (! NILP (Fstring_equal (name, f->name)))
1865 return;
1866
1867 f->name = name;
1868
1869 1870
1871 if (! NILP (f->title))
1872 name = f->title;
1873
1874 if (FRAME_W32_WINDOW (f))
1875 {
1876 if (STRING_MULTIBYTE (name))
1877 name = ENCODE_SYSTEM (name);
1878
1879 BLOCK_INPUT;
1880 SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
1881 UNBLOCK_INPUT;
1882 }
1883 }
1884
1885 1886 1887
1888 void
1889 x_explicitly_set_name (f, arg, oldval)
1890 FRAME_PTR f;
1891 Lisp_Object arg, oldval;
1892 {
1893 x_set_name (f, arg, 1);
1894 }
1895
1896 1897 1898
1899 void
1900 x_implicitly_set_name (f, arg, oldval)
1901 FRAME_PTR f;
1902 Lisp_Object arg, oldval;
1903 {
1904 x_set_name (f, arg, 0);
1905 }
1906
1907 1908
1909
1910 void
1911 x_set_title (f, name, old_name)
1912 struct frame *f;
1913 Lisp_Object name, old_name;
1914 {
1915
1916 if (EQ (name, f->title))
1917 return;
1918
1919 update_mode_lines = 1;
1920
1921 f->title = name;
1922
1923 if (NILP (name))
1924 name = f->name;
1925
1926 if (FRAME_W32_WINDOW (f))
1927 {
1928 if (STRING_MULTIBYTE (name))
1929 name = ENCODE_SYSTEM (name);
1930
1931 BLOCK_INPUT;
1932 SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
1933 UNBLOCK_INPUT;
1934 }
1935 }
1936
1937
1938 void x_set_scroll_bar_default_width (f)
1939 struct frame *f;
1940 {
1941 int wid = FRAME_COLUMN_WIDTH (f);
1942
1943 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
1944 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) +
1945 wid - 1) / wid;
1946 }
1947
1948
1949
1950
1951 Cursor
1952 w32_load_cursor (LPCTSTR name)
1953 {
1954
1955 Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle (NULL),
1956 name, IMAGE_CURSOR, 0, 0,
1957 LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
1958 if (!cursor)
1959 {
1960
1961 cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0,
1962 LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
1963 }
1964 return cursor;
1965 }
1966
1967 extern LRESULT CALLBACK w32_wnd_proc ();
1968
1969 static BOOL
1970 w32_init_class (hinst)
1971 HINSTANCE hinst;
1972 {
1973 WNDCLASS wc;
1974
1975 wc.style = CS_HREDRAW | CS_VREDRAW;
1976 wc.lpfnWndProc = (WNDPROC) w32_wnd_proc;
1977 wc.cbClsExtra = 0;
1978 wc.cbWndExtra = WND_EXTRA_BYTES;
1979 wc.hInstance = hinst;
1980 wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
1981 wc.hCursor = w32_load_cursor (IDC_ARROW);
1982 wc.hbrBackground = NULL;
1983 wc.lpszMenuName = NULL;
1984 wc.lpszClassName = EMACS_CLASS;
1985
1986 return (RegisterClass (&wc));
1987 }
1988
1989 static HWND
1990 w32_createscrollbar (f, bar)
1991 struct frame *f;
1992 struct scroll_bar * bar;
1993 {
1994 return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
1995
1996 XINT (bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
1997 XINT (bar->top),
1998 XINT (bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
1999 XINT (bar->height),
2000 FRAME_W32_WINDOW (f),
2001 NULL,
2002 hinst,
2003 NULL));
2004 }
2005
2006 static void
2007 w32_createwindow (f)
2008 struct frame *f;
2009 {
2010 HWND hwnd;
2011 RECT rect;
2012 Lisp_Object top = Qunbound;
2013 Lisp_Object left = Qunbound;
2014 struct w32_display_info *dpyinfo = &one_w32_display_info;
2015
2016 rect.left = rect.top = 0;
2017 rect.right = FRAME_PIXEL_WIDTH (f);
2018 rect.bottom = FRAME_PIXEL_HEIGHT (f);
2019
2020 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
2021 FRAME_EXTERNAL_MENU_BAR (f));
2022
2023
2024
2025 if (!hprevinst)
2026 {
2027 w32_init_class (hinst);
2028 }
2029
2030 if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
2031 {
2032 XSETINT (left, f->left_pos);
2033 XSETINT (top, f->top_pos);
2034 }
2035 else if (EQ (left, Qunbound) && EQ (top, Qunbound))
2036 {
2037 2038
2039 left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
2040 top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
2041 }
2042
2043 FRAME_W32_WINDOW (f) = hwnd
2044 = CreateWindow (EMACS_CLASS,
2045 f->namebuf,
2046 f->output_data.w32->dwStyle | WS_CLIPCHILDREN,
2047 EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left),
2048 EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top),
2049 rect.right - rect.left,
2050 rect.bottom - rect.top,
2051 NULL,
2052 NULL,
2053 hinst,
2054 NULL);
2055
2056 if (hwnd)
2057 {
2058 SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
2059 SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
2060 SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
2061 SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, f->scroll_bar_actual_width);
2062 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
2063
2064
2065 DragAcceptFiles (hwnd, TRUE);
2066
2067
2068 ShowWindow (hwnd, SW_HIDE);
2069
2070
2071 GetWindowRect (hwnd, &rect);
2072 f->left_pos = rect.left;
2073 f->top_pos = rect.top;
2074 }
2075 }
2076
2077 static void
2078 my_post_msg (wmsg, hwnd, msg, wParam, lParam)
2079 W32Msg * wmsg;
2080 HWND hwnd;
2081 UINT msg;
2082 WPARAM wParam;
2083 LPARAM lParam;
2084 {
2085 wmsg->msg.hwnd = hwnd;
2086 wmsg->msg.message = msg;
2087 wmsg->msg.wParam = wParam;
2088 wmsg->msg.lParam = lParam;
2089 wmsg->msg.time = GetMessageTime ();
2090
2091 post_msg (wmsg);
2092 }
2093
2094 2095 2096 2097 2098 2099 2100 2101 2102 2103
2104
2105 #define EMACS_LCONTROL 0
2106 #define EMACS_RCONTROL 1
2107 #define EMACS_LMENU 2
2108 #define EMACS_RMENU 3
2109
2110 static int modifiers[4];
2111 static int modifiers_recorded;
2112 static int modifier_key_support_tested;
2113
2114 static void
2115 test_modifier_support (unsigned int wparam)
2116 {
2117 unsigned int l, r;
2118
2119 if (wparam != VK_CONTROL && wparam != VK_MENU)
2120 return;
2121 if (wparam == VK_CONTROL)
2122 {
2123 l = VK_LCONTROL;
2124 r = VK_RCONTROL;
2125 }
2126 else
2127 {
2128 l = VK_LMENU;
2129 r = VK_RMENU;
2130 }
2131 if (!(GetKeyState (l) & 0x8000) && !(GetKeyState (r) & 0x8000))
2132 modifiers_recorded = 1;
2133 else
2134 modifiers_recorded = 0;
2135 modifier_key_support_tested = 1;
2136 }
2137
2138 static void
2139 record_keydown (unsigned int wparam, unsigned int lparam)
2140 {
2141 int i;
2142
2143 if (!modifier_key_support_tested)
2144 test_modifier_support (wparam);
2145
2146 if ((wparam != VK_CONTROL && wparam != VK_MENU) || !modifiers_recorded)
2147 return;
2148
2149 if (wparam == VK_CONTROL)
2150 i = (lparam & 0x1000000) ? EMACS_RCONTROL : EMACS_LCONTROL;
2151 else
2152 i = (lparam & 0x1000000) ? EMACS_RMENU : EMACS_LMENU;
2153
2154 modifiers[i] = 1;
2155 }
2156
2157 static void
2158 record_keyup (unsigned int wparam, unsigned int lparam)
2159 {
2160 int i;
2161
2162 if ((wparam != VK_CONTROL && wparam != VK_MENU) || !modifiers_recorded)
2163 return;
2164
2165 if (wparam == VK_CONTROL)
2166 i = (lparam & 0x1000000) ? EMACS_RCONTROL : EMACS_LCONTROL;
2167 else
2168 i = (lparam & 0x1000000) ? EMACS_RMENU : EMACS_LMENU;
2169
2170 modifiers[i] = 0;
2171 }
2172
2173 2174 2175
2176 static void
2177 reset_modifiers ()
2178 {
2179 SHORT ctrl, alt;
2180
2181 if (GetFocus () == NULL)
2182
2183 return;
2184
2185 ctrl = GetAsyncKeyState (VK_CONTROL);
2186 alt = GetAsyncKeyState (VK_MENU);
2187
2188 if (!(ctrl & 0x08000))
2189
2190 modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
2191
2192 if (!(alt & 0x08000))
2193
2194 modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
2195
2196 2197 2198
2199 {
2200 BYTE keystate[256];
2201
2202 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
2203
2204 GetKeyboardState (keystate);
2205 keystate[VK_SHIFT] = CURRENT_STATE (VK_SHIFT);
2206 keystate[VK_CONTROL] = CURRENT_STATE (VK_CONTROL);
2207 keystate[VK_LCONTROL] = CURRENT_STATE (VK_LCONTROL);
2208 keystate[VK_RCONTROL] = CURRENT_STATE (VK_RCONTROL);
2209 keystate[VK_MENU] = CURRENT_STATE (VK_MENU);
2210 keystate[VK_LMENU] = CURRENT_STATE (VK_LMENU);
2211 keystate[VK_RMENU] = CURRENT_STATE (VK_RMENU);
2212 keystate[VK_LWIN] = CURRENT_STATE (VK_LWIN);
2213 keystate[VK_RWIN] = CURRENT_STATE (VK_RWIN);
2214 keystate[VK_APPS] = CURRENT_STATE (VK_APPS);
2215 SetKeyboardState (keystate);
2216 }
2217 }
2218
2219 2220 2221 2222
2223 static void
2224 sync_modifiers ()
2225 {
2226 if (!modifiers_recorded)
2227 return;
2228
2229 if (!(GetKeyState (VK_CONTROL) & 0x8000))
2230 modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0;
2231
2232 if (!(GetKeyState (VK_MENU) & 0x8000))
2233 modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0;
2234 }
2235
2236 static int
2237 modifier_set (int vkey)
2238 {
2239 if (vkey == VK_CAPITAL || vkey == VK_SCROLL)
2240 return (GetKeyState (vkey) & 0x1);
2241 if (!modifiers_recorded)
2242 return (GetKeyState (vkey) & 0x8000);
2243
2244 switch (vkey)
2245 {
2246 case VK_LCONTROL:
2247 return modifiers[EMACS_LCONTROL];
2248 case VK_RCONTROL:
2249 return modifiers[EMACS_RCONTROL];
2250 case VK_LMENU:
2251 return modifiers[EMACS_LMENU];
2252 case VK_RMENU:
2253 return modifiers[EMACS_RMENU];
2254 }
2255 return (GetKeyState (vkey) & 0x8000);
2256 }
2257
2258 2259
2260
2261 unsigned int
2262 w32_key_to_modifier (int key)
2263 {
2264 Lisp_Object key_mapping;
2265
2266 switch (key)
2267 {
2268 case VK_LWIN:
2269 key_mapping = Vw32_lwindow_modifier;
2270 break;
2271 case VK_RWIN:
2272 key_mapping = Vw32_rwindow_modifier;
2273 break;
2274 case VK_APPS:
2275 key_mapping = Vw32_apps_modifier;
2276 break;
2277 case VK_SCROLL:
2278 key_mapping = Vw32_scroll_lock_modifier;
2279 break;
2280 default:
2281 key_mapping = Qnil;
2282 }
2283
2284 2285 2286 2287 2288 2289
2290 if (EQ (key_mapping, Qhyper))
2291 return hyper_modifier;
2292 if (EQ (key_mapping, Qsuper))
2293 return super_modifier;
2294 if (EQ (key_mapping, Qmeta))
2295 return meta_modifier;
2296 if (EQ (key_mapping, Qalt))
2297 return alt_modifier;
2298 if (EQ (key_mapping, Qctrl))
2299 return ctrl_modifier;
2300 if (EQ (key_mapping, Qcontrol))
2301 return ctrl_modifier;
2302 if (EQ (key_mapping, Qshift))
2303 return shift_modifier;
2304
2305
2306 return 0;
2307 }
2308
2309 static unsigned int
2310 w32_get_modifiers ()
2311 {
2312 return ((modifier_set (VK_SHIFT) ? shift_modifier : 0) |
2313 (modifier_set (VK_CONTROL) ? ctrl_modifier : 0) |
2314 (modifier_set (VK_LWIN) ? w32_key_to_modifier (VK_LWIN) : 0) |
2315 (modifier_set (VK_RWIN) ? w32_key_to_modifier (VK_RWIN) : 0) |
2316 (modifier_set (VK_APPS) ? w32_key_to_modifier (VK_APPS) : 0) |
2317 (modifier_set (VK_SCROLL) ? w32_key_to_modifier (VK_SCROLL) : 0) |
2318 (modifier_set (VK_MENU) ?
2319 ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0));
2320 }
2321
2322 2323 2324
2325
2326 static int
2327 construct_console_modifiers ()
2328 {
2329 int mods;
2330
2331 mods = 0;
2332 mods |= (modifier_set (VK_SHIFT)) ? SHIFT_PRESSED : 0;
2333 mods |= (modifier_set (VK_CAPITAL)) ? CAPSLOCK_ON : 0;
2334 mods |= (modifier_set (VK_SCROLL)) ? SCROLLLOCK_ON : 0;
2335 mods |= (modifier_set (VK_NUMLOCK)) ? NUMLOCK_ON : 0;
2336 mods |= (modifier_set (VK_LCONTROL)) ? LEFT_CTRL_PRESSED : 0;
2337 mods |= (modifier_set (VK_RCONTROL)) ? RIGHT_CTRL_PRESSED : 0;
2338 mods |= (modifier_set (VK_LMENU)) ? LEFT_ALT_PRESSED : 0;
2339 mods |= (modifier_set (VK_RMENU)) ? RIGHT_ALT_PRESSED : 0;
2340 mods |= (modifier_set (VK_LWIN)) ? LEFT_WIN_PRESSED : 0;
2341 mods |= (modifier_set (VK_RWIN)) ? RIGHT_WIN_PRESSED : 0;
2342 mods |= (modifier_set (VK_APPS)) ? APPS_PRESSED : 0;
2343
2344 return mods;
2345 }
2346
2347 static int
2348 w32_get_key_modifiers (unsigned int wparam, unsigned int lparam)
2349 {
2350 int mods;
2351
2352
2353 mods = w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam);
2354
2355 return mods;
2356 }
2357
2358 unsigned int
2359 map_keypad_keys (unsigned int virt_key, unsigned int extended)
2360 {
2361 if (virt_key < VK_CLEAR || virt_key > VK_DELETE)
2362 return virt_key;
2363
2364 if (virt_key == VK_RETURN)
2365 return (extended ? VK_NUMPAD_ENTER : VK_RETURN);
2366
2367 if (virt_key >= VK_PRIOR && virt_key <= VK_DOWN)
2368 return (!extended ? (VK_NUMPAD_PRIOR + (virt_key - VK_PRIOR)) : virt_key);
2369
2370 if (virt_key == VK_INSERT || virt_key == VK_DELETE)
2371 return (!extended ? (VK_NUMPAD_INSERT + (virt_key - VK_INSERT)) : virt_key);
2372
2373 if (virt_key == VK_CLEAR)
2374 return (!extended ? VK_NUMPAD_CLEAR : virt_key);
2375
2376 return virt_key;
2377 }
2378
2379 2380 2381 2382
2383 static Lisp_Object w32_grabbed_keys;
2384
2385 #define HOTKEY(vk, mods) make_number (((vk) & 255) | ((mods) << 8))
2386 #define HOTKEY_ID(k) (XFASTINT (k) & 0xbfff)
2387 #define HOTKEY_VK_CODE(k) (XFASTINT (k) & 255)
2388 #define HOTKEY_MODIFIERS(k) (XFASTINT (k) >> 8)
2389
2390 #define RAW_HOTKEY_ID(k) ((k) & 0xbfff)
2391 #define RAW_HOTKEY_VK_CODE(k) ((k) & 255)
2392 #define RAW_HOTKEY_MODIFIERS(k) ((k) >> 8)
2393
2394 2395 2396
2397
2398 static void
2399 register_hot_keys (hwnd)
2400 HWND hwnd;
2401 {
2402 Lisp_Object keylist;
2403
2404
2405 for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
2406 {
2407 Lisp_Object key = XCAR (keylist);
2408
2409
2410 if (!INTEGERP (key))
2411 continue;
2412
2413 RegisterHotKey (hwnd, HOTKEY_ID (key),
2414 HOTKEY_MODIFIERS (key), HOTKEY_VK_CODE (key));
2415 }
2416 }
2417
2418 static void
2419 unregister_hot_keys (hwnd)
2420 HWND hwnd;
2421 {
2422 Lisp_Object keylist;
2423
2424 for (keylist = w32_grabbed_keys; CONSP (keylist); keylist = XCDR (keylist))
2425 {
2426 Lisp_Object key = XCAR (keylist);
2427
2428 if (!INTEGERP (key))
2429 continue;
2430
2431 UnregisterHotKey (hwnd, HOTKEY_ID (key));
2432 }
2433 }
2434
2435
2436
2437 static void
2438 w32_msg_pump (deferred_msg * msg_buf)
2439 {
2440 MSG msg;
2441 int result;
2442 HWND focus_window;
2443
2444 msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
2445
2446 while (GetMessage (&msg, NULL, 0, 0))
2447 {
2448 if (msg.hwnd == NULL)
2449 {
2450 switch (msg.message)
2451 {
2452 case WM_NULL:
2453
2454 break;
2455 case WM_EMACS_CREATEWINDOW:
2456 2457 2458 2459 2460 2461
2462 CoInitialize (NULL);
2463 w32_createwindow ((struct frame *) msg.wParam);
2464 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2465 abort ();
2466 break;
2467 case WM_EMACS_SETLOCALE:
2468 SetThreadLocale (msg.wParam);
2469
2470 break;
2471 case WM_EMACS_SETKEYBOARDLAYOUT:
2472 result = (int) ActivateKeyboardLayout ((HKL) msg.wParam, 0);
2473 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
2474 result, 0))
2475 abort ();
2476 break;
2477 case WM_EMACS_REGISTER_HOT_KEY:
2478 focus_window = GetFocus ();
2479 if (focus_window != NULL)
2480 RegisterHotKey (focus_window,
2481 RAW_HOTKEY_ID (msg.wParam),
2482 RAW_HOTKEY_MODIFIERS (msg.wParam),
2483 RAW_HOTKEY_VK_CODE (msg.wParam));
2484
2485 break;
2486 case WM_EMACS_UNREGISTER_HOT_KEY:
2487 focus_window = GetFocus ();
2488 if (focus_window != NULL)
2489 UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam));
2490 2491 2492 2493
2494 XSETCAR ((Lisp_Object) ((EMACS_INT) msg.lParam), Qnil);
2495 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2496 abort ();
2497 break;
2498 case WM_EMACS_TOGGLE_LOCK_KEY:
2499 {
2500 int vk_code = (int) msg.wParam;
2501 int cur_state = (GetKeyState (vk_code) & 1);
2502 Lisp_Object new_state = (Lisp_Object) ((EMACS_INT) msg.lParam);
2503
2504 2505 2506 2507 2508
2509 if (NILP (new_state)
2510 || (NUMBERP (new_state)
2511 && ((XUINT (new_state)) & 1) != cur_state))
2512 {
2513 one_w32_display_info.faked_key = vk_code;
2514
2515 keybd_event ((BYTE) vk_code,
2516 (BYTE) MapVirtualKey (vk_code, 0),
2517 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
2518 keybd_event ((BYTE) vk_code,
2519 (BYTE) MapVirtualKey (vk_code, 0),
2520 KEYEVENTF_EXTENDEDKEY | 0, 0);
2521 keybd_event ((BYTE) vk_code,
2522 (BYTE) MapVirtualKey (vk_code, 0),
2523 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
2524 cur_state = !cur_state;
2525 }
2526 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE,
2527 cur_state, 0))
2528 abort ();
2529 }
2530 break;
2531 #ifdef MSG_DEBUG
2532 2533
2534 default:
2535 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
2536 #endif
2537 }
2538 }
2539 else
2540 {
2541 DispatchMessage (&msg);
2542 }
2543
2544
2545 if (msg_buf->completed)
2546 break;
2547 }
2548 }
2549
2550 deferred_msg * deferred_msg_head;
2551
2552 static deferred_msg *
2553 find_deferred_msg (HWND hwnd, UINT msg)
2554 {
2555 deferred_msg * item;
2556
2557 2558
2559
2560
2561 for (item = deferred_msg_head; item != NULL; item = item->next)
2562 if (item->w32msg.msg.hwnd == hwnd
2563 && item->w32msg.msg.message == msg)
2564 break;
2565
2566
2567
2568 return item;
2569 }
2570
2571 static LRESULT
2572 send_deferred_msg (deferred_msg * msg_buf,
2573 HWND hwnd,
2574 UINT msg,
2575 WPARAM wParam,
2576 LPARAM lParam)
2577 {
2578
2579 if (GetCurrentThreadId () != dwWindowsThreadId)
2580 abort ();
2581
2582
2583 if (find_deferred_msg (hwnd, msg) != NULL)
2584 abort ();
2585
2586 2587 2588 2589
2590
2591
2592
2593 msg_buf->completed = 0;
2594 msg_buf->next = deferred_msg_head;
2595 deferred_msg_head = msg_buf;
2596 my_post_msg (&msg_buf->w32msg, hwnd, msg, wParam, lParam);
2597
2598
2599
2600 2601
2602 w32_msg_pump (msg_buf);
2603
2604 deferred_msg_head = msg_buf->next;
2605
2606 return msg_buf->result;
2607 }
2608
2609 void
2610 complete_deferred_msg (HWND hwnd, UINT msg, LRESULT result)
2611 {
2612 deferred_msg * msg_buf = find_deferred_msg (hwnd, msg);
2613
2614 if (msg_buf == NULL)
2615
2616 return;
2617
2618 msg_buf->result = result;
2619 msg_buf->completed = 1;
2620
2621
2622 PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
2623 }
2624
2625 static void
2626 cancel_all_deferred_msgs ()
2627 {
2628 deferred_msg * item;
2629
2630 2631
2632
2633
2634 for (item = deferred_msg_head; item != NULL; item = item->next)
2635 {
2636 item->result = 0;
2637 item->completed = 1;
2638 }
2639
2640
2641
2642
2643 PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0);
2644 }
2645
2646 DWORD WINAPI
2647 w32_msg_worker (void *arg)
2648 {
2649 MSG msg;
2650 deferred_msg dummy_buf;
2651
2652
2653
2654 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2655
2656 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2657 abort ();
2658
2659 memset (&dummy_buf, 0, sizeof (dummy_buf));
2660 dummy_buf.w32msg.msg.hwnd = NULL;
2661 dummy_buf.w32msg.msg.message = WM_NULL;
2662
2663 2664
2665 w32_msg_pump (&dummy_buf);
2666
2667 return 0;
2668 }
2669
2670 static void
2671 signal_user_input ()
2672 {
2673
2674 if (!NILP (Vthrow_on_input))
2675 {
2676 Vquit_flag = Vthrow_on_input;
2677 2678
2679 if (immediate_quit && NILP (Vinhibit_quit))
2680 {
2681 immediate_quit = 0;
2682 QUIT;
2683 }
2684 }
2685 }
2686
2687
2688 static void
2689 post_character_message (hwnd, msg, wParam, lParam, modifiers)
2690 HWND hwnd;
2691 UINT msg;
2692 WPARAM wParam;
2693 LPARAM lParam;
2694 DWORD modifiers;
2695
2696 {
2697 W32Msg wmsg;
2698
2699 wmsg.dwModifiers = modifiers;
2700
2701 2702 2703 2704 2705 2706
2707 {
2708 int c = wParam;
2709 if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier)
2710 c = make_ctrl_char (c) & 0377;
2711 if (c == quit_char
2712 || (wmsg.dwModifiers == 0 &&
2713 w32_quit_key && wParam == w32_quit_key))
2714 {
2715 Vquit_flag = Qt;
2716
2717 2718
2719 msg = WM_NULL;
2720
2721
2722 signal_quit ();
2723
2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742
2743 cancel_all_deferred_msgs ();
2744 }
2745 else
2746 signal_user_input ();
2747 }
2748
2749 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2750 }
2751
2752
2753
2754 LRESULT CALLBACK
2755 w32_wnd_proc (hwnd, msg, wParam, lParam)
2756 HWND hwnd;
2757 UINT msg;
2758 WPARAM wParam;
2759 LPARAM lParam;
2760 {
2761 struct frame *f;
2762 struct w32_display_info *dpyinfo = &one_w32_display_info;
2763 W32Msg wmsg;
2764 int windows_translate;
2765 int key;
2766
2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781
2782
2783 switch (msg)
2784 {
2785 case WM_ERASEBKGND:
2786 f = x_window_to_frame (dpyinfo, hwnd);
2787 if (f)
2788 {
2789 HDC hdc = get_frame_dc (f);
2790 GetUpdateRect (hwnd, &wmsg.rect, FALSE);
2791 w32_clear_rect (f, hdc, &wmsg.rect);
2792 release_frame_dc (f, hdc);
2793
2794 #if defined (W32_DEBUG_DISPLAY)
2795 DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
2796 f,
2797 wmsg.rect.left, wmsg.rect.top,
2798 wmsg.rect.right, wmsg.rect.bottom));
2799 #endif
2800 }
2801 return 1;
2802 case WM_PALETTECHANGED:
2803
2804 if ((HWND)wParam != hwnd)
2805 {
2806 f = x_window_to_frame (dpyinfo, hwnd);
2807 if (f)
2808 2809
2810 release_frame_dc (f, get_frame_dc (f));
2811 }
2812 return 0;
2813 case WM_PAINT:
2814 {
2815 PAINTSTRUCT paintStruct;
2816 RECT update_rect;
2817 bzero (&update_rect, sizeof (update_rect));
2818
2819 f = x_window_to_frame (dpyinfo, hwnd);
2820 if (f == 0)
2821 {
2822 DebPrint (("WM_PAINT received for unknown window %p\n", hwnd));
2823 return 0;
2824 }
2825
2826 2827 2828
2829 if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
2830 {
2831 enter_crit ();
2832 BeginPaint (hwnd, &paintStruct);
2833
2834 2835 2836
2837 UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint));
2838
2839 #if defined (W32_DEBUG_DISPLAY)
2840 DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
2841 f,
2842 wmsg.rect.left, wmsg.rect.top,
2843 wmsg.rect.right, wmsg.rect.bottom));
2844 DebPrint ((" [update region is %d,%d-%d,%d]\n",
2845 update_rect.left, update_rect.top,
2846 update_rect.right, update_rect.bottom));
2847 #endif
2848 EndPaint (hwnd, &paintStruct);
2849 leave_crit ();
2850
2851 2852 2853 2854 2855
2856 my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
2857
2858 return 0;
2859 }
2860
2861 2862
2863 GetClientRect (hwnd, &wmsg.rect);
2864 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2865 return 0;
2866 }
2867
2868 case WM_INPUTLANGCHANGE:
2869
2870 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2871
2872 2873
2874 {
2875 int i;
2876 BYTE keystate[256];
2877
2878 GetKeyboardState (keystate);
2879 for (i = 0; i < 256; i++)
2880 if (1
2881 && i != VK_SHIFT
2882 && i != VK_LSHIFT
2883 && i != VK_RSHIFT
2884 && i != VK_CAPITAL
2885 && i != VK_NUMLOCK
2886 && i != VK_SCROLL
2887 && i != VK_CONTROL
2888 && i != VK_LCONTROL
2889 && i != VK_RCONTROL
2890 && i != VK_MENU
2891 && i != VK_LMENU
2892 && i != VK_RMENU
2893 && i != VK_LWIN
2894 && i != VK_RWIN)
2895 keystate[i] = 0;
2896 SetKeyboardState (keystate);
2897 }
2898 goto dflt;
2899
2900 case WM_HOTKEY:
2901
2902 PostMessage (hwnd, WM_KEYDOWN, HIWORD (lParam), 0);
2903 return (0);
2904
2905 case WM_KEYUP:
2906 case WM_SYSKEYUP:
2907 record_keyup (wParam, lParam);
2908 goto dflt;
2909
2910 case WM_KEYDOWN:
2911 case WM_SYSKEYDOWN:
2912
2913 if (dpyinfo->faked_key == wParam)
2914 {
2915 dpyinfo->faked_key = 0;
2916 2917 2918 2919
2920 if (wParam < 256 && lispy_function_keys[wParam])
2921 {
2922 windows_translate = 1;
2923 goto translate;
2924 }
2925 return 0;
2926 }
2927
2928
2929 sync_modifiers ();
2930 record_keydown (wParam, lParam);
2931 wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
2932
2933 windows_translate = 0;
2934
2935 switch (wParam)
2936 {
2937 case VK_LWIN:
2938 if (NILP (Vw32_pass_lwindow_to_system))
2939 {
2940 2941 2942
2943 if (GetAsyncKeyState (wParam) & 1)
2944 {
2945 if (NUMBERP (Vw32_phantom_key_code))
2946 key = XUINT (Vw32_phantom_key_code) & 255;
2947 else
2948 key = VK_SPACE;
2949 dpyinfo->faked_key = key;
2950 keybd_event (key, (BYTE) MapVirtualKey (key, 0), 0, 0);
2951 }
2952 }
2953 if (!NILP (Vw32_lwindow_modifier))
2954 return 0;
2955 break;
2956 case VK_RWIN:
2957 if (NILP (Vw32_pass_rwindow_to_system))
2958 {
2959 if (GetAsyncKeyState (wParam) & 1)
2960 {
2961 if (NUMBERP (Vw32_phantom_key_code))
2962 key = XUINT (Vw32_phantom_key_code) & 255;
2963 else
2964 key = VK_SPACE;
2965 dpyinfo->faked_key = key;
2966 keybd_event (key, (BYTE) MapVirtualKey (key, 0), 0, 0);
2967 }
2968 }
2969 if (!NILP (Vw32_rwindow_modifier))
2970 return 0;
2971 break;
2972 case VK_APPS:
2973 if (!NILP (Vw32_apps_modifier))
2974 return 0;
2975 break;
2976 case VK_MENU:
2977 if (NILP (Vw32_pass_alt_to_system))
2978 2979
2980 return 0;
2981 windows_translate = 1;
2982 break;
2983 case VK_CAPITAL:
2984
2985 if (NILP (Vw32_enable_caps_lock))
2986 goto disable_lock_key;
2987 windows_translate = 1;
2988 break;
2989 case VK_NUMLOCK:
2990
2991 if (NILP (Vw32_enable_num_lock))
2992 goto disable_lock_key;
2993 windows_translate = 1;
2994 break;
2995 case VK_SCROLL:
2996
2997 if (NILP (Vw32_scroll_lock_modifier))
2998 goto disable_lock_key;
2999 windows_translate = 1;
3000 break;
3001 disable_lock_key:
3002 3003 3004 3005
3006 dpyinfo->faked_key = wParam;
3007 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3008 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3009 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3010 KEYEVENTF_EXTENDEDKEY | 0, 0);
3011 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3012 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3013 3014 3015
3016 post_character_message (hwnd, msg, wParam, lParam,
3017 w32_get_key_modifiers (wParam, lParam));
3018 windows_translate = 1;
3019 break;
3020 case VK_CONTROL:
3021 case VK_SHIFT:
3022 case VK_PROCESSKEY:
3023 windows_translate = 1;
3024 break;
3025 case VK_CANCEL:
3026 3027 3028
3029 wParam = VK_PAUSE;
3030 break;
3031 case VK_PAUSE:
3032 3033 3034 3035 3036
3037 if (NILP (Vw32_enable_num_lock) && modifier_set (VK_CONTROL))
3038 wParam = VK_NUMLOCK;
3039 break;
3040 default:
3041
3042 if (wParam > 255 || !lispy_function_keys[wParam])
3043 {
3044 DWORD modifiers = construct_console_modifiers ();
3045
3046 if (!NILP (Vw32_recognize_altgr)
3047 && modifier_set (VK_LCONTROL) && modifier_set (VK_RMENU))
3048 {
3049 3050 3051
3052 windows_translate = 1;
3053 }
3054 else if ((modifiers & (~SHIFT_PRESSED & ~CAPSLOCK_ON)) != 0)
3055 {
3056 3057 3058
3059 if ('A' <= wParam && wParam <= 'Z')
3060 {
3061 3062 3063 3064 3065
3066 if (!modifier_set (VK_SHIFT))
3067 wParam += ('a' - 'A');
3068 msg = WM_CHAR;
3069 }
3070 else
3071 {
3072 3073 3074
3075 int add;
3076 int isdead = 0;
3077 KEY_EVENT_RECORD key;
3078
3079 key.bKeyDown = TRUE;
3080 key.wRepeatCount = 1;
3081 key.wVirtualKeyCode = wParam;
3082 key.wVirtualScanCode = (lParam & 0xFF0000) >> 16;
3083 key.uChar.AsciiChar = 0;
3084 key.dwControlKeyState = modifiers;
3085
3086 add = w32_kbd_patch_key (&key);
3087 3088
3089 while (--add >= 0)
3090 {
3091
3092 post_character_message
3093 (hwnd, WM_CHAR,
3094 (unsigned char) key.uChar.AsciiChar, lParam,
3095 w32_get_key_modifiers (wParam, lParam));
3096 w32_kbd_patch_key (&key);
3097 }
3098 return 0;
3099 }
3100 }
3101 else
3102 {
3103
3104 windows_translate = 1;
3105 }
3106 }
3107 }
3108
3109 translate:
3110 if (windows_translate)
3111 {
3112 MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
3113 windows_msg.time = GetMessageTime ();
3114 TranslateMessage (&windows_msg);
3115 goto dflt;
3116 }
3117
3118
3119
3120 case WM_SYSCHAR:
3121 case WM_CHAR:
3122 post_character_message (hwnd, msg, wParam, lParam,
3123 w32_get_key_modifiers (wParam, lParam));
3124 break;
3125
3126 case WM_UNICHAR:
3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137
3138 if (wParam == UNICODE_NOCHAR)
3139 return TRUE;
3140
3141 {
3142 W32Msg wmsg;
3143 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3144 signal_user_input ();
3145 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3146 }
3147 break;
3148
3149 case WM_IME_CHAR:
3150 3151 3152
3153 if (!get_composition_string_fn)
3154 goto dflt;
3155
3156 else if (!ignore_ime_char)
3157 {
3158 wchar_t * buffer;
3159 int size, i;
3160 W32Msg wmsg;
3161 HIMC context = get_ime_context_fn (hwnd);
3162 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3163
3164 size = get_composition_string_fn (context, GCS_RESULTSTR, buffer, 0);
3165 buffer = alloca(size);
3166 size = get_composition_string_fn (context, GCS_RESULTSTR,
3167 buffer, size);
3168 release_ime_context_fn (hwnd, context);
3169
3170 signal_user_input ();
3171 for (i = 0; i < size / sizeof (wchar_t); i++)
3172 {
3173 my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
3174 lParam);
3175 }
3176 3177
3178 ignore_ime_char = (size / sizeof (wchar_t)) - 1;
3179 }
3180 else
3181 ignore_ime_char--;
3182
3183 break;
3184
3185 case WM_IME_STARTCOMPOSITION:
3186 if (!set_ime_composition_window_fn)
3187 goto dflt;
3188 else
3189 {
3190 COMPOSITIONFORM form;
3191 HIMC context;
3192 struct window *w;
3193
3194 if (!context)
3195 break;
3196
3197 f = x_window_to_frame (dpyinfo, hwnd);
3198 w = XWINDOW (FRAME_SELECTED_WINDOW (f));
3199
3200 form.dwStyle = CFS_RECT;
3201 form.ptCurrentPos.x = w32_system_caret_x;
3202 form.ptCurrentPos.y = w32_system_caret_y;
3203
3204 form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
3205 form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
3206 + WINDOW_HEADER_LINE_HEIGHT (w));
3207 form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
3208 - WINDOW_RIGHT_MARGIN_WIDTH (w)
3209 - WINDOW_RIGHT_FRINGE_WIDTH (w));
3210 form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
3211 - WINDOW_MODE_LINE_HEIGHT (w));
3212
3213 context = get_ime_context_fn (hwnd);
3214 set_ime_composition_window_fn (context, &form);
3215 release_ime_context_fn (hwnd, context);
3216 }
3217 break;
3218
3219 case WM_IME_ENDCOMPOSITION:
3220 ignore_ime_char = 0;
3221 goto dflt;
3222
3223 3224
3225 case WM_LBUTTONDOWN:
3226 case WM_RBUTTONDOWN:
3227 if (w32_num_mouse_buttons > 2)
3228 goto handle_plain_button;
3229
3230 {
3231 int this = (msg == WM_LBUTTONDOWN) ? LMOUSE : RMOUSE;
3232 int other = (msg == WM_LBUTTONDOWN) ? RMOUSE : LMOUSE;
3233
3234 if (button_state & this)
3235 return 0;
3236
3237 if (button_state == 0)
3238 SetCapture (hwnd);
3239
3240 button_state |= this;
3241
3242 if (button_state & other)
3243 {
3244 if (mouse_button_timer)
3245 {
3246 KillTimer (hwnd, mouse_button_timer);
3247 mouse_button_timer = 0;
3248
3249
3250 msg = WM_MBUTTONDOWN;
3251 button_state |= MMOUSE;
3252 }
3253 else if (button_state & MMOUSE)
3254 {
3255 3256 3257 3258
3259 return 0;
3260 }
3261 else
3262 {
3263
3264 post_msg (&saved_mouse_button_msg);
3265 }
3266 wmsg.dwModifiers = w32_get_modifiers ();
3267 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3268 signal_user_input ();
3269
3270
3271 saved_mouse_button_msg.msg.hwnd = 0;
3272 }
3273 else
3274 {
3275
3276 mouse_button_timer =
3277 SetTimer (hwnd, MOUSE_BUTTON_ID,
3278 w32_mouse_button_tolerance, NULL);
3279 saved_mouse_button_msg.msg.hwnd = hwnd;
3280 saved_mouse_button_msg.msg.message = msg;
3281 saved_mouse_button_msg.msg.wParam = wParam;
3282 saved_mouse_button_msg.msg.lParam = lParam;
3283 saved_mouse_button_msg.msg.time = GetMessageTime ();
3284 saved_mouse_button_msg.dwModifiers = w32_get_modifiers ();
3285 }
3286 }
3287 return 0;
3288
3289 case WM_LBUTTONUP:
3290 case WM_RBUTTONUP:
3291 if (w32_num_mouse_buttons > 2)
3292 goto handle_plain_button;
3293
3294 {
3295 int this = (msg == WM_LBUTTONUP) ? LMOUSE : RMOUSE;
3296 int other = (msg == WM_LBUTTONUP) ? RMOUSE : LMOUSE;
3297
3298 if ((button_state & this) == 0)
3299 return 0;
3300
3301 button_state &= ~this;
3302
3303 if (button_state & MMOUSE)
3304 {
3305
3306 if ((button_state & other) == 0)
3307 {
3308 msg = WM_MBUTTONUP;
3309 button_state &= ~MMOUSE;
3310
3311 if (button_state) abort ();
3312 }
3313 else
3314 return 0;
3315 }
3316 else
3317 {
3318
3319 if (saved_mouse_button_msg.msg.hwnd)
3320 {
3321 post_msg (&saved_mouse_button_msg);
3322 }
3323 }
3324 wmsg.dwModifiers = w32_get_modifiers ();
3325 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3326 signal_user_input ();
3327
3328
3329 saved_mouse_button_msg.msg.hwnd = 0;
3330 KillTimer (hwnd, mouse_button_timer);
3331 mouse_button_timer = 0;
3332
3333 if (button_state == 0)
3334 ReleaseCapture ();
3335 }
3336 return 0;
3337
3338 case WM_XBUTTONDOWN:
3339 case WM_XBUTTONUP:
3340 if (w32_pass_extra_mouse_buttons_to_system)
3341 goto dflt;
3342
3343 case WM_MBUTTONDOWN:
3344 case WM_MBUTTONUP:
3345 handle_plain_button:
3346 {
3347 BOOL up;
3348 int button;
3349
3350
3351 f = x_window_to_frame (dpyinfo, hwnd);
3352 if (f && f->output_data.w32->menubar_active)
3353 return 0;
3354
3355 if (parse_button (msg, HIWORD (wParam), &button, &up))
3356 {
3357 if (up) ReleaseCapture ();
3358 else SetCapture (hwnd);
3359 button = (button == 0) ? LMOUSE :
3360 ((button == 1) ? MMOUSE : RMOUSE);
3361 if (up)
3362 button_state &= ~button;
3363 else
3364 button_state |= button;
3365 }
3366 }
3367
3368 wmsg.dwModifiers = w32_get_modifiers ();
3369 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3370 signal_user_input ();
3371
3372 3373
3374 return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
3375
3376 case WM_MOUSEMOVE:
3377 3378 3379 3380
3381 f = x_window_to_frame (dpyinfo, hwnd);
3382 if (f && f->output_data.w32->menubar_active)
3383 return 0;
3384
3385 3386 3387 3388 3389 3390
3391 if (track_mouse_event_fn && !track_mouse_window)
3392 {
3393 TRACKMOUSEEVENT tme;
3394 tme.cbSize = sizeof (tme);
3395 tme.dwFlags = TME_LEAVE;
3396 tme.hwndTrack = hwnd;
3397
3398 track_mouse_event_fn (&tme);
3399 track_mouse_window = hwnd;
3400 }
3401 case WM_VSCROLL:
3402 if (w32_mouse_move_interval <= 0
3403 || (msg == WM_MOUSEMOVE && button_state == 0))
3404 {
3405 wmsg.dwModifiers = w32_get_modifiers ();
3406 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3407 return 0;
3408 }
3409
3410 3411 3412 3413
3414
3415 if (saved_mouse_move_msg.msg.hwnd == 0)
3416 mouse_move_timer =
3417 SetTimer (hwnd, MOUSE_MOVE_ID,
3418 w32_mouse_move_interval, NULL);
3419
3420
3421 saved_mouse_move_msg.msg.hwnd = hwnd;
3422 saved_mouse_move_msg.msg.message = msg;
3423 saved_mouse_move_msg.msg.wParam = wParam;
3424 saved_mouse_move_msg.msg.lParam = lParam;
3425 saved_mouse_move_msg.msg.time = GetMessageTime ();
3426 saved_mouse_move_msg.dwModifiers = w32_get_modifiers ();
3427
3428 return 0;
3429
3430 case WM_MOUSEWHEEL:
3431 case WM_DROPFILES:
3432 wmsg.dwModifiers = w32_get_modifiers ();
3433 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3434 signal_user_input ();
3435 return 0;
3436
3437 case WM_APPCOMMAND:
3438 if (w32_pass_multimedia_buttons_to_system)
3439 goto dflt;
3440
3441 case WM_MOUSEHWHEEL:
3442 wmsg.dwModifiers = w32_get_modifiers ();
3443 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3444 signal_user_input ();
3445 3446 3447
3448 return 1;
3449
3450 case WM_TIMER:
3451
3452 if (wParam == mouse_button_timer)
3453 {
3454 if (saved_mouse_button_msg.msg.hwnd)
3455 {
3456 post_msg (&saved_mouse_button_msg);
3457 signal_user_input ();
3458 saved_mouse_button_msg.msg.hwnd = 0;
3459 }
3460 KillTimer (hwnd, mouse_button_timer);
3461 mouse_button_timer = 0;
3462 }
3463 else if (wParam == mouse_move_timer)
3464 {
3465 if (saved_mouse_move_msg.msg.hwnd)
3466 {
3467 post_msg (&saved_mouse_move_msg);
3468 saved_mouse_move_msg.msg.hwnd = 0;
3469 }
3470 KillTimer (hwnd, mouse_move_timer);
3471 mouse_move_timer = 0;
3472 }
3473 else if (wParam == menu_free_timer)
3474 {
3475 KillTimer (hwnd, menu_free_timer);
3476 menu_free_timer = 0;
3477 f = x_window_to_frame (dpyinfo, hwnd);
3478
3479 if (menubar_in_use
3480 && current_popup_menu == NULL)
3481 {
3482
3483 w32_free_menu_strings (hwnd);
3484 f->output_data.w32->menubar_active = 0;
3485 menubar_in_use = 0;
3486 }
3487 }
3488 else if (wParam == hourglass_timer)
3489 {
3490 KillTimer (hwnd, hourglass_timer);
3491 hourglass_timer = 0;
3492 w32_show_hourglass (x_window_to_frame (dpyinfo, hwnd));
3493 }
3494 return 0;
3495
3496 case WM_NCACTIVATE:
3497 3498 3499 3500 3501
3502 reset_modifiers ();
3503 goto dflt;
3504
3505 case WM_INITMENU:
3506 button_state = 0;
3507 ReleaseCapture ();
3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522
3523
3524 f = x_window_to_frame (dpyinfo, hwnd);
3525 if (f
3526 && (f->output_data.w32->menubar_active
3527 3528 3529 3530 3531
3532 || f->output_data.w32->menubar_widget == NULL))
3533 return 0;
3534
3535 {
3536 deferred_msg msg_buf;
3537
3538 3539
3540 if (find_deferred_msg (hwnd, msg) != NULL)
3541 abort ();
3542
3543 menubar_in_use = 1;
3544
3545 return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam);
3546 }
3547
3548 case WM_EXITMENULOOP:
3549 f = x_window_to_frame (dpyinfo, hwnd);
3550
3551 3552 3553 3554 3555 3556
3557 if (f && menubar_in_use && current_popup_menu == NULL)
3558 menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
3559
3560
3561 if (f && f->output_data.w32->hourglass_p)
3562 SetCursor (f->output_data.w32->hourglass_cursor);
3563
3564 goto dflt;
3565
3566 case WM_MENUSELECT:
3567 3568 3569
3570 {
3571 HMENU menu = (HMENU) lParam;
3572 UINT menu_item = (UINT) LOWORD (wParam);
3573 UINT flags = (UINT) HIWORD (wParam);
3574
3575 w32_menu_display_help (hwnd, menu, menu_item, flags);
3576 }
3577 return 0;
3578
3579 case WM_MEASUREITEM:
3580 f = x_window_to_frame (dpyinfo, hwnd);
3581 if (f)
3582 {
3583 MEASUREITEMSTRUCT * pMis = (MEASUREITEMSTRUCT *) lParam;
3584
3585 if (pMis->CtlType == ODT_MENU)
3586 {
3587
3588 char * title = (char *) pMis->itemData;
3589 HDC hdc = GetDC (hwnd);
3590 HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
3591 LOGFONT menu_logfont;
3592 HFONT old_font;
3593 SIZE size;
3594
3595 GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
3596 menu_logfont.lfWeight = FW_BOLD;
3597 menu_font = CreateFontIndirect (&menu_logfont);
3598 old_font = SelectObject (hdc, menu_font);
3599
3600 pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
3601 if (title)
3602 {
3603 if (unicode_append_menu)
3604 GetTextExtentPoint32W (hdc, (WCHAR *) title,
3605 wcslen ((WCHAR *) title),
3606 &size);
3607 else
3608 GetTextExtentPoint32 (hdc, title, strlen (title), &size);
3609
3610 pMis->itemWidth = size.cx;
3611 if (pMis->itemHeight < size.cy)
3612 pMis->itemHeight = size.cy;
3613 }
3614 else
3615 pMis->itemWidth = 0;
3616
3617 SelectObject (hdc, old_font);
3618 DeleteObject (menu_font);
3619 ReleaseDC (hwnd, hdc);
3620 return TRUE;
3621 }
3622 }
3623 return 0;
3624
3625 case WM_DRAWITEM:
3626 f = x_window_to_frame (dpyinfo, hwnd);
3627 if (f)
3628 {
3629 DRAWITEMSTRUCT * pDis = (DRAWITEMSTRUCT *) lParam;
3630
3631 if (pDis->CtlType == ODT_MENU)
3632 {
3633
3634 char * title = (char *) pDis->itemData;
3635 if (title)
3636 {
3637 HDC hdc = pDis->hDC;
3638 HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
3639 LOGFONT menu_logfont;
3640 HFONT old_font;
3641
3642 GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
3643 menu_logfont.lfWeight = FW_BOLD;
3644 menu_font = CreateFontIndirect (&menu_logfont);
3645 old_font = SelectObject (hdc, menu_font);
3646
3647
3648 if (unicode_append_menu)
3649 ExtTextOutW (hdc,
3650 pDis->rcItem.left
3651 + GetSystemMetrics (SM_CXMENUCHECK),
3652 pDis->rcItem.top,
3653 ETO_OPAQUE, &pDis->rcItem,
3654 (WCHAR *) title,
3655 wcslen ((WCHAR *) title), NULL);
3656 else
3657 ExtTextOut (hdc,
3658 pDis->rcItem.left
3659 + GetSystemMetrics (SM_CXMENUCHECK),
3660 pDis->rcItem.top,
3661 ETO_OPAQUE, &pDis->rcItem,
3662 title, strlen (title), NULL);
3663
3664 SelectObject (hdc, old_font);
3665 DeleteObject (menu_font);
3666 }
3667 return TRUE;
3668 }
3669 }
3670 return 0;
3671
3672 #if 0
3673 3674 3675 3676
3677 case WM_MOUSEACTIVATE:
3678 3679 3680
3681 if (LOWORD (lParam) == HTCLIENT )
3682 return MA_ACTIVATEANDEAT;
3683 goto dflt;
3684 #endif
3685
3686 case WM_MOUSELEAVE:
3687
3688 track_mouse_window = NULL;
3689
3690 case WM_ACTIVATEAPP:
3691 case WM_ACTIVATE:
3692 case WM_WINDOWPOSCHANGED:
3693 case WM_SHOWWINDOW:
3694 3695
3696 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3697 goto dflt;
3698
3699 case WM_SETFOCUS:
3700 dpyinfo->faked_key = 0;
3701 reset_modifiers ();
3702 register_hot_keys (hwnd);
3703 goto command;
3704 case WM_KILLFOCUS:
3705 unregister_hot_keys (hwnd);
3706 button_state = 0;
3707 ReleaseCapture ();
3708
3709 if (w32_system_caret_hwnd)
3710 {
3711 w32_visible_system_caret_hwnd = NULL;
3712 w32_system_caret_hwnd = NULL;
3713 DestroyCaret ();
3714 }
3715 goto command;
3716 case WM_COMMAND:
3717 menubar_in_use = 0;
3718 f = x_window_to_frame (dpyinfo, hwnd);
3719 if (f && HIWORD (wParam) == 0)
3720 {
3721 if (menu_free_timer)
3722 {
3723 KillTimer (hwnd, menu_free_timer);
3724 menu_free_timer = 0;
3725 }
3726 }
3727 case WM_MOVE:
3728 case WM_SIZE:
3729 command:
3730 wmsg.dwModifiers = w32_get_modifiers ();
3731 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3732 goto dflt;
3733
3734 case WM_DESTROY:
3735 CoUninitialize ();
3736 return 0;
3737
3738 case WM_CLOSE:
3739 wmsg.dwModifiers = w32_get_modifiers ();
3740 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3741 return 0;
3742
3743 case WM_WINDOWPOSCHANGING:
3744
3745 if (hwnd == tip_window)
3746 return 0;
3747 {
3748 WINDOWPLACEMENT wp;
3749 LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
3750
3751 wp.length = sizeof (WINDOWPLACEMENT);
3752 GetWindowPlacement (hwnd, &wp);
3753
3754 if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0)
3755 {
3756 RECT rect;
3757 int wdiff;
3758 int hdiff;
3759 DWORD font_width;
3760 DWORD line_height;
3761 DWORD internal_border;
3762 DWORD scrollbar_extra;
3763 RECT wr;
3764
3765 wp.length = sizeof (wp);
3766 GetWindowRect (hwnd, &wr);
3767
3768 enter_crit ();
3769
3770 font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
3771 line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
3772 internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
3773 scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX);
3774
3775 leave_crit ();
3776
3777 memset (&rect, 0, sizeof (rect));
3778 AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
3779 GetMenu (hwnd) != NULL);
3780
3781 3782
3783 wdiff = (lppos->cx - (rect.right - rect.left)
3784 - 2 * internal_border - scrollbar_extra)
3785 % font_width;
3786 hdiff = (lppos->cy - (rect.bottom - rect.top)
3787 - 2 * internal_border)
3788 % line_height;
3789
3790 if (wdiff || hdiff)
3791 {
3792 3793 3794
3795
3796 int cx_mintrack = GetSystemMetrics (SM_CXMINTRACK);
3797 int cy_mintrack = GetSystemMetrics (SM_CYMINTRACK);
3798
3799 lppos->cx = max (lppos->cx - wdiff, cx_mintrack);
3800 lppos->cy = max (lppos->cy - hdiff, cy_mintrack);
3801
3802 if (wp.showCmd != SW_SHOWMAXIMIZED
3803 && (lppos->flags & SWP_NOMOVE) == 0)
3804 {
3805 if (lppos->x != wr.left || lppos->y != wr.top)
3806 {
3807 lppos->x += wdiff;
3808 lppos->y += hdiff;
3809 }
3810 else
3811 {
3812 lppos->flags |= SWP_NOMOVE;
3813 }
3814 }
3815
3816 return 0;
3817 }
3818 }
3819 }
3820
3821 goto dflt;
3822
3823 case WM_GETMINMAXINFO:
3824 3825
3826 ((LPMINMAXINFO) lParam)->ptMaxTrackSize.x = 32767;
3827 ((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;
3828 return 0;
3829
3830 case WM_SETCURSOR:
3831 if (LOWORD (lParam) == HTCLIENT)
3832 {
3833 f = x_window_to_frame (dpyinfo, hwnd);
3834 if (f->output_data.w32->hourglass_p && !menubar_in_use
3835 && !current_popup_menu)
3836 SetCursor (f->output_data.w32->hourglass_cursor);
3837 else
3838 SetCursor (f->output_data.w32->current_cursor);
3839 return 0;
3840 }
3841 goto dflt;
3842
3843 case WM_EMACS_SETCURSOR:
3844 {
3845 Cursor cursor = (Cursor) wParam;
3846 f = x_window_to_frame (dpyinfo, hwnd);
3847 if (f && cursor)
3848 {
3849 f->output_data.w32->current_cursor = cursor;
3850 if (!f->output_data.w32->hourglass_p)
3851 SetCursor (cursor);
3852 }
3853 return 0;
3854 }
3855
3856 case WM_EMACS_CREATESCROLLBAR:
3857 return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
3858 (struct scroll_bar *) lParam);
3859
3860 case WM_EMACS_SHOWWINDOW:
3861 return ShowWindow ((HWND) wParam, (WPARAM) lParam);
3862
3863 case WM_EMACS_SETFOREGROUND:
3864 {
3865 HWND foreground_window;
3866 DWORD foreground_thread, retval;
3867
3868 3869 3870
3871 foreground_window = GetForegroundWindow ();
3872 foreground_thread = GetWindowThreadProcessId (foreground_window, NULL);
3873 if (!foreground_window
3874 || foreground_thread == GetCurrentThreadId ()
3875 || !AttachThreadInput (GetCurrentThreadId (),
3876 foreground_thread, TRUE))
3877 foreground_thread = 0;
3878
3879 retval = SetForegroundWindow ((HWND) wParam);
3880
3881
3882 if (foreground_thread)
3883 AttachThreadInput (GetCurrentThreadId (),
3884 foreground_thread, FALSE);
3885
3886 return retval;
3887 }
3888
3889 case WM_EMACS_SETWINDOWPOS:
3890 {
3891 WINDOWPOS * pos = (WINDOWPOS *) wParam;
3892 return SetWindowPos (hwnd, pos->hwndInsertAfter,
3893 pos->x, pos->y, pos->cx, pos->cy, pos->flags);
3894 }
3895
3896 case WM_EMACS_DESTROYWINDOW:
3897 DragAcceptFiles ((HWND) wParam, FALSE);
3898 return DestroyWindow ((HWND) wParam);
3899
3900 case WM_EMACS_HIDE_CARET:
3901 return HideCaret (hwnd);
3902
3903 case WM_EMACS_SHOW_CARET:
3904 return ShowCaret (hwnd);
3905
3906 case WM_EMACS_DESTROY_CARET:
3907 w32_system_caret_hwnd = NULL;
3908 w32_visible_system_caret_hwnd = NULL;
3909 return DestroyCaret ();
3910
3911 case WM_EMACS_TRACK_CARET:
3912
3913 if (w32_system_caret_hwnd == NULL)
3914 {
3915 3916
3917 w32_system_caret_hwnd = hwnd;
3918 CreateCaret (hwnd, NULL, 0,
3919 w32_system_caret_height);
3920 }
3921
3922 if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y))
3923 return 0;
3924
3925 else if (w32_use_visible_system_caret
3926 && w32_visible_system_caret_hwnd != hwnd)
3927 {
3928 w32_visible_system_caret_hwnd = hwnd;
3929 return ShowCaret (hwnd);
3930 }
3931
3932 else if (!w32_use_visible_system_caret
3933 && w32_visible_system_caret_hwnd)
3934 {
3935 w32_visible_system_caret_hwnd = NULL;
3936 return HideCaret (hwnd);
3937 }
3938 else
3939 return 1;
3940
3941 case WM_EMACS_TRACKPOPUPMENU:
3942 {
3943 UINT flags;
3944 POINT *pos;
3945 int retval;
3946 pos = (POINT *)lParam;
3947 flags = TPM_CENTERALIGN;
3948 if (button_state & LMOUSE)
3949 flags |= TPM_LEFTBUTTON;
3950 else if (button_state & RMOUSE)
3951 flags |= TPM_RIGHTBUTTON;
3952
3953 3954
3955 ReleaseCapture ();
3956 button_state = 0;
3957
3958 3959
3960 f = x_window_to_frame (dpyinfo, hwnd);
3961 if (f)
3962 f->output_data.w32->menubar_active = 1;
3963
3964 if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y,
3965 0, hwnd, NULL))
3966 {
3967 MSG amsg;
3968
3969 while (PeekMessage (&amsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST,
3970 PM_REMOVE));
3971
3972 if (PeekMessage (&amsg, hwnd, WM_COMMAND, WM_COMMAND, PM_REMOVE))
3973 {
3974 retval = LOWORD (amsg.wParam);
3975 }
3976 else
3977 {
3978 retval = 0;
3979 }
3980 }
3981 else
3982 {
3983 retval = -1;
3984 }
3985
3986 return retval;
3987 }
3988
3989 default:
3990
3991 if (msg == msh_mousewheel)
3992 {
3993 wmsg.dwModifiers = w32_get_modifiers ();
3994 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3995 signal_user_input ();
3996 return 0;
3997 }
3998
3999 dflt:
4000 return DefWindowProc (hwnd, msg, wParam, lParam);
4001 }
4002
4003
4004
4005 return 0;
4006 }
4007
4008 static void
4009 my_create_window (f)
4010 struct frame * f;
4011 {
4012 MSG msg;
4013
4014 if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0))
4015 abort ();
4016 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
4017 }
4018
4019
4020 4021 4022 4023
4024 static void
4025 my_create_tip_window (f)
4026 struct frame *f;
4027 {
4028 RECT rect;
4029
4030 rect.left = rect.top = 0;
4031 rect.right = FRAME_PIXEL_WIDTH (f);
4032 rect.bottom = FRAME_PIXEL_HEIGHT (f);
4033
4034 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
4035 FRAME_EXTERNAL_MENU_BAR (f));
4036
4037 tip_window = FRAME_W32_WINDOW (f)
4038 = CreateWindow (EMACS_CLASS,
4039 f->namebuf,
4040 f->output_data.w32->dwStyle,
4041 f->left_pos,
4042 f->top_pos,
4043 rect.right - rect.left,
4044 rect.bottom - rect.top,
4045 FRAME_W32_WINDOW (SELECTED_FRAME ()),
4046 NULL,
4047 hinst,
4048 NULL);
4049
4050 if (tip_window)
4051 {
4052 SetWindowLong (tip_window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
4053 SetWindowLong (tip_window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
4054 SetWindowLong (tip_window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
4055 SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
4056
4057
4058 SetWindowLong (tip_window, WND_SCROLLBAR_INDEX, 0);
4059
4060
4061 ShowWindow (tip_window, SW_HIDE);
4062 }
4063 }
4064
4065
4066
4067
4068 static void
4069 w32_window (f, window_prompting, minibuffer_only)
4070 struct frame *f;
4071 long window_prompting;
4072 int minibuffer_only;
4073 {
4074 BLOCK_INPUT;
4075
4076 4077 4078 4079 4080
4081
4082 {
4083 char *str = (char *) SDATA (Vx_resource_name);
4084 f->namebuf = (char *) xmalloc (strlen (str) + 1);
4085 strcpy (f->namebuf, str);
4086 }
4087
4088 my_create_window (f);
4089
4090 validate_x_resource_name ();
4091
4092 4093 4094 4095
4096 {
4097 Lisp_Object name;
4098 int explicit = f->explicit_name;
4099
4100 f->explicit_name = 0;
4101 name = f->name;
4102 f->name = Qnil;
4103 x_set_name (f, name, explicit);
4104 }
4105
4106 UNBLOCK_INPUT;
4107
4108 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
4109 initialize_frame_menubar (f);
4110
4111 if (FRAME_W32_WINDOW (f) == 0)
4112 error ("Unable to create window");
4113 }
4114
4115 4116 4117
4118
4119 static void
4120 x_icon (f, parms)
4121 struct frame *f;
4122 Lisp_Object parms;
4123 {
4124 Lisp_Object icon_x, icon_y;
4125 struct w32_display_info *dpyinfo = &one_w32_display_info;
4126
4127 4128
4129 icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
4130 icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
4131 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
4132 {
4133 CHECK_NUMBER (icon_x);
4134 CHECK_NUMBER (icon_y);
4135 }
4136 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
4137 error ("Both left and top icon corners of icon must be specified");
4138
4139 BLOCK_INPUT;
4140
4141 if (! EQ (icon_x, Qunbound))
4142 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
4143
4144 #if 0
4145
4146 x_wm_set_window_state
4147 (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
4148 ? IconicState
4149 : NormalState));
4150
4151 x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name)
4152 ? f->icon_name
4153 : f->name)));
4154 #endif
4155
4156 UNBLOCK_INPUT;
4157 }
4158
4159
4160 static void
4161 x_make_gc (f)
4162 struct frame *f;
4163 {
4164 XGCValues gc_values;
4165
4166 BLOCK_INPUT;
4167
4168 4169
4170
4171
4172 gc_values.font = FRAME_FONT (f);
4173
4174
4175 gc_values.foreground = FRAME_BACKGROUND_PIXEL (f);
4176 gc_values.background = f->output_data.w32->cursor_pixel;
4177 f->output_data.w32->cursor_gc
4178 = XCreateGC (NULL, FRAME_W32_WINDOW (f),
4179 (GCFont | GCForeground | GCBackground),
4180 &gc_values);
4181
4182
4183 f->output_data.w32->white_relief.gc = 0;
4184 f->output_data.w32->black_relief.gc = 0;
4185
4186 UNBLOCK_INPUT;
4187 }
4188
4189
4190 4191 4192
4193
4194 static Lisp_Object
4195 unwind_create_frame (frame)
4196 Lisp_Object frame;
4197 {
4198 struct frame *f = XFRAME (frame);
4199
4200
4201 if (!CONSP (Vframe_list) || !EQ (XCAR (Vframe_list), frame))
4202 {
4203 #ifdef GLYPH_DEBUG
4204 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4205 #endif
4206
4207 x_free_frame_resources (f);
4208
4209 #if GLYPH_DEBUG
4210
4211 xassert (dpyinfo->reference_count == dpyinfo_refcount);
4212 xassert (dpyinfo->image_cache->refcount == image_cache_refcount);
4213 #endif
4214 return Qt;
4215 }
4216
4217 return Qnil;
4218 }
4219
4220 static void
4221 x_default_font_parameter (f, parms)
4222 struct frame *f;
4223 Lisp_Object parms;
4224 {
4225 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
4226 Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
4227 RES_TYPE_STRING);
4228 Lisp_Object font;
4229 if (EQ (font_param, Qunbound))
4230 font_param = Qnil;
4231 font = !NILP (font_param) ? font_param
4232 : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
4233
4234 if (!STRINGP (font))
4235 {
4236 int i;
4237 static char *names[]
4238 = { "Courier New-10",
4239 "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
4240 "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
4241 "Fixedsys",
4242 NULL };
4243
4244 for (i = 0; names[i]; i++)
4245 {
4246 font = font_open_by_name (f, names[i]);
4247 if (! NILP (font))
4248 break;
4249 }
4250 if (NILP (font))
4251 error ("No suitable font was found");
4252 }
4253 else if (!NILP (font_param))
4254 {
4255 4256
4257 x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil));
4258 }
4259 x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING);
4260 }
4261
4262 DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
4263 1, 1, 0,
4264 doc: 4265 4266 4267 4268 4269 4270 4271 4272 )
4273 (parameters)
4274 Lisp_Object parameters;
4275 {
4276 struct frame *f;
4277 Lisp_Object frame, tem;
4278 Lisp_Object name;
4279 int minibuffer_only = 0;
4280 long window_prompting = 0;
4281 int width, height;
4282 int count = SPECPDL_INDEX ();
4283 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
4284 Lisp_Object display;
4285 struct w32_display_info *dpyinfo = NULL;
4286 Lisp_Object parent;
4287 struct kboard *kb;
4288
4289 4290
4291 parameters = Fcopy_alist (parameters);
4292
4293 4294
4295 Vx_resource_name = Vinvocation_name;
4296
4297 display = x_get_arg (dpyinfo, parameters, Qterminal, 0, 0, RES_TYPE_NUMBER);
4298 if (EQ (display, Qunbound))
4299 display = x_get_arg (dpyinfo, parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
4300 if (EQ (display, Qunbound))
4301 display = Qnil;
4302 dpyinfo = check_x_display_info (display);
4303 kb = dpyinfo->terminal->kboard;
4304
4305 if (!dpyinfo->terminal->name)
4306 error ("Terminal is not live, can't create new frames on it");
4307
4308 name = x_get_arg (dpyinfo, parameters, Qname, "name", "Name", RES_TYPE_STRING);
4309 if (!STRINGP (name)
4310 && ! EQ (name, Qunbound)
4311 && ! NILP (name))
4312 error ("Invalid frame name--not a string or nil");
4313
4314 if (STRINGP (name))
4315 Vx_resource_name = name;
4316
4317
4318 parent = x_get_arg (dpyinfo, parameters, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
4319 if (EQ (parent, Qunbound))
4320 parent = Qnil;
4321 if (! NILP (parent))
4322 CHECK_NUMBER (parent);
4323
4324
4325 4326
4327 frame = Qnil;
4328 GCPRO4 (parameters, parent, name, frame);
4329 tem = x_get_arg (dpyinfo, parameters, Qminibuffer, "minibuffer", "Minibuffer",
4330 RES_TYPE_SYMBOL);
4331 if (EQ (tem, Qnone) || NILP (tem))
4332 f = make_frame_without_minibuffer (Qnil, kb, display);
4333 else if (EQ (tem, Qonly))
4334 {
4335 f = make_minibuffer_frame ();
4336 minibuffer_only = 1;
4337 }
4338 else if (WINDOWP (tem))
4339 f = make_frame_without_minibuffer (tem, kb, display);
4340 else
4341 f = make_frame (1);
4342
4343 XSETFRAME (frame, f);
4344
4345
4346 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
4347
4348
4349 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
4350
4351 f->terminal = dpyinfo->terminal;
4352 f->terminal->reference_count++;
4353
4354 f->output_method = output_w32;
4355 f->output_data.w32 =
4356 (struct w32_output *) xmalloc (sizeof (struct w32_output));
4357 bzero (f->output_data.w32, sizeof (struct w32_output));
4358 FRAME_FONTSET (f) = -1;
4359
4360 f->icon_name
4361 = x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
4362 RES_TYPE_STRING);
4363 if (! STRINGP (f->icon_name))
4364 f->icon_name = Qnil;
4365
4366
4367
4368
4369 record_unwind_protect (unwind_create_frame, frame);
4370 #if GLYPH_DEBUG
4371 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
4372 dpyinfo_refcount = dpyinfo->reference_count;
4373 #endif
4374
4375
4376
4377 if (!NILP (parent))
4378 {
4379 f->output_data.w32->parent_desc = (Window) XFASTINT (parent);
4380 f->output_data.w32->explicit_parent = 1;
4381 }
4382 else
4383 {
4384 f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
4385 f->output_data.w32->explicit_parent = 0;
4386 }
4387
4388 4389
4390 if (EQ (name, Qunbound) || NILP (name))
4391 {
4392 f->name = build_string (dpyinfo->w32_id_name);
4393 f->explicit_name = 0;
4394 }
4395 else
4396 {
4397 f->name = name;
4398 f->explicit_name = 1;
4399
4400 specbind (Qx_resource_name, name);
4401 }
4402
4403 f->resx = dpyinfo->resx;
4404 f->resy = dpyinfo->resy;
4405
4406 if (uniscribe_available)
4407 register_font_driver (&uniscribe_font_driver, f);
4408 register_font_driver (&w32font_driver, f);
4409
4410 x_default_parameter (f, parameters, Qfont_backend, Qnil,
4411 "fontBackend", "FontBackend", RES_TYPE_STRING);
4412 4413
4414 x_default_font_parameter (f, parameters);
4415 x_default_parameter (f, parameters, Qborder_width, make_number (2),
4416 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
4417
4418 4419
4420 if (NILP (Fassq (Qinternal_border_width, parameters)))
4421 {
4422 Lisp_Object value;
4423
4424 value = x_get_arg (dpyinfo, parameters, Qinternal_border_width,
4425 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
4426 if (! EQ (value, Qunbound))
4427 parameters = Fcons (Fcons (Qinternal_border_width, value),
4428 parameters);
4429 }
4430
4431 x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
4432 "internalBorderWidth", "InternalBorder", RES_TYPE_NUMBER);
4433 x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
4434 "verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
4435
4436
4437 x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
4438 "foreground", "Foreground", RES_TYPE_STRING);
4439 x_default_parameter (f, parameters, Qbackground_color, build_string ("white"),
4440 "background", "Background", RES_TYPE_STRING);
4441 x_default_parameter (f, parameters, Qmouse_color, build_string ("black"),
4442 "pointerColor", "Foreground", RES_TYPE_STRING);
4443 x_default_parameter (f, parameters, Qcursor_color, build_string ("black"),
4444 "cursorColor", "Foreground", RES_TYPE_STRING);
4445 x_default_parameter (f, parameters, Qborder_color, build_string ("black"),
4446 "borderColor", "BorderColor", RES_TYPE_STRING);
4447 x_default_parameter (f, parameters, Qscreen_gamma, Qnil,
4448 "screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
4449 x_default_parameter (f, parameters, Qline_spacing, Qnil,
4450 "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
4451 x_default_parameter (f, parameters, Qleft_fringe, Qnil,
4452 "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
4453 x_default_parameter (f, parameters, Qright_fringe, Qnil,
4454 "rightFringe", "RightFringe", RES_TYPE_NUMBER);
4455
4456
4457 4458 4459 4460 4461 4462
4463 init_frame_faces (f);
4464
4465 x_default_parameter (f, parameters, Qmenu_bar_lines, make_number (1),
4466 "menuBar", "MenuBar", RES_TYPE_NUMBER);
4467 x_default_parameter (f, parameters, Qtool_bar_lines, make_number (1),
4468 "toolBar", "ToolBar", RES_TYPE_NUMBER);
4469
4470 x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
4471 "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
4472 x_default_parameter (f, parameters, Qtitle, Qnil,
4473 "title", "Title", RES_TYPE_STRING);
4474 x_default_parameter (f, parameters, Qfullscreen, Qnil,
4475 "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
4476
4477 f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
4478 f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
4479
4480 f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM);
4481 f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
4482 f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW);
4483 f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
4484 f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
4485 f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
4486
4487 f->output_data.w32->current_cursor = f->output_data.w32->nontext_cursor;
4488
4489 window_prompting = x_figure_window_size (f, parameters, 1);
4490
4491 tem = x_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
4492 f->no_split = minibuffer_only || EQ (tem, Qt);
4493
4494 w32_window (f, window_prompting, minibuffer_only);
4495 x_icon (f, parameters);
4496
4497 x_make_gc (f);
4498
4499
4500 FRAME_W32_DISPLAY_INFO (f)->reference_count++;
4501 Vframe_list = Fcons (frame, Vframe_list);
4502
4503 4504
4505 x_default_parameter (f, parameters, Qicon_type, Qnil,
4506 "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
4507
4508 x_default_parameter (f, parameters, Qauto_raise, Qnil,
4509 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4510 x_default_parameter (f, parameters, Qauto_lower, Qnil,
4511 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
4512 x_default_parameter (f, parameters, Qcursor_type, Qbox,
4513 "cursorType", "CursorType", RES_TYPE_SYMBOL);
4514 x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
4515 "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
4516 x_default_parameter (f, parameters, Qalpha, Qnil,
4517 "alpha", "Alpha", RES_TYPE_NUMBER);
4518
4519 4520 4521
4522 width = FRAME_COLS (f);
4523 height = FRAME_LINES (f);
4524
4525 FRAME_LINES (f) = 0;
4526 SET_FRAME_COLS (f, 0);
4527 change_frame_size (f, height, width, 1, 0, 0);
4528
4529 4530 4531
4532 BLOCK_INPUT;
4533 x_wm_set_size_hint (f, window_prompting, 0);
4534 UNBLOCK_INPUT;
4535
4536 4537 4538
4539 if (! f->output_data.w32->explicit_parent)
4540 {
4541 Lisp_Object visibility;
4542
4543 visibility = x_get_arg (dpyinfo, parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
4544 if (EQ (visibility, Qunbound))
4545 visibility = Qt;
4546
4547 if (EQ (visibility, Qicon))
4548 x_iconify_frame (f);
4549 else if (! NILP (visibility))
4550 x_make_frame_visible (f);
4551 else
4552
4553 ;
4554 }
4555
4556 4557
4558 if (FRAME_HAS_MINIBUF_P (f)
4559 && (!FRAMEP (kb->Vdefault_minibuffer_frame)
4560 || !FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame))))
4561 kb->Vdefault_minibuffer_frame = frame;
4562
4563 4564
4565 for (tem = parameters; CONSP (tem); tem = XCDR (tem))
4566 if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
4567 f->param_alist = Fcons (XCAR (tem), f->param_alist);
4568
4569 UNGCPRO;
4570
4571 4572
4573 Vwindow_list = Qnil;
4574
4575 return unbind_to (count, frame);
4576 }
4577
4578 4579 4580
4581 Lisp_Object
4582 x_get_focus_frame (frame)
4583 struct frame *frame;
4584 {
4585 struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (frame);
4586 Lisp_Object xfocus;
4587 if (! dpyinfo->w32_focus_frame)
4588 return Qnil;
4589
4590 XSETFRAME (xfocus, dpyinfo->w32_focus_frame);
4591 return xfocus;
4592 }
4593
4594 DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
4595 doc: )
4596 (frame)
4597 Lisp_Object frame;
4598 {
4599 x_focus_on_frame (check_x_frame (frame));
4600 return Qnil;
4601 }
4602
4603
4604 DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
4605 doc: )
4606 (color, frame)
4607 Lisp_Object color, frame;
4608 {
4609 XColor foo;
4610 FRAME_PTR f = check_x_frame (frame);
4611
4612 CHECK_STRING (color);
4613
4614 if (w32_defined_color (f, SDATA (color), &foo, 0))
4615 return Qt;
4616 else
4617 return Qnil;
4618 }
4619
4620 DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
4621 doc: )
4622 (color, frame)
4623 Lisp_Object color, frame;
4624 {
4625 XColor foo;
4626 FRAME_PTR f = check_x_frame (frame);
4627
4628 CHECK_STRING (color);
4629
4630 if (w32_defined_color (f, SDATA (color), &foo, 0))
4631 return list3 (make_number ((GetRValue (foo.pixel) << 8)
4632 | GetRValue (foo.pixel)),
4633 make_number ((GetGValue (foo.pixel) << 8)
4634 | GetGValue (foo.pixel)),
4635 make_number ((GetBValue (foo.pixel) << 8)
4636 | GetBValue (foo.pixel)));
4637 else
4638 return Qnil;
4639 }
4640
4641 DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
4642 doc: )
4643 (display)
4644 Lisp_Object display;
4645 {
4646 struct w32_display_info *dpyinfo = check_x_display_info (display);
4647
4648 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 2)
4649 return Qnil;
4650
4651 return Qt;
4652 }
4653
4654 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
4655 Sx_display_grayscale_p, 0, 1, 0,
4656 doc: 4657 4658 4659 4660 )
4661 (display)
4662 Lisp_Object display;
4663 {
4664 struct w32_display_info *dpyinfo = check_x_display_info (display);
4665
4666 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 1)
4667 return Qnil;
4668
4669 return Qt;
4670 }
4671
4672 DEFUN ("x-display-pixel-width", Fx_display_pixel_width,
4673 Sx_display_pixel_width, 0, 1, 0,
4674 doc: 4675 4676 4677 )
4678 (display)
4679 Lisp_Object display;
4680 {
4681 struct w32_display_info *dpyinfo = check_x_display_info (display);
4682
4683 return make_number (x_display_pixel_width (dpyinfo));
4684 }
4685
4686 DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
4687 Sx_display_pixel_height, 0, 1, 0,
4688 doc: 4689 4690 4691 )
4692 (display)
4693 Lisp_Object display;
4694 {
4695 struct w32_display_info *dpyinfo = check_x_display_info (display);
4696
4697 return make_number (x_display_pixel_height (dpyinfo));
4698 }
4699
4700 DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
4701 0, 1, 0,
4702 doc: 4703 4704 4705 )
4706 (display)
4707 Lisp_Object display;
4708 {
4709 struct w32_display_info *dpyinfo = check_x_display_info (display);
4710
4711 return make_number (dpyinfo->n_planes * dpyinfo->n_cbits);
4712 }
4713
4714 DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
4715 0, 1, 0,
4716 doc: 4717 4718 4719 )
4720 (display)
4721 Lisp_Object display;
4722 {
4723 struct w32_display_info *dpyinfo = check_x_display_info (display);
4724 HDC hdc;
4725 int cap;
4726
4727 hdc = GetDC (dpyinfo->root_window);
4728 if (dpyinfo->has_palette)
4729 cap = GetDeviceCaps (hdc, SIZEPALETTE);
4730 else
4731 cap = GetDeviceCaps (hdc, NUMCOLORS);
4732
4733 4734
4735 if (cap < 0)
4736 cap = 1 << min (dpyinfo->n_planes * dpyinfo->n_cbits, 24);
4737
4738 ReleaseDC (dpyinfo->root_window, hdc);
4739
4740 return make_number (cap);
4741 }
4742
4743 DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
4744 Sx_server_max_request_size,
4745 0, 1, 0,
4746 doc: 4747 4748 4749 )
4750 (display)
4751 Lisp_Object display;
4752 {
4753 struct w32_display_info *dpyinfo = check_x_display_info (display);
4754
4755 return make_number (1);
4756 }
4757
4758 DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
4759 doc: 4760 4761 4762 )
4763 (display)
4764 Lisp_Object display;
4765 {
4766 return build_string ("Microsoft Corp.");
4767 }
4768
4769 DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
4770 doc: 4771 4772 4773 4774 4775 4776 4777 )
4778 (display)
4779 Lisp_Object display;
4780 {
4781 return Fcons (make_number (w32_major_version),
4782 Fcons (make_number (w32_minor_version),
4783 Fcons (make_number (w32_build_number), Qnil)));
4784 }
4785
4786 DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
4787 doc: 4788 4789 4790 )
4791 (display)
4792 Lisp_Object display;
4793 {
4794 return make_number (1);
4795 }
4796
4797 DEFUN ("x-display-mm-height", Fx_display_mm_height,
4798 Sx_display_mm_height, 0, 1, 0,
4799 doc: 4800 4801 4802 )
4803 (display)
4804 Lisp_Object display;
4805 {
4806 struct w32_display_info *dpyinfo = check_x_display_info (display);
4807 HDC hdc;
4808 int cap;
4809
4810 hdc = GetDC (dpyinfo->root_window);
4811
4812 cap = GetDeviceCaps (hdc, VERTSIZE);
4813
4814 ReleaseDC (dpyinfo->root_window, hdc);
4815
4816 return make_number (cap);
4817 }
4818
4819 DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
4820 doc: 4821 4822 4823 )
4824 (display)
4825 Lisp_Object display;
4826 {
4827 struct w32_display_info *dpyinfo = check_x_display_info (display);
4828
4829 HDC hdc;
4830 int cap;
4831
4832 hdc = GetDC (dpyinfo->root_window);
4833
4834 cap = GetDeviceCaps (hdc, HORZSIZE);
4835
4836 ReleaseDC (dpyinfo->root_window, hdc);
4837
4838 return make_number (cap);
4839 }
4840
4841 DEFUN ("x-display-backing-store", Fx_display_backing_store,
4842 Sx_display_backing_store, 0, 1, 0,
4843 doc: 4844 4845 4846 4847 )
4848 (display)
4849 Lisp_Object display;
4850 {
4851 return intern ("not-useful");
4852 }
4853
4854 DEFUN ("x-display-visual-class", Fx_display_visual_class,
4855 Sx_display_visual_class, 0, 1, 0,
4856 doc: 4857 4858 4859 4860 4861 4862 )
4863 (display)
4864 Lisp_Object display;
4865 {
4866 struct w32_display_info *dpyinfo = check_x_display_info (display);
4867 Lisp_Object result = Qnil;
4868
4869 if (dpyinfo->has_palette)
4870 result = intern ("pseudo-color");
4871 else if (dpyinfo->n_planes * dpyinfo->n_cbits == 1)
4872 result = intern ("static-grey");
4873 else if (dpyinfo->n_planes * dpyinfo->n_cbits == 4)
4874 result = intern ("static-color");
4875 else if (dpyinfo->n_planes * dpyinfo->n_cbits > 8)
4876 result = intern ("true-color");
4877
4878 return result;
4879 }
4880
4881 DEFUN ("x-display-save-under", Fx_display_save_under,
4882 Sx_display_save_under, 0, 1, 0,
4883 doc: 4884 4885 4886 )
4887 (display)
4888 Lisp_Object display;
4889 {
4890 return Qnil;
4891 }
4892
4893 int
4894 x_pixel_width (f)
4895 register struct frame *f;
4896 {
4897 return FRAME_PIXEL_WIDTH (f);
4898 }
4899
4900 int
4901 x_pixel_height (f)
4902 register struct frame *f;
4903 {
4904 return FRAME_PIXEL_HEIGHT (f);
4905 }
4906
4907 int
4908 x_char_width (f)
4909 register struct frame *f;
4910 {
4911 return FRAME_COLUMN_WIDTH (f);
4912 }
4913
4914 int
4915 x_char_height (f)
4916 register struct frame *f;
4917 {
4918 return FRAME_LINE_HEIGHT (f);
4919 }
4920
4921 int
4922 x_screen_planes (f)
4923 register struct frame *f;
4924 {
4925 return FRAME_W32_DISPLAY_INFO (f)->n_planes;
4926 }
4927
4928 4929
4930
4931 struct w32_display_info *
4932 x_display_info_for_name (name)
4933 Lisp_Object name;
4934 {
4935 Lisp_Object names;
4936 struct w32_display_info *dpyinfo;
4937
4938 CHECK_STRING (name);
4939
4940 for (dpyinfo = &one_w32_display_info, names = w32_display_name_list;
4941 dpyinfo;
4942 dpyinfo = dpyinfo->next, names = XCDR (names))
4943 {
4944 Lisp_Object tem;
4945 tem = Fstring_equal (XCAR (XCAR (names)), name);
4946 if (!NILP (tem))
4947 return dpyinfo;
4948 }
4949
4950
4951 Vx_resource_name = Vinvocation_name;
4952
4953 validate_x_resource_name ();
4954
4955 dpyinfo = w32_term_init (name, (unsigned char *)0,
4956 (char *) SDATA (Vx_resource_name));
4957
4958 if (dpyinfo == 0)
4959 error ("Cannot connect to server %s", SDATA (name));
4960
4961 w32_in_use = 1;
4962 XSETFASTINT (Vwindow_system_version, w32_major_version);
4963
4964 return dpyinfo;
4965 }
4966
4967 DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4968 1, 3, 0, doc: 4969 4970 4971 4972 )
4973 (display, xrm_string, must_succeed)
4974 Lisp_Object display, xrm_string, must_succeed;
4975 {
4976 unsigned char *xrm_option;
4977 struct w32_display_info *dpyinfo;
4978
4979 4980
4981 if (w32_in_use)
4982 return Qnil;
4983
4984 CHECK_STRING (display);
4985 if (! NILP (xrm_string))
4986 CHECK_STRING (xrm_string);
4987
4988 #if 0
4989 if (! EQ (Vwindow_system, intern ("w32")))
4990 error ("Not using Microsoft Windows");
4991 #endif
4992
4993 4994
4995 {
4996 Lisp_Object color_file;
4997 struct gcpro gcpro1;
4998
4999 color_file = build_string ("~/rgb.txt");
5000
5001 GCPRO1 (color_file);
5002
5003 if (NILP (Ffile_readable_p (color_file)))
5004 color_file =
5005 Fexpand_file_name (build_string ("rgb.txt"),
5006 Fsymbol_value (intern ("data-directory")));
5007
5008 Vw32_color_map = Fx_load_color_file (color_file);
5009
5010 UNGCPRO;
5011 }
5012 if (NILP (Vw32_color_map))
5013 Vw32_color_map = Fw32_default_color_map ();
5014
5015
5016 add_system_logical_colors_to_map (&Vw32_color_map);
5017
5018 if (! NILP (xrm_string))
5019 xrm_option = (unsigned char *) SDATA (xrm_string);
5020 else
5021 xrm_option = (unsigned char *) 0;
5022
5023
5024
5025 {
5026 char basename[ MAX_PATH ], *str;
5027
5028 strcpy (basename, SDATA (Vinvocation_name));
5029 str = strrchr (basename, '.');
5030 if (str) *str = 0;
5031 Vinvocation_name = build_string (basename);
5032 }
5033 Vx_resource_name = Vinvocation_name;
5034
5035 validate_x_resource_name ();
5036
5037 5038
5039 dpyinfo = w32_term_init (display, xrm_option,
5040 (char *) SDATA (Vx_resource_name));
5041
5042 if (dpyinfo == 0)
5043 {
5044 if (!NILP (must_succeed))
5045 fatal ("Cannot connect to server %s.\n",
5046 SDATA (display));
5047 else
5048 error ("Cannot connect to server %s", SDATA (display));
5049 }
5050
5051 w32_in_use = 1;
5052
5053 XSETFASTINT (Vwindow_system_version, w32_major_version);
5054 return Qnil;
5055 }
5056
5057 DEFUN ("x-close-connection", Fx_close_connection,
5058 Sx_close_connection, 1, 1, 0,
5059 doc: 5060 5061 )
5062 (display)
5063 Lisp_Object display;
5064 {
5065 struct w32_display_info *dpyinfo = check_x_display_info (display);
5066 int i;
5067
5068 if (dpyinfo->reference_count > 0)
5069 error ("Display still has frames on it");
5070
5071 BLOCK_INPUT;
5072 x_destroy_all_bitmaps (dpyinfo);
5073
5074 x_delete_display (dpyinfo);
5075 UNBLOCK_INPUT;
5076
5077 return Qnil;
5078 }
5079
5080 DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
5081 doc: )
5082 ()
5083 {
5084 Lisp_Object tail, result;
5085
5086 result = Qnil;
5087 for (tail = w32_display_name_list; CONSP (tail); tail = XCDR (tail))
5088 result = Fcons (XCAR (XCAR (tail)), result);
5089
5090 return result;
5091 }
5092
5093 DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
5094 doc: )
5095 (on, display)
5096 Lisp_Object display, on;
5097 {
5098 return Qnil;
5099 }
5100
5101
5102
5103 5104 5105
5106
5107 DEFUN ("x-change-window-property", Fx_change_window_property,
5108 Sx_change_window_property, 2, 6, 0,
5109 doc: 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 )
5125 (prop, value, frame, type, format, outer_p)
5126 Lisp_Object prop, value, frame, type, format, outer_p;
5127 {
5128 #if 0
5129 struct frame *f = check_x_frame (frame);
5130 Atom prop_atom;
5131
5132 CHECK_STRING (prop);
5133 CHECK_STRING (value);
5134
5135 BLOCK_INPUT;
5136 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
5137 XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
5138 prop_atom, XA_STRING, 8, PropModeReplace,
5139 SDATA (value), SCHARS (value));
5140
5141
5142 XFlush (FRAME_W32_DISPLAY (f));
5143 UNBLOCK_INPUT;
5144
5145 #endif
5146
5147 return value;
5148 }
5149
5150
5151 DEFUN ("x-delete-window-property", Fx_delete_window_property,
5152 Sx_delete_window_property, 1, 2, 0,
5153 doc: 5154 )
5155 (prop, frame)
5156 Lisp_Object prop, frame;
5157 {
5158 #if 0
5159
5160 struct frame *f = check_x_frame (frame);
5161 Atom prop_atom;
5162
5163 CHECK_STRING (prop);
5164 BLOCK_INPUT;
5165 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
5166 XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom);
5167
5168
5169 XFlush (FRAME_W32_DISPLAY (f));
5170 UNBLOCK_INPUT;
5171 #endif
5172
5173 return prop;
5174 }
5175
5176
5177 DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
5178 1, 2, 0,
5179 doc: 5180 5181 5182 )
5183 (prop, frame)
5184 Lisp_Object prop, frame;
5185 {
5186 #if 0
5187
5188 struct frame *f = check_x_frame (frame);
5189 Atom prop_atom;
5190 int rc;
5191 Lisp_Object prop_value = Qnil;
5192 char *tmp_data = NULL;
5193 Atom actual_type;
5194 int actual_format;
5195 unsigned long actual_size, bytes_remaining;
5196
5197 CHECK_STRING (prop);
5198 BLOCK_INPUT;
5199 prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False);
5200 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
5201 prop_atom, 0, 0, False, XA_STRING,
5202 &actual_type, &actual_format, &actual_size,
5203 &bytes_remaining, (unsigned char **) &tmp_data);
5204 if (rc == Success)
5205 {
5206 int size = bytes_remaining;
5207
5208 XFree (tmp_data);
5209 tmp_data = NULL;
5210
5211 rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
5212 prop_atom, 0, bytes_remaining,
5213 False, XA_STRING,
5214 &actual_type, &actual_format,
5215 &actual_size, &bytes_remaining,
5216 (unsigned char **) &tmp_data);
5217 if (rc == Success)
5218 prop_value = make_string (tmp_data, size);
5219
5220 XFree (tmp_data);
5221 }
5222
5223 UNBLOCK_INPUT;
5224
5225 return prop_value;
5226
5227 #endif
5228 return Qnil;
5229 }
5230
5231
5232
5233 5234 5235
5236
5237 5238 5239
5240 #define DEFAULT_HOURGLASS_DELAY 1
5241 extern Lisp_Object Vhourglass_delay;
5242
5243
5244 5245
5246
5247 int
5248 hourglass_started ()
5249 {
5250 return hourglass_shown_p || hourglass_timer;
5251 }
5252
5253
5254
5255 void
5256 start_hourglass ()
5257 {
5258 DWORD delay;
5259 int secs, msecs = 0;
5260 struct frame * f = SELECTED_FRAME ();
5261
5262
5263 if (!FRAME_W32_P (f))
5264 return;
5265
5266 cancel_hourglass ();
5267
5268 if (INTEGERP (Vhourglass_delay)
5269 && XINT (Vhourglass_delay) > 0)
5270 secs = XFASTINT (Vhourglass_delay);
5271 else if (FLOATP (Vhourglass_delay)
5272 && XFLOAT_DATA (Vhourglass_delay) > 0)
5273 {
5274 Lisp_Object tem;
5275 tem = Ftruncate (Vhourglass_delay, Qnil);
5276 secs = XFASTINT (tem);
5277 msecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000;
5278 }
5279 else
5280 secs = DEFAULT_HOURGLASS_DELAY;
5281
5282 delay = secs * 1000 + msecs;
5283 hourglass_hwnd = FRAME_W32_WINDOW (f);
5284 hourglass_timer = SetTimer (hourglass_hwnd, HOURGLASS_ID, delay, NULL);
5285 }
5286
5287
5288 5289
5290
5291 void
5292 cancel_hourglass ()
5293 {
5294 if (hourglass_timer)
5295 {
5296 KillTimer (hourglass_hwnd, hourglass_timer);
5297 hourglass_timer = 0;
5298 }
5299
5300 if (hourglass_shown_p)
5301 w32_hide_hourglass ();
5302 }
5303
5304
5305 5306 5307 5308
5309
5310 static void
5311 w32_show_hourglass (f)
5312 struct frame *f;
5313 {
5314 if (!hourglass_shown_p)
5315 {
5316 f->output_data.w32->hourglass_p = 1;
5317 if (!menubar_in_use && !current_popup_menu)
5318 SetCursor (f->output_data.w32->hourglass_cursor);
5319 hourglass_shown_p = 1;
5320 }
5321 }
5322
5323
5324
5325
5326 static void
5327 w32_hide_hourglass ()
5328 {
5329 if (hourglass_shown_p)
5330 {
5331 struct frame *f = x_window_to_frame (&one_w32_display_info,
5332 hourglass_hwnd);
5333 if (f)
5334 f->output_data.w32->hourglass_p = 0;
5335 else
5336
5337 f = SELECTED_FRAME ();
5338
5339 if (FRAME_W32_P (f))
5340 SetCursor (f->output_data.w32->current_cursor);
5341 else
5342
5343 SetCursor (w32_load_cursor (IDC_ARROW));
5344
5345 hourglass_shown_p = 0;
5346 }
5347 }
5348
5349
5350
5351 5352 5353
5354
5355 static Lisp_Object x_create_tip_frame P_ ((struct w32_display_info *,
5356 Lisp_Object, Lisp_Object));
5357 static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object,
5358 Lisp_Object, int, int, int *, int *));
5359
5360
5361
5362 Lisp_Object tip_frame;
5363
5364 5365
5366
5367 Lisp_Object tip_timer;
5368 Window tip_window;
5369
5370 5371
5372
5373 Lisp_Object last_show_tip_args;
5374
5375
5376
5377 Lisp_Object Vx_max_tooltip_size;
5378
5379
5380 static Lisp_Object
5381 unwind_create_tip_frame (frame)
5382 Lisp_Object frame;
5383 {
5384 Lisp_Object deleted;
5385
5386 deleted = unwind_create_frame (frame);
5387 if (EQ (deleted, Qt))
5388 {
5389 tip_window = NULL;
5390 tip_frame = Qnil;
5391 }
5392
5393 return deleted;
5394 }
5395
5396
5397 5398 5399 5400 5401 5402 5403 5404
5405
5406 static Lisp_Object
5407 x_create_tip_frame (dpyinfo, parms, text)
5408 struct w32_display_info *dpyinfo;
5409 Lisp_Object parms, text;
5410 {
5411 struct frame *f;
5412 Lisp_Object frame, tem;
5413 Lisp_Object name;
5414 long window_prompting = 0;
5415 int width, height;
5416 int count = SPECPDL_INDEX ();
5417 struct gcpro gcpro1, gcpro2, gcpro3;
5418 struct kboard *kb;
5419 int face_change_count_before = face_change_count;
5420 Lisp_Object buffer;
5421 struct buffer *old_buffer;
5422
5423 check_w32 ();
5424
5425 5426
5427 Vx_resource_name = Vinvocation_name;
5428
5429 kb = dpyinfo->terminal->kboard;
5430
5431 5432
5433 parms = Fcopy_alist (parms);
5434
5435
5436 name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
5437 if (!STRINGP (name)
5438 && !EQ (name, Qunbound)
5439 && !NILP (name))
5440 error ("Invalid frame name--not a string or nil");
5441 Vx_resource_name = name;
5442
5443 frame = Qnil;
5444 GCPRO3 (parms, name, frame);
5445
5446 f = make_frame (0);
5447 f->wants_modeline = 0;
5448 XSETFRAME (frame, f);
5449
5450 buffer = Fget_buffer_create (build_string (" *tip*"));
5451 Fset_window_buffer (FRAME_ROOT_WINDOW (f), buffer, Qnil);
5452 old_buffer = current_buffer;
5453 set_buffer_internal_1 (XBUFFER (buffer));
5454 current_buffer->truncate_lines = Qnil;
5455 specbind (Qinhibit_read_only, Qt);
5456 specbind (Qinhibit_modification_hooks, Qt);
5457 Ferase_buffer ();
5458 Finsert (1, &text);
5459 set_buffer_internal_1 (old_buffer);
5460
5461 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
5462 record_unwind_protect (unwind_create_tip_frame, frame);
5463
5464 5465 5466 5467
5468 f->terminal = dpyinfo->terminal;
5469 f->terminal->reference_count++;
5470 f->output_method = output_w32;
5471 f->output_data.w32 =
5472 (struct w32_output *) xmalloc (sizeof (struct w32_output));
5473 bzero (f->output_data.w32, sizeof (struct w32_output));
5474
5475 FRAME_FONTSET (f) = -1;
5476 f->icon_name = Qnil;
5477
5478 #if GLYPH_DEBUG
5479 image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount;
5480 dpyinfo_refcount = dpyinfo->reference_count;
5481 #endif
5482 FRAME_KBOARD (f) = kb;
5483 f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
5484 f->output_data.w32->explicit_parent = 0;
5485
5486 5487
5488 if (EQ (name, Qunbound) || NILP (name))
5489 {
5490 f->name = build_string (dpyinfo->w32_id_name);
5491 f->explicit_name = 0;
5492 }
5493 else
5494 {
5495 f->name = name;
5496 f->explicit_name = 1;
5497
5498 specbind (Qx_resource_name, name);
5499 }
5500
5501 f->resx = dpyinfo->resx;
5502 f->resy = dpyinfo->resy;
5503
5504 if (uniscribe_available)
5505 register_font_driver (&uniscribe_font_driver, f);
5506 register_font_driver (&w32font_driver, f);
5507
5508 x_default_parameter (f, parms, Qfont_backend, Qnil,
5509 "fontBackend", "FontBackend", RES_TYPE_STRING);
5510
5511 5512
5513 x_default_font_parameter (f, parms);
5514
5515 x_default_parameter (f, parms, Qborder_width, make_number (2),
5516 "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
5517 5518 5519
5520 if (NILP (Fassq (Qinternal_border_width, parms)))
5521 {
5522 Lisp_Object value;
5523
5524 value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
5525 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
5526 if (! EQ (value, Qunbound))
5527 parms = Fcons (Fcons (Qinternal_border_width, value),
5528 parms);
5529 }
5530 x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
5531 "internalBorderWidth", "internalBorderWidth",
5532 RES_TYPE_NUMBER);
5533
5534
5535 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
5536 "foreground", "Foreground", RES_TYPE_STRING);
5537 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
5538 "background", "Background", RES_TYPE_STRING);
5539 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
5540 "pointerColor", "Foreground", RES_TYPE_STRING);
5541 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
5542 "cursorColor", "Foreground", RES_TYPE_STRING);
5543 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
5544 "borderColor", "BorderColor", RES_TYPE_STRING);
5545
5546 5547 5548 5549 5550 5551
5552 init_frame_faces (f);
5553
5554 f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
5555 f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
5556
5557 window_prompting = x_figure_window_size (f, parms, 0);
5558
5559
5560 f->fringe_cols = 0;
5561 f->left_fringe_width = 0;
5562 f->right_fringe_width = 0;
5563
5564 BLOCK_INPUT;
5565 my_create_tip_window (f);
5566 UNBLOCK_INPUT;
5567
5568 x_make_gc (f);
5569
5570 x_default_parameter (f, parms, Qauto_raise, Qnil,
5571 "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5572 x_default_parameter (f, parms, Qauto_lower, Qnil,
5573 "autoLower", "AutoRaiseLower", RES_TYPE_BOOLEAN);
5574 x_default_parameter (f, parms, Qcursor_type, Qbox,
5575 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5576
5577 5578 5579
5580 width = FRAME_COLS (f);
5581 height = FRAME_LINES (f);
5582 FRAME_LINES (f) = 0;
5583 SET_FRAME_COLS (f, 0);
5584 change_frame_size (f, height, width, 1, 0, 0);
5585
5586
5587 if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
5588 Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
5589 Qnil));
5590
5591 5592 5593 5594 5595 5596 5597 5598
5599 {
5600 Lisp_Object bg = Fframe_parameter (frame, Qbackground_color);
5601 Lisp_Object fg = Fframe_parameter (frame, Qforeground_color);
5602 Lisp_Object colors = Qnil;
5603
5604
5605 tip_frame = frame;
5606 call2 (Qface_set_after_frame_default, frame, Qnil);
5607
5608 if (!EQ (bg, Fframe_parameter (frame, Qbackground_color)))
5609 colors = Fcons (Fcons (Qbackground_color, bg), colors);
5610 if (!EQ (fg, Fframe_parameter (frame, Qforeground_color)))
5611 colors = Fcons (Fcons (Qforeground_color, fg), colors);
5612
5613 if (!NILP (colors))
5614 Fmodify_frame_parameters (frame, colors);
5615 }
5616
5617 f->no_split = 1;
5618
5619 UNGCPRO;
5620
5621 5622 5623
5624 Vframe_list = Fcons (frame, Vframe_list);
5625
5626 5627
5628 FRAME_W32_DISPLAY_INFO (f)->reference_count++;
5629
5630 5631 5632 5633 5634
5635 face_change_count = face_change_count_before;
5636
5637
5638 return unbind_to (count, frame);
5639 }
5640
5641
5642 5643 5644 5645 5646
5647
5648 static void
5649 compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y)
5650 struct frame *f;
5651 Lisp_Object parms, dx, dy;
5652 int width, height;
5653 int *root_x, *root_y;
5654 {
5655 Lisp_Object left, top;
5656 int min_x, min_y, max_x, max_y;
5657
5658
5659 left = Fcdr (Fassq (Qleft, parms));
5660 top = Fcdr (Fassq (Qtop, parms));
5661
5662 5663
5664 if (!INTEGERP (left) || !INTEGERP (top))
5665 {
5666 POINT pt;
5667
5668
5669 min_x = 0;
5670 min_y = 0;
5671 max_x = x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f));
5672 max_y = x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f));
5673
5674 BLOCK_INPUT;
5675 GetCursorPos (&pt);
5676 *root_x = pt.x;
5677 *root_y = pt.y;
5678 UNBLOCK_INPUT;
5679
5680 5681 5682 5683 5684 5685
5686 if (monitor_from_point_fn && get_monitor_info_fn)
5687 {
5688 struct MONITOR_INFO info;
5689 HMONITOR monitor
5690 = monitor_from_point_fn (pt, MONITOR_DEFAULT_TO_NEAREST);
5691 info.cbSize = sizeof (info);
5692
5693 if (get_monitor_info_fn (monitor, &info))
5694 {
5695 min_x = info.rcWork.left;
5696 min_y = info.rcWork.top;
5697 max_x = info.rcWork.right;
5698 max_y = info.rcWork.bottom;
5699 }
5700 }
5701 }
5702
5703 if (INTEGERP (top))
5704 *root_y = XINT (top);
5705 else if (*root_y + XINT (dy) <= min_y)
5706 *root_y = min_y;
5707 else if (*root_y + XINT (dy) + height <= max_y)
5708
5709 *root_y += XINT (dy);
5710 else if (height + XINT (dy) + min_y <= *root_y)
5711
5712 *root_y -= height + XINT (dy);
5713 else
5714
5715 *root_y = min_y;
5716
5717 if (INTEGERP (left))
5718 *root_x = XINT (left);
5719 else if (*root_x + XINT (dx) <= min_x)
5720 *root_x = 0;
5721 else if (*root_x + XINT (dx) + width <= max_x)
5722
5723 *root_x += XINT (dx);
5724 else if (width + XINT (dx) + min_x <= *root_x)
5725
5726 *root_x -= width + XINT (dx);
5727 else
5728
5729 *root_x = min_x;
5730 }
5731
5732
5733 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
5734 doc: 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 )
5757 (string, frame, parms, timeout, dx, dy)
5758 Lisp_Object string, frame, parms, timeout, dx, dy;
5759 {
5760 struct frame *f;
5761 struct window *w;
5762 int root_x, root_y;
5763 struct buffer *old_buffer;
5764 struct text_pos pos;
5765 int i, width, height;
5766 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
5767 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5768 int count = SPECPDL_INDEX ();
5769
5770 specbind (Qinhibit_redisplay, Qt);
5771
5772 GCPRO4 (string, parms, frame, timeout);
5773
5774 CHECK_STRING (string);
5775 f = check_x_frame (frame);
5776 if (NILP (timeout))
5777 timeout = make_number (5);
5778 else
5779 CHECK_NATNUM (timeout);
5780
5781 if (NILP (dx))
5782 dx = make_number (5);
5783 else
5784 CHECK_NUMBER (dx);
5785
5786 if (NILP (dy))
5787 dy = make_number (-10);
5788 else
5789 CHECK_NUMBER (dy);
5790
5791 if (NILP (last_show_tip_args))
5792 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
5793
5794 if (!NILP (tip_frame))
5795 {
5796 Lisp_Object last_string = AREF (last_show_tip_args, 0);
5797 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
5798 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
5799
5800 if (EQ (frame, last_frame)
5801 && !NILP (Fequal (last_string, string))
5802 && !NILP (Fequal (last_parms, parms)))
5803 {
5804 struct frame *f = XFRAME (tip_frame);
5805
5806
5807 if (!NILP (tip_timer))
5808 {
5809 Lisp_Object timer = tip_timer;
5810 tip_timer = Qnil;
5811 call1 (Qcancel_timer, timer);
5812 }
5813
5814 BLOCK_INPUT;
5815 compute_tip_xy (f, parms, dx, dy, FRAME_PIXEL_WIDTH (f),
5816 FRAME_PIXEL_HEIGHT (f), &root_x, &root_y);
5817
5818
5819 SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
5820 root_x, root_y, 0, 0,
5821 SWP_NOSIZE | SWP_NOACTIVATE);
5822
5823
5824 SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOP,
5825 0, 0, 0, 0,
5826 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
5827
5828 UNBLOCK_INPUT;
5829 goto start_timer;
5830 }
5831 }
5832
5833
5834 Fx_hide_tip ();
5835
5836 ASET (last_show_tip_args, 0, string);
5837 ASET (last_show_tip_args, 1, frame);
5838 ASET (last_show_tip_args, 2, parms);
5839
5840
5841 if (NILP (Fassq (Qname, parms)))
5842 parms = Fcons (Fcons (Qname, build_string ("tooltip")), parms);
5843 if (NILP (Fassq (Qinternal_border_width, parms)))
5844 parms = Fcons (Fcons (Qinternal_border_width, make_number (3)), parms);
5845 if (NILP (Fassq (Qborder_width, parms)))
5846 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
5847 if (NILP (Fassq (Qborder_color, parms)))
5848 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
5849 if (NILP (Fassq (Qbackground_color, parms)))
5850 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
5851 parms);
5852
5853 5854
5855 BLOCK_INPUT;
5856
5857 5858
5859 frame = x_create_tip_frame (FRAME_W32_DISPLAY_INFO (f), parms, string);
5860 f = XFRAME (frame);
5861
5862
5863 w = XWINDOW (FRAME_ROOT_WINDOW (f));
5864 w->left_col = w->top_line = make_number (0);
5865
5866 if (CONSP (Vx_max_tooltip_size)
5867 && INTEGERP (XCAR (Vx_max_tooltip_size))
5868 && XINT (XCAR (Vx_max_tooltip_size)) > 0
5869 && INTEGERP (XCDR (Vx_max_tooltip_size))
5870 && XINT (XCDR (Vx_max_tooltip_size)) > 0)
5871 {
5872 w->total_cols = XCAR (Vx_max_tooltip_size);
5873 w->total_lines = XCDR (Vx_max_tooltip_size);
5874 }
5875 else
5876 {
5877 w->total_cols = make_number (80);
5878 w->total_lines = make_number (40);
5879 }
5880
5881 FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
5882 adjust_glyphs (f);
5883 w->pseudo_window_p = 1;
5884
5885
5886 old_buffer = current_buffer;
5887 set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
5888 current_buffer->truncate_lines = Qnil;
5889 clear_glyph_matrix (w->desired_matrix);
5890 clear_glyph_matrix (w->current_matrix);
5891 SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
5892 try_window (FRAME_ROOT_WINDOW (f), pos, 0);
5893
5894
5895 width = height = 0;
5896 for (i = 0; i < w->desired_matrix->nrows; ++i)
5897 {
5898 struct glyph_row *row = &w->desired_matrix->rows[i];
5899 struct glyph *last;
5900 int row_width;
5901
5902
5903 if (!row->enabled_p || !row->displays_text_p)
5904 break;
5905
5906
5907 row->full_width_p = 1;
5908
5909 #ifdef TODO 5910
5911 5912
5913 if (row->used[TEXT_AREA])
5914 {
5915 last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
5916 row_width = row->pixel_width - last->pixel_width;
5917 }
5918 else
5919 #endif
5920 row_width = row->pixel_width;
5921
5922
5923 height += row->height;
5924 width = max (width, row_width);
5925 }
5926
5927 5928
5929 height += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5930 width += 2 * FRAME_INTERNAL_BORDER_WIDTH (f);
5931
5932 5933
5934 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5935
5936 {
5937
5938 RECT rect;
5939 rect.left = rect.top = 0;
5940 rect.right = width;
5941 rect.bottom = height;
5942 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
5943 FRAME_EXTERNAL_MENU_BAR (f));
5944
5945 5946 5947 5948
5949 SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
5950 root_x, root_y, rect.right - rect.left + 3,
5951 rect.bottom - rect.top, SWP_NOACTIVATE);
5952
5953
5954 SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOP,
5955 0, 0, 0, 0,
5956 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
5957
5958
5959 f->async_visible = 1;
5960
5961 ShowWindow (FRAME_W32_WINDOW (f), SW_SHOWNOACTIVATE);
5962 }
5963
5964
5965 w->must_be_updated_p = 1;
5966 update_single_window (w, 1);
5967
5968 UNBLOCK_INPUT;
5969
5970
5971 set_buffer_internal_1 (old_buffer);
5972 windows_or_buffers_changed = old_windows_or_buffers_changed;
5973
5974 start_timer:
5975
5976 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
5977 intern ("x-hide-tip"));
5978
5979 UNGCPRO;
5980 return unbind_to (count, Qnil);
5981 }
5982
5983
5984 DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
5985 doc: 5986 )
5987 ()
5988 {
5989 int count;
5990 Lisp_Object deleted, frame, timer;
5991 struct gcpro gcpro1, gcpro2;
5992
5993
5994 if (NILP (tip_timer) && NILP (tip_frame))
5995 return Qnil;
5996
5997 frame = tip_frame;
5998 timer = tip_timer;
5999 GCPRO2 (frame, timer);
6000 tip_frame = tip_timer = deleted = Qnil;
6001
6002 count = SPECPDL_INDEX ();
6003 specbind (Qinhibit_redisplay, Qt);
6004 specbind (Qinhibit_quit, Qt);
6005
6006 if (!NILP (timer))
6007 call1 (Qcancel_timer, timer);
6008
6009 if (FRAMEP (frame))
6010 {
6011 delete_frame (frame, Qnil);
6012 deleted = Qt;
6013 }
6014
6015 UNGCPRO;
6016 return unbind_to (count, deleted);
6017 }
6018
6019
6020
6021 6022 6023
6024 extern Lisp_Object Qfile_name_history;
6025
6026 6027 6028 6029 6030
6031 UINT CALLBACK
6032 file_dialog_callback (hwnd, msg, wParam, lParam)
6033 HWND hwnd;
6034 UINT msg;
6035 WPARAM wParam;
6036 LPARAM lParam;
6037 {
6038 if (msg == WM_NOTIFY)
6039 {
6040 OFNOTIFY * notify = (OFNOTIFY *)lParam;
6041
6042 if (notify->hdr.code == CDN_TYPECHANGE
6043 || notify->hdr.code == CDN_INITDONE)
6044 {
6045 HWND dialog = GetParent (hwnd);
6046 HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
6047
6048
6049 if (notify->lpOFN->nFilterIndex == 2)
6050 {
6051 CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
6052 "Current Directory");
6053 EnableWindow (edit_control, FALSE);
6054 }
6055 else
6056 {
6057
6058 if (notify->hdr.code == CDN_TYPECHANGE)
6059 CommDlg_OpenSave_SetControlText (dialog,
6060 FILE_NAME_TEXT_FIELD, "");
6061 EnableWindow (edit_control, TRUE);
6062 }
6063 }
6064 }
6065 return 0;
6066 }
6067
6068 6069 6070 6071
6072 typedef struct
6073 {
6074 OPENFILENAME real_details;
6075 void * pReserved;
6076 DWORD dwReserved;
6077 DWORD FlagsEx;
6078 } NEWOPENFILENAME;
6079
6080
6081 DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
6082 doc: 6083 6084 6085 6086 )
6087 (prompt, dir, default_filename, mustmatch, only_dir_p)
6088 Lisp_Object prompt, dir, default_filename, mustmatch, only_dir_p;
6089 {
6090 struct frame *f = SELECTED_FRAME ();
6091 Lisp_Object file = Qnil;
6092 int count = SPECPDL_INDEX ();
6093 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
6094 char filename[MAX_PATH + 1];
6095 char init_dir[MAX_PATH + 1];
6096 int default_filter_index = 1;
6097
6098 GCPRO6 (prompt, dir, default_filename, mustmatch, only_dir_p, file);
6099 CHECK_STRING (prompt);
6100 CHECK_STRING (dir);
6101
6102 6103
6104 dir = Fexpand_file_name (dir, Qnil);
6105 strncpy (init_dir, SDATA (ENCODE_FILE (dir)), MAX_PATH);
6106 init_dir[MAX_PATH] = '\0';
6107 unixtodos_filename (init_dir);
6108
6109 if (STRINGP (default_filename))
6110 {
6111 char *file_name_only;
6112 char *full_path_name = SDATA (ENCODE_FILE (default_filename));
6113
6114 unixtodos_filename (full_path_name);
6115
6116 file_name_only = strrchr (full_path_name, '\\');
6117 if (!file_name_only)
6118 file_name_only = full_path_name;
6119 else
6120 file_name_only++;
6121
6122 strncpy (filename, file_name_only, MAX_PATH);
6123 filename[MAX_PATH] = '\0';
6124 }
6125 else
6126 filename[0] = '\0';
6127
6128 {
6129 NEWOPENFILENAME new_file_details;
6130 BOOL file_opened = FALSE;
6131 OPENFILENAME * file_details = &new_file_details.real_details;
6132
6133
6134 specbind (Qinhibit_redisplay, Qt);
6135 BLOCK_INPUT;
6136
6137 bzero (&new_file_details, sizeof (new_file_details));
6138 6139
6140 if (w32_major_version > 4 && w32_major_version < 95)
6141 file_details->lStructSize = sizeof (NEWOPENFILENAME);
6142 else
6143 file_details->lStructSize = sizeof (OPENFILENAME);
6144
6145 file_details->hwndOwner = FRAME_W32_WINDOW (f);
6146 6147
6148 file_details->lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0";
6149 file_details->lpstrFile = filename;
6150 file_details->nMaxFile = sizeof (filename);
6151 file_details->lpstrInitialDir = init_dir;
6152 file_details->lpstrTitle = SDATA (prompt);
6153
6154 if (! NILP (only_dir_p))
6155 default_filter_index = 2;
6156
6157 file_details->nFilterIndex = default_filter_index;
6158
6159 file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
6160 | OFN_EXPLORER | OFN_ENABLEHOOK);
6161 if (!NILP (mustmatch))
6162 {
6163
6164 file_details->Flags |= OFN_PATHMUSTEXIST;
6165
6166 if (NILP (only_dir_p))
6167 file_details->Flags |= OFN_FILEMUSTEXIST;
6168 }
6169
6170 file_details->lpfnHook = (LPOFNHOOKPROC) file_dialog_callback;
6171
6172 file_opened = GetOpenFileName (file_details);
6173
6174 UNBLOCK_INPUT;
6175
6176 if (file_opened)
6177 {
6178 dostounix_filename (filename);
6179
6180 if (file_details->nFilterIndex == 2)
6181 {
6182
6183 char * last = strrchr (filename, '/');
6184 *last = '\0';
6185 }
6186
6187 file = DECODE_FILE (build_string (filename));
6188 }
6189
6190 else if (!CommDlgExtendedError ())
6191 file = Qnil;
6192
6193 else
6194 file = Fcompleting_read (prompt, intern ("read-file-name-internal"),
6195 dir, mustmatch, dir, Qfile_name_history,
6196 default_filename, Qnil);
6197
6198 file = unbind_to (count, file);
6199 }
6200
6201 UNGCPRO;
6202
6203
6204 if (NILP (file))
6205 Fsignal (Qquit, Qnil);
6206
6207 return unbind_to (count, file);
6208 }
6209
6210
6211 6212
6213 DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
6214 Ssystem_move_file_to_trash, 1, 1, 0,
6215 doc: )
6216 (filename)
6217 Lisp_Object filename;
6218 {
6219 Lisp_Object handler;
6220 Lisp_Object encoded_file;
6221 Lisp_Object operation;
6222
6223 operation = Qdelete_file;
6224 if (!NILP (Ffile_directory_p (filename))
6225 && NILP (Ffile_symlink_p (filename)))
6226 {
6227 operation = intern ("delete-directory");
6228 filename = Fdirectory_file_name (filename);
6229 }
6230 filename = Fexpand_file_name (filename, Qnil);
6231
6232 handler = Ffind_file_name_handler (filename, operation);
6233 if (!NILP (handler))
6234 return call2 (handler, operation, filename);
6235
6236 encoded_file = ENCODE_FILE (filename);
6237
6238 {
6239 const char * path;
6240 SHFILEOPSTRUCT file_op;
6241 char tmp_path[MAX_PATH + 1];
6242
6243 path = map_w32_filename (SDATA (encoded_file), NULL);
6244
6245
6246 _chmod (path, 0666);
6247
6248 bzero (tmp_path, sizeof (tmp_path));
6249 strcpy (tmp_path, path);
6250
6251 bzero (&file_op, sizeof (file_op));
6252 file_op.hwnd = HWND_DESKTOP;
6253 file_op.wFunc = FO_DELETE;
6254 file_op.pFrom = tmp_path;
6255 file_op.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO
6256 | FOF_NOERRORUI | FOF_NO_CONNECTED_ELEMENTS;
6257 file_op.fAnyOperationsAborted = FALSE;
6258
6259 if (SHFileOperation (&file_op) != 0)
6260 report_file_error ("Removing old name", list1 (filename));
6261 }
6262 return Qnil;
6263 }
6264
6265
6266 6267 6268
6269
6270 DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
6271 Sw32_send_sys_command, 1, 2, 0,
6272 doc: 6273 6274 6275 6276 6277 6278 )
6279 (command, frame)
6280 Lisp_Object command, frame;
6281 {
6282 FRAME_PTR f = check_x_frame (frame);
6283
6284 CHECK_NUMBER (command);
6285
6286 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0);
6287
6288 return Qnil;
6289 }
6290
6291 DEFUN ("w32-shell-execute", Fw32_shell_execute, Sw32_shell_execute, 2, 4, 0,
6292 doc: 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 )
6333 (operation, document, parameters, show_flag)
6334 Lisp_Object operation, document, parameters, show_flag;
6335 {
6336 Lisp_Object current_dir;
6337 char *errstr;
6338
6339 CHECK_STRING (document);
6340
6341
6342 current_dir = ENCODE_FILE (current_buffer->directory);
6343 document = ENCODE_FILE (document);
6344 if (STRINGP (parameters))
6345 parameters = ENCODE_SYSTEM (parameters);
6346
6347 if ((int) ShellExecute (NULL,
6348 (STRINGP (operation) ?
6349 SDATA (operation) : NULL),
6350 SDATA (document),
6351 (STRINGP (parameters) ?
6352 SDATA (parameters) : NULL),
6353 SDATA (current_dir),
6354 (INTEGERP (show_flag) ?
6355 XINT (show_flag) : SW_SHOWDEFAULT))
6356 > 32)
6357 return Qt;
6358 errstr = w32_strerror (0);
6359
6360 if (!NILP (Vlocale_coding_system))
6361 {
6362 Lisp_Object decoded =
6363 code_convert_string_norecord (make_unibyte_string (errstr,
6364 strlen (errstr)),
6365 Vlocale_coding_system, 0);
6366 errstr = (char *)SDATA (decoded);
6367 }
6368 error ("ShellExecute failed: %s", errstr);
6369 }
6370
6371 6372 6373
6374 static int
6375 lookup_vk_code (char *key)
6376 {
6377 int i;
6378
6379 for (i = 0; i < 256; i++)
6380 if (lispy_function_keys[i]
6381 && strcmp (lispy_function_keys[i], key) == 0)
6382 return i;
6383
6384 return -1;
6385 }
6386
6387 6388
6389 static Lisp_Object
6390 w32_parse_hot_key (key)
6391 Lisp_Object key;
6392 {
6393
6394 register Lisp_Object c;
6395 int vk_code;
6396 int lisp_modifiers;
6397 int w32_modifiers;
6398 struct gcpro gcpro1;
6399
6400 CHECK_VECTOR (key);
6401
6402 if (XFASTINT (Flength (key)) != 1)
6403 return Qnil;
6404
6405 GCPRO1 (key);
6406
6407 c = Faref (key, make_number (0));
6408
6409 if (CONSP (c) && lucid_event_type_list_p (c))
6410 c = Fevent_convert_list (c);
6411
6412 UNGCPRO;
6413
6414 if (! INTEGERP (c) && ! SYMBOLP (c))
6415 error ("Key definition is invalid");
6416
6417
6418 if (SYMBOLP (c))
6419 {
6420 c = parse_modifiers (c);
6421 lisp_modifiers = XINT (Fcar (Fcdr (c)));
6422 c = Fcar (c);
6423 if (!SYMBOLP (c))
6424 abort ();
6425 vk_code = lookup_vk_code (SDATA (SYMBOL_NAME (c)));
6426 }
6427 else if (INTEGERP (c))
6428 {
6429 lisp_modifiers = XINT (c) & ~CHARACTERBITS;
6430
6431 vk_code = XINT (c) & CHARACTERBITS;
6432 }
6433
6434 if (vk_code < 0 || vk_code > 255)
6435 return Qnil;
6436
6437 if ((lisp_modifiers & meta_modifier) != 0
6438 && !NILP (Vw32_alt_is_meta))
6439 lisp_modifiers |= alt_modifier;
6440
6441
6442 #ifndef MOD_ALT
6443 #define MOD_ALT 0x0001
6444 #define MOD_CONTROL 0x0002
6445 #define MOD_SHIFT 0x0004
6446 #define MOD_WIN 0x0008
6447 #endif
6448
6449
6450 w32_modifiers = (lisp_modifiers & hyper_modifier) ? MOD_WIN : 0;
6451 w32_modifiers |= (lisp_modifiers & alt_modifier) ? MOD_ALT : 0;
6452 w32_modifiers |= (lisp_modifiers & ctrl_modifier) ? MOD_CONTROL : 0;
6453 w32_modifiers |= (lisp_modifiers & shift_modifier) ? MOD_SHIFT : 0;
6454
6455 return HOTKEY (vk_code, w32_modifiers);
6456 }
6457
6458 DEFUN ("w32-register-hot-key", Fw32_register_hot_key,
6459 Sw32_register_hot_key, 1, 1, 0,
6460 doc: 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 )
6472 (key)
6473 Lisp_Object key;
6474 {
6475 key = w32_parse_hot_key (key);
6476
6477 if (!NILP (key) && NILP (Fmemq (key, w32_grabbed_keys)))
6478 {
6479
6480 Lisp_Object item = Fmemq (Qnil, w32_grabbed_keys);
6481
6482
6483 if (NILP (item))
6484 w32_grabbed_keys = Fcons (key, w32_grabbed_keys);
6485 else
6486 XSETCAR (item, key);
6487
6488 6489
6490 #ifdef USE_LISP_UNION_TYPE
6491 PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
6492 (WPARAM) key.i, 0);
6493 #else
6494 PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
6495 (WPARAM) key, 0);
6496 #endif
6497 }
6498
6499 return key;
6500 }
6501
6502 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
6503 Sw32_unregister_hot_key, 1, 1, 0,
6504 doc: )
6505 (key)
6506 Lisp_Object key;
6507 {
6508 Lisp_Object item;
6509
6510 if (!INTEGERP (key))
6511 key = w32_parse_hot_key (key);
6512
6513 item = Fmemq (key, w32_grabbed_keys);
6514
6515 if (!NILP (item))
6516 {
6517 6518
6519 #ifdef USE_LISP_UNION_TYPE
6520 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
6521 (WPARAM) XINT (XCAR (item)), (LPARAM) item.i))
6522 #else
6523 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_UNREGISTER_HOT_KEY,
6524 (WPARAM) XINT (XCAR (item)), (LPARAM) item))
6525 #endif
6526 {
6527 MSG msg;
6528 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
6529 }
6530 return Qt;
6531 }
6532 return Qnil;
6533 }
6534
6535 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys,
6536 Sw32_registered_hot_keys, 0, 0, 0,
6537 doc: )
6538 ()
6539 {
6540 return Fdelq (Qnil, Fcopy_sequence (w32_grabbed_keys));
6541 }
6542
6543 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key,
6544 Sw32_reconstruct_hot_key, 1, 1, 0,
6545 doc: 6546 )
6547 (hotkeyid)
6548 Lisp_Object hotkeyid;
6549 {
6550 int vk_code, w32_modifiers;
6551 Lisp_Object key;
6552
6553 CHECK_NUMBER (hotkeyid);
6554
6555 vk_code = HOTKEY_VK_CODE (hotkeyid);
6556 w32_modifiers = HOTKEY_MODIFIERS (hotkeyid);
6557
6558 if (vk_code < 256 && lispy_function_keys[vk_code])
6559 key = intern (lispy_function_keys[vk_code]);
6560 else
6561 key = make_number (vk_code);
6562
6563 key = Fcons (key, Qnil);
6564 if (w32_modifiers & MOD_SHIFT)
6565 key = Fcons (Qshift, key);
6566 if (w32_modifiers & MOD_CONTROL)
6567 key = Fcons (Qctrl, key);
6568 if (w32_modifiers & MOD_ALT)
6569 key = Fcons (NILP (Vw32_alt_is_meta) ? Qalt : Qmeta, key);
6570 if (w32_modifiers & MOD_WIN)
6571 key = Fcons (Qhyper, key);
6572
6573 return key;
6574 }
6575
6576 DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key,
6577 Sw32_toggle_lock_key, 1, 2, 0,
6578 doc: 6579 6580 6581 )
6582 (key, new_state)
6583 Lisp_Object key, new_state;
6584 {
6585 int vk_code;
6586
6587 if (EQ (key, intern ("capslock")))
6588 vk_code = VK_CAPITAL;
6589 else if (EQ (key, intern ("kp-numlock")))
6590 vk_code = VK_NUMLOCK;
6591 else if (EQ (key, intern ("scroll")))
6592 vk_code = VK_SCROLL;
6593 else
6594 return Qnil;
6595
6596 if (!dwWindowsThreadId)
6597 return make_number (w32_console_toggle_lock_key (vk_code, new_state));
6598
6599 #ifdef USE_LISP_UNION_TYPE
6600 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
6601 (WPARAM) vk_code, (LPARAM) new_state.i))
6602 #else
6603 if (PostThreadMessage (dwWindowsThreadId, WM_EMACS_TOGGLE_LOCK_KEY,
6604 (WPARAM) vk_code, (LPARAM) new_state))
6605 #endif
6606 {
6607 MSG msg;
6608 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
6609 return make_number (msg.wParam);
6610 }
6611 return Qnil;
6612 }
6613
6614 DEFUN ("w32-window-exists-p", Fw32_window_exists_p, Sw32_window_exists_p,
6615 2, 2, 0,
6616 doc: 6617 6618 )
6619 (class, name)
6620 Lisp_Object class, name;
6621 {
6622 HWND hnd;
6623
6624 if (!NILP (class))
6625 CHECK_STRING (class);
6626 if (!NILP (name))
6627 CHECK_STRING (name);
6628
6629 hnd = FindWindow (STRINGP (class) ? ((LPCTSTR) SDATA (class)) : NULL,
6630 STRINGP (name) ? ((LPCTSTR) SDATA (name)) : NULL);
6631 if (!hnd)
6632 return Qnil;
6633 return Qt;
6634 }
6635
6636 DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
6637 doc: 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 )
6649 ()
6650 {
6651 Lisp_Object status = Qnil;
6652
6653 SYSTEM_POWER_STATUS system_status;
6654 if (GetSystemPowerStatus (&system_status))
6655 {
6656 Lisp_Object line_status, battery_status, battery_status_symbol;
6657 Lisp_Object load_percentage, seconds, minutes, hours, remain;
6658 Lisp_Object sequences[8];
6659
6660 long seconds_left = (long) system_status.BatteryLifeTime;
6661
6662 if (system_status.ACLineStatus == 0)
6663 line_status = build_string ("off-line");
6664 else if (system_status.ACLineStatus == 1)
6665 line_status = build_string ("on-line");
6666 else
6667 line_status = build_string ("N/A");
6668
6669 if (system_status.BatteryFlag & 128)
6670 {
6671 battery_status = build_string ("N/A");
6672 battery_status_symbol = empty_unibyte_string;
6673 }
6674 else if (system_status.BatteryFlag & 8)
6675 {
6676 battery_status = build_string ("charging");
6677 battery_status_symbol = build_string ("+");
6678 if (system_status.BatteryFullLifeTime != -1L)
6679 seconds_left = system_status.BatteryFullLifeTime - seconds_left;
6680 }
6681 else if (system_status.BatteryFlag & 4)
6682 {
6683 battery_status = build_string ("critical");
6684 battery_status_symbol = build_string ("!");
6685 }
6686 else if (system_status.BatteryFlag & 2)
6687 {
6688 battery_status = build_string ("low");
6689 battery_status_symbol = build_string ("-");
6690 }
6691 else if (system_status.BatteryFlag & 1)
6692 {
6693 battery_status = build_string ("high");
6694 battery_status_symbol = empty_unibyte_string;
6695 }
6696 else
6697 {
6698 battery_status = build_string ("medium");
6699 battery_status_symbol = empty_unibyte_string;
6700 }
6701
6702 if (system_status.BatteryLifePercent > 100)
6703 load_percentage = build_string ("N/A");
6704 else
6705 {
6706 char buffer[16];
6707 _snprintf (buffer, 16, "%d", system_status.BatteryLifePercent);
6708 load_percentage = build_string (buffer);
6709 }
6710
6711 if (seconds_left < 0)
6712 seconds = minutes = hours = remain = build_string ("N/A");
6713 else
6714 {
6715 long m;
6716 float h;
6717 char buffer[16];
6718 _snprintf (buffer, 16, "%ld", seconds_left);
6719 seconds = build_string (buffer);
6720
6721 m = seconds_left / 60;
6722 _snprintf (buffer, 16, "%ld", m);
6723 minutes = build_string (buffer);
6724
6725 h = seconds_left / 3600.0;
6726 _snprintf (buffer, 16, "%3.1f", h);
6727 hours = build_string (buffer);
6728
6729 _snprintf (buffer, 16, "%ld:%02ld", m / 60, m % 60);
6730 remain = build_string (buffer);
6731 }
6732 sequences[0] = Fcons (make_number ('L'), line_status);
6733 sequences[1] = Fcons (make_number ('B'), battery_status);
6734 sequences[2] = Fcons (make_number ('b'), battery_status_symbol);
6735 sequences[3] = Fcons (make_number ('p'), load_percentage);
6736 sequences[4] = Fcons (make_number ('s'), seconds);
6737 sequences[5] = Fcons (make_number ('m'), minutes);
6738 sequences[6] = Fcons (make_number ('h'), hours);
6739 sequences[7] = Fcons (make_number ('t'), remain);
6740
6741 status = Flist (8, sequences);
6742 }
6743 return status;
6744 }
6745
6746
6747 DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
6748 doc: 6749 6750 6751 6752 )
6753 (filename)
6754 Lisp_Object filename;
6755 {
6756 Lisp_Object encoded, value;
6757
6758 CHECK_STRING (filename);
6759 filename = Fexpand_file_name (filename, Qnil);
6760 encoded = ENCODE_FILE (filename);
6761
6762 value = Qnil;
6763
6764 6765 6766 6767 6768
6769 {
6770 HMODULE hKernel = GetModuleHandle ("kernel32");
6771 BOOL (*pfn_GetDiskFreeSpaceEx)
6772 (char *, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)
6773 = (void *) GetProcAddress (hKernel, "GetDiskFreeSpaceEx");
6774
6775 6776
6777 char rootname[MAX_PATH];
6778 char *name = SDATA (encoded);
6779
6780
6781 if (isalpha (name[0]) && name[1] == ':')
6782 {
6783 rootname[0] = name[0];
6784 rootname[1] = name[1];
6785 rootname[2] = '\\';
6786 rootname[3] = 0;
6787 }
6788 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
6789 {
6790 char *str = rootname;
6791 int slashes = 4;
6792 do
6793 {
6794 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
6795 break;
6796 *str++ = *name++;
6797 }
6798 while ( *name );
6799
6800 *str++ = '\\';
6801 *str = 0;
6802 }
6803
6804 if (pfn_GetDiskFreeSpaceEx)
6805 {
6806 6807
6808 LARGE_INTEGER availbytes;
6809 LARGE_INTEGER freebytes;
6810 LARGE_INTEGER totalbytes;
6811
6812 if (pfn_GetDiskFreeSpaceEx (rootname,
6813 (ULARGE_INTEGER *)&availbytes,
6814 (ULARGE_INTEGER *)&totalbytes,
6815 (ULARGE_INTEGER *)&freebytes))
6816 value = list3 (make_float ((double) totalbytes.QuadPart),
6817 make_float ((double) freebytes.QuadPart),
6818 make_float ((double) availbytes.QuadPart));
6819 }
6820 else
6821 {
6822 DWORD sectors_per_cluster;
6823 DWORD bytes_per_sector;
6824 DWORD free_clusters;
6825 DWORD total_clusters;
6826
6827 if (GetDiskFreeSpace (rootname,
6828 §ors_per_cluster,
6829 &bytes_per_sector,
6830 &free_clusters,
6831 &total_clusters))
6832 value = list3 (make_float ((double) total_clusters
6833 * sectors_per_cluster * bytes_per_sector),
6834 make_float ((double) free_clusters
6835 * sectors_per_cluster * bytes_per_sector),
6836 make_float ((double) free_clusters
6837 * sectors_per_cluster * bytes_per_sector));
6838 }
6839 }
6840
6841 return value;
6842 }
6843
6844 DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
6845 0, 0, 0, doc: )
6846 ()
6847 {
6848 static char pname_buf[256];
6849 int err;
6850 HANDLE hPrn;
6851 PRINTER_INFO_2 *ppi2 = NULL;
6852 DWORD dwNeeded = 0, dwReturned = 0;
6853
6854 6855 6856
6857 if (GetProfileString ("windows", "device", ",,", pname_buf, sizeof (pname_buf)) <= 0)
6858 return Qnil;
6859
6860 strtok (pname_buf, ",");
6861
6862 if (!OpenPrinter (pname_buf, &hPrn, NULL))
6863 return Qnil;
6864 GetPrinter (hPrn, 2, NULL, 0, &dwNeeded);
6865 if (dwNeeded == 0)
6866 {
6867 ClosePrinter (hPrn);
6868 return Qnil;
6869 }
6870
6871 ppi2 = (PRINTER_INFO_2 *) xmalloc (dwNeeded);
6872 if (!ppi2)
6873 {
6874 ClosePrinter (hPrn);
6875 return Qnil;
6876 }
6877
6878 err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned);
6879 ClosePrinter (hPrn);
6880 if (!err)
6881 {
6882 xfree (ppi2);
6883 return Qnil;
6884 }
6885
6886 if (ppi2)
6887 {
6888 if (ppi2->Attributes & PRINTER_ATTRIBUTE_SHARED && ppi2->pServerName)
6889 {
6890
6891 if (*ppi2->pServerName == '\\')
6892 _snprintf (pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName,
6893 ppi2->pShareName);
6894 else
6895 _snprintf (pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName,
6896 ppi2->pShareName);
6897 pname_buf[sizeof (pname_buf) - 1] = '\0';
6898 }
6899 else
6900 {
6901
6902 strncpy (pname_buf, ppi2->pPortName, sizeof (pname_buf));
6903 pname_buf[sizeof (pname_buf) - 1] = '\0';
6904 6905
6906 strtok (pname_buf, ",");
6907 }
6908 xfree (ppi2);
6909 }
6910
6911 return build_string (pname_buf);
6912 }
6913
6914 6915 6916
6917
6918 6919
6920
6921 frame_parm_handler w32_frame_parm_handlers[] =
6922 {
6923 x_set_autoraise,
6924 x_set_autolower,
6925 x_set_background_color,
6926 x_set_border_color,
6927 x_set_border_width,
6928 x_set_cursor_color,
6929 x_set_cursor_type,
6930 x_set_font,
6931 x_set_foreground_color,
6932 x_set_icon_name,
6933 x_set_icon_type,
6934 x_set_internal_border_width,
6935 x_set_menu_bar_lines,
6936 x_set_mouse_color,
6937 x_explicitly_set_name,
6938 x_set_scroll_bar_width,
6939 x_set_title,
6940 x_set_unsplittable,
6941 x_set_vertical_scroll_bars,
6942 x_set_visibility,
6943 x_set_tool_bar_lines,
6944 0,
6945 0,
6946 x_set_screen_gamma,
6947 x_set_line_spacing,
6948 x_set_fringe_width,
6949 x_set_fringe_width,
6950 0,
6951 x_set_fullscreen,
6952 x_set_font_backend,
6953 x_set_alpha,
6954 0,
6955 };
6956
6957 void
6958 syms_of_w32fns ()
6959 {
6960 globals_of_w32fns ();
6961
6962 w32_in_use = 0;
6963 track_mouse_window = NULL;
6964
6965 w32_visible_system_caret_hwnd = NULL;
6966
6967 DEFSYM (Qnone, "none");
6968 DEFSYM (Qsuppress_icon, "suppress-icon");
6969 DEFSYM (Qundefined_color, "undefined-color");
6970 DEFSYM (Qcancel_timer, "cancel-timer");
6971 DEFSYM (Qhyper, "hyper");
6972 DEFSYM (Qsuper, "super");
6973 DEFSYM (Qmeta, "meta");
6974 DEFSYM (Qalt, "alt");
6975 DEFSYM (Qctrl, "ctrl");
6976 DEFSYM (Qcontrol, "control");
6977 DEFSYM (Qshift, "shift");
6978 DEFSYM (Qfont_param, "font-parameter");
6979
6980
6981
6982 Vtext_property_default_nonsticky
6983 = Fcons (Fcons (Qdisplay, Qt), Vtext_property_default_nonsticky);
6984
6985
6986 Fput (Qundefined_color, Qerror_conditions,
6987 pure_cons (Qundefined_color, pure_cons (Qerror, Qnil)));
6988 Fput (Qundefined_color, Qerror_message,
6989 make_pure_c_string ("Undefined color"));
6990
6991 staticpro (&w32_grabbed_keys);
6992 w32_grabbed_keys = Qnil;
6993
6994 DEFVAR_LISP ("w32-color-map", &Vw32_color_map,
6995 doc: );
6996 Vw32_color_map = Qnil;
6997
6998 DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system,
6999 doc: 7000 7001 7002 );
7003 Vw32_pass_alt_to_system = Qnil;
7004
7005 DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta,
7006 doc: 7007 );
7008 Vw32_alt_is_meta = Qt;
7009
7010 DEFVAR_INT ("w32-quit-key", &w32_quit_key,
7011 doc: );
7012 w32_quit_key = 0;
7013
7014 DEFVAR_LISP ("w32-pass-lwindow-to-system",
7015 &Vw32_pass_lwindow_to_system,
7016 doc: 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 );
7027 Vw32_pass_lwindow_to_system = Qt;
7028
7029 DEFVAR_LISP ("w32-pass-rwindow-to-system",
7030 &Vw32_pass_rwindow_to_system,
7031 doc: 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 );
7042 Vw32_pass_rwindow_to_system = Qt;
7043
7044 DEFVAR_LISP ("w32-phantom-key-code",
7045 &Vw32_phantom_key_code,
7046 doc: 7047 7048 7049 7050 7051 );
7052 7053
7054 XSETINT (Vw32_phantom_key_code, 255);
7055
7056 DEFVAR_LISP ("w32-enable-num-lock",
7057 &Vw32_enable_num_lock,
7058 doc: 7059 );
7060 Vw32_enable_num_lock = Qt;
7061
7062 DEFVAR_LISP ("w32-enable-caps-lock",
7063 &Vw32_enable_caps_lock,
7064 doc: 7065 );
7066 Vw32_enable_caps_lock = Qt;
7067
7068 DEFVAR_LISP ("w32-scroll-lock-modifier",
7069 &Vw32_scroll_lock_modifier,
7070 doc: 7071 7072 7073 );
7074 Vw32_scroll_lock_modifier = Qnil;
7075
7076 DEFVAR_LISP ("w32-lwindow-modifier",
7077 &Vw32_lwindow_modifier,
7078 doc: 7079 7080 7081 );
7082 Vw32_lwindow_modifier = Qnil;
7083
7084 DEFVAR_LISP ("w32-rwindow-modifier",
7085 &Vw32_rwindow_modifier,
7086 doc: 7087 7088 7089 );
7090 Vw32_rwindow_modifier = Qnil;
7091
7092 DEFVAR_LISP ("w32-apps-modifier",
7093 &Vw32_apps_modifier,
7094 doc: 7095 7096 7097 );
7098 Vw32_apps_modifier = Qnil;
7099
7100 DEFVAR_BOOL ("w32-enable-synthesized-fonts", &w32_enable_synthesized_fonts,
7101 doc: );
7102 w32_enable_synthesized_fonts = 0;
7103
7104 DEFVAR_LISP ("w32-enable-palette", &Vw32_enable_palette,
7105 doc: );
7106 Vw32_enable_palette = Qt;
7107
7108 DEFVAR_INT ("w32-mouse-button-tolerance",
7109 &w32_mouse_button_tolerance,
7110 doc: 7111 7112 7113 7114 );
7115 w32_mouse_button_tolerance = GetDoubleClickTime () / 2;
7116
7117 DEFVAR_INT ("w32-mouse-move-interval",
7118 &w32_mouse_move_interval,
7119 doc: 7120 7121 7122 );
7123 w32_mouse_move_interval = 0;
7124
7125 DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
7126 &w32_pass_extra_mouse_buttons_to_system,
7127 doc: 7128 7129 7130 7131 7132 );
7133 w32_pass_extra_mouse_buttons_to_system = 0;
7134
7135 DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
7136 &w32_pass_multimedia_buttons_to_system,
7137 doc: 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 );
7156 w32_pass_multimedia_buttons_to_system = 1;
7157
7158 #if 0
7159 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
7160 doc: 7161 7162 );
7163 Vx_pointer_shape = Qnil;
7164
7165 Vx_nontext_pointer_shape = Qnil;
7166
7167 Vx_mode_pointer_shape = Qnil;
7168
7169 DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
7170 doc: 7171 7172 );
7173 Vx_hourglass_pointer_shape = Qnil;
7174
7175 DEFVAR_LISP ("x-sensitive-text-pointer-shape",
7176 &Vx_sensitive_text_pointer_shape,
7177 doc: 7178 7179 );
7180 Vx_sensitive_text_pointer_shape = Qnil;
7181
7182 DEFVAR_LISP ("x-window-horizontal-drag-cursor",
7183 &Vx_window_horizontal_drag_shape,
7184 doc: 7185 7186 );
7187 Vx_window_horizontal_drag_shape = Qnil;
7188 #endif
7189
7190 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
7191 doc: );
7192 Vx_cursor_fore_pixel = Qnil;
7193
7194 DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
7195 doc: 7196 );
7197 Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
7198
7199 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
7200 doc: 7201 7202 );
7203 7204
7205 Vx_no_window_manager = Qnil;
7206
7207 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
7208 &Vx_pixel_size_width_font_regexp,
7209 doc: 7210 7211 7212 7213 7214 );
7215 Vx_pixel_size_width_font_regexp = Qnil;
7216
7217 DEFVAR_LISP ("w32-bdf-filename-alist",
7218 &Vw32_bdf_filename_alist,
7219 doc: );
7220 Vw32_bdf_filename_alist = Qnil;
7221
7222 DEFVAR_BOOL ("w32-strict-fontnames",
7223 &w32_strict_fontnames,
7224 doc: 7225 7226 7227 7228 7229 );
7230 w32_strict_fontnames = 0;
7231
7232 DEFVAR_BOOL ("w32-strict-painting",
7233 &w32_strict_painting,
7234 doc: 7235 7236 );
7237 w32_strict_painting = 1;
7238
7239 #if 0
7240 defsubr (&Sx_change_window_property);
7241 defsubr (&Sx_delete_window_property);
7242 defsubr (&Sx_window_property);
7243 #endif
7244 defsubr (&Sxw_display_color_p);
7245 defsubr (&Sx_display_grayscale_p);
7246 defsubr (&Sxw_color_defined_p);
7247 defsubr (&Sxw_color_values);
7248 defsubr (&Sx_server_max_request_size);
7249 defsubr (&Sx_server_vendor);
7250 defsubr (&Sx_server_version);
7251 defsubr (&Sx_display_pixel_width);
7252 defsubr (&Sx_display_pixel_height);
7253 defsubr (&Sx_display_mm_width);
7254 defsubr (&Sx_display_mm_height);
7255 defsubr (&Sx_display_screens);
7256 defsubr (&Sx_display_planes);
7257 defsubr (&Sx_display_color_cells);
7258 defsubr (&Sx_display_visual_class);
7259 defsubr (&Sx_display_backing_store);
7260 defsubr (&Sx_display_save_under);
7261 defsubr (&Sx_create_frame);
7262 defsubr (&Sx_open_connection);
7263 defsubr (&Sx_close_connection);
7264 defsubr (&Sx_display_list);
7265 defsubr (&Sx_synchronize);
7266 defsubr (&Sx_focus_frame);
7267
7268
7269
7270 defsubr (&Sw32_define_rgb_color);
7271 defsubr (&Sw32_default_color_map);
7272 defsubr (&Sw32_send_sys_command);
7273 defsubr (&Sw32_shell_execute);
7274 defsubr (&Sw32_register_hot_key);
7275 defsubr (&Sw32_unregister_hot_key);
7276 defsubr (&Sw32_registered_hot_keys);
7277 defsubr (&Sw32_reconstruct_hot_key);
7278 defsubr (&Sw32_toggle_lock_key);
7279 defsubr (&Sw32_window_exists_p);
7280 defsubr (&Sw32_battery_status);
7281
7282 defsubr (&Sfile_system_info);
7283 defsubr (&Sdefault_printer_name);
7284
7285 check_window_system_func = check_w32;
7286
7287
7288 hourglass_timer = 0;
7289 hourglass_hwnd = NULL;
7290
7291 defsubr (&Sx_show_tip);
7292 defsubr (&Sx_hide_tip);
7293 tip_timer = Qnil;
7294 staticpro (&tip_timer);
7295 tip_frame = Qnil;
7296 staticpro (&tip_frame);
7297
7298 last_show_tip_args = Qnil;
7299 staticpro (&last_show_tip_args);
7300
7301 defsubr (&Sx_file_dialog);
7302 defsubr (&Ssystem_move_file_to_trash);
7303 }
7304
7305
7306 7307 7308 7309 7310 7311 7312 7313
7314 void
7315 globals_of_w32fns ()
7316 {
7317 HMODULE user32_lib = GetModuleHandle ("user32.dll");
7318 7319 7320 7321
7322 track_mouse_event_fn = (TrackMouseEvent_Proc)
7323 GetProcAddress (user32_lib, "TrackMouseEvent");
7324
7325 clipboard_sequence_fn = (ClipboardSequence_Proc)
7326 GetProcAddress (user32_lib, "GetClipboardSequenceNumber");
7327
7328 monitor_from_point_fn = (MonitorFromPoint_Proc)
7329 GetProcAddress (user32_lib, "MonitorFromPoint");
7330 get_monitor_info_fn = (GetMonitorInfo_Proc)
7331 GetProcAddress (user32_lib, "GetMonitorInfoA");
7332
7333 {
7334 HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
7335 get_composition_string_fn = (ImmGetCompositionString_Proc)
7336 GetProcAddress (imm32_lib, "ImmGetCompositionStringW");
7337 get_ime_context_fn = (ImmGetContext_Proc)
7338 GetProcAddress (imm32_lib, "ImmGetContext");
7339 release_ime_context_fn = (ImmReleaseContext_Proc)
7340 GetProcAddress (imm32_lib, "ImmReleaseContext");
7341 set_ime_composition_window_fn = (ImmSetCompositionWindow_Proc)
7342 GetProcAddress (imm32_lib, "ImmSetCompositionWindow");
7343 }
7344 DEFVAR_INT ("w32-ansi-code-page",
7345 &w32_ansi_code_page,
7346 doc: );
7347 w32_ansi_code_page = GetACP ();
7348
7349
7350 InitCommonControls ();
7351
7352 syms_of_w32uniscribe ();
7353 }
7354
7355 #undef abort
7356
7357 void
7358 w32_abort ()
7359 {
7360 int button;
7361 button = MessageBox (NULL,
7362 "A fatal error has occurred!\n\n"
7363 "Would you like to attach a debugger?\n\n"
7364 "Select YES to debug, NO to abort Emacs"
7365 #if __GNUC__
7366 "\n\n(type \"gdb -p <emacs-PID>\" and\n"
7367 "\"continue\" inside GDB before clicking YES.)"
7368 #endif
7369 , "Emacs Abort Dialog",
7370 MB_ICONEXCLAMATION | MB_TASKMODAL
7371 | MB_SETFOREGROUND | MB_YESNO);
7372 switch (button)
7373 {
7374 case IDYES:
7375 DebugBreak ();
7376 exit (2);
7377 case IDNO:
7378 default:
7379 abort ();
7380 break;
7381 }
7382 }
7383
7384
7385 int
7386 w32_last_error ()
7387 {
7388 return GetLastError ();
7389 }
7390
7391 7392