comparison src/frame-msw.c @ 428:3ecd8885ac67 r21-2-22

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