1 /* Functions for the mswindows window system.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996 Ben Wing.
5 This file is part of XEmacs.
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
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
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. */
22 /* Synched up with: Not synched with FSF. */
26 Ultimately based on FSF.
27 Substantially rewritten for XEmacs by Ben Wing.
28 Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
29 Graphics features added and frame resizing fiddled with by Andy Piper.
37 #include "console-msw.h"
38 #include "glyphs-msw.h"
43 #include "redisplay.h"
46 #define MSWINDOWS_FRAME_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW)
47 #define MSWINDOWS_POPUP_STYLE (WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP \
48 | WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX)
50 #define MSWINDOWS_FRAME_EXSTYLE WS_EX_OVERLAPPEDWINDOW
51 #define MSWINDOWS_POPUP_EXSTYLE WS_EX_PALETTEWINDOW
53 /* Default popup left top corner offset from the same
54 corner of the parent frame, in pixel */
55 #define POPUP_OFFSET 30
57 /* Default popup size, in characters */
58 #define POPUP_WIDTH 30
59 #define POPUP_HEIGHT 10
61 /* Default regular frame size, in characters */
62 #define DEFAULT_FRAME_WIDTH 80
63 #define DEFAULT_FRAME_HEIGHT 35
66 #define ADJR_MENUFLAG TRUE
68 #define ADJR_MENUFLAG FALSE
71 /* Default properties to use when creating frames. */
72 Lisp_Object Vdefault_mswindows_frame_plist;
73 Lisp_Object Vdefault_msprinter_frame_plist;
74 Lisp_Object Vmswindows_use_system_frame_size_defaults;
76 /* This does not need to be GC protected, as it holds a
77 frame Lisp_Object already protected by Fmake_frame */
78 Lisp_Object Vmswindows_frame_being_created;
80 /*---------------------------------------------------------------------*/
81 /*----- DISPLAY FRAME -----*/
82 /*---------------------------------------------------------------------*/
85 mswindows_get_selected_frame_hwnd (void)
87 Lisp_Object frame, device;
89 device = Ffind_device (Qnil, Qmswindows);
92 frame = DEVICE_SELECTED_FRAME (XDEVICE (device));
96 return FRAME_MSWINDOWS_HANDLE (XFRAME (frame));
100 mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
102 Lisp_Object initially_unmapped;
103 Lisp_Object name, height, width, popup, top, left;
104 Lisp_Object frame_obj = Qnil;
106 XEMACS_RECT_WH rect_default;
107 DWORD style, exstyle;
108 HWND hwnd, hwnd_parent;
110 /* Pick up relevant properties */
111 initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil);
112 name = Fplist_get (props, Qname, Qnil);
114 popup = Fplist_get (props, Qpopup, Qnil);
116 popup = Fselected_frame (Qnil);
118 left = Fplist_get (props, Qleft, Qnil);
122 top = Fplist_get (props, Qtop, Qnil);
126 width = Fplist_get (props, Qwidth, Qnil);
130 height = Fplist_get (props, Qheight, Qnil);
134 f->frame_data = xnew_and_zero (struct mswindows_frame);
135 FRAME_MSWINDOWS_TARGET_RECT (f) = xnew_and_zero (XEMACS_RECT_WH);
137 FRAME_MSWINDOWS_TARGET_RECT (f)->left = NILP (left) ? -1 : abs (XINT (left));
138 FRAME_MSWINDOWS_TARGET_RECT (f)->top = NILP (top) ? -1 : abs (XINT (top));
139 FRAME_MSWINDOWS_TARGET_RECT (f)->width = NILP (width) ? -1 :
141 FRAME_MSWINDOWS_TARGET_RECT (f)->height = NILP (height) ? -1 :
144 /* Misc frame stuff */
145 FRAME_MSWINDOWS_MENU_HASH_TABLE(f) = Qnil;
147 FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f) =
148 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
150 /* hashtable of instantiated glyphs on the frame. */
151 FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f) =
152 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
153 FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f) =
154 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
155 FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f) =
156 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
157 /* Will initialize these in WM_SIZE handler. We cannot do it now,
158 because we do not know what is CW_USEDEFAULT height and width */
160 FRAME_HEIGHT (f) = 0;
161 FRAME_PIXWIDTH (f) = 0;
162 FRAME_PIXHEIGHT (f) = 0;
166 style = MSWINDOWS_FRAME_STYLE;
167 exstyle = MSWINDOWS_FRAME_EXSTYLE;
170 rect_default.left = rect_default.top = CW_USEDEFAULT;
171 rect_default.width = rect_default.height = CW_USEDEFAULT;
175 style = MSWINDOWS_POPUP_STYLE;
176 exstyle = MSWINDOWS_POPUP_EXSTYLE;
178 CHECK_MSWINDOWS_FRAME (popup);
179 hwnd_parent = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
180 assert (IsWindow (hwnd_parent));
182 /* We cannot use CW_USEDEFAULT when creating a popup window.
183 So by default, we offset the new popup 30 pixels right
184 and down from its parent, and give it size of 30x10 characters.
185 These dimensions look adequate on both high and low res monitors */
186 GetWindowRect (hwnd_parent, &rect);
187 rect_default.left = rect.left + POPUP_OFFSET;
188 rect_default.top = rect.top + POPUP_OFFSET;
189 char_to_real_pixel_size (f, POPUP_WIDTH, POPUP_HEIGHT,
190 &rect_default.width, &rect_default.height);
193 AdjustWindowRectEx(&rect, style, ADJR_MENUFLAG, exstyle);
195 XSETFRAME (frame_obj, f);
197 Vmswindows_frame_being_created = frame_obj;
199 hwnd = CreateWindowEx (exstyle,
201 STRINGP(f->name) ? XSTRING_DATA(f->name) :
203 (const Extbyte*)XSTRING_DATA(name) :
204 (const Extbyte*)XEMACS_CLASS),
206 rect_default.left, rect_default.top,
207 rect_default.width, rect_default.height,
208 hwnd_parent, NULL, NULL, NULL);
210 Vmswindows_frame_being_created = Qnil;
213 error ("System call to create frame failed");
215 FRAME_MSWINDOWS_HANDLE(f) = hwnd;
217 SetWindowLong (hwnd, XWL_FRAMEOBJ, (LONG)LISP_TO_VOID(frame_obj));
218 FRAME_MSWINDOWS_DC(f) = GetDC (hwnd);
219 SetTextAlign (FRAME_MSWINDOWS_DC(f), TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
223 mswindows_init_frame_2 (struct frame *f, Lisp_Object props)
225 if (NILP (Vmswindows_use_system_frame_size_defaults))
227 /* I don't think anything can set the frame size before this
228 since we don't have X resources. This may change if we look
229 at the registry. Even so these values can get overridden
231 XEMACS_RECT_WH dest = { -1, -1, DEFAULT_FRAME_WIDTH,
232 DEFAULT_FRAME_HEIGHT };
233 mswindows_size_frame_internal (f, &dest);
237 /* Called after frame's properties are set */
239 mswindows_init_frame_3 (struct frame *f)
241 /* Don't do this earlier or we get a WM_PAINT before the frame is ready.
242 * The SW_x parameter in the first call that an app makes to ShowWindow is
243 * ignored, and the parameter specified in the caller's STARTUPINFO is
244 * substituted instead. That parameter is SW_HIDE if we were started by
245 * runemacs, so call this twice. #### runemacs is evil */
246 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
247 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
248 SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
249 DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE);
253 mswindows_after_init_frame (struct frame *f, int first_on_device,
254 int first_on_console)
256 /* Windows, unlike X, is very synchronous. After the initial
257 frame is created, it will never be displayed, except for
258 hollow border, unless we start pumping messages. Load progress
259 messages show in the bottom of the hollow frame, which is ugly.
260 We redisplay the initial frame here, so modeline and root window
263 if (first_on_console)
268 mswindows_mark_frame (struct frame *f)
270 mark_object (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
272 mark_object (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
274 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
275 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
276 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
280 mswindows_focus_on_frame (struct frame *f)
282 SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
286 mswindows_delete_frame (struct frame *f)
290 ReleaseDC(FRAME_MSWINDOWS_HANDLE(f), FRAME_MSWINDOWS_DC(f));
291 DestroyWindow(FRAME_MSWINDOWS_HANDLE(f));
292 xfree (f->frame_data);
298 mswindows_set_frame_size (struct frame *f, int width, int height)
301 rect.left = rect.top = 0;
303 rect.bottom = height;
305 AdjustWindowRectEx (&rect,
306 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
307 GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
308 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
310 if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
311 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
313 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL,
314 0, 0, rect.right-rect.left, rect.bottom-rect.top,
315 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOMOVE);
319 mswindows_set_frame_position (struct frame *f, int xoff, int yoff)
321 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL,
323 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE);
327 mswindows_make_frame_visible (struct frame *f)
329 if (!FRAME_VISIBLE_P(f))
330 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
332 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOW);
338 mswindows_make_frame_invisible (struct frame *f)
340 if (!FRAME_VISIBLE_P(f))
343 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_HIDE);
348 mswindows_frame_totally_visible_p (struct frame *f)
350 RECT rc_me, rc_other, rc_temp;
351 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
353 /* We test against not a whole window rectangle, only against its
354 client part. So, if non-client are is covered and client area is
355 not, we return true. */
356 GetClientRect (hwnd, &rc_me);
357 MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rc_me, 2);
359 /* First see if we're off the desktop */
360 GetWindowRect (GetDesktopWindow(), &rc_other);
361 UnionRect(&rc_temp, &rc_me, &rc_other);
362 if (!EqualRect (&rc_temp, &rc_other))
365 /* Then see if any window above us obscures us */
366 while ((hwnd = GetWindow (hwnd, GW_HWNDPREV)) != NULL)
367 if (IsWindowVisible (hwnd))
369 GetWindowRect (hwnd, &rc_other);
370 if (IntersectRect(&rc_temp, &rc_me, &rc_other))
378 mswindows_frame_visible_p (struct frame *f)
380 return IsWindowVisible (FRAME_MSWINDOWS_HANDLE(f))
381 && !IsIconic (FRAME_MSWINDOWS_HANDLE(f));
386 mswindows_iconify_frame (struct frame *f)
388 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_MINIMIZE);
394 mswindows_frame_iconified_p (struct frame *f)
396 return IsIconic (FRAME_MSWINDOWS_HANDLE(f));
400 mswindows_set_frame_icon (struct frame *f)
402 if (IMAGE_INSTANCEP (f->icon)
403 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon)))
405 if (!XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon))
407 mswindows_initialize_image_instance_icon (XIMAGE_INSTANCE (f->icon),
411 SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HICON,
412 (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon));
417 mswindows_set_frame_pointer (struct frame *f)
419 if (IMAGE_INSTANCEP (f->pointer)
420 && IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (f->pointer)) == IMAGE_POINTER)
422 SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
423 (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
424 /* we only have to do this because GC doesn't cause a mouse
425 event and doesn't give time to event processing even if it
427 SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
432 mswindows_set_mouse_position (struct window *w, int x, int y)
434 struct frame *f = XFRAME (w->frame);
437 pt.x = w->pixel_left + x;
438 pt.y = w->pixel_top + y;
439 ClientToScreen (FRAME_MSWINDOWS_HANDLE(f), &pt);
440 SetCursorPos (pt.x, pt.y);
444 mswindows_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y)
451 /* What's under cursor? */
452 hwnd = WindowFromPoint (pt);
456 /* Get grandest parent of the window */
459 while ((hwnd_parent = GetParent (hwnd)) != NULL)
463 /* Make sure it belongs to us */
464 if (GetWindowThreadProcessId (hwnd, NULL) != GetCurrentThreadId ())
467 /* And that the window is an XEmacs frame */
469 char class_name [sizeof(XEMACS_CLASS) + 1];
470 if (!GetClassName (hwnd, class_name, sizeof(XEMACS_CLASS))
471 || strcmp (class_name, XEMACS_CLASS) != 0)
476 ScreenToClient (hwnd, &pt);
477 VOID_TO_LISP (*frame, GetWindowLong (hwnd, XWL_FRAMEOBJ));
484 mswindows_raise_frame (struct frame *f)
486 BringWindowToTop (FRAME_MSWINDOWS_HANDLE(f));
490 mswindows_lower_frame (struct frame *f)
492 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), HWND_BOTTOM, 0, 0, 0, 0,
493 SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
497 mswindows_set_title_from_bufbyte (struct frame *f, Bufbyte *title)
499 unsigned int new_checksum = hash_string (title, strlen (title));
500 if (new_checksum != FRAME_MSWINDOWS_TITLE_CHECKSUM(f))
502 FRAME_MSWINDOWS_TITLE_CHECKSUM(f) = new_checksum;
503 SetWindowText (FRAME_MSWINDOWS_HANDLE(f), title);
508 mswindows_frame_property (struct frame *f, Lisp_Object property)
510 if (EQ (Qleft, property) || EQ (Qtop, property))
513 GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
514 return make_int (EQ (Qtop, property) ? rc.top : rc.left);
520 mswindows_internal_frame_property_p (struct frame *f, Lisp_Object property)
522 return EQ (property, Qleft)
523 || EQ (property, Qtop);
524 /* #### frame-x.c has also this. Why?
525 || STRINGP (property);
530 mswindows_frame_properties (struct frame *f)
532 Lisp_Object props = Qnil;
534 GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
536 props = cons3 (Qtop, make_int (rc.top), props);
537 props = cons3 (Qleft, make_int (rc.left), props);
543 mswindows_set_frame_properties (struct frame *f, Lisp_Object plist)
546 int width = -1, height = -1;
547 BOOL width_specified_p = FALSE;
548 BOOL height_specified_p = FALSE;
549 BOOL x_specified_p = FALSE;
550 BOOL y_specified_p = FALSE;
553 /* Extract the properties from plist */
554 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
556 Lisp_Object prop = Fcar (tail);
557 Lisp_Object val = Fcar (Fcdr (tail));
561 /* Kludge to handle the font property. */
562 if (EQ (prop, Qfont))
564 /* If the value is not a string we silently ignore it. */
567 Lisp_Object frm, font_spec;
570 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);
572 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
573 update_frame_face_values (f);
576 else if (EQ (prop, Qwidth))
580 width_specified_p = TRUE;
582 else if (EQ (prop, Qheight))
586 height_specified_p = TRUE;
588 else if (EQ (prop, Qleft))
592 x_specified_p = TRUE;
594 else if (EQ (prop, Qtop))
598 y_specified_p = TRUE;
603 /* Now we've extracted the properties, apply them.
604 Do not apply geometric properties during frame creation. This
605 is excessive anyways, and this loses becuase WM_SIZE has not
606 been sent yet, so frame width and height fields are not initialized.
608 unfortunately WM_SIZE loses as well since the resize is only
609 applied once and the first time WM_SIZE is applied not everything
610 is initialised in the frame (toolbars for instance). enabling
611 this always makes no visible difference and fixes a whole host of
612 bugs (and is more consistent with X) so I am going to reenable it.
614 if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f)
615 && (width_specified_p || height_specified_p
616 || x_specified_p || y_specified_p))
618 XEMACS_RECT_WH dest = { x, y, width, height };
620 mswindows_size_frame_internal (f, &dest);
624 void mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
627 int pixel_width, pixel_height;
628 int size_p = (dest->width >=0 || dest->height >=0);
629 int move_p = (dest->top >=0 || dest->left >=0);
630 char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width, &pixel_height);
633 pixel_width = FRAME_PIXWIDTH (f);
634 if (dest->height < 0)
635 pixel_height = FRAME_PIXHEIGHT (f);
637 GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rect);
639 dest->left = rect.left;
641 dest->top = rect.top;
643 rect.left = rect.top = 0;
644 rect.right = pixel_width;
645 rect.bottom = pixel_height;
647 AdjustWindowRectEx (&rect,
648 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
649 GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
650 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
652 /* resize and move the window so that it fits in the workspace. This is
653 not restrictive since this will happen later anyway in WM_SIZE. We
654 have to do this after adjusting the rect to account for menubar
656 mswindows_get_workspace_coords (&ws_rect);
657 pixel_width = rect.right - rect.left;
658 pixel_height = rect.bottom - rect.top;
659 if (pixel_width > ws_rect.right - ws_rect.left)
661 pixel_width = ws_rect.right - ws_rect.left;
664 if (pixel_height > ws_rect.bottom - ws_rect.top)
666 pixel_height = ws_rect.bottom - ws_rect.top;
670 /* adjust position so window is in workspace */
671 if (dest->left + pixel_width > ws_rect.right)
673 dest->left = ws_rect.right - pixel_width;
676 if (dest->left < ws_rect.left)
678 dest->left = ws_rect.left;
682 if (dest->top + pixel_height > ws_rect.bottom)
684 dest->top = ws_rect.bottom - pixel_height;
687 if (dest->top < ws_rect.top)
689 dest->top = ws_rect.top;
693 if (IsIconic (FRAME_MSWINDOWS_HANDLE(f))
694 || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
695 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
697 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL,
698 dest->left, dest->top, pixel_width, pixel_height,
699 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
700 | (size_p ? 0 : SWP_NOSIZE)
701 | (move_p ? 0 : SWP_NOMOVE));
705 mswindows_get_frame_parent (struct frame *f)
707 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
708 hwnd = GetParent (hwnd);
712 VOID_TO_LISP (parent, GetWindowLong (hwnd, XWL_FRAMEOBJ));
713 assert (FRAME_MSWINDOWS_P (XFRAME (parent)));
721 mswindows_update_frame_external_traits (struct frame* frm, Lisp_Object name)
726 mswindows_frame_size_fixed_p (struct frame *f)
728 /* Frame size cannot change if the frame is maximized */
729 return IsZoomed (FRAME_MSWINDOWS_HANDLE (f));
732 /*---------------------------------------------------------------------*/
733 /*----- PRINTER FRAME -----*/
734 /*---------------------------------------------------------------------*/
737 * With some drvier/os combination (I discovered this with HP drviers
738 * under W2K), DC geometry is reset upon StartDoc and EndPage
739 * calls. This is called every time one of these calls is made.
742 apply_dc_geometry (struct frame* f)
744 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
745 SetTextAlign (hdc, TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
746 SetViewportOrgEx (hdc, FRAME_MSPRINTER_PIXLEFT(f),
747 FRAME_MSPRINTER_PIXTOP(f), NULL);
751 msprinter_start_page (struct frame *f)
753 if (!FRAME_MSPRINTER_PAGE_STARTED (f))
755 FRAME_MSPRINTER_PAGE_STARTED (f) = 1;
756 StartPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
757 apply_dc_geometry (f);
762 error_frame_unsizable (struct frame *f)
765 XSETFRAME (frame, f);
766 signal_simple_error ("Cannot resize frame (margins)"
767 " after print job has started.", frame);
771 maybe_error_if_job_active (struct frame *f)
773 if (FRAME_MSPRINTER_JOB_STARTED (f))
774 error_frame_unsizable (f);
778 msprinter_init_frame_1 (struct frame *f, Lisp_Object props)
780 /* Make sure this is the only frame on device. Windows printer can
781 handle only one job at a time. */
782 if (!NILP (DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)))))
783 error ("Only one frame (print job) at a time is allowed on "
784 "this printer device.");
786 f->frame_data = xnew_and_zero (struct msprinter_frame);
788 /* Default margin size is 1" = 1440 twips */
789 FRAME_MSPRINTER_TOP_MARGIN(f) = 1440;
790 FRAME_MSPRINTER_BOTTOM_MARGIN(f) = 1440;
791 FRAME_MSPRINTER_LEFT_MARGIN(f) = 1440;
792 FRAME_MSPRINTER_RIGHT_MARGIN(f) = 1440;
794 /* Negative for "uinspecified" */
795 FRAME_MSPRINTER_CHARWIDTH(f) = -1;
796 FRAME_MSPRINTER_CHARHEIGHT(f) = -1;
800 msprinter_init_frame_3 (struct frame *f)
803 struct device *device = XDEVICE (FRAME_DEVICE (f));
805 int frame_left, frame_top, frame_width, frame_height;
807 /* DC might be recreated in msprinter_apply_devmode,
808 so do not initialize until now */
809 hdc = DEVICE_MSPRINTER_HDC (device);
811 /* Compute geometry properties */
812 frame_left = (MulDiv (GetDeviceCaps (hdc, LOGPIXELSX),
813 FRAME_MSPRINTER_LEFT_MARGIN(f), 1440)
814 - GetDeviceCaps (hdc, PHYSICALOFFSETX));
816 if (FRAME_MSPRINTER_CHARWIDTH(f) > 0)
818 char_to_real_pixel_size (f, FRAME_MSPRINTER_CHARWIDTH(f), 0,
820 FRAME_MSPRINTER_RIGHT_MARGIN(f) =
821 MulDiv (GetDeviceCaps (hdc, PHYSICALWIDTH)
822 - (frame_left + frame_width), 1440,
823 GetDeviceCaps (hdc, LOGPIXELSX));
826 frame_width = (GetDeviceCaps (hdc, PHYSICALWIDTH)
828 - MulDiv (GetDeviceCaps (hdc, LOGPIXELSX),
829 FRAME_MSPRINTER_RIGHT_MARGIN(f), 1440));
831 frame_top = (MulDiv (GetDeviceCaps (hdc, LOGPIXELSY),
832 FRAME_MSPRINTER_TOP_MARGIN(f), 1440)
833 - GetDeviceCaps (hdc, PHYSICALOFFSETY));
835 if (FRAME_MSPRINTER_CHARHEIGHT(f) > 0)
837 char_to_real_pixel_size (f, 0, FRAME_MSPRINTER_CHARHEIGHT(f),
838 NULL, &frame_height);
840 FRAME_MSPRINTER_BOTTOM_MARGIN(f) =
841 MulDiv (GetDeviceCaps (hdc, PHYSICALHEIGHT)
842 - (frame_top + frame_height), 1440,
843 GetDeviceCaps (hdc, LOGPIXELSY));
846 frame_height = (GetDeviceCaps (hdc, PHYSICALHEIGHT)
848 - MulDiv (GetDeviceCaps (hdc, LOGPIXELSY),
849 FRAME_MSPRINTER_BOTTOM_MARGIN(f), 1440));
851 /* Geometry sanity checks */
852 if (!frame_pixsize_valid_p (f, frame_width, frame_height))
853 error ("Area inside print margins has shrunk to naught.");
857 || frame_left + frame_width > GetDeviceCaps (hdc, HORZRES)
858 || frame_top + frame_height > GetDeviceCaps (hdc, VERTRES))
859 error ("Print area is ouside of the printer's hardware printable area.");
861 /* Apply XEmacs frame geometry and layout windows */
864 FRAME_PIXWIDTH(f) = frame_width;
865 FRAME_PIXHEIGHT(f) = frame_height;
866 pixel_to_char_size (f, frame_width, frame_height, &columns, &rows);
867 change_frame_size (f, rows, columns, 0);
870 FRAME_MSPRINTER_PIXLEFT(f) = frame_left;
871 FRAME_MSPRINTER_PIXTOP(f) = frame_top;
873 /* Start print job */
874 di.cbSize = sizeof (di);
875 di.lpszDocName = (STRINGP(f->name)
876 ? (char*) XSTRING_DATA(f->name)
877 : "XEmacs print document");
878 di.lpszOutput = NULL;
879 di.lpszDatatype = NULL;
882 if (StartDoc (hdc, &di) <= 0)
883 error ("Cannot start print job");
885 apply_dc_geometry (f);
887 /* Finish frame setup */
888 FRAME_MSPRINTER_JOB_STARTED (f) = 1;
889 FRAME_VISIBLE_P(f) = 0;
893 msprinter_mark_frame (struct frame *f)
898 msprinter_delete_frame (struct frame *f)
902 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
903 if (FRAME_MSPRINTER_PAGE_STARTED (f))
905 if (FRAME_MSPRINTER_JOB_STARTED (f))
907 xfree (f->frame_data);
914 msprinter_frame_property (struct frame *f, Lisp_Object property)
916 if (EQ (Qleft_margin, property))
917 return make_int (FRAME_MSPRINTER_LEFT_MARGIN(f));
918 else if (EQ (Qtop_margin, property))
919 return make_int (FRAME_MSPRINTER_TOP_MARGIN(f));
920 if (EQ (Qright_margin, property))
921 return make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f));
922 else if (EQ (Qbottom_margin, property))
923 return make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f));
929 msprinter_internal_frame_property_p (struct frame *f, Lisp_Object property)
931 return (EQ (Qleft_margin, property) || EQ (Qtop_margin, property) ||
932 EQ (Qright_margin, property) || EQ (Qbottom_margin, property));
936 msprinter_frame_properties (struct frame *f)
938 Lisp_Object props = Qnil;
939 props = cons3 (Qbottom_margin,
940 make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f)), props);
941 props = cons3 (Qright_margin,
942 make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f)), props);
943 props = cons3 (Qtop_margin,
944 make_int (FRAME_MSPRINTER_TOP_MARGIN(f)), props);
945 props = cons3 (Qleft_margin,
946 make_int (FRAME_MSPRINTER_LEFT_MARGIN(f)), props);
951 msprinter_set_frame_properties (struct frame *f, Lisp_Object plist)
955 /* Extract the properties from plist */
956 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
958 Lisp_Object prop = Fcar (tail);
959 Lisp_Object val = Fcar (Fcdr (tail));
963 if (EQ (prop, Qwidth))
965 maybe_error_if_job_active (f);
969 FRAME_MSPRINTER_CHARWIDTH(f) = XINT (val);
972 if (EQ (prop, Qheight))
974 maybe_error_if_job_active (f);
978 FRAME_MSPRINTER_CHARHEIGHT(f) = XINT (val);
981 else if (EQ (prop, Qleft_margin))
983 maybe_error_if_job_active (f);
985 FRAME_MSPRINTER_LEFT_MARGIN(f) = XINT (val);
987 else if (EQ (prop, Qtop_margin))
989 maybe_error_if_job_active (f);
991 FRAME_MSPRINTER_TOP_MARGIN(f) = XINT (val);
993 else if (EQ (prop, Qright_margin))
995 maybe_error_if_job_active (f);
997 FRAME_MSPRINTER_RIGHT_MARGIN(f) = XINT (val);
999 else if (EQ (prop, Qbottom_margin))
1001 maybe_error_if_job_active (f);
1003 FRAME_MSPRINTER_BOTTOM_MARGIN(f) = XINT (val);
1010 msprinter_set_frame_size (struct frame *f, int width, int height)
1012 /* We're absolutely unsizeable */
1013 error_frame_unsizable (f);
1017 msprinter_eject_page (struct frame *f)
1019 /* #### Should we eject empty pages? */
1020 if (FRAME_MSPRINTER_PAGE_STARTED (f))
1022 FRAME_MSPRINTER_PAGE_STARTED (f) = 0;
1023 EndPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
1024 apply_dc_geometry (f);
1030 console_type_create_frame_mswindows (void)
1032 /* Display frames */
1033 CONSOLE_HAS_METHOD (mswindows, init_frame_1);
1034 CONSOLE_HAS_METHOD (mswindows, init_frame_2);
1035 CONSOLE_HAS_METHOD (mswindows, init_frame_3);
1036 CONSOLE_HAS_METHOD (mswindows, after_init_frame);
1037 CONSOLE_HAS_METHOD (mswindows, mark_frame);
1038 CONSOLE_HAS_METHOD (mswindows, focus_on_frame);
1039 CONSOLE_HAS_METHOD (mswindows, delete_frame);
1040 CONSOLE_HAS_METHOD (mswindows, get_mouse_position);
1041 CONSOLE_HAS_METHOD (mswindows, set_mouse_position);
1042 CONSOLE_HAS_METHOD (mswindows, raise_frame);
1043 CONSOLE_HAS_METHOD (mswindows, lower_frame);
1044 CONSOLE_HAS_METHOD (mswindows, make_frame_visible);
1045 CONSOLE_HAS_METHOD (mswindows, make_frame_invisible);
1046 CONSOLE_HAS_METHOD (mswindows, iconify_frame);
1047 CONSOLE_HAS_METHOD (mswindows, set_frame_size);
1048 CONSOLE_HAS_METHOD (mswindows, set_frame_position);
1049 CONSOLE_HAS_METHOD (mswindows, frame_property);
1050 CONSOLE_HAS_METHOD (mswindows, internal_frame_property_p);
1051 CONSOLE_HAS_METHOD (mswindows, frame_properties);
1052 CONSOLE_HAS_METHOD (mswindows, set_frame_properties);
1053 CONSOLE_HAS_METHOD (mswindows, set_title_from_bufbyte);
1054 /* CONSOLE_HAS_METHOD (mswindows, set_icon_name_from_bufbyte); */
1055 CONSOLE_HAS_METHOD (mswindows, frame_visible_p);
1056 CONSOLE_HAS_METHOD (mswindows, frame_totally_visible_p);
1057 CONSOLE_HAS_METHOD (mswindows, frame_iconified_p);
1058 CONSOLE_HAS_METHOD (mswindows, set_frame_pointer);
1059 CONSOLE_HAS_METHOD (mswindows, set_frame_icon);
1060 CONSOLE_HAS_METHOD (mswindows, get_frame_parent);
1061 CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits);
1062 CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p);
1064 /* Printer frames, aka print jobs */
1065 CONSOLE_HAS_METHOD (msprinter, init_frame_1);
1066 CONSOLE_HAS_METHOD (msprinter, init_frame_3);
1067 CONSOLE_HAS_METHOD (msprinter, mark_frame);
1068 CONSOLE_HAS_METHOD (msprinter, delete_frame);
1069 CONSOLE_HAS_METHOD (msprinter, frame_property);
1070 CONSOLE_HAS_METHOD (msprinter, internal_frame_property_p);
1071 CONSOLE_HAS_METHOD (msprinter, frame_properties);
1072 CONSOLE_HAS_METHOD (msprinter, set_frame_properties);
1073 CONSOLE_HAS_METHOD (msprinter, set_frame_size);
1074 CONSOLE_HAS_METHOD (msprinter, eject_page);
1078 syms_of_frame_mswindows (void)
1083 reinit_vars_of_frame_mswindows (void)
1085 /* Needn't staticpro -- see comment above. */
1086 Vmswindows_frame_being_created = Qnil;
1090 vars_of_frame_mswindows (void)
1092 reinit_vars_of_frame_mswindows ();
1094 DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /*
1095 Controls whether to use system or XEmacs defaults for frame size.
1096 If nil then reasonable defaults are used for intial frame sizes. If t
1097 then the system will choose default sizes for the frame.
1099 Vmswindows_use_system_frame_size_defaults = Qnil;
1101 DEFVAR_LISP ("default-mswindows-frame-plist", &Vdefault_mswindows_frame_plist /*
1102 Plist of default frame-creation properties for mswindows frames.
1103 These override what is specified in `default-frame-plist', but are
1104 overridden by the arguments to the particular call to `make-frame'.
1106 Note: In many cases, properties of a frame are available as specifiers
1107 instead of through the frame-properties mechanism.
1109 Here is a list of recognized frame properties, other than those
1110 documented in `set-frame-properties' (they can be queried and
1111 set at any time, except as otherwise noted):
1113 initially-unmapped If non-nil, the frame will not be visible
1114 when it is created. In this case, you
1115 need to call `make-frame-visible' to make
1117 popup If non-nil, it should be a frame, and this
1118 frame will be created as a "popup" frame
1119 whose parent is the given frame. This
1120 will make the window manager treat the
1121 frame as a dialog box, which may entail
1122 doing different things (e.g. not asking
1123 for positioning, and not iconifying
1124 separate from its parent).
1125 top Y position (in pixels) of the upper-left
1126 outermost corner of the frame (i.e. the
1127 upper-left of the window-manager
1129 left X position (in pixels) of the upper-left
1130 outermost corner of the frame (i.e. the
1131 upper-left of the window-manager
1134 See also `default-frame-plist', which specifies properties which apply
1135 to all frames, not just mswindows frames.
1137 Vdefault_mswindows_frame_plist = Qnil;
1139 mswindows_console_methods->device_specific_frame_props =
1140 &Vdefault_mswindows_frame_plist;
1142 DEFVAR_LISP ("default-msprinter-frame-plist", &Vdefault_msprinter_frame_plist /*
1143 Plist of default frame-creation properties for msprinter print job frames.
1144 These override what is specified in `default-frame-plist', but are
1145 overridden by the arguments to the particular call to `make-frame'.
1147 Note: In many cases, properties of a frame are available as specifiers
1148 instead of through the frame-properties mechanism.
1150 Here is a list of recognized frame properties, other than those
1151 documented in `set-frame-properties' (they can be queried and
1152 set at any time, except as otherwise noted):
1154 left-margin Margin of the page, in twips. Twip is a
1155 top-margin typographical unit of measurement,
1156 right-margin equal to 1/1440 of an inch, or 1/20 of a
1157 bottom-margin point, and roughly equal to 7/400 of a
1158 millimeter. If not specifified, each margin
1159 defaults to one inch (25.4 mm).
1161 MARGINS NOTE. right-margin and bottom-margin are overridden by
1162 the height and width properties. If you want to specify size
1163 of the printable area in character, as with the rest of XEmacs,
1164 use these properties. If height and/or width are nil, then
1165 corresponding margin setting is taken into account. If you
1166 specify height and/or width in `default-frame-plist', but still
1167 want to specify right/bottom margins, set height/width in this
1168 plist to nil, as in this example:
1170 (setq default-frame-plist '(height 55 'width 80)
1171 default-msprinter-frame-plist '(height nil 'width nil))
1173 See also `default-frame-plist', which specifies properties which apply
1174 to all frames, not just mswindows frames.
1176 Vdefault_msprinter_frame_plist = Qnil;
1178 msprinter_console_methods->device_specific_frame_props =
1179 &Vdefault_msprinter_frame_plist;