Mercurial > hg > xemacs-beta
annotate src/frame-msw.c @ 5043:d0c14ea98592
various frame-geometry fixes
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-02-15 Ben Wing <ben@xemacs.org>
* EmacsFrame.c:
* EmacsFrame.c (EmacsFrameResize):
* console-msw-impl.h:
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (FRAME_MSWINDOWS_TARGET_RECT):
* device-tty.c:
* device-tty.c (tty_asynch_device_change):
* event-msw.c:
* event-msw.c (mswindows_wnd_proc):
* faces.c (Fface_list):
* faces.h:
* frame-gtk.c:
* frame-gtk.c (gtk_set_initial_frame_size):
* frame-gtk.c (gtk_set_frame_size):
* frame-msw.c:
* frame-msw.c (mswindows_init_frame_1):
* frame-msw.c (mswindows_set_frame_size):
* frame-msw.c (mswindows_size_frame_internal):
* frame-msw.c (msprinter_init_frame_3):
* frame.c:
* frame.c (enum):
* frame.c (Fmake_frame):
* frame.c (adjust_frame_size):
* frame.c (store_minibuf_frame_prop):
* frame.c (Fframe_property):
* frame.c (Fframe_properties):
* frame.c (Fframe_displayable_pixel_height):
* frame.c (Fframe_displayable_pixel_width):
* frame.c (internal_set_frame_size):
* frame.c (Fset_frame_height):
* frame.c (Fset_frame_pixel_height):
* frame.c (Fset_frame_displayable_pixel_height):
* frame.c (Fset_frame_width):
* frame.c (Fset_frame_pixel_width):
* frame.c (Fset_frame_displayable_pixel_width):
* frame.c (Fset_frame_size):
* frame.c (Fset_frame_pixel_size):
* frame.c (Fset_frame_displayable_pixel_size):
* frame.c (frame_conversion_internal_1):
* frame.c (get_frame_displayable_pixel_size):
* frame.c (change_frame_size_1):
* frame.c (change_frame_size):
* frame.c (generate_title_string):
* frame.h:
* gtk-xemacs.c:
* gtk-xemacs.c (gtk_xemacs_size_request):
* gtk-xemacs.c (gtk_xemacs_size_allocate):
* gtk-xemacs.c (gtk_xemacs_paint):
* gutter.c:
* gutter.c (update_gutter_geometry):
* redisplay.c (end_hold_frame_size_changes):
* redisplay.c (redisplay_frame):
* toolbar.c:
* toolbar.c (update_frame_toolbars_geometry):
* window.c:
* window.c (frame_pixsize_valid_p):
* window.c (check_frame_size):
Various fixes to frame geometry to make it a bit easier to understand
and fix some bugs.
1. IMPORTANT: Some renamings. Will need to be applied carefully to
the carbon repository, in the following order:
-- pixel_to_char_size -> pixel_to_frame_unit_size
-- char_to_pixel_size -> frame_unit_to_pixel_size
-- pixel_to_real_char_size -> pixel_to_char_size
-- char_to_real_pixel_size -> char_to_pixel_size
-- Reverse second and third arguments of change_frame_size() and
change_frame_size_1() to try to make functions consistent in
putting width before height.
-- Eliminate old round_size_to_char, because it didn't really
do anything differently from round_size_to_real_char()
-- round_size_to_real_char -> round_size_to_char; any places that
called the old round_size_to_char should just call the new one.
2. IMPORTANT FOR CARBON: The set_frame_size() method is now passed
sizes in "frame units", like all other frame-sizing functions,
rather than some hacked-up combination of char-cell units and
total pixel size. This only affects window systems that use
"pixelated geometry", and I'm not sure if Carbon is one of them.
MS Windows is pixelated, X and GTK are not. For pixelated-geometry
systems, the size in set_frame_size() is in displayable pixels
rather than total pixels and needs to be converted appropriately;
take a look at the changes made to mswindows_set_frame_size()
method if necessary.
3. Add a big long comment in frame.c describing how frame geometry
works.
4. Remove MS Windows-specific character height and width fields,
duplicative and unused.
5. frame-displayable-pixel-* and set-frame-displayable-pixel-*
didn't use to work on MS Windows, but they do now.
6. In general, clean up the handling of "pixelated geometry" so
that fewer functions have to worry about this. This is really
an abomination that should be removed entirely but that will
have to happen later. Fix some buggy code in
frame_conversion_internal() that happened to "work" because it
was countered by oppositely buggy code in change_frame_size().
7. Clean up some frame-size code in toolbar.c and use functions
already provided in frame.c instead of rolling its own.
8. Fix check_frame_size() in window.c, which formerly didn't take
pixelated geometry into account.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 15 Feb 2010 22:14:11 -0600 |
parents | ae48681c47fa |
children | 2a462149bd6a |
rev | line source |
---|---|
428 | 1 /* Functions for the mswindows window system. |
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | |
5043 | 3 Copyright (C) 1995, 1996, 2001, 2002, 2010 Ben Wing. |
428 | 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 | |
771 | 24 /* This file Mule-ized, 8-14-2000. */ |
25 | |
428 | 26 /* Authorship: |
27 | |
28 Ultimately based on FSF. | |
29 Substantially rewritten for XEmacs by Ben Wing. | |
30 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0. | |
31 Graphics features added and frame resizing fiddled with by Andy Piper. | |
32 */ | |
33 | |
34 #include <config.h> | |
35 #include "lisp.h" | |
36 | |
37 #include "buffer.h" | |
872 | 38 #include "device-impl.h" |
428 | 39 #include "elhash.h" |
40 #include "events.h" | |
41 #include "faces.h" | |
872 | 42 #include "frame-impl.h" |
428 | 43 #include "redisplay.h" |
44 #include "window.h" | |
45 | |
872 | 46 #include "console-msw-impl.h" |
800 | 47 #include "glyphs-msw.h" |
48 | |
428 | 49 #define MSWINDOWS_FRAME_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW) |
50 #define MSWINDOWS_POPUP_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP \ | |
51 | WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX) | |
52 | |
53 #define MSWINDOWS_FRAME_EXSTYLE WS_EX_OVERLAPPEDWINDOW | |
54 #define MSWINDOWS_POPUP_EXSTYLE WS_EX_PALETTEWINDOW | |
55 | |
56 /* Default popup left top corner offset from the same | |
57 corner of the parent frame, in pixel */ | |
58 #define POPUP_OFFSET 30 | |
59 | |
60 /* Default popup size, in characters */ | |
61 #define POPUP_WIDTH 30 | |
62 #define POPUP_HEIGHT 10 | |
63 | |
793 | 64 /* Default regular frame size, in characters; if too big, it will get |
65 shrunk to the workspace size */ | |
428 | 66 #define DEFAULT_FRAME_WIDTH 80 |
793 | 67 #define DEFAULT_FRAME_HEIGHT 50 |
428 | 68 |
69 #ifdef HAVE_MENUBARS | |
70 #define ADJR_MENUFLAG TRUE | |
71 #else | |
72 #define ADJR_MENUFLAG FALSE | |
73 #endif | |
74 | |
75 /* Default properties to use when creating frames. */ | |
76 Lisp_Object Vdefault_mswindows_frame_plist; | |
440 | 77 Lisp_Object Vdefault_msprinter_frame_plist; |
428 | 78 Lisp_Object Vmswindows_use_system_frame_size_defaults; |
79 | |
80 /* This does not need to be GC protected, as it holds a | |
81 frame Lisp_Object already protected by Fmake_frame */ | |
82 Lisp_Object Vmswindows_frame_being_created; | |
83 | |
1204 | 84 static const struct memory_description mswindows_frame_data_description_1 [] = { |
85 #ifdef HAVE_TOOLBARS | |
86 { XD_LISP_OBJECT, offsetof (struct mswindows_frame, toolbar_hash_table) }, | |
87 #endif | |
88 { XD_LISP_OBJECT, offsetof (struct mswindows_frame, menu_hash_table) }, | |
89 { XD_LISP_OBJECT, offsetof (struct mswindows_frame, widget_hash_table1) }, | |
90 { XD_LISP_OBJECT, offsetof (struct mswindows_frame, widget_hash_table2) }, | |
91 { XD_LISP_OBJECT, offsetof (struct mswindows_frame, widget_hash_table3) }, | |
92 { XD_END } | |
93 }; | |
94 | |
3092 | 95 #ifdef NEW_GC |
96 DEFINE_LRECORD_IMPLEMENTATION ("mswindows-frame", mswindows_frame, | |
97 1, /*dumpable-flag*/ | |
98 0, 0, 0, 0, 0, | |
99 mswindows_frame_data_description_1, | |
100 Lisp_Mswindows_Frame); | |
101 #else /* not NEW_GC */ | |
1204 | 102 extern const struct sized_memory_description mswindows_frame_data_description; |
103 | |
104 const struct sized_memory_description mswindows_frame_data_description = { | |
105 sizeof (struct mswindows_frame), mswindows_frame_data_description_1 | |
106 }; | |
3092 | 107 #endif /* not NEW_GC */ |
1204 | 108 |
440 | 109 /*---------------------------------------------------------------------*/ |
110 /*----- DISPLAY FRAME -----*/ | |
111 /*---------------------------------------------------------------------*/ | |
112 | |
3022 | 113 static struct frame * |
114 decode_mswindows_frame (Lisp_Object frame) | |
115 { | |
116 if (NILP (frame)) | |
117 frame = wrap_frame (selected_frame ()); | |
118 CHECK_LIVE_FRAME (frame); | |
119 /* this will also catch dead frames, but putting in the above check | |
120 results in a more useful error */ | |
121 CHECK_MSWINDOWS_FRAME (frame); | |
122 return XFRAME (frame); | |
123 } | |
124 | |
442 | 125 HWND |
126 mswindows_get_selected_frame_hwnd (void) | |
127 { | |
128 Lisp_Object frame, device; | |
129 | |
130 device = Ffind_device (Qnil, Qmswindows); | |
131 if (NILP (device)) | |
132 return NULL; | |
133 frame = DEVICE_SELECTED_FRAME (XDEVICE (device)); | |
134 if (NILP (frame)) | |
135 return NULL; | |
136 | |
137 return FRAME_MSWINDOWS_HANDLE (XFRAME (frame)); | |
138 } | |
139 | |
428 | 140 static void |
771 | 141 mswindows_init_frame_1 (struct frame *f, Lisp_Object props, |
2286 | 142 int UNUSED (frame_name_is_defaulted)) |
428 | 143 { |
144 Lisp_Object initially_unmapped; | |
145 Lisp_Object name, height, width, popup, top, left; | |
146 Lisp_Object frame_obj = Qnil; | |
147 RECT rect; | |
148 XEMACS_RECT_WH rect_default; | |
149 DWORD style, exstyle; | |
150 HWND hwnd, hwnd_parent; | |
151 | |
152 /* Pick up relevant properties */ | |
153 initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil); | |
154 name = Fplist_get (props, Qname, Qnil); | |
442 | 155 |
428 | 156 popup = Fplist_get (props, Qpopup, Qnil); |
157 if (EQ (popup, Qt)) | |
158 popup = Fselected_frame (Qnil); | |
159 | |
160 left = Fplist_get (props, Qleft, Qnil); | |
161 if (!NILP (left)) | |
162 CHECK_INT (left); | |
163 | |
164 top = Fplist_get (props, Qtop, Qnil); | |
165 if (!NILP (top)) | |
166 CHECK_INT (top); | |
167 | |
168 width = Fplist_get (props, Qwidth, Qnil); | |
169 if (!NILP (width)) | |
170 CHECK_INT (width); | |
171 | |
172 height = Fplist_get (props, Qheight, Qnil); | |
173 if (!NILP (height)) | |
174 CHECK_INT (height); | |
175 | |
3092 | 176 #ifdef NEW_GC |
177 f->frame_data = alloc_lrecord_type (struct mswindows_frame, | |
178 &lrecord_mswindows_frame); | |
179 #else /* not NEW_GC */ | |
428 | 180 f->frame_data = xnew_and_zero (struct mswindows_frame); |
3092 | 181 #endif /* not NEW_GC */ |
428 | 182 FRAME_MSWINDOWS_TARGET_RECT (f) = xnew_and_zero (XEMACS_RECT_WH); |
183 | |
184 FRAME_MSWINDOWS_TARGET_RECT (f)->left = NILP (left) ? -1 : abs (XINT (left)); | |
185 FRAME_MSWINDOWS_TARGET_RECT (f)->top = NILP (top) ? -1 : abs (XINT (top)); | |
442 | 186 FRAME_MSWINDOWS_TARGET_RECT (f)->width = NILP (width) ? -1 : |
428 | 187 abs (XINT (width)); |
442 | 188 FRAME_MSWINDOWS_TARGET_RECT (f)->height = NILP (height) ? -1 : |
428 | 189 abs (XINT (height)); |
442 | 190 |
428 | 191 /* Misc frame stuff */ |
771 | 192 FRAME_MSWINDOWS_MENU_HASH_TABLE (f) = Qnil; |
428 | 193 #ifdef HAVE_TOOLBARS |
1130 | 194 /* EQ not EQUAL or we will get QUIT crashes, see below. */ |
771 | 195 FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f) = |
1130 | 196 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ); |
428 | 197 #endif |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4139
diff
changeset
|
198 /* hashtable of instantiated glyphs on the frame. [[ Make them EQ because |
1123 | 199 we only use ints as keys. Otherwise we run into stickiness in |
200 redisplay because internal_equal() can QUIT. See | |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4139
diff
changeset
|
201 enter_redisplay_critical_section(). ]] -- probably not true any more, |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4139
diff
changeset
|
202 now that we have internal_equal_trapping_problems(). --ben */ |
442 | 203 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f) = |
853 | 204 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); |
442 | 205 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f) = |
853 | 206 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); |
442 | 207 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f) = |
853 | 208 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); |
428 | 209 /* Will initialize these in WM_SIZE handler. We cannot do it now, |
210 because we do not know what is CW_USEDEFAULT height and width */ | |
211 FRAME_WIDTH (f) = 0; | |
212 FRAME_HEIGHT (f) = 0; | |
213 FRAME_PIXWIDTH (f) = 0; | |
214 FRAME_PIXHEIGHT (f) = 0; | |
215 | |
216 if (NILP (popup)) | |
217 { | |
218 style = MSWINDOWS_FRAME_STYLE; | |
219 exstyle = MSWINDOWS_FRAME_EXSTYLE; | |
220 hwnd_parent = NULL; | |
221 | |
222 rect_default.left = rect_default.top = CW_USEDEFAULT; | |
223 rect_default.width = rect_default.height = CW_USEDEFAULT; | |
224 } | |
225 else | |
226 { | |
227 style = MSWINDOWS_POPUP_STYLE; | |
228 exstyle = MSWINDOWS_POPUP_EXSTYLE; | |
229 | |
230 CHECK_MSWINDOWS_FRAME (popup); | |
231 hwnd_parent = FRAME_MSWINDOWS_HANDLE (XFRAME (popup)); | |
232 assert (IsWindow (hwnd_parent)); | |
233 | |
234 /* We cannot use CW_USEDEFAULT when creating a popup window. | |
235 So by default, we offset the new popup 30 pixels right | |
236 and down from its parent, and give it size of 30x10 characters. | |
237 These dimensions look adequate on both high and low res monitors */ | |
238 GetWindowRect (hwnd_parent, &rect); | |
239 rect_default.left = rect.left + POPUP_OFFSET; | |
240 rect_default.top = rect.top + POPUP_OFFSET; | |
5043 | 241 char_to_pixel_size (f, POPUP_WIDTH, POPUP_HEIGHT, |
428 | 242 &rect_default.width, &rect_default.height); |
442 | 243 FRAME_MSWINDOWS_POPUP (f) = 1; |
428 | 244 } |
245 | |
771 | 246 AdjustWindowRectEx (&rect, style, ADJR_MENUFLAG, exstyle); |
428 | 247 |
793 | 248 frame_obj = wrap_frame (f); |
428 | 249 |
250 Vmswindows_frame_being_created = frame_obj; | |
771 | 251 { |
252 const Extbyte *nameext = 0; | |
428 | 253 |
771 | 254 if (STRINGP (f->name)) |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
255 nameext = LISP_STRING_TO_TSTR (f->name); |
771 | 256 else if (STRINGP (name)) |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
257 nameext = LISP_STRING_TO_TSTR (name); |
771 | 258 else |
259 nameext = XETEXT (XEMACS_CLASS); | |
260 hwnd = qxeCreateWindowEx (exstyle, | |
261 XETEXT (XEMACS_CLASS), | |
262 nameext, | |
263 style, | |
264 rect_default.left, rect_default.top, | |
265 rect_default.width, rect_default.height, | |
266 hwnd_parent, NULL, NULL, NULL); | |
267 } | |
428 | 268 |
269 Vmswindows_frame_being_created = Qnil; | |
270 | |
271 if (hwnd == NULL) | |
442 | 272 invalid_operation ("System call to create frame failed", |
273 STRINGP (f->name) ? f->name : | |
274 STRINGP (name) ? name : | |
275 Qunbound); | |
771 | 276 |
277 FRAME_MSWINDOWS_HANDLE (f) = hwnd; | |
428 | 278 |
5013 | 279 qxeSetWindowLong (hwnd, XWL_FRAMEOBJ, (LONG)STORE_LISP_IN_VOID (frame_obj)); |
771 | 280 FRAME_MSWINDOWS_DC (f) = GetDC (hwnd); |
281 SetTextAlign (FRAME_MSWINDOWS_DC (f), TA_BASELINE | TA_LEFT | TA_NOUPDATECP); | |
442 | 282 |
771 | 283 #ifdef HAVE_DIALOGS |
442 | 284 if (FRAME_MSWINDOWS_POPUP (f)) |
285 mswindows_register_popup_frame (frame_obj); | |
771 | 286 #endif /* HAVE_DIALOGS */ |
428 | 287 } |
288 | |
289 static void | |
2286 | 290 mswindows_init_frame_2 (struct frame *f, Lisp_Object UNUSED (props)) |
428 | 291 { |
292 if (NILP (Vmswindows_use_system_frame_size_defaults)) | |
293 { | |
294 /* I don't think anything can set the frame size before this | |
295 since we don't have X resources. This may change if we look | |
296 at the registry. Even so these values can get overridden | |
297 later.*/ | |
442 | 298 XEMACS_RECT_WH dest = { -1, -1, DEFAULT_FRAME_WIDTH, |
428 | 299 DEFAULT_FRAME_HEIGHT }; |
300 mswindows_size_frame_internal (f, &dest); | |
301 } | |
302 } | |
303 | |
304 /* Called after frame's properties are set */ | |
305 static void | |
306 mswindows_init_frame_3 (struct frame *f) | |
307 { | |
4139 | 308 /* Don't do this earlier or we get a WM_PAINT before the frame is ready. */ |
309 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL); | |
310 #ifdef CYGWIN | |
311 /* The SW_x parameter in the first call that an app makes to ShowWindow is | |
312 * ignored, and the parameter specified in the caller's STARTUPINFO is | |
313 * substituted instead. That parameter is SW_HIDE if we were started by | |
314 * runemacs, so call this twice. #### runemacs is evil. To see why this | |
315 * second call was restored, see the threads referenced by | |
316 * 20a807210611011157j57ea2b22ue892f4dfcb6aade8@mail.gmail.com and | |
317 * 20a807210708181345m7ac94ff2m43337be71e853d95@mail.gmail.com . */ | |
318 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL); | |
319 #endif | |
320 SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f)); | |
321 DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE); | |
428 | 322 } |
323 | |
324 static void | |
2286 | 325 mswindows_after_init_frame (struct frame *UNUSED (f), |
326 int UNUSED (first_on_device), int first_on_console) | |
428 | 327 { |
328 /* Windows, unlike X, is very synchronous. After the initial | |
442 | 329 frame is created, it will never be displayed, except for |
428 | 330 hollow border, unless we start pumping messages. Load progress |
331 messages show in the bottom of the hollow frame, which is ugly. | |
332 We redisplay the initial frame here, so modeline and root window | |
333 background show. | |
334 */ | |
335 if (first_on_console) | |
336 redisplay (); | |
337 } | |
338 | |
339 static void | |
340 mswindows_mark_frame (struct frame *f) | |
341 { | |
342 mark_object (FRAME_MSWINDOWS_MENU_HASH_TABLE (f)); | |
343 #ifdef HAVE_TOOLBARS | |
344 mark_object (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f)); | |
345 #endif | |
442 | 346 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f)); |
347 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f)); | |
348 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f)); | |
428 | 349 } |
350 | |
351 static void | |
352 mswindows_focus_on_frame (struct frame *f) | |
353 { | |
771 | 354 SetForegroundWindow (FRAME_MSWINDOWS_HANDLE (f)); |
428 | 355 } |
356 | |
357 static void | |
358 mswindows_delete_frame (struct frame *f) | |
359 { | |
360 if (f->frame_data) | |
361 { | |
771 | 362 #ifdef HAVE_DIALOGS |
363 mswindows_unregister_popup_frame (wrap_frame (f)); | |
364 #endif | |
365 ReleaseDC (FRAME_MSWINDOWS_HANDLE (f), FRAME_MSWINDOWS_DC (f)); | |
366 DestroyWindow (FRAME_MSWINDOWS_HANDLE (f)); | |
4117 | 367 #ifndef NEW_GC |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
368 xfree (f->frame_data); |
3092 | 369 #endif /* not NEW_GC */ |
428 | 370 } |
371 f->frame_data = 0; | |
372 } | |
373 | |
374 static void | |
375 mswindows_set_frame_size (struct frame *f, int width, int height) | |
376 { | |
377 RECT rect; | |
5043 | 378 int pwidth, pheight; |
379 | |
380 change_frame_size (f, width, height, 0); | |
381 frame_unit_to_pixel_size (f, width, height, &pwidth, &pheight); | |
1395 | 382 |
428 | 383 rect.left = rect.top = 0; |
5043 | 384 rect.right = pwidth; |
385 rect.bottom = pheight; | |
1395 | 386 |
1318 | 387 /* This can call Lisp, because it runs the window procedure, which can |
388 call redisplay() */ | |
428 | 389 AdjustWindowRectEx (&rect, |
771 | 390 qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_STYLE), |
391 GetMenu (FRAME_MSWINDOWS_HANDLE (f)) != NULL, | |
392 qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_EXSTYLE)); | |
428 | 393 |
2872 | 394 if (IsIconic (FRAME_MSWINDOWS_HANDLE (f))) |
771 | 395 ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_RESTORE); |
428 | 396 |
771 | 397 SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), NULL, |
428 | 398 0, 0, rect.right-rect.left, rect.bottom-rect.top, |
399 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOMOVE); | |
400 } | |
401 | |
402 static void | |
403 mswindows_set_frame_position (struct frame *f, int xoff, int yoff) | |
404 { | |
771 | 405 SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), NULL, |
428 | 406 xoff, yoff, 0, 0, |
407 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE); | |
408 } | |
409 | |
410 static void | |
442 | 411 mswindows_make_frame_visible (struct frame *f) |
428 | 412 { |
771 | 413 if (!FRAME_VISIBLE_P (f)) |
414 ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_RESTORE); | |
428 | 415 else |
771 | 416 ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_SHOW); |
417 SetActiveWindow (FRAME_MSWINDOWS_HANDLE (f)); | |
428 | 418 f->visible = 1; |
419 f->iconified = 0; | |
420 } | |
421 | |
422 static void | |
442 | 423 mswindows_make_frame_invisible (struct frame *f) |
428 | 424 { |
771 | 425 if (!FRAME_VISIBLE_P (f)) |
428 | 426 return; |
427 | |
771 | 428 ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_HIDE); |
428 | 429 f->visible = 0; |
430 } | |
431 | |
432 static int | |
433 mswindows_frame_totally_visible_p (struct frame *f) | |
434 { | |
435 RECT rc_me, rc_other, rc_temp; | |
771 | 436 HWND hwnd = FRAME_MSWINDOWS_HANDLE (f); |
428 | 437 |
438 /* We test against not a whole window rectangle, only against its | |
439 client part. So, if non-client are is covered and client area is | |
440 not, we return true. */ | |
441 GetClientRect (hwnd, &rc_me); | |
2367 | 442 MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT) (void *) (&rc_me), 2); |
428 | 443 |
444 /* First see if we're off the desktop */ | |
771 | 445 GetWindowRect (GetDesktopWindow (), &rc_other); |
446 UnionRect (&rc_temp, &rc_me, &rc_other); | |
428 | 447 if (!EqualRect (&rc_temp, &rc_other)) |
448 return 0; | |
442 | 449 |
428 | 450 /* Then see if any window above us obscures us */ |
451 while ((hwnd = GetWindow (hwnd, GW_HWNDPREV)) != NULL) | |
452 if (IsWindowVisible (hwnd)) | |
453 { | |
454 GetWindowRect (hwnd, &rc_other); | |
771 | 455 if (IntersectRect (&rc_temp, &rc_me, &rc_other)) |
428 | 456 return 0; |
457 } | |
458 | |
459 return 1; | |
460 } | |
461 | |
462 static int | |
463 mswindows_frame_visible_p (struct frame *f) | |
464 { | |
771 | 465 return IsWindowVisible (FRAME_MSWINDOWS_HANDLE (f)) |
466 && !IsIconic (FRAME_MSWINDOWS_HANDLE (f)); | |
428 | 467 } |
468 | |
469 | |
470 static void | |
471 mswindows_iconify_frame (struct frame *f) | |
472 { | |
771 | 473 ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_MINIMIZE); |
428 | 474 f->visible = 0; |
475 f->iconified = 1; | |
476 } | |
477 | |
478 static int | |
479 mswindows_frame_iconified_p (struct frame *f) | |
480 { | |
771 | 481 return IsIconic (FRAME_MSWINDOWS_HANDLE (f)); |
428 | 482 } |
483 | |
484 static void | |
485 mswindows_set_frame_icon (struct frame *f) | |
486 { | |
487 if (IMAGE_INSTANCEP (f->icon) | |
488 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon))) | |
489 { | |
490 if (!XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon)) | |
491 { | |
442 | 492 mswindows_initialize_image_instance_icon (XIMAGE_INSTANCE (f->icon), |
428 | 493 FALSE); |
494 } | |
442 | 495 |
771 | 496 qxeSetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HICON, |
497 (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon)); | |
428 | 498 } |
499 } | |
500 | |
501 static void | |
502 mswindows_set_frame_pointer (struct frame *f) | |
503 { | |
504 if (IMAGE_INSTANCEP (f->pointer) | |
505 && IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (f->pointer)) == IMAGE_POINTER) | |
506 { | |
771 | 507 qxeSetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR, |
508 (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer)); | |
428 | 509 /* we only have to do this because GC doesn't cause a mouse |
510 event and doesn't give time to event processing even if it | |
511 did. */ | |
512 SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer)); | |
513 } | |
514 } | |
515 | |
516 static void | |
517 mswindows_set_mouse_position (struct window *w, int x, int y) | |
518 { | |
519 struct frame *f = XFRAME (w->frame); | |
520 POINT pt; | |
521 | |
522 pt.x = w->pixel_left + x; | |
523 pt.y = w->pixel_top + y; | |
771 | 524 ClientToScreen (FRAME_MSWINDOWS_HANDLE (f), &pt); |
428 | 525 SetCursorPos (pt.x, pt.y); |
526 } | |
527 | |
528 static int | |
2286 | 529 mswindows_get_mouse_position (struct device *UNUSED (d), Lisp_Object *frame, |
530 int *x, int *y) | |
428 | 531 { |
532 POINT pt; | |
533 HWND hwnd; | |
534 | |
535 GetCursorPos (&pt); | |
536 | |
537 /* What's under cursor? */ | |
538 hwnd = WindowFromPoint (pt); | |
539 if (hwnd == NULL) | |
540 return 0; | |
541 | |
542 /* Get grandest parent of the window */ | |
543 { | |
544 HWND hwnd_parent; | |
545 while ((hwnd_parent = GetParent (hwnd)) != NULL) | |
546 hwnd = hwnd_parent; | |
547 } | |
548 | |
549 /* Make sure it belongs to us */ | |
550 if (GetWindowThreadProcessId (hwnd, NULL) != GetCurrentThreadId ()) | |
551 return 0; | |
552 | |
553 /* And that the window is an XEmacs frame */ | |
771 | 554 if (!mswindows_window_is_xemacs (hwnd)) |
555 return 0; | |
428 | 556 |
557 /* Yippie! */ | |
558 ScreenToClient (hwnd, &pt); | |
5013 | 559 *frame = GET_LISP_FROM_VOID ((void *) qxeGetWindowLong (hwnd, XWL_FRAMEOBJ)); |
428 | 560 *x = pt.x; |
561 *y = pt.y; | |
562 return 1; | |
563 } | |
564 | |
565 static void | |
566 mswindows_raise_frame (struct frame *f) | |
567 { | |
771 | 568 BringWindowToTop (FRAME_MSWINDOWS_HANDLE (f)); |
428 | 569 } |
570 | |
571 static void | |
572 mswindows_lower_frame (struct frame *f) | |
573 { | |
771 | 574 SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), HWND_BOTTOM, 0, 0, 0, 0, |
428 | 575 SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING); |
576 } | |
577 | |
578 static void | |
442 | 579 mswindows_enable_frame (struct frame *f) |
580 { | |
581 EnableWindow (FRAME_MSWINDOWS_HANDLE (f), TRUE); | |
582 } | |
583 | |
584 static void | |
585 mswindows_disable_frame (struct frame *f) | |
586 { | |
587 EnableWindow (FRAME_MSWINDOWS_HANDLE (f), FALSE); | |
588 } | |
589 | |
590 static void | |
867 | 591 mswindows_set_title_from_ibyte (struct frame *f, Ibyte *title) |
428 | 592 { |
771 | 593 unsigned int new_checksum = hash_string (title, qxestrlen (title)); |
593 | 594 if (new_checksum != FRAME_MSWINDOWS_TITLE_CHECKSUM (f)) |
428 | 595 { |
593 | 596 Extbyte *title_ext; |
597 | |
598 FRAME_MSWINDOWS_TITLE_CHECKSUM (f) = new_checksum; | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
599 title_ext = ITEXT_TO_TSTR (title); |
771 | 600 qxeSetWindowText (FRAME_MSWINDOWS_HANDLE (f), title_ext); |
428 | 601 } |
602 } | |
603 | |
604 static Lisp_Object | |
3022 | 605 mswindows_window_id (Lisp_Object frame) |
606 { | |
607 Ibyte str[255]; | |
608 struct frame *f = decode_mswindows_frame (frame); | |
609 | |
3023 | 610 qxesprintf (str, "%lu", (unsigned long) FRAME_MSWINDOWS_HANDLE (f)); |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4139
diff
changeset
|
611 return build_istring (str); |
3022 | 612 } |
613 | |
614 static Lisp_Object | |
428 | 615 mswindows_frame_property (struct frame *f, Lisp_Object property) |
616 { | |
617 if (EQ (Qleft, property) || EQ (Qtop, property)) | |
618 { | |
619 RECT rc; | |
771 | 620 GetWindowRect (FRAME_MSWINDOWS_HANDLE (f), &rc); |
428 | 621 return make_int (EQ (Qtop, property) ? rc.top : rc.left); |
622 } | |
3022 | 623 if (EQ (Qwindow_id, property)) |
624 return mswindows_window_id (wrap_frame (f)); | |
625 | |
428 | 626 return Qunbound; |
627 } | |
628 | |
629 static int | |
2286 | 630 mswindows_internal_frame_property_p (struct frame *UNUSED (f), |
631 Lisp_Object property) | |
428 | 632 { |
633 return EQ (property, Qleft) | |
3022 | 634 || EQ (property, Qtop) |
635 || EQ (property, Qwindow_id); | |
428 | 636 /* #### frame-x.c has also this. Why? |
637 || STRINGP (property); | |
638 */ | |
639 } | |
640 | |
641 static Lisp_Object | |
642 mswindows_frame_properties (struct frame *f) | |
643 { | |
644 Lisp_Object props = Qnil; | |
645 RECT rc; | |
771 | 646 GetWindowRect (FRAME_MSWINDOWS_HANDLE (f), &rc); |
428 | 647 |
648 props = cons3 (Qtop, make_int (rc.top), props); | |
649 props = cons3 (Qleft, make_int (rc.left), props); | |
3022 | 650 props = cons3 (Qwindow_id, mswindows_window_id (wrap_frame (f)), props); |
428 | 651 |
652 return props; | |
653 } | |
654 | |
655 static void | |
656 mswindows_set_frame_properties (struct frame *f, Lisp_Object plist) | |
657 { | |
658 int x=-1, y=-1; | |
659 int width = -1, height = -1; | |
660 BOOL width_specified_p = FALSE; | |
661 BOOL height_specified_p = FALSE; | |
662 BOOL x_specified_p = FALSE; | |
663 BOOL y_specified_p = FALSE; | |
664 Lisp_Object tail; | |
665 | |
666 /* Extract the properties from plist */ | |
667 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | |
668 { | |
669 Lisp_Object prop = Fcar (tail); | |
670 Lisp_Object val = Fcar (Fcdr (tail)); | |
671 | |
672 if (SYMBOLP (prop)) | |
673 { | |
674 /* Kludge to handle the font property. */ | |
675 if (EQ (prop, Qfont)) | |
676 { | |
677 /* If the value is not a string we silently ignore it. */ | |
678 if (STRINGP (val)) | |
679 { | |
680 Lisp_Object frm, font_spec; | |
442 | 681 |
793 | 682 frm = wrap_frame (f); |
428 | 683 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil); |
684 | |
685 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil); | |
686 update_frame_face_values (f); | |
687 } | |
688 } | |
689 else if (EQ (prop, Qwidth)) | |
690 { | |
691 CHECK_INT (val); | |
692 width = XINT (val); | |
693 width_specified_p = TRUE; | |
694 } | |
695 else if (EQ (prop, Qheight)) | |
696 { | |
697 CHECK_INT (val); | |
698 height = XINT (val); | |
699 height_specified_p = TRUE; | |
700 } | |
701 else if (EQ (prop, Qleft)) | |
702 { | |
703 CHECK_INT (val); | |
704 x = XINT (val); | |
705 x_specified_p = TRUE; | |
706 } | |
707 else if (EQ (prop, Qtop)) | |
708 { | |
709 CHECK_INT (val); | |
710 y = XINT (val); | |
711 y_specified_p = TRUE; | |
712 } | |
713 } | |
714 } | |
715 | |
716 /* Now we've extracted the properties, apply them. | |
717 Do not apply geometric properties during frame creation. This | |
442 | 718 is excessive anyways, and this loses because WM_SIZE has not |
428 | 719 been sent yet, so frame width and height fields are not initialized. |
442 | 720 |
428 | 721 unfortunately WM_SIZE loses as well since the resize is only |
722 applied once and the first time WM_SIZE is applied not everything | |
723 is initialised in the frame (toolbars for instance). enabling | |
724 this always makes no visible difference and fixes a whole host of | |
725 bugs (and is more consistent with X) so I am going to reenable it. | |
726 --andyp */ | |
727 if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f) | |
440 | 728 && (width_specified_p || height_specified_p |
729 || x_specified_p || y_specified_p)) | |
428 | 730 { |
731 XEMACS_RECT_WH dest = { x, y, width, height }; | |
732 | |
733 mswindows_size_frame_internal (f, &dest); | |
734 } | |
735 } | |
736 | |
506 | 737 void |
771 | 738 mswindows_size_frame_internal (struct frame *f, XEMACS_RECT_WH *dest) |
428 | 739 { |
442 | 740 RECT rect, ws_rect; |
428 | 741 int pixel_width, pixel_height; |
742 int size_p = (dest->width >=0 || dest->height >=0); | |
743 int move_p = (dest->top >=0 || dest->left >=0); | |
5043 | 744 char_to_pixel_size (f, dest->width, dest->height, &pixel_width, |
506 | 745 &pixel_height); |
442 | 746 |
428 | 747 if (dest->width < 0) |
748 pixel_width = FRAME_PIXWIDTH (f); | |
749 if (dest->height < 0) | |
750 pixel_height = FRAME_PIXHEIGHT (f); | |
751 | |
771 | 752 GetWindowRect (FRAME_MSWINDOWS_HANDLE (f), &rect); |
428 | 753 if (dest->left < 0) |
754 dest->left = rect.left; | |
755 if (dest->top < 0) | |
756 dest->top = rect.top; | |
442 | 757 |
428 | 758 rect.left = rect.top = 0; |
759 rect.right = pixel_width; | |
760 rect.bottom = pixel_height; | |
761 | |
762 AdjustWindowRectEx (&rect, | |
771 | 763 qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_STYLE), |
764 GetMenu (FRAME_MSWINDOWS_HANDLE (f)) != NULL, | |
765 qxeGetWindowLong (FRAME_MSWINDOWS_HANDLE (f), GWL_EXSTYLE)); | |
428 | 766 |
442 | 767 /* resize and move the window so that it fits in the workspace. This is |
428 | 768 not restrictive since this will happen later anyway in WM_SIZE. We |
769 have to do this after adjusting the rect to account for menubar | |
770 etc. */ | |
442 | 771 mswindows_get_workspace_coords (&ws_rect); |
428 | 772 pixel_width = rect.right - rect.left; |
773 pixel_height = rect.bottom - rect.top; | |
442 | 774 if (pixel_width > ws_rect.right - ws_rect.left) |
428 | 775 { |
442 | 776 pixel_width = ws_rect.right - ws_rect.left; |
428 | 777 size_p=1; |
778 } | |
442 | 779 if (pixel_height > ws_rect.bottom - ws_rect.top) |
428 | 780 { |
442 | 781 pixel_height = ws_rect.bottom - ws_rect.top; |
428 | 782 size_p=1; |
783 } | |
784 | |
442 | 785 /* adjust position so window is in workspace */ |
786 if (dest->left + pixel_width > ws_rect.right) | |
428 | 787 { |
442 | 788 dest->left = ws_rect.right - pixel_width; |
428 | 789 move_p=1; |
790 } | |
442 | 791 if (dest->left < ws_rect.left) |
428 | 792 { |
442 | 793 dest->left = ws_rect.left; |
428 | 794 move_p=1; |
795 } | |
796 | |
442 | 797 if (dest->top + pixel_height > ws_rect.bottom) |
798 { | |
799 dest->top = ws_rect.bottom - pixel_height; | |
800 move_p=1; | |
801 } | |
802 if (dest->top < ws_rect.top) | |
803 { | |
804 dest->top = ws_rect.top; | |
805 move_p=1; | |
806 } | |
807 | |
771 | 808 if (IsIconic (FRAME_MSWINDOWS_HANDLE (f)) |
809 || IsZoomed (FRAME_MSWINDOWS_HANDLE (f))) | |
810 ShowWindow (FRAME_MSWINDOWS_HANDLE (f), SW_RESTORE); | |
428 | 811 |
771 | 812 SetWindowPos (FRAME_MSWINDOWS_HANDLE (f), NULL, |
428 | 813 dest->left, dest->top, pixel_width, pixel_height, |
814 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | |
815 | (size_p ? 0 : SWP_NOSIZE) | |
816 | (move_p ? 0 : SWP_NOMOVE)); | |
817 } | |
818 | |
819 static Lisp_Object | |
820 mswindows_get_frame_parent (struct frame *f) | |
821 { | |
771 | 822 HWND hwnd = FRAME_MSWINDOWS_HANDLE (f); |
428 | 823 hwnd = GetParent (hwnd); |
824 if (hwnd) | |
825 { | |
826 Lisp_Object parent; | |
5013 | 827 parent = GET_LISP_FROM_VOID ((void *) qxeGetWindowLong (hwnd, XWL_FRAMEOBJ)); |
428 | 828 assert (FRAME_MSWINDOWS_P (XFRAME (parent))); |
829 return parent; | |
830 } | |
831 else | |
832 return Qnil; | |
833 } | |
834 | |
835 static void | |
2286 | 836 mswindows_update_frame_external_traits (struct frame *UNUSED (frm), |
837 Lisp_Object UNUSED (name)) | |
428 | 838 { |
839 } | |
840 | |
841 static int | |
842 mswindows_frame_size_fixed_p (struct frame *f) | |
843 { | |
844 /* Frame size cannot change if the frame is maximized */ | |
845 return IsZoomed (FRAME_MSWINDOWS_HANDLE (f)); | |
846 } | |
847 | |
440 | 848 /*---------------------------------------------------------------------*/ |
849 /*----- PRINTER FRAME -----*/ | |
850 /*---------------------------------------------------------------------*/ | |
851 | |
442 | 852 /* |
853 * With some driver/os combination (I discovered this with HP drivers | |
854 * under W2K), DC geometry is reset upon StartDoc and EndPage | |
855 * calls. This is called every time one of these calls is made. | |
856 */ | |
857 static void | |
858 apply_dc_geometry (struct frame* f) | |
859 { | |
860 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))); | |
861 SetTextAlign (hdc, TA_BASELINE | TA_LEFT | TA_NOUPDATECP); | |
862 SetViewportOrgEx (hdc, FRAME_MSPRINTER_PIXLEFT(f), | |
863 FRAME_MSPRINTER_PIXTOP(f), NULL); | |
864 } | |
865 | |
866 void | |
867 msprinter_start_page (struct frame *f) | |
868 { | |
869 if (!FRAME_MSPRINTER_PAGE_STARTED (f)) | |
870 { | |
871 FRAME_MSPRINTER_PAGE_STARTED (f) = 1; | |
872 StartPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)))); | |
873 apply_dc_geometry (f); | |
874 } | |
875 } | |
440 | 876 |
877 static void | |
878 error_frame_unsizable (struct frame *f) | |
879 { | |
793 | 880 Lisp_Object frame = wrap_frame (f); |
881 | |
442 | 882 invalid_change ("Cannot resize frame (margins) after print job has started.", |
883 frame); | |
440 | 884 } |
885 | |
886 static void | |
887 maybe_error_if_job_active (struct frame *f) | |
888 { | |
889 if (FRAME_MSPRINTER_JOB_STARTED (f)) | |
890 error_frame_unsizable (f); | |
891 } | |
892 | |
893 static void | |
2286 | 894 msprinter_init_frame_1 (struct frame *f, Lisp_Object UNUSED (props), |
895 int UNUSED (frame_name_is_defaulted)) | |
440 | 896 { |
897 /* Make sure this is the only frame on device. Windows printer can | |
898 handle only one job at a time. */ | |
899 if (!NILP (DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f))))) | |
442 | 900 invalid_operation ("Only one frame (print job) at a time is allowed on " |
901 "this printer device", FRAME_DEVICE (f)); | |
440 | 902 |
903 f->frame_data = xnew_and_zero (struct msprinter_frame); | |
904 | |
506 | 905 FRAME_MSPRINTER_TOP_MARGIN (f) = |
906 mswindows_get_default_margin (Qtop_margin); | |
907 FRAME_MSPRINTER_BOTTOM_MARGIN (f) = | |
908 mswindows_get_default_margin (Qbottom_margin); | |
909 FRAME_MSPRINTER_LEFT_MARGIN (f) = | |
910 mswindows_get_default_margin (Qleft_margin); | |
911 FRAME_MSPRINTER_RIGHT_MARGIN (f) = | |
912 mswindows_get_default_margin (Qright_margin); | |
440 | 913 |
914 /* Negative for "uinspecified" */ | |
506 | 915 FRAME_MSPRINTER_CHARWIDTH (f) = -1; |
916 FRAME_MSPRINTER_CHARHEIGHT (f) = -1; | |
440 | 917 } |
918 | |
919 static void | |
920 msprinter_init_frame_3 (struct frame *f) | |
921 { | |
771 | 922 DOCINFOW di; |
440 | 923 struct device *device = XDEVICE (FRAME_DEVICE (f)); |
924 int frame_left, frame_top, frame_width, frame_height; | |
903 | 925 |
442 | 926 /* DC might be recreated in msprinter_apply_devmode, |
927 so do not initialize until now */ | |
903 | 928 HDC hdc = DEVICE_MSPRINTER_HDC (device); |
929 int logpixelsx = GetDeviceCaps (hdc, LOGPIXELSX); | |
930 int logpixelsy = GetDeviceCaps (hdc, LOGPIXELSY); | |
931 int physicaloffsetx = GetDeviceCaps (hdc, PHYSICALOFFSETX); | |
932 int physicaloffsety = GetDeviceCaps (hdc, PHYSICALOFFSETY); | |
933 int physicalheight = GetDeviceCaps (hdc, PHYSICALHEIGHT); | |
934 int physicalwidth = GetDeviceCaps (hdc, PHYSICALWIDTH); | |
440 | 935 |
903 | 936 /* Compute geometry properties. |
937 Conversion is from TWIPS -> inches -> pixels. */ | |
938 frame_left = MulDiv (logpixelsx, FRAME_MSPRINTER_LEFT_MARGIN(f), 1440) | |
939 - physicaloffsetx; | |
940 | |
771 | 941 if (FRAME_MSPRINTER_CHARWIDTH (f) > 0) |
440 | 942 { |
5043 | 943 char_to_pixel_size (f, FRAME_MSPRINTER_CHARWIDTH (f), 0, |
440 | 944 &frame_width, NULL); |
903 | 945 FRAME_MSPRINTER_RIGHT_MARGIN(f) = |
946 MulDiv (physicalwidth - (frame_left + frame_width), 1440, | |
947 logpixelsx); | |
442 | 948 } |
440 | 949 else |
903 | 950 frame_width = physicalwidth - frame_left |
951 - MulDiv (logpixelsx, FRAME_MSPRINTER_RIGHT_MARGIN(f), 1440) | |
952 - physicaloffsetx; | |
440 | 953 |
903 | 954 frame_top = MulDiv (logpixelsy, FRAME_MSPRINTER_TOP_MARGIN(f), 1440) |
955 - physicaloffsety; | |
440 | 956 |
771 | 957 if (FRAME_MSPRINTER_CHARHEIGHT (f) > 0) |
440 | 958 { |
5043 | 959 char_to_pixel_size (f, 0, FRAME_MSPRINTER_CHARHEIGHT (f), |
440 | 960 NULL, &frame_height); |
961 | |
903 | 962 FRAME_MSPRINTER_BOTTOM_MARGIN(f) = |
963 MulDiv (physicalheight - (frame_top + frame_height), 1440, | |
964 logpixelsy); | |
442 | 965 } |
440 | 966 else |
903 | 967 frame_height = physicalheight - frame_top |
968 - MulDiv (logpixelsy, FRAME_MSPRINTER_BOTTOM_MARGIN(f), 1440) | |
969 - physicaloffsety; | |
440 | 970 |
971 /* Geometry sanity checks */ | |
972 if (!frame_pixsize_valid_p (f, frame_width, frame_height)) | |
442 | 973 invalid_operation ("Area inside print margins has shrunk to naught", |
974 STRINGP (f->name) ? f->name : Qunbound); | |
440 | 975 |
976 if (frame_left < 0 | |
977 || frame_top < 0 | |
978 || frame_left + frame_width > GetDeviceCaps (hdc, HORZRES) | |
979 || frame_top + frame_height > GetDeviceCaps (hdc, VERTRES)) | |
546 | 980 invalid_operation ("Print area is outside of the printer's " |
442 | 981 "hardware printable area", |
982 STRINGP (f->name) ? f->name : Qunbound); | |
440 | 983 |
984 /* Apply XEmacs frame geometry and layout windows */ | |
985 { | |
986 int rows, columns; | |
771 | 987 FRAME_PIXWIDTH (f) = frame_width; |
988 FRAME_PIXHEIGHT (f) = frame_height; | |
5043 | 989 pixel_to_frame_unit_size (f, frame_width, frame_height, &columns, &rows); |
990 change_frame_size (f, columns, rows, 0); | |
440 | 991 } |
992 | |
442 | 993 FRAME_MSPRINTER_PIXLEFT(f) = frame_left; |
994 FRAME_MSPRINTER_PIXTOP(f) = frame_top; | |
440 | 995 |
996 /* Start print job */ | |
997 di.cbSize = sizeof (di); | |
771 | 998 { |
999 const Extbyte *nameext; | |
1000 | |
1001 if (STRINGP (f->name)) | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1002 nameext = LISP_STRING_TO_TSTR (f->name); |
771 | 1003 else |
1004 nameext = XETEXT ("XEmacs print document"); | |
1005 di.lpszDocName = (XELPTSTR) nameext; | |
1006 } | |
440 | 1007 di.lpszOutput = NULL; |
1008 di.lpszDatatype = NULL; | |
1009 di.fwType = 0; | |
1010 | |
771 | 1011 if (qxeStartDoc (hdc, &di) <= 0) |
442 | 1012 invalid_operation ("Cannot start print job", |
1013 STRINGP (f->name) ? f->name : Qunbound); | |
1014 | |
1015 apply_dc_geometry (f); | |
440 | 1016 |
1017 /* Finish frame setup */ | |
1018 FRAME_MSPRINTER_JOB_STARTED (f) = 1; | |
771 | 1019 FRAME_VISIBLE_P (f) = 0; |
440 | 1020 } |
1021 | |
1022 static void | |
2286 | 1023 msprinter_mark_frame (struct frame *UNUSED (f)) |
440 | 1024 { |
1025 } | |
1026 | |
1027 static void | |
1028 msprinter_delete_frame (struct frame *f) | |
1029 { | |
1030 if (f->frame_data) | |
1031 { | |
442 | 1032 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))); |
1033 if (FRAME_MSPRINTER_PAGE_STARTED (f)) | |
1034 EndPage (hdc); | |
440 | 1035 if (FRAME_MSPRINTER_JOB_STARTED (f)) |
442 | 1036 EndDoc (hdc); |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1037 xfree (f->frame_data); |
440 | 1038 } |
1039 | |
1040 f->frame_data = 0; | |
1041 } | |
1042 | |
1043 static Lisp_Object | |
1044 msprinter_frame_property (struct frame *f, Lisp_Object property) | |
1045 { | |
1046 if (EQ (Qleft_margin, property)) | |
771 | 1047 return make_int (FRAME_MSPRINTER_LEFT_MARGIN (f)); |
440 | 1048 else if (EQ (Qtop_margin, property)) |
771 | 1049 return make_int (FRAME_MSPRINTER_TOP_MARGIN (f)); |
440 | 1050 if (EQ (Qright_margin, property)) |
771 | 1051 return make_int (FRAME_MSPRINTER_RIGHT_MARGIN (f)); |
440 | 1052 else if (EQ (Qbottom_margin, property)) |
771 | 1053 return make_int (FRAME_MSPRINTER_BOTTOM_MARGIN (f)); |
440 | 1054 else |
1055 return Qunbound; | |
1056 } | |
1057 | |
1058 static int | |
2286 | 1059 msprinter_internal_frame_property_p (struct frame *UNUSED (f), |
1060 Lisp_Object property) | |
440 | 1061 { |
1062 return (EQ (Qleft_margin, property) || EQ (Qtop_margin, property) || | |
442 | 1063 EQ (Qright_margin, property) || EQ (Qbottom_margin, property)); |
440 | 1064 } |
1065 | |
1066 static Lisp_Object | |
1067 msprinter_frame_properties (struct frame *f) | |
1068 { | |
1069 Lisp_Object props = Qnil; | |
1070 props = cons3 (Qbottom_margin, | |
771 | 1071 make_int (FRAME_MSPRINTER_BOTTOM_MARGIN (f)), props); |
440 | 1072 props = cons3 (Qright_margin, |
771 | 1073 make_int (FRAME_MSPRINTER_RIGHT_MARGIN (f)), props); |
440 | 1074 props = cons3 (Qtop_margin, |
771 | 1075 make_int (FRAME_MSPRINTER_TOP_MARGIN (f)), props); |
440 | 1076 props = cons3 (Qleft_margin, |
771 | 1077 make_int (FRAME_MSPRINTER_LEFT_MARGIN (f)), props); |
440 | 1078 return props; |
1079 } | |
1080 | |
1081 static void | |
1082 msprinter_set_frame_properties (struct frame *f, Lisp_Object plist) | |
1083 { | |
1084 Lisp_Object tail; | |
1085 | |
1086 /* Extract the properties from plist */ | |
1087 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | |
1088 { | |
1089 Lisp_Object prop = Fcar (tail); | |
1090 Lisp_Object val = Fcar (Fcdr (tail)); | |
1091 | |
1092 if (SYMBOLP (prop)) | |
1093 { | |
1094 if (EQ (prop, Qwidth)) | |
1095 { | |
1096 maybe_error_if_job_active (f); | |
1097 if (!NILP (val)) | |
1098 { | |
1099 CHECK_NATNUM (val); | |
771 | 1100 FRAME_MSPRINTER_CHARWIDTH (f) = XINT (val); |
440 | 1101 } |
1102 } | |
1103 if (EQ (prop, Qheight)) | |
1104 { | |
1105 maybe_error_if_job_active (f); | |
1106 if (!NILP (val)) | |
1107 { | |
1108 CHECK_NATNUM (val); | |
771 | 1109 FRAME_MSPRINTER_CHARHEIGHT (f) = XINT (val); |
440 | 1110 } |
1111 } | |
1112 else if (EQ (prop, Qleft_margin)) | |
1113 { | |
1114 maybe_error_if_job_active (f); | |
1115 CHECK_NATNUM (val); | |
771 | 1116 FRAME_MSPRINTER_LEFT_MARGIN (f) = XINT (val); |
440 | 1117 } |
1118 else if (EQ (prop, Qtop_margin)) | |
1119 { | |
1120 maybe_error_if_job_active (f); | |
1121 CHECK_NATNUM (val); | |
771 | 1122 FRAME_MSPRINTER_TOP_MARGIN (f) = XINT (val); |
440 | 1123 } |
1124 else if (EQ (prop, Qright_margin)) | |
1125 { | |
1126 maybe_error_if_job_active (f); | |
1127 CHECK_NATNUM (val); | |
771 | 1128 FRAME_MSPRINTER_RIGHT_MARGIN (f) = XINT (val); |
440 | 1129 } |
1130 else if (EQ (prop, Qbottom_margin)) | |
1131 { | |
1132 maybe_error_if_job_active (f); | |
1133 CHECK_NATNUM (val); | |
771 | 1134 FRAME_MSPRINTER_BOTTOM_MARGIN (f) = XINT (val); |
440 | 1135 } |
1136 } | |
1137 } | |
1138 } | |
1139 | |
1140 static void | |
2286 | 1141 msprinter_set_frame_size (struct frame *f, int UNUSED (width), |
1142 int UNUSED (height)) | |
440 | 1143 { |
1144 /* We're absolutely unsizeable */ | |
1145 error_frame_unsizable (f); | |
1146 } | |
1147 | |
442 | 1148 static void |
1149 msprinter_eject_page (struct frame *f) | |
1150 { | |
1151 /* #### Should we eject empty pages? */ | |
1152 if (FRAME_MSPRINTER_PAGE_STARTED (f)) | |
1153 { | |
1154 FRAME_MSPRINTER_PAGE_STARTED (f) = 0; | |
1155 EndPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)))); | |
1156 apply_dc_geometry (f); | |
1157 } | |
1158 } | |
1159 | |
1160 | |
428 | 1161 void |
1162 console_type_create_frame_mswindows (void) | |
1163 { | |
440 | 1164 /* Display frames */ |
428 | 1165 CONSOLE_HAS_METHOD (mswindows, init_frame_1); |
442 | 1166 CONSOLE_HAS_METHOD (mswindows, init_frame_2); |
428 | 1167 CONSOLE_HAS_METHOD (mswindows, init_frame_3); |
1168 CONSOLE_HAS_METHOD (mswindows, after_init_frame); | |
1169 CONSOLE_HAS_METHOD (mswindows, mark_frame); | |
1170 CONSOLE_HAS_METHOD (mswindows, focus_on_frame); | |
1171 CONSOLE_HAS_METHOD (mswindows, delete_frame); | |
1172 CONSOLE_HAS_METHOD (mswindows, get_mouse_position); | |
1173 CONSOLE_HAS_METHOD (mswindows, set_mouse_position); | |
1174 CONSOLE_HAS_METHOD (mswindows, raise_frame); | |
1175 CONSOLE_HAS_METHOD (mswindows, lower_frame); | |
442 | 1176 CONSOLE_HAS_METHOD (mswindows, enable_frame); |
1177 CONSOLE_HAS_METHOD (mswindows, disable_frame); | |
428 | 1178 CONSOLE_HAS_METHOD (mswindows, make_frame_visible); |
1179 CONSOLE_HAS_METHOD (mswindows, make_frame_invisible); | |
1180 CONSOLE_HAS_METHOD (mswindows, iconify_frame); | |
1181 CONSOLE_HAS_METHOD (mswindows, set_frame_size); | |
1182 CONSOLE_HAS_METHOD (mswindows, set_frame_position); | |
1183 CONSOLE_HAS_METHOD (mswindows, frame_property); | |
1184 CONSOLE_HAS_METHOD (mswindows, internal_frame_property_p); | |
1185 CONSOLE_HAS_METHOD (mswindows, frame_properties); | |
1186 CONSOLE_HAS_METHOD (mswindows, set_frame_properties); | |
867 | 1187 CONSOLE_HAS_METHOD (mswindows, set_title_from_ibyte); |
1188 /* CONSOLE_HAS_METHOD (mswindows, set_icon_name_from_ibyte); */ | |
428 | 1189 CONSOLE_HAS_METHOD (mswindows, frame_visible_p); |
1190 CONSOLE_HAS_METHOD (mswindows, frame_totally_visible_p); | |
1191 CONSOLE_HAS_METHOD (mswindows, frame_iconified_p); | |
442 | 1192 CONSOLE_HAS_METHOD (mswindows, set_frame_pointer); |
1193 CONSOLE_HAS_METHOD (mswindows, set_frame_icon); | |
428 | 1194 CONSOLE_HAS_METHOD (mswindows, get_frame_parent); |
1195 CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits); | |
1196 CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p); | |
440 | 1197 |
1198 /* Printer frames, aka print jobs */ | |
1199 CONSOLE_HAS_METHOD (msprinter, init_frame_1); | |
1200 CONSOLE_HAS_METHOD (msprinter, init_frame_3); | |
1201 CONSOLE_HAS_METHOD (msprinter, mark_frame); | |
1202 CONSOLE_HAS_METHOD (msprinter, delete_frame); | |
1203 CONSOLE_HAS_METHOD (msprinter, frame_property); | |
1204 CONSOLE_HAS_METHOD (msprinter, internal_frame_property_p); | |
1205 CONSOLE_HAS_METHOD (msprinter, frame_properties); | |
1206 CONSOLE_HAS_METHOD (msprinter, set_frame_properties); | |
1207 CONSOLE_HAS_METHOD (msprinter, set_frame_size); | |
442 | 1208 CONSOLE_HAS_METHOD (msprinter, eject_page); |
428 | 1209 } |
1210 | |
1211 void | |
1212 syms_of_frame_mswindows (void) | |
1213 { | |
3092 | 1214 #ifdef NEW_GC |
1215 INIT_LRECORD_IMPLEMENTATION (mswindows_frame); | |
1216 #endif /* NEW_GC */ | |
428 | 1217 } |
1218 | |
1219 void | |
1220 reinit_vars_of_frame_mswindows (void) | |
1221 { | |
1222 /* Needn't staticpro -- see comment above. */ | |
1223 Vmswindows_frame_being_created = Qnil; | |
1224 } | |
1225 | |
1226 void | |
1227 vars_of_frame_mswindows (void) | |
1228 { | |
1229 DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /* | |
1230 Controls whether to use system or XEmacs defaults for frame size. | |
442 | 1231 If nil then reasonable defaults are used for initial frame sizes. If t |
428 | 1232 then the system will choose default sizes for the frame. |
1233 */ ); | |
1234 Vmswindows_use_system_frame_size_defaults = Qnil; | |
442 | 1235 |
428 | 1236 DEFVAR_LISP ("default-mswindows-frame-plist", &Vdefault_mswindows_frame_plist /* |
1237 Plist of default frame-creation properties for mswindows frames. | |
1238 These override what is specified in `default-frame-plist', but are | |
1239 overridden by the arguments to the particular call to `make-frame'. | |
1240 | |
1241 Note: In many cases, properties of a frame are available as specifiers | |
1242 instead of through the frame-properties mechanism. | |
1243 | |
1244 Here is a list of recognized frame properties, other than those | |
1245 documented in `set-frame-properties' (they can be queried and | |
1246 set at any time, except as otherwise noted): | |
1247 | |
1248 initially-unmapped If non-nil, the frame will not be visible | |
1249 when it is created. In this case, you | |
1250 need to call `make-frame-visible' to make | |
1251 the frame appear. | |
1252 popup If non-nil, it should be a frame, and this | |
1253 frame will be created as a "popup" frame | |
1254 whose parent is the given frame. This | |
1255 will make the window manager treat the | |
1256 frame as a dialog box, which may entail | |
1257 doing different things (e.g. not asking | |
1258 for positioning, and not iconifying | |
1259 separate from its parent). | |
1260 top Y position (in pixels) of the upper-left | |
1261 outermost corner of the frame (i.e. the | |
1262 upper-left of the window-manager | |
1263 decorations). | |
1264 left X position (in pixels) of the upper-left | |
1265 outermost corner of the frame (i.e. the | |
1266 upper-left of the window-manager | |
1267 decorations). | |
3022 | 1268 window-id Window handle (HWND) of the frame. |
1269 Cannot be set. | |
428 | 1270 |
1271 See also `default-frame-plist', which specifies properties which apply | |
1272 to all frames, not just mswindows frames. | |
1273 */ ); | |
1274 Vdefault_mswindows_frame_plist = Qnil; | |
1275 | |
1276 mswindows_console_methods->device_specific_frame_props = | |
1277 &Vdefault_mswindows_frame_plist; | |
440 | 1278 |
1279 DEFVAR_LISP ("default-msprinter-frame-plist", &Vdefault_msprinter_frame_plist /* | |
1280 Plist of default frame-creation properties for msprinter print job frames. | |
1281 These override what is specified in `default-frame-plist', but are | |
1282 overridden by the arguments to the particular call to `make-frame'. | |
1283 | |
1284 Note: In many cases, properties of a frame are available as specifiers | |
1285 instead of through the frame-properties mechanism. | |
1286 | |
1287 Here is a list of recognized frame properties, other than those | |
1288 documented in `set-frame-properties' (they can be queried and | |
1289 set at any time, except as otherwise noted): | |
1290 | |
1291 left-margin Margin of the page, in twips. Twip is a | |
1292 top-margin typographical unit of measurement, | |
1293 right-margin equal to 1/1440 of an inch, or 1/20 of a | |
1294 bottom-margin point, and roughly equal to 7/400 of a | |
506 | 1295 millimeter. If not specified, the left |
1296 and right margins default to 1 inch | |
1297 (25.4 mm) and the top and bottom margins | |
1298 to 0.5 inch (12.7 mm). | |
440 | 1299 |
1300 MARGINS NOTE. right-margin and bottom-margin are overridden by | |
1301 the height and width properties. If you want to specify size | |
1302 of the printable area in character, as with the rest of XEmacs, | |
1303 use these properties. If height and/or width are nil, then | |
1304 corresponding margin setting is taken into account. If you | |
1305 specify height and/or width in `default-frame-plist', but still | |
1306 want to specify right/bottom margins, set height/width in this | |
1307 plist to nil, as in this example: | |
1308 | |
506 | 1309 (setq default-frame-plist '(height 55 width 80) |
1310 default-msprinter-frame-plist '(height nil width nil)) | |
440 | 1311 |
1312 See also `default-frame-plist', which specifies properties which apply | |
1313 to all frames, not just mswindows frames. | |
1314 */ ); | |
1315 Vdefault_msprinter_frame_plist = Qnil; | |
1316 | |
1317 msprinter_console_methods->device_specific_frame_props = | |
1318 &Vdefault_msprinter_frame_plist; | |
428 | 1319 } |