1 /* Graphical user interface functions for the Microsoft W32 API.
2 Copyright (C) 1989, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Added by Kevin Gallo */
37 #include "dispextern.h"
39 #include "blockinput.h"
42 #include "termhooks.h"
49 extern void free_frame_menubar ();
50 extern struct scroll_bar
*x_window_to_scroll_bar ();
53 extern char *lispy_function_keys
[];
55 /* The colormap for converting color names to RGB values */
56 Lisp_Object Vw32_color_map
;
58 /* Non nil if alt key presses are passed on to Windows. */
59 Lisp_Object Vw32_pass_alt_to_system
;
61 /* Non nil if alt key is translated to meta_modifier, nil if it is translated
63 Lisp_Object Vw32_alt_is_meta
;
65 /* Non nil if left window key events are passed on to Windows (this only
66 affects whether "tapping" the key opens the Start menu). */
67 Lisp_Object Vw32_pass_lwindow_to_system
;
69 /* Non nil if right window key events are passed on to Windows (this
70 only affects whether "tapping" the key opens the Start menu). */
71 Lisp_Object Vw32_pass_rwindow_to_system
;
73 /* Modifier associated with the left "Windows" key, or nil to act as a
75 Lisp_Object Vw32_lwindow_modifier
;
77 /* Modifier associated with the right "Windows" key, or nil to act as a
79 Lisp_Object Vw32_rwindow_modifier
;
81 /* Modifier associated with the "Apps" key, or nil to act as a normal
83 Lisp_Object Vw32_apps_modifier
;
85 /* Value is nil if Num Lock acts as a function key. */
86 Lisp_Object Vw32_enable_num_lock
;
88 /* Value is nil if Caps Lock acts as a function key. */
89 Lisp_Object Vw32_enable_caps_lock
;
91 /* Modifier associated with Scroll Lock, or nil to act as a normal key. */
92 Lisp_Object Vw32_scroll_lock_modifier
;
94 /* Switch to control whether we inhibit requests for italicised fonts (which
95 are synthesized, look ugly, and are trashed by cursor movement under NT). */
96 Lisp_Object Vw32_enable_italics
;
98 /* Enable palette management. */
99 Lisp_Object Vw32_enable_palette
;
101 /* Control how close left/right button down events must be to
102 be converted to a middle button down event. */
103 Lisp_Object Vw32_mouse_button_tolerance
;
105 /* Minimum interval between mouse movement (and scroll bar drag)
106 events that are passed on to the event loop. */
107 Lisp_Object Vw32_mouse_move_interval
;
109 /* The name we're using in resource queries. */
110 Lisp_Object Vx_resource_name
;
112 /* Non nil if no window manager is in use. */
113 Lisp_Object Vx_no_window_manager
;
115 /* The background and shape of the mouse pointer, and shape when not
116 over text or in the modeline. */
117 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
118 /* The shape when over mouse-sensitive text. */
119 Lisp_Object Vx_sensitive_text_pointer_shape
;
121 /* Color of chars displayed in cursor box. */
122 Lisp_Object Vx_cursor_fore_pixel
;
124 /* Nonzero if using Windows. */
125 static int w32_in_use
;
127 /* Search path for bitmap files. */
128 Lisp_Object Vx_bitmap_file_path
;
130 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
131 Lisp_Object Vx_pixel_size_width_font_regexp
;
133 /* A flag to control how to display unibyte 8-bit character. */
134 int unibyte_display_via_language_environment
;
136 /* Evaluate this expression to rebuild the section of syms_of_w32fns
137 that initializes and staticpros the symbols declared below. Note
138 that Emacs 18 has a bug that keeps C-x C-e from being able to
139 evaluate this expression.
142 ;; Accumulate a list of the symbols we want to initialize from the
143 ;; declarations at the top of the file.
144 (goto-char (point-min))
145 (search-forward "/\*&&& symbols declared here &&&*\/\n")
147 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
149 (cons (buffer-substring (match-beginning 1) (match-end 1))
152 (setq symbol-list (nreverse symbol-list))
153 ;; Delete the section of syms_of_... where we initialize the symbols.
154 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
155 (let ((start (point)))
156 (while (looking-at "^ Q")
158 (kill-region start (point)))
159 ;; Write a new symbol initialization section.
161 (insert (format " %s = intern (\"" (car symbol-list)))
162 (let ((start (point)))
163 (insert (substring (car symbol-list) 1))
164 (subst-char-in-region start (point) ?_ ?-))
165 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
166 (setq symbol-list (cdr symbol-list)))))
170 /*&&& symbols declared here &&&*/
171 Lisp_Object Qauto_raise
;
172 Lisp_Object Qauto_lower
;
173 Lisp_Object Qbackground_color
;
175 Lisp_Object Qborder_color
;
176 Lisp_Object Qborder_width
;
178 Lisp_Object Qcursor_color
;
179 Lisp_Object Qcursor_type
;
180 Lisp_Object Qforeground_color
;
181 Lisp_Object Qgeometry
;
182 Lisp_Object Qicon_left
;
183 Lisp_Object Qicon_top
;
184 Lisp_Object Qicon_type
;
185 Lisp_Object Qicon_name
;
186 Lisp_Object Qinternal_border_width
;
189 Lisp_Object Qmouse_color
;
191 Lisp_Object Qparent_id
;
192 Lisp_Object Qscroll_bar_width
;
193 Lisp_Object Qsuppress_icon
;
195 Lisp_Object Qundefined_color
;
196 Lisp_Object Qvertical_scroll_bars
;
197 Lisp_Object Qvisibility
;
198 Lisp_Object Qwindow_id
;
199 Lisp_Object Qx_frame_parameter
;
200 Lisp_Object Qx_resource_name
;
201 Lisp_Object Quser_position
;
202 Lisp_Object Quser_size
;
203 Lisp_Object Qdisplay
;
205 /* State variables for emulating a three button mouse. */
210 static int button_state
= 0;
211 static W32Msg saved_mouse_button_msg
;
212 static unsigned mouse_button_timer
; /* non-zero when timer is active */
213 static W32Msg saved_mouse_move_msg
;
214 static unsigned mouse_move_timer
;
216 /* W95 mousewheel handler */
217 unsigned int msh_mousewheel
= 0;
219 #define MOUSE_BUTTON_ID 1
220 #define MOUSE_MOVE_ID 2
222 /* The below are defined in frame.c. */
223 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
224 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
226 extern Lisp_Object Vwindow_system_version
;
228 Lisp_Object Qface_set_after_frame_default
;
230 extern Lisp_Object last_mouse_scroll_bar
;
231 extern int last_mouse_scroll_bar_pos
;
233 /* From w32term.c. */
234 extern Lisp_Object Vw32_num_mouse_buttons
;
235 extern Lisp_Object Vw32_recognize_altgr
;
238 /* Error if we are not connected to MS-Windows. */
243 error ("MS-Windows not in use or not initialized");
246 /* Nonzero if we can use mouse menus.
247 You should not call this unless HAVE_MENUS is defined. */
255 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
256 and checking validity for W32. */
259 check_x_frame (frame
)
268 CHECK_LIVE_FRAME (frame
, 0);
271 if (! FRAME_W32_P (f
))
272 error ("non-w32 frame used");
276 /* Let the user specify an display with a frame.
277 nil stands for the selected frame--or, if that is not a w32 frame,
278 the first display on the list. */
280 static struct w32_display_info
*
281 check_x_display_info (frame
)
286 if (FRAME_W32_P (selected_frame
))
287 return FRAME_W32_DISPLAY_INFO (selected_frame
);
289 return &one_w32_display_info
;
291 else if (STRINGP (frame
))
292 return x_display_info_for_name (frame
);
297 CHECK_LIVE_FRAME (frame
, 0);
299 if (! FRAME_W32_P (f
))
300 error ("non-w32 frame used");
301 return FRAME_W32_DISPLAY_INFO (f
);
305 /* Return the Emacs frame-object corresponding to an w32 window.
306 It could be the frame's main window or an icon window. */
308 /* This function can be called during GC, so use GC_xxx type test macros. */
311 x_window_to_frame (dpyinfo
, wdesc
)
312 struct w32_display_info
*dpyinfo
;
315 Lisp_Object tail
, frame
;
318 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
320 frame
= XCONS (tail
)->car
;
321 if (!GC_FRAMEP (frame
))
324 if (f
->output_data
.nothing
== 1
325 || FRAME_W32_DISPLAY_INFO (f
) != dpyinfo
)
327 if (FRAME_W32_WINDOW (f
) == wdesc
)
335 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
336 id, which is just an int that this section returns. Bitmaps are
337 reference counted so they can be shared among frames.
339 Bitmap indices are guaranteed to be > 0, so a negative number can
340 be used to indicate no bitmap.
342 If you use x_create_bitmap_from_data, then you must keep track of
343 the bitmaps yourself. That is, creating a bitmap from the same
344 data more than once will not be caught. */
347 /* Functions to access the contents of a bitmap, given an id. */
350 x_bitmap_height (f
, id
)
354 return FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
358 x_bitmap_width (f
, id
)
362 return FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
366 x_bitmap_pixmap (f
, id
)
370 return (int) FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
374 /* Allocate a new bitmap record. Returns index of new record. */
377 x_allocate_bitmap_record (f
)
380 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
383 if (dpyinfo
->bitmaps
== NULL
)
385 dpyinfo
->bitmaps_size
= 10;
387 = (struct w32_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct w32_bitmap_record
));
388 dpyinfo
->bitmaps_last
= 1;
392 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
393 return ++dpyinfo
->bitmaps_last
;
395 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
396 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
399 dpyinfo
->bitmaps_size
*= 2;
401 = (struct w32_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
402 dpyinfo
->bitmaps_size
* sizeof (struct w32_bitmap_record
));
403 return ++dpyinfo
->bitmaps_last
;
406 /* Add one reference to the reference count of the bitmap with id ID. */
409 x_reference_bitmap (f
, id
)
413 ++FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
416 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
419 x_create_bitmap_from_data (f
, bits
, width
, height
)
422 unsigned int width
, height
;
424 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
428 bitmap
= CreateBitmap (width
, height
,
429 FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
430 FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
436 id
= x_allocate_bitmap_record (f
);
437 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
438 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
439 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
440 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
441 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
442 dpyinfo
->bitmaps
[id
- 1].height
= height
;
443 dpyinfo
->bitmaps
[id
- 1].width
= width
;
448 /* Create bitmap from file FILE for frame F. */
451 x_create_bitmap_from_file (f
, file
)
457 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
458 unsigned int width
, height
;
460 int xhot
, yhot
, result
, id
;
466 /* Look for an existing bitmap with the same name. */
467 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
469 if (dpyinfo
->bitmaps
[id
].refcount
470 && dpyinfo
->bitmaps
[id
].file
471 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
473 ++dpyinfo
->bitmaps
[id
].refcount
;
478 /* Search bitmap-file-path for the file, if appropriate. */
479 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
482 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
487 filename
= (char *) XSTRING (found
)->data
;
489 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
495 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
496 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
497 if (result
!= BitmapSuccess
)
500 id
= x_allocate_bitmap_record (f
);
501 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
502 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
503 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
504 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
505 dpyinfo
->bitmaps
[id
- 1].height
= height
;
506 dpyinfo
->bitmaps
[id
- 1].width
= width
;
507 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
513 /* Remove reference to bitmap with id number ID. */
516 x_destroy_bitmap (f
, id
)
520 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
524 --dpyinfo
->bitmaps
[id
- 1].refcount
;
525 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
528 DeleteObject (dpyinfo
->bitmaps
[id
- 1].pixmap
);
529 if (dpyinfo
->bitmaps
[id
- 1].file
)
531 free (dpyinfo
->bitmaps
[id
- 1].file
);
532 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
539 /* Free all the bitmaps for the display specified by DPYINFO. */
542 x_destroy_all_bitmaps (dpyinfo
)
543 struct w32_display_info
*dpyinfo
;
546 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
547 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
549 DeleteObject (dpyinfo
->bitmaps
[i
].pixmap
);
550 if (dpyinfo
->bitmaps
[i
].file
)
551 free (dpyinfo
->bitmaps
[i
].file
);
553 dpyinfo
->bitmaps_last
= 0;
556 /* Connect the frame-parameter names for W32 frames
557 to the ways of passing the parameter values to the window system.
559 The name of a parameter, as a Lisp symbol,
560 has an `x-frame-parameter' property which is an integer in Lisp
561 but can be interpreted as an `enum x_frame_parm' in C. */
565 X_PARM_FOREGROUND_COLOR
,
566 X_PARM_BACKGROUND_COLOR
,
573 X_PARM_INTERNAL_BORDER_WIDTH
,
577 X_PARM_VERT_SCROLL_BAR
,
579 X_PARM_MENU_BAR_LINES
583 struct x_frame_parm_table
586 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
589 void x_set_foreground_color ();
590 void x_set_background_color ();
591 void x_set_mouse_color ();
592 void x_set_cursor_color ();
593 void x_set_border_color ();
594 void x_set_cursor_type ();
595 void x_set_icon_type ();
596 void x_set_icon_name ();
598 void x_set_border_width ();
599 void x_set_internal_border_width ();
600 void x_explicitly_set_name ();
601 void x_set_autoraise ();
602 void x_set_autolower ();
603 void x_set_vertical_scroll_bars ();
604 void x_set_visibility ();
605 void x_set_menu_bar_lines ();
606 void x_set_scroll_bar_width ();
608 void x_set_unsplittable ();
610 static struct x_frame_parm_table x_frame_parms
[] =
612 "auto-raise", x_set_autoraise
,
613 "auto-lower", x_set_autolower
,
614 "background-color", x_set_background_color
,
615 "border-color", x_set_border_color
,
616 "border-width", x_set_border_width
,
617 "cursor-color", x_set_cursor_color
,
618 "cursor-type", x_set_cursor_type
,
620 "foreground-color", x_set_foreground_color
,
621 "icon-name", x_set_icon_name
,
622 "icon-type", x_set_icon_type
,
623 "internal-border-width", x_set_internal_border_width
,
624 "menu-bar-lines", x_set_menu_bar_lines
,
625 "mouse-color", x_set_mouse_color
,
626 "name", x_explicitly_set_name
,
627 "scroll-bar-width", x_set_scroll_bar_width
,
628 "title", x_set_title
,
629 "unsplittable", x_set_unsplittable
,
630 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
631 "visibility", x_set_visibility
,
634 /* Attach the `x-frame-parameter' properties to
635 the Lisp symbol names of parameters relevant to W32. */
637 init_x_parm_symbols ()
641 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
642 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
646 /* Change the parameters of FRAME as specified by ALIST.
647 If a parameter is not specially recognized, do nothing;
648 otherwise call the `x_set_...' function for that parameter. */
651 x_set_frame_parameters (f
, alist
)
657 /* If both of these parameters are present, it's more efficient to
658 set them both at once. So we wait until we've looked at the
659 entire list before we set them. */
663 Lisp_Object left
, top
;
665 /* Same with these. */
666 Lisp_Object icon_left
, icon_top
;
668 /* Record in these vectors all the parms specified. */
672 int left_no_change
= 0, top_no_change
= 0;
673 int icon_left_no_change
= 0, icon_top_no_change
= 0;
676 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
679 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
680 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
682 /* Extract parm names and values into those vectors. */
685 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
687 Lisp_Object elt
, prop
, val
;
690 parms
[i
] = Fcar (elt
);
691 values
[i
] = Fcdr (elt
);
695 top
= left
= Qunbound
;
696 icon_left
= icon_top
= Qunbound
;
698 /* Provide default values for HEIGHT and WIDTH. */
699 width
= FRAME_WIDTH (f
);
700 height
= FRAME_HEIGHT (f
);
702 /* Now process them in reverse of specified order. */
703 for (i
--; i
>= 0; i
--)
705 Lisp_Object prop
, val
;
710 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
711 width
= XFASTINT (val
);
712 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
713 height
= XFASTINT (val
);
714 else if (EQ (prop
, Qtop
))
716 else if (EQ (prop
, Qleft
))
718 else if (EQ (prop
, Qicon_top
))
720 else if (EQ (prop
, Qicon_left
))
724 register Lisp_Object param_index
, old_value
;
726 param_index
= Fget (prop
, Qx_frame_parameter
);
727 old_value
= get_frame_param (f
, prop
);
728 store_frame_param (f
, prop
, val
);
729 if (NATNUMP (param_index
)
730 && (XFASTINT (param_index
)
731 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
732 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
736 /* Don't die if just one of these was set. */
737 if (EQ (left
, Qunbound
))
740 if (f
->output_data
.w32
->left_pos
< 0)
741 left
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.w32
->left_pos
), Qnil
));
743 XSETINT (left
, f
->output_data
.w32
->left_pos
);
745 if (EQ (top
, Qunbound
))
748 if (f
->output_data
.w32
->top_pos
< 0)
749 top
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.w32
->top_pos
), Qnil
));
751 XSETINT (top
, f
->output_data
.w32
->top_pos
);
754 /* If one of the icon positions was not set, preserve or default it. */
755 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
757 icon_left_no_change
= 1;
758 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
759 if (NILP (icon_left
))
760 XSETINT (icon_left
, 0);
762 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
764 icon_top_no_change
= 1;
765 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
767 XSETINT (icon_top
, 0);
770 /* Don't set these parameters unless they've been explicitly
771 specified. The window might be mapped or resized while we're in
772 this function, and we don't want to override that unless the lisp
773 code has asked for it.
775 Don't set these parameters unless they actually differ from the
776 window's current parameters; the window may not actually exist
781 check_frame_size (f
, &height
, &width
);
783 XSETFRAME (frame
, f
);
785 if (XINT (width
) != FRAME_WIDTH (f
)
786 || XINT (height
) != FRAME_HEIGHT (f
))
787 Fset_frame_size (frame
, make_number (width
), make_number (height
));
789 if ((!NILP (left
) || !NILP (top
))
790 && ! (left_no_change
&& top_no_change
)
791 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.w32
->left_pos
792 && NUMBERP (top
) && XINT (top
) == f
->output_data
.w32
->top_pos
))
797 /* Record the signs. */
798 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
799 if (EQ (left
, Qminus
))
800 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
801 else if (INTEGERP (left
))
803 leftpos
= XINT (left
);
805 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
807 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
808 && CONSP (XCONS (left
)->cdr
)
809 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
811 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
812 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
814 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
815 && CONSP (XCONS (left
)->cdr
)
816 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
818 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
821 if (EQ (top
, Qminus
))
822 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
823 else if (INTEGERP (top
))
827 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
829 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
830 && CONSP (XCONS (top
)->cdr
)
831 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
833 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
834 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
836 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
837 && CONSP (XCONS (top
)->cdr
)
838 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
840 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
844 /* Store the numeric value of the position. */
845 f
->output_data
.w32
->top_pos
= toppos
;
846 f
->output_data
.w32
->left_pos
= leftpos
;
848 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
850 /* Actually set that position, and convert to absolute. */
851 x_set_offset (f
, leftpos
, toppos
, -1);
854 if ((!NILP (icon_left
) || !NILP (icon_top
))
855 && ! (icon_left_no_change
&& icon_top_no_change
))
856 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
860 /* Store the screen positions of frame F into XPTR and YPTR.
861 These are the positions of the containing window manager window,
862 not Emacs's own window. */
865 x_real_positions (f
, xptr
, yptr
)
874 GetClientRect(FRAME_W32_WINDOW(f
), &rect
);
875 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
, FRAME_EXTERNAL_MENU_BAR(f
));
881 ClientToScreen (FRAME_W32_WINDOW(f
), &pt
);
887 /* Insert a description of internally-recorded parameters of frame X
888 into the parameter alist *ALISTPTR that is to be given to the user.
889 Only parameters that are specific to W32
890 and whose values are not correctly recorded in the frame's
891 param_alist need to be considered here. */
893 x_report_frame_params (f
, alistptr
)
895 Lisp_Object
*alistptr
;
900 /* Represent negative positions (off the top or left screen edge)
901 in a way that Fmodify_frame_parameters will understand correctly. */
902 XSETINT (tem
, f
->output_data
.w32
->left_pos
);
903 if (f
->output_data
.w32
->left_pos
>= 0)
904 store_in_alist (alistptr
, Qleft
, tem
);
906 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
908 XSETINT (tem
, f
->output_data
.w32
->top_pos
);
909 if (f
->output_data
.w32
->top_pos
>= 0)
910 store_in_alist (alistptr
, Qtop
, tem
);
912 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
914 store_in_alist (alistptr
, Qborder_width
,
915 make_number (f
->output_data
.w32
->border_width
));
916 store_in_alist (alistptr
, Qinternal_border_width
,
917 make_number (f
->output_data
.w32
->internal_border_width
));
918 sprintf (buf
, "%ld", (long) FRAME_W32_WINDOW (f
));
919 store_in_alist (alistptr
, Qwindow_id
,
921 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
922 FRAME_SAMPLE_VISIBILITY (f
);
923 store_in_alist (alistptr
, Qvisibility
,
924 (FRAME_VISIBLE_P (f
) ? Qt
925 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
926 store_in_alist (alistptr
, Qdisplay
,
927 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->car
);
931 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color
, Sw32_define_rgb_color
, 4, 4, 0,
932 "Convert RGB numbers to a windows color reference and associate with NAME (a string).\n\
933 This adds or updates a named color to w32-color-map, making it available for use.\n\
934 The original entry's RGB ref is returned, or nil if the entry is new.")
935 (red
, green
, blue
, name
)
936 Lisp_Object red
, green
, blue
, name
;
939 Lisp_Object oldrgb
= Qnil
;
942 CHECK_NUMBER (red
, 0);
943 CHECK_NUMBER (green
, 0);
944 CHECK_NUMBER (blue
, 0);
945 CHECK_STRING (name
, 0);
947 XSET (rgb
, Lisp_Int
, RGB(XUINT (red
), XUINT (green
), XUINT (blue
)));
951 /* replace existing entry in w32-color-map or add new entry. */
952 entry
= Fassoc (name
, Vw32_color_map
);
955 entry
= Fcons (name
, rgb
);
956 Vw32_color_map
= Fcons (entry
, Vw32_color_map
);
960 oldrgb
= Fcdr (entry
);
961 Fsetcdr (entry
, rgb
);
969 DEFUN ("w32-load-color-file", Fw32_load_color_file
, Sw32_load_color_file
, 1, 1, 0,
970 "Create an alist of color entries from an external file (ie. rgb.txt).\n\
971 Assign this value to w32-color-map to replace the existing color map.\n\
973 The file should define one named RGB color per line like so:\
975 where R,G,B are numbers between 0 and 255 and name is an arbitrary string.")
977 Lisp_Object filename
;
980 Lisp_Object cmap
= Qnil
;
983 CHECK_STRING (filename
, 0);
984 abspath
= Fexpand_file_name (filename
, Qnil
);
986 fp
= fopen (XSTRING (filename
)->data
, "rt");
990 int red
, green
, blue
;
995 while (fgets (buf
, sizeof (buf
), fp
) != NULL
) {
996 if (sscanf (buf
, "%u %u %u %n", &red
, &green
, &blue
, &num
) == 3)
998 char *name
= buf
+ num
;
999 num
= strlen (name
) - 1;
1000 if (name
[num
] == '\n')
1002 cmap
= Fcons (Fcons (build_string (name
),
1003 make_number (RGB (red
, green
, blue
))),
1015 /* The default colors for the w32 color map */
1016 typedef struct colormap_t
1022 colormap_t w32_color_map
[] =
1024 {"snow" , PALETTERGB (255,250,250)},
1025 {"ghost white" , PALETTERGB (248,248,255)},
1026 {"GhostWhite" , PALETTERGB (248,248,255)},
1027 {"white smoke" , PALETTERGB (245,245,245)},
1028 {"WhiteSmoke" , PALETTERGB (245,245,245)},
1029 {"gainsboro" , PALETTERGB (220,220,220)},
1030 {"floral white" , PALETTERGB (255,250,240)},
1031 {"FloralWhite" , PALETTERGB (255,250,240)},
1032 {"old lace" , PALETTERGB (253,245,230)},
1033 {"OldLace" , PALETTERGB (253,245,230)},
1034 {"linen" , PALETTERGB (250,240,230)},
1035 {"antique white" , PALETTERGB (250,235,215)},
1036 {"AntiqueWhite" , PALETTERGB (250,235,215)},
1037 {"papaya whip" , PALETTERGB (255,239,213)},
1038 {"PapayaWhip" , PALETTERGB (255,239,213)},
1039 {"blanched almond" , PALETTERGB (255,235,205)},
1040 {"BlanchedAlmond" , PALETTERGB (255,235,205)},
1041 {"bisque" , PALETTERGB (255,228,196)},
1042 {"peach puff" , PALETTERGB (255,218,185)},
1043 {"PeachPuff" , PALETTERGB (255,218,185)},
1044 {"navajo white" , PALETTERGB (255,222,173)},
1045 {"NavajoWhite" , PALETTERGB (255,222,173)},
1046 {"moccasin" , PALETTERGB (255,228,181)},
1047 {"cornsilk" , PALETTERGB (255,248,220)},
1048 {"ivory" , PALETTERGB (255,255,240)},
1049 {"lemon chiffon" , PALETTERGB (255,250,205)},
1050 {"LemonChiffon" , PALETTERGB (255,250,205)},
1051 {"seashell" , PALETTERGB (255,245,238)},
1052 {"honeydew" , PALETTERGB (240,255,240)},
1053 {"mint cream" , PALETTERGB (245,255,250)},
1054 {"MintCream" , PALETTERGB (245,255,250)},
1055 {"azure" , PALETTERGB (240,255,255)},
1056 {"alice blue" , PALETTERGB (240,248,255)},
1057 {"AliceBlue" , PALETTERGB (240,248,255)},
1058 {"lavender" , PALETTERGB (230,230,250)},
1059 {"lavender blush" , PALETTERGB (255,240,245)},
1060 {"LavenderBlush" , PALETTERGB (255,240,245)},
1061 {"misty rose" , PALETTERGB (255,228,225)},
1062 {"MistyRose" , PALETTERGB (255,228,225)},
1063 {"white" , PALETTERGB (255,255,255)},
1064 {"black" , PALETTERGB ( 0, 0, 0)},
1065 {"dark slate gray" , PALETTERGB ( 47, 79, 79)},
1066 {"DarkSlateGray" , PALETTERGB ( 47, 79, 79)},
1067 {"dark slate grey" , PALETTERGB ( 47, 79, 79)},
1068 {"DarkSlateGrey" , PALETTERGB ( 47, 79, 79)},
1069 {"dim gray" , PALETTERGB (105,105,105)},
1070 {"DimGray" , PALETTERGB (105,105,105)},
1071 {"dim grey" , PALETTERGB (105,105,105)},
1072 {"DimGrey" , PALETTERGB (105,105,105)},
1073 {"slate gray" , PALETTERGB (112,128,144)},
1074 {"SlateGray" , PALETTERGB (112,128,144)},
1075 {"slate grey" , PALETTERGB (112,128,144)},
1076 {"SlateGrey" , PALETTERGB (112,128,144)},
1077 {"light slate gray" , PALETTERGB (119,136,153)},
1078 {"LightSlateGray" , PALETTERGB (119,136,153)},
1079 {"light slate grey" , PALETTERGB (119,136,153)},
1080 {"LightSlateGrey" , PALETTERGB (119,136,153)},
1081 {"gray" , PALETTERGB (190,190,190)},
1082 {"grey" , PALETTERGB (190,190,190)},
1083 {"light grey" , PALETTERGB (211,211,211)},
1084 {"LightGrey" , PALETTERGB (211,211,211)},
1085 {"light gray" , PALETTERGB (211,211,211)},
1086 {"LightGray" , PALETTERGB (211,211,211)},
1087 {"midnight blue" , PALETTERGB ( 25, 25,112)},
1088 {"MidnightBlue" , PALETTERGB ( 25, 25,112)},
1089 {"navy" , PALETTERGB ( 0, 0,128)},
1090 {"navy blue" , PALETTERGB ( 0, 0,128)},
1091 {"NavyBlue" , PALETTERGB ( 0, 0,128)},
1092 {"cornflower blue" , PALETTERGB (100,149,237)},
1093 {"CornflowerBlue" , PALETTERGB (100,149,237)},
1094 {"dark slate blue" , PALETTERGB ( 72, 61,139)},
1095 {"DarkSlateBlue" , PALETTERGB ( 72, 61,139)},
1096 {"slate blue" , PALETTERGB (106, 90,205)},
1097 {"SlateBlue" , PALETTERGB (106, 90,205)},
1098 {"medium slate blue" , PALETTERGB (123,104,238)},
1099 {"MediumSlateBlue" , PALETTERGB (123,104,238)},
1100 {"light slate blue" , PALETTERGB (132,112,255)},
1101 {"LightSlateBlue" , PALETTERGB (132,112,255)},
1102 {"medium blue" , PALETTERGB ( 0, 0,205)},
1103 {"MediumBlue" , PALETTERGB ( 0, 0,205)},
1104 {"royal blue" , PALETTERGB ( 65,105,225)},
1105 {"RoyalBlue" , PALETTERGB ( 65,105,225)},
1106 {"blue" , PALETTERGB ( 0, 0,255)},
1107 {"dodger blue" , PALETTERGB ( 30,144,255)},
1108 {"DodgerBlue" , PALETTERGB ( 30,144,255)},
1109 {"deep sky blue" , PALETTERGB ( 0,191,255)},
1110 {"DeepSkyBlue" , PALETTERGB ( 0,191,255)},
1111 {"sky blue" , PALETTERGB (135,206,235)},
1112 {"SkyBlue" , PALETTERGB (135,206,235)},
1113 {"light sky blue" , PALETTERGB (135,206,250)},
1114 {"LightSkyBlue" , PALETTERGB (135,206,250)},
1115 {"steel blue" , PALETTERGB ( 70,130,180)},
1116 {"SteelBlue" , PALETTERGB ( 70,130,180)},
1117 {"light steel blue" , PALETTERGB (176,196,222)},
1118 {"LightSteelBlue" , PALETTERGB (176,196,222)},
1119 {"light blue" , PALETTERGB (173,216,230)},
1120 {"LightBlue" , PALETTERGB (173,216,230)},
1121 {"powder blue" , PALETTERGB (176,224,230)},
1122 {"PowderBlue" , PALETTERGB (176,224,230)},
1123 {"pale turquoise" , PALETTERGB (175,238,238)},
1124 {"PaleTurquoise" , PALETTERGB (175,238,238)},
1125 {"dark turquoise" , PALETTERGB ( 0,206,209)},
1126 {"DarkTurquoise" , PALETTERGB ( 0,206,209)},
1127 {"medium turquoise" , PALETTERGB ( 72,209,204)},
1128 {"MediumTurquoise" , PALETTERGB ( 72,209,204)},
1129 {"turquoise" , PALETTERGB ( 64,224,208)},
1130 {"cyan" , PALETTERGB ( 0,255,255)},
1131 {"light cyan" , PALETTERGB (224,255,255)},
1132 {"LightCyan" , PALETTERGB (224,255,255)},
1133 {"cadet blue" , PALETTERGB ( 95,158,160)},
1134 {"CadetBlue" , PALETTERGB ( 95,158,160)},
1135 {"medium aquamarine" , PALETTERGB (102,205,170)},
1136 {"MediumAquamarine" , PALETTERGB (102,205,170)},
1137 {"aquamarine" , PALETTERGB (127,255,212)},
1138 {"dark green" , PALETTERGB ( 0,100, 0)},
1139 {"DarkGreen" , PALETTERGB ( 0,100, 0)},
1140 {"dark olive green" , PALETTERGB ( 85,107, 47)},
1141 {"DarkOliveGreen" , PALETTERGB ( 85,107, 47)},
1142 {"dark sea green" , PALETTERGB (143,188,143)},
1143 {"DarkSeaGreen" , PALETTERGB (143,188,143)},
1144 {"sea green" , PALETTERGB ( 46,139, 87)},
1145 {"SeaGreen" , PALETTERGB ( 46,139, 87)},
1146 {"medium sea green" , PALETTERGB ( 60,179,113)},
1147 {"MediumSeaGreen" , PALETTERGB ( 60,179,113)},
1148 {"light sea green" , PALETTERGB ( 32,178,170)},
1149 {"LightSeaGreen" , PALETTERGB ( 32,178,170)},
1150 {"pale green" , PALETTERGB (152,251,152)},
1151 {"PaleGreen" , PALETTERGB (152,251,152)},
1152 {"spring green" , PALETTERGB ( 0,255,127)},
1153 {"SpringGreen" , PALETTERGB ( 0,255,127)},
1154 {"lawn green" , PALETTERGB (124,252, 0)},
1155 {"LawnGreen" , PALETTERGB (124,252, 0)},
1156 {"green" , PALETTERGB ( 0,255, 0)},
1157 {"chartreuse" , PALETTERGB (127,255, 0)},
1158 {"medium spring green" , PALETTERGB ( 0,250,154)},
1159 {"MediumSpringGreen" , PALETTERGB ( 0,250,154)},
1160 {"green yellow" , PALETTERGB (173,255, 47)},
1161 {"GreenYellow" , PALETTERGB (173,255, 47)},
1162 {"lime green" , PALETTERGB ( 50,205, 50)},
1163 {"LimeGreen" , PALETTERGB ( 50,205, 50)},
1164 {"yellow green" , PALETTERGB (154,205, 50)},
1165 {"YellowGreen" , PALETTERGB (154,205, 50)},
1166 {"forest green" , PALETTERGB ( 34,139, 34)},
1167 {"ForestGreen" , PALETTERGB ( 34,139, 34)},
1168 {"olive drab" , PALETTERGB (107,142, 35)},
1169 {"OliveDrab" , PALETTERGB (107,142, 35)},
1170 {"dark khaki" , PALETTERGB (189,183,107)},
1171 {"DarkKhaki" , PALETTERGB (189,183,107)},
1172 {"khaki" , PALETTERGB (240,230,140)},
1173 {"pale goldenrod" , PALETTERGB (238,232,170)},
1174 {"PaleGoldenrod" , PALETTERGB (238,232,170)},
1175 {"light goldenrod yellow" , PALETTERGB (250,250,210)},
1176 {"LightGoldenrodYellow" , PALETTERGB (250,250,210)},
1177 {"light yellow" , PALETTERGB (255,255,224)},
1178 {"LightYellow" , PALETTERGB (255,255,224)},
1179 {"yellow" , PALETTERGB (255,255, 0)},
1180 {"gold" , PALETTERGB (255,215, 0)},
1181 {"light goldenrod" , PALETTERGB (238,221,130)},
1182 {"LightGoldenrod" , PALETTERGB (238,221,130)},
1183 {"goldenrod" , PALETTERGB (218,165, 32)},
1184 {"dark goldenrod" , PALETTERGB (184,134, 11)},
1185 {"DarkGoldenrod" , PALETTERGB (184,134, 11)},
1186 {"rosy brown" , PALETTERGB (188,143,143)},
1187 {"RosyBrown" , PALETTERGB (188,143,143)},
1188 {"indian red" , PALETTERGB (205, 92, 92)},
1189 {"IndianRed" , PALETTERGB (205, 92, 92)},
1190 {"saddle brown" , PALETTERGB (139, 69, 19)},
1191 {"SaddleBrown" , PALETTERGB (139, 69, 19)},
1192 {"sienna" , PALETTERGB (160, 82, 45)},
1193 {"peru" , PALETTERGB (205,133, 63)},
1194 {"burlywood" , PALETTERGB (222,184,135)},
1195 {"beige" , PALETTERGB (245,245,220)},
1196 {"wheat" , PALETTERGB (245,222,179)},
1197 {"sandy brown" , PALETTERGB (244,164, 96)},
1198 {"SandyBrown" , PALETTERGB (244,164, 96)},
1199 {"tan" , PALETTERGB (210,180,140)},
1200 {"chocolate" , PALETTERGB (210,105, 30)},
1201 {"firebrick" , PALETTERGB (178,34, 34)},
1202 {"brown" , PALETTERGB (165,42, 42)},
1203 {"dark salmon" , PALETTERGB (233,150,122)},
1204 {"DarkSalmon" , PALETTERGB (233,150,122)},
1205 {"salmon" , PALETTERGB (250,128,114)},
1206 {"light salmon" , PALETTERGB (255,160,122)},
1207 {"LightSalmon" , PALETTERGB (255,160,122)},
1208 {"orange" , PALETTERGB (255,165, 0)},
1209 {"dark orange" , PALETTERGB (255,140, 0)},
1210 {"DarkOrange" , PALETTERGB (255,140, 0)},
1211 {"coral" , PALETTERGB (255,127, 80)},
1212 {"light coral" , PALETTERGB (240,128,128)},
1213 {"LightCoral" , PALETTERGB (240,128,128)},
1214 {"tomato" , PALETTERGB (255, 99, 71)},
1215 {"orange red" , PALETTERGB (255, 69, 0)},
1216 {"OrangeRed" , PALETTERGB (255, 69, 0)},
1217 {"red" , PALETTERGB (255, 0, 0)},
1218 {"hot pink" , PALETTERGB (255,105,180)},
1219 {"HotPink" , PALETTERGB (255,105,180)},
1220 {"deep pink" , PALETTERGB (255, 20,147)},
1221 {"DeepPink" , PALETTERGB (255, 20,147)},
1222 {"pink" , PALETTERGB (255,192,203)},
1223 {"light pink" , PALETTERGB (255,182,193)},
1224 {"LightPink" , PALETTERGB (255,182,193)},
1225 {"pale violet red" , PALETTERGB (219,112,147)},
1226 {"PaleVioletRed" , PALETTERGB (219,112,147)},
1227 {"maroon" , PALETTERGB (176, 48, 96)},
1228 {"medium violet red" , PALETTERGB (199, 21,133)},
1229 {"MediumVioletRed" , PALETTERGB (199, 21,133)},
1230 {"violet red" , PALETTERGB (208, 32,144)},
1231 {"VioletRed" , PALETTERGB (208, 32,144)},
1232 {"magenta" , PALETTERGB (255, 0,255)},
1233 {"violet" , PALETTERGB (238,130,238)},
1234 {"plum" , PALETTERGB (221,160,221)},
1235 {"orchid" , PALETTERGB (218,112,214)},
1236 {"medium orchid" , PALETTERGB (186, 85,211)},
1237 {"MediumOrchid" , PALETTERGB (186, 85,211)},
1238 {"dark orchid" , PALETTERGB (153, 50,204)},
1239 {"DarkOrchid" , PALETTERGB (153, 50,204)},
1240 {"dark violet" , PALETTERGB (148, 0,211)},
1241 {"DarkViolet" , PALETTERGB (148, 0,211)},
1242 {"blue violet" , PALETTERGB (138, 43,226)},
1243 {"BlueViolet" , PALETTERGB (138, 43,226)},
1244 {"purple" , PALETTERGB (160, 32,240)},
1245 {"medium purple" , PALETTERGB (147,112,219)},
1246 {"MediumPurple" , PALETTERGB (147,112,219)},
1247 {"thistle" , PALETTERGB (216,191,216)},
1248 {"gray0" , PALETTERGB ( 0, 0, 0)},
1249 {"grey0" , PALETTERGB ( 0, 0, 0)},
1250 {"dark grey" , PALETTERGB (169,169,169)},
1251 {"DarkGrey" , PALETTERGB (169,169,169)},
1252 {"dark gray" , PALETTERGB (169,169,169)},
1253 {"DarkGray" , PALETTERGB (169,169,169)},
1254 {"dark blue" , PALETTERGB ( 0, 0,139)},
1255 {"DarkBlue" , PALETTERGB ( 0, 0,139)},
1256 {"dark cyan" , PALETTERGB ( 0,139,139)},
1257 {"DarkCyan" , PALETTERGB ( 0,139,139)},
1258 {"dark magenta" , PALETTERGB (139, 0,139)},
1259 {"DarkMagenta" , PALETTERGB (139, 0,139)},
1260 {"dark red" , PALETTERGB (139, 0, 0)},
1261 {"DarkRed" , PALETTERGB (139, 0, 0)},
1262 {"light green" , PALETTERGB (144,238,144)},
1263 {"LightGreen" , PALETTERGB (144,238,144)},
1266 DEFUN ("w32-default-color-map", Fw32_default_color_map
, Sw32_default_color_map
,
1267 0, 0, 0, "Return the default color map.")
1271 colormap_t
*pc
= w32_color_map
;
1278 for (i
= 0; i
< sizeof (w32_color_map
) / sizeof (w32_color_map
[0]);
1280 cmap
= Fcons (Fcons (build_string (pc
->name
),
1281 make_number (pc
->colorref
)),
1290 w32_to_x_color (rgb
)
1295 CHECK_NUMBER (rgb
, 0);
1299 color
= Frassq (rgb
, Vw32_color_map
);
1304 return (Fcar (color
));
1310 w32_color_map_lookup (colorname
)
1313 Lisp_Object tail
, ret
= Qnil
;
1317 for (tail
= Vw32_color_map
; !NILP (tail
); tail
= Fcdr (tail
))
1319 register Lisp_Object elt
, tem
;
1322 if (!CONSP (elt
)) continue;
1326 if (lstrcmpi (XSTRING (tem
)->data
, colorname
) == 0)
1328 ret
= XUINT (Fcdr (elt
));
1342 x_to_w32_color (colorname
)
1345 register Lisp_Object tail
, ret
= Qnil
;
1349 if (colorname
[0] == '#')
1351 /* Could be an old-style RGB Device specification. */
1354 color
= colorname
+ 1;
1356 size
= strlen(color
);
1357 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1365 for (i
= 0; i
< 3; i
++)
1369 unsigned long value
;
1371 /* The check for 'x' in the following conditional takes into
1372 account the fact that strtol allows a "0x" in front of
1373 our numbers, and we don't. */
1374 if (!isxdigit(color
[0]) || color
[1] == 'x')
1378 value
= strtoul(color
, &end
, 16);
1380 if (errno
== ERANGE
|| end
- color
!= size
)
1385 value
= value
* 0x10;
1396 colorval
|= (value
<< pos
);
1407 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1415 color
= colorname
+ 4;
1416 for (i
= 0; i
< 3; i
++)
1419 unsigned long value
;
1421 /* The check for 'x' in the following conditional takes into
1422 account the fact that strtol allows a "0x" in front of
1423 our numbers, and we don't. */
1424 if (!isxdigit(color
[0]) || color
[1] == 'x')
1426 value
= strtoul(color
, &end
, 16);
1427 if (errno
== ERANGE
)
1429 switch (end
- color
)
1432 value
= value
* 0x10 + value
;
1445 if (value
== ULONG_MAX
)
1447 colorval
|= (value
<< pos
);
1461 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1463 /* This is an RGB Intensity specification. */
1470 color
= colorname
+ 5;
1471 for (i
= 0; i
< 3; i
++)
1477 value
= strtod(color
, &end
);
1478 if (errno
== ERANGE
)
1480 if (value
< 0.0 || value
> 1.0)
1482 val
= (UINT
)(0x100 * value
);
1483 /* We used 0x100 instead of 0xFF to give an continuous
1484 range between 0.0 and 1.0 inclusive. The next statement
1485 fixes the 1.0 case. */
1488 colorval
|= (val
<< pos
);
1502 /* I am not going to attempt to handle any of the CIE color schemes
1503 or TekHVC, since I don't know the algorithms for conversion to
1506 /* If we fail to lookup the color name in w32_color_map, then check the
1507 colorname to see if it can be crudely approximated: If the X color
1508 ends in a number (e.g., "darkseagreen2"), strip the number and
1509 return the result of looking up the base color name. */
1510 ret
= w32_color_map_lookup (colorname
);
1513 int len
= strlen (colorname
);
1515 if (isdigit (colorname
[len
- 1]))
1517 char *ptr
, *approx
= alloca (len
);
1519 strcpy (approx
, colorname
);
1520 ptr
= &approx
[len
- 1];
1521 while (ptr
> approx
&& isdigit (*ptr
))
1524 ret
= w32_color_map_lookup (approx
);
1534 w32_regenerate_palette (FRAME_PTR f
)
1536 struct w32_palette_entry
* list
;
1537 LOGPALETTE
* log_palette
;
1538 HPALETTE new_palette
;
1541 /* don't bother trying to create palette if not supported */
1542 if (! FRAME_W32_DISPLAY_INFO (f
)->has_palette
)
1545 log_palette
= (LOGPALETTE
*)
1546 alloca (sizeof (LOGPALETTE
) +
1547 FRAME_W32_DISPLAY_INFO (f
)->num_colors
* sizeof (PALETTEENTRY
));
1548 log_palette
->palVersion
= 0x300;
1549 log_palette
->palNumEntries
= FRAME_W32_DISPLAY_INFO (f
)->num_colors
;
1551 list
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1553 i
< FRAME_W32_DISPLAY_INFO (f
)->num_colors
;
1554 i
++, list
= list
->next
)
1555 log_palette
->palPalEntry
[i
] = list
->entry
;
1557 new_palette
= CreatePalette (log_palette
);
1561 if (FRAME_W32_DISPLAY_INFO (f
)->palette
)
1562 DeleteObject (FRAME_W32_DISPLAY_INFO (f
)->palette
);
1563 FRAME_W32_DISPLAY_INFO (f
)->palette
= new_palette
;
1565 /* Realize display palette and garbage all frames. */
1566 release_frame_dc (f
, get_frame_dc (f
));
1571 #define W32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1572 #define SET_W32_COLOR(pe, color) \
1575 pe.peRed = GetRValue (color); \
1576 pe.peGreen = GetGValue (color); \
1577 pe.peBlue = GetBValue (color); \
1582 /* Keep these around in case we ever want to track color usage. */
1584 w32_map_color (FRAME_PTR f
, COLORREF color
)
1586 struct w32_palette_entry
* list
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1588 if (NILP (Vw32_enable_palette
))
1591 /* check if color is already mapped */
1594 if (W32_COLOR (list
->entry
) == color
)
1602 /* not already mapped, so add to list and recreate Windows palette */
1603 list
= (struct w32_palette_entry
*)
1604 xmalloc (sizeof (struct w32_palette_entry
));
1605 SET_W32_COLOR (list
->entry
, color
);
1607 list
->next
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1608 FRAME_W32_DISPLAY_INFO (f
)->color_list
= list
;
1609 FRAME_W32_DISPLAY_INFO (f
)->num_colors
++;
1611 /* set flag that palette must be regenerated */
1612 FRAME_W32_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1616 w32_unmap_color (FRAME_PTR f
, COLORREF color
)
1618 struct w32_palette_entry
* list
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1619 struct w32_palette_entry
**prev
= &FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1621 if (NILP (Vw32_enable_palette
))
1624 /* check if color is already mapped */
1627 if (W32_COLOR (list
->entry
) == color
)
1629 if (--list
->refcount
== 0)
1633 FRAME_W32_DISPLAY_INFO (f
)->num_colors
--;
1643 /* set flag that palette must be regenerated */
1644 FRAME_W32_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1648 /* Decide if color named COLOR is valid for the display associated with
1649 the selected frame; if so, return the rgb values in COLOR_DEF.
1650 If ALLOC is nonzero, allocate a new colormap cell. */
1653 defined_color (f
, color
, color_def
, alloc
)
1656 COLORREF
*color_def
;
1659 register Lisp_Object tem
;
1661 tem
= x_to_w32_color (color
);
1665 if (!NILP (Vw32_enable_palette
))
1667 struct w32_palette_entry
* entry
=
1668 FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1669 struct w32_palette_entry
** prev
=
1670 &FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1672 /* check if color is already mapped */
1675 if (W32_COLOR (entry
->entry
) == XUINT (tem
))
1677 prev
= &entry
->next
;
1678 entry
= entry
->next
;
1681 if (entry
== NULL
&& alloc
)
1683 /* not already mapped, so add to list */
1684 entry
= (struct w32_palette_entry
*)
1685 xmalloc (sizeof (struct w32_palette_entry
));
1686 SET_W32_COLOR (entry
->entry
, XUINT (tem
));
1689 FRAME_W32_DISPLAY_INFO (f
)->num_colors
++;
1691 /* set flag that palette must be regenerated */
1692 FRAME_W32_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1695 /* Ensure COLORREF value is snapped to nearest color in (default)
1696 palette by simulating the PALETTERGB macro. This works whether
1697 or not the display device has a palette. */
1698 *color_def
= XUINT (tem
) | 0x2000000;
1707 /* Given a string ARG naming a color, compute a pixel value from it
1708 suitable for screen F.
1709 If F is not a color screen, return DEF (default) regardless of what
1713 x_decode_color (f
, arg
, def
)
1720 CHECK_STRING (arg
, 0);
1722 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1723 return BLACK_PIX_DEFAULT (f
);
1724 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1725 return WHITE_PIX_DEFAULT (f
);
1727 if ((FRAME_W32_DISPLAY_INFO (f
)->n_planes
* FRAME_W32_DISPLAY_INFO (f
)->n_cbits
) == 1)
1730 /* defined_color is responsible for coping with failures
1731 by looking for a near-miss. */
1732 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1735 /* defined_color failed; return an ultimate default. */
1739 /* Functions called only from `x_set_frame_param'
1740 to set individual parameters.
1742 If FRAME_W32_WINDOW (f) is 0,
1743 the frame is being created and its window does not exist yet.
1744 In that case, just record the parameter's new value
1745 in the standard place; do not attempt to change the window. */
1748 x_set_foreground_color (f
, arg
, oldval
)
1750 Lisp_Object arg
, oldval
;
1752 f
->output_data
.w32
->foreground_pixel
1753 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1755 if (FRAME_W32_WINDOW (f
) != 0)
1757 recompute_basic_faces (f
);
1758 if (FRAME_VISIBLE_P (f
))
1764 x_set_background_color (f
, arg
, oldval
)
1766 Lisp_Object arg
, oldval
;
1771 f
->output_data
.w32
->background_pixel
1772 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1774 if (FRAME_W32_WINDOW (f
) != 0)
1776 SetWindowLong (FRAME_W32_WINDOW (f
), WND_BACKGROUND_INDEX
, f
->output_data
.w32
->background_pixel
);
1778 recompute_basic_faces (f
);
1780 if (FRAME_VISIBLE_P (f
))
1786 x_set_mouse_color (f
, arg
, oldval
)
1788 Lisp_Object arg
, oldval
;
1791 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1796 if (!EQ (Qnil
, arg
))
1797 f
->output_data
.w32
->mouse_pixel
1798 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1799 mask_color
= f
->output_data
.w32
->background_pixel
;
1800 /* No invisible pointers. */
1801 if (mask_color
== f
->output_data
.w32
->mouse_pixel
1802 && mask_color
== f
->output_data
.w32
->background_pixel
)
1803 f
->output_data
.w32
->mouse_pixel
= f
->output_data
.w32
->foreground_pixel
;
1808 /* It's not okay to crash if the user selects a screwy cursor. */
1809 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
1811 if (!EQ (Qnil
, Vx_pointer_shape
))
1813 CHECK_NUMBER (Vx_pointer_shape
, 0);
1814 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
1817 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1818 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
1820 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1822 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1823 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1824 XINT (Vx_nontext_pointer_shape
));
1827 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
1828 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1830 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1832 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1833 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1834 XINT (Vx_mode_pointer_shape
));
1837 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1838 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
1840 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1842 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1844 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1845 XINT (Vx_sensitive_text_pointer_shape
));
1848 cross_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
1850 /* Check and report errors with the above calls. */
1851 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
1852 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
1855 XColor fore_color
, back_color
;
1857 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
1858 back_color
.pixel
= mask_color
;
1859 XQueryColor (FRAME_W32_DISPLAY (f
),
1860 DefaultColormap (FRAME_W32_DISPLAY (f
),
1861 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1863 XQueryColor (FRAME_W32_DISPLAY (f
),
1864 DefaultColormap (FRAME_W32_DISPLAY (f
),
1865 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1867 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
1868 &fore_color
, &back_color
);
1869 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
1870 &fore_color
, &back_color
);
1871 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
1872 &fore_color
, &back_color
);
1873 XRecolorCursor (FRAME_W32_DISPLAY (f
), cross_cursor
,
1874 &fore_color
, &back_color
);
1877 if (FRAME_W32_WINDOW (f
) != 0)
1879 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
1882 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
1883 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
1884 f
->output_data
.w32
->text_cursor
= cursor
;
1886 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
1887 && f
->output_data
.w32
->nontext_cursor
!= 0)
1888 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
1889 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
1891 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
1892 && f
->output_data
.w32
->modeline_cursor
!= 0)
1893 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
1894 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
1895 if (cross_cursor
!= f
->output_data
.w32
->cross_cursor
1896 && f
->output_data
.w32
->cross_cursor
!= 0)
1897 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->cross_cursor
);
1898 f
->output_data
.w32
->cross_cursor
= cross_cursor
;
1900 XFlush (FRAME_W32_DISPLAY (f
));
1906 x_set_cursor_color (f
, arg
, oldval
)
1908 Lisp_Object arg
, oldval
;
1910 unsigned long fore_pixel
;
1912 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1913 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1914 WHITE_PIX_DEFAULT (f
));
1916 fore_pixel
= f
->output_data
.w32
->background_pixel
;
1917 f
->output_data
.w32
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1919 /* Make sure that the cursor color differs from the background color. */
1920 if (f
->output_data
.w32
->cursor_pixel
== f
->output_data
.w32
->background_pixel
)
1922 f
->output_data
.w32
->cursor_pixel
= f
->output_data
.w32
->mouse_pixel
;
1923 if (f
->output_data
.w32
->cursor_pixel
== fore_pixel
)
1924 fore_pixel
= f
->output_data
.w32
->background_pixel
;
1926 f
->output_data
.w32
->cursor_foreground_pixel
= fore_pixel
;
1928 if (FRAME_W32_WINDOW (f
) != 0)
1930 if (FRAME_VISIBLE_P (f
))
1932 x_display_cursor (f
, 0);
1933 x_display_cursor (f
, 1);
1938 /* Set the border-color of frame F to value described by ARG.
1939 ARG can be a string naming a color.
1940 The border-color is used for the border that is drawn by the server.
1941 Note that this does not fully take effect if done before
1942 F has a window; it must be redone when the window is created. */
1945 x_set_border_color (f
, arg
, oldval
)
1947 Lisp_Object arg
, oldval
;
1952 CHECK_STRING (arg
, 0);
1953 str
= XSTRING (arg
)->data
;
1955 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1957 x_set_border_pixel (f
, pix
);
1960 /* Set the border-color of frame F to pixel value PIX.
1961 Note that this does not fully take effect if done before
1964 x_set_border_pixel (f
, pix
)
1968 f
->output_data
.w32
->border_pixel
= pix
;
1970 if (FRAME_W32_WINDOW (f
) != 0 && f
->output_data
.w32
->border_width
> 0)
1972 if (FRAME_VISIBLE_P (f
))
1978 x_set_cursor_type (f
, arg
, oldval
)
1980 Lisp_Object arg
, oldval
;
1984 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1985 f
->output_data
.w32
->cursor_width
= 2;
1987 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
1988 && INTEGERP (XCONS (arg
)->cdr
))
1990 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
1991 f
->output_data
.w32
->cursor_width
= XINT (XCONS (arg
)->cdr
);
1994 /* Treat anything unknown as "box cursor".
1995 It was bad to signal an error; people have trouble fixing
1996 .Xdefaults with Emacs, when it has something bad in it. */
1997 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
1999 /* Make sure the cursor gets redrawn. This is overkill, but how
2000 often do people change cursor types? */
2001 update_mode_lines
++;
2005 x_set_icon_type (f
, arg
, oldval
)
2007 Lisp_Object arg
, oldval
;
2015 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2018 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2023 result
= x_text_icon (f
,
2024 (char *) XSTRING ((!NILP (f
->icon_name
)
2028 result
= x_bitmap_icon (f
, arg
);
2033 error ("No icon window available");
2036 /* If the window was unmapped (and its icon was mapped),
2037 the new icon is not mapped, so map the window in its stead. */
2038 if (FRAME_VISIBLE_P (f
))
2040 #ifdef USE_X_TOOLKIT
2041 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2043 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2046 XFlush (FRAME_W32_DISPLAY (f
));
2051 /* Return non-nil if frame F wants a bitmap icon. */
2059 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
2061 return XCONS (tem
)->cdr
;
2067 x_set_icon_name (f
, arg
, oldval
)
2069 Lisp_Object arg
, oldval
;
2076 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2079 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2085 if (f
->output_data
.w32
->icon_bitmap
!= 0)
2090 result
= x_text_icon (f
,
2091 (char *) XSTRING ((!NILP (f
->icon_name
)
2100 error ("No icon window available");
2103 /* If the window was unmapped (and its icon was mapped),
2104 the new icon is not mapped, so map the window in its stead. */
2105 if (FRAME_VISIBLE_P (f
))
2107 #ifdef USE_X_TOOLKIT
2108 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2110 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2113 XFlush (FRAME_W32_DISPLAY (f
));
2118 extern Lisp_Object
x_new_font ();
2119 extern Lisp_Object
x_new_fontset();
2122 x_set_font (f
, arg
, oldval
)
2124 Lisp_Object arg
, oldval
;
2127 Lisp_Object fontset_name
;
2130 CHECK_STRING (arg
, 1);
2132 fontset_name
= Fquery_fontset (arg
, Qnil
);
2135 result
= (STRINGP (fontset_name
)
2136 ? x_new_fontset (f
, XSTRING (fontset_name
)->data
)
2137 : x_new_font (f
, XSTRING (arg
)->data
));
2140 if (EQ (result
, Qnil
))
2141 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
2142 else if (EQ (result
, Qt
))
2143 error ("the characters of the given font have varying widths");
2144 else if (STRINGP (result
))
2146 recompute_basic_faces (f
);
2147 store_frame_param (f
, Qfont
, result
);
2152 XSETFRAME (frame
, f
);
2153 call1 (Qface_set_after_frame_default
, frame
);
2157 x_set_border_width (f
, arg
, oldval
)
2159 Lisp_Object arg
, oldval
;
2161 CHECK_NUMBER (arg
, 0);
2163 if (XINT (arg
) == f
->output_data
.w32
->border_width
)
2166 if (FRAME_W32_WINDOW (f
) != 0)
2167 error ("Cannot change the border width of a window");
2169 f
->output_data
.w32
->border_width
= XINT (arg
);
2173 x_set_internal_border_width (f
, arg
, oldval
)
2175 Lisp_Object arg
, oldval
;
2178 int old
= f
->output_data
.w32
->internal_border_width
;
2180 CHECK_NUMBER (arg
, 0);
2181 f
->output_data
.w32
->internal_border_width
= XINT (arg
);
2182 if (f
->output_data
.w32
->internal_border_width
< 0)
2183 f
->output_data
.w32
->internal_border_width
= 0;
2185 if (f
->output_data
.w32
->internal_border_width
== old
)
2188 if (FRAME_W32_WINDOW (f
) != 0)
2191 x_set_window_size (f
, 0, f
->width
, f
->height
);
2193 SET_FRAME_GARBAGED (f
);
2198 x_set_visibility (f
, value
, oldval
)
2200 Lisp_Object value
, oldval
;
2203 XSETFRAME (frame
, f
);
2206 Fmake_frame_invisible (frame
, Qt
);
2207 else if (EQ (value
, Qicon
))
2208 Ficonify_frame (frame
);
2210 Fmake_frame_visible (frame
);
2214 x_set_menu_bar_lines (f
, value
, oldval
)
2216 Lisp_Object value
, oldval
;
2219 int olines
= FRAME_MENU_BAR_LINES (f
);
2221 /* Right now, menu bars don't work properly in minibuf-only frames;
2222 most of the commands try to apply themselves to the minibuffer
2223 frame itslef, and get an error because you can't switch buffers
2224 in or split the minibuffer window. */
2225 if (FRAME_MINIBUF_ONLY_P (f
))
2228 if (INTEGERP (value
))
2229 nlines
= XINT (value
);
2233 FRAME_MENU_BAR_LINES (f
) = 0;
2235 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2238 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2239 free_frame_menubar (f
);
2240 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2242 /* Adjust the frame size so that the client (text) dimensions
2243 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2245 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2249 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2252 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2253 name; if NAME is a string, set F's name to NAME and set
2254 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2256 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2257 suggesting a new name, which lisp code should override; if
2258 F->explicit_name is set, ignore the new name; otherwise, set it. */
2261 x_set_name (f
, name
, explicit)
2266 /* Make sure that requests from lisp code override requests from
2267 Emacs redisplay code. */
2270 /* If we're switching from explicit to implicit, we had better
2271 update the mode lines and thereby update the title. */
2272 if (f
->explicit_name
&& NILP (name
))
2273 update_mode_lines
= 1;
2275 f
->explicit_name
= ! NILP (name
);
2277 else if (f
->explicit_name
)
2280 /* If NAME is nil, set the name to the w32_id_name. */
2283 /* Check for no change needed in this very common case
2284 before we do any consing. */
2285 if (!strcmp (FRAME_W32_DISPLAY_INFO (f
)->w32_id_name
,
2286 XSTRING (f
->name
)->data
))
2288 name
= build_string (FRAME_W32_DISPLAY_INFO (f
)->w32_id_name
);
2291 CHECK_STRING (name
, 0);
2293 /* Don't change the name if it's already NAME. */
2294 if (! NILP (Fstring_equal (name
, f
->name
)))
2299 /* For setting the frame title, the title parameter should override
2300 the name parameter. */
2301 if (! NILP (f
->title
))
2304 if (FRAME_W32_WINDOW (f
))
2307 SetWindowText(FRAME_W32_WINDOW (f
), XSTRING (name
)->data
);
2312 /* This function should be called when the user's lisp code has
2313 specified a name for the frame; the name will override any set by the
2316 x_explicitly_set_name (f
, arg
, oldval
)
2318 Lisp_Object arg
, oldval
;
2320 x_set_name (f
, arg
, 1);
2323 /* This function should be called by Emacs redisplay code to set the
2324 name; names set this way will never override names set by the user's
2327 x_implicitly_set_name (f
, arg
, oldval
)
2329 Lisp_Object arg
, oldval
;
2331 x_set_name (f
, arg
, 0);
2334 /* Change the title of frame F to NAME.
2335 If NAME is nil, use the frame name as the title.
2337 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2338 name; if NAME is a string, set F's name to NAME and set
2339 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2341 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2342 suggesting a new name, which lisp code should override; if
2343 F->explicit_name is set, ignore the new name; otherwise, set it. */
2346 x_set_title (f
, name
)
2350 /* Don't change the title if it's already NAME. */
2351 if (EQ (name
, f
->title
))
2354 update_mode_lines
= 1;
2361 if (FRAME_W32_WINDOW (f
))
2364 SetWindowText(FRAME_W32_WINDOW (f
), XSTRING (name
)->data
);
2370 x_set_autoraise (f
, arg
, oldval
)
2372 Lisp_Object arg
, oldval
;
2374 f
->auto_raise
= !EQ (Qnil
, arg
);
2378 x_set_autolower (f
, arg
, oldval
)
2380 Lisp_Object arg
, oldval
;
2382 f
->auto_lower
= !EQ (Qnil
, arg
);
2386 x_set_unsplittable (f
, arg
, oldval
)
2388 Lisp_Object arg
, oldval
;
2390 f
->no_split
= !NILP (arg
);
2394 x_set_vertical_scroll_bars (f
, arg
, oldval
)
2396 Lisp_Object arg
, oldval
;
2398 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
2399 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
2400 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2401 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
2403 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = NILP (arg
) ?
2404 vertical_scroll_bar_none
:
2405 /* Put scroll bars on the right by default, as is conventional
2408 ? vertical_scroll_bar_left
2409 : vertical_scroll_bar_right
;
2411 /* We set this parameter before creating the window for the
2412 frame, so we can get the geometry right from the start.
2413 However, if the window hasn't been created yet, we shouldn't
2414 call x_set_window_size. */
2415 if (FRAME_W32_WINDOW (f
))
2416 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2421 x_set_scroll_bar_width (f
, arg
, oldval
)
2423 Lisp_Object arg
, oldval
;
2427 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2428 FRAME_SCROLL_BAR_COLS (f
) = 2;
2430 else if (INTEGERP (arg
) && XINT (arg
) > 0
2431 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2433 int wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
2434 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
2435 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
2436 if (FRAME_W32_WINDOW (f
))
2437 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2441 /* Subroutines of creating an frame. */
2443 /* Make sure that Vx_resource_name is set to a reasonable value.
2444 Fix it up, or set it to `emacs' if it is too hopeless. */
2447 validate_x_resource_name ()
2450 /* Number of valid characters in the resource name. */
2452 /* Number of invalid characters in the resource name. */
2457 if (STRINGP (Vx_resource_name
))
2459 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
2462 len
= XSTRING (Vx_resource_name
)->size
;
2464 /* Only letters, digits, - and _ are valid in resource names.
2465 Count the valid characters and count the invalid ones. */
2466 for (i
= 0; i
< len
; i
++)
2469 if (! ((c
>= 'a' && c
<= 'z')
2470 || (c
>= 'A' && c
<= 'Z')
2471 || (c
>= '0' && c
<= '9')
2472 || c
== '-' || c
== '_'))
2479 /* Not a string => completely invalid. */
2480 bad_count
= 5, good_count
= 0;
2482 /* If name is valid already, return. */
2486 /* If name is entirely invalid, or nearly so, use `emacs'. */
2488 || (good_count
== 1 && bad_count
> 0))
2490 Vx_resource_name
= build_string ("emacs");
2494 /* Name is partly valid. Copy it and replace the invalid characters
2495 with underscores. */
2497 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
2499 for (i
= 0; i
< len
; i
++)
2501 int c
= XSTRING (new)->data
[i
];
2502 if (! ((c
>= 'a' && c
<= 'z')
2503 || (c
>= 'A' && c
<= 'Z')
2504 || (c
>= '0' && c
<= '9')
2505 || c
== '-' || c
== '_'))
2506 XSTRING (new)->data
[i
] = '_';
2511 extern char *x_get_string_resource ();
2513 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
2514 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2515 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2516 class, where INSTANCE is the name under which Emacs was invoked, or\n\
2517 the name specified by the `-name' or `-rn' command-line arguments.\n\
2519 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2520 class, respectively. You must specify both of them or neither.\n\
2521 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2522 and the class is `Emacs.CLASS.SUBCLASS'.")
2523 (attribute
, class, component
, subclass
)
2524 Lisp_Object attribute
, class, component
, subclass
;
2526 register char *value
;
2530 CHECK_STRING (attribute
, 0);
2531 CHECK_STRING (class, 0);
2533 if (!NILP (component
))
2534 CHECK_STRING (component
, 1);
2535 if (!NILP (subclass
))
2536 CHECK_STRING (subclass
, 2);
2537 if (NILP (component
) != NILP (subclass
))
2538 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2540 validate_x_resource_name ();
2542 /* Allocate space for the components, the dots which separate them,
2543 and the final '\0'. Make them big enough for the worst case. */
2544 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
2545 + (STRINGP (component
)
2546 ? XSTRING (component
)->size
: 0)
2547 + XSTRING (attribute
)->size
2550 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2551 + XSTRING (class)->size
2552 + (STRINGP (subclass
)
2553 ? XSTRING (subclass
)->size
: 0)
2556 /* Start with emacs.FRAMENAME for the name (the specific one)
2557 and with `Emacs' for the class key (the general one). */
2558 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2559 strcpy (class_key
, EMACS_CLASS
);
2561 strcat (class_key
, ".");
2562 strcat (class_key
, XSTRING (class)->data
);
2564 if (!NILP (component
))
2566 strcat (class_key
, ".");
2567 strcat (class_key
, XSTRING (subclass
)->data
);
2569 strcat (name_key
, ".");
2570 strcat (name_key
, XSTRING (component
)->data
);
2573 strcat (name_key
, ".");
2574 strcat (name_key
, XSTRING (attribute
)->data
);
2576 value
= x_get_string_resource (Qnil
,
2577 name_key
, class_key
);
2579 if (value
!= (char *) 0)
2580 return build_string (value
);
2585 /* Used when C code wants a resource value. */
2588 x_get_resource_string (attribute
, class)
2589 char *attribute
, *class;
2591 register char *value
;
2595 /* Allocate space for the components, the dots which separate them,
2596 and the final '\0'. */
2597 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2598 + strlen (attribute
) + 2);
2599 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2600 + strlen (class) + 2);
2602 sprintf (name_key
, "%s.%s",
2603 XSTRING (Vinvocation_name
)->data
,
2605 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2607 return x_get_string_resource (selected_frame
,
2608 name_key
, class_key
);
2611 /* Types we might convert a resource string into. */
2614 number
, boolean
, string
, symbol
2617 /* Return the value of parameter PARAM.
2619 First search ALIST, then Vdefault_frame_alist, then the X defaults
2620 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2622 Convert the resource to the type specified by desired_type.
2624 If no default is specified, return Qunbound. If you call
2625 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2626 and don't let it get stored in any Lisp-visible variables! */
2629 x_get_arg (alist
, param
, attribute
, class, type
)
2630 Lisp_Object alist
, param
;
2633 enum resource_types type
;
2635 register Lisp_Object tem
;
2637 tem
= Fassq (param
, alist
);
2639 tem
= Fassq (param
, Vdefault_frame_alist
);
2645 tem
= Fx_get_resource (build_string (attribute
),
2646 build_string (class),
2655 return make_number (atoi (XSTRING (tem
)->data
));
2658 tem
= Fdowncase (tem
);
2659 if (!strcmp (XSTRING (tem
)->data
, "on")
2660 || !strcmp (XSTRING (tem
)->data
, "true"))
2669 /* As a special case, we map the values `true' and `on'
2670 to Qt, and `false' and `off' to Qnil. */
2673 lower
= Fdowncase (tem
);
2674 if (!strcmp (XSTRING (lower
)->data
, "on")
2675 || !strcmp (XSTRING (lower
)->data
, "true"))
2677 else if (!strcmp (XSTRING (lower
)->data
, "off")
2678 || !strcmp (XSTRING (lower
)->data
, "false"))
2681 return Fintern (tem
, Qnil
);
2694 /* Record in frame F the specified or default value according to ALIST
2695 of the parameter named PARAM (a Lisp symbol).
2696 If no value is specified for PARAM, look for an X default for XPROP
2697 on the frame named NAME.
2698 If that is not found either, use the value DEFLT. */
2701 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2708 enum resource_types type
;
2712 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2713 if (EQ (tem
, Qunbound
))
2715 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2719 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2720 "Parse an X-style geometry string STRING.\n\
2721 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2722 The properties returned may include `top', `left', `height', and `width'.\n\
2723 The value of `left' or `top' may be an integer,\n\
2724 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2725 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2730 unsigned int width
, height
;
2733 CHECK_STRING (string
, 0);
2735 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2736 &x
, &y
, &width
, &height
);
2739 if (geometry
& XValue
)
2741 Lisp_Object element
;
2743 if (x
>= 0 && (geometry
& XNegative
))
2744 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2745 else if (x
< 0 && ! (geometry
& XNegative
))
2746 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2748 element
= Fcons (Qleft
, make_number (x
));
2749 result
= Fcons (element
, result
);
2752 if (geometry
& YValue
)
2754 Lisp_Object element
;
2756 if (y
>= 0 && (geometry
& YNegative
))
2757 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2758 else if (y
< 0 && ! (geometry
& YNegative
))
2759 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2761 element
= Fcons (Qtop
, make_number (y
));
2762 result
= Fcons (element
, result
);
2765 if (geometry
& WidthValue
)
2766 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2767 if (geometry
& HeightValue
)
2768 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2773 /* Calculate the desired size and position of this window,
2774 and return the flags saying which aspects were specified.
2776 This function does not make the coordinates positive. */
2778 #define DEFAULT_ROWS 40
2779 #define DEFAULT_COLS 80
2782 x_figure_window_size (f
, parms
)
2786 register Lisp_Object tem0
, tem1
, tem2
;
2787 int height
, width
, left
, top
;
2788 register int geometry
;
2789 long window_prompting
= 0;
2791 /* Default values if we fall through.
2792 Actually, if that happens we should get
2793 window manager prompting. */
2794 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
2795 f
->height
= DEFAULT_ROWS
;
2796 /* Window managers expect that if program-specified
2797 positions are not (0,0), they're intentional, not defaults. */
2798 f
->output_data
.w32
->top_pos
= 0;
2799 f
->output_data
.w32
->left_pos
= 0;
2801 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2802 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2803 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2804 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2806 if (!EQ (tem0
, Qunbound
))
2808 CHECK_NUMBER (tem0
, 0);
2809 f
->height
= XINT (tem0
);
2811 if (!EQ (tem1
, Qunbound
))
2813 CHECK_NUMBER (tem1
, 0);
2814 SET_FRAME_WIDTH (f
, XINT (tem1
));
2816 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2817 window_prompting
|= USSize
;
2819 window_prompting
|= PSize
;
2822 f
->output_data
.w32
->vertical_scroll_bar_extra
2823 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2825 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2826 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2827 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
2828 f
->output_data
.w32
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2829 f
->output_data
.w32
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2831 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2832 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2833 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2834 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2836 if (EQ (tem0
, Qminus
))
2838 f
->output_data
.w32
->top_pos
= 0;
2839 window_prompting
|= YNegative
;
2841 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2842 && CONSP (XCONS (tem0
)->cdr
)
2843 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2845 f
->output_data
.w32
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2846 window_prompting
|= YNegative
;
2848 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2849 && CONSP (XCONS (tem0
)->cdr
)
2850 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2852 f
->output_data
.w32
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2854 else if (EQ (tem0
, Qunbound
))
2855 f
->output_data
.w32
->top_pos
= 0;
2858 CHECK_NUMBER (tem0
, 0);
2859 f
->output_data
.w32
->top_pos
= XINT (tem0
);
2860 if (f
->output_data
.w32
->top_pos
< 0)
2861 window_prompting
|= YNegative
;
2864 if (EQ (tem1
, Qminus
))
2866 f
->output_data
.w32
->left_pos
= 0;
2867 window_prompting
|= XNegative
;
2869 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2870 && CONSP (XCONS (tem1
)->cdr
)
2871 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2873 f
->output_data
.w32
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2874 window_prompting
|= XNegative
;
2876 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2877 && CONSP (XCONS (tem1
)->cdr
)
2878 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2880 f
->output_data
.w32
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2882 else if (EQ (tem1
, Qunbound
))
2883 f
->output_data
.w32
->left_pos
= 0;
2886 CHECK_NUMBER (tem1
, 0);
2887 f
->output_data
.w32
->left_pos
= XINT (tem1
);
2888 if (f
->output_data
.w32
->left_pos
< 0)
2889 window_prompting
|= XNegative
;
2892 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2893 window_prompting
|= USPosition
;
2895 window_prompting
|= PPosition
;
2898 return window_prompting
;
2903 extern LRESULT CALLBACK
w32_wnd_proc ();
2906 w32_init_class (hinst
)
2911 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2912 wc
.lpfnWndProc
= (WNDPROC
) w32_wnd_proc
;
2914 wc
.cbWndExtra
= WND_EXTRA_BYTES
;
2915 wc
.hInstance
= hinst
;
2916 wc
.hIcon
= LoadIcon (hinst
, EMACS_CLASS
);
2917 wc
.hCursor
= LoadCursor (NULL
, IDC_ARROW
);
2918 wc
.hbrBackground
= NULL
; /* GetStockObject (WHITE_BRUSH); */
2919 wc
.lpszMenuName
= NULL
;
2920 wc
.lpszClassName
= EMACS_CLASS
;
2922 return (RegisterClass (&wc
));
2926 w32_createscrollbar (f
, bar
)
2928 struct scroll_bar
* bar
;
2930 return (CreateWindow ("SCROLLBAR", "", SBS_VERT
| WS_CHILD
| WS_VISIBLE
,
2931 /* Position and size of scroll bar. */
2932 XINT(bar
->left
), XINT(bar
->top
),
2933 XINT(bar
->width
), XINT(bar
->height
),
2934 FRAME_W32_WINDOW (f
),
2941 w32_createwindow (f
)
2947 rect
.left
= rect
.top
= 0;
2948 rect
.right
= PIXEL_WIDTH (f
);
2949 rect
.bottom
= PIXEL_HEIGHT (f
);
2951 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
,
2952 FRAME_EXTERNAL_MENU_BAR (f
));
2954 /* Do first time app init */
2958 w32_init_class (hinst
);
2961 FRAME_W32_WINDOW (f
) = hwnd
2962 = CreateWindow (EMACS_CLASS
,
2964 f
->output_data
.w32
->dwStyle
| WS_CLIPCHILDREN
,
2965 f
->output_data
.w32
->left_pos
,
2966 f
->output_data
.w32
->top_pos
,
2967 rect
.right
- rect
.left
,
2968 rect
.bottom
- rect
.top
,
2976 SetWindowLong (hwnd
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
2977 SetWindowLong (hwnd
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
2978 SetWindowLong (hwnd
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
2979 SetWindowLong (hwnd
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
2980 SetWindowLong (hwnd
, WND_BACKGROUND_INDEX
, f
->output_data
.w32
->background_pixel
);
2982 /* Enable drag-n-drop. */
2983 DragAcceptFiles (hwnd
, TRUE
);
2985 /* Do this to discard the default setting specified by our parent. */
2986 ShowWindow (hwnd
, SW_HIDE
);
2991 my_post_msg (wmsg
, hwnd
, msg
, wParam
, lParam
)
2998 wmsg
->msg
.hwnd
= hwnd
;
2999 wmsg
->msg
.message
= msg
;
3000 wmsg
->msg
.wParam
= wParam
;
3001 wmsg
->msg
.lParam
= lParam
;
3002 wmsg
->msg
.time
= GetMessageTime ();
3007 /* GetKeyState and MapVirtualKey on Windows 95 do not actually distinguish
3008 between left and right keys as advertised. We test for this
3009 support dynamically, and set a flag when the support is absent. If
3010 absent, we keep track of the left and right control and alt keys
3011 ourselves. This is particularly necessary on keyboards that rely
3012 upon the AltGr key, which is represented as having the left control
3013 and right alt keys pressed. For these keyboards, we need to know
3014 when the left alt key has been pressed in addition to the AltGr key
3015 so that we can properly support M-AltGr-key sequences (such as M-@
3016 on Swedish keyboards). */
3018 #define EMACS_LCONTROL 0
3019 #define EMACS_RCONTROL 1
3020 #define EMACS_LMENU 2
3021 #define EMACS_RMENU 3
3023 static int modifiers
[4];
3024 static int modifiers_recorded
;
3025 static int modifier_key_support_tested
;
3028 test_modifier_support (unsigned int wparam
)
3032 if (wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
)
3034 if (wparam
== VK_CONTROL
)
3044 if (!(GetKeyState (l
) & 0x8000) && !(GetKeyState (r
) & 0x8000))
3045 modifiers_recorded
= 1;
3047 modifiers_recorded
= 0;
3048 modifier_key_support_tested
= 1;
3052 record_keydown (unsigned int wparam
, unsigned int lparam
)
3056 if (!modifier_key_support_tested
)
3057 test_modifier_support (wparam
);
3059 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
3062 if (wparam
== VK_CONTROL
)
3063 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
3065 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
3071 record_keyup (unsigned int wparam
, unsigned int lparam
)
3075 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
3078 if (wparam
== VK_CONTROL
)
3079 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
3081 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
3086 /* Emacs can lose focus while a modifier key has been pressed. When
3087 it regains focus, be conservative and clear all modifiers since
3088 we cannot reconstruct the left and right modifier state. */
3094 if (!modifiers_recorded
)
3097 ctrl
= GetAsyncKeyState (VK_CONTROL
);
3098 alt
= GetAsyncKeyState (VK_MENU
);
3100 if (ctrl
== 0 || alt
== 0)
3101 /* Emacs doesn't have keyboard focus. Do nothing. */
3104 if (!(ctrl
& 0x08000))
3105 /* Clear any recorded control modifier state. */
3106 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
3108 if (!(alt
& 0x08000))
3109 /* Clear any recorded alt modifier state. */
3110 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
3112 /* Otherwise, leave the modifier state as it was when Emacs lost
3116 /* Synchronize modifier state with what is reported with the current
3117 keystroke. Even if we cannot distinguish between left and right
3118 modifier keys, we know that, if no modifiers are set, then neither
3119 the left or right modifier should be set. */
3123 if (!modifiers_recorded
)
3126 if (!(GetKeyState (VK_CONTROL
) & 0x8000))
3127 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
3129 if (!(GetKeyState (VK_MENU
) & 0x8000))
3130 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
3134 modifier_set (int vkey
)
3136 if (vkey
== VK_CAPITAL
|| vkey
== VK_SCROLL
)
3137 return (GetKeyState (vkey
) & 0x1);
3138 if (!modifiers_recorded
)
3139 return (GetKeyState (vkey
) & 0x8000);
3144 return modifiers
[EMACS_LCONTROL
];
3146 return modifiers
[EMACS_RCONTROL
];
3148 return modifiers
[EMACS_LMENU
];
3150 return modifiers
[EMACS_RMENU
];
3152 return (GetKeyState (vkey
) & 0x8000);
3155 /* Convert between the modifier bits W32 uses and the modifier bits
3159 w32_key_to_modifier (int key
)
3161 Lisp_Object key_mapping
;
3166 key_mapping
= Vw32_lwindow_modifier
;
3169 key_mapping
= Vw32_rwindow_modifier
;
3172 key_mapping
= Vw32_apps_modifier
;
3175 key_mapping
= Vw32_scroll_lock_modifier
;
3181 if (EQ (key_mapping
, intern ("hyper")))
3182 return hyper_modifier
;
3183 if (EQ (key_mapping
, intern ("super")))
3184 return super_modifier
;
3185 if (EQ (key_mapping
, intern ("meta")))
3186 return meta_modifier
;
3187 if (EQ (key_mapping
, intern ("alt")))
3188 return alt_modifier
;
3189 if (EQ (key_mapping
, intern ("ctrl")))
3190 return ctrl_modifier
;
3191 if (EQ (key_mapping
, intern ("control"))) /* synonym for ctrl */
3192 return ctrl_modifier
;
3193 if (EQ (key_mapping
, intern ("shift")))
3194 return shift_modifier
;
3196 /* Don't generate any modifier if not explicitly requested. */
3201 w32_get_modifiers ()
3203 return ((modifier_set (VK_SHIFT
) ? shift_modifier
: 0) |
3204 (modifier_set (VK_CONTROL
) ? ctrl_modifier
: 0) |
3205 (modifier_set (VK_LWIN
) ? w32_key_to_modifier (VK_LWIN
) : 0) |
3206 (modifier_set (VK_RWIN
) ? w32_key_to_modifier (VK_RWIN
) : 0) |
3207 (modifier_set (VK_APPS
) ? w32_key_to_modifier (VK_APPS
) : 0) |
3208 (modifier_set (VK_SCROLL
) ? w32_key_to_modifier (VK_SCROLL
) : 0) |
3209 (modifier_set (VK_MENU
) ?
3210 ((NILP (Vw32_alt_is_meta
)) ? alt_modifier
: meta_modifier
) : 0));
3213 /* We map the VK_* modifiers into console modifier constants
3214 so that we can use the same routines to handle both console
3215 and window input. */
3218 construct_console_modifiers ()
3223 mods
|= (modifier_set (VK_SHIFT
)) ? SHIFT_PRESSED
: 0;
3224 mods
|= (modifier_set (VK_CAPITAL
)) ? CAPSLOCK_ON
: 0;
3225 mods
|= (modifier_set (VK_SCROLL
)) ? SCROLLLOCK_ON
: 0;
3226 mods
|= (modifier_set (VK_NUMLOCK
)) ? NUMLOCK_ON
: 0;
3227 mods
|= (modifier_set (VK_LCONTROL
)) ? LEFT_CTRL_PRESSED
: 0;
3228 mods
|= (modifier_set (VK_RCONTROL
)) ? RIGHT_CTRL_PRESSED
: 0;
3229 mods
|= (modifier_set (VK_LMENU
)) ? LEFT_ALT_PRESSED
: 0;
3230 mods
|= (modifier_set (VK_RMENU
)) ? RIGHT_ALT_PRESSED
: 0;
3231 mods
|= (modifier_set (VK_LWIN
)) ? LEFT_WIN_PRESSED
: 0;
3232 mods
|= (modifier_set (VK_RWIN
)) ? RIGHT_WIN_PRESSED
: 0;
3233 mods
|= (modifier_set (VK_APPS
)) ? APPS_PRESSED
: 0;
3239 w32_get_key_modifiers (unsigned int wparam
, unsigned int lparam
)
3243 /* Convert to emacs modifiers. */
3244 mods
= w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam
);
3250 map_keypad_keys (unsigned int virt_key
, unsigned int extended
)
3252 if (virt_key
< VK_CLEAR
|| virt_key
> VK_DELETE
)
3255 if (virt_key
== VK_RETURN
)
3256 return (extended
? VK_NUMPAD_ENTER
: VK_RETURN
);
3258 if (virt_key
>= VK_PRIOR
&& virt_key
<= VK_DOWN
)
3259 return (!extended
? (VK_NUMPAD_PRIOR
+ (virt_key
- VK_PRIOR
)) : virt_key
);
3261 if (virt_key
== VK_INSERT
|| virt_key
== VK_DELETE
)
3262 return (!extended
? (VK_NUMPAD_INSERT
+ (virt_key
- VK_INSERT
)) : virt_key
);
3264 if (virt_key
== VK_CLEAR
)
3265 return (!extended
? VK_NUMPAD_CLEAR
: virt_key
);
3270 /* List of special key combinations which w32 would normally capture,
3271 but emacs should grab instead. Not directly visible to lisp, to
3272 simplify synchronization. Each item is an integer encoding a virtual
3273 key code and modifier combination to capture. */
3274 Lisp_Object w32_grabbed_keys
;
3276 #define HOTKEY(vk,mods) make_number (((vk) & 255) | ((mods) << 8))
3277 #define HOTKEY_ID(k) (XFASTINT (k) & 0xbfff)
3278 #define HOTKEY_VK_CODE(k) (XFASTINT (k) & 255)
3279 #define HOTKEY_MODIFIERS(k) (XFASTINT (k) >> 8)
3281 /* Register hot-keys for reserved key combinations when Emacs has
3282 keyboard focus, since this is the only way Emacs can receive key
3283 combinations like Alt-Tab which are used by the system. */
3286 register_hot_keys (hwnd
)
3289 Lisp_Object keylist
;
3291 /* Use GC_CONSP, since we are called asynchronously. */
3292 for (keylist
= w32_grabbed_keys
; GC_CONSP (keylist
); keylist
= XCDR (keylist
))
3294 Lisp_Object key
= XCAR (keylist
);
3296 /* Deleted entries get set to nil. */
3297 if (!INTEGERP (key
))
3300 RegisterHotKey (hwnd
, HOTKEY_ID (key
),
3301 HOTKEY_MODIFIERS (key
), HOTKEY_VK_CODE (key
));
3306 unregister_hot_keys (hwnd
)
3309 Lisp_Object keylist
;
3311 /* Use GC_CONSP, since we are called asynchronously. */
3312 for (keylist
= w32_grabbed_keys
; GC_CONSP (keylist
); keylist
= XCDR (keylist
))
3314 Lisp_Object key
= XCAR (keylist
);
3316 if (!INTEGERP (key
))
3319 UnregisterHotKey (hwnd
, HOTKEY_ID (key
));
3324 post_character_message (hwnd
, msg
, wParam
, lParam
, modifiers
)
3334 wmsg
.dwModifiers
= modifiers
;
3336 /* Detect quit_char and set quit-flag directly. Note that we
3337 still need to post a message to ensure the main thread will be
3338 woken up if blocked in sys_select(), but we do NOT want to post
3339 the quit_char message itself (because it will usually be as if
3340 the user had typed quit_char twice). Instead, we post a dummy
3341 message that has no particular effect. */
3344 if (isalpha (c
) && wmsg
.dwModifiers
== ctrl_modifier
)
3345 c
= make_ctrl_char (c
) & 0377;
3350 /* The choice of message is somewhat arbitrary, as long as
3351 the main thread handler just ignores it. */
3354 /* Interrupt any blocking system calls. */
3359 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3362 /* Main message dispatch loop. */
3365 w32_msg_pump (deferred_msg
* msg_buf
)
3371 msh_mousewheel
= RegisterWindowMessage (MSH_MOUSEWHEEL
);
3373 while (GetMessage (&msg
, NULL
, 0, 0))
3375 if (msg
.hwnd
== NULL
)
3377 switch (msg
.message
)
3379 case WM_EMACS_CREATEWINDOW
:
3380 w32_createwindow ((struct frame
*) msg
.wParam
);
3381 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3384 case WM_EMACS_SETLOCALE
:
3385 SetThreadLocale (msg
.wParam
);
3386 /* Reply is not expected. */
3388 case WM_EMACS_SETKEYBOARDLAYOUT
:
3389 result
= (int) ActivateKeyboardLayout ((HKL
) msg
.wParam
, 0);
3390 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
3394 case WM_EMACS_REGISTER_HOT_KEY
:
3395 focus_window
= GetFocus ();
3396 if (focus_window
!= NULL
)
3397 RegisterHotKey (focus_window
,
3398 HOTKEY_ID (msg
.wParam
),
3399 HOTKEY_MODIFIERS (msg
.wParam
),
3400 HOTKEY_VK_CODE (msg
.wParam
));
3401 /* Reply is not expected. */
3403 case WM_EMACS_UNREGISTER_HOT_KEY
:
3404 focus_window
= GetFocus ();
3405 if (focus_window
!= NULL
)
3406 UnregisterHotKey (focus_window
, HOTKEY_ID (msg
.wParam
));
3407 /* Mark item as erased. */
3408 XCAR ((Lisp_Object
) msg
.lParam
) = Qnil
;
3409 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3413 DebPrint (("msg %x not expected by w32_msg_pump\n", msg
.message
));
3418 DispatchMessage (&msg
);
3421 /* Exit nested loop when our deferred message has completed. */
3422 if (msg_buf
->completed
)
3427 deferred_msg
* deferred_msg_head
;
3429 static deferred_msg
*
3430 find_deferred_msg (HWND hwnd
, UINT msg
)
3432 deferred_msg
* item
;
3434 /* Don't actually need synchronization for read access, since
3435 modification of single pointer is always atomic. */
3436 /* enter_crit (); */
3438 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
3439 if (item
->w32msg
.msg
.hwnd
== hwnd
3440 && item
->w32msg
.msg
.message
== msg
)
3443 /* leave_crit (); */
3449 send_deferred_msg (deferred_msg
* msg_buf
,
3455 /* Only input thread can send deferred messages. */
3456 if (GetCurrentThreadId () != dwWindowsThreadId
)
3459 /* It is an error to send a message that is already deferred. */
3460 if (find_deferred_msg (hwnd
, msg
) != NULL
)
3463 /* Enforced synchronization is not needed because this is the only
3464 function that alters deferred_msg_head, and the following critical
3465 section is guaranteed to only be serially reentered (since only the
3466 input thread can call us). */
3468 /* enter_crit (); */
3470 msg_buf
->completed
= 0;
3471 msg_buf
->next
= deferred_msg_head
;
3472 deferred_msg_head
= msg_buf
;
3473 my_post_msg (&msg_buf
->w32msg
, hwnd
, msg
, wParam
, lParam
);
3475 /* leave_crit (); */
3477 /* Start a new nested message loop to process other messages until
3478 this one is completed. */
3479 w32_msg_pump (msg_buf
);
3481 deferred_msg_head
= msg_buf
->next
;
3483 return msg_buf
->result
;
3487 complete_deferred_msg (HWND hwnd
, UINT msg
, LRESULT result
)
3489 deferred_msg
* msg_buf
= find_deferred_msg (hwnd
, msg
);
3491 if (msg_buf
== NULL
)
3494 msg_buf
->result
= result
;
3495 msg_buf
->completed
= 1;
3497 /* Ensure input thread is woken so it notices the completion. */
3498 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
3507 deferred_msg dummy_buf
;
3509 /* Ensure our message queue is created */
3511 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
3513 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3516 memset (&dummy_buf
, 0, sizeof (dummy_buf
));
3517 dummy_buf
.w32msg
.msg
.hwnd
= NULL
;
3518 dummy_buf
.w32msg
.msg
.message
= WM_NULL
;
3520 /* This is the inital message loop which should only exit when the
3521 application quits. */
3522 w32_msg_pump (&dummy_buf
);
3527 /* Main window procedure */
3530 w32_wnd_proc (hwnd
, msg
, wParam
, lParam
)
3537 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
3539 int windows_translate
;
3541 /* Note that it is okay to call x_window_to_frame, even though we are
3542 not running in the main lisp thread, because frame deletion
3543 requires the lisp thread to synchronize with this thread. Thus, if
3544 a frame struct is returned, it can be used without concern that the
3545 lisp thread might make it disappear while we are using it.
3547 NB. Walking the frame list in this thread is safe (as long as
3548 writes of Lisp_Object slots are atomic, which they are on Windows).
3549 Although delete-frame can destructively modify the frame list while
3550 we are walking it, a garbage collection cannot occur until after
3551 delete-frame has synchronized with this thread.
3553 It is also safe to use functions that make GDI calls, such as
3554 w32_clear_rect, because these functions must obtain a DC handle
3555 from the frame struct using get_frame_dc which is thread-aware. */
3560 f
= x_window_to_frame (dpyinfo
, hwnd
);
3563 GetUpdateRect (hwnd
, &wmsg
.rect
, FALSE
);
3564 w32_clear_rect (f
, NULL
, &wmsg
.rect
);
3567 case WM_PALETTECHANGED
:
3568 /* ignore our own changes */
3569 if ((HWND
)wParam
!= hwnd
)
3571 f
= x_window_to_frame (dpyinfo
, hwnd
);
3573 /* get_frame_dc will realize our palette and force all
3574 frames to be redrawn if needed. */
3575 release_frame_dc (f
, get_frame_dc (f
));
3580 PAINTSTRUCT paintStruct
;
3583 BeginPaint (hwnd
, &paintStruct
);
3584 wmsg
.rect
= paintStruct
.rcPaint
;
3585 EndPaint (hwnd
, &paintStruct
);
3588 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3593 case WM_INPUTLANGCHANGE
:
3594 /* Inform lisp thread of keyboard layout changes. */
3595 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3597 /* Clear dead keys in the keyboard state; for simplicity only
3598 preserve modifier key states. */
3603 GetKeyboardState (keystate
);
3604 for (i
= 0; i
< 256; i
++)
3621 SetKeyboardState (keystate
);
3626 /* Synchronize hot keys with normal input. */
3627 PostMessage (hwnd
, WM_KEYDOWN
, HIWORD (lParam
), 0);
3632 record_keyup (wParam
, lParam
);
3637 /* Ignore keystrokes we fake ourself; see below. */
3638 if (dpyinfo
->faked_key
== wParam
)
3640 dpyinfo
->faked_key
= 0;
3644 /* Synchronize modifiers with current keystroke. */
3646 record_keydown (wParam
, lParam
);
3647 wParam
= map_keypad_keys (wParam
, (lParam
& 0x1000000L
) != 0);
3649 windows_translate
= 0;
3654 if (NILP (Vw32_pass_lwindow_to_system
))
3656 /* Prevent system from acting on keyup (which opens the
3657 Start menu if no other key was pressed) by simulating a
3658 press of Space which we will ignore. */
3659 if (GetAsyncKeyState (wParam
) & 1)
3661 dpyinfo
->faked_key
= VK_SPACE
;
3662 keybd_event (VK_SPACE
,
3663 (BYTE
) MapVirtualKey (VK_SPACE
, 0), 0, 0);
3666 if (!NILP (Vw32_lwindow_modifier
))
3670 if (NILP (Vw32_pass_rwindow_to_system
))
3672 if (GetAsyncKeyState (wParam
) & 1)
3674 dpyinfo
->faked_key
= VK_SPACE
;
3675 keybd_event (VK_SPACE
,
3676 (BYTE
) MapVirtualKey (VK_SPACE
, 0), 0, 0);
3679 if (!NILP (Vw32_rwindow_modifier
))
3683 if (!NILP (Vw32_apps_modifier
))
3687 if (NILP (Vw32_pass_alt_to_system
))
3689 windows_translate
= 1;
3692 /* Decide whether to treat as modifier or function key. */
3693 if (NILP (Vw32_enable_caps_lock
))
3694 goto disable_lock_key
;
3697 /* Decide whether to treat as modifier or function key. */
3698 if (NILP (Vw32_enable_num_lock
))
3699 goto disable_lock_key
;
3702 /* Decide whether to treat as modifier or function key. */
3703 if (NILP (Vw32_scroll_lock_modifier
))
3704 goto disable_lock_key
;
3707 /* Ensure the appropriate lock key state is off (and the
3708 indicator light as well). */
3709 if (GetAsyncKeyState (wParam
) & 0x8000)
3711 /* Fake another press of the relevant key. Apparently,
3712 this really is the only way to turn off the indicator. */
3713 dpyinfo
->faked_key
= wParam
;
3714 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3715 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3716 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3717 KEYEVENTF_EXTENDEDKEY
| 0, 0);
3718 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3719 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3724 case VK_PROCESSKEY
: /* Generated by IME. */
3725 windows_translate
= 1;
3728 /* If not defined as a function key, change it to a WM_CHAR message. */
3729 if (lispy_function_keys
[wParam
] == 0)
3731 if (!NILP (Vw32_recognize_altgr
)
3732 && modifier_set (VK_LCONTROL
) && modifier_set (VK_RMENU
))
3734 /* Always let TranslateMessage handle AltGr key chords;
3735 for some reason, ToAscii doesn't always process AltGr
3736 chords correctly. */
3737 windows_translate
= 1;
3739 else if (modifier_set (VK_CONTROL
) || modifier_set (VK_MENU
))
3741 /* Handle key chords including any modifiers other than shift
3742 directly, in order to preserve as much modifier information as
3744 if ('A' <= wParam
&& wParam
<= 'Z')
3746 /* Don't translate modified alphabetic keystrokes,
3747 so the user doesn't need to constantly switch
3748 layout to type control or meta keystrokes when
3749 the normal layout translates alphabetic
3750 characters to non-ascii characters. */
3751 if (!modifier_set (VK_SHIFT
))
3752 wParam
+= ('a' - 'A');
3757 /* Try to handle other keystrokes by determining the
3758 base character (ie. translating the base key plus
3762 KEY_EVENT_RECORD key
;
3764 key
.bKeyDown
= TRUE
;
3765 key
.wRepeatCount
= 1;
3766 key
.wVirtualKeyCode
= wParam
;
3767 key
.wVirtualScanCode
= (lParam
& 0xFF0000) >> 16;
3768 key
.uChar
.AsciiChar
= 0;
3769 key
.dwControlKeyState
= construct_console_modifiers ();
3771 add
= w32_kbd_patch_key (&key
);
3772 /* 0 means an unrecognised keycode, negative means
3773 dead key. Ignore both. */
3776 /* Forward asciified character sequence. */
3777 post_character_message
3778 (hwnd
, WM_CHAR
, key
.uChar
.AsciiChar
, lParam
,
3779 w32_get_key_modifiers (wParam
, lParam
));
3780 w32_kbd_patch_key (&key
);
3787 /* Let TranslateMessage handle everything else. */
3788 windows_translate
= 1;
3793 if (windows_translate
)
3795 MSG windows_msg
= { hwnd
, msg
, wParam
, lParam
, 0, {0,0} };
3797 windows_msg
.time
= GetMessageTime ();
3798 TranslateMessage (&windows_msg
);
3806 post_character_message (hwnd
, msg
, wParam
, lParam
,
3807 w32_get_key_modifiers (wParam
, lParam
));
3810 /* Simulate middle mouse button events when left and right buttons
3811 are used together, but only if user has two button mouse. */
3812 case WM_LBUTTONDOWN
:
3813 case WM_RBUTTONDOWN
:
3814 if (XINT (Vw32_num_mouse_buttons
) == 3)
3815 goto handle_plain_button
;
3818 int this = (msg
== WM_LBUTTONDOWN
) ? LMOUSE
: RMOUSE
;
3819 int other
= (msg
== WM_LBUTTONDOWN
) ? RMOUSE
: LMOUSE
;
3821 if (button_state
& this)
3824 if (button_state
== 0)
3827 button_state
|= this;
3829 if (button_state
& other
)
3831 if (mouse_button_timer
)
3833 KillTimer (hwnd
, mouse_button_timer
);
3834 mouse_button_timer
= 0;
3836 /* Generate middle mouse event instead. */
3837 msg
= WM_MBUTTONDOWN
;
3838 button_state
|= MMOUSE
;
3840 else if (button_state
& MMOUSE
)
3842 /* Ignore button event if we've already generated a
3843 middle mouse down event. This happens if the
3844 user releases and press one of the two buttons
3845 after we've faked a middle mouse event. */
3850 /* Flush out saved message. */
3851 post_msg (&saved_mouse_button_msg
);
3853 wmsg
.dwModifiers
= w32_get_modifiers ();
3854 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3856 /* Clear message buffer. */
3857 saved_mouse_button_msg
.msg
.hwnd
= 0;
3861 /* Hold onto message for now. */
3862 mouse_button_timer
=
3863 SetTimer (hwnd
, MOUSE_BUTTON_ID
, XINT (Vw32_mouse_button_tolerance
), NULL
);
3864 saved_mouse_button_msg
.msg
.hwnd
= hwnd
;
3865 saved_mouse_button_msg
.msg
.message
= msg
;
3866 saved_mouse_button_msg
.msg
.wParam
= wParam
;
3867 saved_mouse_button_msg
.msg
.lParam
= lParam
;
3868 saved_mouse_button_msg
.msg
.time
= GetMessageTime ();
3869 saved_mouse_button_msg
.dwModifiers
= w32_get_modifiers ();
3876 if (XINT (Vw32_num_mouse_buttons
) == 3)
3877 goto handle_plain_button
;
3880 int this = (msg
== WM_LBUTTONUP
) ? LMOUSE
: RMOUSE
;
3881 int other
= (msg
== WM_LBUTTONUP
) ? RMOUSE
: LMOUSE
;
3883 if ((button_state
& this) == 0)
3886 button_state
&= ~this;
3888 if (button_state
& MMOUSE
)
3890 /* Only generate event when second button is released. */
3891 if ((button_state
& other
) == 0)
3894 button_state
&= ~MMOUSE
;
3896 if (button_state
) abort ();
3903 /* Flush out saved message if necessary. */
3904 if (saved_mouse_button_msg
.msg
.hwnd
)
3906 post_msg (&saved_mouse_button_msg
);
3909 wmsg
.dwModifiers
= w32_get_modifiers ();
3910 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3912 /* Always clear message buffer and cancel timer. */
3913 saved_mouse_button_msg
.msg
.hwnd
= 0;
3914 KillTimer (hwnd
, mouse_button_timer
);
3915 mouse_button_timer
= 0;
3917 if (button_state
== 0)
3922 case WM_MBUTTONDOWN
:
3924 handle_plain_button
:
3929 if (parse_button (msg
, &button
, &up
))
3931 if (up
) ReleaseCapture ();
3932 else SetCapture (hwnd
);
3933 button
= (button
== 0) ? LMOUSE
:
3934 ((button
== 1) ? MMOUSE
: RMOUSE
);
3936 button_state
&= ~button
;
3938 button_state
|= button
;
3942 wmsg
.dwModifiers
= w32_get_modifiers ();
3943 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3948 if (XINT (Vw32_mouse_move_interval
) <= 0
3949 || (msg
== WM_MOUSEMOVE
&& button_state
== 0))
3951 wmsg
.dwModifiers
= w32_get_modifiers ();
3952 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3956 /* Hang onto mouse move and scroll messages for a bit, to avoid
3957 sending such events to Emacs faster than it can process them.
3958 If we get more events before the timer from the first message
3959 expires, we just replace the first message. */
3961 if (saved_mouse_move_msg
.msg
.hwnd
== 0)
3963 SetTimer (hwnd
, MOUSE_MOVE_ID
, XINT (Vw32_mouse_move_interval
), NULL
);
3965 /* Hold onto message for now. */
3966 saved_mouse_move_msg
.msg
.hwnd
= hwnd
;
3967 saved_mouse_move_msg
.msg
.message
= msg
;
3968 saved_mouse_move_msg
.msg
.wParam
= wParam
;
3969 saved_mouse_move_msg
.msg
.lParam
= lParam
;
3970 saved_mouse_move_msg
.msg
.time
= GetMessageTime ();
3971 saved_mouse_move_msg
.dwModifiers
= w32_get_modifiers ();
3976 wmsg
.dwModifiers
= w32_get_modifiers ();
3977 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3981 wmsg
.dwModifiers
= w32_get_modifiers ();
3982 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3986 /* Flush out saved messages if necessary. */
3987 if (wParam
== mouse_button_timer
)
3989 if (saved_mouse_button_msg
.msg
.hwnd
)
3991 post_msg (&saved_mouse_button_msg
);
3992 saved_mouse_button_msg
.msg
.hwnd
= 0;
3994 KillTimer (hwnd
, mouse_button_timer
);
3995 mouse_button_timer
= 0;
3997 else if (wParam
== mouse_move_timer
)
3999 if (saved_mouse_move_msg
.msg
.hwnd
)
4001 post_msg (&saved_mouse_move_msg
);
4002 saved_mouse_move_msg
.msg
.hwnd
= 0;
4004 KillTimer (hwnd
, mouse_move_timer
);
4005 mouse_move_timer
= 0;
4010 /* Windows doesn't send us focus messages when putting up and
4011 taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
4012 The only indication we get that something happened is receiving
4013 this message afterwards. So this is a good time to reset our
4014 keyboard modifiers' state. */
4019 /* We must ensure menu bar is fully constructed and up to date
4020 before allowing user interaction with it. To achieve this
4021 we send this message to the lisp thread and wait for a
4022 reply (whose value is not actually needed) to indicate that
4023 the menu bar is now ready for use, so we can now return.
4025 To remain responsive in the meantime, we enter a nested message
4026 loop that can process all other messages.
4028 However, we skip all this if the message results from calling
4029 TrackPopupMenu - in fact, we must NOT attempt to send the lisp
4030 thread a message because it is blocked on us at this point. We
4031 set menubar_active before calling TrackPopupMenu to indicate
4032 this (there is no possibility of confusion with real menubar
4035 f
= x_window_to_frame (dpyinfo
, hwnd
);
4037 && (f
->output_data
.w32
->menubar_active
4038 /* We can receive this message even in the absence of a
4039 menubar (ie. when the system menu is activated) - in this
4040 case we do NOT want to forward the message, otherwise it
4041 will cause the menubar to suddenly appear when the user
4042 had requested it to be turned off! */
4043 || f
->output_data
.w32
->menubar_widget
== NULL
))
4047 deferred_msg msg_buf
;
4049 /* Detect if message has already been deferred; in this case
4050 we cannot return any sensible value to ignore this. */
4051 if (find_deferred_msg (hwnd
, msg
) != NULL
)
4054 return send_deferred_msg (&msg_buf
, hwnd
, msg
, wParam
, lParam
);
4057 case WM_EXITMENULOOP
:
4058 f
= x_window_to_frame (dpyinfo
, hwnd
);
4060 /* Indicate that menubar can be modified again. */
4062 f
->output_data
.w32
->menubar_active
= 0;
4065 case WM_MEASUREITEM
:
4066 f
= x_window_to_frame (dpyinfo
, hwnd
);
4069 MEASUREITEMSTRUCT
* pMis
= (MEASUREITEMSTRUCT
*) lParam
;
4071 if (pMis
->CtlType
== ODT_MENU
)
4073 /* Work out dimensions for popup menu titles. */
4074 char * title
= (char *) pMis
->itemData
;
4075 HDC hdc
= GetDC (hwnd
);
4076 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4077 LOGFONT menu_logfont
;
4081 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4082 menu_logfont
.lfWeight
= FW_BOLD
;
4083 menu_font
= CreateFontIndirect (&menu_logfont
);
4084 old_font
= SelectObject (hdc
, menu_font
);
4086 GetTextExtentPoint32 (hdc
, title
, strlen (title
), &size
);
4087 pMis
->itemWidth
= size
.cx
;
4088 pMis
->itemHeight
= GetSystemMetrics (SM_CYMENUSIZE
);
4089 if (pMis
->itemHeight
< size
.cy
)
4090 pMis
->itemHeight
= size
.cy
;
4092 SelectObject (hdc
, old_font
);
4093 DeleteObject (menu_font
);
4094 ReleaseDC (hwnd
, hdc
);
4101 f
= x_window_to_frame (dpyinfo
, hwnd
);
4104 DRAWITEMSTRUCT
* pDis
= (DRAWITEMSTRUCT
*) lParam
;
4106 if (pDis
->CtlType
== ODT_MENU
)
4108 /* Draw popup menu title. */
4109 char * title
= (char *) pDis
->itemData
;
4110 HDC hdc
= pDis
->hDC
;
4111 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4112 LOGFONT menu_logfont
;
4115 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4116 menu_logfont
.lfWeight
= FW_BOLD
;
4117 menu_font
= CreateFontIndirect (&menu_logfont
);
4118 old_font
= SelectObject (hdc
, menu_font
);
4120 /* Always draw title as if not selected. */
4122 pDis
->rcItem
.left
+ GetSystemMetrics (SM_CXMENUCHECK
),
4124 ETO_OPAQUE
, &pDis
->rcItem
,
4125 title
, strlen (title
), NULL
);
4127 SelectObject (hdc
, old_font
);
4128 DeleteObject (menu_font
);
4135 /* Still not right - can't distinguish between clicks in the
4136 client area of the frame from clicks forwarded from the scroll
4137 bars - may have to hook WM_NCHITTEST to remember the mouse
4138 position and then check if it is in the client area ourselves. */
4139 case WM_MOUSEACTIVATE
:
4140 /* Discard the mouse click that activates a frame, allowing the
4141 user to click anywhere without changing point (or worse!).
4142 Don't eat mouse clicks on scrollbars though!! */
4143 if (LOWORD (lParam
) == HTCLIENT
)
4144 return MA_ACTIVATEANDEAT
;
4148 case WM_ACTIVATEAPP
:
4149 dpyinfo
->faked_key
= 0;
4152 case WM_WINDOWPOSCHANGED
:
4154 /* Inform lisp thread that a frame might have just been obscured
4155 or exposed, so should recheck visibility of all frames. */
4156 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4160 register_hot_keys (hwnd
);
4163 unregister_hot_keys (hwnd
);
4168 wmsg
.dwModifiers
= w32_get_modifiers ();
4169 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4173 wmsg
.dwModifiers
= w32_get_modifiers ();
4174 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4177 case WM_WINDOWPOSCHANGING
:
4180 LPWINDOWPOS lppos
= (WINDOWPOS
*) lParam
;
4182 wp
.length
= sizeof (WINDOWPLACEMENT
);
4183 GetWindowPlacement (hwnd
, &wp
);
4185 if (wp
.showCmd
!= SW_SHOWMINIMIZED
&& (lppos
->flags
& SWP_NOSIZE
) == 0)
4192 DWORD internal_border
;
4193 DWORD scrollbar_extra
;
4196 wp
.length
= sizeof(wp
);
4197 GetWindowRect (hwnd
, &wr
);
4201 font_width
= GetWindowLong (hwnd
, WND_FONTWIDTH_INDEX
);
4202 line_height
= GetWindowLong (hwnd
, WND_LINEHEIGHT_INDEX
);
4203 internal_border
= GetWindowLong (hwnd
, WND_BORDER_INDEX
);
4204 scrollbar_extra
= GetWindowLong (hwnd
, WND_SCROLLBAR_INDEX
);
4208 memset (&rect
, 0, sizeof (rect
));
4209 AdjustWindowRect (&rect
, GetWindowLong (hwnd
, GWL_STYLE
),
4210 GetMenu (hwnd
) != NULL
);
4212 /* Force width and height of client area to be exact
4213 multiples of the character cell dimensions. */
4214 wdiff
= (lppos
->cx
- (rect
.right
- rect
.left
)
4215 - 2 * internal_border
- scrollbar_extra
)
4217 hdiff
= (lppos
->cy
- (rect
.bottom
- rect
.top
)
4218 - 2 * internal_border
)
4223 /* For right/bottom sizing we can just fix the sizes.
4224 However for top/left sizing we will need to fix the X
4225 and Y positions as well. */
4230 if (wp
.showCmd
!= SW_SHOWMAXIMIZED
4231 && (lppos
->flags
& SWP_NOMOVE
) == 0)
4233 if (lppos
->x
!= wr
.left
|| lppos
->y
!= wr
.top
)
4240 lppos
->flags
|= SWP_NOMOVE
;
4251 case WM_EMACS_CREATESCROLLBAR
:
4252 return (LRESULT
) w32_createscrollbar ((struct frame
*) wParam
,
4253 (struct scroll_bar
*) lParam
);
4255 case WM_EMACS_SHOWWINDOW
:
4256 return ShowWindow ((HWND
) wParam
, (WPARAM
) lParam
);
4258 case WM_EMACS_SETFOREGROUND
:
4259 return SetForegroundWindow ((HWND
) wParam
);
4261 case WM_EMACS_SETWINDOWPOS
:
4263 WINDOWPOS
* pos
= (WINDOWPOS
*) wParam
;
4264 return SetWindowPos (hwnd
, pos
->hwndInsertAfter
,
4265 pos
->x
, pos
->y
, pos
->cx
, pos
->cy
, pos
->flags
);
4268 case WM_EMACS_DESTROYWINDOW
:
4269 DragAcceptFiles ((HWND
) wParam
, FALSE
);
4270 return DestroyWindow ((HWND
) wParam
);
4272 case WM_EMACS_TRACKPOPUPMENU
:
4277 pos
= (POINT
*)lParam
;
4278 flags
= TPM_CENTERALIGN
;
4279 if (button_state
& LMOUSE
)
4280 flags
|= TPM_LEFTBUTTON
;
4281 else if (button_state
& RMOUSE
)
4282 flags
|= TPM_RIGHTBUTTON
;
4284 /* Remember we did a SetCapture on the initial mouse down event,
4285 so for safety, we make sure the capture is cancelled now. */
4289 /* Use menubar_active to indicate that WM_INITMENU is from
4290 TrackPopupMenu below, and should be ignored. */
4291 f
= x_window_to_frame (dpyinfo
, hwnd
);
4293 f
->output_data
.w32
->menubar_active
= 1;
4295 if (TrackPopupMenu ((HMENU
)wParam
, flags
, pos
->x
, pos
->y
,
4299 /* Eat any mouse messages during popupmenu */
4300 while (PeekMessage (&amsg
, hwnd
, WM_MOUSEFIRST
, WM_MOUSELAST
,
4302 /* Get the menu selection, if any */
4303 if (PeekMessage (&amsg
, hwnd
, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
))
4305 retval
= LOWORD (amsg
.wParam
);
4321 /* Check for messages registered at runtime. */
4322 if (msg
== msh_mousewheel
)
4324 wmsg
.dwModifiers
= w32_get_modifiers ();
4325 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4330 return DefWindowProc (hwnd
, msg
, wParam
, lParam
);
4334 /* The most common default return code for handled messages is 0. */
4339 my_create_window (f
)
4344 if (!PostThreadMessage (dwWindowsThreadId
, WM_EMACS_CREATEWINDOW
, (WPARAM
)f
, 0))
4346 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
4349 /* Create and set up the w32 window for frame F. */
4352 w32_window (f
, window_prompting
, minibuffer_only
)
4354 long window_prompting
;
4355 int minibuffer_only
;
4359 /* Use the resource name as the top-level window name
4360 for looking up resources. Make a non-Lisp copy
4361 for the window manager, so GC relocation won't bother it.
4363 Elsewhere we specify the window name for the window manager. */
4366 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
4367 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
4368 strcpy (f
->namebuf
, str
);
4371 my_create_window (f
);
4373 validate_x_resource_name ();
4375 /* x_set_name normally ignores requests to set the name if the
4376 requested name is the same as the current name. This is the one
4377 place where that assumption isn't correct; f->name is set, but
4378 the server hasn't been told. */
4381 int explicit = f
->explicit_name
;
4383 f
->explicit_name
= 0;
4386 x_set_name (f
, name
, explicit);
4391 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
4392 initialize_frame_menubar (f
);
4394 if (FRAME_W32_WINDOW (f
) == 0)
4395 error ("Unable to create window");
4398 /* Handle the icon stuff for this window. Perhaps later we might
4399 want an x_set_icon_position which can be called interactively as
4407 Lisp_Object icon_x
, icon_y
;
4409 /* Set the position of the icon. Note that Windows 95 groups all
4410 icons in the tray. */
4411 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
4412 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
4413 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
4415 CHECK_NUMBER (icon_x
, 0);
4416 CHECK_NUMBER (icon_y
, 0);
4418 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
4419 error ("Both left and top icon corners of icon must be specified");
4423 if (! EQ (icon_x
, Qunbound
))
4424 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
4427 /* Start up iconic or window? */
4428 x_wm_set_window_state
4429 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
4433 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
4441 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
4443 "Make a new window, which is called a \"frame\" in Emacs terms.\n\
4444 Returns an Emacs frame object.\n\
4445 ALIST is an alist of frame parameters.\n\
4446 If the parameters specify that the frame should not have a minibuffer,\n\
4447 and do not specify a specific minibuffer window to use,\n\
4448 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
4449 be shared by the new frame.\n\
4451 This function is an internal primitive--use `make-frame' instead.")
4456 Lisp_Object frame
, tem
;
4458 int minibuffer_only
= 0;
4459 long window_prompting
= 0;
4461 int count
= specpdl_ptr
- specpdl
;
4462 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
4463 Lisp_Object display
;
4464 struct w32_display_info
*dpyinfo
;
4470 /* Use this general default value to start with
4471 until we know if this frame has a specified name. */
4472 Vx_resource_name
= Vinvocation_name
;
4474 display
= x_get_arg (parms
, Qdisplay
, 0, 0, string
);
4475 if (EQ (display
, Qunbound
))
4477 dpyinfo
= check_x_display_info (display
);
4479 kb
= dpyinfo
->kboard
;
4481 kb
= &the_only_kboard
;
4484 name
= x_get_arg (parms
, Qname
, "name", "Name", string
);
4486 && ! EQ (name
, Qunbound
)
4488 error ("Invalid frame name--not a string or nil");
4491 Vx_resource_name
= name
;
4493 /* See if parent window is specified. */
4494 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
4495 if (EQ (parent
, Qunbound
))
4497 if (! NILP (parent
))
4498 CHECK_NUMBER (parent
, 0);
4500 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
4501 /* No need to protect DISPLAY because that's not used after passing
4502 it to make_frame_without_minibuffer. */
4504 GCPRO4 (parms
, parent
, name
, frame
);
4505 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
4506 if (EQ (tem
, Qnone
) || NILP (tem
))
4507 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
4508 else if (EQ (tem
, Qonly
))
4510 f
= make_minibuffer_frame ();
4511 minibuffer_only
= 1;
4513 else if (WINDOWP (tem
))
4514 f
= make_frame_without_minibuffer (tem
, kb
, display
);
4518 XSETFRAME (frame
, f
);
4520 /* Note that Windows does support scroll bars. */
4521 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
4522 /* By default, make scrollbars the system standard width. */
4523 f
->scroll_bar_pixel_width
= GetSystemMetrics (SM_CXVSCROLL
);
4525 f
->output_method
= output_w32
;
4526 f
->output_data
.w32
= (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
4527 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
4529 FRAME_FONTSET (f
) = -1;
4532 = x_get_arg (parms
, Qicon_name
, "iconName", "Title", string
);
4533 if (! STRINGP (f
->icon_name
))
4534 f
->icon_name
= Qnil
;
4536 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
4538 FRAME_KBOARD (f
) = kb
;
4541 /* Specify the parent under which to make this window. */
4545 f
->output_data
.w32
->parent_desc
= (Window
) parent
;
4546 f
->output_data
.w32
->explicit_parent
= 1;
4550 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
4551 f
->output_data
.w32
->explicit_parent
= 0;
4554 /* Note that the frame has no physical cursor right now. */
4555 f
->phys_cursor_x
= -1;
4557 /* Set the name; the functions to which we pass f expect the name to
4559 if (EQ (name
, Qunbound
) || NILP (name
))
4561 f
->name
= build_string (dpyinfo
->w32_id_name
);
4562 f
->explicit_name
= 0;
4567 f
->explicit_name
= 1;
4568 /* use the frame's title when getting resources for this frame. */
4569 specbind (Qx_resource_name
, name
);
4572 /* Create fontsets from `global_fontset_alist' before handling fonts. */
4573 for (tem
= Vglobal_fontset_alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
4574 fs_register_fontset (f
, XCONS (tem
)->car
);
4576 /* Extract the window parameters from the supplied values
4577 that are needed to determine window geometry. */
4581 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
4583 /* First, try whatever font the caller has specified. */
4586 tem
= Fquery_fontset (font
, Qnil
);
4588 font
= x_new_fontset (f
, XSTRING (tem
)->data
);
4590 font
= x_new_font (f
, XSTRING (font
)->data
);
4592 /* Try out a font which we hope has bold and italic variations. */
4593 if (!STRINGP (font
))
4594 font
= x_new_font (f
, "-*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
4595 if (! STRINGP (font
))
4596 font
= x_new_font (f
, "-*-Courier-normal-r-*-*-*-97-*-*-c-*-iso8859-1");
4597 /* If those didn't work, look for something which will at least work. */
4598 if (! STRINGP (font
))
4599 font
= x_new_font (f
, "-*-Fixedsys-normal-r-*-*-*-*-90-*-c-*-iso8859-1");
4601 if (! STRINGP (font
))
4602 font
= build_string ("Fixedsys");
4604 x_default_parameter (f
, parms
, Qfont
, font
,
4605 "font", "Font", string
);
4608 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
4609 "borderwidth", "BorderWidth", number
);
4610 /* This defaults to 2 in order to match xterm. We recognize either
4611 internalBorderWidth or internalBorder (which is what xterm calls
4613 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4617 value
= x_get_arg (parms
, Qinternal_border_width
,
4618 "internalBorder", "BorderWidth", number
);
4619 if (! EQ (value
, Qunbound
))
4620 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
4623 /* Default internalBorderWidth to 0 on Windows to match other programs. */
4624 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
4625 "internalBorderWidth", "BorderWidth", number
);
4626 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
4627 "verticalScrollBars", "ScrollBars", boolean
);
4629 /* Also do the stuff which must be set before the window exists. */
4630 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4631 "foreground", "Foreground", string
);
4632 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4633 "background", "Background", string
);
4634 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4635 "pointerColor", "Foreground", string
);
4636 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4637 "cursorColor", "Foreground", string
);
4638 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4639 "borderColor", "BorderColor", string
);
4641 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
4642 "menuBar", "MenuBar", number
);
4643 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
4644 "scrollBarWidth", "ScrollBarWidth", number
);
4645 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
4646 "bufferPredicate", "BufferPredicate", symbol
);
4647 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
4648 "title", "Title", string
);
4650 f
->output_data
.w32
->dwStyle
= WS_OVERLAPPEDWINDOW
;
4651 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
4652 window_prompting
= x_figure_window_size (f
, parms
);
4654 if (window_prompting
& XNegative
)
4656 if (window_prompting
& YNegative
)
4657 f
->output_data
.w32
->win_gravity
= SouthEastGravity
;
4659 f
->output_data
.w32
->win_gravity
= NorthEastGravity
;
4663 if (window_prompting
& YNegative
)
4664 f
->output_data
.w32
->win_gravity
= SouthWestGravity
;
4666 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
4669 f
->output_data
.w32
->size_hint_flags
= window_prompting
;
4671 w32_window (f
, window_prompting
, minibuffer_only
);
4673 init_frame_faces (f
);
4675 /* We need to do this after creating the window, so that the
4676 icon-creation functions can say whose icon they're describing. */
4677 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
4678 "bitmapIcon", "BitmapIcon", symbol
);
4680 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4681 "autoRaise", "AutoRaiseLower", boolean
);
4682 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4683 "autoLower", "AutoRaiseLower", boolean
);
4684 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4685 "cursorType", "CursorType", symbol
);
4687 /* Dimensions, especially f->height, must be done via change_frame_size.
4688 Change will not be effected unless different from the current
4693 SET_FRAME_WIDTH (f
, 0);
4694 change_frame_size (f
, height
, width
, 1, 0);
4696 /* Tell the server what size and position, etc, we want,
4697 and how badly we want them. */
4699 x_wm_set_size_hint (f
, window_prompting
, 0);
4702 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
4703 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
4707 /* It is now ok to make the frame official
4708 even if we get an error below.
4709 And the frame needs to be on Vframe_list
4710 or making it visible won't work. */
4711 Vframe_list
= Fcons (frame
, Vframe_list
);
4713 /* Now that the frame is official, it counts as a reference to
4715 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
4717 /* Make the window appear on the frame and enable display,
4718 unless the caller says not to. However, with explicit parent,
4719 Emacs cannot control visibility, so don't try. */
4720 if (! f
->output_data
.w32
->explicit_parent
)
4722 Lisp_Object visibility
;
4724 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
4725 if (EQ (visibility
, Qunbound
))
4728 if (EQ (visibility
, Qicon
))
4729 x_iconify_frame (f
);
4730 else if (! NILP (visibility
))
4731 x_make_frame_visible (f
);
4733 /* Must have been Qnil. */
4737 return unbind_to (count
, frame
);
4740 /* FRAME is used only to get a handle on the X display. We don't pass the
4741 display info directly because we're called from frame.c, which doesn't
4742 know about that structure. */
4744 x_get_focus_frame (frame
)
4745 struct frame
*frame
;
4747 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (frame
);
4749 if (! dpyinfo
->w32_focus_frame
)
4752 XSETFRAME (xfocus
, dpyinfo
->w32_focus_frame
);
4756 DEFUN ("w32-focus-frame", Fw32_focus_frame
, Sw32_focus_frame
, 1, 1, 0,
4757 "Give FRAME input focus, raising to foreground if necessary.")
4761 x_focus_on_frame (check_x_frame (frame
));
4766 /* Load font named FONTNAME of size SIZE for frame F, and return a
4767 pointer to the structure font_info while allocating it dynamically.
4768 If loading fails, return NULL. */
4770 w32_load_font (f
,fontname
,size
)
4775 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
4776 Lisp_Object font_names
;
4778 #if 0 /* x_load_font attempts to get a list of fonts - presumably to
4779 allow a fuzzier fontname to be specified. w32_list_fonts
4780 appears to be a bit too fuzzy for this purpose. */
4782 /* Get a list of all the fonts that match this name. Once we
4783 have a list of matching fonts, we compare them against the fonts
4784 we already have loaded by comparing names. */
4785 font_names
= w32_list_fonts (f
, build_string (fontname
), size
, 100);
4787 if (!NILP (font_names
))
4792 #if 0 /* This code has nasty side effects that cause Emacs to crash. */
4794 /* First check if any are already loaded, as that is cheaper
4795 than loading another one. */
4796 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4797 for (tail
= font_names
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4798 if (!strcmp (dpyinfo
->font_table
[i
].name
,
4799 XSTRING (XCONS (tail
)->car
)->data
)
4800 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
4801 XSTRING (XCONS (tail
)->car
)->data
))
4802 return (dpyinfo
->font_table
+ i
);
4805 fontname
= (char *) XSTRING (XCONS (font_names
)->car
)->data
;
4811 /* Load the font and add it to the table. */
4815 struct font_info
*fontp
;
4819 if (!fontname
|| !x_to_w32_font (fontname
, &lf
))
4822 if (!*lf
.lfFaceName
)
4823 /* If no name was specified for the font, we get a random font
4824 from CreateFontIndirect - this is not particularly
4825 desirable, especially since CreateFontIndirect does not
4826 fill out the missing name in lf, so we never know what we
4830 font
= (XFontStruct
*) xmalloc (sizeof (XFontStruct
));
4832 if (!font
) return (NULL
);
4836 font
->hfont
= CreateFontIndirect (&lf
);
4838 if (font
->hfont
== NULL
)
4847 hdc
= GetDC (dpyinfo
->root_window
);
4848 oldobj
= SelectObject (hdc
, font
->hfont
);
4849 ok
= GetTextMetrics (hdc
, &font
->tm
);
4850 SelectObject (hdc
, oldobj
);
4851 ReleaseDC (dpyinfo
->root_window
, hdc
);
4858 w32_unload_font (dpyinfo
, font
);
4862 /* Do we need to create the table? */
4863 if (dpyinfo
->font_table_size
== 0)
4865 dpyinfo
->font_table_size
= 16;
4867 = (struct font_info
*) xmalloc (dpyinfo
->font_table_size
4868 * sizeof (struct font_info
));
4870 /* Do we need to grow the table? */
4871 else if (dpyinfo
->n_fonts
4872 >= dpyinfo
->font_table_size
)
4874 dpyinfo
->font_table_size
*= 2;
4876 = (struct font_info
*) xrealloc (dpyinfo
->font_table
,
4877 (dpyinfo
->font_table_size
4878 * sizeof (struct font_info
)));
4881 fontp
= dpyinfo
->font_table
+ dpyinfo
->n_fonts
;
4883 /* Now fill in the slots of *FONTP. */
4886 fontp
->font_idx
= dpyinfo
->n_fonts
;
4887 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
4888 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
4890 /* Work out the font's full name. */
4891 full_name
= (char *)xmalloc (100);
4892 if (full_name
&& w32_to_x_font (&lf
, full_name
, 100))
4893 fontp
->full_name
= full_name
;
4896 /* If all else fails - just use the name we used to load it. */
4898 fontp
->full_name
= fontp
->name
;
4901 fontp
->size
= FONT_WIDTH (font
);
4902 fontp
->height
= FONT_HEIGHT (font
);
4904 /* The slot `encoding' specifies how to map a character
4905 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
4906 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
4907 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
4908 0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
4909 2:0xA020..0xFF7F). For the moment, we don't know which charset
4910 uses this font. So, we set informatoin in fontp->encoding[1]
4911 which is never used by any charset. If mapping can't be
4912 decided, set FONT_ENCODING_NOT_DECIDED. */
4913 fontp
->encoding
[1] = FONT_ENCODING_NOT_DECIDED
;
4915 /* The following three values are set to 0 under W32, which is
4916 what they get set to if XGetFontProperty fails under X. */
4917 fontp
->baseline_offset
= 0;
4918 fontp
->relative_compose
= 0;
4919 fontp
->default_ascent
= FONT_BASE (font
);
4929 w32_unload_font (dpyinfo
, font
)
4930 struct w32_display_info
*dpyinfo
;
4935 if (font
->hfont
) DeleteObject(font
->hfont
);
4940 /* The font conversion stuff between x and w32 */
4942 /* X font string is as follows (from faces.el)
4946 * (weight "\\(bold\\|demibold\\|medium\\)") ; 1
4947 * (weight\? "\\([^-]*\\)") ; 1
4948 * (slant "\\([ior]\\)") ; 2
4949 * (slant\? "\\([^-]?\\)") ; 2
4950 * (swidth "\\([^-]*\\)") ; 3
4951 * (adstyle "[^-]*") ; 4
4952 * (pixelsize "[0-9]+")
4953 * (pointsize "[0-9][0-9]+")
4954 * (resx "[0-9][0-9]+")
4955 * (resy "[0-9][0-9]+")
4956 * (spacing "[cmp?*]")
4957 * (avgwidth "[0-9]+")
4958 * (registry "[^-]+")
4959 * (encoding "[^-]+")
4961 * (setq x-font-regexp
4962 * (concat "\\`\\*?[-?*]"
4963 * foundry - family - weight\? - slant\? - swidth - adstyle -
4964 * pixelsize - pointsize - resx - resy - spacing - registry -
4965 * encoding "[-?*]\\*?\\'"
4967 * (setq x-font-regexp-head
4968 * (concat "\\`[-?*]" foundry - family - weight\? - slant\?
4969 * "\\([-*?]\\|\\'\\)"))
4970 * (setq x-font-regexp-slant (concat - slant -))
4971 * (setq x-font-regexp-weight (concat - weight -))
4975 #define FONT_START "[-?]"
4976 #define FONT_FOUNDRY "[^-]+"
4977 #define FONT_FAMILY "\\([^-]+\\)" /* 1 */
4978 #define FONT_WEIGHT "\\(bold\\|demibold\\|medium\\)" /* 2 */
4979 #define FONT_WEIGHT_Q "\\([^-]*\\)" /* 2 */
4980 #define FONT_SLANT "\\([ior]\\)" /* 3 */
4981 #define FONT_SLANT_Q "\\([^-]?\\)" /* 3 */
4982 #define FONT_SWIDTH "\\([^-]*\\)" /* 4 */
4983 #define FONT_ADSTYLE "[^-]*"
4984 #define FONT_PIXELSIZE "[^-]*"
4985 #define FONT_POINTSIZE "\\([0-9][0-9]+\\|\\*\\)" /* 5 */
4986 #define FONT_RESX "[0-9][0-9]+"
4987 #define FONT_RESY "[0-9][0-9]+"
4988 #define FONT_SPACING "[cmp?*]"
4989 #define FONT_AVGWIDTH "[0-9]+"
4990 #define FONT_REGISTRY "[^-]+"
4991 #define FONT_ENCODING "[^-]+"
4993 #define FONT_REGEXP ("\\`\\*?[-?*]" \
5000 FONT_PIXELSIZE "-" \
5001 FONT_POINTSIZE "-" \
5004 #define FONT_REGEXP_HEAD ("\\`[-?*]" \
5009 "\\([-*?]\\|\\'\\)")
5011 #define FONT_REGEXP_SLANT "-" FONT_SLANT "-"
5012 #define FONT_REGEXP_WEIGHT "-" FONT_WEIGHT "-"
5015 x_to_w32_weight (lpw
)
5018 if (!lpw
) return (FW_DONTCARE
);
5020 if (stricmp (lpw
,"heavy") == 0) return FW_HEAVY
;
5021 else if (stricmp (lpw
,"extrabold") == 0) return FW_EXTRABOLD
;
5022 else if (stricmp (lpw
,"bold") == 0) return FW_BOLD
;
5023 else if (stricmp (lpw
,"demibold") == 0) return FW_SEMIBOLD
;
5024 else if (stricmp (lpw
,"semibold") == 0) return FW_SEMIBOLD
;
5025 else if (stricmp (lpw
,"medium") == 0) return FW_MEDIUM
;
5026 else if (stricmp (lpw
,"normal") == 0) return FW_NORMAL
;
5027 else if (stricmp (lpw
,"light") == 0) return FW_LIGHT
;
5028 else if (stricmp (lpw
,"extralight") == 0) return FW_EXTRALIGHT
;
5029 else if (stricmp (lpw
,"thin") == 0) return FW_THIN
;
5036 w32_to_x_weight (fnweight
)
5039 if (fnweight
>= FW_HEAVY
) return "heavy";
5040 if (fnweight
>= FW_EXTRABOLD
) return "extrabold";
5041 if (fnweight
>= FW_BOLD
) return "bold";
5042 if (fnweight
>= FW_SEMIBOLD
) return "semibold";
5043 if (fnweight
>= FW_MEDIUM
) return "medium";
5044 if (fnweight
>= FW_NORMAL
) return "normal";
5045 if (fnweight
>= FW_LIGHT
) return "light";
5046 if (fnweight
>= FW_EXTRALIGHT
) return "extralight";
5047 if (fnweight
>= FW_THIN
) return "thin";
5053 x_to_w32_charset (lpcs
)
5056 if (!lpcs
) return (0);
5058 if (stricmp (lpcs
,"ansi") == 0) return ANSI_CHARSET
;
5059 else if (stricmp (lpcs
,"iso8859-1") == 0) return ANSI_CHARSET
;
5060 else if (stricmp (lpcs
, "symbol") == 0) return SYMBOL_CHARSET
;
5061 else if (stricmp (lpcs
, "jis") == 0) return SHIFTJIS_CHARSET
;
5062 else if (stricmp (lpcs
, "ksc5601") == 0) return HANGEUL_CHARSET
;
5063 else if (stricmp (lpcs
, "gb2312") == 0) return GB2312_CHARSET
;
5064 else if (stricmp (lpcs
, "big5") == 0) return CHINESEBIG5_CHARSET
;
5065 else if (stricmp (lpcs
, "oem") == 0) return OEM_CHARSET
;
5067 #ifdef EASTEUROPE_CHARSET
5068 else if (stricmp (lpcs
, "iso8859-2") == 0) return EASTEUROPE_CHARSET
;
5069 else if (stricmp (lpcs
, "iso8859-3") == 0) return TURKISH_CHARSET
;
5070 else if (stricmp (lpcs
, "iso8859-4") == 0) return BALTIC_CHARSET
;
5071 else if (stricmp (lpcs
, "iso8859-5") == 0) return RUSSIAN_CHARSET
;
5072 else if (stricmp (lpcs
, "koi8") == 0) return RUSSIAN_CHARSET
;
5073 else if (stricmp (lpcs
, "iso8859-6") == 0) return ARABIC_CHARSET
;
5074 else if (stricmp (lpcs
, "iso8859-7") == 0) return GREEK_CHARSET
;
5075 else if (stricmp (lpcs
, "iso8859-8") == 0) return HEBREW_CHARSET
;
5076 else if (stricmp (lpcs
, "viscii") == 0) return VIETNAMESE_CHARSET
;
5077 else if (stricmp (lpcs
, "vscii") == 0) return VIETNAMESE_CHARSET
;
5078 else if (stricmp (lpcs
, "tis620") == 0) return THAI_CHARSET
;
5079 else if (stricmp (lpcs
, "mac") == 0) return MAC_CHARSET
;
5082 #ifdef UNICODE_CHARSET
5083 else if (stricmp (lpcs
,"iso10646") == 0) return UNICODE_CHARSET
;
5084 else if (stricmp (lpcs
, "unicode") == 0) return UNICODE_CHARSET
;
5086 else if (lpcs
[0] == '#') return atoi (lpcs
+ 1);
5088 return DEFAULT_CHARSET
;
5092 w32_to_x_charset (fncharset
)
5095 static char buf
[16];
5099 /* ansi is considered iso8859-1, as most modern ansi fonts are. */
5100 case ANSI_CHARSET
: return "iso8859-1";
5101 case DEFAULT_CHARSET
: return "ascii-*";
5102 case SYMBOL_CHARSET
: return "*-symbol";
5103 case SHIFTJIS_CHARSET
: return "jisx0212-sjis";
5104 case HANGEUL_CHARSET
: return "ksc5601-*";
5105 case GB2312_CHARSET
: return "gb2312-*";
5106 case CHINESEBIG5_CHARSET
: return "big5-*";
5107 case OEM_CHARSET
: return "*-oem";
5109 /* More recent versions of Windows (95 and NT4.0) define more
5111 #ifdef EASTEUROPE_CHARSET
5112 case EASTEUROPE_CHARSET
: return "iso8859-2";
5113 case TURKISH_CHARSET
: return "iso8859-3";
5114 case BALTIC_CHARSET
: return "iso8859-4";
5115 case RUSSIAN_CHARSET
: return "iso8859-5";
5116 case ARABIC_CHARSET
: return "iso8859-6";
5117 case GREEK_CHARSET
: return "iso8859-7";
5118 case HEBREW_CHARSET
: return "iso8859-8";
5119 case VIETNAMESE_CHARSET
: return "viscii1.1-*";
5120 case THAI_CHARSET
: return "tis620-*";
5121 case MAC_CHARSET
: return "*-mac";
5122 case JOHAB_CHARSET
: break; /* What is this? Latin-9? */
5125 #ifdef UNICODE_CHARSET
5126 case UNICODE_CHARSET
: return "iso10646-unicode";
5129 /* Encode numerical value of unknown charset. */
5130 sprintf (buf
, "*-#%u", fncharset
);
5135 w32_to_x_font (lplogfont
, lpxstr
, len
)
5136 LOGFONT
* lplogfont
;
5141 char height_pixels
[8];
5143 char width_pixels
[8];
5144 char *fontname_dash
;
5146 if (!lpxstr
) abort ();
5151 strncpy (fontname
, lplogfont
->lfFaceName
, 50);
5152 fontname
[49] = '\0'; /* Just in case */
5154 /* Replace dashes with underscores so the dashes are not
5156 fontname_dash
= fontname
;
5157 while (fontname_dash
= strchr (fontname_dash
, '-'))
5158 *fontname_dash
= '_';
5160 if (lplogfont
->lfHeight
)
5162 sprintf (height_pixels
, "%u", abs (lplogfont
->lfHeight
));
5163 sprintf (height_dpi
, "%u",
5164 (abs (lplogfont
->lfHeight
) * 720) / one_w32_display_info
.height_in
);
5168 strcpy (height_pixels
, "*");
5169 strcpy (height_dpi
, "*");
5171 if (lplogfont
->lfWidth
)
5172 sprintf (width_pixels
, "%u", lplogfont
->lfWidth
* 10);
5174 strcpy (width_pixels
, "*");
5176 _snprintf (lpxstr
, len
- 1,
5177 "-*-%s-%s-%c-*-*-%s-%s-*-*-%c-%s-%s",
5179 fontname
, /* family */
5180 w32_to_x_weight (lplogfont
->lfWeight
), /* weight */
5181 lplogfont
->lfItalic
?'i':'r', /* slant */
5183 /* add style name */
5184 height_pixels
, /* pixel size */
5185 height_dpi
, /* point size */
5188 ((lplogfont
->lfPitchAndFamily
& 0x3) == VARIABLE_PITCH
)
5189 ? 'p' : 'c', /* spacing */
5190 width_pixels
, /* avg width */
5191 w32_to_x_charset (lplogfont
->lfCharSet
) /* charset registry
5195 lpxstr
[len
- 1] = 0; /* just to be sure */
5200 x_to_w32_font (lpxstr
, lplogfont
)
5202 LOGFONT
* lplogfont
;
5204 if (!lplogfont
) return (FALSE
);
5206 memset (lplogfont
, 0, sizeof (*lplogfont
));
5208 /* Set default value for each field. */
5210 lplogfont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
5211 lplogfont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
5212 lplogfont
->lfQuality
= DEFAULT_QUALITY
;
5214 /* go for maximum quality */
5215 lplogfont
->lfOutPrecision
= OUT_STROKE_PRECIS
;
5216 lplogfont
->lfClipPrecision
= CLIP_STROKE_PRECIS
;
5217 lplogfont
->lfQuality
= PROOF_QUALITY
;
5220 lplogfont
->lfCharSet
= DEFAULT_CHARSET
;
5221 lplogfont
->lfWeight
= FW_DONTCARE
;
5222 lplogfont
->lfPitchAndFamily
= DEFAULT_PITCH
| FF_DONTCARE
;
5227 /* Provide a simple escape mechanism for specifying Windows font names
5228 * directly -- if font spec does not beginning with '-', assume this
5230 * "<font name>[:height in pixels[:width in pixels[:weight]]]"
5236 char name
[50], weight
[20], slant
, pitch
, pixels
[10], height
[10], width
[10], remainder
[20];
5239 fields
= sscanf (lpxstr
,
5240 "-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%*[^-]-%c-%9[^-]-%19s",
5241 name
, weight
, &slant
, pixels
, height
, &pitch
, width
, remainder
);
5243 if (fields
== EOF
) return (FALSE
);
5245 if (fields
> 0 && name
[0] != '*')
5247 strncpy (lplogfont
->lfFaceName
,name
, LF_FACESIZE
);
5248 lplogfont
->lfFaceName
[LF_FACESIZE
-1] = 0;
5252 lplogfont
->lfFaceName
[0] = 0;
5257 lplogfont
->lfWeight
= x_to_w32_weight ((fields
> 0 ? weight
: ""));
5261 if (!NILP (Vw32_enable_italics
))
5262 lplogfont
->lfItalic
= (fields
> 0 && slant
== 'i');
5266 if (fields
> 0 && pixels
[0] != '*')
5267 lplogfont
->lfHeight
= atoi (pixels
);
5271 if (fields
> 0 && lplogfont
->lfHeight
== 0 && height
[0] != '*')
5272 lplogfont
->lfHeight
= (atoi (height
)
5273 * one_w32_display_info
.height_in
) / 720;
5277 lplogfont
->lfPitchAndFamily
=
5278 (fields
> 0 && pitch
== 'p') ? VARIABLE_PITCH
: FIXED_PITCH
;
5282 if (fields
> 0 && width
[0] != '*')
5283 lplogfont
->lfWidth
= atoi (width
) / 10;
5287 /* Strip the trailing '-' if present. (it shouldn't be, as it
5288 fails the test against xlfn-tight-regexp in fontset.el). */
5290 int len
= strlen (remainder
);
5291 if (len
> 0 && remainder
[len
-1] == '-')
5292 remainder
[len
-1] = 0;
5294 encoding
= remainder
;
5295 if (strncmp (encoding
, "*-", 2) == 0)
5297 lplogfont
->lfCharSet
= x_to_w32_charset (fields
> 0 ? encoding
: "");
5302 char name
[100], height
[10], width
[10], weight
[20];
5304 fields
= sscanf (lpxstr
,
5305 "%99[^:]:%9[^:]:%9[^:]:%19s",
5306 name
, height
, width
, weight
);
5308 if (fields
== EOF
) return (FALSE
);
5312 strncpy (lplogfont
->lfFaceName
,name
, LF_FACESIZE
);
5313 lplogfont
->lfFaceName
[LF_FACESIZE
-1] = 0;
5317 lplogfont
->lfFaceName
[0] = 0;
5323 lplogfont
->lfHeight
= atoi (height
);
5328 lplogfont
->lfWidth
= atoi (width
);
5332 lplogfont
->lfWeight
= x_to_w32_weight ((fields
> 0 ? weight
: ""));
5335 /* This makes TrueType fonts work better. */
5336 lplogfont
->lfHeight
= - abs (lplogfont
->lfHeight
);
5342 w32_font_match (lpszfont1
, lpszfont2
)
5346 char * s1
= lpszfont1
, *e1
;
5347 char * s2
= lpszfont2
, *e2
;
5349 if (s1
== NULL
|| s2
== NULL
) return (FALSE
);
5351 if (*s1
== '-') s1
++;
5352 if (*s2
== '-') s2
++;
5358 e1
= strchr (s1
, '-');
5359 e2
= strchr (s2
, '-');
5361 if (e1
== NULL
|| e2
== NULL
) return (TRUE
);
5366 if (*s1
!= '*' && *s2
!= '*'
5367 && (len1
!= len2
|| strnicmp (s1
, s2
, len1
) != 0))
5375 typedef struct enumfont_t
5380 XFontStruct
*size_ref
;
5381 Lisp_Object
*pattern
;
5387 enum_font_cb2 (lplf
, lptm
, FontType
, lpef
)
5389 NEWTEXTMETRIC
* lptm
;
5393 if (lplf
->elfLogFont
.lfStrikeOut
|| lplf
->elfLogFont
.lfUnderline
)
5396 /* Check that the character set matches if it was specified */
5397 if (lpef
->logfont
.lfCharSet
!= DEFAULT_CHARSET
&&
5398 lplf
->elfLogFont
.lfCharSet
!= lpef
->logfont
.lfCharSet
)
5401 /* We want all fonts cached, so don't compare sizes just yet */
5402 /* if (!lpef->size_ref || lptm->tmMaxCharWidth == FONT_WIDTH (lpef->size_ref)) */
5405 Lisp_Object width
= Qnil
;
5407 if (!NILP (*(lpef
->pattern
)) && FontType
!= RASTER_FONTTYPE
)
5409 /* Scalable fonts are as big as you want them to be. */
5410 lplf
->elfLogFont
.lfHeight
= lpef
->logfont
.lfHeight
;
5411 lplf
->elfLogFont
.lfWidth
= lpef
->logfont
.lfWidth
;
5414 /* The MaxCharWidth is not valid at this stage for scalable fonts. */
5415 if (FontType
== RASTER_FONTTYPE
)
5416 width
= make_number (lptm
->tmMaxCharWidth
);
5418 if (!w32_to_x_font (lplf
, buf
, 100)) return (0);
5420 if (NILP (*(lpef
->pattern
)) || w32_font_match (buf
, XSTRING (*(lpef
->pattern
))->data
))
5422 *lpef
->tail
= Fcons (Fcons (build_string (buf
), width
), Qnil
);
5423 lpef
->tail
= &(XCONS (*lpef
->tail
)->cdr
);
5432 enum_font_cb1 (lplf
, lptm
, FontType
, lpef
)
5434 NEWTEXTMETRIC
* lptm
;
5438 return EnumFontFamilies (lpef
->hdc
,
5439 lplf
->elfLogFont
.lfFaceName
,
5440 (FONTENUMPROC
) enum_font_cb2
,
5445 /* Interface to fontset handler. (adapted from mw32font.c in Meadow
5446 and xterm.c in Emacs 20.3) */
5448 /* Return a list of names of available fonts matching PATTERN on frame
5449 F. If SIZE is not 0, it is the size (maximum bound width) of fonts
5450 to be listed. Frame F NULL means we have not yet created any
5451 frame, which means we can't get proper size info, as we don't have
5452 a device context to use for GetTextMetrics.
5453 MAXNAMES sets a limit on how many fonts to match. */
5456 w32_list_fonts (FRAME_PTR f
, Lisp_Object pattern
, int size
, int maxnames
)
5458 Lisp_Object patterns
, key
, tem
;
5459 Lisp_Object list
= Qnil
, newlist
= Qnil
, second_best
= Qnil
;
5461 /* If we don't have a frame, we can't use the Windows API to list
5462 fonts, as it requires a device context for the Window. This will
5463 only happen during startup if the user specifies a font on the
5464 command line. Print a message on stderr and return nil. */
5470 "Emacs cannot get a list of fonts before the initial frame "
5471 "is created.\nThe font specified on the command line may not "
5473 MessageBox (NULL
, buffer
, "Emacs Warning Dialog",
5474 MB_OK
| MB_ICONEXCLAMATION
| MB_TASKMODAL
);
5479 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
5480 if (NILP (patterns
))
5481 patterns
= Fcons (pattern
, Qnil
);
5483 for (; CONSP (patterns
); patterns
= XCONS (patterns
)->cdr
)
5487 pattern
= XCONS (patterns
)->car
;
5489 /* See if we cached the result for this particular query.
5490 The cache is an alist of the form:
5491 ((PATTERN (FONTNAME . WIDTH) ...) ...)
5494 (tem
= XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
,
5495 !NILP (list
= Fassoc (pattern
, tem
))))
5497 list
= Fcdr_safe (list
);
5498 /* We have a cached list. Don't have to get the list again. */
5503 /* At first, put PATTERN in the cache. */
5505 ef
.pattern
= &pattern
;
5506 ef
.tail
= ef
.head
= &list
;
5508 x_to_w32_font (STRINGP (pattern
) ? XSTRING (pattern
)->data
:
5511 ef
.hdc
= GetDC (FRAME_W32_WINDOW (f
));
5513 EnumFontFamilies (ef
.hdc
, NULL
, (FONTENUMPROC
) enum_font_cb1
,
5516 ReleaseDC (FRAME_W32_WINDOW (f
), ef
.hdc
);
5521 /* Make a list of the fonts we got back.
5522 Store that in the font cache for the display. */
5524 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
5525 = Fcons (Fcons (pattern
, list
),
5526 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
5529 if (NILP (list
)) continue; /* Try the remaining alternatives. */
5531 newlist
= second_best
= Qnil
;
5533 /* Make a list of the fonts that have the right width. */
5534 for (; CONSP (list
); list
= XCONS (list
)->cdr
)
5537 tem
= XCONS (list
)->car
;
5541 if (NILP (XCONS (tem
)->car
))
5545 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
5548 if (!INTEGERP (XCONS (tem
)->cdr
))
5550 /* Since we don't yet know the size of the font, we must
5551 load it and try GetTextMetrics. */
5552 struct w32_display_info
*dpyinfo
5553 = FRAME_W32_DISPLAY_INFO (f
);
5554 W32FontStruct thisinfo
;
5559 if (!x_to_w32_font (XSTRING (XCONS (tem
)->car
)->data
, &lf
))
5563 thisinfo
.hfont
= CreateFontIndirect (&lf
);
5564 if (thisinfo
.hfont
== NULL
)
5567 hdc
= GetDC (dpyinfo
->root_window
);
5568 oldobj
= SelectObject (hdc
, thisinfo
.hfont
);
5569 if (GetTextMetrics (hdc
, &thisinfo
.tm
))
5570 XCONS (tem
)->cdr
= make_number (FONT_WIDTH (&thisinfo
));
5572 XCONS (tem
)->cdr
= make_number (0);
5573 SelectObject (hdc
, oldobj
);
5574 ReleaseDC (dpyinfo
->root_window
, hdc
);
5575 DeleteObject(thisinfo
.hfont
);
5578 found_size
= XINT (XCONS (tem
)->cdr
);
5579 if (found_size
== size
)
5580 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
5582 /* keep track of the closest matching size in case
5583 no exact match is found. */
5584 else if (found_size
> 0)
5586 if (NILP (second_best
))
5588 else if (found_size
< size
)
5590 if (XINT (XCONS (second_best
)->cdr
) > size
5591 || XINT (XCONS (second_best
)->cdr
) < found_size
)
5596 if (XINT (XCONS (second_best
)->cdr
) > size
5597 && XINT (XCONS (second_best
)->cdr
) >
5604 if (!NILP (newlist
))
5606 else if (!NILP (second_best
))
5608 newlist
= Fcons (XCONS (second_best
)->car
, Qnil
);
5616 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
5618 w32_get_font_info (f
, font_idx
)
5622 return (FRAME_W32_FONT_TABLE (f
) + font_idx
);
5627 w32_query_font (struct frame
*f
, char *fontname
)
5630 struct font_info
*pfi
;
5632 pfi
= FRAME_W32_FONT_TABLE (f
);
5634 for (i
= 0; i
< one_w32_display_info
.n_fonts
;i
++, pfi
++)
5636 if (strcmp(pfi
->name
, fontname
) == 0) return pfi
;
5642 /* Find a CCL program for a font specified by FONTP, and set the member
5643 `encoder' of the structure. */
5646 w32_find_ccl_program (fontp
)
5647 struct font_info
*fontp
;
5649 extern Lisp_Object Vfont_ccl_encoder_alist
, Vccl_program_table
;
5650 extern Lisp_Object Qccl_program_idx
;
5651 extern Lisp_Object
resolve_symbol_ccl_program ();
5652 Lisp_Object list
, elt
, ccl_prog
, ccl_id
;
5654 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCONS (list
)->cdr
)
5656 elt
= XCONS (list
)->car
;
5658 && STRINGP (XCONS (elt
)->car
)
5659 && (fast_c_string_match_ignore_case (XCONS (elt
)->car
, fontp
->name
)
5662 if (SYMBOLP (XCONS (elt
)->cdr
) &&
5663 (!NILP (ccl_id
= Fget (XCONS (elt
)->cdr
, Qccl_program_idx
))))
5665 ccl_prog
= XVECTOR (Vccl_program_table
)->contents
[XUINT (ccl_id
)];
5666 if (!CONSP (ccl_prog
)) continue;
5667 ccl_prog
= XCONS (ccl_prog
)->cdr
;
5671 ccl_prog
= XCONS (elt
)->cdr
;
5672 if (!VECTORP (ccl_prog
)) continue;
5676 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
5677 setup_ccl_program (fontp
->font_encoder
,
5678 resolve_symbol_ccl_program (ccl_prog
));
5686 #include "x-list-font.c"
5688 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 4, 0,
5689 "Return a list of the names of available fonts matching PATTERN.\n\
5690 If optional arguments FACE and FRAME are specified, return only fonts\n\
5691 the same size as FACE on FRAME.\n\
5693 PATTERN is a string, perhaps with wildcard characters;\n\
5694 the * character matches any substring, and\n\
5695 the ? character matches any single character.\n\
5696 PATTERN is case-insensitive.\n\
5697 FACE is a face name--a symbol.\n\
5699 The return value is a list of strings, suitable as arguments to\n\
5702 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
5703 even if they match PATTERN and FACE.\n\
5705 The optional fourth argument MAXIMUM sets a limit on how many\n\
5706 fonts to match. The first MAXIMUM fonts are reported.")
5707 (pattern
, face
, frame
, maximum
)
5708 Lisp_Object pattern
, face
, frame
, maximum
;
5713 XFontStruct
*size_ref
;
5714 Lisp_Object namelist
;
5719 CHECK_STRING (pattern
, 0);
5721 CHECK_SYMBOL (face
, 1);
5723 f
= check_x_frame (frame
);
5725 /* Determine the width standard for comparison with the fonts we find. */
5733 /* Don't die if we get called with a terminal frame. */
5734 if (! FRAME_W32_P (f
))
5735 error ("non-w32 frame used in `x-list-fonts'");
5737 face_id
= face_name_id_number (f
, face
);
5739 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
5740 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
5741 size_ref
= f
->output_data
.w32
->font
;
5744 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
5745 if (size_ref
== (XFontStruct
*) (~0))
5746 size_ref
= f
->output_data
.w32
->font
;
5750 /* See if we cached the result for this particular query. */
5751 list
= Fassoc (pattern
,
5752 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
5754 /* We have info in the cache for this PATTERN. */
5757 Lisp_Object tem
, newlist
;
5759 /* We have info about this pattern. */
5760 list
= XCONS (list
)->cdr
;
5767 /* Filter the cached info and return just the fonts that match FACE. */
5769 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
5771 struct font_info
*fontinf
;
5772 XFontStruct
*thisinfo
= NULL
;
5774 fontinf
= w32_load_font (f
, XSTRING (XCONS (tem
)->car
)->data
, 0);
5776 thisinfo
= (XFontStruct
*)fontinf
->font
;
5777 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
5778 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
5780 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), thisinfo
);
5791 ef
.pattern
= &pattern
;
5792 ef
.tail
= ef
.head
= &namelist
;
5794 x_to_w32_font (STRINGP (pattern
) ? XSTRING (pattern
)->data
: NULL
, &ef
.logfont
);
5797 ef
.hdc
= GetDC (FRAME_W32_WINDOW (f
));
5799 EnumFontFamilies (ef
.hdc
, NULL
, (FONTENUMPROC
) enum_font_cb1
, (LPARAM
)&ef
);
5801 ReleaseDC (FRAME_W32_WINDOW (f
), ef
.hdc
);
5811 /* Make a list of all the fonts we got back.
5812 Store that in the font cache for the display. */
5813 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
5814 = Fcons (Fcons (pattern
, namelist
),
5815 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
5817 /* Make a list of the fonts that have the right width. */
5820 for (i
= 0; i
< ef
.numFonts
; i
++)
5828 struct font_info
*fontinf
;
5829 XFontStruct
*thisinfo
= NULL
;
5832 fontinf
= w32_load_font (f
, XSTRING (Fcar (cur
))->data
, 0);
5834 thisinfo
= (XFontStruct
*)fontinf
->font
;
5836 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
5838 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), thisinfo
);
5843 list
= Fcons (build_string (XSTRING (Fcar (cur
))->data
), list
);
5847 list
= Fnreverse (list
);
5854 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
5855 "Return non-nil if color COLOR is supported on frame FRAME.\n\
5856 If FRAME is omitted or nil, use the selected frame.")
5858 Lisp_Object color
, frame
;
5861 FRAME_PTR f
= check_x_frame (frame
);
5863 CHECK_STRING (color
, 1);
5865 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
5871 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
5872 "Return a description of the color named COLOR on frame FRAME.\n\
5873 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
5874 These values appear to range from 0 to 65280 or 65535, depending\n\
5875 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
5876 If FRAME is omitted or nil, use the selected frame.")
5878 Lisp_Object color
, frame
;
5881 FRAME_PTR f
= check_x_frame (frame
);
5883 CHECK_STRING (color
, 1);
5885 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
5889 rgb
[0] = make_number ((GetRValue (foo
) << 8) | GetRValue (foo
));
5890 rgb
[1] = make_number ((GetGValue (foo
) << 8) | GetGValue (foo
));
5891 rgb
[2] = make_number ((GetBValue (foo
) << 8) | GetBValue (foo
));
5892 return Flist (3, rgb
);
5898 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
5899 "Return t if the X display supports color.\n\
5900 The optional argument DISPLAY specifies which display to ask about.\n\
5901 DISPLAY should be either a frame or a display name (a string).\n\
5902 If omitted or nil, that stands for the selected frame's display.")
5904 Lisp_Object display
;
5906 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5908 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
5914 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
5916 "Return t if the X display supports shades of gray.\n\
5917 Note that color displays do support shades of gray.\n\
5918 The optional argument DISPLAY specifies which display to ask about.\n\
5919 DISPLAY should be either a frame or a display name (a string).\n\
5920 If omitted or nil, that stands for the selected frame's display.")
5922 Lisp_Object display
;
5924 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5926 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
5932 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
5934 "Returns the width in pixels of the X display DISPLAY.\n\
5935 The optional argument DISPLAY specifies which display to ask about.\n\
5936 DISPLAY should be either a frame or a display name (a string).\n\
5937 If omitted or nil, that stands for the selected frame's display.")
5939 Lisp_Object display
;
5941 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5943 return make_number (dpyinfo
->width
);
5946 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
5947 Sx_display_pixel_height
, 0, 1, 0,
5948 "Returns the height in pixels of the X display DISPLAY.\n\
5949 The optional argument DISPLAY specifies which display to ask about.\n\
5950 DISPLAY should be either a frame or a display name (a string).\n\
5951 If omitted or nil, that stands for the selected frame's display.")
5953 Lisp_Object display
;
5955 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5957 return make_number (dpyinfo
->height
);
5960 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
5962 "Returns the number of bitplanes of the display DISPLAY.\n\
5963 The optional argument DISPLAY specifies which display to ask about.\n\
5964 DISPLAY should be either a frame or a display name (a string).\n\
5965 If omitted or nil, that stands for the selected frame's display.")
5967 Lisp_Object display
;
5969 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5971 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
5974 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
5976 "Returns the number of color cells of the display DISPLAY.\n\
5977 The optional argument DISPLAY specifies which display to ask about.\n\
5978 DISPLAY should be either a frame or a display name (a string).\n\
5979 If omitted or nil, that stands for the selected frame's display.")
5981 Lisp_Object display
;
5983 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
5987 hdc
= GetDC (dpyinfo
->root_window
);
5988 if (dpyinfo
->has_palette
)
5989 cap
= GetDeviceCaps (hdc
,SIZEPALETTE
);
5991 cap
= GetDeviceCaps (hdc
,NUMCOLORS
);
5993 ReleaseDC (dpyinfo
->root_window
, hdc
);
5995 return make_number (cap
);
5998 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
5999 Sx_server_max_request_size
,
6001 "Returns the maximum request size of the server of display DISPLAY.\n\
6002 The optional argument DISPLAY specifies which display to ask about.\n\
6003 DISPLAY should be either a frame or a display name (a string).\n\
6004 If omitted or nil, that stands for the selected frame's display.")
6006 Lisp_Object display
;
6008 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6010 return make_number (1);
6013 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
6014 "Returns the vendor ID string of the W32 system (Microsoft).\n\
6015 The optional argument DISPLAY specifies which display to ask about.\n\
6016 DISPLAY should be either a frame or a display name (a string).\n\
6017 If omitted or nil, that stands for the selected frame's display.")
6019 Lisp_Object display
;
6021 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6022 char *vendor
= "Microsoft Corp.";
6024 if (! vendor
) vendor
= "";
6025 return build_string (vendor
);
6028 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
6029 "Returns the version numbers of the server of display DISPLAY.\n\
6030 The value is a list of three integers: the major and minor\n\
6031 version numbers, and the vendor-specific release\n\
6032 number. See also the function `x-server-vendor'.\n\n\
6033 The optional argument DISPLAY specifies which display to ask about.\n\
6034 DISPLAY should be either a frame or a display name (a string).\n\
6035 If omitted or nil, that stands for the selected frame's display.")
6037 Lisp_Object display
;
6039 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6041 return Fcons (make_number (w32_major_version
),
6042 Fcons (make_number (w32_minor_version
), Qnil
));
6045 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
6046 "Returns the number of screens on the server of display DISPLAY.\n\
6047 The optional argument DISPLAY specifies which display to ask about.\n\
6048 DISPLAY should be either a frame or a display name (a string).\n\
6049 If omitted or nil, that stands for the selected frame's display.")
6051 Lisp_Object display
;
6053 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6055 return make_number (1);
6058 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
6059 "Returns the height in millimeters of the X display DISPLAY.\n\
6060 The optional argument DISPLAY specifies which display to ask about.\n\
6061 DISPLAY should be either a frame or a display name (a string).\n\
6062 If omitted or nil, that stands for the selected frame's display.")
6064 Lisp_Object display
;
6066 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6070 hdc
= GetDC (dpyinfo
->root_window
);
6072 cap
= GetDeviceCaps (hdc
, VERTSIZE
);
6074 ReleaseDC (dpyinfo
->root_window
, hdc
);
6076 return make_number (cap
);
6079 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
6080 "Returns the width in millimeters of the X display DISPLAY.\n\
6081 The optional argument DISPLAY specifies which display to ask about.\n\
6082 DISPLAY should be either a frame or a display name (a string).\n\
6083 If omitted or nil, that stands for the selected frame's display.")
6085 Lisp_Object display
;
6087 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6092 hdc
= GetDC (dpyinfo
->root_window
);
6094 cap
= GetDeviceCaps (hdc
, HORZSIZE
);
6096 ReleaseDC (dpyinfo
->root_window
, hdc
);
6098 return make_number (cap
);
6101 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
6102 Sx_display_backing_store
, 0, 1, 0,
6103 "Returns an indication of whether display DISPLAY does backing store.\n\
6104 The value may be `always', `when-mapped', or `not-useful'.\n\
6105 The optional argument DISPLAY specifies which display to ask about.\n\
6106 DISPLAY should be either a frame or a display name (a string).\n\
6107 If omitted or nil, that stands for the selected frame's display.")
6109 Lisp_Object display
;
6111 return intern ("not-useful");
6114 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
6115 Sx_display_visual_class
, 0, 1, 0,
6116 "Returns the visual class of the display DISPLAY.\n\
6117 The value is one of the symbols `static-gray', `gray-scale',\n\
6118 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
6119 The optional argument DISPLAY specifies which display to ask about.\n\
6120 DISPLAY should be either a frame or a display name (a string).\n\
6121 If omitted or nil, that stands for the selected frame's display.")
6123 Lisp_Object display
;
6125 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6128 switch (dpyinfo
->visual
->class)
6130 case StaticGray
: return (intern ("static-gray"));
6131 case GrayScale
: return (intern ("gray-scale"));
6132 case StaticColor
: return (intern ("static-color"));
6133 case PseudoColor
: return (intern ("pseudo-color"));
6134 case TrueColor
: return (intern ("true-color"));
6135 case DirectColor
: return (intern ("direct-color"));
6137 error ("Display has an unknown visual class");
6141 error ("Display has an unknown visual class");
6144 DEFUN ("x-display-save-under", Fx_display_save_under
,
6145 Sx_display_save_under
, 0, 1, 0,
6146 "Returns t if the display DISPLAY supports the save-under feature.\n\
6147 The optional argument DISPLAY specifies which display to ask about.\n\
6148 DISPLAY should be either a frame or a display name (a string).\n\
6149 If omitted or nil, that stands for the selected frame's display.")
6151 Lisp_Object display
;
6153 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6160 register struct frame
*f
;
6162 return PIXEL_WIDTH (f
);
6167 register struct frame
*f
;
6169 return PIXEL_HEIGHT (f
);
6174 register struct frame
*f
;
6176 return FONT_WIDTH (f
->output_data
.w32
->font
);
6181 register struct frame
*f
;
6183 return f
->output_data
.w32
->line_height
;
6187 x_screen_planes (frame
)
6190 return (FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_planes
*
6191 FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_cbits
);
6194 /* Return the display structure for the display named NAME.
6195 Open a new connection if necessary. */
6197 struct w32_display_info
*
6198 x_display_info_for_name (name
)
6202 struct w32_display_info
*dpyinfo
;
6204 CHECK_STRING (name
, 0);
6206 for (dpyinfo
= &one_w32_display_info
, names
= w32_display_name_list
;
6208 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
6211 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
6216 /* Use this general default value to start with. */
6217 Vx_resource_name
= Vinvocation_name
;
6219 validate_x_resource_name ();
6221 dpyinfo
= w32_term_init (name
, (unsigned char *)0,
6222 (char *) XSTRING (Vx_resource_name
)->data
);
6225 error ("Cannot connect to server %s", XSTRING (name
)->data
);
6228 XSETFASTINT (Vwindow_system_version
, 3);
6233 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
6234 1, 3, 0, "Open a connection to a server.\n\
6235 DISPLAY is the name of the display to connect to.\n\
6236 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
6237 If the optional third arg MUST-SUCCEED is non-nil,\n\
6238 terminate Emacs if we can't open the connection.")
6239 (display
, xrm_string
, must_succeed
)
6240 Lisp_Object display
, xrm_string
, must_succeed
;
6242 unsigned int n_planes
;
6243 unsigned char *xrm_option
;
6244 struct w32_display_info
*dpyinfo
;
6246 CHECK_STRING (display
, 0);
6247 if (! NILP (xrm_string
))
6248 CHECK_STRING (xrm_string
, 1);
6250 if (! EQ (Vwindow_system
, intern ("w32")))
6251 error ("Not using Microsoft Windows");
6253 /* Allow color mapping to be defined externally; first look in user's
6254 HOME directory, then in Emacs etc dir for a file called rgb.txt. */
6256 Lisp_Object color_file
;
6257 struct gcpro gcpro1
;
6259 color_file
= build_string("~/rgb.txt");
6261 GCPRO1 (color_file
);
6263 if (NILP (Ffile_readable_p (color_file
)))
6265 Fexpand_file_name (build_string ("rgb.txt"),
6266 Fsymbol_value (intern ("data-directory")));
6268 Vw32_color_map
= Fw32_load_color_file (color_file
);
6272 if (NILP (Vw32_color_map
))
6273 Vw32_color_map
= Fw32_default_color_map ();
6275 if (! NILP (xrm_string
))
6276 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
6278 xrm_option
= (unsigned char *) 0;
6280 /* Use this general default value to start with. */
6281 /* First remove .exe suffix from invocation-name - it looks ugly. */
6283 char basename
[ MAX_PATH
], *str
;
6285 strcpy (basename
, XSTRING (Vinvocation_name
)->data
);
6286 str
= strrchr (basename
, '.');
6288 Vinvocation_name
= build_string (basename
);
6290 Vx_resource_name
= Vinvocation_name
;
6292 validate_x_resource_name ();
6294 /* This is what opens the connection and sets x_current_display.
6295 This also initializes many symbols, such as those used for input. */
6296 dpyinfo
= w32_term_init (display
, xrm_option
,
6297 (char *) XSTRING (Vx_resource_name
)->data
);
6301 if (!NILP (must_succeed
))
6302 fatal ("Cannot connect to server %s.\n",
6303 XSTRING (display
)->data
);
6305 error ("Cannot connect to server %s", XSTRING (display
)->data
);
6310 XSETFASTINT (Vwindow_system_version
, 3);
6314 DEFUN ("x-close-connection", Fx_close_connection
,
6315 Sx_close_connection
, 1, 1, 0,
6316 "Close the connection to DISPLAY's server.\n\
6317 For DISPLAY, specify either a frame or a display name (a string).\n\
6318 If DISPLAY is nil, that stands for the selected frame's display.")
6320 Lisp_Object display
;
6322 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6323 struct w32_display_info
*tail
;
6326 if (dpyinfo
->reference_count
> 0)
6327 error ("Display still has frames on it");
6330 /* Free the fonts in the font table. */
6331 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6333 if (dpyinfo
->font_table
[i
].name
)
6334 free (dpyinfo
->font_table
[i
].name
);
6335 /* Don't free the full_name string;
6336 it is always shared with something else. */
6337 w32_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
6339 x_destroy_all_bitmaps (dpyinfo
);
6341 x_delete_display (dpyinfo
);
6347 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
6348 "Return the list of display names that Emacs has connections to.")
6351 Lisp_Object tail
, result
;
6354 for (tail
= w32_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
6355 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
6360 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
6361 "If ON is non-nil, report errors as soon as the erring request is made.\n\
6362 If ON is nil, allow buffering of requests.\n\
6363 This is a noop on W32 systems.\n\
6364 The optional second argument DISPLAY specifies which display to act on.\n\
6365 DISPLAY should be either a frame or a display name (a string).\n\
6366 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
6368 Lisp_Object display
, on
;
6370 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6376 /* These are the w32 specialized functions */
6378 DEFUN ("w32-select-font", Fw32_select_font
, Sw32_select_font
, 0, 1, 0,
6379 "This will display the W32 font dialog and return an X font string corresponding to the selection.")
6383 FRAME_PTR f
= check_x_frame (frame
);
6388 bzero (&cf
, sizeof (cf
));
6390 cf
.lStructSize
= sizeof (cf
);
6391 cf
.hwndOwner
= FRAME_W32_WINDOW (f
);
6392 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
| CF_SCREENFONTS
;
6395 if (!ChooseFont (&cf
) || !w32_to_x_font (&lf
, buf
, 100))
6398 return build_string (buf
);
6401 DEFUN ("w32-send-sys-command", Fw32_send_sys_command
, Sw32_send_sys_command
, 1, 2, 0,
6402 "Send frame a Windows WM_SYSCOMMAND message of type COMMAND.\n\
6403 Some useful values for command are 0xf030 to maximise frame (0xf020\n\
6404 to minimize), 0xf120 to restore frame to original size, and 0xf100\n\
6405 to activate the menubar for keyboard access. 0xf140 activates the\n\
6406 screen saver if defined.\n\
6408 If optional parameter FRAME is not specified, use selected frame.")
6410 Lisp_Object command
, frame
;
6413 FRAME_PTR f
= check_x_frame (frame
);
6415 CHECK_NUMBER (command
, 0);
6417 PostMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, XINT (command
), 0);
6422 /* Lookup virtual keycode from string representing the name of a
6423 non-ascii keystroke into the corresponding virtual key, using
6424 lispy_function_keys. */
6426 lookup_vk_code (char *key
)
6430 for (i
= 0; i
< 256; i
++)
6431 if (lispy_function_keys
[i
] != 0
6432 && strcmp (lispy_function_keys
[i
], key
) == 0)
6438 /* Convert a one-element vector style key sequence to a hot key
6441 w32_parse_hot_key (key
)
6444 /* Copied from Fdefine_key and store_in_keymap. */
6445 register Lisp_Object c
;
6449 struct gcpro gcpro1
;
6451 CHECK_VECTOR (key
, 0);
6453 if (XFASTINT (Flength (key
)) != 1)
6458 c
= Faref (key
, make_number (0));
6460 if (CONSP (c
) && lucid_event_type_list_p (c
))
6461 c
= Fevent_convert_list (c
);
6465 if (! INTEGERP (c
) && ! SYMBOLP (c
))
6466 error ("Key definition is invalid");
6468 /* Work out the base key and the modifiers. */
6471 c
= parse_modifiers (c
);
6472 lisp_modifiers
= Fcar (Fcdr (c
));
6476 vk_code
= lookup_vk_code (XSYMBOL (c
)->name
->data
);
6478 else if (INTEGERP (c
))
6480 lisp_modifiers
= XINT (c
) & ~CHARACTERBITS
;
6481 /* Many ascii characters are their own virtual key code. */
6482 vk_code
= XINT (c
) & CHARACTERBITS
;
6485 if (vk_code
< 0 || vk_code
> 255)
6488 if ((lisp_modifiers
& meta_modifier
) != 0
6489 && !NILP (Vw32_alt_is_meta
))
6490 lisp_modifiers
|= alt_modifier
;
6492 /* Convert lisp modifiers to Windows hot-key form. */
6493 w32_modifiers
= (lisp_modifiers
& hyper_modifier
) ? MOD_WIN
: 0;
6494 w32_modifiers
|= (lisp_modifiers
& alt_modifier
) ? MOD_ALT
: 0;
6495 w32_modifiers
|= (lisp_modifiers
& ctrl_modifier
) ? MOD_CONTROL
: 0;
6496 w32_modifiers
|= (lisp_modifiers
& shift_modifier
) ? MOD_SHIFT
: 0;
6498 return HOTKEY (vk_code
, w32_modifiers
);
6501 DEFUN ("w32-register-hot-key", Fw32_register_hot_key
, Sw32_register_hot_key
, 1, 1, 0,
6502 "Register KEY as a hot-key combination.\n\
6503 Certain key combinations like Alt-Tab are reserved for system use on\n\
6504 Windows, and therefore are normally intercepted by the system. However,\n\
6505 most of these key combinations can be received by registering them as\n\
6506 hot-keys, overriding their special meaning.\n\
6508 KEY must be a one element key definition in vector form that would be\n\
6509 acceptable to `define-key' (e.g. [A-tab] for Alt-Tab). The meta\n\
6510 modifier is interpreted as Alt if `w32-alt-is-meta' is t, and hyper\n\
6511 is always interpreted as the Windows modifier keys.\n\
6513 The return value is the hotkey-id if registered, otherwise nil.")
6517 key
= w32_parse_hot_key (key
);
6519 if (NILP (Fmemq (key
, w32_grabbed_keys
)))
6521 /* Reuse an empty slot if possible. */
6522 Lisp_Object item
= Fmemq (Qnil
, w32_grabbed_keys
);
6524 /* Safe to add new key to list, even if we have focus. */
6526 w32_grabbed_keys
= Fcons (key
, w32_grabbed_keys
);
6530 /* Notify input thread about new hot-key definition, so that it
6531 takes effect without needing to switch focus. */
6532 PostThreadMessage (dwWindowsThreadId
, WM_EMACS_REGISTER_HOT_KEY
,
6539 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key
, Sw32_unregister_hot_key
, 1, 1, 0,
6540 "Unregister HOTKEY as a hot-key combination.")
6546 if (!INTEGERP (key
))
6547 key
= w32_parse_hot_key (key
);
6549 item
= Fmemq (key
, w32_grabbed_keys
);
6553 /* Notify input thread about hot-key definition being removed, so
6554 that it takes effect without needing focus switch. */
6555 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_UNREGISTER_HOT_KEY
,
6556 (WPARAM
) XINT (XCAR (item
)), (LPARAM
) item
))
6559 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
6566 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys
, Sw32_registered_hot_keys
, 0, 0, 0,
6567 "Return list of registered hot-key IDs.")
6570 return Fcopy_sequence (w32_grabbed_keys
);
6573 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key
, Sw32_reconstruct_hot_key
, 1, 1, 0,
6574 "Convert hot-key ID to a lisp key combination.")
6576 Lisp_Object hotkeyid
;
6578 int vk_code
, w32_modifiers
;
6581 CHECK_NUMBER (hotkeyid
, 0);
6583 vk_code
= HOTKEY_VK_CODE (hotkeyid
);
6584 w32_modifiers
= HOTKEY_MODIFIERS (hotkeyid
);
6586 if (lispy_function_keys
[vk_code
])
6587 key
= intern (lispy_function_keys
[vk_code
]);
6589 key
= make_number (vk_code
);
6591 key
= Fcons (key
, Qnil
);
6592 if (w32_modifiers
& MOD_SHIFT
)
6593 key
= Fcons (intern ("shift"), key
);
6594 if (w32_modifiers
& MOD_CONTROL
)
6595 key
= Fcons (intern ("control"), key
);
6596 if (w32_modifiers
& MOD_ALT
)
6597 key
= Fcons (intern (NILP (Vw32_alt_is_meta
) ? "alt" : "meta"), key
);
6598 if (w32_modifiers
& MOD_WIN
)
6599 key
= Fcons (intern ("hyper"), key
);
6606 /* This is zero if not using MS-Windows. */
6609 /* The section below is built by the lisp expression at the top of the file,
6610 just above where these variables are declared. */
6611 /*&&& init symbols here &&&*/
6612 Qauto_raise
= intern ("auto-raise");
6613 staticpro (&Qauto_raise
);
6614 Qauto_lower
= intern ("auto-lower");
6615 staticpro (&Qauto_lower
);
6616 Qbackground_color
= intern ("background-color");
6617 staticpro (&Qbackground_color
);
6618 Qbar
= intern ("bar");
6620 Qborder_color
= intern ("border-color");
6621 staticpro (&Qborder_color
);
6622 Qborder_width
= intern ("border-width");
6623 staticpro (&Qborder_width
);
6624 Qbox
= intern ("box");
6626 Qcursor_color
= intern ("cursor-color");
6627 staticpro (&Qcursor_color
);
6628 Qcursor_type
= intern ("cursor-type");
6629 staticpro (&Qcursor_type
);
6630 Qforeground_color
= intern ("foreground-color");
6631 staticpro (&Qforeground_color
);
6632 Qgeometry
= intern ("geometry");
6633 staticpro (&Qgeometry
);
6634 Qicon_left
= intern ("icon-left");
6635 staticpro (&Qicon_left
);
6636 Qicon_top
= intern ("icon-top");
6637 staticpro (&Qicon_top
);
6638 Qicon_type
= intern ("icon-type");
6639 staticpro (&Qicon_type
);
6640 Qicon_name
= intern ("icon-name");
6641 staticpro (&Qicon_name
);
6642 Qinternal_border_width
= intern ("internal-border-width");
6643 staticpro (&Qinternal_border_width
);
6644 Qleft
= intern ("left");
6646 Qright
= intern ("right");
6647 staticpro (&Qright
);
6648 Qmouse_color
= intern ("mouse-color");
6649 staticpro (&Qmouse_color
);
6650 Qnone
= intern ("none");
6652 Qparent_id
= intern ("parent-id");
6653 staticpro (&Qparent_id
);
6654 Qscroll_bar_width
= intern ("scroll-bar-width");
6655 staticpro (&Qscroll_bar_width
);
6656 Qsuppress_icon
= intern ("suppress-icon");
6657 staticpro (&Qsuppress_icon
);
6658 Qtop
= intern ("top");
6660 Qundefined_color
= intern ("undefined-color");
6661 staticpro (&Qundefined_color
);
6662 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
6663 staticpro (&Qvertical_scroll_bars
);
6664 Qvisibility
= intern ("visibility");
6665 staticpro (&Qvisibility
);
6666 Qwindow_id
= intern ("window-id");
6667 staticpro (&Qwindow_id
);
6668 Qx_frame_parameter
= intern ("x-frame-parameter");
6669 staticpro (&Qx_frame_parameter
);
6670 Qx_resource_name
= intern ("x-resource-name");
6671 staticpro (&Qx_resource_name
);
6672 Quser_position
= intern ("user-position");
6673 staticpro (&Quser_position
);
6674 Quser_size
= intern ("user-size");
6675 staticpro (&Quser_size
);
6676 Qdisplay
= intern ("display");
6677 staticpro (&Qdisplay
);
6678 /* This is the end of symbol initialization. */
6680 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
6681 staticpro (&Qface_set_after_frame_default
);
6683 Fput (Qundefined_color
, Qerror_conditions
,
6684 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
6685 Fput (Qundefined_color
, Qerror_message
,
6686 build_string ("Undefined color"));
6688 staticpro (&w32_grabbed_keys
);
6689 w32_grabbed_keys
= Qnil
;
6691 DEFVAR_LISP ("w32-color-map", &Vw32_color_map
,
6692 "An array of color name mappings for windows.");
6693 Vw32_color_map
= Qnil
;
6695 DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system
,
6696 "Non-nil if alt key presses are passed on to Windows.\n\
6697 When non-nil, for example, alt pressed and released and then space will\n\
6698 open the System menu. When nil, Emacs silently swallows alt key events.");
6699 Vw32_pass_alt_to_system
= Qnil
;
6701 DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta
,
6702 "Non-nil if the alt key is to be considered the same as the meta key.\n\
6703 When nil, Emacs will translate the alt key to the Alt modifier, and not Meta.");
6704 Vw32_alt_is_meta
= Qt
;
6706 DEFVAR_LISP ("w32-pass-lwindow-to-system",
6707 &Vw32_pass_lwindow_to_system
,
6708 "Non-nil if the left \"Windows\" key is passed on to Windows.\n\
6709 When non-nil, the Start menu is opened by tapping the key.");
6710 Vw32_pass_lwindow_to_system
= Qt
;
6712 DEFVAR_LISP ("w32-pass-rwindow-to-system",
6713 &Vw32_pass_rwindow_to_system
,
6714 "Non-nil if the right \"Windows\" key is passed on to Windows.\n\
6715 When non-nil, the Start menu is opened by tapping the key.");
6716 Vw32_pass_rwindow_to_system
= Qt
;
6718 DEFVAR_LISP ("w32-enable-num-lock",
6719 &Vw32_enable_num_lock
,
6720 "Non-nil if Num Lock should act normally.\n\
6721 Set to nil to see Num Lock as the key `kp-numlock'.");
6722 Vw32_enable_num_lock
= Qt
;
6724 DEFVAR_LISP ("w32-enable-caps-lock",
6725 &Vw32_enable_caps_lock
,
6726 "Non-nil if Caps Lock should act normally.\n\
6727 Set to nil to see Caps Lock as the key `capslock'.");
6728 Vw32_enable_caps_lock
= Qt
;
6730 DEFVAR_LISP ("w32-scroll-lock-modifier",
6731 &Vw32_scroll_lock_modifier
,
6732 "Modifier to use for the Scroll Lock on state.\n\
6733 The value can be hyper, super, meta, alt, control or shift for the\n\
6734 respective modifier, or nil to see Scroll Lock as the key `scroll'.\n\
6735 Any other value will cause the key to be ignored.");
6736 Vw32_scroll_lock_modifier
= Qt
;
6738 DEFVAR_LISP ("w32-lwindow-modifier",
6739 &Vw32_lwindow_modifier
,
6740 "Modifier to use for the left \"Windows\" key.\n\
6741 The value can be hyper, super, meta, alt, control or shift for the\n\
6742 respective modifier, or nil to appear as the key `lwindow'.\n\
6743 Any other value will cause the key to be ignored.");
6744 Vw32_lwindow_modifier
= Qnil
;
6746 DEFVAR_LISP ("w32-rwindow-modifier",
6747 &Vw32_rwindow_modifier
,
6748 "Modifier to use for the right \"Windows\" key.\n\
6749 The value can be hyper, super, meta, alt, control or shift for the\n\
6750 respective modifier, or nil to appear as the key `rwindow'.\n\
6751 Any other value will cause the key to be ignored.");
6752 Vw32_rwindow_modifier
= Qnil
;
6754 DEFVAR_LISP ("w32-apps-modifier",
6755 &Vw32_apps_modifier
,
6756 "Modifier to use for the \"Apps\" key.\n\
6757 The value can be hyper, super, meta, alt, control or shift for the\n\
6758 respective modifier, or nil to appear as the key `apps'.\n\
6759 Any other value will cause the key to be ignored.");
6760 Vw32_apps_modifier
= Qnil
;
6762 DEFVAR_LISP ("w32-enable-italics", &Vw32_enable_italics
,
6763 "Non-nil enables selection of artificially italicized fonts.");
6764 Vw32_enable_italics
= Qnil
;
6766 DEFVAR_LISP ("w32-enable-palette", &Vw32_enable_palette
,
6767 "Non-nil enables Windows palette management to map colors exactly.");
6768 Vw32_enable_palette
= Qt
;
6770 DEFVAR_INT ("w32-mouse-button-tolerance",
6771 &Vw32_mouse_button_tolerance
,
6772 "Analogue of double click interval for faking middle mouse events.\n\
6773 The value is the minimum time in milliseconds that must elapse between\n\
6774 left/right button down events before they are considered distinct events.\n\
6775 If both mouse buttons are depressed within this interval, a middle mouse\n\
6776 button down event is generated instead.");
6777 XSETINT (Vw32_mouse_button_tolerance
, GetDoubleClickTime () / 2);
6779 DEFVAR_INT ("w32-mouse-move-interval",
6780 &Vw32_mouse_move_interval
,
6781 "Minimum interval between mouse move events.\n\
6782 The value is the minimum time in milliseconds that must elapse between\n\
6783 successive mouse move (or scroll bar drag) events before they are\n\
6784 reported as lisp events.");
6785 XSETINT (Vw32_mouse_move_interval
, 50);
6787 init_x_parm_symbols ();
6789 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
6790 "List of directories to search for bitmap files for w32.");
6791 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
6793 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
6794 "The shape of the pointer when over text.\n\
6795 Changing the value does not affect existing frames\n\
6796 unless you set the mouse color.");
6797 Vx_pointer_shape
= Qnil
;
6799 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
6800 "The name Emacs uses to look up resources; for internal use only.\n\
6801 `x-get-resource' uses this as the first component of the instance name\n\
6802 when requesting resource values.\n\
6803 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
6804 was invoked, or to the value specified with the `-name' or `-rn'\n\
6805 switches, if present.");
6806 Vx_resource_name
= Qnil
;
6808 Vx_nontext_pointer_shape
= Qnil
;
6810 Vx_mode_pointer_shape
= Qnil
;
6812 DEFVAR_INT ("x-sensitive-text-pointer-shape",
6813 &Vx_sensitive_text_pointer_shape
,
6814 "The shape of the pointer when over mouse-sensitive text.\n\
6815 This variable takes effect when you create a new frame\n\
6816 or when you set the mouse color.");
6817 Vx_sensitive_text_pointer_shape
= Qnil
;
6819 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
6820 "A string indicating the foreground color of the cursor box.");
6821 Vx_cursor_fore_pixel
= Qnil
;
6823 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
6824 "Non-nil if no window manager is in use.\n\
6825 Emacs doesn't try to figure this out; this is always nil\n\
6826 unless you set it to something else.");
6827 /* We don't have any way to find this out, so set it to nil
6828 and maybe the user would like to set it to t. */
6829 Vx_no_window_manager
= Qnil
;
6831 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
6832 &Vx_pixel_size_width_font_regexp
,
6833 "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
6835 Since Emacs gets width of a font matching with this regexp from\n\
6836 PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
6837 such a font. This is especially effective for such large fonts as\n\
6838 Chinese, Japanese, and Korean.");
6839 Vx_pixel_size_width_font_regexp
= Qnil
;
6841 DEFVAR_BOOL ("unibyte-display-via-language-environment",
6842 &unibyte_display_via_language_environment
,
6843 "*Non-nil means display unibyte text according to language environment.\n\
6844 Specifically this means that unibyte non-ASCII characters\n\
6845 are displayed by converting them to the equivalent multibyte characters\n\
6846 according to the current language environment. As a result, they are\n\
6847 displayed according to the current fontset.");
6848 unibyte_display_via_language_environment
= 0;
6850 defsubr (&Sx_get_resource
);
6851 defsubr (&Sx_list_fonts
);
6852 defsubr (&Sx_display_color_p
);
6853 defsubr (&Sx_display_grayscale_p
);
6854 defsubr (&Sx_color_defined_p
);
6855 defsubr (&Sx_color_values
);
6856 defsubr (&Sx_server_max_request_size
);
6857 defsubr (&Sx_server_vendor
);
6858 defsubr (&Sx_server_version
);
6859 defsubr (&Sx_display_pixel_width
);
6860 defsubr (&Sx_display_pixel_height
);
6861 defsubr (&Sx_display_mm_width
);
6862 defsubr (&Sx_display_mm_height
);
6863 defsubr (&Sx_display_screens
);
6864 defsubr (&Sx_display_planes
);
6865 defsubr (&Sx_display_color_cells
);
6866 defsubr (&Sx_display_visual_class
);
6867 defsubr (&Sx_display_backing_store
);
6868 defsubr (&Sx_display_save_under
);
6869 defsubr (&Sx_parse_geometry
);
6870 defsubr (&Sx_create_frame
);
6871 defsubr (&Sx_open_connection
);
6872 defsubr (&Sx_close_connection
);
6873 defsubr (&Sx_display_list
);
6874 defsubr (&Sx_synchronize
);
6876 /* W32 specific functions */
6878 defsubr (&Sw32_focus_frame
);
6879 defsubr (&Sw32_select_font
);
6880 defsubr (&Sw32_define_rgb_color
);
6881 defsubr (&Sw32_default_color_map
);
6882 defsubr (&Sw32_load_color_file
);
6883 defsubr (&Sw32_send_sys_command
);
6884 defsubr (&Sw32_register_hot_key
);
6885 defsubr (&Sw32_unregister_hot_key
);
6886 defsubr (&Sw32_registered_hot_keys
);
6887 defsubr (&Sw32_reconstruct_hot_key
);
6889 /* Setting callback functions for fontset handler. */
6890 get_font_info_func
= w32_get_font_info
;
6891 list_fonts_func
= w32_list_fonts
;
6892 load_font_func
= w32_load_font
;
6893 find_ccl_program_func
= w32_find_ccl_program
;
6894 query_font_func
= w32_query_font
;
6895 set_frame_fontset_func
= x_set_font
;
6896 check_window_system_func
= check_w32
;
6902 /* For convenience when debugging. */
6906 return GetLastError ();
6911 button
= MessageBox (NULL
,
6912 "A fatal error has occurred!\n\n"
6913 "Select Abort to exit, Retry to debug, Ignore to continue",
6914 "Emacs Abort Dialog",
6915 MB_ICONEXCLAMATION
| MB_TASKMODAL
6916 | MB_SETFOREGROUND
| MB_ABORTRETRYIGNORE
);