comparison src/frame-msw.c @ 440:8de8e3f6228a r21-2-28

Import from CVS: tag r21-2-28
author cvs
date Mon, 13 Aug 2007 11:33:38 +0200
parents 3ecd8885ac67
children abe6d1db359e
comparison
equal deleted inserted replaced
439:357dd071b03c 440:8de8e3f6228a
68 #define ADJR_MENUFLAG FALSE 68 #define ADJR_MENUFLAG FALSE
69 #endif 69 #endif
70 70
71 /* Default properties to use when creating frames. */ 71 /* Default properties to use when creating frames. */
72 Lisp_Object Vdefault_mswindows_frame_plist; 72 Lisp_Object Vdefault_mswindows_frame_plist;
73 Lisp_Object Vdefault_msprinter_frame_plist;
73 Lisp_Object Vmswindows_use_system_frame_size_defaults; 74 Lisp_Object Vmswindows_use_system_frame_size_defaults;
74 75
75 /* This does not need to be GC protected, as it holds a 76 /* This does not need to be GC protected, as it holds a
76 frame Lisp_Object already protected by Fmake_frame */ 77 frame Lisp_Object already protected by Fmake_frame */
77 Lisp_Object Vmswindows_frame_being_created; 78 Lisp_Object Vmswindows_frame_being_created;
79
80 /*---------------------------------------------------------------------*/
81 /*----- DISPLAY FRAME -----*/
82 /*---------------------------------------------------------------------*/
78 83
79 static void 84 static void
80 mswindows_init_frame_1 (struct frame *f, Lisp_Object props) 85 mswindows_init_frame_1 (struct frame *f, Lisp_Object props)
81 { 86 {
82 Lisp_Object initially_unmapped; 87 Lisp_Object initially_unmapped;
592 is initialised in the frame (toolbars for instance). enabling 597 is initialised in the frame (toolbars for instance). enabling
593 this always makes no visible difference and fixes a whole host of 598 this always makes no visible difference and fixes a whole host of
594 bugs (and is more consistent with X) so I am going to reenable it. 599 bugs (and is more consistent with X) so I am going to reenable it.
595 --andyp */ 600 --andyp */
596 if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f) 601 if ( FRAME_PIXWIDTH (f) && FRAME_PIXHEIGHT (f)
597 && (width_specified_p || height_specified_p || x_specified_p || y_specified_p)) 602 && (width_specified_p || height_specified_p
603 || x_specified_p || y_specified_p))
598 { 604 {
599 XEMACS_RECT_WH dest = { x, y, width, height }; 605 XEMACS_RECT_WH dest = { x, y, width, height };
600 606
601 mswindows_size_frame_internal (f, &dest); 607 mswindows_size_frame_internal (f, &dest);
602 } 608 }
697 { 703 {
698 /* Frame size cannot change if the frame is maximized */ 704 /* Frame size cannot change if the frame is maximized */
699 return IsZoomed (FRAME_MSWINDOWS_HANDLE (f)); 705 return IsZoomed (FRAME_MSWINDOWS_HANDLE (f));
700 } 706 }
701 707
708 /*---------------------------------------------------------------------*/
709 /*----- PRINTER FRAME -----*/
710 /*---------------------------------------------------------------------*/
711
712 EXFUN (Fset_frame_properties, 2);
713
714 static void
715 error_frame_unsizable (struct frame *f)
716 {
717 Lisp_Object frame;
718 XSETFRAME (frame, f);
719 signal_simple_error ("Cannot resize frame (margins)"
720 " after print job has started.", frame);
721 }
722
723 static void
724 maybe_error_if_job_active (struct frame *f)
725 {
726 if (FRAME_MSPRINTER_JOB_STARTED (f))
727 error_frame_unsizable (f);
728 }
729
730 static void
731 msprinter_init_frame_1 (struct frame *f, Lisp_Object props)
732 {
733 HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f)));
734 Lisp_Object frame_obj = Qnil;
735
736 /* Make sure this is the only frame on device. Windows printer can
737 handle only one job at a time. */
738 if (!NILP (DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)))))
739 error ("Only one frame (print job) at a time is allowed on "
740 "this printer device.");
741
742 f->frame_data = xnew_and_zero (struct msprinter_frame);
743
744 /* Default margin size is 1" = 1440 twips */
745 FRAME_MSPRINTER_TOP_MARGIN(f) = 1440;
746 FRAME_MSPRINTER_BOTTOM_MARGIN(f) = 1440;
747 FRAME_MSPRINTER_LEFT_MARGIN(f) = 1440;
748 FRAME_MSPRINTER_RIGHT_MARGIN(f) = 1440;
749
750 /* Negative for "uinspecified" */
751 FRAME_MSPRINTER_CHARWIDTH(f) = -1;
752 FRAME_MSPRINTER_CHARHEIGHT(f) = -1;
753
754 /* nil is for "system default" for these properties. */
755 FRAME_MSPRINTER_ORIENTATION(f) = Qnil;
756 FRAME_MSPRINTER_DUPLEX(f) = Qnil;
757 }
758
759 static void
760 msprinter_init_frame_3 (struct frame *f)
761 {
762 DOCINFO di;
763 struct device *device = XDEVICE (FRAME_DEVICE (f));
764 HDC hdc = DEVICE_MSPRINTER_HDC (device);
765 int frame_left, frame_top, frame_width, frame_height;
766
767 /* Change printer parameters */
768 {
769 DEVMODE* devmode = msprinter_get_devmode_copy (device);
770 devmode->dmFields = 0;
771
772 if (!NILP (FRAME_MSPRINTER_ORIENTATION(f)))
773 {
774 devmode->dmFields = DM_ORIENTATION;
775 if (EQ (FRAME_MSPRINTER_ORIENTATION(f), Qportrait))
776 devmode->dmOrientation = DMORIENT_PORTRAIT;
777 else if (EQ (FRAME_MSPRINTER_ORIENTATION(f), Qlandscape))
778 devmode->dmOrientation = DMORIENT_LANDSCAPE;
779 else
780 abort();
781 }
782
783 if (!NILP (FRAME_MSPRINTER_DUPLEX(f)))
784 {
785 devmode->dmFields = DM_DUPLEX;
786 if (EQ (FRAME_MSPRINTER_DUPLEX(f), Qnone))
787 devmode->dmDuplex = DMDUP_SIMPLEX;
788 if (EQ (FRAME_MSPRINTER_DUPLEX(f), Qvertical))
789 devmode->dmDuplex = DMDUP_VERTICAL;
790 if (EQ (FRAME_MSPRINTER_DUPLEX(f), Qhorizontal))
791 devmode->dmDuplex = DMDUP_HORIZONTAL;
792 else
793 abort();
794 }
795
796 msprinter_apply_devmode (device, devmode);
797 }
798
799 /* Compute geometry properties */
800 frame_left = (MulDiv (GetDeviceCaps (hdc, LOGPIXELSX),
801 FRAME_MSPRINTER_LEFT_MARGIN(f), 1440)
802 - GetDeviceCaps (hdc, PHYSICALOFFSETX));
803
804 if (FRAME_MSPRINTER_CHARWIDTH(f) > 0)
805 {
806 char_to_real_pixel_size (f, FRAME_MSPRINTER_CHARWIDTH(f), 0,
807 &frame_width, NULL);
808 FRAME_MSPRINTER_RIGHT_MARGIN(f) =
809 MulDiv (GetDeviceCaps (hdc, PHYSICALWIDTH)
810 - (frame_left + frame_width), 1440,
811 GetDeviceCaps (hdc, LOGPIXELSX));
812 }
813 else
814 frame_width = (GetDeviceCaps (hdc, PHYSICALWIDTH)
815 - frame_left
816 - MulDiv (GetDeviceCaps (hdc, LOGPIXELSX),
817 FRAME_MSPRINTER_RIGHT_MARGIN(f), 1440));
818
819 frame_top = (MulDiv (GetDeviceCaps (hdc, LOGPIXELSY),
820 FRAME_MSPRINTER_TOP_MARGIN(f), 1440)
821 - GetDeviceCaps (hdc, PHYSICALOFFSETY));
822
823 if (FRAME_MSPRINTER_CHARHEIGHT(f) > 0)
824 {
825 char_to_real_pixel_size (f, 0, FRAME_MSPRINTER_CHARHEIGHT(f),
826 NULL, &frame_height);
827
828 FRAME_MSPRINTER_BOTTOM_MARGIN(f) =
829 MulDiv (GetDeviceCaps (hdc, PHYSICALHEIGHT)
830 - (frame_top + frame_height), 1440,
831 GetDeviceCaps (hdc, LOGPIXELSY));
832 }
833 else
834 frame_height = (GetDeviceCaps (hdc, PHYSICALHEIGHT)
835 - frame_top
836 - MulDiv (GetDeviceCaps (hdc, LOGPIXELSY),
837 FRAME_MSPRINTER_BOTTOM_MARGIN(f), 1440));
838
839 /* Geometry sanity checks */
840 if (!frame_pixsize_valid_p (f, frame_width, frame_height))
841 error ("Area inside print margins has shrunk to naught.");
842
843 if (frame_left < 0
844 || frame_top < 0
845 || frame_left + frame_width > GetDeviceCaps (hdc, HORZRES)
846 || frame_top + frame_height > GetDeviceCaps (hdc, VERTRES))
847 error ("Print area is ouside of the printer's hardware printable area.");
848
849 /* Apply XEmacs frame geometry and layout windows */
850 {
851 int rows, columns;
852 FRAME_PIXWIDTH(f) = frame_width;
853 FRAME_PIXHEIGHT(f) = frame_height;
854 pixel_to_char_size (f, frame_width, frame_height, &columns, &rows);
855 change_frame_size (f, rows, columns, 0);
856 }
857
858 /* Apply DC geometry */
859 SetTextAlign (hdc, TA_BASELINE | TA_LEFT | TA_NOUPDATECP);
860 SetViewportOrgEx (hdc, frame_left, frame_top, NULL);
861 SetWindowOrgEx (hdc, 0, 0, NULL);
862
863 /* Start print job */
864 di.cbSize = sizeof (di);
865 di.lpszDocName = (STRINGP(f->name)
866 ? (char*) XSTRING_DATA(f->name)
867 : "XEmacs print document");
868 di.lpszOutput = NULL;
869 di.lpszDatatype = NULL;
870 di.fwType = 0;
871
872 if (StartDoc (hdc, &di) <= 0)
873 error ("Cannot start print job");
874
875 /* Finish frame setup */
876 FRAME_MSPRINTER_CDC(f) = CreateCompatibleDC (hdc);
877 FRAME_MSPRINTER_JOB_STARTED (f) = 1;
878 FRAME_VISIBLE_P(f) = 0;
879 }
880
881 static void
882 msprinter_mark_frame (struct frame *f)
883 {
884 /* NOTE: These need not be marked as long as we allow only c-defined
885 symbols for their values. Although, marking these is safer than
886 expensive. [I know a proof to the theorem postulating that a
887 gator is longer than greener. Ask me. -- kkm] */
888 mark_object (FRAME_MSPRINTER_ORIENTATION (f));
889 mark_object (FRAME_MSPRINTER_DUPLEX (f));
890 }
891
892 static void
893 msprinter_delete_frame (struct frame *f)
894 {
895 if (f->frame_data)
896 {
897 if (FRAME_MSPRINTER_JOB_STARTED (f))
898 EndDoc (DEVICE_MSPRINTER_HDC (XDEVICE (FRAME_DEVICE (f))));
899 if (FRAME_MSPRINTER_CDC(f))
900 DeleteDC(FRAME_MSPRINTER_CDC(f));
901 xfree (f->frame_data);
902 }
903
904 f->frame_data = 0;
905 }
906
907 static Lisp_Object
908 msprinter_frame_property (struct frame *f, Lisp_Object property)
909 {
910 if (EQ (Qleft_margin, property))
911 return make_int (FRAME_MSPRINTER_LEFT_MARGIN(f));
912 else if (EQ (Qtop_margin, property))
913 return make_int (FRAME_MSPRINTER_TOP_MARGIN(f));
914 if (EQ (Qright_margin, property))
915 return make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f));
916 else if (EQ (Qbottom_margin, property))
917 return make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f));
918 else if (EQ (Qorientation, property))
919 return FRAME_MSPRINTER_ORIENTATION(f);
920 else if (EQ (Qduplex, property))
921 return FRAME_MSPRINTER_DUPLEX(f);
922 else
923 return Qunbound;
924 }
925
926 static int
927 msprinter_internal_frame_property_p (struct frame *f, Lisp_Object property)
928 {
929 return (EQ (Qleft_margin, property) || EQ (Qtop_margin, property) ||
930 EQ (Qright_margin, property) || EQ (Qbottom_margin, property) ||
931 EQ (Qorientation, property) || EQ (Qduplex, property));
932 }
933
934 static Lisp_Object
935 msprinter_frame_properties (struct frame *f)
936 {
937 Lisp_Object props = Qnil;
938 props = cons3 (Qorientation, FRAME_MSPRINTER_ORIENTATION(f), props);
939 props = cons3 (Qduplex, FRAME_MSPRINTER_DUPLEX(f), props);
940 props = cons3 (Qbottom_margin,
941 make_int (FRAME_MSPRINTER_BOTTOM_MARGIN(f)), props);
942 props = cons3 (Qright_margin,
943 make_int (FRAME_MSPRINTER_RIGHT_MARGIN(f)), props);
944 props = cons3 (Qtop_margin,
945 make_int (FRAME_MSPRINTER_TOP_MARGIN(f)), props);
946 props = cons3 (Qleft_margin,
947 make_int (FRAME_MSPRINTER_LEFT_MARGIN(f)), props);
948 return props;
949 }
950
951 static void
952 msprinter_set_frame_properties (struct frame *f, Lisp_Object plist)
953 {
954 BOOL size_changed_p = FALSE;
955 Lisp_Object tail;
956
957 /* Extract the properties from plist */
958 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
959 {
960 Lisp_Object prop = Fcar (tail);
961 Lisp_Object val = Fcar (Fcdr (tail));
962
963 if (SYMBOLP (prop))
964 {
965 if (EQ (prop, Qwidth))
966 {
967 maybe_error_if_job_active (f);
968 if (!NILP (val))
969 {
970 CHECK_NATNUM (val);
971 FRAME_MSPRINTER_CHARWIDTH(f) = XINT (val);
972 }
973 }
974 if (EQ (prop, Qheight))
975 {
976 maybe_error_if_job_active (f);
977 if (!NILP (val))
978 {
979 CHECK_NATNUM (val);
980 FRAME_MSPRINTER_CHARHEIGHT(f) = XINT (val);
981 }
982 }
983 else if (EQ (prop, Qleft_margin))
984 {
985 maybe_error_if_job_active (f);
986 CHECK_NATNUM (val);
987 FRAME_MSPRINTER_LEFT_MARGIN(f) = XINT (val);
988 }
989 else if (EQ (prop, Qtop_margin))
990 {
991 maybe_error_if_job_active (f);
992 CHECK_NATNUM (val);
993 FRAME_MSPRINTER_TOP_MARGIN(f) = XINT (val);
994 }
995 else if (EQ (prop, Qright_margin))
996 {
997 maybe_error_if_job_active (f);
998 CHECK_NATNUM (val);
999 FRAME_MSPRINTER_RIGHT_MARGIN(f) = XINT (val);
1000 }
1001 else if (EQ (prop, Qbottom_margin))
1002 {
1003 maybe_error_if_job_active (f);
1004 CHECK_NATNUM (val);
1005 FRAME_MSPRINTER_BOTTOM_MARGIN(f) = XINT (val);
1006 }
1007 else if (EQ (prop, Qorientation))
1008 {
1009 maybe_error_if_job_active (f);
1010 CHECK_SYMBOL (val);
1011 if (!NILP(val) &&
1012 !EQ (val, Qportrait) &&
1013 !EQ (val, Qlandscape))
1014 signal_simple_error ("Page orientation can only be "
1015 "'portrait or 'landscape", val);
1016 FRAME_MSPRINTER_ORIENTATION(f) = val;
1017 }
1018 else if (EQ (prop, Qduplex))
1019 {
1020 maybe_error_if_job_active (f);
1021 CHECK_SYMBOL (val);
1022 if (!NILP(val) &&
1023 !EQ (val, Qnone) &&
1024 !EQ (val, Qvertical) &&
1025 !EQ (val, Qhorizontal))
1026 signal_simple_error ("Duplex can only be 'none, "
1027 "'vertical or 'horizontal", val);
1028 FRAME_MSPRINTER_DUPLEX(f) = val;
1029 }
1030 }
1031 }
1032 }
1033
1034 static void
1035 msprinter_set_frame_size (struct frame *f, int width, int height)
1036 {
1037 /* We're absolutely unsizeable */
1038 error_frame_unsizable (f);
1039 }
1040
702 void 1041 void
703 console_type_create_frame_mswindows (void) 1042 console_type_create_frame_mswindows (void)
704 { 1043 {
705 /* frame methods */ 1044 /* Display frames */
706 CONSOLE_HAS_METHOD (mswindows, init_frame_1); 1045 CONSOLE_HAS_METHOD (mswindows, init_frame_1);
707 CONSOLE_HAS_METHOD (mswindows, init_frame_2); 1046 CONSOLE_HAS_METHOD (mswindows, init_frame_2);
708 CONSOLE_HAS_METHOD (mswindows, init_frame_3); 1047 CONSOLE_HAS_METHOD (mswindows, init_frame_3);
709 CONSOLE_HAS_METHOD (mswindows, after_init_frame); 1048 CONSOLE_HAS_METHOD (mswindows, after_init_frame);
710 CONSOLE_HAS_METHOD (mswindows, mark_frame); 1049 CONSOLE_HAS_METHOD (mswindows, mark_frame);
731 CONSOLE_HAS_METHOD (mswindows, set_frame_pointer); 1070 CONSOLE_HAS_METHOD (mswindows, set_frame_pointer);
732 CONSOLE_HAS_METHOD (mswindows, set_frame_icon); 1071 CONSOLE_HAS_METHOD (mswindows, set_frame_icon);
733 CONSOLE_HAS_METHOD (mswindows, get_frame_parent); 1072 CONSOLE_HAS_METHOD (mswindows, get_frame_parent);
734 CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits); 1073 CONSOLE_HAS_METHOD (mswindows, update_frame_external_traits);
735 CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p); 1074 CONSOLE_HAS_METHOD (mswindows, frame_size_fixed_p);
1075
1076 /* Printer frames, aka print jobs */
1077 CONSOLE_HAS_METHOD (msprinter, init_frame_1);
1078 CONSOLE_HAS_METHOD (msprinter, init_frame_3);
1079 CONSOLE_HAS_METHOD (msprinter, mark_frame);
1080 CONSOLE_HAS_METHOD (msprinter, delete_frame);
1081 CONSOLE_HAS_METHOD (msprinter, frame_property);
1082 CONSOLE_HAS_METHOD (msprinter, internal_frame_property_p);
1083 CONSOLE_HAS_METHOD (msprinter, frame_properties);
1084 CONSOLE_HAS_METHOD (msprinter, set_frame_properties);
1085 CONSOLE_HAS_METHOD (msprinter, set_frame_size);
736 } 1086 }
737 1087
738 void 1088 void
739 syms_of_frame_mswindows (void) 1089 syms_of_frame_mswindows (void)
740 { 1090 {
797 */ ); 1147 */ );
798 Vdefault_mswindows_frame_plist = Qnil; 1148 Vdefault_mswindows_frame_plist = Qnil;
799 1149
800 mswindows_console_methods->device_specific_frame_props = 1150 mswindows_console_methods->device_specific_frame_props =
801 &Vdefault_mswindows_frame_plist; 1151 &Vdefault_mswindows_frame_plist;
802 } 1152
1153 DEFVAR_LISP ("default-msprinter-frame-plist", &Vdefault_msprinter_frame_plist /*
1154 Plist of default frame-creation properties for msprinter print job frames.
1155 These override what is specified in `default-frame-plist', but are
1156 overridden by the arguments to the particular call to `make-frame'.
1157
1158 Note: In many cases, properties of a frame are available as specifiers
1159 instead of through the frame-properties mechanism.
1160
1161 Here is a list of recognized frame properties, other than those
1162 documented in `set-frame-properties' (they can be queried and
1163 set at any time, except as otherwise noted):
1164
1165 left-margin Margin of the page, in twips. Twip is a
1166 top-margin typographical unit of measurement,
1167 right-margin equal to 1/1440 of an inch, or 1/20 of a
1168 bottom-margin point, and roughly equal to 7/400 of a
1169 millimeter. If not specifified, each margin
1170 defaults to one inch (25.4 mm).
1171
1172 MARGINS NOTE. right-margin and bottom-margin are overridden by
1173 the height and width properties. If you want to specify size
1174 of the printable area in character, as with the rest of XEmacs,
1175 use these properties. If height and/or width are nil, then
1176 corresponding margin setting is taken into account. If you
1177 specify height and/or width in `default-frame-plist', but still
1178 want to specify right/bottom margins, set height/width in this
1179 plist to nil, as in this example:
1180
1181 (setq default-frame-plist '(height 55 'width 80)
1182 default-msprinter-frame-plist '(height nil 'width nil))
1183
1184
1185 orientation Printer page orientation. Can be 'nil,
1186 indicating system default, 'portrait
1187 or 'landscape.
1188
1189 duplex Duplex printing mode, subject to printer
1190 support. Can be 'nil for the device default,
1191 'none for simplex printing, 'vertical or
1192 'horizontal for duplex page bound along
1193 the corresponding page direction.
1194
1195 See also `default-frame-plist', which specifies properties which apply
1196 to all frames, not just mswindows frames.
1197 */ );
1198 Vdefault_msprinter_frame_plist = Qnil;
1199
1200 msprinter_console_methods->device_specific_frame_props =
1201 &Vdefault_msprinter_frame_plist;
1202 }