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