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);
191 FRAME_MSWINDOWS_POPUP (f) = 1;
194 AdjustWindowRectEx(&rect, style, ADJR_MENUFLAG, exstyle);
196 XSETFRAME (frame_obj, f);
198 Vmswindows_frame_being_created = frame_obj;
200 hwnd = CreateWindowEx (exstyle,
202 STRINGP (f->name) ? (LPCTSTR) XSTRING_DATA (f->name) :
203 (STRINGP (name) ? (LPCTSTR) XSTRING_DATA (name) :
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 invalid_operation ("System call to create frame failed",
214 STRINGP (f->name) ? f->name :
215 STRINGP (name) ? name :
218 FRAME_MSWINDOWS_HANDLE(f) = hwnd;
220 SetWindowLong (hwnd, XWL_FRAMEOBJ, (LONG)LISP_TO_VOID(frame_obj));
221 FRAME_MSWINDOWS_DC(f) = GetDC (hwnd);
222 SetTextAlign (FRAME_MSWINDOWS_DC(f), TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
224 if (FRAME_MSWINDOWS_POPUP (f))
225 mswindows_register_popup_frame (frame_obj);
229 mswindows_init_frame_2 (struct frame *f, Lisp_Object props)
231 if (NILP (Vmswindows_use_system_frame_size_defaults))
233 /* I don't think anything can set the frame size before this
234 since we don't have X resources. This may change if we look
235 at the registry. Even so these values can get overridden
237 XEMACS_RECT_WH dest = { -1, -1, DEFAULT_FRAME_WIDTH,
238 DEFAULT_FRAME_HEIGHT };
239 mswindows_size_frame_internal (f, &dest);
243 /* Called after frame's properties are set */
245 mswindows_init_frame_3 (struct frame *f)
247 /* Don't do this earlier or we get a WM_PAINT before the frame is ready.
248 * The SW_x parameter in the first call that an app makes to ShowWindow is
249 * ignored, and the parameter specified in the caller's STARTUPINFO is
250 * substituted instead. That parameter is SW_HIDE if we were started by
251 * runemacs, so call this twice. #### runemacs is evil */
252 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
253 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
254 SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
255 DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE);
259 mswindows_after_init_frame (struct frame *f, int first_on_device,
260 int first_on_console)
262 /* Windows, unlike X, is very synchronous. After the initial
263 frame is created, it will never be displayed, except for
264 hollow border, unless we start pumping messages. Load progress
265 messages show in the bottom of the hollow frame, which is ugly.
266 We redisplay the initial frame here, so modeline and root window
269 if (first_on_console)
274 mswindows_mark_frame (struct frame *f)
276 mark_object (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
278 mark_object (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
280 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f));
281 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f));
282 mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE3 (f));
286 mswindows_focus_on_frame (struct frame *f)
288 SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
292 mswindows_delete_frame (struct frame *f)
297 XSETFRAME (frame, f);
298 mswindows_unregister_popup_frame (frame);
299 ReleaseDC(FRAME_MSWINDOWS_HANDLE(f), FRAME_MSWINDOWS_DC(f));
300 DestroyWindow(FRAME_MSWINDOWS_HANDLE(f));
301 xfree (f->frame_data);
307 mswindows_set_frame_size (struct frame *f, int width, int height)
312 rect.left = rect.top = 0;
314 rect.bottom = height;
316 pixel_to_char_size (f, rect.right, rect.bottom, &columns, &rows);
317 change_frame_size (f, rows, columns, 0);
319 AdjustWindowRectEx (&rect,
320 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
321 GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
322 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
324 if (IsIconic (FRAME_MSWINDOWS_HANDLE(f)) || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
325 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
327 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL,
328 0, 0, rect.right-rect.left, rect.bottom-rect.top,
329 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOMOVE);
333 mswindows_set_frame_position (struct frame *f, int xoff, int yoff)
335 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL,
337 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE);
341 mswindows_make_frame_visible (struct frame *f)
343 if (!FRAME_VISIBLE_P(f))
344 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
346 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOW);
352 mswindows_make_frame_invisible (struct frame *f)
354 if (!FRAME_VISIBLE_P(f))
357 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_HIDE);
362 mswindows_frame_totally_visible_p (struct frame *f)
364 RECT rc_me, rc_other, rc_temp;
365 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
367 /* We test against not a whole window rectangle, only against its
368 client part. So, if non-client are is covered and client area is
369 not, we return true. */
370 GetClientRect (hwnd, &rc_me);
371 MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rc_me, 2);
373 /* First see if we're off the desktop */
374 GetWindowRect (GetDesktopWindow(), &rc_other);
375 UnionRect(&rc_temp, &rc_me, &rc_other);
376 if (!EqualRect (&rc_temp, &rc_other))
379 /* Then see if any window above us obscures us */
380 while ((hwnd = GetWindow (hwnd, GW_HWNDPREV)) != NULL)
381 if (IsWindowVisible (hwnd))
383 GetWindowRect (hwnd, &rc_other);
384 if (IntersectRect(&rc_temp, &rc_me, &rc_other))
392 mswindows_frame_visible_p (struct frame *f)
394 return IsWindowVisible (FRAME_MSWINDOWS_HANDLE(f))
395 && !IsIconic (FRAME_MSWINDOWS_HANDLE(f));
400 mswindows_iconify_frame (struct frame *f)
402 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_MINIMIZE);
408 mswindows_frame_iconified_p (struct frame *f)
410 return IsIconic (FRAME_MSWINDOWS_HANDLE(f));
414 mswindows_set_frame_icon (struct frame *f)
416 if (IMAGE_INSTANCEP (f->icon)
417 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon)))
419 if (!XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon))
421 mswindows_initialize_image_instance_icon (XIMAGE_INSTANCE (f->icon),
425 SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HICON,
426 (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->icon));
431 mswindows_set_frame_pointer (struct frame *f)
433 if (IMAGE_INSTANCEP (f->pointer)
434 && IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (f->pointer)) == IMAGE_POINTER)
436 SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
437 (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
438 /* we only have to do this because GC doesn't cause a mouse
439 event and doesn't give time to event processing even if it
441 SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
446 mswindows_set_mouse_position (struct window *w, int x, int y)
448 struct frame *f = XFRAME (w->frame);
451 pt.x = w->pixel_left + x;
452 pt.y = w->pixel_top + y;
453 ClientToScreen (FRAME_MSWINDOWS_HANDLE(f), &pt);
454 SetCursorPos (pt.x, pt.y);
458 mswindows_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y)
465 /* What's under cursor? */
466 hwnd = WindowFromPoint (pt);
470 /* Get grandest parent of the window */
473 while ((hwnd_parent = GetParent (hwnd)) != NULL)
477 /* Make sure it belongs to us */
478 if (GetWindowThreadProcessId (hwnd, NULL) != GetCurrentThreadId ())
481 /* And that the window is an XEmacs frame */
483 char class_name [sizeof(XEMACS_CLASS) + 1];
484 if (!GetClassName (hwnd, class_name, sizeof(XEMACS_CLASS))
485 || strcmp (class_name, XEMACS_CLASS) != 0)
490 ScreenToClient (hwnd, &pt);
491 VOID_TO_LISP (*frame, GetWindowLong (hwnd, XWL_FRAMEOBJ));
498 mswindows_raise_frame (struct frame *f)
500 BringWindowToTop (FRAME_MSWINDOWS_HANDLE(f));
504 mswindows_lower_frame (struct frame *f)
506 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), HWND_BOTTOM, 0, 0, 0, 0,
507 SWP_NOSIZE | SWP_NOMOVE | SWP_NOSENDCHANGING);
511 mswindows_enable_frame (struct frame *f)
513 EnableWindow (FRAME_MSWINDOWS_HANDLE (f), TRUE);
517 mswindows_disable_frame (struct frame *f)
519 EnableWindow (FRAME_MSWINDOWS_HANDLE (f), FALSE);
523 mswindows_set_title_from_bufbyte (struct frame *f, Bufbyte *title)
525 unsigned int new_checksum = hash_string (title, strlen (title));
526 if (new_checksum != FRAME_MSWINDOWS_TITLE_CHECKSUM(f))
528 FRAME_MSWINDOWS_TITLE_CHECKSUM(f) = new_checksum;
529 SetWindowText (FRAME_MSWINDOWS_HANDLE(f), title);
534 mswindows_frame_property (struct frame *f, Lisp_Object property)
536 if (EQ (Qleft, property) || EQ (Qtop, property))
539 GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
540 return make_int (EQ (Qtop, property) ? rc.top : rc.left);
546 mswindows_internal_frame_property_p (struct frame *f, Lisp_Object property)
548 return EQ (property, Qleft)
549 || EQ (property, Qtop);
550 /* #### frame-x.c has also this. Why?
551 || STRINGP (property);
556 mswindows_frame_properties (struct frame *f)
558 Lisp_Object props = Qnil;
560 GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rc);
562 props = cons3 (Qtop, make_int (rc.top), props);
563 props = cons3 (Qleft, make_int (rc.left), props);
569 mswindows_set_frame_properties (struct frame *f, Lisp_Object plist)
572 int width = -1, height = -1;
573 BOOL width_specified_p = FALSE;
574 BOOL height_specified_p = FALSE;
575 BOOL x_specified_p = FALSE;
576 BOOL y_specified_p = FALSE;
579 /* Extract the properties from plist */
580 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
582 Lisp_Object prop = Fcar (tail);
583 Lisp_Object val = Fcar (Fcdr (tail));
587 /* Kludge to handle the font property. */
588 if (EQ (prop, Qfont))
590 /* If the value is not a string we silently ignore it. */
593 Lisp_Object frm, font_spec;
596 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil);
598 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil);
599 update_frame_face_values (f);
602 else if (EQ (prop, Qwidth))
606 width_specified_p = TRUE;
608 else if (EQ (prop, Qheight))
612 height_specified_p = TRUE;
614 else if (EQ (prop, Qleft))
618 x_specified_p = TRUE;
620 else if (EQ (prop, Qtop))
624 y_specified_p = TRUE;
629 /* Now we've extracted the properties, apply them.
630 Do not apply geometric properties during frame creation. This
631 is excessive anyways, and this loses because WM_SIZE has not
632 been sent yet, so frame width and height fields are not initialized.
634 unfortunately WM_SIZE loses as well since the resize is only
635 applied once and the first time WM_SIZE is applied not everything
636 is initialised in the frame (toolbars for instance). enabling
637 this always makes no visible difference and fixes a whole host of
638 bugs (and is more consistent with X) so I am going to reenable it.
640 if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f)
641 && (width_specified_p || height_specified_p
642 || x_specified_p || y_specified_p))
644 XEMACS_RECT_WH dest = { x, y, width, height };
646 mswindows_size_frame_internal (f, &dest);
651 mswindows_size_frame_internal (struct frame* f, XEMACS_RECT_WH* dest)
654 int pixel_width, pixel_height;
655 int size_p = (dest->width >=0 || dest->height >=0);
656 int move_p = (dest->top >=0 || dest->left >=0);
657 char_to_real_pixel_size (f, dest->width, dest->height, &pixel_width,
661 pixel_width = FRAME_PIXWIDTH (f);
662 if (dest->height < 0)
663 pixel_height = FRAME_PIXHEIGHT (f);
665 GetWindowRect (FRAME_MSWINDOWS_HANDLE(f), &rect);
667 dest->left = rect.left;
669 dest->top = rect.top;
671 rect.left = rect.top = 0;
672 rect.right = pixel_width;
673 rect.bottom = pixel_height;
675 AdjustWindowRectEx (&rect,
676 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_STYLE),
677 GetMenu (FRAME_MSWINDOWS_HANDLE(f)) != NULL,
678 GetWindowLong (FRAME_MSWINDOWS_HANDLE(f), GWL_EXSTYLE));
680 /* resize and move the window so that it fits in the workspace. This is
681 not restrictive since this will happen later anyway in WM_SIZE. We
682 have to do this after adjusting the rect to account for menubar
684 mswindows_get_workspace_coords (&ws_rect);
685 pixel_width = rect.right - rect.left;
686 pixel_height = rect.bottom - rect.top;
687 if (pixel_width > ws_rect.right - ws_rect.left)
689 pixel_width = ws_rect.right - ws_rect.left;
692 if (pixel_height > ws_rect.bottom - ws_rect.top)
694 pixel_height = ws_rect.bottom - ws_rect.top;
698 /* adjust position so window is in workspace */
699 if (dest->left + pixel_width > ws_rect.right)
701 dest->left = ws_rect.right - pixel_width;
704 if (dest->left < ws_rect.left)
706 dest->left = ws_rect.left;
710 if (dest->top + pixel_height > ws_rect.bottom)
712 dest->top = ws_rect.bottom - pixel_height;
715 if (dest->top < ws_rect.top)
717 dest->top = ws_rect.top;
721 if (IsIconic (FRAME_MSWINDOWS_HANDLE(f))
722 || IsZoomed (FRAME_MSWINDOWS_HANDLE(f)))
723 ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_RESTORE);
725 SetWindowPos (FRAME_MSWINDOWS_HANDLE(f), NULL,
726 dest->left, dest->top, pixel_width, pixel_height,
727 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSENDCHANGING
728 | (size_p ? 0 : SWP_NOSIZE)
729 | (move_p ? 0 : SWP_NOMOVE));
733 mswindows_get_frame_parent (struct frame *f)
735 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
736 hwnd = GetParent (hwnd);
740 VOID_TO_LISP (parent, GetWindowLong (hwnd, XWL_FRAMEOBJ));
741 assert (FRAME_MSWINDOWS_P (XFRAME (parent)));
749 mswindows_update_frame_external_traits (struct frame* frm, Lisp_Object name)
754 mswindows_frame_size_fixed_p (struct frame *f)
756 /* Frame size cannot change if the frame is maximized */
757 return IsZoomed (FRAME_MSWINDOWS_HANDLE (f));
760 /*---------------------------------------------------------------------*/
761 /*----- PRINTER FRAME -----*/
762 /*---------------------------------------------------------------------*/
765 * With some driver/os combination (I discovered this with HP drivers
766 * under W2K), DC geometry is reset upon StartDoc and EndPage
767 * calls. This is called every time one of these calls is made.
770 apply_dc_geometry (struct frame* f)
772 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
773 SetTextAlign (hdc, TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
774 SetViewportOrgEx (hdc, FRAME_MSPRINTER_PIXLEFT(f),
775 FRAME_MSPRINTER_PIXTOP(f), NULL);
779 msprinter_start_page (struct frame *f)
781 if (!FRAME_MSPRINTER_PAGE_STARTED (f))
783 FRAME_MSPRINTER_PAGE_STARTED (f) = 1;
784 StartPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
785 apply_dc_geometry (f);
790 error_frame_unsizable (struct frame *f)
793 XSETFRAME (frame, f);
794 invalid_change ("Cannot resize frame (margins) after print job has started.",
799 maybe_error_if_job_active (struct frame *f)
801 if (FRAME_MSPRINTER_JOB_STARTED (f))
802 error_frame_unsizable (f);
806 msprinter_init_frame_1 (struct frame *f, Lisp_Object props)
808 /* Make sure this is the only frame on device. Windows printer can
809 handle only one job at a time. */
810 if (!NILP (DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)))))
811 invalid_operation ("Only one frame (print job) at a time is allowed on "
812 "this printer device", FRAME_DEVICE (f));
814 f->frame_data = xnew_and_zero (struct msprinter_frame);
816 FRAME_MSPRINTER_TOP_MARGIN (f) =
817 mswindows_get_default_margin (Qtop_margin);
818 FRAME_MSPRINTER_BOTTOM_MARGIN (f) =
819 mswindows_get_default_margin (Qbottom_margin);
820 FRAME_MSPRINTER_LEFT_MARGIN (f) =
821 mswindows_get_default_margin (Qleft_margin);
822 FRAME_MSPRINTER_RIGHT_MARGIN (f) =
823 mswindows_get_default_margin (Qright_margin);
825 /* Negative for "uinspecified" */
826 FRAME_MSPRINTER_CHARWIDTH (f) = -1;
827 FRAME_MSPRINTER_CHARHEIGHT (f) = -1;
831 msprinter_init_frame_3 (struct frame *f)
834 struct device *device = XDEVICE (FRAME_DEVICE (f));
835 int frame_left, frame_top, frame_width, frame_height;
837 /* DC might be recreated in msprinter_apply_devmode,
838 so do not initialize until now */
839 HDC hdc = DEVICE_MSPRINTER_HDC (device);
840 int logpixelsx = GetDeviceCaps (hdc, LOGPIXELSX);
841 int logpixelsy = GetDeviceCaps (hdc, LOGPIXELSY);
842 int physicaloffsetx = GetDeviceCaps (hdc, PHYSICALOFFSETX);
843 int physicaloffsety = GetDeviceCaps (hdc, PHYSICALOFFSETY);
844 int physicalheight = GetDeviceCaps (hdc, PHYSICALHEIGHT);
845 int physicalwidth = GetDeviceCaps (hdc, PHYSICALWIDTH);
847 /* Compute geometry properties.
848 Conversion is from TWIPS -> inches -> pixels. */
849 frame_left = MulDiv (logpixelsx, FRAME_MSPRINTER_LEFT_MARGIN(f), 1440)
852 if (FRAME_MSPRINTER_CHARWIDTH(f) > 0)
854 char_to_real_pixel_size (f, FRAME_MSPRINTER_CHARWIDTH(f), 0,
856 FRAME_MSPRINTER_RIGHT_MARGIN(f) =
857 MulDiv (physicalwidth - (frame_left + frame_width), 1440,
861 frame_width = physicalwidth - frame_left
862 - MulDiv (logpixelsx, FRAME_MSPRINTER_RIGHT_MARGIN(f), 1440)
865 frame_top = MulDiv (logpixelsy, FRAME_MSPRINTER_TOP_MARGIN(f), 1440)
868 if (FRAME_MSPRINTER_CHARHEIGHT(f) > 0)
870 char_to_real_pixel_size (f, 0, FRAME_MSPRINTER_CHARHEIGHT(f),
871 NULL, &frame_height);
873 FRAME_MSPRINTER_BOTTOM_MARGIN(f) =
874 MulDiv (physicalheight - (frame_top + frame_height), 1440,
878 frame_height = physicalheight - frame_top
879 - MulDiv (logpixelsy, FRAME_MSPRINTER_BOTTOM_MARGIN(f), 1440)
882 /* Geometry sanity checks */
883 if (!frame_pixsize_valid_p (f, frame_width, frame_height))
884 invalid_operation ("Area inside print margins has shrunk to naught",
885 STRINGP (f->name) ? f->name : Qunbound);
889 || frame_left + frame_width > GetDeviceCaps (hdc, HORZRES)
890 || frame_top + frame_height > GetDeviceCaps (hdc, VERTRES))
891 invalid_operation ("Print area is ouside of the printer's "
892 "hardware printable area",
893 STRINGP (f->name) ? f->name : Qunbound);
895 /* Apply XEmacs frame geometry and layout windows */
898 FRAME_PIXWIDTH(f) = frame_width;
899 FRAME_PIXHEIGHT(f) = frame_height;
900 pixel_to_char_size (f, frame_width, frame_height, &columns, &rows);
901 change_frame_size (f, rows, columns, 0);
904 FRAME_MSPRINTER_PIXLEFT(f) = frame_left;
905 FRAME_MSPRINTER_PIXTOP(f) = frame_top;
907 /* Start print job */
908 di.cbSize = sizeof (di);
909 di.lpszDocName = (STRINGP(f->name)
910 ? (char*) XSTRING_DATA(f->name)
911 : "XEmacs print document");
912 di.lpszOutput = NULL;
913 di.lpszDatatype = NULL;
916 if (StartDoc (hdc, &di) <= 0)
917 invalid_operation ("Cannot start print job",
918 STRINGP (f->name) ? f->name : Qunbound);
920 apply_dc_geometry (f);
922 /* Finish frame setup */
923 FRAME_MSPRINTER_JOB_STARTED (f) = 1;
924 FRAME_VISIBLE_P(f) = 0;
928 msprinter_mark_frame (struct frame *f)
933 msprinter_delete_frame (struct frame *f)
937 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
938 if (FRAME_MSPRINTER_PAGE_STARTED (f))
940 if (FRAME_MSPRINTER_JOB_STARTED (f))
942 xfree (f->frame_data);
949 msprinter_frame_property (struct frame *f, Lisp_Object property)
951 if (EQ (Qleft_margin, property))
952 return make_int (FRAME_MSPRINTER_LEFT_MARGIN(f));
953 else if (EQ (Qtop_margin, property))
954 return make_int (FRAME_MSPRINTER_TOP_MARGIN(f));
955 if (EQ (Qright_margin, property))
956 return make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f));
957 else if (EQ (Qbottom_margin, property))
958 return make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f));
964 msprinter_internal_frame_property_p (struct frame *f, Lisp_Object property)
966 return (EQ (Qleft_margin, property) || EQ (Qtop_margin, property) ||
967 EQ (Qright_margin, property) || EQ (Qbottom_margin, property));
971 msprinter_frame_properties (struct frame *f)
973 Lisp_Object props = Qnil;
974 props = cons3 (Qbottom_margin,
975 make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f)), props);
976 props = cons3 (Qright_margin,
977 make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f)), props);
978 props = cons3 (Qtop_margin,
979 make_int (FRAME_MSPRINTER_TOP_MARGIN(f)), props);
980 props = cons3 (Qleft_margin,
981 make_int (FRAME_MSPRINTER_LEFT_MARGIN(f)), props);
986 msprinter_set_frame_properties (struct frame *f, Lisp_Object plist)
990 /* Extract the properties from plist */
991 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
993 Lisp_Object prop = Fcar (tail);
994 Lisp_Object val = Fcar (Fcdr (tail));
998 if (EQ (prop, Qwidth))
1000 maybe_error_if_job_active (f);
1004 FRAME_MSPRINTER_CHARWIDTH(f) = XINT (val);
1007 if (EQ (prop, Qheight))
1009 maybe_error_if_job_active (f);
1013 FRAME_MSPRINTER_CHARHEIGHT(f) = XINT (val);
1016 else if (EQ (prop, Qleft_margin))
1018 maybe_error_if_job_active (f);
1020 FRAME_MSPRINTER_LEFT_MARGIN(f) = XINT (val);
1022 else if (EQ (prop, Qtop_margin))
1024 maybe_error_if_job_active (f);
1026 FRAME_MSPRINTER_TOP_MARGIN(f) = XINT (val);
1028 else if (EQ (prop, Qright_margin))
1030 maybe_error_if_job_active (f);
1032 FRAME_MSPRINTER_RIGHT_MARGIN(f) = XINT (val);
1034 else if (EQ (prop, Qbottom_margin))
1036 maybe_error_if_job_active (f);
1038 FRAME_MSPRINTER_BOTTOM_MARGIN(f) = XINT (val);
1045 msprinter_set_frame_size (struct frame *f, int width, int height)
1047 /* We're absolutely unsizeable */
1048 error_frame_unsizable (f);
1052 msprinter_eject_page (struct frame *f)
1054 /* #### Should we eject empty pages? */
1055 if (FRAME_MSPRINTER_PAGE_STARTED (f))
1057 FRAME_MSPRINTER_PAGE_STARTED (f) = 0;
1058 EndPage (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
1059 apply_dc_geometry (f);
1065 console_type_create_frame_mswindows (void)
1067 /* Display frames */
1068 CONSOLE_HAS_METHOD (mswindows, init_frame_1);
1069 CONSOLE_HAS_METHOD (mswindows, init_frame_2);
1070 CONSOLE_HAS_METHOD (mswindows, init_frame_3);
1071 CONSOLE_HAS_METHOD (mswindows, after_init_frame);
1072 CONSOLE_HAS_METHOD (mswindows, mark_frame);
1073 CONSOLE_HAS_METHOD (mswindows, focus_on_frame);
1074 CONSOLE_HAS_METHOD (mswindows, delete_frame);
1075 CONSOLE_HAS_METHOD (mswindows, get_mouse_position);
1076 CONSOLE_HAS_METHOD (mswindows, set_mouse_position);
1077 CONSOLE_HAS_METHOD (mswindows, raise_frame);
1078 CONSOLE_HAS_METHOD (mswindows, lower_frame);
1079 CONSOLE_HAS_METHOD (mswindows, enable_frame);
1080 CONSOLE_HAS_METHOD (mswindows, disable_frame);
1081 CONSOLE_HAS_METHOD (mswindows, make_frame_visible);
1082 CONSOLE_HAS_METHOD (mswindows, make_frame_invisible);
1083 CONSOLE_HAS_METHOD (mswindows, iconify_frame);
1084 CONSOLE_HAS_METHOD (mswindows, set_frame_size);
1085 CONSOLE_HAS_METHOD (mswindows, set_frame_position);
1086 CONSOLE_HAS_METHOD (mswindows, frame_property);
1087 CONSOLE_HAS_METHOD (mswindows, internal_frame_property_p);
1088 CONSOLE_HAS_METHOD (mswindows, frame_properties);
1089 CONSOLE_HAS_METHOD (mswindows, set_frame_properties);
1090 CONSOLE_HAS_METHOD (mswindows, set_title_from_bufbyte);
1091 /* CONSOLE_HAS_METHOD (mswindows, set_icon_name_from_bufbyte); */
1092 CONSOLE_HAS_METHOD (mswindows, frame_visible_p);
1093 CONSOLE_HAS_METHOD (mswindows, frame_totally_visible_p);
1094 CONSOLE_HAS_METHOD (mswindows, frame_iconified_p);
1095 CONSOLE_HAS_METHOD (mswindows, set_frame_pointer);
1096 CONSOLE_HAS_METHOD (mswindows, set_frame_icon);
1097 CONSOLE_HAS_METHOD (mswindows, get_frame_parent);
1098 CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits);
1099 CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p);
1101 /* Printer frames, aka print jobs */
1102 CONSOLE_HAS_METHOD (msprinter, init_frame_1);
1103 CONSOLE_HAS_METHOD (msprinter, init_frame_3);
1104 CONSOLE_HAS_METHOD (msprinter, mark_frame);
1105 CONSOLE_HAS_METHOD (msprinter, delete_frame);
1106 CONSOLE_HAS_METHOD (msprinter, frame_property);
1107 CONSOLE_HAS_METHOD (msprinter, internal_frame_property_p);
1108 CONSOLE_HAS_METHOD (msprinter, frame_properties);
1109 CONSOLE_HAS_METHOD (msprinter, set_frame_properties);
1110 CONSOLE_HAS_METHOD (msprinter, set_frame_size);
1111 CONSOLE_HAS_METHOD (msprinter, eject_page);
1115 syms_of_frame_mswindows (void)
1120 reinit_vars_of_frame_mswindows (void)
1122 /* Needn't staticpro -- see comment above. */
1123 Vmswindows_frame_being_created = Qnil;
1127 vars_of_frame_mswindows (void)
1129 reinit_vars_of_frame_mswindows ();
1131 DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /*
1132 Controls whether to use system or XEmacs defaults for frame size.
1133 If nil then reasonable defaults are used for initial frame sizes. If t
1134 then the system will choose default sizes for the frame.
1136 Vmswindows_use_system_frame_size_defaults = Qnil;
1138 DEFVAR_LISP ("default-mswindows-frame-plist", &Vdefault_mswindows_frame_plist /*
1139 Plist of default frame-creation properties for mswindows frames.
1140 These override what is specified in `default-frame-plist', but are
1141 overridden by the arguments to the particular call to `make-frame'.
1143 Note: In many cases, properties of a frame are available as specifiers
1144 instead of through the frame-properties mechanism.
1146 Here is a list of recognized frame properties, other than those
1147 documented in `set-frame-properties' (they can be queried and
1148 set at any time, except as otherwise noted):
1150 initially-unmapped If non-nil, the frame will not be visible
1151 when it is created. In this case, you
1152 need to call `make-frame-visible' to make
1154 popup If non-nil, it should be a frame, and this
1155 frame will be created as a "popup" frame
1156 whose parent is the given frame. This
1157 will make the window manager treat the
1158 frame as a dialog box, which may entail
1159 doing different things (e.g. not asking
1160 for positioning, and not iconifying
1161 separate from its parent).
1162 top Y position (in pixels) of the upper-left
1163 outermost corner of the frame (i.e. the
1164 upper-left of the window-manager
1166 left X position (in pixels) of the upper-left
1167 outermost corner of the frame (i.e. the
1168 upper-left of the window-manager
1171 See also `default-frame-plist', which specifies properties which apply
1172 to all frames, not just mswindows frames.
1174 Vdefault_mswindows_frame_plist = Qnil;
1176 mswindows_console_methods->device_specific_frame_props =
1177 &Vdefault_mswindows_frame_plist;
1179 DEFVAR_LISP ("default-msprinter-frame-plist", &Vdefault_msprinter_frame_plist /*
1180 Plist of default frame-creation properties for msprinter print job frames.
1181 These override what is specified in `default-frame-plist', but are
1182 overridden by the arguments to the particular call to `make-frame'.
1184 Note: In many cases, properties of a frame are available as specifiers
1185 instead of through the frame-properties mechanism.
1187 Here is a list of recognized frame properties, other than those
1188 documented in `set-frame-properties' (they can be queried and
1189 set at any time, except as otherwise noted):
1191 left-margin Margin of the page, in twips. Twip is a
1192 top-margin typographical unit of measurement,
1193 right-margin equal to 1/1440 of an inch, or 1/20 of a
1194 bottom-margin point, and roughly equal to 7/400 of a
1195 millimeter. If not specified, the left
1196 and right margins default to 1 inch
1197 (25.4 mm) and the top and bottom margins
1198 to 0.5 inch (12.7 mm).
1200 MARGINS NOTE. right-margin and bottom-margin are overridden by
1201 the height and width properties. If you want to specify size
1202 of the printable area in character, as with the rest of XEmacs,
1203 use these properties. If height and/or width are nil, then
1204 corresponding margin setting is taken into account. If you
1205 specify height and/or width in `default-frame-plist', but still
1206 want to specify right/bottom margins, set height/width in this
1207 plist to nil, as in this example:
1209 (setq default-frame-plist '(height 55 width 80)
1210 default-msprinter-frame-plist '(height nil width nil))
1212 See also `default-frame-plist', which specifies properties which apply
1213 to all frames, not just mswindows frames.
1215 Vdefault_msprinter_frame_plist = Qnil;
1217 msprinter_console_methods->device_specific_frame_props =
1218 &Vdefault_msprinter_frame_plist;