backout 1,\b\b.4
[bpt/emacs.git] / src / w32fns.c
CommitLineData
ee78dc32
GV
1/* Functions for the Win32 window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
ee78dc32
GV
20
21/* Added by Kevin Gallo */
22
23#include <signal.h>
24#include <config.h>
25#include <stdio.h>
26
27#include "lisp.h"
28#include "w32term.h"
29#include "frame.h"
30#include "window.h"
31#include "buffer.h"
32#include "dispextern.h"
33#include "keyboard.h"
34#include "blockinput.h"
35#include "paths.h"
36#include "ntheap.h"
37#include "termhooks.h"
38
39#include <commdlg.h>
40
41extern void abort ();
42extern void free_frame_menubar ();
43extern struct scroll_bar *x_window_to_scroll_bar ();
44
45/* The colormap for converting color names to RGB values */
46Lisp_Object Vwin32_color_map;
47
7fb46567
GV
48/* Switch to control whether we inhibit requests for italicised fonts (which
49 are synthesized, look ugly, and are trashed by cursor movement under NT). */
50Lisp_Object Vwin32_enable_italics;
51
52/* Enable palette management. */
53Lisp_Object Vwin32_enable_palette;
54
ee78dc32
GV
55/* The name we're using in resource queries. */
56Lisp_Object Vx_resource_name;
57
58/* Non nil if no window manager is in use. */
59Lisp_Object Vx_no_window_manager;
60
61/* The background and shape of the mouse pointer, and shape when not
62 over text or in the modeline. */
63Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
64/* The shape when over mouse-sensitive text. */
65Lisp_Object Vx_sensitive_text_pointer_shape;
66
67/* Color of chars displayed in cursor box. */
68Lisp_Object Vx_cursor_fore_pixel;
69
70/* Search path for bitmap files. */
71Lisp_Object Vx_bitmap_file_path;
72
73/* Evaluate this expression to rebuild the section of syms_of_w32fns
74 that initializes and staticpros the symbols declared below. Note
75 that Emacs 18 has a bug that keeps C-x C-e from being able to
76 evaluate this expression.
77
78(progn
79 ;; Accumulate a list of the symbols we want to initialize from the
80 ;; declarations at the top of the file.
81 (goto-char (point-min))
82 (search-forward "/\*&&& symbols declared here &&&*\/\n")
83 (let (symbol-list)
84 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
85 (setq symbol-list
86 (cons (buffer-substring (match-beginning 1) (match-end 1))
87 symbol-list))
88 (forward-line 1))
89 (setq symbol-list (nreverse symbol-list))
90 ;; Delete the section of syms_of_... where we initialize the symbols.
91 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
92 (let ((start (point)))
93 (while (looking-at "^ Q")
94 (forward-line 2))
95 (kill-region start (point)))
96 ;; Write a new symbol initialization section.
97 (while symbol-list
98 (insert (format " %s = intern (\"" (car symbol-list)))
99 (let ((start (point)))
100 (insert (substring (car symbol-list) 1))
101 (subst-char-in-region start (point) ?_ ?-))
102 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
103 (setq symbol-list (cdr symbol-list)))))
104
105 */
106
107/*&&& symbols declared here &&&*/
108Lisp_Object Qauto_raise;
109Lisp_Object Qauto_lower;
110Lisp_Object Qbackground_color;
111Lisp_Object Qbar;
112Lisp_Object Qborder_color;
113Lisp_Object Qborder_width;
114Lisp_Object Qbox;
115Lisp_Object Qcursor_color;
116Lisp_Object Qcursor_type;
117Lisp_Object Qfont;
118Lisp_Object Qforeground_color;
119Lisp_Object Qgeometry;
120Lisp_Object Qicon_left;
121Lisp_Object Qicon_top;
122Lisp_Object Qicon_type;
123Lisp_Object Qicon_name;
124Lisp_Object Qinternal_border_width;
125Lisp_Object Qleft;
126Lisp_Object Qmouse_color;
127Lisp_Object Qnone;
128Lisp_Object Qparent_id;
129Lisp_Object Qscroll_bar_width;
130Lisp_Object Qsuppress_icon;
131Lisp_Object Qtop;
132Lisp_Object Qundefined_color;
133Lisp_Object Qvertical_scroll_bars;
134Lisp_Object Qvisibility;
135Lisp_Object Qwindow_id;
136Lisp_Object Qx_frame_parameter;
137Lisp_Object Qx_resource_name;
138Lisp_Object Quser_position;
139Lisp_Object Quser_size;
140Lisp_Object Qdisplay;
141
142/* The below are defined in frame.c. */
143extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth;
144extern Lisp_Object Qunsplittable, Qmenu_bar_lines;
145
146extern Lisp_Object Vwindow_system_version;
147
148extern Lisp_Object last_mouse_scroll_bar;
149extern int last_mouse_scroll_bar_pos;
150Time last_mouse_movement_time;
151
152\f
153/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
154 and checking validity for Win32. */
155
156FRAME_PTR
157check_x_frame (frame)
158 Lisp_Object frame;
159{
160 FRAME_PTR f;
161
162 if (NILP (frame))
163 f = selected_frame;
164 else
165 {
166 CHECK_LIVE_FRAME (frame, 0);
167 f = XFRAME (frame);
168 }
169 if (! FRAME_WIN32_P (f))
170 error ("non-win32 frame used");
171 return f;
172}
173
174/* Let the user specify an display with a frame.
175 nil stands for the selected frame--or, if that is not a win32 frame,
176 the first display on the list. */
177
178static struct win32_display_info *
179check_x_display_info (frame)
180 Lisp_Object frame;
181{
182 if (NILP (frame))
183 {
184 if (FRAME_WIN32_P (selected_frame))
185 return FRAME_WIN32_DISPLAY_INFO (selected_frame);
186 else
187 return &one_win32_display_info;
188 }
189 else if (STRINGP (frame))
190 return x_display_info_for_name (frame);
191 else
192 {
193 FRAME_PTR f;
194
195 CHECK_LIVE_FRAME (frame, 0);
196 f = XFRAME (frame);
197 if (! FRAME_WIN32_P (f))
198 error ("non-win32 frame used");
199 return FRAME_WIN32_DISPLAY_INFO (f);
200 }
201}
202\f
203/* Return the Emacs frame-object corresponding to an win32 window.
204 It could be the frame's main window or an icon window. */
205
206/* This function can be called during GC, so use GC_xxx type test macros. */
207
208struct frame *
209x_window_to_frame (dpyinfo, wdesc)
210 struct win32_display_info *dpyinfo;
211 HWND wdesc;
212{
213 Lisp_Object tail, frame;
214 struct frame *f;
215
216 for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr)
217 {
218 frame = XCONS (tail)->car;
219 if (!GC_FRAMEP (frame))
220 continue;
221 f = XFRAME (frame);
222 if (f->output_data.nothing == 1
223 || FRAME_WIN32_DISPLAY_INFO (f) != dpyinfo)
224 continue;
225 if (FRAME_WIN32_WINDOW (f) == wdesc)
226 return f;
227 }
228 return 0;
229}
230
231\f
232
233/* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
234 id, which is just an int that this section returns. Bitmaps are
235 reference counted so they can be shared among frames.
236
237 Bitmap indices are guaranteed to be > 0, so a negative number can
238 be used to indicate no bitmap.
239
240 If you use x_create_bitmap_from_data, then you must keep track of
241 the bitmaps yourself. That is, creating a bitmap from the same
242 data more than once will not be caught. */
243
244
245/* Functions to access the contents of a bitmap, given an id. */
246
247int
248x_bitmap_height (f, id)
249 FRAME_PTR f;
250 int id;
251{
252 return FRAME_WIN32_DISPLAY_INFO (f)->bitmaps[id - 1].height;
253}
254
255int
256x_bitmap_width (f, id)
257 FRAME_PTR f;
258 int id;
259{
260 return FRAME_WIN32_DISPLAY_INFO (f)->bitmaps[id - 1].width;
261}
262
263int
264x_bitmap_pixmap (f, id)
265 FRAME_PTR f;
266 int id;
267{
268 return (int) FRAME_WIN32_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
269}
270
271
272/* Allocate a new bitmap record. Returns index of new record. */
273
274static int
275x_allocate_bitmap_record (f)
276 FRAME_PTR f;
277{
278 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (f);
279 int i;
280
281 if (dpyinfo->bitmaps == NULL)
282 {
283 dpyinfo->bitmaps_size = 10;
284 dpyinfo->bitmaps
285 = (struct win32_bitmap_record *) xmalloc (dpyinfo->bitmaps_size * sizeof (struct win32_bitmap_record));
286 dpyinfo->bitmaps_last = 1;
287 return 1;
288 }
289
290 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
291 return ++dpyinfo->bitmaps_last;
292
293 for (i = 0; i < dpyinfo->bitmaps_size; ++i)
294 if (dpyinfo->bitmaps[i].refcount == 0)
295 return i + 1;
296
297 dpyinfo->bitmaps_size *= 2;
298 dpyinfo->bitmaps
299 = (struct win32_bitmap_record *) xrealloc (dpyinfo->bitmaps,
300 dpyinfo->bitmaps_size * sizeof (struct win32_bitmap_record));
301 return ++dpyinfo->bitmaps_last;
302}
303
304/* Add one reference to the reference count of the bitmap with id ID. */
305
306void
307x_reference_bitmap (f, id)
308 FRAME_PTR f;
309 int id;
310{
311 ++FRAME_WIN32_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
312}
313
314/* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
315
316int
317x_create_bitmap_from_data (f, bits, width, height)
318 struct frame *f;
319 char *bits;
320 unsigned int width, height;
321{
322 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (f);
323 Pixmap bitmap;
324 int id;
325
326 bitmap = CreateBitmap (width, height,
327 FRAME_WIN32_DISPLAY_INFO (XFRAME (frame))->n_planes,
328 FRAME_WIN32_DISPLAY_INFO (XFRAME (frame))->n_cbits,
329 bits);
330
331 if (! bitmap)
332 return -1;
333
334 id = x_allocate_bitmap_record (f);
335 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
336 dpyinfo->bitmaps[id - 1].file = NULL;
337 dpyinfo->bitmaps[id - 1].hinst = NULL;
338 dpyinfo->bitmaps[id - 1].refcount = 1;
339 dpyinfo->bitmaps[id - 1].depth = 1;
340 dpyinfo->bitmaps[id - 1].height = height;
341 dpyinfo->bitmaps[id - 1].width = width;
342
343 return id;
344}
345
346/* Create bitmap from file FILE for frame F. */
347
348int
349x_create_bitmap_from_file (f, file)
350 struct frame *f;
351 Lisp_Object file;
352{
353 return -1;
354#if 0
355 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (f);
356 unsigned int width, height;
357 Pixmap bitmap;
358 int xhot, yhot, result, id;
359 Lisp_Object found;
360 int fd;
361 char *filename;
362 HINSTANCE hinst;
363
364 /* Look for an existing bitmap with the same name. */
365 for (id = 0; id < dpyinfo->bitmaps_last; ++id)
366 {
367 if (dpyinfo->bitmaps[id].refcount
368 && dpyinfo->bitmaps[id].file
369 && !strcmp (dpyinfo->bitmaps[id].file, (char *) XSTRING (file)->data))
370 {
371 ++dpyinfo->bitmaps[id].refcount;
372 return id + 1;
373 }
374 }
375
376 /* Search bitmap-file-path for the file, if appropriate. */
377 fd = openp (Vx_bitmap_file_path, file, "", &found, 0);
378 if (fd < 0)
379 return -1;
380 close (fd);
381
382 filename = (char *) XSTRING (found)->data;
383
384 hinst = LoadLibraryEx (filename, NULL, LOAD_LIBRARY_AS_DATAFILE);
385
386 if (hinst == NULL)
387 return -1;
388
389
390 result = XReadBitmapFile (FRAME_WIN32_DISPLAY (f), FRAME_WIN32_WINDOW (f),
391 filename, &width, &height, &bitmap, &xhot, &yhot);
392 if (result != BitmapSuccess)
393 return -1;
394
395 id = x_allocate_bitmap_record (f);
396 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
397 dpyinfo->bitmaps[id - 1].refcount = 1;
398 dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (XSTRING (file)->size + 1);
399 dpyinfo->bitmaps[id - 1].depth = 1;
400 dpyinfo->bitmaps[id - 1].height = height;
401 dpyinfo->bitmaps[id - 1].width = width;
402 strcpy (dpyinfo->bitmaps[id - 1].file, XSTRING (file)->data);
403
404 return id;
405#endif
406}
407
408/* Remove reference to bitmap with id number ID. */
409
410int
411x_destroy_bitmap (f, id)
412 FRAME_PTR f;
413 int id;
414{
415 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (f);
416
417 if (id > 0)
418 {
419 --dpyinfo->bitmaps[id - 1].refcount;
420 if (dpyinfo->bitmaps[id - 1].refcount == 0)
421 {
422 BLOCK_INPUT;
423 DeleteObject (dpyinfo->bitmaps[id - 1].pixmap);
424 if (dpyinfo->bitmaps[id - 1].file)
425 {
426 free (dpyinfo->bitmaps[id - 1].file);
427 dpyinfo->bitmaps[id - 1].file = NULL;
428 }
429 UNBLOCK_INPUT;
430 }
431 }
432}
433
434/* Free all the bitmaps for the display specified by DPYINFO. */
435
436static void
437x_destroy_all_bitmaps (dpyinfo)
438 struct win32_display_info *dpyinfo;
439{
440 int i;
441 for (i = 0; i < dpyinfo->bitmaps_last; i++)
442 if (dpyinfo->bitmaps[i].refcount > 0)
443 {
444 DeleteObject (dpyinfo->bitmaps[i].pixmap);
445 if (dpyinfo->bitmaps[i].file)
446 free (dpyinfo->bitmaps[i].file);
447 }
448 dpyinfo->bitmaps_last = 0;
449}
450\f
451/* Connect the frame-parameter names for Win32 frames
452 to the ways of passing the parameter values to the window system.
453
454 The name of a parameter, as a Lisp symbol,
455 has an `x-frame-parameter' property which is an integer in Lisp
456 but can be interpreted as an `enum x_frame_parm' in C. */
457
458enum x_frame_parm
459{
460 X_PARM_FOREGROUND_COLOR,
461 X_PARM_BACKGROUND_COLOR,
462 X_PARM_MOUSE_COLOR,
463 X_PARM_CURSOR_COLOR,
464 X_PARM_BORDER_COLOR,
465 X_PARM_ICON_TYPE,
466 X_PARM_FONT,
467 X_PARM_BORDER_WIDTH,
468 X_PARM_INTERNAL_BORDER_WIDTH,
469 X_PARM_NAME,
470 X_PARM_AUTORAISE,
471 X_PARM_AUTOLOWER,
472 X_PARM_VERT_SCROLL_BAR,
473 X_PARM_VISIBILITY,
474 X_PARM_MENU_BAR_LINES
475};
476
477
478struct x_frame_parm_table
479{
480 char *name;
481 void (*setter)( /* struct frame *frame, Lisp_Object val, oldval */ );
482};
483
484void x_set_foreground_color ();
485void x_set_background_color ();
486void x_set_mouse_color ();
487void x_set_cursor_color ();
488void x_set_border_color ();
489void x_set_cursor_type ();
490void x_set_icon_type ();
491void x_set_icon_name ();
492void x_set_font ();
493void x_set_border_width ();
494void x_set_internal_border_width ();
495void x_explicitly_set_name ();
496void x_set_autoraise ();
497void x_set_autolower ();
498void x_set_vertical_scroll_bars ();
499void x_set_visibility ();
500void x_set_menu_bar_lines ();
501void x_set_scroll_bar_width ();
502void x_set_unsplittable ();
503
504static struct x_frame_parm_table x_frame_parms[] =
505{
506 "foreground-color", x_set_foreground_color,
507 "background-color", x_set_background_color,
508 "mouse-color", x_set_mouse_color,
509 "cursor-color", x_set_cursor_color,
510 "border-color", x_set_border_color,
511 "cursor-type", x_set_cursor_type,
512 "icon-type", x_set_icon_type,
513 "icon-name", x_set_icon_name,
514 "font", x_set_font,
515 "border-width", x_set_border_width,
516 "internal-border-width", x_set_internal_border_width,
517 "name", x_explicitly_set_name,
518 "auto-raise", x_set_autoraise,
519 "auto-lower", x_set_autolower,
520 "vertical-scroll-bars", x_set_vertical_scroll_bars,
521 "visibility", x_set_visibility,
522 "menu-bar-lines", x_set_menu_bar_lines,
523 "scroll-bar-width", x_set_scroll_bar_width,
524 "unsplittable", x_set_unsplittable,
525};
526
527/* Attach the `x-frame-parameter' properties to
528 the Lisp symbol names of parameters relevant to Win32. */
529
530init_x_parm_symbols ()
531{
532 int i;
533
534 for (i = 0; i < sizeof (x_frame_parms) / sizeof (x_frame_parms[0]); i++)
535 Fput (intern (x_frame_parms[i].name), Qx_frame_parameter,
536 make_number (i));
537}
538\f
539/* Change the parameters of FRAME as specified by ALIST.
540 If a parameter is not specially recognized, do nothing;
541 otherwise call the `x_set_...' function for that parameter. */
542
543void
544x_set_frame_parameters (f, alist)
545 FRAME_PTR f;
546 Lisp_Object alist;
547{
548 Lisp_Object tail;
549
550 /* If both of these parameters are present, it's more efficient to
551 set them both at once. So we wait until we've looked at the
552 entire list before we set them. */
553 Lisp_Object width, height;
554
555 /* Same here. */
556 Lisp_Object left, top;
557
558 /* Same with these. */
559 Lisp_Object icon_left, icon_top;
560
561 /* Record in these vectors all the parms specified. */
562 Lisp_Object *parms;
563 Lisp_Object *values;
564 int i;
565 int left_no_change = 0, top_no_change = 0;
566 int icon_left_no_change = 0, icon_top_no_change = 0;
567
568 i = 0;
569 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
570 i++;
571
572 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
573 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
574
575 /* Extract parm names and values into those vectors. */
576
577 i = 0;
578 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
579 {
580 Lisp_Object elt, prop, val;
581
582 elt = Fcar (tail);
583 parms[i] = Fcar (elt);
584 values[i] = Fcdr (elt);
585 i++;
586 }
587
588 width = height = top = left = Qunbound;
589 icon_left = icon_top = Qunbound;
590
591 /* Now process them in reverse of specified order. */
592 for (i--; i >= 0; i--)
593 {
594 Lisp_Object prop, val;
595
596 prop = parms[i];
597 val = values[i];
598
599 if (EQ (prop, Qwidth))
600 width = val;
601 else if (EQ (prop, Qheight))
602 height = val;
603 else if (EQ (prop, Qtop))
604 top = val;
605 else if (EQ (prop, Qleft))
606 left = val;
607 else if (EQ (prop, Qicon_top))
608 icon_top = val;
609 else if (EQ (prop, Qicon_left))
610 icon_left = val;
611 else
612 {
613 register Lisp_Object param_index, old_value;
614
615 param_index = Fget (prop, Qx_frame_parameter);
616 old_value = get_frame_param (f, prop);
617 store_frame_param (f, prop, val);
618 if (NATNUMP (param_index)
619 && (XFASTINT (param_index)
620 < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
7fb46567 621 (*x_frame_parms[XINT (param_index)].setter) (f, val, old_value);
ee78dc32
GV
622 }
623 }
624
625 /* Don't die if just one of these was set. */
626 if (EQ (left, Qunbound))
627 {
628 left_no_change = 1;
629 if (f->output_data.win32->left_pos < 0)
630 left = Fcons (Qplus, Fcons (make_number (f->output_data.win32->left_pos), Qnil));
631 else
632 XSETINT (left, f->output_data.win32->left_pos);
633 }
634 if (EQ (top, Qunbound))
635 {
636 top_no_change = 1;
637 if (f->output_data.win32->top_pos < 0)
638 top = Fcons (Qplus, Fcons (make_number (f->output_data.win32->top_pos), Qnil));
639 else
640 XSETINT (top, f->output_data.win32->top_pos);
641 }
642
643 /* If one of the icon positions was not set, preserve or default it. */
644 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
645 {
646 icon_left_no_change = 1;
647 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
648 if (NILP (icon_left))
649 XSETINT (icon_left, 0);
650 }
651 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
652 {
653 icon_top_no_change = 1;
654 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
655 if (NILP (icon_top))
656 XSETINT (icon_top, 0);
657 }
658
659 /* Don't die if just one of these was set. */
660 if (EQ (width, Qunbound))
661 XSETINT (width, FRAME_WIDTH (f));
662 if (EQ (height, Qunbound))
663 XSETINT (height, FRAME_HEIGHT (f));
664
665 /* Don't set these parameters unless they've been explicitly
666 specified. The window might be mapped or resized while we're in
667 this function, and we don't want to override that unless the lisp
668 code has asked for it.
669
670 Don't set these parameters unless they actually differ from the
671 window's current parameters; the window may not actually exist
672 yet. */
673 {
674 Lisp_Object frame;
675
676 check_frame_size (f, &height, &width);
677
678 XSETFRAME (frame, f);
679
680 if ((NUMBERP (width) && XINT (width) != FRAME_WIDTH (f))
681 || (NUMBERP (height) && XINT (height) != FRAME_HEIGHT (f)))
682 Fset_frame_size (frame, width, height);
683
684 if ((!NILP (left) || !NILP (top))
685 && ! (left_no_change && top_no_change)
686 && ! (NUMBERP (left) && XINT (left) == f->output_data.win32->left_pos
687 && NUMBERP (top) && XINT (top) == f->output_data.win32->top_pos))
688 {
689 int leftpos = 0;
690 int toppos = 0;
691
692 /* Record the signs. */
693 f->output_data.win32->size_hint_flags &= ~ (XNegative | YNegative);
694 if (EQ (left, Qminus))
695 f->output_data.win32->size_hint_flags |= XNegative;
696 else if (INTEGERP (left))
697 {
698 leftpos = XINT (left);
699 if (leftpos < 0)
700 f->output_data.win32->size_hint_flags |= XNegative;
701 }
702 else if (CONSP (left) && EQ (XCONS (left)->car, Qminus)
703 && CONSP (XCONS (left)->cdr)
704 && INTEGERP (XCONS (XCONS (left)->cdr)->car))
705 {
706 leftpos = - XINT (XCONS (XCONS (left)->cdr)->car);
707 f->output_data.win32->size_hint_flags |= XNegative;
708 }
709 else if (CONSP (left) && EQ (XCONS (left)->car, Qplus)
710 && CONSP (XCONS (left)->cdr)
711 && INTEGERP (XCONS (XCONS (left)->cdr)->car))
712 {
713 leftpos = XINT (XCONS (XCONS (left)->cdr)->car);
714 }
715
716 if (EQ (top, Qminus))
717 f->output_data.win32->size_hint_flags |= YNegative;
718 else if (INTEGERP (top))
719 {
720 toppos = XINT (top);
721 if (toppos < 0)
722 f->output_data.win32->size_hint_flags |= YNegative;
723 }
724 else if (CONSP (top) && EQ (XCONS (top)->car, Qminus)
725 && CONSP (XCONS (top)->cdr)
726 && INTEGERP (XCONS (XCONS (top)->cdr)->car))
727 {
728 toppos = - XINT (XCONS (XCONS (top)->cdr)->car);
729 f->output_data.win32->size_hint_flags |= YNegative;
730 }
731 else if (CONSP (top) && EQ (XCONS (top)->car, Qplus)
732 && CONSP (XCONS (top)->cdr)
733 && INTEGERP (XCONS (XCONS (top)->cdr)->car))
734 {
735 toppos = XINT (XCONS (XCONS (top)->cdr)->car);
736 }
737
738
739 /* Store the numeric value of the position. */
740 f->output_data.win32->top_pos = toppos;
741 f->output_data.win32->left_pos = leftpos;
742
743 f->output_data.win32->win_gravity = NorthWestGravity;
744
745 /* Actually set that position, and convert to absolute. */
746 x_set_offset (f, leftpos, toppos, -1);
747 }
748
749 if ((!NILP (icon_left) || !NILP (icon_top))
750 && ! (icon_left_no_change && icon_top_no_change))
751 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
752 }
753}
754
755/* Store the screen positions of frame F into XPTR and YPTR.
756 These are the positions of the containing window manager window,
757 not Emacs's own window. */
758
759void
760x_real_positions (f, xptr, yptr)
761 FRAME_PTR f;
762 int *xptr, *yptr;
763{
764 POINT pt;
7fb46567 765 RECT rect;
ee78dc32 766
7fb46567
GV
767 GetClientRect (FRAME_WIN32_WINDOW (f), &rect);
768 AdjustWindowRect (&rect, f->output_data.win32->dwStyle,
769 FRAME_EXTERNAL_MENU_BAR (f));
ee78dc32 770
7fb46567
GV
771 pt.x = rect.left;
772 pt.y = rect.top;
ee78dc32 773
7fb46567 774 ClientToScreen (FRAME_WIN32_WINDOW (f), &pt);
ee78dc32
GV
775
776 *xptr = pt.x;
777 *yptr = pt.y;
778}
779
780/* Insert a description of internally-recorded parameters of frame X
781 into the parameter alist *ALISTPTR that is to be given to the user.
782 Only parameters that are specific to Win32
783 and whose values are not correctly recorded in the frame's
784 param_alist need to be considered here. */
785
786x_report_frame_params (f, alistptr)
787 struct frame *f;
788 Lisp_Object *alistptr;
789{
790 char buf[16];
791 Lisp_Object tem;
792
793 /* Represent negative positions (off the top or left screen edge)
794 in a way that Fmodify_frame_parameters will understand correctly. */
795 XSETINT (tem, f->output_data.win32->left_pos);
796 if (f->output_data.win32->left_pos >= 0)
797 store_in_alist (alistptr, Qleft, tem);
798 else
799 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
800
801 XSETINT (tem, f->output_data.win32->top_pos);
802 if (f->output_data.win32->top_pos >= 0)
803 store_in_alist (alistptr, Qtop, tem);
804 else
805 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
806
807 store_in_alist (alistptr, Qborder_width,
808 make_number (f->output_data.win32->border_width));
809 store_in_alist (alistptr, Qinternal_border_width,
810 make_number (f->output_data.win32->internal_border_width));
811 sprintf (buf, "%ld", (long) FRAME_WIN32_WINDOW (f));
812 store_in_alist (alistptr, Qwindow_id,
813 build_string (buf));
814 store_in_alist (alistptr, Qicon_name, f->icon_name);
815 FRAME_SAMPLE_VISIBILITY (f);
816 store_in_alist (alistptr, Qvisibility,
817 (FRAME_VISIBLE_P (f) ? Qt
818 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
819 store_in_alist (alistptr, Qdisplay,
820 XCONS (FRAME_WIN32_DISPLAY_INFO (f)->name_list_element)->car);
821}
822\f
823
7fb46567
GV
824DEFUN ("win32-define-rgb-color", Fwin32_define_rgb_color, Swin32_define_rgb_color, 4, 4, 0,
825 "Convert RGB numbers to a windows color reference and associate with\n\
826NAME (a string). This adds or updates a named color to win32-color-map,\n\
827making it available for use. The original entry's RGB ref is returned,\n\
828or nil if the entry is new.")
829 (red, green, blue, name)
830 Lisp_Object red, green, blue, name;
ee78dc32
GV
831{
832 Lisp_Object rgb;
7fb46567
GV
833 Lisp_Object oldrgb = Qnil;
834 Lisp_Object entry;
ee78dc32
GV
835
836 CHECK_NUMBER (red, 0);
837 CHECK_NUMBER (green, 0);
838 CHECK_NUMBER (blue, 0);
7fb46567 839 CHECK_STRING (name, 0);
ee78dc32 840
7fb46567
GV
841 XSET (rgb, Lisp_Int, RGB (XUINT (red), XUINT (green), XUINT (blue)));
842
843 BLOCK_INPUT;
844
845 /* replace existing entry in win32-color-map or add new entry. */
846 entry = Fassoc (name, Vwin32_color_map);
847 if (NILP (entry))
848 {
849 entry = Fcons (name, rgb);
850 Vwin32_color_map = Fcons (entry, Vwin32_color_map);
851 }
852 else
853 {
854 oldrgb = Fcdr (entry);
855 Fsetcdr (entry, rgb);
856 }
857
858 UNBLOCK_INPUT;
ee78dc32 859
7fb46567 860 return (oldrgb);
ee78dc32
GV
861}
862
7fb46567
GV
863DEFUN ("win32-load-color-file", Fwin32_load_color_file, Swin32_load_color_file, 1, 1, 0,
864 "Create an alist of color entries from an external file (ie. rgb.txt).\n\
865Assign this value to win32-color-map to replace the existing color map.\n\
866The file should define one named RGB color per line like so:\
867 R G B name\n\
868where R,G,B are numbers between 0 and 255 and name is an arbitrary string.")
869 (filename)
870 Lisp_Object filename;
871{
872 FILE *fp;
873 Lisp_Object cmap = Qnil;
874 Lisp_Object abspath;
875
876 CHECK_STRING (filename, 0);
877 abspath = Fexpand_file_name (filename, Qnil);
878
879 fp = fopen (XSTRING (filename)->data, "rt");
880 if (fp)
881 {
882 char buf[512];
883 int red, green, blue;
884 int num;
885
886 BLOCK_INPUT;
887
888 while (fgets (buf, sizeof (buf), fp) != NULL)
889 {
890 if (sscanf (buf, "%u %u %u %n]", &red, &green, &blue, &num) == 3)
891 {
892 char *name = buf + num;
893 num = strlen (name) - 1;
894 if (name[num] == '\n')
895 name[num] = 0;
896 cmap = Fcons (Fcons (build_string (name),
897 make_number (RGB (red, green, blue))),
898 cmap);
899 }
900 }
901 fclose (fp);
902
903 UNBLOCK_INPUT;
904 }
905
906 return cmap;
907}
ee78dc32 908
ee78dc32
GV
909/* The default colors for the win32 color map */
910typedef struct colormap_t
911{
912 char *name;
913 COLORREF colorref;
914} colormap_t;
915
916colormap_t win32_color_map[] =
917{
918 {"snow" , RGB (255,250,250)},
919 {"ghost white" , RGB (248,248,255)},
920 {"GhostWhite" , RGB (248,248,255)},
921 {"white smoke" , RGB (245,245,245)},
922 {"WhiteSmoke" , RGB (245,245,245)},
923 {"gainsboro" , RGB (220,220,220)},
924 {"floral white" , RGB (255,250,240)},
925 {"FloralWhite" , RGB (255,250,240)},
926 {"old lace" , RGB (253,245,230)},
927 {"OldLace" , RGB (253,245,230)},
928 {"linen" , RGB (250,240,230)},
929 {"antique white" , RGB (250,235,215)},
930 {"AntiqueWhite" , RGB (250,235,215)},
931 {"papaya whip" , RGB (255,239,213)},
932 {"PapayaWhip" , RGB (255,239,213)},
933 {"blanched almond" , RGB (255,235,205)},
934 {"BlanchedAlmond" , RGB (255,235,205)},
935 {"bisque" , RGB (255,228,196)},
936 {"peach puff" , RGB (255,218,185)},
937 {"PeachPuff" , RGB (255,218,185)},
938 {"navajo white" , RGB (255,222,173)},
939 {"NavajoWhite" , RGB (255,222,173)},
940 {"moccasin" , RGB (255,228,181)},
941 {"cornsilk" , RGB (255,248,220)},
942 {"ivory" , RGB (255,255,240)},
943 {"lemon chiffon" , RGB (255,250,205)},
944 {"LemonChiffon" , RGB (255,250,205)},
945 {"seashell" , RGB (255,245,238)},
946 {"honeydew" , RGB (240,255,240)},
947 {"mint cream" , RGB (245,255,250)},
948 {"MintCream" , RGB (245,255,250)},
949 {"azure" , RGB (240,255,255)},
950 {"alice blue" , RGB (240,248,255)},
951 {"AliceBlue" , RGB (240,248,255)},
952 {"lavender" , RGB (230,230,250)},
953 {"lavender blush" , RGB (255,240,245)},
954 {"LavenderBlush" , RGB (255,240,245)},
955 {"misty rose" , RGB (255,228,225)},
956 {"MistyRose" , RGB (255,228,225)},
957 {"white" , RGB (255,255,255)},
958 {"black" , RGB ( 0, 0, 0)},
959 {"dark slate gray" , RGB ( 47, 79, 79)},
960 {"DarkSlateGray" , RGB ( 47, 79, 79)},
961 {"dark slate grey" , RGB ( 47, 79, 79)},
962 {"DarkSlateGrey" , RGB ( 47, 79, 79)},
963 {"dim gray" , RGB (105,105,105)},
964 {"DimGray" , RGB (105,105,105)},
965 {"dim grey" , RGB (105,105,105)},
966 {"DimGrey" , RGB (105,105,105)},
967 {"slate gray" , RGB (112,128,144)},
968 {"SlateGray" , RGB (112,128,144)},
969 {"slate grey" , RGB (112,128,144)},
970 {"SlateGrey" , RGB (112,128,144)},
971 {"light slate gray" , RGB (119,136,153)},
972 {"LightSlateGray" , RGB (119,136,153)},
973 {"light slate grey" , RGB (119,136,153)},
974 {"LightSlateGrey" , RGB (119,136,153)},
975 {"gray" , RGB (190,190,190)},
976 {"grey" , RGB (190,190,190)},
977 {"light grey" , RGB (211,211,211)},
978 {"LightGrey" , RGB (211,211,211)},
979 {"light gray" , RGB (211,211,211)},
980 {"LightGray" , RGB (211,211,211)},
981 {"midnight blue" , RGB ( 25, 25,112)},
982 {"MidnightBlue" , RGB ( 25, 25,112)},
983 {"navy" , RGB ( 0, 0,128)},
984 {"navy blue" , RGB ( 0, 0,128)},
985 {"NavyBlue" , RGB ( 0, 0,128)},
986 {"cornflower blue" , RGB (100,149,237)},
987 {"CornflowerBlue" , RGB (100,149,237)},
988 {"dark slate blue" , RGB ( 72, 61,139)},
989 {"DarkSlateBlue" , RGB ( 72, 61,139)},
990 {"slate blue" , RGB (106, 90,205)},
991 {"SlateBlue" , RGB (106, 90,205)},
992 {"medium slate blue" , RGB (123,104,238)},
993 {"MediumSlateBlue" , RGB (123,104,238)},
994 {"light slate blue" , RGB (132,112,255)},
995 {"LightSlateBlue" , RGB (132,112,255)},
996 {"medium blue" , RGB ( 0, 0,205)},
997 {"MediumBlue" , RGB ( 0, 0,205)},
998 {"royal blue" , RGB ( 65,105,225)},
999 {"RoyalBlue" , RGB ( 65,105,225)},
1000 {"blue" , RGB ( 0, 0,255)},
1001 {"dodger blue" , RGB ( 30,144,255)},
1002 {"DodgerBlue" , RGB ( 30,144,255)},
1003 {"deep sky blue" , RGB ( 0,191,255)},
1004 {"DeepSkyBlue" , RGB ( 0,191,255)},
1005 {"sky blue" , RGB (135,206,235)},
1006 {"SkyBlue" , RGB (135,206,235)},
1007 {"light sky blue" , RGB (135,206,250)},
1008 {"LightSkyBlue" , RGB (135,206,250)},
1009 {"steel blue" , RGB ( 70,130,180)},
1010 {"SteelBlue" , RGB ( 70,130,180)},
1011 {"light steel blue" , RGB (176,196,222)},
1012 {"LightSteelBlue" , RGB (176,196,222)},
1013 {"light blue" , RGB (173,216,230)},
1014 {"LightBlue" , RGB (173,216,230)},
1015 {"powder blue" , RGB (176,224,230)},
1016 {"PowderBlue" , RGB (176,224,230)},
1017 {"pale turquoise" , RGB (175,238,238)},
1018 {"PaleTurquoise" , RGB (175,238,238)},
1019 {"dark turquoise" , RGB ( 0,206,209)},
1020 {"DarkTurquoise" , RGB ( 0,206,209)},
1021 {"medium turquoise" , RGB ( 72,209,204)},
1022 {"MediumTurquoise" , RGB ( 72,209,204)},
1023 {"turquoise" , RGB ( 64,224,208)},
1024 {"cyan" , RGB ( 0,255,255)},
1025 {"light cyan" , RGB (224,255,255)},
1026 {"LightCyan" , RGB (224,255,255)},
1027 {"cadet blue" , RGB ( 95,158,160)},
1028 {"CadetBlue" , RGB ( 95,158,160)},
1029 {"medium aquamarine" , RGB (102,205,170)},
1030 {"MediumAquamarine" , RGB (102,205,170)},
1031 {"aquamarine" , RGB (127,255,212)},
1032 {"dark green" , RGB ( 0,100, 0)},
1033 {"DarkGreen" , RGB ( 0,100, 0)},
1034 {"dark olive green" , RGB ( 85,107, 47)},
1035 {"DarkOliveGreen" , RGB ( 85,107, 47)},
1036 {"dark sea green" , RGB (143,188,143)},
1037 {"DarkSeaGreen" , RGB (143,188,143)},
1038 {"sea green" , RGB ( 46,139, 87)},
1039 {"SeaGreen" , RGB ( 46,139, 87)},
1040 {"medium sea green" , RGB ( 60,179,113)},
1041 {"MediumSeaGreen" , RGB ( 60,179,113)},
1042 {"light sea green" , RGB ( 32,178,170)},
1043 {"LightSeaGreen" , RGB ( 32,178,170)},
1044 {"pale green" , RGB (152,251,152)},
1045 {"PaleGreen" , RGB (152,251,152)},
1046 {"spring green" , RGB ( 0,255,127)},
1047 {"SpringGreen" , RGB ( 0,255,127)},
1048 {"lawn green" , RGB (124,252, 0)},
1049 {"LawnGreen" , RGB (124,252, 0)},
1050 {"green" , RGB ( 0,255, 0)},
1051 {"chartreuse" , RGB (127,255, 0)},
1052 {"medium spring green" , RGB ( 0,250,154)},
1053 {"MediumSpringGreen" , RGB ( 0,250,154)},
1054 {"green yellow" , RGB (173,255, 47)},
1055 {"GreenYellow" , RGB (173,255, 47)},
1056 {"lime green" , RGB ( 50,205, 50)},
1057 {"LimeGreen" , RGB ( 50,205, 50)},
1058 {"yellow green" , RGB (154,205, 50)},
1059 {"YellowGreen" , RGB (154,205, 50)},
1060 {"forest green" , RGB ( 34,139, 34)},
1061 {"ForestGreen" , RGB ( 34,139, 34)},
1062 {"olive drab" , RGB (107,142, 35)},
1063 {"OliveDrab" , RGB (107,142, 35)},
1064 {"dark khaki" , RGB (189,183,107)},
1065 {"DarkKhaki" , RGB (189,183,107)},
1066 {"khaki" , RGB (240,230,140)},
1067 {"pale goldenrod" , RGB (238,232,170)},
1068 {"PaleGoldenrod" , RGB (238,232,170)},
1069 {"light goldenrod yellow" , RGB (250,250,210)},
1070 {"LightGoldenrodYellow" , RGB (250,250,210)},
1071 {"light yellow" , RGB (255,255,224)},
1072 {"LightYellow" , RGB (255,255,224)},
1073 {"yellow" , RGB (255,255, 0)},
1074 {"gold" , RGB (255,215, 0)},
1075 {"light goldenrod" , RGB (238,221,130)},
1076 {"LightGoldenrod" , RGB (238,221,130)},
1077 {"goldenrod" , RGB (218,165, 32)},
1078 {"dark goldenrod" , RGB (184,134, 11)},
1079 {"DarkGoldenrod" , RGB (184,134, 11)},
1080 {"rosy brown" , RGB (188,143,143)},
1081 {"RosyBrown" , RGB (188,143,143)},
1082 {"indian red" , RGB (205, 92, 92)},
1083 {"IndianRed" , RGB (205, 92, 92)},
1084 {"saddle brown" , RGB (139, 69, 19)},
1085 {"SaddleBrown" , RGB (139, 69, 19)},
1086 {"sienna" , RGB (160, 82, 45)},
1087 {"peru" , RGB (205,133, 63)},
1088 {"burlywood" , RGB (222,184,135)},
1089 {"beige" , RGB (245,245,220)},
1090 {"wheat" , RGB (245,222,179)},
1091 {"sandy brown" , RGB (244,164, 96)},
1092 {"SandyBrown" , RGB (244,164, 96)},
1093 {"tan" , RGB (210,180,140)},
1094 {"chocolate" , RGB (210,105, 30)},
1095 {"firebrick" , RGB (178,34, 34)},
1096 {"brown" , RGB (165,42, 42)},
1097 {"dark salmon" , RGB (233,150,122)},
1098 {"DarkSalmon" , RGB (233,150,122)},
1099 {"salmon" , RGB (250,128,114)},
1100 {"light salmon" , RGB (255,160,122)},
1101 {"LightSalmon" , RGB (255,160,122)},
1102 {"orange" , RGB (255,165, 0)},
1103 {"dark orange" , RGB (255,140, 0)},
1104 {"DarkOrange" , RGB (255,140, 0)},
1105 {"coral" , RGB (255,127, 80)},
1106 {"light coral" , RGB (240,128,128)},
1107 {"LightCoral" , RGB (240,128,128)},
1108 {"tomato" , RGB (255, 99, 71)},
1109 {"orange red" , RGB (255, 69, 0)},
1110 {"OrangeRed" , RGB (255, 69, 0)},
1111 {"red" , RGB (255, 0, 0)},
1112 {"hot pink" , RGB (255,105,180)},
1113 {"HotPink" , RGB (255,105,180)},
1114 {"deep pink" , RGB (255, 20,147)},
1115 {"DeepPink" , RGB (255, 20,147)},
1116 {"pink" , RGB (255,192,203)},
1117 {"light pink" , RGB (255,182,193)},
1118 {"LightPink" , RGB (255,182,193)},
1119 {"pale violet red" , RGB (219,112,147)},
1120 {"PaleVioletRed" , RGB (219,112,147)},
1121 {"maroon" , RGB (176, 48, 96)},
1122 {"medium violet red" , RGB (199, 21,133)},
1123 {"MediumVioletRed" , RGB (199, 21,133)},
1124 {"violet red" , RGB (208, 32,144)},
1125 {"VioletRed" , RGB (208, 32,144)},
1126 {"magenta" , RGB (255, 0,255)},
1127 {"violet" , RGB (238,130,238)},
1128 {"plum" , RGB (221,160,221)},
1129 {"orchid" , RGB (218,112,214)},
1130 {"medium orchid" , RGB (186, 85,211)},
1131 {"MediumOrchid" , RGB (186, 85,211)},
1132 {"dark orchid" , RGB (153, 50,204)},
1133 {"DarkOrchid" , RGB (153, 50,204)},
1134 {"dark violet" , RGB (148, 0,211)},
1135 {"DarkViolet" , RGB (148, 0,211)},
1136 {"blue violet" , RGB (138, 43,226)},
1137 {"BlueViolet" , RGB (138, 43,226)},
1138 {"purple" , RGB (160, 32,240)},
1139 {"medium purple" , RGB (147,112,219)},
1140 {"MediumPurple" , RGB (147,112,219)},
1141 {"thistle" , RGB (216,191,216)},
1142 {"gray0" , RGB ( 0, 0, 0)},
1143 {"grey0" , RGB ( 0, 0, 0)},
1144 {"dark grey" , RGB (169,169,169)},
1145 {"DarkGrey" , RGB (169,169,169)},
1146 {"dark gray" , RGB (169,169,169)},
1147 {"DarkGray" , RGB (169,169,169)},
1148 {"dark blue" , RGB ( 0, 0,139)},
1149 {"DarkBlue" , RGB ( 0, 0,139)},
1150 {"dark cyan" , RGB ( 0,139,139)},
1151 {"DarkCyan" , RGB ( 0,139,139)},
1152 {"dark magenta" , RGB (139, 0,139)},
1153 {"DarkMagenta" , RGB (139, 0,139)},
1154 {"dark red" , RGB (139, 0, 0)},
1155 {"DarkRed" , RGB (139, 0, 0)},
1156 {"light green" , RGB (144,238,144)},
1157 {"LightGreen" , RGB (144,238,144)},
1158};
1159
1160DEFUN ("win32-default-color-map", Fwin32_default_color_map, Swin32_default_color_map,
1161 0, 0, 0, "Return the default color map.")
1162 ()
1163{
1164 int i;
1165 colormap_t *pc = win32_color_map;
1166 Lisp_Object cmap;
1167
1168 BLOCK_INPUT;
1169
1170 cmap = Qnil;
1171
1172 for (i = 0; i < sizeof (win32_color_map) / sizeof (win32_color_map[0]);
1173 pc++, i++)
1174 cmap = Fcons (Fcons (build_string (pc->name),
1175 make_number (pc->colorref)),
1176 cmap);
1177
1178 UNBLOCK_INPUT;
1179
1180 return (cmap);
1181}
ee78dc32
GV
1182
1183Lisp_Object
1184win32_to_x_color (rgb)
1185 Lisp_Object rgb;
1186{
1187 Lisp_Object color;
1188
1189 CHECK_NUMBER (rgb, 0);
1190
1191 BLOCK_INPUT;
1192
1193 color = Frassq (rgb, Vwin32_color_map);
1194
1195 UNBLOCK_INPUT;
1196
1197 if (!NILP (color))
1198 return (Fcar (color));
1199 else
1200 return Qnil;
1201}
1202
1203COLORREF
1204x_to_win32_color (colorname)
1205 char * colorname;
1206{
1207 register Lisp_Object tail, ret = Qnil;
1208
1209 BLOCK_INPUT;
1210
1211 for (tail = Vwin32_color_map; !NILP (tail); tail = Fcdr (tail))
1212 {
1213 register Lisp_Object elt, tem;
1214
1215 elt = Fcar (tail);
1216 if (!CONSP (elt)) continue;
1217
1218 tem = Fcar (elt);
1219
1220 if (lstrcmpi (XSTRING (tem)->data, colorname) == 0)
1221 {
1222 ret = XUINT(Fcdr (elt));
1223 break;
1224 }
1225
1226 QUIT;
1227 }
1228
1229 UNBLOCK_INPUT;
1230
1231 return ret;
1232}
1233
7fb46567
GV
1234
1235void
1236win32_regenerate_palette (FRAME_PTR f)
1237{
1238 struct win32_palette_entry * pList;
1239 LOGPALETTE * p_palette;
1240 HPALETTE h_new_palette;
1241 int i;
1242
1243 /* don't bother trying to create palette if not supported */
1244 if (! FRAME_WIN32_DISPLAY_INFO (f)->has_palette)
1245 return;
1246
1247 p_palette = (LOGPALETTE *)
1248 xmalloc (sizeof (LOGPALETTE) +
1249 FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use * sizeof (PALETTEENTRY));
1250 p_palette->palVersion = 0x300;
1251 p_palette->palNumEntries = FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use;
1252
1253 pList = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1254 for (i = 0; i < FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use;
1255 i++, pList = pList->next)
1256 p_palette->palPalEntry[i] = pList->entry;
1257
1258 h_new_palette = CreatePalette ((LPLOGPALETTE) p_palette);
1259
1260 enter_crit (CRIT_GDI);
1261
1262 if (FRAME_WIN32_DISPLAY_INFO (f)->h_palette)
1263 DeleteObject (FRAME_WIN32_DISPLAY_INFO (f)->h_palette);
1264 FRAME_WIN32_DISPLAY_INFO (f)->h_palette = h_new_palette;
1265
1266 /* Realize display palette and garbage all frames. */
1267 ReleaseFrameDC (f, GetFrameDC (f));
1268
1269 leave_crit (CRIT_GDI);
1270
1271 xfree (p_palette);
1272}
1273
1274#define WIN32_COLOR(pe) RGB (pe.peRed, pe.peGreen, pe.peBlue)
1275#define SET_WIN32_COLOR(pe, color) \
1276 do { \
1277 pe.peRed = GetRValue (color); \
1278 pe.peGreen = GetGValue (color); \
1279 pe.peBlue = GetBValue (color); \
1280 pe.peFlags = 0; \
1281 } while (0)
1282
1283#if 0
1284/* Keep these around in case we ever want to track color usage. */
1285void
1286win32_map_color (FRAME_PTR f, COLORREF color)
1287{
1288 struct win32_palette_entry * pList = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1289
1290 if (NILP (Vwin32_enable_palette))
1291 return;
1292
1293 /* check if color is already mapped */
1294 while (pList)
1295 {
1296 if (WIN32_COLOR (pList->entry) == color)
1297 {
1298 ++pList->refcount;
1299 return;
1300 }
1301 pList = pList->next;
1302 }
1303
1304 /* not already mapped, so add to list and recreate Windows palette */
1305 pList = (struct win32_palette_entry *) xmalloc (sizeof (struct win32_palette_entry));
1306 SET_WIN32_COLOR (pList->entry, color);
1307 pList->refcount = 1;
1308 pList->next = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1309 FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use = pList;
1310 FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use++;
1311
1312 /* set flag that palette must be regenerated */
1313 FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
1314}
1315
1316void
1317win32_unmap_color (FRAME_PTR f, COLORREF color)
1318{
1319 struct win32_palette_entry * pList = FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1320 struct win32_palette_entry **ppPrev = &FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1321
1322 if (NILP (Vwin32_enable_palette))
1323 return;
1324
1325 /* check if color is already mapped */
1326 while (pList)
1327 {
1328 if (WIN32_COLOR (pList->entry) == color)
1329 {
1330 if (--pList->refcount == 0)
1331 {
1332 *ppPrev = pList->next;
1333 xfree (pList);
1334 FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use--;
1335 break;
1336 }
1337 else
1338 return;
1339 }
1340 ppPrev = &pList->next;
1341 pList = pList->next;
1342 }
1343
1344 /* set flag that palette must be regenerated */
1345 FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
1346}
1347#endif
1348
ee78dc32
GV
1349/* Decide if color named COLOR is valid for the display associated with
1350 the selected frame; if so, return the rgb values in COLOR_DEF.
1351 If ALLOC is nonzero, allocate a new colormap cell. */
1352
1353int
1354defined_color (f, color, color_def, alloc)
1355 FRAME_PTR f;
1356 char *color;
1357 COLORREF *color_def;
1358 int alloc;
1359{
1360 register Lisp_Object tem;
7fb46567 1361
ee78dc32 1362 tem = x_to_win32_color (color);
7fb46567 1363
ee78dc32
GV
1364 if (!NILP (tem))
1365 {
7fb46567
GV
1366 if (!NILP (Vwin32_enable_palette))
1367 {
1368 struct win32_palette_entry * pEntry =
1369 FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1370 struct win32_palette_entry ** ppLast =
1371 &FRAME_WIN32_DISPLAY_INFO (f)->p_colors_in_use;
1372
1373 /* check if color is already mapped */
1374 while (pEntry)
1375 {
1376 if (WIN32_COLOR (pEntry->entry) == XUINT(tem))
1377 break;
1378 ppLast = &pEntry->next;
1379 pEntry = pEntry->next;
1380 }
1381
1382 if (pEntry == NULL && alloc)
1383 {
1384 /* not already mapped, so add to list */
1385 pEntry = (struct win32_palette_entry *)
1386 xmalloc (sizeof (struct win32_palette_entry));
1387 SET_WIN32_COLOR (pEntry->entry, XUINT(tem));
1388 pEntry->next = NULL;
1389 *ppLast = pEntry;
1390 FRAME_WIN32_DISPLAY_INFO (f)->n_colors_in_use++;
1391
1392 /* set flag that palette must be regenerated */
1393 FRAME_WIN32_DISPLAY_INFO (f)->regen_palette = TRUE;
1394 }
1395 }
1396 /* whether or not frame can display arbitrary RGB colors, force
1397 COLORREF value to snap to nearest color in system palette by
1398 simulating the PALETTE_RGB macro. */
1399 *color_def = XUINT (tem) | 0x2000000;
ee78dc32 1400 return 1;
ee78dc32 1401 }
7fb46567
GV
1402 else
1403 return 0;
ee78dc32
GV
1404}
1405
1406/* Given a string ARG naming a color, compute a pixel value from it
1407 suitable for screen F.
1408 If F is not a color screen, return DEF (default) regardless of what
1409 ARG says. */
1410
1411int
1412x_decode_color (f, arg, def)
1413 FRAME_PTR f;
1414 Lisp_Object arg;
1415 int def;
1416{
1417 COLORREF cdef;
1418
1419 CHECK_STRING (arg, 0);
1420
1421 if (strcmp (XSTRING (arg)->data, "black") == 0)
1422 return BLACK_PIX_DEFAULT (f);
1423 else if (strcmp (XSTRING (arg)->data, "white") == 0)
1424 return WHITE_PIX_DEFAULT (f);
1425
1426 if ((FRAME_WIN32_DISPLAY_INFO (f)->n_planes * FRAME_WIN32_DISPLAY_INFO (f)->n_cbits) == 1)
1427 return def;
1428
1429 /* defined_color is responsible for coping with failures
1430 by looking for a near-miss. */
1431 if (defined_color (f, XSTRING (arg)->data, &cdef, 1))
1432 return cdef;
1433
1434 /* defined_color failed; return an ultimate default. */
1435 return def;
1436}
1437\f
1438/* Functions called only from `x_set_frame_param'
1439 to set individual parameters.
1440
1441 If FRAME_WIN32_WINDOW (f) is 0,
1442 the frame is being created and its window does not exist yet.
1443 In that case, just record the parameter's new value
1444 in the standard place; do not attempt to change the window. */
1445
1446void
1447x_set_foreground_color (f, arg, oldval)
1448 struct frame *f;
1449 Lisp_Object arg, oldval;
1450{
1451 f->output_data.win32->foreground_pixel
1452 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1453 if (FRAME_WIN32_WINDOW (f) != 0)
1454 {
1455 recompute_basic_faces (f);
1456 if (FRAME_VISIBLE_P (f))
1457 redraw_frame (f);
1458 }
1459}
1460
1461void
1462x_set_background_color (f, arg, oldval)
1463 struct frame *f;
1464 Lisp_Object arg, oldval;
1465{
1466 Pixmap temp;
1467 int mask;
1468
1469 f->output_data.win32->background_pixel
1470 = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
1471
1472 if (FRAME_WIN32_WINDOW (f) != 0)
1473 {
1474 SetWindowLong (FRAME_WIN32_WINDOW (f), WND_BACKGROUND_INDEX, f->output_data.win32->background_pixel);
1475
1476 recompute_basic_faces (f);
1477
1478 if (FRAME_VISIBLE_P (f))
1479 redraw_frame (f);
1480 }
1481}
1482
1483void
1484x_set_mouse_color (f, arg, oldval)
1485 struct frame *f;
1486 Lisp_Object arg, oldval;
1487{
1488#if 0
1489 Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
1490#endif
1491 int mask_color;
1492
1493 if (!EQ (Qnil, arg))
1494 f->output_data.win32->mouse_pixel
1495 = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1496 mask_color = f->output_data.win32->background_pixel;
1497 /* No invisible pointers. */
1498 if (mask_color == f->output_data.win32->mouse_pixel
1499 && mask_color == f->output_data.win32->background_pixel)
1500 f->output_data.win32->mouse_pixel = f->output_data.win32->foreground_pixel;
1501
1502#if 0
1503 BLOCK_INPUT;
1504
1505 /* It's not okay to crash if the user selects a screwy cursor. */
1506 x_catch_errors (FRAME_WIN32_DISPLAY (f));
1507
1508 if (!EQ (Qnil, Vx_pointer_shape))
1509 {
1510 CHECK_NUMBER (Vx_pointer_shape, 0);
1511 cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f), XINT (Vx_pointer_shape));
1512 }
1513 else
1514 cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f), XC_xterm);
1515 x_check_errors (FRAME_WIN32_DISPLAY (f), "bad text pointer cursor: %s");
1516
1517 if (!EQ (Qnil, Vx_nontext_pointer_shape))
1518 {
1519 CHECK_NUMBER (Vx_nontext_pointer_shape, 0);
1520 nontext_cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f),
1521 XINT (Vx_nontext_pointer_shape));
1522 }
1523 else
1524 nontext_cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f), XC_left_ptr);
1525 x_check_errors (FRAME_WIN32_DISPLAY (f), "bad nontext pointer cursor: %s");
1526
1527 if (!EQ (Qnil, Vx_mode_pointer_shape))
1528 {
1529 CHECK_NUMBER (Vx_mode_pointer_shape, 0);
1530 mode_cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f),
1531 XINT (Vx_mode_pointer_shape));
1532 }
1533 else
1534 mode_cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f), XC_xterm);
1535 x_check_errors (FRAME_WIN32_DISPLAY (f), "bad modeline pointer cursor: %s");
1536
1537 if (!EQ (Qnil, Vx_sensitive_text_pointer_shape))
1538 {
1539 CHECK_NUMBER (Vx_sensitive_text_pointer_shape, 0);
1540 cross_cursor
1541 = XCreateFontCursor (FRAME_WIN32_DISPLAY (f),
1542 XINT (Vx_sensitive_text_pointer_shape));
1543 }
1544 else
1545 cross_cursor = XCreateFontCursor (FRAME_WIN32_DISPLAY (f), XC_crosshair);
1546
1547 /* Check and report errors with the above calls. */
1548 x_check_errors (FRAME_WIN32_DISPLAY (f), "can't set cursor shape: %s");
1549 x_uncatch_errors (FRAME_WIN32_DISPLAY (f));
1550
1551 {
1552 XColor fore_color, back_color;
1553
1554 fore_color.pixel = f->output_data.win32->mouse_pixel;
1555 back_color.pixel = mask_color;
1556 XQueryColor (FRAME_WIN32_DISPLAY (f),
1557 DefaultColormap (FRAME_WIN32_DISPLAY (f),
1558 DefaultScreen (FRAME_WIN32_DISPLAY (f))),
1559 &fore_color);
1560 XQueryColor (FRAME_WIN32_DISPLAY (f),
1561 DefaultColormap (FRAME_WIN32_DISPLAY (f),
1562 DefaultScreen (FRAME_WIN32_DISPLAY (f))),
1563 &back_color);
1564 XRecolorCursor (FRAME_WIN32_DISPLAY (f), cursor,
1565 &fore_color, &back_color);
1566 XRecolorCursor (FRAME_WIN32_DISPLAY (f), nontext_cursor,
1567 &fore_color, &back_color);
1568 XRecolorCursor (FRAME_WIN32_DISPLAY (f), mode_cursor,
1569 &fore_color, &back_color);
1570 XRecolorCursor (FRAME_WIN32_DISPLAY (f), cross_cursor,
1571 &fore_color, &back_color);
1572 }
1573
1574 if (FRAME_WIN32_WINDOW (f) != 0)
1575 {
1576 XDefineCursor (FRAME_WIN32_DISPLAY (f), FRAME_WIN32_WINDOW (f), cursor);
1577 }
1578
1579 if (cursor != f->output_data.win32->text_cursor && f->output_data.win32->text_cursor != 0)
1580 XFreeCursor (FRAME_WIN32_DISPLAY (f), f->output_data.win32->text_cursor);
1581 f->output_data.win32->text_cursor = cursor;
1582
1583 if (nontext_cursor != f->output_data.win32->nontext_cursor
1584 && f->output_data.win32->nontext_cursor != 0)
1585 XFreeCursor (FRAME_WIN32_DISPLAY (f), f->output_data.win32->nontext_cursor);
1586 f->output_data.win32->nontext_cursor = nontext_cursor;
1587
1588 if (mode_cursor != f->output_data.win32->modeline_cursor
1589 && f->output_data.win32->modeline_cursor != 0)
1590 XFreeCursor (FRAME_WIN32_DISPLAY (f), f->output_data.win32->modeline_cursor);
1591 f->output_data.win32->modeline_cursor = mode_cursor;
1592 if (cross_cursor != f->output_data.win32->cross_cursor
1593 && f->output_data.win32->cross_cursor != 0)
1594 XFreeCursor (FRAME_WIN32_DISPLAY (f), f->output_data.win32->cross_cursor);
1595 f->output_data.win32->cross_cursor = cross_cursor;
1596
1597 XFlush (FRAME_WIN32_DISPLAY (f));
1598 UNBLOCK_INPUT;
1599#endif
1600}
1601
1602void
1603x_set_cursor_color (f, arg, oldval)
1604 struct frame *f;
1605 Lisp_Object arg, oldval;
1606{
1607 unsigned long fore_pixel;
1608
1609 if (!EQ (Vx_cursor_fore_pixel, Qnil))
1610 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1611 WHITE_PIX_DEFAULT (f));
1612 else
1613 fore_pixel = f->output_data.win32->background_pixel;
1614 f->output_data.win32->cursor_pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1615
1616 /* Make sure that the cursor color differs from the background color. */
1617 if (f->output_data.win32->cursor_pixel == f->output_data.win32->background_pixel)
1618 {
1619 f->output_data.win32->cursor_pixel = f->output_data.win32->mouse_pixel;
1620 if (f->output_data.win32->cursor_pixel == fore_pixel)
1621 fore_pixel = f->output_data.win32->background_pixel;
1622 }
1623 f->output_data.win32->cursor_foreground_pixel = fore_pixel;
1624
1625 if (FRAME_WIN32_WINDOW (f) != 0)
1626 {
1627 if (FRAME_VISIBLE_P (f))
1628 {
1629 x_display_cursor (f, 0);
1630 x_display_cursor (f, 1);
1631 }
1632 }
1633}
1634
1635/* Set the border-color of frame F to value described by ARG.
1636 ARG can be a string naming a color.
1637 The border-color is used for the border that is drawn by the server.
1638 Note that this does not fully take effect if done before
1639 F has a window; it must be redone when the window is created. */
1640
1641void
1642x_set_border_color (f, arg, oldval)
1643 struct frame *f;
1644 Lisp_Object arg, oldval;
1645{
1646 unsigned char *str;
1647 int pix;
1648
1649 CHECK_STRING (arg, 0);
1650 str = XSTRING (arg)->data;
1651
1652 pix = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
1653
1654 x_set_border_pixel (f, pix);
1655}
1656
1657/* Set the border-color of frame F to pixel value PIX.
1658 Note that this does not fully take effect if done before
1659 F has an window. */
1660
1661x_set_border_pixel (f, pix)
1662 struct frame *f;
1663 int pix;
1664{
1665 f->output_data.win32->border_pixel = pix;
1666
1667 if (FRAME_WIN32_WINDOW (f) != 0 && f->output_data.win32->border_width > 0)
1668 {
1669 if (FRAME_VISIBLE_P (f))
1670 redraw_frame (f);
1671 }
1672}
1673
1674void
1675x_set_cursor_type (f, arg, oldval)
1676 FRAME_PTR f;
1677 Lisp_Object arg, oldval;
1678{
1679 if (EQ (arg, Qbar))
1680 {
1681 FRAME_DESIRED_CURSOR (f) = bar_cursor;
1682 f->output_data.win32->cursor_width = 2;
1683 }
1684 else if (CONSP (arg) && EQ (XCONS (arg)->car, Qbar)
1685 && INTEGERP (XCONS (arg)->cdr))
1686 {
1687 FRAME_DESIRED_CURSOR (f) = bar_cursor;
1688 f->output_data.win32->cursor_width = XINT (XCONS (arg)->cdr);
1689 }
1690 else
1691 /* Treat anything unknown as "box cursor".
1692 It was bad to signal an error; people have trouble fixing
1693 .Xdefaults with Emacs, when it has something bad in it. */
1694 FRAME_DESIRED_CURSOR (f) = filled_box_cursor;
1695
1696 /* Make sure the cursor gets redrawn. This is overkill, but how
1697 often do people change cursor types? */
1698 update_mode_lines++;
1699}
1700
1701void
1702x_set_icon_type (f, arg, oldval)
1703 struct frame *f;
1704 Lisp_Object arg, oldval;
1705{
1706#if 0
1707 Lisp_Object tem;
1708 int result;
1709
1710 if (STRINGP (arg))
1711 {
1712 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1713 return;
1714 }
1715 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1716 return;
1717
1718 BLOCK_INPUT;
1719 if (NILP (arg))
1720 result = x_text_icon (f,
1721 (char *) XSTRING ((!NILP (f->icon_name)
1722 ? f->icon_name
1723 : f->name))->data);
1724 else
1725 result = x_bitmap_icon (f, arg);
1726
1727 if (result)
1728 {
1729 UNBLOCK_INPUT;
1730 error ("No icon window available");
1731 }
1732
1733 /* If the window was unmapped (and its icon was mapped),
1734 the new icon is not mapped, so map the window in its stead. */
1735 if (FRAME_VISIBLE_P (f))
1736 {
1737#ifdef USE_X_TOOLKIT
1738 XtPopup (f->output_data.win32->widget, XtGrabNone);
1739#endif
1740 XMapWindow (FRAME_WIN32_DISPLAY (f), FRAME_WIN32_WINDOW (f));
1741 }
1742
1743 XFlush (FRAME_WIN32_DISPLAY (f));
1744 UNBLOCK_INPUT;
1745#endif
1746}
1747
1748/* Return non-nil if frame F wants a bitmap icon. */
1749
1750Lisp_Object
1751x_icon_type (f)
1752 FRAME_PTR f;
1753{
1754 Lisp_Object tem;
1755
1756 tem = assq_no_quit (Qicon_type, f->param_alist);
1757 if (CONSP (tem))
1758 return XCONS (tem)->cdr;
1759 else
1760 return Qnil;
1761}
1762
1763void
1764x_set_icon_name (f, arg, oldval)
1765 struct frame *f;
1766 Lisp_Object arg, oldval;
1767{
1768 Lisp_Object tem;
1769 int result;
1770
1771 if (STRINGP (arg))
1772 {
1773 if (STRINGP (oldval) && EQ (Fstring_equal (oldval, arg), Qt))
1774 return;
1775 }
1776 else if (!STRINGP (oldval) && EQ (oldval, Qnil) == EQ (arg, Qnil))
1777 return;
1778
1779 f->icon_name = arg;
1780
1781#if 0
1782 if (f->output_data.win32->icon_bitmap != 0)
1783 return;
1784
1785 BLOCK_INPUT;
1786
1787 result = x_text_icon (f,
1788 (char *) XSTRING ((!NILP (f->icon_name)
1789 ? f->icon_name
1790 : f->name))->data);
1791
1792 if (result)
1793 {
1794 UNBLOCK_INPUT;
1795 error ("No icon window available");
1796 }
1797
1798 /* If the window was unmapped (and its icon was mapped),
1799 the new icon is not mapped, so map the window in its stead. */
1800 if (FRAME_VISIBLE_P (f))
1801 {
1802#ifdef USE_X_TOOLKIT
1803 XtPopup (f->output_data.win32->widget, XtGrabNone);
1804#endif
1805 XMapWindow (FRAME_WIN32_DISPLAY (f), FRAME_WIN32_WINDOW (f));
1806 }
1807
1808 XFlush (FRAME_WIN32_DISPLAY (f));
1809 UNBLOCK_INPUT;
1810#endif
1811}
1812
1813extern Lisp_Object x_new_font ();
1814
1815void
1816x_set_font (f, arg, oldval)
1817 struct frame *f;
1818 Lisp_Object arg, oldval;
1819{
1820 Lisp_Object result;
1821
1822 CHECK_STRING (arg, 1);
1823
1824 BLOCK_INPUT;
1825 result = x_new_font (f, XSTRING (arg)->data);
1826 UNBLOCK_INPUT;
1827
1828 if (EQ (result, Qnil))
1829 error ("Font \"%s\" is not defined", XSTRING (arg)->data);
1830 else if (EQ (result, Qt))
1831 error ("the characters of the given font have varying widths");
1832 else if (STRINGP (result))
1833 {
1834 recompute_basic_faces (f);
1835 store_frame_param (f, Qfont, result);
1836 }
1837 else
1838 abort ();
1839}
1840
1841void
1842x_set_border_width (f, arg, oldval)
1843 struct frame *f;
1844 Lisp_Object arg, oldval;
1845{
1846 CHECK_NUMBER (arg, 0);
1847
1848 if (XINT (arg) == f->output_data.win32->border_width)
1849 return;
1850
1851 if (FRAME_WIN32_WINDOW (f) != 0)
1852 error ("Cannot change the border width of a window");
1853
1854 f->output_data.win32->border_width = XINT (arg);
1855}
1856
1857void
1858x_set_internal_border_width (f, arg, oldval)
1859 struct frame *f;
1860 Lisp_Object arg, oldval;
1861{
1862 int mask;
1863 int old = f->output_data.win32->internal_border_width;
1864
1865 CHECK_NUMBER (arg, 0);
1866 f->output_data.win32->internal_border_width = XINT (arg);
1867 if (f->output_data.win32->internal_border_width < 0)
1868 f->output_data.win32->internal_border_width = 0;
1869
1870 if (f->output_data.win32->internal_border_width == old)
1871 return;
1872
1873 if (FRAME_WIN32_WINDOW (f) != 0)
1874 {
1875 BLOCK_INPUT;
1876 x_set_window_size (f, 0, f->width, f->height);
1877 UNBLOCK_INPUT;
1878 SET_FRAME_GARBAGED (f);
1879 }
1880}
1881
1882void
1883x_set_visibility (f, value, oldval)
1884 struct frame *f;
1885 Lisp_Object value, oldval;
1886{
1887 Lisp_Object frame;
1888 XSETFRAME (frame, f);
1889
1890 if (NILP (value))
1891 Fmake_frame_invisible (frame, Qt);
1892 else if (EQ (value, Qicon))
1893 Ficonify_frame (frame);
1894 else
1895 Fmake_frame_visible (frame);
1896}
1897
1898void
1899x_set_menu_bar_lines (f, value, oldval)
1900 struct frame *f;
1901 Lisp_Object value, oldval;
1902{
1903 int nlines;
1904 int olines = FRAME_MENU_BAR_LINES (f);
1905
1906 /* Right now, menu bars don't work properly in minibuf-only frames;
1907 most of the commands try to apply themselves to the minibuffer
1908 frame itslef, and get an error because you can't switch buffers
1909 in or split the minibuffer window. */
1910 if (FRAME_MINIBUF_ONLY_P (f))
1911 return;
1912
1913 if (INTEGERP (value))
1914 nlines = XINT (value);
1915 else
1916 nlines = 0;
1917
1918 FRAME_MENU_BAR_LINES (f) = 0;
1919 if (nlines)
1920 FRAME_EXTERNAL_MENU_BAR (f) = 1;
1921 else
1922 {
1923 if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
1924 free_frame_menubar (f);
1925 FRAME_EXTERNAL_MENU_BAR (f) = 0;
1926 }
1927}
1928
1929/* Change the name of frame F to NAME. If NAME is nil, set F's name to
1930 win32_id_name.
1931
1932 If EXPLICIT is non-zero, that indicates that lisp code is setting the
1933 name; if NAME is a string, set F's name to NAME and set
1934 F->explicit_name; if NAME is Qnil, then clear F->explicit_name.
1935
1936 If EXPLICIT is zero, that indicates that Emacs redisplay code is
1937 suggesting a new name, which lisp code should override; if
1938 F->explicit_name is set, ignore the new name; otherwise, set it. */
1939
1940void
1941x_set_name (f, name, explicit)
1942 struct frame *f;
1943 Lisp_Object name;
1944 int explicit;
1945{
1946 /* Make sure that requests from lisp code override requests from
1947 Emacs redisplay code. */
1948 if (explicit)
1949 {
1950 /* If we're switching from explicit to implicit, we had better
1951 update the mode lines and thereby update the title. */
1952 if (f->explicit_name && NILP (name))
1953 update_mode_lines = 1;
1954
1955 f->explicit_name = ! NILP (name);
1956 }
1957 else if (f->explicit_name)
1958 return;
1959
1960 /* If NAME is nil, set the name to the win32_id_name. */
1961 if (NILP (name))
1962 {
1963 /* Check for no change needed in this very common case
1964 before we do any consing. */
1965 if (!strcmp (FRAME_WIN32_DISPLAY_INFO (f)->win32_id_name,
1966 XSTRING (f->name)->data))
1967 return;
1968 name = build_string (FRAME_WIN32_DISPLAY_INFO (f)->win32_id_name);
1969 }
1970 else
1971 CHECK_STRING (name, 0);
1972
1973 /* Don't change the name if it's already NAME. */
1974 if (! NILP (Fstring_equal (name, f->name)))
1975 return;
1976
1977 if (FRAME_WIN32_WINDOW (f))
1978 {
1979 BLOCK_INPUT;
1980 SetWindowText(FRAME_WIN32_WINDOW (f), XSTRING (name)->data);
1981 UNBLOCK_INPUT;
1982 }
1983
1984 f->name = name;
1985}
1986
1987/* This function should be called when the user's lisp code has
1988 specified a name for the frame; the name will override any set by the
1989 redisplay code. */
1990void
1991x_explicitly_set_name (f, arg, oldval)
1992 FRAME_PTR f;
1993 Lisp_Object arg, oldval;
1994{
1995 x_set_name (f, arg, 1);
1996}
1997
1998/* This function should be called by Emacs redisplay code to set the
1999 name; names set this way will never override names set by the user's
2000 lisp code. */
2001void
2002x_implicitly_set_name (f, arg, oldval)
2003 FRAME_PTR f;
2004 Lisp_Object arg, oldval;
2005{
2006 x_set_name (f, arg, 0);
2007}
2008
2009void
2010x_set_autoraise (f, arg, oldval)
2011 struct frame *f;
2012 Lisp_Object arg, oldval;
2013{
2014 f->auto_raise = !EQ (Qnil, arg);
2015}
2016
2017void
2018x_set_autolower (f, arg, oldval)
2019 struct frame *f;
2020 Lisp_Object arg, oldval;
2021{
2022 f->auto_lower = !EQ (Qnil, arg);
2023}
2024
2025void
2026x_set_unsplittable (f, arg, oldval)
2027 struct frame *f;
2028 Lisp_Object arg, oldval;
2029{
2030 f->no_split = !NILP (arg);
2031}
2032
2033void
2034x_set_vertical_scroll_bars (f, arg, oldval)
2035 struct frame *f;
2036 Lisp_Object arg, oldval;
2037{
2038 if (NILP (arg) != ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))
2039 {
2040 FRAME_HAS_VERTICAL_SCROLL_BARS (f) = ! NILP (arg);
2041
2042 /* We set this parameter before creating the window for the
2043 frame, so we can get the geometry right from the start.
2044 However, if the window hasn't been created yet, we shouldn't
2045 call x_set_window_size. */
2046 if (FRAME_WIN32_WINDOW (f))
2047 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
2048 }
2049}
2050
2051void
2052x_set_scroll_bar_width (f, arg, oldval)
2053 struct frame *f;
2054 Lisp_Object arg, oldval;
2055{
2056 if (NILP (arg))
2057 {
2058 FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = 0;
2059 FRAME_SCROLL_BAR_COLS (f) = 2;
2060 }
2061 else if (INTEGERP (arg) && XINT (arg) > 0
2062 && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
2063 {
2064 int wid = FONT_WIDTH (f->output_data.win32->font);
2065 FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg);
2066 FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
2067 if (FRAME_WIN32_WINDOW (f))
2068 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
2069 }
2070}
2071\f
2072/* Subroutines of creating an frame. */
2073
2074/* Make sure that Vx_resource_name is set to a reasonable value.
2075 Fix it up, or set it to `emacs' if it is too hopeless. */
2076
2077static void
2078validate_x_resource_name ()
2079{
2080 int len;
2081 /* Number of valid characters in the resource name. */
2082 int good_count = 0;
2083 /* Number of invalid characters in the resource name. */
2084 int bad_count = 0;
2085 Lisp_Object new;
2086 int i;
2087
2088 if (STRINGP (Vx_resource_name))
2089 {
2090 unsigned char *p = XSTRING (Vx_resource_name)->data;
2091 int i;
2092
2093 len = XSTRING (Vx_resource_name)->size;
2094
2095 /* Only letters, digits, - and _ are valid in resource names.
2096 Count the valid characters and count the invalid ones. */
2097 for (i = 0; i < len; i++)
2098 {
2099 int c = p[i];
2100 if (! ((c >= 'a' && c <= 'z')
2101 || (c >= 'A' && c <= 'Z')
2102 || (c >= '0' && c <= '9')
2103 || c == '-' || c == '_'))
2104 bad_count++;
2105 else
2106 good_count++;
2107 }
2108 }
2109 else
2110 /* Not a string => completely invalid. */
2111 bad_count = 5, good_count = 0;
2112
2113 /* If name is valid already, return. */
2114 if (bad_count == 0)
2115 return;
2116
2117 /* If name is entirely invalid, or nearly so, use `emacs'. */
2118 if (good_count == 0
2119 || (good_count == 1 && bad_count > 0))
2120 {
2121 Vx_resource_name = build_string ("emacs");
2122 return;
2123 }
2124
2125 /* Name is partly valid. Copy it and replace the invalid characters
2126 with underscores. */
2127
2128 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
2129
2130 for (i = 0; i < len; i++)
2131 {
2132 int c = XSTRING (new)->data[i];
2133 if (! ((c >= 'a' && c <= 'z')
2134 || (c >= 'A' && c <= 'Z')
2135 || (c >= '0' && c <= '9')
2136 || c == '-' || c == '_'))
2137 XSTRING (new)->data[i] = '_';
2138 }
2139}
2140
2141
2142extern char *x_get_string_resource ();
2143
2144DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
2145 "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
2146This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
2147class, where INSTANCE is the name under which Emacs was invoked, or\n\
2148the name specified by the `-name' or `-rn' command-line arguments.\n\
2149\n\
2150The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
2151class, respectively. You must specify both of them or neither.\n\
2152If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
2153and the class is `Emacs.CLASS.SUBCLASS'.")
2154 (attribute, class, component, subclass)
2155 Lisp_Object attribute, class, component, subclass;
2156{
2157 register char *value;
2158 char *name_key;
2159 char *class_key;
2160
2161 CHECK_STRING (attribute, 0);
2162 CHECK_STRING (class, 0);
2163
2164 if (!NILP (component))
2165 CHECK_STRING (component, 1);
2166 if (!NILP (subclass))
2167 CHECK_STRING (subclass, 2);
2168 if (NILP (component) != NILP (subclass))
2169 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
2170
2171 validate_x_resource_name ();
2172
2173 /* Allocate space for the components, the dots which separate them,
2174 and the final '\0'. Make them big enough for the worst case. */
2175 name_key = (char *) alloca (XSTRING (Vx_resource_name)->size
2176 + (STRINGP (component)
2177 ? XSTRING (component)->size : 0)
2178 + XSTRING (attribute)->size
2179 + 3);
2180
2181 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
2182 + XSTRING (class)->size
2183 + (STRINGP (subclass)
2184 ? XSTRING (subclass)->size : 0)
2185 + 3);
2186
2187 /* Start with emacs.FRAMENAME for the name (the specific one)
2188 and with `Emacs' for the class key (the general one). */
2189 strcpy (name_key, XSTRING (Vx_resource_name)->data);
2190 strcpy (class_key, EMACS_CLASS);
2191
2192 strcat (class_key, ".");
2193 strcat (class_key, XSTRING (class)->data);
2194
2195 if (!NILP (component))
2196 {
2197 strcat (class_key, ".");
2198 strcat (class_key, XSTRING (subclass)->data);
2199
2200 strcat (name_key, ".");
2201 strcat (name_key, XSTRING (component)->data);
2202 }
2203
2204 strcat (name_key, ".");
2205 strcat (name_key, XSTRING (attribute)->data);
2206
2207 value = x_get_string_resource (Qnil,
2208 name_key, class_key);
2209
2210 if (value != (char *) 0)
2211 return build_string (value);
2212 else
2213 return Qnil;
2214}
2215
2216/* Used when C code wants a resource value. */
2217
2218char *
2219x_get_resource_string (attribute, class)
2220 char *attribute, *class;
2221{
2222 register char *value;
2223 char *name_key;
2224 char *class_key;
2225
2226 /* Allocate space for the components, the dots which separate them,
2227 and the final '\0'. */
2228 name_key = (char *) alloca (XSTRING (Vinvocation_name)->size
2229 + strlen (attribute) + 2);
2230 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
2231 + strlen (class) + 2);
2232
2233 sprintf (name_key, "%s.%s",
2234 XSTRING (Vinvocation_name)->data,
2235 attribute);
2236 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
2237
2238 return x_get_string_resource (selected_frame,
2239 name_key, class_key);
2240}
2241
2242/* Types we might convert a resource string into. */
2243enum resource_types
2244 {
2245 number, boolean, string, symbol
2246 };
2247
2248/* Return the value of parameter PARAM.
2249
2250 First search ALIST, then Vdefault_frame_alist, then the X defaults
2251 database, using ATTRIBUTE as the attribute name and CLASS as its class.
2252
2253 Convert the resource to the type specified by desired_type.
2254
2255 If no default is specified, return Qunbound. If you call
2256 x_get_arg, make sure you deal with Qunbound in a reasonable way,
2257 and don't let it get stored in any Lisp-visible variables! */
2258
2259static Lisp_Object
2260x_get_arg (alist, param, attribute, class, type)
2261 Lisp_Object alist, param;
2262 char *attribute;
2263 char *class;
2264 enum resource_types type;
2265{
2266 register Lisp_Object tem;
2267
2268 tem = Fassq (param, alist);
2269 if (EQ (tem, Qnil))
2270 tem = Fassq (param, Vdefault_frame_alist);
2271 if (EQ (tem, Qnil))
2272 {
2273
2274 if (attribute)
2275 {
2276 tem = Fx_get_resource (build_string (attribute),
2277 build_string (class),
2278 Qnil, Qnil);
2279
2280 if (NILP (tem))
2281 return Qunbound;
2282
2283 switch (type)
2284 {
2285 case number:
2286 return make_number (atoi (XSTRING (tem)->data));
2287
2288 case boolean:
2289 tem = Fdowncase (tem);
2290 if (!strcmp (XSTRING (tem)->data, "on")
2291 || !strcmp (XSTRING (tem)->data, "true"))
2292 return Qt;
2293 else
2294 return Qnil;
2295
2296 case string:
2297 return tem;
2298
2299 case symbol:
2300 /* As a special case, we map the values `true' and `on'
2301 to Qt, and `false' and `off' to Qnil. */
2302 {
2303 Lisp_Object lower;
2304 lower = Fdowncase (tem);
2305 if (!strcmp (XSTRING (lower)->data, "on")
2306 || !strcmp (XSTRING (lower)->data, "true"))
2307 return Qt;
2308 else if (!strcmp (XSTRING (lower)->data, "off")
2309 || !strcmp (XSTRING (lower)->data, "false"))
2310 return Qnil;
2311 else
2312 return Fintern (tem, Qnil);
2313 }
2314
2315 default:
2316 abort ();
2317 }
2318 }
2319 else
2320 return Qunbound;
2321 }
2322 return Fcdr (tem);
2323}
2324
2325/* Record in frame F the specified or default value according to ALIST
2326 of the parameter named PARAM (a Lisp symbol).
2327 If no value is specified for PARAM, look for an X default for XPROP
2328 on the frame named NAME.
2329 If that is not found either, use the value DEFLT. */
2330
2331static Lisp_Object
2332x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
2333 struct frame *f;
2334 Lisp_Object alist;
2335 Lisp_Object prop;
2336 Lisp_Object deflt;
2337 char *xprop;
2338 char *xclass;
2339 enum resource_types type;
2340{
2341 Lisp_Object tem;
2342
2343 tem = x_get_arg (alist, prop, xprop, xclass, type);
2344 if (EQ (tem, Qunbound))
2345 tem = deflt;
2346 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
2347 return tem;
2348}
2349\f
2350DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
2351 "Parse an X-style geometry string STRING.\n\
2352Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
2353The properties returned may include `top', `left', `height', and `width'.\n\
2354The value of `left' or `top' may be an integer,\n\
2355or a list (+ N) meaning N pixels relative to top/left corner,\n\
2356or a list (- N) meaning -N pixels relative to bottom/right corner.")
2357 (string)
2358 Lisp_Object string;
2359{
2360 int geometry, x, y;
2361 unsigned int width, height;
2362 Lisp_Object result;
2363
2364 CHECK_STRING (string, 0);
2365
2366 geometry = XParseGeometry ((char *) XSTRING (string)->data,
2367 &x, &y, &width, &height);
2368
2369 result = Qnil;
2370 if (geometry & XValue)
2371 {
2372 Lisp_Object element;
2373
2374 if (x >= 0 && (geometry & XNegative))
2375 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
2376 else if (x < 0 && ! (geometry & XNegative))
2377 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
2378 else
2379 element = Fcons (Qleft, make_number (x));
2380 result = Fcons (element, result);
2381 }
2382
2383 if (geometry & YValue)
2384 {
2385 Lisp_Object element;
2386
2387 if (y >= 0 && (geometry & YNegative))
2388 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
2389 else if (y < 0 && ! (geometry & YNegative))
2390 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
2391 else
2392 element = Fcons (Qtop, make_number (y));
2393 result = Fcons (element, result);
2394 }
2395
2396 if (geometry & WidthValue)
2397 result = Fcons (Fcons (Qwidth, make_number (width)), result);
2398 if (geometry & HeightValue)
2399 result = Fcons (Fcons (Qheight, make_number (height)), result);
2400
2401 return result;
2402}
2403
2404/* Calculate the desired size and position of this window,
2405 and return the flags saying which aspects were specified.
2406
2407 This function does not make the coordinates positive. */
2408
2409#define DEFAULT_ROWS 40
2410#define DEFAULT_COLS 80
2411
2412static int
2413x_figure_window_size (f, parms)
2414 struct frame *f;
2415 Lisp_Object parms;
2416{
2417 register Lisp_Object tem0, tem1, tem2;
2418 int height, width, left, top;
2419 register int geometry;
2420 long window_prompting = 0;
2421
2422 /* Default values if we fall through.
2423 Actually, if that happens we should get
2424 window manager prompting. */
2425 f->width = DEFAULT_COLS;
2426 f->height = DEFAULT_ROWS;
2427 /* Window managers expect that if program-specified
2428 positions are not (0,0), they're intentional, not defaults. */
2429 f->output_data.win32->top_pos = 0;
2430 f->output_data.win32->left_pos = 0;
2431
2432 tem0 = x_get_arg (parms, Qheight, 0, 0, number);
2433 tem1 = x_get_arg (parms, Qwidth, 0, 0, number);
2434 tem2 = x_get_arg (parms, Quser_size, 0, 0, number);
2435 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
2436 {
2437 if (!EQ (tem0, Qunbound))
2438 {
2439 CHECK_NUMBER (tem0, 0);
2440 f->height = XINT (tem0);
2441 }
2442 if (!EQ (tem1, Qunbound))
2443 {
2444 CHECK_NUMBER (tem1, 0);
2445 f->width = XINT (tem1);
2446 }
2447 if (!NILP (tem2) && !EQ (tem2, Qunbound))
2448 window_prompting |= USSize;
2449 else
2450 window_prompting |= PSize;
2451 }
2452
2453 f->output_data.win32->vertical_scroll_bar_extra
2454 = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
2455 ? 0
2456 : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
2457 ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
2458 : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.win32->font)));
2459 f->output_data.win32->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
2460 f->output_data.win32->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
2461
2462 tem0 = x_get_arg (parms, Qtop, 0, 0, number);
2463 tem1 = x_get_arg (parms, Qleft, 0, 0, number);
2464 tem2 = x_get_arg (parms, Quser_position, 0, 0, number);
2465 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
2466 {
2467 if (EQ (tem0, Qminus))
2468 {
2469 f->output_data.win32->top_pos = 0;
2470 window_prompting |= YNegative;
2471 }
2472 else if (CONSP (tem0) && EQ (XCONS (tem0)->car, Qminus)
2473 && CONSP (XCONS (tem0)->cdr)
2474 && INTEGERP (XCONS (XCONS (tem0)->cdr)->car))
2475 {
2476 f->output_data.win32->top_pos = - XINT (XCONS (XCONS (tem0)->cdr)->car);
2477 window_prompting |= YNegative;
2478 }
2479 else if (CONSP (tem0) && EQ (XCONS (tem0)->car, Qplus)
2480 && CONSP (XCONS (tem0)->cdr)
2481 && INTEGERP (XCONS (XCONS (tem0)->cdr)->car))
2482 {
2483 f->output_data.win32->top_pos = XINT (XCONS (XCONS (tem0)->cdr)->car);
2484 }
2485 else if (EQ (tem0, Qunbound))
2486 f->output_data.win32->top_pos = 0;
2487 else
2488 {
2489 CHECK_NUMBER (tem0, 0);
2490 f->output_data.win32->top_pos = XINT (tem0);
2491 if (f->output_data.win32->top_pos < 0)
2492 window_prompting |= YNegative;
2493 }
2494
2495 if (EQ (tem1, Qminus))
2496 {
2497 f->output_data.win32->left_pos = 0;
2498 window_prompting |= XNegative;
2499 }
2500 else if (CONSP (tem1) && EQ (XCONS (tem1)->car, Qminus)
2501 && CONSP (XCONS (tem1)->cdr)
2502 && INTEGERP (XCONS (XCONS (tem1)->cdr)->car))
2503 {
2504 f->output_data.win32->left_pos = - XINT (XCONS (XCONS (tem1)->cdr)->car);
2505 window_prompting |= XNegative;
2506 }
2507 else if (CONSP (tem1) && EQ (XCONS (tem1)->car, Qplus)
2508 && CONSP (XCONS (tem1)->cdr)
2509 && INTEGERP (XCONS (XCONS (tem1)->cdr)->car))
2510 {
2511 f->output_data.win32->left_pos = XINT (XCONS (XCONS (tem1)->cdr)->car);
2512 }
2513 else if (EQ (tem1, Qunbound))
2514 f->output_data.win32->left_pos = 0;
2515 else
2516 {
2517 CHECK_NUMBER (tem1, 0);
2518 f->output_data.win32->left_pos = XINT (tem1);
2519 if (f->output_data.win32->left_pos < 0)
2520 window_prompting |= XNegative;
2521 }
2522
2523 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
2524 window_prompting |= USPosition;
2525 else
2526 window_prompting |= PPosition;
2527 }
2528
2529 return window_prompting;
2530}
2531
2532\f
2533
2534extern LRESULT CALLBACK win32_wnd_proc ();
2535
2536BOOL
2537win32_init_class (hinst)
2538 HINSTANCE hinst;
2539{
2540 WNDCLASS wc;
2541
7fb46567 2542 wc.style = CS_HREDRAW | CS_VREDRAW;
ee78dc32
GV
2543 wc.lpfnWndProc = (WNDPROC) win32_wnd_proc;
2544 wc.cbClsExtra = 0;
2545 wc.cbWndExtra = WND_EXTRA_BYTES;
2546 wc.hInstance = hinst;
2547 wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
2548 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
2549 wc.hbrBackground = NULL; // GetStockObject (WHITE_BRUSH);
2550 wc.lpszMenuName = NULL;
2551 wc.lpszClassName = EMACS_CLASS;
2552
2553 return (RegisterClass (&wc));
2554}
2555
2556HWND
2557win32_createscrollbar (f, bar)
2558 struct frame *f;
2559 struct scroll_bar * bar;
2560{
2561 return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
2562 /* Position and size of scroll bar. */
2563 XINT(bar->left), XINT(bar->top),
2564 XINT(bar->width), XINT(bar->height),
2565 FRAME_WIN32_WINDOW (f),
2566 NULL,
2567 hinst,
2568 NULL));
2569}
2570
2571void
2572win32_createwindow (f)
2573 struct frame *f;
2574{
2575 HWND hwnd;
2576
2577 /* Do first time app init */
2578
2579 if (!hprevinst)
2580 {
2581 win32_init_class (hinst);
2582 }
2583
2584 FRAME_WIN32_WINDOW (f) = hwnd = CreateWindow (EMACS_CLASS,
2585 f->namebuf,
2586 f->output_data.win32->dwStyle | WS_CLIPCHILDREN,
2587 f->output_data.win32->left_pos,
2588 f->output_data.win32->top_pos,
2589 PIXEL_WIDTH (f),
2590 PIXEL_HEIGHT (f),
2591 NULL,
2592 NULL,
2593 hinst,
2594 NULL);
2595
2596 if (hwnd)
2597 {
2598 SetWindowLong (hwnd, WND_X_UNITS_INDEX, FONT_WIDTH (f->output_data.win32->font));
2599 SetWindowLong (hwnd, WND_Y_UNITS_INDEX, f->output_data.win32->line_height);
2600 SetWindowLong (hwnd, WND_BACKGROUND_INDEX, f->output_data.win32->background_pixel);
2601 }
2602}
2603
2604DWORD
2605win_msg_worker (dw)
2606 DWORD dw;
2607{
2608 MSG msg;
2609
2610 /* Ensure our message queue is created */
2611
2612 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2613
2614 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
2615
2616 while (GetMessage (&msg, NULL, 0, 0))
2617 {
2618 if (msg.hwnd == NULL)
2619 {
2620 switch (msg.message)
2621 {
2622 case WM_EMACS_CREATEWINDOW:
2623 win32_createwindow ((struct frame *) msg.wParam);
2624 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
2625 break;
2626 case WM_EMACS_CREATESCROLLBAR:
2627 {
2628 HWND hwnd = win32_createscrollbar ((struct frame *) msg.wParam,
2629 (struct scroll_bar *) msg.lParam);
2630 PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, (WPARAM)hwnd, 0);
2631 }
2632 break;
2633 case WM_EMACS_KILL:
2634 return (0);
2635 }
2636 }
2637 else
2638 {
2639 DispatchMessage (&msg);
2640 }
2641 }
2642
2643 return (0);
2644}
2645
ee78dc32
GV
2646/* Convert between the modifier bits Win32 uses and the modifier bits
2647 Emacs uses. */
2648unsigned int
2649win32_get_modifiers ()
2650{
2651 return (((GetKeyState (VK_SHIFT)&0x8000) ? shift_modifier : 0) |
2652 ((GetKeyState (VK_CONTROL)&0x8000) ? ctrl_modifier : 0) |
2653 ((GetKeyState (VK_MENU)&0x8000) ? meta_modifier : 0));
2654}
2655
2656void
2657my_post_msg (wmsg, hwnd, msg, wParam, lParam)
2658 Win32Msg * wmsg;
2659 HWND hwnd;
2660 UINT msg;
2661 WPARAM wParam;
2662 LPARAM lParam;
2663{
2664 wmsg->msg.hwnd = hwnd;
2665 wmsg->msg.message = msg;
2666 wmsg->msg.wParam = wParam;
2667 wmsg->msg.lParam = lParam;
2668 wmsg->msg.time = GetMessageTime ();
2669
2670 post_msg (wmsg);
2671}
2672
2673/* Main window procedure */
2674
2675extern char *lispy_function_keys[];
2676
2677LRESULT CALLBACK
2678win32_wnd_proc (hwnd, msg, wParam, lParam)
2679 HWND hwnd;
2680 UINT msg;
2681 WPARAM wParam;
2682 LPARAM lParam;
2683{
2684 struct frame *f;
2685 LRESULT ret = 1;
2686 struct win32_display_info *dpyinfo = &one_win32_display_info;
2687 Win32Msg wmsg;
2688
2689 switch (msg)
2690 {
2691 case WM_ERASEBKGND:
7fb46567
GV
2692 enter_crit (CRIT_GDI);
2693 GetUpdateRect (hwnd, &wmsg.rect, FALSE);
2694 leave_crit (CRIT_GDI);
2695 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2696 return 1;
2697 case WM_PALETTECHANGED:
2698 /* ignore our own changes */
2699 if ((HWND)wParam != hwnd)
ee78dc32 2700 {
7fb46567
GV
2701 /* simply notify main thread it may need to update frames */
2702 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
ee78dc32 2703 }
7fb46567 2704 return 0;
ee78dc32
GV
2705 case WM_PAINT:
2706 {
2707 PAINTSTRUCT paintStruct;
7fb46567
GV
2708
2709 enter_crit (CRIT_GDI);
ee78dc32
GV
2710 BeginPaint (hwnd, &paintStruct);
2711 wmsg.rect = paintStruct.rcPaint;
2712 EndPaint (hwnd, &paintStruct);
7fb46567
GV
2713 leave_crit (CRIT_GDI);
2714
ee78dc32
GV
2715 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2716
2717 return (0);
2718 }
ee78dc32
GV
2719 case WM_KEYDOWN:
2720 case WM_SYSKEYDOWN:
2721#if 0
2722 if (! ((wParam >= VK_BACK && wParam <= VK_TAB)
2723 || (wParam >= VK_CLEAR && wParam <= VK_RETURN)
2724 || (wParam == VK_ESCAPE)
2725 || (wParam >= VK_PRIOR && wParam <= VK_HELP)
2726 || (wParam >= VK_LWIN && wParam <= VK_APPS)
2727 || (wParam >= VK_NUMPAD0 && wParam <= VK_F24)
2728 || (wParam >= VK_NUMLOCK && wParam <= VK_SCROLL)
2729 || (wParam >= VK_ATTN && wParam <= VK_OEM_CLEAR)
2730 || !TranslateMessage (&msg1)))
2731 {
2732 goto dflt;
2733 }
2734#endif
2735
2736 /* Check for special characters since translate message
2737 seems to always indicate true. */
2738
2739 if (wParam == VK_MENU
2740 || wParam == VK_SHIFT
2741 || wParam == VK_CONTROL
2742 || wParam == VK_CAPITAL)
7fb46567 2743 goto dflt;
ee78dc32
GV
2744
2745 /* Anything we do not have a name for needs to be translated or
2746 returned as ascii keystroke. */
2747
2748 if (lispy_function_keys[wParam] == 0)
2749 {
2750 MSG msg1;
2751
2752 msg1.hwnd = hwnd;
2753 msg1.message = msg;
2754 msg1.wParam = wParam;
2755 msg1.lParam = lParam;
2756
2757 if (TranslateMessage (&msg1))
2758 break;
2759 else
2760 msg = WM_CHAR;
2761 }
2762
2763 /* Fall through */
2764
2765 case WM_SYSCHAR:
2766 case WM_CHAR:
2767 wmsg.dwModifiers = win32_get_modifiers ();
2768
2769 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2770 break;
2771 case WM_LBUTTONDOWN:
2772 case WM_LBUTTONUP:
2773 case WM_MBUTTONDOWN:
2774 case WM_MBUTTONUP:
2775 case WM_RBUTTONDOWN:
2776 case WM_RBUTTONUP:
2777 {
2778 BOOL up;
2779
2780 if (parse_button (msg, NULL, &up))
2781 {
2782 if (up) ReleaseCapture ();
2783 else SetCapture (hwnd);
2784 }
2785 }
2786
2787 wmsg.dwModifiers = win32_get_modifiers ();
2788
2789 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2790 goto dflt;
2791 case WM_MOUSEMOVE:
2792 case WM_MOVE:
2793 case WM_SIZE:
2794 case WM_SETFOCUS:
2795 case WM_KILLFOCUS:
2796 case WM_CLOSE:
2797 case WM_VSCROLL:
2798 case WM_SYSCOMMAND:
2799 case WM_COMMAND:
2800 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2801 goto dflt;
2802 case WM_WINDOWPOSCHANGING:
2803 {
2804 WINDOWPLACEMENT wp;
2805 LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
7fb46567
GV
2806
2807 wp.length = sizeof (wp);
ee78dc32
GV
2808 GetWindowPlacement (hwnd, &wp);
2809
2810 if (wp.showCmd != SW_SHOWMINIMIZED && ! (lppos->flags & SWP_NOSIZE))
2811 {
2812 RECT rect;
2813 int wdiff;
2814 int hdiff;
2815 DWORD dwXUnits;
2816 DWORD dwYUnits;
2817 RECT wr;
2818
2819 GetWindowRect (hwnd, &wr);
2820
7fb46567 2821 enter_crit (CRIT_MSG);
ee78dc32
GV
2822
2823 dwXUnits = GetWindowLong (hwnd, WND_X_UNITS_INDEX);
2824 dwYUnits = GetWindowLong (hwnd, WND_Y_UNITS_INDEX);
2825
7fb46567 2826 leave_crit (CRIT_MSG);
ee78dc32
GV
2827
2828 memset (&rect, 0, sizeof (rect));
2829 AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE),
2830 GetMenu (hwnd) != NULL);
2831
2832 /* All windows have an extra pixel so subtract 1 */
2833
2834 wdiff = (lppos->cx - (rect.right - rect.left) - 0) % dwXUnits;
2835 hdiff = (lppos->cy - (rect.bottom - rect.top) - 0) % dwYUnits;
2836
2837 if (wdiff || hdiff)
2838 {
2839 /* For right/bottom sizing we can just fix the sizes.
2840 However for top/left sizing we will need to fix the X
2841 and Y positions as well. */
2842
2843 lppos->cx -= wdiff;
2844 lppos->cy -= hdiff;
2845
2846 if (wp.showCmd != SW_SHOWMAXIMIZED
2847 && ! (lppos->flags & SWP_NOMOVE))
2848 {
2849 if (lppos->x != wr.left || lppos->y != wr.top)
2850 {
2851 lppos->x += wdiff;
2852 lppos->y += hdiff;
2853 }
2854 else
2855 {
2856 lppos->flags |= SWP_NOMOVE;
2857 }
2858 }
2859
2860 ret = 0;
2861 }
2862 }
2863 }
2864
2865 if (ret == 0) return (0);
2866
2867 goto dflt;
2868 case WM_EMACS_DESTROYWINDOW:
2869 DestroyWindow ((HWND) wParam);
2870 break;
2871 default:
2872 dflt:
2873 return DefWindowProc (hwnd, msg, wParam, lParam);
2874 }
2875
2876 return (1);
2877}
2878
2879void
2880my_create_window (f)
2881 struct frame * f;
2882{
2883 MSG msg;
2884
2885 PostThreadMessage (dwWinThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0);
2886 GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
2887}
2888
2889/* Create and set up the win32 window for frame F. */
2890
2891static void
2892win32_window (f, window_prompting, minibuffer_only)
2893 struct frame *f;
2894 long window_prompting;
2895 int minibuffer_only;
2896{
2897 BLOCK_INPUT;
2898
2899 /* Use the resource name as the top-level window name
2900 for looking up resources. Make a non-Lisp copy
2901 for the window manager, so GC relocation won't bother it.
2902
2903 Elsewhere we specify the window name for the window manager. */
2904
2905 {
2906 char *str = (char *) XSTRING (Vx_resource_name)->data;
2907 f->namebuf = (char *) xmalloc (strlen (str) + 1);
2908 strcpy (f->namebuf, str);
2909 }
2910
2911 my_create_window (f);
2912
2913 validate_x_resource_name ();
2914
2915 /* x_set_name normally ignores requests to set the name if the
2916 requested name is the same as the current name. This is the one
2917 place where that assumption isn't correct; f->name is set, but
2918 the server hasn't been told. */
2919 {
2920 Lisp_Object name;
2921 int explicit = f->explicit_name;
2922
2923 f->explicit_name = 0;
2924 name = f->name;
2925 f->name = Qnil;
2926 x_set_name (f, name, explicit);
2927 }
2928
2929 UNBLOCK_INPUT;
2930
2931 if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
2932 initialize_frame_menubar (f);
2933
2934 if (FRAME_WIN32_WINDOW (f) == 0)
2935 error ("Unable to create window");
2936}
2937
2938/* Handle the icon stuff for this window. Perhaps later we might
2939 want an x_set_icon_position which can be called interactively as
2940 well. */
2941
2942static void
2943x_icon (f, parms)
2944 struct frame *f;
2945 Lisp_Object parms;
2946{
2947 Lisp_Object icon_x, icon_y;
2948
2949 /* Set the position of the icon. Note that win95 groups all
2950 icons in the tray. */
2951 icon_x = x_get_arg (parms, Qicon_left, 0, 0, number);
2952 icon_y = x_get_arg (parms, Qicon_top, 0, 0, number);
2953 if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
2954 {
2955 CHECK_NUMBER (icon_x, 0);
2956 CHECK_NUMBER (icon_y, 0);
2957 }
2958 else if (!EQ (icon_x, Qunbound) || !EQ (icon_y, Qunbound))
2959 error ("Both left and top icon corners of icon must be specified");
2960
2961 BLOCK_INPUT;
2962
2963 if (! EQ (icon_x, Qunbound))
2964 x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
2965
2966 UNBLOCK_INPUT;
2967}
2968
2969DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
2970 1, 1, 0,
2971 "Make a new window, which is called a \"frame\" in Emacs terms.\n\
2972Returns an Emacs frame object.\n\
2973ALIST is an alist of frame parameters.\n\
2974If the parameters specify that the frame should not have a minibuffer,\n\
2975and do not specify a specific minibuffer window to use,\n\
2976then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
2977be shared by the new frame.\n\
2978\n\
2979This function is an internal primitive--use `make-frame' instead.")
2980 (parms)
2981 Lisp_Object parms;
2982{
2983 struct frame *f;
2984 Lisp_Object frame, tem;
2985 Lisp_Object name;
2986 int minibuffer_only = 0;
2987 long window_prompting = 0;
2988 int width, height;
2989 int count = specpdl_ptr - specpdl;
2990 struct gcpro gcpro1;
2991 Lisp_Object display;
2992 struct win32_display_info *dpyinfo;
2993 Lisp_Object parent;
2994 struct kboard *kb;
2995
2996 /* Use this general default value to start with
2997 until we know if this frame has a specified name. */
2998 Vx_resource_name = Vinvocation_name;
2999
3000 display = x_get_arg (parms, Qdisplay, 0, 0, string);
3001 if (EQ (display, Qunbound))
3002 display = Qnil;
3003 dpyinfo = check_x_display_info (display);
3004#ifdef MULTI_KBOARD
3005 kb = dpyinfo->kboard;
3006#else
3007 kb = &the_only_kboard;
3008#endif
3009
3010 name = x_get_arg (parms, Qname, "title", "Title", string);
3011 if (!STRINGP (name)
3012 && ! EQ (name, Qunbound)
3013 && ! NILP (name))
3014 error ("Invalid frame name--not a string or nil");
3015
3016 if (STRINGP (name))
3017 Vx_resource_name = name;
3018
3019 /* See if parent window is specified. */
3020 parent = x_get_arg (parms, Qparent_id, NULL, NULL, number);
3021 if (EQ (parent, Qunbound))
3022 parent = Qnil;
3023 if (! NILP (parent))
3024 CHECK_NUMBER (parent, 0);
3025
3026 tem = x_get_arg (parms, Qminibuffer, 0, 0, symbol);
3027 if (EQ (tem, Qnone) || NILP (tem))
3028 f = make_frame_without_minibuffer (Qnil, kb, display);
3029 else if (EQ (tem, Qonly))
3030 {
3031 f = make_minibuffer_frame ();
3032 minibuffer_only = 1;
3033 }
3034 else if (WINDOWP (tem))
3035 f = make_frame_without_minibuffer (tem, kb, display);
3036 else
3037 f = make_frame (1);
3038
3039 /* Note that Windows does support scroll bars. */
3040 FRAME_CAN_HAVE_SCROLL_BARS (f) = 1;
3041
3042 XSETFRAME (frame, f);
3043 GCPRO1 (frame);
3044
3045 f->output_method = output_win32;
3046 f->output_data.win32 = (struct win32_output *) xmalloc (sizeof (struct win32_output));
3047 bzero (f->output_data.win32, sizeof (struct win32_output));
3048
3049/* FRAME_WIN32_DISPLAY_INFO (f) = dpyinfo; */
3050#ifdef MULTI_KBOARD
3051 FRAME_KBOARD (f) = kb;
3052#endif
3053
3054 /* Specify the parent under which to make this window. */
3055
3056 if (!NILP (parent))
3057 {
3058 f->output_data.win32->parent_desc = (Window) parent;
3059 f->output_data.win32->explicit_parent = 1;
3060 }
3061 else
3062 {
3063 f->output_data.win32->parent_desc = FRAME_WIN32_DISPLAY_INFO (f)->root_window;
3064 f->output_data.win32->explicit_parent = 0;
3065 }
3066
3067 /* Note that the frame has no physical cursor right now. */
3068 f->phys_cursor_x = -1;
3069
3070 /* Set the name; the functions to which we pass f expect the name to
3071 be set. */
3072 if (EQ (name, Qunbound) || NILP (name))
3073 {
3074 f->name = build_string (dpyinfo->win32_id_name);
3075 f->explicit_name = 0;
3076 }
3077 else
3078 {
3079 f->name = name;
3080 f->explicit_name = 1;
3081 /* use the frame's title when getting resources for this frame. */
3082 specbind (Qx_resource_name, name);
3083 }
3084
3085 /* Extract the window parameters from the supplied values
3086 that are needed to determine window geometry. */
3087 {
3088 Lisp_Object font;
3089
3090 font = x_get_arg (parms, Qfont, "font", "Font", string);
3091 BLOCK_INPUT;
3092 /* First, try whatever font the caller has specified. */
3093 if (STRINGP (font))
3094 font = x_new_font (f, XSTRING (font)->data);
3095#if 0
3096 /* Try out a font which we hope has bold and italic variations. */
3097 if (!STRINGP (font))
3098 font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3099 if (! STRINGP (font))
3100 font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
3101 if (! STRINGP (font))
3102 /* This was formerly the first thing tried, but it finds too many fonts
3103 and takes too long. */
3104 font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
3105 /* If those didn't work, look for something which will at least work. */
3106 if (! STRINGP (font))
3107 font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
3108 if (! STRINGP (font))
3109 font = x_new_font (f, "-*-system-medium-r-normal-*-*-200-*-*-c-120-*-*");
3110#endif
3111 if (! STRINGP (font))
7fb46567 3112 font = x_new_font (f, "-*-Fixedsys-*-r-*-*-12-90-*-*-c-*-*-*");
ee78dc32
GV
3113 UNBLOCK_INPUT;
3114 if (! STRINGP (font))
3115 font = build_string ("-*-system");
3116
3117 x_default_parameter (f, parms, Qfont, font,
3118 "font", "Font", string);
3119 }
3120
3121 x_default_parameter (f, parms, Qborder_width, make_number (2),
3122 "borderwidth", "BorderWidth", number);
3123 /* This defaults to 2 in order to match xterm. We recognize either
3124 internalBorderWidth or internalBorder (which is what xterm calls
3125 it). */
3126 if (NILP (Fassq (Qinternal_border_width, parms)))
3127 {
3128 Lisp_Object value;
3129
3130 value = x_get_arg (parms, Qinternal_border_width,
3131 "internalBorder", "BorderWidth", number);
3132 if (! EQ (value, Qunbound))
3133 parms = Fcons (Fcons (Qinternal_border_width, value),
3134 parms);
3135 }
3136 x_default_parameter (f, parms, Qinternal_border_width, make_number (0),
3137 "internalBorderWidth", "BorderWidth", number);
3138 x_default_parameter (f, parms, Qvertical_scroll_bars, Qt,
3139 "verticalScrollBars", "ScrollBars", boolean);
3140
3141 /* Also do the stuff which must be set before the window exists. */
3142 x_default_parameter (f, parms, Qforeground_color, build_string ("black"),
3143 "foreground", "Foreground", string);
3144 x_default_parameter (f, parms, Qbackground_color, build_string ("white"),
3145 "background", "Background", string);
3146 x_default_parameter (f, parms, Qmouse_color, build_string ("black"),
3147 "pointerColor", "Foreground", string);
3148 x_default_parameter (f, parms, Qcursor_color, build_string ("black"),
3149 "cursorColor", "Foreground", string);
3150 x_default_parameter (f, parms, Qborder_color, build_string ("black"),
3151 "borderColor", "BorderColor", string);
3152
3153 x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
3154 "menuBar", "MenuBar", number);
3155 x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
3156 "scrollBarWidth", "ScrollBarWidth", number);
3157
3158 f->output_data.win32->dwStyle = WS_OVERLAPPEDWINDOW;
3159 f->output_data.win32->parent_desc = FRAME_WIN32_DISPLAY_INFO (f)->root_window;
3160 window_prompting = x_figure_window_size (f, parms);
3161
3162 if (window_prompting & XNegative)
3163 {
3164 if (window_prompting & YNegative)
3165 f->output_data.win32->win_gravity = SouthEastGravity;
3166 else
3167 f->output_data.win32->win_gravity = NorthEastGravity;
3168 }
3169 else
3170 {
3171 if (window_prompting & YNegative)
3172 f->output_data.win32->win_gravity = SouthWestGravity;
3173 else
3174 f->output_data.win32->win_gravity = NorthWestGravity;
3175 }
3176
3177 f->output_data.win32->size_hint_flags = window_prompting;
3178
3179 win32_window (f, window_prompting, minibuffer_only);
3180 x_icon (f, parms);
3181 init_frame_faces (f);
3182
3183 /* We need to do this after creating the window, so that the
3184 icon-creation functions can say whose icon they're describing. */
3185 x_default_parameter (f, parms, Qicon_type, Qnil,
3186 "bitmapIcon", "BitmapIcon", symbol);
3187
3188 x_default_parameter (f, parms, Qauto_raise, Qnil,
3189 "autoRaise", "AutoRaiseLower", boolean);
3190 x_default_parameter (f, parms, Qauto_lower, Qnil,
3191 "autoLower", "AutoRaiseLower", boolean);
3192 x_default_parameter (f, parms, Qcursor_type, Qbox,
3193 "cursorType", "CursorType", symbol);
3194
3195 /* Dimensions, especially f->height, must be done via change_frame_size.
3196 Change will not be effected unless different from the current
3197 f->height. */
3198 width = f->width;
3199 height = f->height;
3200 f->height = f->width = 0;
3201 change_frame_size (f, height, width, 1, 0);
3202
3203 /* Tell the server what size and position, etc, we want,
3204 and how badly we want them. */
3205 BLOCK_INPUT;
3206 x_wm_set_size_hint (f, window_prompting, 0);
3207 UNBLOCK_INPUT;
3208
3209 tem = x_get_arg (parms, Qunsplittable, 0, 0, boolean);
3210 f->no_split = minibuffer_only || EQ (tem, Qt);
3211
3212 UNGCPRO;
3213
3214 /* It is now ok to make the frame official
3215 even if we get an error below.
3216 And the frame needs to be on Vframe_list
3217 or making it visible won't work. */
3218 Vframe_list = Fcons (frame, Vframe_list);
3219
3220 /* Now that the frame is official, it counts as a reference to
3221 its display. */
3222 FRAME_WIN32_DISPLAY_INFO (f)->reference_count++;
3223
3224 /* Make the window appear on the frame and enable display,
3225 unless the caller says not to. However, with explicit parent,
3226 Emacs cannot control visibility, so don't try. */
3227 if (! f->output_data.win32->explicit_parent)
3228 {
3229 Lisp_Object visibility;
3230
3231 visibility = x_get_arg (parms, Qvisibility, 0, 0, symbol);
3232 if (EQ (visibility, Qunbound))
3233 visibility = Qt;
3234
3235 if (EQ (visibility, Qicon))
3236 x_iconify_frame (f);
3237 else if (! NILP (visibility))
3238 x_make_frame_visible (f);
3239 else
3240 /* Must have been Qnil. */
3241 ;
3242 }
3243
3244 return unbind_to (count, frame);
3245}
3246
3247/* FRAME is used only to get a handle on the X display. We don't pass the
3248 display info directly because we're called from frame.c, which doesn't
3249 know about that structure. */
3250Lisp_Object
3251x_get_focus_frame (frame)
3252 struct frame *frame;
3253{
3254 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (frame);
3255 Lisp_Object xfocus;
3256 if (! dpyinfo->win32_focus_frame)
3257 return Qnil;
3258
3259 XSETFRAME (xfocus, dpyinfo->win32_focus_frame);
3260 return xfocus;
3261}
3262
3263DEFUN ("focus-frame", Ffocus_frame, Sfocus_frame, 1, 1, 0,
3264 "Set the focus on FRAME.")
3265 (frame)
3266 Lisp_Object frame;
3267{
3268 CHECK_LIVE_FRAME (frame, 0);
3269
3270 if (FRAME_WIN32_P (XFRAME (frame)))
3271 {
3272 BLOCK_INPUT;
3273 x_focus_on_frame (XFRAME (frame));
3274 UNBLOCK_INPUT;
3275 return frame;
3276 }
3277
3278 return Qnil;
3279}
3280
3281DEFUN ("unfocus-frame", Funfocus_frame, Sunfocus_frame, 0, 0, 0,
3282 "If a frame has been focused, release it.")
3283 ()
3284{
3285 if (FRAME_WIN32_P (selected_frame))
3286 {
3287 struct win32_display_info *dpyinfo = FRAME_WIN32_DISPLAY_INFO (selected_frame);
3288
3289 if (dpyinfo->win32_focus_frame)
3290 {
3291 BLOCK_INPUT;
3292 x_unfocus_frame (dpyinfo->win32_focus_frame);
3293 UNBLOCK_INPUT;
3294 }
3295 }
3296
3297 return Qnil;
3298}
3299\f
7fb46567
GV
3300XFontStruct *
3301win32_load_font (dpyinfo,name)
3302 struct win32_display_info *dpyinfo;
3303 char *name;
ee78dc32
GV
3304{
3305 XFontStruct * font = NULL;
3306 BOOL ok;
7fb46567
GV
3307 LOGFONT lf;
3308
3309 if (!name || !x_to_win32_font (name, &lf))
3310 return (NULL);
3311
3312 font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
3313 if (!font) return (NULL);
3314
3315 BLOCK_INPUT;
3316
3317 font->hfont = CreateFontIndirect (&lf);
3318
3319 if (font->hfont == NULL)
3320 {
3321 ok = FALSE;
3322 }
3323 else
3324 {
3325 HDC hdc;
3326 HANDLE oldobj;
3327
3328 hdc = GetDC (dpyinfo->root_window);
3329
3330 oldobj = SelectObject (hdc, font->hfont);
3331
3332 ok = GetTextMetrics (hdc, &font->tm);
3333
3334 SelectObject (hdc, oldobj);
3335
3336 ReleaseDC (dpyinfo->root_window, hdc);
ee78dc32 3337 }
ee78dc32 3338
ee78dc32 3339 UNBLOCK_INPUT;
7fb46567 3340
ee78dc32 3341 if (ok) return (font);
7fb46567
GV
3342
3343 win32_unload_font (dpyinfo, font);
ee78dc32
GV
3344 return (NULL);
3345}
3346
3347void
3348win32_unload_font (dpyinfo, font)
3349 struct win32_display_info *dpyinfo;
3350 XFontStruct * font;
3351{
3352 if (font)
3353 {
7fb46567 3354 if (font->hfont) DeleteObject (font->hfont);
ee78dc32
GV
3355 xfree (font);
3356 }
3357}
3358
3359/* The font conversion stuff between x and win32 */
3360
3361/* X font string is as follows (from faces.el)
3362 * (let ((- "[-?]")
3363 * (foundry "[^-]+")
3364 * (family "[^-]+")
3365 * (weight "\\(bold\\|demibold\\|medium\\)") ; 1
3366 * (weight\? "\\([^-]*\\)") ; 1
3367 * (slant "\\([ior]\\)") ; 2
3368 * (slant\? "\\([^-]?\\)") ; 2
3369 * (swidth "\\([^-]*\\)") ; 3
3370 * (adstyle "[^-]*") ; 4
3371 * (pixelsize "[0-9]+")
3372 * (pointsize "[0-9][0-9]+")
3373 * (resx "[0-9][0-9]+")
3374 * (resy "[0-9][0-9]+")
3375 * (spacing "[cmp?*]")
3376 * (avgwidth "[0-9]+")
3377 * (registry "[^-]+")
3378 * (encoding "[^-]+")
3379 * )
3380 * (setq x-font-regexp
3381 * (concat "\\`\\*?[-?*]"
3382 * foundry - family - weight\? - slant\? - swidth - adstyle -
3383 * pixelsize - pointsize - resx - resy - spacing - registry -
3384 * encoding "[-?*]\\*?\\'"
3385 * ))
3386 * (setq x-font-regexp-head
3387 * (concat "\\`[-?*]" foundry - family - weight\? - slant\?
3388 * "\\([-*?]\\|\\'\\)"))
3389 * (setq x-font-regexp-slant (concat - slant -))
3390 * (setq x-font-regexp-weight (concat - weight -))
3391 * nil)
3392 */
3393
3394#define FONT_START "[-?]"
3395#define FONT_FOUNDRY "[^-]+"
3396#define FONT_FAMILY "\\([^-]+\\)" /* 1 */
3397#define FONT_WEIGHT "\\(bold\\|demibold\\|medium\\)" /* 2 */
3398#define FONT_WEIGHT_Q "\\([^-]*\\)" /* 2 */
3399#define FONT_SLANT "\\([ior]\\)" /* 3 */
3400#define FONT_SLANT_Q "\\([^-]?\\)" /* 3 */
3401#define FONT_SWIDTH "\\([^-]*\\)" /* 4 */
3402#define FONT_ADSTYLE "[^-]*"
3403#define FONT_PIXELSIZE "[^-]*"
3404#define FONT_POINTSIZE "\\([0-9][0-9]+\\|\\*\\)" /* 5 */
3405#define FONT_RESX "[0-9][0-9]+"
3406#define FONT_RESY "[0-9][0-9]+"
3407#define FONT_SPACING "[cmp?*]"
3408#define FONT_AVGWIDTH "[0-9]+"
3409#define FONT_REGISTRY "[^-]+"
3410#define FONT_ENCODING "[^-]+"
3411
3412#define FONT_REGEXP ("\\`\\*?[-?*]" \
3413 FONT_FOUNDRY "-" \
3414 FONT_FAMILY "-" \
3415 FONT_WEIGHT_Q "-" \
3416 FONT_SLANT_Q "-" \
3417 FONT_SWIDTH "-" \
3418 FONT_ADSTYLE "-" \
3419 FONT_PIXELSIZE "-" \
3420 FONT_POINTSIZE "-" \
3421 "[-?*]\\|\\'")
3422
3423#define FONT_REGEXP_HEAD ("\\`[-?*]" \
3424 FONT_FOUNDRY "-" \
3425 FONT_FAMILY "-" \
3426 FONT_WEIGHT_Q "-" \
3427 FONT_SLANT_Q \
3428 "\\([-*?]\\|\\'\\)")
3429
3430#define FONT_REGEXP_SLANT "-" FONT_SLANT "-"
3431#define FONT_REGEXP_WEIGHT "-" FONT_WEIGHT "-"
3432
3433LONG
3434x_to_win32_weight (lpw)
3435 char * lpw;
3436{
3437 if (!lpw) return (FW_DONTCARE);
3438
7fb46567
GV
3439 if (stricmp (lpw, "heavy") == 0)
3440 return (FW_HEAVY);
3441 else if (stricmp (lpw, "extrabold") == 0)
3442 return (FW_EXTRABOLD);
3443 else if (stricmp (lpw, "bold") == 0)
ee78dc32
GV
3444 return (FW_BOLD);
3445 else if (stricmp (lpw, "demibold") == 0)
3446 return (FW_SEMIBOLD);
3447 else if (stricmp (lpw, "medium") == 0)
3448 return (FW_MEDIUM);
3449 else if (stricmp (lpw, "normal") == 0)
3450 return (FW_NORMAL);
7fb46567
GV
3451 else if (stricmp (lpw, "light") == 0)
3452 return (FW_LIGHT);
3453 else if (stricmp (lpw, "extralight") == 0)
3454 return (FW_EXTRALIGHT);
3455 else if (stricmp (lpw, "thin") == 0)
3456 return (FW_THIN);
ee78dc32
GV
3457 else
3458 return (FW_DONTCARE);
3459}
3460
7fb46567 3461
ee78dc32
GV
3462char *
3463win32_to_x_weight (fnweight)
3464 int fnweight;
3465{
7fb46567
GV
3466 if (fnweight >= FW_HEAVY)
3467 return "heavy";
3468 else if (fnweight >= FW_EXTRABOLD)
3469 return "extrabold";
3470 else if (fnweight >= FW_BOLD)
3471 return "bold";
3472 else if (fnweight >= FW_SEMIBOLD)
3473 return "semibold";
3474 else if (fnweight >= FW_MEDIUM)
3475 return "medium";
3476 else if (fnweight >= FW_NORMAL)
3477 return "normal";
3478 else if (fnweight >= FW_LIGHT)
3479 return "light";
3480 else if (fnweight >= FW_EXTRALIGHT)
3481 return "extralight";
3482 else if (fnweight >= FW_THIN)
3483 return "thin";
3484 else
3485 return "*";
3486}
3487
3488LONG
3489x_to_win32_charset (lpcs)
3490 char * lpcs;
3491{
3492 if (!lpcs) return (0);
3493
3494 if (stricmp (lpcs, "ansi") == 0)
3495 return (ANSI_CHARSET);
3496 else if (stricmp (lpcs, "iso8859-1") == 0)
3497 return (ANSI_CHARSET);
3498 else if (stricmp (lpcs, "iso8859") == 0)
3499 return (ANSI_CHARSET);
3500 else if (stricmp (lpcs, "oem") == 0)
3501 return (OEM_CHARSET);
3502#ifdef UNICODE_CHARSET
3503 else if (stricmp (lpcs, "unicode") == 0)
3504 return (UNICODE_CHARSET);
3505 else if (stricmp (lpcs, "iso10646") == 0)
3506 return (UNICODE_CHARSET);
3507#endif
3508 else
3509 return (0);
3510}
3511
3512char *
3513win32_to_x_charset (fncharset)
3514 int fncharset;
3515{
3516 switch (fncharset)
3517 {
3518 case ANSI_CHARSET: return "ansi";
3519 case OEM_CHARSET: return "oem";
3520 case SYMBOL_CHARSET: return "symbol";
3521#ifdef UNICODE_CHARSET
3522 case UNICODE_CHARSET: return "unicode";
3523#endif
3524 }
3525 return "*";
ee78dc32
GV
3526}
3527
3528BOOL
3529win32_to_x_font (lplogfont, lpxstr, len)
3530 LOGFONT * lplogfont;
3531 char * lpxstr;
3532 int len;
3533{
3534 if (!lpxstr) return (FALSE);
3535
7fb46567 3536 if (lplogfont)
ee78dc32 3537 {
ee78dc32 3538 _snprintf (lpxstr, len - 1,
7fb46567 3539 "-*-%s-%s-%c-*-*-%d-%d-*-*-%c-%d-*-%s-",
ee78dc32
GV
3540 lplogfont->lfFaceName,
3541 win32_to_x_weight (lplogfont->lfWeight),
3542 lplogfont->lfItalic ? 'i' : 'r',
7fb46567
GV
3543 abs (lplogfont->lfHeight),
3544 (abs (lplogfont->lfHeight) * 720) / one_win32_display_info.height_in,
ee78dc32 3545 ((lplogfont->lfPitchAndFamily & 0x3) == VARIABLE_PITCH) ? 'p' : 'c',
7fb46567
GV
3546 lplogfont->lfWidth * 10,
3547 win32_to_x_charset (lplogfont->lfCharSet)
3548 );
3549 }
3550 else
ee78dc32
GV
3551 {
3552 strncpy (lpxstr, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*-", len - 1);
3553 }
7fb46567 3554
ee78dc32
GV
3555 lpxstr[len - 1] = 0; /* just to be sure */
3556 return (TRUE);
3557}
3558
3559BOOL
3560x_to_win32_font (lpxstr, lplogfont)
3561 char * lpxstr;
3562 LOGFONT * lplogfont;
3563{
3564 if (!lplogfont) return (FALSE);
3565
3566 memset (lplogfont, 0, sizeof (*lplogfont));
3567
ee78dc32
GV
3568 lplogfont->lfOutPrecision = OUT_DEFAULT_PRECIS;
3569 lplogfont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
3570 lplogfont->lfQuality = DEFAULT_QUALITY;
3571
7fb46567
GV
3572 if (!lpxstr)
3573 return FALSE;
3574
3575 /* Provide a simple escape mechanism for specifying Windows font names
3576 * directly -- if font spec does not beginning with '-', assume this
3577 * format:
3578 * "<font name>[:height in pixels[:width in pixels[:weight]]]"
3579 */
ee78dc32 3580
7fb46567
GV
3581 if (*lpxstr == '-')
3582 {
3583 int fields;
3584 char name[50], weight[20], slant, pitch, pixels[10], height[10], width[10], remainder[20];
3585 char * encoding;
3586
3587 fields = sscanf (lpxstr,
3588 "-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%*[^-]-%c-%9[^-]-%19s",
3589 name, weight, &slant, pixels, height, &pitch, width, remainder);
3590
3591 if (fields == EOF) return (FALSE);
3592
3593 if (fields > 0 && name[0] != '*')
3594 {
3595 strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
3596 lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
3597 }
3598 else
ee78dc32 3599 lplogfont->lfFaceName[0] = 0;
7fb46567
GV
3600
3601 fields--;
3602
3603 lplogfont->lfWeight = x_to_win32_weight((fields > 0 ? weight : ""));
3604
3605 fields--;
3606
3607 if (!NILP (Vwin32_enable_italics))
3608 lplogfont->lfItalic = (fields > 0 && slant == 'i');
3609
3610 fields--;
3611
3612 if (fields > 0 && pixels[0] != '*')
3613 lplogfont->lfHeight = atoi (pixels);
3614
3615 fields--;
3616
3617 if (fields > 0 && lplogfont->lfHeight == 0 && height[0] != '*')
3618 lplogfont->lfHeight = (atoi (height)
3619 * one_win32_display_info.height_in) / 720;
3620
3621 fields--;
3622
3623 lplogfont->lfPitchAndFamily =
3624 (fields > 0 && pitch == 'p') ? VARIABLE_PITCH : FIXED_PITCH;
3625
3626 fields--;
3627
3628 if (fields > 0 && width[0] != '*')
3629 lplogfont->lfWidth = atoi (width) / 10;
3630
3631 fields--;
3632
3633 /* Not all font specs include the registry field, so we allow for an
3634 optional registry field before the encoding when parsing
3635 remainder. Also we strip the trailing '-' if present. */
3636 {
3637 int len = strlen (remainder);
3638 if (len > 0 && remainder[len-1] == '-')
3639 remainder[len-1] = 0;
ee78dc32 3640 }
7fb46567
GV
3641 encoding = remainder;
3642 if (strncmp (encoding, "*-", 2) == 0)
3643 encoding += 2;
3644 lplogfont->lfCharSet = x_to_win32_charset (fields > 0 ? encoding : "");
3645 }
3646 else
3647 {
3648 int fields;
3649 char name[100], height[10], width[10], weight[20];
3650
3651 fields = sscanf (lpxstr,
3652 "%99[^:]:%9[^:]:%9[^:]:%19s",
3653 name, height, width, weight);
3654
3655 if (fields == EOF) return (FALSE);
3656
3657 if (fields > 0)
3658 {
3659 strncpy (lplogfont->lfFaceName,name, LF_FACESIZE);
3660 lplogfont->lfFaceName[LF_FACESIZE-1] = 0;
3661 }
3662 else
3663 {
3664 lplogfont->lfFaceName[0] = 0;
3665 }
3666
3667 fields--;
3668
3669 if (fields > 0)
3670 lplogfont->lfHeight = atoi (height);
3671
3672 fields--;
3673
3674 if (fields > 0)
3675 lplogfont->lfWidth = atoi (width);
3676
3677 fields--;
3678
3679 lplogfont->lfWeight = x_to_win32_weight ((fields > 0 ? weight : ""));
3680 }
ee78dc32
GV
3681
3682 return (TRUE);
3683}
3684
3685BOOL
3686win32_font_match (lpszfont1, lpszfont2)
3687 char * lpszfont1;
3688 char * lpszfont2;
3689{
3690 char * s1 = lpszfont1, *e1;
3691 char * s2 = lpszfont2, *e2;
3692
3693 if (s1 == NULL || s2 == NULL) return (FALSE);
3694
3695 if (*s1 == '-') s1++;
3696 if (*s2 == '-') s2++;
3697
3698 while (1)
3699 {
3700 int len1, len2;
3701
3702 e1 = strchr (s1, '-');
3703 e2 = strchr (s2, '-');
3704
3705 if (e1 == NULL || e2 == NULL) return (TRUE);
3706
3707 len1 = e1 - s1;
3708 len2 = e2 - s2;
3709
3710 if (*s1 != '*' && *s2 != '*'
3711 && (len1 != len2 || strnicmp (s1, s2, len1) != 0))
3712 return (FALSE);
3713
3714 s1 = e1 + 1;
3715 s2 = e2 + 1;
3716 }
3717}
3718
3719typedef struct enumfont_t
3720{
3721 HDC hdc;
3722 int numFonts;
3723 XFontStruct *size_ref;
3724 Lisp_Object *pattern;
3725 Lisp_Object *head;
3726 Lisp_Object *tail;
3727} enumfont_t;
3728
3729int CALLBACK
3730enum_font_cb2 (lplf, lptm, FontType, lpef)
3731 ENUMLOGFONT * lplf;
3732 NEWTEXTMETRIC * lptm;
3733 int FontType;
3734 enumfont_t * lpef;
3735{
3736 if (lplf->elfLogFont.lfStrikeOut || lplf->elfLogFont.lfUnderline
3737 || (lplf->elfLogFont.lfCharSet != ANSI_CHARSET && lplf->elfLogFont.lfCharSet != OEM_CHARSET))
3738 return (1);
3739
3740 /* if (!lpef->size_ref || lptm->tmMaxCharWidth == FONT_WIDTH (lpef->size_ref)) */
3741 {
3742 char buf[100];
3743
3744 if (!win32_to_x_font (lplf, buf, 100)) return (0);
3745
3746 if (NILP (*(lpef->pattern)) || win32_font_match (buf, XSTRING (*(lpef->pattern))->data))
3747 {
3748 *lpef->tail = Fcons (build_string (buf), Qnil);
3749 lpef->tail = &XCONS (*lpef->tail)->cdr;
3750 lpef->numFonts++;
3751 }
3752 }
3753
3754 return (1);
3755}
3756
3757int CALLBACK
3758enum_font_cb1 (lplf, lptm, FontType, lpef)
3759 ENUMLOGFONT * lplf;
3760 NEWTEXTMETRIC * lptm;
3761 int FontType;
3762 enumfont_t * lpef;
3763{
3764 return EnumFontFamilies (lpef->hdc,
3765 lplf->elfLogFont.lfFaceName,
3766 (FONTENUMPROC) enum_font_cb2,
3767 (LPARAM) lpef);
3768}
3769
3770
3771DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 3, 0,
3772 "Return a list of the names of available fonts matching PATTERN.\n\
3773If optional arguments FACE and FRAME are specified, return only fonts\n\
3774the same size as FACE on FRAME.\n\
3775\n\
3776PATTERN is a string, perhaps with wildcard characters;\n\
3777 the * character matches any substring, and\n\
3778 the ? character matches any single character.\n\
3779 PATTERN is case-insensitive.\n\
3780FACE is a face name--a symbol.\n\
3781\n\
3782The return value is a list of strings, suitable as arguments to\n\
3783set-face-font.\n\
3784\n\
3785Fonts Emacs can't use (i.e. proportional fonts) may or may not be excluded\n\
3786even if they match PATTERN and FACE.")
3787 (pattern, face, frame)
3788 Lisp_Object pattern, face, frame;
3789{
3790 int num_fonts;
3791 char **names;
3792 XFontStruct *info;
3793 XFontStruct *size_ref;
3794 Lisp_Object namelist;
3795 Lisp_Object list;
3796 FRAME_PTR f;
3797 enumfont_t ef;
3798
3799 CHECK_STRING (pattern, 0);
3800 if (!NILP (face))
3801 CHECK_SYMBOL (face, 1);
3802
3803 f = check_x_frame (frame);
3804
3805 /* Determine the width standard for comparison with the fonts we find. */
3806
3807 if (NILP (face))
3808 size_ref = 0;
3809 else
3810 {
3811 int face_id;
3812
3813 /* Don't die if we get called with a terminal frame. */
3814 if (! FRAME_WIN32_P (f))
3815 error ("non-win32 frame used in `x-list-fonts'");
3816
3817 face_id = face_name_id_number (f, face);
3818
3819 if (face_id < 0 || face_id >= FRAME_N_PARAM_FACES (f)
3820 || FRAME_PARAM_FACES (f) [face_id] == 0)
3821 size_ref = f->output_data.win32->font;
3822 else
3823 {
3824 size_ref = FRAME_PARAM_FACES (f) [face_id]->font;
3825 if (size_ref == (XFontStruct *) (~0))
3826 size_ref = f->output_data.win32->font;
3827 }
3828 }
3829
3830 /* See if we cached the result for this particular query. */
3831 list = Fassoc (pattern,
3832 XCONS (FRAME_WIN32_DISPLAY_INFO (f)->name_list_element)->cdr);
3833
3834 /* We have info in the cache for this PATTERN. */
3835 if (!NILP (list))
3836 {
3837 Lisp_Object tem, newlist;
3838
3839 /* We have info about this pattern. */
3840 list = XCONS (list)->cdr;
3841
3842 if (size_ref == 0)
3843 return list;
3844
3845 BLOCK_INPUT;
3846
3847 /* Filter the cached info and return just the fonts that match FACE. */
3848 newlist = Qnil;
3849 for (tem = list; CONSP (tem); tem = XCONS (tem)->cdr)
3850 {
3851 XFontStruct *thisinfo;
3852
3853 thisinfo = win32_load_font (FRAME_WIN32_DISPLAY_INFO (f), XSTRING (XCONS (tem)->car)->data);
3854
3855 if (thisinfo && same_size_fonts (thisinfo, size_ref))
3856 newlist = Fcons (XCONS (tem)->car, newlist);
3857
3858 win32_unload_font (FRAME_WIN32_DISPLAY_INFO (f), thisinfo);
3859 }
3860
3861 UNBLOCK_INPUT;
3862
3863 return newlist;
3864 }
3865
3866 BLOCK_INPUT;
3867
3868 namelist = Qnil;
3869 ef.pattern = &pattern;
3870 ef.tail = ef.head = &namelist;
3871 ef.numFonts = 0;
3872
3873 {
7fb46567 3874 ef.hdc = GetDC (FRAME_WIN32_WINDOW (f));
ee78dc32
GV
3875
3876 EnumFontFamilies (ef.hdc, NULL, (FONTENUMPROC) enum_font_cb1, (LPARAM)&ef);
3877
3878 ReleaseDC (FRAME_WIN32_WINDOW (f), ef.hdc);
3879 }
3880
3881 UNBLOCK_INPUT;
3882
3883 if (ef.numFonts)
3884 {
3885 int i;
3886 Lisp_Object cur;
3887
3888 /* Make a list of all the fonts we got back.
3889 Store that in the font cache for the display. */
3890 XCONS (FRAME_WIN32_DISPLAY_INFO (f)->name_list_element)->cdr
3891 = Fcons (Fcons (pattern, namelist),
3892 XCONS (FRAME_WIN32_DISPLAY_INFO (f)->name_list_element)->cdr);
3893
3894 /* Make a list of the fonts that have the right width. */
3895 list = Qnil;
3896 cur=namelist;
3897 for (i = 0; i < ef.numFonts; i++)
3898 {
3899 int keeper;
3900
3901 if (!size_ref)
3902 keeper = 1;
3903 else
3904 {
3905 XFontStruct *thisinfo;
3906
3907 BLOCK_INPUT;
3908 thisinfo = win32_load_font (FRAME_WIN32_DISPLAY_INFO (f), XSTRING (Fcar (cur))->data);
3909
3910 keeper = thisinfo && same_size_fonts (thisinfo, size_ref);
3911
3912 win32_unload_font (FRAME_WIN32_DISPLAY_INFO (f), thisinfo);
3913
3914 UNBLOCK_INPUT;
3915 }
3916 if (keeper)
3917 list = Fcons (build_string (XSTRING (Fcar (cur))->data), list);
3918
3919 cur = Fcdr (cur);
3920 }
3921 list = Fnreverse (list);
3922 }
3923
3924 return list;
3925}
3926\f
3927DEFUN ("x-color-defined-p", Fx_color_defined_p, Sx_color_defined_p, 1, 2, 0,
3928 "Return non-nil if color COLOR is supported on frame FRAME.\n\
3929If FRAME is omitted or nil, use the selected frame.")
3930 (color, frame)
3931 Lisp_Object color, frame;
3932{
3933 COLORREF foo;
3934 FRAME_PTR f = check_x_frame (frame);
3935
3936 CHECK_STRING (color, 1);
3937
3938 if (defined_color (f, XSTRING (color)->data, &foo, 0))
3939 return Qt;
3940 else
3941 return Qnil;
3942}
3943
3944DEFUN ("x-color-values", Fx_color_values, Sx_color_values, 1, 2, 0,
3945 "Return a description of the color named COLOR on frame FRAME.\n\
3946The value is a list of integer RGB values--(RED GREEN BLUE).\n\
3947These values appear to range from 0 to 65280 or 65535, depending\n\
3948on the system; white is (65280 65280 65280) or (65535 65535 65535).\n\
3949If FRAME is omitted or nil, use the selected frame.")
3950 (color, frame)
3951 Lisp_Object color, frame;
3952{
3953 COLORREF foo;
3954 FRAME_PTR f = check_x_frame (frame);
3955
3956 CHECK_STRING (color, 1);
3957
3958 if (defined_color (f, XSTRING (color)->data, &foo, 0))
3959 {
3960 Lisp_Object rgb[3];
3961
3962 rgb[0] = make_number (GetRValue (foo));
3963 rgb[1] = make_number (GetGValue (foo));
3964 rgb[2] = make_number (GetBValue (foo));
3965 return Flist (3, rgb);
3966 }
3967 else
3968 return Qnil;
3969}
3970
3971DEFUN ("x-display-color-p", Fx_display_color_p, Sx_display_color_p, 0, 1, 0,
3972 "Return t if the X display supports color.\n\
3973The optional argument DISPLAY specifies which display to ask about.\n\
3974DISPLAY should be either a frame or a display name (a string).\n\
3975If omitted or nil, that stands for the selected frame's display.")
3976 (display)
3977 Lisp_Object display;
3978{
3979 struct win32_display_info *dpyinfo = check_x_display_info (display);
3980
3981 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 2)
3982 return Qnil;
3983
3984 return Qt;
3985}
3986
3987DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
3988 0, 1, 0,
3989 "Return t if the X display supports shades of gray.\n\
3990Note that color displays do support shades of gray.\n\
3991The optional argument DISPLAY specifies which display to ask about.\n\
3992DISPLAY should be either a frame or a display name (a string).\n\
3993If omitted or nil, that stands for the selected frame's display.")
3994 (display)
3995 Lisp_Object display;
3996{
3997 struct win32_display_info *dpyinfo = check_x_display_info (display);
3998
3999 if ((dpyinfo->n_planes * dpyinfo->n_cbits) <= 1)
4000 return Qnil;
4001
4002 return Qt;
4003}
4004
4005DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
4006 0, 1, 0,
4007 "Returns the width in pixels of the X display DISPLAY.\n\
4008The optional argument DISPLAY specifies which display to ask about.\n\
4009DISPLAY should be either a frame or a display name (a string).\n\
4010If omitted or nil, that stands for the selected frame's display.")
4011 (display)
4012 Lisp_Object display;
4013{
4014 struct win32_display_info *dpyinfo = check_x_display_info (display);
4015
4016 return make_number (dpyinfo->width);
4017}
4018
4019DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
4020 Sx_display_pixel_height, 0, 1, 0,
4021 "Returns the height in pixels of the X display DISPLAY.\n\
4022The optional argument DISPLAY specifies which display to ask about.\n\
4023DISPLAY should be either a frame or a display name (a string).\n\
4024If omitted or nil, that stands for the selected frame's display.")
4025 (display)
4026 Lisp_Object display;
4027{
4028 struct win32_display_info *dpyinfo = check_x_display_info (display);
4029
4030 return make_number (dpyinfo->height);
4031}
4032
4033DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
4034 0, 1, 0,
4035 "Returns the number of bitplanes of the display DISPLAY.\n\
4036The optional argument DISPLAY specifies which display to ask about.\n\
4037DISPLAY should be either a frame or a display name (a string).\n\
4038If omitted or nil, that stands for the selected frame's display.")
4039 (display)
4040 Lisp_Object display;
4041{
4042 struct win32_display_info *dpyinfo = check_x_display_info (display);
4043
4044 return make_number (dpyinfo->n_planes * dpyinfo->n_cbits);
4045}
4046
4047DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
4048 0, 1, 0,
4049 "Returns the number of color cells of the display DISPLAY.\n\
4050The optional argument DISPLAY specifies which display to ask about.\n\
4051DISPLAY should be either a frame or a display name (a string).\n\
4052If omitted or nil, that stands for the selected frame's display.")
4053 (display)
4054 Lisp_Object display;
4055{
4056 struct win32_display_info *dpyinfo = check_x_display_info (display);
4057 HDC hdc;
4058 int cap;
4059
7fb46567
GV
4060 hdc = GetDC (dpyinfo->root_window);
4061 if (dpyinfo->has_palette)
4062 cap = GetDeviceCaps (hdc, SIZEPALETTE);
4063 else
4064 cap = GetDeviceCaps (hdc, NUMCOLORS);
ee78dc32
GV
4065
4066 ReleaseDC (dpyinfo->root_window, hdc);
4067
4068 return make_number (cap);
4069}
4070
4071DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
4072 Sx_server_max_request_size,
4073 0, 1, 0,
4074 "Returns the maximum request size of the server of display DISPLAY.\n\
4075The optional argument DISPLAY specifies which display to ask about.\n\
4076DISPLAY should be either a frame or a display name (a string).\n\
4077If omitted or nil, that stands for the selected frame's display.")
4078 (display)
4079 Lisp_Object display;
4080{
4081 struct win32_display_info *dpyinfo = check_x_display_info (display);
4082
4083 return make_number (1);
4084}
4085
4086DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
4087 "Returns the vendor ID string of the Win32 system (Microsoft).\n\
4088The optional argument DISPLAY specifies which display to ask about.\n\
4089DISPLAY should be either a frame or a display name (a string).\n\
4090If omitted or nil, that stands for the selected frame's display.")
4091 (display)
4092 Lisp_Object display;
4093{
4094 struct win32_display_info *dpyinfo = check_x_display_info (display);
4095 char *vendor = "Microsoft Corp.";
4096
4097 if (! vendor) vendor = "";
4098 return build_string (vendor);
4099}
4100
4101DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
4102 "Returns the version numbers of the server of display DISPLAY.\n\
4103The value is a list of three integers: the major and minor\n\
4104version numbers, and the vendor-specific release\n\
4105number. See also the function `x-server-vendor'.\n\n\
4106The optional argument DISPLAY specifies which display to ask about.\n\
4107DISPLAY should be either a frame or a display name (a string).\n\
4108If omitted or nil, that stands for the selected frame's display.")
4109 (display)
4110 Lisp_Object display;
4111{
4112 struct win32_display_info *dpyinfo = check_x_display_info (display);
4113
4114 return Fcons (make_number (nt_major_version),
4115 Fcons (make_number (nt_minor_version), Qnil));
4116}
4117
4118DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
4119 "Returns the number of screens on the server of display DISPLAY.\n\
4120The optional argument DISPLAY specifies which display to ask about.\n\
4121DISPLAY should be either a frame or a display name (a string).\n\
4122If omitted or nil, that stands for the selected frame's display.")
4123 (display)
4124 Lisp_Object display;
4125{
4126 struct win32_display_info *dpyinfo = check_x_display_info (display);
4127
4128 return make_number (1);
4129}
4130
4131DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
4132 "Returns the height in millimeters of the X display DISPLAY.\n\
4133The optional argument DISPLAY specifies which display to ask about.\n\
4134DISPLAY should be either a frame or a display name (a string).\n\
4135If omitted or nil, that stands for the selected frame's display.")
4136 (display)
4137 Lisp_Object display;
4138{
4139 struct win32_display_info *dpyinfo = check_x_display_info (display);
4140 HDC hdc;
4141 int cap;
4142
7fb46567 4143 hdc = GetDC (dpyinfo->root_window);
ee78dc32 4144 cap = GetDeviceCaps (hdc, VERTSIZE);
ee78dc32
GV
4145 ReleaseDC (dpyinfo->root_window, hdc);
4146
4147 return make_number (cap);
4148}
4149
4150DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
4151 "Returns the width in millimeters of the X display DISPLAY.\n\
4152The optional argument DISPLAY specifies which display to ask about.\n\
4153DISPLAY should be either a frame or a display name (a string).\n\
4154If omitted or nil, that stands for the selected frame's display.")
4155 (display)
4156 Lisp_Object display;
4157{
4158 struct win32_display_info *dpyinfo = check_x_display_info (display);
4159
4160 HDC hdc;
4161 int cap;
4162
7fb46567 4163 hdc = GetDC (dpyinfo->root_window);
ee78dc32 4164 cap = GetDeviceCaps (hdc, HORZSIZE);
ee78dc32
GV
4165 ReleaseDC (dpyinfo->root_window, hdc);
4166
4167 return make_number (cap);
4168}
4169
4170DEFUN ("x-display-backing-store", Fx_display_backing_store,
4171 Sx_display_backing_store, 0, 1, 0,
4172 "Returns an indication of whether display DISPLAY does backing store.\n\
4173The value may be `always', `when-mapped', or `not-useful'.\n\
4174The optional argument DISPLAY specifies which display to ask about.\n\
4175DISPLAY should be either a frame or a display name (a string).\n\
4176If omitted or nil, that stands for the selected frame's display.")
4177 (display)
4178 Lisp_Object display;
4179{
4180 return intern ("not-useful");
4181}
4182
4183DEFUN ("x-display-visual-class", Fx_display_visual_class,
4184 Sx_display_visual_class, 0, 1, 0,
4185 "Returns the visual class of the display DISPLAY.\n\
4186The value is one of the symbols `static-gray', `gray-scale',\n\
4187`static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
4188The optional argument DISPLAY specifies which display to ask about.\n\
4189DISPLAY should be either a frame or a display name (a string).\n\
4190If omitted or nil, that stands for the selected frame's display.")
4191 (display)
4192 Lisp_Object display;
4193{
4194 struct win32_display_info *dpyinfo = check_x_display_info (display);
4195
4196#if 0
4197 switch (dpyinfo->visual->class)
4198 {
4199 case StaticGray: return (intern ("static-gray"));
4200 case GrayScale: return (intern ("gray-scale"));
4201 case StaticColor: return (intern ("static-color"));
4202 case PseudoColor: return (intern ("pseudo-color"));
4203 case TrueColor: return (intern ("true-color"));
4204 case DirectColor: return (intern ("direct-color"));
4205 default:
4206 error ("Display has an unknown visual class");
4207 }
4208#endif
4209
4210 error ("Display has an unknown visual class");
4211}
4212
4213DEFUN ("x-display-save-under", Fx_display_save_under,
4214 Sx_display_save_under, 0, 1, 0,
4215 "Returns t if the display DISPLAY supports the save-under feature.\n\
4216The optional argument DISPLAY specifies which display to ask about.\n\
4217DISPLAY should be either a frame or a display name (a string).\n\
4218If omitted or nil, that stands for the selected frame's display.")
4219 (display)
4220 Lisp_Object display;
4221{
4222 struct win32_display_info *dpyinfo = check_x_display_info (display);
4223
4224 return Qnil;
4225}
4226\f
4227int
4228x_pixel_width (f)
4229 register struct frame *f;
4230{
4231 return PIXEL_WIDTH (f);
4232}
4233
4234int
4235x_pixel_height (f)
4236 register struct frame *f;
4237{
4238 return PIXEL_HEIGHT (f);
4239}
4240
4241int
4242x_char_width (f)
4243 register struct frame *f;
4244{
4245 return FONT_WIDTH (f->output_data.win32->font);
4246}
4247
4248int
4249x_char_height (f)
4250 register struct frame *f;
4251{
4252 return f->output_data.win32->line_height;
4253}
4254
4255int
4256x_screen_planes (frame)
4257 Lisp_Object frame;
4258{
4259 return (FRAME_WIN32_DISPLAY_INFO (XFRAME (frame))->n_planes *
4260 FRAME_WIN32_DISPLAY_INFO (XFRAME (frame))->n_cbits);
4261}
4262\f
4263/* Return the display structure for the display named NAME.
4264 Open a new connection if necessary. */
4265
4266struct win32_display_info *
4267x_display_info_for_name (name)
4268 Lisp_Object name;
4269{
4270 Lisp_Object names;
4271 struct win32_display_info *dpyinfo;
4272
4273 CHECK_STRING (name, 0);
4274
4275 for (dpyinfo = &one_win32_display_info, names = win32_display_name_list;
4276 dpyinfo;
4277 dpyinfo = dpyinfo->next, names = XCONS (names)->cdr)
4278 {
4279 Lisp_Object tem;
4280 tem = Fstring_equal (XCONS (XCONS (names)->car)->car, name);
4281 if (!NILP (tem))
4282 return dpyinfo;
4283 }
4284
4285 /* Use this general default value to start with. */
4286 Vx_resource_name = Vinvocation_name;
4287
4288 validate_x_resource_name ();
4289
4290 dpyinfo = win32_term_init (name, (unsigned char *)0,
4291 (char *) XSTRING (Vx_resource_name)->data);
4292
4293 if (dpyinfo == 0)
4294 error ("Cannot connect to server %s", XSTRING (name)->data);
4295
4296 XSETFASTINT (Vwindow_system_version, 3);
4297
4298 return dpyinfo;
4299}
4300
4301DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
4302 1, 3, 0, "Open a connection to a server.\n\
4303DISPLAY is the name of the display to connect to.\n\
4304Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
4305If the optional third arg MUST-SUCCEED is non-nil,\n\
4306terminate Emacs if we can't open the connection.")
4307 (display, xrm_string, must_succeed)
4308 Lisp_Object display, xrm_string, must_succeed;
4309{
4310 unsigned int n_planes;
4311 unsigned char *xrm_option;
4312 struct win32_display_info *dpyinfo;
7fb46567 4313 Lisp_Object color_file = Qnil;
ee78dc32
GV
4314
4315 CHECK_STRING (display, 0);
4316 if (! NILP (xrm_string))
4317 CHECK_STRING (xrm_string, 1);
4318
7fb46567
GV
4319 /* Allow color mapping to be defined externally; first look in user's
4320 HOME directory, then in Emacs etc dir for a file called rgb.txt. */
4321 color_file = build_string ("~/rgb.txt");
4322 if (NILP (color_file) || NILP (Ffile_readable_p (color_file)))
4323 color_file = concat2 (Vdoc_directory, build_string ("rgb.txt"));
4324
4325 Vwin32_color_map = Fwin32_load_color_file (color_file);
4326
4327 if (NILP (Vwin32_color_map))
4328 Vwin32_color_map = Fwin32_default_color_map ();
ee78dc32
GV
4329
4330 if (! NILP (xrm_string))
4331 xrm_option = (unsigned char *) XSTRING (xrm_string)->data;
4332 else
4333 xrm_option = (unsigned char *) 0;
4334
4335 /* Use this general default value to start with. */
4336 Vx_resource_name = Vinvocation_name;
4337
4338 validate_x_resource_name ();
4339
4340 /* This is what opens the connection and sets x_current_display.
4341 This also initializes many symbols, such as those used for input. */
4342 dpyinfo = win32_term_init (display, xrm_option,
4343 (char *) XSTRING (Vx_resource_name)->data);
4344
4345 if (dpyinfo == 0)
4346 {
4347 if (!NILP (must_succeed))
7fb46567 4348 fatal ("Cannot connect to server %s.\n", XSTRING (display)->data);
ee78dc32
GV
4349 else
4350 error ("Cannot connect to server %s", XSTRING (display)->data);
4351 }
4352
4353 XSETFASTINT (Vwindow_system_version, 3);
4354 return Qnil;
4355}
4356
4357DEFUN ("x-close-connection", Fx_close_connection,
4358 Sx_close_connection, 1, 1, 0,
4359 "Close the connection to DISPLAY's server.\n\
4360For DISPLAY, specify either a frame or a display name (a string).\n\
4361If DISPLAY is nil, that stands for the selected frame's display.")
4362 (display)
4363 Lisp_Object display;
4364{
4365 struct win32_display_info *dpyinfo = check_x_display_info (display);
4366 struct win32_display_info *tail;
4367 int i;
4368
4369 if (dpyinfo->reference_count > 0)
4370 error ("Display still has frames on it");
4371
4372 BLOCK_INPUT;
4373 /* Free the fonts in the font table. */
4374 for (i = 0; i < dpyinfo->n_fonts; i++)
4375 {
4376 if (dpyinfo->font_table[i].name)
4377 free (dpyinfo->font_table[i].name);
4378 /* Don't free the full_name string;
4379 it is always shared with something else. */
4380 win32_unload_font (dpyinfo, dpyinfo->font_table[i].font);
4381 }
4382 x_destroy_all_bitmaps (dpyinfo);
4383
4384 x_delete_display (dpyinfo);
4385 UNBLOCK_INPUT;
4386
4387 return Qnil;
4388}
4389
4390DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
4391 "Return the list of display names that Emacs has connections to.")
4392 ()
4393{
4394 Lisp_Object tail, result;
4395
4396 result = Qnil;
4397 for (tail = win32_display_name_list; ! NILP (tail); tail = XCONS (tail)->cdr)
4398 result = Fcons (XCONS (XCONS (tail)->car)->car, result);
4399
4400 return result;
4401}
4402
4403DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
4404 "If ON is non-nil, report errors as soon as the erring request is made.\n\
4405If ON is nil, allow buffering of requests.\n\
4406This is a noop on Win32 systems.\n\
4407The optional second argument DISPLAY specifies which display to act on.\n\
4408DISPLAY should be either a frame or a display name (a string).\n\
4409If DISPLAY is omitted or nil, that stands for the selected frame's display.")
4410 (on, display)
4411 Lisp_Object display, on;
4412{
4413 struct win32_display_info *dpyinfo = check_x_display_info (display);
4414
4415 return Qnil;
4416}
4417
4418\f
4419/* These are the win32 specialized functions */
4420
4421DEFUN ("win32-select-font", Fwin32_select_font, Swin32_select_font, 0, 1, 0,
4422 "This will display the Win32 font dialog and return an X font string corresponding to the selection.")
4423 (frame)
4424 Lisp_Object frame;
4425{
4426 FRAME_PTR f = check_x_frame (frame);
4427 CHOOSEFONT cf;
4428 LOGFONT lf;
4429 char buf[100];
4430
4431 bzero (&cf, sizeof (cf));
4432
4433 cf.lStructSize = sizeof (cf);
4434 cf.hwndOwner = FRAME_WIN32_WINDOW (f);
4435 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST | CF_SCREENFONTS;
4436 cf.lpLogFont = &lf;
4437
4438 if (!ChooseFont (&cf) || !win32_to_x_font (&lf, buf, 100))
7fb46567 4439 return Qnil;
ee78dc32
GV
4440
4441 return build_string (buf);
4442}
4443
4444\f
4445syms_of_win32fns ()
4446{
4447 /* The section below is built by the lisp expression at the top of the file,
4448 just above where these variables are declared. */
4449 /*&&& init symbols here &&&*/
4450 Qauto_raise = intern ("auto-raise");
4451 staticpro (&Qauto_raise);
4452 Qauto_lower = intern ("auto-lower");
4453 staticpro (&Qauto_lower);
4454 Qbackground_color = intern ("background-color");
4455 staticpro (&Qbackground_color);
4456 Qbar = intern ("bar");
4457 staticpro (&Qbar);
4458 Qborder_color = intern ("border-color");
4459 staticpro (&Qborder_color);
4460 Qborder_width = intern ("border-width");
4461 staticpro (&Qborder_width);
4462 Qbox = intern ("box");
4463 staticpro (&Qbox);
4464 Qcursor_color = intern ("cursor-color");
4465 staticpro (&Qcursor_color);
4466 Qcursor_type = intern ("cursor-type");
4467 staticpro (&Qcursor_type);
4468 Qfont = intern ("font");
4469 staticpro (&Qfont);
4470 Qforeground_color = intern ("foreground-color");
4471 staticpro (&Qforeground_color);
4472 Qgeometry = intern ("geometry");
4473 staticpro (&Qgeometry);
4474 Qicon_left = intern ("icon-left");
4475 staticpro (&Qicon_left);
4476 Qicon_top = intern ("icon-top");
4477 staticpro (&Qicon_top);
4478 Qicon_type = intern ("icon-type");
4479 staticpro (&Qicon_type);
4480 Qicon_name = intern ("icon-name");
4481 staticpro (&Qicon_name);
4482 Qinternal_border_width = intern ("internal-border-width");
4483 staticpro (&Qinternal_border_width);
4484 Qleft = intern ("left");
4485 staticpro (&Qleft);
4486 Qmouse_color = intern ("mouse-color");
4487 staticpro (&Qmouse_color);
4488 Qnone = intern ("none");
4489 staticpro (&Qnone);
4490 Qparent_id = intern ("parent-id");
4491 staticpro (&Qparent_id);
4492 Qscroll_bar_width = intern ("scroll-bar-width");
4493 staticpro (&Qscroll_bar_width);
4494 Qsuppress_icon = intern ("suppress-icon");
4495 staticpro (&Qsuppress_icon);
4496 Qtop = intern ("top");
4497 staticpro (&Qtop);
4498 Qundefined_color = intern ("undefined-color");
4499 staticpro (&Qundefined_color);
4500 Qvertical_scroll_bars = intern ("vertical-scroll-bars");
4501 staticpro (&Qvertical_scroll_bars);
4502 Qvisibility = intern ("visibility");
4503 staticpro (&Qvisibility);
4504 Qwindow_id = intern ("window-id");
4505 staticpro (&Qwindow_id);
4506 Qx_frame_parameter = intern ("x-frame-parameter");
4507 staticpro (&Qx_frame_parameter);
4508 Qx_resource_name = intern ("x-resource-name");
4509 staticpro (&Qx_resource_name);
4510 Quser_position = intern ("user-position");
4511 staticpro (&Quser_position);
4512 Quser_size = intern ("user-size");
4513 staticpro (&Quser_size);
4514 Qdisplay = intern ("display");
4515 staticpro (&Qdisplay);
4516 /* This is the end of symbol initialization. */
4517
4518 Fput (Qundefined_color, Qerror_conditions,
4519 Fcons (Qundefined_color, Fcons (Qerror, Qnil)));
4520 Fput (Qundefined_color, Qerror_message,
4521 build_string ("Undefined color"));
4522
4523 DEFVAR_LISP ("win32-color-map", &Vwin32_color_map,
4524 "A array of color name mappings for windows.");
4525 Vwin32_color_map = Qnil;
4526
7fb46567
GV
4527 DEFVAR_LISP ("win32-enable-italics", &Vwin32_enable_italics,
4528 "Non-nil enables selection of artificially italicized fonts.");
4529 Vwin32_enable_italics = Qnil;
4530
4531 DEFVAR_LISP ("win32-enable-palette", &Vwin32_enable_palette,
4532 "Non-nil enables Windows palette management to map colors exactly.");
4533 Vwin32_enable_palette = Qt;
4534
ee78dc32
GV
4535 init_x_parm_symbols ();
4536
4537 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
4538 "List of directories to search for bitmap files for win32.");
4539 Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH");
4540
4541 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
4542 "The shape of the pointer when over text.\n\
4543Changing the value does not affect existing frames\n\
4544unless you set the mouse color.");
4545 Vx_pointer_shape = Qnil;
4546
4547 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4548 "The name Emacs uses to look up resources; for internal use only.\n\
4549`x-get-resource' uses this as the first component of the instance name\n\
4550when requesting resource values.\n\
4551Emacs initially sets `x-resource-name' to the name under which Emacs\n\
4552was invoked, or to the value specified with the `-name' or `-rn'\n\
4553switches, if present.");
4554 Vx_resource_name = Qnil;
4555
4556 Vx_nontext_pointer_shape = Qnil;
4557
4558 Vx_mode_pointer_shape = Qnil;
4559
4560 DEFVAR_INT ("x-sensitive-text-pointer-shape",
4561 &Vx_sensitive_text_pointer_shape,
4562 "The shape of the pointer when over mouse-sensitive text.\n\
4563This variable takes effect when you create a new frame\n\
4564or when you set the mouse color.");
4565 Vx_sensitive_text_pointer_shape = Qnil;
4566
4567 DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
4568 "A string indicating the foreground color of the cursor box.");
4569 Vx_cursor_fore_pixel = Qnil;
4570
4571 DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
4572 "Non-nil if no window manager is in use.\n\
4573Emacs doesn't try to figure this out; this is always nil\n\
4574unless you set it to something else.");
4575 /* We don't have any way to find this out, so set it to nil
4576 and maybe the user would like to set it to t. */
4577 Vx_no_window_manager = Qnil;
4578
4579 defsubr (&Sx_get_resource);
4580 defsubr (&Sx_list_fonts);
4581 defsubr (&Sx_display_color_p);
4582 defsubr (&Sx_display_grayscale_p);
4583 defsubr (&Sx_color_defined_p);
4584 defsubr (&Sx_color_values);
4585 defsubr (&Sx_server_max_request_size);
4586 defsubr (&Sx_server_vendor);
4587 defsubr (&Sx_server_version);
4588 defsubr (&Sx_display_pixel_width);
4589 defsubr (&Sx_display_pixel_height);
4590 defsubr (&Sx_display_mm_width);
4591 defsubr (&Sx_display_mm_height);
4592 defsubr (&Sx_display_screens);
4593 defsubr (&Sx_display_planes);
4594 defsubr (&Sx_display_color_cells);
4595 defsubr (&Sx_display_visual_class);
4596 defsubr (&Sx_display_backing_store);
4597 defsubr (&Sx_display_save_under);
4598 defsubr (&Sx_parse_geometry);
4599 defsubr (&Sx_create_frame);
4600 defsubr (&Sfocus_frame);
4601 defsubr (&Sunfocus_frame);
4602 defsubr (&Sx_open_connection);
4603 defsubr (&Sx_close_connection);
4604 defsubr (&Sx_display_list);
4605 defsubr (&Sx_synchronize);
4606
4607 /* Win32 specific functions */
4608
4609 defsubr (&Swin32_select_font);
7fb46567
GV
4610 defsubr (&Swin32_define_rgb_color);
4611 defsubr (&Swin32_load_color_file);
ee78dc32
GV
4612}
4613
4614#undef abort
4615
4616void
4617win32_abort()
4618{
7fb46567
GV
4619 MessageBox (NULL,
4620 "A fatal error has occurred - aborting!",
4621 "Emacs Abort Dialog",
4622 MB_OK | MB_ICONEXCLAMATION);
4623 abort();
ee78dc32 4624}