Mercurial > hg > xemacs-beta
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 } |