XEmacs 21.2-b1
[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  */
30
31 #include <config.h>
32 #include "lisp.h"
33
34 #include "buffer.h"
35 #include "console-msw.h"
36 #include "glyphs-msw.h"
37 #include "events.h"
38 #include "faces.h"
39 #include "frame.h"
40 #include "redisplay.h"
41 #include "window.h"
42
43 #define MSWINDOWS_FRAME_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW)
44 #define MSWINDOWS_POPUP_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP \
45                                | WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX)
46
47 #define MSWINDOWS_FRAME_EXSTYLE WS_EX_OVERLAPPEDWINDOW
48 #define MSWINDOWS_POPUP_EXSTYLE WS_EX_PALETTEWINDOW
49
50 /* Default popup left top corner offset from the same
51    corner of the parent frame, in pixel */
52 #define POPUP_OFFSET 30
53
54 /* Default popup size, in characters */
55 #define POPUP_WIDTH 30
56 #define POPUP_HEIGHT 10
57
58 /* Default popup size, in characters */
59 #define DEFAULT_FRAME_WIDTH 80
60 #define DEFAULT_FRAME_HEIGHT 35
61
62 #ifdef HAVE_MENUBARS
63 #define ADJR_MENUFLAG TRUE
64 #else
65 #define ADJR_MENUFLAG FALSE
66 #endif
67
68 /* Default properties to use when creating frames.  */
69 Lisp_Object Vdefault_mswindows_frame_plist;
70 Lisp_Object Vmswindows_use_system_frame_size_defaults;
71
72 /* This does not need to be GC protected, as it holds a
73    frame Lisp_Object already protected by Fmake_frame */
74 Lisp_Object Vmswindows_frame_being_created;
75
76 static void
77 mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
78 {
79   Lisp_Object initially_unmapped;
80   Lisp_Object name, height, width, popup, top, left;
81   Lisp_Object frame_obj = Qnil;
82   RECT rect;
83   XEMACS_RECT_WH rect_default;
84   DWORD style, exstyle;
85   HWND hwnd, hwnd_parent;
86
87   /* Pick up relevant properties */
88   initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil);
89   name = Fplist_get (props, Qname, Qnil);
90   
91   popup = Fplist_get (props, Qpopup, Qnil);
92   if (EQ (popup, Qt))
93     popup = Fselected_frame (Qnil);
94
95   left = Fplist_get (props, Qleft, Qnil);
96   if (!NILP (left))
97     CHECK_INT (left);
98
99   top = Fplist_get (props, Qtop, Qnil);
100   if (!NILP (top))
101     CHECK_INT (top);
102
103   width = Fplist_get (props, Qwidth, Qnil);
104   if (!NILP (width))
105     CHECK_INT (width);
106
107   height = Fplist_get (props, Qheight, Qnil);
108   if (!NILP (height))
109     CHECK_INT (height);
110
111   f->frame_data = xnew_and_zero (struct mswindows_frame);
112   FRAME_MSWINDOWS_TARGET_RECT (f) = xnew_and_zero (XEMACS_RECT_WH);
113
114   FRAME_MSWINDOWS_TARGET_RECT (f)->left = NILP (left) ? -1 : abs (XINT (left));
115   FRAME_MSWINDOWS_TARGET_RECT (f)->top = NILP (top) ? -1 : abs (XINT (top));
116   FRAME_MSWINDOWS_TARGET_RECT (f)->width = NILP (width) ? -1 : 
117     abs (XINT (width));
118   FRAME_MSWINDOWS_TARGET_RECT (f)->height = NILP (height) ? -1 : 
119     abs (XINT (height));
120       
121   /* Misc frame stuff */
122   FRAME_MSWINDOWS_DATA(f)->button2_need_lbutton = 0;
123   FRAME_MSWINDOWS_DATA(f)->button2_need_rbutton = 0;
124   FRAME_MSWINDOWS_DATA(f)->button2_is_down = 0;
125   FRAME_MSWINDOWS_DATA(f)->ignore_next_lbutton_up = 0;
126   FRAME_MSWINDOWS_DATA(f)->ignore_next_rbutton_up = 0;
127   FRAME_MSWINDOWS_DATA(f)->sizing = 0;
128   FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Qnil;
129 #ifdef HAVE_TOOLBARS
130   FRAME_MSWINDOWS_TOOLBAR_HASHTABLE(f) = Fmake_hashtable (make_int (50), 
131                                                           Qequal);
132 #endif
133
134   /* Will initialize these in WM_SIZE handler. We cannot do it now,
135      because we do not know what is CW_USEDEFAULT height and width */
136   FRAME_WIDTH (f) = 0;
137   FRAME_HEIGHT (f) = 0;
138   FRAME_PIXWIDTH (f) = 0;
139   FRAME_PIXHEIGHT (f) = 0;
140
141   if (NILP (popup))
142     {
143       style = MSWINDOWS_FRAME_STYLE;
144       exstyle = MSWINDOWS_FRAME_EXSTYLE;
145       hwnd_parent = NULL;
146
147       rect_default.left = rect_default.top = CW_USEDEFAULT;
148       rect_default.width = rect_default.height = CW_USEDEFAULT;
149     }
150   else
151     {
152       style = MSWINDOWS_POPUP_STYLE;
153       exstyle = MSWINDOWS_POPUP_EXSTYLE;
154
155       CHECK_MSWINDOWS_FRAME (popup);
156       hwnd_parent = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
157       assert (IsWindow (hwnd_parent));
158
159       /* We cannot use CW_USEDEFAULT when creating a popup window.
160          So by default, we offset the new popup 30 pixels right
161          and down from its parent, and give it size of 30x10 characters.
162          These dimensions look adequate on both high and low res monitors */
163       GetWindowRect (hwnd_parent, &rect);
164       rect_default.left = rect.left + POPUP_OFFSET;
165       rect_default.top = rect.top + POPUP_OFFSET;
166       char_to_real_pixel_size (f, POPUP_WIDTH, POPUP_HEIGHT,
167                                &rect_default.width, &rect_default.height);
168     }
169
170   AdjustWindowRectEx(&rect, style, ADJR_MENUFLAG, exstyle);
171
172   XSETFRAME (frame_obj, f);
173
174   Vmswindows_frame_being_created = frame_obj;
175
176   hwnd = CreateWindowEx (exstyle,
177                          XEMACS_CLASS,
178                          STRINGP(f->name) ? XSTRING_DATA(f->name) :
179                          (STRINGP(name) ? XSTRING_DATA(name) : XEMACS_CLASS),
180                          style,
181                          rect_default.left, rect_default.top,
182                          rect_default.width, rect_default.height,
183                          hwnd_parent, NULL, NULL, NULL);
184
185   Vmswindows_frame_being_created = Qnil;
186
187   if (hwnd == NULL)
188     error ("System call to create frame failed");
189                            
190   FRAME_MSWINDOWS_HANDLE(f) = hwnd;
191
192   SetWindowLong (hwnd, XWL_FRAMEOBJ, (LONG)LISP_TO_VOID(frame_obj));
193   FRAME_MSWINDOWS_DC(f) = GetDC (hwnd);
194   FRAME_MSWINDOWS_CDC(f) = CreateCompatibleDC (FRAME_MSWINDOWS_CDC(f));
195   SetTextAlign (FRAME_MSWINDOWS_DC(f), TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
196 }
197
198 static void
199 mswindows_init_frame_2 (struct frame *f, Lisp_Object props)
200 {
201   if (NILP (Vmswindows_use_system_frame_size_defaults))
202     {
203       /* I don't think anything can set the frame size before this
204          since we don't have X resources. This may change if we look
205          at the registry. Even so these values can get overridden
206          later.*/
207       XEMACS_RECT_WH dest = { -1, -1, DEFAULT_FRAME_WIDTH, 
208                               DEFAULT_FRAME_HEIGHT };
209       mswindows_size_frame_internal (f, &dest);
210     }
211 }
212
213 /* Called after frame's properties are set */
214 static void
215 mswindows_init_frame_3 (struct frame *f)
216 {
217   /* Don't do this earlier or we get a WM_PAINT before the frame is ready.
218    * The SW_x parameter in the first call that an app makes to ShowWindow is
219    * ignored, and the parameter specified in the caller's STARTUPINFO is 
220    * substituted instead. That parameter is SW_HIDE if we were started by
221    * runemacs, so call this twice. #### runemacs is evil */
222   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
223   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
224   SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
225   DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE);
226 }
227
228 static void
229 mswindows_after_init_frame (struct frame *f, int first_on_device,
230                             int first_on_console)
231 {
232   /* Windows, unlike X, is very synchronous. After the initial
233      frame is created, it will never be displayed, except for 
234      hollow border, unless we start pumping messages. Load progress
235      messages show in the bottom of the hollow frame, which is ugly.
236      We redipsplay the initial frame here, so modeline and root window
237      backgorund show.
238   */
239   if (first_on_console)
240     redisplay ();
241 }
242
243 static void
244 mswindows_mark_frame (struct frame *f, void (*markobj) (Lisp_Object))
245 {
246   ((markobj) (FRAME_MSWINDOWS_MENU_HASHTABLE (f)));
247 #ifdef HAVE_TOOLBARS
248   ((markobj) (FRAME_MSWINDOWS_TOOLBAR_HASHTABLE (f)));
249 #endif
250 }
251
252 static void
253 mswindows_focus_on_frame (struct frame *f)
254 {
255   SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
256 }
257
258 static void
259 mswindows_delete_frame (struct frame *f)
260 {
261   if (f->frame_data)
262     {
263       DeleteDC(FRAME_MSWINDOWS_CDC(f));
264       ReleaseDC(FRAME_MSWINDOWS_HANDLE(f), FRAME_MSWINDOWS_DC(f));
265       DestroyWindow(FRAME_MSWINDOWS_HANDLE(f));
266       xfree (f->frame_data);
267     }
268   f->frame_data = 0;
269 }
270
271 static void
272 mswindows_set_frame_size (struct frame *f, int width, int height)
273 {
274   RECT rect;
275   rect.left = rect.top = 0;
276   rect.right = width;
277   rect.bottom = height;
278
279   AdjustWindowRectEx (&rect,
280                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
281                       GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
282                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
283
284   if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
285     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
286
287   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
288                 0, 0, rect.right-rect.left, rect.bottom-rect.top,
289                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOMOVE);
290 }
291
292 static void
293 mswindows_set_frame_position (struct frame *f, int xoff, int yoff)
294 {
295   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
296                 xoff, yoff, 0, 0,
297                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE);
298 }
299
300 static void
301 mswindows_make_frame_visible (struct frame *f) 
302 {
303   if (f->iconified)
304     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
305   else
306     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
307   f->visible = 1;
308   f->iconified = 0;
309 }
310
311 static void
312 mswindows_make_frame_invisible (struct frame *f) 
313 {
314   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_HIDE);
315   f->visible = -1;
316 }
317
318 static int
319 mswindows_frame_totally_visible_p (struct frame *f)
320 {
321   RECT rc_me, rc_other, rc_temp;
322   HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
323
324   /* We test against not a whole window rectangle, only agaist its
325      client part. So, if non-client are is covered and client area is
326      not, we return true. */
327   GetClientRect (hwnd, &rc_me);
328   MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rc_me, 2);
329
330   /* First see if we're off the desktop */
331   GetWindowRect (GetDesktopWindow(), &rc_other);
332   UnionRect(&rc_temp, &rc_me, &rc_other);
333   if (!EqualRect (&rc_temp, &rc_other))
334     return 0;
335   
336   /* Then see if any window above us obscures us */
337   while ((hwnd = GetWindow (hwnd, GW_HWNDPREV)) != NULL)
338     if (IsWindowVisible (hwnd))
339       {
340         GetWindowRect (hwnd, &rc_other);
341         if (IntersectRect(&rc_temp, &rc_me, &rc_other))
342           return 0;
343       }
344
345   return 1;
346 }
347
348 static int
349 mswindows_frame_visible_p (struct frame *f)
350 {
351   return IsWindowVisible (FRAME_MSWINDOWS_HANDLE(f))
352     && !IsIconic (FRAME_MSWINDOWS_HANDLE(f));
353 }
354
355
356 static void
357 mswindows_iconify_frame (struct frame *f)
358 {
359   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_MINIMIZE);
360   f->visible = 0;
361   f->iconified = 1;
362 }
363
364 static int
365 mswindows_frame_iconified_p (struct frame *f)
366 {
367   return IsIconic (FRAME_MSWINDOWS_HANDLE(f));
368 }
369
370 static void
371 mswindows_set_frame_icon (struct frame *f)
372 {
373   if (IMAGE_INSTANCEP (f->icon)
374       && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon)))
375     {
376       if (!XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon))
377         {
378           mswindows_initialize_image_instance_icon (XIMAGE_INSTANCE (f->icon), 
379                                                     FALSE);
380         }
381       
382       SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HICON, 
383                     (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon));
384     }
385 }
386
387 static void
388 mswindows_set_frame_pointer (struct frame *f)
389 {
390   if (IMAGE_INSTANCEP (f->pointer)
391       && IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (f->pointer)) == IMAGE_POINTER)
392     {
393       SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
394                     (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
395     }
396 }
397
398 static void
399 mswindows_set_mouse_position (struct window *w, int x, int y)
400 {
401   struct frame *f = XFRAME (w->frame);
402   POINT pt;
403
404   pt.x = w->pixel_left + x;
405   pt.y = w->pixel_top  + y;
406   ClientToScreen (FRAME_MSWINDOWS_HANDLE(f), &pt);
407   SetCursorPos (pt.x, pt.y);
408 }
409
410 static int
411 mswindows_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y)
412 {
413   POINT pt;
414   HWND hwnd;
415
416   GetCursorPos (&pt);
417
418   /* What's under cursor? */
419   hwnd = WindowFromPoint (pt);
420   if (hwnd == NULL)
421     return 0;
422
423   /* Get grandest parent of the window */
424   {
425     HWND hwnd_parent;
426     while ((hwnd_parent = GetParent (hwnd)) != NULL)
427       hwnd = hwnd_parent;
428   }
429
430   /* Make sure it belongs to us */
431   if (GetWindowThreadProcessId (hwnd, NULL) != GetCurrentThreadId ())
432     return 0;
433
434   /* And that the window is an XEmacs frame */
435   {
436     char class_name [sizeof(XEMACS_CLASS) + 1];
437     if (!GetClassName (hwnd, class_name, sizeof(XEMACS_CLASS))
438         || strcmp (class_name, XEMACS_CLASS) != 0)
439       return 0;
440   }
441
442   /* Yippie! */
443   ScreenToClient (hwnd, &pt);
444   VOID_TO_LISP (*frame, GetWindowLong (hwnd, XWL_FRAMEOBJ));
445   *x = pt.x;
446   *y = pt.y;
447   return 1;
448 }
449
450 static void
451 mswindows_raise_frame (struct frame *f)
452 {
453   BringWindowToTop (FRAME_MSWINDOWS_HANDLE(f));
454   /* XXX Should we do SetWindowForeground too ? */
455 }
456
457 static void
458 mswindows_lower_frame (struct frame *f)
459 {
460   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), HWND_BOTTOM, 0, 0, 0, 0,
461                 SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
462 }
463
464 static void
465 mswindows_set_title_from_bufbyte (struct frame *f, Bufbyte *title) 
466 {
467   unsigned int new_checksum = hash_string (title, strlen (title));
468   if (new_checksum != FRAME_MSWINDOWS_TITLE_CHECKSUM(f))
469     {
470       FRAME_MSWINDOWS_TITLE_CHECKSUM(f) = new_checksum;
471       SetWindowText (FRAME_MSWINDOWS_HANDLE(f), title);
472     }
473 }
474
475 static Lisp_Object
476 mswindows_frame_property (struct frame *f, Lisp_Object property)
477 {
478   if (EQ (Qleft, property) || EQ (Qtop, property))
479     {
480       RECT rc;
481       GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
482       return make_int (EQ (Qtop,  property) ? rc.top : rc.left);
483     }
484   return Qunbound;
485 }
486
487 static int
488 mswindows_internal_frame_property_p (struct frame *f, Lisp_Object property)
489 {
490   return EQ (property, Qleft)
491     || EQ (property, Qtop);
492   /* #### frame-x.c has also this. Why?
493     || STRINGP (property);
494   */
495 }
496
497 static Lisp_Object
498 mswindows_frame_properties (struct frame *f)
499 {
500   Lisp_Object props = Qnil;
501   RECT rc;
502   GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
503
504   props = cons3 (Qtop,  make_int (rc.top), props);
505   props = cons3 (Qleft, make_int (rc.left), props);
506
507   return props;
508 }
509
510 static void
511 mswindows_set_frame_properties (struct frame *f, Lisp_Object plist)
512 {
513   int x=-1, y=-1;
514   int width = -1, height = -1;
515   BOOL width_specified_p = FALSE;
516   BOOL height_specified_p = FALSE;
517   BOOL x_specified_p = FALSE;
518   BOOL y_specified_p = FALSE;
519   Lisp_Object tail;
520
521   /* Extract the properties from plist */
522   for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
523     {
524       Lisp_Object prop = Fcar (tail);
525       Lisp_Object val = Fcar (Fcdr (tail));
526
527       if (SYMBOLP (prop))
528         {
529           /* Kludge to handle the font property. */
530           if (EQ (prop, Qfont))
531             {
532               /* If the value is not a string we silently ignore it. */
533               if (STRINGP (val))
534                 {
535                   Lisp_Object frm, font_spec;
536                   
537                   XSETFRAME (frm, f);
538                   font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);
539
540                   Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
541                   update_frame_face_values (f);
542                 }
543             }
544           else if (EQ (prop, Qwidth))
545             {
546               CHECK_INT (val);
547               width = XINT (val);
548               width_specified_p = TRUE;
549             }
550           else if (EQ (prop, Qheight))
551             {
552               CHECK_INT (val);
553               height = XINT (val);
554               height_specified_p = TRUE;
555             }
556           else if (EQ (prop, Qleft))
557             {
558               CHECK_INT (val);
559               x = XINT (val);
560               x_specified_p = TRUE;
561             }
562           else if (EQ (prop, Qtop))
563             {
564               CHECK_INT (val);
565               y = XINT (val);
566               y_specified_p = TRUE;
567             }
568         }
569     }
570
571   /* Now we've extracted the properties, apply them.
572      Do not apply geometric properties during frame creation. This
573      is excessive anyways, and this loses becuase WM_SIZE has not
574      been sent yet, so frame width and height fields are not initialized.
575      
576      unfortunately WM_SIZE loses as well since the resize is only
577      applied once and the first time WM_SIZE is applied not everything
578      is initialised in the frame (toolbars for instance). enabling
579      this always makes no visible difference and fixes a whole host of
580      bugs (and is more consistent with X) so I am going to reenable it.
581      --andyp */
582   if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f)
583        && (width_specified_p || height_specified_p || x_specified_p || y_specified_p))
584     {
585       XEMACS_RECT_WH dest = { x, y, width, height };
586
587       mswindows_size_frame_internal (f, &dest);
588     }
589 }
590
591 void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
592 {
593   RECT rect;
594   int pixel_width, pixel_height;
595   int size_p = (dest->width >=0 || dest->height >=0);
596   int move_p = (dest->top >=0 || dest->left >=0);
597
598   char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width, &pixel_height);
599   
600   if (dest->width < 0)
601     pixel_width = FRAME_PIXWIDTH (f);
602   if (dest->height < 0)
603     pixel_height = FRAME_PIXHEIGHT (f);
604
605   GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rect);
606   if (dest->left < 0)
607     dest->left = rect.left;
608   if (dest->top < 0)
609     dest->top = rect.top;
610
611   rect.left = rect.top = 0;
612   rect.right = pixel_width;
613   rect.bottom = pixel_height;
614
615   AdjustWindowRectEx (&rect,
616                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
617                       GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
618                       GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
619
620   if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) 
621       || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
622     ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
623
624   SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL, 
625                 dest->left, dest->top, rect.right - rect.left, rect.bottom - rect.top,
626                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
627                 | (size_p ? 0 : SWP_NOSIZE)
628                 | (move_p ? 0 : SWP_NOMOVE));
629 }
630
631 static Lisp_Object
632 mswindows_get_frame_parent (struct frame *f)
633 {
634   HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
635   hwnd = GetParent (hwnd);
636   if (hwnd)
637     {
638       Lisp_Object parent;
639       VOID_TO_LISP (parent, GetWindowLong (hwnd, XWL_FRAMEOBJ));
640       assert (FRAME_MSWINDOWS_P (XFRAME (parent)));
641       return parent;
642     }
643   else
644     return Qnil;
645 }
646
647 static void
648 mswindows_update_frame_external_traits (struct frame* frm, Lisp_Object name)
649 {
650 }
651
652 static int
653 mswindows_frame_size_fixed_p (struct frame *f)
654 {
655   /* Frame size cannot change if the frame is maximized */
656   return IsZoomed (FRAME_MSWINDOWS_HANDLE (f));
657 }
658
659 void
660 console_type_create_frame_mswindows (void)
661 {
662   /* frame methods */
663   CONSOLE_HAS_METHOD (mswindows, init_frame_1);
664   CONSOLE_HAS_METHOD (mswindows, init_frame_2); 
665   CONSOLE_HAS_METHOD (mswindows, init_frame_3);
666   CONSOLE_HAS_METHOD (mswindows, after_init_frame);
667   CONSOLE_HAS_METHOD (mswindows, mark_frame);
668   CONSOLE_HAS_METHOD (mswindows, focus_on_frame);
669   CONSOLE_HAS_METHOD (mswindows, delete_frame);
670   CONSOLE_HAS_METHOD (mswindows, get_mouse_position);
671   CONSOLE_HAS_METHOD (mswindows, set_mouse_position);
672   CONSOLE_HAS_METHOD (mswindows, raise_frame);
673   CONSOLE_HAS_METHOD (mswindows, lower_frame);
674   CONSOLE_HAS_METHOD (mswindows, make_frame_visible);
675   CONSOLE_HAS_METHOD (mswindows, make_frame_invisible);
676   CONSOLE_HAS_METHOD (mswindows, iconify_frame);
677   CONSOLE_HAS_METHOD (mswindows, set_frame_size);
678   CONSOLE_HAS_METHOD (mswindows, set_frame_position);
679   CONSOLE_HAS_METHOD (mswindows, frame_property);
680   CONSOLE_HAS_METHOD (mswindows, internal_frame_property_p);
681   CONSOLE_HAS_METHOD (mswindows, frame_properties);
682   CONSOLE_HAS_METHOD (mswindows, set_frame_properties);
683   CONSOLE_HAS_METHOD (mswindows, set_title_from_bufbyte);
684 /*  CONSOLE_HAS_METHOD (mswindows, set_icon_name_from_bufbyte); */
685   CONSOLE_HAS_METHOD (mswindows, frame_visible_p);
686   CONSOLE_HAS_METHOD (mswindows, frame_totally_visible_p);
687   CONSOLE_HAS_METHOD (mswindows, frame_iconified_p);
688   CONSOLE_HAS_METHOD (mswindows, set_frame_pointer); 
689   CONSOLE_HAS_METHOD (mswindows, set_frame_icon); 
690   CONSOLE_HAS_METHOD (mswindows, get_frame_parent);
691   CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits);
692   CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p);
693 }
694
695 void
696 syms_of_frame_mswindows (void)
697 {
698 }
699
700 void
701 vars_of_frame_mswindows (void)
702 {
703   /* Needn't staticpro -- see comment above.  */
704   Vmswindows_frame_being_created = Qnil;
705
706   DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /*
707 Controls whether to use system or XEmacs defaults for frame size.
708 If nil then reasonable defaults are used for intial frame sizes. If t
709 then the system will choose default sizes for the frame.
710 */ );
711   Vmswindows_use_system_frame_size_defaults = Qnil;
712   
713   DEFVAR_LISP ("default-mswindows-frame-plist", &Vdefault_mswindows_frame_plist /*
714 Plist of default frame-creation properties for mswindows frames.
715 These override what is specified in `default-frame-plist', but are
716 overridden by the arguments to the particular call to `make-frame'.
717
718 Note: In many cases, properties of a frame are available as specifiers
719 instead of through the frame-properties mechanism.
720
721 Here is a list of recognized frame properties, other than those
722 documented in `set-frame-properties' (they can be queried and
723 set at any time, except as otherwise noted):
724
725   initially-unmapped            If non-nil, the frame will not be visible
726                                 when it is created.  In this case, you
727                                 need to call `make-frame-visible' to make
728                                 the frame appear.
729   popup                         If non-nil, it should be a frame, and this
730                                 frame will be created as a "popup" frame
731                                 whose parent is the given frame.  This
732                                 will make the window manager treat the
733                                 frame as a dialog box, which may entail
734                                 doing different things (e.g. not asking
735                                 for positioning, and not iconifying
736                                 separate from its parent).
737   top                           Y position (in pixels) of the upper-left
738                                 outermost corner of the frame (i.e. the
739                                 upper-left of the window-manager
740                                 decorations).
741   left                          X position (in pixels) of the upper-left
742                                 outermost corner of the frame (i.e. the
743                                 upper-left of the window-manager
744                                 decorations).
745
746 See also `default-frame-plist', which specifies properties which apply
747 to all frames, not just mswindows frames.
748 */ );
749   Vdefault_mswindows_frame_plist = Qnil;
750
751   mswindows_console_methods->device_specific_frame_props =
752     &Vdefault_mswindows_frame_plist;
753 }