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 ();
51 extern int w32_console_toggle_lock_key (int vk_code
, Lisp_Object new_state
);
54 extern char *lispy_function_keys
[];
56 /* The colormap for converting color names to RGB values */
57 Lisp_Object Vw32_color_map
;
59 /* Non nil if alt key presses are passed on to Windows. */
60 Lisp_Object Vw32_pass_alt_to_system
;
62 /* Non nil if alt key is translated to meta_modifier, nil if it is translated
64 Lisp_Object Vw32_alt_is_meta
;
66 /* If non-zero, the windows virtual key code for an alternative quit key. */
67 Lisp_Object Vw32_quit_key
;
69 /* Non nil if left window key events are passed on to Windows (this only
70 affects whether "tapping" the key opens the Start menu). */
71 Lisp_Object Vw32_pass_lwindow_to_system
;
73 /* Non nil if right window key events are passed on to Windows (this
74 only affects whether "tapping" the key opens the Start menu). */
75 Lisp_Object Vw32_pass_rwindow_to_system
;
77 /* Virtual key code used to generate "phantom" key presses in order
78 to stop system from acting on Windows key events. */
79 Lisp_Object Vw32_phantom_key_code
;
81 /* Modifier associated with the left "Windows" key, or nil to act as a
83 Lisp_Object Vw32_lwindow_modifier
;
85 /* Modifier associated with the right "Windows" key, or nil to act as a
87 Lisp_Object Vw32_rwindow_modifier
;
89 /* Modifier associated with the "Apps" key, or nil to act as a normal
91 Lisp_Object Vw32_apps_modifier
;
93 /* Value is nil if Num Lock acts as a function key. */
94 Lisp_Object Vw32_enable_num_lock
;
96 /* Value is nil if Caps Lock acts as a function key. */
97 Lisp_Object Vw32_enable_caps_lock
;
99 /* Modifier associated with Scroll Lock, or nil to act as a normal key. */
100 Lisp_Object Vw32_scroll_lock_modifier
;
102 /* Switch to control whether we inhibit requests for italicised fonts (which
103 are synthesized, look ugly, and are trashed by cursor movement under NT). */
104 Lisp_Object Vw32_enable_italics
;
106 /* Enable palette management. */
107 Lisp_Object Vw32_enable_palette
;
109 /* Control how close left/right button down events must be to
110 be converted to a middle button down event. */
111 Lisp_Object Vw32_mouse_button_tolerance
;
113 /* Minimum interval between mouse movement (and scroll bar drag)
114 events that are passed on to the event loop. */
115 Lisp_Object Vw32_mouse_move_interval
;
117 /* The name we're using in resource queries. */
118 Lisp_Object Vx_resource_name
;
120 /* Non nil if no window manager is in use. */
121 Lisp_Object Vx_no_window_manager
;
123 /* The background and shape of the mouse pointer, and shape when not
124 over text or in the modeline. */
125 Lisp_Object Vx_pointer_shape
, Vx_nontext_pointer_shape
, Vx_mode_pointer_shape
;
126 /* The shape when over mouse-sensitive text. */
127 Lisp_Object Vx_sensitive_text_pointer_shape
;
129 /* Color of chars displayed in cursor box. */
130 Lisp_Object Vx_cursor_fore_pixel
;
132 /* Nonzero if using Windows. */
133 static int w32_in_use
;
135 /* Search path for bitmap files. */
136 Lisp_Object Vx_bitmap_file_path
;
138 /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'. */
139 Lisp_Object Vx_pixel_size_width_font_regexp
;
141 /* Alist of bdf fonts and the files that define them. */
142 Lisp_Object Vw32_bdf_filename_alist
;
144 /* A flag to control how to display unibyte 8-bit character. */
145 int unibyte_display_via_language_environment
;
147 /* Evaluate this expression to rebuild the section of syms_of_w32fns
148 that initializes and staticpros the symbols declared below. Note
149 that Emacs 18 has a bug that keeps C-x C-e from being able to
150 evaluate this expression.
153 ;; Accumulate a list of the symbols we want to initialize from the
154 ;; declarations at the top of the file.
155 (goto-char (point-min))
156 (search-forward "/\*&&& symbols declared here &&&*\/\n")
158 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
160 (cons (buffer-substring (match-beginning 1) (match-end 1))
163 (setq symbol-list (nreverse symbol-list))
164 ;; Delete the section of syms_of_... where we initialize the symbols.
165 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
166 (let ((start (point)))
167 (while (looking-at "^ Q")
169 (kill-region start (point)))
170 ;; Write a new symbol initialization section.
172 (insert (format " %s = intern (\"" (car symbol-list)))
173 (let ((start (point)))
174 (insert (substring (car symbol-list) 1))
175 (subst-char-in-region start (point) ?_ ?-))
176 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
177 (setq symbol-list (cdr symbol-list)))))
181 /*&&& symbols declared here &&&*/
182 Lisp_Object Qauto_raise
;
183 Lisp_Object Qauto_lower
;
184 Lisp_Object Qbackground_color
;
186 Lisp_Object Qborder_color
;
187 Lisp_Object Qborder_width
;
189 Lisp_Object Qcursor_color
;
190 Lisp_Object Qcursor_type
;
191 Lisp_Object Qforeground_color
;
192 Lisp_Object Qgeometry
;
193 Lisp_Object Qicon_left
;
194 Lisp_Object Qicon_top
;
195 Lisp_Object Qicon_type
;
196 Lisp_Object Qicon_name
;
197 Lisp_Object Qinternal_border_width
;
200 Lisp_Object Qmouse_color
;
202 Lisp_Object Qparent_id
;
203 Lisp_Object Qscroll_bar_width
;
204 Lisp_Object Qsuppress_icon
;
206 Lisp_Object Qundefined_color
;
207 Lisp_Object Qvertical_scroll_bars
;
208 Lisp_Object Qvisibility
;
209 Lisp_Object Qwindow_id
;
210 Lisp_Object Qx_frame_parameter
;
211 Lisp_Object Qx_resource_name
;
212 Lisp_Object Quser_position
;
213 Lisp_Object Quser_size
;
214 Lisp_Object Qdisplay
;
221 Lisp_Object Qcontrol
;
224 /* State variables for emulating a three button mouse. */
229 static int button_state
= 0;
230 static W32Msg saved_mouse_button_msg
;
231 static unsigned mouse_button_timer
; /* non-zero when timer is active */
232 static W32Msg saved_mouse_move_msg
;
233 static unsigned mouse_move_timer
;
235 /* W95 mousewheel handler */
236 unsigned int msh_mousewheel
= 0;
238 #define MOUSE_BUTTON_ID 1
239 #define MOUSE_MOVE_ID 2
241 /* The below are defined in frame.c. */
242 extern Lisp_Object Qheight
, Qminibuffer
, Qname
, Qonly
, Qwidth
;
243 extern Lisp_Object Qunsplittable
, Qmenu_bar_lines
, Qbuffer_predicate
, Qtitle
;
245 extern Lisp_Object Vwindow_system_version
;
247 Lisp_Object Qface_set_after_frame_default
;
249 extern Lisp_Object last_mouse_scroll_bar
;
250 extern int last_mouse_scroll_bar_pos
;
252 /* From w32term.c. */
253 extern Lisp_Object Vw32_num_mouse_buttons
;
254 extern Lisp_Object Vw32_recognize_altgr
;
257 /* Error if we are not connected to MS-Windows. */
262 error ("MS-Windows not in use or not initialized");
265 /* Nonzero if we can use mouse menus.
266 You should not call this unless HAVE_MENUS is defined. */
274 /* Extract a frame as a FRAME_PTR, defaulting to the selected frame
275 and checking validity for W32. */
278 check_x_frame (frame
)
287 CHECK_LIVE_FRAME (frame
, 0);
290 if (! FRAME_W32_P (f
))
291 error ("non-w32 frame used");
295 /* Let the user specify an display with a frame.
296 nil stands for the selected frame--or, if that is not a w32 frame,
297 the first display on the list. */
299 static struct w32_display_info
*
300 check_x_display_info (frame
)
305 if (FRAME_W32_P (selected_frame
))
306 return FRAME_W32_DISPLAY_INFO (selected_frame
);
308 return &one_w32_display_info
;
310 else if (STRINGP (frame
))
311 return x_display_info_for_name (frame
);
316 CHECK_LIVE_FRAME (frame
, 0);
318 if (! FRAME_W32_P (f
))
319 error ("non-w32 frame used");
320 return FRAME_W32_DISPLAY_INFO (f
);
324 /* Return the Emacs frame-object corresponding to an w32 window.
325 It could be the frame's main window or an icon window. */
327 /* This function can be called during GC, so use GC_xxx type test macros. */
330 x_window_to_frame (dpyinfo
, wdesc
)
331 struct w32_display_info
*dpyinfo
;
334 Lisp_Object tail
, frame
;
337 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCONS (tail
)->cdr
)
339 frame
= XCONS (tail
)->car
;
340 if (!GC_FRAMEP (frame
))
343 if (f
->output_data
.nothing
== 1
344 || FRAME_W32_DISPLAY_INFO (f
) != dpyinfo
)
346 if (FRAME_W32_WINDOW (f
) == wdesc
)
354 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
355 id, which is just an int that this section returns. Bitmaps are
356 reference counted so they can be shared among frames.
358 Bitmap indices are guaranteed to be > 0, so a negative number can
359 be used to indicate no bitmap.
361 If you use x_create_bitmap_from_data, then you must keep track of
362 the bitmaps yourself. That is, creating a bitmap from the same
363 data more than once will not be caught. */
366 /* Functions to access the contents of a bitmap, given an id. */
369 x_bitmap_height (f
, id
)
373 return FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].height
;
377 x_bitmap_width (f
, id
)
381 return FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].width
;
385 x_bitmap_pixmap (f
, id
)
389 return (int) FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].pixmap
;
393 /* Allocate a new bitmap record. Returns index of new record. */
396 x_allocate_bitmap_record (f
)
399 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
402 if (dpyinfo
->bitmaps
== NULL
)
404 dpyinfo
->bitmaps_size
= 10;
406 = (struct w32_bitmap_record
*) xmalloc (dpyinfo
->bitmaps_size
* sizeof (struct w32_bitmap_record
));
407 dpyinfo
->bitmaps_last
= 1;
411 if (dpyinfo
->bitmaps_last
< dpyinfo
->bitmaps_size
)
412 return ++dpyinfo
->bitmaps_last
;
414 for (i
= 0; i
< dpyinfo
->bitmaps_size
; ++i
)
415 if (dpyinfo
->bitmaps
[i
].refcount
== 0)
418 dpyinfo
->bitmaps_size
*= 2;
420 = (struct w32_bitmap_record
*) xrealloc (dpyinfo
->bitmaps
,
421 dpyinfo
->bitmaps_size
* sizeof (struct w32_bitmap_record
));
422 return ++dpyinfo
->bitmaps_last
;
425 /* Add one reference to the reference count of the bitmap with id ID. */
428 x_reference_bitmap (f
, id
)
432 ++FRAME_W32_DISPLAY_INFO (f
)->bitmaps
[id
- 1].refcount
;
435 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
438 x_create_bitmap_from_data (f
, bits
, width
, height
)
441 unsigned int width
, height
;
443 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
447 bitmap
= CreateBitmap (width
, height
,
448 FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_planes
,
449 FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_cbits
,
455 id
= x_allocate_bitmap_record (f
);
456 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
457 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
458 dpyinfo
->bitmaps
[id
- 1].hinst
= NULL
;
459 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
460 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
461 dpyinfo
->bitmaps
[id
- 1].height
= height
;
462 dpyinfo
->bitmaps
[id
- 1].width
= width
;
467 /* Create bitmap from file FILE for frame F. */
470 x_create_bitmap_from_file (f
, file
)
476 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
477 unsigned int width
, height
;
479 int xhot
, yhot
, result
, id
;
485 /* Look for an existing bitmap with the same name. */
486 for (id
= 0; id
< dpyinfo
->bitmaps_last
; ++id
)
488 if (dpyinfo
->bitmaps
[id
].refcount
489 && dpyinfo
->bitmaps
[id
].file
490 && !strcmp (dpyinfo
->bitmaps
[id
].file
, (char *) XSTRING (file
)->data
))
492 ++dpyinfo
->bitmaps
[id
].refcount
;
497 /* Search bitmap-file-path for the file, if appropriate. */
498 fd
= openp (Vx_bitmap_file_path
, file
, "", &found
, 0);
501 /* LoadLibraryEx won't handle special files handled by Emacs handler. */
506 filename
= (char *) XSTRING (found
)->data
;
508 hinst
= LoadLibraryEx (filename
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
514 result
= XReadBitmapFile (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
),
515 filename
, &width
, &height
, &bitmap
, &xhot
, &yhot
);
516 if (result
!= BitmapSuccess
)
519 id
= x_allocate_bitmap_record (f
);
520 dpyinfo
->bitmaps
[id
- 1].pixmap
= bitmap
;
521 dpyinfo
->bitmaps
[id
- 1].refcount
= 1;
522 dpyinfo
->bitmaps
[id
- 1].file
= (char *) xmalloc (XSTRING (file
)->size
+ 1);
523 dpyinfo
->bitmaps
[id
- 1].depth
= 1;
524 dpyinfo
->bitmaps
[id
- 1].height
= height
;
525 dpyinfo
->bitmaps
[id
- 1].width
= width
;
526 strcpy (dpyinfo
->bitmaps
[id
- 1].file
, XSTRING (file
)->data
);
532 /* Remove reference to bitmap with id number ID. */
535 x_destroy_bitmap (f
, id
)
539 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
543 --dpyinfo
->bitmaps
[id
- 1].refcount
;
544 if (dpyinfo
->bitmaps
[id
- 1].refcount
== 0)
547 DeleteObject (dpyinfo
->bitmaps
[id
- 1].pixmap
);
548 if (dpyinfo
->bitmaps
[id
- 1].file
)
550 free (dpyinfo
->bitmaps
[id
- 1].file
);
551 dpyinfo
->bitmaps
[id
- 1].file
= NULL
;
558 /* Free all the bitmaps for the display specified by DPYINFO. */
561 x_destroy_all_bitmaps (dpyinfo
)
562 struct w32_display_info
*dpyinfo
;
565 for (i
= 0; i
< dpyinfo
->bitmaps_last
; i
++)
566 if (dpyinfo
->bitmaps
[i
].refcount
> 0)
568 DeleteObject (dpyinfo
->bitmaps
[i
].pixmap
);
569 if (dpyinfo
->bitmaps
[i
].file
)
570 free (dpyinfo
->bitmaps
[i
].file
);
572 dpyinfo
->bitmaps_last
= 0;
575 /* Connect the frame-parameter names for W32 frames
576 to the ways of passing the parameter values to the window system.
578 The name of a parameter, as a Lisp symbol,
579 has an `x-frame-parameter' property which is an integer in Lisp
580 but can be interpreted as an `enum x_frame_parm' in C. */
584 X_PARM_FOREGROUND_COLOR
,
585 X_PARM_BACKGROUND_COLOR
,
592 X_PARM_INTERNAL_BORDER_WIDTH
,
596 X_PARM_VERT_SCROLL_BAR
,
598 X_PARM_MENU_BAR_LINES
602 struct x_frame_parm_table
605 void (*setter
)( /* struct frame *frame, Lisp_Object val, oldval */ );
608 void x_set_foreground_color ();
609 void x_set_background_color ();
610 void x_set_mouse_color ();
611 void x_set_cursor_color ();
612 void x_set_border_color ();
613 void x_set_cursor_type ();
614 void x_set_icon_type ();
615 void x_set_icon_name ();
617 void x_set_border_width ();
618 void x_set_internal_border_width ();
619 void x_explicitly_set_name ();
620 void x_set_autoraise ();
621 void x_set_autolower ();
622 void x_set_vertical_scroll_bars ();
623 void x_set_visibility ();
624 void x_set_menu_bar_lines ();
625 void x_set_scroll_bar_width ();
627 void x_set_unsplittable ();
629 static struct x_frame_parm_table x_frame_parms
[] =
631 "auto-raise", x_set_autoraise
,
632 "auto-lower", x_set_autolower
,
633 "background-color", x_set_background_color
,
634 "border-color", x_set_border_color
,
635 "border-width", x_set_border_width
,
636 "cursor-color", x_set_cursor_color
,
637 "cursor-type", x_set_cursor_type
,
639 "foreground-color", x_set_foreground_color
,
640 "icon-name", x_set_icon_name
,
641 "icon-type", x_set_icon_type
,
642 "internal-border-width", x_set_internal_border_width
,
643 "menu-bar-lines", x_set_menu_bar_lines
,
644 "mouse-color", x_set_mouse_color
,
645 "name", x_explicitly_set_name
,
646 "scroll-bar-width", x_set_scroll_bar_width
,
647 "title", x_set_title
,
648 "unsplittable", x_set_unsplittable
,
649 "vertical-scroll-bars", x_set_vertical_scroll_bars
,
650 "visibility", x_set_visibility
,
653 /* Attach the `x-frame-parameter' properties to
654 the Lisp symbol names of parameters relevant to W32. */
656 init_x_parm_symbols ()
660 for (i
= 0; i
< sizeof (x_frame_parms
) / sizeof (x_frame_parms
[0]); i
++)
661 Fput (intern (x_frame_parms
[i
].name
), Qx_frame_parameter
,
665 /* Change the parameters of FRAME as specified by ALIST.
666 If a parameter is not specially recognized, do nothing;
667 otherwise call the `x_set_...' function for that parameter. */
670 x_set_frame_parameters (f
, alist
)
676 /* If both of these parameters are present, it's more efficient to
677 set them both at once. So we wait until we've looked at the
678 entire list before we set them. */
682 Lisp_Object left
, top
;
684 /* Same with these. */
685 Lisp_Object icon_left
, icon_top
;
687 /* Record in these vectors all the parms specified. */
691 int left_no_change
= 0, top_no_change
= 0;
692 int icon_left_no_change
= 0, icon_top_no_change
= 0;
694 struct gcpro gcpro1
, gcpro2
;
697 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
700 parms
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
701 values
= (Lisp_Object
*) alloca (i
* sizeof (Lisp_Object
));
703 /* Extract parm names and values into those vectors. */
706 for (tail
= alist
; CONSP (tail
); tail
= Fcdr (tail
))
708 Lisp_Object elt
, prop
, val
;
711 parms
[i
] = Fcar (elt
);
712 values
[i
] = Fcdr (elt
);
716 /* TAIL and ALIST are not used again below here. */
719 GCPRO2 (*parms
, *values
);
723 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
724 because their values appear in VALUES and strings are not valid. */
725 top
= left
= Qunbound
;
726 icon_left
= icon_top
= Qunbound
;
728 /* Provide default values for HEIGHT and WIDTH. */
729 width
= FRAME_WIDTH (f
);
730 height
= FRAME_HEIGHT (f
);
732 /* Now process them in reverse of specified order. */
733 for (i
--; i
>= 0; i
--)
735 Lisp_Object prop
, val
;
740 if (EQ (prop
, Qwidth
) && NUMBERP (val
))
741 width
= XFASTINT (val
);
742 else if (EQ (prop
, Qheight
) && NUMBERP (val
))
743 height
= XFASTINT (val
);
744 else if (EQ (prop
, Qtop
))
746 else if (EQ (prop
, Qleft
))
748 else if (EQ (prop
, Qicon_top
))
750 else if (EQ (prop
, Qicon_left
))
754 register Lisp_Object param_index
, old_value
;
756 param_index
= Fget (prop
, Qx_frame_parameter
);
757 old_value
= get_frame_param (f
, prop
);
758 store_frame_param (f
, prop
, val
);
759 if (NATNUMP (param_index
)
760 && (XFASTINT (param_index
)
761 < sizeof (x_frame_parms
)/sizeof (x_frame_parms
[0])))
762 (*x_frame_parms
[XINT (param_index
)].setter
)(f
, val
, old_value
);
766 /* Don't die if just one of these was set. */
767 if (EQ (left
, Qunbound
))
770 if (f
->output_data
.w32
->left_pos
< 0)
771 left
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.w32
->left_pos
), Qnil
));
773 XSETINT (left
, f
->output_data
.w32
->left_pos
);
775 if (EQ (top
, Qunbound
))
778 if (f
->output_data
.w32
->top_pos
< 0)
779 top
= Fcons (Qplus
, Fcons (make_number (f
->output_data
.w32
->top_pos
), Qnil
));
781 XSETINT (top
, f
->output_data
.w32
->top_pos
);
784 /* If one of the icon positions was not set, preserve or default it. */
785 if (EQ (icon_left
, Qunbound
) || ! INTEGERP (icon_left
))
787 icon_left_no_change
= 1;
788 icon_left
= Fcdr (Fassq (Qicon_left
, f
->param_alist
));
789 if (NILP (icon_left
))
790 XSETINT (icon_left
, 0);
792 if (EQ (icon_top
, Qunbound
) || ! INTEGERP (icon_top
))
794 icon_top_no_change
= 1;
795 icon_top
= Fcdr (Fassq (Qicon_top
, f
->param_alist
));
797 XSETINT (icon_top
, 0);
800 /* Don't set these parameters unless they've been explicitly
801 specified. The window might be mapped or resized while we're in
802 this function, and we don't want to override that unless the lisp
803 code has asked for it.
805 Don't set these parameters unless they actually differ from the
806 window's current parameters; the window may not actually exist
811 check_frame_size (f
, &height
, &width
);
813 XSETFRAME (frame
, f
);
815 if (XINT (width
) != FRAME_WIDTH (f
)
816 || XINT (height
) != FRAME_HEIGHT (f
))
817 Fset_frame_size (frame
, make_number (width
), make_number (height
));
819 if ((!NILP (left
) || !NILP (top
))
820 && ! (left_no_change
&& top_no_change
)
821 && ! (NUMBERP (left
) && XINT (left
) == f
->output_data
.w32
->left_pos
822 && NUMBERP (top
) && XINT (top
) == f
->output_data
.w32
->top_pos
))
827 /* Record the signs. */
828 f
->output_data
.w32
->size_hint_flags
&= ~ (XNegative
| YNegative
);
829 if (EQ (left
, Qminus
))
830 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
831 else if (INTEGERP (left
))
833 leftpos
= XINT (left
);
835 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
837 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qminus
)
838 && CONSP (XCONS (left
)->cdr
)
839 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
841 leftpos
= - XINT (XCONS (XCONS (left
)->cdr
)->car
);
842 f
->output_data
.w32
->size_hint_flags
|= XNegative
;
844 else if (CONSP (left
) && EQ (XCONS (left
)->car
, Qplus
)
845 && CONSP (XCONS (left
)->cdr
)
846 && INTEGERP (XCONS (XCONS (left
)->cdr
)->car
))
848 leftpos
= XINT (XCONS (XCONS (left
)->cdr
)->car
);
851 if (EQ (top
, Qminus
))
852 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
853 else if (INTEGERP (top
))
857 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
859 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qminus
)
860 && CONSP (XCONS (top
)->cdr
)
861 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
863 toppos
= - XINT (XCONS (XCONS (top
)->cdr
)->car
);
864 f
->output_data
.w32
->size_hint_flags
|= YNegative
;
866 else if (CONSP (top
) && EQ (XCONS (top
)->car
, Qplus
)
867 && CONSP (XCONS (top
)->cdr
)
868 && INTEGERP (XCONS (XCONS (top
)->cdr
)->car
))
870 toppos
= XINT (XCONS (XCONS (top
)->cdr
)->car
);
874 /* Store the numeric value of the position. */
875 f
->output_data
.w32
->top_pos
= toppos
;
876 f
->output_data
.w32
->left_pos
= leftpos
;
878 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
880 /* Actually set that position, and convert to absolute. */
881 x_set_offset (f
, leftpos
, toppos
, -1);
884 if ((!NILP (icon_left
) || !NILP (icon_top
))
885 && ! (icon_left_no_change
&& icon_top_no_change
))
886 x_wm_set_icon_position (f
, XINT (icon_left
), XINT (icon_top
));
892 /* Store the screen positions of frame F into XPTR and YPTR.
893 These are the positions of the containing window manager window,
894 not Emacs's own window. */
897 x_real_positions (f
, xptr
, yptr
)
906 GetClientRect(FRAME_W32_WINDOW(f
), &rect
);
907 AdjustWindowRect(&rect
, f
->output_data
.w32
->dwStyle
, FRAME_EXTERNAL_MENU_BAR(f
));
913 ClientToScreen (FRAME_W32_WINDOW(f
), &pt
);
919 /* Insert a description of internally-recorded parameters of frame X
920 into the parameter alist *ALISTPTR that is to be given to the user.
921 Only parameters that are specific to W32
922 and whose values are not correctly recorded in the frame's
923 param_alist need to be considered here. */
925 x_report_frame_params (f
, alistptr
)
927 Lisp_Object
*alistptr
;
932 /* Represent negative positions (off the top or left screen edge)
933 in a way that Fmodify_frame_parameters will understand correctly. */
934 XSETINT (tem
, f
->output_data
.w32
->left_pos
);
935 if (f
->output_data
.w32
->left_pos
>= 0)
936 store_in_alist (alistptr
, Qleft
, tem
);
938 store_in_alist (alistptr
, Qleft
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
940 XSETINT (tem
, f
->output_data
.w32
->top_pos
);
941 if (f
->output_data
.w32
->top_pos
>= 0)
942 store_in_alist (alistptr
, Qtop
, tem
);
944 store_in_alist (alistptr
, Qtop
, Fcons (Qplus
, Fcons (tem
, Qnil
)));
946 store_in_alist (alistptr
, Qborder_width
,
947 make_number (f
->output_data
.w32
->border_width
));
948 store_in_alist (alistptr
, Qinternal_border_width
,
949 make_number (f
->output_data
.w32
->internal_border_width
));
950 sprintf (buf
, "%ld", (long) FRAME_W32_WINDOW (f
));
951 store_in_alist (alistptr
, Qwindow_id
,
953 store_in_alist (alistptr
, Qicon_name
, f
->icon_name
);
954 FRAME_SAMPLE_VISIBILITY (f
);
955 store_in_alist (alistptr
, Qvisibility
,
956 (FRAME_VISIBLE_P (f
) ? Qt
957 : FRAME_ICONIFIED_P (f
) ? Qicon
: Qnil
));
958 store_in_alist (alistptr
, Qdisplay
,
959 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->car
);
963 DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color
, Sw32_define_rgb_color
, 4, 4, 0,
964 "Convert RGB numbers to a windows color reference and associate with NAME (a string).\n\
965 This adds or updates a named color to w32-color-map, making it available for use.\n\
966 The original entry's RGB ref is returned, or nil if the entry is new.")
967 (red
, green
, blue
, name
)
968 Lisp_Object red
, green
, blue
, name
;
971 Lisp_Object oldrgb
= Qnil
;
974 CHECK_NUMBER (red
, 0);
975 CHECK_NUMBER (green
, 0);
976 CHECK_NUMBER (blue
, 0);
977 CHECK_STRING (name
, 0);
979 XSET (rgb
, Lisp_Int
, RGB(XUINT (red
), XUINT (green
), XUINT (blue
)));
983 /* replace existing entry in w32-color-map or add new entry. */
984 entry
= Fassoc (name
, Vw32_color_map
);
987 entry
= Fcons (name
, rgb
);
988 Vw32_color_map
= Fcons (entry
, Vw32_color_map
);
992 oldrgb
= Fcdr (entry
);
993 Fsetcdr (entry
, rgb
);
1001 DEFUN ("w32-load-color-file", Fw32_load_color_file
, Sw32_load_color_file
, 1, 1, 0,
1002 "Create an alist of color entries from an external file (ie. rgb.txt).\n\
1003 Assign this value to w32-color-map to replace the existing color map.\n\
1005 The file should define one named RGB color per line like so:\
1007 where R,G,B are numbers between 0 and 255 and name is an arbitrary string.")
1009 Lisp_Object filename
;
1012 Lisp_Object cmap
= Qnil
;
1013 Lisp_Object abspath
;
1015 CHECK_STRING (filename
, 0);
1016 abspath
= Fexpand_file_name (filename
, Qnil
);
1018 fp
= fopen (XSTRING (filename
)->data
, "rt");
1022 int red
, green
, blue
;
1027 while (fgets (buf
, sizeof (buf
), fp
) != NULL
) {
1028 if (sscanf (buf
, "%u %u %u %n", &red
, &green
, &blue
, &num
) == 3)
1030 char *name
= buf
+ num
;
1031 num
= strlen (name
) - 1;
1032 if (name
[num
] == '\n')
1034 cmap
= Fcons (Fcons (build_string (name
),
1035 make_number (RGB (red
, green
, blue
))),
1047 /* The default colors for the w32 color map */
1048 typedef struct colormap_t
1054 colormap_t w32_color_map
[] =
1056 {"snow" , PALETTERGB (255,250,250)},
1057 {"ghost white" , PALETTERGB (248,248,255)},
1058 {"GhostWhite" , PALETTERGB (248,248,255)},
1059 {"white smoke" , PALETTERGB (245,245,245)},
1060 {"WhiteSmoke" , PALETTERGB (245,245,245)},
1061 {"gainsboro" , PALETTERGB (220,220,220)},
1062 {"floral white" , PALETTERGB (255,250,240)},
1063 {"FloralWhite" , PALETTERGB (255,250,240)},
1064 {"old lace" , PALETTERGB (253,245,230)},
1065 {"OldLace" , PALETTERGB (253,245,230)},
1066 {"linen" , PALETTERGB (250,240,230)},
1067 {"antique white" , PALETTERGB (250,235,215)},
1068 {"AntiqueWhite" , PALETTERGB (250,235,215)},
1069 {"papaya whip" , PALETTERGB (255,239,213)},
1070 {"PapayaWhip" , PALETTERGB (255,239,213)},
1071 {"blanched almond" , PALETTERGB (255,235,205)},
1072 {"BlanchedAlmond" , PALETTERGB (255,235,205)},
1073 {"bisque" , PALETTERGB (255,228,196)},
1074 {"peach puff" , PALETTERGB (255,218,185)},
1075 {"PeachPuff" , PALETTERGB (255,218,185)},
1076 {"navajo white" , PALETTERGB (255,222,173)},
1077 {"NavajoWhite" , PALETTERGB (255,222,173)},
1078 {"moccasin" , PALETTERGB (255,228,181)},
1079 {"cornsilk" , PALETTERGB (255,248,220)},
1080 {"ivory" , PALETTERGB (255,255,240)},
1081 {"lemon chiffon" , PALETTERGB (255,250,205)},
1082 {"LemonChiffon" , PALETTERGB (255,250,205)},
1083 {"seashell" , PALETTERGB (255,245,238)},
1084 {"honeydew" , PALETTERGB (240,255,240)},
1085 {"mint cream" , PALETTERGB (245,255,250)},
1086 {"MintCream" , PALETTERGB (245,255,250)},
1087 {"azure" , PALETTERGB (240,255,255)},
1088 {"alice blue" , PALETTERGB (240,248,255)},
1089 {"AliceBlue" , PALETTERGB (240,248,255)},
1090 {"lavender" , PALETTERGB (230,230,250)},
1091 {"lavender blush" , PALETTERGB (255,240,245)},
1092 {"LavenderBlush" , PALETTERGB (255,240,245)},
1093 {"misty rose" , PALETTERGB (255,228,225)},
1094 {"MistyRose" , PALETTERGB (255,228,225)},
1095 {"white" , PALETTERGB (255,255,255)},
1096 {"black" , PALETTERGB ( 0, 0, 0)},
1097 {"dark slate gray" , PALETTERGB ( 47, 79, 79)},
1098 {"DarkSlateGray" , PALETTERGB ( 47, 79, 79)},
1099 {"dark slate grey" , PALETTERGB ( 47, 79, 79)},
1100 {"DarkSlateGrey" , PALETTERGB ( 47, 79, 79)},
1101 {"dim gray" , PALETTERGB (105,105,105)},
1102 {"DimGray" , PALETTERGB (105,105,105)},
1103 {"dim grey" , PALETTERGB (105,105,105)},
1104 {"DimGrey" , PALETTERGB (105,105,105)},
1105 {"slate gray" , PALETTERGB (112,128,144)},
1106 {"SlateGray" , PALETTERGB (112,128,144)},
1107 {"slate grey" , PALETTERGB (112,128,144)},
1108 {"SlateGrey" , PALETTERGB (112,128,144)},
1109 {"light slate gray" , PALETTERGB (119,136,153)},
1110 {"LightSlateGray" , PALETTERGB (119,136,153)},
1111 {"light slate grey" , PALETTERGB (119,136,153)},
1112 {"LightSlateGrey" , PALETTERGB (119,136,153)},
1113 {"gray" , PALETTERGB (190,190,190)},
1114 {"grey" , PALETTERGB (190,190,190)},
1115 {"light grey" , PALETTERGB (211,211,211)},
1116 {"LightGrey" , PALETTERGB (211,211,211)},
1117 {"light gray" , PALETTERGB (211,211,211)},
1118 {"LightGray" , PALETTERGB (211,211,211)},
1119 {"midnight blue" , PALETTERGB ( 25, 25,112)},
1120 {"MidnightBlue" , PALETTERGB ( 25, 25,112)},
1121 {"navy" , PALETTERGB ( 0, 0,128)},
1122 {"navy blue" , PALETTERGB ( 0, 0,128)},
1123 {"NavyBlue" , PALETTERGB ( 0, 0,128)},
1124 {"cornflower blue" , PALETTERGB (100,149,237)},
1125 {"CornflowerBlue" , PALETTERGB (100,149,237)},
1126 {"dark slate blue" , PALETTERGB ( 72, 61,139)},
1127 {"DarkSlateBlue" , PALETTERGB ( 72, 61,139)},
1128 {"slate blue" , PALETTERGB (106, 90,205)},
1129 {"SlateBlue" , PALETTERGB (106, 90,205)},
1130 {"medium slate blue" , PALETTERGB (123,104,238)},
1131 {"MediumSlateBlue" , PALETTERGB (123,104,238)},
1132 {"light slate blue" , PALETTERGB (132,112,255)},
1133 {"LightSlateBlue" , PALETTERGB (132,112,255)},
1134 {"medium blue" , PALETTERGB ( 0, 0,205)},
1135 {"MediumBlue" , PALETTERGB ( 0, 0,205)},
1136 {"royal blue" , PALETTERGB ( 65,105,225)},
1137 {"RoyalBlue" , PALETTERGB ( 65,105,225)},
1138 {"blue" , PALETTERGB ( 0, 0,255)},
1139 {"dodger blue" , PALETTERGB ( 30,144,255)},
1140 {"DodgerBlue" , PALETTERGB ( 30,144,255)},
1141 {"deep sky blue" , PALETTERGB ( 0,191,255)},
1142 {"DeepSkyBlue" , PALETTERGB ( 0,191,255)},
1143 {"sky blue" , PALETTERGB (135,206,235)},
1144 {"SkyBlue" , PALETTERGB (135,206,235)},
1145 {"light sky blue" , PALETTERGB (135,206,250)},
1146 {"LightSkyBlue" , PALETTERGB (135,206,250)},
1147 {"steel blue" , PALETTERGB ( 70,130,180)},
1148 {"SteelBlue" , PALETTERGB ( 70,130,180)},
1149 {"light steel blue" , PALETTERGB (176,196,222)},
1150 {"LightSteelBlue" , PALETTERGB (176,196,222)},
1151 {"light blue" , PALETTERGB (173,216,230)},
1152 {"LightBlue" , PALETTERGB (173,216,230)},
1153 {"powder blue" , PALETTERGB (176,224,230)},
1154 {"PowderBlue" , PALETTERGB (176,224,230)},
1155 {"pale turquoise" , PALETTERGB (175,238,238)},
1156 {"PaleTurquoise" , PALETTERGB (175,238,238)},
1157 {"dark turquoise" , PALETTERGB ( 0,206,209)},
1158 {"DarkTurquoise" , PALETTERGB ( 0,206,209)},
1159 {"medium turquoise" , PALETTERGB ( 72,209,204)},
1160 {"MediumTurquoise" , PALETTERGB ( 72,209,204)},
1161 {"turquoise" , PALETTERGB ( 64,224,208)},
1162 {"cyan" , PALETTERGB ( 0,255,255)},
1163 {"light cyan" , PALETTERGB (224,255,255)},
1164 {"LightCyan" , PALETTERGB (224,255,255)},
1165 {"cadet blue" , PALETTERGB ( 95,158,160)},
1166 {"CadetBlue" , PALETTERGB ( 95,158,160)},
1167 {"medium aquamarine" , PALETTERGB (102,205,170)},
1168 {"MediumAquamarine" , PALETTERGB (102,205,170)},
1169 {"aquamarine" , PALETTERGB (127,255,212)},
1170 {"dark green" , PALETTERGB ( 0,100, 0)},
1171 {"DarkGreen" , PALETTERGB ( 0,100, 0)},
1172 {"dark olive green" , PALETTERGB ( 85,107, 47)},
1173 {"DarkOliveGreen" , PALETTERGB ( 85,107, 47)},
1174 {"dark sea green" , PALETTERGB (143,188,143)},
1175 {"DarkSeaGreen" , PALETTERGB (143,188,143)},
1176 {"sea green" , PALETTERGB ( 46,139, 87)},
1177 {"SeaGreen" , PALETTERGB ( 46,139, 87)},
1178 {"medium sea green" , PALETTERGB ( 60,179,113)},
1179 {"MediumSeaGreen" , PALETTERGB ( 60,179,113)},
1180 {"light sea green" , PALETTERGB ( 32,178,170)},
1181 {"LightSeaGreen" , PALETTERGB ( 32,178,170)},
1182 {"pale green" , PALETTERGB (152,251,152)},
1183 {"PaleGreen" , PALETTERGB (152,251,152)},
1184 {"spring green" , PALETTERGB ( 0,255,127)},
1185 {"SpringGreen" , PALETTERGB ( 0,255,127)},
1186 {"lawn green" , PALETTERGB (124,252, 0)},
1187 {"LawnGreen" , PALETTERGB (124,252, 0)},
1188 {"green" , PALETTERGB ( 0,255, 0)},
1189 {"chartreuse" , PALETTERGB (127,255, 0)},
1190 {"medium spring green" , PALETTERGB ( 0,250,154)},
1191 {"MediumSpringGreen" , PALETTERGB ( 0,250,154)},
1192 {"green yellow" , PALETTERGB (173,255, 47)},
1193 {"GreenYellow" , PALETTERGB (173,255, 47)},
1194 {"lime green" , PALETTERGB ( 50,205, 50)},
1195 {"LimeGreen" , PALETTERGB ( 50,205, 50)},
1196 {"yellow green" , PALETTERGB (154,205, 50)},
1197 {"YellowGreen" , PALETTERGB (154,205, 50)},
1198 {"forest green" , PALETTERGB ( 34,139, 34)},
1199 {"ForestGreen" , PALETTERGB ( 34,139, 34)},
1200 {"olive drab" , PALETTERGB (107,142, 35)},
1201 {"OliveDrab" , PALETTERGB (107,142, 35)},
1202 {"dark khaki" , PALETTERGB (189,183,107)},
1203 {"DarkKhaki" , PALETTERGB (189,183,107)},
1204 {"khaki" , PALETTERGB (240,230,140)},
1205 {"pale goldenrod" , PALETTERGB (238,232,170)},
1206 {"PaleGoldenrod" , PALETTERGB (238,232,170)},
1207 {"light goldenrod yellow" , PALETTERGB (250,250,210)},
1208 {"LightGoldenrodYellow" , PALETTERGB (250,250,210)},
1209 {"light yellow" , PALETTERGB (255,255,224)},
1210 {"LightYellow" , PALETTERGB (255,255,224)},
1211 {"yellow" , PALETTERGB (255,255, 0)},
1212 {"gold" , PALETTERGB (255,215, 0)},
1213 {"light goldenrod" , PALETTERGB (238,221,130)},
1214 {"LightGoldenrod" , PALETTERGB (238,221,130)},
1215 {"goldenrod" , PALETTERGB (218,165, 32)},
1216 {"dark goldenrod" , PALETTERGB (184,134, 11)},
1217 {"DarkGoldenrod" , PALETTERGB (184,134, 11)},
1218 {"rosy brown" , PALETTERGB (188,143,143)},
1219 {"RosyBrown" , PALETTERGB (188,143,143)},
1220 {"indian red" , PALETTERGB (205, 92, 92)},
1221 {"IndianRed" , PALETTERGB (205, 92, 92)},
1222 {"saddle brown" , PALETTERGB (139, 69, 19)},
1223 {"SaddleBrown" , PALETTERGB (139, 69, 19)},
1224 {"sienna" , PALETTERGB (160, 82, 45)},
1225 {"peru" , PALETTERGB (205,133, 63)},
1226 {"burlywood" , PALETTERGB (222,184,135)},
1227 {"beige" , PALETTERGB (245,245,220)},
1228 {"wheat" , PALETTERGB (245,222,179)},
1229 {"sandy brown" , PALETTERGB (244,164, 96)},
1230 {"SandyBrown" , PALETTERGB (244,164, 96)},
1231 {"tan" , PALETTERGB (210,180,140)},
1232 {"chocolate" , PALETTERGB (210,105, 30)},
1233 {"firebrick" , PALETTERGB (178,34, 34)},
1234 {"brown" , PALETTERGB (165,42, 42)},
1235 {"dark salmon" , PALETTERGB (233,150,122)},
1236 {"DarkSalmon" , PALETTERGB (233,150,122)},
1237 {"salmon" , PALETTERGB (250,128,114)},
1238 {"light salmon" , PALETTERGB (255,160,122)},
1239 {"LightSalmon" , PALETTERGB (255,160,122)},
1240 {"orange" , PALETTERGB (255,165, 0)},
1241 {"dark orange" , PALETTERGB (255,140, 0)},
1242 {"DarkOrange" , PALETTERGB (255,140, 0)},
1243 {"coral" , PALETTERGB (255,127, 80)},
1244 {"light coral" , PALETTERGB (240,128,128)},
1245 {"LightCoral" , PALETTERGB (240,128,128)},
1246 {"tomato" , PALETTERGB (255, 99, 71)},
1247 {"orange red" , PALETTERGB (255, 69, 0)},
1248 {"OrangeRed" , PALETTERGB (255, 69, 0)},
1249 {"red" , PALETTERGB (255, 0, 0)},
1250 {"hot pink" , PALETTERGB (255,105,180)},
1251 {"HotPink" , PALETTERGB (255,105,180)},
1252 {"deep pink" , PALETTERGB (255, 20,147)},
1253 {"DeepPink" , PALETTERGB (255, 20,147)},
1254 {"pink" , PALETTERGB (255,192,203)},
1255 {"light pink" , PALETTERGB (255,182,193)},
1256 {"LightPink" , PALETTERGB (255,182,193)},
1257 {"pale violet red" , PALETTERGB (219,112,147)},
1258 {"PaleVioletRed" , PALETTERGB (219,112,147)},
1259 {"maroon" , PALETTERGB (176, 48, 96)},
1260 {"medium violet red" , PALETTERGB (199, 21,133)},
1261 {"MediumVioletRed" , PALETTERGB (199, 21,133)},
1262 {"violet red" , PALETTERGB (208, 32,144)},
1263 {"VioletRed" , PALETTERGB (208, 32,144)},
1264 {"magenta" , PALETTERGB (255, 0,255)},
1265 {"violet" , PALETTERGB (238,130,238)},
1266 {"plum" , PALETTERGB (221,160,221)},
1267 {"orchid" , PALETTERGB (218,112,214)},
1268 {"medium orchid" , PALETTERGB (186, 85,211)},
1269 {"MediumOrchid" , PALETTERGB (186, 85,211)},
1270 {"dark orchid" , PALETTERGB (153, 50,204)},
1271 {"DarkOrchid" , PALETTERGB (153, 50,204)},
1272 {"dark violet" , PALETTERGB (148, 0,211)},
1273 {"DarkViolet" , PALETTERGB (148, 0,211)},
1274 {"blue violet" , PALETTERGB (138, 43,226)},
1275 {"BlueViolet" , PALETTERGB (138, 43,226)},
1276 {"purple" , PALETTERGB (160, 32,240)},
1277 {"medium purple" , PALETTERGB (147,112,219)},
1278 {"MediumPurple" , PALETTERGB (147,112,219)},
1279 {"thistle" , PALETTERGB (216,191,216)},
1280 {"gray0" , PALETTERGB ( 0, 0, 0)},
1281 {"grey0" , PALETTERGB ( 0, 0, 0)},
1282 {"dark grey" , PALETTERGB (169,169,169)},
1283 {"DarkGrey" , PALETTERGB (169,169,169)},
1284 {"dark gray" , PALETTERGB (169,169,169)},
1285 {"DarkGray" , PALETTERGB (169,169,169)},
1286 {"dark blue" , PALETTERGB ( 0, 0,139)},
1287 {"DarkBlue" , PALETTERGB ( 0, 0,139)},
1288 {"dark cyan" , PALETTERGB ( 0,139,139)},
1289 {"DarkCyan" , PALETTERGB ( 0,139,139)},
1290 {"dark magenta" , PALETTERGB (139, 0,139)},
1291 {"DarkMagenta" , PALETTERGB (139, 0,139)},
1292 {"dark red" , PALETTERGB (139, 0, 0)},
1293 {"DarkRed" , PALETTERGB (139, 0, 0)},
1294 {"light green" , PALETTERGB (144,238,144)},
1295 {"LightGreen" , PALETTERGB (144,238,144)},
1298 DEFUN ("w32-default-color-map", Fw32_default_color_map
, Sw32_default_color_map
,
1299 0, 0, 0, "Return the default color map.")
1303 colormap_t
*pc
= w32_color_map
;
1310 for (i
= 0; i
< sizeof (w32_color_map
) / sizeof (w32_color_map
[0]);
1312 cmap
= Fcons (Fcons (build_string (pc
->name
),
1313 make_number (pc
->colorref
)),
1322 w32_to_x_color (rgb
)
1327 CHECK_NUMBER (rgb
, 0);
1331 color
= Frassq (rgb
, Vw32_color_map
);
1336 return (Fcar (color
));
1342 w32_color_map_lookup (colorname
)
1345 Lisp_Object tail
, ret
= Qnil
;
1349 for (tail
= Vw32_color_map
; !NILP (tail
); tail
= Fcdr (tail
))
1351 register Lisp_Object elt
, tem
;
1354 if (!CONSP (elt
)) continue;
1358 if (lstrcmpi (XSTRING (tem
)->data
, colorname
) == 0)
1360 ret
= XUINT (Fcdr (elt
));
1374 x_to_w32_color (colorname
)
1377 register Lisp_Object tail
, ret
= Qnil
;
1381 if (colorname
[0] == '#')
1383 /* Could be an old-style RGB Device specification. */
1386 color
= colorname
+ 1;
1388 size
= strlen(color
);
1389 if (size
== 3 || size
== 6 || size
== 9 || size
== 12)
1397 for (i
= 0; i
< 3; i
++)
1401 unsigned long value
;
1403 /* The check for 'x' in the following conditional takes into
1404 account the fact that strtol allows a "0x" in front of
1405 our numbers, and we don't. */
1406 if (!isxdigit(color
[0]) || color
[1] == 'x')
1410 value
= strtoul(color
, &end
, 16);
1412 if (errno
== ERANGE
|| end
- color
!= size
)
1417 value
= value
* 0x10;
1428 colorval
|= (value
<< pos
);
1439 else if (strnicmp(colorname
, "rgb:", 4) == 0)
1447 color
= colorname
+ 4;
1448 for (i
= 0; i
< 3; i
++)
1451 unsigned long value
;
1453 /* The check for 'x' in the following conditional takes into
1454 account the fact that strtol allows a "0x" in front of
1455 our numbers, and we don't. */
1456 if (!isxdigit(color
[0]) || color
[1] == 'x')
1458 value
= strtoul(color
, &end
, 16);
1459 if (errno
== ERANGE
)
1461 switch (end
- color
)
1464 value
= value
* 0x10 + value
;
1477 if (value
== ULONG_MAX
)
1479 colorval
|= (value
<< pos
);
1493 else if (strnicmp(colorname
, "rgbi:", 5) == 0)
1495 /* This is an RGB Intensity specification. */
1502 color
= colorname
+ 5;
1503 for (i
= 0; i
< 3; i
++)
1509 value
= strtod(color
, &end
);
1510 if (errno
== ERANGE
)
1512 if (value
< 0.0 || value
> 1.0)
1514 val
= (UINT
)(0x100 * value
);
1515 /* We used 0x100 instead of 0xFF to give an continuous
1516 range between 0.0 and 1.0 inclusive. The next statement
1517 fixes the 1.0 case. */
1520 colorval
|= (val
<< pos
);
1534 /* I am not going to attempt to handle any of the CIE color schemes
1535 or TekHVC, since I don't know the algorithms for conversion to
1538 /* If we fail to lookup the color name in w32_color_map, then check the
1539 colorname to see if it can be crudely approximated: If the X color
1540 ends in a number (e.g., "darkseagreen2"), strip the number and
1541 return the result of looking up the base color name. */
1542 ret
= w32_color_map_lookup (colorname
);
1545 int len
= strlen (colorname
);
1547 if (isdigit (colorname
[len
- 1]))
1549 char *ptr
, *approx
= alloca (len
);
1551 strcpy (approx
, colorname
);
1552 ptr
= &approx
[len
- 1];
1553 while (ptr
> approx
&& isdigit (*ptr
))
1556 ret
= w32_color_map_lookup (approx
);
1566 w32_regenerate_palette (FRAME_PTR f
)
1568 struct w32_palette_entry
* list
;
1569 LOGPALETTE
* log_palette
;
1570 HPALETTE new_palette
;
1573 /* don't bother trying to create palette if not supported */
1574 if (! FRAME_W32_DISPLAY_INFO (f
)->has_palette
)
1577 log_palette
= (LOGPALETTE
*)
1578 alloca (sizeof (LOGPALETTE
) +
1579 FRAME_W32_DISPLAY_INFO (f
)->num_colors
* sizeof (PALETTEENTRY
));
1580 log_palette
->palVersion
= 0x300;
1581 log_palette
->palNumEntries
= FRAME_W32_DISPLAY_INFO (f
)->num_colors
;
1583 list
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1585 i
< FRAME_W32_DISPLAY_INFO (f
)->num_colors
;
1586 i
++, list
= list
->next
)
1587 log_palette
->palPalEntry
[i
] = list
->entry
;
1589 new_palette
= CreatePalette (log_palette
);
1593 if (FRAME_W32_DISPLAY_INFO (f
)->palette
)
1594 DeleteObject (FRAME_W32_DISPLAY_INFO (f
)->palette
);
1595 FRAME_W32_DISPLAY_INFO (f
)->palette
= new_palette
;
1597 /* Realize display palette and garbage all frames. */
1598 release_frame_dc (f
, get_frame_dc (f
));
1603 #define W32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1604 #define SET_W32_COLOR(pe, color) \
1607 pe.peRed = GetRValue (color); \
1608 pe.peGreen = GetGValue (color); \
1609 pe.peBlue = GetBValue (color); \
1614 /* Keep these around in case we ever want to track color usage. */
1616 w32_map_color (FRAME_PTR f
, COLORREF color
)
1618 struct w32_palette_entry
* list
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1620 if (NILP (Vw32_enable_palette
))
1623 /* check if color is already mapped */
1626 if (W32_COLOR (list
->entry
) == color
)
1634 /* not already mapped, so add to list and recreate Windows palette */
1635 list
= (struct w32_palette_entry
*)
1636 xmalloc (sizeof (struct w32_palette_entry
));
1637 SET_W32_COLOR (list
->entry
, color
);
1639 list
->next
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1640 FRAME_W32_DISPLAY_INFO (f
)->color_list
= list
;
1641 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 w32_unmap_color (FRAME_PTR f
, COLORREF color
)
1650 struct w32_palette_entry
* list
= FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1651 struct w32_palette_entry
**prev
= &FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1653 if (NILP (Vw32_enable_palette
))
1656 /* check if color is already mapped */
1659 if (W32_COLOR (list
->entry
) == color
)
1661 if (--list
->refcount
== 0)
1665 FRAME_W32_DISPLAY_INFO (f
)->num_colors
--;
1675 /* set flag that palette must be regenerated */
1676 FRAME_W32_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1680 /* Decide if color named COLOR is valid for the display associated with
1681 the selected frame; if so, return the rgb values in COLOR_DEF.
1682 If ALLOC is nonzero, allocate a new colormap cell. */
1685 defined_color (f
, color
, color_def
, alloc
)
1688 COLORREF
*color_def
;
1691 register Lisp_Object tem
;
1693 tem
= x_to_w32_color (color
);
1697 if (!NILP (Vw32_enable_palette
))
1699 struct w32_palette_entry
* entry
=
1700 FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1701 struct w32_palette_entry
** prev
=
1702 &FRAME_W32_DISPLAY_INFO (f
)->color_list
;
1704 /* check if color is already mapped */
1707 if (W32_COLOR (entry
->entry
) == XUINT (tem
))
1709 prev
= &entry
->next
;
1710 entry
= entry
->next
;
1713 if (entry
== NULL
&& alloc
)
1715 /* not already mapped, so add to list */
1716 entry
= (struct w32_palette_entry
*)
1717 xmalloc (sizeof (struct w32_palette_entry
));
1718 SET_W32_COLOR (entry
->entry
, XUINT (tem
));
1721 FRAME_W32_DISPLAY_INFO (f
)->num_colors
++;
1723 /* set flag that palette must be regenerated */
1724 FRAME_W32_DISPLAY_INFO (f
)->regen_palette
= TRUE
;
1727 /* Ensure COLORREF value is snapped to nearest color in (default)
1728 palette by simulating the PALETTERGB macro. This works whether
1729 or not the display device has a palette. */
1730 *color_def
= XUINT (tem
) | 0x2000000;
1739 /* Given a string ARG naming a color, compute a pixel value from it
1740 suitable for screen F.
1741 If F is not a color screen, return DEF (default) regardless of what
1745 x_decode_color (f
, arg
, def
)
1752 CHECK_STRING (arg
, 0);
1754 if (strcmp (XSTRING (arg
)->data
, "black") == 0)
1755 return BLACK_PIX_DEFAULT (f
);
1756 else if (strcmp (XSTRING (arg
)->data
, "white") == 0)
1757 return WHITE_PIX_DEFAULT (f
);
1759 if ((FRAME_W32_DISPLAY_INFO (f
)->n_planes
* FRAME_W32_DISPLAY_INFO (f
)->n_cbits
) == 1)
1762 /* defined_color is responsible for coping with failures
1763 by looking for a near-miss. */
1764 if (defined_color (f
, XSTRING (arg
)->data
, &cdef
, 1))
1767 /* defined_color failed; return an ultimate default. */
1771 /* Functions called only from `x_set_frame_param'
1772 to set individual parameters.
1774 If FRAME_W32_WINDOW (f) is 0,
1775 the frame is being created and its window does not exist yet.
1776 In that case, just record the parameter's new value
1777 in the standard place; do not attempt to change the window. */
1780 x_set_foreground_color (f
, arg
, oldval
)
1782 Lisp_Object arg
, oldval
;
1784 f
->output_data
.w32
->foreground_pixel
1785 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1787 if (FRAME_W32_WINDOW (f
) != 0)
1789 recompute_basic_faces (f
);
1790 if (FRAME_VISIBLE_P (f
))
1796 x_set_background_color (f
, arg
, oldval
)
1798 Lisp_Object arg
, oldval
;
1803 f
->output_data
.w32
->background_pixel
1804 = x_decode_color (f
, arg
, WHITE_PIX_DEFAULT (f
));
1806 if (FRAME_W32_WINDOW (f
) != 0)
1808 SetWindowLong (FRAME_W32_WINDOW (f
), WND_BACKGROUND_INDEX
, f
->output_data
.w32
->background_pixel
);
1810 recompute_basic_faces (f
);
1812 if (FRAME_VISIBLE_P (f
))
1818 x_set_mouse_color (f
, arg
, oldval
)
1820 Lisp_Object arg
, oldval
;
1823 Cursor cursor
, nontext_cursor
, mode_cursor
, cross_cursor
;
1828 if (!EQ (Qnil
, arg
))
1829 f
->output_data
.w32
->mouse_pixel
1830 = x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1831 mask_color
= f
->output_data
.w32
->background_pixel
;
1832 /* No invisible pointers. */
1833 if (mask_color
== f
->output_data
.w32
->mouse_pixel
1834 && mask_color
== f
->output_data
.w32
->background_pixel
)
1835 f
->output_data
.w32
->mouse_pixel
= f
->output_data
.w32
->foreground_pixel
;
1840 /* It's not okay to crash if the user selects a screwy cursor. */
1841 count
= x_catch_errors (FRAME_W32_DISPLAY (f
));
1843 if (!EQ (Qnil
, Vx_pointer_shape
))
1845 CHECK_NUMBER (Vx_pointer_shape
, 0);
1846 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XINT (Vx_pointer_shape
));
1849 cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1850 x_check_errors (FRAME_W32_DISPLAY (f
), "bad text pointer cursor: %s");
1852 if (!EQ (Qnil
, Vx_nontext_pointer_shape
))
1854 CHECK_NUMBER (Vx_nontext_pointer_shape
, 0);
1855 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1856 XINT (Vx_nontext_pointer_shape
));
1859 nontext_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_left_ptr
);
1860 x_check_errors (FRAME_W32_DISPLAY (f
), "bad nontext pointer cursor: %s");
1862 if (!EQ (Qnil
, Vx_mode_pointer_shape
))
1864 CHECK_NUMBER (Vx_mode_pointer_shape
, 0);
1865 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1866 XINT (Vx_mode_pointer_shape
));
1869 mode_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_xterm
);
1870 x_check_errors (FRAME_W32_DISPLAY (f
), "bad modeline pointer cursor: %s");
1872 if (!EQ (Qnil
, Vx_sensitive_text_pointer_shape
))
1874 CHECK_NUMBER (Vx_sensitive_text_pointer_shape
, 0);
1876 = XCreateFontCursor (FRAME_W32_DISPLAY (f
),
1877 XINT (Vx_sensitive_text_pointer_shape
));
1880 cross_cursor
= XCreateFontCursor (FRAME_W32_DISPLAY (f
), XC_crosshair
);
1882 /* Check and report errors with the above calls. */
1883 x_check_errors (FRAME_W32_DISPLAY (f
), "can't set cursor shape: %s");
1884 x_uncatch_errors (FRAME_W32_DISPLAY (f
), count
);
1887 XColor fore_color
, back_color
;
1889 fore_color
.pixel
= f
->output_data
.w32
->mouse_pixel
;
1890 back_color
.pixel
= mask_color
;
1891 XQueryColor (FRAME_W32_DISPLAY (f
),
1892 DefaultColormap (FRAME_W32_DISPLAY (f
),
1893 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1895 XQueryColor (FRAME_W32_DISPLAY (f
),
1896 DefaultColormap (FRAME_W32_DISPLAY (f
),
1897 DefaultScreen (FRAME_W32_DISPLAY (f
))),
1899 XRecolorCursor (FRAME_W32_DISPLAY (f
), cursor
,
1900 &fore_color
, &back_color
);
1901 XRecolorCursor (FRAME_W32_DISPLAY (f
), nontext_cursor
,
1902 &fore_color
, &back_color
);
1903 XRecolorCursor (FRAME_W32_DISPLAY (f
), mode_cursor
,
1904 &fore_color
, &back_color
);
1905 XRecolorCursor (FRAME_W32_DISPLAY (f
), cross_cursor
,
1906 &fore_color
, &back_color
);
1909 if (FRAME_W32_WINDOW (f
) != 0)
1911 XDefineCursor (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
), cursor
);
1914 if (cursor
!= f
->output_data
.w32
->text_cursor
&& f
->output_data
.w32
->text_cursor
!= 0)
1915 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->text_cursor
);
1916 f
->output_data
.w32
->text_cursor
= cursor
;
1918 if (nontext_cursor
!= f
->output_data
.w32
->nontext_cursor
1919 && f
->output_data
.w32
->nontext_cursor
!= 0)
1920 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->nontext_cursor
);
1921 f
->output_data
.w32
->nontext_cursor
= nontext_cursor
;
1923 if (mode_cursor
!= f
->output_data
.w32
->modeline_cursor
1924 && f
->output_data
.w32
->modeline_cursor
!= 0)
1925 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->modeline_cursor
);
1926 f
->output_data
.w32
->modeline_cursor
= mode_cursor
;
1927 if (cross_cursor
!= f
->output_data
.w32
->cross_cursor
1928 && f
->output_data
.w32
->cross_cursor
!= 0)
1929 XFreeCursor (FRAME_W32_DISPLAY (f
), f
->output_data
.w32
->cross_cursor
);
1930 f
->output_data
.w32
->cross_cursor
= cross_cursor
;
1932 XFlush (FRAME_W32_DISPLAY (f
));
1938 x_set_cursor_color (f
, arg
, oldval
)
1940 Lisp_Object arg
, oldval
;
1942 unsigned long fore_pixel
;
1944 if (!EQ (Vx_cursor_fore_pixel
, Qnil
))
1945 fore_pixel
= x_decode_color (f
, Vx_cursor_fore_pixel
,
1946 WHITE_PIX_DEFAULT (f
));
1948 fore_pixel
= f
->output_data
.w32
->background_pixel
;
1949 f
->output_data
.w32
->cursor_pixel
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
1951 /* Make sure that the cursor color differs from the background color. */
1952 if (f
->output_data
.w32
->cursor_pixel
== f
->output_data
.w32
->background_pixel
)
1954 f
->output_data
.w32
->cursor_pixel
= f
->output_data
.w32
->mouse_pixel
;
1955 if (f
->output_data
.w32
->cursor_pixel
== fore_pixel
)
1956 fore_pixel
= f
->output_data
.w32
->background_pixel
;
1958 f
->output_data
.w32
->cursor_foreground_pixel
= fore_pixel
;
1960 if (FRAME_W32_WINDOW (f
) != 0)
1962 if (FRAME_VISIBLE_P (f
))
1964 x_display_cursor (f
, 0);
1965 x_display_cursor (f
, 1);
1970 /* Set the border-color of frame F to pixel value PIX.
1971 Note that this does not fully take effect if done before
1974 x_set_border_pixel (f
, pix
)
1978 f
->output_data
.w32
->border_pixel
= pix
;
1980 if (FRAME_W32_WINDOW (f
) != 0 && f
->output_data
.w32
->border_width
> 0)
1982 if (FRAME_VISIBLE_P (f
))
1987 /* Set the border-color of frame F to value described by ARG.
1988 ARG can be a string naming a color.
1989 The border-color is used for the border that is drawn by the server.
1990 Note that this does not fully take effect if done before
1991 F has a window; it must be redone when the window is created. */
1994 x_set_border_color (f
, arg
, oldval
)
1996 Lisp_Object arg
, oldval
;
2001 CHECK_STRING (arg
, 0);
2002 str
= XSTRING (arg
)->data
;
2004 pix
= x_decode_color (f
, arg
, BLACK_PIX_DEFAULT (f
));
2006 x_set_border_pixel (f
, pix
);
2010 x_set_cursor_type (f
, arg
, oldval
)
2012 Lisp_Object arg
, oldval
;
2016 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
2017 f
->output_data
.w32
->cursor_width
= 2;
2019 else if (CONSP (arg
) && EQ (XCONS (arg
)->car
, Qbar
)
2020 && INTEGERP (XCONS (arg
)->cdr
))
2022 FRAME_DESIRED_CURSOR (f
) = bar_cursor
;
2023 f
->output_data
.w32
->cursor_width
= XINT (XCONS (arg
)->cdr
);
2026 /* Treat anything unknown as "box cursor".
2027 It was bad to signal an error; people have trouble fixing
2028 .Xdefaults with Emacs, when it has something bad in it. */
2029 FRAME_DESIRED_CURSOR (f
) = filled_box_cursor
;
2031 /* Make sure the cursor gets redrawn. This is overkill, but how
2032 often do people change cursor types? */
2033 update_mode_lines
++;
2037 x_set_icon_type (f
, arg
, oldval
)
2039 Lisp_Object arg
, oldval
;
2047 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2050 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2055 result
= x_text_icon (f
,
2056 (char *) XSTRING ((!NILP (f
->icon_name
)
2060 result
= x_bitmap_icon (f
, arg
);
2065 error ("No icon window available");
2068 /* If the window was unmapped (and its icon was mapped),
2069 the new icon is not mapped, so map the window in its stead. */
2070 if (FRAME_VISIBLE_P (f
))
2072 #ifdef USE_X_TOOLKIT
2073 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2075 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2078 XFlush (FRAME_W32_DISPLAY (f
));
2083 /* Return non-nil if frame F wants a bitmap icon. */
2091 tem
= assq_no_quit (Qicon_type
, f
->param_alist
);
2093 return XCONS (tem
)->cdr
;
2099 x_set_icon_name (f
, arg
, oldval
)
2101 Lisp_Object arg
, oldval
;
2108 if (STRINGP (oldval
) && EQ (Fstring_equal (oldval
, arg
), Qt
))
2111 else if (!STRINGP (oldval
) && EQ (oldval
, Qnil
) == EQ (arg
, Qnil
))
2117 if (f
->output_data
.w32
->icon_bitmap
!= 0)
2122 result
= x_text_icon (f
,
2123 (char *) XSTRING ((!NILP (f
->icon_name
)
2132 error ("No icon window available");
2135 /* If the window was unmapped (and its icon was mapped),
2136 the new icon is not mapped, so map the window in its stead. */
2137 if (FRAME_VISIBLE_P (f
))
2139 #ifdef USE_X_TOOLKIT
2140 XtPopup (f
->output_data
.w32
->widget
, XtGrabNone
);
2142 XMapWindow (FRAME_W32_DISPLAY (f
), FRAME_W32_WINDOW (f
));
2145 XFlush (FRAME_W32_DISPLAY (f
));
2150 extern Lisp_Object
x_new_font ();
2151 extern Lisp_Object
x_new_fontset();
2154 x_set_font (f
, arg
, oldval
)
2156 Lisp_Object arg
, oldval
;
2159 Lisp_Object fontset_name
;
2162 CHECK_STRING (arg
, 1);
2164 fontset_name
= Fquery_fontset (arg
, Qnil
);
2167 result
= (STRINGP (fontset_name
)
2168 ? x_new_fontset (f
, XSTRING (fontset_name
)->data
)
2169 : x_new_font (f
, XSTRING (arg
)->data
));
2172 if (EQ (result
, Qnil
))
2173 error ("Font \"%s\" is not defined", XSTRING (arg
)->data
);
2174 else if (EQ (result
, Qt
))
2175 error ("the characters of the given font have varying widths");
2176 else if (STRINGP (result
))
2178 recompute_basic_faces (f
);
2179 store_frame_param (f
, Qfont
, result
);
2184 XSETFRAME (frame
, f
);
2185 call1 (Qface_set_after_frame_default
, frame
);
2189 x_set_border_width (f
, arg
, oldval
)
2191 Lisp_Object arg
, oldval
;
2193 CHECK_NUMBER (arg
, 0);
2195 if (XINT (arg
) == f
->output_data
.w32
->border_width
)
2198 if (FRAME_W32_WINDOW (f
) != 0)
2199 error ("Cannot change the border width of a window");
2201 f
->output_data
.w32
->border_width
= XINT (arg
);
2205 x_set_internal_border_width (f
, arg
, oldval
)
2207 Lisp_Object arg
, oldval
;
2210 int old
= f
->output_data
.w32
->internal_border_width
;
2212 CHECK_NUMBER (arg
, 0);
2213 f
->output_data
.w32
->internal_border_width
= XINT (arg
);
2214 if (f
->output_data
.w32
->internal_border_width
< 0)
2215 f
->output_data
.w32
->internal_border_width
= 0;
2217 if (f
->output_data
.w32
->internal_border_width
== old
)
2220 if (FRAME_W32_WINDOW (f
) != 0)
2223 x_set_window_size (f
, 0, f
->width
, f
->height
);
2225 SET_FRAME_GARBAGED (f
);
2230 x_set_visibility (f
, value
, oldval
)
2232 Lisp_Object value
, oldval
;
2235 XSETFRAME (frame
, f
);
2238 Fmake_frame_invisible (frame
, Qt
);
2239 else if (EQ (value
, Qicon
))
2240 Ficonify_frame (frame
);
2242 Fmake_frame_visible (frame
);
2246 x_set_menu_bar_lines (f
, value
, oldval
)
2248 Lisp_Object value
, oldval
;
2251 int olines
= FRAME_MENU_BAR_LINES (f
);
2253 /* Right now, menu bars don't work properly in minibuf-only frames;
2254 most of the commands try to apply themselves to the minibuffer
2255 frame itslef, and get an error because you can't switch buffers
2256 in or split the minibuffer window. */
2257 if (FRAME_MINIBUF_ONLY_P (f
))
2260 if (INTEGERP (value
))
2261 nlines
= XINT (value
);
2265 FRAME_MENU_BAR_LINES (f
) = 0;
2267 FRAME_EXTERNAL_MENU_BAR (f
) = 1;
2270 if (FRAME_EXTERNAL_MENU_BAR (f
) == 1)
2271 free_frame_menubar (f
);
2272 FRAME_EXTERNAL_MENU_BAR (f
) = 0;
2274 /* Adjust the frame size so that the client (text) dimensions
2275 remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
2277 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2281 /* Change the name of frame F to NAME. If NAME is nil, set F's name to
2284 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2285 name; if NAME is a string, set F's name to NAME and set
2286 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2288 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2289 suggesting a new name, which lisp code should override; if
2290 F->explicit_name is set, ignore the new name; otherwise, set it. */
2293 x_set_name (f
, name
, explicit)
2298 /* Make sure that requests from lisp code override requests from
2299 Emacs redisplay code. */
2302 /* If we're switching from explicit to implicit, we had better
2303 update the mode lines and thereby update the title. */
2304 if (f
->explicit_name
&& NILP (name
))
2305 update_mode_lines
= 1;
2307 f
->explicit_name
= ! NILP (name
);
2309 else if (f
->explicit_name
)
2312 /* If NAME is nil, set the name to the w32_id_name. */
2315 /* Check for no change needed in this very common case
2316 before we do any consing. */
2317 if (!strcmp (FRAME_W32_DISPLAY_INFO (f
)->w32_id_name
,
2318 XSTRING (f
->name
)->data
))
2320 name
= build_string (FRAME_W32_DISPLAY_INFO (f
)->w32_id_name
);
2323 CHECK_STRING (name
, 0);
2325 /* Don't change the name if it's already NAME. */
2326 if (! NILP (Fstring_equal (name
, f
->name
)))
2331 /* For setting the frame title, the title parameter should override
2332 the name parameter. */
2333 if (! NILP (f
->title
))
2336 if (FRAME_W32_WINDOW (f
))
2339 SetWindowText(FRAME_W32_WINDOW (f
), XSTRING (name
)->data
);
2344 /* This function should be called when the user's lisp code has
2345 specified a name for the frame; the name will override any set by the
2348 x_explicitly_set_name (f
, arg
, oldval
)
2350 Lisp_Object arg
, oldval
;
2352 x_set_name (f
, arg
, 1);
2355 /* This function should be called by Emacs redisplay code to set the
2356 name; names set this way will never override names set by the user's
2359 x_implicitly_set_name (f
, arg
, oldval
)
2361 Lisp_Object arg
, oldval
;
2363 x_set_name (f
, arg
, 0);
2366 /* Change the title of frame F to NAME.
2367 If NAME is nil, use the frame name as the title.
2369 If EXPLICIT is non-zero, that indicates that lisp code is setting the
2370 name; if NAME is a string, set F's name to NAME and set
2371 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
2373 If EXPLICIT is zero, that indicates that Emacs redisplay code is
2374 suggesting a new name, which lisp code should override; if
2375 F->explicit_name is set, ignore the new name; otherwise, set it. */
2378 x_set_title (f
, name
)
2382 /* Don't change the title if it's already NAME. */
2383 if (EQ (name
, f
->title
))
2386 update_mode_lines
= 1;
2393 if (FRAME_W32_WINDOW (f
))
2396 SetWindowText(FRAME_W32_WINDOW (f
), XSTRING (name
)->data
);
2402 x_set_autoraise (f
, arg
, oldval
)
2404 Lisp_Object arg
, oldval
;
2406 f
->auto_raise
= !EQ (Qnil
, arg
);
2410 x_set_autolower (f
, arg
, oldval
)
2412 Lisp_Object arg
, oldval
;
2414 f
->auto_lower
= !EQ (Qnil
, arg
);
2418 x_set_unsplittable (f
, arg
, oldval
)
2420 Lisp_Object arg
, oldval
;
2422 f
->no_split
= !NILP (arg
);
2426 x_set_vertical_scroll_bars (f
, arg
, oldval
)
2428 Lisp_Object arg
, oldval
;
2430 if ((EQ (arg
, Qleft
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f
))
2431 || (EQ (arg
, Qright
) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
2432 || (NILP (arg
) && FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
2433 || (!NILP (arg
) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f
)))
2435 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = NILP (arg
) ?
2436 vertical_scroll_bar_none
:
2437 /* Put scroll bars on the right by default, as is conventional
2440 ? vertical_scroll_bar_left
2441 : vertical_scroll_bar_right
;
2443 /* We set this parameter before creating the window for the
2444 frame, so we can get the geometry right from the start.
2445 However, if the window hasn't been created yet, we shouldn't
2446 call x_set_window_size. */
2447 if (FRAME_W32_WINDOW (f
))
2448 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2453 x_set_scroll_bar_width (f
, arg
, oldval
)
2455 Lisp_Object arg
, oldval
;
2459 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = 0;
2460 FRAME_SCROLL_BAR_COLS (f
) = 2;
2462 else if (INTEGERP (arg
) && XINT (arg
) > 0
2463 && XFASTINT (arg
) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f
))
2465 int wid
= FONT_WIDTH (f
->output_data
.w32
->font
);
2466 FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) = XFASTINT (arg
);
2467 FRAME_SCROLL_BAR_COLS (f
) = (XFASTINT (arg
) + wid
-1) / wid
;
2468 if (FRAME_W32_WINDOW (f
))
2469 x_set_window_size (f
, 0, FRAME_WIDTH (f
), FRAME_HEIGHT (f
));
2473 /* Subroutines of creating an frame. */
2475 /* Make sure that Vx_resource_name is set to a reasonable value.
2476 Fix it up, or set it to `emacs' if it is too hopeless. */
2479 validate_x_resource_name ()
2482 /* Number of valid characters in the resource name. */
2484 /* Number of invalid characters in the resource name. */
2489 if (STRINGP (Vx_resource_name
))
2491 unsigned char *p
= XSTRING (Vx_resource_name
)->data
;
2494 len
= XSTRING (Vx_resource_name
)->size
;
2496 /* Only letters, digits, - and _ are valid in resource names.
2497 Count the valid characters and count the invalid ones. */
2498 for (i
= 0; i
< len
; i
++)
2501 if (! ((c
>= 'a' && c
<= 'z')
2502 || (c
>= 'A' && c
<= 'Z')
2503 || (c
>= '0' && c
<= '9')
2504 || c
== '-' || c
== '_'))
2511 /* Not a string => completely invalid. */
2512 bad_count
= 5, good_count
= 0;
2514 /* If name is valid already, return. */
2518 /* If name is entirely invalid, or nearly so, use `emacs'. */
2520 || (good_count
== 1 && bad_count
> 0))
2522 Vx_resource_name
= build_string ("emacs");
2526 /* Name is partly valid. Copy it and replace the invalid characters
2527 with underscores. */
2529 Vx_resource_name
= new = Fcopy_sequence (Vx_resource_name
);
2531 for (i
= 0; i
< len
; i
++)
2533 int c
= XSTRING (new)->data
[i
];
2534 if (! ((c
>= 'a' && c
<= 'z')
2535 || (c
>= 'A' && c
<= 'Z')
2536 || (c
>= '0' && c
<= '9')
2537 || c
== '-' || c
== '_'))
2538 XSTRING (new)->data
[i
] = '_';
2543 extern char *x_get_string_resource ();
2545 DEFUN ("x-get-resource", Fx_get_resource
, Sx_get_resource
, 2, 4, 0,
2546 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2547 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2548 class, where INSTANCE is the name under which Emacs was invoked, or\n\
2549 the name specified by the `-name' or `-rn' command-line arguments.\n\
2551 The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2552 class, respectively. You must specify both of them or neither.\n\
2553 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2554 and the class is `Emacs.CLASS.SUBCLASS'.")
2555 (attribute
, class, component
, subclass
)
2556 Lisp_Object attribute
, class, component
, subclass
;
2558 register char *value
;
2562 CHECK_STRING (attribute
, 0);
2563 CHECK_STRING (class, 0);
2565 if (!NILP (component
))
2566 CHECK_STRING (component
, 1);
2567 if (!NILP (subclass
))
2568 CHECK_STRING (subclass
, 2);
2569 if (NILP (component
) != NILP (subclass
))
2570 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2572 validate_x_resource_name ();
2574 /* Allocate space for the components, the dots which separate them,
2575 and the final '\0'. Make them big enough for the worst case. */
2576 name_key
= (char *) alloca (XSTRING (Vx_resource_name
)->size
2577 + (STRINGP (component
)
2578 ? XSTRING (component
)->size
: 0)
2579 + XSTRING (attribute
)->size
2582 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2583 + XSTRING (class)->size
2584 + (STRINGP (subclass
)
2585 ? XSTRING (subclass
)->size
: 0)
2588 /* Start with emacs.FRAMENAME for the name (the specific one)
2589 and with `Emacs' for the class key (the general one). */
2590 strcpy (name_key
, XSTRING (Vx_resource_name
)->data
);
2591 strcpy (class_key
, EMACS_CLASS
);
2593 strcat (class_key
, ".");
2594 strcat (class_key
, XSTRING (class)->data
);
2596 if (!NILP (component
))
2598 strcat (class_key
, ".");
2599 strcat (class_key
, XSTRING (subclass
)->data
);
2601 strcat (name_key
, ".");
2602 strcat (name_key
, XSTRING (component
)->data
);
2605 strcat (name_key
, ".");
2606 strcat (name_key
, XSTRING (attribute
)->data
);
2608 value
= x_get_string_resource (Qnil
,
2609 name_key
, class_key
);
2611 if (value
!= (char *) 0)
2612 return build_string (value
);
2617 /* Used when C code wants a resource value. */
2620 x_get_resource_string (attribute
, class)
2621 char *attribute
, *class;
2623 register char *value
;
2627 /* Allocate space for the components, the dots which separate them,
2628 and the final '\0'. */
2629 name_key
= (char *) alloca (XSTRING (Vinvocation_name
)->size
2630 + strlen (attribute
) + 2);
2631 class_key
= (char *) alloca ((sizeof (EMACS_CLASS
) - 1)
2632 + strlen (class) + 2);
2634 sprintf (name_key
, "%s.%s",
2635 XSTRING (Vinvocation_name
)->data
,
2637 sprintf (class_key
, "%s.%s", EMACS_CLASS
, class);
2639 return x_get_string_resource (selected_frame
,
2640 name_key
, class_key
);
2643 /* Types we might convert a resource string into. */
2646 number
, boolean
, string
, symbol
2649 /* Return the value of parameter PARAM.
2651 First search ALIST, then Vdefault_frame_alist, then the X defaults
2652 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2654 Convert the resource to the type specified by desired_type.
2656 If no default is specified, return Qunbound. If you call
2657 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2658 and don't let it get stored in any Lisp-visible variables! */
2661 x_get_arg (alist
, param
, attribute
, class, type
)
2662 Lisp_Object alist
, param
;
2665 enum resource_types type
;
2667 register Lisp_Object tem
;
2669 tem
= Fassq (param
, alist
);
2671 tem
= Fassq (param
, Vdefault_frame_alist
);
2677 tem
= Fx_get_resource (build_string (attribute
),
2678 build_string (class),
2687 return make_number (atoi (XSTRING (tem
)->data
));
2690 tem
= Fdowncase (tem
);
2691 if (!strcmp (XSTRING (tem
)->data
, "on")
2692 || !strcmp (XSTRING (tem
)->data
, "true"))
2701 /* As a special case, we map the values `true' and `on'
2702 to Qt, and `false' and `off' to Qnil. */
2705 lower
= Fdowncase (tem
);
2706 if (!strcmp (XSTRING (lower
)->data
, "on")
2707 || !strcmp (XSTRING (lower
)->data
, "true"))
2709 else if (!strcmp (XSTRING (lower
)->data
, "off")
2710 || !strcmp (XSTRING (lower
)->data
, "false"))
2713 return Fintern (tem
, Qnil
);
2726 /* Record in frame F the specified or default value according to ALIST
2727 of the parameter named PARAM (a Lisp symbol).
2728 If no value is specified for PARAM, look for an X default for XPROP
2729 on the frame named NAME.
2730 If that is not found either, use the value DEFLT. */
2733 x_default_parameter (f
, alist
, prop
, deflt
, xprop
, xclass
, type
)
2740 enum resource_types type
;
2744 tem
= x_get_arg (alist
, prop
, xprop
, xclass
, type
);
2745 if (EQ (tem
, Qunbound
))
2747 x_set_frame_parameters (f
, Fcons (Fcons (prop
, tem
), Qnil
));
2751 DEFUN ("x-parse-geometry", Fx_parse_geometry
, Sx_parse_geometry
, 1, 1, 0,
2752 "Parse an X-style geometry string STRING.\n\
2753 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2754 The properties returned may include `top', `left', `height', and `width'.\n\
2755 The value of `left' or `top' may be an integer,\n\
2756 or a list (+ N) meaning N pixels relative to top/left corner,\n\
2757 or a list (- N) meaning -N pixels relative to bottom/right corner.")
2762 unsigned int width
, height
;
2765 CHECK_STRING (string
, 0);
2767 geometry
= XParseGeometry ((char *) XSTRING (string
)->data
,
2768 &x
, &y
, &width
, &height
);
2771 if (geometry
& XValue
)
2773 Lisp_Object element
;
2775 if (x
>= 0 && (geometry
& XNegative
))
2776 element
= Fcons (Qleft
, Fcons (Qminus
, Fcons (make_number (-x
), Qnil
)));
2777 else if (x
< 0 && ! (geometry
& XNegative
))
2778 element
= Fcons (Qleft
, Fcons (Qplus
, Fcons (make_number (x
), Qnil
)));
2780 element
= Fcons (Qleft
, make_number (x
));
2781 result
= Fcons (element
, result
);
2784 if (geometry
& YValue
)
2786 Lisp_Object element
;
2788 if (y
>= 0 && (geometry
& YNegative
))
2789 element
= Fcons (Qtop
, Fcons (Qminus
, Fcons (make_number (-y
), Qnil
)));
2790 else if (y
< 0 && ! (geometry
& YNegative
))
2791 element
= Fcons (Qtop
, Fcons (Qplus
, Fcons (make_number (y
), Qnil
)));
2793 element
= Fcons (Qtop
, make_number (y
));
2794 result
= Fcons (element
, result
);
2797 if (geometry
& WidthValue
)
2798 result
= Fcons (Fcons (Qwidth
, make_number (width
)), result
);
2799 if (geometry
& HeightValue
)
2800 result
= Fcons (Fcons (Qheight
, make_number (height
)), result
);
2805 /* Calculate the desired size and position of this window,
2806 and return the flags saying which aspects were specified.
2808 This function does not make the coordinates positive. */
2810 #define DEFAULT_ROWS 40
2811 #define DEFAULT_COLS 80
2814 x_figure_window_size (f
, parms
)
2818 register Lisp_Object tem0
, tem1
, tem2
;
2819 int height
, width
, left
, top
;
2820 register int geometry
;
2821 long window_prompting
= 0;
2823 /* Default values if we fall through.
2824 Actually, if that happens we should get
2825 window manager prompting. */
2826 SET_FRAME_WIDTH (f
, DEFAULT_COLS
);
2827 f
->height
= DEFAULT_ROWS
;
2828 /* Window managers expect that if program-specified
2829 positions are not (0,0), they're intentional, not defaults. */
2830 f
->output_data
.w32
->top_pos
= 0;
2831 f
->output_data
.w32
->left_pos
= 0;
2833 tem0
= x_get_arg (parms
, Qheight
, 0, 0, number
);
2834 tem1
= x_get_arg (parms
, Qwidth
, 0, 0, number
);
2835 tem2
= x_get_arg (parms
, Quser_size
, 0, 0, number
);
2836 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2838 if (!EQ (tem0
, Qunbound
))
2840 CHECK_NUMBER (tem0
, 0);
2841 f
->height
= XINT (tem0
);
2843 if (!EQ (tem1
, Qunbound
))
2845 CHECK_NUMBER (tem1
, 0);
2846 SET_FRAME_WIDTH (f
, XINT (tem1
));
2848 if (!NILP (tem2
) && !EQ (tem2
, Qunbound
))
2849 window_prompting
|= USSize
;
2851 window_prompting
|= PSize
;
2854 f
->output_data
.w32
->vertical_scroll_bar_extra
2855 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
2857 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f
) > 0
2858 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f
)
2859 : (FRAME_SCROLL_BAR_COLS (f
) * FONT_WIDTH (f
->output_data
.w32
->font
)));
2860 f
->output_data
.w32
->pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, f
->width
);
2861 f
->output_data
.w32
->pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, f
->height
);
2863 tem0
= x_get_arg (parms
, Qtop
, 0, 0, number
);
2864 tem1
= x_get_arg (parms
, Qleft
, 0, 0, number
);
2865 tem2
= x_get_arg (parms
, Quser_position
, 0, 0, number
);
2866 if (! EQ (tem0
, Qunbound
) || ! EQ (tem1
, Qunbound
))
2868 if (EQ (tem0
, Qminus
))
2870 f
->output_data
.w32
->top_pos
= 0;
2871 window_prompting
|= YNegative
;
2873 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qminus
)
2874 && CONSP (XCONS (tem0
)->cdr
)
2875 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2877 f
->output_data
.w32
->top_pos
= - XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2878 window_prompting
|= YNegative
;
2880 else if (CONSP (tem0
) && EQ (XCONS (tem0
)->car
, Qplus
)
2881 && CONSP (XCONS (tem0
)->cdr
)
2882 && INTEGERP (XCONS (XCONS (tem0
)->cdr
)->car
))
2884 f
->output_data
.w32
->top_pos
= XINT (XCONS (XCONS (tem0
)->cdr
)->car
);
2886 else if (EQ (tem0
, Qunbound
))
2887 f
->output_data
.w32
->top_pos
= 0;
2890 CHECK_NUMBER (tem0
, 0);
2891 f
->output_data
.w32
->top_pos
= XINT (tem0
);
2892 if (f
->output_data
.w32
->top_pos
< 0)
2893 window_prompting
|= YNegative
;
2896 if (EQ (tem1
, Qminus
))
2898 f
->output_data
.w32
->left_pos
= 0;
2899 window_prompting
|= XNegative
;
2901 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qminus
)
2902 && CONSP (XCONS (tem1
)->cdr
)
2903 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2905 f
->output_data
.w32
->left_pos
= - XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2906 window_prompting
|= XNegative
;
2908 else if (CONSP (tem1
) && EQ (XCONS (tem1
)->car
, Qplus
)
2909 && CONSP (XCONS (tem1
)->cdr
)
2910 && INTEGERP (XCONS (XCONS (tem1
)->cdr
)->car
))
2912 f
->output_data
.w32
->left_pos
= XINT (XCONS (XCONS (tem1
)->cdr
)->car
);
2914 else if (EQ (tem1
, Qunbound
))
2915 f
->output_data
.w32
->left_pos
= 0;
2918 CHECK_NUMBER (tem1
, 0);
2919 f
->output_data
.w32
->left_pos
= XINT (tem1
);
2920 if (f
->output_data
.w32
->left_pos
< 0)
2921 window_prompting
|= XNegative
;
2924 if (!NILP (tem2
) && ! EQ (tem2
, Qunbound
))
2925 window_prompting
|= USPosition
;
2927 window_prompting
|= PPosition
;
2930 return window_prompting
;
2935 extern LRESULT CALLBACK
w32_wnd_proc ();
2938 w32_init_class (hinst
)
2943 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
2944 wc
.lpfnWndProc
= (WNDPROC
) w32_wnd_proc
;
2946 wc
.cbWndExtra
= WND_EXTRA_BYTES
;
2947 wc
.hInstance
= hinst
;
2948 wc
.hIcon
= LoadIcon (hinst
, EMACS_CLASS
);
2949 wc
.hCursor
= LoadCursor (NULL
, IDC_ARROW
);
2950 wc
.hbrBackground
= NULL
; /* GetStockObject (WHITE_BRUSH); */
2951 wc
.lpszMenuName
= NULL
;
2952 wc
.lpszClassName
= EMACS_CLASS
;
2954 return (RegisterClass (&wc
));
2958 w32_createscrollbar (f
, bar
)
2960 struct scroll_bar
* bar
;
2962 return (CreateWindow ("SCROLLBAR", "", SBS_VERT
| WS_CHILD
| WS_VISIBLE
,
2963 /* Position and size of scroll bar. */
2964 XINT(bar
->left
), XINT(bar
->top
),
2965 XINT(bar
->width
), XINT(bar
->height
),
2966 FRAME_W32_WINDOW (f
),
2973 w32_createwindow (f
)
2979 rect
.left
= rect
.top
= 0;
2980 rect
.right
= PIXEL_WIDTH (f
);
2981 rect
.bottom
= PIXEL_HEIGHT (f
);
2983 AdjustWindowRect (&rect
, f
->output_data
.w32
->dwStyle
,
2984 FRAME_EXTERNAL_MENU_BAR (f
));
2986 /* Do first time app init */
2990 w32_init_class (hinst
);
2993 FRAME_W32_WINDOW (f
) = hwnd
2994 = CreateWindow (EMACS_CLASS
,
2996 f
->output_data
.w32
->dwStyle
| WS_CLIPCHILDREN
,
2997 f
->output_data
.w32
->left_pos
,
2998 f
->output_data
.w32
->top_pos
,
2999 rect
.right
- rect
.left
,
3000 rect
.bottom
- rect
.top
,
3008 SetWindowLong (hwnd
, WND_FONTWIDTH_INDEX
, FONT_WIDTH (f
->output_data
.w32
->font
));
3009 SetWindowLong (hwnd
, WND_LINEHEIGHT_INDEX
, f
->output_data
.w32
->line_height
);
3010 SetWindowLong (hwnd
, WND_BORDER_INDEX
, f
->output_data
.w32
->internal_border_width
);
3011 SetWindowLong (hwnd
, WND_SCROLLBAR_INDEX
, f
->output_data
.w32
->vertical_scroll_bar_extra
);
3012 SetWindowLong (hwnd
, WND_BACKGROUND_INDEX
, f
->output_data
.w32
->background_pixel
);
3014 /* Enable drag-n-drop. */
3015 DragAcceptFiles (hwnd
, TRUE
);
3017 /* Do this to discard the default setting specified by our parent. */
3018 ShowWindow (hwnd
, SW_HIDE
);
3023 my_post_msg (wmsg
, hwnd
, msg
, wParam
, lParam
)
3030 wmsg
->msg
.hwnd
= hwnd
;
3031 wmsg
->msg
.message
= msg
;
3032 wmsg
->msg
.wParam
= wParam
;
3033 wmsg
->msg
.lParam
= lParam
;
3034 wmsg
->msg
.time
= GetMessageTime ();
3039 /* GetKeyState and MapVirtualKey on Windows 95 do not actually distinguish
3040 between left and right keys as advertised. We test for this
3041 support dynamically, and set a flag when the support is absent. If
3042 absent, we keep track of the left and right control and alt keys
3043 ourselves. This is particularly necessary on keyboards that rely
3044 upon the AltGr key, which is represented as having the left control
3045 and right alt keys pressed. For these keyboards, we need to know
3046 when the left alt key has been pressed in addition to the AltGr key
3047 so that we can properly support M-AltGr-key sequences (such as M-@
3048 on Swedish keyboards). */
3050 #define EMACS_LCONTROL 0
3051 #define EMACS_RCONTROL 1
3052 #define EMACS_LMENU 2
3053 #define EMACS_RMENU 3
3055 static int modifiers
[4];
3056 static int modifiers_recorded
;
3057 static int modifier_key_support_tested
;
3060 test_modifier_support (unsigned int wparam
)
3064 if (wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
)
3066 if (wparam
== VK_CONTROL
)
3076 if (!(GetKeyState (l
) & 0x8000) && !(GetKeyState (r
) & 0x8000))
3077 modifiers_recorded
= 1;
3079 modifiers_recorded
= 0;
3080 modifier_key_support_tested
= 1;
3084 record_keydown (unsigned int wparam
, unsigned int lparam
)
3088 if (!modifier_key_support_tested
)
3089 test_modifier_support (wparam
);
3091 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
3094 if (wparam
== VK_CONTROL
)
3095 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
3097 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
3103 record_keyup (unsigned int wparam
, unsigned int lparam
)
3107 if ((wparam
!= VK_CONTROL
&& wparam
!= VK_MENU
) || !modifiers_recorded
)
3110 if (wparam
== VK_CONTROL
)
3111 i
= (lparam
& 0x1000000) ? EMACS_RCONTROL
: EMACS_LCONTROL
;
3113 i
= (lparam
& 0x1000000) ? EMACS_RMENU
: EMACS_LMENU
;
3118 /* Emacs can lose focus while a modifier key has been pressed. When
3119 it regains focus, be conservative and clear all modifiers since
3120 we cannot reconstruct the left and right modifier state. */
3126 if (GetFocus () == NULL
)
3127 /* Emacs doesn't have keyboard focus. Do nothing. */
3130 ctrl
= GetAsyncKeyState (VK_CONTROL
);
3131 alt
= GetAsyncKeyState (VK_MENU
);
3133 if (!(ctrl
& 0x08000))
3134 /* Clear any recorded control modifier state. */
3135 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
3137 if (!(alt
& 0x08000))
3138 /* Clear any recorded alt modifier state. */
3139 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
3141 /* Update the state of all modifier keys, because modifiers used in
3142 hot-key combinations can get stuck on if Emacs loses focus as a
3143 result of a hot-key being pressed. */
3147 #define CURRENT_STATE(key) ((GetAsyncKeyState (key) & 0x8000) >> 8)
3149 GetKeyboardState (keystate
);
3150 keystate
[VK_SHIFT
] = CURRENT_STATE (VK_SHIFT
);
3151 keystate
[VK_CONTROL
] = CURRENT_STATE (VK_CONTROL
);
3152 keystate
[VK_LCONTROL
] = CURRENT_STATE (VK_LCONTROL
);
3153 keystate
[VK_RCONTROL
] = CURRENT_STATE (VK_RCONTROL
);
3154 keystate
[VK_MENU
] = CURRENT_STATE (VK_MENU
);
3155 keystate
[VK_LMENU
] = CURRENT_STATE (VK_LMENU
);
3156 keystate
[VK_RMENU
] = CURRENT_STATE (VK_RMENU
);
3157 keystate
[VK_LWIN
] = CURRENT_STATE (VK_LWIN
);
3158 keystate
[VK_RWIN
] = CURRENT_STATE (VK_RWIN
);
3159 keystate
[VK_APPS
] = CURRENT_STATE (VK_APPS
);
3160 SetKeyboardState (keystate
);
3164 /* Synchronize modifier state with what is reported with the current
3165 keystroke. Even if we cannot distinguish between left and right
3166 modifier keys, we know that, if no modifiers are set, then neither
3167 the left or right modifier should be set. */
3171 if (!modifiers_recorded
)
3174 if (!(GetKeyState (VK_CONTROL
) & 0x8000))
3175 modifiers
[EMACS_RCONTROL
] = modifiers
[EMACS_LCONTROL
] = 0;
3177 if (!(GetKeyState (VK_MENU
) & 0x8000))
3178 modifiers
[EMACS_RMENU
] = modifiers
[EMACS_LMENU
] = 0;
3182 modifier_set (int vkey
)
3184 if (vkey
== VK_CAPITAL
|| vkey
== VK_SCROLL
)
3185 return (GetKeyState (vkey
) & 0x1);
3186 if (!modifiers_recorded
)
3187 return (GetKeyState (vkey
) & 0x8000);
3192 return modifiers
[EMACS_LCONTROL
];
3194 return modifiers
[EMACS_RCONTROL
];
3196 return modifiers
[EMACS_LMENU
];
3198 return modifiers
[EMACS_RMENU
];
3200 return (GetKeyState (vkey
) & 0x8000);
3203 /* Convert between the modifier bits W32 uses and the modifier bits
3207 w32_key_to_modifier (int key
)
3209 Lisp_Object key_mapping
;
3214 key_mapping
= Vw32_lwindow_modifier
;
3217 key_mapping
= Vw32_rwindow_modifier
;
3220 key_mapping
= Vw32_apps_modifier
;
3223 key_mapping
= Vw32_scroll_lock_modifier
;
3229 /* NB. This code runs in the input thread, asychronously to the lisp
3230 thread, so we must be careful to ensure access to lisp data is
3231 thread-safe. The following code is safe because the modifier
3232 variable values are updated atomically from lisp and symbols are
3233 not relocated by GC. Also, we don't have to worry about seeing GC
3235 if (EQ (key_mapping
, Qhyper
))
3236 return hyper_modifier
;
3237 if (EQ (key_mapping
, Qsuper
))
3238 return super_modifier
;
3239 if (EQ (key_mapping
, Qmeta
))
3240 return meta_modifier
;
3241 if (EQ (key_mapping
, Qalt
))
3242 return alt_modifier
;
3243 if (EQ (key_mapping
, Qctrl
))
3244 return ctrl_modifier
;
3245 if (EQ (key_mapping
, Qcontrol
)) /* synonym for ctrl */
3246 return ctrl_modifier
;
3247 if (EQ (key_mapping
, Qshift
))
3248 return shift_modifier
;
3250 /* Don't generate any modifier if not explicitly requested. */
3255 w32_get_modifiers ()
3257 return ((modifier_set (VK_SHIFT
) ? shift_modifier
: 0) |
3258 (modifier_set (VK_CONTROL
) ? ctrl_modifier
: 0) |
3259 (modifier_set (VK_LWIN
) ? w32_key_to_modifier (VK_LWIN
) : 0) |
3260 (modifier_set (VK_RWIN
) ? w32_key_to_modifier (VK_RWIN
) : 0) |
3261 (modifier_set (VK_APPS
) ? w32_key_to_modifier (VK_APPS
) : 0) |
3262 (modifier_set (VK_SCROLL
) ? w32_key_to_modifier (VK_SCROLL
) : 0) |
3263 (modifier_set (VK_MENU
) ?
3264 ((NILP (Vw32_alt_is_meta
)) ? alt_modifier
: meta_modifier
) : 0));
3267 /* We map the VK_* modifiers into console modifier constants
3268 so that we can use the same routines to handle both console
3269 and window input. */
3272 construct_console_modifiers ()
3277 mods
|= (modifier_set (VK_SHIFT
)) ? SHIFT_PRESSED
: 0;
3278 mods
|= (modifier_set (VK_CAPITAL
)) ? CAPSLOCK_ON
: 0;
3279 mods
|= (modifier_set (VK_SCROLL
)) ? SCROLLLOCK_ON
: 0;
3280 mods
|= (modifier_set (VK_NUMLOCK
)) ? NUMLOCK_ON
: 0;
3281 mods
|= (modifier_set (VK_LCONTROL
)) ? LEFT_CTRL_PRESSED
: 0;
3282 mods
|= (modifier_set (VK_RCONTROL
)) ? RIGHT_CTRL_PRESSED
: 0;
3283 mods
|= (modifier_set (VK_LMENU
)) ? LEFT_ALT_PRESSED
: 0;
3284 mods
|= (modifier_set (VK_RMENU
)) ? RIGHT_ALT_PRESSED
: 0;
3285 mods
|= (modifier_set (VK_LWIN
)) ? LEFT_WIN_PRESSED
: 0;
3286 mods
|= (modifier_set (VK_RWIN
)) ? RIGHT_WIN_PRESSED
: 0;
3287 mods
|= (modifier_set (VK_APPS
)) ? APPS_PRESSED
: 0;
3293 w32_get_key_modifiers (unsigned int wparam
, unsigned int lparam
)
3297 /* Convert to emacs modifiers. */
3298 mods
= w32_kbd_mods_to_emacs (construct_console_modifiers (), wparam
);
3304 map_keypad_keys (unsigned int virt_key
, unsigned int extended
)
3306 if (virt_key
< VK_CLEAR
|| virt_key
> VK_DELETE
)
3309 if (virt_key
== VK_RETURN
)
3310 return (extended
? VK_NUMPAD_ENTER
: VK_RETURN
);
3312 if (virt_key
>= VK_PRIOR
&& virt_key
<= VK_DOWN
)
3313 return (!extended
? (VK_NUMPAD_PRIOR
+ (virt_key
- VK_PRIOR
)) : virt_key
);
3315 if (virt_key
== VK_INSERT
|| virt_key
== VK_DELETE
)
3316 return (!extended
? (VK_NUMPAD_INSERT
+ (virt_key
- VK_INSERT
)) : virt_key
);
3318 if (virt_key
== VK_CLEAR
)
3319 return (!extended
? VK_NUMPAD_CLEAR
: virt_key
);
3324 /* List of special key combinations which w32 would normally capture,
3325 but emacs should grab instead. Not directly visible to lisp, to
3326 simplify synchronization. Each item is an integer encoding a virtual
3327 key code and modifier combination to capture. */
3328 Lisp_Object w32_grabbed_keys
;
3330 #define HOTKEY(vk,mods) make_number (((vk) & 255) | ((mods) << 8))
3331 #define HOTKEY_ID(k) (XFASTINT (k) & 0xbfff)
3332 #define HOTKEY_VK_CODE(k) (XFASTINT (k) & 255)
3333 #define HOTKEY_MODIFIERS(k) (XFASTINT (k) >> 8)
3335 /* Register hot-keys for reserved key combinations when Emacs has
3336 keyboard focus, since this is the only way Emacs can receive key
3337 combinations like Alt-Tab which are used by the system. */
3340 register_hot_keys (hwnd
)
3343 Lisp_Object keylist
;
3345 /* Use GC_CONSP, since we are called asynchronously. */
3346 for (keylist
= w32_grabbed_keys
; GC_CONSP (keylist
); keylist
= XCDR (keylist
))
3348 Lisp_Object key
= XCAR (keylist
);
3350 /* Deleted entries get set to nil. */
3351 if (!INTEGERP (key
))
3354 RegisterHotKey (hwnd
, HOTKEY_ID (key
),
3355 HOTKEY_MODIFIERS (key
), HOTKEY_VK_CODE (key
));
3360 unregister_hot_keys (hwnd
)
3363 Lisp_Object keylist
;
3365 /* Use GC_CONSP, since we are called asynchronously. */
3366 for (keylist
= w32_grabbed_keys
; GC_CONSP (keylist
); keylist
= XCDR (keylist
))
3368 Lisp_Object key
= XCAR (keylist
);
3370 if (!INTEGERP (key
))
3373 UnregisterHotKey (hwnd
, HOTKEY_ID (key
));
3377 /* Main message dispatch loop. */
3380 w32_msg_pump (deferred_msg
* msg_buf
)
3386 msh_mousewheel
= RegisterWindowMessage (MSH_MOUSEWHEEL
);
3388 while (GetMessage (&msg
, NULL
, 0, 0))
3390 if (msg
.hwnd
== NULL
)
3392 switch (msg
.message
)
3395 /* Produced by complete_deferred_msg; just ignore. */
3397 case WM_EMACS_CREATEWINDOW
:
3398 w32_createwindow ((struct frame
*) msg
.wParam
);
3399 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3402 case WM_EMACS_SETLOCALE
:
3403 SetThreadLocale (msg
.wParam
);
3404 /* Reply is not expected. */
3406 case WM_EMACS_SETKEYBOARDLAYOUT
:
3407 result
= (int) ActivateKeyboardLayout ((HKL
) msg
.wParam
, 0);
3408 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
3412 case WM_EMACS_REGISTER_HOT_KEY
:
3413 focus_window
= GetFocus ();
3414 if (focus_window
!= NULL
)
3415 RegisterHotKey (focus_window
,
3416 HOTKEY_ID (msg
.wParam
),
3417 HOTKEY_MODIFIERS (msg
.wParam
),
3418 HOTKEY_VK_CODE (msg
.wParam
));
3419 /* Reply is not expected. */
3421 case WM_EMACS_UNREGISTER_HOT_KEY
:
3422 focus_window
= GetFocus ();
3423 if (focus_window
!= NULL
)
3424 UnregisterHotKey (focus_window
, HOTKEY_ID (msg
.wParam
));
3425 /* Mark item as erased. NB: this code must be
3426 thread-safe. The next line is okay because the cons
3427 cell is never made into garbage and is not relocated by
3429 XCAR ((Lisp_Object
) msg
.lParam
) = Qnil
;
3430 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3433 case WM_EMACS_TOGGLE_LOCK_KEY
:
3435 int vk_code
= (int) msg
.wParam
;
3436 int cur_state
= (GetKeyState (vk_code
) & 1);
3437 Lisp_Object new_state
= (Lisp_Object
) msg
.lParam
;
3439 /* NB: This code must be thread-safe. It is safe to
3440 call NILP because symbols are not relocated by GC,
3441 and pointer here is not touched by GC (so the markbit
3442 can't be set). Numbers are safe because they are
3443 immediate values. */
3444 if (NILP (new_state
)
3445 || (NUMBERP (new_state
)
3446 && (XUINT (new_state
)) & 1 != cur_state
))
3448 one_w32_display_info
.faked_key
= vk_code
;
3450 keybd_event ((BYTE
) vk_code
,
3451 (BYTE
) MapVirtualKey (vk_code
, 0),
3452 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3453 keybd_event ((BYTE
) vk_code
,
3454 (BYTE
) MapVirtualKey (vk_code
, 0),
3455 KEYEVENTF_EXTENDEDKEY
| 0, 0);
3456 keybd_event ((BYTE
) vk_code
,
3457 (BYTE
) MapVirtualKey (vk_code
, 0),
3458 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3459 cur_state
= !cur_state
;
3461 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
,
3467 DebPrint (("msg %x not expected by w32_msg_pump\n", msg
.message
));
3472 DispatchMessage (&msg
);
3475 /* Exit nested loop when our deferred message has completed. */
3476 if (msg_buf
->completed
)
3481 deferred_msg
* deferred_msg_head
;
3483 static deferred_msg
*
3484 find_deferred_msg (HWND hwnd
, UINT msg
)
3486 deferred_msg
* item
;
3488 /* Don't actually need synchronization for read access, since
3489 modification of single pointer is always atomic. */
3490 /* enter_crit (); */
3492 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
3493 if (item
->w32msg
.msg
.hwnd
== hwnd
3494 && item
->w32msg
.msg
.message
== msg
)
3497 /* leave_crit (); */
3503 send_deferred_msg (deferred_msg
* msg_buf
,
3509 /* Only input thread can send deferred messages. */
3510 if (GetCurrentThreadId () != dwWindowsThreadId
)
3513 /* It is an error to send a message that is already deferred. */
3514 if (find_deferred_msg (hwnd
, msg
) != NULL
)
3517 /* Enforced synchronization is not needed because this is the only
3518 function that alters deferred_msg_head, and the following critical
3519 section is guaranteed to only be serially reentered (since only the
3520 input thread can call us). */
3522 /* enter_crit (); */
3524 msg_buf
->completed
= 0;
3525 msg_buf
->next
= deferred_msg_head
;
3526 deferred_msg_head
= msg_buf
;
3527 my_post_msg (&msg_buf
->w32msg
, hwnd
, msg
, wParam
, lParam
);
3529 /* leave_crit (); */
3531 /* Start a new nested message loop to process other messages until
3532 this one is completed. */
3533 w32_msg_pump (msg_buf
);
3535 deferred_msg_head
= msg_buf
->next
;
3537 return msg_buf
->result
;
3541 complete_deferred_msg (HWND hwnd
, UINT msg
, LRESULT result
)
3543 deferred_msg
* msg_buf
= find_deferred_msg (hwnd
, msg
);
3545 if (msg_buf
== NULL
)
3546 /* Message may have been cancelled, so don't abort(). */
3549 msg_buf
->result
= result
;
3550 msg_buf
->completed
= 1;
3552 /* Ensure input thread is woken so it notices the completion. */
3553 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
3557 cancel_all_deferred_msgs ()
3559 deferred_msg
* item
;
3561 /* Don't actually need synchronization for read access, since
3562 modification of single pointer is always atomic. */
3563 /* enter_crit (); */
3565 for (item
= deferred_msg_head
; item
!= NULL
; item
= item
->next
)
3568 item
->completed
= 1;
3571 /* leave_crit (); */
3573 /* Ensure input thread is woken so it notices the completion. */
3574 PostThreadMessage (dwWindowsThreadId
, WM_NULL
, 0, 0);
3582 deferred_msg dummy_buf
;
3584 /* Ensure our message queue is created */
3586 PeekMessage (&msg
, NULL
, 0, 0, PM_NOREMOVE
);
3588 if (!PostThreadMessage (dwMainThreadId
, WM_EMACS_DONE
, 0, 0))
3591 memset (&dummy_buf
, 0, sizeof (dummy_buf
));
3592 dummy_buf
.w32msg
.msg
.hwnd
= NULL
;
3593 dummy_buf
.w32msg
.msg
.message
= WM_NULL
;
3595 /* This is the inital message loop which should only exit when the
3596 application quits. */
3597 w32_msg_pump (&dummy_buf
);
3603 post_character_message (hwnd
, msg
, wParam
, lParam
, modifiers
)
3613 wmsg
.dwModifiers
= modifiers
;
3615 /* Detect quit_char and set quit-flag directly. Note that we
3616 still need to post a message to ensure the main thread will be
3617 woken up if blocked in sys_select(), but we do NOT want to post
3618 the quit_char message itself (because it will usually be as if
3619 the user had typed quit_char twice). Instead, we post a dummy
3620 message that has no particular effect. */
3623 if (isalpha (c
) && wmsg
.dwModifiers
== ctrl_modifier
)
3624 c
= make_ctrl_char (c
) & 0377;
3626 || (wmsg
.dwModifiers
== 0 &&
3627 XFASTINT (Vw32_quit_key
) && wParam
== XFASTINT (Vw32_quit_key
)))
3631 /* The choice of message is somewhat arbitrary, as long as
3632 the main thread handler just ignores it. */
3635 /* Interrupt any blocking system calls. */
3638 /* As a safety precaution, forcibly complete any deferred
3639 messages. This is a kludge, but I don't see any particularly
3640 clean way to handle the situation where a deferred message is
3641 "dropped" in the lisp thread, and will thus never be
3642 completed, eg. by the user trying to activate the menubar
3643 when the lisp thread is busy, and then typing C-g when the
3644 menubar doesn't open promptly (with the result that the
3645 menubar never responds at all because the deferred
3646 WM_INITMENU message is never completed). Another problem
3647 situation is when the lisp thread calls SendMessage (to send
3648 a window manager command) when a message has been deferred;
3649 the lisp thread gets blocked indefinitely waiting for the
3650 deferred message to be completed, which itself is waiting for
3651 the lisp thread to respond.
3653 Note that we don't want to block the input thread waiting for
3654 a reponse from the lisp thread (although that would at least
3655 solve the deadlock problem above), because we want to be able
3656 to receive C-g to interrupt the lisp thread. */
3657 cancel_all_deferred_msgs ();
3661 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3664 /* Main window procedure */
3667 w32_wnd_proc (hwnd
, msg
, wParam
, lParam
)
3674 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
3676 int windows_translate
;
3679 /* Note that it is okay to call x_window_to_frame, even though we are
3680 not running in the main lisp thread, because frame deletion
3681 requires the lisp thread to synchronize with this thread. Thus, if
3682 a frame struct is returned, it can be used without concern that the
3683 lisp thread might make it disappear while we are using it.
3685 NB. Walking the frame list in this thread is safe (as long as
3686 writes of Lisp_Object slots are atomic, which they are on Windows).
3687 Although delete-frame can destructively modify the frame list while
3688 we are walking it, a garbage collection cannot occur until after
3689 delete-frame has synchronized with this thread.
3691 It is also safe to use functions that make GDI calls, such as
3692 w32_clear_rect, because these functions must obtain a DC handle
3693 from the frame struct using get_frame_dc which is thread-aware. */
3698 f
= x_window_to_frame (dpyinfo
, hwnd
);
3701 GetUpdateRect (hwnd
, &wmsg
.rect
, FALSE
);
3702 w32_clear_rect (f
, NULL
, &wmsg
.rect
);
3705 case WM_PALETTECHANGED
:
3706 /* ignore our own changes */
3707 if ((HWND
)wParam
!= hwnd
)
3709 f
= x_window_to_frame (dpyinfo
, hwnd
);
3711 /* get_frame_dc will realize our palette and force all
3712 frames to be redrawn if needed. */
3713 release_frame_dc (f
, get_frame_dc (f
));
3718 PAINTSTRUCT paintStruct
;
3721 BeginPaint (hwnd
, &paintStruct
);
3722 wmsg
.rect
= paintStruct
.rcPaint
;
3723 EndPaint (hwnd
, &paintStruct
);
3726 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3731 case WM_INPUTLANGCHANGE
:
3732 /* Inform lisp thread of keyboard layout changes. */
3733 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
3735 /* Clear dead keys in the keyboard state; for simplicity only
3736 preserve modifier key states. */
3741 GetKeyboardState (keystate
);
3742 for (i
= 0; i
< 256; i
++)
3759 SetKeyboardState (keystate
);
3764 /* Synchronize hot keys with normal input. */
3765 PostMessage (hwnd
, WM_KEYDOWN
, HIWORD (lParam
), 0);
3770 record_keyup (wParam
, lParam
);
3775 /* Ignore keystrokes we fake ourself; see below. */
3776 if (dpyinfo
->faked_key
== wParam
)
3778 dpyinfo
->faked_key
= 0;
3779 /* Make sure TranslateMessage sees them though (as long as
3780 they don't produce WM_CHAR messages). This ensures that
3781 indicator lights are toggled promptly on Windows 9x, for
3783 if (lispy_function_keys
[wParam
] != 0)
3785 windows_translate
= 1;
3791 /* Synchronize modifiers with current keystroke. */
3793 record_keydown (wParam
, lParam
);
3794 wParam
= map_keypad_keys (wParam
, (lParam
& 0x1000000L
) != 0);
3796 windows_translate
= 0;
3801 if (NILP (Vw32_pass_lwindow_to_system
))
3803 /* Prevent system from acting on keyup (which opens the
3804 Start menu if no other key was pressed) by simulating a
3805 press of Space which we will ignore. */
3806 if (GetAsyncKeyState (wParam
) & 1)
3808 if (NUMBERP (Vw32_phantom_key_code
))
3809 key
= XUINT (Vw32_phantom_key_code
) & 255;
3812 dpyinfo
->faked_key
= key
;
3813 keybd_event (key
, (BYTE
) MapVirtualKey (key
, 0), 0, 0);
3816 if (!NILP (Vw32_lwindow_modifier
))
3820 if (NILP (Vw32_pass_rwindow_to_system
))
3822 if (GetAsyncKeyState (wParam
) & 1)
3824 if (NUMBERP (Vw32_phantom_key_code
))
3825 key
= XUINT (Vw32_phantom_key_code
) & 255;
3828 dpyinfo
->faked_key
= key
;
3829 keybd_event (key
, (BYTE
) MapVirtualKey (key
, 0), 0, 0);
3832 if (!NILP (Vw32_rwindow_modifier
))
3836 if (!NILP (Vw32_apps_modifier
))
3840 if (NILP (Vw32_pass_alt_to_system
))
3841 /* Prevent DefWindowProc from activating the menu bar if an
3842 Alt key is pressed and released by itself. */
3844 windows_translate
= 1;
3847 /* Decide whether to treat as modifier or function key. */
3848 if (NILP (Vw32_enable_caps_lock
))
3849 goto disable_lock_key
;
3850 windows_translate
= 1;
3853 /* Decide whether to treat as modifier or function key. */
3854 if (NILP (Vw32_enable_num_lock
))
3855 goto disable_lock_key
;
3856 windows_translate
= 1;
3859 /* Decide whether to treat as modifier or function key. */
3860 if (NILP (Vw32_scroll_lock_modifier
))
3861 goto disable_lock_key
;
3862 windows_translate
= 1;
3865 /* Ensure the appropriate lock key state (and indicator light)
3866 remains in the same state. We do this by faking another
3867 press of the relevant key. Apparently, this really is the
3868 only way to toggle the state of the indicator lights. */
3869 dpyinfo
->faked_key
= wParam
;
3870 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3871 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3872 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3873 KEYEVENTF_EXTENDEDKEY
| 0, 0);
3874 keybd_event ((BYTE
) wParam
, (BYTE
) MapVirtualKey (wParam
, 0),
3875 KEYEVENTF_EXTENDEDKEY
| KEYEVENTF_KEYUP
, 0);
3876 /* Ensure indicator lights are updated promptly on Windows 9x
3877 (TranslateMessage apparently does this), after forwarding
3879 post_character_message (hwnd
, msg
, wParam
, lParam
,
3880 w32_get_key_modifiers (wParam
, lParam
));
3881 windows_translate
= 1;
3885 case VK_PROCESSKEY
: /* Generated by IME. */
3886 windows_translate
= 1;
3889 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
3890 which is confusing for purposes of key binding; convert
3891 VK_CANCEL events into VK_PAUSE events. */
3895 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
3896 for purposes of key binding; convert these back into
3897 VK_NUMLOCK events, at least when we want to see NumLock key
3898 presses. (Note that there is never any possibility that
3899 VK_PAUSE with Ctrl really is C-Pause as per above.) */
3900 if (NILP (Vw32_enable_num_lock
) && modifier_set (VK_CONTROL
))
3901 wParam
= VK_NUMLOCK
;
3904 /* If not defined as a function key, change it to a WM_CHAR message. */
3905 if (lispy_function_keys
[wParam
] == 0)
3907 DWORD modifiers
= construct_console_modifiers ();
3909 if (!NILP (Vw32_recognize_altgr
)
3910 && modifier_set (VK_LCONTROL
) && modifier_set (VK_RMENU
))
3912 /* Always let TranslateMessage handle AltGr key chords;
3913 for some reason, ToAscii doesn't always process AltGr
3914 chords correctly. */
3915 windows_translate
= 1;
3917 else if ((modifiers
& (~SHIFT_PRESSED
& ~CAPSLOCK_ON
)) != 0)
3919 /* Handle key chords including any modifiers other
3920 than shift directly, in order to preserve as much
3921 modifier information as possible. */
3922 if ('A' <= wParam
&& wParam
<= 'Z')
3924 /* Don't translate modified alphabetic keystrokes,
3925 so the user doesn't need to constantly switch
3926 layout to type control or meta keystrokes when
3927 the normal layout translates alphabetic
3928 characters to non-ascii characters. */
3929 if (!modifier_set (VK_SHIFT
))
3930 wParam
+= ('a' - 'A');
3935 /* Try to handle other keystrokes by determining the
3936 base character (ie. translating the base key plus
3940 KEY_EVENT_RECORD key
;
3942 key
.bKeyDown
= TRUE
;
3943 key
.wRepeatCount
= 1;
3944 key
.wVirtualKeyCode
= wParam
;
3945 key
.wVirtualScanCode
= (lParam
& 0xFF0000) >> 16;
3946 key
.uChar
.AsciiChar
= 0;
3947 key
.dwControlKeyState
= modifiers
;
3949 add
= w32_kbd_patch_key (&key
);
3950 /* 0 means an unrecognised keycode, negative means
3951 dead key. Ignore both. */
3954 /* Forward asciified character sequence. */
3955 post_character_message
3956 (hwnd
, WM_CHAR
, key
.uChar
.AsciiChar
, lParam
,
3957 w32_get_key_modifiers (wParam
, lParam
));
3958 w32_kbd_patch_key (&key
);
3965 /* Let TranslateMessage handle everything else. */
3966 windows_translate
= 1;
3972 if (windows_translate
)
3974 MSG windows_msg
= { hwnd
, msg
, wParam
, lParam
, 0, {0,0} };
3976 windows_msg
.time
= GetMessageTime ();
3977 TranslateMessage (&windows_msg
);
3985 post_character_message (hwnd
, msg
, wParam
, lParam
,
3986 w32_get_key_modifiers (wParam
, lParam
));
3989 /* Simulate middle mouse button events when left and right buttons
3990 are used together, but only if user has two button mouse. */
3991 case WM_LBUTTONDOWN
:
3992 case WM_RBUTTONDOWN
:
3993 if (XINT (Vw32_num_mouse_buttons
) == 3)
3994 goto handle_plain_button
;
3997 int this = (msg
== WM_LBUTTONDOWN
) ? LMOUSE
: RMOUSE
;
3998 int other
= (msg
== WM_LBUTTONDOWN
) ? RMOUSE
: LMOUSE
;
4000 if (button_state
& this)
4003 if (button_state
== 0)
4006 button_state
|= this;
4008 if (button_state
& other
)
4010 if (mouse_button_timer
)
4012 KillTimer (hwnd
, mouse_button_timer
);
4013 mouse_button_timer
= 0;
4015 /* Generate middle mouse event instead. */
4016 msg
= WM_MBUTTONDOWN
;
4017 button_state
|= MMOUSE
;
4019 else if (button_state
& MMOUSE
)
4021 /* Ignore button event if we've already generated a
4022 middle mouse down event. This happens if the
4023 user releases and press one of the two buttons
4024 after we've faked a middle mouse event. */
4029 /* Flush out saved message. */
4030 post_msg (&saved_mouse_button_msg
);
4032 wmsg
.dwModifiers
= w32_get_modifiers ();
4033 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4035 /* Clear message buffer. */
4036 saved_mouse_button_msg
.msg
.hwnd
= 0;
4040 /* Hold onto message for now. */
4041 mouse_button_timer
=
4042 SetTimer (hwnd
, MOUSE_BUTTON_ID
,
4043 XINT (Vw32_mouse_button_tolerance
), NULL
);
4044 saved_mouse_button_msg
.msg
.hwnd
= hwnd
;
4045 saved_mouse_button_msg
.msg
.message
= msg
;
4046 saved_mouse_button_msg
.msg
.wParam
= wParam
;
4047 saved_mouse_button_msg
.msg
.lParam
= lParam
;
4048 saved_mouse_button_msg
.msg
.time
= GetMessageTime ();
4049 saved_mouse_button_msg
.dwModifiers
= w32_get_modifiers ();
4056 if (XINT (Vw32_num_mouse_buttons
) == 3)
4057 goto handle_plain_button
;
4060 int this = (msg
== WM_LBUTTONUP
) ? LMOUSE
: RMOUSE
;
4061 int other
= (msg
== WM_LBUTTONUP
) ? RMOUSE
: LMOUSE
;
4063 if ((button_state
& this) == 0)
4066 button_state
&= ~this;
4068 if (button_state
& MMOUSE
)
4070 /* Only generate event when second button is released. */
4071 if ((button_state
& other
) == 0)
4074 button_state
&= ~MMOUSE
;
4076 if (button_state
) abort ();
4083 /* Flush out saved message if necessary. */
4084 if (saved_mouse_button_msg
.msg
.hwnd
)
4086 post_msg (&saved_mouse_button_msg
);
4089 wmsg
.dwModifiers
= w32_get_modifiers ();
4090 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4092 /* Always clear message buffer and cancel timer. */
4093 saved_mouse_button_msg
.msg
.hwnd
= 0;
4094 KillTimer (hwnd
, mouse_button_timer
);
4095 mouse_button_timer
= 0;
4097 if (button_state
== 0)
4102 case WM_MBUTTONDOWN
:
4104 handle_plain_button
:
4109 if (parse_button (msg
, &button
, &up
))
4111 if (up
) ReleaseCapture ();
4112 else SetCapture (hwnd
);
4113 button
= (button
== 0) ? LMOUSE
:
4114 ((button
== 1) ? MMOUSE
: RMOUSE
);
4116 button_state
&= ~button
;
4118 button_state
|= button
;
4122 wmsg
.dwModifiers
= w32_get_modifiers ();
4123 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4128 if (XINT (Vw32_mouse_move_interval
) <= 0
4129 || (msg
== WM_MOUSEMOVE
&& button_state
== 0))
4131 wmsg
.dwModifiers
= w32_get_modifiers ();
4132 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4136 /* Hang onto mouse move and scroll messages for a bit, to avoid
4137 sending such events to Emacs faster than it can process them.
4138 If we get more events before the timer from the first message
4139 expires, we just replace the first message. */
4141 if (saved_mouse_move_msg
.msg
.hwnd
== 0)
4143 SetTimer (hwnd
, MOUSE_MOVE_ID
,
4144 XINT (Vw32_mouse_move_interval
), NULL
);
4146 /* Hold onto message for now. */
4147 saved_mouse_move_msg
.msg
.hwnd
= hwnd
;
4148 saved_mouse_move_msg
.msg
.message
= msg
;
4149 saved_mouse_move_msg
.msg
.wParam
= wParam
;
4150 saved_mouse_move_msg
.msg
.lParam
= lParam
;
4151 saved_mouse_move_msg
.msg
.time
= GetMessageTime ();
4152 saved_mouse_move_msg
.dwModifiers
= w32_get_modifiers ();
4157 wmsg
.dwModifiers
= w32_get_modifiers ();
4158 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4162 wmsg
.dwModifiers
= w32_get_modifiers ();
4163 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4167 /* Flush out saved messages if necessary. */
4168 if (wParam
== mouse_button_timer
)
4170 if (saved_mouse_button_msg
.msg
.hwnd
)
4172 post_msg (&saved_mouse_button_msg
);
4173 saved_mouse_button_msg
.msg
.hwnd
= 0;
4175 KillTimer (hwnd
, mouse_button_timer
);
4176 mouse_button_timer
= 0;
4178 else if (wParam
== mouse_move_timer
)
4180 if (saved_mouse_move_msg
.msg
.hwnd
)
4182 post_msg (&saved_mouse_move_msg
);
4183 saved_mouse_move_msg
.msg
.hwnd
= 0;
4185 KillTimer (hwnd
, mouse_move_timer
);
4186 mouse_move_timer
= 0;
4191 /* Windows doesn't send us focus messages when putting up and
4192 taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95.
4193 The only indication we get that something happened is receiving
4194 this message afterwards. So this is a good time to reset our
4195 keyboard modifiers' state. */
4200 /* We must ensure menu bar is fully constructed and up to date
4201 before allowing user interaction with it. To achieve this
4202 we send this message to the lisp thread and wait for a
4203 reply (whose value is not actually needed) to indicate that
4204 the menu bar is now ready for use, so we can now return.
4206 To remain responsive in the meantime, we enter a nested message
4207 loop that can process all other messages.
4209 However, we skip all this if the message results from calling
4210 TrackPopupMenu - in fact, we must NOT attempt to send the lisp
4211 thread a message because it is blocked on us at this point. We
4212 set menubar_active before calling TrackPopupMenu to indicate
4213 this (there is no possibility of confusion with real menubar
4216 f
= x_window_to_frame (dpyinfo
, hwnd
);
4218 && (f
->output_data
.w32
->menubar_active
4219 /* We can receive this message even in the absence of a
4220 menubar (ie. when the system menu is activated) - in this
4221 case we do NOT want to forward the message, otherwise it
4222 will cause the menubar to suddenly appear when the user
4223 had requested it to be turned off! */
4224 || f
->output_data
.w32
->menubar_widget
== NULL
))
4228 deferred_msg msg_buf
;
4230 /* Detect if message has already been deferred; in this case
4231 we cannot return any sensible value to ignore this. */
4232 if (find_deferred_msg (hwnd
, msg
) != NULL
)
4235 return send_deferred_msg (&msg_buf
, hwnd
, msg
, wParam
, lParam
);
4238 case WM_EXITMENULOOP
:
4239 f
= x_window_to_frame (dpyinfo
, hwnd
);
4241 /* Indicate that menubar can be modified again. */
4243 f
->output_data
.w32
->menubar_active
= 0;
4246 case WM_MEASUREITEM
:
4247 f
= x_window_to_frame (dpyinfo
, hwnd
);
4250 MEASUREITEMSTRUCT
* pMis
= (MEASUREITEMSTRUCT
*) lParam
;
4252 if (pMis
->CtlType
== ODT_MENU
)
4254 /* Work out dimensions for popup menu titles. */
4255 char * title
= (char *) pMis
->itemData
;
4256 HDC hdc
= GetDC (hwnd
);
4257 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4258 LOGFONT menu_logfont
;
4262 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4263 menu_logfont
.lfWeight
= FW_BOLD
;
4264 menu_font
= CreateFontIndirect (&menu_logfont
);
4265 old_font
= SelectObject (hdc
, menu_font
);
4267 GetTextExtentPoint32 (hdc
, title
, strlen (title
), &size
);
4268 pMis
->itemWidth
= size
.cx
;
4269 pMis
->itemHeight
= GetSystemMetrics (SM_CYMENUSIZE
);
4270 if (pMis
->itemHeight
< size
.cy
)
4271 pMis
->itemHeight
= size
.cy
;
4273 SelectObject (hdc
, old_font
);
4274 DeleteObject (menu_font
);
4275 ReleaseDC (hwnd
, hdc
);
4282 f
= x_window_to_frame (dpyinfo
, hwnd
);
4285 DRAWITEMSTRUCT
* pDis
= (DRAWITEMSTRUCT
*) lParam
;
4287 if (pDis
->CtlType
== ODT_MENU
)
4289 /* Draw popup menu title. */
4290 char * title
= (char *) pDis
->itemData
;
4291 HDC hdc
= pDis
->hDC
;
4292 HFONT menu_font
= GetCurrentObject (hdc
, OBJ_FONT
);
4293 LOGFONT menu_logfont
;
4296 GetObject (menu_font
, sizeof (menu_logfont
), &menu_logfont
);
4297 menu_logfont
.lfWeight
= FW_BOLD
;
4298 menu_font
= CreateFontIndirect (&menu_logfont
);
4299 old_font
= SelectObject (hdc
, menu_font
);
4301 /* Always draw title as if not selected. */
4303 pDis
->rcItem
.left
+ GetSystemMetrics (SM_CXMENUCHECK
),
4305 ETO_OPAQUE
, &pDis
->rcItem
,
4306 title
, strlen (title
), NULL
);
4308 SelectObject (hdc
, old_font
);
4309 DeleteObject (menu_font
);
4316 /* Still not right - can't distinguish between clicks in the
4317 client area of the frame from clicks forwarded from the scroll
4318 bars - may have to hook WM_NCHITTEST to remember the mouse
4319 position and then check if it is in the client area ourselves. */
4320 case WM_MOUSEACTIVATE
:
4321 /* Discard the mouse click that activates a frame, allowing the
4322 user to click anywhere without changing point (or worse!).
4323 Don't eat mouse clicks on scrollbars though!! */
4324 if (LOWORD (lParam
) == HTCLIENT
)
4325 return MA_ACTIVATEANDEAT
;
4329 case WM_ACTIVATEAPP
:
4331 case WM_WINDOWPOSCHANGED
:
4333 /* Inform lisp thread that a frame might have just been obscured
4334 or exposed, so should recheck visibility of all frames. */
4335 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4339 dpyinfo
->faked_key
= 0;
4341 register_hot_keys (hwnd
);
4344 unregister_hot_keys (hwnd
);
4349 wmsg
.dwModifiers
= w32_get_modifiers ();
4350 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4354 wmsg
.dwModifiers
= w32_get_modifiers ();
4355 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4358 case WM_WINDOWPOSCHANGING
:
4361 LPWINDOWPOS lppos
= (WINDOWPOS
*) lParam
;
4363 wp
.length
= sizeof (WINDOWPLACEMENT
);
4364 GetWindowPlacement (hwnd
, &wp
);
4366 if (wp
.showCmd
!= SW_SHOWMINIMIZED
&& (lppos
->flags
& SWP_NOSIZE
) == 0)
4373 DWORD internal_border
;
4374 DWORD scrollbar_extra
;
4377 wp
.length
= sizeof(wp
);
4378 GetWindowRect (hwnd
, &wr
);
4382 font_width
= GetWindowLong (hwnd
, WND_FONTWIDTH_INDEX
);
4383 line_height
= GetWindowLong (hwnd
, WND_LINEHEIGHT_INDEX
);
4384 internal_border
= GetWindowLong (hwnd
, WND_BORDER_INDEX
);
4385 scrollbar_extra
= GetWindowLong (hwnd
, WND_SCROLLBAR_INDEX
);
4389 memset (&rect
, 0, sizeof (rect
));
4390 AdjustWindowRect (&rect
, GetWindowLong (hwnd
, GWL_STYLE
),
4391 GetMenu (hwnd
) != NULL
);
4393 /* Force width and height of client area to be exact
4394 multiples of the character cell dimensions. */
4395 wdiff
= (lppos
->cx
- (rect
.right
- rect
.left
)
4396 - 2 * internal_border
- scrollbar_extra
)
4398 hdiff
= (lppos
->cy
- (rect
.bottom
- rect
.top
)
4399 - 2 * internal_border
)
4404 /* For right/bottom sizing we can just fix the sizes.
4405 However for top/left sizing we will need to fix the X
4406 and Y positions as well. */
4411 if (wp
.showCmd
!= SW_SHOWMAXIMIZED
4412 && (lppos
->flags
& SWP_NOMOVE
) == 0)
4414 if (lppos
->x
!= wr
.left
|| lppos
->y
!= wr
.top
)
4421 lppos
->flags
|= SWP_NOMOVE
;
4432 case WM_EMACS_CREATESCROLLBAR
:
4433 return (LRESULT
) w32_createscrollbar ((struct frame
*) wParam
,
4434 (struct scroll_bar
*) lParam
);
4436 case WM_EMACS_SHOWWINDOW
:
4437 return ShowWindow ((HWND
) wParam
, (WPARAM
) lParam
);
4439 case WM_EMACS_SETFOREGROUND
:
4440 return SetForegroundWindow ((HWND
) wParam
);
4442 case WM_EMACS_SETWINDOWPOS
:
4444 WINDOWPOS
* pos
= (WINDOWPOS
*) wParam
;
4445 return SetWindowPos (hwnd
, pos
->hwndInsertAfter
,
4446 pos
->x
, pos
->y
, pos
->cx
, pos
->cy
, pos
->flags
);
4449 case WM_EMACS_DESTROYWINDOW
:
4450 DragAcceptFiles ((HWND
) wParam
, FALSE
);
4451 return DestroyWindow ((HWND
) wParam
);
4453 case WM_EMACS_TRACKPOPUPMENU
:
4458 pos
= (POINT
*)lParam
;
4459 flags
= TPM_CENTERALIGN
;
4460 if (button_state
& LMOUSE
)
4461 flags
|= TPM_LEFTBUTTON
;
4462 else if (button_state
& RMOUSE
)
4463 flags
|= TPM_RIGHTBUTTON
;
4465 /* Remember we did a SetCapture on the initial mouse down event,
4466 so for safety, we make sure the capture is cancelled now. */
4470 /* Use menubar_active to indicate that WM_INITMENU is from
4471 TrackPopupMenu below, and should be ignored. */
4472 f
= x_window_to_frame (dpyinfo
, hwnd
);
4474 f
->output_data
.w32
->menubar_active
= 1;
4476 if (TrackPopupMenu ((HMENU
)wParam
, flags
, pos
->x
, pos
->y
,
4480 /* Eat any mouse messages during popupmenu */
4481 while (PeekMessage (&amsg
, hwnd
, WM_MOUSEFIRST
, WM_MOUSELAST
,
4483 /* Get the menu selection, if any */
4484 if (PeekMessage (&amsg
, hwnd
, WM_COMMAND
, WM_COMMAND
, PM_REMOVE
))
4486 retval
= LOWORD (amsg
.wParam
);
4502 /* Check for messages registered at runtime. */
4503 if (msg
== msh_mousewheel
)
4505 wmsg
.dwModifiers
= w32_get_modifiers ();
4506 my_post_msg (&wmsg
, hwnd
, msg
, wParam
, lParam
);
4511 return DefWindowProc (hwnd
, msg
, wParam
, lParam
);
4515 /* The most common default return code for handled messages is 0. */
4520 my_create_window (f
)
4525 if (!PostThreadMessage (dwWindowsThreadId
, WM_EMACS_CREATEWINDOW
, (WPARAM
)f
, 0))
4527 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
4530 /* Create and set up the w32 window for frame F. */
4533 w32_window (f
, window_prompting
, minibuffer_only
)
4535 long window_prompting
;
4536 int minibuffer_only
;
4540 /* Use the resource name as the top-level window name
4541 for looking up resources. Make a non-Lisp copy
4542 for the window manager, so GC relocation won't bother it.
4544 Elsewhere we specify the window name for the window manager. */
4547 char *str
= (char *) XSTRING (Vx_resource_name
)->data
;
4548 f
->namebuf
= (char *) xmalloc (strlen (str
) + 1);
4549 strcpy (f
->namebuf
, str
);
4552 my_create_window (f
);
4554 validate_x_resource_name ();
4556 /* x_set_name normally ignores requests to set the name if the
4557 requested name is the same as the current name. This is the one
4558 place where that assumption isn't correct; f->name is set, but
4559 the server hasn't been told. */
4562 int explicit = f
->explicit_name
;
4564 f
->explicit_name
= 0;
4567 x_set_name (f
, name
, explicit);
4572 if (!minibuffer_only
&& FRAME_EXTERNAL_MENU_BAR (f
))
4573 initialize_frame_menubar (f
);
4575 if (FRAME_W32_WINDOW (f
) == 0)
4576 error ("Unable to create window");
4579 /* Handle the icon stuff for this window. Perhaps later we might
4580 want an x_set_icon_position which can be called interactively as
4588 Lisp_Object icon_x
, icon_y
;
4590 /* Set the position of the icon. Note that Windows 95 groups all
4591 icons in the tray. */
4592 icon_x
= x_get_arg (parms
, Qicon_left
, 0, 0, number
);
4593 icon_y
= x_get_arg (parms
, Qicon_top
, 0, 0, number
);
4594 if (!EQ (icon_x
, Qunbound
) && !EQ (icon_y
, Qunbound
))
4596 CHECK_NUMBER (icon_x
, 0);
4597 CHECK_NUMBER (icon_y
, 0);
4599 else if (!EQ (icon_x
, Qunbound
) || !EQ (icon_y
, Qunbound
))
4600 error ("Both left and top icon corners of icon must be specified");
4604 if (! EQ (icon_x
, Qunbound
))
4605 x_wm_set_icon_position (f
, XINT (icon_x
), XINT (icon_y
));
4608 /* Start up iconic or window? */
4609 x_wm_set_window_state
4610 (f
, (EQ (x_get_arg (parms
, Qvisibility
, 0, 0, symbol
), Qicon
)
4614 x_text_icon (f
, (char *) XSTRING ((!NILP (f
->icon_name
)
4622 DEFUN ("x-create-frame", Fx_create_frame
, Sx_create_frame
,
4624 "Make a new window, which is called a \"frame\" in Emacs terms.\n\
4625 Returns an Emacs frame object.\n\
4626 ALIST is an alist of frame parameters.\n\
4627 If the parameters specify that the frame should not have a minibuffer,\n\
4628 and do not specify a specific minibuffer window to use,\n\
4629 then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
4630 be shared by the new frame.\n\
4632 This function is an internal primitive--use `make-frame' instead.")
4637 Lisp_Object frame
, tem
;
4639 int minibuffer_only
= 0;
4640 long window_prompting
= 0;
4642 int count
= specpdl_ptr
- specpdl
;
4643 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
4644 Lisp_Object display
;
4645 struct w32_display_info
*dpyinfo
;
4651 /* Use this general default value to start with
4652 until we know if this frame has a specified name. */
4653 Vx_resource_name
= Vinvocation_name
;
4655 display
= x_get_arg (parms
, Qdisplay
, 0, 0, string
);
4656 if (EQ (display
, Qunbound
))
4658 dpyinfo
= check_x_display_info (display
);
4660 kb
= dpyinfo
->kboard
;
4662 kb
= &the_only_kboard
;
4665 name
= x_get_arg (parms
, Qname
, "name", "Name", string
);
4667 && ! EQ (name
, Qunbound
)
4669 error ("Invalid frame name--not a string or nil");
4672 Vx_resource_name
= name
;
4674 /* See if parent window is specified. */
4675 parent
= x_get_arg (parms
, Qparent_id
, NULL
, NULL
, number
);
4676 if (EQ (parent
, Qunbound
))
4678 if (! NILP (parent
))
4679 CHECK_NUMBER (parent
, 0);
4681 /* make_frame_without_minibuffer can run Lisp code and garbage collect. */
4682 /* No need to protect DISPLAY because that's not used after passing
4683 it to make_frame_without_minibuffer. */
4685 GCPRO4 (parms
, parent
, name
, frame
);
4686 tem
= x_get_arg (parms
, Qminibuffer
, 0, 0, symbol
);
4687 if (EQ (tem
, Qnone
) || NILP (tem
))
4688 f
= make_frame_without_minibuffer (Qnil
, kb
, display
);
4689 else if (EQ (tem
, Qonly
))
4691 f
= make_minibuffer_frame ();
4692 minibuffer_only
= 1;
4694 else if (WINDOWP (tem
))
4695 f
= make_frame_without_minibuffer (tem
, kb
, display
);
4699 XSETFRAME (frame
, f
);
4701 /* Note that Windows does support scroll bars. */
4702 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
4703 /* By default, make scrollbars the system standard width. */
4704 f
->scroll_bar_pixel_width
= GetSystemMetrics (SM_CXVSCROLL
);
4706 f
->output_method
= output_w32
;
4707 f
->output_data
.w32
= (struct w32_output
*) xmalloc (sizeof (struct w32_output
));
4708 bzero (f
->output_data
.w32
, sizeof (struct w32_output
));
4710 FRAME_FONTSET (f
) = -1;
4713 = x_get_arg (parms
, Qicon_name
, "iconName", "Title", string
);
4714 if (! STRINGP (f
->icon_name
))
4715 f
->icon_name
= Qnil
;
4717 /* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
4719 FRAME_KBOARD (f
) = kb
;
4722 /* Specify the parent under which to make this window. */
4726 f
->output_data
.w32
->parent_desc
= (Window
) parent
;
4727 f
->output_data
.w32
->explicit_parent
= 1;
4731 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
4732 f
->output_data
.w32
->explicit_parent
= 0;
4735 /* Note that the frame has no physical cursor right now. */
4736 f
->phys_cursor_x
= -1;
4738 /* Set the name; the functions to which we pass f expect the name to
4740 if (EQ (name
, Qunbound
) || NILP (name
))
4742 f
->name
= build_string (dpyinfo
->w32_id_name
);
4743 f
->explicit_name
= 0;
4748 f
->explicit_name
= 1;
4749 /* use the frame's title when getting resources for this frame. */
4750 specbind (Qx_resource_name
, name
);
4753 /* Create fontsets from `global_fontset_alist' before handling fonts. */
4754 for (tem
= Vglobal_fontset_alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
4755 fs_register_fontset (f
, XCONS (tem
)->car
);
4757 /* Extract the window parameters from the supplied values
4758 that are needed to determine window geometry. */
4762 font
= x_get_arg (parms
, Qfont
, "font", "Font", string
);
4764 /* First, try whatever font the caller has specified. */
4767 tem
= Fquery_fontset (font
, Qnil
);
4769 font
= x_new_fontset (f
, XSTRING (tem
)->data
);
4771 font
= x_new_font (f
, XSTRING (font
)->data
);
4773 /* Try out a font which we hope has bold and italic variations. */
4774 if (!STRINGP (font
))
4775 font
= x_new_font (f
, "-*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
4776 if (! STRINGP (font
))
4777 font
= x_new_font (f
, "-*-Courier-normal-r-*-*-*-97-*-*-c-*-iso8859-1");
4778 /* If those didn't work, look for something which will at least work. */
4779 if (! STRINGP (font
))
4780 font
= x_new_font (f
, "-*-Fixedsys-normal-r-*-*-*-*-90-*-c-*-iso8859-1");
4782 if (! STRINGP (font
))
4783 font
= build_string ("Fixedsys");
4785 x_default_parameter (f
, parms
, Qfont
, font
,
4786 "font", "Font", string
);
4789 x_default_parameter (f
, parms
, Qborder_width
, make_number (2),
4790 "borderwidth", "BorderWidth", number
);
4791 /* This defaults to 2 in order to match xterm. We recognize either
4792 internalBorderWidth or internalBorder (which is what xterm calls
4794 if (NILP (Fassq (Qinternal_border_width
, parms
)))
4798 value
= x_get_arg (parms
, Qinternal_border_width
,
4799 "internalBorder", "BorderWidth", number
);
4800 if (! EQ (value
, Qunbound
))
4801 parms
= Fcons (Fcons (Qinternal_border_width
, value
),
4804 /* Default internalBorderWidth to 0 on Windows to match other programs. */
4805 x_default_parameter (f
, parms
, Qinternal_border_width
, make_number (0),
4806 "internalBorderWidth", "BorderWidth", number
);
4807 x_default_parameter (f
, parms
, Qvertical_scroll_bars
, Qt
,
4808 "verticalScrollBars", "ScrollBars", boolean
);
4810 /* Also do the stuff which must be set before the window exists. */
4811 x_default_parameter (f
, parms
, Qforeground_color
, build_string ("black"),
4812 "foreground", "Foreground", string
);
4813 x_default_parameter (f
, parms
, Qbackground_color
, build_string ("white"),
4814 "background", "Background", string
);
4815 x_default_parameter (f
, parms
, Qmouse_color
, build_string ("black"),
4816 "pointerColor", "Foreground", string
);
4817 x_default_parameter (f
, parms
, Qcursor_color
, build_string ("black"),
4818 "cursorColor", "Foreground", string
);
4819 x_default_parameter (f
, parms
, Qborder_color
, build_string ("black"),
4820 "borderColor", "BorderColor", string
);
4822 x_default_parameter (f
, parms
, Qmenu_bar_lines
, make_number (1),
4823 "menuBar", "MenuBar", number
);
4824 x_default_parameter (f
, parms
, Qscroll_bar_width
, Qnil
,
4825 "scrollBarWidth", "ScrollBarWidth", number
);
4826 x_default_parameter (f
, parms
, Qbuffer_predicate
, Qnil
,
4827 "bufferPredicate", "BufferPredicate", symbol
);
4828 x_default_parameter (f
, parms
, Qtitle
, Qnil
,
4829 "title", "Title", string
);
4831 f
->output_data
.w32
->dwStyle
= WS_OVERLAPPEDWINDOW
;
4832 f
->output_data
.w32
->parent_desc
= FRAME_W32_DISPLAY_INFO (f
)->root_window
;
4833 window_prompting
= x_figure_window_size (f
, parms
);
4835 if (window_prompting
& XNegative
)
4837 if (window_prompting
& YNegative
)
4838 f
->output_data
.w32
->win_gravity
= SouthEastGravity
;
4840 f
->output_data
.w32
->win_gravity
= NorthEastGravity
;
4844 if (window_prompting
& YNegative
)
4845 f
->output_data
.w32
->win_gravity
= SouthWestGravity
;
4847 f
->output_data
.w32
->win_gravity
= NorthWestGravity
;
4850 f
->output_data
.w32
->size_hint_flags
= window_prompting
;
4852 w32_window (f
, window_prompting
, minibuffer_only
);
4854 init_frame_faces (f
);
4856 /* We need to do this after creating the window, so that the
4857 icon-creation functions can say whose icon they're describing. */
4858 x_default_parameter (f
, parms
, Qicon_type
, Qnil
,
4859 "bitmapIcon", "BitmapIcon", symbol
);
4861 x_default_parameter (f
, parms
, Qauto_raise
, Qnil
,
4862 "autoRaise", "AutoRaiseLower", boolean
);
4863 x_default_parameter (f
, parms
, Qauto_lower
, Qnil
,
4864 "autoLower", "AutoRaiseLower", boolean
);
4865 x_default_parameter (f
, parms
, Qcursor_type
, Qbox
,
4866 "cursorType", "CursorType", symbol
);
4868 /* Dimensions, especially f->height, must be done via change_frame_size.
4869 Change will not be effected unless different from the current
4874 SET_FRAME_WIDTH (f
, 0);
4875 change_frame_size (f
, height
, width
, 1, 0);
4877 /* Tell the server what size and position, etc, we want,
4878 and how badly we want them. */
4880 x_wm_set_size_hint (f
, window_prompting
, 0);
4883 tem
= x_get_arg (parms
, Qunsplittable
, 0, 0, boolean
);
4884 f
->no_split
= minibuffer_only
|| EQ (tem
, Qt
);
4888 /* It is now ok to make the frame official
4889 even if we get an error below.
4890 And the frame needs to be on Vframe_list
4891 or making it visible won't work. */
4892 Vframe_list
= Fcons (frame
, Vframe_list
);
4894 /* Now that the frame is official, it counts as a reference to
4896 FRAME_W32_DISPLAY_INFO (f
)->reference_count
++;
4898 /* Make the window appear on the frame and enable display,
4899 unless the caller says not to. However, with explicit parent,
4900 Emacs cannot control visibility, so don't try. */
4901 if (! f
->output_data
.w32
->explicit_parent
)
4903 Lisp_Object visibility
;
4905 visibility
= x_get_arg (parms
, Qvisibility
, 0, 0, symbol
);
4906 if (EQ (visibility
, Qunbound
))
4909 if (EQ (visibility
, Qicon
))
4910 x_iconify_frame (f
);
4911 else if (! NILP (visibility
))
4912 x_make_frame_visible (f
);
4914 /* Must have been Qnil. */
4918 return unbind_to (count
, frame
);
4921 /* FRAME is used only to get a handle on the X display. We don't pass the
4922 display info directly because we're called from frame.c, which doesn't
4923 know about that structure. */
4925 x_get_focus_frame (frame
)
4926 struct frame
*frame
;
4928 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (frame
);
4930 if (! dpyinfo
->w32_focus_frame
)
4933 XSETFRAME (xfocus
, dpyinfo
->w32_focus_frame
);
4937 DEFUN ("w32-focus-frame", Fw32_focus_frame
, Sw32_focus_frame
, 1, 1, 0,
4938 "Give FRAME input focus, raising to foreground if necessary.")
4942 x_focus_on_frame (check_x_frame (frame
));
4947 struct font_info
*w32_load_bdf_font (struct frame
*f
, char *fontname
,
4948 int size
, char* filename
);
4951 w32_load_system_font (f
,fontname
,size
)
4956 struct w32_display_info
*dpyinfo
= FRAME_W32_DISPLAY_INFO (f
);
4957 Lisp_Object font_names
;
4959 /* Get a list of all the fonts that match this name. Once we
4960 have a list of matching fonts, we compare them against the fonts
4961 we already have loaded by comparing names. */
4962 font_names
= w32_list_fonts (f
, build_string (fontname
), size
, 100);
4964 if (!NILP (font_names
))
4968 #if 0 /* This code has nasty side effects that cause Emacs to crash. */
4970 /* First check if any are already loaded, as that is cheaper
4971 than loading another one. */
4972 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
4973 for (tail
= font_names
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
4974 if (!strcmp (dpyinfo
->font_table
[i
].name
,
4975 XSTRING (XCONS (tail
)->car
)->data
)
4976 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
4977 XSTRING (XCONS (tail
)->car
)->data
))
4978 return (dpyinfo
->font_table
+ i
);
4980 fontname
= (char *) XSTRING (XCONS (font_names
)->car
)->data
;
4984 /* If EnumFontFamiliesEx was available, we got a full list of
4985 fonts back so stop now to avoid the possibility of loading a
4986 random font. If we had to fall back to EnumFontFamilies, the
4987 list is incomplete, so continue whether the font we want was
4989 HMODULE gdi32
= GetModuleHandle ("gdi32.dll");
4990 FARPROC enum_font_families_ex
4991 = GetProcAddress ( gdi32
, "EnumFontFamiliesExA");
4992 if (enum_font_families_ex
)
4996 /* Load the font and add it to the table. */
4998 char *full_name
, *encoding
;
5000 struct font_info
*fontp
;
5004 if (!fontname
|| !x_to_w32_font (fontname
, &lf
))
5007 if (!*lf
.lfFaceName
)
5008 /* If no name was specified for the font, we get a random font
5009 from CreateFontIndirect - this is not particularly
5010 desirable, especially since CreateFontIndirect does not
5011 fill out the missing name in lf, so we never know what we
5015 font
= (XFontStruct
*) xmalloc (sizeof (XFontStruct
));
5017 /* Set bdf to NULL to indicate that this is a Windows font. */
5022 font
->hfont
= CreateFontIndirect (&lf
);
5024 if (font
->hfont
== NULL
)
5033 hdc
= GetDC (dpyinfo
->root_window
);
5034 oldobj
= SelectObject (hdc
, font
->hfont
);
5035 ok
= GetTextMetrics (hdc
, &font
->tm
);
5036 SelectObject (hdc
, oldobj
);
5037 ReleaseDC (dpyinfo
->root_window
, hdc
);
5044 w32_unload_font (dpyinfo
, font
);
5048 /* Do we need to create the table? */
5049 if (dpyinfo
->font_table_size
== 0)
5051 dpyinfo
->font_table_size
= 16;
5053 = (struct font_info
*) xmalloc (dpyinfo
->font_table_size
5054 * sizeof (struct font_info
));
5056 /* Do we need to grow the table? */
5057 else if (dpyinfo
->n_fonts
5058 >= dpyinfo
->font_table_size
)
5060 dpyinfo
->font_table_size
*= 2;
5062 = (struct font_info
*) xrealloc (dpyinfo
->font_table
,
5063 (dpyinfo
->font_table_size
5064 * sizeof (struct font_info
)));
5067 fontp
= dpyinfo
->font_table
+ dpyinfo
->n_fonts
;
5069 /* Now fill in the slots of *FONTP. */
5072 fontp
->font_idx
= dpyinfo
->n_fonts
;
5073 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
5074 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
5076 /* Work out the font's full name. */
5077 full_name
= (char *)xmalloc (100);
5078 if (full_name
&& w32_to_x_font (&lf
, full_name
, 100))
5079 fontp
->full_name
= full_name
;
5082 /* If all else fails - just use the name we used to load it. */
5084 fontp
->full_name
= fontp
->name
;
5087 fontp
->size
= FONT_WIDTH (font
);
5088 fontp
->height
= FONT_HEIGHT (font
);
5090 /* The slot `encoding' specifies how to map a character
5091 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
5092 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
5093 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
5094 0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
5095 2:0xA020..0xFF7F). For the moment, we don't know which charset
5096 uses this font. So, we set informatoin in fontp->encoding[1]
5097 which is never used by any charset. If mapping can't be
5098 decided, set FONT_ENCODING_NOT_DECIDED. */
5100 /* SJIS fonts need to be set to type 4, all others seem to work as
5101 type FONT_ENCODING_NOT_DECIDED. */
5102 encoding
= strrchr (fontp
->name
, '-');
5103 if (encoding
&& stricmp (encoding
+1, "sjis") == 0)
5104 fontp
->encoding
[1] = 4;
5106 fontp
->encoding
[1] = FONT_ENCODING_NOT_DECIDED
;
5108 /* The following three values are set to 0 under W32, which is
5109 what they get set to if XGetFontProperty fails under X. */
5110 fontp
->baseline_offset
= 0;
5111 fontp
->relative_compose
= 0;
5112 fontp
->default_ascent
= 0;
5121 /* Load font named FONTNAME of size SIZE for frame F, and return a
5122 pointer to the structure font_info while allocating it dynamically.
5123 If loading fails, return NULL. */
5125 w32_load_font (f
,fontname
,size
)
5130 Lisp_Object bdf_fonts
;
5131 struct font_info
*retval
= NULL
;
5133 bdf_fonts
= w32_list_bdf_fonts (build_string (fontname
));
5135 while (!retval
&& CONSP (bdf_fonts
))
5137 char *bdf_name
, *bdf_file
;
5138 Lisp_Object bdf_pair
;
5140 bdf_name
= XSTRING (XCONS (bdf_fonts
)->car
)->data
;
5141 bdf_pair
= Fassoc (XCONS (bdf_fonts
)->car
, Vw32_bdf_filename_alist
);
5142 bdf_file
= XSTRING (XCONS (bdf_pair
)->cdr
)->data
;
5144 retval
= w32_load_bdf_font (f
, bdf_name
, size
, bdf_file
);
5146 bdf_fonts
= XCONS (bdf_fonts
)->cdr
;
5152 return w32_load_system_font(f
, fontname
, size
);
5157 w32_unload_font (dpyinfo
, font
)
5158 struct w32_display_info
*dpyinfo
;
5163 if (font
->bdf
) w32_free_bdf_font (font
->bdf
);
5165 if (font
->hfont
) DeleteObject(font
->hfont
);
5170 /* The font conversion stuff between x and w32 */
5172 /* X font string is as follows (from faces.el)
5176 * (weight "\\(bold\\|demibold\\|medium\\)") ; 1
5177 * (weight\? "\\([^-]*\\)") ; 1
5178 * (slant "\\([ior]\\)") ; 2
5179 * (slant\? "\\([^-]?\\)") ; 2
5180 * (swidth "\\([^-]*\\)") ; 3
5181 * (adstyle "[^-]*") ; 4
5182 * (pixelsize "[0-9]+")
5183 * (pointsize "[0-9][0-9]+")
5184 * (resx "[0-9][0-9]+")
5185 * (resy "[0-9][0-9]+")
5186 * (spacing "[cmp?*]")
5187 * (avgwidth "[0-9]+")
5188 * (registry "[^-]+")
5189 * (encoding "[^-]+")
5191 * (setq x-font-regexp
5192 * (concat "\\`\\*?[-?*]"
5193 * foundry - family - weight\? - slant\? - swidth - adstyle -
5194 * pixelsize - pointsize - resx - resy - spacing - registry -
5195 * encoding "[-?*]\\*?\\'"
5197 * (setq x-font-regexp-head
5198 * (concat "\\`[-?*]" foundry - family - weight\? - slant\?
5199 * "\\([-*?]\\|\\'\\)"))
5200 * (setq x-font-regexp-slant (concat - slant -))
5201 * (setq x-font-regexp-weight (concat - weight -))
5205 #define FONT_START "[-?]"
5206 #define FONT_FOUNDRY "[^-]+"
5207 #define FONT_FAMILY "\\([^-]+\\)" /* 1 */
5208 #define FONT_WEIGHT "\\(bold\\|demibold\\|medium\\)" /* 2 */
5209 #define FONT_WEIGHT_Q "\\([^-]*\\)" /* 2 */
5210 #define FONT_SLANT "\\([ior]\\)" /* 3 */
5211 #define FONT_SLANT_Q "\\([^-]?\\)" /* 3 */
5212 #define FONT_SWIDTH "\\([^-]*\\)" /* 4 */
5213 #define FONT_ADSTYLE "[^-]*"
5214 #define FONT_PIXELSIZE "[^-]*"
5215 #define FONT_POINTSIZE "\\([0-9][0-9]+\\|\\*\\)" /* 5 */
5216 #define FONT_RESX "[0-9][0-9]+"
5217 #define FONT_RESY "[0-9][0-9]+"
5218 #define FONT_SPACING "[cmp?*]"
5219 #define FONT_AVGWIDTH "[0-9]+"
5220 #define FONT_REGISTRY "[^-]+"
5221 #define FONT_ENCODING "[^-]+"
5223 #define FONT_REGEXP ("\\`\\*?[-?*]" \
5230 FONT_PIXELSIZE "-" \
5231 FONT_POINTSIZE "-" \
5234 #define FONT_REGEXP_HEAD ("\\`[-?*]" \
5239 "\\([-*?]\\|\\'\\)")
5241 #define FONT_REGEXP_SLANT "-" FONT_SLANT "-"
5242 #define FONT_REGEXP_WEIGHT "-" FONT_WEIGHT "-"
5245 x_to_w32_weight (lpw
)
5248 if (!lpw
) return (FW_DONTCARE
);
5250 if (stricmp (lpw
,"heavy") == 0) return FW_HEAVY
;
5251 else if (stricmp (lpw
,"extrabold") == 0) return FW_EXTRABOLD
;
5252 else if (stricmp (lpw
,"bold") == 0) return FW_BOLD
;
5253 else if (stricmp (lpw
,"demibold") == 0) return FW_SEMIBOLD
;
5254 else if (stricmp (lpw
,"semibold") == 0) return FW_SEMIBOLD
;
5255 else if (stricmp (lpw
,"medium") == 0) return FW_MEDIUM
;
5256 else if (stricmp (lpw
,"normal") == 0) return FW_NORMAL
;
5257 else if (stricmp (lpw
,"light") == 0) return FW_LIGHT
;
5258 else if (stricmp (lpw
,"extralight") == 0) return FW_EXTRALIGHT
;
5259 else if (stricmp (lpw
,"thin") == 0) return FW_THIN
;
5266 w32_to_x_weight (fnweight
)
5269 if (fnweight
>= FW_HEAVY
) return "heavy";
5270 if (fnweight
>= FW_EXTRABOLD
) return "extrabold";
5271 if (fnweight
>= FW_BOLD
) return "bold";
5272 if (fnweight
>= FW_SEMIBOLD
) return "semibold";
5273 if (fnweight
>= FW_MEDIUM
) return "medium";
5274 if (fnweight
>= FW_NORMAL
) return "normal";
5275 if (fnweight
>= FW_LIGHT
) return "light";
5276 if (fnweight
>= FW_EXTRALIGHT
) return "extralight";
5277 if (fnweight
>= FW_THIN
) return "thin";
5283 x_to_w32_charset (lpcs
)
5286 if (!lpcs
) return (0);
5288 if (stricmp (lpcs
,"ansi") == 0) return ANSI_CHARSET
;
5289 else if (stricmp (lpcs
,"iso8859-1") == 0) return ANSI_CHARSET
;
5290 else if (stricmp (lpcs
, "ms-symbol") == 0) return SYMBOL_CHARSET
;
5291 else if (stricmp (lpcs
, "jis") == 0) return SHIFTJIS_CHARSET
;
5292 else if (stricmp (lpcs
, "ksc5601.1987") == 0) return HANGEUL_CHARSET
;
5293 else if (stricmp (lpcs
, "gb2312") == 0) return GB2312_CHARSET
;
5294 else if (stricmp (lpcs
, "big5") == 0) return CHINESEBIG5_CHARSET
;
5295 else if (stricmp (lpcs
, "ms-oem") == 0) return OEM_CHARSET
;
5297 #ifdef EASTEUROPE_CHARSET
5298 else if (stricmp (lpcs
, "iso8859-2") == 0) return EASTEUROPE_CHARSET
;
5299 else if (stricmp (lpcs
, "iso8859-3") == 0) return TURKISH_CHARSET
;
5300 else if (stricmp (lpcs
, "iso8859-4") == 0) return BALTIC_CHARSET
;
5301 else if (stricmp (lpcs
, "iso8859-5") == 0) return RUSSIAN_CHARSET
;
5302 else if (stricmp (lpcs
, "koi8") == 0) return RUSSIAN_CHARSET
;
5303 else if (stricmp (lpcs
, "iso8859-6") == 0) return ARABIC_CHARSET
;
5304 else if (stricmp (lpcs
, "iso8859-7") == 0) return GREEK_CHARSET
;
5305 else if (stricmp (lpcs
, "iso8859-8") == 0) return HEBREW_CHARSET
;
5306 else if (stricmp (lpcs
, "iso8859-9") == 0) return TURKISH_CHARSET
;
5307 else if (stricmp (lpcs
, "viscii") == 0) return VIETNAMESE_CHARSET
;
5308 else if (stricmp (lpcs
, "vscii") == 0) return VIETNAMESE_CHARSET
;
5309 else if (stricmp (lpcs
, "tis620") == 0) return THAI_CHARSET
;
5310 else if (stricmp (lpcs
, "mac") == 0) return MAC_CHARSET
;
5311 else if (stricmp (lpcs
, "ksc5601.1992") == 0) return JOHAB_CHARSET
;
5312 /* For backwards compatibility with previous 20.4 pretests. */
5313 else if (stricmp (lpcs
, "ksc5601") == 0) return HANGEUL_CHARSET
;
5314 else if (stricmp (lpcs
, "johab") == 0) return JOHAB_CHARSET
;
5317 #ifdef UNICODE_CHARSET
5318 else if (stricmp (lpcs
,"iso10646") == 0) return UNICODE_CHARSET
;
5319 else if (stricmp (lpcs
, "unicode") == 0) return UNICODE_CHARSET
;
5321 else if (lpcs
[0] == '#') return atoi (lpcs
+ 1);
5323 return DEFAULT_CHARSET
;
5327 w32_to_x_charset (fncharset
)
5330 static char buf
[16];
5334 /* ansi is considered iso8859-1, as most modern ansi fonts are. */
5335 case ANSI_CHARSET
: return "iso8859-1";
5336 case DEFAULT_CHARSET
: return "ascii-*";
5337 case SYMBOL_CHARSET
: return "ms-symbol";
5338 case SHIFTJIS_CHARSET
: return "jisx0208-sjis";
5339 case HANGEUL_CHARSET
: return "ksc5601.1987-*";
5340 case GB2312_CHARSET
: return "gb2312-*";
5341 case CHINESEBIG5_CHARSET
: return "big5-*";
5342 case OEM_CHARSET
: return "ms-oem";
5344 /* More recent versions of Windows (95 and NT4.0) define more
5346 #ifdef EASTEUROPE_CHARSET
5347 case EASTEUROPE_CHARSET
: return "iso8859-2";
5348 case TURKISH_CHARSET
: return "iso8859-9";
5349 case BALTIC_CHARSET
: return "iso8859-4";
5351 /* W95 with international support but not IE4 often has the
5352 KOI8-R codepage but not ISO8859-5. */
5353 case RUSSIAN_CHARSET
:
5354 if (!IsValidCodePage(28595) && IsValidCodePage(20886))
5358 case ARABIC_CHARSET
: return "iso8859-6";
5359 case GREEK_CHARSET
: return "iso8859-7";
5360 case HEBREW_CHARSET
: return "iso8859-8";
5361 case VIETNAMESE_CHARSET
: return "viscii1.1-*";
5362 case THAI_CHARSET
: return "tis620-*";
5363 case MAC_CHARSET
: return "mac-*";
5364 case JOHAB_CHARSET
: return "ksc5601.1992-*";
5368 #ifdef UNICODE_CHARSET
5369 case UNICODE_CHARSET
: return "iso10646-unicode";
5372 /* Encode numerical value of unknown charset. */
5373 sprintf (buf
, "*-#%u", fncharset
);
5378 w32_to_x_font (lplogfont
, lpxstr
, len
)
5379 LOGFONT
* lplogfont
;
5384 char height_pixels
[8];
5386 char width_pixels
[8];
5387 char *fontname_dash
;
5388 int display_resy
= one_w32_display_info
.height_in
;
5389 int display_resx
= one_w32_display_info
.width_in
;
5391 if (!lpxstr
) abort ();
5396 strncpy (fontname
, lplogfont
->lfFaceName
, 50);
5397 fontname
[49] = '\0'; /* Just in case */
5399 /* Replace dashes with underscores so the dashes are not
5401 fontname_dash
= fontname
;
5402 while (fontname_dash
= strchr (fontname_dash
, '-'))
5403 *fontname_dash
= '_';
5405 if (lplogfont
->lfHeight
)
5407 sprintf (height_pixels
, "%u", abs (lplogfont
->lfHeight
));
5408 sprintf (height_dpi
, "%u",
5409 abs (lplogfont
->lfHeight
) * 720 / display_resy
);
5413 strcpy (height_pixels
, "*");
5414 strcpy (height_dpi
, "*");
5416 if (lplogfont
->lfWidth
)
5417 sprintf (width_pixels
, "%u", lplogfont
->lfWidth
* 10);
5419 strcpy (width_pixels
, "*");
5421 _snprintf (lpxstr
, len
- 1,
5422 "-*-%s-%s-%c-*-*-%s-%s-%d-%d-%c-%s-%s",
5424 fontname
, /* family */
5425 w32_to_x_weight (lplogfont
->lfWeight
), /* weight */
5426 lplogfont
->lfItalic
?'i':'r', /* slant */
5428 /* add style name */
5429 height_pixels
, /* pixel size */
5430 height_dpi
, /* point size */
5431 display_resx
, /* resx */
5432 display_resy
, /* resy */
5433 ((lplogfont
->lfPitchAndFamily
& 0x3) == VARIABLE_PITCH
)
5434 ? 'p' : 'c', /* spacing */
5435 width_pixels
, /* avg width */
5436 w32_to_x_charset (lplogfont
->lfCharSet
) /* charset registry
5440 lpxstr
[len
- 1] = 0; /* just to be sure */
5445 x_to_w32_font (lpxstr
, lplogfont
)
5447 LOGFONT
* lplogfont
;
5449 if (!lplogfont
) return (FALSE
);
5451 memset (lplogfont
, 0, sizeof (*lplogfont
));
5453 /* Set default value for each field. */
5455 lplogfont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
5456 lplogfont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
5457 lplogfont
->lfQuality
= DEFAULT_QUALITY
;
5459 /* go for maximum quality */
5460 lplogfont
->lfOutPrecision
= OUT_STROKE_PRECIS
;
5461 lplogfont
->lfClipPrecision
= CLIP_STROKE_PRECIS
;
5462 lplogfont
->lfQuality
= PROOF_QUALITY
;
5465 lplogfont
->lfCharSet
= DEFAULT_CHARSET
;
5466 lplogfont
->lfWeight
= FW_DONTCARE
;
5467 lplogfont
->lfPitchAndFamily
= DEFAULT_PITCH
| FF_DONTCARE
;
5472 /* Provide a simple escape mechanism for specifying Windows font names
5473 * directly -- if font spec does not beginning with '-', assume this
5475 * "<font name>[:height in pixels[:width in pixels[:weight]]]"
5481 char name
[50], weight
[20], slant
, pitch
, pixels
[10], height
[10],
5482 width
[10], resy
[10], remainder
[20];
5484 int dpi
= one_w32_display_info
.height_in
;
5486 fields
= sscanf (lpxstr
,
5487 "-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%9[^-]-%c-%9[^-]-%19s",
5488 name
, weight
, &slant
, pixels
, height
, resy
, &pitch
, width
, remainder
);
5489 if (fields
== EOF
) return (FALSE
);
5491 if (fields
> 0 && name
[0] != '*')
5493 strncpy (lplogfont
->lfFaceName
,name
, LF_FACESIZE
);
5494 lplogfont
->lfFaceName
[LF_FACESIZE
-1] = 0;
5498 lplogfont
->lfFaceName
[0] = 0;
5503 lplogfont
->lfWeight
= x_to_w32_weight ((fields
> 0 ? weight
: ""));
5507 if (!NILP (Vw32_enable_italics
))
5508 lplogfont
->lfItalic
= (fields
> 0 && slant
== 'i');
5512 if (fields
> 0 && pixels
[0] != '*')
5513 lplogfont
->lfHeight
= atoi (pixels
);
5517 if (fields
> 0 && resy
[0] != '*')
5519 tem
= atoi (pixels
);
5520 if (tem
> 0) dpi
= tem
;
5523 if (fields
> -1 && lplogfont
->lfHeight
== 0 && height
[0] != '*')
5524 lplogfont
->lfHeight
= atoi (height
) * dpi
/ 720;
5527 lplogfont
->lfPitchAndFamily
=
5528 (fields
> 0 && pitch
== 'p') ? VARIABLE_PITCH
: FIXED_PITCH
;
5532 if (fields
> 0 && width
[0] != '*')
5533 lplogfont
->lfWidth
= atoi (width
) / 10;
5537 /* Strip the trailing '-' if present. (it shouldn't be, as it
5538 fails the test against xlfn-tight-regexp in fontset.el). */
5540 int len
= strlen (remainder
);
5541 if (len
> 0 && remainder
[len
-1] == '-')
5542 remainder
[len
-1] = 0;
5544 encoding
= remainder
;
5545 if (strncmp (encoding
, "*-", 2) == 0)
5547 lplogfont
->lfCharSet
= x_to_w32_charset (fields
> 0 ? encoding
: "");
5552 char name
[100], height
[10], width
[10], weight
[20];
5554 fields
= sscanf (lpxstr
,
5555 "%99[^:]:%9[^:]:%9[^:]:%19s",
5556 name
, height
, width
, weight
);
5558 if (fields
== EOF
) return (FALSE
);
5562 strncpy (lplogfont
->lfFaceName
,name
, LF_FACESIZE
);
5563 lplogfont
->lfFaceName
[LF_FACESIZE
-1] = 0;
5567 lplogfont
->lfFaceName
[0] = 0;
5573 lplogfont
->lfHeight
= atoi (height
);
5578 lplogfont
->lfWidth
= atoi (width
);
5582 lplogfont
->lfWeight
= x_to_w32_weight ((fields
> 0 ? weight
: ""));
5585 /* This makes TrueType fonts work better. */
5586 lplogfont
->lfHeight
= - abs (lplogfont
->lfHeight
);
5592 w32_font_match (lpszfont1
, lpszfont2
)
5596 char * s1
= lpszfont1
, *e1
, *w1
;
5597 char * s2
= lpszfont2
, *e2
, *w2
;
5599 if (s1
== NULL
|| s2
== NULL
) return (FALSE
);
5601 if (*s1
== '-') s1
++;
5602 if (*s2
== '-') s2
++;
5606 int len1
, len2
, len3
=0;
5608 e1
= strchr (s1
, '-');
5609 e2
= strchr (s2
, '-');
5610 w1
= strchr (s1
, '*');
5611 w2
= strchr (s2
, '*');
5624 if (w2
&& w2
< e2
&& ( len3
== 0 || (w2
- s2
) < len3
))
5627 /* Whole field is not a wildcard, and ...*/
5628 if (*s1
!= '*' && *s2
!= '*' && *s1
!= '-' && *s2
!= '-'
5629 /* Lengths are different and there are no wildcards, or ... */
5630 && ((len1
!= len2
&& len3
== 0) ||
5631 /* strings don't match up until first wildcard or end. */
5632 strnicmp (s1
, s2
, len3
> 0 ? len3
: len1
) != 0))
5635 if (e1
== NULL
|| e2
== NULL
)
5643 /* Callback functions, and a structure holding info they need, for
5644 listing system fonts on W32. We need one set of functions to do the
5645 job properly, but these don't work on NT 3.51 and earlier, so we
5646 have a second set which don't handle character sets properly to
5649 In both cases, there are two passes made. The first pass gets one
5650 font from each family, the second pass lists all the fonts from
5653 typedef struct enumfont_t
5658 XFontStruct
*size_ref
;
5659 Lisp_Object
*pattern
;
5664 enum_font_cb2 (lplf
, lptm
, FontType
, lpef
)
5666 NEWTEXTMETRIC
* lptm
;
5670 if (lplf
->elfLogFont
.lfStrikeOut
|| lplf
->elfLogFont
.lfUnderline
)
5673 /* Check that the character set matches if it was specified */
5674 if (lpef
->logfont
.lfCharSet
!= DEFAULT_CHARSET
&&
5675 lplf
->elfLogFont
.lfCharSet
!= lpef
->logfont
.lfCharSet
)
5678 /* We want all fonts cached, so don't compare sizes just yet */
5679 /* if (!lpef->size_ref || lptm->tmMaxCharWidth == FONT_WIDTH (lpef->size_ref)) */
5682 Lisp_Object width
= Qnil
;
5684 if (!NILP (*(lpef
->pattern
)) && FontType
!= RASTER_FONTTYPE
)
5686 /* Scalable fonts are as big as you want them to be. */
5687 lplf
->elfLogFont
.lfHeight
= lpef
->logfont
.lfHeight
;
5688 lplf
->elfLogFont
.lfWidth
= lpef
->logfont
.lfWidth
;
5691 /* The MaxCharWidth is not valid at this stage for scalable fonts. */
5692 if (FontType
== RASTER_FONTTYPE
)
5693 width
= make_number (lptm
->tmMaxCharWidth
);
5695 if (!w32_to_x_font (&(lplf
->elfLogFont
), buf
, 100))
5698 if (NILP (*(lpef
->pattern
))
5699 || w32_font_match (buf
, XSTRING (*(lpef
->pattern
))->data
))
5701 *lpef
->tail
= Fcons (Fcons (build_string (buf
), width
), Qnil
);
5702 lpef
->tail
= &(XCONS (*lpef
->tail
)->cdr
);
5711 enum_font_cb1 (lplf
, lptm
, FontType
, lpef
)
5713 NEWTEXTMETRIC
* lptm
;
5717 return EnumFontFamilies (lpef
->hdc
,
5718 lplf
->elfLogFont
.lfFaceName
,
5719 (FONTENUMPROC
) enum_font_cb2
,
5725 enum_fontex_cb2 (lplf
, lptm
, font_type
, lpef
)
5726 ENUMLOGFONTEX
* lplf
;
5727 NEWTEXTMETRICEX
* lptm
;
5731 /* We are not interested in the extra info we get back from the 'Ex
5732 version - only the fact that we get character set variations
5733 enumerated seperately. */
5734 return enum_font_cb2 ((ENUMLOGFONT
*) lplf
, (NEWTEXTMETRIC
*) lptm
,
5739 enum_fontex_cb1 (lplf
, lptm
, font_type
, lpef
)
5740 ENUMLOGFONTEX
* lplf
;
5741 NEWTEXTMETRICEX
* lptm
;
5745 HMODULE gdi32
= GetModuleHandle ("gdi32.dll");
5746 FARPROC enum_font_families_ex
5747 = GetProcAddress ( gdi32
, "EnumFontFamiliesExA");
5748 /* We don't really expect EnumFontFamiliesEx to disappear once we
5749 get here, so don't bother handling it gracefully. */
5750 if (enum_font_families_ex
== NULL
)
5751 error ("gdi32.dll has disappeared!");
5752 return enum_font_families_ex (lpef
->hdc
,
5754 (FONTENUMPROC
) enum_fontex_cb2
,
5758 /* Interface to fontset handler. (adapted from mw32font.c in Meadow
5759 and xterm.c in Emacs 20.3) */
5761 Lisp_Object
w32_list_bdf_fonts (Lisp_Object pattern
, int max_names
)
5763 char *fontname
, *ptnstr
;
5764 Lisp_Object list
, tem
, newlist
= Qnil
;
5767 list
= Vw32_bdf_filename_alist
;
5768 ptnstr
= XSTRING (pattern
)->data
;
5770 for ( ; CONSP (list
); list
= XCONS (list
)->cdr
)
5772 tem
= XCONS (list
)->car
;
5774 fontname
= XSTRING (XCONS (tem
)->car
)->data
;
5775 else if (STRINGP (tem
))
5776 fontname
= XSTRING (tem
)->data
;
5780 if (w32_font_match (fontname
, ptnstr
))
5782 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
5784 if (n_fonts
>= max_names
)
5792 Lisp_Object
w32_list_synthesized_fonts (FRAME_PTR f
, Lisp_Object pattern
,
5793 int size
, int max_names
);
5795 /* Return a list of names of available fonts matching PATTERN on frame
5796 F. If SIZE is not 0, it is the size (maximum bound width) of fonts
5797 to be listed. Frame F NULL means we have not yet created any
5798 frame, which means we can't get proper size info, as we don't have
5799 a device context to use for GetTextMetrics.
5800 MAXNAMES sets a limit on how many fonts to match. */
5803 w32_list_fonts (FRAME_PTR f
, Lisp_Object pattern
, int size
, int maxnames
)
5805 Lisp_Object patterns
, key
, tem
, tpat
;
5806 Lisp_Object list
= Qnil
, newlist
= Qnil
, second_best
= Qnil
;
5807 struct w32_display_info
*dpyinfo
= &one_w32_display_info
;
5810 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
5811 if (NILP (patterns
))
5812 patterns
= Fcons (pattern
, Qnil
);
5814 for (; CONSP (patterns
); patterns
= XCONS (patterns
)->cdr
)
5818 tpat
= XCONS (patterns
)->car
;
5820 /* See if we cached the result for this particular query.
5821 The cache is an alist of the form:
5822 ((PATTERN (FONTNAME . WIDTH) ...) ...)
5824 if (tem
= XCONS (dpyinfo
->name_list_element
)->cdr
,
5825 !NILP (list
= Fassoc (tpat
, tem
)))
5827 list
= Fcdr_safe (list
);
5828 /* We have a cached list. Don't have to get the list again. */
5833 /* At first, put PATTERN in the cache. */
5839 /* Use EnumFontFamiliesEx where it is available, as it knows
5840 about character sets. Fall back to EnumFontFamilies for
5841 older versions of NT that don't support the 'Ex function. */
5842 x_to_w32_font (STRINGP (tpat
) ? XSTRING (tpat
)->data
:
5845 LOGFONT font_match_pattern
;
5846 HMODULE gdi32
= GetModuleHandle ("gdi32.dll");
5847 FARPROC enum_font_families_ex
5848 = GetProcAddress ( gdi32
, "EnumFontFamiliesExA");
5850 /* We do our own pattern matching so we can handle wildcards. */
5851 font_match_pattern
.lfFaceName
[0] = 0;
5852 font_match_pattern
.lfPitchAndFamily
= 0;
5853 /* We can use the charset, because if it is a wildcard it will
5854 be DEFAULT_CHARSET anyway. */
5855 font_match_pattern
.lfCharSet
= ef
.logfont
.lfCharSet
;
5857 ef
.hdc
= GetDC (dpyinfo
->root_window
);
5859 if (enum_font_families_ex
)
5860 enum_font_families_ex (ef
.hdc
,
5861 &font_match_pattern
,
5862 (FONTENUMPROC
) enum_fontex_cb1
,
5865 EnumFontFamilies (ef
.hdc
, NULL
, (FONTENUMPROC
) enum_font_cb1
,
5868 ReleaseDC (dpyinfo
->root_window
, ef
.hdc
);
5873 /* Make a list of the fonts we got back.
5874 Store that in the font cache for the display. */
5875 XCONS (dpyinfo
->name_list_element
)->cdr
5876 = Fcons (Fcons (tpat
, list
),
5877 XCONS (dpyinfo
->name_list_element
)->cdr
);
5880 if (NILP (list
)) continue; /* Try the remaining alternatives. */
5882 newlist
= second_best
= Qnil
;
5884 /* Make a list of the fonts that have the right width. */
5885 for (; CONSP (list
); list
= XCONS (list
)->cdr
)
5888 tem
= XCONS (list
)->car
;
5892 if (NILP (XCONS (tem
)->car
))
5896 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
5898 if (n_fonts
>= maxnames
)
5903 if (!INTEGERP (XCONS (tem
)->cdr
))
5905 /* Since we don't yet know the size of the font, we must
5906 load it and try GetTextMetrics. */
5907 W32FontStruct thisinfo
;
5912 if (!x_to_w32_font (XSTRING (XCONS (tem
)->car
)->data
, &lf
))
5916 thisinfo
.bdf
= NULL
;
5917 thisinfo
.hfont
= CreateFontIndirect (&lf
);
5918 if (thisinfo
.hfont
== NULL
)
5921 hdc
= GetDC (dpyinfo
->root_window
);
5922 oldobj
= SelectObject (hdc
, thisinfo
.hfont
);
5923 if (GetTextMetrics (hdc
, &thisinfo
.tm
))
5924 XCONS (tem
)->cdr
= make_number (FONT_WIDTH (&thisinfo
));
5926 XCONS (tem
)->cdr
= make_number (0);
5927 SelectObject (hdc
, oldobj
);
5928 ReleaseDC (dpyinfo
->root_window
, hdc
);
5929 DeleteObject(thisinfo
.hfont
);
5932 found_size
= XINT (XCONS (tem
)->cdr
);
5933 if (found_size
== size
)
5935 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
5937 if (n_fonts
>= maxnames
)
5940 /* keep track of the closest matching size in case
5941 no exact match is found. */
5942 else if (found_size
> 0)
5944 if (NILP (second_best
))
5947 else if (found_size
< size
)
5949 if (XINT (XCONS (second_best
)->cdr
) > size
5950 || XINT (XCONS (second_best
)->cdr
) < found_size
)
5955 if (XINT (XCONS (second_best
)->cdr
) > size
5956 && XINT (XCONS (second_best
)->cdr
) >
5963 if (!NILP (newlist
))
5965 else if (!NILP (second_best
))
5967 newlist
= Fcons (XCONS (second_best
)->car
, Qnil
);
5972 /* Include any bdf fonts. */
5973 if (n_fonts
< maxnames
)
5975 Lisp_Object combined
[2];
5976 combined
[0] = w32_list_bdf_fonts (pattern
, maxnames
- n_fonts
);
5977 combined
[1] = newlist
;
5978 newlist
= Fnconc(2, combined
);
5981 /* If we can't find a font that matches, check if Windows would be
5982 able to synthesize it from a different style. */
5983 if (NILP (newlist
) && !NILP (Vw32_enable_italics
))
5984 newlist
= w32_list_synthesized_fonts (f
, pattern
, size
, maxnames
);
5990 w32_list_synthesized_fonts (f
, pattern
, size
, max_names
)
5992 Lisp_Object pattern
;
5997 char *full_pattn
, *new_pattn
, foundary
[50], family
[50], *pattn_part2
;
5998 char style
[20], slant
;
5999 Lisp_Object matches
, match
, tem
, synthed_matches
= Qnil
;
6001 full_pattn
= XSTRING (pattern
)->data
;
6003 pattn_part2
= alloca (XSTRING (pattern
)->size
);
6004 /* Allow some space for wildcard expansion. */
6005 new_pattn
= alloca (XSTRING (pattern
)->size
+ 100);
6007 fields
= sscanf (full_pattn
, "-%49[^-]-%49[^-]-%19[^-]-%c-%s",
6008 foundary
, family
, style
, &slant
, pattn_part2
);
6009 if (fields
== EOF
|| fields
< 5)
6012 /* If the style and slant are wildcards already there is no point
6013 checking again (and we don't want to keep recursing). */
6014 if (*style
== '*' && slant
== '*')
6017 sprintf (new_pattn
, "-%s-%s-*-*-%s", foundary
, family
, pattn_part2
);
6019 matches
= w32_list_fonts (f
, build_string (new_pattn
), size
, max_names
);
6021 for ( ; CONSP (matches
); matches
= XCONS (matches
)->cdr
)
6023 tem
= XCONS (matches
)->car
;
6027 full_pattn
= XSTRING (tem
)->data
;
6028 fields
= sscanf (full_pattn
, "-%49[^-]-%49[^-]-%*[^-]-%*c-%s",
6029 foundary
, family
, pattn_part2
);
6030 if (fields
== EOF
|| fields
< 3)
6033 sprintf (new_pattn
, "-%s-%s-%s-%c-%s", foundary
, family
, style
,
6034 slant
, pattn_part2
);
6036 synthed_matches
= Fcons (build_string (new_pattn
),
6040 return synthed_matches
;
6044 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6046 w32_get_font_info (f
, font_idx
)
6050 return (FRAME_W32_FONT_TABLE (f
) + font_idx
);
6055 w32_query_font (struct frame
*f
, char *fontname
)
6058 struct font_info
*pfi
;
6060 pfi
= FRAME_W32_FONT_TABLE (f
);
6062 for (i
= 0; i
< one_w32_display_info
.n_fonts
;i
++, pfi
++)
6064 if (strcmp(pfi
->name
, fontname
) == 0) return pfi
;
6070 /* Find a CCL program for a font specified by FONTP, and set the member
6071 `encoder' of the structure. */
6074 w32_find_ccl_program (fontp
)
6075 struct font_info
*fontp
;
6077 extern Lisp_Object Vfont_ccl_encoder_alist
, Vccl_program_table
;
6078 extern Lisp_Object Qccl_program_idx
;
6079 extern Lisp_Object
resolve_symbol_ccl_program ();
6080 Lisp_Object list
, elt
, ccl_prog
, ccl_id
;
6082 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCONS (list
)->cdr
)
6084 elt
= XCONS (list
)->car
;
6086 && STRINGP (XCONS (elt
)->car
)
6087 && (fast_c_string_match_ignore_case (XCONS (elt
)->car
, fontp
->name
)
6090 if (SYMBOLP (XCONS (elt
)->cdr
) &&
6091 (!NILP (ccl_id
= Fget (XCONS (elt
)->cdr
, Qccl_program_idx
))))
6093 ccl_prog
= XVECTOR (Vccl_program_table
)->contents
[XUINT (ccl_id
)];
6094 if (!CONSP (ccl_prog
)) continue;
6095 ccl_prog
= XCONS (ccl_prog
)->cdr
;
6099 ccl_prog
= XCONS (elt
)->cdr
;
6100 if (!VECTORP (ccl_prog
)) continue;
6104 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
6105 setup_ccl_program (fontp
->font_encoder
,
6106 resolve_symbol_ccl_program (ccl_prog
));
6114 #include "x-list-font.c"
6116 DEFUN ("x-list-fonts", Fx_list_fonts
, Sx_list_fonts
, 1, 4, 0,
6117 "Return a list of the names of available fonts matching PATTERN.\n\
6118 If optional arguments FACE and FRAME are specified, return only fonts\n\
6119 the same size as FACE on FRAME.\n\
6121 PATTERN is a string, perhaps with wildcard characters;\n\
6122 the * character matches any substring, and\n\
6123 the ? character matches any single character.\n\
6124 PATTERN is case-insensitive.\n\
6125 FACE is a face name--a symbol.\n\
6127 The return value is a list of strings, suitable as arguments to\n\
6130 Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
6131 even if they match PATTERN and FACE.\n\
6133 The optional fourth argument MAXIMUM sets a limit on how many\n\
6134 fonts to match. The first MAXIMUM fonts are reported.")
6135 (pattern
, face
, frame
, maximum
)
6136 Lisp_Object pattern
, face
, frame
, maximum
;
6141 XFontStruct
*size_ref
;
6142 Lisp_Object namelist
;
6147 CHECK_STRING (pattern
, 0);
6149 CHECK_SYMBOL (face
, 1);
6151 f
= check_x_frame (frame
);
6153 /* Determine the width standard for comparison with the fonts we find. */
6161 /* Don't die if we get called with a terminal frame. */
6162 if (! FRAME_W32_P (f
))
6163 error ("non-w32 frame used in `x-list-fonts'");
6165 face_id
= face_name_id_number (f
, face
);
6167 if (face_id
< 0 || face_id
>= FRAME_N_PARAM_FACES (f
)
6168 || FRAME_PARAM_FACES (f
) [face_id
] == 0)
6169 size_ref
= f
->output_data
.w32
->font
;
6172 size_ref
= FRAME_PARAM_FACES (f
) [face_id
]->font
;
6173 if (size_ref
== (XFontStruct
*) (~0))
6174 size_ref
= f
->output_data
.w32
->font
;
6178 /* See if we cached the result for this particular query. */
6179 list
= Fassoc (pattern
,
6180 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
6182 /* We have info in the cache for this PATTERN. */
6185 Lisp_Object tem
, newlist
;
6187 /* We have info about this pattern. */
6188 list
= XCONS (list
)->cdr
;
6195 /* Filter the cached info and return just the fonts that match FACE. */
6197 for (tem
= list
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
6199 struct font_info
*fontinf
;
6200 XFontStruct
*thisinfo
= NULL
;
6202 fontinf
= w32_load_font (f
, XSTRING (XCONS (tem
)->car
)->data
, 0);
6204 thisinfo
= (XFontStruct
*)fontinf
->font
;
6205 if (thisinfo
&& same_size_fonts (thisinfo
, size_ref
))
6206 newlist
= Fcons (XCONS (tem
)->car
, newlist
);
6208 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), thisinfo
);
6219 ef
.pattern
= &pattern
;
6222 x_to_w32_font (STRINGP (pattern
) ? XSTRING (pattern
)->data
: NULL
, &ef
.logfont
);
6225 ef
.hdc
= GetDC (FRAME_W32_WINDOW (f
));
6227 EnumFontFamilies (ef
.hdc
, NULL
, (FONTENUMPROC
) enum_font_cb1
, (LPARAM
)&ef
);
6229 ReleaseDC (FRAME_W32_WINDOW (f
), ef
.hdc
);
6239 /* Make a list of all the fonts we got back.
6240 Store that in the font cache for the display. */
6241 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
6242 = Fcons (Fcons (pattern
, namelist
),
6243 XCONS (FRAME_W32_DISPLAY_INFO (f
)->name_list_element
)->cdr
);
6245 /* Make a list of the fonts that have the right width. */
6248 for (i
= 0; i
< ef
.numFonts
; i
++)
6256 struct font_info
*fontinf
;
6257 XFontStruct
*thisinfo
= NULL
;
6260 fontinf
= w32_load_font (f
, XSTRING (Fcar (cur
))->data
, 0);
6262 thisinfo
= (XFontStruct
*)fontinf
->font
;
6264 keeper
= thisinfo
&& same_size_fonts (thisinfo
, size_ref
);
6266 w32_unload_font (FRAME_W32_DISPLAY_INFO (f
), thisinfo
);
6271 list
= Fcons (build_string (XSTRING (Fcar (cur
))->data
), list
);
6275 list
= Fnreverse (list
);
6282 DEFUN ("w32-find-bdf-fonts", Fw32_find_bdf_fonts
, Sw32_find_bdf_fonts
,
6284 "Return a list of BDF fonts in DIR, suitable for appending to\n\
6285 w32-bdf-filename-alist. Fonts which do not contain an xfld description\n\
6286 will not be included in the list. DIR may be a list of directories.")
6288 Lisp_Object directory
;
6290 Lisp_Object list
= Qnil
;
6291 struct gcpro gcpro1
, gcpro2
;
6293 if (!CONSP (directory
))
6294 return w32_find_bdf_fonts_in_dir (directory
);
6296 for ( ; CONSP (directory
); directory
= XCONS (directory
)->cdr
)
6298 Lisp_Object pair
[2];
6301 GCPRO2 (directory
, list
);
6302 pair
[1] = w32_find_bdf_fonts_in_dir( XCONS (directory
)->car
);
6303 list
= Fnconc( 2, pair
);
6309 /* Find BDF files in a specified directory. (use GCPRO when calling,
6310 as this calls lisp to get a directory listing). */
6311 Lisp_Object
w32_find_bdf_fonts_in_dir( Lisp_Object directory
)
6313 Lisp_Object filelist
, list
= Qnil
;
6316 if (!STRINGP(directory
))
6319 filelist
= Fdirectory_files (directory
, Qt
,
6320 build_string (".*\\.[bB][dD][fF]"), Qt
);
6322 for ( ; CONSP(filelist
); filelist
= XCONS (filelist
)->cdr
)
6324 Lisp_Object filename
= XCONS (filelist
)->car
;
6325 if (w32_BDF_to_x_font (XSTRING (filename
)->data
, fontname
, 100))
6326 store_in_alist (&list
, build_string (fontname
), filename
);
6332 DEFUN ("x-color-defined-p", Fx_color_defined_p
, Sx_color_defined_p
, 1, 2, 0,
6333 "Return non-nil if color COLOR is supported on frame FRAME.\n\
6334 If FRAME is omitted or nil, use the selected frame.")
6336 Lisp_Object color
, frame
;
6339 FRAME_PTR f
= check_x_frame (frame
);
6341 CHECK_STRING (color
, 1);
6343 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
6349 DEFUN ("x-color-values", Fx_color_values
, Sx_color_values
, 1, 2, 0,
6350 "Return a description of the color named COLOR on frame FRAME.\n\
6351 The value is a list of integer RGB values--(RED GREEN BLUE).\n\
6352 These values appear to range from 0 to 65280 or 65535, depending\n\
6353 on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
6354 If FRAME is omitted or nil, use the selected frame.")
6356 Lisp_Object color
, frame
;
6359 FRAME_PTR f
= check_x_frame (frame
);
6361 CHECK_STRING (color
, 1);
6363 if (defined_color (f
, XSTRING (color
)->data
, &foo
, 0))
6367 rgb
[0] = make_number ((GetRValue (foo
) << 8) | GetRValue (foo
));
6368 rgb
[1] = make_number ((GetGValue (foo
) << 8) | GetGValue (foo
));
6369 rgb
[2] = make_number ((GetBValue (foo
) << 8) | GetBValue (foo
));
6370 return Flist (3, rgb
);
6376 DEFUN ("x-display-color-p", Fx_display_color_p
, Sx_display_color_p
, 0, 1, 0,
6377 "Return t if the X display supports color.\n\
6378 The optional argument DISPLAY specifies which display to ask about.\n\
6379 DISPLAY should be either a frame or a display name (a string).\n\
6380 If omitted or nil, that stands for the selected frame's display.")
6382 Lisp_Object display
;
6384 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6386 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 2)
6392 DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p
, Sx_display_grayscale_p
,
6394 "Return t if the X display supports shades of gray.\n\
6395 Note that color displays do support shades of gray.\n\
6396 The optional argument DISPLAY specifies which display to ask about.\n\
6397 DISPLAY should be either a frame or a display name (a string).\n\
6398 If omitted or nil, that stands for the selected frame's display.")
6400 Lisp_Object display
;
6402 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6404 if ((dpyinfo
->n_planes
* dpyinfo
->n_cbits
) <= 1)
6410 DEFUN ("x-display-pixel-width", Fx_display_pixel_width
, Sx_display_pixel_width
,
6412 "Returns the width in pixels of the X display DISPLAY.\n\
6413 The optional argument DISPLAY specifies which display to ask about.\n\
6414 DISPLAY should be either a frame or a display name (a string).\n\
6415 If omitted or nil, that stands for the selected frame's display.")
6417 Lisp_Object display
;
6419 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6421 return make_number (dpyinfo
->width
);
6424 DEFUN ("x-display-pixel-height", Fx_display_pixel_height
,
6425 Sx_display_pixel_height
, 0, 1, 0,
6426 "Returns the height in pixels of the X display DISPLAY.\n\
6427 The optional argument DISPLAY specifies which display to ask about.\n\
6428 DISPLAY should be either a frame or a display name (a string).\n\
6429 If omitted or nil, that stands for the selected frame's display.")
6431 Lisp_Object display
;
6433 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6435 return make_number (dpyinfo
->height
);
6438 DEFUN ("x-display-planes", Fx_display_planes
, Sx_display_planes
,
6440 "Returns the number of bitplanes of the display DISPLAY.\n\
6441 The optional argument DISPLAY specifies which display to ask about.\n\
6442 DISPLAY should be either a frame or a display name (a string).\n\
6443 If omitted or nil, that stands for the selected frame's display.")
6445 Lisp_Object display
;
6447 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6449 return make_number (dpyinfo
->n_planes
* dpyinfo
->n_cbits
);
6452 DEFUN ("x-display-color-cells", Fx_display_color_cells
, Sx_display_color_cells
,
6454 "Returns the number of color cells of the display DISPLAY.\n\
6455 The optional argument DISPLAY specifies which display to ask about.\n\
6456 DISPLAY should be either a frame or a display name (a string).\n\
6457 If omitted or nil, that stands for the selected frame's display.")
6459 Lisp_Object display
;
6461 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6465 hdc
= GetDC (dpyinfo
->root_window
);
6466 if (dpyinfo
->has_palette
)
6467 cap
= GetDeviceCaps (hdc
,SIZEPALETTE
);
6469 cap
= GetDeviceCaps (hdc
,NUMCOLORS
);
6471 ReleaseDC (dpyinfo
->root_window
, hdc
);
6473 return make_number (cap
);
6476 DEFUN ("x-server-max-request-size", Fx_server_max_request_size
,
6477 Sx_server_max_request_size
,
6479 "Returns the maximum request size of the server of display DISPLAY.\n\
6480 The optional argument DISPLAY specifies which display to ask about.\n\
6481 DISPLAY should be either a frame or a display name (a string).\n\
6482 If omitted or nil, that stands for the selected frame's display.")
6484 Lisp_Object display
;
6486 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6488 return make_number (1);
6491 DEFUN ("x-server-vendor", Fx_server_vendor
, Sx_server_vendor
, 0, 1, 0,
6492 "Returns the vendor ID string of the W32 system (Microsoft).\n\
6493 The optional argument DISPLAY specifies which display to ask about.\n\
6494 DISPLAY should be either a frame or a display name (a string).\n\
6495 If omitted or nil, that stands for the selected frame's display.")
6497 Lisp_Object display
;
6499 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6500 char *vendor
= "Microsoft Corp.";
6502 if (! vendor
) vendor
= "";
6503 return build_string (vendor
);
6506 DEFUN ("x-server-version", Fx_server_version
, Sx_server_version
, 0, 1, 0,
6507 "Returns the version numbers of the server of display DISPLAY.\n\
6508 The value is a list of three integers: the major and minor\n\
6509 version numbers, and the vendor-specific release\n\
6510 number. See also the function `x-server-vendor'.\n\n\
6511 The optional argument DISPLAY specifies which display to ask about.\n\
6512 DISPLAY should be either a frame or a display name (a string).\n\
6513 If omitted or nil, that stands for the selected frame's display.")
6515 Lisp_Object display
;
6517 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6519 return Fcons (make_number (w32_major_version
),
6520 Fcons (make_number (w32_minor_version
), Qnil
));
6523 DEFUN ("x-display-screens", Fx_display_screens
, Sx_display_screens
, 0, 1, 0,
6524 "Returns the number of screens on the server of display DISPLAY.\n\
6525 The optional argument DISPLAY specifies which display to ask about.\n\
6526 DISPLAY should be either a frame or a display name (a string).\n\
6527 If omitted or nil, that stands for the selected frame's display.")
6529 Lisp_Object display
;
6531 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6533 return make_number (1);
6536 DEFUN ("x-display-mm-height", Fx_display_mm_height
, Sx_display_mm_height
, 0, 1, 0,
6537 "Returns the height in millimeters of the X display DISPLAY.\n\
6538 The optional argument DISPLAY specifies which display to ask about.\n\
6539 DISPLAY should be either a frame or a display name (a string).\n\
6540 If omitted or nil, that stands for the selected frame's display.")
6542 Lisp_Object display
;
6544 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6548 hdc
= GetDC (dpyinfo
->root_window
);
6550 cap
= GetDeviceCaps (hdc
, VERTSIZE
);
6552 ReleaseDC (dpyinfo
->root_window
, hdc
);
6554 return make_number (cap
);
6557 DEFUN ("x-display-mm-width", Fx_display_mm_width
, Sx_display_mm_width
, 0, 1, 0,
6558 "Returns the width in millimeters of the X display DISPLAY.\n\
6559 The optional argument DISPLAY specifies which display to ask about.\n\
6560 DISPLAY should be either a frame or a display name (a string).\n\
6561 If omitted or nil, that stands for the selected frame's display.")
6563 Lisp_Object display
;
6565 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6570 hdc
= GetDC (dpyinfo
->root_window
);
6572 cap
= GetDeviceCaps (hdc
, HORZSIZE
);
6574 ReleaseDC (dpyinfo
->root_window
, hdc
);
6576 return make_number (cap
);
6579 DEFUN ("x-display-backing-store", Fx_display_backing_store
,
6580 Sx_display_backing_store
, 0, 1, 0,
6581 "Returns an indication of whether display DISPLAY does backing store.\n\
6582 The value may be `always', `when-mapped', or `not-useful'.\n\
6583 The optional argument DISPLAY specifies which display to ask about.\n\
6584 DISPLAY should be either a frame or a display name (a string).\n\
6585 If omitted or nil, that stands for the selected frame's display.")
6587 Lisp_Object display
;
6589 return intern ("not-useful");
6592 DEFUN ("x-display-visual-class", Fx_display_visual_class
,
6593 Sx_display_visual_class
, 0, 1, 0,
6594 "Returns the visual class of the display DISPLAY.\n\
6595 The value is one of the symbols `static-gray', `gray-scale',\n\
6596 `static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
6597 The optional argument DISPLAY specifies which display to ask about.\n\
6598 DISPLAY should be either a frame or a display name (a string).\n\
6599 If omitted or nil, that stands for the selected frame's display.")
6601 Lisp_Object display
;
6603 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6606 switch (dpyinfo
->visual
->class)
6608 case StaticGray
: return (intern ("static-gray"));
6609 case GrayScale
: return (intern ("gray-scale"));
6610 case StaticColor
: return (intern ("static-color"));
6611 case PseudoColor
: return (intern ("pseudo-color"));
6612 case TrueColor
: return (intern ("true-color"));
6613 case DirectColor
: return (intern ("direct-color"));
6615 error ("Display has an unknown visual class");
6619 error ("Display has an unknown visual class");
6622 DEFUN ("x-display-save-under", Fx_display_save_under
,
6623 Sx_display_save_under
, 0, 1, 0,
6624 "Returns t if the display DISPLAY supports the save-under feature.\n\
6625 The optional argument DISPLAY specifies which display to ask about.\n\
6626 DISPLAY should be either a frame or a display name (a string).\n\
6627 If omitted or nil, that stands for the selected frame's display.")
6629 Lisp_Object display
;
6631 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6638 register struct frame
*f
;
6640 return PIXEL_WIDTH (f
);
6645 register struct frame
*f
;
6647 return PIXEL_HEIGHT (f
);
6652 register struct frame
*f
;
6654 return FONT_WIDTH (f
->output_data
.w32
->font
);
6659 register struct frame
*f
;
6661 return f
->output_data
.w32
->line_height
;
6665 x_screen_planes (frame
)
6668 return (FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_planes
*
6669 FRAME_W32_DISPLAY_INFO (XFRAME (frame
))->n_cbits
);
6672 /* Return the display structure for the display named NAME.
6673 Open a new connection if necessary. */
6675 struct w32_display_info
*
6676 x_display_info_for_name (name
)
6680 struct w32_display_info
*dpyinfo
;
6682 CHECK_STRING (name
, 0);
6684 for (dpyinfo
= &one_w32_display_info
, names
= w32_display_name_list
;
6686 dpyinfo
= dpyinfo
->next
, names
= XCONS (names
)->cdr
)
6689 tem
= Fstring_equal (XCONS (XCONS (names
)->car
)->car
, name
);
6694 /* Use this general default value to start with. */
6695 Vx_resource_name
= Vinvocation_name
;
6697 validate_x_resource_name ();
6699 dpyinfo
= w32_term_init (name
, (unsigned char *)0,
6700 (char *) XSTRING (Vx_resource_name
)->data
);
6703 error ("Cannot connect to server %s", XSTRING (name
)->data
);
6706 XSETFASTINT (Vwindow_system_version
, 3);
6711 DEFUN ("x-open-connection", Fx_open_connection
, Sx_open_connection
,
6712 1, 3, 0, "Open a connection to a server.\n\
6713 DISPLAY is the name of the display to connect to.\n\
6714 Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
6715 If the optional third arg MUST-SUCCEED is non-nil,\n\
6716 terminate Emacs if we can't open the connection.")
6717 (display
, xrm_string
, must_succeed
)
6718 Lisp_Object display
, xrm_string
, must_succeed
;
6720 unsigned int n_planes
;
6721 unsigned char *xrm_option
;
6722 struct w32_display_info
*dpyinfo
;
6724 CHECK_STRING (display
, 0);
6725 if (! NILP (xrm_string
))
6726 CHECK_STRING (xrm_string
, 1);
6728 if (! EQ (Vwindow_system
, intern ("w32")))
6729 error ("Not using Microsoft Windows");
6731 /* Allow color mapping to be defined externally; first look in user's
6732 HOME directory, then in Emacs etc dir for a file called rgb.txt. */
6734 Lisp_Object color_file
;
6735 struct gcpro gcpro1
;
6737 color_file
= build_string("~/rgb.txt");
6739 GCPRO1 (color_file
);
6741 if (NILP (Ffile_readable_p (color_file
)))
6743 Fexpand_file_name (build_string ("rgb.txt"),
6744 Fsymbol_value (intern ("data-directory")));
6746 Vw32_color_map
= Fw32_load_color_file (color_file
);
6750 if (NILP (Vw32_color_map
))
6751 Vw32_color_map
= Fw32_default_color_map ();
6753 if (! NILP (xrm_string
))
6754 xrm_option
= (unsigned char *) XSTRING (xrm_string
)->data
;
6756 xrm_option
= (unsigned char *) 0;
6758 /* Use this general default value to start with. */
6759 /* First remove .exe suffix from invocation-name - it looks ugly. */
6761 char basename
[ MAX_PATH
], *str
;
6763 strcpy (basename
, XSTRING (Vinvocation_name
)->data
);
6764 str
= strrchr (basename
, '.');
6766 Vinvocation_name
= build_string (basename
);
6768 Vx_resource_name
= Vinvocation_name
;
6770 validate_x_resource_name ();
6772 /* This is what opens the connection and sets x_current_display.
6773 This also initializes many symbols, such as those used for input. */
6774 dpyinfo
= w32_term_init (display
, xrm_option
,
6775 (char *) XSTRING (Vx_resource_name
)->data
);
6779 if (!NILP (must_succeed
))
6780 fatal ("Cannot connect to server %s.\n",
6781 XSTRING (display
)->data
);
6783 error ("Cannot connect to server %s", XSTRING (display
)->data
);
6788 XSETFASTINT (Vwindow_system_version
, 3);
6792 DEFUN ("x-close-connection", Fx_close_connection
,
6793 Sx_close_connection
, 1, 1, 0,
6794 "Close the connection to DISPLAY's server.\n\
6795 For DISPLAY, specify either a frame or a display name (a string).\n\
6796 If DISPLAY is nil, that stands for the selected frame's display.")
6798 Lisp_Object display
;
6800 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6801 struct w32_display_info
*tail
;
6804 if (dpyinfo
->reference_count
> 0)
6805 error ("Display still has frames on it");
6808 /* Free the fonts in the font table. */
6809 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
6811 if (dpyinfo
->font_table
[i
].name
)
6812 free (dpyinfo
->font_table
[i
].name
);
6813 /* Don't free the full_name string;
6814 it is always shared with something else. */
6815 w32_unload_font (dpyinfo
, dpyinfo
->font_table
[i
].font
);
6817 x_destroy_all_bitmaps (dpyinfo
);
6819 x_delete_display (dpyinfo
);
6825 DEFUN ("x-display-list", Fx_display_list
, Sx_display_list
, 0, 0, 0,
6826 "Return the list of display names that Emacs has connections to.")
6829 Lisp_Object tail
, result
;
6832 for (tail
= w32_display_name_list
; ! NILP (tail
); tail
= XCONS (tail
)->cdr
)
6833 result
= Fcons (XCONS (XCONS (tail
)->car
)->car
, result
);
6838 DEFUN ("x-synchronize", Fx_synchronize
, Sx_synchronize
, 1, 2, 0,
6839 "If ON is non-nil, report errors as soon as the erring request is made.\n\
6840 If ON is nil, allow buffering of requests.\n\
6841 This is a noop on W32 systems.\n\
6842 The optional second argument DISPLAY specifies which display to act on.\n\
6843 DISPLAY should be either a frame or a display name (a string).\n\
6844 If DISPLAY is omitted or nil, that stands for the selected frame's display.")
6846 Lisp_Object display
, on
;
6848 struct w32_display_info
*dpyinfo
= check_x_display_info (display
);
6854 /* These are the w32 specialized functions */
6856 DEFUN ("w32-select-font", Fw32_select_font
, Sw32_select_font
, 0, 1, 0,
6857 "This will display the W32 font dialog and return an X font string corresponding to the selection.")
6861 FRAME_PTR f
= check_x_frame (frame
);
6866 bzero (&cf
, sizeof (cf
));
6868 cf
.lStructSize
= sizeof (cf
);
6869 cf
.hwndOwner
= FRAME_W32_WINDOW (f
);
6870 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
| CF_SCREENFONTS
;
6873 if (!ChooseFont (&cf
) || !w32_to_x_font (&lf
, buf
, 100))
6876 return build_string (buf
);
6879 DEFUN ("w32-send-sys-command", Fw32_send_sys_command
, Sw32_send_sys_command
, 1, 2, 0,
6880 "Send frame a Windows WM_SYSCOMMAND message of type COMMAND.\n\
6881 Some useful values for command are 0xf030 to maximise frame (0xf020\n\
6882 to minimize), 0xf120 to restore frame to original size, and 0xf100\n\
6883 to activate the menubar for keyboard access. 0xf140 activates the\n\
6884 screen saver if defined.\n\
6886 If optional parameter FRAME is not specified, use selected frame.")
6888 Lisp_Object command
, frame
;
6891 FRAME_PTR f
= check_x_frame (frame
);
6893 CHECK_NUMBER (command
, 0);
6895 SendMessage (FRAME_W32_WINDOW (f
), WM_SYSCOMMAND
, XINT (command
), 0);
6900 /* Lookup virtual keycode from string representing the name of a
6901 non-ascii keystroke into the corresponding virtual key, using
6902 lispy_function_keys. */
6904 lookup_vk_code (char *key
)
6908 for (i
= 0; i
< 256; i
++)
6909 if (lispy_function_keys
[i
] != 0
6910 && strcmp (lispy_function_keys
[i
], key
) == 0)
6916 /* Convert a one-element vector style key sequence to a hot key
6919 w32_parse_hot_key (key
)
6922 /* Copied from Fdefine_key and store_in_keymap. */
6923 register Lisp_Object c
;
6927 struct gcpro gcpro1
;
6929 CHECK_VECTOR (key
, 0);
6931 if (XFASTINT (Flength (key
)) != 1)
6936 c
= Faref (key
, make_number (0));
6938 if (CONSP (c
) && lucid_event_type_list_p (c
))
6939 c
= Fevent_convert_list (c
);
6943 if (! INTEGERP (c
) && ! SYMBOLP (c
))
6944 error ("Key definition is invalid");
6946 /* Work out the base key and the modifiers. */
6949 c
= parse_modifiers (c
);
6950 lisp_modifiers
= Fcar (Fcdr (c
));
6954 vk_code
= lookup_vk_code (XSYMBOL (c
)->name
->data
);
6956 else if (INTEGERP (c
))
6958 lisp_modifiers
= XINT (c
) & ~CHARACTERBITS
;
6959 /* Many ascii characters are their own virtual key code. */
6960 vk_code
= XINT (c
) & CHARACTERBITS
;
6963 if (vk_code
< 0 || vk_code
> 255)
6966 if ((lisp_modifiers
& meta_modifier
) != 0
6967 && !NILP (Vw32_alt_is_meta
))
6968 lisp_modifiers
|= alt_modifier
;
6970 /* Convert lisp modifiers to Windows hot-key form. */
6971 w32_modifiers
= (lisp_modifiers
& hyper_modifier
) ? MOD_WIN
: 0;
6972 w32_modifiers
|= (lisp_modifiers
& alt_modifier
) ? MOD_ALT
: 0;
6973 w32_modifiers
|= (lisp_modifiers
& ctrl_modifier
) ? MOD_CONTROL
: 0;
6974 w32_modifiers
|= (lisp_modifiers
& shift_modifier
) ? MOD_SHIFT
: 0;
6976 return HOTKEY (vk_code
, w32_modifiers
);
6979 DEFUN ("w32-register-hot-key", Fw32_register_hot_key
, Sw32_register_hot_key
, 1, 1, 0,
6980 "Register KEY as a hot-key combination.\n\
6981 Certain key combinations like Alt-Tab are reserved for system use on\n\
6982 Windows, and therefore are normally intercepted by the system. However,\n\
6983 most of these key combinations can be received by registering them as\n\
6984 hot-keys, overriding their special meaning.\n\
6986 KEY must be a one element key definition in vector form that would be\n\
6987 acceptable to `define-key' (e.g. [A-tab] for Alt-Tab). The meta\n\
6988 modifier is interpreted as Alt if `w32-alt-is-meta' is t, and hyper\n\
6989 is always interpreted as the Windows modifier keys.\n\
6991 The return value is the hotkey-id if registered, otherwise nil.")
6995 key
= w32_parse_hot_key (key
);
6997 if (NILP (Fmemq (key
, w32_grabbed_keys
)))
6999 /* Reuse an empty slot if possible. */
7000 Lisp_Object item
= Fmemq (Qnil
, w32_grabbed_keys
);
7002 /* Safe to add new key to list, even if we have focus. */
7004 w32_grabbed_keys
= Fcons (key
, w32_grabbed_keys
);
7008 /* Notify input thread about new hot-key definition, so that it
7009 takes effect without needing to switch focus. */
7010 PostThreadMessage (dwWindowsThreadId
, WM_EMACS_REGISTER_HOT_KEY
,
7017 DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key
, Sw32_unregister_hot_key
, 1, 1, 0,
7018 "Unregister HOTKEY as a hot-key combination.")
7024 if (!INTEGERP (key
))
7025 key
= w32_parse_hot_key (key
);
7027 item
= Fmemq (key
, w32_grabbed_keys
);
7031 /* Notify input thread about hot-key definition being removed, so
7032 that it takes effect without needing focus switch. */
7033 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_UNREGISTER_HOT_KEY
,
7034 (WPARAM
) XINT (XCAR (item
)), (LPARAM
) item
))
7037 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
7044 DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys
, Sw32_registered_hot_keys
, 0, 0, 0,
7045 "Return list of registered hot-key IDs.")
7048 return Fcopy_sequence (w32_grabbed_keys
);
7051 DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key
, Sw32_reconstruct_hot_key
, 1, 1, 0,
7052 "Convert hot-key ID to a lisp key combination.")
7054 Lisp_Object hotkeyid
;
7056 int vk_code
, w32_modifiers
;
7059 CHECK_NUMBER (hotkeyid
, 0);
7061 vk_code
= HOTKEY_VK_CODE (hotkeyid
);
7062 w32_modifiers
= HOTKEY_MODIFIERS (hotkeyid
);
7064 if (lispy_function_keys
[vk_code
])
7065 key
= intern (lispy_function_keys
[vk_code
]);
7067 key
= make_number (vk_code
);
7069 key
= Fcons (key
, Qnil
);
7070 if (w32_modifiers
& MOD_SHIFT
)
7071 key
= Fcons (Qshift
, key
);
7072 if (w32_modifiers
& MOD_CONTROL
)
7073 key
= Fcons (Qctrl
, key
);
7074 if (w32_modifiers
& MOD_ALT
)
7075 key
= Fcons (NILP (Vw32_alt_is_meta
) ? Qalt
: Qmeta
, key
);
7076 if (w32_modifiers
& MOD_WIN
)
7077 key
= Fcons (Qhyper
, key
);
7082 DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key
, Sw32_toggle_lock_key
, 1, 2, 0,
7083 "Toggle the state of the lock key KEY.\n\
7084 KEY can be `capslock', `kp-numlock', or `scroll'.\n\
7085 If the optional parameter NEW-STATE is a number, then the state of KEY\n\
7086 is set to off if the low bit of NEW-STATE is zero, otherwise on.")
7088 Lisp_Object key
, new_state
;
7093 if (EQ (key
, intern ("capslock")))
7094 vk_code
= VK_CAPITAL
;
7095 else if (EQ (key
, intern ("kp-numlock")))
7096 vk_code
= VK_NUMLOCK
;
7097 else if (EQ (key
, intern ("scroll")))
7098 vk_code
= VK_SCROLL
;
7102 if (!dwWindowsThreadId
)
7103 return make_number (w32_console_toggle_lock_key (vk_code
, new_state
));
7105 if (PostThreadMessage (dwWindowsThreadId
, WM_EMACS_TOGGLE_LOCK_KEY
,
7106 (WPARAM
) vk_code
, (LPARAM
) new_state
))
7109 GetMessage (&msg
, NULL
, WM_EMACS_DONE
, WM_EMACS_DONE
);
7110 return make_number (msg
.wParam
);
7117 /* This is zero if not using MS-Windows. */
7120 /* The section below is built by the lisp expression at the top of the file,
7121 just above where these variables are declared. */
7122 /*&&& init symbols here &&&*/
7123 Qauto_raise
= intern ("auto-raise");
7124 staticpro (&Qauto_raise
);
7125 Qauto_lower
= intern ("auto-lower");
7126 staticpro (&Qauto_lower
);
7127 Qbackground_color
= intern ("background-color");
7128 staticpro (&Qbackground_color
);
7129 Qbar
= intern ("bar");
7131 Qborder_color
= intern ("border-color");
7132 staticpro (&Qborder_color
);
7133 Qborder_width
= intern ("border-width");
7134 staticpro (&Qborder_width
);
7135 Qbox
= intern ("box");
7137 Qcursor_color
= intern ("cursor-color");
7138 staticpro (&Qcursor_color
);
7139 Qcursor_type
= intern ("cursor-type");
7140 staticpro (&Qcursor_type
);
7141 Qforeground_color
= intern ("foreground-color");
7142 staticpro (&Qforeground_color
);
7143 Qgeometry
= intern ("geometry");
7144 staticpro (&Qgeometry
);
7145 Qicon_left
= intern ("icon-left");
7146 staticpro (&Qicon_left
);
7147 Qicon_top
= intern ("icon-top");
7148 staticpro (&Qicon_top
);
7149 Qicon_type
= intern ("icon-type");
7150 staticpro (&Qicon_type
);
7151 Qicon_name
= intern ("icon-name");
7152 staticpro (&Qicon_name
);
7153 Qinternal_border_width
= intern ("internal-border-width");
7154 staticpro (&Qinternal_border_width
);
7155 Qleft
= intern ("left");
7157 Qright
= intern ("right");
7158 staticpro (&Qright
);
7159 Qmouse_color
= intern ("mouse-color");
7160 staticpro (&Qmouse_color
);
7161 Qnone
= intern ("none");
7163 Qparent_id
= intern ("parent-id");
7164 staticpro (&Qparent_id
);
7165 Qscroll_bar_width
= intern ("scroll-bar-width");
7166 staticpro (&Qscroll_bar_width
);
7167 Qsuppress_icon
= intern ("suppress-icon");
7168 staticpro (&Qsuppress_icon
);
7169 Qtop
= intern ("top");
7171 Qundefined_color
= intern ("undefined-color");
7172 staticpro (&Qundefined_color
);
7173 Qvertical_scroll_bars
= intern ("vertical-scroll-bars");
7174 staticpro (&Qvertical_scroll_bars
);
7175 Qvisibility
= intern ("visibility");
7176 staticpro (&Qvisibility
);
7177 Qwindow_id
= intern ("window-id");
7178 staticpro (&Qwindow_id
);
7179 Qx_frame_parameter
= intern ("x-frame-parameter");
7180 staticpro (&Qx_frame_parameter
);
7181 Qx_resource_name
= intern ("x-resource-name");
7182 staticpro (&Qx_resource_name
);
7183 Quser_position
= intern ("user-position");
7184 staticpro (&Quser_position
);
7185 Quser_size
= intern ("user-size");
7186 staticpro (&Quser_size
);
7187 Qdisplay
= intern ("display");
7188 staticpro (&Qdisplay
);
7189 /* This is the end of symbol initialization. */
7191 Qhyper
= intern ("hyper");
7192 staticpro (&Qhyper
);
7193 Qsuper
= intern ("super");
7194 staticpro (&Qsuper
);
7195 Qmeta
= intern ("meta");
7197 Qalt
= intern ("alt");
7199 Qctrl
= intern ("ctrl");
7201 Qcontrol
= intern ("control");
7202 staticpro (&Qcontrol
);
7203 Qshift
= intern ("shift");
7204 staticpro (&Qshift
);
7206 Qface_set_after_frame_default
= intern ("face-set-after-frame-default");
7207 staticpro (&Qface_set_after_frame_default
);
7209 Fput (Qundefined_color
, Qerror_conditions
,
7210 Fcons (Qundefined_color
, Fcons (Qerror
, Qnil
)));
7211 Fput (Qundefined_color
, Qerror_message
,
7212 build_string ("Undefined color"));
7214 staticpro (&w32_grabbed_keys
);
7215 w32_grabbed_keys
= Qnil
;
7217 DEFVAR_LISP ("w32-color-map", &Vw32_color_map
,
7218 "An array of color name mappings for windows.");
7219 Vw32_color_map
= Qnil
;
7221 DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system
,
7222 "Non-nil if alt key presses are passed on to Windows.\n\
7223 When non-nil, for example, alt pressed and released and then space will\n\
7224 open the System menu. When nil, Emacs silently swallows alt key events.");
7225 Vw32_pass_alt_to_system
= Qnil
;
7227 DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta
,
7228 "Non-nil if the alt key is to be considered the same as the meta key.\n\
7229 When nil, Emacs will translate the alt key to the Alt modifier, and not Meta.");
7230 Vw32_alt_is_meta
= Qt
;
7232 DEFVAR_INT ("w32-quit-key", &Vw32_quit_key
,
7233 "If non-zero, the virtual key code for an alternative quit key.");
7234 XSETINT (Vw32_quit_key
, 0);
7236 DEFVAR_LISP ("w32-pass-lwindow-to-system",
7237 &Vw32_pass_lwindow_to_system
,
7238 "Non-nil if the left \"Windows\" key is passed on to Windows.\n\
7239 When non-nil, the Start menu is opened by tapping the key.");
7240 Vw32_pass_lwindow_to_system
= Qt
;
7242 DEFVAR_LISP ("w32-pass-rwindow-to-system",
7243 &Vw32_pass_rwindow_to_system
,
7244 "Non-nil if the right \"Windows\" key is passed on to Windows.\n\
7245 When non-nil, the Start menu is opened by tapping the key.");
7246 Vw32_pass_rwindow_to_system
= Qt
;
7248 DEFVAR_INT ("w32-phantom-key-code",
7249 &Vw32_phantom_key_code
,
7250 "Virtual key code used to generate \"phantom\" key presses.\n\
7251 Value is a number between 0 and 255.\n\
7253 Phantom key presses are generated in order to stop the system from\n\
7254 acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or\n\
7255 `w32-pass-rwindow-to-system' is nil.");
7256 Vw32_phantom_key_code
= VK_SPACE
;
7258 DEFVAR_LISP ("w32-enable-num-lock",
7259 &Vw32_enable_num_lock
,
7260 "Non-nil if Num Lock should act normally.\n\
7261 Set to nil to see Num Lock as the key `kp-numlock'.");
7262 Vw32_enable_num_lock
= Qt
;
7264 DEFVAR_LISP ("w32-enable-caps-lock",
7265 &Vw32_enable_caps_lock
,
7266 "Non-nil if Caps Lock should act normally.\n\
7267 Set to nil to see Caps Lock as the key `capslock'.");
7268 Vw32_enable_caps_lock
= Qt
;
7270 DEFVAR_LISP ("w32-scroll-lock-modifier",
7271 &Vw32_scroll_lock_modifier
,
7272 "Modifier to use for the Scroll Lock on state.\n\
7273 The value can be hyper, super, meta, alt, control or shift for the\n\
7274 respective modifier, or nil to see Scroll Lock as the key `scroll'.\n\
7275 Any other value will cause the key to be ignored.");
7276 Vw32_scroll_lock_modifier
= Qt
;
7278 DEFVAR_LISP ("w32-lwindow-modifier",
7279 &Vw32_lwindow_modifier
,
7280 "Modifier to use for the left \"Windows\" key.\n\
7281 The value can be hyper, super, meta, alt, control or shift for the\n\
7282 respective modifier, or nil to appear as the key `lwindow'.\n\
7283 Any other value will cause the key to be ignored.");
7284 Vw32_lwindow_modifier
= Qnil
;
7286 DEFVAR_LISP ("w32-rwindow-modifier",
7287 &Vw32_rwindow_modifier
,
7288 "Modifier to use for the right \"Windows\" key.\n\
7289 The value can be hyper, super, meta, alt, control or shift for the\n\
7290 respective modifier, or nil to appear as the key `rwindow'.\n\
7291 Any other value will cause the key to be ignored.");
7292 Vw32_rwindow_modifier
= Qnil
;
7294 DEFVAR_LISP ("w32-apps-modifier",
7295 &Vw32_apps_modifier
,
7296 "Modifier to use for the \"Apps\" key.\n\
7297 The value can be hyper, super, meta, alt, control or shift for the\n\
7298 respective modifier, or nil to appear as the key `apps'.\n\
7299 Any other value will cause the key to be ignored.");
7300 Vw32_apps_modifier
= Qnil
;
7302 DEFVAR_LISP ("w32-enable-italics", &Vw32_enable_italics
,
7303 "Non-nil enables selection of artificially italicized fonts.");
7304 Vw32_enable_italics
= Qnil
;
7306 DEFVAR_LISP ("w32-enable-palette", &Vw32_enable_palette
,
7307 "Non-nil enables Windows palette management to map colors exactly.");
7308 Vw32_enable_palette
= Qt
;
7310 DEFVAR_INT ("w32-mouse-button-tolerance",
7311 &Vw32_mouse_button_tolerance
,
7312 "Analogue of double click interval for faking middle mouse events.\n\
7313 The value is the minimum time in milliseconds that must elapse between\n\
7314 left/right button down events before they are considered distinct events.\n\
7315 If both mouse buttons are depressed within this interval, a middle mouse\n\
7316 button down event is generated instead.");
7317 XSETINT (Vw32_mouse_button_tolerance
, GetDoubleClickTime () / 2);
7319 DEFVAR_INT ("w32-mouse-move-interval",
7320 &Vw32_mouse_move_interval
,
7321 "Minimum interval between mouse move events.\n\
7322 The value is the minimum time in milliseconds that must elapse between\n\
7323 successive mouse move (or scroll bar drag) events before they are\n\
7324 reported as lisp events.");
7325 XSETINT (Vw32_mouse_move_interval
, 0);
7327 init_x_parm_symbols ();
7329 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path
,
7330 "List of directories to search for bitmap files for w32.");
7331 Vx_bitmap_file_path
= decode_env_path ((char *) 0, "PATH");
7333 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape
,
7334 "The shape of the pointer when over text.\n\
7335 Changing the value does not affect existing frames\n\
7336 unless you set the mouse color.");
7337 Vx_pointer_shape
= Qnil
;
7339 DEFVAR_LISP ("x-resource-name", &Vx_resource_name
,
7340 "The name Emacs uses to look up resources; for internal use only.\n\
7341 `x-get-resource' uses this as the first component of the instance name\n\
7342 when requesting resource values.\n\
7343 Emacs initially sets `x-resource-name' to the name under which Emacs\n\
7344 was invoked, or to the value specified with the `-name' or `-rn'\n\
7345 switches, if present.");
7346 Vx_resource_name
= Qnil
;
7348 Vx_nontext_pointer_shape
= Qnil
;
7350 Vx_mode_pointer_shape
= Qnil
;
7352 DEFVAR_INT ("x-sensitive-text-pointer-shape",
7353 &Vx_sensitive_text_pointer_shape
,
7354 "The shape of the pointer when over mouse-sensitive text.\n\
7355 This variable takes effect when you create a new frame\n\
7356 or when you set the mouse color.");
7357 Vx_sensitive_text_pointer_shape
= Qnil
;
7359 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel
,
7360 "A string indicating the foreground color of the cursor box.");
7361 Vx_cursor_fore_pixel
= Qnil
;
7363 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager
,
7364 "Non-nil if no window manager is in use.\n\
7365 Emacs doesn't try to figure this out; this is always nil\n\
7366 unless you set it to something else.");
7367 /* We don't have any way to find this out, so set it to nil
7368 and maybe the user would like to set it to t. */
7369 Vx_no_window_manager
= Qnil
;
7371 DEFVAR_LISP ("x-pixel-size-width-font-regexp",
7372 &Vx_pixel_size_width_font_regexp
,
7373 "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
7375 Since Emacs gets width of a font matching with this regexp from\n\
7376 PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
7377 such a font. This is especially effective for such large fonts as\n\
7378 Chinese, Japanese, and Korean.");
7379 Vx_pixel_size_width_font_regexp
= Qnil
;
7381 DEFVAR_BOOL ("unibyte-display-via-language-environment",
7382 &unibyte_display_via_language_environment
,
7383 "*Non-nil means display unibyte text according to language environment.\n\
7384 Specifically this means that unibyte non-ASCII characters\n\
7385 are displayed by converting them to the equivalent multibyte characters\n\
7386 according to the current language environment. As a result, they are\n\
7387 displayed according to the current fontset.");
7388 unibyte_display_via_language_environment
= 0;
7390 DEFVAR_LISP ("w32-bdf-filename-alist",
7391 &Vw32_bdf_filename_alist
,
7392 "List of bdf fonts and their corresponding filenames.");
7393 Vw32_bdf_filename_alist
= Qnil
;
7395 defsubr (&Sx_get_resource
);
7396 defsubr (&Sx_list_fonts
);
7397 defsubr (&Sx_display_color_p
);
7398 defsubr (&Sx_display_grayscale_p
);
7399 defsubr (&Sx_color_defined_p
);
7400 defsubr (&Sx_color_values
);
7401 defsubr (&Sx_server_max_request_size
);
7402 defsubr (&Sx_server_vendor
);
7403 defsubr (&Sx_server_version
);
7404 defsubr (&Sx_display_pixel_width
);
7405 defsubr (&Sx_display_pixel_height
);
7406 defsubr (&Sx_display_mm_width
);
7407 defsubr (&Sx_display_mm_height
);
7408 defsubr (&Sx_display_screens
);
7409 defsubr (&Sx_display_planes
);
7410 defsubr (&Sx_display_color_cells
);
7411 defsubr (&Sx_display_visual_class
);
7412 defsubr (&Sx_display_backing_store
);
7413 defsubr (&Sx_display_save_under
);
7414 defsubr (&Sx_parse_geometry
);
7415 defsubr (&Sx_create_frame
);
7416 defsubr (&Sx_open_connection
);
7417 defsubr (&Sx_close_connection
);
7418 defsubr (&Sx_display_list
);
7419 defsubr (&Sx_synchronize
);
7421 /* W32 specific functions */
7423 defsubr (&Sw32_focus_frame
);
7424 defsubr (&Sw32_select_font
);
7425 defsubr (&Sw32_define_rgb_color
);
7426 defsubr (&Sw32_default_color_map
);
7427 defsubr (&Sw32_load_color_file
);
7428 defsubr (&Sw32_send_sys_command
);
7429 defsubr (&Sw32_register_hot_key
);
7430 defsubr (&Sw32_unregister_hot_key
);
7431 defsubr (&Sw32_registered_hot_keys
);
7432 defsubr (&Sw32_reconstruct_hot_key
);
7433 defsubr (&Sw32_toggle_lock_key
);
7434 defsubr (&Sw32_find_bdf_fonts
);
7436 /* Setting callback functions for fontset handler. */
7437 get_font_info_func
= w32_get_font_info
;
7438 list_fonts_func
= w32_list_fonts
;
7439 load_font_func
= w32_load_font
;
7440 find_ccl_program_func
= w32_find_ccl_program
;
7441 query_font_func
= w32_query_font
;
7442 set_frame_fontset_func
= x_set_font
;
7443 check_window_system_func
= check_w32
;
7452 button
= MessageBox (NULL
,
7453 "A fatal error has occurred!\n\n"
7454 "Select Abort to exit, Retry to debug, Ignore to continue",
7455 "Emacs Abort Dialog",
7456 MB_ICONEXCLAMATION
| MB_TASKMODAL
7457 | MB_SETFOREGROUND
| MB_ABORTRETRYIGNORE
);
7472 /* For convenience when debugging. */
7476 return GetLastError ();