XEmacs 21.2.33 "Melpomene".
[chise/xemacs-chise.git.1] / src / frame-msw.c
1 /* Functions for the mswindows window system.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3    Copyright (C) 1995, 1996 Ben Wing.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Not synched with FSF. */
23
24 /* Authorship:
25
26    Ultimately based on FSF.
27    Substantially rewritten for XEmacs by Ben Wing.
28    Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
29    Graphics features added and frame resizing fiddled with by Andy Piper.
30  */
31
32 #include <config.h>
33 #include "lisp.h"
34
35 #include "buffer.h"
36 #include "elhash.h"
37 #include "console-msw.h"
38 #include "glyphs-msw.h"
39 #include "elhash.h"
40 #include "events.h"
41 #include "faces.h"
42 #include "frame.h"
43 #include "redisplay.h"
44 #include "window.h"
45
46 #define MSWINDOWS_FRAME_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW)
47 #define MSWINDOWS_POPUP_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP \
48                                | WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX)
49
50 #define MSWINDOWS_FRAME_EXSTYLE WS_EX_OVERLAPPEDWINDOW
51 #define MSWINDOWS_POPUP_EXSTYLE WS_EX_PALETTEWINDOW
52
53 /* Default popup left top corner offset from the same
54    corner of the parent frame, in pixel */
55 #define POPUP_OFFSET 30
56
57 /* Default popup size, in characters */
58 #define POPUP_WIDTH 30
59 #define POPUP_HEIGHT 10
60
61 /* Default regular frame size, in characters */
62 #define DEFAULT_FRAME_WIDTH 80
63 #define DEFAULT_FRAME_HEIGHT 35
64
65 #ifdef HAVE_MENUBARS
66 #define ADJR_MENUFLAG TRUE
67 #else
68 #define ADJR_MENUFLAG FALSE
69 #endif
70
71 /* Default properties to use when creating frames.  */
72 Lisp_Object Vdefault_mswindows_frame_plist;
73 Lisp_Object Vdefault_msprinter_frame_plist;
74 Lisp_Object Vmswindows_use_system_frame_size_defaults;
75
76 /* This does not need to be GC protected, as it holds a
77    frame Lisp_Object already protected by Fmake_frame */
78 Lisp_Object Vmswindows_frame_being_created;
79
80 /*---------------------------------------------------------------------*/
81 /*-----                    DISPLAY FRAME                          -----*/
82 /*---------------------------------------------------------------------*/
83
84 static void
85 mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
86 {
87   Lisp_Object initially_unmapped;
88   Lisp_Object name, height, width, popup, top, left;
89   Lisp_Object frame_obj = Qnil;
90   RECT rect;
91   XEMACS_RECT_WH rect_default;
92   DWORD style, exstyle;
93   HWND hwnd, hwnd_parent;
94
95   /* Pick up relevant properties */
96   initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil);
97   name = Fplist_get (props, Qname, Qnil);
98   
99   popup = Fplist_get (props, Qpopup, Qnil);
100   if (EQ (popup, Qt))
101     popup = Fselected_frame (Qnil);
102
103   left = Fplist_get (props, Qleft, Qnil);
104   if (!NILP (left))
105     CHECK_INT (left);
106
107   top = Fplist_get (props, Qtop, Qnil);
108   if (!NILP (top))
109     CHECK_INT (top);
110
111   width = Fplist_get (props, Qwidth, Qnil);
112   if (!NILP (width))
113     CHECK_INT (width);
114
115   height = Fplist_get (props, Qheight, Qnil);
116   if (!NILP (height))
117     CHECK_INT (height);
118
119   f->frame_data = xnew_and_zero (struct mswindows_frame);
120   FRAME_MSWINDOWS_TARGET_RECT (f) = xnew_and_zero (XEMACS_RECT_WH);
121
122   FRAME_MSWINDOWS_TARGET_RECT (f)->left = NILP (left) ? -1 : abs (XINT (left));
123   FRAME_MSWINDOWS_TARGET_RECT (f)->top = NILP (top) ? -1 : abs (XINT (top));
124   FRAME_MSWINDOWS_TARGET_RECT (f)->width = NILP (width) ? -1 : 
125     abs (XINT (width));
126   FRAME_MSWINDOWS_TARGET_RECT (f)->height = NILP (height) ? -1 : 
127     abs (XINT (height));
128       
129   /* Misc frame stuff */
130   FRAME_MSWINDOWS_DATA(f)->button2_need_lbutton = 0;
131   FRAME_MSWINDOWS_DATA(f)->button2_need_rbutton = 0;
132   FRAME_MSWINDOWS_DATA(f)->button2_is_down = 0;
133   FRAME_MSWINDOWS_DATA(f)->ignore_next_lbutton_up = 0;
134   FRAME_MSWINDOWS_DATA(f)->ignore_next_rbutton_up = 0;
135   FRAME_MSWINDOWS_DATA(f)->sizing = 0;
136   FRAME_MSWINDOWS_DATA(f)->paint_pending = 0;
137   FRAME_MSWINDOWS_MENU_HASH_TABLE(f) = Qnil;
138 #ifdef HAVE_TOOLBARS
139   FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f) = 
140     make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
141 #endif
142   /* hashtable of instantiated glyphs on the frame. */
143   FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f) = 
144     make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
145   FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f) = 
146     make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
147   FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f) = 
148     make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
149   /* Will initialize these in WM_SIZE handler. We cannot do it now,
150      because we do not know what is CW_USEDEFAULT height and width */
151   FRAME_WIDTH (f) = 0;
152   FRAME_HEIGHT (f) = 0;
153   FRAME_PIXWIDTH (f) = 0;
154   FRAME_PIXHEIGHT (f) = 0;
155
156   if (NILP (popup))
157     {
158       style = MSWINDOWS_FRAME_STYLE;
159       exstyle = MSWINDOWS_FRAME_EXSTYLE;
160       hwnd_parent = NULL;
161
162       rect_default.left = rect_default.top = CW_USEDEFAULT;
163       rect_default.width = rect_default.height = CW_USEDEFAULT;
164     }
165   else
166     {
167       style = MSWINDOWS_POPUP_STYLE;
168       exstyle = MSWINDOWS_POPUP_EXSTYLE;
169
170       CHECK_MSWINDOWS_FRAME (popup);
171       hwnd_parent = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
172       assert (IsWindow (hwnd_parent));
173
174       /* We cannot use CW_USEDEFAULT when creating a popup window.
175          So by default, we offset the new popup 30 pixels right
176          and down from its parent, and give it size of 30x10 characters.
177          These dimensions look adequate on both high and low res monitors */
178       GetWindowRect (hwnd_parent, &rect);
179       rect_default.left = rect.left + POPUP_OFFSET;
180       rect_default.top = rect.top + POPUP_OFFSET;
181       char_to_real_pixel_size (f, POPUP_WIDTH, POPUP_HEIGHT,
182                                &rect_default.width, &rect_default.height);
183     }
184
185   AdjustWindowRectEx(&rect, style, ADJR_MENUFLAG, exstyle);
186
187   XSETFRAME (frame_obj, f);
188
189   Vmswindows_frame_being_created = frame_obj;
190
191   hwnd = CreateWindowEx (exstyle,
192                          XEMACS_CLASS,
193                          STRINGP(f->name) ? XSTRING_DATA(f->name) :
194                          (STRINGP(name) ? 
195                           (const Extbyte*)XSTRING_DATA(name) : 
196                           (const Extbyte*)XEMACS_CLASS),
197                          style,
198                          rect_default.left, rect_default.top,
199                          rect_default.width, rect_default.height,
200                          hwnd_parent, NULL, NULL, NULL);
201
202   Vmswindows_frame_being_created = Qnil;
203
204   if (hwnd == NULL)
205     error ("System call to create frame failed");
206                            
207   FRAME_MSWINDOWS_HANDLE(f) = hwnd;
208
209   SetWindowLong (hwnd, XWL_FRAMEOBJ, (LONG)LISP_TO_VOID(frame_obj));
210   FRAME_MSWINDOWS_DC(f) = GetDC (hwnd);
211   SetTextAlign (FRAME_MSWINDOWS_DC(f), TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
212 }
213
214 static void
215 mswindows_init_frame_2 (struct frame *f, Lisp_Object props)
216 {
217   if (NILP (Vmswindows_use_system_frame_size_defaults))
218     {
219       /* I don't think anything can set the frame size before this
220          since we don't have X resources. This may change if we look
221          at the registry. Even so these values can get overridden
222          later.*/
223       XEMACS_RECT_WH dest = { -1, -1, DEFAULT_FRAME_WIDTH, 
224                               DEFAULT_FRAME_HEIGHT };
225       mswindows_size_frame_internal (f, &dest);
226     }
227 }
228
229 /* Called after frame's properties are set */
230 static void
231 mswindows_init_frame_3 (struct frame *f)
232 {
233   /* Don't do this earlier or we get a WM_PAINT before the frame is ready.
234    * The SW_x parameter in the first call that an app makes to ShowWindow is
235    * ignored, and the parameter specified in the caller's STARTUPINFO is 
236    * substituted instead. That parameter is SW_HIDE if we were started by
237    * runemacs, so call this twice. #### runemacs is evil */
238   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
239   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
240   SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
241   DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE);
242 }
243
244 static void
245 mswindows_after_init_frame (struct frame *f, int first_on_device,
246                             int first_on_console)
247 {
248   /* Windows, unlike X, is very synchronous. After the initial
249      frame is created, it will never be displayed, except for 
250      hollow border, unless we start pumping messages. Load progress
251      messages show in the bottom of the hollow frame, which is ugly.
252      We redisplay the initial frame here, so modeline and root window
253      background show.
254   */
255   if (first_on_console)
256     redisplay ();
257 }
258
259 static void
260 mswindows_mark_frame (struct frame *f)
261 {
262   mark_object (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
263 #ifdef HAVE_TOOLBARS
264   mark_object (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
265 #endif
266   mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
267   mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
268   mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
269 }
270
271 static void
272 mswindows_focus_on_frame (struct frame *f)
273 {
274   SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
275 }
276
277 static void
278 mswindows_delete_frame (struct frame *f)
279 {
280   if (f->frame_data)
281     {
282       ReleaseDC(FRAME_MSWINDOWS_HANDLE(f), FRAME_MSWINDOWS_DC(f));
283       DestroyWindow(FRAME_MSWINDOWS_HANDLE(f));
284       xfree (f->frame_data);
285     }
286   f->frame_data = 0;
287 }
288
289 static void
290 mswindows_set_frame_size (struct frame *f, int width, int height)
291 {
292   RECT rect;
293   rect.left = rect.top = 0;
294   rect.right = width;
295   rect.bottom = height;
296
297   AdjustWindowRectEx (&rect,
298                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
299                       GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
300                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
301
302   if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
303     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
304
305   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
306                 0, 0, rect.right-rect.left, rect.bottom-rect.top,
307                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOMOVE);
308 }
309
310 static void
311 mswindows_set_frame_position (struct frame *f, int xoff, int yoff)
312 {
313   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
314                 xoff, yoff, 0, 0,
315                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE);
316 }
317
318 static void
319 mswindows_make_frame_visible (struct frame *f) 
320 {
321   if (!FRAME_VISIBLE_P(f))
322     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
323   else
324     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOW);
325   f->visible = 1;
326   f->iconified = 0;
327 }
328
329 static void
330 mswindows_make_frame_invisible (struct frame *f) 
331 {
332   if (!FRAME_VISIBLE_P(f))
333     return;
334
335   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_HIDE);
336   f->visible = 0;
337 }
338
339 static int
340 mswindows_frame_totally_visible_p (struct frame *f)
341 {
342   RECT rc_me, rc_other, rc_temp;
343   HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
344
345   /* We test against not a whole window rectangle, only against its
346      client part. So, if non-client are is covered and client area is
347      not, we return true. */
348   GetClientRect (hwnd, &rc_me);
349   MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rc_me, 2);
350
351   /* First see if we're off the desktop */
352   GetWindowRect (GetDesktopWindow(), &rc_other);
353   UnionRect(&rc_temp, &rc_me, &rc_other);
354   if (!EqualRect (&rc_temp, &rc_other))
355     return 0;
356   
357   /* Then see if any window above us obscures us */
358   while ((hwnd = GetWindow (hwnd, GW_HWNDPREV)) != NULL)
359     if (IsWindowVisible (hwnd))
360       {
361         GetWindowRect (hwnd, &rc_other);
362         if (IntersectRect(&rc_temp, &rc_me, &rc_other))
363           return 0;
364       }
365
366   return 1;
367 }
368
369 static int
370 mswindows_frame_visible_p (struct frame *f)
371 {
372   return IsWindowVisible (FRAME_MSWINDOWS_HANDLE(f))
373     && !IsIconic (FRAME_MSWINDOWS_HANDLE(f));
374 }
375
376
377 static void
378 mswindows_iconify_frame (struct frame *f)
379 {
380   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_MINIMIZE);
381   f->visible = 0;
382   f->iconified = 1;
383 }
384
385 static int
386 mswindows_frame_iconified_p (struct frame *f)
387 {
388   return IsIconic (FRAME_MSWINDOWS_HANDLE(f));
389 }
390
391 static void
392 mswindows_set_frame_icon (struct frame *f)
393 {
394   if (IMAGE_INSTANCEP (f->icon)
395       && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon)))
396     {
397       if (!XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon))
398         {
399           mswindows_initialize_image_instance_icon (XIMAGE_INSTANCE (f->icon), 
400                                                     FALSE);
401         }
402       
403       SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HICON, 
404                     (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon));
405     }
406 }
407
408 static void
409 mswindows_set_frame_pointer (struct frame *f)
410 {
411   if (IMAGE_INSTANCEP (f->pointer)
412       && IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (f->pointer)) == IMAGE_POINTER)
413     {
414       SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
415                     (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
416       /* we only have to do this because GC doesn't cause a mouse
417          event and doesn't give time to event processing even if it
418          did. */
419       SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
420     }
421 }
422
423 static void
424 mswindows_set_mouse_position (struct window *w, int x, int y)
425 {
426   struct frame *f = XFRAME (w->frame);
427   POINT pt;
428
429   pt.x = w->pixel_left + x;
430   pt.y = w->pixel_top  + y;
431   ClientToScreen (FRAME_MSWINDOWS_HANDLE(f), &pt);
432   SetCursorPos (pt.x, pt.y);
433 }
434
435 static int
436 mswindows_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y)
437 {
438   POINT pt;
439   HWND hwnd;
440
441   GetCursorPos (&pt);
442
443   /* What's under cursor? */
444   hwnd = WindowFromPoint (pt);
445   if (hwnd == NULL)
446     return 0;
447
448   /* Get grandest parent of the window */
449   {
450     HWND hwnd_parent;
451     while ((hwnd_parent = GetParent (hwnd)) != NULL)
452       hwnd = hwnd_parent;
453   }
454
455   /* Make sure it belongs to us */
456   if (GetWindowThreadProcessId (hwnd, NULL) != GetCurrentThreadId ())
457     return 0;
458
459   /* And that the window is an XEmacs frame */
460   {
461     char class_name [sizeof(XEMACS_CLASS) + 1];
462     if (!GetClassName (hwnd, class_name, sizeof(XEMACS_CLASS))
463         || strcmp (class_name, XEMACS_CLASS) != 0)
464       return 0;
465   }
466
467   /* Yippie! */
468   ScreenToClient (hwnd, &pt);
469   VOID_TO_LISP (*frame, GetWindowLong (hwnd, XWL_FRAMEOBJ));
470   *x = pt.x;
471   *y = pt.y;
472   return 1;
473 }
474
475 static void
476 mswindows_raise_frame (struct frame *f)
477 {
478   BringWindowToTop (FRAME_MSWINDOWS_HANDLE(f));
479 }
480
481 static void
482 mswindows_lower_frame (struct frame *f)
483 {
484   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), HWND_BOTTOM, 0, 0, 0, 0,
485                 SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
486 }
487
488 static void
489 mswindows_set_title_from_bufbyte (struct frame *f, Bufbyte *title) 
490 {
491   unsigned int new_checksum = hash_string (title, strlen (title));
492   if (new_checksum != FRAME_MSWINDOWS_TITLE_CHECKSUM(f))
493     {
494       FRAME_MSWINDOWS_TITLE_CHECKSUM(f) = new_checksum;
495       SetWindowText (FRAME_MSWINDOWS_HANDLE(f), title);
496     }
497 }
498
499 static Lisp_Object
500 mswindows_frame_property (struct frame *f, Lisp_Object property)
501 {
502   if (EQ (Qleft, property) || EQ (Qtop, property))
503     {
504       RECT rc;
505       GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
506       return make_int (EQ (Qtop,  property) ? rc.top : rc.left);
507     }
508   return Qunbound;
509 }
510
511 static int
512 mswindows_internal_frame_property_p (struct frame *f, Lisp_Object property)
513 {
514   return EQ (property, Qleft)
515     || EQ (property, Qtop);
516   /* #### frame-x.c has also this. Why?
517     || STRINGP (property);
518   */
519 }
520
521 static Lisp_Object
522 mswindows_frame_properties (struct frame *f)
523 {
524   Lisp_Object props = Qnil;
525   RECT rc;
526   GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
527
528   props = cons3 (Qtop,  make_int (rc.top), props);
529   props = cons3 (Qleft, make_int (rc.left), props);
530
531   return props;
532 }
533
534 static void
535 mswindows_set_frame_properties (struct frame *f, Lisp_Object plist)
536 {
537   int x=-1, y=-1;
538   int width = -1, height = -1;
539   BOOL width_specified_p = FALSE;
540   BOOL height_specified_p = FALSE;
541   BOOL x_specified_p = FALSE;
542   BOOL y_specified_p = FALSE;
543   Lisp_Object tail;
544
545   /* Extract the properties from plist */
546   for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
547     {
548       Lisp_Object prop = Fcar (tail);
549       Lisp_Object val = Fcar (Fcdr (tail));
550
551       if (SYMBOLP (prop))
552         {
553           /* Kludge to handle the font property. */
554           if (EQ (prop, Qfont))
555             {
556               /* If the value is not a string we silently ignore it. */
557               if (STRINGP (val))
558                 {
559                   Lisp_Object frm, font_spec;
560                   
561                   XSETFRAME (frm, f);
562                   font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);
563
564                   Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
565                   update_frame_face_values (f);
566                 }
567             }
568           else if (EQ (prop, Qwidth))
569             {
570               CHECK_INT (val);
571               width = XINT (val);
572               width_specified_p = TRUE;
573             }
574           else if (EQ (prop, Qheight))
575             {
576               CHECK_INT (val);
577               height = XINT (val);
578               height_specified_p = TRUE;
579             }
580           else if (EQ (prop, Qleft))
581             {
582               CHECK_INT (val);
583               x = XINT (val);
584               x_specified_p = TRUE;
585             }
586           else if (EQ (prop, Qtop))
587             {
588               CHECK_INT (val);
589               y = XINT (val);
590               y_specified_p = TRUE;
591             }
592         }
593     }
594
595   /* Now we've extracted the properties, apply them.
596      Do not apply geometric properties during frame creation. This
597      is excessive anyways, and this loses becuase WM_SIZE has not
598      been sent yet, so frame width and height fields are not initialized.
599      
600      unfortunately WM_SIZE loses as well since the resize is only
601      applied once and the first time WM_SIZE is applied not everything
602      is initialised in the frame (toolbars for instance). enabling
603      this always makes no visible difference and fixes a whole host of
604      bugs (and is more consistent with X) so I am going to reenable it.
605      --andyp */
606   if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f)
607        && (width_specified_p || height_specified_p
608            || x_specified_p || y_specified_p))
609     {
610       XEMACS_RECT_WH dest = { x, y, width, height };
611
612       mswindows_size_frame_internal (f, &dest);
613     }
614 }
615
616 void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
617 {
618   RECT rect, ws_rect;
619   int pixel_width, pixel_height;
620   int size_p = (dest->width >=0 || dest->height >=0);
621   int move_p = (dest->top >=0 || dest->left >=0);
622   char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width, &pixel_height);
623   
624   if (dest->width < 0)
625     pixel_width = FRAME_PIXWIDTH (f);
626   if (dest->height < 0)
627     pixel_height = FRAME_PIXHEIGHT (f);
628
629   GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rect);
630   if (dest->left < 0)
631     dest->left = rect.left;
632   if (dest->top < 0)
633     dest->top = rect.top;
634   
635   rect.left = rect.top = 0;
636   rect.right = pixel_width;
637   rect.bottom = pixel_height;
638
639   AdjustWindowRectEx (&rect,
640                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
641                       GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
642                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
643
644   /* resize and move the window so that it fits in the workspace. This is
645   not restrictive since this will happen later anyway in WM_SIZE.  We
646   have to do this after adjusting the rect to account for menubar
647   etc. */
648   msw_get_workspace_coords (&ws_rect);
649   pixel_width = rect.right - rect.left;
650   pixel_height = rect.bottom - rect.top;
651   if (pixel_width > ws_rect.right - ws_rect.left)
652     {
653       pixel_width = ws_rect.right - ws_rect.left;
654       size_p=1;
655     }
656   if (pixel_height > ws_rect.bottom - ws_rect.top)
657     {
658       pixel_height = ws_rect.bottom - ws_rect.top;
659       size_p=1;
660     }
661
662   /* adjust position so window is in workspace */
663   if (dest->left + pixel_width > ws_rect.right)
664     {
665       dest->left = ws_rect.right - pixel_width;
666       move_p=1;
667     }
668   if (dest->left < ws_rect.left)
669     {
670       dest->left = ws_rect.left;
671       move_p=1;
672     }
673
674   if (dest->top + pixel_height > ws_rect.bottom)
675     {
676       dest->top = ws_rect.bottom - pixel_height;
677       move_p=1;
678     }
679   if (dest->top < ws_rect.top)
680     {
681       dest->top = ws_rect.top;
682       move_p=1;
683     }
684
685   if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) 
686       || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
687     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
688
689   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
690                 dest->left, dest->top, pixel_width, pixel_height,
691                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
692                 | (size_p ? 0 : SWP_NOSIZE)
693                 | (move_p ? 0 : SWP_NOMOVE));
694 }
695
696 static Lisp_Object
697 mswindows_get_frame_parent (struct frame *f)
698 {
699   HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
700   hwnd = GetParent (hwnd);
701   if (hwnd)
702     {
703       Lisp_Object parent;
704       VOID_TO_LISP (parent, GetWindowLong (hwnd, XWL_FRAMEOBJ));
705       assert (FRAME_MSWINDOWS_P (XFRAME (parent)));
706       return parent;
707     }
708   else
709     return Qnil;
710 }
711
712 static void
713 mswindows_update_frame_external_traits (struct frame* frm, Lisp_Object name)
714 {
715 }
716
717 static int
718 mswindows_frame_size_fixed_p (struct frame *f)
719 {
720   /* Frame size cannot change if the frame is maximized */
721   return IsZoomed (FRAME_MSWINDOWS_HANDLE (f));
722 }
723
724 /*---------------------------------------------------------------------*/
725 /*-----                    PRINTER FRAME                          -----*/
726 /*---------------------------------------------------------------------*/
727
728 void
729 msprinter_start_page (struct frame *f)
730 {
731   if (!FRAME_MSPRINTER_PAGE_STARTED (f))
732     {
733       FRAME_MSPRINTER_PAGE_STARTED (f) = 1;
734       StartPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
735     }
736 }
737
738 static void
739 error_frame_unsizable (struct frame *f)
740 {
741   Lisp_Object frame;
742   XSETFRAME (frame, f);
743   signal_simple_error ("Cannot resize frame (margins)"
744                        " after print job has started.", frame);
745 }
746
747 static void
748 maybe_error_if_job_active (struct frame *f)
749 {
750   if (FRAME_MSPRINTER_JOB_STARTED (f))
751     error_frame_unsizable (f);
752 }
753
754 static void
755 msprinter_init_frame_1 (struct frame *f, Lisp_Object props)
756 {
757   /* Make sure this is the only frame on device. Windows printer can
758      handle only one job at a time. */
759   if (!NILP (DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)))))
760     error ("Only one frame (print job) at a time is allowed on "
761            "this printer device.");
762
763   f->frame_data = xnew_and_zero (struct msprinter_frame);
764
765   /* Default margin size is 1" = 1440 twips */
766   FRAME_MSPRINTER_TOP_MARGIN(f) = 1440;
767   FRAME_MSPRINTER_BOTTOM_MARGIN(f) = 1440;
768   FRAME_MSPRINTER_LEFT_MARGIN(f) = 1440;
769   FRAME_MSPRINTER_RIGHT_MARGIN(f) = 1440;
770
771   /* Negative for "uinspecified" */
772   FRAME_MSPRINTER_CHARWIDTH(f) = -1;
773   FRAME_MSPRINTER_CHARHEIGHT(f) = -1;
774
775   /* nil is for "system default" for these properties. */
776   FRAME_MSPRINTER_ORIENTATION(f) = Qnil;
777   FRAME_MSPRINTER_DUPLEX(f) = Qnil;
778 }
779
780 static void
781 msprinter_init_frame_3 (struct frame *f)
782 {
783   DOCINFO di;
784   struct device *device = XDEVICE (FRAME_DEVICE (f));
785   HDC hdc;
786   int frame_left, frame_top, frame_width, frame_height;
787
788   /* Change printer parameters */
789   {
790     DEVMODE* devmode = msprinter_get_devmode_copy (device);
791     devmode->dmFields = 0;
792
793     if (!NILP (FRAME_MSPRINTER_ORIENTATION(f)))
794       {
795         devmode->dmFields = DM_ORIENTATION;
796         if (EQ (FRAME_MSPRINTER_ORIENTATION(f), Qportrait))
797           devmode->dmOrientation = DMORIENT_PORTRAIT;
798         else if (EQ (FRAME_MSPRINTER_ORIENTATION(f), Qlandscape))
799           devmode->dmOrientation = DMORIENT_LANDSCAPE;
800         else
801           abort();
802       }
803
804     if (!NILP (FRAME_MSPRINTER_DUPLEX(f)))
805       {
806         devmode->dmFields = DM_DUPLEX;
807         if (EQ (FRAME_MSPRINTER_DUPLEX(f), Qnone))
808           devmode->dmDuplex = DMDUP_SIMPLEX;
809         if (EQ (FRAME_MSPRINTER_DUPLEX(f), Qvertical))
810           devmode->dmDuplex = DMDUP_VERTICAL;
811         if (EQ (FRAME_MSPRINTER_DUPLEX(f), Qhorizontal))
812           devmode->dmDuplex = DMDUP_HORIZONTAL;
813         else
814           abort();
815       }
816
817     assert (!FRAME_MSPRINTER_PAGE_STARTED (f));
818     msprinter_apply_devmode (device, devmode);
819   }
820
821   /* DC might be recreated in msprinter_apply_devmode,
822      so do not initialize until now */
823   hdc = DEVICE_MSPRINTER_HDC (device);
824
825   /* Compute geometry properties */
826   frame_left = (MulDiv (GetDeviceCaps (hdc, LOGPIXELSX),
827                         FRAME_MSPRINTER_LEFT_MARGIN(f), 1440)
828                 - GetDeviceCaps (hdc, PHYSICALOFFSETX));
829   
830   if (FRAME_MSPRINTER_CHARWIDTH(f) > 0)
831     {
832       char_to_real_pixel_size (f, FRAME_MSPRINTER_CHARWIDTH(f), 0,
833                                &frame_width, NULL);
834       FRAME_MSPRINTER_RIGHT_MARGIN(f) = 
835         MulDiv (GetDeviceCaps (hdc, PHYSICALWIDTH)
836                 - (frame_left + frame_width), 1440,
837                 GetDeviceCaps (hdc, LOGPIXELSX));
838     }           
839   else
840     frame_width = (GetDeviceCaps (hdc, PHYSICALWIDTH)
841                    - frame_left
842                    - MulDiv (GetDeviceCaps (hdc, LOGPIXELSX),
843                              FRAME_MSPRINTER_RIGHT_MARGIN(f), 1440));
844
845   frame_top = (MulDiv (GetDeviceCaps (hdc, LOGPIXELSY),
846                        FRAME_MSPRINTER_TOP_MARGIN(f), 1440)
847                - GetDeviceCaps (hdc, PHYSICALOFFSETY));
848
849   if (FRAME_MSPRINTER_CHARHEIGHT(f) > 0)
850     {
851       char_to_real_pixel_size (f, 0, FRAME_MSPRINTER_CHARHEIGHT(f),
852                                NULL, &frame_height);
853
854       FRAME_MSPRINTER_BOTTOM_MARGIN(f) = 
855         MulDiv (GetDeviceCaps (hdc, PHYSICALHEIGHT)
856                 - (frame_top + frame_height), 1440,
857                 GetDeviceCaps (hdc, LOGPIXELSY));
858     }           
859   else
860     frame_height = (GetDeviceCaps (hdc, PHYSICALHEIGHT)
861                     - frame_top
862                     - MulDiv (GetDeviceCaps (hdc, LOGPIXELSY),
863                               FRAME_MSPRINTER_BOTTOM_MARGIN(f), 1440));
864
865   /* Geometry sanity checks */
866   if (!frame_pixsize_valid_p (f, frame_width, frame_height))
867     error ("Area inside print margins has shrunk to naught.");
868
869   if (frame_left < 0
870       || frame_top < 0
871       || frame_left + frame_width > GetDeviceCaps (hdc, HORZRES)
872       || frame_top + frame_height > GetDeviceCaps (hdc, VERTRES))
873     error ("Print area is ouside of the printer's hardware printable area.");
874
875   /* Apply XEmacs frame geometry and layout windows */
876   {
877     int rows, columns;
878     FRAME_PIXWIDTH(f) = frame_width;
879     FRAME_PIXHEIGHT(f) = frame_height;
880     pixel_to_char_size (f, frame_width, frame_height, &columns, &rows);
881     change_frame_size (f, rows, columns, 0);
882   }
883
884   /* Apply DC geometry */
885   SetTextAlign (hdc, TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
886   SetViewportOrgEx (hdc, frame_left, frame_top, NULL);
887   SetWindowOrgEx (hdc, 0, 0, NULL);
888
889   /* Start print job */
890   di.cbSize = sizeof (di);
891   di.lpszDocName = (STRINGP(f->name)
892                     ? (char*) XSTRING_DATA(f->name)
893                     : "XEmacs print document");
894   di.lpszOutput = NULL;
895   di.lpszDatatype = NULL;
896   di.fwType = 0;
897
898   if (StartDoc (hdc, &di) <= 0)
899     error ("Cannot start print job");
900
901   /* Finish frame setup */
902   FRAME_MSPRINTER_JOB_STARTED (f) = 1;
903   FRAME_VISIBLE_P(f) = 0;
904 }
905
906 static void
907 msprinter_mark_frame (struct frame *f)
908 {
909   /* NOTE: These need not be marked as long as we allow only c-defined
910      symbols for their values.  Although, marking these is safer than
911      expensive.  [I know a proof to the theorem postulating that a
912      gator is longer than greener. Ask me. -- kkm] */
913   mark_object (FRAME_MSPRINTER_ORIENTATION (f));
914   mark_object (FRAME_MSPRINTER_DUPLEX (f));
915 }
916
917 static void
918 msprinter_delete_frame (struct frame *f)
919 {
920   if (f->frame_data)
921     {
922       HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
923       if (FRAME_MSPRINTER_PAGE_STARTED (f))
924         EndPage (hdc);
925       if (FRAME_MSPRINTER_JOB_STARTED (f))
926         EndDoc (hdc);
927       xfree (f->frame_data);
928     }
929
930   f->frame_data = 0;
931 }
932
933 static Lisp_Object
934 msprinter_frame_property (struct frame *f, Lisp_Object property)
935 {
936   if (EQ (Qleft_margin, property))
937     return make_int (FRAME_MSPRINTER_LEFT_MARGIN(f));
938   else if (EQ (Qtop_margin, property))
939     return make_int (FRAME_MSPRINTER_TOP_MARGIN(f));
940   if (EQ (Qright_margin, property))
941     return make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f));
942   else if (EQ (Qbottom_margin, property))
943     return make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f));
944   else if (EQ (Qorientation, property))
945     return FRAME_MSPRINTER_ORIENTATION(f);
946   else if (EQ (Qduplex, property))
947     return FRAME_MSPRINTER_DUPLEX(f);
948   else
949     return Qunbound;
950 }
951
952 static int
953 msprinter_internal_frame_property_p (struct frame *f, Lisp_Object property)
954 {
955   return (EQ (Qleft_margin, property) || EQ (Qtop_margin, property) ||
956           EQ (Qright_margin, property) || EQ (Qbottom_margin, property) ||
957           EQ (Qorientation, property) || EQ (Qduplex, property));
958 }
959
960 static Lisp_Object
961 msprinter_frame_properties (struct frame *f)
962 {
963   Lisp_Object props = Qnil;
964   props = cons3 (Qorientation, FRAME_MSPRINTER_ORIENTATION(f), props);
965   props = cons3 (Qduplex, FRAME_MSPRINTER_DUPLEX(f), props);
966   props = cons3 (Qbottom_margin,
967                  make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f)), props);
968   props = cons3 (Qright_margin,
969                  make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f)), props);
970   props = cons3 (Qtop_margin,
971                  make_int (FRAME_MSPRINTER_TOP_MARGIN(f)), props);
972   props = cons3 (Qleft_margin,
973                  make_int (FRAME_MSPRINTER_LEFT_MARGIN(f)), props);
974   return props;
975 }
976
977 static void
978 msprinter_set_frame_properties (struct frame *f, Lisp_Object plist)
979 {
980   Lisp_Object tail;
981
982   /* Extract the properties from plist */
983   for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
984     {
985       Lisp_Object prop = Fcar (tail);
986       Lisp_Object val = Fcar (Fcdr (tail));
987
988       if (SYMBOLP (prop))
989         {
990           if (EQ (prop, Qwidth))
991             {
992               maybe_error_if_job_active (f);
993               if (!NILP (val))
994                 {
995                   CHECK_NATNUM (val);
996                   FRAME_MSPRINTER_CHARWIDTH(f) = XINT (val);
997                 }
998             }
999           if (EQ (prop, Qheight))
1000             {
1001               maybe_error_if_job_active (f);
1002               if (!NILP (val))
1003                 {
1004                   CHECK_NATNUM (val);
1005                   FRAME_MSPRINTER_CHARHEIGHT(f) = XINT (val);
1006                 }
1007             }
1008           else if (EQ (prop, Qleft_margin))
1009             {
1010               maybe_error_if_job_active (f);
1011               CHECK_NATNUM (val);
1012               FRAME_MSPRINTER_LEFT_MARGIN(f) = XINT (val);
1013             }
1014           else if (EQ (prop, Qtop_margin))
1015             {
1016               maybe_error_if_job_active (f);
1017               CHECK_NATNUM (val);
1018               FRAME_MSPRINTER_TOP_MARGIN(f) = XINT (val);
1019             }
1020           else if (EQ (prop, Qright_margin))
1021             {
1022               maybe_error_if_job_active (f);
1023               CHECK_NATNUM (val);
1024               FRAME_MSPRINTER_RIGHT_MARGIN(f) = XINT (val);
1025             }
1026           else if (EQ (prop, Qbottom_margin))
1027             {
1028               maybe_error_if_job_active (f);
1029               CHECK_NATNUM (val);
1030               FRAME_MSPRINTER_BOTTOM_MARGIN(f) = XINT (val);
1031             }
1032           else if (EQ (prop, Qorientation))
1033             {
1034               maybe_error_if_job_active (f);
1035               CHECK_SYMBOL (val);
1036               if (!NILP(val) &&
1037                   !EQ (val, Qportrait) &&
1038                   !EQ (val, Qlandscape))
1039                 signal_simple_error ("Page orientation can only be "
1040                                      "'portrait or 'landscape", val);
1041               FRAME_MSPRINTER_ORIENTATION(f) = val;
1042             }
1043           else if (EQ (prop, Qduplex))
1044             {
1045               maybe_error_if_job_active (f);
1046               CHECK_SYMBOL (val);
1047               if (!NILP(val) &&
1048                   !EQ (val, Qnone) &&
1049                   !EQ (val, Qvertical) &&
1050                   !EQ (val, Qhorizontal))
1051                 signal_simple_error ("Duplex can only be 'none, "
1052                                      "'vertical or 'horizontal", val);
1053               FRAME_MSPRINTER_DUPLEX(f) = val;
1054             }
1055         }
1056     }
1057 }
1058
1059 static void
1060 msprinter_set_frame_size (struct frame *f, int width, int height)
1061 {
1062   /* We're absolutely unsizeable */
1063   error_frame_unsizable (f);
1064 }
1065
1066 static void
1067 msprinter_eject_page (struct frame *f)
1068 {
1069   /* #### Should we eject empty pages? */
1070   if (FRAME_MSPRINTER_PAGE_STARTED (f))
1071     {
1072       FRAME_MSPRINTER_PAGE_STARTED (f) = 0;
1073       EndPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
1074     }
1075 }
1076
1077 \f
1078 void
1079 console_type_create_frame_mswindows (void)
1080 {
1081   /* Display frames */
1082   CONSOLE_HAS_METHOD (mswindows, init_frame_1);
1083   CONSOLE_HAS_METHOD (mswindows, init_frame_2); 
1084   CONSOLE_HAS_METHOD (mswindows, init_frame_3);
1085   CONSOLE_HAS_METHOD (mswindows, after_init_frame);
1086   CONSOLE_HAS_METHOD (mswindows, mark_frame);
1087   CONSOLE_HAS_METHOD (mswindows, focus_on_frame);
1088   CONSOLE_HAS_METHOD (mswindows, delete_frame);
1089   CONSOLE_HAS_METHOD (mswindows, get_mouse_position);
1090   CONSOLE_HAS_METHOD (mswindows, set_mouse_position);
1091   CONSOLE_HAS_METHOD (mswindows, raise_frame);
1092   CONSOLE_HAS_METHOD (mswindows, lower_frame);
1093   CONSOLE_HAS_METHOD (mswindows, make_frame_visible);
1094   CONSOLE_HAS_METHOD (mswindows, make_frame_invisible);
1095   CONSOLE_HAS_METHOD (mswindows, iconify_frame);
1096   CONSOLE_HAS_METHOD (mswindows, set_frame_size);
1097   CONSOLE_HAS_METHOD (mswindows, set_frame_position);
1098   CONSOLE_HAS_METHOD (mswindows, frame_property);
1099   CONSOLE_HAS_METHOD (mswindows, internal_frame_property_p);
1100   CONSOLE_HAS_METHOD (mswindows, frame_properties);
1101   CONSOLE_HAS_METHOD (mswindows, set_frame_properties);
1102   CONSOLE_HAS_METHOD (mswindows, set_title_from_bufbyte);
1103 /*  CONSOLE_HAS_METHOD (mswindows, set_icon_name_from_bufbyte); */
1104   CONSOLE_HAS_METHOD (mswindows, frame_visible_p);
1105   CONSOLE_HAS_METHOD (mswindows, frame_totally_visible_p);
1106   CONSOLE_HAS_METHOD (mswindows, frame_iconified_p);
1107   CONSOLE_HAS_METHOD (mswindows, set_frame_pointer); 
1108   CONSOLE_HAS_METHOD (mswindows, set_frame_icon); 
1109   CONSOLE_HAS_METHOD (mswindows, get_frame_parent);
1110   CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits);
1111   CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p);
1112
1113   /* Printer frames, aka print jobs */
1114   CONSOLE_HAS_METHOD (msprinter, init_frame_1);
1115   CONSOLE_HAS_METHOD (msprinter, init_frame_3);
1116   CONSOLE_HAS_METHOD (msprinter, mark_frame);
1117   CONSOLE_HAS_METHOD (msprinter, delete_frame);
1118   CONSOLE_HAS_METHOD (msprinter, frame_property);
1119   CONSOLE_HAS_METHOD (msprinter, internal_frame_property_p);
1120   CONSOLE_HAS_METHOD (msprinter, frame_properties);
1121   CONSOLE_HAS_METHOD (msprinter, set_frame_properties);
1122   CONSOLE_HAS_METHOD (msprinter, set_frame_size);
1123   CONSOLE_HAS_METHOD (msprinter, eject_page);
1124 }
1125
1126 void
1127 syms_of_frame_mswindows (void)
1128 {
1129 }
1130
1131 void
1132 reinit_vars_of_frame_mswindows (void)
1133 {
1134   /* Needn't staticpro -- see comment above.  */
1135   Vmswindows_frame_being_created = Qnil;
1136 }
1137
1138 void
1139 vars_of_frame_mswindows (void)
1140 {
1141   reinit_vars_of_frame_mswindows ();
1142
1143   DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /*
1144 Controls whether to use system or XEmacs defaults for frame size.
1145 If nil then reasonable defaults are used for intial frame sizes. If t
1146 then the system will choose default sizes for the frame.
1147 */ );
1148   Vmswindows_use_system_frame_size_defaults = Qnil;
1149   
1150   DEFVAR_LISP ("default-mswindows-frame-plist", &Vdefault_mswindows_frame_plist /*
1151 Plist of default frame-creation properties for mswindows frames.
1152 These override what is specified in `default-frame-plist', but are
1153 overridden by the arguments to the particular call to `make-frame'.
1154
1155 Note: In many cases, properties of a frame are available as specifiers
1156 instead of through the frame-properties mechanism.
1157
1158 Here is a list of recognized frame properties, other than those
1159 documented in `set-frame-properties' (they can be queried and
1160 set at any time, except as otherwise noted):
1161
1162   initially-unmapped            If non-nil, the frame will not be visible
1163                                 when it is created.  In this case, you
1164                                 need to call `make-frame-visible' to make
1165                                 the frame appear.
1166   popup                         If non-nil, it should be a frame, and this
1167                                 frame will be created as a "popup" frame
1168                                 whose parent is the given frame.  This
1169                                 will make the window manager treat the
1170                                 frame as a dialog box, which may entail
1171                                 doing different things (e.g. not asking
1172                                 for positioning, and not iconifying
1173                                 separate from its parent).
1174   top                           Y position (in pixels) of the upper-left
1175                                 outermost corner of the frame (i.e. the
1176                                 upper-left of the window-manager
1177                                 decorations).
1178   left                          X position (in pixels) of the upper-left
1179                                 outermost corner of the frame (i.e. the
1180                                 upper-left of the window-manager
1181                                 decorations).
1182
1183 See also `default-frame-plist', which specifies properties which apply
1184 to all frames, not just mswindows frames.
1185 */ );
1186   Vdefault_mswindows_frame_plist = Qnil;
1187
1188   mswindows_console_methods->device_specific_frame_props =
1189     &Vdefault_mswindows_frame_plist;
1190
1191   DEFVAR_LISP ("default-msprinter-frame-plist", &Vdefault_msprinter_frame_plist /*
1192 Plist of default frame-creation properties for msprinter print job frames.
1193 These override what is specified in `default-frame-plist', but are
1194 overridden by the arguments to the particular call to `make-frame'.
1195
1196 Note: In many cases, properties of a frame are available as specifiers
1197 instead of through the frame-properties mechanism.
1198
1199 Here is a list of recognized frame properties, other than those
1200 documented in `set-frame-properties' (they can be queried and
1201 set at any time, except as otherwise noted):
1202
1203   left-margin                   Margin of the page, in twips. Twip is a
1204   top-margin                    typographical unit of measurement,
1205   right-margin                  equal to 1/1440 of an inch, or 1/20 of a
1206   bottom-margin                 point, and roughly equal to 7/400 of a
1207                                 millimeter. If not specifified, each margin
1208                                 defaults to one inch (25.4 mm).
1209
1210      MARGINS NOTE. right-margin and bottom-margin are overridden by
1211        the height and width properties. If you want to specify size
1212        of the printable area in character, as with the rest of XEmacs,
1213        use these properties. If height and/or width are nil, then
1214        corresponding margin setting is taken into account. If you
1215        specify height and/or width in `default-frame-plist', but still
1216        want to specify right/bottom margins, set height/width in this
1217        plist to nil, as in this example:
1218
1219           (setq default-frame-plist '(height 55 'width 80)
1220                 default-msprinter-frame-plist '(height nil 'width nil))
1221
1222
1223   orientation                   Printer page orientation. Can be 'nil,
1224                                 indicating system default, 'portrait
1225                                 or 'landscape.
1226
1227   duplex                        Duplex printing mode, subject to printer
1228                                 support. Can be 'nil for the device default,
1229                                 'none for simplex printing, 'vertical or
1230                                 'horizontal for duplex page bound along
1231                                 the corresponding page direction.
1232
1233 See also `default-frame-plist', which specifies properties which apply
1234 to all frames, not just mswindows frames.
1235 */ );
1236   Vdefault_msprinter_frame_plist = Qnil;
1237
1238   msprinter_console_methods->device_specific_frame_props =
1239     &Vdefault_msprinter_frame_plist;
1240 }