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