summaryrefslogtreecommitdiff
path: root/hw/xprint
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xprint')
-rw-r--r--hw/xprint/AttrValid.c702
-rw-r--r--hw/xprint/AttrValid.h220
-rw-r--r--hw/xprint/DiPrint.h81
-rw-r--r--hw/xprint/Init.c1921
-rw-r--r--hw/xprint/Makefile.am42
-rw-r--r--hw/xprint/Oid.c3182
-rw-r--r--hw/xprint/Oid.h294
-rw-r--r--hw/xprint/OidDefs.h171
-rw-r--r--hw/xprint/OidStrs.h173
-rw-r--r--hw/xprint/Util.c372
-rw-r--r--hw/xprint/ValTree.c193
-rw-r--r--hw/xprint/attributes.c1737
-rw-r--r--hw/xprint/attributes.h131
-rw-r--r--hw/xprint/config/C/Makefile.am1
-rw-r--r--hw/xprint/config/C/print/Makefile.am14
-rw-r--r--hw/xprint/config/C/print/Xprinters49
-rw-r--r--hw/xprint/config/C/print/attributes/Makefile.am3
-rw-r--r--hw/xprint/config/C/print/attributes/document49
-rw-r--r--hw/xprint/config/C/print/attributes/job25
-rw-r--r--hw/xprint/config/C/print/attributes/printer96
-rw-r--r--hw/xprint/config/C/print/ddx-config/Makefile.am1
-rw-r--r--hw/xprint/config/C/print/ddx-config/raster/Makefile.am3
-rw-r--r--hw/xprint/config/C/print/ddx-config/raster/pcl39
-rw-r--r--hw/xprint/config/C/print/ddx-config/raster/postscript0
-rw-r--r--hw/xprint/config/C/print/models/CANONBJ10E-GS/Makefile.am3
-rw-r--r--hw/xprint/config/C/print/models/CANONBJ10E-GS/model-config23
-rw-r--r--hw/xprint/config/C/print/models/CANONC3200-PS/Makefile.am5
-rw-r--r--hw/xprint/config/C/print/models/CANONC3200-PS/fonts/Makefile.am54
-rw-r--r--hw/xprint/config/C/print/models/CANONC3200-PS/model-config40
-rw-r--r--hw/xprint/config/C/print/models/GSdefault/Makefile.am3
-rw-r--r--hw/xprint/config/C/print/models/GSdefault/model-config137
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/Makefile.am5
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00051.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00052.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00053.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00054.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00055.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00056.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00057.pmfbin0 -> 5632 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00058.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00059.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00060.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00061.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00062.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00063.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00064.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00065.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00066.pmfbin0 -> 5732 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00067.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00068.pmfbin0 -> 5732 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00069.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00070.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00071.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00072.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00073.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00074.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00075.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00076.pmfbin0 -> 5716 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00077.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00079.pmfbin0 -> 5656 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00080.pmfbin0 -> 5664 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00081.pmfbin0 -> 5672 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00082.pmfbin0 -> 5660 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00083.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00084.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00085.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00086.pmfbin0 -> 5716 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00087.pmfbin0 -> 5752 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00088.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00089.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00090.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00091.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00092.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00093.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00094.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/Makefile.am50
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/README197
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.alias0
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.dir45
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/fonts/lpr0ye1a.pmfbin0 -> 4296 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPDJ1600C/model-config40
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4050-PS/Makefile.am5
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4050-PS/fonts/Makefile.am54
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4050-PS/model-config36
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/Makefile.am5
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00051.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00052.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00053.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00054.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00055.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00056.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00057.pmfbin0 -> 5632 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00058.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00059.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00060.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00061.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00062.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00063.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00064.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00065.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00066.pmfbin0 -> 5732 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00067.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00068.pmfbin0 -> 5732 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00069.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00070.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00071.pmfbin0 -> 5740 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00072.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00073.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00074.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00075.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00076.pmfbin0 -> 5716 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00077.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00079.pmfbin0 -> 5656 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00080.pmfbin0 -> 5664 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00081.pmfbin0 -> 5672 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00082.pmfbin0 -> 5660 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00083.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00084.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00085.pmfbin0 -> 5724 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00086.pmfbin0 -> 5716 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00087.pmfbin0 -> 5752 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00088.pmfbin0 -> 5720 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00089.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00090.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00091.pmfbin0 -> 5744 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00092.pmfbin0 -> 5736 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00093.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00094.pmfbin0 -> 5728 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/Makefile.am50
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/README203
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.alias0
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.dir45
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/fonts/lpr0ye1a.pmfbin0 -> 4296 bytes
-rw-r--r--hw/xprint/config/C/print/models/HPLJ4family/model-config39
-rw-r--r--hw/xprint/config/C/print/models/Makefile.am11
-rw-r--r--hw/xprint/config/C/print/models/PS2PDFspooldir-GS/Makefile.am3
-rw-r--r--hw/xprint/config/C/print/models/PS2PDFspooldir-GS/model-config72
-rwxr-xr-xhw/xprint/config/C/print/models/PS2PDFspooldir-GS/ps2pdf_spooltodir.sh130
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/Makefile.am5
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Book.pmfbin0 -> 6716 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-BookOblique.pmfbin0 -> 6728 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Demi.pmfbin0 -> 6712 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-DemiOblique.pmfbin0 -> 6724 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Bold.pmfbin0 -> 6612 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Courier-BoldOblique.pmfbin0 -> 6636 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Oblique.pmfbin0 -> 6608 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Courier.pmfbin0 -> 6592 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Bold.pmfbin0 -> 6680 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-BoldOblique.pmfbin0 -> 6692 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Oblique.pmfbin0 -> 6688 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica.pmfbin0 -> 6672 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Book.pmfbin0 -> 6628 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-BookOblique.pmfbin0 -> 6640 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Demi.pmfbin0 -> 6624 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-DemiOblique.pmfbin0 -> 6636 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Makefile.am44
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Bold.pmfbin0 -> 6644 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-BoldItalic.pmfbin0 -> 6656 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Italic.pmfbin0 -> 6652 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Roman.pmfbin0 -> 6648 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Demi.pmfbin0 -> 6680 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-DemiItalic.pmfbin0 -> 6692 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Light.pmfbin0 -> 6684 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-LightItalic.pmfbin0 -> 6696 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Symbol.pmfbin0 -> 6556 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Times-Bold.pmfbin0 -> 6660 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Times-BoldItalic.pmfbin0 -> 6672 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Times-Italic.pmfbin0 -> 6668 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/Times-Roman.pmfbin0 -> 6664 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/fonts/ZapfDingbats.pmfbin0 -> 6676 bytes
-rw-r--r--hw/xprint/config/C/print/models/PSdefault/model-config136
-rw-r--r--hw/xprint/config/C/print/models/PSspooldir/Makefile.am3
-rw-r--r--hw/xprint/config/C/print/models/PSspooldir/model-config71
-rwxr-xr-xhw/xprint/config/C/print/models/PSspooldir/spooltodir.sh127
-rw-r--r--hw/xprint/config/C/print/models/SPSPARC2/Makefile.am5
-rw-r--r--hw/xprint/config/C/print/models/SPSPARC2/fonts/Makefile.am37
-rw-r--r--hw/xprint/config/C/print/models/SPSPARC2/model-config18
-rw-r--r--hw/xprint/config/Makefile.am712
-rw-r--r--hw/xprint/config/README318
-rw-r--r--hw/xprint/config/en_US/Makefile.am1
-rw-r--r--hw/xprint/config/en_US/print/Makefile.am1
-rw-r--r--hw/xprint/config/en_US/print/attributes/Makefile.am3
-rw-r--r--hw/xprint/config/en_US/print/attributes/document13
-rw-r--r--hw/xprint/ddxInit.c379
-rw-r--r--hw/xprint/doc/Makefile.am19
-rw-r--r--hw/xprint/doc/Xprt.html115
-rw-r--r--hw/xprint/doc/Xprt.man.pre196
-rw-r--r--hw/xprint/doc/Xprt.sgml371
-rw-r--r--hw/xprint/etc/Makefile.am1
-rw-r--r--hw/xprint/etc/Xsession.d/Makefile.am1
-rw-r--r--hw/xprint/etc/Xsession.d/cde_xsessiond_xprint.sh30
-rw-r--r--hw/xprint/etc/init.d/Makefile.am1
-rw-r--r--hw/xprint/etc/init.d/xprint.cpp1277
-rw-r--r--hw/xprint/etc/profile.d/Makefile.am1
-rw-r--r--hw/xprint/etc/profile.d/xprint.csh16
-rw-r--r--hw/xprint/etc/profile.d/xprint.sh16
-rw-r--r--hw/xprint/mediaSizes.c783
-rw-r--r--hw/xprint/pcl-mono/Makefile.am5
-rw-r--r--hw/xprint/pcl/Makefile.am6
-rw-r--r--hw/xprint/pcl/Makefile.am.inc28
-rw-r--r--hw/xprint/pcl/Pcl.h625
-rw-r--r--hw/xprint/pcl/PclArc.c270
-rw-r--r--hw/xprint/pcl/PclArea.c437
-rw-r--r--hw/xprint/pcl/PclAttVal.c207
-rw-r--r--hw/xprint/pcl/PclAttr.c87
-rw-r--r--hw/xprint/pcl/PclColor.c851
-rw-r--r--hw/xprint/pcl/PclCursor.c115
-rw-r--r--hw/xprint/pcl/PclDef.h68
-rw-r--r--hw/xprint/pcl/PclFonts.c74
-rw-r--r--hw/xprint/pcl/PclGC.c969
-rw-r--r--hw/xprint/pcl/PclInit.c629
-rw-r--r--hw/xprint/pcl/PclLine.c316
-rw-r--r--hw/xprint/pcl/PclMisc.c306
-rw-r--r--hw/xprint/pcl/PclPixel.c159
-rw-r--r--hw/xprint/pcl/PclPolygon.c353
-rw-r--r--hw/xprint/pcl/PclPrint.c711
-rw-r--r--hw/xprint/pcl/PclSFonts.c429
-rw-r--r--hw/xprint/pcl/PclSFonts.h116
-rw-r--r--hw/xprint/pcl/PclSpans.c139
-rw-r--r--hw/xprint/pcl/PclText.c936
-rw-r--r--hw/xprint/pcl/PclWindow.c452
-rw-r--r--hw/xprint/pcl/Pclmap.h213
-rw-r--r--hw/xprint/ps/Makefile.am42
-rw-r--r--hw/xprint/ps/Ps.h602
-rw-r--r--hw/xprint/ps/PsArc.c182
-rw-r--r--hw/xprint/ps/PsArea.c391
-rw-r--r--hw/xprint/ps/PsAttVal.c290
-rw-r--r--hw/xprint/ps/PsAttr.c117
-rw-r--r--hw/xprint/ps/PsCache.c328
-rw-r--r--hw/xprint/ps/PsColor.c258
-rw-r--r--hw/xprint/ps/PsDef.h97
-rw-r--r--hw/xprint/ps/PsFTFonts.c85
-rw-r--r--hw/xprint/ps/PsFonts.c874
-rw-r--r--hw/xprint/ps/PsGC.c415
-rw-r--r--hw/xprint/ps/PsImageUtil.c330
-rw-r--r--hw/xprint/ps/PsInit.c665
-rw-r--r--hw/xprint/ps/PsLine.c192
-rw-r--r--hw/xprint/ps/PsMisc.c324
-rw-r--r--hw/xprint/ps/PsPixel.c157
-rw-r--r--hw/xprint/ps/PsPixmap.c620
-rw-r--r--hw/xprint/ps/PsPolygon.c260
-rw-r--r--hw/xprint/ps/PsPrint.c459
-rw-r--r--hw/xprint/ps/PsSpans.c166
-rw-r--r--hw/xprint/ps/PsText.c582
-rw-r--r--hw/xprint/ps/PsWindow.c460
-rw-r--r--hw/xprint/ps/psout.c1790
-rw-r--r--hw/xprint/ps/psout.h336
-rw-r--r--hw/xprint/ps/psout_ft.c335
-rw-r--r--hw/xprint/ps/psout_ftpstype1.c185
-rw-r--r--hw/xprint/ps/psout_ftpstype3.c439
-rw-r--r--hw/xprint/ps/ttf2pt1wrap.c14
-rw-r--r--hw/xprint/raster/Makefile.am11
-rw-r--r--hw/xprint/raster/Raster.c1573
-rw-r--r--hw/xprint/raster/Raster.h118
-rw-r--r--hw/xprint/raster/RasterAttVal.c269
-rw-r--r--hw/xprint/spooler.c204
-rw-r--r--hw/xprint/spooler.h76
257 files changed, 37201 insertions, 0 deletions
diff --git a/hw/xprint/AttrValid.c b/hw/xprint/AttrValid.c
new file mode 100644
index 000000000..cf9476003
--- /dev/null
+++ b/hw/xprint/AttrValid.c
@@ -0,0 +1,702 @@
+/* $Xorg: AttrValid.c,v 1.4 2001/03/14 18:43:17 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <scrnintstr.h>
+
+#include "attributes.h"
+
+/*
+ * default medium-source-sizes supported = na-letter w/.25" margins
+ */
+static XpOidMediumDiscreteSize DefaultMediumSize = {
+ xpoid_val_medium_size_na_letter, xFalse, {6.35, 209.55, 6.35, 273.05}
+};
+static XpOidMediumDiscreteSizeList DefaultMediumSizeList = {
+ &DefaultMediumSize, 1
+};
+static XpOidMediumSourceSize DefaultMediumSourceSize = {
+ xpoid_unspecified, XpOidMediumSS_DISCRETE, { &DefaultMediumSizeList }
+};
+static XpOidMediumSS DefaultMediumSS = {
+ &DefaultMediumSourceSize, 1
+};
+
+/*
+ * if 'valid_oid_list' is NULL any oid found is considered valid
+ */
+XpOid
+XpGetOidAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oid_list)
+{
+ XpOid value_oid;
+
+ value_oid = XpOidFromString(XpGetStringAttr(pContext, pool, oid));
+ if((const XpOidList*)NULL == valid_oid_list
+ ||
+ XpOidListHasOid(valid_oid_list, value_oid))
+ {
+ return value_oid;
+ }
+ else
+ {
+ return xpoid_none;
+ }
+}
+
+void
+XpPutOidAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ XpOid value_oid)
+{
+ XpPutStringAttr(pContext, pool, oid, XpOidString(value_oid));
+}
+
+void
+XpValidateOidAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oids,
+ XpOid default_oid)
+{
+ XpOid value_oid;
+ value_oid = XpGetOidAttr(pContext, pool, oid, valid_oids);
+ XpPutOidAttr(pContext, pool, oid,
+ value_oid == xpoid_none ? default_oid : value_oid);
+}
+
+/*
+ * if 'valid_card_list' is NULL any cardinal found is considered valid
+ */
+unsigned long
+XpGetCardAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_card_list)
+{
+ unsigned long value_card;
+
+ if(XpOidParseUnsignedValue(XpGetStringAttr(pContext, pool, oid),
+ (const char**)NULL,
+ &value_card))
+ {
+ if((const XpOidCardList*)NULL == valid_card_list
+ ||
+ XpOidCardListHasCard(valid_card_list, value_card))
+ {
+ return value_card;
+ }
+ }
+ return 0;
+}
+
+void
+XpPutCardAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ unsigned long value_card)
+{
+ if(value_card > 0)
+ {
+ char value_out[16];
+ sprintf(value_out, "%lu", value_card);
+ XpPutStringAttr(pContext, pool, oid, value_out);
+ }
+ else
+ XpPutStringAttr(pContext, pool, oid, (const char*)NULL);
+}
+
+void
+XpValidateCardAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_cards,
+ unsigned long default_card)
+{
+ unsigned long value_card;
+ value_card = XpGetCardAttr(pContext, pool, oid, valid_cards);
+ XpPutCardAttr(pContext, pool, oid,
+ value_card == 0 ? default_card : value_card);
+}
+
+XpOidList*
+XpGetListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oid_list)
+{
+ return XpOidListNew(XpGetStringAttr(pContext, pool, oid), valid_oid_list);
+}
+
+void
+XpPutListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* list)
+{
+ char* value_out;
+
+ value_out = XpOidListString(list);
+ XpPutStringAttr(pContext, pool, oid, value_out);
+ XpOidFree(value_out);
+}
+
+void
+XpValidateListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oids,
+ const XpOidList* default_oids)
+{
+ XpOidList* list = XpGetListAttr(pContext, pool, oid, valid_oids);
+ if(XpOidListCount(list) == 0)
+ XpPutListAttr(pContext, pool, oid, default_oids);
+ else
+ XpPutListAttr(pContext, pool, oid, list);
+ XpOidListDelete(list);
+}
+
+XpOidCardList*
+XpGetCardListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_card_list)
+{
+ return XpOidCardListNew(XpGetStringAttr(pContext, pool, oid),
+ valid_card_list);
+}
+
+void
+XpPutCardListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* list)
+{
+ char* value_out;
+
+ value_out = XpOidCardListString(list);
+ XpPutStringAttr(pContext, pool, oid, value_out);
+ XpOidFree(value_out);
+}
+
+void
+XpValidateCardListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_cards,
+ const XpOidCardList* default_cards)
+{
+ XpOidCardList* list = XpGetCardListAttr(pContext, pool, oid, valid_cards);
+ if(XpOidCardListCount(list) == 0 && (XpOidCardList*)NULL != default_cards)
+ XpPutCardListAttr(pContext, pool, oid, default_cards);
+ else
+ XpPutCardListAttr(pContext, pool, oid, list);
+ XpOidCardListDelete(list);
+}
+
+XpOidDocFmtList*
+XpGetDocFmtListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidDocFmtList* valid_fmt_list)
+{
+ return XpOidDocFmtListNew(XpGetStringAttr(pContext, pool, oid),
+ valid_fmt_list);
+}
+
+void
+XpPutDocFmtListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidDocFmtList* list)
+{
+ char* value_out;
+
+ value_out = XpOidDocFmtListString(list);
+ XpPutStringAttr(pContext, pool, oid, value_out);
+ XpOidFree(value_out);
+}
+
+void
+XpValidateDocFmtListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidDocFmtList* valid_fmts,
+ const XpOidDocFmtList* default_fmts)
+{
+ XpOidDocFmtList* list;
+
+ list = XpGetDocFmtListAttr(pContext, pool, oid, valid_fmts);
+ if(XpOidDocFmtListCount(list) == 0
+ &&
+ (XpOidDocFmtList*)NULL != default_fmts)
+ {
+ XpPutDocFmtListAttr(pContext, pool, oid, default_fmts);
+ }
+ else
+ {
+ XpPutDocFmtListAttr(pContext, pool, oid, list);
+ }
+ XpOidDocFmtListDelete(list);
+}
+
+XpOidMediumSS*
+XpGetMediumSSAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_sizes)
+{
+ return XpOidMediumSSNew(XpGetStringAttr(pContext, pool, oid),
+ valid_trays, valid_sizes);
+}
+
+void
+XpPutMediumSSAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidMediumSS* msss)
+{
+ char* value_out;
+
+ value_out = XpOidMediumSSString(msss);
+ XpPutStringAttr(pContext, pool, oid, value_out);
+ XpOidFree(value_out);
+}
+
+const XpOidMediumSS*
+XpGetDefaultMediumSS()
+{
+ return &DefaultMediumSS;
+}
+
+XpOidTrayMediumList*
+XpGetTrayMediumListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_trays,
+ const XpOidMediumSS* msss)
+{
+ return XpOidTrayMediumListNew(XpGetStringAttr(pContext, pool, oid),
+ valid_trays, msss);
+}
+
+void
+XpPutTrayMediumListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidTrayMediumList* tm)
+{
+ char* value_out;
+
+ value_out = XpOidTrayMediumListString(tm);
+ XpPutStringAttr(pContext, pool, oid, value_out);
+ XpOidFree(value_out);
+}
+
+void
+XpValidatePrinterMediaAttrs(XpContextPtr pContext,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_sizes)
+{
+ const XpOidMediumSS* msss;
+ XpOidMediumSS* pool_msss;
+ XpOidTrayMediumList* tm;
+
+ pool_msss = XpGetMediumSSAttr(pContext, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported,
+ valid_trays, valid_sizes);
+ if(0 == XpOidMediumSSCount(pool_msss))
+ msss = XpGetDefaultMediumSS();
+ else
+ msss = pool_msss;
+ XpPutMediumSSAttr(pContext, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported, msss);
+
+ tm = XpGetTrayMediumListAttr(pContext, XPPrinterAttr,
+ xpoid_att_input_trays_medium,
+ valid_trays, msss);
+ XpPutTrayMediumListAttr(pContext, XPPrinterAttr,
+ xpoid_att_input_trays_medium, tm);
+
+ XpOidMediumSSDelete(pool_msss);
+ XpOidTrayMediumListDelete(tm);
+}
+
+
+void
+XpValidatePrinterPool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr)
+{
+ /*
+ * content-orientations-supported
+ */
+ XpValidateListAttr(pContext, XPPrinterAttr,
+ xpoid_att_content_orientations_supported,
+ vpr->valid_content_orientations_supported,
+ vpr->default_content_orientations_supported);
+ /*
+ * document-formats-supported
+ */
+ XpValidateDocFmtListAttr(pContext, XPPrinterAttr,
+ xpoid_att_document_formats_supported,
+ vpr->valid_document_formats_supported,
+ vpr->default_document_formats_supported);
+ /*
+ * plexes-supported
+ */
+ XpValidateListAttr(pContext, XPPrinterAttr, xpoid_att_plexes_supported,
+ vpr->valid_plexes_supported,
+ vpr->default_plexes_supported);
+ /*
+ * printer-resolutions-supported
+ */
+ XpValidateCardListAttr(pContext, XPPrinterAttr,
+ xpoid_att_printer_resolutions_supported,
+ vpr->valid_printer_resolutions_supported,
+ vpr->default_printer_resolutions_supported);
+ /*
+ * xp-embedded-formats-supported
+ */
+ XpValidateDocFmtListAttr(pContext, XPPrinterAttr,
+ xpoid_att_xp_embedded_formats_supported,
+ vpr->valid_xp_embedded_formats_supported,
+ vpr->default_xp_embedded_formats_supported);
+ /*
+ * xp-listfonts-modes-supported
+ */
+ XpValidateListAttr(pContext, XPPrinterAttr,
+ xpoid_att_xp_listfonts_modes_supported,
+ vpr->valid_xp_listfonts_modes_supported,
+ vpr->default_xp_listfonts_modes_supported);
+ /*
+ * xp-raw-formats-supported
+ */
+ XpValidateDocFmtListAttr(pContext, XPPrinterAttr,
+ xpoid_att_xp_raw_formats_supported,
+ vpr->valid_xp_raw_formats_supported,
+ vpr->default_xp_raw_formats_supported);
+ /*
+ * xp-setup-proviso
+ */
+ XpValidateOidAttr(pContext, XPPrinterAttr, xpoid_att_xp_setup_proviso,
+ vpr->valid_xp_setup_proviso, xpoid_none);
+ /*
+ * medium-source-sizes-supported
+ * input-trays-mdeium
+ */
+ XpValidatePrinterMediaAttrs(pContext,
+ vpr->valid_input_trays,
+ vpr->valid_medium_sizes);
+ /*
+ * available-compressions-supported
+ */
+ XpValidateListAttr(pContext, XPPrinterAttr,
+ xpoid_att_available_compressions_supported,
+ vpr->valid_available_compressions_supported,
+ vpr->default_available_compressions_supported);
+}
+
+
+void
+XpValidateNotificationProfile(XpContextPtr pContext)
+{
+ const char* value_in;
+ const char* value_out;
+
+ value_in = XpGetStringAttr(pContext, XPJobAttr,
+ xpoid_att_notification_profile);
+ value_out = XpOidNotifyString(XpOidNotifyParse(value_in));
+ XpPutStringAttr(pContext, XPJobAttr,
+ xpoid_att_notification_profile, value_out);
+}
+
+void
+XpValidateJobPool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr)
+{
+ /*
+ * Note: the 'vpr' argument is unused in this
+ * implementation; it is reserved for future use
+ */
+ XpOidList* job_attrs_supported;
+ /*
+ * only validate attributes found in job-attributes-supported
+ */
+ job_attrs_supported = XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_job_attributes_supported,
+ (const XpOidList*)NULL);
+ /*
+ * notification-profile
+ */
+ if(XpOidListHasOid(job_attrs_supported, xpoid_att_notification_profile))
+ {
+ XpValidateNotificationProfile(pContext);
+ }
+ /*
+ * clean up
+ */
+ XpOidListDelete(job_attrs_supported);
+}
+
+
+static void
+XpValidateDocOrPagePool(XpContextPtr pContext,
+ XPAttributes pool, /* XPDocAttr or XPPageAttr */
+ const XpOidList* attrs_supported,
+ const XpValidatePoolsRec* vpr)
+{
+ /*
+ * content-orientation
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_content_orientation))
+ {
+ XpOidList* content_orientations_supported;
+ content_orientations_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_content_orientations_supported,
+ vpr->valid_content_orientations_supported);
+ XpValidateOidAttr(pContext, pool, xpoid_att_content_orientation,
+ content_orientations_supported, xpoid_none);
+ XpOidListDelete(content_orientations_supported);
+ }
+ /*
+ * copy-count
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_copy_count))
+ XpValidateCardAttr(pContext, pool, xpoid_att_copy_count,
+ (const XpOidCardList*)NULL, 0);
+ /*
+ * default-printer-resolution
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_default_printer_resolution))
+ {
+ XpOidCardList* printer_resolutions_supported;
+ printer_resolutions_supported =
+ XpGetCardListAttr(pContext, XPPrinterAttr,
+ xpoid_att_printer_resolutions_supported,
+ vpr->valid_printer_resolutions_supported);
+ XpValidateCardAttr(pContext, pool,
+ xpoid_att_default_printer_resolution,
+ printer_resolutions_supported, 0);
+ XpOidCardListDelete(printer_resolutions_supported);
+ }
+ /*
+ * default-input-tray
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_default_input_tray))
+ {
+ XpOidTrayMediumList* input_trays_medium;
+ const char* value_in;
+ XpOid value_tray;
+
+ input_trays_medium =
+ XpGetTrayMediumListAttr(pContext, XPPrinterAttr,
+ xpoid_att_input_trays_medium,
+ (const XpOidList*)NULL,
+ (const XpOidMediumSS*)NULL);
+ value_in =
+ XpGetStringAttr(pContext, pool, xpoid_att_default_input_tray);
+ value_tray = XpOidFromString(value_in);
+ if(!XpOidTrayMediumListHasTray(input_trays_medium, value_tray))
+ value_tray = xpoid_none;
+ XpPutOidAttr(pContext, pool, xpoid_att_default_input_tray, value_tray);
+ XpOidTrayMediumListDelete(input_trays_medium);
+ }
+ /*
+ * default-medium
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_default_medium))
+ {
+ XpOidMediumSS* msss;
+ const char* value_in;
+ XpOid value_size;
+
+ msss = XpGetMediumSSAttr(pContext, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported,
+ (const XpOidList*)NULL,
+ (const XpOidList*)NULL);
+ value_in = XpGetStringAttr(pContext, pool, xpoid_att_default_medium);
+ value_size = XpOidFromString(value_in);
+ if(!XpOidMediumSSHasSize(msss, value_size))
+ value_size = xpoid_none;
+ XpPutOidAttr(pContext, pool, xpoid_att_default_medium, value_size);
+ XpOidMediumSSDelete(msss);
+ }
+ /*
+ * document-format
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_document_format))
+ {
+ XpOidDocFmtList* document_formats_supported;
+ const char* value_in;
+ XpOidDocFmt* document_format;
+ const char* value_out;
+
+ document_formats_supported =
+ XpGetDocFmtListAttr(pContext, XPPrinterAttr,
+ xpoid_att_document_formats_supported,
+ vpr->valid_document_formats_supported);
+ value_in = XpGetStringAttr(pContext, pool, xpoid_att_document_format);
+ document_format = XpOidDocFmtNew(value_in);
+ if(XpOidDocFmtListHasFmt(document_formats_supported, document_format))
+ value_out = XpOidDocFmtString(document_format);
+ else
+ value_out = XpOidDocFmtString(vpr->default_document_format);
+ XpOidDocFmtListDelete(document_formats_supported);
+ XpOidDocFmtDelete(document_format);
+ XpPutStringAttr(pContext, pool, xpoid_att_document_format, value_out);
+ XpOidFree(value_out);
+ }
+ /*
+ * plex
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_plex))
+ {
+ XpOidList* plexes_supported;
+ plexes_supported =
+ XpGetListAttr(pContext, XPPrinterAttr, xpoid_att_plexes_supported,
+ vpr->valid_plexes_supported);
+ XpValidateOidAttr(pContext, pool, xpoid_att_plex,
+ plexes_supported, xpoid_none);
+ XpOidListDelete(plexes_supported);
+ }
+ /*
+ * xp-listfonts-modes
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_xp_listfonts_modes))
+ {
+ XpOidList* xp_listfonts_modes_supported;
+ xp_listfonts_modes_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_xp_listfonts_modes_supported,
+ vpr->valid_xp_listfonts_modes_supported);
+ XpValidateListAttr(pContext, pool, xpoid_att_xp_listfonts_modes,
+ xp_listfonts_modes_supported,
+ (const XpOidList*)NULL);
+ XpOidListDelete(xp_listfonts_modes_supported);
+ }
+ /*
+ * available-compressions
+ */
+ if(XpOidListHasOid(attrs_supported, xpoid_att_available_compression))
+ {
+ XpOidList* available_compressions_supported;
+ available_compressions_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_available_compressions_supported,
+ vpr->valid_available_compressions_supported);
+ XpValidateOidAttr(pContext, pool, xpoid_att_available_compression,
+ available_compressions_supported, xpoid_none);
+ XpOidListDelete(available_compressions_supported);
+ }
+}
+
+void
+XpValidateDocumentPool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr)
+{
+ XpOidList* document_attrs_supported;
+ /*
+ * only validate attributes found in document-attributes-supported
+ */
+ document_attrs_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_document_attributes_supported,
+ (const XpOidList*)NULL);
+ /*
+ * validate
+ */
+ XpValidateDocOrPagePool(pContext, XPDocAttr,
+ document_attrs_supported, vpr);
+ /*
+ * clean up
+ */
+ XpOidListDelete(document_attrs_supported);
+}
+
+void
+XpValidatePagePool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr)
+{
+ XpOidList* page_attrs_supported;
+ /*
+ * only validate attributes found in xp-page-attributes-supported
+ */
+ page_attrs_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_xp_page_attributes_supported,
+ (const XpOidList*)NULL);
+ /*
+ * validate
+ */
+ XpValidateDocOrPagePool(pContext, XPPageAttr,
+ page_attrs_supported, vpr);
+ /*
+ * clean up
+ */
+ XpOidListDelete(page_attrs_supported);
+}
+
+void
+XpValidateAttributePool(XpContextPtr pContext,
+ XPAttributes pool,
+ const XpValidatePoolsRec* vpr)
+{
+ switch(pool)
+ {
+ case XPPrinterAttr:
+ XpValidatePrinterPool(pContext, vpr);
+ break;
+
+ case XPDocAttr:
+ XpValidateDocumentPool(pContext, vpr);
+ break;
+
+ case XPJobAttr:
+ XpValidateJobPool(pContext, vpr);
+ break;
+
+ case XPPageAttr:
+ XpValidatePagePool(pContext, vpr);
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/hw/xprint/AttrValid.h b/hw/xprint/AttrValid.h
new file mode 100644
index 000000000..fab3a7f5e
--- /dev/null
+++ b/hw/xprint/AttrValid.h
@@ -0,0 +1,220 @@
+/* $Xorg: AttrValid.h,v 1.4 2001/03/14 18:43:40 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _Xp_AttrValid_h
+#define _Xp_AttrValid_h
+
+#include <X11/extensions/Printstr.h>
+#include "Oid.h"
+
+#define XpNumber(a) (sizeof(a) / sizeof(*(a)))
+
+/*
+ * Attribute pool validation valid values and defaults
+ */
+typedef struct
+{
+ XpOidList* valid_content_orientations_supported;
+ XpOidList* default_content_orientations_supported;
+
+ XpOidDocFmtList* valid_document_formats_supported;
+ XpOidDocFmtList* default_document_formats_supported;
+
+ XpOidList* valid_input_trays;
+ XpOidList* valid_medium_sizes;
+
+ XpOidList* valid_plexes_supported;
+ XpOidList* default_plexes_supported;
+
+ XpOidCardList* valid_printer_resolutions_supported;
+ XpOidCardList* default_printer_resolutions_supported;
+
+ XpOidDocFmtList* valid_xp_embedded_formats_supported;
+ XpOidDocFmtList* default_xp_embedded_formats_supported;
+
+ XpOidList* valid_xp_listfonts_modes_supported;
+ XpOidList* default_xp_listfonts_modes_supported;
+
+ XpOidDocFmtList* valid_xp_raw_formats_supported;
+ XpOidDocFmtList* default_xp_raw_formats_supported;
+
+ XpOidList* valid_xp_setup_proviso;
+
+ XpOidDocFmt* default_document_format;
+ XpOidList* valid_available_compressions_supported;
+ XpOidList* default_available_compressions_supported;
+
+} XpValidatePoolsRec;
+
+/*
+ * XpOid resource access
+ */
+#define XpGetStringAttr(pContext, pool, oid) \
+ (const char*)XpGetOneAttribute(pContext, pool, (char*)XpOidString(oid))
+#define XpPutStringAttr(pContext, pool, oid, value) \
+ XpPutOneAttribute(pContext, pool, XpOidString(oid), value)
+
+#ifdef _XP_PRINT_SERVER_ /* needed for XpContextPtr in Printstr.h */
+
+/*
+ * XpOid-valued attribute access
+ */
+XpOid XpGetOidAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oid_list);
+void XpPutOidAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ XpOid value_oid);
+void XpValidateOidAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oids,
+ XpOid default_oid);
+/*
+ * cardinal-valued attribute access
+ */
+unsigned long XpGetCardAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_card_list);
+void XpPutCardAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ unsigned long value_card);
+void XpValidateCardAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_cards,
+ unsigned long default_card);
+/*
+ * XpOidList-valued attribute access
+ */
+XpOidList* XpGetListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oid_list);
+void XpPutListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* list);
+void XpValidateListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_oids,
+ const XpOidList* default_oids);
+/*
+ * XpOidCardList-valued attribute access
+ */
+XpOidCardList* XpGetCardListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_card_list);
+void XpPutCardListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* list);
+void XpValidateCardListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidCardList* valid_cards,
+ const XpOidCardList* default_cards);
+/*
+ * XpOidDocFmtList-valued attribute access
+ */
+XpOidDocFmtList* XpGetDocFmtListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidDocFmtList* valid_fmt_list);
+void XpPutDocFmtListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidDocFmtList* list);
+void XpValidateDocFmtListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidDocFmtList* valid_fmts,
+ const XpOidDocFmtList* default_fmts);
+/*
+ * XpOidMediumSS-valued attribute access
+ */
+XpOidMediumSS* XpGetMediumSSAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_sizes);
+void XpPutMediumSSAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidMediumSS* msss);
+const XpOidMediumSS* XpGetDefaultMediumSS(void);
+
+/*
+ * XpOidTrayMediumList-valued attribute access
+ */
+XpOidTrayMediumList* XpGetTrayMediumListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidList* valid_trays,
+ const XpOidMediumSS* msss);
+void XpPutTrayMediumListAttr(XpContextPtr pContext,
+ XPAttributes pool,
+ XpOid oid,
+ const XpOidTrayMediumList* tm);
+void XpValidatePrinterMediaAttrs(XpContextPtr pContext,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_sizes);
+/*
+ * Attribute pool validation
+ */
+void XpValidateAttributePool(XpContextPtr pContext,
+ XPAttributes pool,
+ const XpValidatePoolsRec* vpr);
+void XpValidatePrinterPool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr);
+void XpValidateNotificationProfile(XpContextPtr pContext);
+void XpValidateJobPool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr);
+void XpValidateDocumentPool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr);
+void XpValidatePagePool(XpContextPtr pContext,
+ const XpValidatePoolsRec* vpr);
+
+#endif /* _XP_PRINT_SERVER_ */
+
+#endif /* _Xp_AttrValid_h - don't add anything after this line */
diff --git a/hw/xprint/DiPrint.h b/hw/xprint/DiPrint.h
new file mode 100644
index 000000000..a26477971
--- /dev/null
+++ b/hw/xprint/DiPrint.h
@@ -0,0 +1,81 @@
+/* $Xorg: DiPrint.h,v 1.3 2000/08/17 19:48:04 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/*
+ * The XpDiListEntry struct is the type of each element of the array
+ * handed back to the extension code to handle a GetPrinterList request.
+ * We don't use the printerDb directly because of the desire to handle
+ * multiple locales. Creating this new array for each GetPrinterList
+ * request will allow us to build it with the description in the locale of
+ * the requesting client.
+ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _XpDiPrint_H_
+#define _XpDiPrint_H_ 1
+
+#include "scrnintstr.h"
+
+typedef struct _diListEntry {
+ char *name;
+ char *description;
+ char *localeName;
+ unsigned long rootWinId;
+} XpDiListEntry;
+
+extern void XpDiFreePrinterList(XpDiListEntry **list);
+
+extern XpDiListEntry **XpDiGetPrinterList(
+ int nameLen,
+ char *name,
+ int localeLen,
+ char *locale);
+
+extern char * XpDiGetDriverName(int index, char *printerName);
+
+extern WindowPtr XpDiValidatePrinter(char *printerName, int printerNameLen);
+
+extern int PrinterOptions(int argc, char **argv, int i);
+
+extern void PrinterUseMsg(void);
+
+extern void PrinterInitGlobals(void);
+
+extern void PrinterInitOutput(ScreenInfo *pScreenInfo, int argc, char **argv);
+
+extern void _XpVoidNoop(void);
+
+extern Bool _XpBoolNoop(void);
+
+#endif /* _XpDiPrint_H_ */
diff --git a/hw/xprint/Init.c b/hw/xprint/Init.c
new file mode 100644
index 000000000..0f1be6791
--- /dev/null
+++ b/hw/xprint/Init.c
@@ -0,0 +1,1921 @@
+/* $Xorg: Init.c,v 1.5 2001/03/07 17:31:33 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996-2004 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+(c) Copyright 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: printer/Init.c
+** *
+** * Contents:
+** * The InitOutput routine here would presumably
+** * be called from the normal server's InitOutput
+** * after all display screens have been added.
+** * There is are ifdef'd routines suitable for
+** * use in building a printer-only server. Turn
+** * on the "PRINTER_ONLY_SERVER" define if this is
+** * to be the only ddx-level driver.
+** *
+** * Copyright: Copyright 1993,1995 Hewlett-Packard Company
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <locale.h>
+#ifdef __hpux
+#include <sys/sysmacros.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS 1
+#include <X11/Xproto.h>
+#include <servermd.h>
+
+#include "screenint.h"
+#include "input.h"
+#include "cursor.h"
+#include "misc.h"
+#include "windowstr.h"
+#include "inputstr.h"
+
+#include "gcstruct.h"
+#include <X11/fonts/fontstruct.h>
+#include "errno.h"
+
+typedef char *XPointer;
+#define HAVE_XPointer 1
+
+#define Status int
+#include <X11/Xresource.h>
+
+#include "DiPrint.h"
+#include "attributes.h"
+
+#include "os.h"
+#include "spooler.h"
+
+static void GenericScreenInit(
+ int index,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv);
+static Bool InitPrintDrivers(
+ int index,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv);
+
+/*
+ * The following two defines are used to build the name "X*printers", where
+ * the "*" is replaced by the display number. This is used to construct
+ * the name of the default printers configuration file if the -XpFile
+ * command line option was not specified.
+ */
+#define XNPRINTERSFILEPREFIX "/X"
+#define XNPRINTERSFILESUFFIX "printers"
+#define XPRINTERSFILENAME "Xprinters"
+
+#define MODELDIRNAME "/models"
+#define FONTDIRNAME "/fonts"
+
+#ifdef XPRASTERDDX
+
+static
+PixmapFormatRec RasterPixmapFormats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD }
+};
+#define NUMRASTFORMATS (sizeof RasterPixmapFormats)/(sizeof RasterPixmapFormats[0])
+
+#include "raster/Raster.h"
+
+#endif
+
+#ifdef XPPCLDDX
+
+static
+PixmapFormatRec ColorPclPixmapFormats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD }
+};
+
+#define NUMCPCLFORMATS (sizeof ColorPclPixmapFormats)/(sizeof ColorPclPixmapFormats[0])
+
+#endif
+
+#ifdef XPMONOPCLDDX
+
+static
+PixmapFormatRec MonoPclPixmapFormats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD }
+};
+
+#define NUMMPCLFORMATS (sizeof MonoPclPixmapFormats)/(sizeof MonoPclPixmapFormats[0])
+
+#endif
+
+#if defined(XPPCLDDX) || defined(XPMONOPCLDDX)
+#include "pcl/Pcl.h"
+#endif
+
+#ifdef XPPSDDX
+
+static
+PixmapFormatRec PSPixmapFormats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 12, 16, BITMAP_SCANLINE_PAD },
+ { 14, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD }
+};
+
+#define NUMPSFORMATS (sizeof PSPixmapFormats)/(sizeof PSPixmapFormats[0])
+
+#include "ps/Ps.h"
+
+#endif
+
+/*
+ * The driverInitArray contains an entry for each driver the
+ * server knows about. Each element contains pointers to pixmap formats, the
+ * driver's initialization routine, and pointers to the driver's
+ * attribute validation rec, and/or a driver function which
+ * returns the maximum medium width&height, and maximum resolution
+ * given a printer name. Either the validation rec OR the dimension
+ * function can be NULL. If the function is non-NULL then it
+ * will be called, and will be passed the (possibly NULL) validation rec.
+ * If the function is NULL, then XpGetMaxWidthHeightRes() is called.
+ */
+typedef struct _driverInitRec {
+ char *driverName;
+ pBFunc initFunc;
+ XpValidatePoolsRec *pValRec;
+ pVFunc dimensionsFunc;
+ PixmapFormatRec *pFmts;
+ int numFmts;
+} driverInitRec;
+
+static driverInitRec driverInits[] = {
+#ifdef XPRASTERDDX
+ {
+ "XP-RASTER",
+ InitializeRasterDriver,
+ &RasterValidatePoolsRec,
+ (pVFunc) NULL,
+ RasterPixmapFormats,
+ NUMRASTFORMATS
+ },
+#endif
+#ifdef XPPCLDDX
+ {
+ "XP-PCL-COLOR",
+ InitializeColorPclDriver,
+ &PclValidatePoolsRec,
+ (pVFunc) NULL,
+ ColorPclPixmapFormats,
+ NUMCPCLFORMATS
+ },
+#endif
+#ifdef XPMONOPCLDDX
+ {
+ "XP-PCL-MONO",
+ InitializeMonoPclDriver,
+ &PclValidatePoolsRec,
+ (pVFunc) NULL,
+ MonoPclPixmapFormats,
+ NUMMPCLFORMATS
+ },
+#endif
+#ifdef XPPSDDX
+ {
+ "XP-POSTSCRIPT",
+ InitializePsDriver,
+ &PsValidatePoolsRec,
+ (pVFunc) NULL,
+ PSPixmapFormats,
+ NUMPSFORMATS
+ },
+#endif
+};
+
+
+/*
+ * The printerDb variable points to a list of PrinterDbEntry structs
+ * which map printer names with screen numbers and driver names.
+ */
+typedef struct _printerDbEntry {
+ struct _printerDbEntry *next;
+ char *name;
+ char *qualifier;
+ int screenNum;
+ char *driverName;
+ char *desc;
+} PrinterDbEntry, *PrinterDbPtr;
+
+static PrinterDbPtr printerDb = (PrinterDbPtr)NULL;
+
+/*
+ * The nameMap is a list used in initializing the attribute store
+ * for each printer. The list is freed once the printerDb is built
+ * and the attribute stores for all printers have been initialized.
+ */
+typedef struct _nameMapEntry {
+ struct _nameMapEntry *next;
+ char *name;
+ char *qualifier;
+} NameMapEntry, *NameMapPtr;
+
+static NameMapPtr nameMap = (NameMapPtr)NULL;
+
+/*
+ * The driverMap is a list which provides the mapping between driver names
+ * and screen numbers. It is built and used
+ * by RehashPrinterList to correctly fill in the screenNum field in the
+ * printerDb entries. The list is freed before RehashPrinterList terminates.
+ */
+typedef struct _driverMapping {
+ struct _driverMapping *next;
+ char *driverName;
+ int screenNum;
+} DriverMapEntry, *DriverMapPtr;
+
+static const char configFilePath[] =
+"/etc/dt/config/print:/usr/dt/config/print";
+
+static const char printServerConfigDir[] = "XPSERVERCONFIGDIR";
+
+static char *configFileName = (char *)NULL;
+static Bool freeDefaultFontPath = FALSE;
+static char *origFontPath = (char *)NULL;
+
+static Bool xprintInitGlobalsCalled = FALSE;
+/*
+ * This function is responsible for doing initalisation of any global
+ * variables at an very early point of server startup (even before
+ * |ProcessCommandLine()|.
+ */
+void PrinterInitGlobals(void)
+{
+ xprintInitGlobalsCalled = TRUE;
+
+#ifdef DAMAGE
+ /* Disable DAMAGE extension for now as it does not work with
+ * the Postscript DDX yet (see
+ * https://bugs.freedesktop.org/show_bug.cgi?id=1660) ...
+ * (you can enable the DAMAGE extension explicitly via
+ * % X +extension DAMAGE ... #) ;-( */
+ noDamageExtension = TRUE;
+#endif /* DAMAGE */
+
+#ifdef SMART_SCHEDULE
+ /* Somehow the XF86 "smart scheduler" completely kills the Xprint DDX
+ * (see http://xprint.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=467
+ * ("Xfree86's "smart scheduler" breaks Xprt") */
+ SmartScheduleDisable = TRUE;
+#endif /* SMART_SCHEDULE */
+
+ /* Disable internal screensaver for Xprint (workaround for
+ * http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=567 ("Xorg
+ * Xprt starts to consume 100% CPU when being idle for some time")) */
+ defaultScreenSaverTime = 0;
+
+ /* Ensure that the maximum request size for the BIGREQUESTS extension
+ * is at least 8MB (see
+ * http://xprint.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=622 - "RFE:
+ * Xprt's default BIGREQUESTS extension buffer size should be 8MB")
+ */
+ maxBigRequestSize = (8*1048576)-1;
+
+ /* Xprt should not reset by default when the last client exists
+ * (default for Xprt is |0|, video Xservers use |DE_RESET|) */
+ dispatchExceptionAtReset = 0;
+}
+
+/*
+ * PrinterUseMsg() prints usage for the Xprint-specific options
+ */
+void PrinterUseMsg(void)
+{
+ XpSpoolerTypePtr curr = xpstm;
+
+ /* Option '-XpFile' */
+ ErrorF("-XpFile file specifies an alternate `Xprinters' file, rather\n");
+ ErrorF(" than the default one (e.g.\n");
+ ErrorF(" `${XPCONFIGDIR}/${LANG}/print/Xprinters') or\n");
+ ErrorF(" `${XPCONFIGDIR}/C/print/Xprinters'.\n");
+
+ /* Option '-XpSpoolerType' */
+ ErrorF("-XpSpoolerType string specifies a spooler type.\n");
+ ErrorF(" Supported values are:\n");
+
+ while( curr->name != NULL )
+ {
+ ErrorF(" - '%s'\n", curr->name);
+ curr++;
+ }
+ ErrorF(" (multiple values can be specified, seperated by ':',\n");
+ ErrorF(" the first active spooler will be chosen).\n");
+ ErrorF(" default is '%s'.\n", XPDEFAULTSPOOLERNAMELIST);
+}
+
+/*
+ * PrinterOptions checks argv[i] to see if it is our command line
+ * option specifying a configuration file name. It returns the index
+ * of the next option to process.
+ */
+int
+PrinterOptions(
+ int argc,
+ char **argv,
+ int i)
+{
+ if(strcmp(argv[i], "-XpFile") == 0)
+ {
+ if ((i + 1) >= argc) {
+ ddxUseMsg ();
+ return i + 2;
+ }
+ configFileName = argv[i + 1];
+ return i + 2;
+ }
+ else if(strcmp(argv[i], "-XpSpoolerType") == 0)
+ {
+ if ((i + 1) >= argc) {
+ ddxUseMsg ();
+ return i + 2;
+ }
+ XpSetSpoolerTypeNameList(argv[i + 1]);
+ return i + 2;
+ }
+ else
+ {
+ return i;
+ }
+}
+
+/************************************************************
+ * GetInitFunc --
+ *
+ * This routine is called from the InitPrintDrivers function.
+ * Given the name of a driver, return a pointer to the driver's
+ * initialization function.
+ *
+ * Results:
+ * Returns a pointer to the initialization function for the driver.
+ *
+ *
+ ************************************************************/
+
+/*
+typedef Bool (*pIFunc)();
+static pIFunc
+GetInitFunc(driverName)
+*/
+
+static pBFunc GetInitFunc(char *driverName)
+{
+ driverInitRec *pInitRec;
+ int numDrivers = sizeof(driverInits)/sizeof(driverInitRec);
+ int i;
+
+ for(pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++)
+ {
+ if( !strcmp( driverName, pInitRec->driverName ) )
+ return pInitRec->initFunc;
+ }
+
+ return 0;
+}
+
+static void
+GetDimFuncAndRec(
+ char *driverName,
+ XpValidatePoolsRec **pValRec,
+ pVFunc *dimensionsFunc)
+{
+ driverInitRec *pInitRec;
+ int numDrivers = sizeof(driverInits)/sizeof(driverInitRec);
+ int i;
+
+ for(pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++)
+ {
+ if( !strcmp( driverName, pInitRec->driverName ) )
+ {
+ *dimensionsFunc = pInitRec->dimensionsFunc;
+ *pValRec = pInitRec->pValRec;
+ return ;
+ }
+ }
+
+ *dimensionsFunc = 0;
+ *pValRec = 0;
+ return;
+}
+
+static void
+FreePrinterDb(void)
+{
+ PrinterDbPtr pCurEntry, pNextEntry;
+
+ for(pCurEntry = printerDb, pNextEntry = (PrinterDbPtr)NULL;
+ pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pNextEntry)
+ {
+ pNextEntry = pCurEntry->next;
+ if(pCurEntry->name != (char *)NULL)
+ xfree(pCurEntry->name);
+ if(pCurEntry->desc != (char *)NULL)
+ xfree(pCurEntry->desc);
+ /*
+ * We don't free the driver name, because it's expected to simply
+ * be a pointer into the xrm database.
+ */
+ xfree(pCurEntry);
+ }
+ printerDb = (PrinterDbPtr)NULL;
+}
+
+/*
+ * AddPrinterDbName allocates an entry in the printerDb list, and
+ * initializes the "name". It returns TRUE if the element was
+ * successfully added, and FALSE if an allocation error ocurred.
+ * XXX AddPrinterDbName needs to check for (and not add) duplicate names.
+ */
+static Bool
+AddPrinterDbName(char *name, char *desc)
+{
+ PrinterDbPtr pEntry = (PrinterDbPtr)xalloc(sizeof(PrinterDbEntry));
+
+ if(pEntry == (PrinterDbPtr)NULL) return FALSE;
+ pEntry->name = (name != NULL) ? strdup(name) : NULL;
+ pEntry->desc = (desc != NULL) ? strdup(desc) : NULL;
+ pEntry->qualifier = (char *)NULL;
+
+ if(printerDb == (PrinterDbPtr)NULL)
+ {
+ pEntry->next = (PrinterDbPtr)NULL;
+ printerDb = pEntry;
+ }
+ else
+ {
+ pEntry->next = printerDb;
+ printerDb = pEntry;
+ }
+ return TRUE;
+}
+
+static int
+AugmentPrinterDb(const char *command)
+{
+ FILE *fp;
+ char name[256];
+ int num_printers = 0; /* Number of printers we found */
+ size_t namelen;
+ char *desc = NULL;
+
+ fp = popen(command, "r");
+ /* XXX is a 256 character limit overly restrictive for printer names? */
+ while(fgets(name, 256, fp) != (char *)NULL && (namelen=strlen(name)))
+ {
+ char *option = name;
+
+ name[namelen-1] = (char)'\0'; /* strip the \n */
+
+#define XP_DESCRIPTOR "xp-printerattr.descriptor="
+#define XP_DESCRIPTOR_LEN (sizeof(XP_DESCRIPTOR)-1)
+ while ((option = strchr(option, '\t'))) {
+ option++; /* Skip the '\t' */
+ if (!strncmp(option, XP_DESCRIPTOR, XP_DESCRIPTOR_LEN)) {
+ *(option-1) = '\0'; /* Kill the '\t' (only if we found a valid option) */
+ option += XP_DESCRIPTOR_LEN;
+ if (*option != '\0') {
+ desc = option;
+ }
+ }
+ else
+ {
+ /* Unknown option */
+ ErrorF("AugmentPrinterDb: Unknown option '%s'\n", option);
+ }
+ }
+ AddPrinterDbName(name, desc);
+ num_printers++;
+ }
+ pclose(fp);
+ return num_printers;
+}
+
+/*
+ * FreeNameMap frees all remaining memory associated with the nameMap.
+ */
+static void
+FreeNameMap(void)
+{
+ NameMapPtr pEntry, pTmp;
+
+ for(pEntry = nameMap, pTmp = (NameMapPtr)NULL;
+ pEntry != (NameMapPtr)NULL;
+ pEntry = pTmp)
+ {
+ if(pEntry->name != (char *)NULL)
+ xfree(pEntry->name);
+ if(pEntry->qualifier != (char *)NULL)
+ xfree(pEntry->qualifier);
+ pTmp = pEntry->next;
+ xfree(pEntry);
+ }
+ nameMap = (NameMapPtr)NULL;
+}
+
+/*
+ * AddNameMap adds an element to the nameMap linked list.
+ */
+static Bool
+AddNameMap(char *name, char *qualifier)
+{
+ NameMapPtr pEntry;
+
+ if((pEntry = (NameMapPtr)xalloc(sizeof(NameMapEntry))) == (NameMapPtr)NULL)
+ return FALSE;
+ pEntry->name = name;
+ pEntry->qualifier = qualifier;
+ pEntry->next = nameMap;
+ nameMap = pEntry;
+ return TRUE;
+}
+
+/*
+ * MergeNameMap - puts the "map" names (aka qualifiers, aliases) into
+ * the printerDb. This should be called once, after both the printerDb
+ * and nameMap lists are complete. When/if MergeNameMap finds a map for
+ * an entry in the printerDb, the qualifier is _moved_ (not copied) to
+ * the printerDb. This means that the qualifier pointer in the nameMap
+ * is NULLed out.
+ */
+static void
+MergeNameMap(void)
+{
+ NameMapPtr pMap;
+ PrinterDbPtr pDb;
+
+ for(pMap = nameMap; pMap != (NameMapPtr)NULL; pMap = pMap->next)
+ {
+ for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
+ {
+ if(!strcmp(pMap->name, pDb->name))
+ {
+ pDb->qualifier = pMap->qualifier;
+ pMap->qualifier = (char *)NULL;
+ }
+ }
+ }
+}
+
+/*
+ * CreatePrinterAttrs causes the attribute stores to be built for
+ * each printer in the printerDb.
+ */
+static void
+CreatePrinterAttrs(void)
+{
+ PrinterDbPtr pDb;
+
+ for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
+ {
+ XpBuildAttributeStore(pDb->name, (pDb->qualifier)?
+ pDb->qualifier : pDb->name);
+ }
+}
+
+#ifdef XPPSDDX
+#define defaultDriver "XP-POSTSCRIPT"
+#else
+#ifdef XPPCLDDX
+#define defaultDriver "XP-PCL-COLOR"
+#else
+#ifdef XPMONOPCLDDX
+#define defaultDriver "XP-PCL-MONO"
+#else
+#define defaultDriver "XP-RASTER"
+#endif
+#endif
+#endif
+
+/*
+ * StoreDriverNames - queries the attribute store for the ddx-identifier.
+ * if the ddx-identifier is not in the attribute database, then a default
+ * ddx-identifier is store in both the attribute store for the printer,
+ * and in the printerDb.
+ * The ddx-identifier is stored in the printerDb for use in initializing
+ * the screens.
+ */
+static void
+StoreDriverNames(void)
+{
+ PrinterDbPtr pEntry;
+
+ for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL;
+ pEntry = pEntry->next)
+ {
+ pEntry->driverName = (char*)XpGetPrinterAttribute(pEntry->name,
+ "xp-ddx-identifier");
+ if(pEntry->driverName == (char *)NULL ||
+ strlen(pEntry->driverName) == 0 ||
+ GetInitFunc(pEntry->driverName) == (Bool(*)())NULL)
+ {
+ if (pEntry->driverName && (strlen(pEntry->driverName) != 0)) {
+ ErrorF("Xp Extension: Can't load driver %s\n",
+ pEntry->driverName);
+ ErrorF(" init function missing\n");
+ }
+
+ pEntry->driverName = defaultDriver;
+ XpAddPrinterAttribute(pEntry->name,
+ (pEntry->qualifier != (char *)NULL)?
+ pEntry->qualifier : pEntry->name,
+ "*xp-ddx-identifier", pEntry->driverName);
+ }
+ }
+}
+
+/*
+ * StoreDescriptors - queries the attribute store for the descriptor.
+ * if the descriptor is not in the attribute database, then the descriptor
+ * from the printerDb is store in the attribute store for the printer.
+ */
+static void
+StoreDescriptors(void)
+{
+ PrinterDbPtr pEntry;
+
+ for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL;
+ pEntry = pEntry->next)
+ {
+ if (pEntry->desc != NULL)
+ {
+ XpAddPrinterAttribute(pEntry->name,
+ (pEntry->qualifier != (char *)NULL)?
+ pEntry->qualifier : pEntry->name,
+ "*descriptor", pEntry->desc);
+ }
+ }
+}
+
+static char *
+MbStrchr(
+ char *str,
+ int ch)
+{
+ size_t mbCurMax = MB_CUR_MAX;
+ wchar_t targetChar, curChar;
+ char tmpChar;
+ int i, numBytes, byteLen;
+
+ if(mbCurMax <= 1) return strchr(str, ch);
+
+ tmpChar = (char)ch;
+ mbtowc(&targetChar, &tmpChar, mbCurMax);
+ for(i = 0, numBytes = 0, byteLen = strlen(str); i < byteLen; i += numBytes)
+ {
+ numBytes = mbtowc(&curChar, &str[i], mbCurMax);
+ if(curChar == targetChar) return &str[i];
+ }
+ return (char *)NULL;
+}
+
+/*
+ * GetConfigFileName - Looks for a "Xprinters" file in
+ * $(XPRINTDIR)/$LANG/print, and then in $(XPRINTDIR)/C/print. If it
+ * finds such a file, it returns the path to the file. The returned
+ * string must be freed by the caller.
+ */
+static char *
+GetConfigFileName(void)
+{
+ /*
+ * We need to find the system-wide file, if one exists. This
+ * file can be in either $(XPRINTDIR)/$LANG/print, or in
+ * $(PRINTDIR)/C/print, and the file itself is named "Xprinters".
+ */
+ char *dirName, *filePath;
+
+ /*
+ * Check for a LANG-specific file.
+ */
+ if((dirName = XpGetConfigDir(TRUE)))
+ {
+ filePath = (char *)xalloc(strlen(dirName) +
+ strlen(XPRINTERSFILENAME) + 2);
+
+ if(filePath == (char *)NULL)
+ {
+ xfree(dirName);
+ return (char *)NULL;
+ }
+
+ sprintf(filePath, "%s/%s", dirName, XPRINTERSFILENAME);
+ xfree(dirName);
+ if(access(filePath, R_OK) == 0)
+ return filePath;
+
+ xfree(filePath);
+ }
+
+ if((dirName = XpGetConfigDir(FALSE)))
+ {
+ filePath = (char *)xalloc(strlen(dirName) +
+ strlen(XPRINTERSFILENAME) + 2);
+ if(filePath == (char *)NULL)
+ {
+ xfree(dirName);
+ return (char *)NULL;
+ }
+ sprintf(filePath, "%s/%s", dirName, XPRINTERSFILENAME);
+ xfree(dirName);
+ if(access(filePath, R_OK) == 0)
+ return filePath;
+ xfree(filePath);
+ }
+ return (char *)NULL;
+}
+
+/*
+ * BuildPrinterDb - reads the config file if it exists, and if necessary
+ * executes a command such as lpstat to generate a list of printers.
+ * XXX
+ * XXX BuildPrinterDb must be rewritten to allow 16-bit characters in
+ * XXX printer names. The will involve replacing the use of strtok() and its
+ * XXX related functions.
+ * XXX At the same time, BuildPrinterDb and it's support routines should have
+ * XXX allocation error checking added.
+ * XXX
+ */
+static PrinterDbPtr
+BuildPrinterDb(void)
+{
+ Bool defaultAugment = TRUE, freeConfigFileName;
+
+ if(configFileName && access(configFileName, R_OK) != 0)
+ {
+ ErrorF("Xp Extension: Can't open file %s\n", configFileName);
+ }
+ if(!configFileName && (configFileName = GetConfigFileName()))
+ freeConfigFileName = TRUE;
+ else
+ freeConfigFileName = FALSE;
+
+ if(configFileName != (char *)NULL && access(configFileName, R_OK) == 0)
+ {
+ char line[256];
+ FILE *fp = fopen(configFileName, "r");
+
+ while(fgets(line, 256, fp) != (char *)NULL)
+ {
+ char *tok, *ptr;
+ if((tok = strtok(line, " \t\012")) != (char *)NULL)
+ {
+ if(tok[0] == (char)'#') continue;
+ if(strcmp(tok, "Printer") == 0)
+ {
+ while((tok = strtok((char *)NULL, " \t")) != (char *)NULL)
+ {
+ if((ptr = MbStrchr(tok, '\012')))
+ *ptr = (char)'\0';
+ AddPrinterDbName(tok, NULL);
+ }
+ }
+ else if(strcmp(tok, "Map") == 0)
+ {
+ char *name, *qualifier;
+
+ if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL)
+ continue;
+ name = strdup(tok);
+ if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL)
+ {
+ xfree(name);
+ continue;
+ }
+ qualifier = strdup(tok);
+ AddNameMap(name, qualifier);
+ }
+ else if(strcmp(tok, "Augment_Printer_List") == 0)
+ {
+ if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL)
+ continue;
+
+ if(strcmp(tok, "%default%") == 0)
+ continue;
+ defaultAugment = FALSE;
+ if(strcmp(tok, "%none%") == 0)
+ continue;
+ AugmentPrinterDb(tok);
+ }
+ else
+ break; /* XXX Generate an error? */
+ }
+ }
+ fclose(fp);
+ }
+
+ if(defaultAugment == TRUE)
+ {
+ XpSpoolerTypePtr curr_spooler_type; /* spooler we are currently probing for queues */
+ int num_printers_found; /* number of printers found by |AugmentPrinterDb()| */
+ char *tok_lasts; /* strtok_r() position token */
+ char *spnamelist; /* list of spooler names, seperated by ":" */
+ char *spname; /* spooler name */
+
+ spnamelist = strdup(XpGetSpoolerTypeNameList()); /* strtok_r() modifies string so dup' it first */
+
+ for( spname = strtok_r(spnamelist, ":", &tok_lasts) ;
+ spname != NULL ;
+ spname = strtok_r(NULL, ":", &tok_lasts) )
+ {
+ curr_spooler_type = XpSpoolerNameToXpSpoolerType(spname);
+ if(!curr_spooler_type)
+ {
+ FatalError("BuildPrinterDb: No spooler type entry found for '%s'.\n", spname);
+ }
+
+ if(curr_spooler_type->list_queues_command == NULL ||
+ strlen(curr_spooler_type->list_queues_command) == 0)
+ {
+ continue;
+ }
+
+ num_printers_found = AugmentPrinterDb(curr_spooler_type->list_queues_command);
+ /* Did we found a spooler which works ? */
+ if(num_printers_found > 0)
+ {
+ spooler_type = curr_spooler_type;
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "BuildPrinterDb: using '%s'.\n", spooler_type->name);
+#endif /* DEBUG_gisburn */
+ break;
+ }
+ }
+
+ free(spnamelist);
+ }
+
+ MergeNameMap();
+ FreeNameMap();
+
+ /* Create the attribute stores for all printers */
+ CreatePrinterAttrs();
+
+ /*
+ * Find the drivers for each printers, and store the driver names
+ * in the printerDb
+ */
+ StoreDriverNames();
+ StoreDescriptors();
+
+ if(freeConfigFileName)
+ {
+ xfree(configFileName);
+ configFileName = (char *)NULL;
+ }
+
+ return printerDb;
+}
+
+static void
+FreeDriverMap(DriverMapPtr driverMap)
+{
+ DriverMapPtr pCurEntry, pNextEntry;
+
+ for(pCurEntry = driverMap, pNextEntry = (DriverMapPtr)NULL;
+ pCurEntry != (DriverMapPtr)NULL; pCurEntry = pNextEntry)
+ {
+ pNextEntry = pCurEntry->next;
+ if(pCurEntry->driverName != (char *)NULL)
+ xfree(pCurEntry->driverName);
+ xfree(pCurEntry);
+ }
+}
+
+/*
+ * XpRehashPrinterList rebuilds the list of printers known to the
+ * server. It first walks the printerDb to build a table mapping
+ * driver names and screen numbers, since this is not an easy mapping
+ * to change in the sample server. The normal configuration files are
+ * then read & parsed to create the new list of printers. Printers
+ * which require drivers other than those already initialized are
+ * deleted from the printerDb. This leaves attribute stores in place
+ * for inaccessible printers, but those stores will be cleaned up in
+ * the next rehash or server recycle.
+ */
+int
+XpRehashPrinterList(void)
+{
+ PrinterDbPtr pEntry, pPrev;
+ DriverMapPtr driverMap = (DriverMapPtr)NULL, pDrvEnt;
+ int result;
+
+ /* Build driverMap */
+ for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL; pEntry = pEntry->next)
+ {
+ for(pDrvEnt = driverMap; pDrvEnt != (DriverMapPtr)NULL;
+ pDrvEnt = pDrvEnt->next)
+ {
+ if(!strcmp(pEntry->driverName, pDrvEnt->driverName))
+ break;
+ }
+
+ if(pDrvEnt != (DriverMapPtr)NULL)
+ continue;
+
+ if((pDrvEnt = (DriverMapPtr)xalloc(sizeof(DriverMapEntry))) ==
+ (DriverMapPtr)NULL)
+ {
+ FreeDriverMap(driverMap);
+ return BadAlloc;
+ }
+ pDrvEnt->driverName = strdup(pEntry->driverName);
+ pDrvEnt->screenNum = pEntry->screenNum;
+ pDrvEnt->next = driverMap;
+ driverMap = pDrvEnt;
+ }
+
+ /* Free the old printerDb */
+ FreePrinterDb();
+
+ /* Free/Rehash attribute stores */
+ if((result = XpRehashAttributes()) != Success)
+ return result;
+
+ /* Build a new printerDb */
+ if(BuildPrinterDb() == (PrinterDbPtr)NULL)
+ return BadAlloc;
+
+ /* Walk PrinterDb & either store screenNum, or delete printerDb entry */
+ for(pEntry = printerDb, pPrev = (PrinterDbPtr)NULL;
+ pEntry != (PrinterDbPtr)NULL; pEntry = pEntry->next)
+ {
+ for(pDrvEnt = driverMap; pDrvEnt != (DriverMapPtr)NULL;
+ pDrvEnt = pDrvEnt->next)
+ {
+ if(!strcmp(printerDb->driverName, pDrvEnt->driverName))
+ break;
+ }
+
+ /*
+ * Either store the screen number, or delete the printerDb entry.
+ * Deleting the entry leaves orphaned attribute stores, but they'll
+ * get cleaned up at the next rehash or server recycle.
+ */
+ if(pDrvEnt != (DriverMapPtr)NULL)
+ {
+ pEntry->screenNum = pDrvEnt->screenNum;
+ pPrev = pEntry;
+ }
+ else {
+ if(pPrev)
+ pPrev->next = pEntry->next;
+ else
+ pPrev = pEntry->next;
+ if(pEntry->name != (char *)NULL)
+ xfree(pEntry->name);
+ xfree(pEntry);
+ pEntry = pPrev;
+ }
+ }
+
+ FreeDriverMap(driverMap);
+
+ return Success;
+}
+
+/*
+ * ValidateFontDir looks for a valid font directory for the specified
+ * printer model within the specified configuration directory. It returns
+ * the directory name, or NULL if no valid font directory was found.
+ * It is the caller's responsibility to free the returned font directory
+ * name.
+ */
+static char *
+ValidateFontDir(
+ char *configDir,
+ char *modelName)
+{
+ char *pathName;
+
+ if(!configDir || !modelName)
+ return (char *)NULL;
+
+ pathName = (char *)xalloc(strlen(configDir) + strlen(MODELDIRNAME) +
+ strlen(modelName) + strlen(FONTDIRNAME) +
+ strlen("fonts.dir") + 5);
+ if(!pathName)
+ return (char *)NULL;
+ sprintf(pathName, "%s/%s/%s/%s/%s", configDir, MODELDIRNAME, modelName,
+ FONTDIRNAME, "fonts.dir");
+ if(access(pathName, R_OK) != 0)
+ {
+ xfree(pathName);
+ return (char *)NULL;
+ }
+ pathName[strlen(pathName) - 9] = (char)'\0'; /* erase fonts.dir */
+ return pathName;
+}
+
+/*
+ * FindFontDir returns a pointer to the path name of the font directory
+ * for the specified printer model name, if such a directory exists.
+ * The directory contents are superficially checked for validity.
+ * The caller must free the returned char *.
+ *
+ * We first look in the locale-specific model-config directory, and
+ * then fall back to the C language model-config directory.
+ */
+static char *
+FindFontDir(
+ char *modelName)
+{
+ char *configDir, *fontDir;
+
+ if(!modelName || !strlen(modelName))
+ return (char *)NULL;
+
+ configDir = XpGetConfigDir(TRUE);
+ if((fontDir = ValidateFontDir(configDir, modelName)))
+ {
+ xfree(configDir);
+ return fontDir;
+ }
+
+ if(configDir)
+ xfree(configDir);
+ configDir = XpGetConfigDir(FALSE);
+ fontDir = ValidateFontDir(configDir, modelName);
+
+ xfree(configDir);
+
+ return fontDir;
+}
+
+/*
+ * AddToFontPath adds the specified font path element to the global
+ * defaultFontPath string. It adds the keyword "PRINTER:" to the front
+ * of the path to denote that this is a printer-specific font path
+ * element.
+ */
+static char PATH_PREFIX[] = "PRINTER:";
+static int PATH_PREFIX_LEN = sizeof(PATH_PREFIX) - 1; /* same as strlen() */
+
+static void
+AddToFontPath(
+ char *pathName)
+{
+ char *newPath;
+ Bool freeOldPath;
+
+ if(defaultFontPath == origFontPath)
+ freeOldPath = FALSE;
+ else
+ freeOldPath = TRUE;
+
+ newPath = (char *)xalloc(strlen(defaultFontPath) + strlen(pathName) +
+ PATH_PREFIX_LEN + 2);
+
+ sprintf(newPath, "%s%s,%s", PATH_PREFIX, pathName, defaultFontPath);
+
+ if(freeOldPath)
+ xfree(defaultFontPath);
+
+ defaultFontPath = newPath;
+ return;
+}
+
+/*
+ * AugmentFontPath adds printer-model-specific font path elements to
+ * the front of the font path global variable "defaultFontPath" (dix/globals.c).
+ * We can't call SetFontPath() because the font code has not yet been
+ * initialized when InitOutput is called (from whence this routine is called).
+ *
+ * This utilizes the static variables origFontPath and
+ * freeDefaultFontPath to track the original contents of defaultFontPath,
+ * and to properly free the modified version upon server recycle.
+ */
+static void
+AugmentFontPath(void)
+{
+ char *modelID, **allIDs = (char **)NULL;
+ PrinterDbPtr pDbEntry;
+ int numModels, i;
+
+ if(!origFontPath)
+ origFontPath = defaultFontPath;
+
+ if(freeDefaultFontPath)
+ {
+ xfree(defaultFontPath);
+ defaultFontPath = origFontPath;
+ freeDefaultFontPath = FALSE;
+ }
+
+ /*
+ * Build a list of printer models to check for internal fonts.
+ */
+ for(pDbEntry = printerDb, numModels = 0;
+ pDbEntry != (PrinterDbPtr)NULL;
+ pDbEntry = pDbEntry->next)
+ {
+ modelID =
+ (char*)XpGetPrinterAttribute(pDbEntry->name,
+ "xp-model-identifier");
+
+ if(modelID && strlen(modelID) != 0)
+ {
+ /* look for current model in the list of allIDs */
+ for(i = 0; i < numModels; i++)
+ {
+ if(!strcmp(modelID, allIDs[i]))
+ {
+ modelID = (char *)NULL;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If this printer's model-identifier isn't in the allIDs list,
+ * then add it to allIDs.
+ */
+ if(modelID && strlen(modelID) != 0)
+ {
+ allIDs = (char **)xrealloc(allIDs, (numModels+2) * sizeof(char *));
+ if(allIDs == (char **)NULL)
+ return;
+ allIDs[numModels] = modelID;
+ allIDs[numModels + 1] = (char *)NULL;
+ numModels++;
+ }
+ }
+
+ /* for each model, check for a valid font directory, and add it to
+ * the front of defaultFontPath.
+ */
+ for(i = 0; allIDs != (char **)NULL && allIDs[i] != (char *)NULL; i ++)
+ {
+ char *fontDir;
+ if((fontDir = FindFontDir(allIDs[i])))
+ {
+ AddToFontPath(fontDir);
+ xfree(fontDir);
+ freeDefaultFontPath = TRUE;
+ }
+ }
+
+ if(allIDs)
+ xfree(allIDs);
+
+ return;
+}
+
+/*
+ * XpClientIsBitmapClient is called by the font code to find out if
+ * a particular client should be granted access to bitmap fonts.
+ * This function works by
+ * calling XpContextOfClient (in Xserver/Xext/xprint.c) to determine
+ * the context associated with the client, and then queries the context's
+ * attributes to determine whether the bitmap fonts should be visible.
+ * It looks at the value of the xp-listfonts-modes document/page attribute to
+ * see if xp-list-glyph-fonts has been left out of the mode list. Only
+ * if the xp-listfonts-modes attribute exists, and it does not contain
+ * xp-list-glyph-fonts does this function return FALSE. In any other
+ * case the funtion returns TRUE, indicating that the bitmap fonts
+ * should be visible to the client.
+ */
+Bool
+XpClientIsBitmapClient(
+ ClientPtr client)
+{
+ XpContextPtr pContext;
+ char *mode;
+
+ if(!(pContext = XpContextOfClient(client)))
+ return TRUE;
+
+ /*
+ * Check the page attributes, and if it's not defined there, then
+ * check the document attributes.
+ */
+ mode = XpGetOneAttribute(pContext, XPPageAttr, "xp-listfonts-modes");
+ if(!mode || !strlen(mode))
+ {
+ mode = XpGetOneAttribute(pContext, XPDocAttr, "xp-listfonts-modes");
+ if(!mode || !strlen(mode))
+ return TRUE;
+ }
+
+ if(!strstr(mode, "xp-list-glyph-fonts"))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * XpClientIsPrintClient is called by the font code to find out if
+ * a particular client has set a context which references a printer
+ * which utilizes a particular font path.
+ * This function works by calling XpContextOfClient
+ * (in Xserver/Xext/xprint.c) to determine the context associated with
+ * the client and then looks at the value of the xp-listfonts-modes
+ * document/page attribute to see if xp-list-internal-printer-fonts has
+ * been left out of the mode list.
+ * If the xp-listfonts-modes attribute exists, and it does not contain
+ * xp-list-internal-printer-fonts this function returns FALSE.
+ * Otherwise it looks up the font directory for the context. The font
+ * directory is then compared with the directory specified in the
+ * FontPathElement which is passed in.
+ */
+Bool
+XpClientIsPrintClient(
+ ClientPtr client,
+ FontPathElementPtr fpe)
+{
+ XpContextPtr pContext;
+ char *mode;
+ char *modelID, *fontDir;
+
+ if(!(pContext = XpContextOfClient(client)))
+ return FALSE;
+
+ /*
+ * Check the page attributes, and if it's not defined there, then
+ * check the document attributes.
+ */
+ mode = XpGetOneAttribute(pContext, XPPageAttr, "xp-listfonts-modes");
+ if(!mode || !strlen(mode))
+ {
+ mode = XpGetOneAttribute(pContext, XPDocAttr, "xp-listfonts-modes");
+ }
+
+ if(mode && strlen(mode))
+ {
+ if(!strstr(mode, "xp-list-internal-printer-fonts"))
+ return FALSE;
+ }
+
+ if (!fpe)
+ return TRUE;
+
+ modelID = XpGetOneAttribute(pContext, XPPrinterAttr, "xp-model-identifier");
+ if(!modelID || !strlen(modelID))
+ return FALSE;
+
+ if(!(fontDir = FindFontDir(modelID)))
+ return FALSE;
+
+ /*
+ * The grunge here is to ignore the PATH_PREFIX at the front of the
+ * fpe->name.
+ */
+ if(fpe->name_length < PATH_PREFIX_LEN ||
+ (strlen(fontDir) != (fpe->name_length - PATH_PREFIX_LEN)) ||
+ strncmp(fontDir, fpe->name + PATH_PREFIX_LEN,
+ fpe->name_length - PATH_PREFIX_LEN))
+ {
+ xfree(fontDir);
+ return FALSE;
+ }
+ xfree(fontDir);
+ return TRUE;
+}
+
+static void
+AddFormats(ScreenInfo *pScreenInfo, char *driverName)
+{
+ int i, j;
+ driverInitRec *pInitRec;
+ int numDrivers = sizeof(driverInits)/sizeof(driverInitRec);
+ PixmapFormatRec *formats;
+ int numfmts;
+
+ for (pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++)
+ {
+ if ( !strcmp( driverName, pInitRec->driverName ) )
+ break;
+ }
+ if (i >= numDrivers)
+ return;
+ formats = pInitRec->pFmts;
+ numfmts = pInitRec->numFmts;
+ for (i = 0; i < numfmts && pScreenInfo->numPixmapFormats < MAXFORMATS; i++)
+ {
+ for (j = 0; j < pScreenInfo->numPixmapFormats; j++) {
+ if (pScreenInfo->formats[j].depth == formats[i].depth &&
+ pScreenInfo->formats[j].bitsPerPixel == formats[i].bitsPerPixel &&
+ pScreenInfo->formats[j].scanlinePad == formats[i].scanlinePad)
+ break;
+ }
+ if (j == pScreenInfo->numPixmapFormats) {
+ pScreenInfo->formats[j] = formats[i];
+ pScreenInfo->numPixmapFormats++;
+ }
+ }
+}
+
+/************************************************************
+ * PrinterInitOutput --
+ * This routine is to be called from a ddx's InitOutput
+ * during the server startup initialization, and when
+ * the server is to be reset. The routine creates the
+ * screens associated with configured printers by calling
+ * dix:AddScreen. The configuration information comes from a
+ * database read from the X*printers file.
+ *
+ * Results:
+ * The array of ScreenRec pointers referenced by
+ * pScreenInfo->screen is increased by the addition
+ * of the printer screen(s), as is the value of
+ * pScreenInfo->numScreens. This is done via calls
+ * to AddScreen() in dix.
+ *
+ ************************************************************/
+
+void
+PrinterInitOutput(
+ ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv)
+{
+ PrinterDbPtr pDb, pDbEntry;
+ int driverCount = 0, i;
+ char **driverNames;
+ char *configDir;
+
+ /* This should NEVER happen, but... */
+ if( !xprintInitGlobalsCalled )
+ {
+ FatalError("Internal error: PrinterInitGlobals() not called.");
+ }
+#ifdef SMART_SCHEDULE
+ /* |PrinterInitGlobals| should have set |SmartScheduleDisable| to
+ * |TRUE| - if not we will trigger this safeguard. */
+ if( SmartScheduleDisable != TRUE )
+ {
+ FatalError("Internal error: XF86 smart scheduler incompatible to Xprint DDX.");
+ }
+#endif /* SMART_SCHEDULE */
+ /* Safeguard for
+ * http://pdx.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=567 ("Xorg
+ * Xprt starts to consume 100% CPU when being idle for some time")
+ * |PrinterInitGlobals| should have set |defaultScreenSaverTime| to
+ * |0| - if not we will trigger this trap. */
+ if( defaultScreenSaverTime != 0 )
+ {
+ FatalError("Internal screen saver must be OFF for printing.");
+ }
+
+ /* Print a warnung when the maximum request size of the BIGREQUESTS
+ * extension is smaller than 8MB (see
+ * http://xprint.freedesktop.org/cgi-bin/bugzilla/show_bug.cgi?id=622)
+ */
+ if (maxBigRequestSize < (8*1048576)-1) {
+ ErrorF("Xp Extension: BIGREQUESTS max. request is currently %ld bytes "
+ ", recommemded minimum for Xprint is 8MB.\n", (long)maxBigRequestSize);
+ }
+
+ /*
+ * this little test is just a warning at startup to make sure
+ * that the config directory exists.
+ *
+ * what this ugly looking if says is that if both ways of
+ * calling configDir works and both directories don't exist,
+ * then print an error saying we can't find the non-lang one.
+ */
+ if (((configDir = XpGetConfigDir(TRUE)) != NULL) &&
+ (access(configDir, F_OK) == 0))
+ {
+ xfree(configDir);
+ }
+ else if (((configDir = XpGetConfigDir(FALSE)) != NULL) &&
+ (access(configDir, F_OK) == 0))
+ {
+ xfree(configDir);
+ }
+ else {
+ /* Refuse to start when we do not have our config dir... */
+ FatalError("Xp Extension: could not find config dir %s\n",
+ configDir ? configDir : XPRINTDIR);
+ }
+
+ if(printerDb != (PrinterDbPtr)NULL)
+ FreePrinterDb();
+
+ /*
+ * Calling BuildPrinterDb serves to build the printer database,
+ * and to initialize the attribute store for each printer.
+ * The driver can, if it so desires, modify the attribute
+ * store at a later time.
+ */
+ if((pDb = BuildPrinterDb()) == (PrinterDbPtr)NULL) return;
+
+ /*
+ * We now have to decide how many screens to initialize, and call
+ * AddScreen for each one. The printerDb must be properly initialized
+ * for at least one screen's worth of printers prior to calling AddScreen
+ * because InitPrintDrivers reads the printerDb to determine which
+ * driver(s) to init on a particular screen.
+ * We put each driver's printers on a different
+ * screen, and call AddScreen for each screen/driver pair.
+ */
+ /* count the number of printers */
+ for(pDbEntry = pDb, driverCount = 0; pDbEntry != (PrinterDbPtr)NULL;
+ pDbEntry = pDbEntry->next, driverCount++)
+ ;
+ /*
+ * Allocate memory for the worst case - a driver per printer
+ */
+ driverNames = (char **)xalloc(sizeof(char *) * driverCount);
+
+ /*
+ * Assign the driver for the first printer to the first screen
+ */
+ pDb->screenNum = screenInfo.numScreens;
+ driverNames[0] = pDb->driverName;
+ driverCount = 1;
+ AddFormats(pScreenInfo, pDb->driverName);
+
+ /*
+ * For each printer, look to see if its driver is already assigned
+ * to a screen, and if so copy that screen number into the printerDb.
+ * Otherwise, assign a new screen number to the driver for this
+ * printer.
+ */
+ for(pDbEntry = pDb; pDbEntry != (PrinterDbPtr)NULL;
+ pDbEntry = pDbEntry->next)
+ {
+ Bool foundMatch;
+
+ for(i = 0, foundMatch = FALSE; i < driverCount; i++)
+ {
+ if(!strcmp(driverNames[i], pDbEntry->driverName))
+ {
+ foundMatch = TRUE;
+ pDbEntry->screenNum = screenInfo.numScreens + i;
+ break;
+ }
+ }
+ if(foundMatch == FALSE)
+ {
+ driverNames[driverCount] = pDbEntry->driverName;
+ pDbEntry->screenNum = screenInfo.numScreens + driverCount;
+ AddFormats(pScreenInfo, pDbEntry->driverName);
+ driverCount++;
+ }
+ }
+
+ for(i = 0; i < driverCount; i++)
+ {
+ int curScreen = screenInfo.numScreens;
+ if(AddScreen(InitPrintDrivers, argc, argv) < 0)
+ {
+ PrinterDbPtr pPrev;
+ /*
+ * AddScreen failed, so we pull the associated printers
+ * from the list.
+ */
+ ErrorF("Xp Extension: Could not add screen for driver %s\n",
+ driverNames[i]);
+ for(pPrev = pDbEntry = printerDb; pDbEntry != (PrinterDbPtr)NULL;
+ pDbEntry = pDbEntry->next)
+ {
+ if(pDbEntry->screenNum == curScreen)
+ {
+ if(pPrev == printerDb)
+ {
+ printerDb = pDbEntry->next;
+ pPrev = printerDb;
+ }
+ else
+ pPrev->next = pDbEntry->next;
+
+ xfree(pDbEntry->name);
+ xfree(pDbEntry);
+ pDbEntry = pPrev;
+ }
+ else
+ {
+ if(pDbEntry->screenNum > curScreen)
+ pDbEntry->screenNum--;
+ pPrev = pDbEntry;
+ }
+ }
+ }
+ }
+
+ xfree(driverNames);
+
+ AugmentFontPath();
+
+ if(pScreenInfo->numScreens > MAXSCREENS)
+ {
+ ErrorF("The number of printer screens requested ");
+ ErrorF("exceeds the allowable limit of %d screens.\n", MAXSCREENS);
+ ErrorF("Please reduce the number of requested printers in your ");
+ ErrorF("\nX%sprinters file.", display);
+ ErrorF("Server exiting...\n");
+ exit(-1);
+ }
+}
+
+/*
+ * InitPrintDrivers is called from dix:AddScreen. It in turn calls the
+ * driver initialization routine for any and all drivers which are
+ * implicated in supporting printers on the particular screen number
+ * specified by the "index" parameter. The printerDb variable is used
+ * to determine which printers are to be associated with a particular
+ * screen.
+ */
+static Bool
+InitPrintDrivers(
+ int index,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv)
+{
+ PrinterDbPtr pDb, pDb2;
+
+ GenericScreenInit(index, pScreen, argc, argv);
+
+ for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
+ {
+ if(pDb->screenNum == index)
+ {
+ Bool callInit = TRUE;
+ for(pDb2 = printerDb; pDb2 != pDb; pDb2 = pDb2->next)
+ {
+ if(!strcmp(pDb->driverName, pDb2->driverName))
+ {
+ callInit = FALSE;
+ break;
+ }
+ }
+ if(callInit == TRUE)
+ {
+ Bool (*initFunc)(BFuncArgs);
+ initFunc = GetInitFunc(pDb->driverName);
+ if(initFunc(index, pScreen, argc, argv) == FALSE)
+ {
+ /* XXX - What do I do if the driver's init fails? */
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+void
+_XpVoidNoop(void)
+{
+ return;
+}
+
+Bool
+_XpBoolNoop(void)
+{
+ return TRUE;
+}
+
+/*
+ * GenericScreenInit - The common initializations required by all
+ * printer screens and drivers. It sets the screen's cursor functions
+ * to Noops, and computes the maximum screen (i.e. medium) dimensions.
+ */
+
+static void
+GenericScreenInit(
+ int index,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv)
+{
+ float fWidth, fHeight, maxWidth, maxHeight;
+ unsigned short width, height;
+ PrinterDbPtr pDb;
+ int res, maxRes;
+
+ /*
+ * Set the cursor ops to no-op functions.
+ */
+ pScreen->DisplayCursor = (DisplayCursorProcPtr)_XpBoolNoop;
+ pScreen->RealizeCursor = (RealizeCursorProcPtr)_XpBoolNoop;
+ pScreen->UnrealizeCursor = (UnrealizeCursorProcPtr)_XpBoolNoop;
+ pScreen->SetCursorPosition = (SetCursorPositionProcPtr)_XpBoolNoop;
+ pScreen->ConstrainCursor = (ConstrainCursorProcPtr)_XpVoidNoop;
+ pScreen->CursorLimits = (CursorLimitsProcPtr)_XpVoidNoop;
+ pScreen->RecolorCursor = (RecolorCursorProcPtr)_XpVoidNoop;
+
+ /*
+ * Find the largest paper size for all the printers on the given
+ * screen.
+ */
+ maxRes = 0;
+ maxWidth = maxHeight = 0.0;
+ for( pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
+ {
+ if(pDb->screenNum == index)
+ {
+
+ XpValidatePoolsRec *pValRec;
+ pVFunc dimensionsFunc;
+
+ GetDimFuncAndRec(pDb->driverName, &pValRec, &dimensionsFunc);
+ if(dimensionsFunc != (pVFunc)NULL)
+ dimensionsFunc(pDb->name, pValRec, &fWidth, &fHeight, &res);
+ else
+ XpGetMaxWidthHeightRes(pDb->name, pValRec, &fWidth,
+ &fHeight, &res);
+ if( res > maxRes )
+ maxRes = res;
+ if( fWidth > maxWidth )
+ maxWidth = fWidth;
+ if( fHeight > maxHeight )
+ maxHeight = fHeight;
+ }
+ }
+
+ width = (unsigned short) (maxWidth * maxRes / 25.4);
+ height = (unsigned short) (maxHeight * maxRes / 25.4);
+ pScreen->width = pScreen->height = ( width > height ) ? width :
+ height;
+
+ pScreen->mmWidth = pScreen->mmHeight = ( maxWidth > maxHeight ) ?
+ (unsigned short)(maxWidth + 0.5) :
+ (unsigned short)(maxHeight + 0.5);
+}
+
+#if 0 /* No one uses this anymore... */
+/*
+ * QualifyName - takes an unqualified file name such as X6printers and
+ * a colon-separated list of directory path names such as
+ * /etc/opt/dt:/opt/dt/config.
+ *
+ * Returns a fully qualified file path name such as /etc/opt/dt/X6printers.
+ * The returned value is malloc'd, and the caller is responsible for
+ * freeing the associated memory.
+ */
+static char *
+QualifyName(char *fileName, char *searchPath)
+{
+ char * curPath = searchPath;
+ char * nextPath;
+ char * chance;
+ FILE *pFile;
+
+ if (fileName == NULL || searchPath == NULL)
+ return NULL;
+
+ while (1) {
+ if ((nextPath = strchr(curPath, ':')) != NULL)
+ *nextPath = 0;
+
+ chance = (char *)xalloc(strlen(curPath) + strlen(fileName) + 2);
+ sprintf(chance,"%s/%s",curPath,fileName);
+
+ /* see if we can read from the file */
+ if((pFile = fopen(chance, "r")) != (FILE *)NULL)
+ {
+ fclose(pFile);
+ /* ... restore the colon, .... */
+ if (nextPath)
+ *nextPath = ':';
+
+ return chance;
+ }
+
+ xfree(chance);
+
+ if (nextPath == NULL) /* End of path list? */
+ break;
+
+ /* try the next path */
+ curPath = nextPath + 1;
+ }
+ return NULL;
+}
+#endif
+
+/*
+ * FillPrinterListEntry fills in a single XpDiListEntry element with data
+ * derived from the supplied PrinterDbPtr element.
+ *
+ * XXX A smarter (i.e. future) version of this routine might inspect the
+ * XXX "locale" parameter and attempt to match the "description" and
+ * XXX "localeName" elements of the XpDiListEntry to the specified locale.
+ */
+static void
+FillPrinterListEntry(
+ XpDiListEntry *pEntry,
+ PrinterDbPtr pDb,
+ int localeLen,
+ char *locale)
+{
+ static char *localeStr = (char *)NULL;
+
+ if(localeStr == (char *)NULL)
+ localeStr = strdup(setlocale(LC_ALL, (const char *)NULL));
+
+ pEntry->name = pDb->name;
+ pEntry->description =
+ (char*)XpGetPrinterAttribute(pDb->name, "descriptor");
+ pEntry->localeName = localeStr;
+ pEntry->rootWinId = WindowTable[pDb->screenNum]->drawable.id;
+}
+
+/*
+ * GetPrinterListInfo fills in the XpDiListEntry struct pointed to by the
+ * parameter pEntry with the information regarding the printer specified
+ * by the name and nameLen parameters. The pointers placed in the
+ * XpDiListEntry structure MUST NOT be freed by the caller. They are
+ * pointers into existing long-lived databases.
+ *
+ */
+static Bool
+GetPrinterListInfo(
+ XpDiListEntry *pEntry,
+ int nameLen,
+ char *name,
+ int localeLen,
+ char *locale)
+{
+ PrinterDbPtr pDb;
+
+ for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next)
+ {
+ if(strlen(pDb->name) == nameLen && !strncmp(pDb->name, name, nameLen))
+ {
+ FillPrinterListEntry(pEntry, pDb, localeLen, locale);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * XpDiFreePrinterList is the approved method of releasing memory used
+ * for a printer list.
+ */
+void
+XpDiFreePrinterList(XpDiListEntry **list)
+{
+ int i;
+
+ for(i = 0; list[i] != (XpDiListEntry *)NULL; i++)
+ xfree(list[i]);
+ xfree(list);
+}
+
+/*
+ * XpDiGetPrinterList returns a pointer to a NULL-terminated array of
+ * XpDiListEntry pointers. Each entry structure contains the name,
+ * description, root window, and locale of a printer. The call returns
+ * either a list of all printers configured on the server, or it returns
+ * the information for one specific printer depending on the values passed
+ * in. Non-NULL values passed in indicate that only the information for
+ * the one specific printer is desired, while NULL values indicate that
+ * the information for all printers is desired.
+ */
+XpDiListEntry **
+XpDiGetPrinterList(
+ int nameLen,
+ char *name,
+ int localeLen,
+ char *locale)
+{
+ XpDiListEntry **pList;
+
+ if(!nameLen || name == (char *)NULL)
+ {
+ int i;
+ PrinterDbPtr pDb;
+
+ for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL;
+ pDb = pDb->next, i++)
+ ;
+
+ if((pList = (XpDiListEntry **)xalloc((i+1) * sizeof(XpDiListEntry *)))
+ == (XpDiListEntry **)NULL)
+ return pList;
+
+ pList[i] = (XpDiListEntry *)NULL;
+ for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL;
+ pDb = pDb->next, i++)
+ {
+ if((pList[i] = (XpDiListEntry *)xalloc(sizeof(XpDiListEntry)))==
+ (XpDiListEntry *)NULL)
+ {
+ XpDiFreePrinterList(pList);
+ return (XpDiListEntry **)NULL;
+ }
+ FillPrinterListEntry(pList[i], pDb, localeLen, locale);
+ }
+ }
+ else
+ {
+ if((pList = (XpDiListEntry **)xalloc(2 * sizeof(XpDiListEntry *))) ==
+ (XpDiListEntry **)NULL)
+ return pList;
+
+ if((pList[0] = (XpDiListEntry *)xalloc(sizeof(XpDiListEntry))) ==
+ (XpDiListEntry *)NULL)
+ {
+ xfree(pList);
+ return (XpDiListEntry **)NULL;
+ }
+ pList[1] = (XpDiListEntry *)NULL;
+ if(GetPrinterListInfo(pList[0], nameLen, name, localeLen, locale) ==
+ FALSE)
+ {
+ xfree(pList[0]);
+ pList[0] = (XpDiListEntry *)NULL;
+ }
+ }
+ return pList;
+}
+
+WindowPtr
+XpDiValidatePrinter(char *printerName, int printerNameLen)
+{
+ PrinterDbPtr pCurEntry;
+
+ for(pCurEntry = printerDb;
+ pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next)
+ {
+ if(strlen(pCurEntry->name) == printerNameLen &&
+ !strncmp(pCurEntry->name, printerName, printerNameLen))
+ return WindowTable[pCurEntry->screenNum];
+ }
+ return (WindowPtr)NULL;
+}
+
+/*
+ * XpDiGetDriverName takes a screen index and a printer name, and returns
+ * a pointer to the name of the driver to be used for the specified printer
+ * on the specified screen.
+ */
+char *
+XpDiGetDriverName(int index, char *printerName)
+{
+
+ PrinterDbPtr pCurEntry;
+
+ for(pCurEntry = printerDb;
+ pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next)
+ {
+ if(pCurEntry->screenNum == index &&
+ !strcmp(pCurEntry->name, printerName))
+ return pCurEntry->driverName;
+ }
+
+ return (char *)NULL; /* XXX Should we supply a default driverName? */
+}
+
diff --git a/hw/xprint/Makefile.am b/hw/xprint/Makefile.am
new file mode 100644
index 000000000..46647a519
--- /dev/null
+++ b/hw/xprint/Makefile.am
@@ -0,0 +1,42 @@
+SUBDIRS = doc pcl pcl-mono raster ps etc config
+
+bin_PROGRAMS = Xprt
+
+Xprt_CFLAGS = @SERVER_DEFINES@ @DIX_CFLAGS@ @XPRINT_CFLAGS@ \
+ -DXPRINT -DPRINT_ONLY_SERVER -D_XP_PRINT_SERVER_ \
+ -DXPRINTDIR=\"$(prefix)/X11/xserver\" \
+ -DXPRASTERDDX -DXPPCLDDX -DXPMONOPCLDDX -DXPPSDDX
+
+Xprt_LDFLAGS = -L$(top_srcdir)
+Xprt_LDADD = @XPRINT_LIBS@ ps/libps.la raster/libraster.la \
+ pcl/libpcl.la pcl-mono/libpcl.la ../../fb/libfb.la \
+ ../../render/librender.la ../../mi/libmi.la ../../Xext/libXext.la \
+ @FREETYPE_LIBS@
+
+miinitext-wrapper.c:
+ echo "#include \"$(top_srcdir)/mi/miinitext.c\"" >> $@
+
+dpmsstubs-wrapper.c:
+ echo "#include \"$(top_srcdir)/Xext/dpmsstubs.c\"" >> $@
+
+Xprt_SOURCES = \
+ attributes.c \
+ attributes.h \
+ AttrValid.c \
+ AttrValid.h \
+ ddxInit.c \
+ DiPrint.h \
+ Init.c \
+ mediaSizes.c \
+ Oid.c \
+ OidDefs.h \
+ Oid.h \
+ OidStrs.h \
+ spooler.c \
+ spooler.h \
+ Util.c \
+ miinitext-wrapper.c \
+ dpmsstubs-wrapper.c \
+ $(top_srcdir)/fb/fbcmap.c
+
+EXTRA_DIST = ValTree.c
diff --git a/hw/xprint/Oid.c b/hw/xprint/Oid.c
new file mode 100644
index 000000000..e4dadd519
--- /dev/null
+++ b/hw/xprint/Oid.c
@@ -0,0 +1,3182 @@
+/* $Xorg: Oid.c,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "attributes.h"
+
+/*
+ * XpOidNotify value strings
+ */
+#define NOTIFY_EMAIL_STR "{{event-report-job-completed} electronic-mail}"
+#define NOTIFY_NONE_STR "{}"
+
+#define SafeStrLen(s) ((s) ? strlen((s)) : 0)
+
+/*
+ * entry type for the object identifier string map
+ */
+typedef struct _XpOidStringMapEntry
+{
+ const char* string;
+ int length;
+ int msg_set;
+ int msg_number;
+ const char* default_message;
+
+} XpOidStringMapEntry;
+
+/*
+ * include the auto-generated static XpOidStringMap
+ */
+#include "OidStrs.h"
+
+/*
+ * XpOid static function declarations
+ */
+static XpOid XpOidParse(const char* value_string,
+ const char** ptr_return);
+/*
+ * XpOidList static function declarations
+ */
+static XpOidList* XpOidListParse(const char* value_string,
+ const XpOidList* valid_oids,
+ const char** ptr_return, int i);
+
+/*
+ * XpOidList static function declarations
+ */
+static XpOidCardList* XpOidCardListParse(const char* value_string,
+ const XpOidCardList* valid_cards,
+ const char** ptr_return, int i);
+
+/*
+ * XpOidMediumSourceSize static function declarations
+ */
+static XpOidMediumSS* MediumSSParse(const char* value_string,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_medium_sizes,
+ const char** ptr_return, int i);
+static XpOidMediumContinuousSize* MediumContinuousSizeParse(const char*,
+ const char**);
+static void MediumContinuousSizeDelete(XpOidMediumContinuousSize* me);
+static XpOidMediumDiscreteSizeList* MediumDiscreteSizeListParse(const char*,
+ const XpOidList*,
+ const char**,
+ int i);
+static void MediumDiscreteSizeListDelete(XpOidMediumDiscreteSizeList* list);
+
+static BOOL ParseArea(const char* value_string,
+ const char** ptr_return,
+ XpOidArea* area_return);
+static BOOL ParseRealRange(const char* value_string,
+ const char** ptr_return,
+ XpOidRealRange* range_return);
+
+/*
+ * XpOidTrayMediumList static function declarations
+ */
+static XpOidTrayMediumList* TrayMediumListParse(const char* value_string,
+ const XpOidList* valid_trays,
+ const char** ptr_return,
+ int i);
+static void TrayMediumListValidate(XpOidTrayMediumList* me,
+ const XpOidMediumSS* msss);
+
+/*
+ * XpOidDocFmt
+ */
+static BOOL XpOidDocFmtNext(XpOidDocFmt* doc_fmt,
+ const char* value_string,
+ const char** ptr_return);
+
+/*
+ * XpOidDocFmtListParse
+ */
+static XpOidDocFmtList* XpOidDocFmtListParse(const char* value_string,
+ const XpOidDocFmtList* valid_fmts,
+ const char** ptr_return, int i);
+
+/*
+ * misc. parsing static function declarations
+ */
+static BOOL ParseBoolValue(const char* value_string,
+ const char** ptr_return,
+ BOOL* bool_return);
+static BOOL ParseRealValue(const char* value_string,
+ const char** ptr_return,
+ float* real_return);
+static BOOL ParseSeqEnd(
+ const char* value_string,
+ const char** ptr_return);
+static BOOL ParseSeqStart(
+ const char* value_string,
+ const char** ptr_return);
+static BOOL ParseUnspecifiedValue(
+ const char* value_string,
+ const char** ptr_return);
+static int SpanToken(
+ const char* string);
+static int SpanWhitespace(
+ const char* string);
+
+/*
+ * String comparison function.
+ */
+#ifdef HAVE_STRCASECMP
+# define StrnCaseCmp(s1, s2, len) strncasecmp(s1, s2, len)
+#else
+static int StrnCaseCmp(const char *s1, const char *s2, size_t len);
+#endif
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidString
+ *
+ * Description:
+ *
+ * Obtain the string representation of an XpOid.
+ *
+ * Example: XpOidString(xpoid_copy_count) returns "copy-count".
+ *
+ * Return value:
+ *
+ * A const pointer to the string.
+ */
+const char*
+XpOidString(XpOid xp_oid)
+{
+ /*
+ * XpOid enum values are index values into the string map
+ */
+ return XpOidStringMap[xp_oid].string;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidStringLength
+ *
+ * Description:
+ *
+ * Obtain the length of the string representation for a given
+ * XpOid.
+ *
+ * Return value:
+ *
+ * The string length in bytes.
+ *
+ */
+int
+XpOidStringLength(XpOid xp_oid)
+{
+ /*
+ * XpOid enum values are index values into the string map
+ */
+ return XpOidStringMap[xp_oid].length;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidFromString
+ *
+ * Description:
+ *
+ * Obtains the XpOid given a string representation of an XpOid.
+ *
+ * Example: XpOidFromString("copy-count") returns 'xpoid_copy_count'.
+ *
+ * Return value:
+ *
+ * The XpOid if successful. 'xpoid_none' if the string pointed to by
+ * 'value is not recognized or if 'value' is NULL.
+ */
+XpOid
+XpOidFromString(const char* value)
+{
+ if(value == (const char*)NULL)
+ return xpoid_none;
+ else
+ return XpOidParse(value, (const char**)NULL);
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidParse
+ *
+ * Description:
+ *
+ * Parse the next whitespace-delimited string from 'value_string'
+ * updating 'ptr_return' to point to the next unparsed location in
+ * 'value_string'. 'ptr_return' can be NULL.
+ *
+ * Return value:
+ *
+ * The corresponding XpOid for the parsed name string.
+ * A return value of xpoid_none is returned if the parsed name
+ * was not a valid oid or if no name was found.
+ *
+ */
+static XpOid
+XpOidParse(const char* value_string,
+ const char** ptr_return)
+{
+ const char* ptr;
+ int length;
+ int i;
+ /*
+ * skip leading whitespace
+ */
+ ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * get the whitespace-delimited token length
+ */
+ length = SpanToken(ptr);
+ /*
+ * match the oid string in the map
+ */
+ for(i = 0; i < XpOidStringMapCount; i++)
+ if(length == XpOidStringMap[i].length)
+ if(strncmp(ptr, XpOidStringMap[i].string, length) == 0)
+ break;
+ if(i == XpOidStringMapCount)
+ i = xpoid_none;
+ /*
+ * update the return pointer and return
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr+length;
+ return i;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidListNew
+ *
+ * Description:
+ *
+ * Creates a new XpOidList initialized from a whitespace-delimited
+ * list of recognized string representations of oids. The returned
+ * list will contain only oids found within the passed 'valid_oids'
+ * XpOidList.
+ *
+ * Note: One may notice that in order to create an XpOidList with
+ * this function, an XpOidList is needed; the 'valid_oids' list
+ * is often an statically initialized structure. XpOidListInit
+ * can also be used.
+ *
+ * Return value:
+ *
+ * NULL if the passed 'value_string' is NULL.
+ *
+ * If the list indicated by 'value_string' is empty or contains only
+ * unrecognized oid string representations, a new XpOidList
+ * containing zero elements is returned.
+ *
+ * If 'valid_oids' is NULL all oids are considered valid.
+ *
+ */
+XpOidList*
+XpOidListNew(const char* value_string,
+ const XpOidList* valid_oids)
+{
+ if(value_string == (const char*)NULL)
+ return (XpOidList*)NULL;
+ else
+ {
+ const char* ptr;
+ return XpOidListParse(value_string, valid_oids, &ptr, 0);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidListDelete
+ *
+ * Description:
+ *
+ * Frees the memory allocated for 'list'.
+ *
+ * Return value:
+ *
+ * None.
+ *
+ */
+void
+XpOidListDelete(XpOidList* list)
+{
+ if(list != (XpOidList*)NULL)
+ {
+ XpOidFree((char*)list->list);
+ XpOidFree((char*)list);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidListParse
+ *
+ * Description:
+ *
+ * This function recursively parses the whitespace-delimited list of
+ * oid string representations passed via 'value_string'. Oids are
+ * only added to the resulting list if they are found within the
+ * passed 'valid_oids' XpOidList.
+ *
+ * 'ptr_return' points to a char* variable allocated by the
+ * caller, and is really only of use during recursion (upon return to
+ * the original caller, it will point to the end of value_string).
+ *
+ * 'value_string' and 'ptr_return' *cannot* be NULL.
+ *
+ * Return value:
+ *
+ * A newly allocated and initialized XpOidList.
+ *
+ * If the list indicated by 'value_string' is empty or contains only
+ * unrecognized oid string representations, a new XpOidList
+ * containing zero elements is returned.
+ *
+ * If 'valid_oids' is NULL all oids are considered valid.
+ *
+ */
+static XpOidList*
+XpOidListParse(const char* value_string,
+ const XpOidList* valid_oids,
+ const char** ptr_return,
+ int i)
+{
+ XpOid oid;
+ XpOidList* list;
+ /*
+ * parse the next valid oid out of the value string
+ */
+ ptr_return = &value_string;
+ while(1)
+ {
+ if(**ptr_return == '\0')
+ {
+ /*
+ * end of value string; stop parsing
+ */
+ oid = xpoid_none;
+ break;
+ }
+ /*
+ * parse the next oid from the value
+ */
+ oid = XpOidParse(*ptr_return, ptr_return);
+ if(xpoid_none == oid)
+ {
+ /*
+ * unrecognized oid; keep parsing
+ */
+ continue;
+ }
+ if((const XpOidList*)NULL == valid_oids
+ ||
+ XpOidListHasOid(valid_oids, oid))
+ {
+ /*
+ * valid oid found; stop parsing
+ */
+ break;
+ }
+ }
+
+ if(oid == xpoid_none)
+ {
+ /*
+ * end of value string; allocate the list structure
+ */
+ list = (XpOidList*)XpOidCalloc(1, sizeof(XpOidList));
+ list->count = i;
+ list->list = (XpOid*)XpOidCalloc(i, sizeof(XpOid));
+ }
+ else
+ {
+ /*
+ * recurse
+ */
+ list = XpOidListParse(*ptr_return, valid_oids, ptr_return, i+1);
+ /*
+ * set the oid in the list
+ */
+ list->list[i] = oid;
+ }
+ /*
+ * return
+ */
+ return list;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidListHasOid
+ *
+ * Description:
+ *
+ * Determines if 'oid' is an element of 'list'.
+ *
+ * Return value:
+ *
+ * xTrue if the oid is found in the list.
+ *
+ * xFalse if the oid is not in the list, or if 'list' is NULL.
+ *
+ */
+BOOL
+XpOidListHasOid(const XpOidList* list, XpOid oid)
+{
+ int i;
+ if(list != (XpOidList*)NULL)
+ for(i = 0; i < list->count; i++)
+ if(list->list[i] == oid)
+ return xTrue;
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidListGetIndex
+ *
+ * Description:
+ *
+ * Returns the array index of 'oid' in 'list'
+ *
+ * Return value:
+ *
+ * The index of 'oid' in list.
+ *
+ * -1 if the oid is not in the list, or if 'list' is NULL.
+ *
+ */
+int
+XpOidListGetIndex(const XpOidList* list, XpOid oid)
+{
+ int i;
+ if(list != (XpOidList*)NULL)
+ for(i = 0; i < list->count; i++)
+ if(list->list[i] == oid)
+ return i;
+ return -1;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidListString
+ *
+ * Description:
+ *
+ * Creates a string representation of an XpOidList structure.
+ *
+ * Return value:
+ *
+ * A newly allocated
+ *
+ */
+char*
+XpOidListString(const XpOidList* me)
+{
+ int i;
+ int length;
+ char* str;
+ char* ptr;
+ /*
+ * allocate enough memory for the oid string representations,
+ * including intervening whitespace
+ */
+ for(i = 0, length = 0; i < XpOidListCount(me); i++)
+ length += XpOidStringLength(XpOidListGetOid(me, i)) + 1;
+ str = XpOidMalloc(length+1);
+ /*
+ * format the list
+ */
+ for(i = 0, ptr = str; i < XpOidListCount(me); i++)
+#if defined(sun) && !defined(SVR4)
+ {
+ sprintf(ptr, "%s ", XpOidString(XpOidListGetOid(me, i)));
+ ptr += strlen(ptr);
+ }
+#else
+ ptr += sprintf(ptr, "%s ", XpOidString(XpOidListGetOid(me, i)));
+#endif
+ /*
+ * chop trailing whitespace or terminate empty string
+ */
+ str[length] = '\0';
+ /*
+ * return
+ */
+ return str;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListNew
+ *
+ * Description:
+ *
+ * Creates a new instance of an empty XpOidLinkedList.
+ *
+ * Return value:
+ *
+ * The new XpOidLinkedList.
+ *
+ */
+XpOidLinkedList*
+XpOidLinkedListNew()
+{
+ return (XpOidLinkedList*)XpOidCalloc(1, sizeof(XpOidLinkedList));
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListDelete
+ *
+ * Description:
+ *
+ * Frees the memory allocated for a XpOidLinkedList.
+ *
+ * Return value:
+ *
+ * None.
+ *
+ */
+void
+XpOidLinkedListDelete(XpOidLinkedList* me)
+{
+ if(me != (XpOidLinkedList*)NULL)
+ {
+ while(me->head)
+ {
+ me->current = me->head;
+ me->head = me->current->next;
+ XpOidFree((char*)me->current);
+ }
+ XpOidFree((char*)me);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListGetOid
+ *
+ * Description:
+ *
+ * Retrieves the oid at position 'i' (zero-based) in the
+ * XpOidLinkedList 'me'.
+ *
+ * Return value:
+ *
+ * The oid at position 'i'.
+ *
+ * xpoid_none if the oid was not found, or the list is empty (or if
+ * the list contains xpoid_none at position 'i').
+ */
+XpOid
+XpOidLinkedListGetOid(XpOidLinkedList* me, int i)
+{
+ if(me == (XpOidLinkedList*)NULL || i < 0 || i >= me->count)
+ {
+ return xpoid_none;
+ }
+ else
+ {
+ me->current = me->head;
+ while(i--) me->current = me->current->next;
+ return me->current->oid;
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListAddOid
+ *
+ * Description:
+ *
+ * Adds an oid to the end of an XpOidLinkedList.
+ *
+ * Return value:
+ *
+ * None.
+ *
+ */
+void
+XpOidLinkedListAddOid(XpOidLinkedList* me, XpOid oid)
+{
+ me->current = (XpOidNode)XpOidCalloc(1, sizeof(struct XpOidNodeStruct));
+ me->current->oid = oid;
+ ++me->count;
+ if(me->tail)
+ {
+ me->tail->next = me->current;
+ me->tail = me->current;
+ }
+ else
+ me->head = me->tail = me->current;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListGetIndex
+ *
+ * Description:
+ *
+ * Returns the position of an oid in a XpOidLinkedList.
+ *
+ * Return value:
+ *
+ * The zero-based position of 'oid' in the list.
+ *
+ * -1 if the oid is not in the list, or if 'me' is NULL.
+ *
+ */
+int
+XpOidLinkedListGetIndex(XpOidLinkedList* me, XpOid oid)
+{
+ if((XpOidLinkedList*)NULL != me)
+ {
+ int i = 0;
+ me->current = me->head;
+ while(me->current)
+ if(me->current->oid == oid)
+ {
+ return i;
+ }
+ else
+ {
+ ++i;
+ me->current = me->current->next;
+ }
+ }
+ return -1;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListHasOid
+ *
+ * Description:
+ *
+ * Determines if an oid is an element of a XpOidLinkedList.
+ *
+ * Return value:
+ *
+ * xTrue if the oid is found in the list.
+ *
+ * xFalse if the oid is not in the list, or if 'me' is NULL.
+ */
+BOOL
+XpOidLinkedListHasOid(XpOidLinkedList* me,
+ XpOid oid)
+{
+ if((XpOidLinkedList*)NULL != me)
+ {
+ me->current = me->head;
+ while(me->current)
+ if(me->current->oid == oid)
+ return xTrue;
+ else
+ me->current = me->current->next;
+ }
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListFirstOid
+ *
+ * Description:
+ *
+ * Positions the XpOidLinkedList 'current' pointer to the first entry
+ * in the list.
+ *
+ * Return value:
+ *
+ * The first oid in the list, or xpoid_none if the list NULL or
+ * empty.
+ */
+XpOid
+XpOidLinkedListFirstOid(XpOidLinkedList* me)
+{
+ if((XpOidLinkedList*)NULL != me && (me->current = me->head))
+ return me->current->oid;
+ else
+ return xpoid_none;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidLinkedListNextOid
+ *
+ * Description:
+ *
+ * Positions the XpOidLinkedList 'current' pointer to the next entry
+ * in the list.
+ *
+ * Return value:
+ *
+ * The next oid, or xpoid_none if the end of the list has been
+ * reached.
+ */
+XpOid
+XpOidLinkedListNextOid(XpOidLinkedList* me)
+{
+ if(me->current ? (me->current = me->current->next) : xFalse)
+ return me->current->oid;
+ else
+ return xpoid_none;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidMediumSSNew
+ *
+ * Description:
+ *
+ * Creates a new XpOidMediumSS initialized from a string value
+ * specified using the medium-source-sizes syntax. See
+ * MediumSSParse() below for parsing details.
+ *
+ * Return value:
+ *
+ * NULL if the passed 'value_string' is NULL, or if a syntax error is
+ * encountered while parsing the medium-source-sizes value.
+ *
+ */
+XpOidMediumSS*
+XpOidMediumSSNew(const char* value_string,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_medium_sizes)
+{
+ if(value_string == (const char*)NULL)
+ return (XpOidMediumSS*)NULL;
+ else
+ {
+ const char* ptr = value_string + SpanWhitespace(value_string);
+ if(*ptr == '\0')
+ return (XpOidMediumSS*)NULL;
+ else
+ return MediumSSParse(ptr, valid_trays, valid_medium_sizes,
+ &ptr, 0);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: MediumSSParse
+ *
+ * Description:
+ *
+ * 'ptr_return' *cannot* be NULL.
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+static XpOidMediumSS*
+MediumSSParse(const char* value_string,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_medium_sizes,
+ const char** ptr_return,
+ int i)
+{
+ XpOidMediumSS* medium_ss;
+ XpOidMediumSourceSize mss;
+ /*
+ * check for the start of a new MediumSourceSize sequence
+ */
+ if(ParseSeqStart(value_string, ptr_return))
+ {
+ /*
+ * check for an unspecified tray value
+ */
+ if(ParseUnspecifiedValue(*ptr_return, ptr_return))
+ mss.input_tray = xpoid_unspecified;
+ else
+ {
+ const char* tray_str;
+ *ptr_return += SpanWhitespace(*ptr_return);
+ tray_str = *ptr_return;
+ /*
+ * parse out the input tray
+ */
+ mss.input_tray = XpOidParse(*ptr_return, ptr_return);
+ if((const XpOidList*)NULL != valid_trays
+ &&
+ !XpOidListHasOid(valid_trays, mss.input_tray)
+ )
+ mss.input_tray = xpoid_none;
+ if(xpoid_none == mss.input_tray)
+ {
+ char* invalid_tray_str;
+ int len = *ptr_return - tray_str;
+ if(len > 0)
+ {
+ invalid_tray_str = XpOidMalloc(len+1);
+ strncpy(invalid_tray_str, tray_str, len);
+ invalid_tray_str[len] = '\0';
+ ErrorF("%s\nInvalid tray (%s) found. Will attempt to continue parsing.\n",
+ XPMSG_WARN_MSS, invalid_tray_str);
+ XpOidFree(invalid_tray_str);
+ }
+ }
+ }
+ /*
+ * attempt to parse a Continuous MediumSize sequence
+ */
+ mss.ms.continuous_size =
+ MediumContinuousSizeParse(*ptr_return, ptr_return);
+ if(mss.ms.continuous_size != (XpOidMediumContinuousSize*)NULL)
+ {
+ mss.mstag = XpOidMediumSS_CONTINUOUS;
+ }
+ else
+ {
+ /*
+ * not continuous, try Discrete MediumSize
+ */
+ mss.ms.discrete =
+ MediumDiscreteSizeListParse(*ptr_return, valid_medium_sizes,
+ ptr_return, 0);
+ if(mss.ms.discrete == (XpOidMediumDiscreteSizeList*)NULL)
+ {
+ const char* tray_str;
+ /*
+ * syntax error (MediumDiscreteSizeListParse reports error)
+ */
+ switch(mss.input_tray)
+ {
+ case xpoid_none:
+ tray_str = "an invalid";
+ break;
+ case xpoid_unspecified:
+ tray_str = "default (tray specifier omitted)";
+ break;
+ default:
+ tray_str = XpOidString(mss.input_tray);
+ break;
+ }
+ ErrorF("%s\nError occurred while parsing medium sizes for %s tray.\n",
+ XPMSG_WARN_MSS, tray_str);
+ return NULL;
+ }
+ mss.mstag = XpOidMediumSS_DISCRETE;
+ }
+ /*
+ * parse out the MediumSourceSize sequence end
+ */
+ if(!ParseSeqEnd(*ptr_return, ptr_return))
+ {
+ /*
+ * syntax error
+ */
+ ErrorF("%s\nSequence End expected. Unparsed data: %s\n",
+ XPMSG_WARN_MSS, *ptr_return);
+ return NULL;
+ }
+ /*
+ * recurse to parse the next MediumSourceSize sequence
+ */
+ medium_ss = MediumSSParse(*ptr_return,
+ valid_trays, valid_medium_sizes,
+ ptr_return,
+ xpoid_none == mss.input_tray ? i : i+1);
+ if(medium_ss == (XpOidMediumSS*)NULL
+ ||
+ xpoid_none == mss.input_tray)
+ {
+ /*
+ * syntax error or invalid tray - clean up
+ */
+ switch(mss.mstag)
+ {
+ case XpOidMediumSS_CONTINUOUS:
+ MediumContinuousSizeDelete(mss.ms.continuous_size);
+ break;
+ case XpOidMediumSS_DISCRETE:
+ MediumDiscreteSizeListDelete(mss.ms.discrete);
+ break;
+ }
+ if(medium_ss == (XpOidMediumSS*)NULL)
+ /*
+ * syntax error - return
+ */
+ return NULL;
+ }
+ if(xpoid_none != mss.input_tray)
+ {
+ /*
+ * copy the current MediumSourceSize into the array
+ */
+ memmove((medium_ss->mss)+i, &mss, sizeof(XpOidMediumSourceSize));
+ }
+ }
+ else
+ {
+ /*
+ * MediumSourceSize sequence start not found
+ */
+ if(**ptr_return == '\0')
+ {
+ if(0 == i)
+ {
+ ErrorF("%s\nNo valid trays found.\n", XPMSG_WARN_MSS);
+ return NULL;
+ }
+ /*
+ * end of value string; allocate the MediumSS structure
+ */
+ medium_ss = (XpOidMediumSS*)XpOidCalloc(1, sizeof(XpOidMediumSS));
+ medium_ss->count = i;
+ medium_ss->mss = (XpOidMediumSourceSize*)
+ XpOidCalloc(i, sizeof(XpOidMediumSourceSize));
+ }
+ else
+ {
+ /*
+ * syntax error
+ */
+ ErrorF("%s\nSequence Start expected.\nunparsed data: %s\n",
+ XPMSG_WARN_MSS, *ptr_return);
+ return NULL;
+ }
+ }
+ return medium_ss;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidMediumSSDelete
+ *
+ * Description:
+ *
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+void
+XpOidMediumSSDelete(XpOidMediumSS* me)
+{
+ if(me != (XpOidMediumSS*)NULL)
+ {
+ int i;
+ for(i = 0; i < me->count; i++)
+ {
+ switch((me->mss)[i].mstag)
+ {
+ case XpOidMediumSS_CONTINUOUS:
+ MediumContinuousSizeDelete((me->mss)[i].ms.continuous_size);
+ break;
+ case XpOidMediumSS_DISCRETE:
+ MediumDiscreteSizeListDelete((me->mss)[i].ms.discrete);
+ break;
+ }
+ }
+ XpOidFree((char*)me);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidMediumSSHasSize
+ *
+ * Description:
+ *
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+BOOL
+XpOidMediumSSHasSize(XpOidMediumSS* me, XpOid page_size)
+{
+ int i_mss, i_ds;
+ XpOidMediumDiscreteSizeList* ds_list;
+
+ if(me != (XpOidMediumSS*)NULL && page_size != xpoid_none)
+ for(i_mss = 0; i_mss < me->count; i_mss++)
+ {
+ switch((me->mss)[i_mss].mstag)
+ {
+ case XpOidMediumSS_DISCRETE:
+ ds_list = (me->mss)[i_mss].ms.discrete;
+ for(i_ds = 0; i_ds < ds_list->count; i_ds++)
+ if(page_size == (ds_list->list)[i_ds].page_size)
+ return xTrue;
+ break;
+
+ case XpOidMediumSS_CONTINUOUS:
+ /*
+ * unsupported
+ */
+ break;
+ }
+ }
+ /*
+ * return
+ */
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidMediumSSString
+ *
+ * Description:
+ *
+ * Creates a string representation of an XpOidMediumSS structure.
+ *
+ * Return value:
+ *
+ * A newly allocated
+ *
+ */
+char* XpOidMediumSSString(const XpOidMediumSS* me)
+{
+ int itray, isize;
+ int valid_size_count;
+ int length;
+ char* str;
+ char* ptr;
+ XpOidMediumDiscreteSize* ds;
+ char buf[128];
+ /*
+ * determine the size of the string representation
+ */
+ for(itray = 0, length = 0; itray < XpOidMediumSSCount(me); itray++)
+ {
+ if(xpoid_none == me->mss[itray].input_tray
+ ||
+ XpOidMediumSS_CONTINUOUS == me->mss[itray].mstag)
+ {
+ /*
+ * skip invalid tray or unsupported continuous size spec
+ */
+ continue;
+ }
+ for(isize = 0, valid_size_count = 0;
+ isize < me->mss[itray].ms.discrete->count;
+ isize++)
+ {
+ ds = me->mss[itray].ms.discrete->list+isize;
+ if(ds->page_size == xpoid_none)
+ continue;
+ ++valid_size_count;
+ length += XpOidStringLength(ds->page_size);
+ length += ds->long_edge_feeds ? 4 : 5; /* "True" or "False" */
+#if defined(sun) && !defined(SVR4)
+ sprintf(buf, "{%.4f %.4f %.4f %.4f}",
+ ds->assured_reproduction_area.minimum_x,
+ ds->assured_reproduction_area.maximum_x,
+ ds->assured_reproduction_area.minimum_y,
+ ds->assured_reproduction_area.maximum_y);
+ length += strlen(buf);
+#else
+ length += sprintf(buf, "{%.4f %.4f %.4f %.4f}",
+ ds->assured_reproduction_area.minimum_x,
+ ds->assured_reproduction_area.maximum_x,
+ ds->assured_reproduction_area.minimum_y,
+ ds->assured_reproduction_area.maximum_y);
+#endif
+ length += 5; /* "{<size> <feed> <area>} " */
+ }
+ if(valid_size_count == 0)
+ {
+ /*
+ * no valid sizes, skip
+ */
+ continue;
+ }
+ if(xpoid_unspecified == me->mss[itray].input_tray)
+ length += 2; /* "''" */
+ else
+ length += XpOidStringLength(me->mss[itray].input_tray);
+ length += 4; /* "{<tray> <sizes>} " */
+ }
+ /*
+ * allocate
+ */
+ str = XpOidMalloc(length+1);
+ /*
+ * format
+ */
+ for(itray = 0, ptr = str; itray < XpOidMediumSSCount(me); itray++)
+ {
+ if(xpoid_none == me->mss[itray].input_tray
+ ||
+ XpOidMediumSS_CONTINUOUS == me->mss[itray].mstag)
+ {
+ /*
+ * skip invalid tray or unsupported continuous size spec
+ */
+ continue;
+ }
+ /*
+ * check to ensure all of the specified sizes are valid
+ */
+ for(isize = 0, valid_size_count = 0;
+ isize < me->mss[itray].ms.discrete->count;
+ isize++)
+ {
+ ds = me->mss[itray].ms.discrete->list+isize;
+ if(ds->page_size != xpoid_none)
+ ++valid_size_count;
+ }
+ if(valid_size_count == 0)
+ {
+ /*
+ * no valid sizes, skip
+ */
+ continue;
+ }
+
+ if(xpoid_unspecified == me->mss[itray].input_tray)
+ {
+#if defined(sun) && !defined(SVR4)
+ sprintf(ptr, "{'' ");
+ ptr += strlen(ptr);
+#else
+ ptr += sprintf(ptr, "{'' ");
+#endif
+ }
+ else
+ {
+#if defined(sun) && !defined(SVR4)
+ sprintf(ptr, "{%s ", XpOidString(me->mss[itray].input_tray));
+ ptr += strlen(ptr);
+#else
+ ptr += sprintf(ptr, "{%s ",
+ XpOidString(me->mss[itray].input_tray));
+#endif
+ }
+ for(isize = 0; isize < me->mss[itray].ms.discrete->count; isize++)
+ {
+ ds = me->mss[itray].ms.discrete->list+isize;
+ if(ds->page_size != xpoid_none)
+#if defined(sun) && !defined(SVR4)
+ {
+ sprintf(ptr, "{%s %s {%.4f %.4f %.4f %.4f}} ",
+ XpOidString(ds->page_size),
+ ds->long_edge_feeds ? "True" : "False",
+ ds->assured_reproduction_area.minimum_x,
+ ds->assured_reproduction_area.maximum_x,
+ ds->assured_reproduction_area.minimum_y,
+ ds->assured_reproduction_area.maximum_y);
+ ptr += strlen(ptr);
+ }
+#else
+ ptr += sprintf(ptr, "{%s %s {%.4f %.4f %.4f %.4f}} ",
+ XpOidString(ds->page_size),
+ ds->long_edge_feeds ? "True" : "False",
+ ds->assured_reproduction_area.minimum_x,
+ ds->assured_reproduction_area.maximum_x,
+ ds->assured_reproduction_area.minimum_y,
+ ds->assured_reproduction_area.maximum_y);
+#endif
+ }
+#if defined(sun) && !defined(SVR4)
+ sprintf(ptr, "} ");
+ ptr += strlen(ptr);
+#else
+ ptr += sprintf(ptr, "} ");
+#endif
+ }
+ /*
+ * chop trailing whitespace or terminate empty string
+ */
+ str[length] = '\0';
+ /*
+ * return
+ */
+ return str;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: MediumContinuousSizeParse
+ *
+ * Description:
+ *
+ * 'ptr_return' *cannot* be NULL.
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+static XpOidMediumContinuousSize*
+MediumContinuousSizeParse(const char* value_string,
+ const char** ptr_return)
+{
+ const char* first_nonws_ptr;
+ XpOidMediumContinuousSize* mcs = NULL;
+ /*
+ * skip leading whitespace
+ */
+ first_nonws_ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * parse out the MediumSize sequence start char
+ */
+ if(!ParseSeqStart(first_nonws_ptr, ptr_return))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * peek ahead to see if it looks like we actually have a continuous
+ * size spec (looking for the sequence start char on the 1st range spec)
+ */
+ if(!ParseSeqStart(*ptr_return, (const char**)NULL))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * Ok, let's go for it
+ */
+ mcs = (XpOidMediumContinuousSize*)
+ XpOidCalloc(1, sizeof(XpOidMediumContinuousSize));
+ /*
+ * "range across the feed direction"
+ */
+ if(!ParseRealRange(*ptr_return, ptr_return, &mcs->range_across_feed))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * "increment across the feed direction" (optional, default 0)
+ */
+ if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
+ if(!ParseRealValue(*ptr_return, ptr_return,
+ &mcs->increment_across_feed))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * "range in the feed direction"
+ */
+ if(!ParseRealRange(*ptr_return, ptr_return, &mcs->range_in_feed))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * "increment in the feed direction" (optional, default 0)
+ */
+ if(!ParseUnspecifiedValue(*ptr_return, ptr_return))
+ if(!ParseRealValue(*ptr_return, ptr_return,
+ &mcs->increment_in_feed))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * "long edge feeds" flag (default TRUE)
+ */
+ if(ParseUnspecifiedValue(*ptr_return, ptr_return))
+ mcs->long_edge_feeds = xTrue;
+ else
+ if(!ParseBoolValue(*ptr_return, ptr_return, &mcs->long_edge_feeds))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * "generic assured reproduction area"
+ */
+ if(!ParseArea(*ptr_return, ptr_return, &mcs->assured_reproduction_area))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * parse out the MediumSize sequence end character
+ */
+ if(!ParseSeqEnd(*ptr_return, ptr_return))
+ goto MediumContinuousSizeParse_error;
+ /*
+ * return
+ */
+ return mcs;
+
+
+ MediumContinuousSizeParse_error:
+ /*
+ * syntax error - don't log since this function may be called
+ * as a lookahead
+ */
+ *ptr_return = first_nonws_ptr;
+ XpOidFree((char*)mcs);
+ return NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: MediumContinuousSizeDelete
+ *
+ * Description:
+ *
+ * 'ptr_return' *cannot* be NULL.
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+static void
+MediumContinuousSizeDelete(XpOidMediumContinuousSize* me)
+{
+ XpOidFree((char*)me);
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: MediumDiscreteSizeListParse
+ *
+ * Description:
+ *
+ * 'ptr_return' *cannot* be NULL.
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+static XpOidMediumDiscreteSizeList*
+MediumDiscreteSizeListParse(const char* value_string,
+ const XpOidList* valid_medium_sizes,
+ const char** ptr_return,
+ int i)
+{
+ XpOidMediumDiscreteSizeList* list;
+ XpOidMediumDiscreteSize mds;
+ /*
+ * check for the start of a new MediumSize sequence
+ */
+ if(ParseSeqStart(value_string, ptr_return))
+ {
+ /*
+ * "page size"
+ */
+ mds.page_size = XpOidParse(*ptr_return, ptr_return);
+ if((const XpOidList*)NULL != valid_medium_sizes
+ &&
+ !XpOidListHasOid(valid_medium_sizes, mds.page_size)
+ )
+ mds.page_size = xpoid_none;
+ /*
+ * "long edge feeds" flag (default TRUE)
+ */
+ if(ParseUnspecifiedValue(*ptr_return, ptr_return))
+ mds.long_edge_feeds = xTrue;
+ else
+ if(!ParseBoolValue(*ptr_return, ptr_return,
+ &mds.long_edge_feeds))
+ {
+ /*
+ * syntax error
+ */
+ ErrorF("%s\nBoolean expected.\nunparsed data: %s\n",
+ XPMSG_WARN_MSS, *ptr_return);
+ return (XpOidMediumDiscreteSizeList*)NULL;
+ }
+ /*
+ * "assured reproduction area"
+ */
+ if(!ParseArea(*ptr_return, ptr_return,
+ &mds.assured_reproduction_area))
+ {
+ /*
+ * syntax error
+ */
+ ErrorF("%s\nArea specification error.\nunparsed data: %s\n",
+ XPMSG_WARN_MSS, *ptr_return);
+ return (XpOidMediumDiscreteSizeList*)NULL;
+ }
+ /*
+ * parse out the MediumSize sequence end character
+ */
+ if(!ParseSeqEnd(*ptr_return, ptr_return))
+ {
+ ErrorF("%s\nSequence End expected. Unparsed data: %s\n",
+ XPMSG_WARN_MSS, *ptr_return);
+ return (XpOidMediumDiscreteSizeList*)NULL;
+ }
+ /*
+ * recurse to parse the next Discrete MediumSize sequence
+ */
+ if(mds.page_size == xpoid_none)
+ {
+ list = MediumDiscreteSizeListParse(*ptr_return, valid_medium_sizes,
+ ptr_return, i);
+ }
+ else
+ {
+ list = MediumDiscreteSizeListParse(*ptr_return, valid_medium_sizes,
+ ptr_return, i+1);
+ if(list != (XpOidMediumDiscreteSizeList*)NULL)
+ {
+ /*
+ * copy the current discrete MediumSize into the list
+ */
+ memmove((list->list)+i, &mds, sizeof(XpOidMediumDiscreteSize));
+ }
+ }
+ }
+ else
+ {
+ /*
+ * MediumSize sequence start not found; end of the discrete sizes
+ * list
+ */
+ if(0 == i)
+ {
+ ErrorF("%s\nNo valid medium sizes found for tray.\n",
+ XPMSG_WARN_MSS);
+ return (XpOidMediumDiscreteSizeList*)NULL;
+ }
+ list = (XpOidMediumDiscreteSizeList*)
+ XpOidCalloc(1, sizeof(XpOidMediumDiscreteSizeList));
+ list->count = i;
+ list->list = (XpOidMediumDiscreteSize*)
+ XpOidCalloc(i, sizeof(XpOidMediumDiscreteSize));
+ }
+ return list;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: MediumDiscreteSizeListDelete
+ *
+ * Description:
+ *
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+static void
+MediumDiscreteSizeListDelete(XpOidMediumDiscreteSizeList* list)
+{
+ if(list != (XpOidMediumDiscreteSizeList*)NULL)
+ {
+ XpOidFree((char*)list->list);
+ XpOidFree((char*)list);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidTrayMediumListNew
+ *
+ * Description:
+ *
+ * Only need the valid trays; validation requires bumping up against
+ * msss using TrayMediumListValidate; this needs valid trays
+ * because of unspecified trays ion msss, but
+ * TrayMediumListValidate will take care of invalid sizes...
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+XpOidTrayMediumList*
+XpOidTrayMediumListNew(const char* value_string,
+ const XpOidList* valid_trays,
+ const XpOidMediumSS* msss)
+{
+ if(value_string == (const char*)NULL)
+ return (XpOidTrayMediumList*)NULL;
+ else
+ {
+ const char* ptr;
+ XpOidTrayMediumList* me;
+ me = TrayMediumListParse(value_string, valid_trays, &ptr, 0);
+ if((XpOidTrayMediumList*)NULL != me)
+ TrayMediumListValidate(me, msss);
+ return me;
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidTrayMediumListDelete
+ *
+ * Description:
+ *
+ *
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+void
+XpOidTrayMediumListDelete(XpOidTrayMediumList* list)
+{
+ if(list != (XpOidTrayMediumList*)NULL)
+ {
+ XpOidFree((char*)list->list);
+ XpOidFree((char*)list);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: TrayMediumListParse
+ *
+ * Description:
+ *
+ * 'ptr_return' *cannot* be NULL.
+ *
+ * Return value:
+ *
+ *
+ *
+ */
+static XpOidTrayMediumList*
+TrayMediumListParse(const char* value_string,
+ const XpOidList* valid_trays,
+ const char** ptr_return, int i)
+{
+ XpOidTrayMedium tm;
+ XpOidTrayMediumList* list;
+ /*
+ * check for the start of a new InputTrayMedium sequence
+ */
+ if(ParseSeqStart(value_string, ptr_return))
+ {
+ /*
+ * "input tray"
+ */
+ tm.input_tray = XpOidParse(*ptr_return, ptr_return);
+ if((XpOidList*)NULL != valid_trays
+ &&
+ !XpOidListHasOid(valid_trays, tm.input_tray)
+ )
+ tm.input_tray = xpoid_none;
+ /*
+ * "medium"
+ */
+ tm.medium = XpOidParse(*ptr_return, ptr_return);
+ /*
+ * parse out the InputTrayMedium sequence end character
+ */
+ if(!ParseSeqEnd(*ptr_return, ptr_return))
+ {
+ ErrorF("%s\n", XPMSG_WARN_ITM);
+ return NULL;
+ }
+ /*
+ * recurse to parse the next InputTrayMedium sequence
+ */
+ list = TrayMediumListParse(*ptr_return, valid_trays, ptr_return, i+1);
+ if(list != (XpOidTrayMediumList*)NULL)
+ {
+ /*
+ * copy the current InputTrayMedium into the list
+ */
+ memmove((list->list)+i, &tm, sizeof(XpOidTrayMedium));
+ }
+ }
+ else
+ {
+ /*
+ * InputTrayMedium sequence start not found
+ */
+ if(**ptr_return == '\0')
+ {
+ /*
+ * end of the list
+ */
+ list = (XpOidTrayMediumList*)
+ XpOidCalloc(1, sizeof(XpOidTrayMediumList));
+ list->count = i;
+ list->list = (XpOidTrayMedium*)
+ XpOidCalloc(i, sizeof(XpOidTrayMedium));
+ }
+ else
+ {
+ /*
+ * syntax error
+ */
+ ErrorF("%s\n", XPMSG_WARN_ITM);
+ return NULL;
+ }
+ }
+ /*
+ * return
+ */
+ return list;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: TrayMediumListValidate
+ *
+ * Description:
+ *
+ * Validate the input-trays-medium list based on a passed
+ * medium-source-sizes-supported structure. The validated
+ * input-trays-medium list will have the same number of entries upon
+ * return from this function. Invalid entries are indicated by
+ * setting the tray specification to xpoid_none.
+ *
+ * Return value:
+ *
+ * None.
+ *
+ */
+static void
+TrayMediumListValidate(XpOidTrayMediumList* me,
+ const XpOidMediumSS* msss)
+{
+ int i_mss, i_ds, i_itm;
+ XpOid current_tray, current_medium;
+ XpOidMediumDiscreteSizeList* unspecified_tray_ds;
+ XpOidMediumDiscreteSizeList* tray_ds;
+
+ if(msss == (XpOidMediumSS*)NULL
+ ||
+ me == (XpOidTrayMediumList*)NULL)
+ {
+ return;
+ }
+ /*
+ * loop through the input trays medium list
+ */
+ for(i_itm = 0; i_itm < XpOidTrayMediumListCount(me); i_itm++)
+ {
+ current_tray = XpOidTrayMediumListTray(me, i_itm);
+ if(current_tray == xpoid_none)
+ continue;
+ current_medium = XpOidTrayMediumListMedium(me, i_itm);
+ if(current_medium == xpoid_none)
+ {
+ /*
+ * no medium; invalidate this entry
+ */
+ me->list[i_itm].input_tray = xpoid_none;
+ continue;
+ }
+ /*
+ * loop through the MediumSourceSizes, looking for an appropriate
+ * discrete sizes spec for the current tray
+ */
+ unspecified_tray_ds = (XpOidMediumDiscreteSizeList*)NULL;
+ tray_ds = (XpOidMediumDiscreteSizeList*)NULL;
+ for(i_mss = 0;
+ i_mss < msss->count &&
+ tray_ds == (XpOidMediumDiscreteSizeList*)NULL;
+ i_mss++)
+ {
+ switch((msss->mss)[i_mss].mstag)
+ {
+ case XpOidMediumSS_DISCRETE:
+ if((msss->mss)[i_mss].input_tray == current_tray)
+ tray_ds = (msss->mss)[i_mss].ms.discrete;
+ else if((msss->mss)[i_mss].input_tray == xpoid_unspecified)
+ unspecified_tray_ds = (msss->mss)[i_mss].ms.discrete;
+ break;
+
+ case XpOidMediumSS_CONTINUOUS:
+ /*
+ * unsupported
+ */
+ break;
+ }
+ }
+ /*
+ * if the tray was not matched, use the unspecified tray size
+ * list
+ */
+ if(tray_ds == (XpOidMediumDiscreteSizeList*)NULL)
+ {
+ if(unspecified_tray_ds == (XpOidMediumDiscreteSizeList*)NULL)
+ {
+ /*
+ * not even an unspecified tray, invalidate this
+ * input-trays-medium entry.
+ */
+ me->list[i_itm].input_tray = xpoid_none;
+ continue;
+ }
+ else
+ tray_ds = unspecified_tray_ds;
+ }
+ /*
+ * loop through the discrete sizes list, looking for a size that
+ * matches the medium for the current input tray
+ */
+ for(i_ds = 0; i_ds < tray_ds->count; i_ds++)
+ {
+ /*
+ * check to see if the current input tray's medium size
+ * matches the current discrete size
+ *
+ * Note: in the CDEnext SI, medium identifiers coincide with
+ * medium-size identifiers. If the DP-Medium object is
+ * ever implemented, this check would need to be
+ * changed so that the input tray's medium size is
+ * obtained from the indicated Medium object, and not
+ * inferred from the medium identifier itself.
+ */
+ if((tray_ds->list)[i_ds].page_size == current_medium)
+ {
+ /*
+ * The current input tray's medium size matches the
+ * current discrete medium size.
+ */
+ break;
+ }
+ }
+ if(i_ds == tray_ds->count)
+ {
+ /*
+ * The current input tray's medium size was not found in the
+ * discrete size list; mark the input tray medium entry
+ * invalid
+ */
+ me->list[i_itm].input_tray = xpoid_none;
+ }
+
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidTrayMediumListString
+ *
+ * Description:
+ *
+ * Creates a string representation of an XpOidTrayMediumList structure.
+ *
+ * Return value:
+ *
+ * A newly allocated
+ *
+ */
+char* XpOidTrayMediumListString(const XpOidTrayMediumList* me)
+{
+ int i;
+ int length;
+ char* str;
+ char* ptr;
+ XpOid tray;
+ /*
+ * allocate enough memory for the string representation,
+ * including intervening delimiters and whitespace
+ */
+ for(i = 0, length = 0; i < XpOidTrayMediumListCount(me); i++)
+ {
+ tray = XpOidTrayMediumListTray(me, i);
+ if(xpoid_none != tray)
+ {
+ length += XpOidStringLength(tray);
+ length += XpOidStringLength(XpOidTrayMediumListMedium(me, i));
+ length += 4;
+ }
+ }
+ str = XpOidMalloc(length+1);
+ /*
+ * format the list
+ */
+ for(i = 0, ptr = str; i < XpOidTrayMediumListCount(me); i++)
+ {
+ tray = XpOidTrayMediumListTray(me, i);
+ if(xpoid_none != tray)
+ {
+#if defined(sun) && !defined(SVR4)
+ sprintf(ptr, "{%s %s} ",
+ XpOidString(tray),
+ XpOidString(XpOidTrayMediumListMedium(me, i)));
+ ptr += strlen(ptr);
+#else
+ ptr += sprintf(ptr, "{%s %s} ",
+ XpOidString(tray),
+ XpOidString(XpOidTrayMediumListMedium(me, i)));
+#endif
+ }
+ }
+ /*
+ * chop trailing whitespace or terminate empty string
+ */
+ str[length] = '\0';
+ /*
+ * return
+ */
+ return str;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidTrayMediumListHasTray
+ *
+ * Description:
+ *
+ * Determines if 'tray' is found in 'list'.
+ *
+ * Return value:
+ *
+ * xTrue if the tray is found in the list.
+ *
+ * xFalse if the tray is not in the list, or if 'list' is NULL.
+ *
+ */
+BOOL
+XpOidTrayMediumListHasTray(const XpOidTrayMediumList* list, XpOid tray)
+{
+ int i;
+ if(list != (XpOidTrayMediumList*)NULL && tray != xpoid_none)
+ for(i = 0; i < list->count; i++)
+ if(XpOidTrayMediumListTray(list, i) == tray)
+ return xTrue;
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseArea
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out and returns a XpOidArea.
+ *
+ * Return value:
+ *
+ * xTrue if the XpOidArea was successfully parsed. ptr_return is
+ * updated to point to location where the parsing ended.
+ *
+ * xFalse if a XpOidArea was not found; ptr_return is updated
+ * to point to the first non-whitespace char in value_string.
+ *
+ */
+static BOOL
+ParseArea(const char* value_string,
+ const char** ptr_return,
+ XpOidArea* area_return)
+{
+ const char* first_nonws_ptr;
+ const char* ptr;
+ /*
+ * skip leading whitespace
+ */
+ first_nonws_ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * parse out the area sequence start
+ */
+ if(!ParseSeqStart(first_nonws_ptr, &ptr))
+ goto ParseArea_error;
+ /*
+ * parse the minimum x value
+ */
+ if(!ParseRealValue(ptr, &ptr,
+ area_return ? &area_return->minimum_x : NULL))
+ goto ParseArea_error;
+ /*
+ * parse the maximum x value
+ */
+ if(!ParseRealValue(ptr, &ptr,
+ area_return ? &area_return->maximum_x : NULL))
+ goto ParseArea_error;
+ /*
+ * parse the minimum y value
+ */
+ if(!ParseRealValue(ptr, &ptr,
+ area_return ? &area_return->minimum_y : NULL))
+ goto ParseArea_error;
+ /*
+ * parse the maximum y value
+ */
+ if(!ParseRealValue(ptr, &ptr,
+ area_return ? &area_return->maximum_y : NULL))
+ goto ParseArea_error;
+ /*
+ * parse out the area sequence end
+ */
+ if(!ParseSeqEnd(ptr, &ptr))
+ goto ParseArea_error;
+ /*
+ * update the return pointer
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ /*
+ * return
+ */
+ return xTrue;
+
+
+ ParseArea_error:
+ /*
+ * syntax error
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = first_nonws_ptr;
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseRealRange
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out and returns a
+ * XpOidRealRange.
+ *
+ * Return value:
+ *
+ * xTrue if the XpOidRealRange was successfully
+ * parsed. ptr_return is updated to point to location where the
+ * parsing ended.
+ *
+ * xFalse if a XpOidRealRange was not found; ptr_return is
+ * updated to point to the first non-whitespace char in value_string.
+ *
+ */
+static BOOL
+ParseRealRange(const char* value_string,
+ const char** ptr_return,
+ XpOidRealRange* range_return)
+{
+ const char* first_nonws_ptr;
+ const char* ptr;
+ /*
+ * skip leading whitespace
+ */
+ first_nonws_ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * parse out the range sequence start
+ */
+ if(!ParseSeqStart(first_nonws_ptr, &ptr))
+ goto ParseRealRange_error;
+ /*
+ * parse the lower bound
+ */
+ if(!ParseRealValue(ptr, &ptr,
+ range_return ? &range_return->lower_bound : NULL))
+ goto ParseRealRange_error;
+ /*
+ * parse the upper bound
+ */
+ if(!ParseRealValue(ptr, &ptr,
+ range_return ? &range_return->upper_bound : NULL))
+ goto ParseRealRange_error;
+ /*
+ * parse out the range sequence end
+ */
+ if(!ParseSeqEnd(ptr, &ptr))
+ goto ParseRealRange_error;
+ /*
+ * update the return pointer
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ /*
+ * return
+ */
+ return xTrue;
+
+
+ ParseRealRange_error:
+ /*
+ * syntax error
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = first_nonws_ptr;
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidNotifyParse
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+XpOidNotify XpOidNotifyParse(const char* value_string)
+{
+ const char* ptr = value_string;
+
+ if(value_string == (const char*)NULL)
+ return XPOID_NOTIFY_NONE;
+ /*
+ * look for an event handling profile sequence start
+ */
+ if(!ParseSeqStart(value_string, &ptr))
+ {
+ if('\0' == *ptr)
+ /*
+ * empty value is valid
+ */
+ return XPOID_NOTIFY_NONE;
+ else
+ return XPOID_NOTIFY_UNSUPPORTED;
+ }
+ /*
+ * look for an event set sequence start
+ */
+ if(!ParseSeqStart(ptr, &ptr))
+ {
+ /*
+ * check for an empty event handling profile
+ */
+ if(ParseSeqEnd(ptr, &ptr))
+ {
+ ptr += SpanWhitespace(ptr);
+ if(*ptr == '\0')
+ /*
+ * valid empty event handling profile sequence
+ */
+ return XPOID_NOTIFY_NONE;
+ }
+ return XPOID_NOTIFY_UNSUPPORTED;
+ }
+ /*
+ * the only event in the set should be report job completed
+ */
+ if(xpoid_val_event_report_job_completed != XpOidParse(ptr, &ptr))
+ return XPOID_NOTIFY_UNSUPPORTED;
+ /*
+ * event set sequence end
+ */
+ if(!ParseSeqEnd(ptr, &ptr))
+ return XPOID_NOTIFY_UNSUPPORTED;
+ /*
+ * delivery method of electronic mail
+ */
+ if(xpoid_val_delivery_method_electronic_mail != XpOidParse(ptr, &ptr))
+ return XPOID_NOTIFY_UNSUPPORTED;
+ /*
+ * event handling profile sequence end
+ */
+ if(!ParseSeqEnd(ptr, &ptr))
+ return XPOID_NOTIFY_UNSUPPORTED;
+ /*
+ * end of value
+ */
+ ptr += SpanWhitespace(ptr);
+ if('\0' == *ptr)
+ /*
+ * valid supported notification profile
+ */
+ return XPOID_NOTIFY_EMAIL;
+ else
+ return XPOID_NOTIFY_UNSUPPORTED;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidNotifyString
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+const char* XpOidNotifyString(XpOidNotify notify)
+{
+ switch(notify)
+ {
+ case XPOID_NOTIFY_NONE:
+ return NOTIFY_NONE_STR;
+ case XPOID_NOTIFY_EMAIL:
+ return NOTIFY_EMAIL_STR;
+ case XPOID_NOTIFY_UNSUPPORTED:
+ return (const char *)NULL;
+ }
+
+ ErrorF("XpOidNotifyString: Unsupported notify=%ld\n", (long)notify);
+ return (const char *)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtNew
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+XpOidDocFmt*
+XpOidDocFmtNew(const char* value_string)
+{
+ XpOidDocFmt* doc_fmt;
+ const char* ptr;
+
+ if((const char*)NULL == value_string)
+ return (XpOidDocFmt*)NULL;
+ ptr = value_string + SpanWhitespace(value_string);
+ if('\0' == *ptr)
+ return (XpOidDocFmt*)NULL;
+ /*
+ * get the document format from the value string
+ */
+ doc_fmt = (XpOidDocFmt*)XpOidCalloc(1, sizeof(XpOidDocFmt));
+ if(xTrue == XpOidDocFmtNext(doc_fmt, ptr, &ptr))
+ {
+ /*
+ * verify that the document format is the only value specified
+ */
+ ptr += SpanWhitespace(ptr);
+ if('\0' == *ptr)
+ /*
+ * valid document-format value
+ */
+ return doc_fmt;
+ }
+ /*
+ * invalid
+ */
+ XpOidDocFmtDelete(doc_fmt);
+ ErrorF("%s\n", XPMSG_WARN_DOC_FMT);
+ return (XpOidDocFmt*)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtDelete
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+void
+XpOidDocFmtDelete(XpOidDocFmt* doc_fmt)
+{
+ if((XpOidDocFmt*)NULL != doc_fmt)
+ {
+ XpOidFree(doc_fmt->format);
+ XpOidFree(doc_fmt->variant);
+ XpOidFree(doc_fmt->version);
+ XpOidFree(doc_fmt);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtString
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+char*
+XpOidDocFmtString(XpOidDocFmt* doc_fmt)
+{
+ if((XpOidDocFmt*)NULL != doc_fmt)
+ {
+ if((char*)NULL != doc_fmt->format)
+ {
+ char* str = XpOidMalloc(1+SafeStrLen(doc_fmt->format)+
+ 1+SafeStrLen(doc_fmt->variant)+
+ 1+SafeStrLen(doc_fmt->version)+
+ 1+1);
+ sprintf(str, "{%s %s %s}", doc_fmt->format,
+ (char*)NULL != doc_fmt->variant ? doc_fmt->variant : "",
+ (char*)NULL != doc_fmt->version ? doc_fmt->version : "");
+ return str;
+ }
+ }
+ return (char*)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtNext
+ *
+ * Description:
+ *
+ * Assumes non-NULL value string.
+ *
+ * Return value:
+ *
+ *
+ */
+static BOOL
+XpOidDocFmtNext(XpOidDocFmt* doc_fmt,
+ const char* value_string,
+ const char** ptr_return)
+{
+ const char* ptr;
+ const char* first_nonws_ptr;
+ const char* format;
+ const char* variant;
+ const char* version;
+ int format_len;
+ int variant_len;
+ int version_len;
+ /*
+ * skip leading whitespace
+ */
+ ptr = value_string + SpanWhitespace(value_string);
+ first_nonws_ptr = ptr;
+ /*
+ * sequence start
+ */
+ if(!ParseSeqStart(ptr, &ptr))
+ goto XpOidDocFmtNext_error;
+ /*
+ * skip whitepace to the start of the document format, and save the
+ * location
+ */
+ ptr += SpanWhitespace(ptr);
+ format = ptr;
+ /*
+ * document format
+ */
+ if(0 == (format_len = SpanToken(ptr)))
+ goto XpOidDocFmtNext_error;
+ ptr += format_len;
+ /*
+ * optional variant
+ */
+ ptr += SpanWhitespace(ptr);
+ variant = ptr;
+ if(0 != (variant_len = SpanToken(ptr)))
+ {
+ ptr += variant_len;
+ /*
+ * optional version
+ */
+ ptr += SpanWhitespace(ptr);
+ version = ptr;
+ version_len = SpanToken(ptr);
+ ptr += version_len;
+ }
+ else
+ version_len = 0;
+ /*
+ * sequence end
+ */
+ if(!ParseSeqEnd(ptr, &ptr))
+ goto XpOidDocFmtNext_error;
+ /*
+ * update return pointer
+ */
+ if((const char**)NULL != ptr_return)
+ *ptr_return = ptr;
+ /*
+ * update the passed document format struct
+ */
+ memset(doc_fmt, 0, sizeof(XpOidDocFmt));
+ doc_fmt->format = XpOidMalloc(format_len+1);
+ strncpy(doc_fmt->format, format, format_len);
+ doc_fmt->format[format_len] = '\0';
+ if(0 < variant_len)
+ {
+ doc_fmt->variant = XpOidMalloc(variant_len+1);
+ strncpy(doc_fmt->variant, variant, variant_len);
+ doc_fmt->variant[variant_len] = '\0';
+ if(0 < version_len)
+ {
+ doc_fmt->version = XpOidMalloc(version_len+1);
+ strncpy(doc_fmt->version, version, version_len);
+ doc_fmt->version[version_len] = '\0';
+ }
+ }
+ return xTrue;
+
+ XpOidDocFmtNext_error:
+ if((const char**)NULL != ptr_return)
+ *ptr_return = first_nonws_ptr;
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtListNew
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+XpOidDocFmtList*
+XpOidDocFmtListNew(const char* value_string,
+ const XpOidDocFmtList* valid_fmts)
+{
+ if((char*)NULL != value_string)
+ {
+ const char* ptr;
+ return XpOidDocFmtListParse(value_string, valid_fmts, &ptr, 0);
+ }
+ return (XpOidDocFmtList*)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtListDelete
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+void
+XpOidDocFmtListDelete(XpOidDocFmtList* list)
+{
+ if((XpOidDocFmtList*)NULL != list)
+ {
+ int i;
+ for(i = 0; i < list->count; i++)
+ {
+ XpOidFree(list->list[i].format);
+ XpOidFree(list->list[i].variant);
+ XpOidFree(list->list[i].version);
+ }
+ XpOidFree(list->list);
+ XpOidFree(list);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtListString
+ *
+ * Description:
+ *
+ * Assumes the passed structure is valid.
+ *
+ * Return value:
+ *
+ *
+ */
+char*
+XpOidDocFmtListString(const XpOidDocFmtList* list)
+{
+ if((XpOidDocFmtList*)NULL != list)
+ {
+ if(0 < list->count)
+ {
+ int i;
+ int str_len;
+ char* str;
+ char* ptr;
+ /*
+ * allocate the return string
+ */
+ for(i = 0, str_len = 0; i < list->count; i++)
+ {
+ str_len +=
+ 1 + SafeStrLen(list->list[i].format) +
+ 1 + SafeStrLen(list->list[i].variant) +
+ 1 + SafeStrLen(list->list[i].version) + 2;
+ }
+ str = XpOidMalloc(str_len+1);
+ /*
+ * print the list into the string and return it
+ */
+ ptr = str;
+ for(i = 0; i < list->count; i++)
+ {
+ XpOidDocFmt* df = &list->list[i];
+
+#if defined(sun) && !defined(SVR4)
+ sprintf(ptr, "{%s %s %s} ",
+ df->format,
+ (char*)NULL != df->variant ? df->variant : "",
+ (char*)NULL != df->version ? df->version : "");
+ ptr += strlen(ptr);
+#else
+ ptr +=
+ sprintf(ptr, "{%s %s %s} ",
+ df->format,
+ (char*)NULL != df->variant ? df->variant : "",
+ (char*)NULL != df->version ? df->version : "");
+#endif
+ }
+ return str;
+ }
+ }
+ return (char*)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtListParse
+ *
+ * Description:
+ *
+ * Assumes the passed value_string and ptr_return are non-NULL.
+ *
+ * Return value:
+ *
+ *
+ */
+static XpOidDocFmtList*
+XpOidDocFmtListParse(const char* value_string,
+ const XpOidDocFmtList* valid_fmts,
+ const char** ptr_return,
+ int i)
+{
+ XpOidDocFmt doc_fmt;
+ XpOidDocFmtList* list;
+ BOOL status;
+ /*
+ * get the next document-format from the value string, skipping
+ * values not found in the passed list of valid formats
+ */
+ *ptr_return = value_string;
+ while((status = XpOidDocFmtNext(&doc_fmt, *ptr_return, ptr_return))
+ &&
+ (const XpOidDocFmtList*)NULL != valid_fmts
+ &&
+ !XpOidDocFmtListHasFmt(valid_fmts, &doc_fmt)
+ );
+
+ if(xFalse == status)
+ {
+ if('\0' == **ptr_return)
+ {
+ if(0 == i)
+ {
+ /*
+ * empty value string
+ */
+ return (XpOidDocFmtList*)NULL;
+ }
+ else
+ {
+ /*
+ * done parsing; allocate the list and return
+ */
+ list =
+ (XpOidDocFmtList*)XpOidCalloc(1, sizeof(XpOidDocFmtList));
+ list->count = i;
+ list->list = (XpOidDocFmt*)XpOidCalloc(i, sizeof(XpOidDocFmt));
+ return list;
+ }
+ }
+ else
+ {
+ /*
+ * invalid document format
+ */
+ ErrorF("%s\n", XPMSG_WARN_DOCFMT_LIST);
+ return (XpOidDocFmtList*)NULL;
+ }
+ }
+ else
+ {
+ /*
+ * recurse to parse remaining document formats
+ */
+ list = XpOidDocFmtListParse(*ptr_return, valid_fmts, ptr_return, i+1);
+ if((XpOidDocFmtList*)NULL != list)
+ {
+ /*
+ * add this doc fmt to the list
+ */
+ list->list[i].format = doc_fmt.format;
+ list->list[i].variant = doc_fmt.variant;
+ list->list[i].version = doc_fmt.version;
+ }
+ return list;
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidDocFmtListHasFmt
+ *
+ * Description:
+ *
+ * Assumes the passed structure is valid.
+ *
+ * Return value:
+ *
+ *
+ */
+BOOL
+XpOidDocFmtListHasFmt(const XpOidDocFmtList* list,
+ const XpOidDocFmt* fmt)
+{
+ int i;
+ if(list != (XpOidDocFmtList*)NULL
+ &&
+ fmt != (XpOidDocFmt*)NULL
+ &&
+ fmt->format != (char*)NULL
+ )
+ {
+ for(i = 0; i < list->count; i++)
+ {
+ /*
+ * formats must match
+ */
+ if(strcmp(fmt->format, list->list[i].format) != 0)
+ continue;
+ /*
+ * variants must both be NULL or match
+ */
+ if(fmt->variant == (char*)NULL)
+ {
+ if(list->list[i].variant == (char*)NULL)
+ return xTrue;
+ else
+ continue;
+ }
+ if(list->list[i].variant == (char*)NULL)
+ continue;
+ if(strcmp(fmt->variant, list->list[i].variant) != 0)
+ continue;
+ /*
+ * versions must both be NULL or match
+ */
+ if(fmt->version == (char*)NULL)
+ {
+ if(list->list[i].version == (char*)NULL)
+ return xTrue;
+ else
+ continue;
+ }
+ if(list->list[i].version == (char*)NULL)
+ continue;
+ if(strcmp(fmt->version, list->list[i].version) == 0)
+ return xTrue;
+ }
+ }
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidCardListNew
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+XpOidCardList*
+XpOidCardListNew(const char* value_string, const XpOidCardList* valid_cards)
+{
+ if((const char*)NULL != value_string)
+ {
+ const char* ptr;
+
+ return XpOidCardListParse(value_string, valid_cards, &ptr, 0);
+ }
+ else
+ return (XpOidCardList*)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidCardListDelete
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+void
+XpOidCardListDelete(XpOidCardList* list)
+{
+ if((XpOidCardList*)NULL != list)
+ {
+ XpOidFree(list->list);
+ XpOidFree(list);
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidCardListString
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+char*
+XpOidCardListString(const XpOidCardList* list)
+{
+ if((XpOidCardList*)NULL != list)
+ {
+ char buf[48];
+ int str_len;
+ char* str;
+ int i;
+ char* ptr;
+ /*
+ * allocate the output string
+ */
+ for(i = 0, str_len = 0; i < list->count; i++)
+#if defined(sun) && !defined(SVR4)
+ {
+ sprintf(buf, "%lu", list->list[i]) + 1;
+ str_len += strlen(buf);
+ }
+#else
+ str_len += sprintf(buf, "%lu", list->list[i]) + 1;
+#endif
+ str = XpOidMalloc(str_len+1);
+ /*
+ * write the list to the string
+ */
+ for(i = 0, ptr = str; i < list->count; i++)
+#if defined(sun) && !defined(SVR4)
+ {
+ sprintf(ptr, "%lu ", list->list[i]);
+ ptr += strlen(ptr);
+ }
+#else
+ ptr += sprintf(ptr, "%lu ", list->list[i]);
+#endif
+ return str;
+ }
+ else
+ return (char*)NULL;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidCardListHasCard
+ *
+ * Description:
+ *
+ * Determines if 'card' is an element of 'list'.
+ *
+ * Return value:
+ *
+ * xTrue if the card is found in the list.
+ *
+ * xFalse if the card is not in the list, or if 'list' is NULL.
+ *
+ */
+BOOL
+XpOidCardListHasCard(const XpOidCardList* list, unsigned long card)
+{
+ int i;
+ if(list != (XpOidCardList*)NULL)
+ for(i = 0; i < list->count; i++)
+ if(list->list[i] == card)
+ return xTrue;
+ return xFalse;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidCardListParse
+ *
+ * Description:
+ *
+ * Assumes the passed value_string and ptr_return are non-NULL.
+ *
+ * Return value:
+ *
+ *
+ */
+static XpOidCardList*
+XpOidCardListParse(const char* value_string,
+ const XpOidCardList* valid_cards,
+ const char** ptr_return,
+ int i)
+{
+ unsigned long card;
+ XpOidCardList* list;
+ BOOL status;
+
+ /*
+ * get the next card from the value string, skipping values not
+ * found in the passed list of valid cards
+ */
+ *ptr_return = value_string;
+ while((status = XpOidParseUnsignedValue(*ptr_return, ptr_return, &card))
+ &&
+ (const XpOidCardList*)NULL != valid_cards
+ &&
+ !XpOidCardListHasCard(valid_cards, card)
+ );
+
+ if(xFalse == status)
+ {
+ if('\0' == **ptr_return)
+ {
+ if(0 == i)
+ {
+ /*
+ * empty value string
+ */
+ return (XpOidCardList*)NULL;
+ }
+ else
+ {
+ /*
+ * done parsing; allocate the list and return
+ */
+ list = (XpOidCardList*)XpOidCalloc(1, sizeof(XpOidCardList));
+ list->count = i;
+ list->list =
+ (unsigned long*)XpOidCalloc(i, sizeof(unsigned long));
+ return list;
+ }
+ }
+ else
+ {
+ /*
+ * parsing error
+ */
+ ErrorF("%s\n", XPMSG_WARN_CARD_LIST);
+ return (XpOidCardList*)NULL;
+ }
+ }
+ else
+ {
+ /*
+ * recurse to parse remaining cardinal values
+ */
+ list = XpOidCardListParse(*ptr_return, valid_cards, ptr_return, i+1);
+ if((XpOidCardList*)NULL != list)
+ {
+ /*
+ * add this value to the list
+ */
+ list->list[i] = card;
+ }
+ return list;
+ }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseBoolValue
+ *
+ * Description:
+ *
+ *
+ * Return value:
+ *
+ *
+ */
+static BOOL
+ParseBoolValue(const char* value_string,
+ const char** ptr_return,
+ BOOL* bool_return)
+{
+ const char* ptr;
+ int length;
+ BOOL status;
+ /*
+ * skip leading whitespace
+ */
+ ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * get the whitespace-delimited token length
+ */
+ length = SpanToken(ptr);
+ /*
+ * determine if true or false or bad
+ */
+ if(StrnCaseCmp(ptr, "TRUE", length) == 0)
+ {
+ if(bool_return != (BOOL*)NULL)
+ *bool_return = xTrue;
+ status = xTrue;
+ }
+ else if(StrnCaseCmp(ptr, "FALSE", length) == 0)
+ {
+ if(bool_return != (BOOL*)NULL)
+ *bool_return = xFalse;
+ status = xTrue;
+ }
+ else
+ {
+ /*
+ * syntax error
+ */
+ status = xFalse;
+ }
+ /*
+ * update the return pointer and return
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = status ? ptr+length : ptr;
+ return status;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: XpOidParseUnsignedValue
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out and returns a unsigned number.
+ *
+ * Return value:
+ *
+ * xTrue if a unsigned number was successfully parsed. ptr_return is
+ * updated to point to location where the unsigned number parsing
+ * ended.
+ *
+ * xFalse if a unsigned number was not found; ptr_return is updated
+ * to point to the first non-whitespace char in value_string.
+ *
+ */
+BOOL
+XpOidParseUnsignedValue(const char* value_string,
+ const char** ptr_return,
+ unsigned long* unsigned_return)
+{
+ long value;
+ BOOL status;
+ const char* first_nonws_ptr;
+ const char* ptr;
+ /*
+ * skip leading whitespace
+ */
+ first_nonws_ptr = value_string + SpanWhitespace(value_string);
+ value = strtol(first_nonws_ptr, (char**)(&ptr), 0);
+ if(ptr == first_nonws_ptr || value < 0)
+ status = xFalse;
+ else
+ status = xTrue;
+ /*
+ * update return parms
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ if(unsigned_return != (unsigned long*)NULL)
+ *unsigned_return = (unsigned long)value;
+ /*
+ * return
+ */
+ return status;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseRealValue
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out and returns a real number.
+ *
+ * Return value:
+ *
+ * xTrue if a real number was successfully parsed. ptr_return is
+ * updated to point to location where the real number parsing
+ * ended.
+ *
+ * xFalse if a real number was not found; ptr_return is updated
+ * to point to the first non-whitespace char in value_string.
+ *
+ */
+static BOOL
+ParseRealValue(const char* value_string,
+ const char** ptr_return,
+ float* real_return)
+{
+ float real_value;
+ BOOL status;
+ const char* first_nonws_ptr;
+ const char* ptr;
+ /*
+ * skip leading whitespace
+ */
+ first_nonws_ptr = value_string + SpanWhitespace(value_string);
+ real_value = (float)strtod(first_nonws_ptr, (char**)(&ptr));
+ if(ptr == first_nonws_ptr)
+ status = xFalse;
+ else
+ status = xTrue;
+ /*
+ * update return parms
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ if(real_return != (float*)NULL)
+ *real_return = real_value;
+ /*
+ * return
+ */
+ return status;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseSeqEnd
+ *
+ * Description:
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out the sequence end
+ * character '}'.
+ *
+ * Return value:
+ *
+ * xTrue if the sequence end character was parsed; ptr_return is
+ * updated to point to the first char following the sequence end
+ * character.
+ *
+ * xFalse if the sequence end character was not found; ptr_return is
+ * updated to point to the first non-whitespace char in value_string.
+ *
+ */
+static BOOL
+ParseSeqEnd(const char* value_string,
+ const char** ptr_return)
+{
+ const char* ptr;
+ BOOL status;
+ /*
+ * skip leading whitespace
+ */
+ ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * parse out the sequence end character
+ */
+ if(*ptr == '}')
+ {
+ status = xTrue;
+ ++ptr;
+ }
+ else
+ status = xFalse;
+ /*
+ * update the return pointer
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ /*
+ * return
+ */
+ return status;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseSeqStart
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out the sequence start
+ * character '{'.
+ *
+ * Return value:
+ *
+ * xTrue if the sequence start character was parsed; ptr_return is
+ * updated to point to the first char following the sequence start
+ * character.
+ *
+ * xFalse if the sequence start character was not found; ptr_return is
+ * updated to point to the first non-whitespace char in value_string.
+ *
+ */
+static BOOL
+ParseSeqStart(const char* value_string,
+ const char** ptr_return)
+{
+ const char* ptr;
+ BOOL status;
+ /*
+ * skip leading whitespace
+ */
+ ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * parse out the sequence start character
+ */
+ if(*ptr == '{')
+ {
+ status = xTrue;
+ ++ptr;
+ }
+ else
+ status = xFalse;
+ /*
+ * update the return pointer
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ /*
+ * return
+ */
+ return status;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: ParseUnspecifiedValue
+ *
+ * Description:
+ *
+ * Skips leading whitespace and parses out an unspecified optional
+ * value (i.e. matching '' or "" - skips all data between the set of
+ * quotes).
+ *
+ * Return value:
+ *
+ * xTrue if an unspecified value was parsed; ptr_return is updated to
+ * point to the first char following the trailing quote.
+ *
+ * xFalse if an unspecified value was not found; ptr_return is updated
+ * to point to the first non-whitespace char in value_string.
+ *
+ */
+static BOOL
+ParseUnspecifiedValue(const char* value_string,
+ const char** ptr_return)
+{
+ BOOL status;
+ const char* ptr;
+ /*
+ * skip leading whitespace
+ */
+ ptr = value_string + SpanWhitespace(value_string);
+ /*
+ * parse out an unspecified optional value ('' or "")
+ */
+ if(*ptr == '\'' || *ptr == '"')
+ {
+ char delim[2];
+
+ if(ptr_return != (const char**)NULL)
+ {
+ delim[0] = *ptr;
+ delim[1] = '\0';
+ /*
+ * skip over the matching delimiter
+ */
+ ++ptr;
+ ptr += strcspn(ptr, delim);
+ if(*ptr != '\0')
+ ++ptr;
+ }
+ status = xTrue;
+ }
+ else
+ status = xFalse;
+ /*
+ * update the return pointer
+ */
+ if(ptr_return != (const char**)NULL)
+ *ptr_return = ptr;
+ /*
+ * return
+ */
+ return status;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: SpanToken
+ *
+ * Description:
+ *
+ * Returns the length of the initial segment of the passed string
+ * that consists entirely of non-whitespace and non-sequence
+ * delimiter characters.
+ *
+ *
+ */
+static int
+SpanToken(const char* string)
+{
+ const char* ptr;
+ for(ptr = string;
+ *ptr != '\0' && !isspace(*ptr) && *ptr != '{' && *ptr != '}';
+ ++ptr);
+ return ptr - string;
+}
+
+/*
+ * ------------------------------------------------------------------------
+ * Name: SpanWhitespace
+ *
+ * Description:
+ *
+ * Returns the length of the initial segment of the passed string
+ * that consists entirely of whitespace characters.
+ *
+ *
+ */
+static int
+SpanWhitespace(const char* string)
+{
+ const char* ptr;
+ for(ptr = string; *ptr != '\0' && isspace(*ptr); ++ptr);
+ return ptr - string;
+}
+
+#ifndef HAVE_STRCASECMP
+/*
+ * ------------------------------------------------------------------------
+ * Name: StrnCaseCmp
+ *
+ * Description:
+ *
+ * Implements strncasecmp() for those platforms that need it.
+ *
+ *
+ */
+static int
+StrnCaseCmp(const char *s1, const char *s2, size_t len)
+{
+ char c1, c2;
+ int result;
+
+ while (len--)
+ {
+ c1 = *s1++;
+ c2 = *s2++;
+ result = tolower(c1) - tolower(c2);
+
+ if (result != 0)
+ return result;
+ }
+
+ return 0;
+}
+#endif
diff --git a/hw/xprint/Oid.h b/hw/xprint/Oid.h
new file mode 100644
index 000000000..fc9f12a5b
--- /dev/null
+++ b/hw/xprint/Oid.h
@@ -0,0 +1,294 @@
+/* $Xorg: Oid.h,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _Xp_Oid_h
+#define _Xp_Oid_h
+
+#include <X11/Xproto.h>
+
+/*
+ * include the auto-generated XpOid enum definition
+ */
+#include "OidDefs.h"
+
+/*
+ * messages
+ */
+#define XPMSG_WARN_MSS "Syntax error parsing medium-source-sizes"
+#define XPMSG_WARN_ITM "Syntax error parsing input-trays-medium"
+#define XPMSG_WARN_DOC_FMT "Syntax error parsing document format"
+#define XPMSG_WARN_DOCFMT_LIST "Syntax error parsing document format list"
+#define XPMSG_WARN_CARD_LIST "Syntax error parsing cardinal list"
+
+/*
+ * macros for memory allocation
+ */
+#define XpOidMalloc(size) ((char*)Xalloc((unsigned long)(size)))
+#define XpOidCalloc(count, size) \
+ ((char*)Xcalloc((unsigned long)((count)*(size))))
+#define XpOidFree(mem) (Xfree((unsigned long*)(mem)))
+
+/*
+ * list of object identifiers
+ */
+typedef struct _XpOidList
+{
+ XpOid* list;
+ int count;
+} XpOidList;
+
+/*
+ * linked list of object identifiers
+ */
+typedef struct XpOidNodeStruct
+{
+ XpOid oid;
+ struct XpOidNodeStruct* next;
+} *XpOidNode;
+
+typedef struct _XpOidLinkedList
+{
+ XpOidNode head;
+ XpOidNode tail;
+ XpOidNode current;
+ int count;
+} XpOidLinkedList;
+
+/*
+ * XpOidMediumSourceSize and related definitions
+ */
+typedef struct
+{
+ float minimum_x;
+ float maximum_x;
+ float minimum_y;
+ float maximum_y;
+} XpOidArea;
+
+typedef struct
+{
+ float lower_bound;
+ float upper_bound;
+} XpOidRealRange;
+
+typedef struct
+{
+ XpOidRealRange range_across_feed;
+ float increment_across_feed;
+ XpOidRealRange range_in_feed;
+ float increment_in_feed;
+ BOOL long_edge_feeds;
+ XpOidArea assured_reproduction_area;
+} XpOidMediumContinuousSize;
+
+typedef struct
+{
+ XpOid page_size;
+ BOOL long_edge_feeds;
+ XpOidArea assured_reproduction_area;
+} XpOidMediumDiscreteSize;
+
+typedef struct
+{
+ XpOidMediumDiscreteSize* list;
+ int count;
+} XpOidMediumDiscreteSizeList;
+
+typedef struct
+{
+ XpOid input_tray; /* may be set to xpoid_none or xpoid_unspecified */
+ enum { XpOidMediumSS_DISCRETE, XpOidMediumSS_CONTINUOUS } mstag;
+ union
+ {
+ XpOidMediumDiscreteSizeList* discrete;
+ XpOidMediumContinuousSize* continuous_size;
+ } ms; /* "ms" is short for medium-size */
+
+} XpOidMediumSourceSize;
+
+typedef struct
+{
+ XpOidMediumSourceSize* mss;
+ int count;
+} XpOidMediumSS;
+
+
+typedef struct
+{
+ XpOid input_tray; /* may be set to xpoid_none */
+ XpOid medium;
+} XpOidTrayMedium;
+
+typedef struct
+{
+ XpOidTrayMedium* list;
+ int count;
+} XpOidTrayMediumList;
+
+typedef enum {
+ XPOID_NOTIFY_UNSUPPORTED,
+ XPOID_NOTIFY_NONE,
+ XPOID_NOTIFY_EMAIL
+} XpOidNotify;
+
+typedef struct
+{
+ unsigned long *list;
+ int count;
+} XpOidCardList;
+
+typedef struct
+{
+ char* format;
+ char* variant;
+ char* version;
+} XpOidDocFmt;
+
+typedef struct
+{
+ XpOidDocFmt* list;
+ int count;
+} XpOidDocFmtList;
+
+
+/*
+ * XpOid public methods
+ */
+const char* XpOidString(XpOid);
+int XpOidStringLength(XpOid);
+XpOid XpOidFromString(const char* value);
+BOOL XpOidTrayMediumListHasTray(const XpOidTrayMediumList* list, XpOid tray);
+
+/*
+ * XpOidList public methods
+ */
+XpOidList* XpOidListNew(const char* value_string,
+ const XpOidList* valid_oids);
+#define XpOidListInit(l, a, c) { (l)->list = (a); (l)->count = (c); }
+void XpOidListDelete(XpOidList*);
+#define XpOidListCount(l) ((l) ? (l)->count : 0)
+#define XpOidListGetOid(l, i) ((l) ? (l)->list[(i)] : xpoid_none)
+int XpOidListGetIndex(const XpOidList* list, XpOid oid);
+BOOL XpOidListHasOid(const XpOidList* list, XpOid oid);
+char* XpOidListString(const XpOidList*);
+
+
+/*
+ * XpOidLinkedList public methods
+ */
+XpOidLinkedList* XpOidLinkedListNew(void);
+void XpOidLinkedListDelete(XpOidLinkedList*);
+#define XpOidLinkedListCount(l) ((l) ? (l)->count : 0)
+XpOid XpOidLinkedListGetOid(XpOidLinkedList* list, int i);
+void XpOidLinkedListAddOid(XpOidLinkedList* list, XpOid oid);
+int XpOidLinkedListGetIndex(XpOidLinkedList* list, XpOid oid);
+BOOL XpOidLinkedListHasOid(XpOidLinkedList* list,
+ XpOid oid);
+XpOid XpOidLinkedListFirstOid(XpOidLinkedList* list);
+XpOid XpOidLinkedListNextOid(XpOidLinkedList* list);
+
+/*
+ * XpOidMediumSourceSize public methods
+ */
+XpOidMediumSS* XpOidMediumSSNew(const char* value_string,
+ const XpOidList* valid_trays,
+ const XpOidList* valid_medium_sizes);
+void XpOidMediumSSDelete(XpOidMediumSS*);
+#define XpOidMediumSSCount(me) ((me) ? (me)->count : 0)
+BOOL XpOidMediumSSHasSize(XpOidMediumSS*, XpOid medium_size);
+char* XpOidMediumSSString(const XpOidMediumSS*);
+
+/*
+ * XpOidTrayMediumList public methods
+ */
+XpOidTrayMediumList* XpOidTrayMediumListNew(const char* value_string,
+ const XpOidList* valid_trays,
+ const XpOidMediumSS* msss);
+void XpOidTrayMediumListDelete(XpOidTrayMediumList* me);
+#define XpOidTrayMediumListCount(me) ((me) ? (me)->count : 0)
+#define XpOidTrayMediumListTray(me, i) \
+ ((me) ? (me)->list[(i)].input_tray : xpoid_none)
+#define XpOidTrayMediumListMedium(me, i) \
+ ((me) ? (me)->list[(i)].medium : xpoid_none)
+char* XpOidTrayMediumListString(const XpOidTrayMediumList*);
+
+/*
+ * XpOidNotify public methods
+ */
+XpOidNotify XpOidNotifyParse(const char* value_string);
+const char* XpOidNotifyString(XpOidNotify notify);
+
+/*
+ * XpOidDocFmt public methods
+ */
+XpOidDocFmt* XpOidDocFmtNew(const char* value_string);
+void XpOidDocFmtDelete(XpOidDocFmt*);
+char* XpOidDocFmtString(XpOidDocFmt*);
+
+/*
+ * XpOidDocFmtList public methods
+ */
+XpOidDocFmtList* XpOidDocFmtListNew(const char* value_string,
+ const XpOidDocFmtList* valid_fmts);
+void XpOidDocFmtListDelete(XpOidDocFmtList*);
+char* XpOidDocFmtListString(const XpOidDocFmtList*);
+#define XpOidDocFmtListCount(me) ((me) ? (me)->count : 0)
+#define XpOidDocFmtListGetDocFmt(me, i) \
+ ((me) ? &(me)->list[(i)] : (XpDocFmt*)NULL)
+BOOL XpOidDocFmtListHasFmt(const XpOidDocFmtList* list,
+ const XpOidDocFmt* fmt);
+/*
+ * XpOidCardList public methods
+ */
+XpOidCardList* XpOidCardListNew(const char* value_string,
+ const XpOidCardList* valid_cards);
+#define XpOidCardListInit(l, a, c) { (l)->list = (a); (l)->count = (c); }
+void XpOidCardListDelete(XpOidCardList*);
+char* XpOidCardListString(const XpOidCardList*);
+#define XpOidCardListCount(me) ((me) ? (me)->count : 0)
+#define XpOidCardListGetCard(me, i) ((me) ? (me)->list[(i)] : 0)
+BOOL XpOidCardListHasCard(const XpOidCardList*, unsigned long);
+
+/*
+ * misc parsing functions
+ */
+BOOL XpOidParseUnsignedValue(const char* value_string,
+ const char** ptr_return,
+ unsigned long* unsigned_return);
+
+
+#endif /* _Xp_Oid_h - don't add anything after this line */
diff --git a/hw/xprint/OidDefs.h b/hw/xprint/OidDefs.h
new file mode 100644
index 000000000..55b6568f0
--- /dev/null
+++ b/hw/xprint/OidDefs.h
@@ -0,0 +1,171 @@
+/* $Xorg: OidDefs.h,v 1.4 2001/03/14 18:45:13 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* This is an automatically-generated file. Do not edit. */
+
+typedef enum {
+ xpoid_none,
+ xpoid_unspecified,
+ xpoid_att_descriptor,
+ xpoid_att_content_orientation,
+ xpoid_att_copy_count,
+ xpoid_att_default_printer_resolution,
+ xpoid_att_default_input_tray,
+ xpoid_att_default_medium,
+ xpoid_att_document_format,
+ xpoid_att_plex,
+ xpoid_att_xp_listfonts_modes,
+ xpoid_att_job_name,
+ xpoid_att_job_owner,
+ xpoid_att_notification_profile,
+ xpoid_att_xp_setup_state,
+ xpoid_att_xp_spooler_command_options,
+ xpoid_att_content_orientations_supported,
+ xpoid_att_document_formats_supported,
+ xpoid_att_dt_pdm_command,
+ xpoid_att_input_trays_medium,
+ xpoid_att_medium_source_sizes_supported,
+ xpoid_att_plexes_supported,
+ xpoid_att_printer_model,
+ xpoid_att_printer_name,
+ xpoid_att_printer_resolutions_supported,
+ xpoid_att_xp_embedded_formats_supported,
+ xpoid_att_xp_listfonts_modes_supported,
+ xpoid_att_xp_page_attributes_supported,
+ xpoid_att_xp_raw_formats_supported,
+ xpoid_att_xp_setup_proviso,
+ xpoid_att_document_attributes_supported,
+ xpoid_att_job_attributes_supported,
+ xpoid_att_locale,
+ xpoid_att_multiple_documents_supported,
+ xpoid_att_available_compression,
+ xpoid_att_available_compressions_supported,
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape,
+ xpoid_val_content_orientation_reverse_portrait,
+ xpoid_val_content_orientation_reverse_landscape,
+ xpoid_val_medium_size_iso_a0,
+ xpoid_val_medium_size_iso_a1,
+ xpoid_val_medium_size_iso_a2,
+ xpoid_val_medium_size_iso_a3,
+ xpoid_val_medium_size_iso_a4,
+ xpoid_val_medium_size_iso_a5,
+ xpoid_val_medium_size_iso_a6,
+ xpoid_val_medium_size_iso_a7,
+ xpoid_val_medium_size_iso_a8,
+ xpoid_val_medium_size_iso_a9,
+ xpoid_val_medium_size_iso_a10,
+ xpoid_val_medium_size_iso_b0,
+ xpoid_val_medium_size_iso_b1,
+ xpoid_val_medium_size_iso_b2,
+ xpoid_val_medium_size_iso_b3,
+ xpoid_val_medium_size_iso_b4,
+ xpoid_val_medium_size_iso_b5,
+ xpoid_val_medium_size_iso_b6,
+ xpoid_val_medium_size_iso_b7,
+ xpoid_val_medium_size_iso_b8,
+ xpoid_val_medium_size_iso_b9,
+ xpoid_val_medium_size_iso_b10,
+ xpoid_val_medium_size_na_letter,
+ xpoid_val_medium_size_na_legal,
+ xpoid_val_medium_size_executive,
+ xpoid_val_medium_size_folio,
+ xpoid_val_medium_size_invoice,
+ xpoid_val_medium_size_ledger,
+ xpoid_val_medium_size_quarto,
+ xpoid_val_medium_size_iso_c3,
+ xpoid_val_medium_size_iso_c4,
+ xpoid_val_medium_size_iso_c5,
+ xpoid_val_medium_size_iso_c6,
+ xpoid_val_medium_size_iso_designated_long,
+ xpoid_val_medium_size_na_10x13_envelope,
+ xpoid_val_medium_size_na_9x12_envelope,
+ xpoid_val_medium_size_na_number_10_envelope,
+ xpoid_val_medium_size_na_7x9_envelope,
+ xpoid_val_medium_size_na_9x11_envelope,
+ xpoid_val_medium_size_na_10x14_envelope,
+ xpoid_val_medium_size_na_number_9_envelope,
+ xpoid_val_medium_size_na_6x9_envelope,
+ xpoid_val_medium_size_na_10x15_envelope,
+ xpoid_val_medium_size_monarch_envelope,
+ xpoid_val_medium_size_a,
+ xpoid_val_medium_size_b,
+ xpoid_val_medium_size_c,
+ xpoid_val_medium_size_d,
+ xpoid_val_medium_size_e,
+ xpoid_val_medium_size_jis_b0,
+ xpoid_val_medium_size_jis_b1,
+ xpoid_val_medium_size_jis_b2,
+ xpoid_val_medium_size_jis_b3,
+ xpoid_val_medium_size_jis_b4,
+ xpoid_val_medium_size_jis_b5,
+ xpoid_val_medium_size_jis_b6,
+ xpoid_val_medium_size_jis_b7,
+ xpoid_val_medium_size_jis_b8,
+ xpoid_val_medium_size_jis_b9,
+ xpoid_val_medium_size_jis_b10,
+ xpoid_val_medium_size_hp_2x_postcard,
+ xpoid_val_medium_size_hp_european_edp,
+ xpoid_val_medium_size_hp_mini,
+ xpoid_val_medium_size_hp_postcard,
+ xpoid_val_medium_size_hp_tabloid,
+ xpoid_val_medium_size_hp_us_edp,
+ xpoid_val_medium_size_hp_us_government_legal,
+ xpoid_val_medium_size_hp_us_government_letter,
+ xpoid_val_plex_simplex,
+ xpoid_val_plex_duplex,
+ xpoid_val_plex_tumble,
+ xpoid_val_input_tray_top,
+ xpoid_val_input_tray_middle,
+ xpoid_val_input_tray_bottom,
+ xpoid_val_input_tray_envelope,
+ xpoid_val_input_tray_manual,
+ xpoid_val_input_tray_large_capacity,
+ xpoid_val_input_tray_main,
+ xpoid_val_input_tray_side,
+ xpoid_val_event_report_job_completed,
+ xpoid_val_delivery_method_electronic_mail,
+ xpoid_val_xp_setup_mandatory,
+ xpoid_val_xp_setup_optional,
+ xpoid_val_xp_setup_ok,
+ xpoid_val_xp_setup_incomplete,
+ xpoid_val_xp_list_glyph_fonts,
+ xpoid_val_xp_list_internal_printer_fonts,
+ xpoid_val_available_compressions_0,
+ xpoid_val_available_compressions_01,
+ xpoid_val_available_compressions_02,
+ xpoid_val_available_compressions_03,
+ xpoid_val_available_compressions_012,
+ xpoid_val_available_compressions_013,
+ xpoid_val_available_compressions_023,
+ xpoid_val_available_compressions_0123
+} XpOid;
diff --git a/hw/xprint/OidStrs.h b/hw/xprint/OidStrs.h
new file mode 100644
index 000000000..1792a6e16
--- /dev/null
+++ b/hw/xprint/OidStrs.h
@@ -0,0 +1,173 @@
+/* $Xorg: OidStrs.h,v 1.4 2001/03/14 18:45:40 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* This is an automatically-generated file. Do not edit. */
+
+static int XpOidStringMapCount = 127;
+
+static const XpOidStringMapEntry XpOidStringMap[] = {
+ { "", 0 },
+ { "", 0 },
+ { "descriptor", 10 },
+ { "content-orientation", 19 },
+ { "copy-count", 10 },
+ { "default-printer-resolution", 26 },
+ { "default-input-tray", 18 },
+ { "default-medium", 14 },
+ { "document-format", 15 },
+ { "plex", 4 },
+ { "xp-listfonts-modes", 18 },
+ { "job-name", 8 },
+ { "job-owner", 9 },
+ { "notification-profile", 20 },
+ { "xp-setup-state", 14 },
+ { "xp-spooler-command-options", 26 },
+ { "content-orientations-supported", 30 },
+ { "document-formats-supported", 26 },
+ { "dt-pdm-command", 14 },
+ { "input-trays-medium", 18 },
+ { "medium-source-sizes-supported", 29 },
+ { "plexes-supported", 16 },
+ { "printer-model", 13 },
+ { "printer-name", 12 },
+ { "printer-resolutions-supported", 29 },
+ { "xp-embedded-formats-supported", 29 },
+ { "xp-listfonts-modes-supported", 28 },
+ { "xp-page-attributes-supported", 28 },
+ { "xp-raw-formats-supported", 24 },
+ { "xp-setup-proviso", 16 },
+ { "document-attributes-supported", 29 },
+ { "job-attributes-supported", 24 },
+ { "locale", 6 },
+ { "multiple-documents-supported", 28 },
+ { "available-compression", 21 },
+ { "available-compressions-supported", 32 },
+ { "portrait", 8 },
+ { "landscape", 9 },
+ { "reverse-portrait", 16 },
+ { "reverse-landscape", 17 },
+ { "iso-a0", 6 },
+ { "iso-a1", 6 },
+ { "iso-a2", 6 },
+ { "iso-a3", 6 },
+ { "iso-a4", 6 },
+ { "iso-a5", 6 },
+ { "iso-a6", 6 },
+ { "iso-a7", 6 },
+ { "iso-a8", 6 },
+ { "iso-a9", 6 },
+ { "iso-a10", 7 },
+ { "iso-b0", 6 },
+ { "iso-b1", 6 },
+ { "iso-b2", 6 },
+ { "iso-b3", 6 },
+ { "iso-b4", 6 },
+ { "iso-b5", 6 },
+ { "iso-b6", 6 },
+ { "iso-b7", 6 },
+ { "iso-b8", 6 },
+ { "iso-b9", 6 },
+ { "iso-b10", 7 },
+ { "na-letter", 9 },
+ { "na-legal", 8 },
+ { "executive", 9 },
+ { "folio", 5 },
+ { "invoice", 7 },
+ { "ledger", 6 },
+ { "quarto", 6 },
+ { "iso-c3", 6 },
+ { "iso-c4", 6 },
+ { "iso-c5", 6 },
+ { "iso-c6", 6 },
+ { "iso-designated-long", 19 },
+ { "na-10x13-envelope", 17 },
+ { "na-9x12-envelope", 16 },
+ { "na-number-10-envelope", 21 },
+ { "na-7x9-envelope", 15 },
+ { "na-9x11-envelope", 16 },
+ { "na-10x14-envelope", 17 },
+ { "na-number-9-envelope", 20 },
+ { "na-6x9-envelope", 15 },
+ { "na-10x15-envelope", 17 },
+ { "monarch-envelope", 16 },
+ { "a", 1 },
+ { "b", 1 },
+ { "c", 1 },
+ { "d", 1 },
+ { "e", 1 },
+ { "jis-b0", 6 },
+ { "jis-b1", 6 },
+ { "jis-b2", 6 },
+ { "jis-b3", 6 },
+ { "jis-b4", 6 },
+ { "jis-b5", 6 },
+ { "jis-b6", 6 },
+ { "jis-b7", 6 },
+ { "jis-b8", 6 },
+ { "jis-b9", 6 },
+ { "jis-b10", 7 },
+ { "hp-2x-postcard", 14 },
+ { "hp-european-edp", 15 },
+ { "hp-mini", 7 },
+ { "hp-postcard", 11 },
+ { "hp-tabloid", 10 },
+ { "hp-us-edp", 9 },
+ { "hp-us-government-legal", 22 },
+ { "hp-us-government-letter", 23 },
+ { "simplex", 7 },
+ { "duplex", 6 },
+ { "tumble", 6 },
+ { "top", 3 },
+ { "middle", 6 },
+ { "bottom", 6 },
+ { "envelope", 8 },
+ { "manual", 6 },
+ { "large-capacity", 14 },
+ { "main", 4 },
+ { "side", 4 },
+ { "event-report-job-completed", 26 },
+ { "electronic-mail", 15 },
+ { "xp-setup-mandatory", 18 },
+ { "xp-setup-optional", 17 },
+ { "xp-setup-ok", 11 },
+ { "xp-setup-incomplete", 19 },
+ { "xp-list-glyph-fonts", 19 },
+ { "xp-list-internal-printer-fonts", 30 },
+ { "0", 1 },
+ { "01", 2 },
+ { "02", 2 },
+ { "03", 2 },
+ { "012", 3 },
+ { "013", 3 },
+ { "023", 3 },
+ { "0123", 4 }
+};
diff --git a/hw/xprint/Util.c b/hw/xprint/Util.c
new file mode 100644
index 000000000..12a2562a4
--- /dev/null
+++ b/hw/xprint/Util.c
@@ -0,0 +1,372 @@
+/* $Xorg: Util.c,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/Util.c,v 1.12 2001/08/01 00:44:45 tsi Exp $ */
+
+/* To get the tempnam() prototype in <stdio.h> */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#if defined(linux) && defined(__STRICT_ANSI__)
+#undef __STRICT_ANSI__
+#endif
+
+#include <X11/Xos.h> /* for unistd.h and string.h */
+#include <stdio.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include "misc.h"
+#include "dixstruct.h"
+
+#include <X11/extensions/Print.h>
+
+#include "attributes.h"
+
+#define IN_FILE_STRING "%(InFile)%"
+#define OUT_FILE_STRING "%(OutFile)%"
+
+/*
+ * ReplaceAnyString returns a string combining the input strings.
+ * It replaces all occurances of 'target' with the supplied
+ * 'replacement'.
+ * The original input string will generally be freed,
+ * and the caller is responsible for freeing whatever string is returned.
+ */
+char *
+ReplaceAnyString(
+ char *string,
+ char *target,
+ char *replacement)
+{
+ char *pKeyString;
+
+ if(replacement != (char *)NULL)
+ {
+ while((pKeyString = strstr(string, target)) != (char *)NULL)
+ {
+ char *newString;
+
+ newString = (char *)xalloc(strlen(string) + strlen(replacement) -
+ strlen(target) + 1);
+ strncpy(newString, string, pKeyString - string);
+ newString[pKeyString - string] = '\0';
+ strcat(newString, replacement);
+ strcat(newString, pKeyString + strlen(target));
+ xfree(string);
+ string = newString;
+ }
+ }
+
+ return string;
+}
+
+/*
+ * ReplaceFileString returns a string combining the input strings.
+ * It replaces all occurances of IN_FILE_STRING with the supplied
+ * inFileName, and all occurances of OUT_FILE_STRING with the
+ * supplied outFileName. The original input string will generally be freed,
+ * and the caller is responsible for freeing whatever string is returned.
+ */
+char *
+ReplaceFileString(
+ char *string,
+ char *inFileName,
+ char *outFileName)
+{
+ char *pKeyString,
+ *pInFileString = IN_FILE_STRING,
+ *pOutFileString = OUT_FILE_STRING;
+
+ if(inFileName != (char *)NULL)
+ {
+ while((pKeyString = strstr(string, pInFileString)) !=
+ (char *)NULL)
+ {
+ char *newString;
+
+ newString = (char *)xalloc(strlen(string) +
+ strlen(inFileName) + 1);
+ strncpy(newString, string, pKeyString - string);
+ newString[pKeyString - string] = '\0';
+ strcat(newString, inFileName);
+ strcat(newString, pKeyString + strlen(pInFileString));
+ xfree(string);
+ string = newString;
+ }
+ }
+
+ if(outFileName != (char *)NULL)
+ {
+ while((pKeyString = strstr(string, pOutFileString)) !=
+ (char *)NULL)
+ {
+ char *newString;
+
+ newString = (char *)xalloc(strlen(string) +
+ strlen(outFileName) + 1);
+ strncpy(newString, string, pKeyString - string);
+ newString[pKeyString - string] = '\0';
+ strcat(newString, outFileName);
+ strcat(newString, pKeyString + strlen(pOutFileString));
+ xfree(string);
+ string = newString;
+ }
+ }
+ return string;
+}
+
+
+/*
+ * TransferBytes reads numBytes of data from pSrcFile and writes them
+ * to pDstFile. It returns the number of bytes actually transfered,
+ * which will be numBytes if it's successful. Neither pSrcFile nor
+ * pDstFile are rewound or their pointers otherwise modified prior to
+ * beginning the transfer.
+ */
+int
+TransferBytes(
+ FILE *pSrcFile,
+ FILE *pDstFile,
+ int numBytes)
+{
+ char buf[10240];
+#define BUF_SIZE (sizeof(buf)*sizeof(char))
+ int bytesWritten = 0;
+ unsigned bytesToXfer;
+
+ for(bytesToXfer = min(BUF_SIZE, (unsigned)numBytes);
+ bytesToXfer > 0;
+ bytesToXfer = min(BUF_SIZE, (unsigned)(numBytes - bytesWritten)))
+ {
+ if(fread((void *)buf, (size_t) 1, bytesToXfer, pSrcFile) < bytesToXfer)
+ return bytesWritten;
+ if(fwrite((void *)buf, (size_t) 1, bytesToXfer, pDstFile) < bytesToXfer)
+ return bytesWritten;
+ bytesWritten += bytesToXfer;
+ }
+ return bytesWritten;
+}
+
+/*
+ * CopyContentsAndDelete - does the work of copying and deleting the
+ * pre, no, and post raster files as well as the raster file itself.
+ */
+Bool
+CopyContentsAndDelete(
+ FILE **ppSrcFile,
+ char **pSrcFileName,
+ FILE *pDstFile)
+{
+ struct stat statBuf;
+
+ if(stat(*pSrcFileName, &statBuf) < 0)
+ return FALSE;
+ rewind(*ppSrcFile);
+ if(TransferBytes(*ppSrcFile, pDstFile,
+ (int)statBuf.st_size) != (int)statBuf.st_size)
+ return FALSE;
+ fclose(*ppSrcFile);
+ *ppSrcFile = (FILE *)NULL;
+ unlink(*pSrcFileName);
+ xfree(*pSrcFileName);
+ *pSrcFileName = (char *)NULL;
+
+ return TRUE;
+}
+
+
+#define QUADPAD(x) ((((x)+3)>>2)<<2)
+
+int
+XpSendDocumentData(
+ ClientPtr client,
+ FILE *fp,
+ int fileLen,
+ int maxBufSize)
+{
+ xPrintGetDocumentDataReply *pRep;
+ int bytesWritten;
+ unsigned bytesToWrite;
+ int result = Success;
+
+ if(client->clientGone)
+ return Success;
+
+ pRep = (xPrintGetDocumentDataReply *)xalloc(sz_xPrintGetDocumentDataReply+
+ QUADPAD(maxBufSize));
+
+ for(bytesToWrite = min(maxBufSize, fileLen),
+ bytesWritten = 0;
+ bytesToWrite > 0;
+ bytesToWrite = min(maxBufSize, fileLen - bytesWritten))
+ {
+ pRep->type = X_Reply;
+ pRep->sequenceNumber = client->sequence;
+ pRep->length = (QUADPAD(bytesToWrite)) >> 2;
+ pRep->dataLen = bytesToWrite;
+
+ if(fread((void *)(pRep + 1), 1, bytesToWrite, fp) < bytesToWrite)
+ {
+ result = BadAlloc; /* XXX poor error choice? */
+ pRep->statusCode = 2; /* XXX Is this the right value??? */
+ }
+ else
+ pRep->statusCode = 0; /* XXX Ignored??? */
+
+ pRep->finishedFlag = FALSE;
+
+ if (client->swapped) {
+ int n;
+ long l;
+
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, l);
+ swapl(&pRep->statusCode, l); /* XXX Why are these longs??? */
+ swapl(&pRep->finishedFlag, l); /* XXX Why are these longs??? */
+ swapl(&pRep->dataLen, l);
+ }
+
+ (void)WriteToClient(client,
+ sz_xPrintGetDocumentDataReply + bytesToWrite,
+ (char *)pRep);
+ bytesWritten += bytesToWrite;
+ }
+
+ xfree(pRep);
+ return result;
+}
+
+/*
+ * XpFinishDocData - send a DocumentData reply with the "finishedFlag"
+ * field set to TRUE. This routine should be called from the EndJob
+ * function of a driver after the driver has sent all required
+ * document data (presumably via XpSendDocumentData).
+ */
+int
+XpFinishDocData(
+ ClientPtr client)
+{
+ xPrintGetDocumentDataReply rep;
+
+ if(client->clientGone)
+ return Success;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.dataLen = 0;
+ rep.finishedFlag = TRUE;
+ rep.statusCode = 0;
+
+ if (client->swapped) {
+ int n;
+ long l;
+
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, l);
+ swapl(&rep.statusCode, l); /* XXX Why are these longs??? */
+ swapl(&rep.finishedFlag, l); /* XXX Why are these longs??? */
+ swapl(&rep.dataLen, l);
+ }
+
+ (void)WriteToClient(client, sz_xPrintGetDocumentDataReply, (char *)&rep);
+ return Success;
+}
+
+#ifndef HAVE_MKSTEMP
+static
+char *XpDirName(char *fname)
+{
+ char *fn, *ptr;
+
+ fn = (char *)xalloc(strlen(fname) + 1);
+ if (fn) {
+ strcpy(fn, fname);
+ ptr = strrchr(fn, '/');
+ if (!ptr) {
+ ptr = fn;
+ *ptr++ = '.';
+ } else if (ptr == fn)
+ ptr++;
+ *ptr = '\0';
+ }
+ return fn;
+}
+#endif
+
+Bool
+XpOpenTmpFile(
+ char *mode,
+ char **fname,
+ FILE **stream)
+{
+#ifndef HAVE_MKSTEMP
+ char *fn = NULL;
+
+ /* note that there is a small race condition here... */
+ if (!(*fname = tempnam(NULL, NULL)) ||
+ !(fn = XpDirName(*fname)) ||
+ access(fn, W_OK) ||
+ !(*stream = fopen(*fname, mode)))
+
+ {
+ xfree(fn);
+ xfree(*fname);
+ *fname = NULL;
+ *stream = NULL;
+ return FALSE;
+ }
+ xfree(fn);
+#else
+ int fd;
+
+ *stream = NULL;
+ *fname = (char *)xalloc(14);
+ if (*fname == NULL)
+ return FALSE;
+ strcpy(*fname, "/tmp/xpXXXXXX");
+ fd = mkstemp(*fname);
+ if (fd < 0) {
+ xfree(*fname);
+ *fname = NULL;
+ return FALSE;
+ }
+ *stream = fdopen(fd, mode);
+ if (stream == NULL) {
+ xfree(*fname);
+ *fname = NULL;
+ return FALSE;
+ }
+#endif
+ return TRUE;
+}
diff --git a/hw/xprint/ValTree.c b/hw/xprint/ValTree.c
new file mode 100644
index 000000000..6fa631617
--- /dev/null
+++ b/hw/xprint/ValTree.c
@@ -0,0 +1,193 @@
+/* $Xorg: ValTree.c,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86$ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "mivalidate.h"
+
+/*
+ * XpValidateTree - a validateTree routine which ignores overlapping
+ * top-level windows when computing the clip lists for such windows.
+ * This can be used by any driver which maintains a separate memory
+ * store for each top-level window (with its respective children).
+ * If the pParent is not the root window, then miValidateTree
+ * is used unmodified.
+ *
+ * The strategy if pParent is the root is to save off the
+ * current values of pParent->firstChild and pParent->lastChild,
+ * replacing both with the single child of interest. We save off
+ * pChild->prevSib and pChild->nextSib, and replace them with NullWindow.
+ * We save off pParent->clipList, and replace it with
+ * pParent->winSize - pChild->winSize. We then call miValidateTree
+ * to do the needed ComputeClips on the pChild's heirarchy.
+ * pParent's clipList is then recomputed based on the sizes
+ * of its children, and the saved pointers are restored.
+ * The trees associated with the siblings of pChild must be descended
+ * and cleaned of any marks (i.e. the valdata pointer freed, and set to NULL),
+ * and pParent' AfterValidate structure's exposed field must be updated.
+ */
+/*ARGSUSED*/
+int
+XpValidateTree (pParent, pChild, kind)
+ WindowPtr pParent; /* Parent to validate */
+ WindowPtr pChild; /* First child of pParent that was
+ * affected */
+ VTKind kind; /* What kind of configuration caused call */
+{
+ RegionRec origPrntClip; /* orig clipList for parent */
+ RegionRec childClip; /* The new borderClip for the current
+ * child */
+ RegionRec tmpPrntClip; /* parent clipList - child borderClip */
+ RegionRec exposed; /* For intermediate calculations */
+ register ScreenPtr pScreen;
+ register WindowPtr pWin;
+ Bool overlap;
+ int viewvals;
+ Bool forward;
+
+ WindowPtr origFirstChild, origLastChild, origPrevSib, origNextSib;
+
+ /*
+ * If we're validating something other than a top-level window,
+ * then just invoke miValidateTree.
+ */
+ if(pParent->parent != NullWindow)
+ return miValidateTree(pParent, pChild, kind);
+
+ /*
+ * If it's a stack change of top levels then it's a no-op for
+ * this scheme, so we just clean up any marks on windows and return.
+ */
+ if(kind == VTStack)
+ {
+ CleanMarks(pParent);
+ return 1;
+ }
+
+ pScreen = pParent->drawable.pScreen;
+ if (pChild == NullWindow)
+ pChild = pParent->firstChild;
+
+ /* Save off the existing window heirarchy */
+ origFirstChild = pParent->firstChild;
+ origLastChild = pParent->lastChild;
+ origPrevSib = pChild->prevSib;
+ origNextSib = pChild->nextSib;
+ pParent->firstChild = pChild;
+ pParent->lastChild = pChild;
+ pChild->prevSib = NullWindow;
+ pChild->nextSib = NullWindow;
+
+ /*
+ * Set pParent's clipList to be its winSize minus the pChild's
+ * borderSize.
+ */
+ origPrntClip = pParent->clipList;
+ REGION_NULL(pScreen, &tmpPrntClip);
+ REGION_SUBRACT(pScreen, &tmpPrntClip, &pParent->winSize,
+ &pChild->borderSize);
+ pParent->clipList = tmpPrntClip;
+
+ /*
+ * Call miValidateTree on the pruned tree.
+ */
+ (void) miValidateTree(pParent, pChild, kind);
+
+ /* Restore the saved heirarchy */
+ pChild->prevSib = origPrevSib;
+ pChild->nextSib = origNextSib;
+ pParent->firstChild = origFirstChild;
+ pParent->lastChild = origLastChild;
+
+ /*
+ * Compute pParent's clipList by taking its winSize and subracting
+ * the borderSize of each of its children.
+ */
+ for(pWin = pParent->firstChild,
+ REGION_COPY(pScreen, &pParent->clipList, &pParent->winSize);
+ pWin != NullWindow;
+ pWin = pWin->nextSib)
+ {
+ REGION_SUBTRACT(pScreen, &pParent->clipList, &pParent->clipList,
+ &pWin->borderSize);
+ }
+
+ /*
+ * Compute pParent's AfterValidate structure by subracting the original
+ * clipList from the newly computed clipList.
+ */
+ REGION_NULL(pScreen, &pParent->valdata->after.exposed);
+ REGION_SUBTRACT(pScreen, &pParent->valdata->after.exposed,
+ &pParent->clipList, &origPrntClip);
+
+ /*
+ * Remove the marks from all but pParent and pChild's heirarchy.
+ * i.e. from all of pChild's siblings and their children.
+ */
+ for(pWin = pParent->firstChild; pWin != NullWindow; pWin = pWin->nextSib)
+ {
+ WindowPtr pCurChild = pWin;
+
+ if(pCurChild == pChild)
+ continue;
+
+ while (1)
+ {
+ if(pCurChild->valdata)
+ {
+ xfree(pCurChild->valdata);
+ pCurChild->valdata = (ValidatePtr)NULL;
+ }
+
+ if (pCurChild->firstChild)
+ {
+ pCurChild = pCurChild->firstChild;
+ continue;
+ }
+ while (!pCurChild->nextSib && (pCurChild != pWin))
+ pCurChild = pCurChild->parent;
+ if (pCurChild == pWin)
+ break;
+ pCurChild = pCurChild->nextSib;
+ }
+ }
+}
diff --git a/hw/xprint/attributes.c b/hw/xprint/attributes.c
new file mode 100644
index 000000000..8e4c811cb
--- /dev/null
+++ b/hw/xprint/attributes.c
@@ -0,0 +1,1737 @@
+/* $Xorg: attributes.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: attributes.c
+** *
+** * Contents:
+** * Implementation of the attribute store for Xp.
+** *
+** * Copyright: Copyright 1995 Hewlett-Packard Company
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/Xproto.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#if (defined(sun) && defined(SVR4)) || defined(__SCO__) || defined(__UNIXWARE__)
+#include <wchar.h>
+#endif
+#include "scrnintstr.h"
+
+#include <X11/extensions/Printstr.h>
+
+#include "attributes.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+
+#include "spooler.h"
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+
+static XrmDatabase CopyDb(XrmDatabase inDb);
+
+extern XrmDatabase XpSpoolerGetServerAttributes(void);
+
+static int attrGeneration = 0;
+
+typedef struct {
+ XrmDatabase *pDb;
+ char *qualifier;
+ char *modelId;
+} DbEnumStruct;
+
+typedef struct {
+ char *stringDb;
+ int nextPos;
+ int space;
+} StringDbStruct;
+
+typedef struct _printerAttrs {
+ struct _printerAttrs *next;
+ char *name;
+ char *qualifier;
+ XrmDatabase printerAttrs;
+ XrmDatabase docAttrs;
+ XrmDatabase jobAttrs;
+} PrAttrs, *PrAttrPtr;
+
+static PrAttrPtr attrList = (PrAttrPtr)NULL;
+
+typedef struct _systemAttrs {
+ XrmDatabase doc;
+ XrmDatabase job;
+ XrmDatabase printers;
+ XrmDatabase server;
+} SysAttrs, *SysAttrsPtr;
+
+SysAttrs systemAttributes;
+
+/*
+ * attrCtxtPrivIndex hold the attribute store's context private index.
+ * This index is allocated at the time the attribute store is initialized.
+ */
+static int attrCtxtPrivIndex;
+
+/*
+ * The ContextAttrs structure descibes the context private space reserved
+ * by the attribute store.
+ */
+typedef struct _contextAttrs {
+ XrmDatabase printerAttrs;
+ XrmDatabase docAttrs;
+ XrmDatabase jobAttrs;
+ XrmDatabase pageAttrs;
+} ContextAttrs, *ContextAttrPtr;
+
+/*
+ * XPDIR is relative to (i.e. is a subdir of) XPRINTDIR/$LANG.
+ */
+static const char XPDIR[] = "/print";
+/*
+ * The following files/directories define or are within subdirectories of the
+ * above-defined XPDIR.
+ */
+static const char XPPRINTERATTRFILE[] = "/attributes/printer";
+static const char XPJOBATTRFILE[] = "/attributes/job";
+static const char XPDOCATTRFILE[] = "/attributes/document";
+static const char XPMODELDIR[] = "/models";
+
+static char NULL_STRING[] = "\0";
+
+/*
+ * XpGetConfigDirBase returns a string containing the path name of the base
+ * where the print server configuration directory is localed.
+ */
+static
+char *XpGetConfigDirBase(void)
+{
+ char *configDir;
+
+ /*
+ * If the XPCONFIGDIR environment variable is not set, then use the
+ * compile-time constant XPRINTDIR. XPRINTDIR is passed in on the
+ * compile command line, and is defined in $(TOP)/config/cf/Project.tmpl.
+ */
+ if((configDir = getenv("XPCONFIGDIR")) == (char *)NULL)
+ configDir = XPRINTDIR;
+
+ return configDir;
+}
+
+/*
+ * XpGetConfigDir returns a string containing the path name of the print
+ * server configuration directory. If the useLocale parameter is False
+ * the it returns the path to the "/C" directory. If the useLocale
+ * parameter is True it returns the path to the directory associated with
+ * $LANG. It makes no attempt to ensure that the directory actually exists.
+ */
+char *
+XpGetConfigDir(Bool useLocale)
+{
+ char *dirName, *langName, *langDir, *configDir;
+ Bool freeLangDir = False;
+
+ if(useLocale == False) langDir = "/C";
+ else
+ {
+ langName = getenv("LC_ALL");
+ if (langName == NULL) {
+ langName = getenv("LANG");
+ }
+
+ if(langName == (char *)NULL)
+ return (char *)NULL;
+ else
+ {
+ if(strcmp(langName, "C") == 0)
+ return (char *)NULL;
+ langDir = (char *)xalloc(strlen(langName) + 2);
+ sprintf(langDir, "/%s", langName);
+ freeLangDir = True;
+ }
+ }
+
+ configDir = XpGetConfigDirBase();
+
+ dirName = (char *)xalloc(strlen(configDir) + strlen(XPDIR) +
+ strlen(langDir) + 1);
+ sprintf(dirName, "%s%s%s", configDir, langDir, XPDIR);
+
+ if(freeLangDir == True)
+ xfree(langDir);
+
+ return dirName;
+}
+
+/*
+ * GetMergedDatabase reads and merges xrmdb files from the top-level printer
+ * config directory, and from the directory associated with the current
+ * locale (if other than the top-level).
+ */
+static XrmDatabase
+GetMergedDatabase(const char *attrName)
+{
+ char *dirName, *fileName;
+ XrmDatabase db;
+
+ if((dirName = XpGetConfigDir(False)) == (char *)NULL)
+ return (XrmDatabase)NULL;
+ if((fileName = (char *)xalloc(strlen(dirName) + strlen(attrName) + 1)) ==
+ (char *)NULL)
+ return (XrmDatabase)NULL;
+ sprintf(fileName, "%s%s", dirName, attrName);
+ db = XrmGetFileDatabase(fileName);
+ xfree(fileName);
+ xfree(dirName);
+
+ if((dirName = XpGetConfigDir(True)) == (char *)NULL)
+ return db;
+ if((fileName = (char *)xalloc(strlen(dirName) + strlen(attrName) + 1)) ==
+ (char *)NULL)
+ return db;
+ sprintf(fileName, "%s%s", dirName, attrName);
+ (void)XrmCombineFileDatabase(fileName, &db, True);
+ xfree(fileName);
+ xfree(dirName);
+
+ return db;
+}
+
+/*
+ * BuildSystemAttributes reads the on-disk configuration files for printers,
+ * initial job, and initial document attributes. The resulting xrm
+ * databases are then dissected as needed for each printer.
+ * It also allocates a contextPrivate space for the attributes,
+ * reserving space to store pointers to the attribute stores for
+ * the context.
+ */
+static void
+BuildSystemAttributes(void)
+{
+ if(systemAttributes.printers != (XrmDatabase)NULL)
+ XrmDestroyDatabase(systemAttributes.printers);
+ systemAttributes.printers = GetMergedDatabase(XPPRINTERATTRFILE);
+ if(systemAttributes.job != (XrmDatabase)NULL)
+ XrmDestroyDatabase(systemAttributes.job);
+ systemAttributes.job = GetMergedDatabase(XPJOBATTRFILE);
+ if(systemAttributes.doc != (XrmDatabase)NULL)
+ XrmDestroyDatabase(systemAttributes.doc);
+ systemAttributes.doc = GetMergedDatabase(XPDOCATTRFILE);
+ if(systemAttributes.server != (XrmDatabase)NULL)
+ XrmDestroyDatabase(systemAttributes.server);
+ systemAttributes.server = XpSpoolerGetServerAttributes();
+ return;
+}
+
+/*
+ * AddDbEntry is called by XrmEnumerateDatabase, and adds the supplied
+ * database entry to the database pointed to within the "DbEnumStruct"
+ * passed as the client_data (aka "closure").
+ */
+static Bool
+AddDbEntry(
+ XrmDatabase *sourceDB,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation *type,
+ XrmValue *value,
+ XPointer client_data)
+{
+ DbEnumStruct *pEnumStruct = (DbEnumStruct *)client_data;
+ XrmName xrm_name[5];
+ XrmClass xrm_class[5];
+ XrmBinding xrm_bind[3];
+ XrmValue realVal;
+ XrmRepresentation rep_type;
+
+ xrm_name[0] = XrmStringToQuark (pEnumStruct->qualifier);
+ xrm_class[0] = XrmStringToQuark (pEnumStruct->modelId);
+
+ for(;*quarks; quarks++)
+ xrm_name[1] = xrm_class[1] = *quarks;
+
+ xrm_name[2] = (XrmQuark)NULL;
+ xrm_class[2] = (XrmQuark)NULL;
+
+ if(XrmQGetResource (*sourceDB, xrm_name, xrm_class, &rep_type, &realVal))
+ {
+ xrm_bind[0] = XrmBindLoosely;
+
+ xrm_name[0] = xrm_name[1];
+ xrm_name[1] = NULLQUARK;
+
+ XrmQPutStringResource(pEnumStruct->pDb, xrm_bind, xrm_name,
+ (char *)realVal.addr);
+ }
+
+ return FALSE;
+}
+
+/*
+ * BuildPrinterAttrs - builds and returns an XrmDatabase for the printer
+ * of the specified name/qualifier, if we have enough information.
+ * If we don't have a model-config
+ * file, then just enumerate the systemAttributes->printers database,
+ * otherwise read in the model-config database and merge into it the
+ * systemAttributes->printers database. This database is then enumerated
+ * with the printer qualifier (and the model name as class if we have it), and
+ * the resulting elements are stored into the database for this particular
+ * printer.
+ */
+static XrmDatabase
+BuildPrinterAttrs(
+ char *printerName,
+ char *qualifierName)
+{
+ XrmDatabase printerDB = (XrmDatabase)NULL;
+
+ if(systemAttributes.printers != (XrmDatabase)NULL)
+ {
+ char *fileName;
+ XrmDatabase modelDB = (XrmDatabase)NULL;
+ XrmName xrm_name[5], xrm_class[2];
+ XrmRepresentation rep_type;
+ XrmValue value;
+ DbEnumStruct enumStruct;
+ Bool freeModelDB = False;
+ /*
+ * Build the initial db based on the model-config files
+ */
+ xrm_name[0] = XrmStringToQuark (qualifierName);
+ xrm_name[1] = XrmStringToQuark ("xp-model-identifier");
+ xrm_name[2] = (XrmQuark)NULL;
+ XrmQGetResource (systemAttributes.printers, xrm_name, xrm_name,
+ &rep_type, &value);
+
+ if(value.addr != (XPointer)NULL)
+ {
+ fileName = (char *)xalloc(strlen(XPMODELDIR) +
+ strlen((char *)value.addr) +
+ strlen("model-config") + 3);
+ sprintf(fileName, "%s/%s/%s", XPMODELDIR, value.addr,
+ "model-config");
+ modelDB = GetMergedDatabase(fileName);
+ xfree(fileName);
+ if(modelDB != (XrmDatabase)NULL)
+ {
+ XrmDatabase tempDB = (XrmDatabase)NULL;
+ /*
+ * have to make a temp copy because MergeDatabase destroys
+ * the "source" database. Merge in the printers DB
+ */
+ tempDB = CopyDb(systemAttributes.printers);
+ XrmMergeDatabases(tempDB, &modelDB);
+ freeModelDB = True;
+ }
+ }
+
+ /*
+ * Check to see if we knew the name AND found a database file
+ */
+ if(modelDB == (XrmDatabase)NULL)
+ modelDB = systemAttributes.printers;
+
+ xrm_name[0] = XrmStringToQuark (qualifierName);
+ xrm_name[1] = (XrmQuark)NULL;
+ xrm_class[0] = XrmStringToQuark((char *)value.addr);
+ xrm_class[1] = (XrmQuark)NULL;
+ enumStruct.pDb = &printerDB;
+ enumStruct.qualifier = (char *)qualifierName;
+ enumStruct.modelId = (char *)value.addr;
+ XrmEnumerateDatabase(modelDB, xrm_name, xrm_class, XrmEnumAllLevels,
+ AddDbEntry, (XPointer) &enumStruct);
+
+ if(freeModelDB == True) XrmDestroyDatabase(modelDB);
+ }
+ XrmPutStringResource(&printerDB, "*printer-name", printerName);
+ XrmPutStringResource(&printerDB, "*qualifier", qualifierName);
+ return printerDB;
+}
+
+/*
+ * BuildABase - builds an XrmDatabase by enumerating the supplied sourceBase
+ * database for elements relevant for the printer named by printerName,
+ * and deriving a class for printerName from the model declared in the
+ * systemAttributes.printers database. If no model is defined for this
+ * printer then the printerName is used as the class as well.
+ *
+ * This is used to build the initial value document and initial value
+ * job attribute databases for each printer by searching the system
+ * level doc and job databases.
+ */
+static XrmDatabase
+BuildABase(
+ char *printerName,
+ char *qualifierName,
+ XrmDatabase sourceBase)
+{
+ XrmDatabase builtDB = (XrmDatabase)NULL;
+
+ if(sourceBase != (XrmDatabase)NULL)
+ {
+ XrmName xrm_name[5], xrm_class[2];
+ XrmRepresentation rep_type;
+ XrmValue value;
+ DbEnumStruct enumStruct;
+
+ /*
+ * Retrieve the model name for use as the class.
+ */
+ xrm_name[0] = XrmStringToQuark (printerName);
+ xrm_name[1] = XrmStringToQuark ("xp-model-identifier");
+ xrm_name[2] = (XrmQuark)NULL;
+ XrmQGetResource (systemAttributes.printers, xrm_name, xrm_name,
+ &rep_type, &value);
+ /*
+ * if we have a model name then use it as the class, otherwise
+ * just use the printer name as the class as well as the name.
+ */
+ if(value.addr != (XPointer)NULL)
+ xrm_class[0] = XrmStringToQuark((char *)value.addr);
+ else
+ xrm_class[0] = xrm_name[0];
+ xrm_class[1] = (XrmQuark)NULL;
+
+ xrm_name[1] = (XrmQuark)NULL;
+
+ enumStruct.pDb = &builtDB;
+ enumStruct.qualifier = (char *)qualifierName;
+ enumStruct.modelId = (char *)value.addr;
+ XrmEnumerateDatabase(sourceBase, xrm_name, xrm_class, XrmEnumAllLevels,
+ AddDbEntry, (XPointer) &enumStruct);
+ }
+
+ XrmPutStringResource(&builtDB, "*qualifier", qualifierName);
+
+ return builtDB;
+}
+
+/*
+ * FreeAttrList is called upon server recycle, and frees the printer
+ * databases stored in the global attrList.
+ */
+static void
+FreeAttrList(void)
+{
+ PrAttrPtr pAttr, pNext;
+
+ for(pAttr = attrList, pNext = attrList;
+ pAttr != (PrAttrPtr)NULL;
+ pAttr = pNext)
+ {
+ pNext = pAttr->next;
+ if(pAttr->printerAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pAttr->printerAttrs);
+ if(pAttr->docAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pAttr->docAttrs);
+ if(pAttr->jobAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pAttr->jobAttrs);
+ xfree(pAttr->name);
+ xfree(pAttr->qualifier);
+ xfree(pAttr);
+ }
+ attrList = (PrAttrPtr)NULL;
+}
+
+/*
+ * XpRehashAttributes - frees the per-printer attribute list and
+ * calls BuildSystemAttributes to rebuild the overall attribute
+ * store. It is expected that a caller of this will follow it
+ * by calling XpBuildAttributeStore for a new list of printers.
+ */
+int
+XpRehashAttributes(void)
+{
+ if(attrList != (PrAttrPtr)NULL)
+ FreeAttrList();
+ BuildSystemAttributes();
+ return Success;
+}
+
+/*
+ * XpBuildAttributeStore - creates the attribute database associated
+ * with the specified printer. The first time this is called it
+ * calls BuildSystemAttributes to create the system-level databases.
+ */
+void
+XpBuildAttributeStore(
+ char *printerName,
+ char *qualifierName)
+{
+ PrAttrPtr pAttr;
+
+ if((pAttr = (PrAttrPtr)xalloc(sizeof(PrAttrs))) == (PrAttrPtr)NULL)
+ return;
+
+ if(attrGeneration != serverGeneration)
+ {
+ if(attrList != (PrAttrPtr)NULL)
+ FreeAttrList();
+ attrCtxtPrivIndex = XpAllocateContextPrivateIndex();
+ XpAllocateContextPrivate(attrCtxtPrivIndex, sizeof(ContextAttrs));
+ BuildSystemAttributes();
+
+ attrGeneration = serverGeneration;
+ }
+
+ if(attrList == (PrAttrPtr)NULL)
+ {
+ pAttr->next = (PrAttrPtr)NULL;
+ attrList = pAttr;
+ }
+ else
+ {
+ pAttr->next = attrList;
+ attrList = pAttr;
+ }
+
+ pAttr->name = strdup(printerName);
+ pAttr->qualifier = strdup(qualifierName);
+ pAttr->printerAttrs = BuildPrinterAttrs(printerName, qualifierName);
+ pAttr->docAttrs = BuildABase(printerName, qualifierName,
+ systemAttributes.doc);
+ pAttr->jobAttrs = BuildABase(printerName, qualifierName,
+ systemAttributes.job);
+}
+
+
+static Bool
+StoreEntry(
+ XrmDatabase *sourceDB,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation *type,
+ XrmValue *value,
+ XPointer client_data)
+{
+ XrmDatabase *outDb = (XrmDatabase *)client_data;
+
+ XrmQPutStringResource(outDb, bindings, quarks, (char *)value->addr);
+
+ return FALSE;
+}
+
+/*
+ * XpCopyDb - makes a copy of the specified XrmDatabase and returns
+ * the copy.
+ */
+static XrmDatabase
+CopyDb(XrmDatabase inDb)
+{
+ XrmDatabase outDb = (XrmDatabase)NULL;
+ XrmQuark empty = NULLQUARK;
+
+ (void)XrmEnumerateDatabase(inDb, &empty, &empty, XrmEnumAllLevels,
+ StoreEntry, (XPointer) &outDb);
+ return outDb;
+}
+
+/*
+ * XpInitAttributes - initializes the attribute store for the specified
+ * context. It does this by making copies of the printer, doc, and job
+ * attributes databases for the printer associated with the context.
+ */
+void
+XpInitAttributes(XpContextPtr pContext)
+{
+ ContextAttrPtr pCtxtAttrs;
+ PrAttrPtr pPrAttr = attrList;
+
+ /* Initialize all the pointers to NULL */
+ pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+ (void)memset((void *)pCtxtAttrs, 0, (size_t) sizeof(ContextAttrs));
+
+ for(pPrAttr = attrList; pPrAttr != (PrAttrPtr)NULL; pPrAttr = pPrAttr->next)
+ if(!strcmp(pPrAttr->name, pContext->printerName)) break;
+
+ if(pPrAttr != (PrAttrPtr)NULL)
+ {
+ pCtxtAttrs->printerAttrs = CopyDb(pPrAttr->printerAttrs);
+ pCtxtAttrs->docAttrs = CopyDb(pPrAttr->docAttrs);
+ pCtxtAttrs->jobAttrs = CopyDb(pPrAttr->jobAttrs);
+ }
+}
+
+void
+XpDestroyAttributes(
+ XpContextPtr pContext)
+{
+ ContextAttrPtr pCtxtAttrs;
+
+ pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+
+ if(pCtxtAttrs->printerAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->printerAttrs);
+ if(pCtxtAttrs->docAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->docAttrs);
+ if(pCtxtAttrs->jobAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->jobAttrs);
+ if(pCtxtAttrs->pageAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->pageAttrs);
+}
+
+/*
+ * XpGetOneAttribute returns the string value of the specified attribute
+ * in the specified class for the specified print context. If the attribute
+ * doesn't exist in the database for this context, or if the class database
+ * doesn't exist for this context, then NULL is returned. The caller must
+ * not free the returned string, as the returned pointer points into the
+ * database. This function can also return a value from the server attributes,
+ * in which case the pContext parameter is ignored.
+ */
+char *
+XpGetOneAttribute(
+ XpContextPtr pContext,
+ XPAttributes class,
+ char *attributeName)
+{
+ ContextAttrPtr pCtxtAttrs;
+ XrmDatabase db = (XrmDatabase)NULL;
+ XrmName xrm_name[3];
+ XrmRepresentation rep_type;
+ XrmValue value;
+
+ if(class == XPServerAttr)
+ {
+ if(systemAttributes.server == (XrmDatabase)NULL)
+ return NULL_STRING;
+
+ xrm_name[0] = XrmStringToQuark (attributeName);
+ xrm_name[1] = (XrmQuark)NULL;
+ XrmQGetResource(systemAttributes.server, xrm_name, xrm_name,
+ &rep_type, &value);
+
+ if(value.addr == (char *)NULL)
+ return NULL_STRING;
+ return (char *)value.addr;
+ }
+ else
+ {
+ pCtxtAttrs=(ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+ switch(class)
+ {
+ case XPPrinterAttr:
+ db = pCtxtAttrs->printerAttrs;
+ break;
+ case XPDocAttr:
+ db = pCtxtAttrs->docAttrs;
+ break;
+ case XPJobAttr:
+ db = pCtxtAttrs->jobAttrs;
+ break;
+ case XPPageAttr:
+ db = pCtxtAttrs->pageAttrs;
+ break;
+ default:
+ break;
+ }
+ }
+ if(db == (XrmDatabase)NULL)
+ return NULL_STRING;
+
+ xrm_name[0] = XrmStringToQuark ("qualifier");
+ xrm_name[1] = (XrmQuark)NULL;
+ XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value);
+
+ xrm_name[0] = XrmStringToQuark (value.addr);
+ xrm_name[1] = XrmStringToQuark (attributeName);
+ xrm_name[2] = (XrmQuark)NULL;
+ if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value))
+ return (char *)value.addr;
+ else
+ return NULL_STRING;
+}
+
+/*
+ * XpPutOneAttribute updates one attribute for the specified
+ * context and class. This function is intended for use by the attribute
+ * validation module which updates the XrmDatabases directly. This
+ * function does not recognize XPServerAttr.
+ */
+void
+XpPutOneAttribute(
+ XpContextPtr pContext,
+ XPAttributes class,
+ const char* attributeName,
+ const char* value)
+{
+ ContextAttrPtr pCtxtAttrs;
+ XrmDatabase db;
+ XrmBinding bindings[1];
+ XrmQuark quarks[2];
+
+ pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+ switch(class)
+ {
+ case XPPrinterAttr:
+ db = pCtxtAttrs->printerAttrs;
+ break;
+ case XPDocAttr:
+ db = pCtxtAttrs->docAttrs;
+ break;
+ case XPJobAttr:
+ db = pCtxtAttrs->jobAttrs;
+ break;
+ case XPPageAttr:
+ db = pCtxtAttrs->pageAttrs;
+ break;
+ default:
+ return;
+ }
+ bindings[0] = XrmBindLoosely;
+ quarks[0] = XrmStringToQuark(attributeName);
+ quarks[1] = (XrmQuark)NULL;
+ XrmQPutStringResource(&db, bindings, quarks, value ? value : "");
+}
+
+
+
+/*******************************************************************************
+ *
+ * The following routines: ExpandSpace, PutString, PutByte, and AppendEntry
+ * form the functional core of the GetAttributes routine. Xrm does not
+ * supply a routine to form a string database from an XrmDatabase, except
+ * by writing the database to a file. This code avoids the file system
+ * overhead, but is a bit clunky in its memory management.
+ *
+ ******************************************************************************/
+
+/*
+ * ExpandSpace expands the memory allocated for the string database in
+ * the StringDbStruct passed in, and updates the "space" field of the
+ * struct to indicate the new amount of space available.
+ */
+static Bool
+ExpandSpace(
+ StringDbStruct *pStr)
+{
+ char *newSpace;
+
+ if((newSpace = (char *)xrealloc(pStr->stringDb, pStr->nextPos + pStr->space
+ + 1024)) == (char *)NULL)
+ return False;
+ pStr->space += 1024;
+ pStr->stringDb = newSpace;
+ return True;
+}
+
+/*
+ * PutString puts the contents of a null-terminated string into the string
+ * database in the StringDbStruct passed in. If there is insufficient room
+ * for the string, ExpandSpace is called, and the nextPos and space fields
+ * are updated.
+ */
+static void
+PutString(
+ StringDbStruct *pStr,
+ char *pString)
+{
+ int len = strlen(pString);
+
+ if(len >= pStr->space)
+ if(!ExpandSpace(pStr))
+ return;
+ strcpy(&pStr->stringDb[pStr->nextPos], pString);
+ pStr->nextPos += len;
+ pStr->space -= len;
+}
+
+/*
+ * PutByte puts a single byte value in to the string database in the passed-in
+ * StringDbStruct. ExpandSpace is called if there is insufficient room for
+ * the byte, and the nextPos and space fields are updated.
+ */
+static void
+PutByte(
+ StringDbStruct *pStr,
+ char byte)
+{
+ if(pStr->space <= 1)
+ if(!ExpandSpace(pStr))
+ return;
+ pStr->stringDb[pStr->nextPos] = byte;
+ pStr->nextPos++;
+ pStr->space--;
+}
+
+#define XrmQString XrmPermStringToQuark("String")
+
+/*
+ * AppendEntry is called by XrmEnumerateDatabase, and serves to append
+ * a database entry onto a string database. The passed-in "closure"
+ * struct contains a pointer to the string, and a count of the remaining
+ * bytes. If there are insufficient remaining bytes then the struct
+ * is realloced, and the count of the space remaining is updated.
+ * Database elements of types other than String are ignored!
+ * This code is based directly on that in "DumpEntry" in Xrm.c.
+ */
+static Bool
+AppendEntry(
+ XrmDatabase *db,
+ XrmBindingList bindings,
+ XrmQuarkList quarks,
+ XrmRepresentation *type,
+ XrmValuePtr value,
+ XPointer data)
+{
+ StringDbStruct *pEnumStr = (StringDbStruct *)data;
+ Bool firstNameSeen;
+ unsigned int i;
+ char *s, c;
+
+ if (*type != XrmQString)
+ return False;
+
+ for (firstNameSeen = False; *quarks; bindings++, quarks++) {
+ if (*bindings == XrmBindLoosely) {
+ PutString(pEnumStr, "*");
+ } else if (firstNameSeen) {
+ PutString(pEnumStr, ".");
+ }
+ firstNameSeen = True;
+ PutString(pEnumStr, XrmQuarkToString(*quarks));
+ }
+ s = value->addr;
+ i = value->size;
+ PutString(pEnumStr, ":\t");
+ if(i) i--;
+
+ if (i && (*s == ' ' || *s == '\t'))
+ PutByte(pEnumStr, '\\'); /* preserve leading whitespace */
+
+ while (i--) {
+ c = *s++;
+ if (c == '\n') {
+ if (i)
+ PutString(pEnumStr, "\\n\\\n");
+ else
+ PutString(pEnumStr, "\\n");
+ } else if (c == '\\')
+ PutString(pEnumStr, "\\\\");
+ else if ((c < ' ' && c != '\t') ||
+ ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0))
+ {
+ char temp[4];
+ (void) sprintf(temp, "\\%03o", (unsigned char)c);
+ PutString(pEnumStr, temp);
+ }
+ else
+ PutByte(pEnumStr, c);
+ }
+ PutByte(pEnumStr, '\n');
+ pEnumStr->stringDb[pEnumStr->nextPos] = (char)'\0';
+ return False;
+}
+
+/*
+ * XpGetAttributes returns a string database version of the Xrm database
+ * for the specified context and class. This function can also return the
+ * contents of the server attributes, in which case the pContext parameter
+ * is ignored.
+ *
+ * The caller is responsible for freeing the returned string,
+ * unlike XpGetOneAttribute, where the caller must not free the string.
+ */
+char *
+XpGetAttributes(
+ XpContextPtr pContext,
+ XPAttributes class)
+{
+ ContextAttrPtr pCtxtAttrs;
+ XrmDatabase db = (XrmDatabase)NULL;
+ StringDbStruct enumStruct;
+ XrmQuark empty = NULLQUARK;
+
+ if(class == XPServerAttr)
+ db = systemAttributes.server;
+ else
+ {
+ pCtxtAttrs=(ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+ switch(class)
+ {
+ case XPServerAttr:
+ db = systemAttributes.server;
+ break;
+ case XPPrinterAttr:
+ db = pCtxtAttrs->printerAttrs;
+ break;
+ case XPDocAttr:
+ db = pCtxtAttrs->docAttrs;
+ break;
+ case XPJobAttr:
+ db = pCtxtAttrs->jobAttrs;
+ break;
+ case XPPageAttr:
+ db = pCtxtAttrs->pageAttrs;
+ break;
+ default:
+ break;
+ }
+ }
+ if(db == (XrmDatabase)NULL)
+ {
+ char *retval = (char *)xalloc(1);
+ retval[0] = (char)'\0';
+ return retval;
+ }
+
+ if((enumStruct.stringDb = (char *)xalloc(1024)) == (char *)NULL)
+ return (char *)NULL;
+ enumStruct.stringDb[0] = (char)'\0';
+ enumStruct.nextPos = 0;
+ enumStruct.space = 1024;
+ (void)XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
+ AppendEntry, (XPointer) &enumStruct);
+
+ return enumStruct.stringDb;
+}
+
+int
+XpAugmentAttributes(
+ XpContextPtr pContext,
+ XPAttributes class,
+ char *attributes)
+{
+ XrmDatabase db;
+ ContextAttrPtr pCtxtAttrs;
+
+ db = XrmGetStringDatabase(attributes);
+ if(db == (XrmDatabase)NULL) return BadAlloc;
+
+ pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+ switch(class)
+ {
+ case XPPrinterAttr:
+ XrmMergeDatabases(db, &pCtxtAttrs->printerAttrs);
+ break;
+ case XPDocAttr:
+ XrmMergeDatabases(db, &pCtxtAttrs->docAttrs);
+ break;
+ case XPJobAttr:
+ XrmMergeDatabases(db, &pCtxtAttrs->jobAttrs);
+ break;
+ case XPPageAttr:
+ XrmMergeDatabases(db, &pCtxtAttrs->pageAttrs);
+ break;
+ default:
+ break;
+ }
+ return Success;
+}
+
+/*
+ * XpSetAttributes - sets the attribute stores for a specified context.
+ */
+int
+XpSetAttributes(
+ XpContextPtr pContext,
+ XPAttributes class,
+ char *attributes)
+{
+ XrmDatabase db;
+ ContextAttrPtr pCtxtAttrs;
+
+ db = XrmGetStringDatabase(attributes);
+ if(db == (XrmDatabase)NULL) return BadAlloc;
+
+ pCtxtAttrs=(ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr;
+ switch(class)
+ {
+ case XPPrinterAttr:
+ if(pCtxtAttrs->printerAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->printerAttrs);
+ pCtxtAttrs->printerAttrs = db;
+ break;
+ case XPDocAttr:
+ if(pCtxtAttrs->docAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->docAttrs);
+ pCtxtAttrs->docAttrs = db;
+ break;
+ case XPJobAttr:
+ if(pCtxtAttrs->jobAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->jobAttrs);
+ pCtxtAttrs->jobAttrs = db;
+ break;
+ case XPPageAttr:
+ if(pCtxtAttrs->pageAttrs != (XrmDatabase)NULL)
+ XrmDestroyDatabase(pCtxtAttrs->pageAttrs);
+ pCtxtAttrs->pageAttrs = db;
+ break;
+ default:
+ break;
+ }
+ return Success;
+}
+
+void
+XpAddPrinterAttribute(
+ char *printerName,
+ char *printerQualifier,
+ char *attributeName,
+ char *attributeValue)
+{
+ PrAttrPtr pAttr;
+
+ for(pAttr = attrList; pAttr != (PrAttrPtr)NULL; pAttr = pAttr->next)
+ {
+ if(!strcmp(printerQualifier, pAttr->qualifier))
+ {
+ XrmPutStringResource(&pAttr->printerAttrs, attributeName,
+ attributeValue);
+ break;
+ }
+ }
+}
+
+const char *
+XpGetPrinterAttribute(const char *printerName,
+ const char *attribute)
+{
+ PrAttrPtr pAttr;
+ XrmValue value;
+ char *type;
+
+ for(pAttr = attrList; pAttr != (PrAttrPtr)NULL; pAttr = pAttr->next)
+ {
+ if(!strcmp(printerName, pAttr->qualifier))
+ {
+ char *attrStr;
+
+ attrStr = (char *)xalloc(strlen(printerName) + strlen(attribute) +
+ 2);
+ sprintf(attrStr, "%s.%s", printerName, attribute);
+ XrmGetResource(pAttr->printerAttrs, attrStr, attrStr,
+ &type, &value);
+ xfree(attrStr);
+ break;
+ }
+ }
+ if(value.addr != (XPointer)NULL && strlen(value.addr) != 0)
+ return value.addr;
+ else
+ return "";
+}
+
+/*******************************************************************************
+ *
+ * The following routines are not attribute routines, but are rather
+ * spooler interface functions. They should presumably move to
+ * a SpoolerIf.c of some similarly named file.
+ *
+ ******************************************************************************/
+#include <locale.h>
+
+static char serverAttrStr[] = "*document-attributes-supported: copy-count\n\
+*job-attributes-supported: job-name job-owner\
+ notification-profile xp-spooler-command-options\n\
+*multiple-documents-supported: False";
+
+XrmDatabase
+XpSpoolerGetServerAttributes(void)
+{
+ char *totalAttrs, *localeName;
+ XrmDatabase db;
+
+ localeName = setlocale(LC_CTYPE, (char *)NULL);
+ if(!localeName || strlen(localeName) == 0)
+ localeName = "C";
+
+ if((totalAttrs = (char *)xalloc(strlen(serverAttrStr) + strlen(localeName)
+ + 11)) == (char *)NULL)
+ return (XrmDatabase)NULL;
+ sprintf(totalAttrs, "%s\n%s\t%s", serverAttrStr, "*locale:", localeName);
+
+ db = XrmGetStringDatabase(totalAttrs);
+ xfree(totalAttrs);
+ return db;
+}
+
+/*
+ * Tailf() works similar to "/bin/tail -f fd_in >fd_out" until
+ * the process |child| terminates (the child status is
+ * returned in |child_status|).
+ * This function is used to copy the stdout/stderr output of a
+ * child to fd_out until the child terminates.
+ */
+static
+void Tailf(int fd_in, int fd_out, pid_t child, int *child_status)
+{
+ char b[256];
+ ssize_t sz;
+ Bool childDone = FALSE;
+ struct timeval timeout;
+ long fpos = 0; /* XXX: this is not correct for largefile support */
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
+
+ for(;;)
+ {
+ /* Check whether the child is still alive or not */
+ if (waitpid(child, child_status, WNOHANG) == child)
+ childDone = TRUE;
+
+ /* Copy traffic from |fd_in| to |fd_out|
+ * (Note we have to use |pread()| here to avoid race conditions
+ * between a child process writing to the same file using the
+ * same file pointer (|dup(2)| and |fork(2)| just duplicate the
+ * file handle but not the pointer)).
+ */
+ while ((sz = pread(fd_in, b, sizeof(b), fpos)) > 0)
+ {
+ fpos += sz;
+ write(fd_out, b, sz);
+ }
+
+ if (childDone)
+ break;
+
+ (void)select(0, NULL, NULL, NULL, &timeout);
+ }
+}
+
+/*
+ * SendFileToCommand takes three character pointers - the file name,
+ * the command to execute,
+ * and the "argv" style NULL-terminated vector of arguments for the command.
+ * The command is exec'd, and the file contents are sent to the command
+ * via stdin.
+ *
+ * WARNING: This function will try to adopt the userId of the supplied
+ * user name prior to exec'ing the supplied command.
+ */
+static void
+SendFileToCommand(
+ XpContextPtr pContext,
+ char *fileName,
+ char *pCommand,
+ char **argVector,
+ char *userName)
+{
+ pid_t childPid;
+ int pipefd[2];
+ int status;
+ struct stat statBuf;
+ FILE *fp, *outPipe;
+ FILE *resFp; /* output from launched command */
+ int resfd;
+
+ resFp = tmpfile();
+ if (resFp == NULL)
+ {
+ ErrorF("SendFileToCommand: Cannot open temporary file for command output\n");
+ return;
+ }
+ resfd = fileno(resFp);
+
+ if(pipe(pipefd))
+ {
+ ErrorF("SendFileToCommand: Cannot open pipe\n");
+ fclose(resFp);
+ return;
+ }
+
+ if(stat(fileName, &statBuf) < 0 || (int)statBuf.st_size == 0)
+ {
+ close(pipefd[0]);
+ close(pipefd[1]);
+ fclose(resFp);
+ return;
+ }
+
+ fp = fopen(fileName, "r");
+ if(fp == (FILE *)NULL)
+ {
+ ErrorF("SendFileToCommand: Cannot open scratch spool file '%s'\n", fileName);
+ close(pipefd[0]);
+ close(pipefd[1]);
+ fclose(resFp);
+ return;
+ }
+
+ if((childPid = fork()) == 0)
+ {
+ close(pipefd[1]);
+
+ /* Replace current stdin with input from the pipe */
+ close(STDIN_FILENO);
+ dup(pipefd[0]);
+ close(pipefd[0]);
+
+ /* Close current stdout and redirect it to resfd */
+ close(STDOUT_FILENO);
+ dup(resfd);
+
+ /* Close current stderr and redirect it to resfd
+ * (valgrind may not like that, in this case simply start it using
+ * % valgrind 50>/dev/tty --logfile-fd=50 <more-options> ./Xprt ... #)
+ */
+ close(STDERR_FILENO);
+ dup(resfd);
+
+ fclose(resFp);
+
+ /*
+ * If a user name is specified, try to set our uid to match that
+ * user name. This is to allow e.g. a banner page to show the
+ * name of the printing user rather than the user who started
+ * the print server.
+ */
+ if(userName)
+ {
+ uid_t myUid;
+
+ if((myUid = geteuid()) == (uid_t)0)
+ {
+ struct passwd *pPasswd;
+
+ if((pPasswd = getpwnam(userName)))
+ {
+ if (setgid((gid_t)pPasswd->pw_gid) != 0)
+ perror("SendFileToCommand: setgid() failure.");
+
+ if (initgroups(userName, (gid_t)pPasswd->pw_gid) != 0)
+ perror("SendFileToCommand: initgroups() failure.");
+
+ if (setuid((uid_t)pPasswd->pw_uid) != 0)
+ perror("SendFileToCommand: setuid() failure.");
+ }
+ }
+ }
+ /* return BadAlloc? */
+ if (execv(pCommand, argVector) == -1) {
+ FatalError("unable to exec '%s'", pCommand);
+ }
+ }
+ else
+ {
+ (void) close(pipefd[0]);
+
+ outPipe = fdopen(pipefd[1], "w");
+ (void) TransferBytes(fp, outPipe, (int)statBuf.st_size);
+
+ (void) fclose(outPipe);
+ (void) fclose(fp);
+
+ /* Wait for spooler child (and send all it's output to stderr) */
+ Tailf(resfd, STDERR_FILENO, childPid, &status);
+
+ if (status != EXIT_SUCCESS)
+ {
+ ErrorF("SendFileToCommand: spooler command returned non-zero status %d.\n", status);
+ }
+
+ /* Store "xp-spooler-command-results" XPJobAttr that the
+ * client can fetch it on demand */
+ if ((fstat(resfd, &statBuf) >= 0) && (statBuf.st_size >= 0))
+ {
+ long bufSize;
+ char *buf;
+
+ bufSize = statBuf.st_size;
+
+ /* Clamp buffer size to 4MB to prevent that we allocate giant
+ * buffers if the spooler goes mad and spams it's stdout/stderr
+ * channel. */
+ bufSize = MIN(bufSize, 4*1024*1024);
+
+ buf = xalloc(bufSize+1);
+ if (buf != NULL)
+ {
+ bufSize = pread(resfd, buf, bufSize, 0);
+ buf[bufSize]='\0';
+
+ /* XXX: This should be converted from local multibyte encoding to
+ * Compound Text encoding first */
+ XpPutOneAttribute(pContext, XPJobAttr, "xp-spooler-command-results", buf);
+
+ xfree(buf);
+ }
+ }
+ else
+ {
+ ErrorF("SendFileToCommand: fstat() failed.\n");
+ }
+
+ fclose(resFp);
+ }
+ return;
+}
+
+/*
+ * ReplaceAllKeywords causes all the predefined keywords (e.g. %options%)
+ * to be replaced with the appropriate values derived from the attribute
+ * store for the supplied print context. The ReplaceAnyString utility
+ * routine is used to perform the actual replacements.
+ */
+
+static char *
+ReplaceAllKeywords(
+ XpContextPtr pContext,
+ char *command)
+{
+ char *cmdOpt;
+
+ cmdOpt = XpGetOneAttribute(pContext, XPPrinterAttr,
+ "xp-spooler-printer-name");
+ if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0)
+ command = ReplaceAnyString(command, "%printer-name%", cmdOpt);
+ else
+ command = ReplaceAnyString(command, "%printer-name%",
+ pContext->printerName);
+
+ cmdOpt = XpGetOneAttribute(pContext, XPDocAttr, "copy-count");
+ if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0)
+ command = ReplaceAnyString(command, "%copy-count%", cmdOpt);
+ else
+ command = ReplaceAnyString(command, "%copy-count%", "1");
+
+ cmdOpt = XpGetOneAttribute(pContext, XPJobAttr, "job-name");
+ if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0)
+ command = ReplaceAnyString(command, "%job-name%", cmdOpt);
+ else
+ command = ReplaceAnyString(command, "%job-name%", "");
+
+ cmdOpt = XpGetOneAttribute(pContext, XPJobAttr, "job-owner");
+ if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0)
+ command = ReplaceAnyString(command, "%job-owner%", cmdOpt);
+ else
+ command = ReplaceAnyString(command, "%job-owner%", "");
+
+ cmdOpt = XpGetOneAttribute(pContext, XPJobAttr,
+ "xp-spooler-command-options");
+ if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0)
+ command = ReplaceAnyString(command, "%options%", cmdOpt);
+ else
+ command = ReplaceAnyString(command, "%options%", "");
+
+ /* New in xprint.mozdev.org release 007 - replace "%xpconfigdir%" with
+ * location of $XPCONFIGDIR */
+ command = ReplaceAnyString(command, "%xpconfigdir%", XpGetConfigDirBase());
+
+ return command;
+}
+
+#ifdef __QNX__
+#define toascii( c ) ((unsigned)(c) & 0x007f)
+#endif
+
+#if defined(CSRG_BASED) || \
+ defined(linux) || \
+ defined(__CYGWIN__) || \
+ (defined(sun) && !defined(SVR4)) || \
+ (defined(SVR4) && !defined(sun) && !defined(__UNIXWARE__)) || \
+ defined(__UNIXOS2__) || \
+ defined(ISC) || \
+ defined(Lynx) || \
+ defined(__QNX__) || \
+ defined(__DARWIN__)
+#define iswspace(c) (isascii(c) && isspace(toascii(c)))
+#endif
+
+/*
+ * GetToken - takes in a string and returns a malloc'd copy of the
+ * first non-white-space sequence of characters in the string.
+ * It returns the number of _bytes_ (NOT characters) parsed through
+ * the inStr to get to the end of the returned token.
+ */
+static int
+GetToken(
+ char *inStr,
+ char **outStr)
+{
+ size_t mbCurMax = MB_CUR_MAX;
+ wchar_t curChar;
+ int i, numBytes, byteLen = strlen(inStr);
+ char *tok;
+
+ /*
+ * read through any leading white space.
+ */
+ for(i = 0, numBytes = 0; i < byteLen; i += numBytes)
+ {
+ numBytes = mbtowc(&curChar, &inStr[i], mbCurMax);
+ if(!iswspace(curChar))
+ break;
+ }
+ tok = inStr + i;
+
+ /*
+ * find the end of the token.
+ */
+ byteLen = strlen(tok);
+ for(i = 0, numBytes = 0; i < byteLen; i += numBytes)
+ {
+ numBytes = mbtowc(&curChar, &tok[i], mbCurMax);
+ if(iswspace(curChar))
+ break;
+ }
+
+ if((*outStr = (char *)xalloc(i + 1)) == (char *)NULL)
+ return 0;
+ strncpy(*outStr, tok, i);
+ (*outStr)[i] = (char)'\0';
+ return (tok + i) - inStr;
+}
+
+static void
+FreeVector(
+ char **vector)
+{
+ int i;
+
+ if(vector == (char **)NULL) return;
+
+ for(i = 0; vector[i] != (char *)NULL; i++)
+ xfree(vector[i]);
+ xfree(vector);
+}
+
+
+/*
+ * AddVector appends the pAddition arg vector to the pTarget arg vector.
+ * If the pTarget cannot be realloc'd, then pTarget is set to NULL.
+ */
+static void
+AddVector(
+ char ***pTarget,
+ char **pAddition)
+{
+ int numTarget, numAdd, i;
+
+ for(numTarget = 0; (*pTarget)[numTarget] != (char *)NULL; numTarget++)
+ ;
+ for(numAdd = 0; pAddition[numAdd] != (char *)NULL; numAdd++)
+ ;
+
+ *pTarget = (char **)xrealloc((void *)*pTarget, (numTarget + numAdd + 1) *
+ sizeof(char *));
+ if(*pTarget == (char **)NULL)
+ return;
+ for(i = 0; i < numAdd; i++)
+ (*pTarget)[numTarget + i] = pAddition[i];
+
+ (*pTarget)[numTarget + numAdd] = (char *)NULL;
+}
+
+static char **
+BuildArgVector(
+ char *argString,
+ XpContextPtr pContext)
+{
+ char **pVector;
+ char *curTok;
+ int numChars, i;
+ static int beenHere = 0; /* prevent recursion on embedded %options%
+ */
+
+ pVector = (char **)xalloc(sizeof(char *));
+ pVector[0] = (char *)NULL;
+ for(i = 0; (numChars = GetToken(argString, &curTok)) != 0;
+ i++, argString += numChars)
+ {
+ if(beenHere || strcmp(curTok, "%options%"))
+ {
+ if(curTok[0] == (char)'\0')
+ {
+ xfree(curTok);
+ }
+ else
+ {
+ pVector = (char **)xrealloc((void *)pVector,
+ (i + 2)*sizeof(char *));
+ if(pVector == (char **)NULL)
+ return (char **)NULL;
+ pVector[i] = curTok;
+ pVector[i + 1] = (char *)NULL;
+ }
+ }
+ else if(!beenHere)
+ {
+ char **optionsVec;
+
+ curTok = ReplaceAllKeywords(pContext, curTok);
+ beenHere = 1;
+ optionsVec = BuildArgVector(curTok, pContext);
+ xfree(curTok);
+ beenHere = 0;
+ AddVector(&pVector, optionsVec);
+ xfree(optionsVec);
+ }
+ }
+ if(numChars == 0 && curTok != (char *)NULL)
+ xfree(curTok);
+ return pVector;
+}
+
+/*
+ * VectorizeCommand takes a string and breaks it into a command name and
+ * an array of character pointers suitable for handing to execv. The
+ * array is NULL-terminated.
+ * The returned char * is the command name, and should be freed when no
+ * longer needed. The array elements returned in the pVector parameter
+ * should be individually freed, and the array itself should also be
+ * freed when no longer needed.
+ */
+static char *
+VectorizeCommand(
+ char *command,
+ char ***pVector,
+ XpContextPtr pContext)
+{
+ char *cmdName;
+ int numChars;
+
+ if(command == (char *)NULL)
+ return (char *)NULL;
+
+ numChars = GetToken(command, &cmdName);
+
+ if(cmdName == (char *)NULL)
+ return (char *)NULL;
+
+ /* Mangle the command name, too... */
+ cmdName = ReplaceAllKeywords(pContext, cmdName);
+
+ if(cmdName == (char *)NULL)
+ return (char *)NULL;
+
+ *pVector = BuildArgVector(command, pContext);
+
+ return cmdName;
+}
+
+int
+XpSubmitJob(fileName, pContext)
+ char *fileName;
+ XpContextPtr pContext;
+{
+ char **vector, *cmdNam, *command, *userName;
+ int i;
+
+ command = XpGetOneAttribute(pContext, XPPrinterAttr, "xp-spooler-command");
+ if(command == (char *)NULL || strlen(command) == 0)
+ {
+ if( spooler_type )
+ {
+ command = strdup(spooler_type->spool_command);
+ }
+ else
+ {
+ ErrorF("XpSubmitJob: No default spool command defined.\n");
+ }
+ }
+ else
+ {
+ command = strdup(command);
+ }
+ if(command == (char *)NULL)
+ {
+ ErrorF("XpSubmitJob: No spooler command found, cannot submit job.\n");
+ return BadAlloc;
+ }
+
+ cmdNam = VectorizeCommand(command, &vector, pContext);
+ xfree(command);
+
+ if(cmdNam == (char *)NULL)
+ return BadAlloc;
+
+ for(i = 0; vector[i] != (char *)NULL; i++)
+ {
+ vector[i] = ReplaceAllKeywords(pContext, vector[i]);
+ if(vector[i] == (char *)NULL)
+ {
+ xfree(cmdNam);
+ for(i = 0; vector[i] != (char *)NULL; i++)
+ xfree(vector[i]);
+ xfree(vector);
+ return BadAlloc;
+ }
+ }
+
+ userName = XpGetOneAttribute(pContext, XPJobAttr, "job-owner");
+ if(userName != (char *)NULL && strlen(userName) == 0)
+ userName = (char *)NULL;
+
+ SendFileToCommand(pContext, fileName, cmdNam, vector, userName);
+
+ FreeVector(vector);
+ xfree(cmdNam);
+
+ return Success;
+}
+
+/*
+ * SearchInputTrays()
+ *
+ * Given a tray, return the medium in the tray. Conversely, given a
+ * medium, return a tray in which it can be found. In either case,
+ * return NULL if the given tray or medium cannot be found.
+ */
+#define TRAY 0
+#define MEDIUM 1
+
+static char *
+SearchInputTrays(XpContextPtr pCon,
+ int which,
+ char *val)
+{
+ char *inputTraysMedium, tray[80], medium[80], *copy;
+ char *pS, *pE, *pLast;
+
+ inputTraysMedium = XpGetOneAttribute( pCon, XPPrinterAttr,
+ "input-trays-medium" );
+
+ copy = strdup( inputTraysMedium );
+ pS = copy;
+ pLast = copy + strlen( copy );
+
+ while( pS < pLast )
+ {
+ while( *pS && *pS != '{' )
+ pS++;
+
+ pE = ++pS;
+ while( *pE && *pE != '}' )
+ pE++;
+ *pE = '\0';
+
+ sscanf( pS, "%s %s", tray, medium );
+
+ if( which == MEDIUM && !strcmp( val, medium ) )
+ {
+ xfree( copy );
+ return strdup( tray );
+ }
+
+ if( which == TRAY && !strcmp( val, tray ) )
+ {
+ xfree( copy );
+ return strdup( medium );
+ }
+
+ pS = pE + 1;
+ }
+
+ xfree( copy );
+ return strdup( NULL_STRING );
+}
+
+/*
+ * XpGetTrayMediumFromContext()
+ *
+ * Given a print context, hit the input-trays-medium,
+ * default-input-tray and default-medium attributes to find the
+ * appropriate tray to use, and the medium in that tray.
+ */
+void
+XpGetTrayMediumFromContext(XpContextPtr pCon,
+ char **medium,
+ char **tray)
+{
+ char *defMedium, *defTray;
+ char *t, *m;
+
+ defMedium = XpGetOneAttribute( pCon, XPPageAttr,
+ "default-medium" );
+ if( *defMedium == '\0' )
+ defMedium = XpGetOneAttribute( pCon, XPDocAttr,
+ "default-medium" );
+
+ defTray = XpGetOneAttribute( pCon, XPPageAttr,
+ "default-input-tray" );
+ if( *defTray == '\0' )
+ defTray = XpGetOneAttribute( pCon, XPDocAttr,
+ "default-input-tray" );
+
+ /*
+ * First, check to see if the default tray has the default medium
+ * installed. This is the ideal case.
+ */
+ m = SearchInputTrays( pCon, TRAY, defTray );
+ if( !strcmp( m, defMedium ) )
+ {
+ xfree( m );
+ *tray = strdup( defTray );
+ *medium = strdup( defMedium );
+ return;
+ }
+
+ /*
+ * If the default tray doesn't have the default medium, search for
+ * a tray which has the default medium.
+ */
+ t = SearchInputTrays( pCon, MEDIUM, defMedium );
+ if( t )
+ {
+ *tray = t;
+ *medium = strdup( defMedium );
+ return;
+ }
+
+ /*
+ * If all else fails, just return the default tray, and whatever
+ * medium happens to be there. Note that we simply return
+ * whatever is in the attribute store. Any further correction is
+ * left up to the DDX driver.
+ */
+ *tray = strdup( defTray );
+ *medium = m;
+ xfree( t );
+}
diff --git a/hw/xprint/attributes.h b/hw/xprint/attributes.h
new file mode 100644
index 000000000..40df4fd0b
--- /dev/null
+++ b/hw/xprint/attributes.h
@@ -0,0 +1,131 @@
+/* $Xorg: attributes.h,v 1.4 2001/03/14 18:42:44 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _Xp_attributes_h
+#define _Xp_attributes_h 1
+
+#include "scrnintstr.h"
+#include "AttrValid.h"
+
+#define BFuncArgs int ndx, ScreenPtr pScreen, int argc, char **argv
+typedef Bool (*pBFunc)(BFuncArgs);
+
+#define VFuncArgs char *name, XpValidatePoolsRec *pValRec, float *width, float *height, int *res
+typedef void (*pVFunc)(VFuncArgs);
+
+/*
+ * attributes.c
+ */
+void XpInitAttributes(XpContextPtr pContext);
+void XpBuildAttributeStore(char *printerName,
+ char *qualifierName);
+void XpAddPrinterAttribute(char *printerName,
+ char *printerQualifier,
+ char *attributeName,
+ char *attributeValue);
+void XpDestroyAttributes(XpContextPtr pContext);
+char *XpGetConfigDir(Bool useLocale);
+char *XpGetOneAttribute(XpContextPtr pContext,
+ XPAttributes class,
+ char *attributeName);
+void XpPutOneAttribute(XpContextPtr pContext,
+ XPAttributes class,
+ const char* attributeName,
+ const char* value);
+int XpRehashAttributes(void);
+char *XpGetAttributes(XpContextPtr pContext,
+ XPAttributes class);
+int XpAugmentAttributes(XpContextPtr pContext,
+ XPAttributes class,
+ char *attributes);
+int XpSetAttributes(XpContextPtr pContext,
+ XPAttributes class,
+ char *attributes);
+const char *XpGetPrinterAttribute(const char *printerName,
+ const char *attribute);
+void XpGetTrayMediumFromContext(XpContextPtr pCon,
+ char **medium,
+ char **tray);
+int XpSubmitJob(char *fileName, XpContextPtr pContext);
+
+/*
+ * mediaSizes.c
+ */
+int XpGetResolution(XpContextPtr pContext);
+XpOid XpGetContentOrientation(XpContextPtr pContext);
+XpOid XpGetAvailableCompression(XpContextPtr pContext);
+XpOid XpGetPlex(XpContextPtr pContext);
+XpOid XpGetPageSize(XpContextPtr pContext,
+ XpOid* pTray,
+ const XpOidMediumSS* msss);
+void XpGetMediumMillimeters(XpOid page_size,
+ float *width,
+ float *height);
+void XpGetMediumDimensions(XpContextPtr pContext,
+ unsigned short *width,
+ unsigned short *height);
+void XpGetReproductionArea(XpContextPtr pContext,
+ xRectangle *pRect);
+void XpGetMaxWidthHeightRes(const char *printer_name,
+ const XpValidatePoolsRec* vpr,
+ float *width,
+ float *height,
+ int* resolution);
+
+/* Util.c */
+char *ReplaceAnyString(char *string,
+ char *target,
+ char *replacement);
+char *ReplaceFileString(char *string,
+ char *inFileName,
+ char *outFileName);
+int TransferBytes(FILE *pSrcFile,
+ FILE *pDstFile,
+ int numBytes);
+Bool CopyContentsAndDelete(FILE **ppSrcFile,
+ char **pSrcFileName,
+ FILE *pDstFile);
+int XpSendDocumentData(ClientPtr client,
+ FILE *fp,
+ int fileLen,
+ int maxBufSize);
+int XpFinishDocData(ClientPtr client);
+Bool XpOpenTmpFile(char *mode,
+ char **fname,
+ FILE **stream);
+
+#endif /* _Xp_attributes_h */
diff --git a/hw/xprint/config/C/Makefile.am b/hw/xprint/config/C/Makefile.am
new file mode 100644
index 000000000..0390ed2d4
--- /dev/null
+++ b/hw/xprint/config/C/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = print
diff --git a/hw/xprint/config/C/print/Makefile.am b/hw/xprint/config/C/print/Makefile.am
new file mode 100644
index 000000000..e3c01da60
--- /dev/null
+++ b/hw/xprint/config/C/print/Makefile.am
@@ -0,0 +1,14 @@
+SUBDIRS = attributes ddx-config models
+
+xpcdir = @xpconfigdir@/C/print
+
+
+Xprinters.ghostscript: $(srcdir)/Xprinters
+ sed < $(srcdir)/Xprinters "s/#Printer xp_pdf_spooldir_tmp_Xprintjobs/Printer xp_pdf_spooldir_tmp_Xprintjobs/" > Xprinters.ghostscript
+
+
+
+dist_xpc_DATA = Xprinters
+xpc_DATA = Xprinters.ghostscript
+
+CLEANFILES = Xprinters.ghostscript
diff --git a/hw/xprint/config/C/print/Xprinters b/hw/xprint/config/C/print/Xprinters
new file mode 100644
index 000000000..a32c02dc2
--- /dev/null
+++ b/hw/xprint/config/C/print/Xprinters
@@ -0,0 +1,49 @@
+########################################################################
+#
+# $Xorg: Xprinters,v 1.3 2000/08/17 19:48:02 cpqbld Exp $
+#
+# X*printers sample configuration file
+#
+#
+# This file belongs in /usr/lib/X11/X*printers, where the "*" is the
+# display number of the server. For example, if the server is
+# invoked using the command X :0, then the X0printers file is used.
+########################################################################
+
+########################################################################
+# Use lpstat to augment the list of printers managed by the
+# server. (This is the default behavior if the X*printers file does
+# not exist, or if an "Augment_Printer_List" line is not specified.)
+########################################################################
+#Augment_Printer_List %(default)%
+
+########################################################################
+# Use the specified command pipeline to augment the list of printers
+# managed by the server.
+########################################################################
+#Augment_Printer_List lpstat -a | cut -d " " -f 1 # equivalent to default
+
+########################################################################
+# Do not augment the list of printers managed by the server.
+########################################################################
+#Augment_Printer_List %none%
+
+########################################################################
+# Preconfigured entry for the PSspooldir model
+# (which sends jobs to /tmp/Xprintjobs instead to a physical printer)
+########################################################################
+#Printer xp_pdf_spooldir_tmp_Xprintjobs
+Printer xp_ps_spooldir_tmp_Xprintjobs
+
+########################################################################
+# Add individual printers to the list of printers managed by the
+# server. These are aliases, determined by driver name.
+########################################################################
+
+
+# EXAMPLES
+#
+# Printer xppspr
+# Printer xppclpr
+# Printer xppclmonopr
+# Printer xprasterpr
diff --git a/hw/xprint/config/C/print/attributes/Makefile.am b/hw/xprint/config/C/print/attributes/Makefile.am
new file mode 100644
index 000000000..0d2cceaff
--- /dev/null
+++ b/hw/xprint/config/C/print/attributes/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/C/print/attributes
+
+dist_xpc_DATA = document job printer
diff --git a/hw/xprint/config/C/print/attributes/document b/hw/xprint/config/C/print/attributes/document
new file mode 100644
index 000000000..b1651bd94
--- /dev/null
+++ b/hw/xprint/config/C/print/attributes/document
@@ -0,0 +1,49 @@
+# $Xorg: document,v 1.3 2000/08/17 19:48:03 cpqbld Exp $
+# Document DPA-Object initial attribute values
+
+# Attribute IDs must be qualified by using one of the following
+# (listed in order of precedence):
+#
+# printer-name
+# Set this attribute for a specific printer.
+# Example: "dj_1.plex: duplex"
+#
+# printer-model
+# Set this attribute for all printers of a specific model.
+# Example: "HPDJ1600C.plex: duplex"
+#
+# '*'
+# Set this attribute for all printers.
+# Example: "*.plex: duplex"
+
+
+*content-orientation: portrait
+*copy-count: 1
+*default-medium: iso-a4
+*default-printer-resolution: 600
+
+# "PSspooldir" jobs should always be 300 DPI
+# (to be compatible to DPS-based PostScript viewers such as sdtimage)
+PSspooldir.default-printer-resolution: 300
+
+# "PS2PDFspooldir-GS" jobs should always be 600 DPI
+PS2PDFspooldir-GS.default-printer-resolution: 600
+
+# Some resolution defaults to make applications happy which are too lazy
+# to pick an own default in absence of "default-printer-resolution"
+HPLJ4050-PS.default-printer-resolution: 600
+SPSPARC2.default-printer-resolution: 300
+CANONBJ10E-GS.default-printer-resolution: 360
+CANONC3200-PS.default-printer-resolution: 600
+
+# EXAMPLES
+#
+# *content-orientation: landscape
+# *copy-count: 3
+# *default-input-tray: main
+# *default-medium: iso-a4
+# *default-printer-resolution: 600
+# *document-format: {PCL 5}
+# *plex: simplex
+# *xp-listfonts-modes: xp-list-internal-printer-fonts
+
diff --git a/hw/xprint/config/C/print/attributes/job b/hw/xprint/config/C/print/attributes/job
new file mode 100644
index 000000000..aa1911dcd
--- /dev/null
+++ b/hw/xprint/config/C/print/attributes/job
@@ -0,0 +1,25 @@
+# $Xorg: job,v 1.3 2000/08/17 19:48:03 cpqbld Exp $
+# Job DPA-Object initial attribute values
+
+# Attribute IDs must be qualified by using one of the following
+# (listed in order of precedence):
+#
+# printer-name
+# Set this attribute for a specific printer.
+# Example: "laser_1.job-priority: 1"
+#
+# printer-model
+# Set this attribute for all printers of a specific model.
+# Example: "HPDJ1600C.job-priority: 1"
+#
+# '*'
+# Set this attribute for all printers.
+# Example: "*.job-priority: 1"
+
+*notification-profile: {}
+
+# EXAMPLES
+#
+# *job-name: Example Job Name
+# *notification-profile: {{event-report-job-completed} electronic-mail}
+# *xp-spooler-command-options: -onb
diff --git a/hw/xprint/config/C/print/attributes/printer b/hw/xprint/config/C/print/attributes/printer
new file mode 100644
index 000000000..41e13b44b
--- /dev/null
+++ b/hw/xprint/config/C/print/attributes/printer
@@ -0,0 +1,96 @@
+# $Xorg: printer,v 1.3 2000/08/17 19:48:03 cpqbld Exp $
+# Printer DPA-Object initial attribute values
+
+# Attribute IDs must be qualified by using one of the following
+# (listed in order of precedence):
+#
+# printer-name
+# Set this attribute for a specific printer.
+# Example: "dj_1.document-formats-ready: {pcl 5}"
+#
+# printer-model
+# Set this attribute for all printers of a specific model.
+# Example: "HPDJ1600C.document-formats-ready: {pcl 5}"
+#
+# '*'
+# Set this attribute for all printers.
+# Example: "*.document-formats-ready: {pcl 5}"
+
+# Remove this line and replace them with per printer settings
+# if you want to use more than one DDX!!
+*xp-model-identifier: PSdefault
+
+
+# Sample entry for the "PSspooldir" model
+# Just add a printer called "xp_ps_spooldir_tmp_Xprintjobs" to "Xprinters"
+# and you will get an extra printer which files the PostScript jobs
+# in the "/tmp/Xprintjobs/" directory.
+xp_ps_spooldir_tmp_Xprintjobs.xp-model-identifier: PSspooldir
+
+# Sample entry for the "PS2PDFspooldir-GS" model
+# Just add a printer called "xp_pdf_spooldir_tmp_Xprintjobs" to "Xprinters"
+# and you will get an extra printer which convertes the PostScript jobs
+# to PDF using "ps2pdf" and files them into the "/tmp/Xprintjobs/" directory.
+# NOTE: Future versions of Xprint will use the PDF DDX instead directly
+# instead of relying on GhostScript/ps2pdf...
+xp_pdf_spooldir_tmp_Xprintjobs.xp-model-identifier: PS2PDFspooldir-GS
+
+
+# IMPORTANT EXAMPLES
+#
+# The following are examples of how a printer name is bound
+# to a model-config file and ddx driver.
+#
+# Warning: most X-Servers have a hard limit on the number of ddx
+# drivers (ie, screens) they can support at runtime (usually 3 or
+# 4). Whatever the number of printers, they cannot create a
+# dependency for more than the limit on ddx drivers. Assuming
+# "Xprinters" listed all four xp*pr printers below, X-Servers
+# with a limit of 3 would not work.
+#
+# xppspr.xp-model-identifier: HPDJ1600C
+# xppspr.xp-ddx-identifier: XP-POSTSCRIPT
+# xppspr.document-formats-ready: { PostScript 2 }
+#
+# xppclpr.xp-model-identifier: HPDJ1600C
+# xppclpr.xp-ddx-identifier: XP-PCL-COLOR
+# xppclpr.document-formats-ready: { PCL 5 }
+#
+# xppclmonopr.xp-model-identifier: HPDJ1600C
+# xppclmonopr.xp-ddx-identifier: XP-PCL-MONO
+# xppclmonopr.document-formats-ready: { PCL 5 }
+#
+# xprasterpr.xp-model-identifier: HPDJ1600C
+# xprasterpr.xp-ddx-identifier: XP-RASTER
+
+
+# MORE EXAMPLES of items often configured in this file
+#
+# *descriptor: This printer has not been given a name
+# *dt-pdm-command: dtpdm
+# *input-trays-medium: {top na-letter} {bottom iso-a4}
+# *xp-model-identifier: HPDJ1600C
+# *xp-spooler-command: /opt/mystuff/bin/mylp -p %printer-name% -c %copy-count% \
+# -j %job-name% -o %options%
+
+
+# USUALLY SET BY THE ddx driver
+#
+# *content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+
+
+# USUALLY SET BY THE model-config FILE
+#
+# *document-formats-supported: {PCL 5}
+# *medium-source-sizes-supported: \
+# { top {iso-a4 FALSE {10 200 10 287}} {iso-a5 FALSE {10 138 10 200}} } \
+# { bottom {iso-a4 FALSE {10 200 10 287}} {iso-a5 FALSE {10 138 10 200}} }
+# *plexes-supported: simplex duplex tumble
+# *printer-model: Hewlett-Packard LaserJet IV
+# *printer-resolutions-supported: 300
+# *xp-ddx-identifier: XP-PCL-COLOR
+# *xp-embedded-formats-supported: {PCL 5} {HPGL 2}
+# *xp-listfonts-modes-supported: xp-list-internal-printer-fonts
+# *xp-raw-formats-supported: {PCL 5}
+# *xp-setup-proviso: xp-setup-optional
+
diff --git a/hw/xprint/config/C/print/ddx-config/Makefile.am b/hw/xprint/config/C/print/ddx-config/Makefile.am
new file mode 100644
index 000000000..907edca75
--- /dev/null
+++ b/hw/xprint/config/C/print/ddx-config/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = raster
diff --git a/hw/xprint/config/C/print/ddx-config/raster/Makefile.am b/hw/xprint/config/C/print/ddx-config/raster/Makefile.am
new file mode 100644
index 000000000..79bfb59df
--- /dev/null
+++ b/hw/xprint/config/C/print/ddx-config/raster/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/C/print/ddx-config/raster
+
+dist_xpc_DATA = pcl postscript
diff --git a/hw/xprint/config/C/print/ddx-config/raster/pcl b/hw/xprint/config/C/print/ddx-config/raster/pcl
new file mode 100644
index 000000000..15d33e7b3
--- /dev/null
+++ b/hw/xprint/config/C/print/ddx-config/raster/pcl
@@ -0,0 +1,39 @@
+# $Xorg: pcl,v 1.3 2000/08/17 19:48:03 cpqbld Exp $
+# This is the file which you should customize to include the printers that
+# will print through the raster driver. The early part of this file
+# specifies some commn useful defaults. You can override them when
+# you list your printers in the second part of this file. This file is
+# an X Resource file. To learn more about this file format, consult
+# the functional specification.
+
+# Note that the reference printer for CDEnext is the HP DeskJet 1600C.
+# This driver may work for other printers, but the reference printer
+# is the only officially supported printer.
+
+
+# DEFAULTS
+# ========
+
+# The attributes below apply to all printers unless the section below
+# specifies something different for the printer.
+
+# Default printer attributes
+# --------------------------
+# Printer attributes control the choices that users will see in the
+# setup dialog for those printers.
+
+# The attributes below apply to all printes unless the section below
+# specifies something different for the printer.
+
+*.media-ready: na-letter-white
+*.descriptor: Printer supported by CDEnext DtPrint System.
+*.printer-model: HPDJ1600C
+
+# Printer Specifics
+
+# Use this section to override the defaults listed above or to override the
+# printer attributes described in the model file.
+# The lines describing "laser" are just a sample to help you get started.
+
+# laser.printer-name: laser
+# laser.spooler-name: laser
diff --git a/hw/xprint/config/C/print/ddx-config/raster/postscript b/hw/xprint/config/C/print/ddx-config/raster/postscript
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/hw/xprint/config/C/print/ddx-config/raster/postscript
diff --git a/hw/xprint/config/C/print/models/CANONBJ10E-GS/Makefile.am b/hw/xprint/config/C/print/models/CANONBJ10E-GS/Makefile.am
new file mode 100644
index 000000000..951b9af97
--- /dev/null
+++ b/hw/xprint/config/C/print/models/CANONBJ10E-GS/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/C/print/models/CANONBJ10E-GS
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/CANONBJ10E-GS/model-config b/hw/xprint/config/C/print/models/CANONBJ10E-GS/model-config
new file mode 100644
index 000000000..97bfd8196
--- /dev/null
+++ b/hw/xprint/config/C/print/models/CANONBJ10E-GS/model-config
@@ -0,0 +1,23 @@
+# $Xprint.org: CANONBJ10E-GS model-config,v 1.4 2003/02/10 14:48:04 gisburn Exp $
+
+*content-orientations-supported: portrait landscape
+*descriptor: Canon BJ-10e (GhostScript)
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {iso-b5 FALSE {6.35 169.65 6.35 243.65}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+}
+
+*plexes-supported: simplex
+*printer-model: "Canon BJ-10e (GhostScript)"
+*printer-resolutions-supported: 360
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+# EOF.
diff --git a/hw/xprint/config/C/print/models/CANONC3200-PS/Makefile.am b/hw/xprint/config/C/print/models/CANONC3200-PS/Makefile.am
new file mode 100644
index 000000000..771b40864
--- /dev/null
+++ b/hw/xprint/config/C/print/models/CANONC3200-PS/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = fonts
+
+xpcdir = @xpconfigdir@/C/print/models/CANONC3200-PS
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/CANONC3200-PS/fonts/Makefile.am b/hw/xprint/config/C/print/models/CANONC3200-PS/fonts/Makefile.am
new file mode 100644
index 000000000..5be5419ba
--- /dev/null
+++ b/hw/xprint/config/C/print/models/CANONC3200-PS/fonts/Makefile.am
@@ -0,0 +1,54 @@
+xpcdir = @xpconfigdir@/C/print/models/CANONC3200-PS/fonts
+
+parentdir = @xpconfigdir@/C/print/models/PSdefault/fonts
+
+XPFONTS = \
+ AvantGarde-Book.pmf \
+ AvantGarde-BookOblique.pmf \
+ AvantGarde-Demi.pmf \
+ AvantGarde-DemiOblique.pmf \
+ Courier-Bold.pmf \
+ Courier-BoldOblique.pmf \
+ Courier-Oblique.pmf \
+ Courier.pmf \
+ Helvetica-Bold.pmf \
+ Helvetica-BoldOblique.pmf \
+ Helvetica-Oblique.pmf \
+ Helvetica.pmf \
+ LubalinGraph-Book.pmf \
+ LubalinGraph-BookOblique.pmf \
+ LubalinGraph-Demi.pmf \
+ LubalinGraph-DemiOblique.pmf \
+ NewCenturySchlbk-Bold.pmf \
+ NewCenturySchlbk-BoldItalic.pmf \
+ NewCenturySchlbk-Italic.pmf \
+ NewCenturySchlbk-Roman.pmf \
+ Souvenir-Demi.pmf \
+ Souvenir-DemiItalic.pmf \
+ Souvenir-Light.pmf \
+ Souvenir-LightItalic.pmf \
+ Symbol.pmf \
+ Times-Bold.pmf \
+ Times-BoldItalic.pmf \
+ Times-Italic.pmf \
+ Times-Roman.pmf \
+ ZapfDingbats.pmf
+
+dest = $(DESTDIR)$(xpcdir)
+
+remove-stuff:
+ for x in $(XPFONTS) ; do \
+ rm -f $(dest)/$$x ; \
+ done
+
+ @rm -f $(dest)/fonts.dir
+
+install-data-hook: remove-stuff
+ mkdir -p $(dest) ; \
+ for x in $(XPFONTS) ; do \
+ ln -s $(parentdir)/$$x $(dest)/$$x ; \
+ done
+
+ $(MKFONTSCALE) -b -s -l $(dest)
+
+uninstall-hook: remove-stuff
diff --git a/hw/xprint/config/C/print/models/CANONC3200-PS/model-config b/hw/xprint/config/C/print/models/CANONC3200-PS/model-config
new file mode 100644
index 000000000..cdb3f4958
--- /dev/null
+++ b/hw/xprint/config/C/print/models/CANONC3200-PS/model-config
@@ -0,0 +1,40 @@
+# $Xprint.org: CANONC3200-PS model-config,v 1.1 2004/06/24 09:18:04 gisburn Exp $
+# model-config for the PostScript DDX
+#
+# automatically generated by xpppdtomodelconfig V0.1
+#
+# DO NOT MODIFY THIS FILE!!
+#
+# Attributes supported for this printer model
+*content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+*descriptor: Canon iR C3200
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {iso-a4 FALSE {4.002 206 4.002 293}}\
+ {na-letter FALSE {4.002 211.9 4.002 275.4}}\
+ {na-legal FALSE {4.002 211.9 4.002 351.6}}\
+ {iso-a3 FALSE {4.002 293 4.002 416}}\
+ {iso-a5 FALSE {4.002 144 4.002 206}}\
+ {iso-b4 FALSE {4.002 246 4.002 349}}\
+ {iso-b5 FALSE {4.002 172 4.002 246}}\
+ {executive FALSE {4.002 180.1 4.002 262.7}}\
+ {invoice FALSE {4.002 135.7 4.002 211.9}}\
+ {monarch-envelope FALSE {4.002 94.3 4.002 186.5}}\
+ {na-number-10-envelop FALSE {4.002 100.8 4.002 237.3}}\
+ {iso-c5 FALSE {4.002 158 4.002 225}}\
+}
+
+*plexes-supported: simplex duplex tumble
+*printer-model: "Canon iR C3200"
+*printer-resolutions-supported: 600
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+# NOTE: xp-psddx-* attributes are EXPERIMENTAL for now.
+*xp-psddx-download-fonts: pfa pfb ttf ttc otf otc
+*xp-psddx-download-font-type: pstype1
+# EOF.
diff --git a/hw/xprint/config/C/print/models/GSdefault/Makefile.am b/hw/xprint/config/C/print/models/GSdefault/Makefile.am
new file mode 100644
index 000000000..be0426c76
--- /dev/null
+++ b/hw/xprint/config/C/print/models/GSdefault/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/C/print/models/GSdefault
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/GSdefault/model-config b/hw/xprint/config/C/print/models/GSdefault/model-config
new file mode 100644
index 000000000..61dac18b8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/GSdefault/model-config
@@ -0,0 +1,137 @@
+# $Xprint.org: GSdefault model-config,v 1.1 2003/02/10 14:48:04 gisburn Exp $
+# Generic default model-config for the PostScript DDX when using GhostScript
+# as printer driver
+#
+# DO NOT MODIFY THIS FILE!!
+#
+# If you want to make customisations for your printer create a copy
+# of this printer model.
+# Example (for creating a model config "MYCOMPANYlaserxx"):
+# 1. Create model config dir:
+# % mkdir MYCOMPANYlaserxx
+# 2. Link (or copy) the PMF (printer font metrics) for the
+# printer buildin fonts:
+# % ln -s GSdefault/fonts MYCOMPANYlaserxx/.
+# 3. Copy the model config file:
+# % cp GSdefault/model-config MYCOMPANYlaserxx/.
+# 4. Customize MYCOMPANYlaserxx/model-config to match your needs.
+#
+
+# Attributes supported for this printer model
+# You may want to cut the lists here down to the attributes supported
+# by your printer.
+*content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+*descriptor: GhostScript default model
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {executive FALSE {6.35 177.80 6.35 260.35}}\
+ {folio FALSE {6.35 204.47 6.35 323.85}}\
+ {invoice FALSE {6.35 133.35 6.35 209.55}}\
+ {ledger FALSE {6.35 273.05 6.35 425.45}}\
+ {quarto FALSE {6.35 209.55 6.35 268.732}}\
+ {a FALSE {6.35 209.55 6.35 273.05}}\
+ {b FALSE {6.35 273.05 6.35 425.45}}\
+ {c FALSE {6.35 425.45 6.35 552.45}}\
+ {d FALSE {6.35 552.45 6.35 857.25}}\
+ {e FALSE {6.35 857.25 6.35 1111.25}}\
+ {na-6x9-envelope FALSE {6.35 146.05 6.35 222.25}}\
+ {na-10x15-envelope FALSE {6.35 247.65 6.35 374.65}}\
+ {monarch-envelope FALSE {6.35 91.948 6.35 184.15}}\
+ {na-10x13-envelope FALSE {6.35 247.65 6.35 323.85}}\
+ {na-9x12-envelope FALSE {6.35 222.25 6.35 298.45}}\
+ {na-number-10-envelope FALSE {6.35 98.425 6.35 234.95}}\
+ {na-7x9-envelope FALSE {6.35 171.45 6.35 222.25}}\
+ {na-9x11-envelope FALSE {6.35 222.25 6.35 273.05}}\
+ {na-10x14-envelope FALSE {6.35 247.65 6.35 349.25}}\
+ {na-number-9-envelope FALSE {6.35 92.075 6.35 219.075}}\
+ {iso-a0 FALSE {6.35 834.65 6.35 1182.65}}\
+ {iso-a1 FALSE {6.35 587.65 6.35 834.65}}\
+ {iso-a2 FALSE {6.35 413.65 6.35 587.65}}\
+ {iso-a3 FALSE {6.35 290.65 6.35 413.65}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {iso-a5 FALSE {6.35 141.65 6.35 203.65}}\
+ {iso-a6 FALSE {6.35 98.65 6.35 141.65}}\
+ {iso-a7 FALSE {6.35 67.65 6.35 98.65}}\
+ {iso-a8 FALSE {6.35 45.65 6.35 67.65}}\
+ {iso-a9 FALSE {6.35 30.65 6.35 45.65}}\
+ {iso-a10 FALSE {6.35 19.65 6.35 30.65}}\
+ {iso-b1 FALSE {6.35 700.65 6.35 993.65}}\
+ {iso-b2 FALSE {6.35 493.65 6.35 700.65}}\
+ {iso-b3 FALSE {6.35 346.65 6.35 493.65}}\
+ {iso-b4 FALSE {6.35 243.65 6.35 346.65}}\
+ {iso-b5 FALSE {6.35 169.65 6.35 243.65}}\
+ {iso-b6 FALSE {6.35 118.65 6.35 169.65}}\
+ {iso-b7 FALSE {6.35 81.65 6.35 118.65}}\
+ {iso-b8 FALSE {6.35 55.65 6.35 81.65}}\
+ {iso-b9 FALSE {6.35 37.65 6.35 55.65}}\
+ {iso-b10 FALSE {6.35 24.65 6.35 37.65}}\
+ {jis-b1 FALSE {6.35 721.65 6.35 1023.65}}\
+ {jis-b2 FALSE {6.35 508.65 6.35 721.65}}\
+ {jis-b3 FALSE {6.35 357.65 6.35 508.65}}\
+ {jis-b4 FALSE {6.35 250.65 6.35 357.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+ {jis-b6 FALSE {6.35 121.65 6.35 175.65}}\
+ {jis-b7 FALSE {6.35 84.65 6.35 121.65}}\
+ {jis-b8 FALSE {6.35 57.65 6.35 84.65}}\
+ {jis-b9 FALSE {6.35 38.65 6.35 57.65}}\
+ {jis-b10 FALSE {6.35 25.65 6.35 38.65}}\
+ {iso-c3 FALSE {6.35 317.65 6.35 451.65}}\
+ {iso-c4 FALSE {6.35 222.65 6.35 317.65}}\
+ {iso-c5 FALSE {6.35 155.65 6.35 222.65}}\
+ {iso-c6 FALSE {6.35 107.65 6.35 155.65}}\
+ {iso-designated-long FALSE {6.35 103.65 6.35 213.65}}\
+ {hp-2x-postcard FALSE {6.35 141.65 6.35 193.65}}\
+ {hp-european-edp FALSE {6.35 298.45 6.35 349.25}}\
+ {hp-mini FALSE {6.35 133.35 6.35 209.55}}\
+ {hp-postcard FALSE {6.35 93.65 6.35 141.65}}\
+ {hp-tabloid FALSE {6.35 273.05 6.35 425.45}}\
+ {hp-us-edp FALSE {6.35 273.05 6.35 349.25}}\
+ {hp-us-government-legal FALSE {6.35 196.85 6.35 323.85}}\
+ {hp-us-government-letter FALSE {6.35 196.85 6.35 247.65}}\
+}
+# If you have more than one tray use the following example:
+# 1. List the supported trays
+#*input-trays-supported: main manual
+# 2. Define each tray and it's paper sizes
+#*medium-source-sizes-supported: \
+#{ main \
+# {na-letter FALSE {6.35 209.55 6.35 273.05}} \
+# {na-legal FALSE {6.35 209.55 6.35 349.25}} \
+# {iso-a4 FALSE {6.35 203.65 6.35 290.65}} \
+#} \
+#{ manual \
+# {iso-a5 FALSE {6.35 141.65 6.35 203.65}} \
+# {iso-c5 FALSE {6.35 155.65 6.35 222.65}} \
+# {iso-designated-long FALSE {6.35 103.65 6.35 213.65}} \
+# {jis-b5 FALSE {6.35 175.65 6.35 250.65}} \
+# {monarch-envelope FALSE {6.35 91.948 6.35 184.15}} \
+# {na-legal FALSE {6.35 209.55 6.35 349.25}} \
+# {na-number-10-envelope FALSE {6.35 98.425 6.35 234.95}} \
+# {executive FALSE {6.35 177.8 6.35 260.35}} \
+# {iso-a3 FALSE {6.35 290.65 6.35 413.65}} \
+# {iso-a0 FALSE {6.35 834.65 6.35 1182.65}} \
+#}
+*plexes-supported: simplex duplex tumble
+*printer-model: "GhostScript default model"
+# 75, 100, 120, 150, 180, 200, 240, 300, 360, 400, 600, 720,
+# 940, 1200 and 2440 are supported DPI values, we limit it here
+# to some common values:
+*printer-resolutions-supported: 300 360 400 600
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+
+# NOTE: xp-psddx-* attributes are EXPERIMENTAL for now.
+# xp-psddx-download-fonts defines which fonts should be downloaded as outlines
+# (valid types are "pfa", "pfb", "ttf", "ttc", "otf", "otc")
+*xp-psddx-download-fonts: pfa pfb ttf ttc otf otc
+# xp-psddx-download-font-type defines which font type is used to download outlines
+# (valid values are "bitmap", "pstype1" and "pstype3")
+*xp-psddx-download-font-type: pstype1
+# EOF.
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/Makefile.am b/hw/xprint/config/C/print/models/HPDJ1600C/Makefile.am
new file mode 100644
index 000000000..1c8b3b5c6
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = fonts
+
+xpcdir = @xpconfigdir@/C/print/models/HPDJ1600C
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00051.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00051.pmf
new file mode 100644
index 000000000..09cc489a5
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00051.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00052.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00052.pmf
new file mode 100644
index 000000000..b21a9a2a8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00052.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00053.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00053.pmf
new file mode 100644
index 000000000..485b874c5
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00053.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00054.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00054.pmf
new file mode 100644
index 000000000..524934c71
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00054.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00055.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00055.pmf
new file mode 100644
index 000000000..2ef9bc52c
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00055.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00056.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00056.pmf
new file mode 100644
index 000000000..3d69311ef
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00056.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00057.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00057.pmf
new file mode 100644
index 000000000..3833d4f54
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00057.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00058.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00058.pmf
new file mode 100644
index 000000000..289a95e5c
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00058.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00059.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00059.pmf
new file mode 100644
index 000000000..a5984bed1
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00059.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00060.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00060.pmf
new file mode 100644
index 000000000..df27cd71e
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00060.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00061.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00061.pmf
new file mode 100644
index 000000000..fb2b5a433
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00061.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00062.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00062.pmf
new file mode 100644
index 000000000..f0e58c435
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00062.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00063.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00063.pmf
new file mode 100644
index 000000000..8821ff155
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00063.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00064.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00064.pmf
new file mode 100644
index 000000000..e5980fc0e
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00064.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00065.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00065.pmf
new file mode 100644
index 000000000..d9a151d7f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00065.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00066.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00066.pmf
new file mode 100644
index 000000000..d14fca56f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00066.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00067.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00067.pmf
new file mode 100644
index 000000000..7a341506f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00067.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00068.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00068.pmf
new file mode 100644
index 000000000..c20e39a21
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00068.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00069.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00069.pmf
new file mode 100644
index 000000000..4a4a35281
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00069.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00070.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00070.pmf
new file mode 100644
index 000000000..8d97d4339
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00070.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00071.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00071.pmf
new file mode 100644
index 000000000..19844c9c6
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00071.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00072.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00072.pmf
new file mode 100644
index 000000000..5415c3f44
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00072.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00073.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00073.pmf
new file mode 100644
index 000000000..038dfdb46
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00073.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00074.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00074.pmf
new file mode 100644
index 000000000..382a78575
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00074.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00075.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00075.pmf
new file mode 100644
index 000000000..1c7edf653
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00075.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00076.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00076.pmf
new file mode 100644
index 000000000..2f077f40f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00076.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00077.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00077.pmf
new file mode 100644
index 000000000..1ce190d51
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00077.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00079.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00079.pmf
new file mode 100644
index 000000000..45d6906ba
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00079.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00080.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00080.pmf
new file mode 100644
index 000000000..b991b5edb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00080.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00081.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00081.pmf
new file mode 100644
index 000000000..1935a9f00
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00081.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00082.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00082.pmf
new file mode 100644
index 000000000..2000dc057
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00082.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00083.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00083.pmf
new file mode 100644
index 000000000..90f0e45a8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00083.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00084.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00084.pmf
new file mode 100644
index 000000000..52ba39b96
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00084.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00085.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00085.pmf
new file mode 100644
index 000000000..f5c9053af
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00085.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00086.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00086.pmf
new file mode 100644
index 000000000..b7586ca61
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00086.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00087.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00087.pmf
new file mode 100644
index 000000000..82f054999
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00087.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00088.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00088.pmf
new file mode 100644
index 000000000..591c96b59
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00088.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00089.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00089.pmf
new file mode 100644
index 000000000..c8160954a
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00089.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00090.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00090.pmf
new file mode 100644
index 000000000..895cfe26a
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00090.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00091.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00091.pmf
new file mode 100644
index 000000000..3bdcae4ba
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00091.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00092.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00092.pmf
new file mode 100644
index 000000000..a56d47504
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00092.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00093.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00093.pmf
new file mode 100644
index 000000000..c85f3b4de
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00093.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00094.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00094.pmf
new file mode 100644
index 000000000..875bf1df8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/9nb00094.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/Makefile.am b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/Makefile.am
new file mode 100644
index 000000000..b32079e1d
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/Makefile.am
@@ -0,0 +1,50 @@
+xpcdir = @xpconfigdir@/C/print/models/HPDJ1600C/fonts
+
+dist_xpc_DATA = \
+ 9nb00051.pmf \
+ 9nb00052.pmf \
+ 9nb00053.pmf \
+ 9nb00054.pmf \
+ 9nb00055.pmf \
+ 9nb00056.pmf \
+ 9nb00057.pmf \
+ 9nb00058.pmf \
+ 9nb00059.pmf \
+ 9nb00060.pmf \
+ 9nb00061.pmf \
+ 9nb00062.pmf \
+ 9nb00063.pmf \
+ 9nb00064.pmf \
+ 9nb00065.pmf \
+ 9nb00066.pmf \
+ 9nb00067.pmf \
+ 9nb00068.pmf \
+ 9nb00069.pmf \
+ 9nb00070.pmf \
+ 9nb00071.pmf \
+ 9nb00072.pmf \
+ 9nb00073.pmf \
+ 9nb00074.pmf \
+ 9nb00075.pmf \
+ 9nb00076.pmf \
+ 9nb00077.pmf \
+ 9nb00079.pmf \
+ 9nb00080.pmf \
+ 9nb00081.pmf \
+ 9nb00082.pmf \
+ 9nb00083.pmf \
+ 9nb00084.pmf \
+ 9nb00085.pmf \
+ 9nb00086.pmf \
+ 9nb00087.pmf \
+ 9nb00088.pmf \
+ 9nb00089.pmf \
+ 9nb00090.pmf \
+ 9nb00091.pmf \
+ 9nb00092.pmf \
+ 9nb00093.pmf \
+ 9nb00094.pmf \
+ lpr0ye1a.pmf \
+ fonts.alias \
+ fonts.dir \
+ README
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/README b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/README
new file mode 100644
index 000000000..cccc2be32
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/README
@@ -0,0 +1,197 @@
+$Xorg: README,v 1.3 2000/08/17 19:48:04 cpqbld Exp $
+
+This directory contains "printer metric files" for the X Print
+Server suitable for the DeskJet 1600C printer. The following
+*.pmf files were generated by the Hewlett-Packard Company.
+
+ 9nb00051.pmf
+ 9nb00052.pmf
+ 9nb00053.pmf
+ 9nb00054.pmf
+ 9nb00055.pmf
+ 9nb00056.pmf
+ 9nb00057.pmf
+ 9nb00058.pmf
+ 9nb00059.pmf
+ 9nb00060.pmf
+ 9nb00061.pmf
+ 9nb00062.pmf
+ 9nb00063.pmf
+ 9nb00064.pmf
+ 9nb00065.pmf
+ 9nb00066.pmf
+ 9nb00067.pmf
+ 9nb00068.pmf
+ 9nb00069.pmf
+ 9nb00070.pmf
+ 9nb00071.pmf
+ 9nb00072.pmf
+ 9nb00073.pmf
+ 9nb00074.pmf
+ 9nb00075.pmf
+ 9nb00076.pmf
+ 9nb00077.pmf
+ 9nb00079.pmf
+ 9nb00080.pmf
+ 9nb00081.pmf
+ 9nb00082.pmf
+ 9nb00083.pmf
+ 9nb00084.pmf
+ 9nb00085.pmf
+ 9nb00086.pmf
+ 9nb00087.pmf
+ 9nb00088.pmf
+ 9nb00089.pmf
+ 9nb00090.pmf
+ 9nb00091.pmf
+ 9nb00092.pmf
+ 9nb00093.pmf
+ 9nb00094.pmf
+ lpr0ye1a.pmf
+
+For reasons of not supporting iso8859.1 and hp-roman8, the following
+DeskJet 1600C printer fonts were not converted to *.pmf files.
+
+ 9nb00078.pmf
+ 9nb00095.pmf
+ lpr0ylga.pmf
+ lpr0ypca.pmf
+ lpr0ypda.pmf
+ lpr0ypma.pmf
+ lpr0yr8a.pmf
+
+Output from the conversion utility is as follows:
+
+ Creating iso8859 1 pmf for 9nb00051.tfm as iso8859.1/9nb00051.pmf
+ -COMPUGRAPHIC-Albertus-Extra Bold-r-Normal--8782-2500-2540-2540-P-42480-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00052.tfm as iso8859.1/9nb00052.pmf
+ -COMPUGRAPHIC-Albertus-Semi Bold-r-Normal--8782-2500-2540-2540-P-37640-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00053.tfm as iso8859.1/9nb00053.pmf
+ -COMPUGRAPHIC-Antique Olive-Bold-r-Normal--8782-2500-2540-2540-P-50490-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00054.tfm as iso8859.1/9nb00054.pmf
+ -COMPUGRAPHIC-Antique Olive-Medium-i-Normal--8782-2500-2540-2540-P-46140-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00055.tfm as iso8859.1/9nb00055.pmf
+ -COMPUGRAPHIC-Antique Olive-Medium-r-Normal--8782-2500-2540-2540-P-46380-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00056.tfm as iso8859.1/9nb00056.pmf
+ -Monotype-Arial-Bold-r-Normal--2048-2500-589-589-P-9800-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00057.tfm as iso8859.1/9nb00057.pmf
+ -Monotype-Arial-Medium-i-Normal--2048-2500-589-589-P-9040-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00058.tfm as iso8859.1/9nb00058.pmf
+ -Monotype-Arial-Bold-i-Normal--2048-2500-589-589-P-9800-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00059.tfm as iso8859.1/9nb00059.pmf
+ -Monotype-Arial-Medium-r-Normal--2048-2500-589-589-P-9040-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00060.tfm as iso8859.1/9nb00060.pmf
+ -COMPUGRAPHIC-Clarendon-Bold-r-Condensed--8782-2500-2540-2540-P-35080-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00061.tfm as iso8859.1/9nb00061.pmf
+ -COMPUGRAPHIC-Courier-Bold-r-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00062.tfm as iso8859.1/9nb00062.pmf
+ -COMPUGRAPHIC-Courier-Medium-i-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00063.tfm as iso8859.1/9nb00063.pmf
+ -COMPUGRAPHIC-Courier-Bold-i-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00064.tfm as iso8859.1/9nb00064.pmf
+ -COMPUGRAPHIC-Courier-Medium-r-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00065.tfm as iso8859.1/9nb00065.pmf
+ -COMPUGRAPHIC-Garamond-Bold-r-Normal--8782-2500-2540-2540-P-38730-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00066.tfm as iso8859.1/9nb00066.pmf
+ -COMPUGRAPHIC-Garamond-Medium-i-Normal--8782-2500-2540-2540-P-34280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00067.tfm as iso8859.1/9nb00067.pmf
+ -COMPUGRAPHIC-Garamond-Bold-i-Normal--8782-2500-2540-2540-P-37020-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00068.tfm as iso8859.1/9nb00068.pmf
+ -COMPUGRAPHIC-Garamond-Medium-r-Normal--8782-2500-2540-2540-P-36560-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00069.tfm as iso8859.1/9nb00069.pmf
+ -COMPUGRAPHIC-Letter Gothic-Bold-r-Normal--8782-2500-2540-2540-M-44090-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00070.tfm as iso8859.1/9nb00070.pmf
+ -COMPUGRAPHIC-Letter Gothic-Medium-i-Normal--8782-2500-2540-2540-M-44090-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00071.tfm as iso8859.1/9nb00071.pmf
+ -COMPUGRAPHIC-Letter Gothic-Medium-r-Normal--8782-2500-2540-2540-M-44090-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00072.tfm as iso8859.1/9nb00072.pmf
+ -COMPUGRAPHIC-Marigold-Medium-r-Normal--8782-2500-2540-2540-P-21890-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00073.tfm as iso8859.1/9nb00073.pmf
+ -COMPUGRAPHIC-Omega-Bold-r-Normal--8782-2500-2540-2540-P-38600-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00074.tfm as iso8859.1/9nb00074.pmf
+ -COMPUGRAPHIC-Omega-Medium-i-Normal--8782-2500-2540-2540-P-37980-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00075.tfm as iso8859.1/9nb00075.pmf
+ -COMPUGRAPHIC-Omega-Bold-i-Normal--8782-2500-2540-2540-P-38560-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00076.tfm as iso8859.1/9nb00076.pmf
+ -COMPUGRAPHIC-Omega-Medium-r-Normal--8782-2500-2540-2540-P-37770-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00077.tfm as iso8859.1/9nb00077.pmf
+ -COMPUGRAPHIC-Coronet-Medium-i-Normal--8782-2500-2540-2540-P-22870-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00079.tfm as iso8859.1/9nb00079.pmf
+ -Monotype-Times New Roman-Bold-r-Normal--2048-2500-589-589-P-8740-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00080.tfm as iso8859.1/9nb00080.pmf
+ -Monotype-Times New Roman-Medium-i-Normal--2048-2500-589-589-P-8230-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00081.tfm as iso8859.1/9nb00081.pmf
+ -Monotype-Times New Roman-Bold-i-Normal--2048-2500-589-589-P-8440-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00082.tfm as iso8859.1/9nb00082.pmf
+ -Monotype-Times New Roman-Medium-r-Normal--2048-2500-589-589-P-8210-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00083.tfm as iso8859.1/9nb00083.pmf
+ -COMPUGRAPHIC-Times-Bold-r-Normal--8782-2500-2540-2540-P-38200-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00084.tfm as iso8859.1/9nb00084.pmf
+ -COMPUGRAPHIC-Times-Medium-i-Normal--8782-2500-2540-2540-P-36000-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00085.tfm as iso8859.1/9nb00085.pmf
+ -COMPUGRAPHIC-Times-Bold-i-Normal--8782-2500-2540-2540-P-36900-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00086.tfm as iso8859.1/9nb00086.pmf
+ -COMPUGRAPHIC-Times-Medium-r-Normal--8782-2500-2540-2540-P-36080-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00087.tfm as iso8859.1/9nb00087.pmf
+ -COMPUGRAPHIC-Univers-Medium-i-Condensed--8782-2500-2540-2540-P-29970-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00088.tfm as iso8859.1/9nb00088.pmf
+ -COMPUGRAPHIC-Univers-Bold-r-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00089.tfm as iso8859.1/9nb00089.pmf
+ -COMPUGRAPHIC-Univers-Medium-r-Condensed--8782-2500-2540-2540-P-29970-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00090.tfm as iso8859.1/9nb00090.pmf
+ -COMPUGRAPHIC-Univers-Bold-r-Condensed--8782-2500-2540-2540-P-33030-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00091.tfm as iso8859.1/9nb00091.pmf
+ -COMPUGRAPHIC-Univers-Bold-i-Condensed--8782-2500-2540-2540-P-33030-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00092.tfm as iso8859.1/9nb00092.pmf
+ -COMPUGRAPHIC-Univers-Medium-i-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00093.tfm as iso8859.1/9nb00093.pmf
+ -COMPUGRAPHIC-Univers-Bold-i-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00094.tfm as iso8859.1/9nb00094.pmf
+ -COMPUGRAPHIC-Univers-Medium-r-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for lpr0ye1a.tfm as iso8859.1/lpr0ye1a.pmf
+ -HP-Line Printer-Medium-r-Normal--35-85-300-300-M-180-iso8859-1
+ ------------------------------------
+
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.alias b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.alias
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.alias
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.dir b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.dir
new file mode 100644
index 000000000..da702ccc1
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/fonts.dir
@@ -0,0 +1,45 @@
+44
+lpr0ye1a.pmf -hp-line printer-medium-r-normal--35-85-300-300-m-180-iso8859-1
+9nb00080.pmf -monotype-times new roman-medium-i-normal--2048-2500-589-589-p-8230-iso8859-1
+9nb00092.pmf -compugraphic-univers-medium-i-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00081.pmf -monotype-times new roman-bold-i-normal--2048-2500-589-589-p-8440-iso8859-1
+9nb00093.pmf -compugraphic-univers-bold-i-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00082.pmf -monotype-times new roman-medium-r-normal--2048-2500-589-589-p-8210-iso8859-1
+9nb00090.pmf -compugraphic-univers-bold-r-condensed--8782-2500-2540-2540-p-33030-iso8859-1
+9nb00083.pmf -compugraphic-times-bold-r-normal--8782-2500-2540-2540-p-38200-iso8859-1
+9nb00091.pmf -compugraphic-univers-bold-i-condensed--8782-2500-2540-2540-p-33030-iso8859-1
+9nb00084.pmf -compugraphic-times-medium-i-normal--8782-2500-2540-2540-p-36000-iso8859-1
+9nb00085.pmf -compugraphic-times-bold-i-normal--8782-2500-2540-2540-p-36900-iso8859-1
+9nb00086.pmf -compugraphic-times-medium-r-normal--8782-2500-2540-2540-p-36080-iso8859-1
+9nb00094.pmf -compugraphic-univers-medium-r-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00087.pmf -compugraphic-univers-medium-i-condensed--8782-2500-2540-2540-p-29970-iso8859-1
+9nb00088.pmf -compugraphic-univers-bold-r-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00089.pmf -compugraphic-univers-medium-r-condensed--8782-2500-2540-2540-p-29970-iso8859-1
+9nb00058.pmf -monotype-arial-bold-i-normal--2048-2500-589-589-p-9800-iso8859-1
+9nb00059.pmf -monotype-arial-medium-r-normal--2048-2500-589-589-p-9040-iso8859-1
+9nb00068.pmf -compugraphic-garamond-medium-r-normal--8782-2500-2540-2540-p-36560-iso8859-1
+9nb00069.pmf -compugraphic-letter gothic-bold-r-normal--8782-2500-2540-2540-m-44090-iso8859-1
+9nb00079.pmf -monotype-times new roman-bold-r-normal--2048-2500-589-589-p-8740-iso8859-1
+9nb00052.pmf -compugraphic-albertus-semi bold-r-normal--8782-2500-2540-2540-p-37640-iso8859-1
+9nb00064.pmf -compugraphic-courier-medium-r-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00076.pmf -compugraphic-omega-medium-r-normal--8782-2500-2540-2540-p-37770-iso8859-1
+9nb00053.pmf -compugraphic-antique olive-bold-r-normal--8782-2500-2540-2540-p-50490-iso8859-1
+9nb00065.pmf -compugraphic-garamond-bold-r-normal--8782-2500-2540-2540-p-38730-iso8859-1
+9nb00077.pmf -compugraphic-coronet-medium-i-normal--8782-2500-2540-2540-p-22870-iso8859-1
+9nb00066.pmf -compugraphic-garamond-medium-i-normal--8782-2500-2540-2540-p-34280-iso8859-1
+9nb00074.pmf -compugraphic-omega-medium-i-normal--8782-2500-2540-2540-p-37980-iso8859-1
+9nb00051.pmf -compugraphic-albertus-extra bold-r-normal--8782-2500-2540-2540-p-42480-iso8859-1
+9nb00067.pmf -compugraphic-garamond-bold-i-normal--8782-2500-2540-2540-p-37020-iso8859-1
+9nb00075.pmf -compugraphic-omega-bold-i-normal--8782-2500-2540-2540-p-38560-iso8859-1
+9nb00056.pmf -monotype-arial-bold-r-normal--2048-2500-589-589-p-9800-iso8859-1
+9nb00060.pmf -compugraphic-clarendon-bold-r-condensed--8782-2500-2540-2540-p-35080-iso8859-1
+9nb00072.pmf -compugraphic-marigold-medium-r-normal--8782-2500-2540-2540-p-21890-iso8859-1
+9nb00057.pmf -monotype-arial-medium-i-normal--2048-2500-589-589-p-9040-iso8859-1
+9nb00061.pmf -compugraphic-courier-bold-r-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00073.pmf -compugraphic-omega-bold-r-normal--8782-2500-2540-2540-p-38600-iso8859-1
+9nb00054.pmf -compugraphic-antique olive-medium-i-normal--8782-2500-2540-2540-p-46140-iso8859-1
+9nb00062.pmf -compugraphic-courier-medium-i-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00070.pmf -compugraphic-letter gothic-medium-i-normal--8782-2500-2540-2540-m-44090-iso8859-1
+9nb00055.pmf -compugraphic-antique olive-medium-r-normal--8782-2500-2540-2540-p-46380-iso8859-1
+9nb00063.pmf -compugraphic-courier-bold-i-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00071.pmf -compugraphic-letter gothic-medium-r-normal--8782-2500-2540-2540-m-44090-iso8859-1
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/fonts/lpr0ye1a.pmf b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/lpr0ye1a.pmf
new file mode 100644
index 000000000..483748893
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/fonts/lpr0ye1a.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPDJ1600C/model-config b/hw/xprint/config/C/print/models/HPDJ1600C/model-config
new file mode 100644
index 000000000..5d45d4495
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPDJ1600C/model-config
@@ -0,0 +1,40 @@
+# $Xprint.org: HPDJ1600C model-config,v 1.4 2002/11/07 19:48:04 gisburn Exp $
+# This is the configuration file for the HP DeskJet 1600C printer.
+#
+# The CDEnext SI supports two 1600C drivers XP-PCL-MONO and
+# XP-PCL-COLOR, which work with this configuration file.
+#
+
+*content-orientations-supported: portrait landscape
+*descriptor: Hewlett-Packard DeskJet 1600C
+*document-formats-supported: {PCL 5} {PostScript 2}
+*input-trays-supported:
+# 1/4" unprintable margins
+*medium-source-sizes-supported:\
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {executive FALSE {6.35 177.75 6.35 260.35}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {iso-a3 FALSE {6.35 290.65 6.35 413.35}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {jis-b4 FALSE {6.35 251.65 6.35 367.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+ {monarch-envelope FALSE {6.35 91.94 6.35 184.15}}\
+ {iso-designated-long FALSE {6.35 103.65 6.35 213.65}}\
+ {iso-c5 FALSE {6.35 155.65 6.35 222.65}}\
+ {na-number-10-envelope FALSE {6.35 98.45 6.35 234.95}}\
+ {hp-tabloid FALSE {6.35 273.05 6.35 425.45}}\
+ {ledger FALSE {6.35 273.05 6.35 425.45}}\
+ {b FALSE {6.35 273.05 6.35 425.45}}\
+ {hp-japanese-postcard FALSE {6 94 6 142 }}\
+ {hp-japanese-doublepostcard FALSE {6 142 6 194 }}\
+}
+*plexes-supported: simplex duplex
+*printer-model: "Hewlett-Packard DeskJet 1600C"
+*printer-resolutions-supported: 300
+*xp-ddx-identifier: XP-PCL-COLOR
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: { PCL 5 } { PostScript 2 }
+*xp-raw-formats-supported: { PCL 5 }
+*xp-setup-proviso: setup-optional
+# EOF.
diff --git a/hw/xprint/config/C/print/models/HPLJ4050-PS/Makefile.am b/hw/xprint/config/C/print/models/HPLJ4050-PS/Makefile.am
new file mode 100644
index 000000000..b8cdfa6c4
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4050-PS/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = fonts
+
+xpcdir = @xpconfigdir@/C/print/models/HPLJ4050-PS
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/HPLJ4050-PS/fonts/Makefile.am b/hw/xprint/config/C/print/models/HPLJ4050-PS/fonts/Makefile.am
new file mode 100644
index 000000000..2ff9ab7e7
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4050-PS/fonts/Makefile.am
@@ -0,0 +1,54 @@
+xpcdir = @xpconfigdir@/C/print/models/HPLJ4050-PS/fonts
+
+parentdir = @xpconfigdir@/C/print/models/PSdefault/fonts
+
+XPFONTS = \
+ AvantGarde-Book.pmf \
+ AvantGarde-BookOblique.pmf \
+ AvantGarde-Demi.pmf \
+ AvantGarde-DemiOblique.pmf \
+ Courier-Bold.pmf \
+ Courier-BoldOblique.pmf \
+ Courier-Oblique.pmf \
+ Courier.pmf \
+ Helvetica-Bold.pmf \
+ Helvetica-BoldOblique.pmf \
+ Helvetica-Oblique.pmf \
+ Helvetica.pmf \
+ LubalinGraph-Book.pmf \
+ LubalinGraph-BookOblique.pmf \
+ LubalinGraph-Demi.pmf \
+ LubalinGraph-DemiOblique.pmf \
+ NewCenturySchlbk-Bold.pmf \
+ NewCenturySchlbk-BoldItalic.pmf \
+ NewCenturySchlbk-Italic.pmf \
+ NewCenturySchlbk-Roman.pmf \
+ Souvenir-Demi.pmf \
+ Souvenir-DemiItalic.pmf \
+ Souvenir-Light.pmf \
+ Souvenir-LightItalic.pmf \
+ Symbol.pmf \
+ Times-Bold.pmf \
+ Times-BoldItalic.pmf \
+ Times-Italic.pmf \
+ Times-Roman.pmf \
+ ZapfDingbats.pmf
+
+dest = $(DESTDIR)$(xpcdir)
+
+remove-stuff:
+ for x in $(XPFONTS) ; do \
+ rm -f $(dest)/$$x ; \
+ done
+
+ @rm -f $(dest)/fonts.dir
+
+install-data-hook: remove-stuff
+ mkdir -p $(dest) ; \
+ for x in $(XPFONTS) ; do \
+ ln -s $(parentdir)/$$x $(dest)/$$x ; \
+ done
+
+ $(MKFONTSCALE) -b -s -l $(dest)
+
+uninstall-hook: remove-stuff
diff --git a/hw/xprint/config/C/print/models/HPLJ4050-PS/model-config b/hw/xprint/config/C/print/models/HPLJ4050-PS/model-config
new file mode 100644
index 000000000..159206de2
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4050-PS/model-config
@@ -0,0 +1,36 @@
+# $Xprint.org: HPLJ4050-PS model-config,v 1.1 2003/12/16 00:48:04 gisburn Exp $
+# model-config for the HP LaserJet 4050 PostScript printer series
+#
+*content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+*descriptor: Hewlett-Packard LaserJet 4050 PostScript printer
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {executive FALSE {6.35 177.80 6.35 260.35}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {iso-a5 FALSE {6.35 141.65 6.35 203.65}}\
+ {iso-b5 FALSE {6.35 169.65 6.35 243.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+}
+
+# Duplex unit is optional for HPLJ4050 series
+*plexes-supported: simplex
+*printer-model: "Hewlett-Packard LaserJet 4050 PostScript printer"
+*printer-resolutions-supported: 600 1200
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+
+# NOTE: xp-psddx-* attributes are EXPERIMENTAL for now.
+# xp-psddx-download-fonts defines which fonts should be downloaded as outlines
+# (valid types are "pfa", "pfb", "ttf", "ttc", "otf", "otc")
+*xp-psddx-download-fonts: pfa pfb ttf ttc otf otc
+# xp-psddx-download-font-type defines which font type is used to download outlines
+# (valid values are "bitmap", "pstype1" and "pstype3")
+*xp-psddx-download-font-type: pstype1
+# EOF.
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/Makefile.am b/hw/xprint/config/C/print/models/HPLJ4family/Makefile.am
new file mode 100644
index 000000000..2089737a9
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = fonts
+
+xpcdir = @xpconfigdir@/C/print/models/HPLJ4family
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00051.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00051.pmf
new file mode 100644
index 000000000..09cc489a5
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00051.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00052.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00052.pmf
new file mode 100644
index 000000000..b21a9a2a8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00052.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00053.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00053.pmf
new file mode 100644
index 000000000..485b874c5
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00053.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00054.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00054.pmf
new file mode 100644
index 000000000..524934c71
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00054.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00055.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00055.pmf
new file mode 100644
index 000000000..2ef9bc52c
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00055.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00056.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00056.pmf
new file mode 100644
index 000000000..3d69311ef
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00056.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00057.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00057.pmf
new file mode 100644
index 000000000..3833d4f54
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00057.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00058.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00058.pmf
new file mode 100644
index 000000000..289a95e5c
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00058.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00059.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00059.pmf
new file mode 100644
index 000000000..a5984bed1
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00059.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00060.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00060.pmf
new file mode 100644
index 000000000..df27cd71e
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00060.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00061.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00061.pmf
new file mode 100644
index 000000000..fb2b5a433
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00061.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00062.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00062.pmf
new file mode 100644
index 000000000..f0e58c435
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00062.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00063.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00063.pmf
new file mode 100644
index 000000000..8821ff155
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00063.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00064.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00064.pmf
new file mode 100644
index 000000000..e5980fc0e
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00064.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00065.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00065.pmf
new file mode 100644
index 000000000..d9a151d7f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00065.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00066.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00066.pmf
new file mode 100644
index 000000000..d14fca56f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00066.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00067.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00067.pmf
new file mode 100644
index 000000000..7a341506f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00067.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00068.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00068.pmf
new file mode 100644
index 000000000..c20e39a21
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00068.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00069.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00069.pmf
new file mode 100644
index 000000000..4a4a35281
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00069.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00070.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00070.pmf
new file mode 100644
index 000000000..8d97d4339
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00070.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00071.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00071.pmf
new file mode 100644
index 000000000..19844c9c6
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00071.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00072.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00072.pmf
new file mode 100644
index 000000000..5415c3f44
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00072.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00073.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00073.pmf
new file mode 100644
index 000000000..038dfdb46
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00073.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00074.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00074.pmf
new file mode 100644
index 000000000..382a78575
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00074.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00075.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00075.pmf
new file mode 100644
index 000000000..1c7edf653
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00075.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00076.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00076.pmf
new file mode 100644
index 000000000..2f077f40f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00076.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00077.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00077.pmf
new file mode 100644
index 000000000..1ce190d51
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00077.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00079.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00079.pmf
new file mode 100644
index 000000000..45d6906ba
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00079.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00080.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00080.pmf
new file mode 100644
index 000000000..b991b5edb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00080.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00081.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00081.pmf
new file mode 100644
index 000000000..1935a9f00
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00081.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00082.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00082.pmf
new file mode 100644
index 000000000..2000dc057
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00082.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00083.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00083.pmf
new file mode 100644
index 000000000..90f0e45a8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00083.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00084.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00084.pmf
new file mode 100644
index 000000000..52ba39b96
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00084.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00085.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00085.pmf
new file mode 100644
index 000000000..f5c9053af
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00085.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00086.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00086.pmf
new file mode 100644
index 000000000..b7586ca61
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00086.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00087.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00087.pmf
new file mode 100644
index 000000000..82f054999
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00087.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00088.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00088.pmf
new file mode 100644
index 000000000..591c96b59
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00088.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00089.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00089.pmf
new file mode 100644
index 000000000..c8160954a
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00089.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00090.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00090.pmf
new file mode 100644
index 000000000..895cfe26a
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00090.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00091.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00091.pmf
new file mode 100644
index 000000000..3bdcae4ba
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00091.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00092.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00092.pmf
new file mode 100644
index 000000000..a56d47504
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00092.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00093.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00093.pmf
new file mode 100644
index 000000000..c85f3b4de
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00093.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00094.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00094.pmf
new file mode 100644
index 000000000..875bf1df8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/9nb00094.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/Makefile.am b/hw/xprint/config/C/print/models/HPLJ4family/fonts/Makefile.am
new file mode 100644
index 000000000..daec9d20e
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/Makefile.am
@@ -0,0 +1,50 @@
+xpcdir = @xpconfigdir@/C/print/models/HPLJ4family/fonts
+
+dist_xpc_DATA = \
+ 9nb00051.pmf \
+ 9nb00052.pmf \
+ 9nb00053.pmf \
+ 9nb00054.pmf \
+ 9nb00055.pmf \
+ 9nb00056.pmf \
+ 9nb00057.pmf \
+ 9nb00058.pmf \
+ 9nb00059.pmf \
+ 9nb00060.pmf \
+ 9nb00061.pmf \
+ 9nb00062.pmf \
+ 9nb00063.pmf \
+ 9nb00064.pmf \
+ 9nb00065.pmf \
+ 9nb00066.pmf \
+ 9nb00067.pmf \
+ 9nb00068.pmf \
+ 9nb00069.pmf \
+ 9nb00070.pmf \
+ 9nb00071.pmf \
+ 9nb00072.pmf \
+ 9nb00073.pmf \
+ 9nb00074.pmf \
+ 9nb00075.pmf \
+ 9nb00076.pmf \
+ 9nb00077.pmf \
+ 9nb00079.pmf \
+ 9nb00080.pmf \
+ 9nb00081.pmf \
+ 9nb00082.pmf \
+ 9nb00083.pmf \
+ 9nb00084.pmf \
+ 9nb00085.pmf \
+ 9nb00086.pmf \
+ 9nb00087.pmf \
+ 9nb00088.pmf \
+ 9nb00089.pmf \
+ 9nb00090.pmf \
+ 9nb00091.pmf \
+ 9nb00092.pmf \
+ 9nb00093.pmf \
+ 9nb00094.pmf \
+ fonts.alias \
+ fonts.dir \
+ lpr0ye1a.pmf \
+ README
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/README b/hw/xprint/config/C/print/models/HPLJ4family/fonts/README
new file mode 100644
index 000000000..2c9821834
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/README
@@ -0,0 +1,203 @@
+$Xorg: README,v 1.3 2000/08/17 19:48:04 cpqbld Exp $
+
+This directory contains "printer metric files" for the X Print
+Server suitable for the LaserJet 4 family of printers - 4, 4L,
+4M, 4ML, 4MP, 4P, 4Si, 4Si-MX. The following *.pmf files were
+generated by the Hewlett-Packard Company.
+
+ 9nb00051.pmf
+ 9nb00052.pmf
+ 9nb00053.pmf
+ 9nb00054.pmf
+ 9nb00055.pmf
+ * 9nb00056.pmf
+ * 9nb00057.pmf
+ * 9nb00058.pmf
+ * 9nb00059.pmf
+ * 9nb00060.pmf
+ 9nb00061.pmf
+ 9nb00062.pmf
+ 9nb00063.pmf
+ 9nb00064.pmf
+ * 9nb00065.pmf
+ * 9nb00066.pmf
+ * 9nb00067.pmf
+ * 9nb00068.pmf
+ 9nb00069.pmf
+ 9nb00070.pmf
+ 9nb00071.pmf
+ * 9nb00072.pmf
+ * 9nb00073.pmf
+ * 9nb00074.pmf
+ * 9nb00075.pmf
+ * 9nb00076.pmf
+ 9nb00077.pmf
+ * 9nb00079.pmf
+ * 9nb00080.pmf
+ * 9nb00081.pmf
+ * 9nb00082.pmf
+ 9nb00083.pmf
+ 9nb00084.pmf
+ 9nb00085.pmf
+ 9nb00086.pmf
+ 9nb00087.pmf
+ 9nb00088.pmf
+ 9nb00089.pmf
+ 9nb00090.pmf
+ 9nb00091.pmf
+ 9nb00092.pmf
+ 9nb00093.pmf
+ 9nb00094.pmf
+ lpr0ye1a.pmf
+
+
+ * note - the marked fonts are NOT supported by the 4L printer. If
+ making extensive use of the 4L, you may want to create a special
+ 4L model-config area and exclude these fonts.
+
+For reasons of not supporting iso8859.1 and hp-roman8, the following
+Laserjet 4 printer fonts were not converted to *.pmf files.
+
+ 9nb00078.pmf
+ 9nb00095.pmf
+ lpr0ylga.pmf
+ lpr0ypca.pmf
+ lpr0ypda.pmf
+ lpr0ypma.pmf
+ lpr0yr8a.pmf
+
+Output from the conversion utility is as follows:
+
+ Creating iso8859 1 pmf for 9nb00051.tfm as iso8859.1/9nb00051.pmf
+ -COMPUGRAPHIC-Albertus-Extra Bold-r-Normal--8782-2500-2540-2540-P-42480-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00052.tfm as iso8859.1/9nb00052.pmf
+ -COMPUGRAPHIC-Albertus-Semi Bold-r-Normal--8782-2500-2540-2540-P-37640-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00053.tfm as iso8859.1/9nb00053.pmf
+ -COMPUGRAPHIC-Antique Olive-Bold-r-Normal--8782-2500-2540-2540-P-50490-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00054.tfm as iso8859.1/9nb00054.pmf
+ -COMPUGRAPHIC-Antique Olive-Medium-i-Normal--8782-2500-2540-2540-P-46140-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00055.tfm as iso8859.1/9nb00055.pmf
+ -COMPUGRAPHIC-Antique Olive-Medium-r-Normal--8782-2500-2540-2540-P-46380-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00056.tfm as iso8859.1/9nb00056.pmf
+ -Monotype-Arial-Bold-r-Normal--2048-2500-589-589-P-9800-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00057.tfm as iso8859.1/9nb00057.pmf
+ -Monotype-Arial-Medium-i-Normal--2048-2500-589-589-P-9040-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00058.tfm as iso8859.1/9nb00058.pmf
+ -Monotype-Arial-Bold-i-Normal--2048-2500-589-589-P-9800-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00059.tfm as iso8859.1/9nb00059.pmf
+ -Monotype-Arial-Medium-r-Normal--2048-2500-589-589-P-9040-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00060.tfm as iso8859.1/9nb00060.pmf
+ -COMPUGRAPHIC-Clarendon-Bold-r-Condensed--8782-2500-2540-2540-P-35080-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00061.tfm as iso8859.1/9nb00061.pmf
+ -COMPUGRAPHIC-Courier-Bold-r-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00062.tfm as iso8859.1/9nb00062.pmf
+ -COMPUGRAPHIC-Courier-Medium-i-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00063.tfm as iso8859.1/9nb00063.pmf
+ -COMPUGRAPHIC-Courier-Bold-i-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00064.tfm as iso8859.1/9nb00064.pmf
+ -COMPUGRAPHIC-Courier-Medium-r-Normal--8782-2500-2540-2540-M-52910-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00065.tfm as iso8859.1/9nb00065.pmf
+ -COMPUGRAPHIC-Garamond-Bold-r-Normal--8782-2500-2540-2540-P-38730-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00066.tfm as iso8859.1/9nb00066.pmf
+ -COMPUGRAPHIC-Garamond-Medium-i-Normal--8782-2500-2540-2540-P-34280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00067.tfm as iso8859.1/9nb00067.pmf
+ -COMPUGRAPHIC-Garamond-Bold-i-Normal--8782-2500-2540-2540-P-37020-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00068.tfm as iso8859.1/9nb00068.pmf
+ -COMPUGRAPHIC-Garamond-Medium-r-Normal--8782-2500-2540-2540-P-36560-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00069.tfm as iso8859.1/9nb00069.pmf
+ -COMPUGRAPHIC-Letter Gothic-Bold-r-Normal--8782-2500-2540-2540-M-44090-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00070.tfm as iso8859.1/9nb00070.pmf
+ -COMPUGRAPHIC-Letter Gothic-Medium-i-Normal--8782-2500-2540-2540-M-44090-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00071.tfm as iso8859.1/9nb00071.pmf
+ -COMPUGRAPHIC-Letter Gothic-Medium-r-Normal--8782-2500-2540-2540-M-44090-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00072.tfm as iso8859.1/9nb00072.pmf
+ -COMPUGRAPHIC-Marigold-Medium-r-Normal--8782-2500-2540-2540-P-21890-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00073.tfm as iso8859.1/9nb00073.pmf
+ -COMPUGRAPHIC-Omega-Bold-r-Normal--8782-2500-2540-2540-P-38600-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00074.tfm as iso8859.1/9nb00074.pmf
+ -COMPUGRAPHIC-Omega-Medium-i-Normal--8782-2500-2540-2540-P-37980-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00075.tfm as iso8859.1/9nb00075.pmf
+ -COMPUGRAPHIC-Omega-Bold-i-Normal--8782-2500-2540-2540-P-38560-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00076.tfm as iso8859.1/9nb00076.pmf
+ -COMPUGRAPHIC-Omega-Medium-r-Normal--8782-2500-2540-2540-P-37770-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00077.tfm as iso8859.1/9nb00077.pmf
+ -COMPUGRAPHIC-Coronet-Medium-i-Normal--8782-2500-2540-2540-P-22870-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00079.tfm as iso8859.1/9nb00079.pmf
+ -Monotype-Times New Roman-Bold-r-Normal--2048-2500-589-589-P-8740-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00080.tfm as iso8859.1/9nb00080.pmf
+ -Monotype-Times New Roman-Medium-i-Normal--2048-2500-589-589-P-8230-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00081.tfm as iso8859.1/9nb00081.pmf
+ -Monotype-Times New Roman-Bold-i-Normal--2048-2500-589-589-P-8440-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00082.tfm as iso8859.1/9nb00082.pmf
+ -Monotype-Times New Roman-Medium-r-Normal--2048-2500-589-589-P-8210-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00083.tfm as iso8859.1/9nb00083.pmf
+ -COMPUGRAPHIC-Times-Bold-r-Normal--8782-2500-2540-2540-P-38200-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00084.tfm as iso8859.1/9nb00084.pmf
+ -COMPUGRAPHIC-Times-Medium-i-Normal--8782-2500-2540-2540-P-36000-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00085.tfm as iso8859.1/9nb00085.pmf
+ -COMPUGRAPHIC-Times-Bold-i-Normal--8782-2500-2540-2540-P-36900-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00086.tfm as iso8859.1/9nb00086.pmf
+ -COMPUGRAPHIC-Times-Medium-r-Normal--8782-2500-2540-2540-P-36080-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00087.tfm as iso8859.1/9nb00087.pmf
+ -COMPUGRAPHIC-Univers-Medium-i-Condensed--8782-2500-2540-2540-P-29970-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00088.tfm as iso8859.1/9nb00088.pmf
+ -COMPUGRAPHIC-Univers-Bold-r-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00089.tfm as iso8859.1/9nb00089.pmf
+ -COMPUGRAPHIC-Univers-Medium-r-Condensed--8782-2500-2540-2540-P-29970-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00090.tfm as iso8859.1/9nb00090.pmf
+ -COMPUGRAPHIC-Univers-Bold-r-Condensed--8782-2500-2540-2540-P-33030-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00091.tfm as iso8859.1/9nb00091.pmf
+ -COMPUGRAPHIC-Univers-Bold-i-Condensed--8782-2500-2540-2540-P-33030-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00092.tfm as iso8859.1/9nb00092.pmf
+ -COMPUGRAPHIC-Univers-Medium-i-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00093.tfm as iso8859.1/9nb00093.pmf
+ -COMPUGRAPHIC-Univers-Bold-i-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for 9nb00094.tfm as iso8859.1/9nb00094.pmf
+ -COMPUGRAPHIC-Univers-Medium-r-Normal--8782-2500-2540-2540-P-41280-iso8859-1
+ ------------------------------------
+ Creating iso8859 1 pmf for lpr0ye1a.tfm as iso8859.1/lpr0ye1a.pmf
+ -HP-Line Printer-Medium-r-Normal--35-85-300-300-M-180-iso8859-1
+ ------------------------------------
+
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.alias b/hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.alias
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.alias
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.dir b/hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.dir
new file mode 100644
index 000000000..da702ccc1
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/fonts.dir
@@ -0,0 +1,45 @@
+44
+lpr0ye1a.pmf -hp-line printer-medium-r-normal--35-85-300-300-m-180-iso8859-1
+9nb00080.pmf -monotype-times new roman-medium-i-normal--2048-2500-589-589-p-8230-iso8859-1
+9nb00092.pmf -compugraphic-univers-medium-i-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00081.pmf -monotype-times new roman-bold-i-normal--2048-2500-589-589-p-8440-iso8859-1
+9nb00093.pmf -compugraphic-univers-bold-i-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00082.pmf -monotype-times new roman-medium-r-normal--2048-2500-589-589-p-8210-iso8859-1
+9nb00090.pmf -compugraphic-univers-bold-r-condensed--8782-2500-2540-2540-p-33030-iso8859-1
+9nb00083.pmf -compugraphic-times-bold-r-normal--8782-2500-2540-2540-p-38200-iso8859-1
+9nb00091.pmf -compugraphic-univers-bold-i-condensed--8782-2500-2540-2540-p-33030-iso8859-1
+9nb00084.pmf -compugraphic-times-medium-i-normal--8782-2500-2540-2540-p-36000-iso8859-1
+9nb00085.pmf -compugraphic-times-bold-i-normal--8782-2500-2540-2540-p-36900-iso8859-1
+9nb00086.pmf -compugraphic-times-medium-r-normal--8782-2500-2540-2540-p-36080-iso8859-1
+9nb00094.pmf -compugraphic-univers-medium-r-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00087.pmf -compugraphic-univers-medium-i-condensed--8782-2500-2540-2540-p-29970-iso8859-1
+9nb00088.pmf -compugraphic-univers-bold-r-normal--8782-2500-2540-2540-p-41280-iso8859-1
+9nb00089.pmf -compugraphic-univers-medium-r-condensed--8782-2500-2540-2540-p-29970-iso8859-1
+9nb00058.pmf -monotype-arial-bold-i-normal--2048-2500-589-589-p-9800-iso8859-1
+9nb00059.pmf -monotype-arial-medium-r-normal--2048-2500-589-589-p-9040-iso8859-1
+9nb00068.pmf -compugraphic-garamond-medium-r-normal--8782-2500-2540-2540-p-36560-iso8859-1
+9nb00069.pmf -compugraphic-letter gothic-bold-r-normal--8782-2500-2540-2540-m-44090-iso8859-1
+9nb00079.pmf -monotype-times new roman-bold-r-normal--2048-2500-589-589-p-8740-iso8859-1
+9nb00052.pmf -compugraphic-albertus-semi bold-r-normal--8782-2500-2540-2540-p-37640-iso8859-1
+9nb00064.pmf -compugraphic-courier-medium-r-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00076.pmf -compugraphic-omega-medium-r-normal--8782-2500-2540-2540-p-37770-iso8859-1
+9nb00053.pmf -compugraphic-antique olive-bold-r-normal--8782-2500-2540-2540-p-50490-iso8859-1
+9nb00065.pmf -compugraphic-garamond-bold-r-normal--8782-2500-2540-2540-p-38730-iso8859-1
+9nb00077.pmf -compugraphic-coronet-medium-i-normal--8782-2500-2540-2540-p-22870-iso8859-1
+9nb00066.pmf -compugraphic-garamond-medium-i-normal--8782-2500-2540-2540-p-34280-iso8859-1
+9nb00074.pmf -compugraphic-omega-medium-i-normal--8782-2500-2540-2540-p-37980-iso8859-1
+9nb00051.pmf -compugraphic-albertus-extra bold-r-normal--8782-2500-2540-2540-p-42480-iso8859-1
+9nb00067.pmf -compugraphic-garamond-bold-i-normal--8782-2500-2540-2540-p-37020-iso8859-1
+9nb00075.pmf -compugraphic-omega-bold-i-normal--8782-2500-2540-2540-p-38560-iso8859-1
+9nb00056.pmf -monotype-arial-bold-r-normal--2048-2500-589-589-p-9800-iso8859-1
+9nb00060.pmf -compugraphic-clarendon-bold-r-condensed--8782-2500-2540-2540-p-35080-iso8859-1
+9nb00072.pmf -compugraphic-marigold-medium-r-normal--8782-2500-2540-2540-p-21890-iso8859-1
+9nb00057.pmf -monotype-arial-medium-i-normal--2048-2500-589-589-p-9040-iso8859-1
+9nb00061.pmf -compugraphic-courier-bold-r-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00073.pmf -compugraphic-omega-bold-r-normal--8782-2500-2540-2540-p-38600-iso8859-1
+9nb00054.pmf -compugraphic-antique olive-medium-i-normal--8782-2500-2540-2540-p-46140-iso8859-1
+9nb00062.pmf -compugraphic-courier-medium-i-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00070.pmf -compugraphic-letter gothic-medium-i-normal--8782-2500-2540-2540-m-44090-iso8859-1
+9nb00055.pmf -compugraphic-antique olive-medium-r-normal--8782-2500-2540-2540-p-46380-iso8859-1
+9nb00063.pmf -compugraphic-courier-bold-i-normal--8782-2500-2540-2540-m-52910-iso8859-1
+9nb00071.pmf -compugraphic-letter gothic-medium-r-normal--8782-2500-2540-2540-m-44090-iso8859-1
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/fonts/lpr0ye1a.pmf b/hw/xprint/config/C/print/models/HPLJ4family/fonts/lpr0ye1a.pmf
new file mode 100644
index 000000000..483748893
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/fonts/lpr0ye1a.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/HPLJ4family/model-config b/hw/xprint/config/C/print/models/HPLJ4family/model-config
new file mode 100644
index 000000000..1ac997ebe
--- /dev/null
+++ b/hw/xprint/config/C/print/models/HPLJ4family/model-config
@@ -0,0 +1,39 @@
+# $Xprint.org: HPLJ4family model-config,v 1.4 2002/11/07 19:48:04 gisburn Exp $
+# This is the configuration file for the HP LaserJet 4 Printers.
+#
+# Though not a deliverable for the CDEnext SI, the XP-PCL-MONO
+# driver should be able to support the LaserJet 4 printers.
+#
+*content-orientations-supported: portrait landscape
+*descriptor: Hewlett-Packard LaserJet 4 Series
+*document-formats-supported: {PCL 5} {PostScript 2}
+*input-trays-supported:
+# 1/4" unprintable margins
+*medium-source-sizes-supported:\
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {executive FALSE {6.35 177.75 6.35 260.35}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {iso-a3 FALSE {6.35 290.65 6.35 413.35}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {jis-b4 FALSE {6.35 251.65 6.35 367.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+ {monarch-envelope FALSE {6.35 91.94 6.35 184.15}}\
+ {iso-designated-long FALSE {6.35 103.65 6.35 213.65}}\
+ {iso-c5 FALSE {6.35 155.65 6.35 222.65}}\
+ {na-number-10-envelope FALSE {6.35 98.45 6.35 234.95}}\
+ {hp-tabloid FALSE {6.35 273.05 6.35 425.45}}\
+ {ledger FALSE {6.35 273.05 6.35 425.45}}\
+ {b FALSE {6.35 273.05 6.35 425.45}}\
+ {hp-japanese-postcard FALSE {6 94 6 142 }}\
+ {hp-japanese-doublepostcard FALSE {6 142 6 194 }}\
+}
+*plexes-supported: simplex duplex
+*printer-model: "Hewlett-Packard LaserJet 4 Series"
+*printer-resolutions-supported: 300 600
+*xp-ddx-identifier: XP-PCL-MONO
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: { PCL 5 } { PostScript 2 }
+*xp-raw-formats-supported: { PCL 5 }
+*xp-setup-proviso: setup-optional
+# EOF.
diff --git a/hw/xprint/config/C/print/models/Makefile.am b/hw/xprint/config/C/print/models/Makefile.am
new file mode 100644
index 000000000..488a06a75
--- /dev/null
+++ b/hw/xprint/config/C/print/models/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = \
+ PSdefault \
+ CANONBJ10E-GS \
+ CANONC3200-PS \
+ GSdefault \
+ HPDJ1600C \
+ HPLJ4050-PS \
+ HPLJ4family \
+ PS2PDFspooldir-GS \
+ PSspooldir \
+ SPSPARC2
diff --git a/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/Makefile.am b/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/Makefile.am
new file mode 100644
index 000000000..37b57d7bb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/C/print/models/PS2PDFspooldir-GS
+
+dist_xpc_DATA = model-config ps2pdf_spooltodir.sh
diff --git a/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/model-config b/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/model-config
new file mode 100644
index 000000000..1d74b8676
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/model-config
@@ -0,0 +1,72 @@
+# $Xprint.org: PS2PDFspooldir-GS model-config,v 1.1 2003/11/20 03:48:04 gisburn Exp $
+# PostScript DDX model-config which converts jobs to PDF via GhostScript's "ps2pdf"
+# and then sends them to a spool dir instead to a print queue
+#
+# This model is basically a cut-down GSdefault model with a custom *xp-spooler-command
+#
+# DO NOT MODIFY THIS FILE!!
+#
+# If you want to make customisations for your printer create a copy
+# of this printer model.
+# Example (for creating a model config "MYCOMPANYlaserxx"):
+# 1. Create model config dir:
+# % mkdir MYCOMPANYlaserxx
+# 2. Link (or copy) the PMF (printer font metrics) for the
+# printer buildin fonts:
+# % ln -s PS2PDFspooldir-GS/fonts MYCOMPANYlaserxx/.
+# 3. Copy the model config file:
+# % cp PS2PDFspooldir-GS/model-config MYCOMPANYlaserxx/.
+# 4. Customize MYCOMPANYlaserxx/model-config to match your needs.
+#
+# Attributes supported for this printer model
+*content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+*descriptor: PDF job spool dir /tmp/Xprintjobs
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {executive FALSE {6.35 177.80 6.35 260.35}}\
+ {ledger FALSE {6.35 273.05 6.35 425.45}}\
+ {quarto FALSE {6.35 209.55 6.35 268.732}}\
+ {iso-a3 FALSE {6.35 290.65 6.35 413.65}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {iso-a5 FALSE {6.35 141.65 6.35 203.65}}\
+ {iso-b3 FALSE {6.35 346.65 6.35 493.65}}\
+ {iso-b4 FALSE {6.35 243.65 6.35 346.65}}\
+ {iso-b5 FALSE {6.35 169.65 6.35 243.65}}\
+ {jis-b3 FALSE {6.35 357.65 6.35 508.65}}\
+ {jis-b4 FALSE {6.35 250.65 6.35 357.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+ {iso-c3 FALSE {6.35 317.65 6.35 451.65}}\
+ {iso-c4 FALSE {6.35 222.65 6.35 317.65}}\
+ {iso-c5 FALSE {6.35 155.65 6.35 222.65}}\
+}
+
+*plexes-supported: simplex duplex tumble
+*printer-model: "PDF job spool dir /tmp/Xprintjobs"
+# 75, 100, 120, 150, 180, 200, 240, 300, 360, 400, 600, 720,
+# 940, 1200 and 2440 are supported DPI values, we limit it here
+# to some common values:
+*printer-resolutions-supported: 300 360 400 600
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+
+# Use custom spooler script which sends the output to a dir instead to a printer queue
+# Note that "%xpconfigdir%" is currently only supported in Xprt servers build
+# from xprint.mozdev.org sources, other platforms have replace it with the
+# absolute path name to the script
+*xp-spooler-command: %xpconfigdir%/C/print/models/PS2PDFspooldir-GS/ps2pdf_spooltodir.sh -d /tmp/Xprintjobs -s .pdf -u 077 -p %printer-name% -c %copy-count% -t %job-name% -o "%options%"
+
+# NOTE: xp-psddx-* attributes are EXPERIMENTAL for now.
+# xp-psddx-download-fonts defines which fonts should be downloaded as outlines
+# (valid types are "pfa", "pfb", "ttf", "ttc", "otf", "otc")
+*xp-psddx-download-fonts: pfa pfb ttf ttc otf otc
+# xp-psddx-download-font-type defines which font type is used to download outlines
+# (valid values are "bitmap", "pstype1" and "pstype3")
+*xp-psddx-download-font-type: pstype1
+# EOF.
diff --git a/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/ps2pdf_spooltodir.sh b/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/ps2pdf_spooltodir.sh
new file mode 100755
index 000000000..5739807d8
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PS2PDFspooldir-GS/ps2pdf_spooltodir.sh
@@ -0,0 +1,130 @@
+#!/bin/sh
+PATH=/usr/bin:/usr/sbin:/bin:/sbin:/usr/local/bin
+export PATH
+
+verbose_msgs="false"
+DEFAULT_SPOOLDIR=/tmp/Xprintjobs
+
+usage()
+{
+ printf "Usage: ${0}: [options]\n"
+ printf "-v\tbe verbose\n"
+ printf "-d dirname\tdefine spool dir\n"
+ printf "-p string\tname of printer selected by user\n"
+ printf "-c integer\tnumber of copies\n"
+ printf "-t string\tjob title\n"
+ printf "-s string\tfile name suffix\n"
+ printf "-o string\tspooler options\n"
+ printf "-u mask\tpermission mask for new files (see umask)\n"
+ exit 2
+}
+
+verbose()
+{
+ if ${verbose_msgs} ; then
+ echo "$1"
+ fi
+}
+
+spooldir="${DEFAULT_SPOOLDIR}"
+printername=
+num_job_copies=
+job_title=
+filename_suffix=
+spooler_options=
+permmask=
+while getopts va:b:d:p:c:t:s:o:u: i
+do
+ case $i in
+ v)
+ verbose_msgs="true"
+ ;;
+ d)
+ spooldir="$OPTARG"
+ ;;
+ p)
+ printername="$OPTARG"
+ ;;
+ c)
+ num_job_copies="$OPTARG"
+ ;;
+ t)
+ job_title="$OPTARG"
+ ;;
+ s)
+ filename_suffix="$OPTARG"
+ ;;
+ o)
+ spooler_options="$OPTARG"
+ ;;
+ u)
+ permmask="$OPTARG"
+ ;;
+ ?) usage
+ ;;
+ esac
+done
+
+verbose "# spooldir=\"$spooldir\""
+verbose "# printername=\"$printername\""
+verbose "# num_job_copies=\"$num_job_copies\""
+verbose "# job_title=\"$job_title\""
+verbose "# spooler_options=\"$spooler_options\""
+verbose "# umask=\"$permmask\""
+
+if [ ! -d "${DEFAULT_SPOOLDIR}" ] ; then
+ mkdir "${DEFAULT_SPOOLDIR}"
+ chmod a+rwxt "${DEFAULT_SPOOLDIR}"
+fi
+
+if [ "${permmask}" != "" ] ; then
+ umask ${permmask}
+fi
+
+if [ ! -d "$spooldir" ] ; then
+ echo "$0: spooldir \"$spooldir\" does not exits." >&2
+ exit 1
+fi
+if [ ! -w "$spooldir" ] ; then
+ echo "$0: Cannot write to spooldir \"$spooldir\"." >&2
+ exit 1
+fi
+
+# Create first part of the output file name (prefix and an "unique"
+# id(=date and time))...
+filename="Xpjob_`date +%Y%m%d%H%M%S`"
+
+# ... then add options ...
+if [ "${printername}" != "" ] ; then
+ filename="${filename}_${printername}"
+fi
+if [ "${num_job_copies}" != "" -a "${num_job_copies}" != "1" ] ; then
+ filename="${filename}_copies_${num_job_copies}"
+fi
+if [ "${job_title}" != "" ] ; then
+ filename="${filename}_title_${job_title}"
+fi
+
+# ... mangle output file name and filter chars (like whitespaces)
+# which may screw-up further processing by other shell scripts ...
+filename="`echo \"${filename}\" | tr '[:blank:]' '_' | tr -c -d '[:alnum:]_.-'`"
+
+# ... add path and suffix ...
+filename="${spooldir}/${filename}${filename_suffix}"
+
+verbose "# File name is \"$filename\"."
+
+# ... and finally capture stdin to the file (we are using "gs" directly to
+# avoid the problem that "ps2pdf" is not available in all Linux
+# distributions by default).
+#ps2pdf - - | cat >"${filename}"
+gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite "-sOutputFile=-" -dCompatibilityLevel=1.2 -c .setpdfwrite -f - | cat >"${filename}"
+
+if ${verbose_msgs} ; then
+ printf "# File is " ; ls -l "${filename}"
+fi
+
+verbose "# Done."
+
+exit 0
+# EOF.
diff --git a/hw/xprint/config/C/print/models/PSdefault/Makefile.am b/hw/xprint/config/C/print/models/PSdefault/Makefile.am
new file mode 100644
index 000000000..040f26077
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = fonts
+
+xpcdir = @xpconfigdir@/C/print/models/PSdefault
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Book.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Book.pmf
new file mode 100644
index 000000000..331178985
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Book.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-BookOblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-BookOblique.pmf
new file mode 100644
index 000000000..61bcb22b9
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-BookOblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Demi.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Demi.pmf
new file mode 100644
index 000000000..88ccf0834
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-Demi.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-DemiOblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-DemiOblique.pmf
new file mode 100644
index 000000000..45cc8857b
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/AvantGarde-DemiOblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Bold.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Bold.pmf
new file mode 100644
index 000000000..ac760fdb9
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Bold.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-BoldOblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-BoldOblique.pmf
new file mode 100644
index 000000000..8db974018
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-BoldOblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Oblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Oblique.pmf
new file mode 100644
index 000000000..87aee16cc
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier-Oblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Courier.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier.pmf
new file mode 100644
index 000000000..6109c8c11
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Courier.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Bold.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Bold.pmf
new file mode 100644
index 000000000..30d462d95
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Bold.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-BoldOblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-BoldOblique.pmf
new file mode 100644
index 000000000..89619516f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-BoldOblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Oblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Oblique.pmf
new file mode 100644
index 000000000..2a0de8afc
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica-Oblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica.pmf
new file mode 100644
index 000000000..b1fd475bb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Helvetica.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Book.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Book.pmf
new file mode 100644
index 000000000..aff4b4949
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Book.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-BookOblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-BookOblique.pmf
new file mode 100644
index 000000000..b5b77f353
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-BookOblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Demi.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Demi.pmf
new file mode 100644
index 000000000..100339854
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-Demi.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-DemiOblique.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-DemiOblique.pmf
new file mode 100644
index 000000000..a8550e70d
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/LubalinGraph-DemiOblique.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Makefile.am b/hw/xprint/config/C/print/models/PSdefault/fonts/Makefile.am
new file mode 100644
index 000000000..7cdfd8ee9
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Makefile.am
@@ -0,0 +1,44 @@
+xpcdir = @xpconfigdir@/C/print/models/PSdefault/fonts
+
+dist_xpc_DATA = \
+ AvantGarde-BookOblique.pmf \
+ AvantGarde-Book.pmf \
+ AvantGarde-DemiOblique.pmf \
+ AvantGarde-Demi.pmf \
+ Courier-BoldOblique.pmf \
+ Courier-Bold.pmf \
+ Courier-Oblique.pmf \
+ Courier.pmf \
+ Helvetica-BoldOblique.pmf \
+ Helvetica-Bold.pmf \
+ Helvetica-Oblique.pmf \
+ Helvetica.pmf \
+ LubalinGraph-BookOblique.pmf \
+ LubalinGraph-Book.pmf \
+ LubalinGraph-DemiOblique.pmf \
+ LubalinGraph-Demi.pmf \
+ NewCenturySchlbk-BoldItalic.pmf \
+ NewCenturySchlbk-Bold.pmf \
+ NewCenturySchlbk-Italic.pmf \
+ NewCenturySchlbk-Roman.pmf \
+ Souvenir-DemiItalic.pmf \
+ Souvenir-Demi.pmf \
+ Souvenir-LightItalic.pmf \
+ Souvenir-Light.pmf \
+ Symbol.pmf \
+ Times-BoldItalic.pmf \
+ Times-Bold.pmf \
+ Times-Italic.pmf \
+ Times-Roman.pmf \
+ ZapfDingbats.pmf
+
+
+dest = $(DESTDIR)$(xpcdir)
+
+remove-stuff:
+ @rm -f $(dest)/fonts.dir
+
+install-data-hook: remove-stuff
+ $(MKFONTSCALE) -b -s -l $(dest)
+
+uninstall-hook: remove-stuff
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Bold.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Bold.pmf
new file mode 100644
index 000000000..ab22aabf5
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Bold.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-BoldItalic.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-BoldItalic.pmf
new file mode 100644
index 000000000..e68811eb7
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-BoldItalic.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Italic.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Italic.pmf
new file mode 100644
index 000000000..390f223cb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Italic.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Roman.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Roman.pmf
new file mode 100644
index 000000000..655b9b6c0
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/NewCenturySchlbk-Roman.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Demi.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Demi.pmf
new file mode 100644
index 000000000..5e786ec42
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Demi.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-DemiItalic.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-DemiItalic.pmf
new file mode 100644
index 000000000..094b348cc
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-DemiItalic.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Light.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Light.pmf
new file mode 100644
index 000000000..0bb62bde6
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-Light.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-LightItalic.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-LightItalic.pmf
new file mode 100644
index 000000000..3c19a7fbf
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Souvenir-LightItalic.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Symbol.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Symbol.pmf
new file mode 100644
index 000000000..48925f816
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Symbol.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Bold.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Bold.pmf
new file mode 100644
index 000000000..cf46ca03f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Bold.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Times-BoldItalic.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-BoldItalic.pmf
new file mode 100644
index 000000000..ffe51af80
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-BoldItalic.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Italic.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Italic.pmf
new file mode 100644
index 000000000..865433f83
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Italic.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Roman.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Roman.pmf
new file mode 100644
index 000000000..625e0c43f
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/Times-Roman.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/fonts/ZapfDingbats.pmf b/hw/xprint/config/C/print/models/PSdefault/fonts/ZapfDingbats.pmf
new file mode 100644
index 000000000..1ae9a7688
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/fonts/ZapfDingbats.pmf
Binary files differ
diff --git a/hw/xprint/config/C/print/models/PSdefault/model-config b/hw/xprint/config/C/print/models/PSdefault/model-config
new file mode 100644
index 000000000..05a19d859
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSdefault/model-config
@@ -0,0 +1,136 @@
+# $Xprint.org: PSdefault model-config,v 1.2 2002/11/07 19:48:04 gisburn Exp $
+# Generic default model-config for the PostScript DDX
+#
+# DO NOT MODIFY THIS FILE!!
+#
+# If you want to make customisations for your printer create a copy
+# of this printer model.
+# Example (for creating a model config "MYCOMPANYlaserxx"):
+# 1. Create model config dir:
+# % mkdir MYCOMPANYlaserxx
+# 2. Link (or copy) the PMF (printer font metrics) for the
+# printer buildin fonts:
+# % ln -s PSdefault/fonts MYCOMPANYlaserxx/.
+# 3. Copy the model config file:
+# % cp PSdefault/model-config MYCOMPANYlaserxx/.
+# 4. Customize MYCOMPANYlaserxx/model-config to match your needs.
+#
+
+# Attributes supported for this printer model
+# You may want to cut the lists here down to the attributes supported
+# by your printer.
+*content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+*descriptor: PostScript default model
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {executive FALSE {6.35 177.80 6.35 260.35}}\
+ {folio FALSE {6.35 204.47 6.35 323.85}}\
+ {invoice FALSE {6.35 133.35 6.35 209.55}}\
+ {ledger FALSE {6.35 273.05 6.35 425.45}}\
+ {quarto FALSE {6.35 209.55 6.35 268.732}}\
+ {a FALSE {6.35 209.55 6.35 273.05}}\
+ {b FALSE {6.35 273.05 6.35 425.45}}\
+ {c FALSE {6.35 425.45 6.35 552.45}}\
+ {d FALSE {6.35 552.45 6.35 857.25}}\
+ {e FALSE {6.35 857.25 6.35 1111.25}}\
+ {na-6x9-envelope FALSE {6.35 146.05 6.35 222.25}}\
+ {na-10x15-envelope FALSE {6.35 247.65 6.35 374.65}}\
+ {monarch-envelope FALSE {6.35 91.948 6.35 184.15}}\
+ {na-10x13-envelope FALSE {6.35 247.65 6.35 323.85}}\
+ {na-9x12-envelope FALSE {6.35 222.25 6.35 298.45}}\
+ {na-number-10-envelope FALSE {6.35 98.425 6.35 234.95}}\
+ {na-7x9-envelope FALSE {6.35 171.45 6.35 222.25}}\
+ {na-9x11-envelope FALSE {6.35 222.25 6.35 273.05}}\
+ {na-10x14-envelope FALSE {6.35 247.65 6.35 349.25}}\
+ {na-number-9-envelope FALSE {6.35 92.075 6.35 219.075}}\
+ {iso-a0 FALSE {6.35 834.65 6.35 1182.65}}\
+ {iso-a1 FALSE {6.35 587.65 6.35 834.65}}\
+ {iso-a2 FALSE {6.35 413.65 6.35 587.65}}\
+ {iso-a3 FALSE {6.35 290.65 6.35 413.65}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {iso-a5 FALSE {6.35 141.65 6.35 203.65}}\
+ {iso-a6 FALSE {6.35 98.65 6.35 141.65}}\
+ {iso-a7 FALSE {6.35 67.65 6.35 98.65}}\
+ {iso-a8 FALSE {6.35 45.65 6.35 67.65}}\
+ {iso-a9 FALSE {6.35 30.65 6.35 45.65}}\
+ {iso-a10 FALSE {6.35 19.65 6.35 30.65}}\
+ {iso-b1 FALSE {6.35 700.65 6.35 993.65}}\
+ {iso-b2 FALSE {6.35 493.65 6.35 700.65}}\
+ {iso-b3 FALSE {6.35 346.65 6.35 493.65}}\
+ {iso-b4 FALSE {6.35 243.65 6.35 346.65}}\
+ {iso-b5 FALSE {6.35 169.65 6.35 243.65}}\
+ {iso-b6 FALSE {6.35 118.65 6.35 169.65}}\
+ {iso-b7 FALSE {6.35 81.65 6.35 118.65}}\
+ {iso-b8 FALSE {6.35 55.65 6.35 81.65}}\
+ {iso-b9 FALSE {6.35 37.65 6.35 55.65}}\
+ {iso-b10 FALSE {6.35 24.65 6.35 37.65}}\
+ {jis-b1 FALSE {6.35 721.65 6.35 1023.65}}\
+ {jis-b2 FALSE {6.35 508.65 6.35 721.65}}\
+ {jis-b3 FALSE {6.35 357.65 6.35 508.65}}\
+ {jis-b4 FALSE {6.35 250.65 6.35 357.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+ {jis-b6 FALSE {6.35 121.65 6.35 175.65}}\
+ {jis-b7 FALSE {6.35 84.65 6.35 121.65}}\
+ {jis-b8 FALSE {6.35 57.65 6.35 84.65}}\
+ {jis-b9 FALSE {6.35 38.65 6.35 57.65}}\
+ {jis-b10 FALSE {6.35 25.65 6.35 38.65}}\
+ {iso-c3 FALSE {6.35 317.65 6.35 451.65}}\
+ {iso-c4 FALSE {6.35 222.65 6.35 317.65}}\
+ {iso-c5 FALSE {6.35 155.65 6.35 222.65}}\
+ {iso-c6 FALSE {6.35 107.65 6.35 155.65}}\
+ {iso-designated-long FALSE {6.35 103.65 6.35 213.65}}\
+ {hp-2x-postcard FALSE {6.35 141.65 6.35 193.65}}\
+ {hp-european-edp FALSE {6.35 298.45 6.35 349.25}}\
+ {hp-mini FALSE {6.35 133.35 6.35 209.55}}\
+ {hp-postcard FALSE {6.35 93.65 6.35 141.65}}\
+ {hp-tabloid FALSE {6.35 273.05 6.35 425.45}}\
+ {hp-us-edp FALSE {6.35 273.05 6.35 349.25}}\
+ {hp-us-government-legal FALSE {6.35 196.85 6.35 323.85}}\
+ {hp-us-government-letter FALSE {6.35 196.85 6.35 247.65}}\
+}
+# If you have more than one tray use the following example:
+# 1. List the supported trays
+#*input-trays-supported: main manual
+# 2. Define each tray and it's paper sizes
+#*medium-source-sizes-supported: \
+#{ main \
+# {na-letter FALSE {6.35 209.55 6.35 273.05}} \
+# {na-legal FALSE {6.35 209.55 6.35 349.25}} \
+# {iso-a4 FALSE {6.35 203.65 6.35 290.65}} \
+#} \
+#{ manual \
+# {iso-a5 FALSE {6.35 141.65 6.35 203.65}} \
+# {iso-c5 FALSE {6.35 155.65 6.35 222.65}} \
+# {iso-designated-long FALSE {6.35 103.65 6.35 213.65}} \
+# {jis-b5 FALSE {6.35 175.65 6.35 250.65}} \
+# {monarch-envelope FALSE {6.35 91.948 6.35 184.15}} \
+# {na-legal FALSE {6.35 209.55 6.35 349.25}} \
+# {na-number-10-envelope FALSE {6.35 98.425 6.35 234.95}} \
+# {executive FALSE {6.35 177.8 6.35 260.35}} \
+# {iso-a3 FALSE {6.35 290.65 6.35 413.65}} \
+# {iso-a0 FALSE {6.35 834.65 6.35 1182.65}} \
+#}
+*plexes-supported: simplex duplex tumble
+*printer-model: "PostScript default model"
+# 75, 100, 120, 150, 180, 200, 240, 300, 360, 400, 600, 720,
+# 940, 1200 and 2440 are supported DPI values, we limit it here
+# to some common values:
+*printer-resolutions-supported: 300 360 400 600
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+
+# NOTE: xp-psddx-* attributes are EXPERIMENTAL for now.
+# xp-psddx-download-fonts defines which fonts should be downloaded as outlines
+# (valid types are "pfa", "pfb", "ttf", "ttc", "otf", "otc")
+*xp-psddx-download-fonts: pfa pfb ttf ttc otf otc
+# xp-psddx-download-font-type defines which font type is used to download outlines
+# (valid values are "bitmap", "pstype1" and "pstype3")
+*xp-psddx-download-font-type: pstype1
+# EOF.
diff --git a/hw/xprint/config/C/print/models/PSspooldir/Makefile.am b/hw/xprint/config/C/print/models/PSspooldir/Makefile.am
new file mode 100644
index 000000000..52313aa23
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSspooldir/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/C/print/models/PSspooldir
+
+dist_xpc_DATA = model-config spooltodir.sh
diff --git a/hw/xprint/config/C/print/models/PSspooldir/model-config b/hw/xprint/config/C/print/models/PSspooldir/model-config
new file mode 100644
index 000000000..6bb477767
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSspooldir/model-config
@@ -0,0 +1,71 @@
+# $Xprint.org: PSspooldir model-config,v 1.1 2002/11/25 19:48:04 gisburn Exp $
+# PostScript DDX model-config which sends jobs to a spool dir instead to a print queue
+#
+# This model is basically a cut-down PSdefault model with a custom *xp-spooler-command
+#
+# DO NOT MODIFY THIS FILE!!
+#
+# If you want to make customisations for your printer create a copy
+# of this printer model.
+# Example (for creating a model config "MYCOMPANYlaserxx"):
+# 1. Create model config dir:
+# % mkdir MYCOMPANYlaserxx
+# 2. Link (or copy) the PMF (printer font metrics) for the
+# printer buildin fonts:
+# % ln -s PSspooldir/fonts MYCOMPANYlaserxx/.
+# 3. Copy the model config file:
+# % cp PSspooldir/model-config MYCOMPANYlaserxx/.
+# 4. Customize MYCOMPANYlaserxx/model-config to match your needs.
+#
+# Attributes supported for this printer model
+*content-orientations-supported: portrait landscape reverse-portrait reverse-landscape
+*descriptor: PostScript job spool dir /tmp/Xprintjobs
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+{ '' \
+ {na-letter FALSE {6.35 209.55 6.35 273.05}}\
+ {na-legal FALSE {6.35 209.55 6.35 349.25}}\
+ {executive FALSE {6.35 177.80 6.35 260.35}}\
+ {ledger FALSE {6.35 273.05 6.35 425.45}}\
+ {quarto FALSE {6.35 209.55 6.35 268.732}}\
+ {iso-a3 FALSE {6.35 290.65 6.35 413.65}}\
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}\
+ {iso-a5 FALSE {6.35 141.65 6.35 203.65}}\
+ {iso-b3 FALSE {6.35 346.65 6.35 493.65}}\
+ {iso-b4 FALSE {6.35 243.65 6.35 346.65}}\
+ {iso-b5 FALSE {6.35 169.65 6.35 243.65}}\
+ {jis-b3 FALSE {6.35 357.65 6.35 508.65}}\
+ {jis-b4 FALSE {6.35 250.65 6.35 357.65}}\
+ {jis-b5 FALSE {6.35 175.65 6.35 250.65}}\
+ {iso-c3 FALSE {6.35 317.65 6.35 451.65}}\
+ {iso-c4 FALSE {6.35 222.65 6.35 317.65}}\
+ {iso-c5 FALSE {6.35 155.65 6.35 222.65}}\
+}
+
+*plexes-supported: simplex duplex tumble
+*printer-model: "PostScript job spool dir /tmp/Xprintjobs"
+# 75, 100, 120, 150, 180, 200, 240, 300, 360, 400, 600, 720,
+# 940, 1200 and 2440 are supported DPI values, we limit it here
+# to some common values:
+*printer-resolutions-supported: 300 360 400 600
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+
+# Use custom spooler script which sends the output to a dir instead to a printer queue
+# Note that "%xpconfigdir%" is currently only supported in Xprt servers build
+# from xprint.mozdev.org sources, other platforms have replace it with the
+# absolute path name to the script
+*xp-spooler-command: %xpconfigdir%/C/print/models/PSspooldir/spooltodir.sh -d /tmp/Xprintjobs -s .ps -u 077 -p %printer-name% -c %copy-count% -t %job-name% -o "%options%"
+
+# NOTE: xp-psddx-* attributes are EXPERIMENTAL for now.
+# xp-psddx-download-fonts defines which fonts should be downloaded as outlines
+# (valid types are "pfa", "pfb", "ttf", "ttc", "otf", "otc")
+*xp-psddx-download-fonts: pfa pfb ttf ttc otf otc
+# xp-psddx-download-font-type defines which font type is used to download outlines
+# (valid values are "bitmap", "pstype1" and "pstype3")
+*xp-psddx-download-font-type: pstype1
+# EOF.
diff --git a/hw/xprint/config/C/print/models/PSspooldir/spooltodir.sh b/hw/xprint/config/C/print/models/PSspooldir/spooltodir.sh
new file mode 100755
index 000000000..aba14e1b3
--- /dev/null
+++ b/hw/xprint/config/C/print/models/PSspooldir/spooltodir.sh
@@ -0,0 +1,127 @@
+#!/bin/sh
+PATH=/usr/bin:/usr/sbin:/bin:/sbin
+export PATH
+
+verbose_msgs="false"
+DEFAULT_SPOOLDIR=/tmp/Xprintjobs
+
+usage()
+{
+ printf "Usage: ${0}: [options]\n"
+ printf "-v\tbe verbose\n"
+ printf "-d dirname\tdefine spool dir\n"
+ printf "-p string\tname of printer selected by user\n"
+ printf "-c integer\tnumber of copies\n"
+ printf "-t string\tjob title\n"
+ printf "-s string\tfile name suffix\n"
+ printf "-o string\tspooler options\n"
+ printf "-u mask\tpermission mask for new files (see umask)\n"
+ exit 2
+}
+
+verbose()
+{
+ if ${verbose_msgs} ; then
+ echo "$1"
+ fi
+}
+
+spooldir="${DEFAULT_SPOOLDIR}"
+printername=
+num_job_copies=
+job_title=
+filename_suffix=
+spooler_options=
+permmask=
+while getopts va:b:d:p:c:t:s:o:u: i
+do
+ case $i in
+ v)
+ verbose_msgs="true"
+ ;;
+ d)
+ spooldir="$OPTARG"
+ ;;
+ p)
+ printername="$OPTARG"
+ ;;
+ c)
+ num_job_copies="$OPTARG"
+ ;;
+ t)
+ job_title="$OPTARG"
+ ;;
+ s)
+ filename_suffix="$OPTARG"
+ ;;
+ o)
+ spooler_options="$OPTARG"
+ ;;
+ u)
+ permmask="$OPTARG"
+ ;;
+ ?) usage
+ ;;
+ esac
+done
+
+verbose "# spooldir=\"$spooldir\""
+verbose "# printername=\"$printername\""
+verbose "# num_job_copies=\"$num_job_copies\""
+verbose "# job_title=\"$job_title\""
+verbose "# spooler_options=\"$spooler_options\""
+verbose "# umask=\"$permmask\""
+
+if [ ! -d "${DEFAULT_SPOOLDIR}" ] ; then
+ mkdir "${DEFAULT_SPOOLDIR}"
+ chmod a+rwxt "${DEFAULT_SPOOLDIR}"
+fi
+
+if [ "${permmask}" != "" ] ; then
+ umask ${permmask}
+fi
+
+if [ ! -d "$spooldir" ] ; then
+ echo "$0: spooldir \"$spooldir\" does not exits." >&2
+ exit 1
+fi
+if [ ! -w "$spooldir" ] ; then
+ echo "$0: Cannot write to spooldir \"$spooldir\"." >&2
+ exit 1
+fi
+
+# Create first part of the output file name (prefix and an "unique"
+# id(=date and time))...
+filename="Xpjob_`date +%Y%m%d%H%M%S`"
+
+# ... then add options ...
+if [ "${printername}" != "" ] ; then
+ filename="${filename}_${printername}"
+fi
+if [ "${num_job_copies}" != "" -a "${num_job_copies}" != "1" ] ; then
+ filename="${filename}_copies_${num_job_copies}"
+fi
+if [ "${job_title}" != "" ] ; then
+ filename="${filename}_title_${job_title}"
+fi
+
+# ... mangle output file name and filter chars (like whitespaces)
+# which may screw-up further processing by other shell scripts ...
+filename="`echo \"${filename}\" | tr '[:blank:]' '_' | tr -c -d '[:alnum:]_.-'`"
+
+# ... add path and suffix ...
+filename="${spooldir}/${filename}${filename_suffix}"
+
+verbose "# File name is \"$filename\"."
+
+# ... and finally capture stdin to the file.
+cat >"${filename}"
+
+if ${verbose_msgs} ; then
+ printf "# File is " ; ls -l "${filename}"
+fi
+
+verbose "# Done."
+
+exit 0
+# EOF.
diff --git a/hw/xprint/config/C/print/models/SPSPARC2/Makefile.am b/hw/xprint/config/C/print/models/SPSPARC2/Makefile.am
new file mode 100644
index 000000000..5a56f90fb
--- /dev/null
+++ b/hw/xprint/config/C/print/models/SPSPARC2/Makefile.am
@@ -0,0 +1,5 @@
+SUBDIRS = fonts
+
+xpcdir = @xpconfigdir@/C/print/models/SPSPARC2
+
+dist_xpc_DATA = model-config
diff --git a/hw/xprint/config/C/print/models/SPSPARC2/fonts/Makefile.am b/hw/xprint/config/C/print/models/SPSPARC2/fonts/Makefile.am
new file mode 100644
index 000000000..8cc269459
--- /dev/null
+++ b/hw/xprint/config/C/print/models/SPSPARC2/fonts/Makefile.am
@@ -0,0 +1,37 @@
+xpcdir = @xpconfigdir@/C/print/models/SPSPARC2/fonts
+
+parentdir = @xpconfigdir@/C/print/models/PSdefault/fonts
+
+XPFONTS = \
+ Courier-Bold.pmf \
+ Courier-BoldOblique.pmf \
+ Courier-Oblique.pmf \
+ Courier.pmf \
+ Helvetica-Bold.pmf \
+ Helvetica-BoldOblique.pmf \
+ Helvetica-Oblique.pmf \
+ Helvetica.pmf \
+ Symbol.pmf \
+ Times-Bold.pmf \
+ Times-BoldItalic.pmf \
+ Times-Italic.pmf \
+ Times-Roman.pmf
+
+dest = $(DESTDIR)$(xpcdir)
+
+remove-stuff:
+ for x in $(XPFONTS) ; do \
+ rm -f $(dest)/$$x ; \
+ done
+
+ rm -f $(dest)/fonts.dir
+
+install-data-hook: remove-stuff
+ mkdir -p $(dest) ; \
+ for x in $(XPFONTS) ; do \
+ ln -s $(parentdir)/$$x $(dest)/$$x ; \
+ done
+
+ $(MKFONTSCALE) -b -s -l $(dest)
+
+uninstall-hook: remove-stuff
diff --git a/hw/xprint/config/C/print/models/SPSPARC2/model-config b/hw/xprint/config/C/print/models/SPSPARC2/model-config
new file mode 100644
index 000000000..9f29b9992
--- /dev/null
+++ b/hw/xprint/config/C/print/models/SPSPARC2/model-config
@@ -0,0 +1,18 @@
+# $Xprint.org: SPSPARC2 model-config,v 1.4 2002/11/07 19:48:04 gisburn Exp $
+*content-orientations-supported: portrait landscape
+*descriptor: SunPics SPARCprinter II
+*document-formats-supported: {POSTSCRIPT 2}
+*input-trays-supported:
+*medium-source-sizes-supported: \
+ { '' {na-letter FALSE {6.35 209.55 6.35 273.05}} \
+ {na-legal FALSE {6.35 209.55 6.35 349.25}} \
+ {iso-a4 FALSE {6.35 203.65 6.35 290.65}}}
+*plexes-supported: simplex
+*printer-model: "SunPics SPARCprinter II"
+*printer-resolutions-supported: 300
+*xp-ddx-identifier: XP-POSTSCRIPT
+*xp-listfonts-modes-supported: xp-list-internal-printer-fonts xp-list-glyph-fonts
+*xp-embedded-formats-supported: {POSTSCRIPT 2}
+*xp-raw-formats-supported: {POSTSCRIPT 2}
+*xp-setup-proviso: setup-optional
+# EOF.
diff --git a/hw/xprint/config/Makefile.am b/hw/xprint/config/Makefile.am
new file mode 100644
index 000000000..a5ea214c4
--- /dev/null
+++ b/hw/xprint/config/Makefile.am
@@ -0,0 +1,712 @@
+## Locale mappings
+## Notes:
+## - only ASCII chars are allowed
+## - "C" and "en_US" should not be used, they are real directories
+
+# List of locales which should be linked to the "C" locale
+
+SUBDIRS = C en_US
+
+xpconfigdir = @xpconfigdir@
+
+C_LOCALES= \
+ POSIX \
+ af_ZA \
+ af_ZA.iso88591 \
+ ar \
+ ar_AE \
+ ar_AE.iso88596 \
+ ar_AE.utf8 \
+ ar_BH \
+ ar_BH.iso88596 \
+ ar_BH.utf8 \
+ ar_DZ \
+ ar_DZ.iso88596 \
+ ar_DZ.utf8 \
+ ar_EG \
+ ar_EG.ISO8859-6 \
+ ar_EG.UTF-8 \
+ ar_EG.iso88596 \
+ ar_EG.utf8 \
+ ar_IN.utf8 \
+ ar_IQ \
+ ar_IQ.iso88596 \
+ ar_IQ.utf8 \
+ ar_JO \
+ ar_JO.iso88596 \
+ ar_JO.utf8 \
+ ar_KW \
+ ar_KW.iso88596 \
+ ar_KW.utf8 \
+ ar_LB \
+ ar_LB.iso88596 \
+ ar_LB.utf8 \
+ ar_LY \
+ ar_LY.iso88596 \
+ ar_LY.utf8 \
+ ar_MA \
+ ar_MA.iso88596 \
+ ar_MA.utf8 \
+ ar_OM \
+ ar_OM.iso88596 \
+ ar_OM.utf8 \
+ ar_QA \
+ ar_QA.iso88596 \
+ ar_QA.utf8 \
+ ar_SA \
+ ar_SA.iso88596 \
+ ar_SA.utf8 \
+ ar_SD \
+ ar_SD.iso88596 \
+ ar_SD.utf8 \
+ ar_SY \
+ ar_SY.iso88596 \
+ ar_SY.utf8 \
+ ar_TN \
+ ar_TN.iso88596 \
+ ar_TN.utf8 \
+ ar_YE \
+ ar_YE.iso88596 \
+ ar_YE.utf8 \
+ be_BY \
+ be_BY.cp1251 \
+ be_BY.utf8 \
+ bg_BG \
+ bg_BG.ISO8859-5 \
+ bg_BG.cp1251 \
+ bg_BG.utf8 \
+ bn_IN.UTF-8 \
+ bn_IN.utf8 \
+ br_FR \
+ br_FR.iso88591 \
+ bs \
+ bs_BA \
+ bs_BA.iso88592 \
+ bs_BA.ISO8859-2 \
+ bs_BA.ISO-8859-2 \
+ bs_BA.ISO_8859-2 \
+ bs_BA.UTF-8 \
+ bokmal \
+ ca \
+ ca.ISO8859-1 \
+ ca.ISO8859-15 \
+ ca_ES \
+ ca_ES.ISO8859-1 \
+ ca_ES.ISO8859-15 \
+ ca_ES.iso88591 \
+ ca_ES.iso885915@euro \
+ ca_ES.utf8 \
+ ca_ES@euro \
+ catalan \
+ croatian \
+ cs_CZ \
+ cs_CZ.ISO8859-2 \
+ cs_CZ.iso88592 \
+ cs_CZ.utf8 \
+ cy_GB \
+ cy_GB.iso885914 \
+ cz \
+ cz.ISO8859-2 \
+ czech \
+ da \
+ da.ISO8859-1 \
+ da.ISO8859-15 \
+ danish \
+ dansk \
+ da_DK \
+ da_DK.ISO8859-1 \
+ da_DK.ISO8859-15 \
+ da_DK.iso88591 \
+ da_DK.iso885915 \
+ da_DK.utf8 \
+ de \
+ de.ISO8859-1 \
+ de.ISO8859-15 \
+ de.UTF-8 \
+ deutsch \
+ de_AT \
+ de_AT.ISO8859-1 \
+ de_AT.ISO8859-15 \
+ de_AT.iso88591 \
+ de_AT.iso885915@euro \
+ de_AT.utf8 \
+ de_AT@euro \
+ de_BE \
+ de_BE.iso88591 \
+ de_BE.iso885915@euro \
+ de_BE@euro \
+ de_CH \
+ de_CH.ISO8859-1 \
+ de_CH.iso88591 \
+ de_CH.utf8 \
+ de_DE \
+ de_DE.ISO8859-1 \
+ de_DE.ISO8859-15 \
+ de_DE.UTF-8 \
+ de_DE.iso88591 \
+ de_DE.iso885915@euro \
+ de_DE.utf8 \
+ de_DE@euro \
+ de_LU \
+ de_LU.iso88591 \
+ de_LU.iso885915@euro \
+ de_LU.utf8 \
+ de_LU@euro \
+ el_GR \
+ el_GR.ISO8859-7 \
+ el_GR.ISO8859-7@euro \
+ el_GR.iso88597 \
+ el_GR.utf8 \
+ en_AU \
+ en_AU.ISO8859-1 \
+ en_AU.iso88591 \
+ en_AU.utf8 \
+ en_BW \
+ en_BW.iso88591 \
+ en_DK \
+ en_DK.iso88591 \
+ en_GB \
+ en_GB.ISO8859-1 \
+ en_GB.ISO8859-15 \
+ en_GB.iso88591 \
+ en_GB.iso885915 \
+ en_GB.utf8 \
+ en_HK \
+ en_HK.iso88591 \
+ en_IE \
+ en_IE.ISO8859-1 \
+ en_IE.ISO8859-15 \
+ en_IE.iso88591 \
+ en_IE.iso885915@euro \
+ en_IE.utf8 \
+ en_IE@euro \
+ en_IN \
+ en_IN.utf8 \
+ en_NZ \
+ en_NZ.ISO8859-1 \
+ en_NZ.iso88591 \
+ en_NZ.utf8 \
+ en_PH \
+ en_PH.iso88591 \
+ en_SG \
+ en_SG.iso88591 \
+ en_ZA \
+ en_ZA.iso88591 \
+ en_ZA.utf8 \
+ en_ZW \
+ en_ZW.iso88591 \
+ es_AR \
+ es_AR.ISO8859-1 \
+ es_AR.iso88591 \
+ es_AR.utf8 \
+ es_BO \
+ es_BO.ISO8859-1 \
+ es_BO.iso88591 \
+ es_BO.utf8 \
+ es_CL \
+ es_CL.ISO8859-1 \
+ es_CL.iso88591 \
+ es_CL.utf8 \
+ es_CO \
+ es_CO.ISO8859-1 \
+ es_CO.iso88591 \
+ es_CO.utf8 \
+ es_CR \
+ es_CR.ISO8859-1 \
+ es_CR.iso88591 \
+ es_CR.utf8 \
+ es_DO \
+ es_DO.iso88591 \
+ es_DO.utf8 \
+ es_EC \
+ es_EC.ISO8859-1 \
+ es_EC.iso88591 \
+ es_EC.utf8 \
+ es_ES \
+ es_ES.ISO8859-1 \
+ es_ES.ISO8859-15 \
+ es_ES.UTF-8 \
+ es_ES.iso88591 \
+ es_ES.iso885915@euro \
+ es_ES.utf8 \
+ es_ES@euro \
+ es_GT \
+ es_GT.ISO8859-1 \
+ es_GT.iso88591 \
+ es_GT.utf8 \
+ es_HN \
+ es_HN.iso88591 \
+ es_HN.utf8 \
+ es_MX \
+ es_MX.ISO8859-1 \
+ es_MX.iso88591 \
+ es_MX.utf8 \
+ es_NI \
+ es_NI.ISO8859-1 \
+ es_NI.iso88591 \
+ es_NI.utf8 \
+ es_PA \
+ es_PA.ISO8859-1 \
+ es_PA.iso88591 \
+ es_PA.utf8 \
+ es_PE \
+ es_PE.ISO8859-1 \
+ es_PE.iso88591 \
+ es_PE.utf8 \
+ es_PY \
+ es_PY.ISO8859-1 \
+ es_PY.iso88591 \
+ es_PY.utf8 \
+ es_SV \
+ es_SV.ISO8859-1 \
+ es_SV.iso88591 \
+ es_SV.utf8 \
+ es_UY \
+ es_UY.ISO8859-1 \
+ es_UY.iso88591 \
+ es_UY.utf8 \
+ es_VE \
+ es_VE.ISO8859-1 \
+ es_VE.iso88591 \
+ es_VE.utf8 \
+ et_EE \
+ et_EE.ISO8859-15 \
+ et_EE.iso88591 \
+ et_EE.utf8 \
+ eu_ES \
+ eu_ES.iso88591 \
+ eu_ES.iso885915@euro \
+ eu_ES@euro \
+ fa_IR.utf8 \
+ fi_FI \
+ fi_FI.ISO8859-1 \
+ fi_FI.ISO8859-15 \
+ fi_FI.UTF-8 \
+ fi_FI.iso88591 \
+ fi_FI.iso885915@euro \
+ fi_FI.utf8 \
+ fi_FI@euro \
+ fo_FO \
+ fo_FO.iso88591 \
+ fo_FO.utf8 \
+ fr_BE \
+ fr_BE.ISO8859-1 \
+ fr_BE.ISO8859-15 \
+ fr_BE.UTF-8 \
+ fr_BE.iso88591 \
+ fr_BE.iso885915@euro \
+ fr_BE.utf8 \
+ fr_BE@euro \
+ fr_CH \
+ fr_CH.ISO8859-1 \
+ fr_CH.iso88591 \
+ fr_CH.utf8 \
+ fr_FR \
+ fr_FR.ISO8859-1 \
+ fr_FR.ISO8859-15 \
+ fr_FR.UTF-8 \
+ fr_FR.iso88591 \
+ fr_FR.iso885915@euro \
+ fr_FR.utf8 \
+ fr_FR@euro \
+ fr_LU \
+ fr_LU.iso88591 \
+ fr_LU.iso885915@euro \
+ fr_LU.utf8 \
+ fr_LU@euro \
+ ga_IE \
+ ga_IE.iso88591 \
+ ga_IE.iso885915@euro \
+ ga_IE.utf8 \
+ ga_IE@euro \
+ gl_ES \
+ gl_ES.iso88591 \
+ gl_ES.iso885915@euro \
+ gl_ES.utf8 \
+ gl_ES@euro \
+ gu_IN.UTF-8 \
+ gu_IN.utf8 \
+ gv_GB \
+ gv_GB.iso88591 \
+ hebrew \
+ he \
+ he_IL \
+ he_IL.ISO8859-8 \
+ he_IL.UTF-8 \
+ he_IL.iso88598 \
+ he_IL.utf8 \
+ hi_IN.UTF-8 \
+ hi_IN.utf8 \
+ hr_HR \
+ hr_HR.ISO8859-2 \
+ hr_HR.iso88592 \
+ hr_HR.utf8 \
+ hu_HU \
+ hu_HU.ISO8859-2 \
+ hu_HU.iso88592 \
+ hu_HU.utf8 \
+ id_ID \
+ id_ID.iso88591 \
+ id_ID.utf8 \
+ is_IS \
+ is_IS.ISO8859-1 \
+ is_IS.iso88591 \
+ is_IS.utf8 \
+ it \
+ it.ISO8859-1 \
+ it.ISO8859-15 \
+ it.UTF-8 \
+ italian \
+ it_CH \
+ it_CH.iso88591 \
+ it_CH.utf8 \
+ it_IT \
+ it_IT.ISO8859-1 \
+ it_IT.ISO8859-15 \
+ it_IT.UTF-8 \
+ it_IT.iso88591 \
+ it_IT.iso885915@euro \
+ it_IT.utf8 \
+ it_IT@euro \
+ iw_IL \
+ iw_IL.iso88598 \
+ ja \
+ japan \
+ japanese \
+ japanese.euc \
+ japanese.sjis \
+ ja_JP \
+ ja_JP.EUC \
+ ja_JP.PCK \
+ ja_JP.UTF-8 \
+ ja_JP.eucJP \
+ ja_JP.eucjp \
+ ja_JP.sjis \
+ ja_JP.ujis \
+ ja_JP.utf8 \
+ ka_GE \
+ ka_GE.georgianps \
+ kl_GL \
+ kl_GL.iso88591 \
+ kl_GL.utf8 \
+ ko \
+ ko.UTF-8 \
+ korean \
+ korean.euc \
+ ko_KR \
+ ko_KR.EUC \
+ ko_KR.EUC@dict \
+ ko_KR.UTF-8 \
+ ko_KR.UTF-8@dict \
+ ko_KR.euckr \
+ ko_KR.utf8 \
+ kw_GB \
+ kw_GB.iso88591 \
+ lt_LT \
+ lt_LT.ISO8859-13 \
+ lt_LT.iso885913 \
+ lt_LT.utf8 \
+ lithuanian \
+ lt \
+ lt.ISO8859-13 \
+ lv \
+ lv.ISO8859-13 \
+ lv_LV \
+ lv_LV.ISO8859-13 \
+ lv_LV.iso885913 \
+ lv_LV.utf8 \
+ mi_NZ \
+ mi_NZ.iso885913 \
+ mk_MK \
+ mk_MK.ISO8859-5 \
+ mk_MK.iso88595 \
+ mk_MK.utf8 \
+ mr_IN.utf8 \
+ ms_MY \
+ ms_MY.iso88591 \
+ mt_MT \
+ mt_MT.iso88593 \
+ nb_NO \
+ nb_NO.ISO-8859-1 \
+ nl \
+ nl.ISO8859-1 \
+ nl.ISO8859-15 \
+ nl_BE \
+ nl_BE.ISO8859-1 \
+ nl_BE.ISO8859-15 \
+ nl_BE.iso88591 \
+ nl_BE.iso885915@euro \
+ nl_BE.utf8 \
+ nl_BE@euro \
+ nl_NL \
+ nl_NL.ISO8859-1 \
+ nl_NL.ISO8859-15 \
+ nl_NL.iso88591 \
+ nl_NL.iso885915@euro \
+ nl_NL.utf8 \
+ nl_NL@euro \
+ nn_NO \
+ nn_NO.iso88591 \
+ no \
+ no.ISO8859-1 \
+ no_NO \
+ no_NO.ISO8859-1@bokmal \
+ no_NO.ISO8859-1@nynorsk \
+ no_NO.iso88591 \
+ no_NO.utf8 \
+ norwegian \
+ oc_FR \
+ oc_FR.iso88591 \
+ pa_IN.UTF-8 \
+ pa_IN.utf8 \
+ polish \
+ pl_PL \
+ pl_PL.ISO8859-2 \
+ pl_PL.UTF-8 \
+ pl_PL.iso88592 \
+ pl_PL.utf8 \
+ portuguese \
+ pt \
+ pt.ISO8859-1 \
+ pt.ISO8859-15 \
+ pt_BR \
+ pt_BR.ISO8859-1 \
+ pt_BR.ISO-8859-1 \
+ pt_BR.ISO_8859-1 \
+ pt_BR.iso88591 \
+ pt_BR.iso885915 \
+ pt_BR.88591 \
+ pt_BR.88591.en \
+ pt_BR.utf8 \
+ pt_BR.UTF-8 \
+ pt_PT \
+ pt_PT.ISO8859-1 \
+ pt_PT.ISO8859-15 \
+ pt_PT.iso88591 \
+ pt_PT.iso885915@euro \
+ pt_PT.utf8 \
+ pt_PT@euro \
+ ro_RO \
+ ro_RO.ISO8859-2 \
+ ro_RO.iso88592 \
+ ro_RO.utf8 \
+ ru \
+ ru.ISO8859-5 \
+ ru.UTF-8 \
+ ru.ansi1251 \
+ ru.koi8-r \
+ ru_SU \
+ russian \
+ ru_RU \
+ ru_RU.ANSI1251 \
+ ru_RU.ISO8859-5 \
+ ru_RU.KOI8-R \
+ ru_RU.UTF-8 \
+ ru_RU.iso88595 \
+ ru_RU.koi8r \
+ ru_RU.utf8 \
+ ru_UA \
+ ru_UA.koi8u \
+ romanian \
+ se_NO \
+ se_NO.utf8 \
+ si \
+ sinhala \
+ si_LK \
+ si_LK.UTF8 \
+ sk \
+ sk.ISO8859-2 \
+ slovak \
+ slovene \
+ slovenian \
+ spanish \
+ sk_SK \
+ sk_SK.ISO8859-2 \
+ sk_SK.iso88592 \
+ sk_SK.utf8 \
+ sh \
+ sh.ISO8859-2 \
+ sh_BA.ISO8859-2@bosnia \
+ sh_YU \
+ sh_YU.iso88592 \
+ sh_YU.utf8 \
+ sl_SI \
+ sl_SI.ISO8859-2 \
+ sl_SI.iso88592 \
+ sl_SI.utf8 \
+ su \
+ su.ISO8859-1 \
+ sq_AL \
+ sq_AL.ISO8859-2 \
+ sq_AL.iso88591 \
+ sq_AL.utf8 \
+ sr_SP \
+ sr_SP.ISO8859-5 \
+ sr_YU \
+ sr_YU.ISO8859-5 \
+ sr_YU.iso88592 \
+ sr_YU.iso88595@cyrillic \
+ sr_YU.utf8 \
+ sr_YU@cyrillic \
+ sv \
+ sv.ISO8859-1 \
+ sv.ISO8859-15 \
+ sv.UTF-8 \
+ sv_FI \
+ sv_FI.iso88591 \
+ sv_FI.iso885915@euro \
+ sv_FI.utf8 \
+ sv_FI@euro \
+ sv_SE \
+ sv_SE.ISO8859-1 \
+ sv_SE.ISO8859-15 \
+ sv_SE.UTF-8 \
+ sv_SE.iso88591 \
+ sv_SE.iso885915 \
+ sv_SE.utf8 \
+ swedish \
+ ta_IN \
+ ta_IN.utf8 \
+ te_IN \
+ te_IN.utf8 \
+ tg_TJ \
+ tg_TJ.koi8t \
+ th \
+ thai \
+ th_TH \
+ th_TH.ISO8859-11 \
+ th_TH.TIS620 \
+ th_TH.UTF-8 \
+ th_TH.tis620 \
+ th_TH.utf8 \
+ tl_PH \
+ tl_PH.iso88591 \
+ tr \
+ tr.ISO8859-9 \
+ turkish \
+ tr_TR \
+ tr_TR.ISO8859-9 \
+ tr_TR.UTF-8 \
+ tr_TR.iso88599 \
+ tr_TR.utf8 \
+ uk_UA \
+ uk_UA.koi8u \
+ uk_UA.utf8 \
+ ur_PK \
+ ur_PK.utf8 \
+ uz_UZ \
+ uz_UZ.iso88591 \
+ vi_VN \
+ vi_VN.tcvn \
+ vi_VN.utf8 \
+ wa_BE \
+ wa_BE.iso88591 \
+ wa_BE.iso885915@euro \
+ wa_BE@euro \
+ zh \
+ zh.GBK \
+ zh.UTF-8 \
+ zh_CN \
+ zh_CN.EUC \
+ zh_CN.EUC@pinyin \
+ zh_CN.EUC@radical \
+ zh_CN.EUC@stroke \
+ zh_CN.GB18030 \
+ zh_CN.GB18030@pinyin \
+ zh_CN.GB18030@radical \
+ zh_CN.GB18030@stroke \
+ zh_CN.GBK \
+ zh_CN.GBK@pinyin \
+ zh_CN.GBK@radical \
+ zh_CN.GBK@stroke \
+ zh_CN.UTF-8 \
+ zh_CN.UTF-8@pinyin \
+ zh_CN.UTF-8@radical \
+ zh_CN.UTF-8@stroke \
+ zh_CN.gb18030 \
+ zh_CN.gb2312 \
+ zh_CN.gbk \
+ zh_CN.utf8 \
+ zh_HK \
+ zh_HK.BIG5HK \
+ zh_HK.BIG5HK@radical \
+ zh_HK.BIG5HK@stroke \
+ zh_HK.UTF-8 \
+ zh_HK.UTF-8@radical \
+ zh_HK.UTF-8@stroke \
+ zh_HK.big5hkscs \
+ zh_HK.utf8 \
+ zh_TW \
+ zh_TW.BIG5 \
+ zh_TW.BIG5@pinyin \
+ zh_TW.BIG5@radical \
+ zh_TW.BIG5@stroke \
+ zh_TW.BIG5@zhuyin \
+ zh_TW.EUC \
+ zh_TW.EUC@pinyin \
+ zh_TW.EUC@radical \
+ zh_TW.EUC@stroke \
+ zh_TW.EUC@zhuyin \
+ zh_TW.UTF-8 \
+ zh_TW.UTF-8@pinyin \
+ zh_TW.UTF-8@radical \
+ zh_TW.UTF-8@stroke \
+ zh_TW.UTF-8@zhuyin \
+ zh_TW.big5 \
+ zh_TW.euctw \
+ zh_TW.utf8
+
+
+# List of locales which should be linked to the "en_US" locale,
+# e.g. these locales should get the defaults (for example that
+# US-Letter is used as default papersize) mainly used in the USA
+US_LOCALES= \
+ en_CA \
+ en_CA.ISO8859-1 \
+ en_CA.iso88591 \
+ en_CA.utf8 \
+ en_US.ISO8859-1 \
+ en_US.ISO8859-15 \
+ en_US.UTF-8 \
+ en_US.iso88591 \
+ en_US.iso885915 \
+ en_US.utf8 \
+ es_PR \
+ es_PR.iso88591 \
+ es_PR.utf8 \
+ es_US \
+ es_US.iso88591 \
+ fr_CA \
+ fr_CA.ISO8859-1 \
+ fr_CA.iso88591 \
+ fr_CA.utf8 \
+ yi_US \
+ yi_US.cp1255
+
+dest = $(DESTDIR)$(xpconfigdir)
+
+remove-links:
+ for dir in $(US_LOCALES) ; do \
+ rm -f $(dest)/$${dir} ; \
+ done ; \
+ \
+ for dir in $(C_LOCALES) ; do \
+ rm -f $(dest)/$${dir} ; \
+ done ;
+
+install-data-local: remove-links
+ mkdir -p $(dest) ; \
+ mkdir -p $(dest)/C; \
+ mkdir -p $(dest)/en_US; \
+ \
+ for dir in $(US_LOCALES) ; do \
+ ln -s en_US $(dest)/$${dir} ; \
+ done ; \
+ \
+ for dir in $(C_LOCALES) ; do \
+ ln -s C $(dest)/$${dir} ; \
+ done ;
+
+uninstall-hook: remove-links
+
+EXTRA_DIST = README
diff --git a/hw/xprint/config/README b/hw/xprint/config/README
new file mode 100644
index 000000000..d7447815d
--- /dev/null
+++ b/hw/xprint/config/README
@@ -0,0 +1,318 @@
+
+ --------------------------------------
+ The X Print Service - The Basics
+ --------------------------------------
+
+Index
+ - 1.0 X Print Service Overview
+
+ - 2.0 How the X Print Service Works
+
+ - 3.0 Using the X Print Service
+ - 3.1 X Print Server Configuration
+ - 3.2 Starting the X Print Service
+ - 3.3 Configuring the environment
+ - 3.4 General End-User Sequence
+
+
+1.0 X Print Service Overview
+=============================
+
+The "X Print Service" technology allows X rendering to devices such as
+printers and fax. Most of the service is available in the X11
+technology stack as Xp, with the remainder in the CDE technology stack
+as DtPrint. Modifications have also been made to the Motif technology
+stack to support Xp and DtPrint.
+
+The Xp portion consists of:
+ * Xp Extension for the X-Server (included in the X-Server Xprt)
+ * Xp Extension API for the client side (libXp)
+ * PCL ddx driver that converts core X to native PCL
+ * Postscript ddx driver that converts core X to native Postscript
+ * Raster ddx driver that generates xwd rasters which can be
+ converted to PCL or Postscript rasters
+
+The DtPrint portion consists of:
+ * A collection of print GUIs (libDtPrint)
+ * A Print Dialog Manager that can assist a client in
+ setting printing options (dtpdm, dtpdmd)
+
+From an X clients perspective, it can attach to one of two nearly
+identical X-Servers, a "Video" X-Server, and a "Print" X-Server
+which has the additional Xp capability but otherwise looks and
+behaves the same.
+
+
+
+2.0 How the X Print Service Works
+==================================
+
+The X Print Service expands on the traditional X-Server and Xlib world
+in four ways.
+
+1. Most obvious is the use of "print ddx drivers" instead of
+ "video ddx drivers". While a video ddx driver modifies pixels
+ in a video frame buffer, a print ddx driver generates "page
+ description language (PDL)" output such as PCL or Postscript.
+
+ Once a print ddx driver generates PDL output, it can be sent to
+ a spooler such as lp(1) or retrieved by the client.
+
+ Though not currently done, a single X-Server can support both
+ print and video ddx drivers.
+
+2. Since printers support "paged" output, unlike video, a portion
+ of the Xp Extension supports APIs to delineate printed output.
+ For example, XpStartPage and XpEndPage tell the X-Server where
+ a physical page starts and ends in an otherwise continuous
+ stream of X rendering primitives. Likewise, XpStartJob and
+ XpEndJob determine when a collection of pages starts and ends.
+ XpEndJob typically causes the generated PDL to be submitted to
+ a spooler, such as lp(1).
+
+3. Since printers have extensive capabilities, another portion of
+ the Xp Extension supports APIs to manipulate "print contexts".
+
+ Once a printer is selected using the Xp Extension API, a print
+ context to represent it can be created. A print context
+ embodies the printer selected - it contains the printer's
+ default capabilities, selectable range of capabilities,
+ printer state, and generated output. Some "attributes" within
+ the print context can be modified by the user, and the
+ X-Server and print ddx driver will react accordingly. For
+ example, the attribute "content-orientation" can be set to
+ "landscape" or "portrait".
+
+4. Since printers can have "built in" fonts, the Xp Extension in
+ the X-Server works with the print ddx drivers to make
+ available (for printing only) additional fonts on a per print
+ context basis.
+
+ When a print context is created and set for a given printer,
+ the X font calls may be able to access additional printer
+ fonts. To do this (typically), the X-Server must have access
+ to "printer metric files" (.pmf) that describe at minimum the
+ metrics of the built in fonts.
+
+
+
+3.0 Using the X Print Service
+==============================
+
+There are three tasks to start the X Print Service: 1) configuring the
+X Print Server, 2) starting the X Print Service, 3) configuring the user
+session so that clients can find the running X Print Service.
+
+The tasks are described in detail below.
+
+
+3.1 X Print Server Configuration
+---------------------------------
+
+The X Print Server (Xprt) can read a number of configuration files which
+control its behavior and support for printers. Each vendor platform has
+a default location for this information. Xprt can also read the
+environment variable XPCONFIGDIR to locate alternate configuration
+directories. Common settings include:
+
+ * export XPCONFIGDIR=/X11/lib/X11/XpConfig/
+
+ * export XPCONFIGDIR=/proj/x11/xc/programs/Xserver/XpConfig/
+
+Xprt has many built-in defaults, and lacking any configuration files,
+will immediately try to support all printers visible via lpstat(1).
+
+In order of importance for configuration by a system administrator, the
+configuration files for a "C" locale are as follows.
+
+ ${XPCONFIGDIR}/C/print/Xprinters
+
+ `Xprinters' is the top most configuration file. It tells
+ Xprt which specific printer names (e.g. mylaser) should
+ be supported, and whether lpstat(1) or other commands
+ should be used to automatically supplement the list of
+ printers.
+
+ ${XPCONFIGDIR}/C/print/attributes/printer
+
+ The `printer' file maps printer names to model
+ configurations (see `model-config' below). For example,
+ "mylaser" could be mapped to a "HPDJ1600C", and all other
+ arbitrary printers could be mapped to a default, such as
+ "HPLJ4SI". When depending on lpstat(1) in the Xprinters
+ file, setting up defaults in `printer' becomes all the
+ more important.
+
+ ${XPCONFIGDIR}/C/print/attributes/document
+
+ The `document' file specifies the initial document values
+ for any print jobs. For example, which paper tray to
+ use, what default resolution, etc.
+
+ ${XPCONFIGDIR}/C/print/attributes/job
+
+ The `job' file specifies the initial job values for any
+ print jobs. For example, "notification-profile" can be
+ set so that when a print job is successfully sent to a
+ printer, e-mail is sent to the user.
+
+ ${XPCONFIGDIR}/C/print/models/HPDJ1600C/model-config
+ ${XPCONFIGDIR}/C/print/models/HPDJ1600C/fonts/fonts.dir
+ ${XPCONFIGDIR}/C/print/models/HPDJ1600C/fonts/9nb00051.pmf
+ ${XPCONFIGDIR}/C/print/models/HPDJ1600C/fonts/9nb00093.pmf
+
+ The `model-config' file has attributes that describe the
+ printer model's capabilities and default settings.
+ Printer model fonts may also be present. The model-config
+ file also identifies the print ddx driver to be used.
+
+ For each printer model supported, a complete hierarchy of
+ files should exist. In most cases, these files do not
+ need to be modified.
+
+ ${XPCONFIGDIR}/C/print/ddx-config/raster/pcl
+ ${XPCONFIGDIR}/C/print/ddx-config/raster/postscript
+
+ The print ddx drivers can have highly specific
+ configuration files to control their behavior. In most
+ cases, these files do not need to be modified.
+
+
+3.2 Starting the X Print Service
+---------------------------------
+
+The summary checklist for starting the X Print Service is as follows:
+
+1. Choose an execution model for the X Print Service. The X
+ Print Service can be run on a per-user session basis, per
+ machine basis, or can be run on a few machines globally
+ available to a number of users.
+
+2. If print jobs are to be submitted to a spooler (almost always
+ the case), make sure all needed printers are available to the
+ spooler subsystem (most often lp(1)) on the same machine
+ running the X Print Service.
+
+3. Configure the X Print Server. See ``X Print Server
+ Configuration''.
+
+4. Depending on #1, start the X Print Server process "Xprt", and
+ then the Print Dialog Manager Daemon process "dtpdmd" at the
+ appropriate times.
+
+The details are described below.
+
+Because the X Print Service is based on X, it can be easily distributed.
+The most significant factors in which execution model to choose will be
+driven by:
+
+ * how many printers will be accessable through the printer
+ subsystem on any given machine. A system administrator may
+ choose to cluster printers on a few given machines, or
+ scatter them across an organization and possibly make
+ extensive use of remote spoolers to make them globally
+ available.
+
+ * how many machines will need a copy of the X Print Server
+ configuration files. The files have been architected so
+ that one super-set version of them can be maintained and
+ distributed (e.g. via NFS), and a per-machine or per-user
+ version of the `Xprinters' is all that is needed to have the
+ appropriate information in them utilized or ignored.
+
+ * how many users can demand services from a given X Print
+ Service.
+
+With the above in mind, some obvious execution models include:
+
+ * Global - in this model, the system administrator is choosing
+ to run the X Print Service on a *few* select machines with
+ appropriate printers configured, and allow clients access to
+ the global resource. This can centralize the administration
+ of printers and configuration files, but may have to be
+ monitored for performance loading.
+
+ Startup would likely be done by boot-up scripts.
+
+ * Per-machine - every machine with potential X Print Service
+ users would run the service. Printer and configuration file
+ administration is decentralized, and usage would be limited
+ to the users on the machine.
+
+ Startup would likely be done by boot-up scripts.
+
+ * Per-user session - every user would run an entire X Print
+ Service for themselves. In the future, the Video X Server
+ normally started may contain Print X Server capability, so
+ this model becomes very natural.
+
+ Startup would likely be done at session login or by
+ launching actions or processes manually once the user
+ logs in. Note: the dtpdmd must be started after Xprt.
+
+Starting of the processes is straight forward. In strict order:
+
+ [machineA] % Xprt [-XpFile <Xprinters file>] [:dispNum] &
+
+ Note that Xprt will look for configuration files in either
+ a default location or where XPCONFIGDIR points.
+
+ -XpFile specifies an alternate `Xprinters' file, rather
+ than the default one or `${XPCONFIGDIR}/C/print/Xprinters'.
+
+ [machineA] % dtpdmd -d machineA[:dispNum] [-l /tmp/dtpdmd.log] &
+
+ The dtpdmd will maintain an X-Selection on the X-Server,
+ and will start dtpdm's as required to service requests.
+
+In all but the per-user session model, the machine running the dtpdmd
+(thus dtpdm's) will need display authorization to the users video
+display.
+
+
+
+3.3 Configuring the environment
+--------------------------------
+
+Once a X Print Server and dtpdmd have been started -- many of them
+in some cases -- clients will need to find and use them. There are
+two mechanisms that allow clients to discover X Print Servers and
+printers.
+
+ * "X Print Specifier" - assuming usage of the DtPrint print
+ dialogs, the following notation is understood:
+
+ printer_name@machine[:dispNum]
+
+ For example:
+
+ colorlj7@printhub:2
+
+ In the above example, the X Print Server running at `printhub:2'
+ is assumed to support the printer named `colorlj7'.
+
+ * "XPSERVERLIST" - assuming usage of the DtPrint print dialogs,
+ the environment variable "XPSERVERLIST" can contain a list
+ of X Print Servers. For example:
+
+ XPSERVERLIST="printhub:2 printhub:3 otherdept:0"
+
+ Then in the dialogs, only a printer name needs to be entered.
+ The dialog will then search the X Print Servers in XPSERVERLIST
+ for a server than supports the printer, and then establish
+ contact.
+
+3.4 General End-User Sequence
+------------------------------
+
+From most CDEnext applications, printing is accomplished by bringing
+down the <File> menu and selecting <Print...>. This will result in
+the DtPrintSetupBox dialog, which will request the name of a printer,
+and offer limited capability to configure print options (e.g. number
+of copies). If the user wishes, they can select <Setup...>, which
+will start a dtpdm capable of modifying additional print options.
+Finally, the user should select <Print>.
+
+
+
+$Xorg: README,v 1.3 2000/08/17 19:48:02 cpqbld Exp $
diff --git a/hw/xprint/config/en_US/Makefile.am b/hw/xprint/config/en_US/Makefile.am
new file mode 100644
index 000000000..0390ed2d4
--- /dev/null
+++ b/hw/xprint/config/en_US/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = print
diff --git a/hw/xprint/config/en_US/print/Makefile.am b/hw/xprint/config/en_US/print/Makefile.am
new file mode 100644
index 000000000..025003339
--- /dev/null
+++ b/hw/xprint/config/en_US/print/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = attributes
diff --git a/hw/xprint/config/en_US/print/attributes/Makefile.am b/hw/xprint/config/en_US/print/attributes/Makefile.am
new file mode 100644
index 000000000..8a05004d1
--- /dev/null
+++ b/hw/xprint/config/en_US/print/attributes/Makefile.am
@@ -0,0 +1,3 @@
+xpcdir = @xpconfigdir@/en_US/print/attributes
+
+dist_xpc_DATA = document
diff --git a/hw/xprint/config/en_US/print/attributes/document b/hw/xprint/config/en_US/print/attributes/document
new file mode 100644
index 000000000..253c46bce
--- /dev/null
+++ b/hw/xprint/config/en_US/print/attributes/document
@@ -0,0 +1,13 @@
+# $Xorg: document,v 1.2 2002/11/30 22:10:03 gisburn Exp $
+# Document DPA-Object initial attribute values for en_US(-like) locales
+#
+# Note that the defaults (for all locales) are set in
+# ${XPCONFIGDIR}/C/print/attributes/document
+# Values in ${XPCONFIGDIR}/${LANG}/print/attributes/document are used to
+# set/override these defaults for a specific locale on demand
+
+# US and some other countries use US-Letter as default paper size
+# ("C"-locale default is "ISO-A4")
+*default-medium: na-letter
+
+# EOF.
diff --git a/hw/xprint/ddxInit.c b/hw/xprint/ddxInit.c
new file mode 100644
index 000000000..d4c0b9a4c
--- /dev/null
+++ b/hw/xprint/ddxInit.c
@@ -0,0 +1,379 @@
+/* $Xorg: ddxInit.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "servermd.h"
+#include "DiPrint.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * InitOutput --
+ * If this is built as a print-only server, then we must supply
+ * an InitOutput routine. If a normal server's real ddx InitOutput
+ * is used, then it should call PrinterInitOutput if it so desires.
+ * The ddx-level hook is needed to allow the printer stuff to
+ * create additional screens. An extension can't reliably do
+ * this for two reasons:
+ *
+ * 1) If InitOutput doesn't create any screens, then main()
+ * exits before calling InitExtensions().
+ *
+ * 2) Other extensions may rely on knowing about all screens
+ * when they initialize, and we can't guarantee the order
+ * of extension initialization.
+ *
+ * Results:
+ * ScreenInfo filled in, and PrinterInitOutput is called to create
+ * the screens associated with printers.
+ *
+ * Side Effects:
+ * None
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void
+InitOutput(
+ ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv)
+
+{
+ pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ pScreenInfo->numPixmapFormats = 0; /* get them in PrinterInitOutput */
+ screenInfo.numVideoScreens = 0;
+
+#ifdef PRINT_ONLY_SERVER
+ PrinterInitOutput(pScreenInfo, argc, argv);
+#endif
+
+}
+
+static void
+BellProc(
+ int volume,
+ DeviceIntPtr pDev)
+{
+ return;
+}
+
+static void
+KeyControlProc(
+ DeviceIntPtr pDev,
+ KeybdCtrl *ctrl)
+{
+ return;
+}
+
+static KeySym printKeyMap[256];
+static CARD8 printModMap[256];
+
+static int
+KeyboardProc(
+ DevicePtr pKbd,
+ int what,
+ int argc,
+ char *argv[])
+{
+ KeySymsRec keySyms;
+
+ keySyms.minKeyCode = 8;
+ keySyms.maxKeyCode = 8;
+ keySyms.mapWidth = 1;
+ keySyms.map = printKeyMap;
+
+ switch(what)
+ {
+ case DEVICE_INIT:
+ InitKeyboardDeviceStruct(pKbd, &keySyms, printModMap,
+ (BellProcPtr)BellProc,
+ KeyControlProc);
+ break;
+ case DEVICE_ON:
+ break;
+ case DEVICE_OFF:
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+ return Success;
+}
+
+#include "../mi/mipointer.h"
+static int
+PointerProc(
+ DevicePtr pPtr,
+ int what,
+ int argc,
+ char *argv[])
+{
+#define NUM_BUTTONS 1
+ CARD8 map[NUM_BUTTONS];
+
+ switch(what)
+ {
+ case DEVICE_INIT:
+ {
+ map[0] = 0;
+ InitPointerDeviceStruct(pPtr, map, NUM_BUTTONS,
+ miPointerGetMotionEvents,
+ (PtrCtrlProcPtr)_XpVoidNoop,
+ miPointerGetMotionBufferSize());
+ break;
+ }
+ case DEVICE_ON:
+ break;
+ case DEVICE_OFF:
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+ return Success;
+}
+
+void
+InitInput(
+ int argc,
+ char **argv)
+{
+ DeviceIntPtr ptr, kbd;
+
+ ptr = AddInputDevice((DeviceProc)PointerProc, TRUE);
+ kbd = AddInputDevice((DeviceProc)KeyboardProc, TRUE);
+ RegisterPointerDevice(ptr);
+ RegisterKeyboardDevice(kbd);
+ return;
+}
+
+
+Bool
+LegalModifier(
+ unsigned int key,
+ DevicePtr dev)
+{
+ return TRUE;
+}
+
+void
+ProcessInputEvents(void)
+{
+}
+
+#ifdef __DARWIN__
+#include "micmap.h"
+
+void GlxExtensionInit(void);
+void GlxWrapInitVisuals(miInitVisualsProcPtr *procPtr);
+
+void
+DarwinHandleGUI(int argc, char *argv[])
+{
+}
+
+void DarwinGlxExtensionInit(void)
+{
+ GlxExtensionInit();
+}
+
+void DarwinGlxWrapInitVisuals(
+ miInitVisualsProcPtr *procPtr)
+{
+ GlxWrapInitVisuals(procPtr);
+}
+#endif
+
+#ifdef DDXOSINIT
+void
+OsVendorInit(void)
+{
+}
+#endif
+
+#ifdef DDXOSFATALERROR
+void
+OsVendorFatalError(void)
+{
+}
+#endif
+
+#ifdef DDXBEFORERESET
+void
+ddxBeforeReset(void)
+{
+ return;
+}
+#endif
+
+#ifdef DDXTIME
+CARD32
+GetTimeInMillis(void)
+{
+ struct timeval tp;
+
+ X_GETTIMEOFDAY(&tp);
+ return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
+#endif
+
+/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
+void ddxInitGlobals(void)
+{
+ PrinterInitGlobals();
+}
+
+/****************************************
+* ddxUseMsg()
+*
+* Called my usemsg from os/utils/c
+*
+*****************************************/
+
+void ddxUseMsg(void)
+{
+}
+
+void AbortDDX (void)
+{
+}
+
+void ddxGiveUp(void) /* Called by GiveUp() */
+{
+}
+
+int
+ddxProcessArgument (
+ int argc,
+ char *argv[],
+ int i)
+{
+ return(0);
+}
+
+#ifdef XINPUT
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "XIstubs.h"
+#include "exglobals.h"
+
+int
+ChangePointerDevice (
+ DeviceIntPtr old_dev,
+ DeviceIntPtr new_dev,
+ unsigned char x,
+ unsigned char y)
+{
+ return (BadDevice);
+}
+
+int
+ChangeDeviceControl (
+ register ClientPtr client,
+ DeviceIntPtr dev,
+ xDeviceCtl *control)
+{
+ return BadMatch;
+}
+
+void
+OpenInputDevice (
+ DeviceIntPtr dev,
+ ClientPtr client,
+ int *status)
+{
+ return;
+}
+
+void
+AddOtherInputDevices (void)
+{
+ return;
+}
+
+void
+CloseInputDevice (
+ DeviceIntPtr dev,
+ ClientPtr client)
+{
+ return;
+}
+
+int
+ChangeKeyboardDevice (
+ DeviceIntPtr old_dev,
+ DeviceIntPtr new_dev)
+{
+ return (Success);
+}
+
+int
+SetDeviceMode (
+ register ClientPtr client,
+ DeviceIntPtr dev,
+ int mode)
+{
+ return BadMatch;
+}
+
+int
+SetDeviceValuators (
+ register ClientPtr client,
+ DeviceIntPtr dev,
+ int *valuators,
+ int first_valuator,
+ int num_valuators)
+{
+ return BadMatch;
+}
+
+
+#endif /* XINPUT */
+
+#ifdef AIXV3
+/*
+ * This is just to get the server to link on AIX, where some bits
+ * that should be in os/ are instead in hw/ibm.
+ */
+int SelectWaitTime = 10000; /* usec */
+#endif
diff --git a/hw/xprint/doc/Makefile.am b/hw/xprint/doc/Makefile.am
new file mode 100644
index 000000000..c0cb9d3d9
--- /dev/null
+++ b/hw/xprint/doc/Makefile.am
@@ -0,0 +1,19 @@
+MAN_SRCS = Xprt.man.pre
+
+appmandir = $(APP_MAN_DIR)
+
+appman_PRE = Xprt.man
+appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@)
+
+include $(top_srcdir)/cpprules.in
+
+BUILT_SOURCES = $(appman_PRE)
+CLEANFILES = $(appman_PRE) $(appman_DATA)
+
+SUFFIXES += .$(APP_MAN_SUFFIX) .man
+
+.man.$(APP_MAN_SUFFIX):
+ -rm -f $@
+ $(LN_S) $< $@
+
+EXTRA_DIST = $(MAN_SRCS) Xprt.html Xprt.sgml
diff --git a/hw/xprint/doc/Xprt.html b/hw/xprint/doc/Xprt.html
new file mode 100644
index 000000000..f84a3c134
--- /dev/null
+++ b/hw/xprint/doc/Xprt.html
@@ -0,0 +1,115 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Xprt</title><meta name="generator" content="DocBook XSL Stylesheets V1.62.4"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"><a name="Xprt"></a><div class="titlepage"><div></div><div></div></div><div class="refnamediv"><h2>Name</h2><p>Xprt &#8212; Print server for X Version 11</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><tt class="command">Xprt</tt> [<tt class="option">-ac</tt>] [<tt class="option">-audit <i class="replaceable"><tt>level</tt></i></tt>] [<tt class="option">-pn</tt>] [<tt class="option">-fp <i class="replaceable"><tt>fontpath</tt></i></tt>] [<tt class="option">-XpFile <i class="replaceable"><tt>file</tt></i></tt>] [<tt class="option">-XpSpoolerType <i class="replaceable"><tt>spoolername</tt></i></tt>] [<tt class="option">:<i class="replaceable"><tt>display</tt></i></tt>]</p></div></div><div class="refsect1" lang="en"><a name="id2804962"></a><h2>DESCRIPTION</h2><p><span><b class="command">Xprt</b></span> is the Xprint print server
+ for version 11 of the X Window system for non display devices
+ such as printers and fax machines.</p><p>Xprint is an advanced printing system which enables X11
+ applications to use devices like printers, FAX or create
+ documents in formats like PostScript, PCL or PDF. It may be used by
+ clients such as <span class="application">mozilla</span>.
+ </p><p>Xprint is a very flexible, extensible, scaleable, client/server
+ print system based on ISO 10175 (and some other specs) and the X11
+ rendering protocol.
+ Using Xprint an application can search, query and use devices like
+ printers, FAX machines or create documents in formats like PDF.
+ In particular, an application can seek a printer, query supported
+ attributes (like paper size, trays, fonts etc.), configure the printer
+ device to match it's needs and print on it like on any other X device
+ reusing parts of the code which is used for the video card Xserver.
+ </p></div><div xmlns:ns1="" class="refsect1" lang="en"><a name="id2805117"></a><h2>USAGE</h2><p>
+ Although Xprt may be invoked from the command line, it is
+ preferable to run it as a daemon via the init script
+ <tt class="filename">/etc/init.d/xprint</tt> (where this script exists).
+ </p><p>Client programs such as mozilla will require environment
+ variable <tt class="envar">${XPSERVERLIST}</tt> to be set, identifying the
+ &quot;display&quot; on which Xprt is running. This variable may be set
+ for all users via <tt class="filename">/etc/profile</tt> (or similar), using
+ <b class="userinput"><tt>/etc/init.d/xprint get_xpserverlist</tt></b>:
+ </p><div class="informalexample"><pre class="programlisting">export XPSERVERLIST=`/etc/init.d/xprint get_xpserverlist`</pre></div></div><div class="refsect1" lang="en"><a name="id2805150"></a><h2>OPTIONS</h2><p>Many of Xprt's command line options are shared in common
+ with the usual X servers (see <span class="citerefentry"><span class="refentrytitle">Xserver</span>(1x)</span>).
+ Commonly used options include:</p><div class="variablelist"><dl><dt><span class="term"><tt class="option">:<i class="replaceable"><tt>display</tt></i></tt></span></dt><dd><p> The X server runs on the given display. If multiple X
+ servers are to run simultaneously on a host, each must
+ have a unique display number. Note that the standard X
+ server (for video displays) typically runs on display
+ :0. If <tt class="filename">/etc/init.d/xprint</tt> is used
+ to invoke Xprt, it may be configured to automatically assign an available
+ display number.</p></dd><dt><span class="term"><tt class="option">-ac</tt></span></dt><dd><p>disables host-based access control mechanisms. Enables access
+ by any host, and permits any host to modify the access control
+ list. Use with extreme caution. This option exists primarily
+ for running test suites remotely.</p></dd><dt><span class="term"><tt class="option">-audit <i class="replaceable"><tt>level</tt></i></tt></span></dt><dd><p>sets the audit trail level. The default level is 1, meaning
+ only connection rejections are reported. Level 2 additionally
+ reports all successful connections and disconnects. Level 4
+ enables messages from the SECURITY extension, if present,
+ including generation and revocation of authorizations and
+ violations of the security policy. Level 0 turns off the audit
+ trail. Audit lines are sent as standard error output.</p></dd><dt><span class="term"><tt class="option">-fp <i class="replaceable"><tt>fontpath</tt></i></tt></span></dt><dd><p>sets the search path for fonts. This path is a comma
+ separated list of directories which Xprt searches for
+ font databases.</p></dd><dt><span class="term"><tt class="option">-pn</tt></span></dt><dd><p>permits the server to continue running if it fails to
+ establish all of its well-known sockets (connection
+ points for clients), but establishes at least
+ one.</p></dd><dt><span class="term"><tt class="option">-XpFile <i class="replaceable"><tt>file</tt></i></tt></span></dt><dd><p>Sets an altername Xprinters file (see section FILES).</p></dd><dt><span class="term"><tt class="option">-XpSpoolerType <i class="replaceable"><tt>spoolername</tt></i></tt></span></dt><dd xmlns:ns2=""><p>
+ Defines the spooler system to be used for print job spooling.
+ Supported values in xprint.mozdev.org release 009 are:
+ </p><table class="simplelist" border="0" summary="Simple list"><tr><td>aix</td></tr><tr><td>aix4</td></tr><tr><td>bsd</td></tr><tr><td>osf</td></tr><tr><td>solaris</td></tr><tr><td>sysv</td></tr><tr><td>uxp</td></tr><tr><td>cups</td></tr><tr><td>lprng</td></tr><tr><td>other</td></tr><tr><td>none</td></tr></table><p>
+ (multiple values can be specified, seperated by ':', the first active spooler will be chosen).
+ The default value is platform-specific and can be obtained via
+ </p><pre class="programlisting">Xprt -h</pre><p>.
+ </p></dd></dl></div></div><div xmlns:ns3="" class="refsect1" lang="en"><a name="id2805336"></a><h2>ENVIRONMENT</h2><p>
+ The following environment variables are recognized by the X print server
+ (environment variables recognized by Xprint clients are described in
+ <span class="citerefentry"><span class="refentrytitle">Xprint</span>(7)</span>):
+
+ </p><div class="variablelist"><dl><dt><span class="term"><tt class="envar">${XPCONFIGDIR}</tt></span></dt><dd><p> This environment variable points to the root
+ of the Xprint server configuration directory hierarchy.
+ If the variable is not defined, the default
+ path is be assumed. The default path may be
+ <tt class="filename">/usr/X11R6/lib/X11/xserver/</tt>,
+ <tt class="filename">/usr/lib/X11/xserver/</tt>,
+ <tt class="filename">/usr/share/Xprint/xserver/</tt> or
+ <tt class="filename">/usr/openwin/server/etc/XpConfig</tt>, depending on the
+ system, and may be configured in <tt class="filename">/etc/init.d/xprint</tt>.</p></dd><dt><span class="term"><tt class="envar">${LANG}</tt></span></dt><dd><p>
+ This environment variable selects the locale settings used by the Xprint server.
+ Xprt allows language-specific settings (stored in <tt class="filename">${XPCONFIGDIR}/${LANG}/print/</tt>)
+ which will override the default settings (stored in <tt class="filename">${XPCONFIGDIR}/C/print/</tt>).
+ If <tt class="envar">${LANG}</tt> is not set &quot;C&quot; is assumed.
+ </p></dd></dl></div></div><div class="refsect1" lang="en"><a name="id2805421"></a><h2>FILES</h2><div class="variablelist"><dl><dt><span class="term"><tt class="filename">${XPCONFIGDIR}/${LANG}/print/Xprinters</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/Xprinters</tt></span></dt><dd><p>
+ `Xprinters' is the top most configuration file. It tells
+ Xprt which specific printer names (e.g. mylaser) should
+ be supported, and whether <span class="citerefentry"><span class="refentrytitle">lpstat</span>(1)</span> or other commands
+ should be used to automatically supplement the list of
+ printers.
+ </p></dd><dt><span class="term"><tt class="filename">${XPCONFIGDIR}/${LANG}/print/attributes/printer</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/attributes/printer</tt></span></dt><dd><p>
+ The `printer' file maps printer names to model
+ configurations (see `model-config' below). For example,
+ &quot;mylaser&quot; could be mapped to a &quot;HPDJ1600C&quot;, and all other
+ arbitrary printers could be mapped to a default, such as
+ &quot;HPLJ4SI&quot;. When depending on <span class="citerefentry"><span class="refentrytitle">lpstat</span>(1)</span> in the Xprinters
+ file, setting up defaults in `printer' becomes all the
+ more important.
+ </p></dd><dt><span class="term"><tt class="filename">${XPCONFIGDIR}/${LANG}/print/attributes/document</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/attributes/document</tt></span></dt><dd><p>
+ The `document' file specifies the initial document values
+ for any print jobs. For example, which paper tray to
+ use, what default resolution, etc.
+ </p></dd><dt><span class="term"><tt class="filename">${XPCONFIGDIR}/${LANG}/print/attributes/job</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/attributes/job</tt></span></dt><dd><p>
+ The `job' file specifies the initial job values for any
+ print jobs. For example, &quot;notification-profile&quot; can be
+ set so that when a print job is successfully sent to a
+ printer, e-mail is sent to the user.
+ </p></dd><dt><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/models/PSdefault/model-config</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/models/PSdefault/fonts/fonts.dir</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/models/PSdefault/fonts/9nb00051.pmf</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/models/PSdefault/fonts/9nb00093.pmf</tt></span></dt><dd><p>
+ The `model-config' file has attributes that describe the
+ printer model's capabilities and default settings.
+ Printer model fonts may also be present. The model-config
+ file also identifies the print ddx driver to be used.
+
+ For each printer model supported, a complete hierarchy of
+ files should exist. In most cases, these files do not
+ need to be modified.
+ </p></dd><dt><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/ddx-config/raster/pdf</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/ddx-config/raster/pcl</tt>, </span><span class="term"><tt class="filename">${XPCONFIGDIR}/C/print/ddx-config/raster/postscript</tt></span></dt><dd><p>
+ The print ddx drivers can have highly specific
+ configuration files to control their behavior. In most
+ cases, these files do not need to be modified.
+ </p></dd></dl></div></div><div class="refsect1" lang="en"><a name="id2805584"></a><h2>SEE ALSO</h2><p><span class="simplelist"><span class="citerefentry"><span class="refentrytitle">Xprint</span>(7)</span>, <span class="citerefentry"><span class="refentrytitle">X11</span>(7)</span>, <span class="citerefentry"><span class="refentrytitle">xplsprinters</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">xprehashprinterlist</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">xphelloworld</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">xpxmhelloworld</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">xpawhelloworld</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">xpxthelloworld</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">xpsimplehelloworld</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">Xserver</span>(1x)</span>, <span class="citerefentry"><span class="refentrytitle">libXp</span>(3x)</span>, <span class="citerefentry"><span class="refentrytitle">libXprintUtils</span>(3x)</span>, <span class="citerefentry"><span class="refentrytitle">libXprintAppUtils</span>(3x)</span>, <span class="citerefentry"><span class="refentrytitle">XmPrintShell</span>(3x)</span>, <span class="citerefentry"><span class="refentrytitle">XawPrintShell</span>(3x)</span>, Xprint FAQ (<a href="http://xprint.mozdev.org/docs/Xprint_FAQ.html" target="_top">http://xprint.mozdev.org/docs/Xprint_FAQ.html</a>), Xprint main site (<a href="http://xprint.mozdev.org/" target="_top">http://xprint.mozdev.org/</a>)</span></p></div><div class="refsect1" lang="en"><a name="id2805757"></a><h2>AUTHORS</h2><p>
+ This manual page was written by
+ Drew Parsons <tt class="email">&lt;<a href="mailto:dparsons@debian.org">dparsons@debian.org</a>&gt;</tt> and
+ Roland Mainz <tt class="email">&lt;<a href="mailto:roland.mainz@nrubsig.org">roland.mainz@nrubsig.org</a>&gt;</tt>,
+ with some help from the man page at
+ <a href="http://www.sins.com.au/unix/manpages/Xprt.html" target="_top">http://www.sins.com.au/unix/manpages/Xprt.html</a> and the XFree86
+ man page for <span class="citerefentry"><span class="refentrytitle">Xserver</span>(1)</span>.
+ </p></div></div></body></html>
diff --git a/hw/xprint/doc/Xprt.man.pre b/hw/xprint/doc/Xprt.man.pre
new file mode 100644
index 000000000..7599a1344
--- /dev/null
+++ b/hw/xprint/doc/Xprt.man.pre
@@ -0,0 +1,196 @@
+.\" -*- coding: us-ascii -*-
+.TH Xprt __appmansuffix__ "25 November 2004"
+.SH NAME
+Xprt \- Print server for X Version 11
+.SH SYNOPSIS
+.ad l
+\fBXprt\fR \kx
+.if (\nxu > (\n(.lu / 2)) .nr x (\n(.lu / 5)
+'in \n(.iu+\nxu
+[\fB\-ac\fR] [\fB\-audit \fBlevel\fR\fR] [\fB\-pn\fR] [\fB\-fp \fBfontpath\fR\fR] [\fB\-XpFile \fBfile\fR\fR] [\fB\-XpSpoolerType \fBspoolername\fR\fR] [\fB:\fBdisplay\fR\fR]
+'in \n(.iu-\nxu
+.ad b
+.SH DESCRIPTION
+Xprt is the Xprint print server
+for version 11 of the X Window system for non display devices
+such as printers and fax machines.
+.PP
+Xprint is an advanced printing system which enables X11
+applications to use devices like printers, FAX or create
+documents in formats like PostScript, PCL or PDF. It may be used by
+clients such as mozilla.
+.PP
+Xprint is a very flexible, extensible, scaleable, client/server
+print system based on ISO 10175 (and some other specs) and the X11
+rendering protocol.
+Using Xprint an application can search, query and use devices like
+printers, FAX machines or create documents in formats like PDF.
+In particular, an application can seek a printer, query supported
+attributes (like paper size, trays, fonts etc.), configure the printer
+device to match it's needs and print on it like on any other X device
+reusing parts of the code which is used for the video card Xserver.
+.SH USAGE
+Although Xprt may be invoked from the command line, it is
+preferable to run it as a daemon via the init script
+\fB/etc/init.d/xprint\fR (where this script exists).
+.PP
+Client programs such as mozilla will require environment
+variable \fB${XPSERVERLIST}\fR to be set, identifying the
+"display" on which Xprt is running. This variable may be set
+for all users via \fB/etc/profile\fR (or similar), using
+\fB/etc/init.d/xprint get_xpserverlist\fR:
+
+.nf
+export XPSERVERLIST=`/etc/init.d/xprint get_xpserverlist`
+.fi
+
+.SH OPTIONS
+Many of Xprt's command line options are shared in common
+with the usual X servers (see \fBXserver\fR(__appmansuffix__)).
+Commonly used options include:
+.TP
+\fB:\fIdisplay\fB\fR
+The X server runs on the given display. If multiple X
+servers are to run simultaneously on a host, each must
+have a unique display number. Note that the standard X
+server (for video displays) typically runs on display
+:0. If \fB/etc/init.d/xprint\fR is used
+to invoke Xprt, it may be configured to automatically assign an available
+display number.
+.TP
+\fB\-ac\fR
+disables host-based access control mechanisms. Enables access
+by any host, and permits any host to modify the access control
+list. Use with extreme caution. This option exists primarily
+for running test suites remotely.
+.TP
+\fB\-audit \fIlevel\fB\fR
+sets the audit trail level. The default level is 1, meaning
+only connection rejections are reported. Level 2 additionally
+reports all successful connections and disconnects. Level 4
+enables messages from the SECURITY extension, if present,
+including generation and revocation of authorizations and
+violations of the security policy. Level 0 turns off the audit
+trail. Audit lines are sent as standard error output.
+.TP
+\fB\-fp \fIfontpath\fB\fR
+sets the search path for fonts. This path is a comma
+separated list of directories which Xprt searches for
+font databases.
+.TP
+\fB\-pn\fR
+permits the server to continue running if it fails to
+establish all of its well-known sockets (connection
+points for clients), but establishes at least
+one.
+.TP
+\fB\-XpFile \fIfile\fB\fR
+Sets an altername Xprinters file (see section FILES).
+.TP
+\fB\-XpSpoolerType \fIspoolername\fB\fR
+Defines the spooler system to be used for print job spooling.
+Supported values in xprint.mozdev.org release 009 are:
+
+aix
+
+aix4
+
+bsd
+
+osf
+
+solaris
+
+sysv
+
+uxp
+
+cups
+
+lprng
+
+other
+
+none
+
+(multiple values can be specified, seperated by ':', the first active spooler will be chosen).
+The default value is platform-specific and can be obtained via
+
+.nf
+Xprt \-h
+.fi
+
+\&.
+.SH ENVIRONMENT
+The following environment variables are recognized by the X print server
+(environment variables recognized by Xprint clients are described in
+\fBXprint\fR(__miscmansuffix__)):
+.TP
+\fB${XPCONFIGDIR}\fR
+This environment variable points to the root
+of the Xprint server configuration directory hierarchy.
+If the variable is not defined, the default
+path is be assumed. The default path may be
+\fB/usr/X11R6/lib/X11/xserver/\fR,
+\fB/usr/lib/X11/xserver/\fR,
+\fB/usr/share/Xprint/xserver/\fR or
+\fB/usr/openwin/server/etc/XpConfig\fR, depending on the
+system, and may be configured in \fB/etc/init.d/xprint\fR.
+.TP
+\fB${LANG}\fR
+This environment variable selects the locale settings used by the Xprint server.
+Xprt allows language-specific settings (stored in \fB${XPCONFIGDIR}/${LANG}/print/\fR)
+which will override the default settings (stored in \fB${XPCONFIGDIR}/C/print/\fR).
+If \fB${LANG}\fR is not set "C" is assumed.
+.PP
+.SH FILES
+.TP
+\fB${XPCONFIGDIR}/${LANG}/print/Xprinters\fR, \fB${XPCONFIGDIR}/C/print/Xprinters\fR
+`Xprinters' is the top most configuration file. It tells
+Xprt which specific printer names (e.g. mylaser) should
+be supported, and whether \fBlpstat\fR(1) or other commands
+should be used to automatically supplement the list of
+printers.
+.TP
+\fB${XPCONFIGDIR}/${LANG}/print/attributes/printer\fR, \fB${XPCONFIGDIR}/C/print/attributes/printer\fR
+The `printer' file maps printer names to model
+configurations (see `model-config' below). For example,
+"mylaser" could be mapped to a "HPDJ1600C", and all other
+arbitrary printers could be mapped to a default, such as
+"HPLJ4SI". When depending on \fBlpstat\fR(1) in the Xprinters
+file, setting up defaults in `printer' becomes all the
+more important.
+.TP
+\fB${XPCONFIGDIR}/${LANG}/print/attributes/document\fR, \fB${XPCONFIGDIR}/C/print/attributes/document\fR
+The `document' file specifies the initial document values
+for any print jobs. For example, which paper tray to
+use, what default resolution, etc.
+.TP
+\fB${XPCONFIGDIR}/${LANG}/print/attributes/job\fR, \fB${XPCONFIGDIR}/C/print/attributes/job\fR
+The `job' file specifies the initial job values for any
+print jobs. For example, "notification-profile" can be
+set so that when a print job is successfully sent to a
+printer, e-mail is sent to the user.
+.TP
+\fB${XPCONFIGDIR}/C/print/models/PSdefault/model\-config\fR, \fB${XPCONFIGDIR}/C/print/models/PSdefault/fonts/fonts.dir\fR, \fB${XPCONFIGDIR}/C/print/models/PSdefault/fonts/9nb00051.pmf\fR, \fB${XPCONFIGDIR}/C/print/models/PSdefault/fonts/9nb00093.pmf\fR
+The `model-config' file has attributes that describe the
+printer model's capabilities and default settings.
+Printer model fonts may also be present. The model-config
+file also identifies the print ddx driver to be used.
+For each printer model supported, a complete hierarchy of
+files should exist. In most cases, these files do not
+need to be modified.
+.TP
+\fB${XPCONFIGDIR}/C/print/ddx\-config/raster/pdf\fR, \fB${XPCONFIGDIR}/C/print/ddx\-config/raster/pcl\fR, \fB${XPCONFIGDIR}/C/print/ddx\-config/raster/postscript\fR
+The print ddx drivers can have highly specific
+configuration files to control their behavior. In most
+cases, these files do not need to be modified.
+.SH "SEE ALSO"
+\fBXprint\fR(__miscmansuffix__), \fBX11\fR(__miscmansuffix__), \fBxplsprinters\fR(__appmansuffix__), \fBxprehashprinterlist\fR(__appmansuffix__), \fBxphelloworld\fR(__appmansuffix__), \fBxpxmhelloworld\fR(__appmansuffix__), \fBxpawhelloworld\fR(__appmansuffix__), \fBxpxthelloworld\fR(__appmansuffix__), \fBxpsimplehelloworld\fR(__appmansuffix__), \fBXserver\fR(__appmansuffix__), \fBlibXp\fR(__libmansuffix__), \fBlibXprintUtils\fR(__libmansuffix__), \fBlibXprintAppUtils\fR(__libmansuffix__), \fBXmPrintShell\fR(__libmansuffix__), \fBXawPrintShell\fR(__libmansuffix__), Xprint FAQ (http://xprint.mozdev.org/docs/Xprint_FAQ.html), Xprint main site (http://xprint.mozdev.org/)
+.SH AUTHORS
+This manual page was written by
+Drew Parsons <dparsons@debian.org> and
+Roland Mainz <roland.mainz@nrubsig.org>,
+with some help from the man page at
+http://www.sins.com.au/unix/manpages/Xprt.html and the XFree86
+man page for \fBXserver\fR(1).
diff --git a/hw/xprint/doc/Xprt.sgml b/hw/xprint/doc/Xprt.sgml
new file mode 100644
index 000000000..0ffa39fcb
--- /dev/null
+++ b/hw/xprint/doc/Xprt.sgml
@@ -0,0 +1,371 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.2//EN" 'http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd'>
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+ page: 'docbook-to-man manpage.sgml > manpage.1'. You may view
+ the manual page with: 'docbook-to-man manpage.sgml | nroff -man | less'.
+ A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+ docbook-to-man $< > $@
+
+HTML generation can be done like this:
+% xsltproc ==docbook /usr/share/sgml/docbook/docbook-xsl-stylesheets-1.60.1/html/docbook.xsl Xprint.sgml >Xprint.html
+ -->
+
+<refentry id="Xprt">
+ <refmeta>
+ <refentrytitle>Xprt</refentrytitle>
+ <manvolnum>__appmansuffix__</manvolnum>
+ </refmeta>
+ <refnamediv>
+ <refname>Xprt</refname>
+
+ <refpurpose>Print server for X Version 11</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>Xprt</command>
+
+ <arg><option>-ac</option></arg>
+
+ <arg><option>-audit <replaceable>level</replaceable></option></arg>
+
+ <arg><option>-pn</option></arg>
+
+ <arg><option>-fp <replaceable>fontpath</replaceable></option></arg>
+
+ <arg><option>-XpFile <replaceable>file</replaceable></option></arg>
+
+ <arg><option>-XpSpoolerType <replaceable>spoolername</replaceable></option></arg>
+
+ <arg><option>:<replaceable>display</replaceable></option></arg>
+
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para><command>Xprt</command> is the Xprint print server
+ for version 11 of the X Window system for non display devices
+ such as printers and fax machines.</para>
+
+ <para>Xprint is an advanced printing system which enables X11
+ applications to use devices like printers, FAX or create
+ documents in formats like PostScript, PCL or PDF. It may be used by
+ clients such as <application>mozilla</application>.
+ </para>
+
+ <para>Xprint is a very flexible, extensible, scaleable, client/server
+ print system based on ISO 10175 (and some other specs) and the X11
+ rendering protocol.
+ Using Xprint an application can search, query and use devices like
+ printers, FAX machines or create documents in formats like PDF.
+ In particular, an application can seek a printer, query supported
+ attributes (like paper size, trays, fonts etc.), configure the printer
+ device to match it's needs and print on it like on any other X device
+ reusing parts of the code which is used for the video card Xserver.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>USAGE</title>
+
+ <para>
+ Although Xprt may be invoked from the command line, it is
+ preferable to run it as a daemon via the init script
+ <filename>/etc/init.d/xprint</filename> (where this script exists).
+ </para>
+
+ <para>Client programs such as mozilla will require environment
+ variable <envar>${XPSERVERLIST}</envar> to be set, identifying the
+ "display" on which Xprt is running. This variable may be set
+ for all users via <filename>/etc/profile</filename> (or similar), using
+ <userinput>/etc/init.d/xprint get_xpserverlist</userinput>:
+ <informalexample>
+ <programlisting>export XPSERVERLIST=`/etc/init.d/xprint get_xpserverlist`</programlisting>
+ </informalexample>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <para>Many of Xprt's command line options are shared in common
+ with the usual X servers (see <citerefentry><refentrytitle>Xserver</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry>).
+ Commonly used options include:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>:<replaceable>display</replaceable></option>
+ </term>
+ <listitem>
+ <para> The X server runs on the given display. If multiple X
+ servers are to run simultaneously on a host, each must
+ have a unique display number. Note that the standard X
+ server (for video displays) typically runs on display
+ :0. If <filename>/etc/init.d/xprint</filename> is used
+ to invoke Xprt, it may be configured to automatically assign an available
+ display number.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-ac</option>
+ </term>
+ <listitem>
+ <para>disables host-based access control mechanisms. Enables access
+ by any host, and permits any host to modify the access control
+ list. Use with extreme caution. This option exists primarily
+ for running test suites remotely.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-audit <replaceable>level</replaceable></option>
+ </term>
+ <listitem>
+ <para>sets the audit trail level. The default level is 1, meaning
+ only connection rejections are reported. Level 2 additionally
+ reports all successful connections and disconnects. Level 4
+ enables messages from the SECURITY extension, if present,
+ including generation and revocation of authorizations and
+ violations of the security policy. Level 0 turns off the audit
+ trail. Audit lines are sent as standard error output.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-fp <replaceable>fontpath</replaceable></option>
+ </term>
+ <listitem>
+ <para>sets the search path for fonts. This path is a comma
+ separated list of directories which Xprt searches for
+ font databases.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-pn</option>
+ </term>
+ <listitem>
+ <para>permits the server to continue running if it fails to
+ establish all of its well-known sockets (connection
+ points for clients), but establishes at least
+ one.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-XpFile <replaceable>file</replaceable></option>
+ </term>
+ <listitem>
+ <para>Sets an altername Xprinters file (see section FILES).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-XpSpoolerType <replaceable>spoolername</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Defines the spooler system to be used for print job spooling.
+ Supported values in xprint.mozdev.org release 009 are:
+ <simplelist type="vert">
+ <member>aix</member>
+ <member>aix4</member>
+ <member>bsd</member>
+ <member>osf</member>
+ <member>solaris</member>
+ <member>sysv</member>
+ <member>uxp</member>
+ <member>cups</member>
+ <member>lprng</member>
+ <member>other</member>
+ <member>none</member>
+ </simplelist>
+ (multiple values can be specified, seperated by ':', the first active spooler will be chosen).
+ The default value is platform-specific and can be obtained via
+ <programlisting>Xprt -h</programlisting>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>ENVIRONMENT</title>
+ <para>
+ The following environment variables are recognized by the X print server
+ (environment variables recognized by Xprint clients are described in
+ <citerefentry><refentrytitle>Xprint</refentrytitle><manvolnum>__miscmansuffix__</manvolnum></citerefentry>):
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>${XPCONFIGDIR}</envar></term>
+ <listitem>
+ <para> This environment variable points to the root
+ of the Xprint server configuration directory hierarchy.
+ If the variable is not defined, the default
+ path is be assumed. The default path may be
+ <filename>/usr/X11R6/lib/X11/xserver/</filename>,
+ <filename>/usr/lib/X11/xserver/</filename>,
+ <filename>/usr/share/Xprint/xserver/</filename> or
+ <filename>/usr/openwin/server/etc/XpConfig</filename>, depending on the
+ system, and may be configured in <filename>/etc/init.d/xprint</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>${LANG}</envar></term>
+ <listitem>
+ <para>
+ This environment variable selects the locale settings used by the Xprint server.
+ Xprt allows language-specific settings (stored in <filename>${XPCONFIGDIR}/${LANG}/print/</filename>)
+ which will override the default settings (stored in <filename>${XPCONFIGDIR}/C/print/</filename>).
+ If <envar>${LANG}</envar> is not set "C" is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>FILES</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>${XPCONFIGDIR}/${LANG}/print/Xprinters</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/Xprinters</filename></term>
+ <listitem>
+ <para>
+ `Xprinters' is the top most configuration file. It tells
+ Xprt which specific printer names (e.g. mylaser) should
+ be supported, and whether <citerefentry><refentrytitle>lpstat</refentrytitle><manvolnum>1</manvolnum></citerefentry> or other commands
+ should be used to automatically supplement the list of
+ printers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>${XPCONFIGDIR}/${LANG}/print/attributes/printer</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/attributes/printer</filename></term>
+ <listitem>
+ <para>
+ The `printer' file maps printer names to model
+ configurations (see `model-config' below). For example,
+ "mylaser" could be mapped to a "HPDJ1600C", and all other
+ arbitrary printers could be mapped to a default, such as
+ "HPLJ4SI". When depending on <citerefentry><refentrytitle>lpstat</refentrytitle><manvolnum>1</manvolnum></citerefentry> in the Xprinters
+ file, setting up defaults in `printer' becomes all the
+ more important.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>${XPCONFIGDIR}/${LANG}/print/attributes/document</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/attributes/document</filename></term>
+ <listitem>
+ <para>
+ The `document' file specifies the initial document values
+ for any print jobs. For example, which paper tray to
+ use, what default resolution, etc.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>${XPCONFIGDIR}/${LANG}/print/attributes/job</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/attributes/job</filename></term>
+ <listitem>
+ <para>
+ The `job' file specifies the initial job values for any
+ print jobs. For example, "notification-profile" can be
+ set so that when a print job is successfully sent to a
+ printer, e-mail is sent to the user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>${XPCONFIGDIR}/C/print/models/PSdefault/model-config</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/models/PSdefault/fonts/fonts.dir</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/models/PSdefault/fonts/9nb00051.pmf</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/models/PSdefault/fonts/9nb00093.pmf</filename></term>
+
+ <listitem>
+ <para>
+ The `model-config' file has attributes that describe the
+ printer model's capabilities and default settings.
+ Printer model fonts may also be present. The model-config
+ file also identifies the print ddx driver to be used.
+
+ For each printer model supported, a complete hierarchy of
+ files should exist. In most cases, these files do not
+ need to be modified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>${XPCONFIGDIR}/C/print/ddx-config/raster/pdf</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/ddx-config/raster/pcl</filename></term>
+ <term><filename>${XPCONFIGDIR}/C/print/ddx-config/raster/postscript</filename></term>
+
+ <listitem>
+ <para>
+ The print ddx drivers can have highly specific
+ configuration files to control their behavior. In most
+ cases, these files do not need to be modified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <simplelist type="inline">
+ <!-- specific references -->
+ <!-- none -->
+
+ <!-- Xprint general references -->
+ <member><citerefentry><refentrytitle>Xprint</refentrytitle><manvolnum>__miscmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>X11</refentrytitle><manvolnum>__miscmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xplsprinters</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xprehashprinterlist</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xphelloworld</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xpxmhelloworld</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xpawhelloworld</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xpxthelloworld</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>xpsimplehelloworld</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>Xserver</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+<!--
+ <member><citerefentry><refentrytitle>Xprt</refentrytitle><manvolnum>__appmansuffix__</manvolnum></citerefentry></member>
+-->
+ <!-- ToDO: Add manual pages for the single Xprint DDX implementations (PostScript/PDF/PCL/PCL-MONO/Raster/etc.) -->
+ <member><citerefentry><refentrytitle>libXp</refentrytitle><manvolnum>__libmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>libXprintUtils</refentrytitle><manvolnum>__libmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>libXprintAppUtils</refentrytitle><manvolnum>__libmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>XmPrintShell</refentrytitle><manvolnum>__libmansuffix__</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>XawPrintShell</refentrytitle><manvolnum>__libmansuffix__</manvolnum></citerefentry></member>
+ <member>Xprint FAQ (<ulink url="http://xprint.mozdev.org/docs/Xprint_FAQ.html">http://xprint.mozdev.org/docs/Xprint_FAQ.html</ulink>)</member>
+ <member>Xprint main site (<ulink url="http://xprint.mozdev.org/">http://xprint.mozdev.org/</ulink>)</member>
+ </simplelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>AUTHORS</title>
+ <para>
+ This manual page was written by
+ Drew Parsons <email>dparsons@debian.org</email> and
+ Roland Mainz <email>roland.mainz@nrubsig.org</email>,
+ with some help from the man page at
+ <ulink url="http://www.sins.com.au/unix/manpages/Xprt.html">http://www.sins.com.au/unix/manpages/Xprt.html</ulink> and the XFree86
+ man page for <citerefentry><refentrytitle>Xserver</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
+ </refsect1>
+</refentry>
+
+
+
diff --git a/hw/xprint/etc/Makefile.am b/hw/xprint/etc/Makefile.am
new file mode 100644
index 000000000..0a960cd1b
--- /dev/null
+++ b/hw/xprint/etc/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = init.d profile.d Xsession.d
diff --git a/hw/xprint/etc/Xsession.d/Makefile.am b/hw/xprint/etc/Xsession.d/Makefile.am
new file mode 100644
index 000000000..e0277d9d4
--- /dev/null
+++ b/hw/xprint/etc/Xsession.d/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = cde_xsessiond_xprint.sh
diff --git a/hw/xprint/etc/Xsession.d/cde_xsessiond_xprint.sh b/hw/xprint/etc/Xsession.d/cde_xsessiond_xprint.sh
new file mode 100644
index 000000000..3fb6bba7c
--- /dev/null
+++ b/hw/xprint/etc/Xsession.d/cde_xsessiond_xprint.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#####################################################################
+### File: 0018.xprint
+###
+### Default Location: /usr/dt/config/Xsession.d/
+###
+### Purpose: Setup Xprint env vars
+###
+### Description: This script is invoked by means of the Xsession file
+### at user login.
+###
+### Invoked by: /usr/dt/bin/Xsession
+###
+### (c) Copyright 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+###
+### please send bugfixes or comments to http://xprint.mozdev.org/
+###
+#####################################################################
+
+
+#
+# Obtain list of Xprint servers
+#
+
+if [ -f "/etc/init.d/xprint" ] ; then
+ XPSERVERLIST="`/bin/sh /etc/init.d/xprint get_xpserverlist`"
+ export XPSERVERLIST
+fi
+
+########################## eof #####################
diff --git a/hw/xprint/etc/init.d/Makefile.am b/hw/xprint/etc/init.d/Makefile.am
new file mode 100644
index 000000000..cc03cfab4
--- /dev/null
+++ b/hw/xprint/etc/init.d/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = xprint.cpp
diff --git a/hw/xprint/etc/init.d/xprint.cpp b/hw/xprint/etc/init.d/xprint.cpp
new file mode 100644
index 000000000..dbfd1e139
--- /dev/null
+++ b/hw/xprint/etc/init.d/xprint.cpp
@@ -0,0 +1,1277 @@
+XCOMM!/bin/sh
+XCOMM
+XCOMM Copyright 2002-2004 by Roland Mainz <roland.mainz@nrubsig.org>.
+XCOMM
+XCOMM This script manages the Xprint server side
+
+XCOMM Basic support for IRIX-style "chkconfig"
+XCOMM chkconfig: 2345 61 61
+XCOMM description: Startup/shutdown script for Xprint server(s)
+
+XCOMM Basic support for the Linux Standard Base Specification 1.0.0
+XCOMM (Note: The Should-Start/Stop lines are there so that this works in the
+XCOMM future, when the LSB adopts these. The X-UnitedLinux lines are there
+XCOMM so that it works right now.)
+XCOMM## BEGIN INIT INFO
+XCOMM Provides: xprint
+XCOMM Required-Start: $local_fs $remote_fs $syslog $network
+XCOMM Required-Stop: $local_fs $remote_fs $syslog
+XCOMM Should-Start: cups lpd xfs
+XCOMM Should-Stop: cups lpd xfs
+XCOMM X-UnitedLinux-Should-Start: cups lpd xfs
+XCOMM X-UnitedLinux-Should-Stop: cups lpd xfs
+XCOMM Default-Start: 3 5
+XCOMM Default-Stop: 0 1 2 6
+XCOMM Description: Startup/shutdown script for Xprint server(s)
+XCOMM## END INIT INFO
+
+#undef sun
+#undef unix
+
+XCOMM###########################################################################
+XCOMM
+XCOMM This script has three main tasks:
+XCOMM 1. Start Xprint servers ("Xprt") at boot time.
+XCOMM 2. Shutdown Xprint servers when the machine is being shut down.
+XCOMM 3. Query the list of available printers.
+XCOMM
+XCOMM Additional tasks are:
+XCOMM 4. Restart ('restart'|'force-reload') and conditional restart
+XCOMM ('condrestart'/'try-restart') for Linux support
+XCOMM 5. Wrapping of application call with setting XPSERVERLIST ('wrapper')
+XCOMM
+XCOMM Usage:
+XCOMM - Start Xprint server(s) manually:
+XCOMM % /etc/init.d/xprint start
+XCOMM
+XCOMM - Stop Xprint server(s) manually:
+XCOMM % /etc/init.d/xprint stop
+XCOMM
+XCOMM - Populate $XPSERVERLIST env var (for example as part of a global
+XCOMM login script like /etc/profile or per-user login scripts like
+XCOMM $HOME/.profile (sh/ksh/bash))
+XCOMM % XPSERVERLIST="`/etc/init.d/xprint get_xpserverlist`"
+XCOMM % export XPSERVERLIST
+XCOMM
+XCOMM Installation:
+XCOMM Copy this script to /etc/init.d/xprint and make sure that it is
+XCOMM executable. If your installation is LSB-compliant, then run
+XCOMM % /usr/lib/lsb/install_initd /etc/init.d/xprint
+XCOMM to start the service on startup. Otherwise, manually create links
+XCOMM to the matching run levels.
+XCOMM Examples:
+XCOMM - Solaris 2.7/2.8/2.9:
+XCOMM % cp xprint /etc/init.d/xprint
+XCOMM % chmod a+rx /etc/init.d/xprint
+XCOMM % ln /etc/init.d/xprint /etc/rc0.d/K38xprint
+XCOMM % ln /etc/init.d/xprint /etc/rc1.d/K38xprint
+XCOMM % ln /etc/init.d/xprint /etc/rc2.d/S81xprint
+XCOMM % ln /etc/init.d/xprint /etc/rcS.d/K38xprint
+XCOMM
+XCOMM - SuSE Linux 7.3
+XCOMM % cp xprint /etc/init.d/xprint
+XCOMM % chmod a+rx /etc/init.d/xprint
+XCOMM % ln -s ../xprint /etc/init.d/rc3.d/K13xprint
+XCOMM % ln -s ../xprint /etc/init.d/rc3.d/S12xprint
+XCOMM % ln -s ../xprint /etc/init.d/rc5.d/K13xprint
+XCOMM % ln -s ../xprint /etc/init.d/rc5.d/S12xprint
+XCOMM % ln -s ../xprint /etc/init.d/rc2.d/K13xprint
+XCOMM % ln -s ../xprint /etc/init.d/rc2.d/S12xprint
+XCOMM
+XCOMM - SuSE Linux 6.4:
+XCOMM % cp xprint /sbin/init.d/xprint
+XCOMM % chmod a+rx /sbin/init.d/xprint
+XCOMM % ln -s ../xprint /sbin/init.d/rc2.d/K20xprint
+XCOMM % ln -s ../xprint /sbin/init.d/rc2.d/S20xprint
+XCOMM % ln -s ../xprint /sbin/init.d/rc3.d/K20xprint
+XCOMM % ln -s ../xprint /sbin/init.d/rc3.d/S20xprint
+XCOMM
+XCOMM Notes:
+XCOMM - The Xprint servers must be started _after_ the print
+XCOMM spooler or the server(s) may refuse to start
+XCOMM - The script should be readable by all users to ensure that they
+XCOMM can use the "get_xpserverlist"-option
+XCOMM
+XCOMM Custom configuration:
+XCOMM - Edit the function setup_config() in this script to match your needs
+XCOMM
+XCOMM Known bugs/ToDo/Notes:
+XCOMM - The shell script assumes that a Xserver can be reached via
+XCOMM "hostname:displaynum" where "hostname" is obtained from
+XCOMM "/usr/bin/hostname". It may happen that a kernel firewall
+XCOMM blocks an X connection on the same host (e.g. client && Xserver
+XCOMM are running on the same host).
+XCOMM Suggested fix: Fix the firewall config.
+XCOMM Suggested workaround: Edit this script and replace the use of
+XCOMM /usr/bin/hostname with "echo 'localhost'".
+XCOMM
+XCOMM###########################################################################
+XCOMM
+
+
+XCOMM###########################################################################
+
+fatal_error()
+{
+ echo "${0}: ## FATAL ERROR: ${1}" 1>&2
+ exit 1
+}
+
+error_echo()
+{
+ echo "${0}: ## ERROR: ${1}" 1>&2
+}
+
+warning_echo()
+{
+ echo "${0}: ## WARNING: ${1}" 1>&2
+}
+
+verbose_echo()
+{
+ echo "${0}: ${1}"
+}
+
+msg()
+{
+ echo "${1}"
+}
+
+XCOMM###########################################################################
+
+#ifndef OS_LINUX
+XCOMM Force use of a POSIX conformant sh
+XCOMM (Solaris /sbin/sh is plain Bourne shell)
+[ "$1" != "posix_sh_forced" -a -x /bin/ksh ] && exec /bin/ksh "$0" posix_sh_forced "$@"
+[ "$1" != "posix_sh_forced" -a -x /bin/bash ] && exec /bin/bash --norc --noprofile "$0" posix_sh_forced "$@"
+[ "$1" != "posix_sh_forced" -a -x /usr/local/bin/ksh ] && exec /usr/local/bin/ksh "$0" posix_sh_forced "$@"
+[ "$1" != "posix_sh_forced" -a -x /usr/local/bin/bash ] && exec /usr/local/bin/bash --norc --noprofile "$0" posix_sh_forced "$@"
+if [ "$1" != "posix_sh_forced" ] ; then
+ echo "${0}: ## FATAL ERROR: No POSIX-shell found." 1>&2
+ exit 1
+fi
+
+shift # Drop "posix_sh_forced"
+#endif /* !OS_LINUX */
+
+XCOMM#debug
+XCOMM set -x
+
+XCOMM Change current dir to a location which is writeable by everyone
+cd /tmp
+
+XCOMM Clear some environment variables
+unset TEMP TMPDIR SCREENDIR
+
+XCOMM Set search path for commands
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+#ifdef OS_SOLARIS
+export PATH=/usr/xpg4/bin:${PATH}
+#endif
+
+XCOMM# Try to figure-out where X11 was installed
+#if defined(OS_SOLARIS)
+XPROJECTROOT=/usr/openwin
+export OPENWINHOME=/usr/openwin
+#elif defined(OS_AIX)
+XPROJECTROOT=/usr/lpp/X11
+#else
+#if defined(ProjectRoot)
+[ -d ProjectRoot/bin ] && XPROJECTROOT=ProjectRoot
+#endif
+[ -d /usr/X11/bin ] && XPROJECTROOT=/usr/X11
+[ -d /usr/X11R6/bin ] && XPROJECTROOT=/usr/X11R6
+#endif
+XPCUSTOMGLUE=DEF_XPCUSTOMGLUE # This is used for customizing this script
+export XPROJECTROOT XPCUSTOMGLUE
+
+if [ -z "${XPROJECTROOT}" ] ; then
+ fatal_error "Unknown XProjectRoot."
+fi
+
+XCOMM Set the location of the Xprt binary we want to use.
+XPRT_BIN="${XPROJECTROOT}/bin/Xprt"
+
+XCOMM Set the location of the global file where we store the locations
+XCOMM of the system-wide servers
+if [ -d /var/run ] ; then
+ XP_GLOBAL_SERVERS=/var/run/Xprint_servers
+else
+ XP_GLOBAL_SERVERS=/tmp/.Xprint_servers
+fi
+
+XCOMM ${LOGNAME} will not work if user su'ed into another account
+export CURRLOGNAME="$(id -u -n)"
+
+XCOMM Set location where we want to store the list of Xprint servers managed
+XCOMM by this user
+XCOMM - If we start as "root" use the global file
+XCOMM - If we start as normal user use a per-user file
+
+if [ "${CURRLOGNAME}" != "root" -a "${CURRLOGNAME}" != "" ] ; then
+ XP_PER_USER_SERVERS="/tmp/.Xprint_servers_${CURRLOGNAME}"
+ XP_SERVERS="${XP_PER_USER_SERVERS}"
+else
+ XP_SERVERS="${XP_GLOBAL_SERVERS}"
+fi
+
+XCOMM Set umask that owner can r/w all files and everyone else can read them
+umask 022
+
+XCOMM Bump limit for per-process open files to ensure that Xprt can open many many fonts
+ulimit -n 1024
+
+XCOMM###########################################################################
+
+XCOMM Get list of fonts for a given display
+get_fontlist_from_display()
+{
+ ${XPROJECTROOT}/bin/xset -display "${1}" q |
+ awk "/Font Path:/ { i=1 ; next } i==1 { print \$0 ; i=0 }" |
+ fontpath2fontlist
+}
+
+XCOMM Get list from a fontserver config
+get_fontlist_from_xfs_config()
+{
+ if [ ! -r "${1}" ] ; then
+ return 0
+ fi
+
+ (
+ cat "${1}" |
+ while read -r i ; do
+ for val in $i; do
+ case $val in
+ \#*) break ;;
+ ?*=*) key="${val%%=*}" ;;
+ =*) key="${tok}" ;;
+ *) [ "${key}" = "catalogue" -a "${tok}" != "" ] && echo "${tok}" ;;
+ esac
+ tok="${val#*=}"
+ done
+ done
+ ) | tr "," "\n" | fontpath2fontlist
+}
+
+get_fontlist_from_all_xfs_configs()
+{
+ get_fontlist_from_xfs_config "/etc/openwin/fs/fontserver.cfg"
+ get_fontlist_from_xfs_config "/usr/openwin/lib/X11/fontserver.cfg"
+ get_fontlist_from_xfs_config "/etc/X11/fs-xtt/config"
+ get_fontlist_from_xfs_config "/etc/X11/fs/config"
+ get_fontlist_from_xfs_config "/etc/X11/xfs/config"
+ get_fontlist_from_xfs_config "${XPROJECTROOT}/lib/X11/fs/config"
+}
+
+get_fontlist_from_xf86config()
+{
+ srcxconf=""
+
+ XCOMM see xorg.conf(5x) manual page for the list of locations used here
+ [ "${srcxconf}" = "" -a -f "/etc/X11/xorg.conf" ] && srcxconf="/etc/X11/xorg.conf"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf" ] && srcxconf="/usr/X11R6/etc/X11/xorg.conf"
+ [ "${srcxconf}" = "" -a -f "/etc/X11/xorg.conf-4" ] && srcxconf="/etc/X11/xorg.conf-4"
+ [ "${srcxconf}" = "" -a -f "/etc/X11/xorg.conf" ] && srcxconf="/etc/X11/xorg.conf"
+ [ "${srcxconf}" = "" -a -f "/etc/xorg.conf" ] && srcxconf="/etc/xorg.conf"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf.${hostname}" ] && srcxconf="/usr/X11R6/etc/X11/xorg.conf.${hostname}"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf-4" ] && srcxconf="/usr/X11R6/etc/X11/xorg.conf-4"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/etc/X11/xorg.conf" ] && srcxconf="/usr/X11R6/etc/X11/xorg.conf"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/lib/X11/xorg.conf.${hostname}" ] && srcxconf="/usr/X11R6/lib/X11/xorg.conf.${hostname}"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/lib/X11/xorg.conf-4" ] && srcxconf="/usr/X11R6/lib/X11/xorg.conf-4"
+ [ "${srcxconf}" = "" -a -f "/usr/X11R6/lib/X11/xorg.conf" ] && srcxconf="/usr/X11R6/lib/X11/xorg.conf"
+
+ XCOMM Xfree86 locations
+ [ "${srcxconf}" = "" -a -f "/etc/X11/XF86Config-4" ] && srcxconf="/etc/X11/XF86Config-4"
+ [ "${srcxconf}" = "" -a -f "/etc/X11/XF86Config" ] && srcxconf="/etc/X11/XF86Config"
+
+
+ if [ "${srcxconf}" = "" ] ; then
+ return 0
+ fi
+
+ currsection=""
+ cat "${srcxconf}" |
+ while read i1 i2 i3 i4 ; do
+ # Strip "\"" from I2
+ i2="${i2#\"}" ; i2="${i2%\"}"
+
+ case "${i1}" in
+ \#*)
+ continue
+ ;;
+ 'Section')
+ currsection="${i2}"
+ ;;
+ 'EndSection')
+ currsection=""
+ ;;
+ 'FontPath')
+ [ "$currsection" = "Files" ] && echo "${i2%:unscaled}"
+ ;;
+ esac
+ done | egrep -v -i "tcp/|tcp4/|tcp6/|unix/"
+
+ return 0
+}
+
+get_fontlist_from_defoma()
+{
+ # Include Debian defoma font directory where relevant
+ if [ -d "/var/lib/defoma/x-ttcidfont-conf.d/dirs" ] ; then
+ find "/var/lib/defoma/x-ttcidfont-conf.d/dirs" -name fonts.dir |
+ while read i ; do echo "${i%/fonts.dir}" ; done
+ fi
+}
+
+XCOMM Get list of system fonts
+get_system_fontlist()
+{
+#if defined(OS_SOLARIS)
+ ## List the standard X11 fonts
+ # echo "${XPROJECTROOT}/lib/X11/fonts/F3/"
+ # echo "${XPROJECTROOT}/lib/X11/fonts/F3bitmaps/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/Type1/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/Type1/outline/"
+ # We cannot use /usr/openwin/lib/X11/fonts/Type1/sun/ - see
+ # http://xprint.mozdev.org/bugs/show_bug.cgi?id=5726
+ # ("Xprint doesn't start under Solaris 2.9 due *.ps files in /usr/openwin/lib/X11/fonts/Type1/sun/fonts.dir")
+ #echo "${XPROJECTROOT}/lib/X11/fonts/Type1/sun/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/TrueType/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/Speedo/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/misc/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/75dpi/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/100dpi/"
+
+ ## List all fonts in all locales installed on this machine
+ cat /usr/openwin/lib/locale/''*/OWfontpath | tr "," "\n" | sort -u
+#elif defined(OS_LINUX)
+ (
+ get_fontlist_from_defoma
+
+ get_fontlist_from_xf86config
+
+ # Getting font paths from XFS is mainly required for compatibilty to RedHat
+ get_fontlist_from_all_xfs_configs
+
+ ## List all fonts in all locales installed on this machine
+ (
+ [ -d "/usr/share/fonts" ] && find /usr/share/fonts -name fonts.dir
+ find "${XPROJECTROOT}/lib/X11/fonts" -name fonts.dir
+ ) |
+ while read i ; do echo "${i%/fonts.dir}" ; done
+ ) | sort -u
+#else
+ ## List the standard X11 fonts
+ # (AIX should be handled like Solaris but I did not found a way to
+ # enumerate all fonts in all installed locales without scanning the
+ # dirs manually)
+ echo "${XPROJECTROOT}/lib/X11/fonts/Type1/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/TrueType/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/TTF/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/Speedo/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/misc/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/75dpi/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/100dpi/"
+ echo "${XPROJECTROOT}/lib/X11/fonts/"
+#endif
+}
+
+XCOMM Filter fonts per given extended regular expressions
+XCOMM (and make sure we filter any model-config fonts - they are managed by Xprt internally)
+filter_fontlist()
+{
+ egrep -- "${1}" | fgrep -v "/models/" | egrep -v -- "${2}"
+}
+
+XCOMM Filter font paths with unsupported font types
+XCOMM (such as CID fonts)
+filter_unsupported_fonts()
+{
+ egrep -v -i "/cid(/$|$)|/csl(/$|$)"
+}
+
+XCOMM Validate fontpath
+XCOMM Only return valid font path entries (note that these entries may
+XCOMM include non-file stuff like font server references)
+validate_fontlist()
+{
+ while read i ; do
+ case "${i}" in
+ # Check if font path entry is a font server...
+ tcp/''*|tcp4/''*|tcp6/''*|unix/''*)
+ echo "${i}"
+ ;;
+ # ... if not check if the path is accessible
+ # and has a valid "fonts.dir" index
+ *)
+ [ -f "${i}/fonts.dir" ] && echo "${i}"
+ ;;
+ esac
+ done
+}
+
+XCOMM Build a comma-seperated list of fonts (font path) from a list of fonts
+fontlist2fontpath()
+{
+ fp=""
+ read fp;
+ while read i ; do
+ fp="${fp},${i}"
+ done
+
+ echo "$fp"
+}
+
+XCOMM Build a list (one item per line) of fonts from a font path
+fontpath2fontlist()
+{
+ while read i ; do
+ echo "${i}" | tr "," "\n"
+ done
+}
+
+XCOMM Sort scaleable fonts (PS Type1 and TrueType) first in a font list
+sort_scaleable_fonts_first()
+{
+ i="$(fontlist2fontpath)"
+ # First list PS Type1 fonts...
+ echo "${i}" | fontpath2fontlist | fgrep "/Type1"
+ # ... then TrueType fonts ...
+ echo "${i}" | fontpath2fontlist | egrep -i "/TrueType|/TT(/$|$)|/TTF(/$|$)"
+ # ... then all others
+ echo "${i}" | fontpath2fontlist | egrep -v -i "/Type1|/TrueType|/TT(/$|$)|/TTF(/$|$)"
+}
+
+XCOMM Check if a X display is used by a Xserver or not
+XCOMM Known bugs:
+XCOMM - there is no way in plain bourne shell or bash (see comment about ksh93
+XCOMM below) to test if a Xserver sits only on a socket and not on a pipe
+XCOMM - some Xserver's don't cleanup their stuff in /tmp on exit which may end
+XCOMM in the problem that we don't detect possible free display numbers
+XCOMM (one problem is that only ksh93 can do stuff like
+XCOMM "cat </dev/tcp/0.0.0.0/6001")
+CheckIfDisplayIsInUse()
+{
+ id=$1
+
+ [ -r "/tmp/.X${id}-lock" ] && return 0;
+ [ -r "/tmp/.X11-unix/X${id}" ] && return 0;
+ [ -r "/tmp/.X11-pipe/X${id}" ] && return 0;
+
+ return 1;
+}
+
+lastdisplaynumreturned_store=/tmp/.Xp_last_display_returned_by_findfreexdisplaynum_${RANDOM}_${RANDOM}
+
+XCOMM Try to find a free display number
+FindFreeXDisplayNum()
+{
+ if [ -r "${lastdisplaynumreturned_store}" ] ; then
+ i="$(cat "${lastdisplaynumreturned_store}")"
+ else
+ i=32 # start at display 32
+ fi
+
+ while [ $i -lt 127 ] ; do
+ i=$(($i + 1))
+
+ if CheckIfDisplayIsInUse $i ; then
+ true
+ else
+ echo "$i"
+ echo "$i" >"${lastdisplaynumreturned_store}"
+ return 0
+ fi
+ done
+
+ # Using "magic" value of 189 here due lack of a better solution
+ echo "189"
+ echo "189" >"${lastdisplaynumreturned_store}"
+ return 0
+}
+
+XCOMM Check if a process exists or not
+pexists()
+{
+ [ "$1" = "" ] && return 1;
+
+ # Use of /proc would be better but not all platforms (like AIX) have procfs
+ [ "$(ps -p $1 | fgrep $1)" != "" ] && return 0;
+ return 1
+}
+
+XCOMM Check if there is a spooler running...
+is_spooler_running()
+{
+ # This covers Linux lpd, CUPS, Solaris and AIX 4.x - but what about
+ # AIX 5.x, HP-UX and IRIX ?
+
+ [ "$(ps -A | egrep 'lpd|lpsched|cupsd|qdaemon' | fgrep -v 'grep')" != "" ] && return 0;
+ return 1
+}
+
+XCOMM Wait until the spooler system has been started (but not more than 30secs)
+wait_for_print_spooler()
+{
+ for i in 1 2 3 4 5 6 7 8 9 10 ; do
+ is_spooler_running && return 0;
+ sleep 3
+ done
+
+ return 0
+}
+
+lock_server_registry()
+{
+ lock_counter=0 # counts in 1/100s
+ waiting_for_lock_msg_send="false"
+ while ! mkdir "${XP_SERVERS}.lock" 2>/dev/null ; do
+ # print notice after 2 seconds
+ if [ ${lock_counter} -gt 200 -a "${waiting_for_lock_msg_send}" != "true" ] ; then
+ echo "${0}: waiting for lock(=${XP_SERVERS}.lock)..."
+ waiting_for_lock_msg_send="true"
+ fi
+
+ # tread the lock as "broken" after 20 seconds
+ if [ ${lock_counter} -gt 2000 ] ; then
+ echo "${0}: WARNING: lock timeout for lock(=${XP_SERVERS}.lock)."
+ return 0
+ fi
+
+ if [ -x /bin/usleep ] ; then
+ /bin/usleep 200000
+ lock_counter=$((${lock_counter} + 20)) # 20/100s
+ else
+ sleep 1
+ lock_counter=$((${lock_counter} + 100)) # 100/100s
+ fi
+ done
+}
+
+unlock_server_registry()
+{
+ rmdir "${XP_SERVERS}.lock"
+}
+
+XCOMM Kill dead registry locks (silently!)
+kill_dead_registry_locks()
+{
+ rm -Rf "${XP_SERVERS}.lock"
+}
+
+XCOMM Start Xprint servers
+start_servers()
+{
+ # Write registry "intro" ...
+ lock_server_registry
+ echo "# Xprint server list" >>"${XP_SERVERS}"
+ echo "# File is for private use for ${0}." >>"${XP_SERVERS}"
+ echo "# Do not edit, rely on the content or file format." >>"${XP_SERVERS}"
+ unlock_server_registry
+
+ hostname="$(hostname)"
+
+ default_fontpath="$(get_system_fontlist | fontlist2fontpath)"
+ default_fontpath_acceptpattern=".*";
+ default_fontpath_rejectpattern="_No_Match_"; # Match nothing
+
+ curr=0
+ while [ $curr -lt $num_xpstart ] ; do
+ if [ "${xpstart_remote_server[$curr]}" != "" ] ; then
+ # Remote Xprt, just put the entry into the registry
+ lock_server_registry
+ echo "display=${xpstart_remote_server[$curr]}" >>"${XP_SERVERS}"
+ unlock_server_registry
+ else
+ # Run block in seperate process to avoid that changes to the
+ # xpstart_* variables affect the next cycle
+ (
+ # Use defaults if there are no special options
+ [ "${xpstart_fontpath[$curr]}" = "" ] && xpstart_fontpath[$curr]="${default_fontpath}";
+ [ "${xpstart_fontpath_acceptpattern[$curr]}" = "" ] && xpstart_fontpath_acceptpattern[$curr]="$default_fontpath_acceptpattern";
+ [ "${xpstart_fontpath_rejectpattern[$curr]}" = "" ] && xpstart_fontpath_rejectpattern[$curr]="$default_fontpath_rejectpattern";
+ [ "${xpstart_displayid[$curr]}" = "" ] && xpstart_displayid[$curr]="$(FindFreeXDisplayNum)"
+ [ "${xpstart_logger[$curr]}" = "" ] && xpstart_logger[$curr]="logger -p lpr.notice -t Xprt_${xpstart_displayid[$curr]}";
+ [ "${xpstart_logfile[$curr]}" = "" ] && xpstart_logfile[$curr]="/dev/null";
+ [ "${xpstart_xprt_binary[$curr]}" = "" ] && xpstart_xprt_binary[$curr]="${XPRT_BIN}";
+ if [ "${xpstart_xprt_binary[$curr]}" = "/usr/openwin/bin/Xprt" -o "$(uname -s)" = "SunOS" ] ; then
+ # Solaris /usr/openwin/bin/Xprt does not support "-nolisten tcp"
+ # yet nor is it possible to run a Xserver on a unix socket only
+ # in Solaris since access to the unix domain sockets in
+ # /tmp/.X11-pipe and /tmp/.X11-unix is restricted to applications
+ # with group-id "root" (e.g. the Xprt server would need to be
+ # setgid "root" that plain users can start it listening on a unix
+ # socket only)
+ [ "${xpstart_options[$curr]}" = "" ] && xpstart_options[$curr]="-ac -pn"
+ else
+ [ "${xpstart_options[$curr]}" = "" ] && xpstart_options[$curr]="-ac -pn -nolisten tcp"
+ fi
+
+ # Check if the Xprt binary is available
+ if [ ! -x "${xpstart_xprt_binary[$curr]}" ] ; then
+ error_echo "Can't find \"${xpstart_xprt_binary[$curr]}\"."
+ exit 1 # exit block
+ fi
+
+ # Verify and set location of font encodings directory file
+ if [ "${xpstart_font_encodings_dir[$curr]}" = "" ] ; then
+ if [ -f "${XPROJECTROOT}/lib/X11/fonts/xf86encodings/encodings.dir" ] ; then
+ xpstart_font_encodings_dir[$curr]="${XPROJECTROOT}/lib/X11/fonts/xf86encodings/encodings.dir"
+ else
+ xpstart_font_encodings_dir[$curr]="${XPROJECTROOT}/lib/X11/fonts/encodings/encodings.dir";
+ fi
+ fi
+
+ unset FONT_ENCODINGS_DIRECTORY
+ if [ ! -f "${xpstart_font_encodings_dir[$curr]}" ] ; then
+ warning_echo "Can't find \"${xpstart_font_encodings_dir[$curr]}\", TrueType font support may not work."
+ fi
+
+ export FONT_ENCODINGS_DIRECTORY="${xpstart_font_encodings_dir[$curr]}"
+
+ # Generate font path (containing only valid font path elements)
+ # from input font path and filter expressions
+ curr_fp=$(echo "${xpstart_fontpath[$curr]}" |
+ fontpath2fontlist |
+ filter_fontlist "${xpstart_fontpath_acceptpattern[$curr]}" "${xpstart_fontpath_rejectpattern[$curr]}" |
+ filter_unsupported_fonts |
+ sort_scaleable_fonts_first |
+ validate_fontlist |
+ fontlist2fontpath)
+
+ # Set Xserver auditing level option
+ unset curr_audit
+ if [ "${xpstart_auditlevel[$curr]}" != "" ] ; then
+ curr_audit="-audit ${xpstart_auditlevel[$curr]}"
+ fi
+
+ # Set Xprt -XpFile option
+ unset curr_xpfile
+ if [ "${xpstart_xpfile[$curr]}" != "" ] ; then
+ curr_xpfile="-XpFile ${xpstart_xpfile[$curr]}"
+ fi
+
+ # Set custom XPCONFIGDIR (if there is one)
+ unset XPCONFIGDIR
+ if [ "${xpstart_xpconfigdir[$curr]}" != "" ] ; then
+ export XPCONFIGDIR="${xpstart_xpconfigdir[$curr]}"
+ fi
+
+ # If someone uses "-nolisten tcp" make sure we do not add a hostname to force local transport
+ if [ "$(echo "${xpstart_options[$curr]}" | egrep "nolisten.*tcp")" != "" ] ; then
+ xp_display=":${xpstart_displayid[$curr]}"
+ else
+ xp_display="${hostname}:${xpstart_displayid[$curr]}"
+ fi
+
+ (
+ (
+ "${xpstart_xprt_binary[$curr]}" \
+ ${xpstart_options[$curr]} \
+ ${curr_xpfile} ${curr_audit} \
+ -fp ${curr_fp} \
+ :${xpstart_displayid[$curr]} &
+ server_pid="$!"
+
+ # Append the new server to the registry
+ lock_server_registry
+ echo "display=${xp_display} display_id=${xpstart_displayid[$curr]} pid=${server_pid}" >>"${XP_SERVERS}"
+ unlock_server_registry
+
+ wait
+ echo "Xprint server pid=${server_pid} done, exitcode=$?."
+
+ # Remove the dead server from the registry
+ # (only if the registry still exists - if /etc/init.d/xprint stop" gets called the registry
+ # will be removed - and we should not re-create it afterwards...)
+ lock_server_registry
+ if [ -f "${XP_SERVERS}" ] ; then
+ x="$(cat "${XP_SERVERS}")" # Store content of file "${XP_SERVERS}" in var "x"
+ echo "${x}" | fgrep -v "display_id=${xpstart_displayid[$curr]} pid=${server_pid}" >"${XP_SERVERS}"
+ fi
+ unlock_server_registry
+ ) 2>&1 | while read i ; do echo "$i" | tee -a "${xpstart_logfile[$curr]}" | ${xpstart_logger[$curr]} ; done
+ ) &
+ )
+ fi
+
+ curr=$(($curr + 1))
+ done
+
+ # Remove tmp. file created by |FindFreeXDisplayNum()|
+ rm -f "${lastdisplaynumreturned_store}"
+
+ # Done.
+ lock_server_registry
+ echo "# EOF." >>"${XP_SERVERS}"
+ unlock_server_registry
+ return 0
+}
+
+
+XCOMM Convenience function to check setup and start Xprt server(s)
+do_start()
+{
+ if [ -f "${XP_SERVERS}" ] ; then
+ numservers="$(do_get_xpserverlist | wc -l)"
+ if [ ${numservers} -gt 0 ] ; then
+ verbose_echo "Xprint servers are already running."
+ return 0
+ else
+ verbose_echo "Old server registry found, cleaning-up..."
+ do_stop
+ fi
+ fi
+
+ # Check if we can write the registry file
+ touch "${XP_SERVERS}" 2>/dev/null
+ if [ ! -f "${XP_SERVERS}" ] ; then
+ error_echo "Cannot create \"${XP_SERVERS}\"."
+ # exit code 4 = user had insufficient privilege (LSB)
+ exit 4
+ fi
+
+ if ! setup_config ; then
+ error_echo "setup_config failed."
+ exit 1
+ fi
+
+ # Provide two paths here - one which simply starts the Xprt servers,
+ # assuming that there is a print spooler already running (or that
+ # ${XPCONFIG}/C/print/Xprinters provides static print queue entries
+ # (like for the PSspooldir print model)) and a 2nd path which
+ # explicitly checks if the print queue daemons are running
+ if true ; then
+ msg "Starting Xprint servers: Xprt."
+ start_servers
+ else
+ # Continue in the background if there is no spooler running yet (that
+ # we don't hold off the boot process nor run in a possible race-condition
+ # when /etc/init.d/lpd was not called yet but the runlevel script waits
+ # for us to finish first ...
+ if is_spooler_running ; then
+ msg "Starting Xprint servers: Xprt."
+ start_servers
+ else
+ msg "Starting Xprint servers (in the background): Xprt."
+ (wait_for_print_spooler ; start_servers) &
+ sleep 5
+ fi
+ fi
+
+ if [ "${CURRLOGNAME}" = "root" -a -d /var/lock/subsys/ ] ; then
+ touch /var/lock/subsys/xprint
+ fi
+}
+
+XCOMM Convenience function to stop Xprt server(s)
+do_stop()
+{
+ msg "Stopping Xprint servers: Xprt."
+
+ lock_server_registry
+ if [ -f "${XP_SERVERS}" ] ; then
+ reglist="$(cat "${XP_SERVERS}")"
+ rm -f "${XP_SERVERS}"
+ fi
+ unlock_server_registry
+
+ if [ "${reglist}" != "" ] ; then
+ echo "${reglist}" |
+ grep "^display=.*:.* pid=[0-9]*$" |
+ while read i ; do
+ (
+ eval ${i}
+ if pexists ${pid} ; then
+ kill ${pid}
+ fi
+
+ # Remove the X sockets/pipes which are not in use anymore
+ # (It would be better if the Xservers would cleanup this
+ # automatically, but most Xservers do not do that... ;-(
+ # Note that this will not work on Solaris where applications
+ # must run with groupid="root" if they want to write into
+ # /tmp/.X11-unix/ and/or /tmp/.X11-pipe/)
+ if [ "${display_id}" != "" ] ; then
+ rm -f "/tmp/.X${display_id}-lock" 2>/dev/null
+ rm -f "/tmp/.X11-unix/X${display_id}" 2>/dev/null
+ rm -f "/tmp/.X11-pipe/X${display_id}" 2>/dev/null
+ fi
+ )
+ done
+ fi
+
+ if [ "${CURRLOGNAME}" = "root" -a -d /var/lock/subsys/ ] ; then
+ rm -f /var/lock/subsys/xprint
+ fi
+
+ # Remove any outstanding (dead) locks and cleanup
+ rm -f "${XP_SERVERS}"
+ kill_dead_registry_locks
+}
+
+XCOMM Convenience function to obtain a list of available Xprint servers
+do_get_xpserverlist()
+{
+ if [ -f "${XP_PER_USER_SERVERS}" -o -f "${XP_GLOBAL_SERVERS}" ] ; then
+ xpserverlist=$(
+ # Enumerate both per-user and global servers (in that order)
+ (
+ [ -f "${XP_PER_USER_SERVERS}" ] && cat "${XP_PER_USER_SERVERS}"
+ [ -f "${XP_GLOBAL_SERVERS}" ] && cat "${XP_GLOBAL_SERVERS}"
+ ) |
+ egrep "^display=.*:.* pid=[0-9]*$|^display=.*:[0-9]*$" |
+ while read i ; do
+ (
+ pid="none"
+ eval ${i}
+ # Check if the Xprt process exists (if possible)
+ if [ "$pid" != "none" ] ; then
+ if pexists ${pid} ; then
+ echo ${display}
+ fi
+ else
+ echo ${display}
+ fi
+ )
+ done | tr "\n" " "
+ )
+ # Only produce output if we have some entries...
+ [ "${xpserverlist}" != "" ] && echo "${xpserverlist}"
+ fi
+}
+
+do_restart()
+{
+ msg "Restarting Xprint server(s): Xprt."
+ do_stop
+ sleep 1
+ do_start
+}
+
+do_diag()
+{
+ echo "##### Diag start $(date)."
+
+ # General info
+ echo "## General info start."
+ (
+ echo "PATH=\"${PATH}\""
+ echo "TZ=\"${TZ}\""
+ echo "LANG=\"${LANG}\""
+ echo "uname -a=\"$(uname -a)\""
+ echo "uname -s=\"$(uname -s)\""
+ echo "uname -p=\"$(uname -p)\""
+ echo "uname -i=\"$(uname -i)\""
+ echo "uname -m=\"$(uname -m)\""
+ echo "has /etc/SuSE-release ... $([ -f "/etc/SuSE-release" ] && echo "yes" || echo "no")"
+ echo "has /etc/redhat-release ... $([ -f "/etc/redhat-release" ] && echo "yes" || echo "no")"
+ echo "has /etc/debian_version ... $([ -f "/etc/debian_version" ] && echo "yes" || echo "no")"
+ echo "how many Xprt servers are running ...$(ps -ef | fgrep Xprt | fgrep -v "grep" | wc -l)"
+ ) 2>&1 | while read i ; do echo " $i" ; done
+ echo "## General info end."
+
+ # Testing font paths
+ echo "## Testing font paths start."
+ (
+ get_system_fontlist |
+ filter_unsupported_fonts |
+ sort_scaleable_fonts_first |
+ validate_fontlist | while read d ; do
+ echo "#### Testing \"${d}\" ..."
+ if [ ! -d "$d" ] ; then
+ echo "# Error: $d does not exists."
+ continue
+ fi
+ if [ ! -r "$d" ] ; then
+ echo "# Error: $d not readable."
+ continue
+ fi
+ if [ ! -f "${d}/fonts.dir" ] ; then
+ echo "# Error: ${d}/fonts.dir not found."
+ continue
+ else
+ if [ ! -r "${d}/fonts.dir" ] ; then
+ echo "# Error: ${d}/fonts.dir not readable."
+ continue
+ fi
+ fi
+ if [ -f "${d}/fonts.alias" ] ; then
+ if [ ! -r "${d}/fonts.alias" ] ; then
+ echo "# Error: ${d}/fonts.alias not readable."
+ fi
+ fi
+
+ if [ "$(cat "${d}/fonts.dir" | fgrep 'cursor')" != "" ] ; then
+ echo "${d}/fonts.dir has cursor font."
+ fi
+ if [ "$(cat "${d}/fonts.dir" | fgrep 'fixed')" != "" ] ; then
+ echo "${d}/fonts.dir has fixed font."
+ fi
+
+ if [ -r "${d}/fonts.alias" ] ; then
+ if [ "$(cat "${d}/fonts.alias" | fgrep 'cursor')" != "" ] ; then
+ echo "${d}/fonts.alias has cursor font."
+ fi
+ if [ "$(cat "${d}/fonts.alias" | fgrep 'fixed')" != "" ] ; then
+ echo "${d}/fonts.alias has fixed font."
+ fi
+ fi
+
+ linenum=0
+ cat "${d}/fonts.dir" | while read i1 i2 i3 i4 ; do
+ linenum=$((${linenum} + 1))
+ [ ${linenum} -eq 1 ] && continue
+
+ if [ ! -f "${d}/${i1}" ] ; then
+ echo "ERROR: ${d}/fonts.dir line ${linenum} has non-exististant font \"${i1}\" (=\"${i1} ${i2} ${i3} ${i4}\")"
+ fi
+ done
+ done
+ ) 2>&1 | while read i ; do echo " $i" ; done
+ echo "## Testing font paths end."
+
+ echo "##### Diag End $(date)."
+}
+
+XCOMM Set platform-defaults for setup_config()
+setup_config_defaults()
+{
+ curr_num_xpstart="${1}"
+
+ #### Defaults for Linux/Solaris
+ # Start Xprt using builtin XPCONFIGDIR at a free display numer
+ # (Solaris(=SunOS5.x)'s /usr/openwin/bin/Xprt supports TrueType fonts,
+ # therefore we don't need to filter them)
+ xpstart_fontpath[${curr_num_xpstart}]="";
+ xpstart_fontpath_acceptpattern[${curr_num_xpstart}]=".*";
+ xpstart_fontpath_rejectpattern[${curr_num_xpstart}]="/Speedo|/F3bitmaps|/F3";
+ xpstart_displayid[${curr_num_xpstart}]="";
+ xpstart_xpconfigdir[${curr_num_xpstart}]="";
+ xpstart_xpfile[${curr_num_xpstart}]="";
+ xpstart_auditlevel[${curr_num_xpstart}]="4";
+ xpstart_options[${curr_num_xpstart}]="";
+ xpstart_logger[${curr_num_xpstart}]="";
+ # Check whether we have /dev/stderr (needed for old AIX + old Debian)
+ if [ -w "/dev/stderr" ] ; then
+ xpstart_logfile[${curr_num_xpstart}]="/dev/stderr";
+ else
+ xpstart_logfile[${curr_num_xpstart}]="/dev/tty";
+ fi
+ xpstart_xprt_binary[${curr_num_xpstart}]="";
+
+ # Custom rules for the GISWxprintglue package on Solaris
+ # (which uses Solaris's /usr/openwin/bin/Xprt but a custom config)
+ if [ "${XPCUSTOMGLUE}" = "GISWxprintglue" ] ; then
+ xpstart_xpconfigdir[${curr_num_xpstart}]="/opt/GISWxprintglue/server/etc/XpConfig"
+ xpstart_xprt_binary[${curr_num_xpstart}]="/usr/openwin/bin/Xprt"
+ fi
+ # Custom rules for the GISWxprint package on Solaris
+ # (which uses both it's own Xprt and a custom config)
+ if [ "${XPCUSTOMGLUE}" = "GISWxprint" ] ; then
+ xpstart_xpconfigdir[${curr_num_xpstart}]="/opt/GISWxprint/server/etc/XpConfig"
+ xpstart_xprt_binary[${curr_num_xpstart}]="/opt/GISWxprint/bin/Xprt"
+ xpstart_font_encodings_dir[${curr_num_xpstart}]="/opt/GISWxprint/lib/X11/fonts/encodings/encodings.dir"
+ fi
+
+ #######################################################
+ ###
+ ### Debian Xprint package default configuration
+ ###
+ if [ "${XPCUSTOMGLUE}" = "DebianGlue" ] ; then
+ # Set XPCONFIGDIR=/usr/share/Xprint/xserver
+ xpstart_xpconfigdir[${curr_num_xpstart}]="/usr/share/Xprint/xserver";
+
+ # Use fixed display ID (":64"), or else all client programs will have to be
+ # restarted simply to update XPSERVERLIST to the latest ID when upgrading,
+ # which would be a nightmare.
+ xpstart_displayid[${curr_num_xpstart}]=64;
+
+ # Do not send any messages to console
+ xpstart_logfile[${curr_num_xpstart}]="/dev/null";
+
+ # By default use binary provided by Debian's "xprt-xprintorg" package
+ # (=/usr/bin/Xprt), otherwise leave blank (e.g. use script's default
+ # (=/usr/X11R6/bin/Xprt))
+ if [ -x "/usr/bin/Xprt" ] ; then
+ xpstart_xprt_binary[${curr_num_xpstart}]="/usr/bin/Xprt";
+ fi
+ fi
+ ###
+ ### End Debian default configuration
+ ###
+ #######################################################
+}
+
+fetch_etc_initd_xprint_envvars()
+{
+ curr_num_xpstart="${1}"
+
+ ## Process some $ETC_INITD_XPRINT_* vars after all which may be used by
+ # a user to override the hardcoded values here when starting Xprt per-user
+ # (a more flexible way is to provide an own setup config script in
+ # "~./Xprint_per_user_startup" - see above)
+ if [ "${ETC_INITD_XPRINT_XPRT_PATH}" != "" ] ; then
+ xpstart_xprt_binary[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPRT_PATH}"
+ fi
+ if [ "${ETC_INITD_XPRINT_XPCONFIGDIR}" != "" ] ; then
+ xpstart_xpconfigdir[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPCONFIGDIR}"
+ fi
+ if [ "${ETC_INITD_XPRINT_XPFILE}" != "" ] ; then
+ xpstart_xpfile[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPFILE}"
+ fi
+ if [ "${ETC_INITD_XPRINT_LOGFILE}" != "" ] ; then
+ xpstart_logfile[${curr_num_xpstart}]="${ETC_INITD_XPRINT_LOGFILE}"
+ fi
+ if [ "${ETC_INITD_XPRINT_DISPLAYID}" != "" ] ; then
+ xpstart_displayid[${curr_num_xpstart}]="${ETC_INITD_XPRINT_DISPLAYID}"
+ fi
+ if [ "${ETC_INITD_XPRINT_FONTPATH}" != "" ] ; then
+ xpstart_fontpath[${curr_num_xpstart}]="${ETC_INITD_XPRINT_FONTPATH}"
+ fi
+ if [ "${ETC_INITD_XPRINT_XPRT_OPTIONS}" != "" ] ; then
+ xpstart_options[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XPRT_OPTIONS}"
+ fi
+ if [ "${ETC_INITD_XPRINT_AUDITLEVEL}" != "" ] ; then
+ xpstart_auditlevel[${curr_num_xpstart}]="${ETC_INITD_XPRINT_AUDITLEVEL}"
+ fi
+ if [ "${ETC_INITD_XPRINT_XF86ENCODINGSDIR}" != "" ] ; then
+ xpstart_font_encodings_dir[${curr_num_xpstart}]="${ETC_INITD_XPRINT_XF86ENCODINGSDIR}"
+ fi
+}
+
+XCOMM###########################################################################
+XCOMM setup_config() sets the configuration parameters used to start one
+XCOMM or more Xprint servers ("Xprt").
+XCOMM The following variables are used:
+XCOMM - "num_xpstart" - number of servers to start
+XCOMM - "xpstart_fontpath[index]" - custom font path. Leave blank if you want
+XCOMM the platform-specific default
+XCOMM - "xpstart_fontpath_acceptpattern[index]" - extended regular expression
+XCOMM (see egrep(1)) used to filter the font path - items only pass this
+XCOMM filter if they match the pattern (leave blank if you want to filter
+XCOMM nothing)
+XCOMM - "xpstart_fontpath_rejectpattern[index]" - extended regular expression
+XCOMM (see egrep(1)) used to filter the font path - items only pass this
+XCOMM filter if they do not match the pattern (leave blank if you want to
+XCOMM filter nothing)
+XCOMM - "xpstart_font_encodings_dir[index]" - location of "encodings.dir".
+XCOMM Leave blank to use the default.
+XCOMM - "xpstart_displayid[index]" - display id to use for the Xprint server
+XCOMM (leave blank to choose the next available free display id)
+XCOMM - "xpstart_xpconfigdir[index]" - value for custom XPCONFIGDIR (leave blank
+XCOMM if you don not want that that XPCONFIGDIR is set at Xprt startup)
+XCOMM - "xpstart_xpfile[index]" - value used for Xprt's "-XpFile" option (leave
+XCOMM blank if you do not want to set this option)
+XCOMM - "xpstart_auditlevel[index]" - set Xserver auditing level (leave blank to
+XCOMM use no auditing)
+XCOMM - "xpstart_options[index]" - set further Xprt options (leave blank to set
+XCOMM no further options)
+XCOMM - "xpstart_logger[index]" - utility which gets stderr/stdout messages from
+XCOMM Xprt and sends them to a logging daemon. Leave blank to use /usr/bin/logger
+XCOMM to send such messages to the lpr.notice syslog)
+XCOMM - "xpstart_logfile[index]" - log file to append stderr/stdout messages from
+XCOMM Xprt to. Leave blank to send messages to /dev/null
+XCOMM - "xpstart_xprt_binary[index]" - set custom Xprt binary (leave blank to use
+XCOMM the platform-specifc default)
+setup_config()
+{
+ num_xpstart=0;
+
+ if [ "${ETC_INITD_XPRINT_CUSTOM_SETUP_CONFIG}" != "" ] ; then
+ user_cfg="${ETC_INITD_XPRINT_CUSTOM_SETUP_CONFIG}"
+ else
+ user_cfg="${HOME}/.Xprint_per_user_startup"
+ fi
+
+ # Source per-user ~/.Xprint_per_user_startup file if there is one
+ # (and do not use the script's defaults below)
+ if [ -r "${user_cfg}" ] ; then
+ # Define API version which should be checked by ${HOME}/.Xprint_per_user_startup
+ # ${HOME}/.Xprint_per_user_startup should bail-out if the version differ
+ etc_initd_xprint_api_version=2
+
+ # Source per-user settings script
+ . "${user_cfg}"
+
+ # done with setting the config for per-user Xprt instances
+ return 0;
+ else
+ # Use /etc/init.d/xprint's builtin config
+ # Each entry should start with |setup_config_defaults| to pull the
+ # platform defaults and finish with |num_xpstart=$(($num_xpstart + 1))|
+ # to end the entry
+
+ # Set platform-defaults
+ setup_config_defaults "${num_xpstart}"
+
+ ## -- snip --
+
+ # Admins can put their stuff "in" here...
+
+ ## -- snip --
+
+ # Override script's builtin values with those a user may set via the
+ # $ETC_INIITD_XPRINT_* env vars
+ fetch_etc_initd_xprint_envvars "${num_xpstart}"
+
+ num_xpstart=$((${num_xpstart} + 1))
+
+ return 0;
+ fi
+
+ #### Sample 1:
+ # # Start Xprt on a free display ID with custom XPCONFIGDIR and without
+ # # Speedo and TrueType fonts
+ # xpstart_fontpath_rejectpattern[$num_xpstart]="/Speedo|/TrueType|/TT(/$|$)|/TTF(/$|$)";
+ # xpstart_xpconfigdir[$num_xpstart]="/home/gisburn/cwork/Xprint/Xprt_config/XpConfig";
+ # xpstart_auditlevel[$num_xpstart]="4";
+ # xpstart_options[$num_xpstart]="-ac -pn";
+ #num_xpstart=$(($num_xpstart + 1))
+
+
+ #### Sample 2:
+ # # Start Xprt without TrueType fonts on a display 55 with custom
+ # # XPCONFIGDIR
+ # xpstart_fontpath_rejectpattern[$num_xpstart]="/TrueType|/TT(/$|$)|/TTF(/$|$)";
+ # xpstart_displayid[$num_xpstart]=55;
+ # xpstart_xpconfigdir[$num_xpstart]="/home/gisburn/cwork/Xprint/Xprt_config/XpConfig";
+ # xpstart_auditlevel[$num_xpstart]=4;
+ # xpstart_options[$num_xpstart]="-ac -pn";
+ #num_xpstart=$(($num_xpstart + 1))
+
+ #### Sample 3:
+ # # Start Xprt without TrueType fonts on a display 56 with custom
+ # # XPCONFIGDIR and alternate "Xprinters" file
+ # xpstart_fontpath_rejectpattern[$num_xpstart]="/TrueType|/TT(/$|$)|/TTF(/$|$)";
+ # xpstart_displayid[$num_xpstart]=56;
+ # xpstart_xpconfigdir[$num_xpstart]="/etc/XpConfig/default";
+ # xpstart_xpfile[$num_xpstart]="/etc/XpConfig/default/Xprinters_test2"
+ # xpstart_auditlevel[$num_xpstart]="4";
+ # xpstart_options[$num_xpstart]="-ac -pn";
+ # xpstart_xprt_binary[$num_xpstart]="";
+ #num_xpstart=$(($num_xpstart + 1))
+
+ #### Sample 4:
+ # # Start Xprt with Solaris ISO-8859-7 (greek(="el") locale) fonts on
+ # # display 57
+ # xpstart_fontpath[$num_xpstart]="/usr/openwin/lib/locale/iso_8859_7/X11/fonts/75dpi,/usr/openwin/lib/locale/iso_8859_7/X11/fonts/Type1,/usr/openwin/lib/X11/fonts/misc/";
+ # xpstart_fontpath_acceptpattern[$num_xpstart]="";
+ # xpstart_fontpath_rejectpattern[$num_xpstart]="_No_Match_";
+ # xpstart_displayid[$num_xpstart]="57";
+ # xpstart_auditlevel[$num_xpstart]="4";
+ # xpstart_options[$num_xpstart]="-ac -pn";
+ #num_xpstart=$(($num_xpstart + 1))
+
+ #### Sample 5:
+ # # Start Xprt with the font list of an existing Xserver (excluding Speedo fonts) on
+ # # display 58
+ # # Note that this only works within a X session. At system boot time
+ # # there will be no $DISPLAY to fetch the information from!!
+ # xpstart_fontpath[$num_xpstart]="$(get_fontlist_from_display ${DISPLAY} | fontlist2fontpath)";
+ # xpstart_fontpath_acceptpattern[$num_xpstart]="";
+ # xpstart_fontpath_rejectpattern[$num_xpstart]="";
+ # xpstart_displayid[$num_xpstart]="58";
+ # xpstart_xpconfigdir[$num_xpstart]="";
+ # xpstart_auditlevel[$num_xpstart]="4";
+ # xpstart_options[$num_xpstart]="-ac -pn";
+ # xpstart_xprt_binary[$num_xpstart]="";
+ #num_xpstart=$(($num_xpstart + 1))
+
+ #### Sample 6:
+ # # List remote Xprt's here
+ # # (note that there is no test to check whether these DISPLAYs are valid!)
+ # xpstart_remote_server[$num_xpstart]="sera:12" ; num_xpstart=$(($num_xpstart + 1))
+ # xpstart_remote_server[$num_xpstart]="gandalf:19" ; num_xpstart=$(($num_xpstart + 1))
+}
+
+XCOMM###########################################################################
+
+XCOMM Main
+case "$1" in
+ ## Start Xprint servers
+ 'start')
+ do_start
+ ;;
+
+ ## Stop Xprint servers
+ # Note that this does _not_ kill Xprt instances started using this script
+ # by non-root users
+ 'stop')
+ do_stop
+ ;;
+
+ ## Restart Xprint servers
+ 'restart'|'force-reload')
+ do_restart
+ ;;
+
+ ## Reload configuration without stopping and restarting
+ 'reload')
+ # not supported
+ msg "reload not supported, use 'restart' or 'force-reload'"
+ exit 3
+ ;;
+
+ ## Restart Xprint only if it is already running
+ 'condrestart'|'try-restart')
+ # only restart if it is already running
+ [ -f /var/lock/subsys/xprint ] && do_restart || :
+ ;;
+
+ ## Get list of all Xprint servers for this user
+ # (incl. per-user and system-wide instances)
+ 'get_xpserverlist')
+ do_get_xpserverlist
+ ;;
+
+ ## Get status of Xprint servers, RedHat-style
+ 'status')
+ x="$(do_get_xpserverlist)"
+ if [ "${x}" != "" ] ; then
+ msg "Xprint (${x}) is running..."
+ exit 0
+ else
+ msg "Xprint is stopped"
+ exit 3
+ fi
+ ;;
+
+ ## Wrapper
+ 'wrapper')
+ cmd="${2}"
+ [ "${cmd}" = "" ] && fatal_error "No command given."
+ shift ; shift
+ export XPSERVERLIST="$(do_get_xpserverlist)"
+ [ "${XPSERVERLIST}" = "" ] && fatal_error "No Xprint servers found."
+ exec "${cmd}" "$@"
+ ;;
+
+ ## Wrapper for "xplsprinters"
+ 'lsprinters')
+ [ "${ETC_INITD_XPRINT_XPLSPRINTERS_PATH}" != "" ] && cmd="${ETC_INITD_XPRINT_XPLSPRINTERS_PATH}"
+ [ "${cmd}" = "" -a "${XPCUSTOMGLUE}" = "GISWxprintglue" ] && cmd="/opt/GISWxprintglue/bin/xplsprinters"
+ [ "${cmd}" = "" -a "${XPCUSTOMGLUE}" = "GISWxprint" ] && cmd="/opt/GISWxprint/bin/xplsprinters"
+ [ "${cmd}" = "" -a "${XPROJECTROOT}" != "" ] && cmd="${XPROJECTROOT}/bin/xplsprinters"
+ [ "${cmd}" = "" ] && cmd="xplsprinters"
+
+ shift
+ export XPSERVERLIST="$(do_get_xpserverlist)"
+ [ "${XPSERVERLIST}" = "" ] && fatal_error "No Xprint servers found."
+ exec "${cmd}" "$@"
+ ;;
+
+ ## Diagnostics
+ 'diag')
+ do_diag
+ ;;
+
+ ## Print usage
+ *)
+ msg "Usage: $0 { start | stop | restart | reload | force-reload | status | condrestart | try-restart | wrapper | lsprinters | get_xpserverlist | diag }"
+ exit 2
+esac
+exit 0
+
+XCOMM EOF.
diff --git a/hw/xprint/etc/profile.d/Makefile.am b/hw/xprint/etc/profile.d/Makefile.am
new file mode 100644
index 000000000..b91a9115a
--- /dev/null
+++ b/hw/xprint/etc/profile.d/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = xprint.csh xprint.sh
diff --git a/hw/xprint/etc/profile.d/xprint.csh b/hw/xprint/etc/profile.d/xprint.csh
new file mode 100644
index 000000000..7cc675840
--- /dev/null
+++ b/hw/xprint/etc/profile.d/xprint.csh
@@ -0,0 +1,16 @@
+#
+# /etc/profile.d/xprint.csh
+#
+# Copyright (c) 2002-2004 by Roland Mainz <roland.mainz@nrubsig.org>
+# please send bugfixes or comments to http://xprint.mozdev.org/
+
+
+#
+# Obtain list of Xprint servers
+#
+
+if ( -f /etc/init.d/xprint ) then
+ setenv XPSERVERLIST "`/bin/sh /etc/init.d/xprint get_xpserverlist`"
+endif
+
+# /etc/profile.d/xprint.csh ends here.
diff --git a/hw/xprint/etc/profile.d/xprint.sh b/hw/xprint/etc/profile.d/xprint.sh
new file mode 100644
index 000000000..b5b46c1e7
--- /dev/null
+++ b/hw/xprint/etc/profile.d/xprint.sh
@@ -0,0 +1,16 @@
+#
+# /etc/profile.d/xprint.sh
+#
+# Copyright (c) 2002-2004 by Roland Mainz <roland.mainz@nrubsig.org>
+# please send bugfixes or comments to http://xprint.mozdev.org/
+
+#
+# Obtain list of Xprint servers
+#
+
+if [ -f "/etc/init.d/xprint" ] ; then
+ XPSERVERLIST="`/bin/sh /etc/init.d/xprint get_xpserverlist`"
+ export XPSERVERLIST
+fi
+
+# /etc/profile.d/xprint.sh ends here.
diff --git a/hw/xprint/mediaSizes.c b/hw/xprint/mediaSizes.c
new file mode 100644
index 000000000..7f582199d
--- /dev/null
+++ b/hw/xprint/mediaSizes.c
@@ -0,0 +1,783 @@
+/* $Xorg: mediaSizes.c,v 1.4 2001/03/14 18:44:37 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: mediaSizes.c
+** *
+** * Contents:
+** * Routines to return the sizes associated
+** * with particular media and particular printers.
+** *
+** * Created: 2/19/96
+** *
+** * Copyright: Copyright 1993,1995 Hewlett-Packard Company
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <locale.h>
+
+#include <X11/X.h>
+#include "dixstruct.h"
+#include "screenint.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include <X11/fonts/fontstruct.h>
+
+#include "DiPrint.h"
+#include "attributes.h"
+
+typedef struct {
+ XpOid page_size;
+ float width;
+ float height;
+} PageDimensionsRec;
+
+static PageDimensionsRec PageDimensions[] =
+{
+ {xpoid_val_medium_size_na_letter, 215.9, 279.4},
+ {xpoid_val_medium_size_na_legal, 215.9, 355.6},
+ {xpoid_val_medium_size_executive, 184.15, 266.7},
+ {xpoid_val_medium_size_folio, 210.82, 330.2},
+ {xpoid_val_medium_size_invoice, 139.7, 215.9},
+ {xpoid_val_medium_size_ledger, 279.4, 431.8},
+ {xpoid_val_medium_size_quarto, 215.9, 275.082},
+ {xpoid_val_medium_size_a, 215.9, 279.4},
+ {xpoid_val_medium_size_b, 279.4, 431.8},
+ {xpoid_val_medium_size_c, 431.8, 558.8},
+ {xpoid_val_medium_size_d, 558.8, 863.6},
+ {xpoid_val_medium_size_e, 863.6, 1117.6},
+ {xpoid_val_medium_size_na_6x9_envelope, 152.4, 228.6},
+ {xpoid_val_medium_size_na_10x15_envelope, 254, 381},
+ {xpoid_val_medium_size_monarch_envelope, 98.298, 190.5},
+ {xpoid_val_medium_size_na_10x13_envelope, 254, 330.2},
+ {xpoid_val_medium_size_na_9x12_envelope, 228.6, 304.8},
+ {xpoid_val_medium_size_na_number_10_envelope, 104.775, 241.3},
+ {xpoid_val_medium_size_na_7x9_envelope, 177.8, 228.6},
+ {xpoid_val_medium_size_na_9x11_envelope, 228.6, 279.4},
+ {xpoid_val_medium_size_na_10x14_envelope, 254, 355.6},
+ {xpoid_val_medium_size_na_number_9_envelope, 98.425, 225.425},
+ {xpoid_val_medium_size_iso_a0, 841, 1189},
+ {xpoid_val_medium_size_iso_a1, 594, 841},
+ {xpoid_val_medium_size_iso_a2, 420, 594},
+ {xpoid_val_medium_size_iso_a3, 297, 420},
+ {xpoid_val_medium_size_iso_a4, 210, 297},
+ {xpoid_val_medium_size_iso_a5, 148, 210},
+ {xpoid_val_medium_size_iso_a6, 105, 148},
+ {xpoid_val_medium_size_iso_a7, 74, 105},
+ {xpoid_val_medium_size_iso_a8, 52, 74},
+ {xpoid_val_medium_size_iso_a9, 37, 52},
+ {xpoid_val_medium_size_iso_a10, 26, 37},
+ {xpoid_val_medium_size_iso_b0, 1000, 1414},
+ {xpoid_val_medium_size_iso_b1, 707, 1000},
+ {xpoid_val_medium_size_iso_b2, 500, 707},
+ {xpoid_val_medium_size_iso_b3, 353, 500},
+ {xpoid_val_medium_size_iso_b4, 250, 353},
+ {xpoid_val_medium_size_iso_b5, 176, 250},
+ {xpoid_val_medium_size_iso_b6, 125, 176},
+ {xpoid_val_medium_size_iso_b7, 88, 125},
+ {xpoid_val_medium_size_iso_b8, 62, 88},
+ {xpoid_val_medium_size_iso_b9, 44, 62},
+ {xpoid_val_medium_size_iso_b10, 31, 44},
+ {xpoid_val_medium_size_jis_b0, 1030, 1456},
+ {xpoid_val_medium_size_jis_b1, 728, 1030},
+ {xpoid_val_medium_size_jis_b2, 515, 728},
+ {xpoid_val_medium_size_jis_b3, 364, 515},
+ {xpoid_val_medium_size_jis_b4, 257, 364},
+ {xpoid_val_medium_size_jis_b5, 182, 257},
+ {xpoid_val_medium_size_jis_b6, 128, 182},
+ {xpoid_val_medium_size_jis_b7, 91, 128},
+ {xpoid_val_medium_size_jis_b8, 64, 91},
+ {xpoid_val_medium_size_jis_b9, 45, 64},
+ {xpoid_val_medium_size_jis_b10, 32, 45},
+ {xpoid_val_medium_size_hp_2x_postcard, 148, 200},
+ {xpoid_val_medium_size_hp_european_edp, 304.8, 355.6},
+ {xpoid_val_medium_size_hp_mini, 139.7, 215.9},
+ {xpoid_val_medium_size_hp_postcard, 100, 148},
+ {xpoid_val_medium_size_hp_tabloid, 279.4, 431.8},
+ {xpoid_val_medium_size_hp_us_edp, 279.4, 355.6},
+ {xpoid_val_medium_size_hp_us_government_legal, 203.2, 330.2},
+ {xpoid_val_medium_size_hp_us_government_letter, 203.2, 254},
+ {xpoid_val_medium_size_iso_c3, 324, 458},
+ {xpoid_val_medium_size_iso_c4, 229, 324},
+ {xpoid_val_medium_size_iso_c5, 162, 229},
+ {xpoid_val_medium_size_iso_c6, 114, 162},
+ {xpoid_val_medium_size_iso_designated_long, 110, 220}
+};
+
+/*
+ * XpGetResolution returns an integer representing the printer resolution
+ * in dots-per-inch for the specified print context.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+int
+XpGetResolution(
+ XpContextPtr pContext)
+{
+ unsigned long resolution;
+
+ resolution = XpGetCardAttr(pContext, XPPageAttr,
+ xpoid_att_default_printer_resolution,
+ (XpOidCardList*)NULL);
+ if(0 == resolution)
+ resolution = XpGetCardAttr(pContext, XPDocAttr,
+ xpoid_att_default_printer_resolution,
+ (XpOidCardList*)NULL);
+ if(0 == resolution)
+ {
+ XpOidCardList* resolutions_supported;
+ /*
+ * default-printer-resolution not specified; default to 1st entry
+ * in printer-resolutions-supported.
+ */
+ resolutions_supported =
+ XpGetCardListAttr(pContext, XPPrinterAttr,
+ xpoid_att_printer_resolutions_supported,
+ (XpOidCardList*)NULL);
+ resolution = XpOidCardListGetCard(resolutions_supported, 0);
+ XpOidCardListDelete(resolutions_supported);
+ }
+ return (int)resolution;
+}
+
+/*
+ * XpGetContentOrientation determines the content-orientation as
+ * determined by the passed context. The page and document pools are
+ * queried in turn for a specified content-orientation attribute. If none
+ * is found the first content-orientation in the
+ * content-orientations-supported printer attribute is taken as the
+ * default.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+XpOid
+XpGetContentOrientation(
+ XpContextPtr pContext)
+{
+ XpOid orientation;
+
+ orientation = XpGetOidAttr(pContext, XPPageAttr,
+ xpoid_att_content_orientation,
+ (XpOidList*)NULL);
+ if(xpoid_none == orientation)
+ orientation = XpGetOidAttr(pContext, XPDocAttr,
+ xpoid_att_content_orientation,
+ (XpOidList*)NULL);
+ if(xpoid_none == orientation)
+ {
+ XpOidList* content_orientations_supported;
+
+ content_orientations_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_content_orientations_supported,
+ (XpOidList*)NULL);
+ orientation = XpOidListGetOid(content_orientations_supported, 0);
+ XpOidListDelete(content_orientations_supported);
+ }
+ return orientation;
+}
+
+/*
+ * XpGetAvailableCompression determines the available-compression as
+ * determined by the passed context. The page and document pools are
+ * queried in turn for a specified content-orientation attribute. If none
+ * is found the first available-compression in the
+ * avaiable-compressions-supported printer attribute is taken as the
+ * default.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+XpOid
+XpGetAvailableCompression(
+ XpContextPtr pContext)
+{
+ XpOid compression;
+
+ compression = XpGetOidAttr(pContext, XPPageAttr,
+ xpoid_att_available_compression,
+ (XpOidList*)NULL);
+ if(xpoid_none == compression)
+ compression = XpGetOidAttr(pContext, XPDocAttr,
+ xpoid_att_available_compression,
+ (XpOidList*)NULL);
+ if(xpoid_none == compression)
+ {
+ XpOidList* available_compressions_supported;
+
+ available_compressions_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_available_compressions_supported,
+ (XpOidList*)NULL);
+ compression = XpOidListGetOid(available_compressions_supported, 0);
+ XpOidListDelete(available_compressions_supported);
+ }
+ return compression;
+}
+
+/*
+ * XpGetPlex determines the plex as determined by the passed context. The page
+ * and document pools are queried in turn for a specified plex attribute. If
+ * none is found the first plex in the plexes-supported printer attribute is
+ * taken as the default.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+XpOid
+XpGetPlex(
+ XpContextPtr pContext)
+{
+ XpOid plex;
+
+ plex = XpGetOidAttr(pContext, XPPageAttr, xpoid_att_plex,
+ (XpOidList*)NULL);
+ if(xpoid_none == plex)
+ plex = XpGetOidAttr(pContext, XPDocAttr, xpoid_att_plex,
+ (XpOidList*)NULL);
+ if(xpoid_none == plex)
+ {
+ XpOidList* plexes_supported;
+
+ plexes_supported =
+ XpGetListAttr(pContext, XPPrinterAttr,
+ xpoid_att_plexes_supported,
+ (XpOidList*)NULL);
+ plex = XpOidListGetOid(plexes_supported, 0);
+ XpOidListDelete(plexes_supported);
+ }
+ return plex;
+}
+
+/*
+ * XpGetPageSize returns the XpOid of the current page size (medium names
+ * are page sizes in this implementation) as indicated by the passed
+ * context.
+ *
+ * The relevant input-tray is returned in pTray. This parm must not be
+ * NULL. If the input-tray is not indicated or irrelevant, xpoid_none
+ * will be returned.
+ *
+ * This function optionally takes a XpOidMediumSS representation of the
+ * medium-source-sizes-supported attribute in order to avoid parsing the
+ * string value twice for calling functions that need to parse m-s-s-s
+ * anyway (e.g. XpGetReproductionArea). If the caller has no other reason
+ * to parse medium-source-sizes-supported, it is recommended that NULL be
+ * passed. This function will obtain medium-source-sizes-supported if it
+ * needs to.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+XpOid
+XpGetPageSize(XpContextPtr pContext,
+ XpOid* pTray,
+ const XpOidMediumSS* msss)
+{
+ XpOid medium;
+ /*
+ * check to see if default-medium is specified
+ */
+ medium = XpGetOidAttr(pContext, XPPageAttr, xpoid_att_default_medium,
+ (const XpOidList*)NULL);
+ if(medium == xpoid_none)
+ {
+ /*
+ * default-medium not in page pool; try the document pool
+ */
+ medium = XpGetOidAttr(pContext, XPDocAttr, xpoid_att_default_medium,
+ (const XpOidList*)NULL);
+ }
+ if(medium == xpoid_none)
+ {
+ /*
+ * default-medium not specified; try default-input-tray
+ */
+ *pTray = XpGetOidAttr(pContext, XPPageAttr,
+ xpoid_att_default_input_tray,
+ (const XpOidList*)NULL);
+ if(*pTray == xpoid_none)
+ {
+ /*
+ * default-input-tray not in page pool; try the document pool
+ */
+ *pTray = XpGetOidAttr(pContext, XPDocAttr,
+ xpoid_att_default_input_tray,
+ (const XpOidList*)NULL);
+ }
+ if(*pTray != xpoid_none)
+ {
+ /*
+ * default-input-tray found; get corresponding medium from
+ * input-trays-medium
+ */
+ XpOidTrayMediumList* input_trays_medium;
+ int i;
+
+ input_trays_medium =
+ XpGetTrayMediumListAttr(pContext, XPPrinterAttr,
+ xpoid_att_input_trays_medium,
+ (const XpOidList*)NULL,
+ (const XpOidMediumSS*)NULL);
+ for(i = 0; i < XpOidTrayMediumListCount(input_trays_medium); i++)
+ {
+ if(*pTray == XpOidTrayMediumListTray(input_trays_medium, i))
+ {
+ medium = XpOidTrayMediumListMedium(input_trays_medium, i);
+ break;
+ }
+ }
+ XpOidTrayMediumListDelete(input_trays_medium);
+ }
+ }
+ else
+ *pTray = xpoid_none;
+
+ if(medium == xpoid_none)
+ {
+ XpOidMediumSS* local_msss = (XpOidMediumSS*)NULL;
+ int i_mss, i_ds;
+ XpOidMediumDiscreteSizeList* ds_list;
+ /*
+ * no medium specified; use 1st page size found in
+ * medium-source-sizes-supported
+ */
+ if((XpOidMediumSS*)NULL == msss)
+ msss = local_msss =
+ XpGetMediumSSAttr(pContext, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported,
+ (const XpOidList*)NULL,
+ (const XpOidList*)NULL);
+ for(i_mss = 0;
+ i_mss < XpOidMediumSSCount(msss) && xpoid_none == medium;
+ i_mss++)
+ {
+ if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag
+ &&
+ xpoid_none != (msss->mss)[i_mss].input_tray)
+ {
+ ds_list = (msss->mss)[i_mss].ms.discrete;
+ for(i_ds = 0; i_ds < ds_list->count; i_ds++)
+ {
+ if(xpoid_none != (ds_list->list)[i_ds].page_size)
+ {
+ medium = (ds_list->list)[i_ds].page_size;
+ break;
+ }
+ }
+ }
+ }
+ XpOidMediumSSDelete(local_msss);
+ }
+ return medium;
+}
+
+/*
+ * XpGetMediumMillimeters returns into the supplied float pointers the
+ * width and height in millimeters of the passed page size identifier.
+ */
+void
+XpGetMediumMillimeters(
+ XpOid page_size,
+ float *width, /* return */
+ float *height) /* return */
+{
+ int i;
+
+ *width = *height = 0;
+ for(i = 0; i < XpNumber(PageDimensions); i++)
+ {
+ if(page_size == PageDimensions[i].page_size)
+ {
+ *width = PageDimensions[i].width;
+ *height = PageDimensions[i].height;
+ return;
+ }
+ }
+}
+
+/*
+ * Converts a millimeter specification into pixels given a resolution in
+ * DPI.
+ */
+static float
+MmToPixels(float mm, int resolution)
+{
+ float f;
+
+ f = mm * resolution;
+ f /= 25.4;
+ return f;
+}
+
+/*
+ * XpGetMediumDimensions returns into the supplied short pointers the
+ * width and height in pixels of the medium associated with the specified
+ * print context. It obtains the page size associated with the current
+ * medium by calling XpGetPageSize. It passes XpGetMediumMillimeters the
+ * page size, and converts the returned millimeter dimensions into pixels
+ * using the resolution returned by XpGetResolution.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+void
+XpGetMediumDimensions(
+ XpContextPtr pContext,
+ unsigned short *width, /* return */
+ unsigned short *height) /* return */
+{
+ XpOid page_size;
+ XpOid tray;
+ XpOid orientation;
+
+ int resolution;
+ float w_mm, h_mm;
+
+ page_size = XpGetPageSize(pContext, &tray, (XpOidMediumSS*)NULL);
+ if(page_size == xpoid_none)
+ {
+ /*
+ * fail-safe: if the pools have been validated, this defaulting logic
+ * isn't needed.
+ */
+ page_size = xpoid_val_medium_size_na_letter;
+ }
+ XpGetMediumMillimeters(page_size, &w_mm, &h_mm);
+ resolution = XpGetResolution(pContext);
+ orientation = XpGetContentOrientation(pContext);
+ switch(orientation)
+ {
+ case xpoid_val_content_orientation_landscape:
+ case xpoid_val_content_orientation_reverse_landscape:
+ /*
+ * transpose width and height
+ */
+ *height = MmToPixels(w_mm, resolution);
+ *width = MmToPixels(h_mm, resolution);
+ break;
+
+ default:
+ *width = MmToPixels(w_mm, resolution);
+ *height = MmToPixels(h_mm, resolution);
+ break;
+ }
+}
+
+/*
+ * XRectangleFromXpOidArea converts an XpOidArea area specification
+ * into an XRectangle. The passed resolution is used to convert from
+ * millimeters (XpOidArea) into pixels (XRectangle).
+ */
+static void
+XRectangleFromXpOidArea(
+ xRectangle *pRect,
+ const XpOidArea* repro,
+ int resolution,
+ XpOid orientation)
+{
+ switch(orientation)
+ {
+ case xpoid_val_content_orientation_landscape:
+ case xpoid_val_content_orientation_reverse_landscape:
+ /*
+ * transpose x and y, width and height
+ */
+ pRect->y = MmToPixels(repro->minimum_x, resolution);
+ pRect->x = MmToPixels(repro->minimum_y, resolution);
+ pRect->height =
+ MmToPixels(repro->maximum_x - repro->minimum_x, resolution);
+ pRect->width =
+ MmToPixels(repro->maximum_y - repro->minimum_y, resolution);
+ break;
+
+ default:
+ pRect->x = MmToPixels(repro->minimum_x, resolution);
+ pRect->y = MmToPixels(repro->minimum_y, resolution);
+ pRect->width =
+ MmToPixels(repro->maximum_x - repro->minimum_x, resolution);
+ pRect->height =
+ MmToPixels(repro->maximum_y - repro->minimum_y, resolution);
+ break;
+ }
+}
+
+/*
+ * XpGetReproductionArea queries the current pool attribute values in
+ * order to determine the reproduction area for the currently selected
+ * medium.
+ *
+ * First the current page size (equivalent to current medium) and tray
+ * (if specified) is retrieved via XpGetPageSize. The value of the
+ * medium-source-sizes-supported attribute is interrogated until a matching
+ * entry for the current page size and tray is found. The reproduction
+ * area defined for the current entry is converted into an XRectangle
+ * using XRectangleFromXpOidArea and returned to the caller.
+ *
+ * Note: This routine assumes the values found in the passed context's
+ * attributes pools have been validated.
+ */
+void
+XpGetReproductionArea(XpContextPtr pContext,
+ xRectangle *pRect)
+{
+ XpOid page_size;
+ XpOid tray;
+ XpOidMediumSS* msss;
+ int i_mss, i_ds;
+ XpOidMediumDiscreteSizeList* ds_list;
+ XpOidArea* repro;
+ BOOL done;
+ int resolution;
+ XpOid orientation;
+ /*
+ * find the appropriate assured reproduction area for the current
+ * tray and page size in the medium-source-sizes-supported attribute.
+ */
+ msss = XpGetMediumSSAttr(pContext, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported,
+ (const XpOidList*)NULL,
+ (const XpOidList*)NULL);
+ page_size = XpGetPageSize(pContext, &tray, msss);
+ resolution = XpGetResolution(pContext);
+ orientation = XpGetContentOrientation(pContext);
+
+ memset(pRect, 0, sizeof(xRectangle));
+
+ if(xpoid_none == tray)
+ {
+ /*
+ * no tray specified; use 1st matching page size
+ */
+ for(i_mss = 0, done = xFalse;
+ i_mss < XpOidMediumSSCount(msss) && !done;
+ i_mss++)
+ {
+ if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag
+ &&
+ xpoid_none != (msss->mss)[i_mss].input_tray)
+ {
+ ds_list = (msss->mss)[i_mss].ms.discrete;
+ for(i_ds = 0; i_ds < ds_list->count; i_ds++)
+ {
+ if(page_size == (ds_list->list)[i_ds].page_size)
+ {
+ repro =
+ &(ds_list->list)[i_ds].assured_reproduction_area;
+ XRectangleFromXpOidArea(pRect, repro,
+ resolution, orientation);
+ done = xTrue;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * tray && page size specified; find matching entry
+ */
+ for(i_mss = 0, done = xFalse;
+ i_mss < XpOidMediumSSCount(msss) && !done;
+ i_mss++)
+ {
+ if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag
+ &&
+ xpoid_none != (msss->mss)[i_mss].input_tray
+ &&
+ (tray == (msss->mss)[i_mss].input_tray
+ ||
+ xpoid_unspecified == (msss->mss)[i_mss].input_tray)
+ )
+ {
+ ds_list = (msss->mss)[i_mss].ms.discrete;
+ for(i_ds = 0; i_ds < ds_list->count; i_ds++)
+ {
+ if(page_size == (ds_list->list)[i_ds].page_size)
+ {
+ repro =
+ &(ds_list->list)[i_ds].assured_reproduction_area;
+ XRectangleFromXpOidArea(pRect, repro,
+ resolution, orientation);
+ if(xpoid_unspecified != (msss->mss)[i_mss].input_tray)
+ {
+ /*
+ * exact match on tray takes precendence over
+ * unspecified tray entry in m-s-s-s
+ */
+ done = xTrue;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ XpOidMediumSSDelete(msss);
+}
+
+/*
+ * XpGetMaxWidthHeightRes returns into the supplied width and height
+ * unsigned short pointers the dimensions in millimeters of the largest
+ * supported media for a specific printer. It looks at the
+ * medium-source-sizes-supported attribute (if it exists) to determine
+ * the list of possible media, and calls XpGetMediumMillimeters to get the
+ * dimensions for each medium. If the m-s-s-s attribute is not defined,
+ * then the dimensions for the na-letter medium is returned.
+ *
+ * This function also returns the largest resolution in DPI defined in
+ * printer-resolutions-supported. If printer-resolutions-supported is not
+ * specified, the default is obtained from the passed XpValidatePoolsRec.
+ *
+ * The passed XpValidatePoolsRec is also used to determine valid values
+ * when parsing attribute values.
+ */
+void
+XpGetMaxWidthHeightRes(
+ const char *printer_name,
+ const XpValidatePoolsRec* vpr,
+ float *width,
+ float *height,
+ int* resolution)
+{
+ const char* value;
+ const char* attr_str;
+ XpOidMediumSS* pool_msss;
+ const XpOidMediumSS* msss;
+ int i_mss, i_ds;
+ XpOidMediumDiscreteSizeList* ds_list;
+ float w, h;
+ XpOidCardList* pool_resolutions_supported;
+ const XpOidCardList* resolutions_supported;
+ int i;
+ int res;
+ /*
+ * get the max medium width and height
+ */
+ attr_str = XpOidString(xpoid_att_medium_source_sizes_supported);
+ value = XpGetPrinterAttribute(printer_name, attr_str);
+ pool_msss = XpOidMediumSSNew(value,
+ vpr->valid_input_trays,
+ vpr->valid_medium_sizes);
+ if(0 == XpOidMediumSSCount(pool_msss))
+ msss = XpGetDefaultMediumSS();
+ else
+ msss = pool_msss;
+ *width = *height = 0;
+ for(i_mss = 0; i_mss < XpOidMediumSSCount(msss); i_mss++)
+ {
+ if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag
+ &&
+ xpoid_none != (msss->mss)[i_mss].input_tray)
+ {
+ ds_list = (msss->mss)[i_mss].ms.discrete;
+ for(i_ds = 0; i_ds < ds_list->count; i_ds++)
+ {
+ if(xpoid_none != (ds_list->list)[i_ds].page_size)
+ {
+ XpGetMediumMillimeters((ds_list->list)[i_ds].page_size,
+ &w, &h);
+ if(w > *width) *width = w;
+ if(h > *height) *height = h;
+ }
+ }
+ }
+ }
+ XpOidMediumSSDelete(pool_msss);
+ /*
+ * get the maximum resolution
+ */
+ attr_str = XpOidString(xpoid_att_printer_resolutions_supported);
+ value = XpGetPrinterAttribute(printer_name, attr_str);
+ pool_resolutions_supported =
+ XpOidCardListNew(value, vpr->valid_printer_resolutions_supported);
+ if(0 == XpOidCardListCount(pool_resolutions_supported))
+ resolutions_supported = vpr->default_printer_resolutions_supported;
+ else
+ resolutions_supported = pool_resolutions_supported;
+ *resolution = 0;
+ for(i = 0; i < XpOidCardListCount(resolutions_supported); i++)
+ {
+ res = XpOidCardListGetCard(resolutions_supported, i);
+ if(res > *resolution) *resolution = res;
+ }
+ XpOidCardListDelete(pool_resolutions_supported);
+}
+
+FontResolutionPtr
+XpGetClientResolutions(client, num)
+ ClientPtr client;
+ int *num;
+{
+ static struct _FontResolution res;
+ int resolution = XpGetResolution(XpContextOfClient(client));
+
+ res.x_resolution = resolution;
+ res.y_resolution = resolution;
+
+ res.point_size = 120;
+
+ *num = 1;
+
+ return &res;
+}
+
+
+void XpSetFontResFunc(client)
+ ClientPtr client;
+{
+ client->fontResFunc = XpGetClientResolutions;
+}
+
+
+void XpUnsetFontResFunc(client)
+ ClientPtr client;
+{
+ client->fontResFunc = NULL;
+}
diff --git a/hw/xprint/pcl-mono/Makefile.am b/hw/xprint/pcl-mono/Makefile.am
new file mode 100644
index 000000000..4d8dfc682
--- /dev/null
+++ b/hw/xprint/pcl-mono/Makefile.am
@@ -0,0 +1,5 @@
+noinst_LTLIBRARIES = libpcl.la
+
+PCL_DRIVER = -DXP_PCL_MONO
+
+include ../pcl/Makefile.am.inc
diff --git a/hw/xprint/pcl/Makefile.am b/hw/xprint/pcl/Makefile.am
new file mode 100644
index 000000000..90133e8e2
--- /dev/null
+++ b/hw/xprint/pcl/Makefile.am
@@ -0,0 +1,6 @@
+noinst_LTLIBRARIES = libpcl.la
+
+PCL_DRIVER = -DXP_PCL_COLOR
+
+include ../pcl/Makefile.am.inc
+
diff --git a/hw/xprint/pcl/Makefile.am.inc b/hw/xprint/pcl/Makefile.am.inc
new file mode 100644
index 000000000..38a784e13
--- /dev/null
+++ b/hw/xprint/pcl/Makefile.am.inc
@@ -0,0 +1,28 @@
+INCLUDES = -I$(top_srcdir)/hw/xprint
+
+AM_CFLAGS = @SERVER_DEFINES@ @DIX_CFLAGS@ @XPRINT_CFLAGS@ \
+ -D_XP_PRINT_SERVER_ -DPSZ=8 $(PCL_DRIVER)
+
+libpcl_la_SOURCES = \
+ $(srcdir)/../pcl/PclArc.c \
+ $(srcdir)/../pcl/PclArea.c \
+ $(srcdir)/../pcl/PclAttr.c \
+ $(srcdir)/../pcl/PclAttVal.c \
+ $(srcdir)/../pcl/PclColor.c \
+ $(srcdir)/../pcl/PclCursor.c \
+ $(srcdir)/../pcl/PclDef.h \
+ $(srcdir)/../pcl/PclFonts.c \
+ $(srcdir)/../pcl/PclGC.c \
+ $(srcdir)/../pcl/Pcl.h \
+ $(srcdir)/../pcl/PclInit.c \
+ $(srcdir)/../pcl/PclLine.c \
+ $(srcdir)/../pcl/Pclmap.h \
+ $(srcdir)/../pcl/PclMisc.c \
+ $(srcdir)/../pcl/PclPixel.c \
+ $(srcdir)/../pcl/PclPolygon.c \
+ $(srcdir)/../pcl/PclPrint.c \
+ $(srcdir)/../pcl/PclSFonts.c \
+ $(srcdir)/../pcl/PclSFonts.h \
+ $(srcdir)/../pcl/PclSpans.c \
+ $(srcdir)/../pcl/PclText.c \
+ $(srcdir)/../pcl/PclWindow.c
diff --git a/hw/xprint/pcl/Pcl.h b/hw/xprint/pcl/Pcl.h
new file mode 100644
index 000000000..bb1f52b2c
--- /dev/null
+++ b/hw/xprint/pcl/Pcl.h
@@ -0,0 +1,625 @@
+/* $Xorg: Pcl.h,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: Pcl.h
+** *
+** * Contents: defines and includes for the Pcl driver
+** * for a printing X server.
+** *
+** * Created: 1/30/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/Pcl.h,v 1.12 2001/12/21 21:02:05 dawes Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PCL_H_
+#define _PCL_H_
+
+#include <stdio.h>
+#include "scrnintstr.h"
+
+#include "PclDef.h"
+#include "Pclmap.h"
+#include "PclSFonts.h"
+
+#include <X11/extensions/Print.h>
+#include <X11/extensions/Printstr.h>
+
+#include "regionstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+
+/*
+ * Some sleazes to force the XrmDB stuff into the server
+ */
+#ifndef HAVE_XPointer
+typedef char *XPointer;
+#endif
+#define Status int
+#define True 1
+#define False 0
+#include "misc.h"
+#include <X11/Xfuncproto.h>
+#include <X11/Xresource.h>
+#include "attributes.h"
+
+/******
+ * externally visible variables from PclInit.c
+ ******/
+extern int PclScreenPrivateIndex, PclWindowPrivateIndex;
+extern int PclContextPrivateIndex;
+extern int PclPixmapPrivateIndex;
+extern int PclGCPrivateIndex;
+
+/******
+ * externally visible variables from PclAttVal.c
+ ******/
+extern XpValidatePoolsRec PclValidatePoolsRec;
+
+/*
+ * This structure defines a mapping from an X colormap ID to a list of
+ * print contexts which use the colormap.
+ */
+typedef struct _pclcontextlist {
+ XpContextPtr context;
+ struct _pclcontextlist *next;
+} PclContextList, *PclContextListPtr;
+
+typedef struct _pclcmaptocontexts {
+ long colormapId;
+ PclContextListPtr contexts;
+ struct _pclcmaptocontexts *next;
+} PclCmapToContexts;
+
+typedef struct {
+ PclCmapToContexts *colormaps;
+ CloseScreenProcPtr CloseScreen;
+} PclScreenPrivRec, *PclScreenPrivPtr;
+
+/*
+ * This structure defines a mapping from an X colormap ID to a PCL
+ * palette ID.
+ */
+typedef struct _palettemap {
+ long colormapId;
+ int paletteId;
+ int downloaded;
+ struct _palettemap *next;
+} PclPaletteMap, *PclPaletteMapPtr;
+
+typedef struct {
+ char *jobFileName;
+ FILE *pJobFile;
+ char *pageFileName;
+ FILE *pPageFile;
+ GC lastGC;
+ unsigned char *dash;
+ int validGC;
+ ClientPtr getDocClient;
+ int getDocBufSize;
+ PclSoftFontInfoPtr pSoftFontInfo;
+ PclPaletteMapPtr palettes;
+ int currentPalette;
+ int nextPaletteId;
+ PclPaletteMap staticGrayPalette;
+ PclPaletteMap trueColorPalette;
+ PclPaletteMap specialTrueColorPalette;
+ unsigned char *ctbl;
+ int ctbldim;
+ int isRaw;
+#ifdef XP_PCL_LJ3
+ unsigned int fcount;
+ unsigned int fcount_max;
+ char *figures;
+#endif /* XP_PCL_LJ3 */
+} PclContextPrivRec, *PclContextPrivPtr;
+
+typedef struct {
+ int validContext;
+ XpContextPtr context;
+} PclWindowPrivRec, *PclWindowPrivPtr;
+
+typedef struct {
+ unsigned long stippleFg, stippleBg;
+} PclGCPrivRec, *PclGCPrivPtr;
+
+typedef struct {
+ XpContextPtr context;
+ char *tempFileName;
+ FILE *tempFile;
+ GC lastGC;
+ int validGC;
+} PclPixmapPrivRec, *PclPixmapPrivPtr;
+
+/******
+ * Defined functions
+ ******/
+#define SEND_PCL(f,c) fwrite( c, sizeof( char ), strlen( c ), f )
+#define SEND_PCL_COUNT(f,c,n) fwrite( c, sizeof( char ), n, f )
+
+#ifndef XP_PCL_LJ3
+#define SAVE_PCL(f,p,c) SEND_PCL(f,c)
+#define SAVE_PCL_COUNT(f,p,c,n) SEND_PCL_COUNT(f,c,n)
+#define MACRO_START(f,p) SEND_PCL(f, "\033&f1Y\033&f0X")
+#define MACRO_END(f) SEND_PCL(f, "\033&f1X")
+#else
+#define SAVE_PCL(f,p,c) PclSpoolFigs(p, c, strlen(c))
+#define SAVE_PCL_COUNT(f,p,c,n) PclSpoolFigs(p, c, n)
+#define MACRO_START(f,p) p->fcount = 0
+#define MACRO_END(f) /* do nothing */
+#endif /* XP_PCL_LJ3 */
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/******
+ * Functions in PclArc.c
+ ******/
+extern void PclPolyArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs);
+extern void PclPolyFillArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs);
+
+/******
+ * Functions in PclArea.c
+ ******/
+extern void PclPutImage(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage);
+extern RegionPtr PclCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty);
+RegionPtr PclCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long plane);
+
+
+/******
+ * Functions in PclAttr.c
+ ******/
+extern char *PclGetAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool );
+extern char *PclGetOneAttribute(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attr );
+extern int PclAugmentAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attrs );
+extern int PclSetAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attrs );
+
+/******
+ * Functions in PclColor.c
+ ******/
+extern Bool PclCreateDefColormap(ScreenPtr pScreen);
+extern Bool PclCreateColormap(ColormapPtr pColor);
+extern void PclDestroyColormap(ColormapPtr pColor);
+extern void PclInstallColormap(ColormapPtr pColor);
+extern void PclUninstallColormap(ColormapPtr pColor);
+extern int PclListInstalledColormaps(ScreenPtr pScreen,
+ XID *pCmapList);
+extern void PclStoreColors(ColormapPtr pColor,
+ int ndef,
+ xColorItem *pdefs);
+extern void PclResolveColor(unsigned short *pRed,
+ unsigned short *pGreen,
+ unsigned short *pBlue,
+ VisualPtr pVisual);
+extern int PclUpdateColormap(DrawablePtr pDrawable,
+ XpContextPtr pCon,
+ GCPtr gc,
+ FILE *outFile);
+extern void PclLookUp(ColormapPtr cmap,
+ PclContextPrivPtr cPriv,
+ unsigned short *r,
+ unsigned short *g,
+ unsigned short *b);
+extern PclPaletteMapPtr PclFindPaletteMap(PclContextPrivPtr cPriv,
+ ColormapPtr cmap,
+ GCPtr gc);
+extern unsigned char *PclReadMap(char *, int *);
+
+
+/******
+ * Functions in PclCursor.c
+ ******/
+extern void PclConstrainCursor(
+ ScreenPtr pScreen,
+ BoxPtr pBox);
+extern void PclCursorLimits(
+ ScreenPtr pScreen,
+ CursorPtr pCursor,
+ BoxPtr pHotBox,
+ BoxPtr pTopLeftbox);
+extern Bool PclDisplayCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor);
+extern Bool PclRealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor);
+extern Bool PclUnrealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor);
+extern void PclRecolorCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor,
+ Bool displayed);
+extern Bool PclSetCursorPosition(
+ ScreenPtr pScreen,
+ int x,
+ int y,
+ Bool generateEvent);
+
+/******
+ * Functions in PclSFonts.c
+ ******/
+extern void
+PclDownloadSoftFont8(
+ FILE *fp,
+ PclSoftFontInfoPtr pSoftFontInfo,
+ PclFontHead8Ptr pfh,
+ PclCharDataPtr pcd,
+ unsigned char *code);
+extern void PclDownloadSoftFont16(
+ FILE *fp,
+ PclSoftFontInfoPtr pSoftFontInfo,
+ PclFontHead16Ptr pfh,
+ PclCharDataPtr pcd,
+ unsigned char row,
+ unsigned char col);
+extern PclSoftFontInfoPtr PclCreateSoftFontInfo(void);
+extern void PclDestroySoftFontInfo(
+ PclSoftFontInfoPtr pSoftFontInfo );
+
+/******
+ * Functions in PclGC.c
+ ******/
+extern Bool PclCreateGC(GCPtr pGC);
+extern void PclDestroyGC(GCPtr pGC);
+extern int PclUpdateDrawableGC(
+ GCPtr pGC,
+ DrawablePtr pDrawable,
+ FILE **outFile);
+extern void PclValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable);
+extern void PclSetDrawablePrivateStuff(
+ DrawablePtr pDrawable,
+ GC gc );
+extern int PclGetDrawablePrivateStuff(
+ DrawablePtr pDrawable,
+ GC *gc,
+ unsigned long *valid,
+ FILE **file );
+extern void PclSetDrawablePrivateGC(
+ DrawablePtr pDrawable,
+ GC gc);
+extern void PclComputeCompositeClip(
+ GCPtr pGC,
+ DrawablePtr pDrawable);
+
+/******
+ * Functions in PclInit.c
+ ******/
+extern Bool PclCloseScreen(
+ int index,
+ ScreenPtr pScreen);
+extern Bool InitializeColorPclDriver(
+ int ndx,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv);
+extern Bool InitializeMonoPclDriver(
+ int ndx,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv);
+extern Bool InitializeLj3PclDriver(
+ int ndx,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv);
+extern XpContextPtr PclGetContextFromWindow( WindowPtr win );
+
+/******
+ * Functions in PclLine.c
+ ******/
+extern void PclPolyLine(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nPoints,
+ xPoint *pPoints);
+extern void PclPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSegments,
+ xSegment *pSegments);
+
+/******
+ * Functions in PclMisc.c
+ ******/
+extern void PclQueryBestSize(
+ int class,
+ short *pwidth,
+ short *pheight,
+ ScreenPtr pScreen);
+extern char *GetPropString(WindowPtr pWin, char *propName);
+extern int SystemCmd(char *cmdStr);
+extern int PclGetMediumDimensions(
+ XpContextPtr pCon,
+ CARD16 *pWidth,
+ CARD16 *pHeight);
+extern int PclGetReproducibleArea(
+ XpContextPtr pCon,
+ xRectangle *pRect);
+extern void PclSendData(
+ FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ BoxPtr pbox,
+ int nbox,
+ double ratio);
+
+/******
+ * Functions in PclPixel.c
+ ******/
+extern void PclPolyPoint(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nPoints,
+ xPoint *pPoints);
+extern void PclPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int width,
+ int height,
+ int x,
+ int y);
+
+/******
+ * Functions in PclPixmap.c
+ ******/
+extern PixmapPtr PclCreatePixmap(
+ ScreenPtr pScreen,
+ int width,
+ int height,
+ int depth);
+extern Bool PclDestroyPixmap(PixmapPtr pPixmap);
+
+/******
+ * Functions in PclPolygon.c
+ ******/
+extern void PclPolyRectangle(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects);
+extern void PclFillPolygon(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int nPoints,
+ DDXPointPtr pPoints);
+extern void PclPolyFillRect(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects);
+
+/******
+ * Functions in PclSpans.c
+ ******/
+extern void PclFillSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSpans,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int fSorted);
+extern void PclSetSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pSrc,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int nSpans,
+ int fSorted);
+
+/******
+ * Functions in PclText.c
+ ******/
+extern int PclPolyText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *string);
+extern int PclPolyText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *string);
+extern void PclImageText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *string);
+extern void PclImageText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *string);
+extern void PclImageGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyphs,
+ CharInfoPtr *pCharInfo,
+ pointer pGlyphBase);
+extern void PclPolyGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyphs,
+ CharInfoPtr *pCharInfo,
+ pointer pGlyphBase);
+
+/******
+ * Functions in PclWindow.c
+ ******/
+extern Bool PclCreateWindow(register WindowPtr pWin);
+extern Bool PclDestroyWindow(WindowPtr pWin);
+extern Bool PclMapWindow(WindowPtr pWindow);
+extern Bool PclPositionWindow(
+ register WindowPtr pWin,
+ int x,
+ int y);
+extern Bool PclUnmapWindow(WindowPtr pWindow);
+extern void PclCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+extern Bool PclChangeWindowAttributes(
+ register WindowPtr pWin,
+ register unsigned long mask);
+extern void PclPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what);
+
+/******
+ * Functions in PclFonts.c
+ ******/
+extern Bool PclRealizeFont(
+ ScreenPtr pscr,
+ FontPtr pFont);
+extern Bool PclUnrealizeFont(
+ ScreenPtr pscr,
+ FontPtr pFont);
+
+/******
+ * Functions in PclPrint.c
+ ******/
+extern int PclStartJob(
+ XpContextPtr pCon,
+ Bool sendClientData,
+ ClientPtr client);
+extern int PclEndJob(
+ XpContextPtr pCon,
+ Bool cancel);
+extern int PclStartPage(
+ XpContextPtr pCon,
+ WindowPtr pWin);
+extern int PclEndPage(
+ XpContextPtr pCon,
+ WindowPtr pWin);
+extern int PclStartDoc(XpContextPtr pCon,
+ XPDocumentType type);
+extern int PclEndDoc(
+ XpContextPtr pCon,
+ Bool cancel);
+extern int PclDocumentData(
+ XpContextPtr pCon,
+ DrawablePtr pDraw,
+ char *pData,
+ int len_data,
+ char *pFmt,
+ int len_fmt,
+ char *pOpt,
+ int len_opt,
+ ClientPtr client);
+extern int PclGetDocumentData(
+ XpContextPtr pCon,
+ ClientPtr client,
+ int maxBufferSize);
+
+
+#endif /* _PCL_H_ */
diff --git a/hw/xprint/pcl/PclArc.c b/hw/xprint/pcl/PclArc.c
new file mode 100644
index 000000000..d675e1699
--- /dev/null
+++ b/hw/xprint/pcl/PclArc.c
@@ -0,0 +1,270 @@
+/* $Xorg: PclArc.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclArc.c
+** *
+** * Contents:
+** * Arc-drawing code for the PCL DDX driver
+** *
+** * Created: 10/23/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclArc.c,v 1.4 1999/12/13 02:12:53 robin Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <errno.h>
+
+#include "Pcl.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "attributes.h"
+
+static void
+PclDoArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs,
+ void (*DoIt)(FILE *, PclContextPrivPtr, double, double, xArc))
+{
+ char t[80];
+ FILE *outFile;
+ int nbox, i;
+ BoxPtr pbox;
+ BoxRec r;
+ RegionPtr drawRegion, region, transClip;
+ short fudge;
+ int xoffset, yoffset;
+ XpContextPtr pCon;
+ PclContextPrivPtr pConPriv;
+ xRectangle repro;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ fudge = 3 * pGC->lineWidth;
+
+ pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+ XpGetReproductionArea( pCon, &repro );
+
+ /*
+ * Generate the PCL code to draw the collection of arcs, by
+ * defining it as a macro which uses the HP-GL/2 arc drawing
+ * function.
+ */
+
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ for( i = 0; i < nArcs; i++ )
+ {
+ xArc Arc = pArcs[i];
+ double b, X, Y, ratio;
+ double angle1;
+
+ MACRO_START( outFile, pConPriv );
+ SAVE_PCL( outFile, pConPriv, "\033%0B" );
+
+ /* Calculate the start of the arc */
+ if( ( Arc.angle1 / 64 ) % 360 == 90 )
+ {
+ X = 0;
+ Y = -Arc.height / 2.0;
+ }
+ else if( ( Arc.angle1 / 64 ) % 360 == 270 )
+ {
+ X = 0;
+ Y = Arc.height / 2.0;
+ }
+ else
+ {
+ /* Convert the angle to radians */
+ angle1 = ( Arc.angle1 / 64.0 ) * 3.141592654 / 180.0;
+
+ b = (Arc.height / 2.0);
+ X = b * cos( angle1 );
+ Y = -b * sin( angle1 );
+ }
+
+ /* Change the coordinate system to scale the ellipse */
+ ratio = (double)Arc.height / (double)Arc.width;
+
+ sprintf( t, "SC%.2f,%.2f,%d,%d;",
+ (repro.x - Arc.width / 2 - xoffset - Arc.x) * ratio,
+ (repro.x - Arc.width / 2 - xoffset - Arc.x +
+ repro.width) * ratio,
+ repro.y - Arc.height / 2 - yoffset - Arc.y + repro.height,
+ repro.y - Arc.height / 2 - yoffset - Arc.y);
+ SAVE_PCL( outFile, pConPriv, t );
+
+ DoIt( outFile, pConPriv, X, Y, Arc );
+
+ /* Build the bounding box */
+ r.x1 = -Arc.width / 2 - fudge;
+ r.y1 = -Arc.height / 2 - fudge;
+ r.x2 = Arc.width / 2 + fudge;
+ r.y2 = Arc.height / 2 + fudge;
+ drawRegion = REGION_CREATE( pGC->pScreen, &r, 0 );
+
+ SAVE_PCL( outFile, pConPriv, "\033%0A" );
+ MACRO_END( outFile );
+
+ /*
+ * Intersect the bounding box with the clip region.
+ */
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ transClip = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ REGION_COPY( pGC->pScreen, transClip, pGC->pCompositeClip );
+ REGION_TRANSLATE( pGC->pScreen, transClip,
+ -(xoffset + Arc.x + Arc.width / 2),
+ -(yoffset + Arc.y + Arc.height / 2) );
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, transClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the collection of arcs to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, ratio);
+
+ /*
+ * Restore the coordinate system
+ */
+ sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x,
+ repro.x + repro.width, repro.y + repro.height,
+ repro.y );
+ SEND_PCL( outFile, t );
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ REGION_DESTROY( pGC->pScreen, transClip );
+ }
+}
+
+/*
+ * Draw a simple non-filled arc, centered on the origin and starting
+ * at the given point.
+ */
+static void
+DrawArc(FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ double X,
+ double Y,
+ xArc A)
+{
+ char t[80];
+
+ sprintf( t, "PU%d,%d;PD;AA0,0,%.2f;", (int)X, (int)Y,
+ (float)A.angle2 / -64.0 );
+ SAVE_PCL(outFile, pConPriv, t);
+}
+
+void
+PclPolyArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ PclDoArc( pDrawable, pGC, nArcs, pArcs, DrawArc );
+}
+
+/*
+ * Draw a filled wedge, from the origin, to the given point, through
+ * the appropriate angle, and back to the origin.
+ */
+static void
+DoWedge(FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ double X,
+ double Y,
+ xArc A)
+{
+ char t[80];
+
+ sprintf( t, "PU0,0;WG%.2f,%.2f,%.2f;", sqrt( X * X + Y * Y ),
+ (float)A.angle1 / -64.0,
+ (float)A.angle2 / -64.0 );
+ SAVE_PCL(outFile, pConPriv, t);
+}
+
+static void
+DoChord(FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ double X,
+ double Y,
+ xArc A)
+{
+ char t[80];
+
+ sprintf( t, "PU%d,%d;PM0;AA0,0,%.2f;PA%d,%d;PM2;FP;", (int)X, (int)Y,
+ (float)A.angle2 / -64.0 , (int)X, (int)Y );
+ SAVE_PCL(outFile, pConPriv, t);
+}
+
+
+void
+PclPolyFillArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ switch( pGC->arcMode )
+ {
+ case ArcChord:
+ PclDoArc( pDrawable, pGC, nArcs, pArcs, DoChord );
+ break;
+ case ArcPieSlice:
+ PclDoArc( pDrawable, pGC, nArcs, pArcs, DoWedge );
+ break;
+ }
+}
diff --git a/hw/xprint/pcl/PclArea.c b/hw/xprint/pcl/PclArea.c
new file mode 100644
index 000000000..dc9156b17
--- /dev/null
+++ b/hw/xprint/pcl/PclArea.c
@@ -0,0 +1,437 @@
+/* $Xorg: PclArea.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclArea.c
+** *
+** * Contents:
+** * Image and Area functions for the PCL DDX driver
+** *
+** * Created: 10/23/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclArea.c,v 1.8 2001/01/17 22:36:30 dawes Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "Pcl.h"
+#include "pixmapstr.h"
+#include "region.h"
+
+#include "fb.h"
+
+void
+PclPutImage(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage)
+{
+ PixmapPtr pPixmap;
+ unsigned long oldFg, oldBg;
+ XID gcv[3];
+ unsigned long oldPlanemask;
+ unsigned long i;
+ long bytesPer;
+
+ if( ( w == 0 ) || ( h == 0 ) )
+ return;
+
+ if( format != XYPixmap )
+ {
+ pPixmap = GetScratchPixmapHeader( pDrawable->pScreen,
+ w+leftPad, h, depth,
+ BitsPerPixel( depth ),
+ PixmapBytePad( w + leftPad,
+ depth ), (pointer)pImage );
+ if( !pPixmap )
+ return;
+
+ if( format == ZPixmap )
+ (void)(*pGC->ops->CopyArea)( (DrawablePtr)pPixmap, pDrawable, pGC,
+ leftPad, 0, w, h, x, y );
+ else
+ (void)(*pGC->ops->CopyPlane)( (DrawablePtr)pPixmap, pDrawable, pGC,
+ leftPad, 0, w, h, x, y, 1 );
+ FreeScratchPixmapHeader( pPixmap );
+ }
+ else
+ {
+ pPixmap = GetScratchPixmapHeader( pDrawable->pScreen,
+ w+leftPad, h, depth,
+ BitsPerPixel( depth ),
+ PixmapBytePad( w + leftPad,
+ depth ), (pointer)pImage );
+
+ if( !pPixmap )
+ return;
+
+ depth = pGC->depth;
+ oldPlanemask = pGC->planemask;
+ oldFg = pGC->fgPixel;
+ oldBg = pGC->bgPixel;
+ gcv[0] = ~0L;
+ gcv[1] = 0;
+ DoChangeGC( pGC, GCForeground | GCBackground, gcv, 0 );
+ bytesPer = (long)h * BitmapBytePad( w + leftPad );
+
+ for( i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer )
+ {
+ if( i & oldPlanemask )
+ {
+ gcv[0] = i;
+ DoChangeGC( pGC, GCPlaneMask, gcv, 0 );
+ ValidateGC( pDrawable, pGC );
+ fbPutImage( (DrawablePtr)pPixmap, pGC, 1, x, y, w, h,
+ leftPad, XYBitmap, pImage );
+ }
+ }
+ gcv[0] = oldPlanemask;
+ gcv[1] = oldFg;
+ gcv[2] = oldBg;
+ DoChangeGC( pGC, GCPlaneMask | GCForeground | GCBackground,
+ gcv, 0 );
+
+ PclCopyArea( (DrawablePtr)pPixmap, pDrawable, pGC, leftPad,
+ 0, w, h, x, y );
+ FreeScratchPixmapHeader( pPixmap );
+ }
+}
+
+/*
+ * PclMonoPixmapFragment()
+ *
+ * Given a 1-bit-deep pixmap, send the appropriate part of it to the
+ * output file as a PCL raster graphics command.
+ */
+static void
+PclMonoPixmapFragment(FILE *outFile,
+ PixmapPtr pix,
+ short x1,
+ short y1,
+ short x2,
+ short y2,
+ short dstx,
+ short dsty)
+{
+ char *bits, t[80], *row;
+ int h, w, i;
+
+ /*
+ * Create a storage area large enough to hold the entire pixmap,
+ * then use fbGetImage to get the appropriate bits.
+ */
+ h = y2 - y1;
+ w = BitmapBytePad( x2 - x1 );
+
+ bits = (char *)xalloc( h * w );
+ fbGetImage( (DrawablePtr)pix, x1, y1, x2 - x1, h,
+ XYPixmap, ~0, bits );
+
+ /*
+ * Move the cursor to the appropriate place on the page. We have
+ * to jump into HP-GL/2 to do this correctly, then go back to PCL
+ * for the actual drawing.
+ */
+ sprintf( t, "\033%%0BPU%d,%d;\033%%1A", dstx, dsty );
+ SEND_PCL( outFile, t );
+
+ /*
+ * Now, wrap the raster in the appropriate PCL code. Right now,
+ * it's going to go down the wire without any compression. That
+ * will have to be good enough for the sample implementation.
+ */
+ sprintf( t, "\033*t300R\033*r%dT\033*r%dS\033*r1A\033*b0M",
+ h, x2 - x1 );
+ SEND_PCL( outFile, t );
+
+ sprintf( t, "\033*b%dW", w );
+ for( row = bits, i = 0; i <= h; i++, row += w )
+ {
+ SEND_PCL( outFile, t );
+ SEND_PCL_COUNT( outFile, row, w );
+ }
+
+ SEND_PCL( outFile, "\033*rC" );
+
+ /*
+ * Clean things up a bit
+ */
+ xfree( bits );
+}
+
+static void
+PclColorPixmapFragment(FILE *outFile,
+ PixmapPtr pix,
+ short x1,
+ short y1,
+ short x2,
+ short y2,
+ short dstx,
+ short dsty)
+{
+ char *bits, t[80], *row;
+ int h, w, i;
+
+ /*
+ * Create a storage area large enough to hold the entire pixmap,
+ * then use fbGetImage to get the appropriate bits.
+ */
+ h = y2 - y1;
+ w = PixmapBytePad( x2 - x1, pix->drawable.depth );
+
+ bits = (char *)xalloc( h * w );
+ fbGetImage( (DrawablePtr)pix, x1, y1, x2 - x1, h, ZPixmap, ~0, bits );
+
+ /*
+ * Move the cursor to the appropriate place on the page. We have
+ * to jump into HP-GL/2 to do this correctly, then go back to PCL
+ * for the actual drawing.
+ */
+ sprintf( t, "\033%%0BPU%d,%d;\033%%1A", dstx, dsty );
+ SEND_PCL( outFile, t );
+
+ /*
+ * Now, wrap the raster in the appropriate PCL code. Right now,
+ * it's going to go down the wire without any compression. That
+ * will have to be good enough for the sample implementation.
+ */
+ sprintf( t, "\033*t300R\033*r%dt%ds1A\033*b0M",
+ h, x2 - x1 );
+ SEND_PCL( outFile, t );
+
+ sprintf( t, "\033*b%dW", w );
+ for( row = bits, i = 0; i < h; i++, row += w )
+ {
+ SEND_PCL( outFile, t );
+ SEND_PCL_COUNT( outFile, row, w );
+ }
+
+ SEND_PCL( outFile, "\033*rC" );
+
+ /*
+ * Clean things up a bit
+ */
+ xfree( bits );
+}
+
+RegionPtr
+PclCopyArea(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty)
+{
+ PixmapPtr pixSrc = (PixmapPtr)pSrc;
+/*
+ FILE *srcFile;
+ GC srcGC;
+*/
+ FILE *dstFile;
+ GC dstGC;
+ unsigned long valid;
+ RegionPtr drawRegion, region, whole, ret;
+ BoxRec box;
+ BoxPtr prect;
+ int nrect;
+ void (*doFragment)(FILE *, PixmapPtr, short, short, short, short,
+ short, short );
+
+ /*
+ * Since we don't store any information on a per-window basis, we
+ * can't copy from a window.
+ */
+ if( pSrc->type == DRAWABLE_WINDOW )
+ return NULL;
+
+ /*
+ * If we're copying from a pixmap to a pixmap, we just use the
+ * fb code to do the work.
+ */
+ if( pDst->type == DRAWABLE_PIXMAP )
+ fbCopyArea( pSrc, pDst, pGC, srcx, srcy, width, height, dstx, dsty );
+
+/*
+ PclGetDrawablePrivateStuff( pSrc, &srcGC, &valid, &srcFile );
+*/
+ PclGetDrawablePrivateStuff( pDst, &dstGC, &valid, &dstFile );
+
+ /*
+ * If we're copying to a window, we have to do some actual
+ * drawing, instead of just handing it off to fb. Start
+ * by determining the region that will be drawn.
+ */
+ box.x1 = srcx;
+ box.y1 = srcy;
+ box.x2 = srcx + width;
+ box.y2 = srcy + height;
+ drawRegion = REGION_CREATE( pGC->pScreen, &box, 0 );
+ REGION_TRANSLATE( pGC->pScreen, drawRegion, dstx, dsty );
+
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * Now select the operation to be performed on each box in the
+ * region.
+ */
+ if( pSrc->depth == 1 )
+ doFragment = PclMonoPixmapFragment;
+ else
+ doFragment = PclColorPixmapFragment;
+
+ /*
+ * Actually draw each section of the bitmap.
+ */
+ nrect = REGION_NUM_RECTS( region );
+ prect = REGION_RECTS( region );
+
+ while( nrect )
+ {
+ (*doFragment)( dstFile, (PixmapPtr)pSrc, prect->x1 - dstx,
+ prect->y1 - dsty, prect->x2 - dstx,
+ prect->y2 - dsty, prect->x1, prect->y1 );
+
+ nrect--;
+ prect++;
+ }
+
+ /*
+ * Update the destination's GC to the source's GC.
+ */
+/*
+ PclSetDrawablePrivateGC( pDst, srcGC );
+*/
+
+ /*
+ * Determine the region that needs to be returned. This is the
+ * region of the source that falls outside the boundary of the
+ * pixmap.
+ */
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pixSrc->drawable.width;
+ box.y2 = pixSrc->drawable.height;
+ whole = REGION_CREATE( pGC->pScreen, &box, 0 );
+ ret = REGION_CREATE( pGC->pScreen, NULL, 0 );
+
+ REGION_TRANSLATE( pGC->pScreen, drawRegion, -dstx, -dsty );
+ REGION_SUBTRACT( pGC->pScreen, ret, drawRegion, whole );
+
+ /*
+ * Clean up the regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ REGION_DESTROY( pGC->pScreen, whole );
+
+ if( REGION_NOTEMPTY( pGC->pScreen, ret ) )
+ return ret;
+ else
+ {
+ REGION_DESTROY( pGC->pScreen, ret );
+ return NULL;
+ }
+}
+
+RegionPtr
+PclCopyPlane(DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long plane)
+{
+ RegionPtr reg;
+ GCPtr scratchGC;
+ PixmapPtr scratchPix;
+
+ /*
+ * Since we don't store PCL on a per-window basis, there's no good
+ * way to copy from a window.
+ */
+ if( pSrc->type == DRAWABLE_WINDOW )
+ return NULL;
+
+ /* Copying from a pixmap to a pixmap is already implemented by fb. */
+ if( pSrc->type == DRAWABLE_PIXMAP &&
+ pDst->type == DRAWABLE_PIXMAP )
+ fbCopyPlane( pSrc, pDst, pGC, srcx, srcy, width, height,
+ dstx, dsty, plane );
+
+ /*
+ * We can use fbCopyPlane to do the work of grabbing the plane and
+ * converting it to the desired visual. Once that's done, we already
+ * know how to do a CopyArea.
+ */
+ scratchPix = (*pDst->pScreen->CreatePixmap)( pDst->pScreen, width,
+ height, pDst->depth );
+
+ scratchGC = GetScratchGC( pDst->depth, pDst->pScreen );
+ CopyGC( pGC, scratchGC, ~0L );
+
+ fbValidateGC( scratchGC, ~0L, (DrawablePtr)scratchPix );
+ fbCopyPlane( pSrc, (DrawablePtr)scratchPix, scratchGC,
+ srcx, srcy, width, height, 0, 0, plane );
+
+ reg = PclCopyArea( (DrawablePtr)scratchPix, pDst, pGC, 0, 0, width,
+ height, dstx, dsty );
+
+ FreeScratchGC( scratchGC );
+
+ (*pDst->pScreen->DestroyPixmap)( scratchPix );
+
+ return reg;
+}
diff --git a/hw/xprint/pcl/PclAttVal.c b/hw/xprint/pcl/PclAttVal.c
new file mode 100644
index 000000000..adbd197fd
--- /dev/null
+++ b/hw/xprint/pcl/PclAttVal.c
@@ -0,0 +1,207 @@
+/*
+ * $Xorg: PclAttVal.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $
+ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Pcl.h"
+#include "AttrValid.h"
+
+/*
+ * define valid values and defaults for Printer pool
+ */
+static XpOid ValidContentOrientationsOids[] = {
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape,
+ xpoid_val_content_orientation_reverse_portrait,
+ xpoid_val_content_orientation_reverse_landscape
+};
+static XpOidList ValidContentOrientations = {
+ ValidContentOrientationsOids, XpNumber(ValidContentOrientationsOids)
+};
+
+static XpOid DefaultContentOrientationsOids[] = {
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape
+};
+static XpOidList DefaultContentOrientations = {
+ DefaultContentOrientationsOids, XpNumber(DefaultContentOrientationsOids)
+};
+
+static XpOid ValidPlexesOids[] = {
+ xpoid_val_plex_simplex, xpoid_val_plex_duplex, xpoid_val_plex_tumble
+};
+static XpOidList ValidPlexes = {
+ ValidPlexesOids, XpNumber(ValidPlexesOids)
+};
+
+static XpOid DefaultPlexesOids[] = {
+ xpoid_val_plex_simplex
+};
+static XpOidList DefaultPlexes = {
+ DefaultPlexesOids, XpNumber(DefaultPlexesOids)
+};
+
+static unsigned long ValidPrinterResolutionsCards[] = {
+ 300
+};
+static XpOidCardList ValidPrinterResolutions = {
+ ValidPrinterResolutionsCards, XpNumber(ValidPrinterResolutionsCards)
+};
+
+static unsigned long DefaultPrinterResolutionsCards[] = {
+ 300
+};
+static XpOidCardList DefaultPrinterResolutions = {
+ DefaultPrinterResolutionsCards, XpNumber(DefaultPrinterResolutionsCards)
+};
+
+static XpOid ValidListfontsModesOids[] = {
+ xpoid_val_xp_list_internal_printer_fonts, xpoid_val_xp_list_glyph_fonts
+};
+static XpOidList ValidListfontsModes = {
+ ValidListfontsModesOids, XpNumber(ValidListfontsModesOids)
+};
+
+static XpOid DefaultListfontsModesOids[] = {
+ xpoid_val_xp_list_glyph_fonts
+};
+static XpOidList DefaultListfontsModes = {
+ DefaultListfontsModesOids, XpNumber(DefaultListfontsModesOids)
+};
+
+static XpOid ValidSetupProvisoOids[] = {
+ xpoid_val_xp_setup_mandatory, xpoid_val_xp_setup_optional
+};
+static XpOidList ValidSetupProviso = {
+
+
+ ValidSetupProvisoOids, XpNumber(ValidSetupProvisoOids)
+};
+
+static XpOidDocFmt ValidDocFormatsSupportedFmts[] = {
+ { "PCL", "5", NULL },
+};
+static XpOidDocFmtList ValidDocFormatsSupported = {
+ ValidDocFormatsSupportedFmts, XpNumber(ValidDocFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultDocFormatsSupportedFmts[] = {
+ { "PCL", "5", NULL }
+};
+static XpOidDocFmtList DefaultDocFormatsSupported = {
+ DefaultDocFormatsSupportedFmts, XpNumber(DefaultDocFormatsSupportedFmts)
+};
+
+static XpOidDocFmt ValidEmbeddedFormatsSupportedFmts[] = {
+ { "HPGL", "2", NULL },
+};
+static XpOidDocFmtList ValidEmbeddedFormatsSupported = {
+ ValidEmbeddedFormatsSupportedFmts, XpNumber(ValidEmbeddedFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultEmbeddedFormatsSupportedFmts[] = {
+ { "HPGL", "2", NULL }
+};
+static XpOidDocFmtList DefaultEmbeddedFormatsSupported = {
+ DefaultEmbeddedFormatsSupportedFmts, XpNumber(DefaultEmbeddedFormatsSupportedFmts)
+};
+
+static XpOidDocFmt ValidRawFormatsSupportedFmts[] = {
+ { "PCL", "5", NULL },
+ { "Postscript", "2", NULL },
+ { "ASCII", NULL, NULL }
+
+};
+static XpOidDocFmtList ValidRawFormatsSupported = {
+ ValidRawFormatsSupportedFmts, XpNumber(ValidRawFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultRawFormatsSupportedFmts[] = {
+ { "PCL", "5", NULL }
+};
+static XpOidDocFmtList DefaultRawFormatsSupported = {
+ DefaultRawFormatsSupportedFmts, XpNumber(DefaultRawFormatsSupportedFmts)
+};
+
+static XpOid ValidInputTraysOids[] = {
+ xpoid_val_input_tray_manual,
+ xpoid_val_input_tray_main,
+ xpoid_val_input_tray_envelope,
+ xpoid_val_input_tray_large_capacity,
+ xpoid_val_input_tray_bottom
+};
+static XpOidList ValidInputTrays = {
+ ValidInputTraysOids, XpNumber(ValidInputTraysOids)
+};
+
+static XpOid ValidMediumSizesOids[] = {
+ xpoid_val_medium_size_iso_a3,
+ xpoid_val_medium_size_iso_a4,
+ xpoid_val_medium_size_na_letter,
+ xpoid_val_medium_size_na_legal,
+ xpoid_val_medium_size_executive,
+ xpoid_val_medium_size_ledger,
+ xpoid_val_medium_size_iso_c5,
+ xpoid_val_medium_size_iso_designated_long,
+ xpoid_val_medium_size_na_number_10_envelope,
+ xpoid_val_medium_size_monarch_envelope,
+ xpoid_val_medium_size_jis_b5,
+};
+static XpOidList ValidMediumSizes = {
+ ValidMediumSizesOids, XpNumber(ValidMediumSizesOids)
+};
+
+static XpOidDocFmt DefaultDocumentFormat = {
+ "PCL", "5", NULL
+};
+
+
+/*
+ * init struct for XpValidate*Pool
+ */
+XpValidatePoolsRec PclValidatePoolsRec = {
+ &ValidContentOrientations, &DefaultContentOrientations,
+ &ValidDocFormatsSupported, &DefaultDocFormatsSupported,
+ &ValidInputTrays, &ValidMediumSizes,
+ &ValidPlexes, &DefaultPlexes,
+ &ValidPrinterResolutions, &DefaultPrinterResolutions,
+ &ValidEmbeddedFormatsSupported, &DefaultEmbeddedFormatsSupported,
+ &ValidListfontsModes, &DefaultListfontsModes,
+ &ValidRawFormatsSupported, &DefaultRawFormatsSupported,
+ &ValidSetupProviso,
+ &DefaultDocumentFormat
+};
diff --git a/hw/xprint/pcl/PclAttr.c b/hw/xprint/pcl/PclAttr.c
new file mode 100644
index 000000000..3cde053f1
--- /dev/null
+++ b/hw/xprint/pcl/PclAttr.c
@@ -0,0 +1,87 @@
+/* $Xorg: PclAttr.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclAttr.c
+** *
+** * Contents:
+** * Attribute-handling functions for the PCL driver
+** *
+** * Created: 2/2/96
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Pcl.h"
+#include "attributes.h"
+
+char *
+PclGetAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool )
+{
+ return XpGetAttributes( pCon, pool );
+}
+
+char *
+PclGetOneAttribute(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attr )
+{
+ return XpGetOneAttribute( pCon, pool, attr );
+}
+int
+PclAugmentAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attrs )
+{
+ return XpAugmentAttributes( pCon, pool, attrs );
+}
+
+int
+PclSetAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attrs )
+{
+ return XpSetAttributes( pCon, pool, attrs );
+}
diff --git a/hw/xprint/pcl/PclColor.c b/hw/xprint/pcl/PclColor.c
new file mode 100644
index 000000000..37d42a521
--- /dev/null
+++ b/hw/xprint/pcl/PclColor.c
@@ -0,0 +1,851 @@
+/* $Xorg: PclColor.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclColorInit.c
+** *
+** * Contents:
+** * Colormap handing code of Pcl driver for the
+** * print server.
+** *
+** * Created: 4/8/96
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclColor.c,v 1.9tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "colormapst.h"
+#include "windowstr.h"
+#include "resource.h"
+
+#include "Pcl.h"
+#include "fb.h"
+
+static void lookup(unsigned char *src,
+ unsigned char *dst,
+ int num,
+ unsigned char *map,
+ int dim);
+static void trilinear(unsigned char *p,
+ unsigned char *out,
+ unsigned char *d,
+ int dim,
+ unsigned char def);
+
+
+/*
+ * This seems to be (and is) a duplication of effort; one would think
+ * that fbCreateDefColormap would be sufficient. It almost is. The
+ * only change made in this function is that the black and white pixels
+ * are allocated with three separate variables for red, green and blue
+ * values, instead of the single variable in fbCreateDefColormap. The
+ * single variable leads to the one value being corrected by
+ * ResolveColor three times, which leads to incorrect colors.
+ */
+
+Bool
+PclCreateDefColormap(ScreenPtr pScreen)
+{
+ unsigned short wp_red = ~0, wp_green = ~0, wp_blue = ~0;
+ unsigned short bp_red = 0, bp_green = 0, bp_blue = 0;
+ VisualPtr pVisual;
+ ColormapPtr cmap;
+ Pixel wp, bp;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
+ 0)
+ != Success)
+ return FALSE;
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+ if ((AllocColor(cmap, &wp_red, &wp_green, &wp_blue, &wp, 0) !=
+ Success) ||
+ (AllocColor(cmap, &bp_red, &bp_green, &bp_blue, &bp, 0) !=
+ Success))
+ return FALSE;
+
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+
+ (*pScreen->InstallColormap)(cmap);
+ return TRUE;
+}
+
+/*
+ * Add colormap to list of colormaps on screen
+ */
+Bool
+PclCreateColormap(ColormapPtr pColor)
+{
+ PclCmapToContexts *new;
+ PclScreenPrivPtr sPriv;
+
+ sPriv = (PclScreenPrivPtr)pColor->pScreen
+ ->devPrivates[PclScreenPrivateIndex].ptr;
+
+ /*
+ * Use existing code to initialize the values in the colormap
+ */
+ fbInitializeColormap( pColor );
+
+ /*
+ * Set up the mapping between the color map and the context
+ */
+ new = (PclCmapToContexts *)xalloc( sizeof( PclCmapToContexts ) );
+
+ if( new )
+ {
+ new->colormapId = pColor->mid;
+ new->contexts = NULL;
+ new->next = sPriv->colormaps;
+ sPriv->colormaps = new;
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void
+PclDestroyColormap(ColormapPtr pColor)
+{
+ PclScreenPrivPtr sPriv;
+ PclCmapToContexts *pCmap, *tCmap = 0;
+ PclContextListPtr con, tCon;
+ PclContextPrivPtr cPriv;
+ PclPaletteMapPtr pPal;
+ char t[80];
+
+ /*
+ * At DestroyContext time, colormaps may be destroyed twice, so if the
+ * pointer is NULL, just crash out.
+ */
+ if( !pColor )
+ return;
+
+ /*
+ * Find the colormap <-> contexts mapping
+ */
+ sPriv = (PclScreenPrivPtr)pColor->pScreen
+ ->devPrivates[PclScreenPrivateIndex].ptr;
+ pCmap = sPriv->colormaps;
+ while( pCmap )
+ {
+ if( pCmap->colormapId == pColor->mid )
+ break;
+ tCmap = pCmap;
+ pCmap = pCmap->next;
+ }
+
+ /*
+ * For each context, delete the palette in the printer and
+ * free the mapping.
+ */
+ if( pCmap )
+ {
+ con = pCmap->contexts;
+ while( con )
+ {
+ cPriv = con->context->devPrivates[PclContextPrivateIndex].ptr;
+
+ pPal = cPriv->palettes;
+ while( pPal )
+ {
+ if( pPal->colormapId == pColor->mid )
+ break;
+ pPal = pPal->next;
+ }
+
+ if( cPriv->pPageFile )
+ {
+ sprintf( t, "\033&p%dI\033*p2C", pPal->paletteId );
+ SEND_PCL( cPriv->pPageFile, t );
+ }
+
+ tCon = con;
+ con = con->next;
+ xfree( tCon );
+ }
+
+ /*
+ * Delete the colormap<->contexts mapping
+ */
+ if( sPriv->colormaps == pCmap )
+ /* Delete from the front */
+ sPriv->colormaps = pCmap->next;
+ else
+ /* Delete from the middle */
+ tCmap->next = pCmap->next;
+ free( pCmap );
+ }
+}
+
+void
+PclInstallColormap(ColormapPtr pColor)
+{
+}
+
+void
+PclUninstallColormap(ColormapPtr pColor)
+{
+}
+
+int
+PclListInstalledColormaps(ScreenPtr pScreen,
+ XID *pCmapList)
+{
+ return 0;
+}
+
+void
+PclStoreColors(ColormapPtr pColor,
+ int ndef,
+ xColorItem *pdefs)
+{
+ PclCmapToContexts *p;
+ PclScreenPrivPtr sPriv;
+ PclContextListPtr con;
+ PclContextPrivPtr cPriv;
+ PclPaletteMapPtr pMap;
+ char t[80];
+ int i;
+
+ sPriv = (PclScreenPrivPtr)pColor->pScreen
+ ->devPrivates[PclScreenPrivateIndex].ptr;
+ p = sPriv->colormaps;
+ while( p )
+ {
+ if( p->colormapId == pColor->mid )
+ break;
+ p = p->next;
+ }
+
+ if( p )
+ {
+ con = p->contexts;
+ while( con )
+ {
+ /*
+ * For each context, get the palette ID and update the
+ * appropriate palette.
+ */
+ cPriv = con->context
+ ->devPrivates[PclContextPrivateIndex].ptr;
+ pMap = PclFindPaletteMap( cPriv, pColor, NULL );
+
+ /*
+ * Update the palette
+ */
+ sprintf( t, "\033&p%dS", pMap->paletteId );
+ SEND_PCL( cPriv->pPageFile, t );
+
+ if( pColor->class == PseudoColor )
+ {
+ unsigned short r, g, b;
+ unsigned int pID;
+ for( i = 0; i < ndef; i++ )
+ {
+ pID = pdefs[i].pixel;
+ if ( pColor->red[i].fShared )
+ {
+ r = pColor->red[pID].co.shco.red->color;
+ g = pColor->red[pID].co.shco.green->color;
+ b = pColor->red[pID].co.shco.blue->color;
+ }
+ else
+ {
+ r = pColor->red[pID].co.local.red;
+ g = pColor->red[pID].co.local.green;
+ b = pColor->red[pID].co.local.blue;
+ }
+
+ if( pdefs[i].flags & DoRed )
+ r = pdefs[i].red;
+ if( pdefs[i].flags & DoGreen )
+ g = pdefs[i].green;
+ if( pdefs[i].flags & DoBlue )
+ b = pdefs[i].blue;
+ PclLookUp(pColor, cPriv, &r, &g, &b);
+ sprintf( t, "\033*v%ua%ub%uc%dI", r, g, b, pID);
+ SEND_PCL( cPriv->pPageFile, t );
+ }
+ }
+
+ sprintf( t, "\033&p%dS", cPriv->currentPalette );
+ SEND_PCL( cPriv->pPageFile, t );
+
+ con = con->next;
+ }
+ }
+}
+
+void
+PclResolveColor(unsigned short *pRed,
+ unsigned short *pGreen,
+ unsigned short *pBlue,
+ VisualPtr pVisual)
+{
+ /*
+ * We need to map the X color range of [0,65535] to the PCL color
+ * range of [0,32767].
+ */
+ *pRed >>= 1;
+ *pGreen >>= 1;
+ *pBlue >>= 1;
+}
+
+PclPaletteMapPtr
+PclFindPaletteMap(PclContextPrivPtr cPriv,
+ ColormapPtr cmap,
+ GCPtr gc)
+{
+ PclPaletteMapPtr p = cPriv->palettes, new;
+
+ /*
+ * If the colormap is static, grab one of the special palettes. If we come
+ * into this from StoreColors, there will be no GC, but by definition we're
+ * looking at a dynamic color map, so the special colors will not be
+ * needed.
+ */
+ if( gc )
+ {
+ if( cmap->pVisual->class == StaticGray )
+ return &( cPriv->staticGrayPalette );
+ else if( cmap->pVisual->class == TrueColor )
+ {
+ if( gc->fillStyle == FillTiled && !( gc->tileIsPixel ) )
+ return &( cPriv->specialTrueColorPalette );
+ else
+ return &( cPriv->trueColorPalette );
+ }
+ }
+
+
+ /* Look for the colormap ID <-> palette ID mapping */
+ while( p )
+ {
+ if( p->colormapId == cmap->mid )
+ return p;
+ p = p->next;
+ }
+
+ /* If the colormap isn't already there, make an entry for it */
+ new = (PclPaletteMapPtr)xalloc( sizeof( PclPaletteMap ) );
+ new->colormapId = cmap->mid;
+ new->paletteId = cPriv->nextPaletteId++;
+ new->downloaded = 0;
+ new->next = cPriv->palettes;
+ cPriv->palettes = new;
+ return new;
+}
+
+int
+PclUpdateColormap(DrawablePtr pDrawable,
+ XpContextPtr pCon,
+ GCPtr gc,
+ FILE *outFile)
+{
+ PclScreenPrivPtr sPriv;
+
+ PclContextPrivPtr cPriv;
+ PclPaletteMapPtr pMap;
+ PclCmapToContexts *pCmap;
+ PclContextListPtr new;
+ char t[80];
+ Colormap c;
+ ColormapPtr cmap;
+ WindowPtr win = (WindowPtr)pDrawable;
+ unsigned short r, g, b, rr, gg, bb;
+ int i;
+
+ cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ c = wColormap( win );
+ cmap = (ColormapPtr)LookupIDByType( c, RT_COLORMAP );
+ pMap = PclFindPaletteMap( cPriv, cmap, gc );
+
+ if( cPriv->currentPalette == pMap->paletteId )
+ /*
+ * If the requested colormap is already active, nothing needs to
+ * be done.
+ */
+ return FALSE;
+
+ /*
+ * Now we activate the palette in the printer
+ */
+ sprintf( t, "\033&p%dS", pMap->paletteId );
+ SEND_PCL( outFile, t );
+ cPriv->currentPalette = pMap->paletteId;
+
+ if( pMap->downloaded == 0 )
+ /*
+ * If the requested colormap has not been downloaded to the
+ * printer, we need to do that before activating it.
+ */
+ {
+ /*
+ * Add the colormap to the screen-level colormap<->context mapping.
+ */
+ sPriv = (PclScreenPrivPtr)cmap->pScreen
+ ->devPrivates[PclScreenPrivateIndex].ptr;
+ pCmap = sPriv->colormaps;
+ while( pCmap && ( pCmap->colormapId != cmap->mid ) )
+ pCmap = pCmap->next;
+ new = (PclContextListPtr)xalloc( sizeof( PclContextList ) );
+ new->context = pCon;
+ new->next = pCmap->contexts;
+ pCmap->contexts = new;
+
+ /*
+ * XXX Download the colormap
+ */
+ if( cmap->class == StaticGray )
+ {
+#ifdef XP_PCL_COLOR
+ sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 1, 1, 1, 1, 1 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 12 );
+
+ /* Send the white reference point... */
+ sprintf( t, "%c%c%c%c%c%c", 0x7f, 0xff, 0x7f, 0xff,
+ 0x7f, 0xff );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* ... and the black reference point */
+ sprintf( t, "%c%c%c%c%c%c", 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* Now program the two colors */
+ sprintf( t, "\033*v0a0b0c%ldI", (long) cmap->pScreen->blackPixel );
+ SEND_PCL( cPriv->pPageFile, t );
+ sprintf( t, "\033*v32767a32767b32767c%ldI",
+ (long) cmap->pScreen->whitePixel );
+ SEND_PCL( cPriv->pPageFile, t );
+#endif /* XP_PCL_COLOR */
+ }
+ else if( cmap->class == PseudoColor )
+ {
+ sprintf( t,
+ "\033*v18W%c%c%c%c%c%c",
+ 0, 1, cmap->pVisual->nplanes, 16, 16, 16 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 12 );
+
+ /* Send the white reference point... */
+ if ( cPriv->ctbl != NULL )
+ sprintf( t, "%c%c%c%c%c%c", 0x00, 0xff, 0x00, 0xff,
+ 0x00, 0xff );
+ else
+ sprintf( t, "%c%c%c%c%c%c", 0x7f, 0xff, 0x7f, 0xff,
+ 0x7f, 0xff );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* ... and the black reference point */
+ sprintf( t, "%c%c%c%c%c%c", 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ for(i = 0; i < cmap->pVisual->ColormapEntries; i++ )
+ {
+ if( cmap->red[i].fShared )
+ {
+ r = cmap->red[i].co.shco.red->color;
+ g = cmap->red[i].co.shco.green->color;
+ b = cmap->red[i].co.shco.blue->color;
+ }
+ else
+ {
+ r = cmap->red[i].co.local.red;
+ g = cmap->red[i].co.local.green;
+ b = cmap->red[i].co.local.blue;
+ }
+ PclLookUp(cmap, cPriv, &r, &g, &b);
+ sprintf( t, "\033*v%ua%ub%uc%dI", r, g, b, i );
+ SEND_PCL( outFile, t );
+ }
+ }
+ else if( cmap->class == TrueColor )
+ {
+ unsigned short lim;
+
+ if( gc->fillStyle == FillTiled && !( gc->tileIsPixel ) )
+ {
+ if( cPriv->ctbl != NULL )
+ {
+ /* Send the "special" colormap for 24-bit fills */
+ sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 1,
+ 8,
+ cmap->pVisual->bitsPerRGBValue,
+ cmap->pVisual->bitsPerRGBValue,
+ cmap->pVisual->bitsPerRGBValue );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 12 );
+
+ /* Send the white reference point... */
+ sprintf( t, "%c%c%c%c%c%c",
+ 0x00, 0xff,
+ 0x00, 0xff,
+ 0x00, 0xff );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* ... and the black reference point */
+ sprintf( t, "%c%c%c%c%c%c",
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* Now send the color entries, RRRGGGBB */
+ i=0;
+ for( r = 0; r < 8; r++ )
+ for( g = 0; g < 8; g ++ )
+ for( b = 0; b < 4; b++ )
+ {
+ rr = (r * 0xff)/7;
+ gg = (g * 0xff)/7;
+ bb = (b * 0xff)/3;
+ PclLookUp(cmap, cPriv, &rr, &gg, &bb);
+ sprintf( t, "\033*v%ua%ub%uc%dI",
+ rr, gg, bb, i );
+ SEND_PCL( outFile, t );
+ i++;
+ }
+ }
+ else
+ {
+ /* Send the "special" colormap for 24-bit fills */
+ sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 1,
+ 8,
+ cmap->pVisual->bitsPerRGBValue,
+ cmap->pVisual->bitsPerRGBValue,
+ cmap->pVisual->bitsPerRGBValue );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 12 );
+
+ /* Send the white reference point... */
+ sprintf( t, "%c%c%c%c%c%c",
+ 0x00, 0x07,
+ 0x00, 0x07,
+ 0x00, 0x03 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* ... and the black reference point */
+ sprintf( t, "%c%c%c%c%c%c",
+ 0x00, 0x00,
+ 0x00, 0x00,
+ 0x00, 0x00 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* Now send the color entries, RRRGGGBB */
+ i=0;
+ for( r = 0; r < 8; r++ )
+ for( g = 0; g < 8; g ++ )
+ for( b = 0; b < 4; b++ )
+ {
+ sprintf( t, "\033*v%ua%ub%uc%dI",
+ r, g, b, i );
+ SEND_PCL( outFile, t );
+ i++;
+ }
+ }
+
+ }
+ else
+ {
+ lim = (1 << cmap->pVisual->bitsPerRGBValue) - 1;
+
+ /* Send the "special" colormap for 24-bit fills */
+ sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 3,
+ cmap->pVisual->nplanes,
+ cmap->pVisual->bitsPerRGBValue,
+ cmap->pVisual->bitsPerRGBValue,
+ cmap->pVisual->bitsPerRGBValue );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 12 );
+
+ /* Send the white reference point... */
+ sprintf( t, "%c%c%c%c%c%c",
+ (lim >> 8) & 0xff, lim & 0xff,
+ (lim >> 8) & 0xff, lim & 0xff,
+ (lim >> 8) & 0xff, lim & 0xff);
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+
+ /* ... and the black reference point */
+ sprintf( t, "%c%c%c%c%c%c", 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 );
+ SEND_PCL_COUNT( cPriv->pPageFile, t, 6 );
+ }
+
+ }
+ pMap->downloaded = 1;
+ }
+ return TRUE;
+
+}
+
+void PclLookUp(
+ ColormapPtr cmap,
+ PclContextPrivPtr cPriv,
+ unsigned short *r,
+ unsigned short *g,
+ unsigned short *b
+)
+{
+ unsigned char cdata[3];
+
+ if( cmap->class == PseudoColor )
+ {
+ if( cPriv->ctbl != NULL )
+ {
+ cdata[0] = *r >> 8;
+ cdata[1] = *g >> 8;
+ cdata[2] = *b >> 8;
+ lookup(cdata, cdata, 1, cPriv->ctbl, cPriv->ctbldim);
+ *r = cdata[0];
+ *g = cdata[1];
+ *b = cdata[2];
+ }
+ else
+ {
+ *r >>= 1;
+ *g >>= 1;
+ *b >>= 1;
+ }
+ }
+ else if( cmap->class == TrueColor )
+ {
+ if( cPriv->ctbl != NULL )
+ {
+ cdata[0] = *r;
+ cdata[1] = *g;
+ cdata[2] = *b;
+ lookup(cdata, cdata, 1, cPriv->ctbl, cPriv->ctbldim);
+ *r = cdata[0];
+ *g = cdata[1];
+ *b = cdata[2];
+ }
+ }
+ return;
+}
+
+unsigned char *PclReadMap(char *name, int *dim)
+{
+ FILE *fp;
+ unsigned char *data;
+ long size;
+
+ if ((fp=fopen(name, "r")) == NULL) {
+ return(NULL);
+ }
+
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+
+ /* Could do this with a lookup table, if the constraint is that the
+ 3 map dimensions must be equal. */
+ switch (size) {
+ case 8*8*8*3:
+ *dim = 8;
+ break;
+ case 16*16*16*3:
+ *dim = 16;
+ break;
+ case 17*17*17*3:
+ *dim = 17;
+ break;
+ case 65*65*65*3:
+ *dim = 65;
+ break;
+ default:
+ fclose(fp);
+ return(NULL);
+ }
+
+ if ((data = (unsigned char *) xalloc(sizeof(char) * size)) == NULL) {
+ fclose(fp);
+ return(NULL);
+ }
+
+ fseek(fp, 0, SEEK_SET);
+
+ if (fread(data, sizeof(char), size, fp) != (unsigned) size) {
+ fclose(fp);
+ free(data);
+ return(NULL);
+ }
+
+ fclose(fp);
+ return(data);
+}
+
+/************************************************************************
+ *
+ * Here is the mapper.
+ *
+ ************************************************************************/
+
+#define SCL(x) ((x)*(dim-1)/255)
+/* Interleaved-map lookup */
+static void lookup(unsigned char *src, unsigned char *dst, int num, unsigned char *map, int dim)
+{
+ int i;
+
+#define _INTERPOLATE
+#ifndef _INTERPOLATE
+ unsigned char *p1, *p2, *p3;
+
+ for (i=0; i<num; i++) {
+ p1 = map + (SCL(src[0])*dim*dim + SCL(src[1])*dim + SCL(src[2])) * 3;
+ *dst++ = *p1++;
+ *dst++ = *p1++;
+ *dst++ = *p1++;
+ src += 3;
+ }
+#else
+ for (i=0; i<num; i++) {
+ trilinear(src, dst, map, dim, 128);
+ src += 3;
+ dst += 3;
+ }
+#endif
+}
+
+/*
+ * C code from the article
+ * "Tri-linear Interpolation"
+ * by Steve Hill, sah@ukc.ac.uk
+ * in "Graphics Gems IV", Academic Press, 1994
+ *
+ * Fri Feb 16 14:12:43 PST 1996
+ * Modified to use for 8-bit color mapping -- A. Fitzhugh,
+ * HP Labs, Printing Technology Department
+ */
+
+/* linear interpolation from l (when a=0) to h (when a=1)*/
+/* (equal to (a*h)+((1-a)*l) */
+#define LERP(a,l,h) ((l)+((((h)-(l))*(a))>>8))
+
+static void trilinear(unsigned char *p, unsigned char *out, unsigned char *d, int dim, unsigned char def)
+{
+#define DENS(X, Y, Z, ch) d[((X*dim+Y)*dim+Z)*3+ch]
+
+ int x0, y0, z0,
+ x1, y1, z1,
+ i;
+ unsigned char *dp,
+ fx, fy, fz,
+ d000, d001, d010, d011,
+ d100, d101, d110, d111,
+ dx00, dx01, dx10, dx11,
+ dxy0, dxy1;
+ float scale;
+
+ scale = 255.0 / (dim-1);
+
+ x0 = p[0] / scale;
+ y0 = p[1] / scale;
+ z0 = p[2] / scale;
+
+ /* Fractions should range from 0-1.0 (fixed point 8-256) */
+ fx = (((int) (p[0] - x0 * scale)) << 8) / 255;
+ fy = (((int) (p[1] - y0 * scale)) << 8) / 255;
+ fz = (((int) (p[2] - z0 * scale)) << 8) / 255;
+
+ x1 = x0 + 1;
+ y1 = y0 + 1;
+ z1 = z0 + 1;
+
+ for (i=0; i<3; i++) {
+
+ if (x0 >= 0 && x1 < dim &&
+ y0 >= 0 && y1 < dim &&
+ z0 >= 0 && z1 < dim) {
+ dp = &DENS(x0, y0, z0, i);
+ d000 = dp[0];
+ d100 = dp[3];
+ dp += dim*3;
+ d010 = dp[0];
+ d110 = dp[3];
+ dp += dim*dim*3;
+ d011 = dp[0];
+ d111 = dp[3];
+ dp -= dim*3;
+ d001 = dp[0];
+ d101 = dp[3];
+ } else {
+# define INRANGE(X, Y, Z) \
+ ((X) >= 0 && (X) < dim && \
+ (Y) >= 0 && (Y) < dim && \
+ (Z) >= 0 && (Z) < dim)
+
+ d000 = INRANGE(x0, y0, z0) ? DENS(x0, y0, z0, i) : def;
+ d001 = INRANGE(x0, y0, z1) ? DENS(x0, y0, z1, i) : def;
+ d010 = INRANGE(x0, y1, z0) ? DENS(x0, y1, z0, i) : def;
+ d011 = INRANGE(x0, y1, z1) ? DENS(x0, y1, z1, i) : def;
+
+ d100 = INRANGE(x1, y0, z0) ? DENS(x1, y0, z0, i) : def;
+ d101 = INRANGE(x1, y0, z1) ? DENS(x1, y0, z1, i) : def;
+ d110 = INRANGE(x1, y1, z0) ? DENS(x1, y1, z0, i) : def;
+ d111 = INRANGE(x1, y1, z1) ? DENS(x1, y1, z1, i) : def;
+ }
+
+ dx00 = LERP(fx, d000, d100);
+ dx01 = LERP(fx, d001, d101);
+ dx10 = LERP(fx, d010, d110);
+ dx11 = LERP(fx, d011, d111);
+
+ dxy0 = LERP(fy, dx00, dx10);
+ dxy1 = LERP(fy, dx01, dx11);
+
+ out[i] = LERP(fz, dxy0, dxy1);
+ }
+}
+
diff --git a/hw/xprint/pcl/PclCursor.c b/hw/xprint/pcl/PclCursor.c
new file mode 100644
index 000000000..f50c355e9
--- /dev/null
+++ b/hw/xprint/pcl/PclCursor.c
@@ -0,0 +1,115 @@
+/* $Xorg: PclCursor.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclCursor.c
+** *
+** * Contents:
+** * Cursor-handling code for the PCL DDX driver
+** *
+** * Created: 1/18/96
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclCursor.c,v 1.3 1999/12/16 02:26:27 robin Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+
+#include "Pcl.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PclConstrainCursor(
+ ScreenPtr pScreen,
+ BoxPtr pBox)
+{
+}
+
+void
+PclCursorLimits(
+ ScreenPtr pScreen,
+ CursorPtr pCursor,
+ BoxPtr pHotBox,
+ BoxPtr pTopLeftBox)
+{
+}
+
+Bool
+PclDisplayCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ return True;
+}
+
+Bool
+PclRealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ return True;
+}
+
+Bool
+PclUnrealizeCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ return True;
+}
+
+void
+PclRecolorCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCursor,
+ Bool displayed)
+{
+}
+
+Bool
+PclSetCursorPosition(
+ ScreenPtr pScreen,
+ int x,
+ int y,
+ Bool generateEvent)
+{
+ return True;
+}
diff --git a/hw/xprint/pcl/PclDef.h b/hw/xprint/pcl/PclDef.h
new file mode 100644
index 000000000..275bd63ec
--- /dev/null
+++ b/hw/xprint/pcl/PclDef.h
@@ -0,0 +1,68 @@
+/* $Xorg: PclDef.h,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclDef.h
+** *
+** * Contents: extran defines and includes for the Pcl driver
+** * for a printing X server.
+** *
+** * Created: 7/31/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PCLDEF_H_
+#define _PCLDEF_H_
+
+#define DT_PRINT_JOB_HEADER "DT_PRINT_JOB_HEADER"
+#define DT_PRINT_JOB_TRAILER "DT_PRINT_JOB_TRAILER"
+#define DT_PRINT_JOB_COMMAND "DT_PRINT_JOB_COMMAND"
+#define DT_PRINT_JOB_EXEC_COMMAND "DT_PRINT_JOB_EXEC_COMMAND"
+#define DT_PRINT_JOB_EXEC_OPTIONS "DT_PRINT_JOB_EXEC_OPTION"
+#define DT_PRINT_PAGE_HEADER "DT_PRINT_PAGE_HEADER"
+#define DT_PRINT_PAGE_TRAILER "DT_PRINT_PAGE_TRAILER"
+#define DT_PRINT_PAGE_COMMAND "DT_PRINT_PAGE_COMMAND"
+
+#define DT_IN_FILE_STRING "%(InFile)%"
+#define DT_OUT_FILE_STRING "%(OutFile)%"
+#define DT_ALLOWED_COMMANDS_FILE "printCommands"
+
+#endif /* _PCLDEF_H_ */
diff --git a/hw/xprint/pcl/PclFonts.c b/hw/xprint/pcl/PclFonts.c
new file mode 100644
index 000000000..591435faa
--- /dev/null
+++ b/hw/xprint/pcl/PclFonts.c
@@ -0,0 +1,74 @@
+/* $Xorg: PclFonts.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclFonts.c
+** *
+** * Contents:
+** * Font code for Pcl driver.
+** *
+** * Created: 2/03/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/* $XFree86$ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "regionstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+
+#include "Pcl.h"
+
+Bool
+PclRealizeFont(
+ ScreenPtr pscr,
+ FontPtr pFont)
+{
+ return TRUE;
+}
+
+Bool
+PclUnrealizeFont(
+ ScreenPtr pscr,
+ FontPtr pFont)
+{
+ return TRUE;
+}
diff --git a/hw/xprint/pcl/PclGC.c b/hw/xprint/pcl/PclGC.c
new file mode 100644
index 000000000..c47986eed
--- /dev/null
+++ b/hw/xprint/pcl/PclGC.c
@@ -0,0 +1,969 @@
+/* $Xorg: PclGC.c,v 1.4 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclGC.c
+** *
+** * Contents:
+** * Graphics Context handling for the PCL driver
+** *
+** * Created: 10/11/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclGC.c,v 1.9 2001/01/19 18:34:28 dawes Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "gcstruct.h"
+
+#include "Pcl.h"
+#include "pixmapstr.h"
+#include "colormapst.h"
+#include "windowstr.h"
+#include "fb.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+static GCOps PclGCOps =
+{
+ PclFillSpans,
+ PclSetSpans,
+ PclPutImage,
+ PclCopyArea,
+ PclCopyPlane,
+ PclPolyPoint,
+ PclPolyLine,
+ PclPolySegment,
+ PclPolyRectangle,
+ PclPolyArc,
+ PclFillPolygon,
+ PclPolyFillRect,
+ PclPolyFillArc,
+ PclPolyText8,
+ PclPolyText16,
+ PclImageText8,
+ PclImageText16,
+ PclImageGlyphBlt,
+ PclPolyGlyphBlt,
+ PclPushPixels
+}
+;
+
+
+static GCFuncs PclGCFuncs =
+{
+ PclValidateGC,
+ miChangeGC,
+ miCopyGC,
+ PclDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+}
+;
+
+Bool
+PclCreateGC(GCPtr pGC)
+{
+ if (fbCreateGC(pGC) == FALSE)
+ return FALSE;
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ pGC->ops = &PclGCOps;
+ pGC->funcs = &PclGCFuncs;
+
+ return TRUE;
+}
+
+void
+PclDestroyGC(GCPtr pGC)
+{
+ /* fb doesn't specialize DestroyGC */
+ miDestroyGC( pGC );
+}
+
+
+int
+PclGetDrawablePrivateStuff(
+ DrawablePtr pDrawable,
+ GC *gc,
+ unsigned long *valid,
+ FILE **file)
+{
+ XpContextPtr pCon;
+ PclContextPrivPtr cPriv;
+
+ switch( pDrawable->type )
+ {
+ case DRAWABLE_PIXMAP:
+ /*
+ * If we ever get here, something is wrong.
+ */
+ return FALSE;
+
+ case DRAWABLE_WINDOW:
+ pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
+
+ if( pCon == NULL )
+ return FALSE;
+ else
+ {
+ cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr;
+ *gc = cPriv->lastGC;
+ *valid = cPriv->validGC;
+ *file = cPriv->pPageFile;
+ return TRUE;
+ }
+
+ default:
+ return FALSE;
+ }
+}
+
+void
+PclSetDrawablePrivateGC(
+ DrawablePtr pDrawable,
+ GC gc)
+{
+ PixmapPtr pix;
+ XpContextPtr pCon;
+ PclPixmapPrivPtr pixPriv;
+ PclContextPrivPtr pPriv;
+ int i;
+
+ switch( pDrawable->type )
+ {
+ case DRAWABLE_PIXMAP:
+ pix = (PixmapPtr)pDrawable;
+ pixPriv = pix->devPrivates[PclPixmapPrivateIndex].ptr;
+
+ pixPriv->lastGC = gc;
+ pixPriv->validGC = 1;
+ break;
+
+ case DRAWABLE_WINDOW:
+ pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
+ pPriv = ((PclContextPrivPtr)
+ (pCon->devPrivates[PclContextPrivateIndex].ptr));
+
+ pPriv->validGC = 1;
+ pPriv->lastGC = gc;
+
+ /*
+ * Store the dash list separately, to avoid having it freed
+ * out from under us.
+ */
+ if( pPriv->dash != NULL )
+ xfree( pPriv->dash );
+ if( gc.numInDashList != 0 )
+ {
+ pPriv->dash = (unsigned char *)xalloc( sizeof( unsigned char )
+ * gc.numInDashList );
+ for( i = 0; i < gc.numInDashList; i++ )
+ pPriv->dash[i] = gc.dash[i];
+ }
+ else
+ pPriv->dash = NULL;
+
+
+ /*
+ * Store the dash list separately, to avoid having it freed
+ * out from under us.
+ */
+ if( pPriv->dash != NULL )
+ xfree( pPriv->dash );
+ if( gc.numInDashList != 0 )
+ {
+ pPriv->dash = (unsigned char *)xalloc( sizeof( unsigned char )
+ * gc.numInDashList );
+ for( i = 0; i < gc.numInDashList; i++ )
+ pPriv->dash[i] = gc.dash[i];
+ }
+ else
+ pPriv->dash = NULL;
+
+ break;
+ }
+}
+
+static void
+PclSendPattern(char *bits,
+ int sz,
+ int depth,
+ int h,
+ int w,
+ int patNum,
+ FILE *outFile)
+{
+ char t[80], *row, *mod;
+ int w2;
+ int i, j;
+
+ SEND_PCL( outFile, "\033%0A" );
+
+ if( depth == 1 )
+ {
+ /* Each row must be word-aligned */
+ w2 = ( w / 8 ) + ( ( w%8 ) ? 1 : 0 );
+/*
+ if( w2 % 2 )
+ w2++;
+*/
+
+ sprintf( t, "\033*c%dg%dW", patNum, h * w2 + 8 );
+ SEND_PCL( outFile, t );
+
+ sprintf( t, "%c%c%c%c%c%c%c%c", 0, 0, 1, 0, h>>8, h&0xff, w>>8,
+ w&0xff );
+ SEND_PCL_COUNT( outFile, t, 8 );
+
+ for( row = bits, i = 0; i < h; i++, row += BitmapBytePad( w ) )
+ SEND_PCL_COUNT( outFile, row, w2 );
+ }
+ else if( depth == 8 )
+ {
+ w2 = ( w % 2 ) ? w + 1 : w;
+
+ sprintf( t, "\033*c%dg%dW", patNum, h * w2 + 8 );
+ SEND_PCL( outFile, t );
+
+ sprintf( t, "%c%c%c%c%c%c%c%c", 1, 0, 8, 0, h>>8, h&0xff,
+ w>>8, w&0xff );
+ SEND_PCL_COUNT( outFile, t, 8 );
+
+ for( row = bits, i = 0; i < h; i++,
+ row += PixmapBytePad( w, 8 ) )
+ SEND_PCL_COUNT( outFile, row, w2 );
+ }
+ else
+ {
+ w2 = ( w % 2 ) ? w + 1 : w;
+
+ sprintf( t, "\033*c%dg%dW", patNum, h * w2 + 8 );
+ SEND_PCL( outFile, t );
+
+ sprintf( t, "%c%c%c%c%c%c%c%c", 1, 0, 8, 0, h>>8, h&0xff,
+ w>>8, w&0xff );
+ SEND_PCL_COUNT( outFile, t, 8 );
+
+ mod = (char *)xalloc( w2 );
+
+ for( row = bits, i = 0; i < h; i++,
+ row += PixmapBytePad( w, 24 ) )
+ {
+ char r, g, b;
+ for( j = 0; j < w2; j++ ) {
+ r = ((row[j*4+1] >> 5) & 0x7) << 5;
+ g = ((row[j*4+2] >> 5) & 0x7) << 2;
+ b = ((row[j*4+3] >> 6) & 0x3);
+ mod[j] = r | g | b;
+ }
+ SEND_PCL_COUNT( outFile, mod, w2 );
+ }
+
+ xfree( mod );
+ }
+
+ SEND_PCL( outFile, "\033%0B" );
+}
+
+int
+PclUpdateDrawableGC(
+ GCPtr pGC,
+ DrawablePtr pDrawable,
+ FILE **outFile)
+{
+ Mask changeMask = 0;
+ GC dGC;
+ unsigned long valid;
+ int i;
+ XpContextPtr pCon;
+ PclContextPrivPtr cPriv;
+ PclGCPrivPtr gcPriv = (PclGCPrivPtr)
+ (pGC->devPrivates[PclGCPrivateIndex].ptr);
+
+ if( !PclGetDrawablePrivateStuff( pDrawable, &dGC, &valid, outFile ) )
+ return FALSE;
+
+ pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
+ cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ /*
+ * Here's where we update the colormap. Since there can be
+ * different colormaps installed on each window, we need to check
+ * before each drawing request that the correct palette is active in
+ * the printer. This is as good a place as any.
+ */
+ if( !PclUpdateColormap( pDrawable, pCon, pGC, *outFile ) )
+ return FALSE;
+
+ /*
+ * If the drawable's last GC is NULL, this means that this is
+ * the first time the drawable is being used. Therefore, we need
+ * to emit PCL for all the GC fields.
+ */
+ if( valid == 0 )
+ changeMask = ~0;
+
+ /*
+ * If we have two different GC structures, there is no alternative
+ * but to scan through them both to determine the changeMask.
+ */
+ else
+ {
+ if( dGC.alu != pGC->alu )
+ changeMask |= GCFunction;
+ if( dGC.fgPixel != pGC->fgPixel )
+ changeMask |= GCForeground;
+ if( dGC.bgPixel != pGC->bgPixel )
+ changeMask |= GCBackground;
+ if( dGC.lineWidth != pGC->lineWidth )
+ changeMask |= GCLineWidth;
+ if( dGC.lineStyle != pGC->lineStyle )
+ changeMask |= GCLineStyle;
+ if( dGC.capStyle != pGC->capStyle )
+ changeMask |= GCCapStyle;
+ if( dGC.joinStyle != pGC->joinStyle )
+ changeMask |= GCJoinStyle;
+ if( dGC.fillStyle != pGC->fillStyle )
+ changeMask |= GCFillStyle;
+ if( dGC.tile.pixmap != pGC->tile.pixmap )
+ changeMask |= GCTile;
+ if( dGC.stipple != pGC->stipple )
+ changeMask |= GCStipple;
+ if( dGC.patOrg.x != pGC->patOrg.x )
+ changeMask |= GCTileStipXOrigin;
+ if( dGC.patOrg.y != pGC->patOrg.y )
+ changeMask |= GCTileStipYOrigin;
+
+ if( dGC.numInDashList == pGC->numInDashList )
+ {
+ for( i = 0; i < dGC.numInDashList; i++ )
+ if( cPriv->dash[i] != pGC->dash[i] )
+ {
+ changeMask |= GCDashList;
+ break;
+ }
+ }
+ else
+ changeMask |= GCDashList;
+ }
+
+ /*
+ * Once the changeMask has been determined, we scan it and emit
+ * the appropriate PCL code to set the drawing attributes.
+ */
+
+ /* Must be in HP-GL/2 mode to set attributes */
+ SEND_PCL( *outFile, "\033%0B" );
+
+ if( changeMask & GCFunction )
+ {
+#ifdef XP_PCL_COLOR
+
+ if( pGC->alu == GXclear )
+ SEND_PCL( *outFile, "SP0;" );
+ else
+ SEND_PCL( *outFile, "SP1;" );
+#else
+ if( pGC->alu == GXclear )
+ SEND_PCL( *outFile, "SP0;" );
+ else
+ SEND_PCL( *outFile, "SP1;" );
+#endif /* XP_PCL_COLOR */
+ }
+
+#if 0
+ if( changeMask & GCFunction )
+ {
+ int rop = -1;
+ char t[10];
+
+ switch( pGC->alu )
+ {
+ case GXclear:
+ rop = 1;
+ break;
+ case GXand:
+ rop = 136;
+ break;
+ case GXandReverse:
+ rop = 68;
+ break;
+ case GXcopy:
+ rop = 204;
+ break;
+ case GXandInverted:
+ rop = 34;
+ break;
+ case GXnoop:
+ rop = 170;
+ break;
+ case GXxor:
+ rop = 238;
+ break;
+ case GXor:
+ rop = 238;
+ break;
+ case GXnor:
+ rop = 17;
+ break;
+ case GXequiv:
+ rop = 153;
+ break;
+ case GXinvert:
+ rop = 85;
+ break;
+ case GXorReverse:
+ rop = 221;
+ break;
+ case GXcopyInverted:
+ rop = 51;
+ break;
+ case GXorInverted:
+ rop = 187;
+ break;
+ case GXnand:
+ rop = 119;
+ break;
+ case GXset:
+ rop = 0;
+ break;
+ }
+ if( rop != -1 )
+ {
+ sprintf( t, "MC1,%d;", rop );
+ SEND_PCL( *outFile, t );
+#endif
+
+ if( changeMask & GCForeground )
+ switch( pGC->fgPixel )
+ {
+ case 1:
+ SEND_PCL( *outFile, "SP1;" );
+ break;
+ default:
+ SEND_PCL( *outFile, "SP0;" );
+ break;
+ }
+
+ if( changeMask & GCForeground )
+ {
+#ifdef XP_PCL_COLOR
+ ColormapPtr cmap;
+ Colormap c;
+ char t[40];
+
+ c = wColormap( ((WindowPtr)pDrawable) );
+ cmap = (ColormapPtr)LookupIDByType( c, RT_COLORMAP );
+
+ if( cmap->class == TrueColor )
+ {
+ if( pGC->fillStyle != FillTiled || pGC->tileIsPixel ) {
+ unsigned short r, g, b;
+
+ r = (pGC->fgPixel & cmap->pVisual->redMask)
+ >> (cmap->pVisual->offsetRed );
+ g = (pGC->fgPixel & cmap->pVisual->greenMask)
+ >> (cmap->pVisual->offsetGreen);
+ b = (pGC->fgPixel & cmap->pVisual->blueMask)
+ >> (cmap->pVisual->offsetBlue);
+
+ PclLookUp(cmap, cPriv, &r, &g, &b);
+ sprintf( t, "\033%%0A\033*v%ua%ub%uc0I\033%%0B", r, g, b);
+ SEND_PCL( *outFile, t );
+ }
+ }
+ else /* PseudoColor or StaticGray */
+ {
+ sprintf( t, "SP%ld;", (long) pGC->fgPixel );
+ SEND_PCL( *outFile, t );
+ }
+#else
+ ScreenPtr screen;
+ screen = pDrawable->pScreen;
+ if ( pGC->fgPixel == screen->whitePixel )
+ SEND_PCL( *outFile, "SP0;");
+ else
+ SEND_PCL( *outFile, "SP1;");
+#endif /* XP_PCL_COLOR */
+ }
+
+ if( changeMask & GCJoinStyle )
+ switch( pGC->joinStyle )
+ {
+ case JoinMiter:
+ SEND_PCL( *outFile, "LA2,1;" );
+ break;
+ case JoinRound:
+ SEND_PCL( *outFile, "LA2,4;" );
+ break;
+ case JoinBevel:
+ SEND_PCL( *outFile, "LA2,5;" );
+ break;
+ }
+
+ if( changeMask & GCCapStyle )
+ switch( pGC->capStyle )
+ {
+ case CapNotLast:
+ case CapButt:
+ SEND_PCL( *outFile, "LA1,1;" );
+ break;
+ case CapRound:
+ SEND_PCL( *outFile, "LA1,4;" );
+ break;
+ case CapProjecting:
+ SEND_PCL( *outFile, "LA1,2;" );
+ break;
+ }
+
+ if( changeMask & GCLineWidth )
+ {
+ float penWidth, pixelsPerMM;
+ ScreenPtr screen;
+ char temp[30];
+
+ if( pGC->lineWidth == 0 || pGC->lineWidth == 1 )
+ /* A pen width of 0.0 mm gives a one-pixel-wide line */
+ penWidth = 0.0;
+ else
+ {
+ screen = pDrawable->pScreen;
+ pixelsPerMM = (float)screen->width / (float)screen->mmWidth;
+
+ penWidth = pGC->lineWidth / pixelsPerMM;
+ }
+ sprintf( temp, "PW%g;", penWidth );
+ SEND_PCL( *outFile, temp );
+ }
+
+ if( changeMask & GCLineStyle )
+ {
+ int i, num = pGC->numInDashList;
+ double total;
+ char t[30];
+
+ switch( pGC->lineStyle )
+ {
+ case LineSolid:
+ SEND_PCL( *outFile, "LT;" );
+ break;
+ case LineOnOffDash:
+ /*
+ * Calculate the pattern length of the dashes, in pixels,
+ * then convert to mm
+ */
+ for( i = 0, total = 0.0; i < 20 && i < num; i++ )
+ total += pGC->dash[i];
+ if( num % 2 )
+ for( i = num; i < 20 && i < num + num; i++ )
+ total += pGC->dash[i-num];
+
+ total *= ( (double)pDrawable->pScreen->mmWidth /
+ (double)pDrawable->pScreen->width );
+
+ sprintf( t, "LT8,%f,1;", total );
+ SEND_PCL( *outFile, t );
+ break;
+ }
+ }
+
+
+ if( changeMask & GCFillStyle )
+ switch( pGC->fillStyle )
+ {
+ case FillSolid:
+ SEND_PCL( *outFile, "FT1;TR0;CF;" );
+ break;
+ case FillTiled:
+ SEND_PCL( *outFile, "FT22,100;TR0;CF2,0;" );
+ break;
+ case FillOpaqueStippled:
+ SEND_PCL( *outFile, "FT22,101;TR0;CF2,0;" );
+ if( pGC->fgPixel != gcPriv->stippleFg ||
+ pGC->bgPixel != gcPriv->stippleBg )
+ changeMask |= GCStipple;
+ break;
+ case FillStippled:
+ SEND_PCL( *outFile, "FT22,102;TR1;CF2,0;" );
+ break;
+ }
+
+ if( changeMask & GCTile && !pGC->tileIsPixel )
+ {
+ char *bits;
+ int h, w, sz;
+
+ h = pGC->tile.pixmap->drawable.height;
+ w = pGC->tile.pixmap->drawable.width;
+
+ sz = h * PixmapBytePad(w, pGC->tile.pixmap->drawable.depth);
+ bits = (char *)xalloc(sz);
+ fbGetImage(&(pGC->tile.pixmap->drawable), 0, 0, w, h, XYPixmap, ~0,
+ bits);
+ PclSendPattern( bits, sz, 1, h, w, 100, *outFile );
+ xfree( bits );
+ }
+
+ if( changeMask & ( GCTileStipXOrigin | GCTileStipYOrigin ) )
+ {
+ char t[30];
+
+ sprintf( t, "AC%d,%d;", pGC->patOrg.x, pGC->patOrg.y );
+ SEND_PCL( *outFile, t );
+ }
+
+ /*
+ * We have to resend the stipple pattern either when the stipple itself
+ * changes, or if we're in FillOpaqueStippled mode and either the
+ * foreground or the background color changes.
+ */
+ if( changeMask & GCStipple ||
+ ( pGC->fillStyle == FillOpaqueStippled &&
+ ( pGC->fgPixel != gcPriv->stippleFg ||
+ pGC->bgPixel != gcPriv->stippleBg ) ) )
+ {
+ int h, w, i, sz, w2;
+ char *bits, *row, t[30];
+ PixmapPtr scratchPix;
+ GCPtr scratchGC;
+
+ if( pGC->stipple != NULL )
+ {
+ SEND_PCL( *outFile, "\033%0A" );
+
+ h = pGC->stipple->drawable.height;
+ w = pGC->stipple->drawable.width;
+ sz = h * BitmapBytePad( w );
+
+ bits = (char *)xalloc( sz );
+ fbGetImage( &(pGC->stipple->drawable), 0, 0, w, h, XYPixmap, ~0, bits );
+
+ w2 = ( w / 8 ) + ( ( w%8 ) ? 1 : 0 );
+ /*
+ * XXX The PCL docs say that I need to word-align each
+ * XXX row, but I get garbage when I do...
+ */
+ /*
+ if( w2 % 2 )
+ w2++;
+ */
+
+ sprintf( t, "\033*c102g%dW", h * w2 + 8 );
+ SEND_PCL( *outFile, t );
+
+ sprintf( t, "%c%c%c%c%c%c%c%c", 0, 0, 1, 0, h>>8, h&0xff, w>>8,
+ w&0xff );
+ SEND_PCL_COUNT( *outFile, t, 8 );
+
+ for( row = bits, i = 0; i < h; i++, row += BitmapBytePad( w ) )
+ SEND_PCL_COUNT( *outFile, row, w2 );
+
+ SEND_PCL( *outFile, "\033%0B" );
+
+ xfree( bits );
+
+ /*
+ * Also do the opaque stipple, as a tile
+ */
+ if( pGC->depth != 1 )
+ sz = h * PixmapBytePad( w, pGC->depth );
+ bits = (char *)xalloc( sz );
+
+ scratchPix =
+ (*pGC->pScreen->CreatePixmap)( pGC->pScreen,
+ w, h, pGC->depth );
+ scratchGC = GetScratchGC( pGC->depth, pGC->pScreen );
+ CopyGC( pGC, scratchGC, ~0L );
+
+ fbValidateGC(scratchGC, ~0L, (DrawablePtr)scratchPix);
+ fbCopyPlane(&(pGC->stipple->drawable), (DrawablePtr)scratchPix,
+ scratchGC, 0, 0, w, h, 0, 0, 1);
+ fbGetImage(&(scratchPix->drawable), 0, 0, w, h, XYPixmap, ~0,
+ bits);
+ PclSendPattern( bits, sz, pGC->depth, h, w, 101, *outFile );
+ FreeScratchGC( scratchGC );
+ (*pGC->pScreen->DestroyPixmap)( scratchPix );
+ xfree( bits );
+ }
+ }
+
+ if( changeMask & ( GCTileStipXOrigin | GCTileStipYOrigin ) )
+ {
+ char t[30];
+
+ sprintf( t, "AC%d,%d;", pGC->patOrg.x, pGC->patOrg.y );
+ SEND_PCL( *outFile, t );
+ }
+
+ if( changeMask & GCDashList )
+ {
+ int num = pGC->numInDashList;
+ double total;
+ char dashes[20];
+ char t[100], t2[20];
+
+ /* Make up the doubled dash list, if necessary */
+ for( i = 0; i < 20 && i < num; i++ )
+ dashes[i] = pGC->dash[i];
+
+ if( num % 2 )
+ {
+ for( i = num; i < 20 && i < num + num; i++ )
+ dashes[i] = dashes[i-num];
+ if( ( num *= 2 ) > 20 )
+ num = 20;
+ }
+
+ /* Add up dash lengths to get percentage */
+ for( i = 0, total = 0; i < num; i++ )
+ total += dashes[i];
+
+ /* Build up the HP-GL/2 for the dash list */
+ strcpy( t, "UL8" );
+ for( i = 0; i < num; i++ )
+ {
+ sprintf( t2, ",%d",
+ (int)( ( (double)dashes[i] / total * 100.0 ) + 0.5 ) );
+ strcat( t, t2 );
+ }
+ strcat( t, ";" );
+ SEND_PCL( *outFile, t );
+ }
+
+
+ /* Go back to PCL mode */
+ SEND_PCL( *outFile, "\033%0A" );
+
+ /*
+ * Update the drawable's private information, which includes
+ * erasing the drawable's private changeMask, since all the
+ * changes have been made.
+ */
+ if( changeMask )
+ PclSetDrawablePrivateGC( pDrawable, *pGC );
+
+ return TRUE;
+}
+
+/*
+ * PclComputeCompositeClip()
+ *
+ * I'd like to use the miComputeCompositeClip function, but it sticks
+ * things into the mi GC privates, where the PCL driver can't get at
+ * it. So, rather than mess around with the mi code, I ripped it out
+ * and made the appropriate changes here.
+ */
+
+
+void
+PclComputeCompositeClip(
+ GCPtr pGC,
+ DrawablePtr pDrawable)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ }
+ else
+ {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pGC->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping the
+ * pointer we got, and remembering whether or not should destroy (or
+ * maybe re-use) it later. this way, we avoid unnecessary copying of
+ * regions. (this wins especially if many clients clip by children
+ * and have no client clip.)
+ */
+ if (pGC->clientClipType == CT_NONE)
+ {
+ if (freeCompClip)
+ REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
+ pGC->pCompositeClip = pregWin;
+ pGC->freeCompClip = freeTmpClip;
+ }
+ else
+ {
+ /*
+ * we need one 'real' region to put into the composite clip. if
+ * pregWin the current composite clip are real, we can get rid of
+ * one. if pregWin is real and the current composite clip isn't,
+ * use pregWin for the composite clip. if the current composite
+ * clip is real and pregWin isn't, use the current composite
+ * clip. if neither is real, create a new region.
+ */
+
+ REGION_TRANSLATE(pGC->pScreen, pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+
+ if (freeCompClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ if (freeTmpClip)
+ REGION_DESTROY(pGC->pScreen, pregWin);
+ }
+ else if (freeTmpClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, pregWin, pregWin,
+ pGC->clientClip);
+ pGC->pCompositeClip = pregWin;
+ }
+ else
+ {
+ pGC->pCompositeClip = REGION_CREATE(pGC->pScreen, NullBox, 0);
+ REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ }
+ pGC->freeCompClip = TRUE;
+ REGION_TRANSLATE(pGC->pScreen, pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+ }
+ } /* end of composite clip for a window */
+ else
+ {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ pixbounds.x1 = 0;
+ pixbounds.y1 = 0;
+ pixbounds.x2 = pDrawable->width;
+ pixbounds.y2 = pDrawable->height;
+
+ if (pGC->freeCompClip)
+ {
+ REGION_RESET(pGC->pScreen, pGC->pCompositeClip, &pixbounds);
+ }
+ else
+ {
+ pGC->freeCompClip = TRUE;
+ pGC->pCompositeClip = REGION_CREATE(pGC->pScreen, &pixbounds, 1);
+ }
+
+ if (pGC->clientClipType == CT_REGION)
+ {
+ REGION_TRANSLATE(pGC->pScreen, pGC->pCompositeClip,
+ -pGC->clipOrg.x, -pGC->clipOrg.y);
+ REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
+ pGC->pCompositeClip, pGC->clientClip);
+ REGION_TRANSLATE(pGC->pScreen, pGC->pCompositeClip,
+ pGC->clipOrg.x, pGC->clipOrg.y);
+ }
+ } /* end of composite clip for pixmap */
+}
+
+/*
+ * PclValidateGC()
+ *
+ * Unlike many screen GCValidate routines, this function should not need
+ * to mess with setting the drawing functions. Different drawing
+ * functions are usually needed to optimize such things as drawing
+ * wide or dashed lines; this functionality will be handled primarily
+ * by the printer itself, while the necessary PCL code to set the
+ * attributes will be done in PclUpdateDrawableGC().
+ */
+
+/*ARGSUSED*/
+void
+PclValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable)
+{
+ /*
+ * Pixmaps should be handled by their respective validation
+ * functions.
+ */
+ if( pDrawable->type == DRAWABLE_PIXMAP )
+ {
+ fbValidateGC(pGC, ~0, pDrawable);
+ return;
+ }
+
+ /*
+ * Reset the drawing operations
+ */
+ pGC->ops = &PclGCOps;
+
+ /*
+ * Validate the information, and correct it if necessary.
+ */
+
+ /*
+ * If necessary, compute the composite clip region. (Code ripped
+ * from migc.c)
+ */
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ PclComputeCompositeClip(pGC, pDrawable);
+ }
+
+ /*
+ * PCL does not directly support the DoubleDash line style, nor is
+ * there an easy way to simulate it, so we'll just change it to a
+ * LineOnOffDash, which is supported by PCL.
+ */
+ if( ( changes & GCLineStyle ) && ( pGC->lineStyle == LineDoubleDash ) )
+ pGC->lineStyle = LineOnOffDash;
+
+ /*
+ * Update the drawable's changeMask to reflect the changes made to the GC.
+ */
+/*
+ PclSetDrawablePrivateGC( pDrawable, *pGC, changes );
+*/
+}
diff --git a/hw/xprint/pcl/PclInit.c b/hw/xprint/pcl/PclInit.c
new file mode 100644
index 000000000..272f4da9a
--- /dev/null
+++ b/hw/xprint/pcl/PclInit.c
@@ -0,0 +1,629 @@
+/* $Xorg: PclInit.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclInit.c
+** *
+** * Contents:
+** * Initialization code of Pcl driver for the print server.
+** *
+** * Created: 1/30/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclInit.c,v 1.11 2001/12/21 21:02:05 dawes Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "Pcl.h"
+
+#include "fb.h"
+#include <X11/Xos.h> /* for unlink() */
+
+#include "attributes.h"
+#include "DiPrint.h"
+
+#define MODELDIRNAME "/models"
+
+static void AllocatePclPrivates(ScreenPtr pScreen);
+static int PclInitContext(XpContextPtr pCon);
+static Bool PclDestroyContext(XpContextPtr pCon);
+
+int PclScreenPrivateIndex;
+int PclContextPrivateIndex;
+int PclPixmapPrivateIndex;
+int PclWindowPrivateIndex;
+int PclGCPrivateIndex;
+
+#ifdef XP_PCL_COLOR
+/*
+ * The supported visuals on this screen
+ */
+static VisualRec Visuals[] =
+{
+ { 1, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0 },
+ { 2, PseudoColor, 8, 256, 8, 0, 0, 0, 0, 0, 0 },
+ { 3, TrueColor, 8, 256, 24, 0xFF0000, 0xFF00, 0xFF, 16, 8, 0 }
+};
+
+/*
+ * The supported depths on this screen
+ */
+static DepthRec Depths[] =
+{
+ { 1, 1, NULL },
+ { 8, 1, NULL },
+ { 24, 1, NULL }
+};
+#else
+/*
+ * The supported visuals on this screen
+ */
+static VisualRec Visuals[] =
+{
+ { 1, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0}
+};
+
+/*
+ * The supported depths on this screen
+ */
+static DepthRec Depths[] =
+{
+ { 1, 1, NULL }
+};
+#endif /* XP_PCL_COLOR */
+
+
+#define NUM_VISUALS(visuals) (sizeof(visuals) / sizeof(VisualRec))
+#define NUM_DEPTHS(depths) (sizeof(depths) / sizeof(DepthRec))
+
+Bool
+PclCloseScreen(int index,
+ ScreenPtr pScreen)
+{
+ PclScreenPrivPtr pPriv = pScreen->devPrivates[PclScreenPrivateIndex].ptr;
+
+ pScreen->CloseScreen = pPriv->CloseScreen;
+ xfree( pPriv );
+
+ return (*pScreen->CloseScreen)(index, pScreen);
+}
+
+Bool
+InitializePclDriver(
+ int ndx,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv)
+{
+ int maxRes, xRes, yRes, maxDim;
+ unsigned i;
+ PclScreenPrivPtr pPriv;
+
+ /*
+ * Register this driver's InitContext function with the print
+ * extension. This is a bit sleazy, as the extension hasn't yet
+ * been initialized, but the extensionneeds to know this, and this
+ * seems the best time to provide the information.
+ */
+#ifdef XP_PCL_COLOR
+ XpRegisterInitFunc( pScreen, "XP-PCL-COLOR", PclInitContext );
+#elif XP_PCL_MONO
+ XpRegisterInitFunc( pScreen, "XP-PCL-MONO", PclInitContext );
+#else
+ XpRegisterInitFunc( pScreen, "XP-PCL-LJ3", PclInitContext );
+#endif /* XP_PCL_MONO */
+
+ /*
+ * Create and fill in the devPrivate for the PCL driver.
+ */
+ AllocatePclPrivates(pScreen);
+
+ pPriv =
+ (PclScreenPrivPtr)pScreen->devPrivates[PclScreenPrivateIndex].ptr;
+
+ maxDim = MAX( pScreen->height, pScreen->width );
+ xRes = pScreen->width / ( pScreen->mmWidth / 25.4 );
+ yRes = pScreen->height / ( pScreen->mmHeight / 25.4 );
+ maxRes = MAX( xRes, yRes );
+
+#ifdef XP_PCL_COLOR
+ fbScreenInit( pScreen, NULL, maxDim, maxDim, maxRes, maxRes,
+ maxRes, 8 ); /* XXX what's the depth here? */
+ /* Clean up the fields that we stomp (code taken from fbCloseScreen) */
+ for( i = 0; (int) i < pScreen->numDepths; i++ )
+ xfree( pScreen->allowedDepths[i].vids );
+ xfree( pScreen->allowedDepths );
+ xfree( pScreen->visuals );
+#else
+ fbScreenInit( pScreen, NULL, maxDim, maxDim, maxRes, maxRes,
+ maxRes, 1 );
+#endif /* XP_PCL_COLOR */
+
+ miInitializeBackingStore ( pScreen );
+
+ pScreen->defColormap = FakeClientID(0);
+ pScreen->blackPixel = 1;
+ pScreen->whitePixel = 0;
+
+ pPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = PclCloseScreen;
+
+ pScreen->QueryBestSize = (QueryBestSizeProcPtr)PclQueryBestSize;
+ pScreen->SaveScreen = (SaveScreenProcPtr)_XpBoolNoop;
+ pScreen->GetImage = (GetImageProcPtr)_XpVoidNoop;
+ pScreen->GetSpans = (GetSpansProcPtr)_XpVoidNoop;
+ pScreen->CreateWindow = PclCreateWindow;
+ pScreen->DestroyWindow = PclDestroyWindow;
+/*
+ pScreen->PositionWindow = PclPositionWindow;
+*/
+ pScreen->ChangeWindowAttributes = PclChangeWindowAttributes;
+/*
+ pScreen->RealizeWindow = PclMapWindow;
+ pScreen->UnrealizeWindow = PclUnmapWindow;
+*/
+ pScreen->PaintWindowBackground = PclPaintWindow;
+ pScreen->PaintWindowBorder = PclPaintWindow;
+ pScreen->CopyWindow = PclCopyWindow; /* XXX Hard routine to write! */
+
+ pScreen->CreatePixmap = fbCreatePixmap;
+ pScreen->DestroyPixmap = fbDestroyPixmap;
+ pScreen->RealizeFont = PclRealizeFont;
+ pScreen->UnrealizeFont = PclUnrealizeFont;
+ pScreen->CreateGC = PclCreateGC;
+
+ pScreen->CreateColormap = PclCreateColormap;
+ pScreen->DestroyColormap = PclDestroyColormap;
+ pScreen->InstallColormap = (InstallColormapProcPtr)NoopDDA;
+ pScreen->UninstallColormap = (UninstallColormapProcPtr)NoopDDA;
+ pScreen->ListInstalledColormaps = PclListInstalledColormaps;
+ pScreen->StoreColors = PclStoreColors;
+/*
+ pScreen->ResolveColor = PclResolveColor;
+*/
+
+ pScreen->BitmapToRegion = fbPixmapToRegion;
+
+ pScreen->ConstrainCursor = PclConstrainCursor;
+ pScreen->CursorLimits = PclCursorLimits;
+ pScreen->DisplayCursor = PclDisplayCursor;
+ pScreen->RealizeCursor = PclRealizeCursor;
+ pScreen->UnrealizeCursor = PclUnrealizeCursor;
+ pScreen->RecolorCursor = PclRecolorCursor;
+ pScreen->SetCursorPosition = PclSetCursorPosition;
+
+ pScreen->visuals = Visuals;
+ pScreen->numVisuals = NUM_VISUALS( Visuals );
+ pScreen->allowedDepths = Depths;
+ pScreen->numDepths = NUM_DEPTHS( Depths );
+
+ for( i = 0; i < NUM_DEPTHS( Depths ); i++ )
+ {
+ pScreen->allowedDepths[i].vids =
+ (VisualID *)xalloc( sizeof(VisualID ) );
+ pScreen->allowedDepths[i].vids[0] = i + 1;
+ }
+
+#ifdef XP_PCL_COLOR
+ pScreen->rootVisual = 2;
+ pScreen->rootDepth = 8;
+#else
+ pScreen->rootVisual = 1;
+ pScreen->rootDepth = 1;
+#endif /* XP_PCL_COLOR */
+
+ pPriv->colormaps = NULL;
+ PclCreateDefColormap( pScreen );
+
+ return TRUE;
+}
+
+static void
+AllocatePclPrivates(ScreenPtr pScreen)
+{
+ static unsigned long PclGeneration = 0;
+
+ if((unsigned long) PclGeneration != serverGeneration)
+ {
+ PclScreenPrivateIndex = AllocateScreenPrivateIndex();
+
+ PclWindowPrivateIndex = AllocateWindowPrivateIndex();
+ AllocateWindowPrivate( pScreen, PclWindowPrivateIndex,
+ sizeof( PclWindowPrivRec ) );
+
+ PclContextPrivateIndex = XpAllocateContextPrivateIndex();
+ XpAllocateContextPrivate( PclContextPrivateIndex,
+ sizeof( PclContextPrivRec ) );
+
+ PclGCPrivateIndex = AllocateGCPrivateIndex();
+ AllocateGCPrivate( pScreen, PclGCPrivateIndex,
+ sizeof( PclGCPrivRec ) );
+
+ PclPixmapPrivateIndex = AllocatePixmapPrivateIndex();
+ AllocatePixmapPrivate( pScreen, PclPixmapPrivateIndex,
+ sizeof( PclPixmapPrivRec ) );
+
+ PclGeneration = serverGeneration;
+ }
+
+ pScreen->devPrivates[PclScreenPrivateIndex].ptr = (pointer)xalloc(
+ sizeof(PclScreenPrivRec));
+}
+
+/*
+ * PclInitContext
+ *
+ * Establish the appropriate values for a PrintContext used with the PCL
+ * driver.
+ */
+
+static char DOC_ATT_SUPP[]="document-attributes-supported";
+static char DOC_ATT_VAL[]="document-format xp-listfonts-modes";
+static char JOB_ATT_SUPP[]="job-attributes-supported";
+static char JOB_ATT_VAL[]="";
+static char PAGE_ATT_SUPP[]="xp-page-attributes-supported";
+static char PAGE_ATT_VAL[]="content-orientation default-printer-resolution \
+default-input-tray default-medium plex xp-listfonts-modes";
+
+static int
+PclInitContext(XpContextPtr pCon)
+{
+ XpDriverFuncsPtr pFuncs;
+ PclContextPrivPtr pConPriv;
+ char *server, *attrStr;
+ char *modelID;
+ char *configDir;
+ char *pathName;
+ int i, j;
+ float width, height;
+ XpOidMediumDiscreteSizeList* ds_list;
+ XpOidArea* repro;
+ XpOid page_size;
+ XpOidMediumSS* m;
+
+ /*
+ * Initialize the attribute store for this printer.
+ */
+ XpInitAttributes( pCon );
+
+ /*
+ * Initialize the function pointers
+ */
+ pFuncs = &( pCon->funcs );
+ pFuncs->StartJob = PclStartJob;
+ pFuncs->EndJob = PclEndJob;
+ pFuncs->StartDoc = PclStartDoc;
+ pFuncs->EndDoc = PclEndDoc;
+ pFuncs->StartPage = PclStartPage;
+ pFuncs->EndPage = PclEndPage;
+ pFuncs->PutDocumentData = PclDocumentData;
+ pFuncs->GetDocumentData = PclGetDocumentData;
+ pFuncs->GetAttributes = PclGetAttributes;
+ pFuncs->SetAttributes = PclSetAttributes;
+ pFuncs->AugmentAttributes = PclAugmentAttributes;
+ pFuncs->GetOneAttribute = PclGetOneAttribute;
+ pFuncs->DestroyContext = PclDestroyContext;
+ pFuncs->GetMediumDimensions = PclGetMediumDimensions;
+ pFuncs->GetReproducibleArea = PclGetReproducibleArea;
+
+
+ /*
+ * Set up the context privates
+ */
+ pConPriv =
+ (PclContextPrivPtr)pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ pConPriv->jobFileName = (char *)NULL;
+ pConPriv->pageFileName = (char *)NULL;
+ pConPriv->pJobFile = (FILE *)NULL;
+ pConPriv->pPageFile = (FILE *)NULL;
+ pConPriv->dash = NULL;
+ pConPriv->validGC = 0;
+
+ pConPriv->getDocClient = (ClientPtr)NULL;
+ pConPriv->getDocBufSize = 0;
+ modelID = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-model-identifier");
+ if ( (configDir = XpGetConfigDir(False)) != (char *) NULL ) {
+ pathName = (char *)xalloc(strlen(configDir) + strlen(MODELDIRNAME) +
+ strlen(modelID) + strlen("color.map") + 4);
+ if (pathName) {
+ sprintf(pathName, "%s/%s/%s/%s", configDir, MODELDIRNAME, modelID,
+ "color.map");
+ pConPriv->ctbl = PclReadMap(pathName, &pConPriv->ctbldim);
+ xfree(pathName);
+
+ } else
+ pConPriv->ctbl = NULL;
+ } else
+ pConPriv->ctbl = NULL;
+
+#ifdef XP_PCL_LJ3
+ /*
+ * Initialize the spooling buffer for saving the figures temporary
+ * (LaserJet IIIs printers don't support the macro function which
+ * includes some HP-GL/2 commands.)
+ */
+ pConPriv->fcount = 0;
+ if ( !(pConPriv->figures = (char *)xalloc(1024)) )
+ pConPriv->fcount_max = 0;
+ else
+ pConPriv->fcount_max = 1024;
+#endif /* XP_PCL_LJ3 */
+
+ /*
+ * document-attributes-supported
+ */
+ server = XpGetOneAttribute( pCon, XPServerAttr, DOC_ATT_SUPP );
+ if( ( attrStr = (char *)xalloc(strlen(server) + strlen(DOC_ATT_SUPP)
+ + strlen(DOC_ATT_VAL) +
+ strlen(PAGE_ATT_VAL) + 8 ) )
+ == (char *)NULL )
+ return BadAlloc;
+ sprintf( attrStr, "*%s:\t%s %s %s", DOC_ATT_SUPP, server,
+ DOC_ATT_VAL, PAGE_ATT_VAL );
+ XpAugmentAttributes( pCon, XPPrinterAttr, attrStr );
+ xfree( attrStr );
+
+ /*
+ * job-attributes-supported
+ */
+ server = XpGetOneAttribute( pCon, XPServerAttr, JOB_ATT_SUPP );
+ if( ( attrStr = (char *)xalloc(strlen(server) + strlen(JOB_ATT_SUPP)
+ + strlen(JOB_ATT_VAL) + 8 ) )
+ == (char *)NULL )
+ return BadAlloc;
+ sprintf( attrStr, "*%s:\t%s %s", JOB_ATT_SUPP, server, JOB_ATT_VAL );
+ XpAugmentAttributes( pCon, XPPrinterAttr, attrStr );
+ xfree( attrStr );
+
+ /*
+ * xp-page-attributes-supported
+ */
+ server = XpGetOneAttribute( pCon, XPServerAttr, PAGE_ATT_SUPP );
+ if( ( attrStr = (char *)xalloc(strlen(server) + strlen(PAGE_ATT_SUPP)
+ + strlen(PAGE_ATT_VAL) + 8 ) )
+ == (char *)NULL )
+ return BadAlloc;
+ sprintf( attrStr, "*%s:\t%s %s", PAGE_ATT_SUPP, server, PAGE_ATT_VAL );
+ XpAugmentAttributes( pCon, XPPrinterAttr, attrStr );
+ xfree( attrStr );
+
+ /*
+ * Validate the attribute pools
+ */
+ XpValidateAttributePool( pCon, XPPrinterAttr, &PclValidatePoolsRec );
+
+ /*
+ * Munge the reproducible areas to reflect the fact that PCL will not let
+ * me move the right or left margins closer than .25" to the edge of the
+ * paper.
+ */
+ m = XpGetMediumSSAttr( pCon, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported,
+ (const XpOidList*) NULL,
+ (const XpOidList*) NULL );
+ for( i = 0; i < XpOidMediumSSCount( m ); i++ )
+ {
+ if( XpOidMediumSS_DISCRETE == (m->mss)[i].mstag )
+ {
+ ds_list = (m->mss)[i].ms.discrete;
+ for( j = 0; j < ds_list->count; j++ )
+ {
+ repro = &(ds_list->list)[j].assured_reproduction_area;
+ page_size = (ds_list->list)[j].page_size;
+ XpGetMediumMillimeters( page_size, &width, &height );
+
+ if( repro->minimum_x < 6.35 )
+ repro->minimum_x = 6.35;
+ if( width - repro->maximum_x < 6.35 )
+ repro->maximum_x = width - 6.35;
+ }
+ }
+ }
+ XpPutMediumSSAttr( pCon, XPPrinterAttr,
+ xpoid_att_medium_source_sizes_supported, m );
+ XpOidMediumSSDelete( m );
+
+ /*
+ * Finish validating the attribute pools
+ */
+
+ XpValidateAttributePool( pCon, XPDocAttr, &PclValidatePoolsRec );
+ XpValidateAttributePool( pCon, XPJobAttr, &PclValidatePoolsRec );
+ XpValidateAttributePool( pCon, XPPageAttr, &PclValidatePoolsRec );
+
+ /*
+ * Clear out the colormap storage
+ */
+ pConPriv->palettes = NULL;
+
+ return Success;
+}
+
+static Bool
+PclDestroyContext(XpContextPtr pCon)
+{
+ PclContextPrivPtr pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+ PclPaletteMapPtr p, t;
+ PclCmapToContexts *pCmap;
+ ScreenPtr screen;
+ PclScreenPrivPtr sPriv;
+ PclContextListPtr con, prevCon, temp;
+
+
+ /*
+ * Clean up the temporary files
+ */
+ if( pConPriv->pPageFile != (FILE *)NULL )
+ {
+ fclose( pConPriv->pPageFile );
+ pConPriv->pPageFile = (FILE *)NULL;
+ }
+ if( pConPriv->pageFileName != (char *)NULL )
+ {
+ unlink( pConPriv->pageFileName );
+ xfree( pConPriv->pageFileName );
+ pConPriv->pageFileName = (char *)NULL;
+ }
+
+ if( pConPriv->pJobFile != (FILE *)NULL )
+ {
+ fclose( pConPriv->pJobFile );
+ pConPriv->pJobFile = NULL;
+ }
+ if( pConPriv->jobFileName != (char *)NULL )
+ {
+ unlink( pConPriv->jobFileName );
+ xfree( pConPriv->jobFileName );
+ pConPriv->jobFileName = (char *)NULL;
+ }
+
+ xfree( pConPriv->dash );
+ xfree(pConPriv->ctbl);
+ pConPriv->ctbl = NULL;
+#ifdef XP_PCL_LJ3
+ xfree( pConPriv->figures );
+#endif /* XP_PCL_LJ3 */
+
+ /*
+ * Destroy the colormap<->palette mappings
+ */
+ p = pConPriv->palettes;
+ while( p )
+ {
+ t = p;
+ p = p->next;
+ xfree( t );
+ }
+ pConPriv->palettes = NULL;
+
+ /*
+ * Remove the context from the screen-level colormap<->contexts mappings
+ */
+ screen = screenInfo.screens[pCon->screenNum];
+ sPriv = (PclScreenPrivPtr)screen->devPrivates[PclScreenPrivateIndex].ptr;
+ pCmap = sPriv->colormaps;
+ while( pCmap )
+ {
+ con = pCmap->contexts;
+ prevCon = NULL;
+
+ while( con )
+ {
+ if( con->context->contextID == pCon->contextID )
+ {
+ if( prevCon )
+ {
+ temp = con;
+ prevCon->next = con = con->next;
+ }
+ else
+ {
+ temp = pCmap->contexts;
+ pCmap->contexts = con = con->next;
+ }
+ xfree( temp );
+ }
+ else
+ con = con->next;
+ }
+
+ pCmap = pCmap->next;
+ }
+
+ XpDestroyAttributes(pCon);
+
+ return Success;
+}
+
+XpContextPtr
+PclGetContextFromWindow(WindowPtr win)
+{
+ PclWindowPrivPtr pPriv;
+
+ while( win )
+ {
+ pPriv =
+ (PclWindowPrivPtr)win->devPrivates[PclWindowPrivateIndex].ptr;
+ if( pPriv->validContext )
+ return pPriv->context;
+
+ win = win->parent;
+ }
+
+ return NULL;
+}
diff --git a/hw/xprint/pcl/PclLine.c b/hw/xprint/pcl/PclLine.c
new file mode 100644
index 000000000..f2b564df8
--- /dev/null
+++ b/hw/xprint/pcl/PclLine.c
@@ -0,0 +1,316 @@
+/* $Xorg: PclLine.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclLine.c
+** *
+** * Contents:
+** * Line drawing routines for the PCL driver
+** *
+** * Created: 10/11/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclLine.c,v 1.6 1999/12/13 02:12:55 robin Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Pcl.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+/*
+ * PclPolyLine()
+ * PclPolySegment()
+ *
+ * Generates PCL code to draw a polyline, or a collection of distinct
+ * line segments, clipped by the current clip region. Since PCL
+ * supports clipping to a rectangle, and the clip region is
+ * represented as a collection of visible rectangles, we can draw and
+ * clip the line by repeatedly drawing the complete line, clipped to
+ * each rectangle in the clip region.
+ *
+ * Since each box in the clipping region generates approximately 30
+ * bytes of PCL code, we have to have a way to avoid having a large
+ * number of boxes. The worst problem the case where the clipping
+ * region is a collection of one-pixel-high boxes, perhaps arising
+ * from a bitmap clip mask, or a region defined by a non-rectangular
+ * polygon.
+ *
+ * To alleviate this problem, we create a second clipping region,
+ * which consists of the union of the bounding boxes of each line
+ * segment. (Each bounding box is also increased by some amount
+ * related to the current line width to allow for non-zero-width
+ * lines, and for the various end and join styles.) This region is
+ * intersected with the "real" clipping region to get the region used
+ * to actually clip the polyline. This should result in a significant
+ * reduction in the number of clip rectangles, as the region-handling
+ * code should consolidate many of the fragments of one-pixel-high
+ * rectangles into larger rectangles.
+ */
+
+void
+PclPolyLine(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nPoints,
+ xPoint *pPoints)
+{
+ char t[80];
+ FILE *outFile;
+ int xoffset = 0, yoffset = 0;
+ int nbox;
+ BoxPtr pbox;
+ xRectangle *drawRects, *r;
+ RegionPtr drawRegion, region;
+ short fudge;
+ int i;
+ XpContextPtr pCon;
+ PclContextPrivPtr pConPriv;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ /*
+ * Allocate the storage required to deal with the clipping
+ * regions.
+ */
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ drawRects = (xRectangle *)
+ xalloc( ( nPoints - 1 ) * sizeof( xRectangle ) );
+
+ /*
+ * Calculate the "fudge factor" based on the line width.
+ * Multiplying by three seems to be a good first guess.
+ * XXX I need to think of a way to test this.
+ */
+ fudge = 3 * pGC->lineWidth + 1;
+
+ /*
+ * Generate the PCL code to draw the polyline, by defining it as a
+ * macro which uses the HP-GL/2 line drawing function.
+ */
+
+ MACRO_START( outFile, pConPriv );
+ SAVE_PCL( outFile, pConPriv, "\033%0B" );
+
+ sprintf( t, "PU%d,%dPD\n", pPoints[0].x + pDrawable->x,
+ pPoints[0].y + pDrawable->y );
+ SAVE_PCL( outFile, pConPriv, t ); /* Move to the start of the polyline */
+
+ switch( mode )
+ {
+ case CoordModeOrigin:
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+ SAVE_PCL( outFile, pConPriv, "PA" );
+ break;
+ case CoordModePrevious:
+ xoffset = yoffset = 0;
+ SAVE_PCL( outFile, pConPriv, "PR" );
+ break;
+ }
+
+ /*
+ * Build the "drawing region" as we build the PCL to draw the
+ * line.
+ */
+ for(i = 1, r = drawRects; i < nPoints; i++, r++ )
+ {
+ if( i != 1 )
+ SAVE_PCL( outFile, pConPriv, "," );
+
+ sprintf( t, "%d,%d", pPoints[i].x + xoffset,
+ pPoints[i].y + yoffset );
+ SAVE_PCL( outFile, pConPriv, t );
+
+ r->x = MIN( pPoints[i-1].x, pPoints[i].x ) + xoffset - fudge;
+ r->y = MIN( pPoints[i-1].y, pPoints[i].y ) + yoffset - fudge;
+ r->width = abs( pPoints[i-1].x - pPoints[i].x ) + 2 * fudge;
+ r->height = abs( pPoints[i-1].y - pPoints[i].y ) + 2 * fudge;
+ }
+ SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */
+ MACRO_END( outFile );
+
+ /*
+ * Convert the collection of rectangles into a proper region, then
+ * intersect it with the clip region.
+ */
+ drawRegion = RECTS_TO_REGION( pGC->pScreen, nPoints - 1,
+ drawRects, CT_UNSORTED );
+ if( mode == CoordModePrevious )
+ REGION_TRANSLATE( pGC->pScreen, drawRegion, pPoints[0].x, pPoints[0].y );
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the entire polyline to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ xfree( drawRects );
+}
+
+void
+PclPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSegments,
+ xSegment *pSegments)
+{
+ FILE *outFile, *dummy;
+ char t[80];
+ int xoffset, yoffset;
+ int nbox, i;
+ unsigned long valid;
+ BoxPtr pbox;
+ xRectangle *drawRects, *r;
+ RegionPtr drawRegion, region;
+ short fudge;
+ XpContextPtr pCon;
+ PclContextPrivPtr pConPriv;
+ GC cacheGC;
+
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ /*
+ * Allocate the storage for the temporary regions.
+ */
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ drawRects = (xRectangle *)
+ xalloc( nSegments * sizeof( xRectangle ) );
+
+ /*
+ * Calculate the fudge factor, based on the line width
+ */
+ fudge = pGC->lineWidth * 3 + 1;
+
+ /*
+ * Turn off line joining.
+ */
+ SEND_PCL( outFile, "\033%0BLA2,6;\033%0A" );
+
+ /*
+ * Generate the PCL code to draw the segments, by defining them as
+ * a macro which uses the HP-GL/2 line drawing function.
+ *
+ * XXX I wonder if this should be implemented using the Encoded
+ * XXX Polyline function. Since I'm only sending it once, it's not
+ * XXX necessarily too important.
+ */
+
+ MACRO_START( outFile, pConPriv );
+ SAVE_PCL( outFile, pConPriv, "\033%0B" );
+
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ for( i = 0, r = drawRects; i < nSegments; i++, r++ )
+ {
+ r->x = MIN( pSegments[i].x1, pSegments[i].x2 ) + xoffset;
+ r->y = MIN( pSegments[i].y1, pSegments[i].y2 ) + yoffset;
+ r->width = abs( pSegments[i].x1 - pSegments[i].x2 );
+ r->height = abs( pSegments[i].y1 - pSegments[i].y2 );
+
+ sprintf( t, "PU%d,%d;PD%d,%d;", pSegments[i].x1 + xoffset,
+ pSegments[i].y1 + yoffset, pSegments[i].x2 +
+ xoffset, pSegments[i].y2 + yoffset );
+ SAVE_PCL( outFile, pConPriv, t );
+
+ r->x -= fudge;
+ r->y -= fudge;
+ r->width += 2 * fudge;
+ r->height += 2 * fudge;
+ }
+ SAVE_PCL( outFile, pConPriv, "\033%0A" );
+ MACRO_END ( outFile );
+
+ /*
+ * Convert the collection of rectangles into a proper region, then
+ * intersect it with the clip region.
+ */
+ drawRegion = RECTS_TO_REGION( pGC->pScreen, nSegments,
+ drawRects, CT_UNSORTED );
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the entire set of segments to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Now we need to reset the line join mode to whatever it was at before.
+ * The easiest way is to force the cached GC's joinstyle to be different
+ * from the current GC's joinstyle, then re-update the GC. This way, we
+ * don't have to duplicate code unnecessarily.
+ */
+ PclGetDrawablePrivateStuff( pDrawable, &cacheGC, &valid, &dummy );
+ cacheGC.joinStyle = !cacheGC.joinStyle;
+ PclSetDrawablePrivateGC( pDrawable, cacheGC );
+ PclUpdateDrawableGC( pGC, pDrawable, &outFile );
+
+ /*
+ * Clean up
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ xfree( drawRects );
+}
diff --git a/hw/xprint/pcl/PclMisc.c b/hw/xprint/pcl/PclMisc.c
new file mode 100644
index 000000000..3a958e783
--- /dev/null
+++ b/hw/xprint/pcl/PclMisc.c
@@ -0,0 +1,306 @@
+/* $Xorg: PclMisc.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclMisc.c
+** *
+** * Contents:
+** * Miscellaneous code for Pcl driver.
+** *
+** * Created: 2/01/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclMisc.c,v 1.10tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <X11/Xos.h> /* for SIGCLD on pre-POSIX systems */
+#include "Pcl.h"
+
+#include "cursor.h"
+#include "resource.h"
+
+#include "windowstr.h"
+#include "propertyst.h"
+#include "attributes.h"
+
+
+/*ARGSUSED*/
+void
+PclQueryBestSize(
+ int type,
+ short *pwidth,
+ short *pheight,
+ ScreenPtr pScreen)
+{
+ unsigned width, highBit;
+
+ switch(type)
+ {
+ case CursorShape:
+ *pwidth = 0;
+ *pheight = 0;
+ break;
+ case TileShape:
+ case StippleShape:
+ width = *pwidth;
+ if (!width) break;
+ /* Return the nearest power of two >= what they gave us */
+ highBit = 0x80000000;
+ /* Find the highest 1 bit in the given width */
+ while(!(highBit & width))
+ highBit >>= 1;
+ /* If greater than that then return the next power of two */
+ if((highBit - 1) & width)
+ highBit <<= 1;
+ *pwidth = highBit;
+ /* height is a don't-care */
+ break;
+ }
+}
+
+/*
+ * GetPropString searches the window heirarchy from pWin up looking for
+ * a property by the name of propName. If found, returns the property's
+ * value. If not, it returns NULL.
+ */
+char *
+GetPropString(
+ WindowPtr pWin,
+ char *propName)
+{
+ Atom atom;
+ PropertyPtr pProp = (PropertyPtr)NULL;
+ char *retVal;
+
+ atom = MakeAtom(propName, strlen(propName), FALSE);
+ if(atom != BAD_RESOURCE)
+ {
+ WindowPtr pPropWin;
+ int n;
+
+ /*
+ * The atom has been defined, but it might only exist as a
+ * property on an unrelated window.
+ */
+ for(pPropWin = pWin; pPropWin != (WindowPtr)NULL;
+ pPropWin = pPropWin->parent)
+ {
+ for(pProp = (PropertyPtr)(wUserProps(pPropWin));
+ pProp != (PropertyPtr)NULL;
+ pProp = pProp->next)
+ {
+ if (pProp->propertyName == atom)
+ break;
+ }
+ if(pProp != (PropertyPtr)NULL)
+ break;
+ }
+ if(pProp == (PropertyPtr)NULL)
+ return (char *)NULL;
+
+ n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+ retVal = (char *)xalloc(n + 1);
+ (void)memcpy((void *)retVal, (void *)pProp->data, n);
+ retVal[n] = '\0';
+
+ return retVal;
+ }
+
+ return (char *)NULL;
+}
+
+#include <signal.h>
+#include <errno.h>
+
+/* ARGSUSED */
+static void SigchldHndlr (
+ int dummy)
+{
+ int status;
+ int olderrno = errno;
+ struct sigaction act;
+ sigfillset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = SigchldHndlr;
+
+ (void) wait (&status);
+
+ /*
+ * Is this really necessary?
+ */
+ sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
+ errno = olderrno;
+}
+
+/*
+ * SystemCmd provides a wrapper for the 'system' library call. The call
+ * appears to be sensitive to the handling of SIGCHLD, so this wrapper
+ * sets the status to SIG_DFL, and then resets the established handler
+ * after system returns.
+ */
+int
+SystemCmd(char *cmdStr)
+{
+ int status;
+ struct sigaction newAct, oldAct;
+ sigfillset(&newAct.sa_mask);
+ newAct.sa_flags = 0;
+ newAct.sa_handler = SIG_DFL;
+ sigfillset(&oldAct.sa_mask);
+ oldAct.sa_flags = 0;
+ oldAct.sa_handler = SigchldHndlr;
+
+ /*
+ * get the old handler, and set the action to IGN
+ */
+ sigaction(SIGCHLD, &newAct, &oldAct);
+
+ status = system (cmdStr);
+
+ sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL);
+ return status;
+}
+
+
+/*
+ * PclGetMediumDimensions is installed in the GetMediumDimensions field
+ * of each Pcl-initialized context.
+ */
+int
+PclGetMediumDimensions(XpContextPtr pCon,
+ CARD16 *width,
+ CARD16 *height)
+{
+ XpGetMediumDimensions(pCon, width, height);
+ return Success;
+}
+
+/*
+ * PclGetReproducibleArea is installed in the GetReproducibleArea field
+ * of each Pcl-initialized context.
+ */
+int
+PclGetReproducibleArea(XpContextPtr pCon,
+ xRectangle *pRect)
+{
+ XpGetReproductionArea(pCon, pRect);
+ return Success;
+}
+
+#ifdef XP_PCL_LJ3
+/*
+ * PclSpoolFigs spooled the rendering PCL/HP-GL2 commands into the
+ * temporary buffer pointed by figures pointer in pcl private context.
+ * LaserJet IIIs printers don't support the macro function which
+ * includes some HP-GL/2 commands.
+ */
+void
+PclSpoolFigs(PclContextPrivPtr pConPriv, char *t, int n)
+{
+char *ptr;
+
+ ptr = pConPriv->figures;
+ while ( ( pConPriv->fcount + n) > pConPriv->fcount_max ) {
+ ptr = (char *)xrealloc(ptr, 1024 + pConPriv->fcount_max);
+ if ( !ptr )
+ return;
+ pConPriv->figures = ptr;
+ pConPriv->fcount_max += 1024;
+ }
+ ptr += pConPriv->fcount;
+ pConPriv->fcount += n;
+ memcpy(ptr, t, n);
+}
+#endif /* XP_PCL_LJ3 */
+
+/*
+ * PclSendData:
+ * For XP-PCL-COLOR/XP-PCL-MONO, it executes the macro stored before
+ * in the clipped area.
+ * For XP-PCL-LJ3, it draws the spooled figures in the clipped area.
+ */
+void
+PclSendData(
+ FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ BoxPtr pbox,
+ int nbox,
+ double ratio
+)
+{
+char *ptr;
+int n;
+char t[80];
+
+#ifdef XP_PCL_LJ3
+ ptr = pConPriv->figures;
+ n = pConPriv->fcount;
+#else
+ ptr = "\033&f3X";
+ n = 5;
+#endif /* XP_PCL_LJ3 */
+
+ while( nbox )
+ {
+ /*
+ * Set the HP-GL/2 input window to the current
+ * rectangle in the clip region, then send the code to
+ * execute the macro defined above.
+ */
+ if (ratio == 1.0)
+ sprintf( t, "\033%%0BIW%d,%d,%d,%d;\033%%0A",
+ pbox->x1, pbox->y1,
+ pbox->x2, pbox->y2 );
+ else
+ sprintf( t, "\033%%0BIW%g,%d,%g,%d;\033%%0A",
+ ratio * pbox->x1, pbox->y1,
+ ratio * pbox->x2, pbox->y2 );
+
+ SEND_PCL( outFile, t );
+ SEND_PCL_COUNT( outFile, ptr, n);
+
+ nbox--;
+ pbox++;
+ }
+}
diff --git a/hw/xprint/pcl/PclPixel.c b/hw/xprint/pcl/PclPixel.c
new file mode 100644
index 000000000..bfad618ed
--- /dev/null
+++ b/hw/xprint/pcl/PclPixel.c
@@ -0,0 +1,159 @@
+/* $Xorg: PclPixel.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclPixel.c
+** *
+** * Contents:
+** * Pixel-drawing code for the PCL DDX driver
+** *
+** * Created: 10/23/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclPixel.c,v 1.6tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Pcl.h"
+
+void
+PclPolyPoint( pDrawable, pGC, mode, nPoints, pPoints )
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int nPoints;
+ xPoint *pPoints;
+{
+ char t[80];
+ FILE *outFile;
+ int xoffset, yoffset;
+ BoxRec box;
+ int xloc, yloc, i;
+#if 0
+ XpContextPtr pCon;
+ PclContextPrivPtr cPriv;
+ PclPixmapPrivPtr pPriv;
+#endif
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ /*
+ * Enter HP-GL/2 and change the line style to one in which only
+ * the vertices of the specified polyline are drawn. We must also
+ * temporarily change the line width so that only a single pixel
+ * is drawn. Then move to the first possible location.
+ */
+ xloc = pPoints[0].x + pDrawable->x;
+ yloc = pPoints[0].y + pDrawable->y;
+
+ sprintf( t, "\27%%0BPW0,0;LT0;PU;PA%d,%d", xloc, yloc );
+ SEND_PCL( outFile, t );
+
+ /*
+ * Check each point against the clip region. If it is outside the
+ * region, don't send the PCL to the printer.
+ */
+
+ for( i = 0; i < nPoints; i++ )
+ {
+ if( POINT_IN_REGION( pGC->pScreen, pGC->clientClip, xloc, yloc, &box ) )
+ {
+ sprintf( t, ",%d,%d", xloc, yloc );
+ SEND_PCL( outFile, t );
+ }
+
+ if( mode == CoordModeOrigin )
+ {
+ xloc = pPoints[i+1].x + xoffset;
+ yloc = pPoints[i+1].y + yoffset;
+ }
+ else
+ {
+ xloc += pPoints[i+1].x;
+ yloc += pPoints[i+1].y;
+ }
+ }
+
+#if 0
+ /*
+ * Change the line style and width back to what they were before
+ * this routine was called. No, this isn't pretty...
+ */
+ if( pDrawable->type == DRAWABLE_WINDOW )
+ {
+ pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
+ cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr;
+ cPriv->changeMask = GCLineWidth | GCLineStyle;
+ }
+ else
+ {
+ pPriv =
+ ((PixmapPtr)pDrawable)->devPrivates[PclPixmapPrivateIndex].ptr;
+ pPriv->changeMask = GCLineWidth | GCLineStyle;
+ }
+#endif
+
+ PclUpdateDrawableGC( pGC, pDrawable, &outFile );
+
+ /*
+ * Go back to PCL
+ */
+ SEND_PCL( outFile, "\27%0A" );
+}
+
+void
+PclPushPixels( pGC, pBitmap, pDrawable, width, height, x, y )
+ GCPtr pGC;
+ PixmapPtr pBitmap;
+ DrawablePtr pDrawable;
+ int width;
+ int height;
+ int x;
+ int y;
+{
+}
diff --git a/hw/xprint/pcl/PclPolygon.c b/hw/xprint/pcl/PclPolygon.c
new file mode 100644
index 000000000..41ba4b1c0
--- /dev/null
+++ b/hw/xprint/pcl/PclPolygon.c
@@ -0,0 +1,353 @@
+/* $Xorg: PclPolygon.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclPolygon.c
+** *
+** * Contents:
+** * Draws Polygons and Rectangles for the PCL DDX
+** *
+** * Created: 10/23/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclPolygon.c,v 1.6 1999/12/13 02:12:56 robin Exp $ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Pcl.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PclPolyRectangle(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ char t[80];
+ FILE *outFile;
+ int nbox, i;
+ BoxPtr pbox;
+ xRectangle *drawRects, *r;
+ RegionPtr drawRegion, region;
+ short fudge;
+ int xoffset, yoffset;
+ XpContextPtr pCon;
+ PclContextPrivPtr pConPriv;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ /*
+ * Allocate the storage required to deal with the clipping
+ * regions.
+ */
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ drawRects = (xRectangle *)xalloc( nRects * sizeof( xRectangle ) );
+
+ fudge = 3 * pGC->lineWidth + 1;
+
+ /*
+ * Generate the PCL code to draw the rectangles, by defining them
+ * as a macro which uses the HP-GL/2 rectangle drawing function.
+ */
+ MACRO_START( outFile, pConPriv );
+ SAVE_PCL( outFile, pConPriv, "\033%0B" );
+
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ for( i = 0, r = drawRects; i < nRects; i++, r++ )
+ {
+ xRectangle rect = pRects[i];
+
+ /* Draw the rectangle */
+ sprintf( t, "PU%d,%d;ER%d,%d;", rect.x + xoffset,
+ rect.y + yoffset, rect.width, rect.height );
+ SAVE_PCL( outFile, pConPriv, t );
+
+ /* Build the bounding box */
+ r->x = MIN( rect.x, rect.x + rect.width ) + xoffset -
+ fudge;
+ r->y = MIN( rect.y, rect.y + rect.height ) + yoffset -
+ fudge;
+ r->width = rect.width + 2 * fudge;
+ r->height = rect.height + 2 * fudge;
+ }
+ SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */
+ MACRO_END( outFile );
+
+ /*
+ * Convert the collection of rectangles to a proper region, then
+ * intersect it with the clip region.
+ */
+ drawRegion = RECTS_TO_REGION( pGC->pScreen, nRects,
+ drawRects, CT_UNSORTED );
+
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the set of rectangles to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ xfree( drawRects );
+}
+
+void
+PclFillPolygon(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int nPoints,
+ DDXPointPtr pPoints)
+{
+ char t[80];
+ FILE *outFile;
+ int nbox, i;
+ BoxPtr pbox;
+ BoxRec box;
+ RegionPtr drawRegion, region;
+ int xoffset, yoffset;
+ int xtop, xbottom, yleft, yright;
+ int fillRule;
+ XpContextPtr pCon;
+ PclContextPrivPtr pConPriv;
+ char *command;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ /*
+ * Generate the PCL code to draw the filled polygon, by defining
+ * it as a macro which uses the HP-GL/2 polygon drawing function.
+ */
+ MACRO_START( outFile, pConPriv );
+ SAVE_PCL( outFile, pConPriv, "\033%0B" );
+
+ if( mode == CoordModeOrigin )
+ {
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+ command = "PA";
+ }
+ else
+ {
+ xoffset = yoffset = 0;
+ command = "PR";
+ }
+
+ /* Begin the polygon */
+ sprintf( t, "PU%d,%d;PM0;%s", pPoints[0].x + xoffset, pPoints[0].y
+ + yoffset, command );
+ SAVE_PCL( outFile, pConPriv, t );
+
+ /* Seed the bounding box */
+ xtop = xbottom = pPoints[0].x + xoffset;
+ yleft = yright = pPoints[0].y + yoffset;
+
+ /* Add the rest of the points to the polygon */
+ for( i = 1; i < nPoints; i++ )
+ {
+ if( i != 1 )
+ SAVE_PCL( outFile, pConPriv, "," );
+
+ sprintf( t, "%d,%d", pPoints[i].x + xoffset, pPoints[i].y +
+ yoffset );
+ SAVE_PCL( outFile, pConPriv, t );
+
+ /* Update the bounding box */
+ xtop = MIN( xtop, pPoints[i].x + xoffset );
+ xbottom = MAX( xbottom, pPoints[i].x + xoffset );
+ yleft = MIN( yleft, pPoints[i].y + yoffset );
+ yright = MAX( yright, pPoints[i].y + yoffset );
+ }
+
+ /* Close the polygon and the macro */
+
+ if( pGC->fillRule == EvenOddRule )
+ fillRule = 0;
+ else
+ fillRule = 1;
+
+ sprintf( t, ";PM2;FP%d;\033%%0A", fillRule );
+ SAVE_PCL( outFile, pConPriv, t );
+ MACRO_END ( outFile );
+
+ /*
+ * Build the bounding region from the bounding box of the polygon
+ */
+ box.x1 = xtop;
+ box.y1 = yleft;
+ box.x2 = xbottom;
+ box.y2 = yright;
+ drawRegion = REGION_CREATE( pGC->pScreen, &box, 0 );
+
+ if( mode == CoordModePrevious )
+ REGION_TRANSLATE( pGC->pScreen, drawRegion, pPoints[0].x, pPoints[0].y );
+
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the polygon to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+}
+
+void
+PclPolyFillRect(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ char t[80];
+ FILE *outFile;
+ int nbox, i;
+ BoxPtr pbox;
+ xRectangle *drawRects, *r;
+ RegionPtr drawRegion, region;
+ int xoffset, yoffset;
+ short fudge;
+ XpContextPtr pCon;
+ PclContextPrivPtr pConPriv;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ /*
+ * Allocate the storage required to deal with the clipping
+ * regions.
+ */
+ region = REGION_CREATE( pGC->pScreen, NULL, 0 );
+ drawRects = (xRectangle *)xalloc( nRects * sizeof( xRectangle ) );
+
+
+ fudge = 3 * pGC->lineWidth + 1;
+
+ /*
+ * Generate the PCL code to draw the filled rectangles, by
+ * defining them as a macro which uses the HP-GL/2 rectangle
+ * drawing function.
+ */
+ MACRO_START( outFile, pConPriv );
+ SAVE_PCL( outFile, pConPriv, "\033%0B" );
+
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ for( i = 0, r = drawRects; i < nRects; i++, r++ )
+ {
+ xRectangle rect = pRects[i];
+
+ /* Draw the rectangle */
+ sprintf( t, "PU%d,%d;RR%d,%d;", rect.x + xoffset, rect.y +
+ yoffset, rect.width, rect.height );
+ SAVE_PCL( outFile, pConPriv, t );
+
+ /* Build the bounding box */
+ r->x = MIN( rect.x, rect.x + rect.width ) + xoffset - fudge;
+ r->y = MIN( rect.y, rect.y + rect.height ) + yoffset -
+ fudge;
+ r->width = rect.width + 2 * fudge;
+ r->height = rect.height + 2 * fudge;
+ }
+ SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */
+ MACRO_END( outFile );
+
+ /*
+ * Convert the collection of rectangles to a proper region, then
+ * intersect it with the clip region.
+ */
+ drawRegion = RECTS_TO_REGION( pGC->pScreen, nRects,
+ drawRects, CT_UNSORTED );
+ REGION_INTERSECT( pGC->pScreen, region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the set of rectangles to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ xfree( drawRects );
+}
diff --git a/hw/xprint/pcl/PclPrint.c b/hw/xprint/pcl/PclPrint.c
new file mode 100644
index 000000000..701710253
--- /dev/null
+++ b/hw/xprint/pcl/PclPrint.c
@@ -0,0 +1,711 @@
+/* $Xorg: PclPrint.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclPrint.c
+** *
+** * Contents: Print extension code of Pcl driver
+** *
+** * Created: 2/03/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclPrint.c,v 1.7tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <X11/Xprotostr.h>
+
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#undef NEED_EVENTS
+
+#include "Pcl.h"
+
+#include "windowstr.h"
+#include "attributes.h"
+#include "AttrValid.h"
+#include "Oid.h"
+
+int
+PclStartJob(
+ XpContextPtr pCon,
+ Bool sendClientData,
+ ClientPtr client)
+{
+ PclContextPrivPtr pConPriv =
+ (PclContextPrivPtr)pCon->devPrivates[PclContextPrivateIndex].ptr;
+ PclPaletteMap *pal;
+
+ /*
+ * Check for existing page file, and delete it if it exists.
+ */
+ if(pConPriv->pageFileName != (char *)NULL)
+ {
+ if(pConPriv->pPageFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ }
+ unlink(pConPriv->pageFileName);
+ xfree(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+ }
+
+ /*
+ * Create a temporary file to store the printer output.
+ */
+ if (!XpOpenTmpFile("w+", &pConPriv->jobFileName, &pConPriv->pJobFile))
+ return BadAlloc;
+
+ /*
+ * Create/Initialize the SoftFontInfo structure
+ */
+ pConPriv->pSoftFontInfo = PclCreateSoftFontInfo();
+
+ /*
+ * Set up the colormap handling
+ */
+ pConPriv->palettes = NULL;
+ pConPriv->nextPaletteId = 4;
+ pConPriv->currentPalette = 0;
+
+ pal = &( pConPriv->staticGrayPalette );
+ pal->paletteId = 1;
+ pal->downloaded = 0;
+
+ pal = &( pConPriv->trueColorPalette );
+ pal->paletteId = 2;
+ pal->downloaded = 0;
+
+ pal = &( pConPriv->specialTrueColorPalette );
+ pal->paletteId = 3;
+ pal->downloaded = 0;
+
+ return Success;
+}
+
+int
+PclEndJob(
+ XpContextPtr pCon,
+ Bool cancel)
+{
+ PclContextPrivPtr priv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+#ifdef CCP_DEBUG
+ FILE *xpoutput;
+#endif
+ FILE *fp;
+ int retVal;
+ char *fileName, *trailer;
+ struct stat statBuf;
+ PclPaletteMapPtr p;
+
+ trailer = "\033%-12345X@PJL RESET\n";
+
+ if( cancel == True )
+ {
+ if( priv->getDocClient != (ClientPtr)NULL ) {
+ XpFinishDocData( priv->getDocClient );
+
+ priv->getDocClient = NULL;
+ priv->getDocBufSize = 0;
+ }
+
+ return Success;
+ }
+
+ if( priv->getDocClient != (ClientPtr)NULL && priv->getDocBufSize > 0 )
+ {
+ /*
+ * We need to stash the trailer information somewhere...
+ */
+ if (!XpOpenTmpFile("w+", &fileName, &fp))
+ return BadAlloc;
+
+#ifndef XP_PCL_LJ3
+ SEND_PCL( fp, trailer );
+ rewind( fp );
+
+ retVal = XpSendDocumentData( priv->getDocClient, fp,
+ strlen( trailer ),
+ priv->getDocBufSize );
+#endif /* XP_PCL_LJ3 */
+
+ fclose( fp );
+ unlink( fileName );
+ xfree( fileName );
+
+ if( priv->getDocClient != (ClientPtr)NULL ) {
+ XpFinishDocData( priv->getDocClient );
+
+ priv->getDocClient = NULL;
+ priv->getDocBufSize = 0;
+ }
+
+ return retVal;
+ }
+
+#ifndef XP_PCL_LJ3
+ SEND_PCL( priv->pJobFile, trailer );
+#endif /* XP_PCL_LJ3 */
+
+ /*
+ * Submit the job to the spooler
+ */
+ fflush( priv->pJobFile );
+
+ /*
+ * Dump the job file to another output file, for testing
+ * purposes.
+ */
+ rewind( priv->pJobFile );
+ stat( priv->jobFileName, &statBuf );
+
+#ifdef CCP_DEBUG
+ unlink( "/users/prince/XpOutput" );
+ xpoutput = fopen( "/users/prince/XpOutput", "w" );
+
+ rewind( priv->pJobFile );
+ TransferBytes( priv->pJobFile, xpoutput,
+ (int)statBuf.st_size );
+ fclose( xpoutput );
+#endif
+
+ XpSubmitJob( priv->jobFileName, pCon );
+ fclose( priv->pJobFile );
+ unlink( priv->jobFileName );
+ xfree( priv->jobFileName );
+ priv->jobFileName = NULL;
+
+ PclDestroySoftFontInfo(priv->pSoftFontInfo);
+ priv->pSoftFontInfo = (PclSoftFontInfoPtr) NULL;
+
+ /*
+ * Clear out the colormap cache
+ */
+ p = priv->palettes;
+ while( p )
+ {
+ p->downloaded = 0;
+ p = p->next;
+ }
+
+ return Success;
+}
+
+/* StartPage
+ *
+ * If page file exists
+ * close page file
+ * set page file pointer = NULL
+ * unlink page file
+ * Create a new page file
+ * Send the page header information to the page file
+ * ClearArea the window and all descendant windows
+ */
+int
+PclStartPage(
+ XpContextPtr pCon,
+ WindowPtr pWin)
+{
+ PclContextPrivPtr pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+ PclWindowPrivPtr pWinPriv =
+ (PclWindowPrivPtr)pWin->devPrivates[PclWindowPrivateIndex].ptr;
+ xRectangle repro;
+ char t[80];
+ XpOid orient, plex, tray, medium;
+ int dir, plexNum, num;
+
+ /*
+ * Put a pointer to the context in the window private structure
+ */
+ pWinPriv->validContext = 1;
+ pWinPriv->context = pCon;
+
+ /*
+ * Clear out the old page file, if necessary
+ */
+ if(pConPriv->pPageFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ }
+ if(pConPriv->pageFileName != (char *)NULL)
+ {
+ unlink(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+ }
+
+ /*
+ * Make up a new page file.
+ */
+ if (!XpOpenTmpFile("w+", &pConPriv->pageFileName, &pConPriv->pPageFile))
+ return BadAlloc;
+
+ /*
+ * Reset the GC cached in the context private struct.
+ */
+ pConPriv->validGC = 0;
+
+ /*
+ * Set the page orientation
+ */
+ orient = XpGetContentOrientation( pCon );
+ switch( orient )
+ {
+ case xpoid_val_content_orientation_landscape:
+ dir = 1;
+ break;
+ case xpoid_val_content_orientation_reverse_portrait:
+ dir = 2;
+ break;
+ case xpoid_val_content_orientation_reverse_landscape:
+ dir = 3;
+ break;
+ case xpoid_val_content_orientation_portrait:
+ default:
+ dir = 0;
+ break;
+ }
+ sprintf( t, "\033&l%dO", dir );
+ SEND_PCL( pConPriv->pPageFile, t );
+
+ /*
+ * Set the duplexing method. Since PCL wants to think of it in
+ * terms of the "binding edge," and the attribute store thinks in
+ * "duplex/tumble," this is a little complicated.
+ *
+ * Actually, this has no bearing on the output, since the HP1600C
+ * will only print on one side of the paper, and ignore all
+ * requests to enable duplexing. But, in an attempt to keep this
+ * driver somewhat generic, we'll enable it anyway.
+ */
+ plex = XpGetPlex( pCon );
+
+ if( plex == xpoid_val_plex_duplex )
+ {
+ if( dir == 0 || dir == 2 )
+ plexNum = 1;
+ else
+ plexNum = 2;
+ }
+ else if( plex == xpoid_val_plex_tumble )
+ {
+ if( dir == 0 || dir == 2 )
+ plexNum = 2;
+ else
+ plexNum = 1;
+ }
+ else
+ plexNum = 0;
+ sprintf( t, "\033&l%dS", plexNum );
+ SEND_PCL( pConPriv->pPageFile, t );
+
+ /*
+ * Set the input tray or medium. If XpGetPageSize gives us a valid medium,
+ * we can just send that to the printer, and let the printer handle the
+ * details. Otherwise, we select the tray returned from XpGetPageSize,
+ * which will be either a tray that should contain the correct medium
+ * (possibly with operator intervention), or the default tray from the
+ * config files.
+ */
+ medium = XpGetPageSize( pCon, &tray, NULL );
+ if( medium != xpoid_none )
+ {
+ switch( medium )
+ {
+ case xpoid_val_medium_size_na_legal:
+ num = 3;
+ break;
+ case xpoid_val_medium_size_iso_a3:
+ num = 27;
+ break;
+ case xpoid_val_medium_size_iso_a4:
+ num = 26;
+ break;
+ case xpoid_val_medium_size_executive:
+ num = 1;
+ break;
+ case xpoid_val_medium_size_ledger:
+ num = 6;
+ break;
+ case xpoid_val_medium_size_monarch_envelope:
+ num = 80;
+ break;
+ case xpoid_val_medium_size_na_number_10_envelope:
+ num = 81;
+ break;
+ case xpoid_val_medium_size_iso_designated_long:
+ num = 90;
+ break;
+ case xpoid_val_medium_size_iso_c5:
+ num = 91;
+ break;
+ case xpoid_val_medium_size_iso_b5:
+ num = 100;
+ break;
+ case xpoid_val_medium_size_jis_b5:
+ num = 45;
+ break;
+ case xpoid_val_medium_size_na_letter:
+ default:
+ num = 2;
+ break;
+ }
+ sprintf( t, "\033&l%dA", num );
+ SEND_PCL( pConPriv->pPageFile, t );
+ }
+ else
+ {
+ switch( tray )
+ {
+ case xpoid_val_input_tray_manual:
+ num = 2;
+ break;
+ case xpoid_val_input_tray_envelope:
+ num = 3;
+ break;
+ case xpoid_val_input_tray_large_capacity:
+ num = 5;
+ break;
+ case xpoid_val_input_tray_bottom:
+ num = 4;
+ break;
+ case xpoid_val_input_tray_main:
+ default:
+ num = 1;
+ break;
+ }
+ sprintf( t, "\033&l%dH", num );
+ SEND_PCL( pConPriv->pPageFile, t );
+ }
+
+ /*
+ * Set the scaling factors so that the HP-GL/2 coordinate system
+ * matches the X coordinate system, both in axis orientation and
+ * in unit<->pixel conversion.
+ */
+ XpGetReproductionArea( pCon, &repro );
+
+ sprintf( t, "\033&l0E\033*p%dx%dY", repro.x - 75, repro.y );
+ SEND_PCL( pConPriv->pPageFile, t );
+
+ sprintf( t, "\033*c%dx%dY\033*c0T", (int)(repro.width / 300.0 * 720.0),
+ (int)(repro.height / 300.0 * 720.0) );
+ SEND_PCL( pConPriv->pPageFile, t );
+
+ sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, repro.x +
+ repro.width, repro.y + repro.height, repro.y );
+ SEND_PCL( pConPriv->pPageFile, t );
+
+ return Success;
+}
+
+/*
+ * When sending the generated PCL code back to the client, we send everything
+ * that we have generated so far for the job. After sending the data, we clean
+ * out the job file, to avoid repeatedly sending the same data.
+ */
+
+static int
+SendDocData( PclContextPrivPtr pPriv )
+{
+ struct stat statBuf;
+ int ret;
+
+ rewind( pPriv->pJobFile );
+ if( stat( pPriv->jobFileName, &statBuf ) < 0 )
+ return BadAlloc;
+
+ ret = XpSendDocumentData( pPriv->getDocClient, pPriv->pJobFile,
+ (int)statBuf.st_size, pPriv->getDocBufSize );
+
+ /*
+ * Clean out the job file
+ */
+ fclose( pPriv->pJobFile );
+ unlink( pPriv->jobFileName );
+
+ xfree(pPriv->jobFileName);
+
+ if (!XpOpenTmpFile("w+", &pPriv->jobFileName, &pPriv->pJobFile))
+ return BadAlloc;
+
+ return ret;
+}
+
+/*
+ * EndPage:
+ *
+ * Write page trailer to page file
+ * Write page file to job file
+ */
+int
+PclEndPage(
+ XpContextPtr pCon,
+ WindowPtr pWin)
+{
+ PclContextPrivPtr pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ struct stat statBuf;
+
+ /*
+ * Send the page trailer to the page file.
+ */
+ SEND_PCL( pConPriv->pPageFile, "\014" );
+ fflush( pConPriv->pPageFile );
+
+ /*
+ * Write the page file contents to the job file, or to the
+ * whatever client has called GetDocumentData.
+ *
+ * pWinPriv->pPageFile must first be set to the start of the page file.
+ */
+ rewind(pConPriv->pPageFile);
+ if(stat(pConPriv->pageFileName, &statBuf) < 0)
+ return BadAlloc;
+
+ if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile,
+ (int)statBuf.st_size) != (int)statBuf.st_size)
+ return BadAlloc;
+
+ if( pConPriv->getDocClient != (ClientPtr)NULL &&
+ pConPriv->getDocBufSize > 0 )
+ {
+ return SendDocData( pConPriv );
+ }
+
+ return Success;
+}
+
+/*
+ * The PclStartDoc() and PclEndDoc() functions serve basically as NOOP
+ * placeholders. This driver doesn't deal with the notion of multiple
+ * documents per page.
+ */
+
+int
+PclStartDoc(XpContextPtr pCon,
+ XPDocumentType type)
+{
+ PclContextPrivPtr pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+#ifndef XP_PCL_LJ3
+ /*
+ * Set the printer resolution for the page. Since we can only
+ * render color at 300dpi, we just hard-code this.
+ */
+ SEND_PCL( pConPriv->pJobFile,
+ "\033%-12345X@PJL SET RESOLUTION = 300\r\n" );
+#endif /* XP_PCL_LJ3 */
+
+ /*
+ * Initialize HP-GL/2
+ */
+ SEND_PCL( pConPriv->pJobFile, "\033E\033%0BIN,SP1,TR0;\033%0A" );
+
+ /*
+ * Stash the type of the document (used by PutDocumentData operation)
+ */
+ pConPriv->isRaw = (type == XPDocRaw);
+
+ return Success;
+}
+
+int
+PclEndDoc(
+ XpContextPtr pCon,
+ Bool cancel)
+{
+ /*
+ * XXX What should I do if I get cancel == TRUE?
+ */
+ return Success;
+}
+
+/*
+ * PclDocumentData()
+ *
+ * Hand any pre-generated PDL down to the spool files, formatting it
+ * as necessary to fit the given window.
+ *
+ */
+
+#define DOC_PCL 1
+#define DOC_HPGL 2
+
+int
+PclDocumentData(
+ XpContextPtr pCon,
+ DrawablePtr pDraw,
+ char *pData,
+ int len_data,
+ char *pFmt,
+ int len_fmt,
+ char *pOpt,
+ int len_opt,
+ ClientPtr client)
+{
+ int type = 0;
+ PclContextPrivPtr pPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+ XpOidDocFmtList *formats;
+ XpOidDocFmt *f;
+ char t[80];
+ xRectangle repro;
+
+ /*
+ * Verify the input format
+ */
+ formats = XpGetDocFmtListAttr( pCon, XPPrinterAttr,
+ (pPriv->isRaw) ?
+ xpoid_att_xp_raw_formats_supported :
+ xpoid_att_xp_embedded_formats_supported,
+ NULL );
+ f = XpOidDocFmtNew( pFmt );
+ if( !XpOidDocFmtListHasFmt( formats, f ) )
+ {
+ XpOidDocFmtListDelete( formats );
+ XpOidDocFmtDelete( f );
+ return BadMatch;
+ }
+ XpOidDocFmtListDelete( formats );
+
+ if( !(pPriv->isRaw) )
+ {
+ if( !strcmp( f->format, "PCL" ) )
+ type = DOC_PCL;
+ else if( !strcmp( f->format, "HPGL" ) )
+ type = DOC_HPGL;
+ else
+ {
+ XpOidDocFmtDelete( f );
+ return BadMatch;
+ }
+
+ switch( type )
+ {
+ case DOC_HPGL:
+ /*
+ * Move the picture frame to the appropriate place on the page,
+ * then assume that the embedded code will scale it properly.
+ */
+ sprintf( t, "\033&l0E\033*p%dx%dY",
+ pDraw->x - 75,
+ pDraw->y );
+ SEND_PCL( pPriv->pPageFile, t );
+
+ sprintf( t, "\033*c%dx%dY\033*coT",
+ (int)( pDraw->width / 300.0 * 720.0 ),
+ (int)( pDraw->height / 300.0 * 720.0 ) );
+ SEND_PCL( pPriv->pPageFile, t );
+ break;
+ }
+ }
+
+
+ /*
+ * Send the data down the pipe
+ */
+ SEND_PCL_COUNT( pPriv->pPageFile, pData, len_data );
+
+ /*
+ * If it's not a raw document, clean up the embedding
+ */
+ if( !(pPriv->isRaw) )
+ switch( type )
+ {
+ case DOC_HPGL:
+ /*
+ * Reset the picture frame
+ */
+ XpGetReproductionArea( pCon, &repro );
+
+ sprintf( t, "\033&l0E\033*p%dx%dY", repro.x - 75, repro.y );
+ SEND_PCL( pPriv->pPageFile, t );
+
+ sprintf( t, "\033*c%dx%dY\033*c0T",
+ (int)(repro.width / 300.0 * 720.0),
+ (int)(repro.height / 300.0 * 720.0) );
+ SEND_PCL( pPriv->pPageFile, t );
+
+ sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, repro.x +
+ repro.width, repro.y + repro.height, repro.y );
+ SEND_PCL( pPriv->pPageFile, t );
+ break;
+ }
+
+ XpOidDocFmtDelete( f );
+ return Success;
+}
+
+/*
+ *
+ * PclGetDocumentData()
+ *
+ * This function allows the driver to send the generated PCL back to
+ * the client.
+ *
+ * XXX This function is barely spec'ed, much less implemented!
+ */
+
+int
+PclGetDocumentData(
+ XpContextPtr pCon,
+ ClientPtr client,
+ int maxBufferSize)
+{
+ PclContextPrivPtr pPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+
+ pPriv->getDocClient = client;
+ pPriv->getDocBufSize = maxBufferSize;
+
+ return Success;
+}
diff --git a/hw/xprint/pcl/PclSFonts.c b/hw/xprint/pcl/PclSFonts.c
new file mode 100644
index 000000000..287c5c14f
--- /dev/null
+++ b/hw/xprint/pcl/PclSFonts.c
@@ -0,0 +1,429 @@
+/* $Xorg: PclSFonts.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclSFonts.c
+** *
+** * Contents:
+** * Send Soft Font Download data to the specified
+** * file pointer.
+** *
+** * Created: 3/4/96
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclSFonts.c,v 1.7tsi Exp $ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include "Pcl.h"
+
+static char tmp1;
+static short tmp2;
+#define Put1byte(fp, x) tmp1=x; fwrite((char *)&tmp1, 1, 1, fp)
+#define Put2bytes(fp, x) tmp2=x; fwrite((char *)&tmp2, 2, 1, fp)
+
+#define ESC 0x1b
+#define SYMBOL_SET 277
+
+static unsigned int PclDownloadChar(FILE *,PclCharDataPtr,unsigned short,unsigned char);
+static unsigned int PclDownloadHeader(FILE *, PclFontDescPtr, unsigned short);
+
+#ifdef PCL_FONT_COMPRESS
+static unsigned char *compress_bitmap_data(PclCharDataPtr, unsigned int *);
+#endif /* PCL_FONT_COMPRESS */
+
+/* -*- PclDownloadSoftFont8 -*-
+ * Send the Character Definition Command for 8-bit font
+ * **************************************************************************/
+void
+PclDownloadSoftFont8(
+ FILE *fp,
+ PclSoftFontInfoPtr pSoftFontInfo,
+ PclFontHead8Ptr pfh,
+ PclCharDataPtr pcd,
+ unsigned char *code
+)
+{
+ /*
+ * Check whether the font header has already been downloaded.
+ * If not, download it.
+ */
+
+ if ( !pfh->fid ) {
+ pfh->fid = pSoftFontInfo->cur_max_fid++;
+ PclDownloadHeader(fp, &(pfh->fd), pfh->fid);
+ }
+ pfh->index[*code] = *code;
+ PclDownloadChar(fp, pcd, pfh->fid, pfh->index[*code]);
+
+}
+
+/* -*- PclDownloadSoftFont16 -*-
+ * Send the Character Definition Command for 16 bit font
+ * **************************************************************************/
+void
+PclDownloadSoftFont16(
+ FILE *fp,
+ PclSoftFontInfoPtr pSoftFontInfo,
+ PclFontHead16Ptr pfh,
+ PclCharDataPtr pcd,
+ unsigned char row,
+ unsigned char col
+)
+{
+ /*
+ * Check whether the font header is already downloaded.
+ * If not, download it.
+ */
+
+ if ( !pfh->cur_cindex ) {
+ pfh->cur_fid = pSoftFontInfo->cur_max_fid++;
+ PclDownloadHeader(fp, &(pfh->fd), pfh->cur_fid);
+ }
+ pfh->index[row][col].fid = pfh->cur_fid;
+ pfh->index[row][col].cindex = pfh->cur_cindex++;
+
+ PclDownloadChar(fp, pcd, pfh->index[row][col].fid, pfh->index[row][col].cindex);
+}
+
+/* -*- PclCreateSoftFontInfo -*-
+ * Create and Initialize the structure for storing the information
+ * of the downloaded soft font.
+ * **************************************************************************/
+PclSoftFontInfoPtr
+PclCreateSoftFontInfo(void)
+{
+PclSoftFontInfoPtr pSoftFontInfo;
+
+ pSoftFontInfo = (PclSoftFontInfoPtr)xalloc(sizeof(PclSoftFontInfoRec));
+ if ( pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
+ return (PclSoftFontInfoPtr) NULL;
+ pSoftFontInfo->phead8 = (PclFontHead8Ptr)NULL;
+ pSoftFontInfo->phead16 = (PclFontHead16Ptr)NULL;
+ pSoftFontInfo->pinfont = (PclInternalFontPtr)NULL;
+ pSoftFontInfo->cur_max_fid = 1;
+ return pSoftFontInfo;
+}
+
+/* -*- PclDestroySoftFontInfo -*-
+ * Destroy the soft font information structure
+ * **************************************************************************/
+void
+PclDestroySoftFontInfo( PclSoftFontInfoPtr pSoftFontInfo )
+{
+PclFontHead8Ptr pfh8, pfh8_next;
+PclFontHead16Ptr pfh16, pfh16_next;
+PclInternalFontPtr pin, pin_next;
+unsigned char nindex_row;
+int i;
+
+ if ( pSoftFontInfo == (PclSoftFontInfoPtr) NULL )
+ return;
+
+ pfh8 = pSoftFontInfo->phead8;
+ while (pfh8 != (PclFontHead8Ptr) NULL) {
+ xfree(pfh8->fontname);
+ xfree(pfh8->index);
+ pfh8_next = pfh8->next;
+ xfree(pfh8);
+ pfh8 = pfh8_next;
+ }
+
+ pfh16 = pSoftFontInfo->phead16;
+ while (pfh16 != (PclFontHead16Ptr) NULL) {
+ xfree(pfh16->fontname);
+ nindex_row = pfh16->lastRow - pfh16->firstRow + 1;
+ for (i=0; i<nindex_row; i++)
+ xfree(pfh16->index[i]);
+ xfree(pfh16->index);
+ pfh16_next = pfh16->next;
+ xfree(pfh16);
+ pfh16 = pfh16_next;
+ }
+
+ pin = pSoftFontInfo->pinfont;
+ while (pin != (PclInternalFontPtr) NULL) {
+ xfree(pin->fontname);
+ pin_next = pin->next;
+ xfree(pin);
+ pin = pin_next;
+ }
+
+ xfree(pSoftFontInfo);
+}
+
+/* -*- PclDownloadHeader -*-
+ * Send the Font Header Commnad.
+ * Format 0 : Font Header for Pcl Bitmapped Fonts
+ * Format 20 : Font Header for Resolution Specified Bitmapped Fonts
+ * **************************************************************************/
+static unsigned int
+PclDownloadHeader(
+ FILE *fp,
+ PclFontDescPtr fd,
+ unsigned short fid
+)
+{
+int nbytes;
+
+#ifdef XP_PCL_LJ3
+ nbytes = 64;
+#else
+ nbytes = 68;
+#endif /* XP_PCL_LJ3 */
+ /*
+ * Font ID Command : Esc *c#D
+ * (Default = 0, Range = 0 - 32767)
+ */
+ fprintf(fp, "%c*c%dD", ESC, fid);
+
+ /*
+ * Font Header Commnad : Esc )s#W[font header data]
+ * (Default = 0, Range = 0 - 32767)
+ */
+ fprintf(fp, "%c)s%dW", ESC, nbytes);
+
+ Put2bytes(fp, nbytes); /* Font Description Size */
+#ifdef XP_PCL_LJ3
+ Put1byte(fp, 0); /* Header Format */
+#else
+ Put1byte(fp, 20); /* Header Format */
+#endif /* XP_PCL_LJ3 */
+ Put1byte(fp, 2); /* Font Type */
+ Put2bytes(fp, 0); /* Style MSB */
+ Put2bytes(fp, fd->ascent); /* BaseLine Position */
+ Put2bytes(fp, fd->cellwidth); /* Cell Width */
+ Put2bytes(fp, fd->cellheight); /* Cell Height */
+ Put1byte(fp, 0); /* Orienation */
+ Put1byte(fp, fd->spacing); /* Spacing */
+ Put2bytes(fp, SYMBOL_SET); /* Symbol Set */
+ Put2bytes(fp, fd->pitch*4); /* font pitch */
+ Put2bytes(fp, fd->cellheight * 4); /* Height */
+ Put2bytes(fp, 0); /* x-Height */
+ Put1byte(fp, 0); /* width type (normal) */
+ Put1byte(fp, 0); /* Style LSB */
+ Put1byte(fp, 0); /* Stroke Weight */
+ Put1byte(fp, 5); /* Typeface LSB */
+ Put1byte(fp, 0); /* Typeface MSB */
+ Put1byte(fp, 0); /* Serif Style */
+ Put1byte(fp, 0); /* Quality */
+ Put1byte(fp, 0); /* Placement */
+ Put1byte(fp, 0); /* Underline Position */
+ Put1byte(fp, 0); /* Underline Thickness */
+ Put2bytes(fp, fd->cellheight*1.2); /* Text Height */
+ Put2bytes(fp, fd->cellwidth * 4); /* Text Width */
+ Put2bytes(fp, 0); /* First Code */
+ Put2bytes(fp, 255); /* Last Code */
+ Put1byte(fp, 0); /* Pitch Extend */
+ Put1byte(fp, 0); /* Height Extend */
+ Put2bytes(fp, 0); /* Cap Height */
+ Put2bytes(fp, 0); /* Font Number 1 */
+ Put2bytes(fp, 0); /* Font Number 2 */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+ Put2bytes(fp, 0); /* Font Name */
+
+#ifdef XP_PCL_LJ3
+ return 64;
+#else
+ Put2bytes(fp, 300); /* X Resolution */
+ Put2bytes(fp, 300); /* Y Resolution */
+ return 68;
+#endif /* XP_PCL_LJ3 */
+
+}
+
+/* -*- PclDownloadCharacter -*-
+ * Send the Character Definition Command.
+ * **************************************************************************/
+static unsigned int
+PclDownloadChar(
+ FILE *fp,
+ PclCharDataPtr cd,
+ unsigned short fid,
+ unsigned char code
+)
+{
+unsigned int nbytes, n;
+unsigned char *raster;
+
+ /*
+ * Font ID Command : Esc *c#D
+ * (Default = 0, Range = 0 - 32767)
+ * Character Code Command : Esc *c#E
+ * (Default = 0, Range = 0 - 65535)
+ */
+ fprintf(fp, "%c*c%dd%dE", ESC, fid, code);
+
+ /*
+ * Character Definition Command : Esc (s#W[character descriptor and data]
+ * (Default = N/A, Range = 0 - 32767)
+ */
+
+ nbytes = n = cd->height * ((cd->width + 7) / 8);
+#ifdef PCL_FONT_COMPRESS
+ raster = compress_bitmap_data(cd, &nbytes);
+#else
+ raster = (unsigned char *)NULL;
+#endif /* PCL_FONT_COMPRESS */
+ fprintf(fp, "%c(s%dW", ESC, nbytes + 16);
+
+ Put1byte(fp, 4); /* Format */
+ Put1byte(fp, 0); /* Continuation */
+ Put1byte(fp, 14); /* Descriptor Size */
+ if (raster) { /* Class */
+ Put1byte(fp, 2);
+ } else {
+ Put1byte(fp, 1); /* Class */
+ }
+ Put2bytes(fp, 0); /* Orientation */
+ Put2bytes(fp, cd->h_offset); /* left offset */
+ Put2bytes(fp, cd->v_offset); /* top offset */
+ Put2bytes(fp, cd->width); /* character width */
+ Put2bytes(fp, cd->height); /* character height */
+ Put2bytes(fp, cd->font_pitch*4); /* delta X */
+
+ /*
+ * Raster Character Data
+ */
+ if (raster) {
+ fwrite(raster, nbytes, 1, fp);
+ xfree(raster);
+ } else
+ fwrite(cd->raster_top, nbytes, 1, fp);
+
+ return n + 16;
+}
+
+
+#ifdef PCL_FONT_COMPRESS
+/* -*- compress_bitmap_data -*-
+ * Compress Bitmap data
+ * **************************************************************************/
+static unsigned char *
+compress_bitmap_data(
+ PclCharDataPtr cd,
+ unsigned int *nbytes
+)
+{
+unsigned int byte_width;
+unsigned char *raster, *rptr_s, *rptr_e, *rptr_end;
+unsigned char *tmp_s, *tmp_ptr;
+unsigned char *p;
+unsigned char cur, pixel;
+unsigned int num;
+
+int i, j, k, w;
+
+ byte_width = (cd->width + 7) / 8;
+ *nbytes = cd->height * byte_width;
+
+ /* Create buffer for storing compress bitmap glyph */
+ raster = (unsigned char *)xalloc(*nbytes);
+ rptr_s = raster;
+ rptr_e = raster;
+ rptr_end = raster + *nbytes;
+
+ tmp_s = (unsigned char *)xalloc(cd->width * 8 + 2);
+
+ p = cd->raster_top;
+ for (i=0; i<cd->height; i++) {
+ tmp_ptr = tmp_s;
+ *tmp_ptr++ = 0;
+ if ( (*p>>7)&0x1 == 1 ) {
+ *tmp_ptr++ = 0;
+ cur = 1;
+ } else {
+ cur = 0;
+ }
+ num = 0;
+ for (j=0, w=0; j<byte_width; j++, p++) {
+ for (k=0; k<8 && w<cd->width; k++, w++) {
+ pixel = (*p>>(7-k))&0x1;
+ if ( pixel == cur ) {
+ num++;
+ } else {
+ cur = pixel;
+ while (num > 255) {
+ *tmp_ptr++ = 255;
+ *tmp_ptr++ = 0;
+ num -= 255;
+ }
+ *tmp_ptr++ = num;
+ num = 1;
+ }
+ }
+ }
+ if ( pixel == cur ) {
+ while (num > 255) {
+ *tmp_ptr++ = 255;
+ *tmp_ptr++ = 0;
+ num -= 255;
+ }
+ *tmp_ptr++ = num&0xff;
+ } else
+ *tmp_ptr++ = num;
+
+ if ( ((rptr_e - rptr_s) == (tmp_ptr - tmp_s)) &&
+ !memcmp(rptr_s+1, tmp_s+1, (tmp_ptr - tmp_s) - 1) )
+ *rptr_s += 1;
+ else {
+ if ( rptr_e + (tmp_ptr - tmp_s) > rptr_end ) {
+ xfree(raster);
+ xfree(tmp_s);
+ return (unsigned char *)NULL;
+ }
+ memcpy (rptr_e, tmp_s, tmp_ptr - tmp_s);
+ rptr_s = rptr_e;
+ rptr_e = rptr_s + (tmp_ptr - tmp_s);
+ }
+ }
+ xfree(tmp_s);
+ *nbytes = rptr_e - raster;
+
+ return raster;
+}
+#endif /* PCL_FONT_COMPRESS */
diff --git a/hw/xprint/pcl/PclSFonts.h b/hw/xprint/pcl/PclSFonts.h
new file mode 100644
index 000000000..fdd62f651
--- /dev/null
+++ b/hw/xprint/pcl/PclSFonts.h
@@ -0,0 +1,116 @@
+/* $Xorg: PclSFonts.h,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PCLFONTS_H
+#define _PCLFONTS_H
+
+/* -*-H-*-
+******************************************************************************
+******************************************************************************
+*
+* File: PclFonts.h
+* Description: Send Soft Font Download data to the specified file pointer.
+*
+*
+******************************************************************************
+******************************************************************************
+*/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+
+typedef struct {
+ unsigned char fid; /* sfont font ID */
+ unsigned char cindex; /* character indext */
+} PclFontMapRec, PclFontMapPtr;
+
+typedef struct {
+ int h_offset;
+ int v_offset;
+ unsigned int width;
+ unsigned int height;
+ int font_pitch;
+ unsigned char *raster_top;
+} PclCharDataRec, *PclCharDataPtr;
+
+typedef struct {
+ unsigned char spacing;
+ unsigned int pitch;
+ unsigned int cellheight;
+ unsigned int cellwidth;
+ int ascent;
+ int descent;
+} PclFontDescRec, *PclFontDescPtr;
+
+typedef struct _PclFontHead8Rec {
+ char *fontname;
+ PclFontDescRec fd;
+ unsigned short fid;
+ unsigned char *index;
+ struct _PclFontHead8Rec *next;
+} PclFontHead8Rec, *PclFontHead8Ptr;
+
+typedef struct _PclFontHead16Rec {
+ char *fontname;
+ PclFontDescRec fd;
+ unsigned short cur_fid;
+ unsigned char cur_cindex;
+ PclFontMapRec **index;
+ unsigned short firstCol;
+ unsigned short lastCol;
+ unsigned short firstRow;
+ unsigned short lastRow;
+ struct _PclFontHead16Rec *next;
+} PclFontHead16Rec, *PclFontHead16Ptr;
+
+typedef struct _PclInternalFontRec {
+ char *fontname;
+ float pitch;
+ float height;
+ char *pcl_font_name;
+ char *spacing;
+ struct _PclInternalFontRec *next;
+} PclInternalFontRec, *PclInternalFontPtr;
+
+typedef struct {
+ PclFontHead8Ptr phead8;
+ PclFontHead16Ptr phead16;
+ PclInternalFontPtr pinfont;
+ unsigned char cur_max_fid;
+} PclSoftFontInfoRec, *PclSoftFontInfoPtr;
+
+#define MONOSPACE 0
+#define PROPSPACE 1
+
+#endif /* _PCLFONTS_H */
diff --git a/hw/xprint/pcl/PclSpans.c b/hw/xprint/pcl/PclSpans.c
new file mode 100644
index 000000000..51c0137fc
--- /dev/null
+++ b/hw/xprint/pcl/PclSpans.c
@@ -0,0 +1,139 @@
+/* $Xorg: PclSpans.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclSpans.c
+** *
+** * Contents:
+** * Code to set and fill spans in the PCL DDX
+** *
+** * Created: 10/23/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclSpans.c,v 1.5 1999/12/13 02:12:57 robin Exp $ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Pcl.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PclFillSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSpans,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int fSorted)
+{
+ char t[80];
+ FILE *outFile;
+ int xoffset, yoffset;
+ xRectangle *rects, *r;
+ RegionPtr fillRegion, region = 0;
+ int i;
+ int nbox;
+ BoxPtr pbox;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return;
+
+ /*
+ * Build a region out of the spans
+ */
+ rects = (xRectangle *)xalloc( nSpans * sizeof( xRectangle ) );
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ for( i = 0, r = rects; i < nSpans; i++, r++ )
+ {
+ r->x = pPoints[i].x + xoffset;
+ r->y = pPoints[i].y + yoffset;
+ r->width = pWidths[i];
+ r->height = 1;
+ }
+ fillRegion = RECTS_TO_REGION( pGC->pScreen, nSpans, rects, ( fSorted ) ?
+ CT_YSORTED : CT_UNSORTED );
+
+ /*
+ * Intersect this region with the clip region. Whatever's left,
+ * should be filled.
+ */
+ REGION_INTERSECT( pGC->pScreen, region, fillRegion, pGC->clientClip );
+
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ /* Enter HP-GL/2 */
+ SEND_PCL( outFile, "\27%0B" );
+
+ while( nbox )
+ {
+ sprintf( t, "PU%d,%d;RR%d,%d;", pbox->x1, pbox->y1,
+ pbox->x2, pbox->y2 );
+ SEND_PCL( outFile, t );
+
+ nbox--;
+ pbox++;
+ }
+
+ /* Go back to PCL */
+ SEND_PCL( outFile, "\27%0A" );
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, fillRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+ xfree( rects );
+}
+
+void
+PclSetSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pSrc,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int nSpans,
+ int fSorted)
+{
+}
diff --git a/hw/xprint/pcl/PclText.c b/hw/xprint/pcl/PclText.c
new file mode 100644
index 000000000..be794772c
--- /dev/null
+++ b/hw/xprint/pcl/PclText.c
@@ -0,0 +1,936 @@
+/* $Xorg: PclText.c,v 1.5 2001/03/06 16:28:48 pookie Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclText.c
+** *
+** * Contents:
+** * Character-drawing routines for the PCL DDX
+** *
+** * Created: 10/23/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclText.c,v 1.10tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef DO_TWO_BYTE_PCL
+#include "iconv.h"
+#endif /* DO_TWO_BYTE_PCL */
+#include "gcstruct.h"
+#include "windowstr.h"
+
+#include "Pcl.h"
+#include "migc.h"
+#include <X11/Xatom.h>
+
+#include "PclSFonts.h"
+
+static PclFontHead8Ptr makeFontHeader8 (FontPtr, PclSoftFontInfoPtr);
+static PclFontHead16Ptr makeFontHeader16(FontPtr, PclSoftFontInfoPtr);
+static PclInternalFontPtr makeInternalFont(FontPtr, PclSoftFontInfoPtr);
+static void fillFontDescData(FontPtr, PclFontDescPtr, unsigned int);
+static PclCharDataPtr fillCharDescData(PclCharDataPtr, CharInfoPtr);
+static void output_text(FILE *, PclContextPrivPtr, unsigned char);
+static char * getFontName(FontPtr);
+static char isInternal(FontPtr);
+static void selectInternalFont(FILE *, PclInternalFontPtr, int);
+static void selectSize(FILE *, PclContextPrivPtr, PclInternalFontPtr);
+static char t[80];
+
+#ifdef DO_TWO_BYTE_PCL
+static void code_conv(PclSoftFontInfoPtr, FontPtr, char *, char *);
+#endif /* DO_TWO_BYTE_PCL */
+
+#define ESC 0x1b
+#define PER 0x25
+#define ETX 0x3
+#define ETX_ALT 0x2a
+#define DOWNLOAD_FONT 0
+#define INTERNAL_FONT 1
+
+int
+PclPolyText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *string)
+{
+XpContextPtr pCon;
+PclContextPrivPtr pConPriv;
+unsigned long n, i;
+int w;
+CharInfoPtr charinfo[255], *chinfo;
+
+FILE *outFile;
+PclSoftFontInfoPtr pSoftFontInfo;
+PclFontHead8Ptr pfh8 = (PclFontHead8Ptr)NULL;
+PclInternalFontPtr pin = (PclInternalFontPtr)NULL;
+PclCharDataRec cd;
+unsigned char *p;
+unsigned char last_fid;
+int max_ascent, max_descent;
+
+int nbox;
+BoxPtr pbox;
+BoxRec box;
+RegionPtr drawRegion, region;
+char font_type;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return x;
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
+ Linear8Bit, &n, charinfo);
+ if ( n == 0 )
+ return x;
+
+ pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+ pSoftFontInfo = pConPriv->pSoftFontInfo;
+ font_type = isInternal(pGC->font);
+ if ( font_type == DOWNLOAD_FONT ) {
+ /*
+ * Create Soft Font Header Information
+ */
+ pfh8 = makeFontHeader8(pGC->font, pSoftFontInfo);
+ if (!pfh8)
+ return x;
+
+ /*
+ * exec Soft Font Downloading
+ */
+ p = (unsigned char *)string;
+ for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
+ if ( !pfh8->index[*p] ) {
+ fillCharDescData(&cd, *chinfo);
+ PclDownloadSoftFont8(pConPriv->pJobFile, pSoftFontInfo,
+ pfh8, &cd, p);
+ xfree(cd.raster_top);
+ }
+ }
+
+ /*
+ * print characters
+ */
+ MACRO_START( outFile, pConPriv );
+ sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
+ x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
+ ETX);
+ SAVE_PCL( outFile, pConPriv, t );
+ SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
+
+ last_fid = 0;
+ w = 0;
+ max_ascent = charinfo[0]->metrics.ascent;
+ max_descent = charinfo[0]->metrics.descent;
+ p = (unsigned char *)string;
+ for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
+ if ( last_fid != pfh8->fid ) {
+ sprintf(t, "%c;FI%d;SS;LB", ETX, pfh8->fid);
+ SAVE_PCL( outFile, pConPriv, t );
+
+ last_fid = pfh8->fid;
+ }
+
+ output_text(outFile, pConPriv, pfh8->index[*p]);
+
+ w += (*chinfo)->metrics.characterWidth;
+ max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
+ max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
+ }
+
+ sprintf(t, "%c", ETX);
+ SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
+ sprintf(t, "TD0;\033%%1A");
+ SAVE_PCL( outFile, pConPriv, t );
+ MACRO_END( outFile );
+
+ } else {
+ int fid = 0;
+
+ pin = makeInternalFont(pGC->font, pSoftFontInfo);
+ if (!pin)
+ return x;
+
+ selectInternalFont(outFile, pin, fid);
+
+ /*
+ * print characters
+ */
+ MACRO_START( outFile, pConPriv );
+ sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
+ x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
+ ETX);
+ SAVE_PCL( outFile, pConPriv, t );
+ selectSize(outFile, pConPriv, pin);
+ SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
+
+ w = 0;
+ max_ascent = charinfo[0]->metrics.ascent;
+ max_descent = charinfo[0]->metrics.descent;
+ p = (unsigned char *)string;
+ for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) {
+ output_text(outFile, pConPriv, *p);
+
+ w += (*chinfo)->metrics.characterWidth;
+ max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
+ max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
+ }
+ sprintf(t, "%c", ETX);
+ SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
+ sprintf(t, "TD0;\033%%1A");
+ SAVE_PCL( outFile, pConPriv, t );
+ MACRO_END( outFile );
+ }
+
+ /*
+ * Convert the collection of rectangles into a proper region, then
+ * intersect it with the clip region.
+ */
+ box.x1 = x + pDrawable->x;
+ box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent;
+ box.x2 = x + w + pDrawable->x;
+ box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent;
+
+ drawRegion = miRegionCreate( &box, 0 );
+ region = miRegionCreate( NULL, 0 );
+ miIntersect( region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the entire polyline to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+
+ return x+w;
+}
+
+int
+PclPolyText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *string)
+{
+XpContextPtr pCon;
+PclContextPrivPtr pConPriv;
+unsigned long n, i;
+int w;
+CharInfoPtr charinfo[255], *chinfo;
+
+FILE *outFile;
+PclSoftFontInfoPtr pSoftFontInfo;
+PclFontHead16Ptr pfh16 = (PclFontHead16Ptr)NULL;
+PclCharDataRec cd;
+FontInfoPtr pfi;
+unsigned char row, col;
+char *p;
+unsigned char last_fid;
+int max_ascent, max_descent;
+unsigned short def;
+
+int nbox;
+BoxPtr pbox;
+BoxRec box;
+RegionPtr drawRegion, region;
+char font_type;
+
+ if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
+ return x;
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+
+ pCon = PclGetContextFromWindow( (WindowPtr)pDrawable );
+ pConPriv = (PclContextPrivPtr)
+ pCon->devPrivates[PclContextPrivateIndex].ptr;
+ pSoftFontInfo = pConPriv->pSoftFontInfo;
+
+ font_type = isInternal(pGC->font);
+ if ( font_type == DOWNLOAD_FONT ) {
+ /*
+ * Create Soft Font Header Information
+ */
+ pfh16 = makeFontHeader16(pGC->font, pSoftFontInfo);
+ if (!pfh16)
+ return x;
+
+ /*
+ * exec Soft Font Downloading
+ */
+ pfi = (FontInfoRec *)&pGC->font->info;
+ p = (char *)string;
+ for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
+ row = *p & 0xff;
+ col = *(p+1) & 0xff;
+ if ( (pfi->firstRow <= row) && (row <= pfi->lastRow)
+ && (pfi->firstCol <= col) && (col <= pfi->lastCol) ) {
+ row = row - pfi->firstRow;
+ col = col - pfi->firstCol;
+ } else {
+ def = pfi->defaultCh;
+ row = ((def>>8)&0xff) - pfi->firstRow;
+ col = (def&0xff) - pfi->firstCol;
+ }
+ if ( !pfh16->index[row][col].fid ) {
+ fillCharDescData(&cd, *chinfo);
+ PclDownloadSoftFont16(pConPriv->pJobFile, pSoftFontInfo,
+ pfh16, &cd, row, col);
+ xfree(cd.raster_top);
+ }
+ }
+
+ /*
+ * print characters
+ */
+ MACRO_START( outFile, pConPriv );
+ sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
+ x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
+ ETX);
+ SAVE_PCL( outFile, pConPriv, t );
+ SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 );
+
+ last_fid = 0;
+
+ w = 0;
+ max_ascent = charinfo[0]->metrics.ascent;
+ max_descent = charinfo[0]->metrics.descent;
+ for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
+ row = *p & 0xff;
+ col = *(p+1) & 0xff;
+ if ( (pfi->firstRow <= row) && (row <= pfi->lastRow)
+ && (pfi->firstCol <= col) && (col <= pfi->lastCol) ) {
+ row = row - pfi->firstRow;
+ col = col - pfi->firstCol;
+ } else {
+ def = pfi->defaultCh;
+ row = ((def>>8)&0xff) - pfi->firstRow;
+ col = (def&0xff) - pfi->firstCol;
+ }
+ if ( last_fid != pfh16->index[row][col].fid ) {
+ sprintf(t, "%cFI%d;SS;LB",
+ ETX, pfh16->index[row][col].fid);
+ SAVE_PCL( outFile, pConPriv, t );
+ last_fid = pfh16->index[row][col].fid;
+ }
+
+ output_text(outFile, pConPriv, pfh16->index[row][col].cindex);
+
+ w += (*chinfo)->metrics.characterWidth;
+ max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
+ max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
+ }
+ sprintf(t, "%c", ETX);
+ SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
+ sprintf(t, "TD0;\033%%1A");
+ SAVE_PCL( outFile, pConPriv, t );
+ MACRO_END( outFile );
+
+ } else {
+#ifdef DO_TWO_BYTE_PCL
+ PclInternalFontPtr pin;
+ int fid = 0;
+
+ pin = makeInternalFont(pGC->font, pSoftFontInfo);
+ if (!pin)
+ return x;
+
+ selectInternalFont(outFile, pin, fid);
+ fprintf(outFile, "%c&t31P", ESC);
+
+ /*
+ * print characters
+ */
+ MACRO_START( outFile, pConPriv );
+ sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;",
+ x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent,
+ ETX);
+ SAVE_PCL( outFile, pConPriv, t );
+ sprintf(t, "TD0;\033%%1A");
+ SAVE_PCL( outFile, pConPriv, t );
+
+ w = 0;
+ last_fid = 0;
+ max_ascent = charinfo[0]->metrics.ascent;
+ max_descent = charinfo[0]->metrics.descent;
+ for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) {
+ char tobuf[3];
+ code_conv(pSoftFontInfo, pGC->font, (char *)p, tobuf);
+ fprintf(outFile, "%c%c", tobuf[0], tobuf[1]);
+
+ w += (*chinfo)->metrics.characterWidth;
+ max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent);
+ max_descent = MAX(max_descent, (*chinfo)->metrics.descent);
+ }
+ MACRO_END( outFile );
+#else
+ return x;
+#endif /* DO_TWO_BYTE_PCL */
+ }
+
+ /*
+ * Convert the collection of rectangles into a proper region, then
+ * intersect it with the clip region.
+ */
+ box.x1 = x + pDrawable->x;
+ box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent;
+ box.x2 = x + w + pDrawable->x;
+ box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent;
+
+ drawRegion = miRegionCreate( &box, 0 );
+ region = miRegionCreate( NULL, 0 );
+ miIntersect( region, drawRegion, pGC->pCompositeClip );
+
+ /*
+ * For each rectangle in the clip region, set the HP-GL/2 "input
+ * window" and render the entire polyline to it.
+ */
+ pbox = REGION_RECTS( region );
+ nbox = REGION_NUM_RECTS( region );
+
+ PclSendData(outFile, pConPriv, pbox, nbox, 1.0);
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY( pGC->pScreen, drawRegion );
+ REGION_DESTROY( pGC->pScreen, region );
+
+ return x+w;
+}
+
+void
+PclImageText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *string)
+{
+}
+
+void
+PclImageText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *string)
+{
+}
+
+void
+PclImageGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nGlyphs,
+ CharInfoPtr *pCharInfo,
+ pointer pGlyphBase)
+{
+}
+
+void
+PclPolyGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nGlyphs,
+ CharInfoPtr *pCharInfo,
+ pointer pGlyphBase)
+{
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static PclFontHead8Ptr
+makeFontHeader8(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
+{
+PclFontHead8Ptr phead8 = pSoftFontInfo->phead8;
+PclFontHead8Ptr pfh8 = phead8;
+PclFontHead8Ptr prev = (PclFontHead8Ptr)NULL;
+FontInfoPtr pfi;
+char *fontname;
+unsigned char nindex;
+int i;
+unsigned long n;
+CharInfoPtr charinfo[1];
+unsigned int space_width;
+
+ if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
+ return (PclFontHead8Ptr)NULL;
+
+ /*
+ * Verify it has already been created, if so, return it.
+ */
+ if ( (fontname = getFontName(pfont)) == (char *)NULL)
+ return (PclFontHead8Ptr)NULL;
+
+ while (pfh8 != (PclFontHead8Ptr) NULL) {
+ if (!strcmp(pfh8->fontname, fontname))
+ return pfh8;
+ prev = pfh8;
+ pfh8 = pfh8->next;
+ }
+
+ /*
+ * Create Font Header Information
+ */
+ pfh8 = (PclFontHead8Ptr)xalloc(sizeof(PclFontHead8Rec));
+ if (pfh8 == (PclFontHead8Ptr)NULL)
+ return (PclFontHead8Ptr)NULL;
+
+ pfi = (FontInfoRec *)&pfont->info;
+ GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh,
+ Linear8Bit, &n, charinfo);
+ if ( n )
+ space_width = charinfo[0]->metrics.characterWidth;
+ else
+ space_width = FONTMAXBOUNDS(pfont,characterWidth);
+
+ fillFontDescData(pfont, &(pfh8->fd), space_width);
+ pfh8->fid = 0;
+ pfh8->fontname = (char *)xalloc(strlen(fontname) + 1);
+ if (pfh8->fontname == (char *)NULL) {
+ xfree(pfh8);
+ return (PclFontHead8Ptr) NULL;
+ }
+ strcpy(pfh8->fontname, fontname);
+
+ nindex = 0xff;
+ pfh8->index = (unsigned char *)xalloc(nindex);
+ if ( pfh8->index == (unsigned char *) NULL ) {
+ xfree(pfh8->fontname);
+ xfree(pfh8);
+ return (PclFontHead8Ptr) NULL;
+ }
+
+ for (i=0; i<=nindex; i++)
+ pfh8->index[i] = 0x0;
+
+ pfh8->next = (PclFontHead8Ptr)NULL;
+
+ if ( prev == (PclFontHead8Ptr) NULL)
+ pSoftFontInfo->phead8 = pfh8;
+ else
+ prev->next = pfh8;
+
+ return pfh8;
+}
+
+static PclFontHead16Ptr
+makeFontHeader16(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
+{
+PclFontHead16Ptr phead16 = pSoftFontInfo->phead16;
+PclFontHead16Ptr pfh16 = phead16;
+PclFontHead16Ptr prev = (PclFontHead16Ptr)NULL;
+PclFontMapRec ** index;
+FontInfoPtr pfi;
+char *fontname;
+unsigned char nindex_row, nindex_col;
+int i, j;
+unsigned long n;
+CharInfoPtr charinfo[1];
+unsigned int space_width;
+
+ if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
+ return (PclFontHead16Ptr)NULL;
+
+ /*
+ * Verify it has already been created, if so, return it.
+ */
+ if ( (fontname = getFontName(pfont)) == (char *)NULL)
+ return (PclFontHead16Ptr)NULL;
+
+ while (pfh16 != (PclFontHead16Ptr) NULL) {
+ if (!strcmp(pfh16->fontname, fontname))
+ return pfh16;
+ prev = pfh16;
+ pfh16 = pfh16->next;
+ }
+
+ /*
+ * Create Font Header Information
+ */
+ pfh16 = (PclFontHead16Ptr)xalloc(sizeof(PclFontHead16Rec));
+ if (pfh16 == (PclFontHead16Ptr)NULL)
+ return (PclFontHead16Ptr)NULL;
+
+ pfi = (FontInfoRec *)&pfont->info;
+ GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh,
+ (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+
+ if ( n )
+ space_width = charinfo[0]->metrics.characterWidth;
+ else
+ space_width = FONTMAXBOUNDS(pfont,characterWidth);
+
+ fillFontDescData(pfont, &(pfh16->fd), space_width);
+ pfh16->cur_fid = 0;
+ pfh16->cur_cindex = 0;
+ pfh16->fontname = (char *)xalloc(strlen(fontname) + 1);
+ if (pfh16->fontname == (char *)NULL) {
+ xfree(pfh16);
+ return (PclFontHead16Ptr) NULL;
+ }
+ strcpy(pfh16->fontname, fontname);
+
+ pfi = (FontInfoRec *)&pfont->info;
+ nindex_col = pfi->lastCol - pfi->firstCol + 1;
+ nindex_row = pfi->lastRow - pfi->firstRow + 1;
+ index = (PclFontMapRec **)xalloc(sizeof(PclFontMapRec *)*nindex_row);
+ if (index == (PclFontMapRec **)NULL) {
+ xfree(pfh16->fontname);
+ xfree(pfh16);
+ return (PclFontHead16Ptr) NULL;
+ }
+ for (i=0; i<nindex_row; i++) {
+ index[i] = (PclFontMapRec *)xalloc(sizeof(PclFontMapRec)*nindex_col);
+ if (index[i] == (PclFontMapRec *)NULL) {
+ for(j=0; j<i; j++)
+ xfree(index[j]);
+ xfree(pfh16->fontname);
+ xfree(pfh16);
+ return (PclFontHead16Ptr) NULL;
+ }
+ for (j=0; j<=nindex_col; j++)
+ index[i][j].fid = 0x0;
+ }
+
+ pfh16->index = index;
+ pfh16->firstCol = pfi->firstCol;
+ pfh16->lastCol = pfi->lastCol;
+ pfh16->firstRow = pfi->firstRow;
+ pfh16->lastRow = pfi->lastRow;
+ pfh16->next = (PclFontHead16Ptr)NULL;
+
+ if ( prev == (PclFontHead16Ptr) NULL)
+ pSoftFontInfo->phead16 = pfh16;
+ else
+ prev->next = pfh16;
+
+ return pfh16;
+}
+
+static PclInternalFontPtr
+makeInternalFont(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo)
+{
+PclInternalFontPtr pinfont = pSoftFontInfo->pinfont;
+PclInternalFontPtr pin = pinfont;
+PclInternalFontPtr prev = (PclInternalFontPtr)NULL;
+FontPropPtr props;
+FontInfoPtr pfi;
+char *fontname;
+Atom xa_pcl_font_name, xa_res, xa_ave_width, xa_spacing;
+int width = 1;
+int mask;
+int i;
+
+ if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL)
+ return (PclInternalFontPtr)NULL;
+
+ /*
+ * Verify it has already been created, if so, return it.
+ */
+ if ( (fontname = getFontName(pfont)) == (char *)NULL)
+ return (PclInternalFontPtr)NULL;
+
+ while (pin != (PclInternalFontPtr) NULL) {
+ if (!strcmp(pin->fontname, fontname))
+ return pin;
+ prev = pin;
+ pin = pin->next;
+ }
+
+ /*
+ * Create Internal Font Information
+ */
+ pin = (PclInternalFontPtr)xalloc(sizeof(PclInternalFontRec));
+ if (pin == (PclInternalFontPtr)NULL)
+ return (PclInternalFontPtr)NULL;
+
+ pin->fontname = (char *)xalloc(strlen(fontname) + 1);
+ if (pin->fontname == (char *)NULL) {
+ xfree(pin);
+ return (PclInternalFontPtr) NULL;
+ }
+ strcpy(pin->fontname, fontname);
+
+ xa_pcl_font_name = MakeAtom("PCL_FONT_NAME", strlen("PCL_FONT_NAME"), TRUE);
+ xa_res = MakeAtom("RESOLUTION_X", strlen("RESOLUTION_X"), TRUE);
+ xa_ave_width = MakeAtom("AVERAGE_WIDTH", strlen("AVERAGE_WIDTH"), TRUE);
+ xa_spacing = MakeAtom("SPACING", strlen("SPACING"), TRUE);
+ pfi = (FontInfoRec *)&pfont->info;
+ props = pfi->props;
+
+ mask = 0;
+ for (i=0; i<pfi->nprops; i++, props++) {
+ if ( (Atom) props->name == xa_pcl_font_name ) {
+ pin->pcl_font_name = NameForAtom(props->value);
+ mask |= 0x1;
+ } else if ( props->name == XA_POINT_SIZE ) {
+ pin->height = (float) props->value / 10.0;
+ mask |= 0x2;
+ } else if ( (Atom) props->name == xa_res ) {
+ mask |= 0x4;
+ } else if ( (Atom) props->name == xa_ave_width ) {
+ width = (int) props->value / 10;
+ mask |= 0x8;
+ } else if ( (Atom) props->name == xa_spacing ) {
+ pin->spacing = NameForAtom(props->value);
+ mask |= 0x10;
+ }
+ }
+ if ( mask != 0x1f ) {
+ xfree(pin->fontname);
+ xfree(pin);
+ return (PclInternalFontPtr) NULL;
+ }
+
+ if ( *pin->spacing != 'P' || *pin->spacing != 'p' ) {
+ if (width == 0)
+ width = 1;
+ pin->pitch = (float) 300.0 / width; /* Hard-Code: Resolution is 300 */
+ }
+
+ pin->next = (PclInternalFontPtr)NULL;
+ if ( prev == (PclInternalFontPtr) NULL)
+ pSoftFontInfo->pinfont = pin;
+ else
+ prev->next = pin;
+
+ return pin;
+}
+
+static void
+fillFontDescData(FontPtr pfont, PclFontDescPtr pfd, unsigned int space)
+{
+FontInfoPtr pfi;
+
+ pfi = (FontInfoRec *)&pfont->info;
+
+ if ( (pfi->maxbounds.leftSideBearing == pfi->minbounds.leftSideBearing)
+ && (pfi->maxbounds.rightSideBearing == pfi->minbounds.rightSideBearing)
+ && (pfi->maxbounds.characterWidth == pfi->minbounds.characterWidth)
+ && (pfi->maxbounds.ascent == pfi->minbounds.ascent)
+ && (pfi->maxbounds.descent == pfi->minbounds.descent)
+ )
+ pfd->spacing = MONOSPACE;
+ else
+ pfd->spacing = PROPSPACE;
+
+ pfd->pitch = space;
+ pfd->cellheight = FONTMAXBOUNDS(pfont,ascent)
+ + FONTMAXBOUNDS(pfont,descent);
+ pfd->cellwidth = FONTMAXBOUNDS(pfont,rightSideBearing)
+ - FONTMINBOUNDS(pfont,leftSideBearing);
+ pfd->ascent = FONTMAXBOUNDS(pfont,ascent); /*FONTASCENT(pfont);*/
+ pfd->descent = FONTMAXBOUNDS(pfont,descent); /*FONTDESCENT(pfont);*/
+}
+
+static PclCharDataPtr
+fillCharDescData(PclCharDataPtr pcd, CharInfoPtr pci)
+{
+unsigned int byte_width;
+unsigned char *p;
+register int nbyGlyphWidth;
+unsigned char *pglyph, *pg;
+unsigned int i, j;
+
+ pcd->h_offset = pci->metrics.leftSideBearing;
+ pcd->v_offset = pci->metrics.ascent;
+ pcd->width = pci->metrics.rightSideBearing
+ - pci->metrics.leftSideBearing;
+ pcd->height = pci->metrics.ascent + pci->metrics.descent;
+ pcd->font_pitch = pci->metrics.characterWidth;
+
+ byte_width = (pcd->width + 7)/8;
+ pcd->raster_top = (unsigned char *)xalloc(byte_width * pcd->height);
+ if (pcd->raster_top == (unsigned char *)NULL)
+ return (PclCharDataPtr)NULL;
+
+ p = pcd->raster_top;
+ nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ for (i=0; i<pcd->height; i++) {
+ pg = pglyph + nbyGlyphWidth * i;
+ for (j=0; j<byte_width; j++)
+ *p++ = *pg++;
+ }
+ return pcd;
+}
+
+static void
+output_text(FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ unsigned char index)
+{
+ if ( index == ETX ) {
+ sprintf(t, "%c;DT%c,1;LB%c%c;DT%c,1;LB",
+ ETX, ETX_ALT, ETX, ETX_ALT, ETX);
+ SAVE_PCL( outFile, pConPriv, t );
+ } else {
+ sprintf(t, "%c", index);
+ SAVE_PCL_COUNT( outFile, pConPriv, t, 1 );
+ }
+}
+
+static char *
+getFontName(FontPtr pfont)
+{
+int i;
+FontInfoPtr pfi;
+FontPropPtr props;
+char *fontname;
+
+ pfi = (FontInfoRec *)&pfont->info;
+ props = pfi->props;
+ fontname = (char *) NULL;
+ for (i=0; i<pfi->nprops; i++, props++) {
+ if ( props->name == XA_FONT ) {
+ fontname = (char *)NameForAtom(props->value);
+ break;
+ }
+ }
+ return fontname;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/* Internal Font Selection */
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static char
+isInternal(FontPtr pfont)
+{
+int i;
+FontInfoPtr pfi;
+FontPropPtr props;
+Atom dest;
+
+ dest = MakeAtom("PRINTER_RESIDENT_FONT", strlen("PRINTER_RESIDENT_FONT"), TRUE);
+
+ pfi = (FontInfoRec *)&pfont->info;
+ props = pfi->props;
+ for (i=0; i<pfi->nprops; i++, props++) {
+ if ( (Atom) props->name == dest && props->value == 2 )
+ return INTERNAL_FONT;
+ }
+ return DOWNLOAD_FONT;
+}
+
+static void
+selectInternalFont(FILE *outFile, PclInternalFontPtr pin, int fid)
+{
+ fprintf(outFile, "%c*c%dD", ESC, fid);
+ if ( *pin->spacing == 'P' || *pin->spacing == 'p' )
+ fprintf(outFile, pin->pcl_font_name, pin->height);
+ else
+ fprintf(outFile, pin->pcl_font_name, pin->pitch);
+ fprintf(outFile, "%c*c6F", ESC);
+}
+
+static void
+selectSize(FILE *outFile,
+ PclContextPrivPtr pConPriv,
+ PclInternalFontPtr pin)
+{
+ if ( *pin->spacing == 'P' || *pin->spacing == 'p' ) {
+ sprintf(t, "SD4,%f;", pin->height);
+ SAVE_PCL( outFile, pConPriv, t );
+ } else {
+ sprintf(t, "SD3,%f;", pin->pitch);
+ SAVE_PCL( outFile, pConPriv, t );
+ }
+ return;
+}
+
+#ifdef DO_TWO_BYTE_PCL
+static void
+code_conv(
+ PclSoftFontInfoPtr pSoftFontInfo,
+ FontPtr pfont,
+ char *from,
+ char *to
+)
+{
+iconv_t cd;
+char frombuf[9], *fromptr;
+size_t inbyte = 5, outbyte=2;
+
+ fromptr = frombuf;
+ frombuf[0] = 0x1b; /* Esc */
+ frombuf[1] = 0x24; /* $ */
+ frombuf[2] = 0x42; /* B */
+ frombuf[3] = *from;
+ frombuf[4] = *(from+1);
+ frombuf[5] = 0x1b; /* Esc */
+ frombuf[6] = 0x28; /* ( */
+ frombuf[7] = 0x4a; /* J */
+ frombuf[8] = 0x0;
+ if ((cd = iconv_open("sjis", "jis")) == (iconv_t)(-1)) {
+ *to = (unsigned char)NULL;
+ return;
+ }
+
+ if ( iconv(cd, &fromptr, &inbyte, &to, &outbyte) == -1 )
+ *to = (unsigned char)NULL;
+
+ iconv_close(cd);
+ return;
+}
+#endif /* DO_TWO_BYTE_PCL */
diff --git a/hw/xprint/pcl/PclWindow.c b/hw/xprint/pcl/PclWindow.c
new file mode 100644
index 000000000..cac5826e9
--- /dev/null
+++ b/hw/xprint/pcl/PclWindow.c
@@ -0,0 +1,452 @@
+/* $Xorg: PclWindow.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PclWindow.c
+** *
+** * Contents:
+** * Window code for Pcl driver.
+** *
+** * Created: 2/02/95
+** *
+** *********************************************************
+**
+********************************************************************/
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclWindow.c,v 1.10tsi Exp $ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "mistruct.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Pcl.h"
+
+#if 0
+/*
+ * The following list of strings defines the properties which will be
+ * placed on the screen's root window if the property was defined in
+ * the start-up configuration resource database.
+ */
+static /* const */ char *propStrings[] = {
+ DT_PRINT_JOB_HEADER,
+ DT_PRINT_JOB_TRAILER,
+ DT_PRINT_JOB_COMMAND, /* old-obsolete */
+ DT_PRINT_JOB_EXEC_COMMAND,
+ DT_PRINT_JOB_EXEC_OPTIONS,
+ DT_PRINT_PAGE_HEADER,
+ DT_PRINT_PAGE_TRAILER,
+ DT_PRINT_PAGE_COMMAND,
+ (char *)NULL
+};
+#endif
+
+/*
+ * PclCreateWindow - watch for the creation of the root window.
+ * When it's created, register the screen with the print extension,
+ * and put the default command/header properties on it.
+ */
+/*ARGSUSED*/
+
+Bool
+PclCreateWindow(
+ register WindowPtr pWin)
+{
+ PclWindowPrivPtr pPriv;
+
+#if 0
+ Bool status = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PclScreenPrivPtr pScreenPriv = (PclScreenPrivPtr)
+ pScreen->devPrivates[PclScreenPrivateIndex].ptr;
+ PclWindowPrivPtr pWinPriv = (PclWindowPrivPtr)
+ pWin->devPrivates[PclWindowPrivateIndex].ptr;
+
+ /*
+ * Initialize this window's private struct.
+ */
+ pWinPriv->jobFileName = (char *)NULL;
+ pWinPriv->pJobFile = (FILE *)NULL;
+ pWinPriv->pageFileName = (char *)NULL;
+ pWinPriv->pPageFile = (FILE *)NULL;
+
+ if(pWin->parent == (WindowPtr)NULL) /* root window? */
+ {
+ Atom propName; /* type = XA_STRING */
+ char *propVal;
+ int i;
+ XrmDatabase rmdb = pScreenPriv->resDB;
+
+ /*
+ * Put the defaults spec'd in the config files in properties on this
+ * screen's root window.
+ */
+ for(i = 0; propStrings[i] != (char *)NULL; i++)
+ {
+ if((propVal = _DtPrintGetPrinterResource(pWin, rmdb,
+ propStrings[i])) !=
+ (char *)NULL)
+ {
+ propName = MakeAtom(propStrings[i], strlen(propStrings[i]),
+ TRUE);
+ ChangeWindowProperty(pWin, propName, XA_STRING, 8,
+ PropModeReplace, strlen(propVal),
+ (pointer)propVal, FALSE);
+ xfree(propVal);
+ }
+ }
+ }
+
+ return status;
+#endif
+
+ /*
+ * Invalidate the window's private print context.
+ */
+ pPriv = (PclWindowPrivPtr)pWin->devPrivates[PclWindowPrivateIndex].ptr;
+ pPriv->validContext = 0;
+
+ return TRUE;
+}
+
+
+/*ARGSUSED*/
+Bool PclMapWindow(
+ WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+/*ARGSUSED*/
+Bool
+PclPositionWindow(
+ register WindowPtr pWin,
+ int x,
+ int y)
+{
+ return TRUE;
+}
+
+/*ARGSUSED*/
+Bool
+PclUnmapWindow(
+ WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+/*ARGSUSED*/
+void
+PclCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+}
+
+/*ARGSUSED*/
+Bool
+PclChangeWindowAttributes(
+ register WindowPtr pWin,
+ register unsigned long mask)
+{
+ if( pWin->backingStore != NotUseful )
+ {
+ pWin->backingStore = NotUseful;
+ mask |= CWBackingStore;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This function is largely ripped from miPaintWindow, but modified so
+ * that the background is not painted to the root window, and so that
+ * the backing store is not referenced.
+ */
+void
+PclPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what)
+{
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ pointer gcval[7];
+ pointer newValues [COUNT_BITS];
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+ gcmask = 0;
+
+ /*
+ * We don't want to paint a window that has no place to put the
+ * PCL output.
+ */
+ if( PclGetContextFromWindow( pWin ) == (XpContextPtr)NULL )
+ return;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)
+ (pWin->parent, pRegion, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND] = (pointer)pWin->background.pixel;
+ newValues[FILLSTYLE] = (pointer)FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE] = (pointer)pWin->background.pixmap;
+ newValues[FILLSTYLE] = (pointer)FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin |
+ GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND] = (pointer)pWin->border.pixel;
+ newValues[FILLSTYLE] = (pointer)FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE] = (pointer)pWin->border.pixmap;
+ newValues[FILLSTYLE] = (pointer)FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin
+ | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(pRegion) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION] = (pointer)GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ DEALLOCATE_LOCAL(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX] = (pointer)(long)pBgWin->drawable.x;
+ newValues[ABSY] = (pointer)(long)pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX] = (pointer)0;
+ newValues[ABSY] = (pointer)0;
+ }
+
+/*
+ * XXX Backing store is turned off for the PCL driver
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC,
+ GuaranteeVisBack);
+ */
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if ((pointer)(long) pGC->alu != newValues[FUNCTION]) {
+ gcmask |= index;
+ gcval[i++] = newValues[FUNCTION];
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ((pointer)(long) pGC->patOrg.x != newValues[ABSX]) {
+ gcmask |= index;
+ gcval[i++] = newValues[ABSX];
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ((pointer)(long) pGC->patOrg.y != newValues[ABSY]) {
+ gcmask |= index;
+ gcval[i++] = newValues[ABSY];
+ }
+ break;
+ case GCClipMask:
+ if ((pointer)(long) pGC->clientClipType != (pointer)CT_NONE) {
+ gcmask |= index;
+ gcval[i++] = (pointer)CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ((pointer)(long) pGC->subWindowMode != newValues[SUBWINDOW]) {
+ gcmask |= index;
+ gcval[i++] = newValues[SUBWINDOW];
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel ||
+ (pointer) pGC->tile.pixmap != newValues[TILE])
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[TILE];
+ }
+ break;
+ case GCFillStyle:
+ if ((pointer)(long) pGC->fillStyle != newValues[FILLSTYLE]) {
+ gcmask |= index;
+ gcval[i++] = newValues[FILLSTYLE];
+ }
+ break;
+ case GCForeground:
+ if ((pointer) pGC->fgPixel != newValues[FOREGROUND]) {
+ gcmask |= index;
+ gcval[i++] = newValues[FOREGROUND];
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ DoChangeGC(pGC, gcmask, (XID *)gcval, 1);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = REGION_NUM_RECTS(pRegion);
+ pbox = REGION_RECTS(pRegion);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ DEALLOCATE_LOCAL(prect);
+
+/*
+ * XXX Backing store is turned off for the PCL driver
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC,
+ GuaranteeNothing);
+ */
+
+ if (what == PW_BORDER)
+ {
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+
+}
+
+/*ARGSUSED*/
+Bool
+PclDestroyWindow(
+ WindowPtr pWin)
+{
+ return TRUE;
+}
+
diff --git a/hw/xprint/pcl/Pclmap.h b/hw/xprint/pcl/Pclmap.h
new file mode 100644
index 000000000..5224fd9e3
--- /dev/null
+++ b/hw/xprint/pcl/Pclmap.h
@@ -0,0 +1,213 @@
+/* $Xorg: Pclmap.h,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/pcl/Pclmap.h,v 1.5 2001/07/25 15:05:00 dawes Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PCLMAP_H_
+#define _PCLMAP_H_
+
+#ifdef XP_PCL_COLOR
+#ifdef CATNAME
+#undef CATNAME
+#endif
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define PCLNAME(subname) PclCr##subname
+#define CATNAME(prefix,subname) prefix##Color##subname
+#else
+#define PCLNAME(subname) PclCr/**/subname
+#define CATNAME(prefix,subname) prefix/**/Color/**/subname
+#endif
+#endif /* XP_PCL_COLOR */
+
+#ifdef XP_PCL_MONO
+#ifdef CATNAME
+#undef CATNAME
+#endif
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define PCLNAME(subname) PclMn##subname
+#define CATNAME(prefix,subname) prefix##Mono##subname
+#else
+#define PCLNAME(subname) PclMn/**/subname
+#define CATNAME(prefix,subname) prefix/**/Mono/**/subname
+#endif
+#endif /* XP_PCL_MONO */
+
+#ifdef XP_PCL_LJ3
+#ifdef CATNAME
+#undef CATNAME
+#endif
+#if !defined(UNIXCPP) || defined(ANSICPP)
+#define PCLNAME(subname) PclLj3##subname
+#define CATNAME(prefix,subname) prefix##Lj3##subname
+#else
+#define PCLNAME(subname) PclLj3/**/subname
+#define CATNAME(prefix,subname) prefix/**/Lj3/**/subname
+#endif
+#endif /* XP_PCL_LJ3 */
+
+#ifdef PCLNAME
+
+/* PclInit.c */
+#define InitializePclDriver CATNAME(Initialize, PclDriver)
+#define PclCloseScreen PCLNAME(CloseScreen)
+#define PclGetContextFromWindow PCLNAME(GetContextFromWindow)
+#define PclScreenPrivateIndex PCLNAME(ScreenPrivateIndex)
+#define PclWindowPrivateIndex PCLNAME(WindowPrivateIndex)
+#define PclContextPrivateIndex PCLNAME(ContextPrivateIndex)
+#define PclPixmapPrivateIndex PCLNAME(PixmapPrivateIndex)
+#define PclGCPrivateIndex PCLNAME(GCPrivateIndex)
+
+/* PclPrint.c */
+#define PclStartJob PCLNAME(StartJob)
+#define PclEndJob PCLNAME(EndJob)
+#define PclStartPage PCLNAME(StartPage)
+#define PclEndPage PCLNAME(EndPage)
+#define PclStartDoc PCLNAME(StartDoc)
+#define PclEndDoc PCLNAME(EndDoc)
+#define PclDocumentData PCLNAME(DocumentData)
+#define PclGetDocumentData PCLNAME(GetDocumentData)
+
+/* PclWindow.c */
+#define PclCreateWindow PCLNAME(CreateWindow)
+#define PclMapWindow PCLNAME(MapWindow)
+#define PclPositionWindow PCLNAME(PositionWindow)
+#define PclUnmapWindow PCLNAME(UnmapWindow)
+#define PclCopyWindow PCLNAME(CopyWindow)
+#define PclChangeWindowAttributes PCLNAME(ChangeWindowAttributes)
+#define PclPaintWindow PCLNAME(PaintWindow)
+#define PclDestroyWindow PCLNAME(DestroyWindow)
+
+/* PclGC.c */
+#define PclCreateGC PCLNAME(CreateGC)
+#define PclDestroyGC PCLNAME(DestroyGC)
+#define PclGetDrawablePrivateStuff PCLNAME(GetDrawablePrivateStuff)
+#define PclSetDrawablePrivateGC PCLNAME(SetDrawablePrivateGC)
+#define PclSendPattern PCLNAME(SendPattern)
+#define PclUpdateDrawableGC PCLNAME(UpdateDrawableGC)
+#define PclComputeCompositeClip PCLNAME(ComputeCompositeClip)
+#define PclValidateGC PCLNAME(ValidateGC)
+
+/* PclAttr.c */
+#define PclGetAttributes PCLNAME(GetAttributes)
+#define PclGetOneAttribute PCLNAME(GetOneAttribute)
+#define PclAugmentAttributes PCLNAME(AugmentAttributes)
+#define PclSetAttributes PCLNAME(SetAttributes)
+
+/* PclColor.c */
+#define PclLookUp PCLNAME(LookUp)
+#define PclCreateDefColormap PCLNAME(CreateDefColormap)
+#define PclCreateColormap PCLNAME(CreateColormap)
+#define PclDestroyColormap PCLNAME(DestroyColormap)
+#define PclInstallColormap PCLNAME(InstallColormap)
+#define PclUninstallColormap PCLNAME(UninstallColormap)
+#define PclListInstalledColormaps PCLNAME(ListInstalledColormaps)
+#define PclStoreColors PCLNAME(StoreColors)
+#define PclResolveColor PCLNAME(ResolveColor)
+#define PclFindPaletteMap PCLNAME(FindPaletteMap)
+#define PclUpdateColormap PCLNAME(UpdateColormap)
+#define PclReadMap PCLNAME(ReadMap)
+
+/* PclPixmap.c */
+#define PclCreatePixmap PCLNAME(CreatePixmap)
+#define PclDestroyPixmap PCLNAME(DestroyPixmap)
+
+/* PclArc.c */
+#define PclDoArc PCLNAME(DoArc)
+#define PclPolyArc PCLNAME(PolyArc)
+#define PclPolyFillArc PCLNAME(PolyFillArc)
+
+/* PclArea.c */
+#define PclPutImage PCLNAME(PutImage)
+#define PclCopyArea PCLNAME(CopyArea)
+#define PclCopyPlane PCLNAME(CopyPlane)
+
+/* PclLine */
+#define PclPolyLine PCLNAME(PolyLine)
+#define PclPolySegment PCLNAME(PolySegment)
+
+/* PclPixel.c */
+#define PclPolyPoint PCLNAME(PolyPoint)
+#define PclPushPixels PCLNAME(PushPixels)
+
+/* PclPolygon.c */
+#define PclPolyRectangle PCLNAME(PolyRectangle)
+#define PclFillPolygon PCLNAME(FillPolygon)
+#define PclPolyFillRect PCLNAME(PolyFillRect)
+
+/* PclSpans.c */
+#define PclFillSpans PCLNAME(FillSpans)
+#define PclSetSpans PCLNAME(SetSpans)
+
+/* PclText.c */
+#define PclPolyText8 PCLNAME(PolyText8)
+#define PclPolyText16 PCLNAME(PolyText16)
+#define PclImageText8 PCLNAME(ImageText8)
+#define PclImageText16 PCLNAME(ImageText16)
+#define PclImageGlyphBlt PCLNAME(ImageGlyphBlt)
+#define PclPolyGlyphBlt PCLNAME(PolyGlyphBlt)
+#define PclPolyGlyphBlt PCLNAME(PolyGlyphBlt)
+
+/* PclFonts.c */
+#define PclRealizeFont PCLNAME(RealizeFont)
+#define PclUnrealizeFont PCLNAME(UnrealizeFont)
+
+/* PclSFonts.c */
+#define PclDownloadSoftFont8 PCLNAME(DownloadSoftFont8)
+#define PclDownloadSoftFont16 PCLNAME(DownloadSoftFont16)
+#define PclCreateSoftFontInfo PCLNAME(CreateSoftFontInfo)
+#define PclDestroySoftFontInfo PCLNAME(DestroySoftFontInfo)
+
+/* PclMisc.c */
+#define PclQueryBestSize PCLNAME(QueryBestSize)
+#define GetPropString PCLNAME(GetPropString)
+#define SystemCmd PCLNAME(SystemCmd)
+#define PclGetMediumDimensions PCLNAME(GetMediumDimensions)
+#define PclGetReproducibleArea PCLNAME(GetReproducibleArea)
+#define PclSpoolFigs PCLNAME(SpoolFigs)
+#define PclSendData PCLNAME(SendData)
+
+/* PclCursor.c */
+#define PclConstrainCursor PCLNAME(ConstrainCursor)
+#define PclCursorLimits PCLNAME(CursorLimits)
+#define PclDisplayCursor PCLNAME(DisplayCursor)
+#define PclRealizeCursor PCLNAME(RealizeCursor)
+#define PclUnrealizeCursor PCLNAME(UnrealizeCursor)
+#define PclRecolorCursor PCLNAME(RecolorCursor)
+#define PclSetCursorPosition PCLNAME(SetCursorPosition)
+
+#endif
+
+#endif /* _PCLMAP_H_ */
diff --git a/hw/xprint/ps/Makefile.am b/hw/xprint/ps/Makefile.am
new file mode 100644
index 000000000..90872d9da
--- /dev/null
+++ b/hw/xprint/ps/Makefile.am
@@ -0,0 +1,42 @@
+noinst_LTLIBRARIES = libps.la
+
+INCLUDES = -I$(top_srcdir)/hw/xprint
+
+AM_CFLAGS = @SERVER_DEFINES@ @DIX_CFLAGS@ @XPRINT_CFLAGS@ @FREETYPE_CFLAGS@ \
+ -D_XP_PRINT_SERVER_ -DPSZ=8 -DXP_PSTEXT
+
+libps_la_SOURCES = \
+ PsArc.c \
+ PsArea.c \
+ PsAttr.c \
+ PsAttVal.c \
+ PsCache.c \
+ PsColor.c \
+ PsDef.h \
+ PsFonts.c \
+ PsGC.c \
+ Ps.h \
+ PsImageUtil.c \
+ PsInit.c \
+ PsLine.c \
+ PsMisc.c \
+ psout.c \
+ psout.h \
+ PsPixel.c \
+ PsPixmap.c \
+ PsPolygon.c \
+ PsPrint.c \
+ PsSpans.c \
+ PsText.c \
+ PsWindow.c
+
+EXTRA_DIST = PsFTFonts.c \
+ psout_ft.c \
+ psout_ftpstype1.c \
+ psout_ftpstype3.c \
+ ttf2pt1wrap.c
+
+if XP_USE_FREETYPE
+ AM_CFLAGS += -DXP_USE_FREETYPE
+ libps_la_SOURCES += $(EXTRA_DIST)
+endif
diff --git a/hw/xprint/ps/Ps.h b/hw/xprint/ps/Ps.h
new file mode 100644
index 000000000..4effc2066
--- /dev/null
+++ b/hw/xprint/ps/Ps.h
@@ -0,0 +1,602 @@
+/* $Xorg: Ps.h,v 1.5 2001/02/09 02:04:35 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: Ps.h
+** *
+** * Contents: defines and includes for the Ps driver
+** * for a printing X server.
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PS_H_
+#define _PS_H_
+
+#include <stdio.h>
+
+#ifdef abs
+#undef abs /* this is because of a non-Spec1170ness in misc.h */
+#endif
+#include <stdlib.h>
+#include "scrnintstr.h"
+#include "dix.h"
+
+#include "PsDef.h"
+#include "psout.h"
+
+#include <X11/extensions/Print.h>
+#include <X11/extensions/Printstr.h>
+
+#include "regionstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+
+/*
+ * Some sleazes to force the XrmDB stuff into the server
+ */
+#ifndef HAVE_XPointer
+typedef char *XPointer;
+#define Status int
+#define True 1
+#define False 0
+#endif
+
+#include "misc.h"
+#include <X11/Xfuncproto.h>
+#include <X11/Xresource.h>
+#include "attributes.h"
+
+
+/*
+ * Public index variables from PsInit.c
+ */
+
+extern int PsScreenPrivateIndex;
+extern int PsWindowPrivateIndex;
+extern int PsContextPrivateIndex;
+extern int PsPixmapPrivateIndex;
+extern XpValidatePoolsRec PsValidatePoolsRec;
+
+/*
+ * Display list structures
+ */
+
+#define DPY_BLOCKSIZE 4096
+
+typedef struct
+{
+ int mode;
+ int nPoints;
+ xPoint *pPoints;
+} PsPolyPointsRec;
+
+typedef struct
+{
+ int nSegments;
+ xSegment *pSegments;
+} PsSegmentsRec;
+
+typedef struct
+{
+ int nRects;
+ xRectangle *pRects;
+} PsRectanglesRec;
+
+typedef struct
+{
+ int nArcs;
+ xArc *pArcs;
+} PsArcsRec;
+
+typedef struct
+{
+ int x;
+ int y;
+ int count;
+ char *string;
+} PsText8Rec;
+
+typedef struct
+{
+ int x;
+ int y;
+ int count;
+ unsigned short *string;
+} PsText16Rec;
+
+typedef struct
+{
+ int depth;
+ int x;
+ int y;
+ int w;
+ int h;
+ int leftPad;
+ int format;
+ int res; /* image resolution */
+ char *pData;
+} PsImageRec;
+
+typedef struct
+{
+ int x;
+ int y;
+ int w;
+ int h;
+} PsFrameRec;
+
+typedef enum
+{
+ PolyPointCmd,
+ PolyLineCmd,
+ PolySegmentCmd,
+ PolyRectangleCmd,
+ FillPolygonCmd,
+ PolyFillRectCmd,
+ PolyArcCmd,
+ PolyFillArcCmd,
+ Text8Cmd,
+ Text16Cmd,
+ TextI8Cmd,
+ TextI16Cmd,
+ PutImageCmd,
+ BeginFrameCmd,
+ EndFrameCmd
+} DisplayElmType;
+
+typedef struct _DisplayElmRec
+{
+ DisplayElmType type;
+ GCPtr gc;
+ union
+ {
+ PsPolyPointsRec polyPts;
+ PsSegmentsRec segments;
+ PsRectanglesRec rects;
+ PsArcsRec arcs;
+ PsText8Rec text8;
+ PsText16Rec text16;
+ PsImageRec image;
+ PsFrameRec frame;
+ } c;
+} DisplayElmRec;
+
+typedef DisplayElmRec *DisplayElmPtr;
+
+typedef struct _DisplayListRec
+{
+ struct _DisplayListRec *next;
+ int nelms;
+ DisplayElmRec elms[DPY_BLOCKSIZE];
+} DisplayListRec;
+
+typedef DisplayListRec *DisplayListPtr;
+
+/*
+ * Private structures
+ */
+
+typedef struct
+{
+ XrmDatabase resDB;
+ Bool (*DestroyWindow)(WindowPtr);
+} PsScreenPrivRec, *PsScreenPrivPtr;
+
+typedef struct PsFontTypeInfoRec PsFontTypeInfoRec;
+
+/* Structure to hold information about one font on disk
+ * Notes:
+ * - multiple XLFD names can refer to the same |PsFontTypeInfoRec| (if
+ * they all use the same font on the disk)
+ * - the FreeType font download code uses multiple |PsFontTypeInfoRec|
+ * records for one font on disk if they differ in the encoding being
+ * used (this is an exception from the
+ * 'one-|PsFontTypeInfoRec|-per-font-on-disk'-design; maybe it it is better
+ * to rework that in a later step and add a new per-encoding structure).
+ */
+struct PsFontTypeInfoRec
+{
+ PsFontTypeInfoRec *next; /* Next record in list... */
+ char *adobe_ps_name; /* PostScript font name (from the
+ * "_ADOBE_POSTSCRIPT_FONTNAME" atom) */
+ char *download_ps_name; /* PostScript font name used for font download */
+ char *filename; /* File name of font */
+#ifdef XP_USE_FREETYPE
+ char *ft_download_encoding; /* encoding used for download */
+ PsFTDownloadFontType ft_download_font_type; /* PS font type used for download (e.g. Type1/Type3/CID/etc.) */
+#endif /* XP_USE_FREETYPE */
+ int is_iso_encoding; /* Is this font encoded in ISO Latin 1 ? */
+ int font_type; /* See PSFTI_FONT_TYPE_* below... */
+ Bool downloadableFont; /* Font can be downloaded */
+ Bool alreadyDownloaded[256]; /* Font has been downloaded (for 256 8bit "sub"-font) */
+};
+
+#define PSFTI_FONT_TYPE_OTHER (0)
+#define PSFTI_FONT_TYPE_PMF (1)
+#define PSFTI_FONT_TYPE_PS_TYPE1_PFA (2)
+#define PSFTI_FONT_TYPE_PS_TYPE1_PFB (3)
+#define PSFTI_FONT_TYPE_TRUETYPE (4)
+/* PSFTI_FONT_TYPE_FREETYPE is means the font is handled by the freetype engine */
+#define PSFTI_FONT_TYPE_FREETYPE (5)
+
+typedef struct PsFontInfoRec PsFontInfoRec;
+
+/* Structure which represents our context info for a single XLFD font
+ * Note that multiple |PsFontInfoRec| records can share the same
+ * |PsFontTypeInfoRec| record - the |PsFontInfoRec| records represent
+ * different appearances of the same font on disk(=|PsFontTypeInfoRec|)).
+ */
+struct PsFontInfoRec
+{
+ PsFontInfoRec *next; /* Next record in list... */
+ /* |font| and |font_fontPrivate| are used by |PsFindFontInfoRec()| to
+ * identify a font */
+ FontPtr font; /* The font this record is for */
+ pointer font_fontPrivate;
+ PsFontTypeInfoRec *ftir; /* Record about the font file on disk */
+ const char *dfl_name; /* XLFD for this font */
+ int size; /* Font size. Use |mtx| if |size==0| */
+ float mtx[4]; /* Transformation matrix (see |size|) */
+};
+
+typedef struct
+{
+ char *jobFileName;
+ FILE *pJobFile;
+ GC lastGC;
+ unsigned char *dash;
+ int validGC;
+ ClientPtr getDocClient;
+ int getDocBufSize;
+ PsOutPtr pPsOut;
+ PsFontTypeInfoRec *fontTypeInfoRecords;
+ PsFontInfoRec *fontInfoRecords;
+} PsContextPrivRec, *PsContextPrivPtr;
+
+typedef struct
+{
+ int validContext;
+ XpContextPtr context;
+} PsWindowPrivRec, *PsWindowPrivPtr;
+
+typedef struct
+{
+ XpContextPtr context;
+ GC lastGC;
+ int validGC;
+ DisplayListPtr dispList;
+} PsPixmapPrivRec, *PsPixmapPrivPtr;
+
+/*
+ * Macro functions
+ */
+
+#define SEND_PS(f,c) fwrite( c, sizeof( char ), strlen( c ), f )
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/*
+ * Functions in PsInit.c
+ */
+
+extern Bool InitializePsDriver(int ndx, ScreenPtr pScreen, int argc,
+ char **argv);
+extern XpContextPtr PsGetContextFromWindow(WindowPtr win);
+
+/*
+ * Functions in PsCache.c
+ */
+
+extern int PsBmIsImageCached(int gWidth, int gHeight, char *pBuffer);
+extern int PsBmPutImageInCache(int gWidth, int gHeight, char *pBuffer);
+extern void PsBmClearImageCache(void);
+
+/*
+ * Functions in PsPrint.c
+ */
+
+extern int PsStartJob(XpContextPtr pCon, Bool sendClientData, ClientPtr client);
+extern int PsEndJob(XpContextPtr pCon, Bool cancel);
+extern int PsStartPage(XpContextPtr pCon, WindowPtr pWin);
+extern int PsEndPage(XpContextPtr pCon, WindowPtr pWin);
+extern int PsStartDoc(XpContextPtr pCon, XPDocumentType type);
+extern int PsEndDoc(XpContextPtr pCon, Bool cancel);
+extern int PsDocumentData(XpContextPtr pCon, DrawablePtr pDraw, char *pData,
+ int len_data, char *pFmt, int len_fmt, char *pOpt, int len_opt,
+ ClientPtr client);
+extern int PsGetDocumentData(XpContextPtr pCon, ClientPtr client,
+ int maxBufferSize);
+
+/*
+ * Functions in PsGC.c
+ */
+
+extern Bool PsCreateGC(GCPtr pGC);
+extern PsContextPrivPtr PsGetPsContextPriv( DrawablePtr pDrawable );
+extern int PsUpdateDrawableGC(GCPtr pGC, DrawablePtr pDrawable,
+ PsOutPtr *psOut, ColormapPtr *cMap);
+extern void PsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
+extern void PsChangeGC(GCPtr pGC, unsigned long changes);
+extern void PsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+extern void PsDestroyGC(GCPtr pGC);
+extern void PsChangeClip(GCPtr pGC, int type, pointer pValue, int nrects);
+extern void PsDestroyClip(GCPtr pGC);
+extern void PsCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+extern GCPtr PsCreateAndCopyGC(DrawablePtr pDrawable, GCPtr pSrc);
+
+/*
+ * Functions in PsMisc.c
+ */
+
+extern void PsQueryBestSize(int type, short *pwidth, short *pheight,
+ ScreenPtr pScreen);
+extern Bool PsCloseScreen(int index, ScreenPtr pScreen);
+extern void PsLineAttrs(PsOutPtr psOut, GCPtr pGC, ColormapPtr cMap);
+extern int PsGetMediumDimensions(
+ XpContextPtr pCon,
+ CARD16 *pWidth,
+ CARD16 *pHeight);
+extern int PsGetReproducibleArea(
+ XpContextPtr pCon,
+ xRectangle *pRect);
+extern int PsSetImageResolution(
+ XpContextPtr pCon,
+ int imageRes,
+ Bool *status);
+
+/*
+ * Functions in PsSpans.c
+ */
+
+extern void PsFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans,
+ DDXPointPtr pPoints, int *pWidths, int fSorted);
+extern void PsSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
+ DDXPointPtr pPoints, int *pWidths, int nSpans,
+ int fSorted);
+
+/*
+ * Functions in PsArea.c
+ */
+
+extern void PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ int imageRes, char *pImage);
+extern void PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad,
+ int format, int imageRes, char *pImage);
+extern void PsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *pImage);
+extern void PsPutImageMask(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage);
+extern RegionPtr PsCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty);
+extern RegionPtr PsCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long plane);
+
+/*
+ * Functions in PsPixel.c
+ */
+
+extern void PsPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int nPoints, xPoint *pPoints);
+extern void PsPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable,
+ int width, int height, int x, int y);
+
+/*
+ * Functions in PsLine.c
+ */
+
+extern void PsPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int nPoints, xPoint *pPoints);
+extern void PsPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments,
+ xSegment *pSegments);
+
+/*
+ * Functions in PsPolygon.c
+ */
+
+extern void PsPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRects,
+ xRectangle *pRects);
+extern void PsFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int nPoints, DDXPointPtr pPoints);
+extern void PsPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRects,
+ xRectangle *pRects);
+
+/*
+ * Functions in PsPolygon.c
+ */
+
+extern void PsPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs,
+ xArc *pArcs);
+extern void PsPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs,
+ xArc *pArcs);
+
+/*
+ * Functions in PsText.c
+ */
+
+extern int PsPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, char *string);
+extern int PsPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, unsigned short *string);
+extern void PsImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, char *string);
+extern void PsImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, unsigned short *string);
+extern void PsImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ unsigned int nGlyphs, CharInfoPtr *pCharInfo,
+ pointer pGlyphBase);
+extern void PsPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ unsigned int nGlyphs, CharInfoPtr *pCharInfo,
+ pointer pGlyphBase);
+
+/*
+ * Functions in PsWindow.c
+ */
+
+extern Bool PsCreateWindow(WindowPtr pWin);
+extern Bool PsMapWindow(WindowPtr pWin);
+extern Bool PsPositionWindow(WindowPtr pWin, int x, int y);
+extern Bool PsUnmapWindow(WindowPtr pWin);
+extern void PsCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+extern Bool PsChangeWindowAttributes(WindowPtr pWin, unsigned long mask);
+extern void PsPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
+extern Bool PsDestroyWindow(WindowPtr pWin);
+
+/*
+ * Functions in PsFonts.c
+ */
+
+extern Bool PsRealizeFont(ScreenPtr pscr, FontPtr pFont);
+extern Bool PsUnrealizeFont(ScreenPtr pscr, FontPtr pFont);
+extern char *PsGetFontName(FontPtr pFont);
+extern int PsGetFontSize(FontPtr pFont, float *mtx);
+extern char *PsGetPSFontName(FontPtr pFont);
+extern char *PsGetPSFaceOrFontName(FontPtr pFont);
+extern int PsIsISOLatin1Encoding(FontPtr pFont);
+extern char *PsGetEncodingName(FontPtr pFont);
+extern PsFontInfoRec *PsGetFontInfoRec(DrawablePtr pDrawable, FontPtr pFont);
+extern void PsFreeFontInfoRecords(PsContextPrivPtr priv);
+extern PsFTDownloadFontType PsGetFTDownloadFontType(void);
+
+/*
+ * Functions in PsFTFonts.c
+ */
+
+extern char *PsGetFTFontFileName(FontPtr pFont);
+extern Bool PsIsFreeTypeFont(FontPtr pFont);
+
+/*
+ * Functions in PsAttr.c
+ */
+
+extern char *PsGetAttributes(XpContextPtr pCon, XPAttributes pool);
+extern char *PsGetOneAttribute(XpContextPtr pCon, XPAttributes pool,
+ char *attr);
+extern int PsAugmentAttributes(XpContextPtr pCon, XPAttributes pool,
+ char *attrs);
+extern int PsSetAttributes(XpContextPtr pCon, XPAttributes pool, char *attrs);
+
+/*
+ * Functions in PsColor.c
+ */
+
+extern Bool PsCreateColormap(ColormapPtr pColor);
+extern void PsDestroyColormap(ColormapPtr pColor);
+extern void PsInstallColormap(ColormapPtr pColor);
+extern void PsUninstallColormap(ColormapPtr pColor);
+extern int PsListInstalledColormaps(ScreenPtr pScreen, XID *pCmapList);
+extern void PsStoreColors(ColormapPtr pColor, int ndef, xColorItem *pdefs);
+extern void PsResolveColor(unsigned short *pRed, unsigned short *pGreen,
+ unsigned short *pBlue, VisualPtr pVisual);
+extern PsOutColor PsGetPixelColor(ColormapPtr cMap, int pixval);
+extern void PsSetFillColor(DrawablePtr pDrawable, GCPtr pGC, PsOutPtr psOut,
+ ColormapPtr cMap);
+
+/*
+ * Functions in PsPixmap.c
+ */
+
+extern PixmapPtr PsCreatePixmap(ScreenPtr pScreen, int width, int height,
+ int depth);
+extern void PsScrubPixmap(PixmapPtr pPixmap);
+extern Bool PsDestroyPixmap(PixmapPtr pPixmap);
+extern DisplayListPtr PsGetFreeDisplayBlock(PsPixmapPrivPtr priv);
+extern void PsReplay(DisplayElmPtr elm, DrawablePtr pDrawable);
+extern void PsReplayPixmap(PixmapPtr pix, DrawablePtr pDrawable);
+extern int PsCloneDisplayElm(PixmapPtr dst,
+ DisplayElmPtr elm, DisplayElmPtr newElm,
+ int xoff, int yoff);
+extern void PsCopyDisplayList(PixmapPtr src, PixmapPtr dst, int xoff,
+ int yoff, int x, int y, int w, int h);
+extern PsElmPtr PsCreateFillElementList(PixmapPtr pix, int *nElms);
+extern PsElmPtr PsCloneFillElementList(int nElms, PsElmPtr elms);
+extern void PsDestroyFillElementList(int nElms, PsElmPtr elms);
+
+/*
+ * Functions in PsImageUtil.c
+ */
+
+extern unsigned long
+PsGetImagePixel(char *pImage, int depth, int w, int h, int leftPad, int format,
+ int px, int py);
+
+#endif /* _PS_H_ */
diff --git a/hw/xprint/ps/PsArc.c b/hw/xprint/ps/PsArc.c
new file mode 100644
index 000000000..511971e7a
--- /dev/null
+++ b/hw/xprint/ps/PsArc.c
@@ -0,0 +1,182 @@
+/* $Xorg: PsArc.c,v 1.4 2001/02/09 02:04:35 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsArc.c
+** *
+** * Contents: Arc-drawing code for the PS DDX driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PsPolyArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolyArcCmd;
+ elm->gc = gc;
+ elm->c.arcs.nArcs = nArcs;
+ elm->c.arcs.pArcs = (xArc *)xalloc(nArcs*sizeof(xArc));
+ memcpy(elm->c.arcs.pArcs, pArcs, nArcs*sizeof(xArc));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ PsLineAttrs(psOut, pGC, cMap);
+ for( i=0 ; i<nArcs ; i++ )
+ {
+ PsOut_DrawArc(psOut, (int)pArcs[i].x, (int)pArcs[i].y,
+ (int)pArcs[i].width, (int)pArcs[i].height,
+ (float)pArcs[i].angle1/64.,
+ (float)pArcs[i].angle2/64.);
+ }
+ }
+}
+
+void
+PsPolyFillArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nArcs,
+ xArc *pArcs)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolyFillArcCmd;
+ elm->gc = gc;
+ elm->c.arcs.nArcs = nArcs;
+ elm->c.arcs.pArcs = (xArc *)xalloc(nArcs*sizeof(xArc));
+ memcpy(elm->c.arcs.pArcs, pArcs, nArcs*sizeof(xArc));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ PsArcEnum styl;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsSetFillColor(pDrawable, pGC, psOut, cMap);
+ PsLineAttrs(psOut, pGC, cMap);
+ if( pGC->arcMode==ArcChord ) styl = PsChord;
+ else styl = PsPieSlice;
+ for( i=0 ; i<nArcs ; i++ )
+ {
+ PsOut_FillArc(psOut, (int)pArcs[i].x, (int)pArcs[i].y,
+ (int)pArcs[i].width, (int)pArcs[i].height,
+ (float)pArcs[i].angle1/64.,
+ (float)pArcs[i].angle2/64., styl);
+ }
+ }
+}
diff --git a/hw/xprint/ps/PsArea.c b/hw/xprint/ps/PsArea.c
new file mode 100644
index 000000000..bf6f8f42a
--- /dev/null
+++ b/hw/xprint/ps/PsArea.c
@@ -0,0 +1,391 @@
+/* $Xorg: PsArea.c,v 1.6 2001/03/14 18:27:44 pookie Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996, 2000 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsArea.c
+** *
+** * Contents: Image and Area functions for the PS DDX driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+
+void
+PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, int imageRes, char *pImage)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ int size = PixmapBytePad(w, depth)*h;
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+ elm = &disp->elms[disp->nelms];
+ elm->type = PutImageCmd;
+ elm->gc = gc;
+ elm->c.image.depth = depth;
+ elm->c.image.x = x;
+ elm->c.image.y = y;
+ elm->c.image.w = w;
+ elm->c.image.h = h;
+ elm->c.image.leftPad = leftPad;
+ elm->c.image.format = format;
+ elm->c.image.res = imageRes;
+ elm->c.image.pData = (char *)xalloc(size);
+ memcpy(elm->c.image.pData, pImage, size);
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i, j;
+ int r, c;
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ int pageRes, sw, sh;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ if (!imageRes) {
+ sw = w;
+ sh = h;
+ } else {
+ pageRes = XpGetResolution(XpGetPrintContext(requestingClient));
+ sw = (float)w * (float)pageRes / (float)imageRes + 0.5;
+ sh = (float)h * (float)pageRes / (float)imageRes + 0.5;
+ }
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+
+ if( depth!=1 )
+ {
+ PsOut_BeginImage(psOut, 0, 0, x, y, w, h, sw, sh, 3);
+
+ for( r=0 ; r<h ; r++ )
+ {
+ for( c=0 ; c<w ; c++ )
+ {
+ unsigned long pv = PsGetImagePixel(pImage, depth, w, h, leftPad, format, c, r);
+ PsOutColor clr = PsGetPixelColor(cMap, pv);
+ /* XXX: This needs to be fixed for endian swapping and to support
+ * depths deeper than 8bit per R-,G-,B-gun... */
+ unsigned long val = PSOUTCOLOR_TO_RGB24BIT(clr);
+ char *ipt = (char *)&val;
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+ {
+ long l;
+ swapl(&val, l);
+ }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+#else
+#error Unsupported byte order
+#endif
+ PsOut_OutImageBytes(psOut, 3, &ipt[1]);
+ }
+ }
+
+ PsOut_EndImage(psOut);
+ }
+ else
+ {
+ int rowsiz = BitmapBytePad(w);
+ int psrsiz = (w+7)/8;
+ PsOut_BeginImage(psOut, PsGetPixelColor(cMap, pGC->bgPixel),
+ PsGetPixelColor(cMap, pGC->fgPixel),
+ x, y, w, h, sw, sh, 1);
+ for( r=0 ; r<h ; r++ )
+ {
+ char *pt = &pImage[rowsiz*r];
+ for( i=0 ; i<psrsiz ; i++ )
+ {
+ int iv_, iv = (int)pt[i]&0xFF;
+ char c;
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+ { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+ iv_ = iv;
+#else
+#error Unsupported byte order
+#endif
+ c = iv_;
+ PsOut_OutImageBytes(psOut, 1, &c);
+ }
+ }
+ PsOut_EndImage(psOut);
+ }
+ }
+}
+
+void
+PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, int imageRes, char *pImage)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ int size = PixmapBytePad(w, depth)*h;
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+ elm = &disp->elms[disp->nelms];
+ elm->type = PutImageCmd;
+ elm->gc = gc;
+ elm->c.image.depth = depth;
+ elm->c.image.x = x;
+ elm->c.image.y = y;
+ elm->c.image.w = w;
+ elm->c.image.h = h;
+ elm->c.image.leftPad = leftPad;
+ elm->c.image.format = format;
+ elm->c.image.res = imageRes;
+ elm->c.image.pData = (char *)xalloc(size);
+ memcpy(elm->c.image.pData, pImage, size);
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i, j;
+ int r, c;
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ int pageRes, sw, sh;
+#ifdef BM_CACHE
+ long cache_id = 0;
+#endif
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ if (!imageRes) {
+ sw = w;
+ sh = h;
+ } else {
+ pageRes = XpGetResolution(XpGetPrintContext(requestingClient));
+ sw = (float)w * (float)pageRes / (float)imageRes + 0.5;
+ sh = (float)h * (float)pageRes / (float)imageRes + 0.5;
+ }
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+
+#ifdef BM_CACHE
+ cache_id = PsBmIsImageCached(w, h, pImage);
+
+ if(!cache_id)
+ {
+ cache_id = PsBmPutImageInCache(w, h, pImage);
+
+ if(!cache_id)
+ return;
+
+ PsOut_BeginImageCache(psOut, cache_id);
+#endif
+ if( depth!=1 )
+ {
+ PsOut_BeginImageIM(psOut, 0, 0, x, y, w, h, sw, sh, 3);
+
+ for( r=0 ; r<h ; r++ )
+ {
+ for( c=0 ; c<w ; c++ )
+ {
+ unsigned long pv = PsGetImagePixel(pImage, depth, w, h, leftPad, format, c, r);
+ PsOutColor clr = PsGetPixelColor(cMap, pv);
+ /* XXX: This needs to be fixed for endian swapping and to support
+ * depths deeper than 8bit per R-,G-,B-gun... */
+ unsigned long val = PSOUTCOLOR_TO_RGB24BIT(clr);
+ char *ipt = (char *)&val;
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+ {
+ long l;
+ swapl(&val, l);
+ }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+#else
+#error Unsupported byte order
+#endif
+ PsOut_OutImageBytes(psOut, 3, &ipt[1]);
+ }
+ }
+
+ PsOut_EndImage(psOut);
+ }
+ else
+ {
+ int rowsiz = BitmapBytePad(w);
+ int psrsiz = (w+7)/8;
+ PsOut_BeginImageIM(psOut, PsGetPixelColor(cMap, pGC->bgPixel),
+ PsGetPixelColor(cMap, pGC->fgPixel),
+ x, y, w, h, sw, sh, 1);
+ for( r=0 ; r<h ; r++ )
+ {
+ char *pt = &pImage[rowsiz*r];
+ for( i=0 ; i<psrsiz ; i++ )
+ {
+ int iv_, iv = (int)pt[i]&0xFF;
+ char c;
+/* XXX: Is this the right way to detect the platform endianess ? */
+#if IMAGE_BYTE_ORDER == LSBFirst
+ { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); }
+#elif IMAGE_BYTE_ORDER == MSBFirst
+ iv_ = iv;
+#else
+#error Unsupported byte order
+#endif
+ c = iv_;
+ PsOut_OutImageBytes(psOut, 1, &c);
+ }
+ }
+ PsOut_EndImage(psOut);
+ }
+#ifdef BM_CACHE
+ PsOut_EndImageCache(psOut);
+ }
+ PsOut_ImageCache(psOut, x, y, cache_id, PsGetPixelColor(cMap, pGC->bgPixel),
+ PsGetPixelColor(cMap, pGC->fgPixel));
+#endif
+ }
+}
+void
+PsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage)
+{
+ XpContextPtr pcon;
+ if (requestingClient && (pcon = XpGetPrintContext(requestingClient)))
+ PsPutScaledImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+ pcon->imageRes, pImage);
+}
+void
+PsPutImageMask(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage)
+{
+ XpContextPtr pcon;
+ if (requestingClient && (pcon = XpGetPrintContext(requestingClient)))
+ PsPutScaledImageIM(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+ pcon->imageRes, pImage);
+}
+
+RegionPtr
+PsCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int width, int height, int dstx, int dsty)
+{
+ PixmapPtr src = (PixmapPtr)pSrc;
+ PixmapPtr dst = (PixmapPtr)pDst;
+
+ if( pSrc->type!=DRAWABLE_PIXMAP ) return NULL;
+ if( pDst->type!=DRAWABLE_PIXMAP )
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ if( PsUpdateDrawableGC(pGC, pDst, &psOut, &cMap)==FALSE ) return NULL;
+ PsOut_Offset(psOut, pDst->x, pDst->y);
+ PsOut_BeginFrame(psOut, dstx-srcx, dsty-srcy, dstx, dsty, width, height);
+ PsReplayPixmap(src, pDst);
+ PsOut_EndFrame(psOut);
+ }
+ else PsCopyDisplayList(src, dst, dstx-srcx, dsty-srcy, dstx, dsty,
+ width, height);
+ return NULL;
+}
+
+RegionPtr
+PsCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
+ int width, int height, int dstx, int dsty, unsigned long plane)
+{
+ PixmapPtr src = (PixmapPtr)pSrc;
+ PixmapPtr dst = (PixmapPtr)pDst;
+
+ if( pSrc->type!=DRAWABLE_PIXMAP ) return NULL;
+ if( pDst->type!=DRAWABLE_PIXMAP )
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ if( PsUpdateDrawableGC(pGC, pDst, &psOut, &cMap)==FALSE ) return NULL;
+ PsOut_Offset(psOut, pDst->x, pDst->y);
+ PsOut_BeginFrame(psOut, dstx-srcx, dsty-srcy, dstx, dsty, width, height);
+ PsReplayPixmap(src, pDst);
+ PsOut_EndFrame(psOut);
+ }
+ else PsCopyDisplayList(src, dst, dstx-srcx, dsty-srcy, dstx, dsty,
+ width, height);
+ return NULL;
+}
diff --git a/hw/xprint/ps/PsAttVal.c b/hw/xprint/ps/PsAttVal.c
new file mode 100644
index 000000000..fc23ffef5
--- /dev/null
+++ b/hw/xprint/ps/PsAttVal.c
@@ -0,0 +1,290 @@
+/*
+ * $Xorg: PsAttVal.c,v 1.5 2001/03/13 18:45:31 pookie Exp $
+ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "AttrValid.h"
+
+/*
+ * define valid values and defaults for Printer pool
+ */
+static XpOid ValidContentOrientationsOids[] = {
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape,
+ xpoid_val_content_orientation_reverse_portrait,
+ xpoid_val_content_orientation_reverse_landscape
+};
+static XpOidList ValidContentOrientations = {
+ ValidContentOrientationsOids, XpNumber(ValidContentOrientationsOids)
+};
+
+static XpOid DefaultContentOrientationsOids[] = {
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape
+};
+static XpOidList DefaultContentOrientations = {
+ DefaultContentOrientationsOids, XpNumber(DefaultContentOrientationsOids)
+};
+
+static XpOid ValidPlexesOids[] = {
+ xpoid_val_plex_simplex, xpoid_val_plex_duplex, xpoid_val_plex_tumble
+};
+static XpOidList ValidPlexes = {
+ ValidPlexesOids, XpNumber(ValidPlexesOids)
+};
+
+static XpOid DefaultPlexesOids[] = {
+ xpoid_val_plex_simplex
+};
+static XpOidList DefaultPlexes = {
+ DefaultPlexesOids, XpNumber(DefaultPlexesOids)
+};
+
+static unsigned long ValidPrinterResolutionsCards[] = {
+ 75,
+ 100,
+ 120,
+ 150,
+ 180,
+ 200,
+ 240,
+ 300,
+ 360,
+ 400,
+ 600,
+ 720,
+ 940,
+ 1200,
+ 1440,
+ 2400
+};
+static XpOidCardList ValidPrinterResolutions = {
+ ValidPrinterResolutionsCards, XpNumber(ValidPrinterResolutionsCards)
+};
+
+static unsigned long DefaultPrinterResolutionsCards[] = {
+ 75,
+ 100,
+ 120,
+ 150,
+ 180,
+ 200,
+ 240,
+ 300,
+ 360,
+ 400,
+ 600,
+ 720,
+ 940,
+ 1200
+};
+static XpOidCardList DefaultPrinterResolutions = {
+ DefaultPrinterResolutionsCards, XpNumber(DefaultPrinterResolutionsCards)
+};
+
+static XpOid ValidListfontsModesOids[] = {
+ xpoid_val_xp_list_internal_printer_fonts, xpoid_val_xp_list_glyph_fonts
+};
+static XpOidList ValidListfontsModes = {
+ ValidListfontsModesOids, XpNumber(ValidListfontsModesOids)
+};
+
+static XpOid DefaultListfontsModesOids[] = {
+ xpoid_val_xp_list_glyph_fonts
+};
+static XpOidList DefaultListfontsModes = {
+ DefaultListfontsModesOids, XpNumber(DefaultListfontsModesOids)
+};
+
+static XpOid ValidSetupProvisoOids[] = {
+ xpoid_val_xp_setup_mandatory, xpoid_val_xp_setup_optional
+};
+static XpOidList ValidSetupProviso = {
+
+
+ ValidSetupProvisoOids, XpNumber(ValidSetupProvisoOids)
+};
+
+static XpOidDocFmt ValidDocFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList ValidDocFormatsSupported = {
+ ValidDocFormatsSupportedFmts, XpNumber(ValidDocFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultDocFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList DefaultDocFormatsSupported = {
+ DefaultDocFormatsSupportedFmts, XpNumber(DefaultDocFormatsSupportedFmts)
+};
+
+static XpOidDocFmt ValidEmbeddedFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList ValidEmbeddedFormatsSupported = {
+ ValidEmbeddedFormatsSupportedFmts, XpNumber(ValidEmbeddedFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultEmbeddedFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList DefaultEmbeddedFormatsSupported = {
+ DefaultEmbeddedFormatsSupportedFmts, XpNumber(DefaultEmbeddedFormatsSupportedFmts)
+};
+
+static XpOidDocFmt ValidRawFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+
+};
+static XpOidDocFmtList ValidRawFormatsSupported = {
+ ValidRawFormatsSupportedFmts, XpNumber(ValidRawFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultRawFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList DefaultRawFormatsSupported = {
+ DefaultRawFormatsSupportedFmts, XpNumber(DefaultRawFormatsSupportedFmts)
+};
+
+static XpOid ValidInputTraysOids[] = {
+ xpoid_val_input_tray_manual,
+ xpoid_val_input_tray_main,
+ xpoid_val_input_tray_envelope,
+ xpoid_val_input_tray_large_capacity,
+ xpoid_val_input_tray_bottom
+};
+static XpOidList ValidInputTrays = {
+ ValidInputTraysOids, XpNumber(ValidInputTraysOids)
+};
+
+static XpOid ValidMediumSizesOids[] = {
+ xpoid_val_medium_size_iso_a0,
+ xpoid_val_medium_size_iso_a1,
+ xpoid_val_medium_size_iso_a2,
+ xpoid_val_medium_size_iso_a3,
+ xpoid_val_medium_size_iso_a4,
+ xpoid_val_medium_size_iso_a5,
+ xpoid_val_medium_size_iso_a6,
+ xpoid_val_medium_size_iso_a7,
+ xpoid_val_medium_size_iso_a8,
+ xpoid_val_medium_size_iso_a9,
+ xpoid_val_medium_size_iso_a10,
+ xpoid_val_medium_size_iso_b0,
+ xpoid_val_medium_size_iso_b1,
+ xpoid_val_medium_size_iso_b2,
+ xpoid_val_medium_size_iso_b3,
+ xpoid_val_medium_size_iso_b4,
+ xpoid_val_medium_size_iso_b5,
+ xpoid_val_medium_size_iso_b6,
+ xpoid_val_medium_size_iso_b7,
+ xpoid_val_medium_size_iso_b8,
+ xpoid_val_medium_size_iso_b9,
+ xpoid_val_medium_size_iso_b10,
+ xpoid_val_medium_size_na_letter,
+ xpoid_val_medium_size_na_legal,
+ xpoid_val_medium_size_executive,
+ xpoid_val_medium_size_folio,
+ xpoid_val_medium_size_invoice,
+ xpoid_val_medium_size_ledger,
+ xpoid_val_medium_size_quarto,
+ xpoid_val_medium_size_iso_c3,
+ xpoid_val_medium_size_iso_c4,
+ xpoid_val_medium_size_iso_c5,
+ xpoid_val_medium_size_iso_c6,
+ xpoid_val_medium_size_iso_designated_long,
+ xpoid_val_medium_size_na_10x13_envelope,
+ xpoid_val_medium_size_na_9x12_envelope,
+ xpoid_val_medium_size_na_number_10_envelope,
+ xpoid_val_medium_size_na_7x9_envelope,
+ xpoid_val_medium_size_na_9x11_envelope,
+ xpoid_val_medium_size_na_10x14_envelope,
+ xpoid_val_medium_size_na_number_9_envelope,
+ xpoid_val_medium_size_na_6x9_envelope,
+ xpoid_val_medium_size_na_10x15_envelope,
+ xpoid_val_medium_size_monarch_envelope,
+ xpoid_val_medium_size_a,
+ xpoid_val_medium_size_b,
+ xpoid_val_medium_size_c,
+ xpoid_val_medium_size_d,
+ xpoid_val_medium_size_e,
+ xpoid_val_medium_size_jis_b0,
+ xpoid_val_medium_size_jis_b1,
+ xpoid_val_medium_size_jis_b2,
+ xpoid_val_medium_size_jis_b3,
+ xpoid_val_medium_size_jis_b4,
+ xpoid_val_medium_size_jis_b5,
+ xpoid_val_medium_size_jis_b6,
+ xpoid_val_medium_size_jis_b7,
+ xpoid_val_medium_size_jis_b8,
+ xpoid_val_medium_size_jis_b9,
+ xpoid_val_medium_size_jis_b10,
+ xpoid_val_medium_size_hp_2x_postcard,
+ xpoid_val_medium_size_hp_european_edp,
+ xpoid_val_medium_size_hp_mini,
+ xpoid_val_medium_size_hp_postcard,
+ xpoid_val_medium_size_hp_tabloid,
+ xpoid_val_medium_size_hp_us_edp,
+ xpoid_val_medium_size_hp_us_government_legal,
+ xpoid_val_medium_size_hp_us_government_letter,
+};
+static XpOidList ValidMediumSizes = {
+ ValidMediumSizesOids, XpNumber(ValidMediumSizesOids)
+};
+
+static XpOidDocFmt DefaultDocumentFormat = {
+ "Postscript", "2", NULL
+};
+
+
+/*
+ * init struct for XpValidate*Pool
+ */
+XpValidatePoolsRec PsValidatePoolsRec = {
+ &ValidContentOrientations, &DefaultContentOrientations,
+ &ValidDocFormatsSupported, &DefaultDocFormatsSupported,
+ &ValidInputTrays, &ValidMediumSizes,
+ &ValidPlexes, &DefaultPlexes,
+ &ValidPrinterResolutions, &DefaultPrinterResolutions,
+ &ValidEmbeddedFormatsSupported, &DefaultEmbeddedFormatsSupported,
+ &ValidListfontsModes, &DefaultListfontsModes,
+ &ValidRawFormatsSupported, &DefaultRawFormatsSupported,
+ &ValidSetupProviso,
+ &DefaultDocumentFormat
+};
diff --git a/hw/xprint/ps/PsAttr.c b/hw/xprint/ps/PsAttr.c
new file mode 100644
index 000000000..74da5a0e1
--- /dev/null
+++ b/hw/xprint/ps/PsAttr.c
@@ -0,0 +1,117 @@
+/* $Xorg: PsAttr.c,v 1.4 2001/02/09 02:04:35 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsAttr.c
+** *
+** * Contents: Attribute-handling functions for the PS driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "attributes.h"
+
+char *
+PsGetAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool)
+{
+ return XpGetAttributes(pCon, pool);
+}
+
+char *
+PsGetOneAttribute(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attr)
+{
+ return XpGetOneAttribute(pCon, pool, attr);
+}
+
+int
+PsAugmentAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attrs)
+{
+ return XpAugmentAttributes(pCon, pool, attrs);
+}
+
+int
+PsSetAttributes(
+ XpContextPtr pCon,
+ XPAttributes pool,
+ char *attrs)
+{
+ return XpSetAttributes(pCon, pool, attrs);
+}
diff --git a/hw/xprint/ps/PsCache.c b/hw/xprint/ps/PsCache.c
new file mode 100644
index 000000000..5c823a13e
--- /dev/null
+++ b/hw/xprint/ps/PsCache.c
@@ -0,0 +1,328 @@
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsCache.c
+** *
+** * Contents: Character-caching routines
+** *
+** * Created By: Jay Hobson (Sun MicroSystems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include <X11/fonts/fntfil.h>
+#include <X11/fonts/fntfilst.h>
+
+#define GET 0
+#define RESET 1
+
+struct bm_cache_list {
+ struct bm_cache_list *next;
+ struct bm_cache_list *prev;
+ int height;
+ long id;
+ char *pBuffer;
+};
+
+struct bm_cache_head {
+ struct bm_cache_list *head;
+ int width;
+ struct bm_cache_head *next;
+ struct bm_cache_head *prev;
+};
+
+static struct bm_cache_head *bm_cache = NULL;
+
+static long
+PsBmUniqueId(int func)
+{
+ static long unique_id = 0;
+
+ if(func == RESET)
+ {
+ unique_id = 0;
+ return 0;
+ }
+ else
+ return ++unique_id;
+}
+
+int
+PsBmIsImageCached(
+ int gWidth,
+ int gHeight,
+ char *pBuffer)
+{
+ int return_val = 0;
+ struct bm_cache_head *pList = bm_cache;
+
+ while(pList != NULL && !return_val)
+ {
+ if(pList->width == gWidth)
+ {
+ struct bm_cache_list *pItem = pList->head;
+
+ while(pItem != NULL)
+ {
+ if(pItem->height == gHeight)
+ {
+ int length = 4*(gWidth/32+(gWidth%32!=0))*gHeight;
+
+ if(!memcmp(pItem->pBuffer, pBuffer, sizeof(char)*length))
+ {
+ return_val = pItem->id;
+ break;
+ }
+ }
+ else if(pItem->height > gHeight)
+ break;
+
+ pItem = pItem->next;
+ }
+ }
+ else if(pList->width > gWidth)
+ break;
+
+ pList = pList->next;
+ }
+ return return_val;
+}
+
+int
+PsBmPutImageInCache(
+ int gWidth,
+ int gHeight,
+ char *pBuffer)
+{
+ int return_val = 0;
+ struct bm_cache_head *pList = bm_cache;
+ struct bm_cache_list *pNew;
+ int length = 4*(gWidth/32+(gWidth%32!=0))*gHeight;
+
+ if(gWidth == 1 && gHeight == 1 && pBuffer[0] == 0)
+ return return_val;
+
+ pNew = (struct bm_cache_list *)malloc(sizeof(struct bm_cache_list));
+ pNew->next = NULL;
+ pNew->prev = NULL;
+ pNew->height = gHeight;
+ pNew->id = PsBmUniqueId(GET);
+ pNew->pBuffer = (char *)malloc(sizeof(char)*length);
+
+ memcpy(pNew->pBuffer, pBuffer, length);
+
+ while(pList != NULL)
+ {
+ if(pList->width == gWidth)
+ {
+ struct bm_cache_list *pItem = pList->head;
+
+ while(pItem != NULL)
+ {
+ if(pItem->height >= gHeight)
+ {
+ pNew->next = pItem;
+ pNew->prev = pItem->prev;
+ if(pItem->prev != NULL)
+ pItem->prev->next = pNew;
+ else
+ pList->head = pNew;
+ pItem->prev = pNew;
+
+ return_val = pNew->id;
+
+ break;
+ }
+ else if(pItem->next == NULL)
+ {
+ pNew->prev = pItem;
+ pItem->next = pNew;
+
+ return_val = pNew->id;
+
+ break;
+ }
+
+ pItem = pItem->next;
+ }
+
+ break;
+ }
+
+ pList = pList->next;
+ }
+
+ if(pList == NULL)
+ {
+ struct bm_cache_head *pNewList;
+
+ pNewList = (struct bm_cache_head *)malloc(sizeof(struct bm_cache_head));
+
+ pNewList->next = NULL;
+ pNewList->prev = NULL;
+ pNewList->width = gWidth;
+ pNewList->head = pNew;
+
+ if(bm_cache == NULL)
+ {
+ bm_cache = pNewList;
+ return_val = pNew->id;
+ }
+ else
+ {
+ pList = bm_cache;
+
+ while(pList != NULL)
+ {
+ if(pList->width > gWidth)
+ {
+ pNewList->next = pList;
+ pNewList->prev = pList->prev;
+
+ if(pList->prev != NULL)
+ pList->prev->next = pNewList;
+ else
+ bm_cache = pNewList;
+ pList->prev = pNewList;
+
+ return_val = pNew->id;
+
+ break;
+ }
+ else if(pList->next == NULL)
+ {
+ pNewList->prev = pList;
+ pList->next = pNewList;
+
+ return_val = pNew->id;
+
+ break;
+ }
+
+ pList = pList->next;
+ }
+ }
+ }
+
+ return return_val;
+}
+
+
+static void
+PsBmClearImageCacheItem(
+ struct bm_cache_list *pItem)
+{
+ if(pItem != NULL)
+ {
+ if(pItem->pBuffer != NULL)
+ free(pItem->pBuffer);
+ pItem->pBuffer = NULL;
+
+ if(pItem->next)
+ PsBmClearImageCacheItem(pItem->next);
+ pItem->next = NULL;
+
+ free(pItem);
+ pItem = NULL;
+ }
+}
+
+static void
+PsBmClearImageCacheList(
+ struct bm_cache_head *pList)
+{
+ if(pList != NULL)
+ {
+ if(pList->head)
+ PsBmClearImageCacheItem(pList->head);
+ pList->head = NULL;
+
+ if(pList->next)
+ PsBmClearImageCacheList(pList->next);
+ pList->next = NULL;
+
+ free(pList);
+ pList = NULL;
+ }
+}
+
+void
+PsBmClearImageCache(void)
+{
+ PsBmClearImageCacheList(bm_cache);
+
+ bm_cache = NULL;
+
+ PsBmUniqueId(RESET);
+}
+
diff --git a/hw/xprint/ps/PsColor.c b/hw/xprint/ps/PsColor.c
new file mode 100644
index 000000000..91a44f85a
--- /dev/null
+++ b/hw/xprint/ps/PsColor.c
@@ -0,0 +1,258 @@
+/* $Xorg: PsColor.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsColor.c
+** *
+** * Contents: Color routines for the PS driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "mi.h"
+#include "micmap.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "colormapst.h"
+
+Bool
+PsCreateColormap(ColormapPtr pColor)
+{
+ return miInitializeColormap(pColor);
+}
+
+void
+PsDestroyColormap(ColormapPtr pColor)
+{
+ /* NO-OP */
+}
+
+void
+PsInstallColormap(ColormapPtr pColor)
+{
+ miInstallColormap(pColor);
+}
+
+void
+PsUninstallColormap(ColormapPtr pColor)
+{
+ miUninstallColormap(pColor);
+}
+
+int
+PsListInstalledColormaps(
+ ScreenPtr pScreen,
+ XID *pCmapList)
+{
+ return miListInstalledColormaps(pScreen, pCmapList);
+}
+
+void
+PsStoreColors(
+ ColormapPtr pColor,
+ int ndef,
+ xColorItem *pdefs)
+{
+ int i;
+ for( i=0 ; i<ndef ; i++ )
+ {
+ if( pdefs[i].flags&DoRed )
+ pColor->red[pdefs[i].pixel].co.local.red = pdefs[i].red;
+ if( pdefs[i].flags&DoGreen )
+ pColor->red[pdefs[i].pixel].co.local.green = pdefs[i].green;
+ if( pdefs[i].flags&DoBlue )
+ pColor->red[pdefs[i].pixel].co.local.blue = pdefs[i].blue;
+ }
+}
+
+void
+PsResolveColor(
+ unsigned short *pRed,
+ unsigned short *pGreen,
+ unsigned short *pBlue,
+ VisualPtr pVisual)
+{
+ miResolveColor(pRed, pGreen, pBlue, pVisual);
+}
+
+PsOutColor
+PsGetPixelColor(ColormapPtr cMap, int pixval)
+{
+ VisualPtr v = cMap->pVisual;
+ switch( v->class )
+ {
+ case TrueColor:
+ {
+ PsOutColor p = pixval;
+ PsOutColor r, g, b;
+
+ r = (p & v->redMask) >> v->offsetRed;
+ g = (p & v->greenMask) >> v->offsetGreen;
+ b = (p & v->blueMask) >> v->offsetBlue;
+
+ r = cMap->red[r].co.local.red;
+ g = cMap->green[g].co.local.green;
+ b = cMap->blue[b].co.local.blue;
+
+#ifdef PSOUT_USE_DEEPCOLOR
+ return((r<<32)|(g<<16)|b);
+#else
+ r >>= 8;
+ g >>= 8;
+ b >>= 8;
+
+ return((r<<16)|(g<<8)|b);
+#endif /* PSOUT_USE_DEEPCOLOR */
+ }
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ {
+ PsOutColor r, g, b;
+
+ if( pixval < 0 || pixval > v->ColormapEntries)
+ return(0);
+
+ r = cMap->red[pixval].co.local.red;
+ g = cMap->red[pixval].co.local.green;
+ b = cMap->red[pixval].co.local.blue;
+
+ if ((v->class | DynamicClass) == GrayScale)
+ {
+ /* rescale to gray (see |miResolveColor()|) */
+ r = g = b = (30L*r + 59L*g + 11L*b) / 100L;
+ }
+
+#ifdef PSOUT_USE_DEEPCOLOR
+ return((r<<32)|(g<<16)|b);
+#else
+ r >>= 8;
+ g >>= 8;
+ b >>= 8;
+
+ return((r<<16)|(g<<8)|b);
+#endif /* PSOUT_USE_DEEPCOLOR */
+ }
+ default:
+ FatalError("PsGetPixelColor: Unsupported visual %x\n",
+ (int)cMap->pVisual->class);
+ break;
+ }
+
+ return 0; /* NO-OP*/
+}
+
+void
+PsSetFillColor(DrawablePtr pDrawable, GCPtr pGC, PsOutPtr psOut,
+ ColormapPtr cMap)
+{
+ switch(pGC->fillStyle)
+ {
+ case FillSolid:
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ break;
+ case FillTiled:
+ if( !PsOut_BeginPattern(psOut, pGC->tile.pixmap,
+ pGC->tile.pixmap->drawable.width,
+ pGC->tile.pixmap->drawable.height, PsTile, 0, 0) )
+ {
+ PsReplayPixmap(pGC->tile.pixmap, pDrawable);
+ PsOut_EndPattern(psOut);
+ }
+ PsOut_SetPattern(psOut, pGC->tile.pixmap, PsTile);
+ break;
+ case FillStippled:
+ if( !PsOut_BeginPattern(psOut, pGC->stipple,
+ pGC->stipple->drawable.width,
+ pGC->stipple->drawable.height, PsStip, 0,
+ PsGetPixelColor(cMap, pGC->fgPixel)) )
+ {
+ PsReplayPixmap(pGC->stipple, pDrawable);
+ PsOut_EndPattern(psOut);
+ }
+ PsOut_SetPattern(psOut, pGC->stipple, PsStip);
+ break;
+ case FillOpaqueStippled:
+ if( !PsOut_BeginPattern(psOut, pGC->stipple,
+ pGC->stipple->drawable.width,
+ pGC->stipple->drawable.height, PsOpStip,
+ PsGetPixelColor(cMap, pGC->bgPixel),
+ PsGetPixelColor(cMap, pGC->fgPixel)) )
+ {
+ PsReplayPixmap(pGC->stipple, pDrawable);
+ PsOut_EndPattern(psOut);
+ }
+ PsOut_SetPattern(psOut, pGC->stipple, PsOpStip);
+ break;
+ }
+}
diff --git a/hw/xprint/ps/PsDef.h b/hw/xprint/ps/PsDef.h
new file mode 100644
index 000000000..cf45c8516
--- /dev/null
+++ b/hw/xprint/ps/PsDef.h
@@ -0,0 +1,97 @@
+/* $Xorg: PsDef.h,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsDef.h
+** *
+** * Contents: extran defines and includes for the Ps driver
+** * for a printing X server.
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _PSDEF_H_
+#define _PSDEF_H_
+
+#define DT_PRINT_JOB_HEADER "DT_PRINT_JOB_HEADER"
+#define DT_PRINT_JOB_TRAILER "DT_PRINT_JOB_TRAILER"
+#define DT_PRINT_JOB_COMMAND "DT_PRINT_JOB_COMMAND"
+#define DT_PRINT_JOB_EXEC_COMMAND "DT_PRINT_JOB_EXEC_COMMAND"
+#define DT_PRINT_JOB_EXEC_OPTIONS "DT_PRINT_JOB_EXEC_OPTION"
+#define DT_PRINT_PAGE_HEADER "DT_PRINT_PAGE_HEADER"
+#define DT_PRINT_PAGE_TRAILER "DT_PRINT_PAGE_TRAILER"
+#define DT_PRINT_PAGE_COMMAND "DT_PRINT_PAGE_COMMAND"
+
+#define DT_IN_FILE_STRING "%(InFile)%"
+#define DT_OUT_FILE_STRING "%(OutFile)%"
+#define DT_ALLOWED_COMMANDS_FILE "printCommands"
+
+#endif /* _PSDEF_H_ */
diff --git a/hw/xprint/ps/PsFTFonts.c b/hw/xprint/ps/PsFTFonts.c
new file mode 100644
index 000000000..8857ae43e
--- /dev/null
+++ b/hw/xprint/ps/PsFTFonts.c
@@ -0,0 +1,85 @@
+
+/*
+Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <ctype.h>
+#include <limits.h>
+#include <sys/stat.h>
+
+#include "regionstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include <X11/fonts/fontxlfd.h>
+#include <X11/fonts/fntfil.h>
+#include <X11/fonts/fntfilst.h>
+
+#include "Ps.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include <X11/fonts/ft.h>
+#define NOT_IN_FTFUNCS
+#include <X11/fonts/ftfuncs.h>
+
+char *
+PsGetFTFontFileName(FontPtr pFont)
+{
+ FTFontPtr tf = (FTFontPtr)pFont->fontPrivate;
+ return tf->instance->face->filename;
+}
+
+Bool
+PsIsFreeTypeFont(FontPtr pFont)
+{
+ int i;
+ int nprops = pFont->info.nprops;
+ FontPropPtr props = pFont->info.props;
+ /* "RASTERIZER_NAME" must match the rasterizer name set in
+ * xc/lib/font/FreeType/ftfuncs.c */
+ Atom name = MakeAtom("RASTERIZER_NAME", 15, True);
+ Atom value = (Atom)0;
+ char *rv;
+
+ for( i=0 ; i<nprops ; i++ )
+ {
+ if( props[i].name==name )
+ { value = props[i].value; break; }
+ }
+ if( !value )
+ return False;
+
+ rv = NameForAtom(value);
+ if( !rv )
+ return False;
+
+ if( memcmp(rv, "FreeType", 8) == 0 )
+ return True;
+
+ return False;
+}
+
diff --git a/hw/xprint/ps/PsFonts.c b/hw/xprint/ps/PsFonts.c
new file mode 100644
index 000000000..c4d5b03e2
--- /dev/null
+++ b/hw/xprint/ps/PsFonts.c
@@ -0,0 +1,874 @@
+/* $Xorg: PsFonts.c,v 1.6 2001/03/06 16:30:15 pookie Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsFonts.c
+** *
+** * Contents: Font code for PS driver.
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "regionstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include <X11/fonts/fontxlfd.h>
+#include <X11/fonts/fntfil.h>
+#include <X11/fonts/fntfilst.h>
+
+#include "Ps.h"
+
+#include <ctype.h>
+#include <limits.h>
+#include <sys/stat.h>
+
+Bool
+PsRealizeFont(
+ ScreenPtr pscr,
+ FontPtr pFont)
+{
+ return TRUE;
+}
+
+Bool
+PsUnrealizeFont(
+ ScreenPtr pscr,
+ FontPtr pFont)
+{
+ return TRUE;
+}
+
+char *
+PsGetFontName(FontPtr pFont)
+{
+ int i;
+ int nprops = pFont->info.nprops;
+ FontPropPtr props = pFont->info.props;
+ Atom name = MakeAtom("FONT", 4, True);
+ Atom value = (Atom)0;
+
+ for( i=0 ; i<nprops ; i++ )
+ {
+ if( (Atom)props[i].name==name )
+ { value = props[i].value; break; }
+ }
+ if( !value ) return (char *)0;
+ return NameForAtom(value);
+}
+
+int
+PsGetFontSize(FontPtr pFont, float *mtx)
+{
+ FontScalableRec vals;
+ char *name = PsGetFontName(pFont);
+ int value = 0;
+
+ FontParseXLFDName(name, &vals, FONT_XLFD_REPLACE_NONE);
+ if( vals.values_supplied&PIXELSIZE_ARRAY )
+ {
+ int i;
+ for( i=0 ; i<4 ; i++ )
+ mtx[i] = (float)vals.pixel_matrix[i];
+ }
+ else
+ {
+ value = vals.pixel;
+ if( !value ) value = 20;
+ }
+ return value;
+}
+
+char *
+PsGetPSFontName(FontPtr pFont)
+{
+ int i;
+ int nprops = pFont->info.nprops;
+ FontPropPtr props = pFont->info.props;
+ /* "_ADOBE_POSTSCRIPT_FONTNAME" maps directly to a PMF OBJ_NAME attribute
+ * name - changing the name will break printer-builtin fonts. */
+ Atom name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, True);
+ Atom value = (Atom)0;
+
+ for( i=0 ; i<nprops ; i++ )
+ {
+ if( (Atom)props[i].name==name )
+ { value = props[i].value; break; }
+ }
+ if( !value ) return (char *)0;
+ return NameForAtom(value);
+}
+
+int
+PsIsISOLatin1Encoding(FontPtr pFont)
+{
+ int i;
+ int nprops = pFont->info.nprops;
+ FontPropPtr props = pFont->info.props;
+ Atom reg = MakeAtom("CHARSET_REGISTRY", 16, True);
+ Atom enc = MakeAtom("CHARSET_ENCODING", 16, True);
+ Atom rv = 0, ev = 0;
+ char *rp = 0;
+ char *ep = 0;
+
+ for( i=0 ; i<nprops ; i++ )
+ {
+ if( (Atom)props[i].name==reg ) rv = props[i].value;
+ if( (Atom)props[i].name==enc ) ev = props[i].value;
+ }
+ if( rv ) rp = NameForAtom(rv);
+ if( ev ) ep = NameForAtom(ev);
+ if( (!rp) || (!ep) ) return(0);
+ if( (char)tolower(rp[0])!='i' ||
+ (char)tolower(rp[1])!='s' ||
+ (char)tolower(rp[2])!='o' ||
+ memcmp(&rp[3], "8859", 4)!=0 ||
+ ep[0]!='1' ) return(0);
+ return(1);
+}
+
+/* Return the encoding part of the XLFD (e.g. "*-iso8859-6.8x" etc.)*/
+char *PsGetEncodingName(FontPtr pFont)
+{
+ int i;
+ int nprops = pFont->info.nprops;
+ FontPropPtr props = pFont->info.props;
+ Atom fnt = MakeAtom("FONT", 4, True);
+ Atom reg = MakeAtom("CHARSET_REGISTRY", 16, True);
+ Atom enc = MakeAtom("CHARSET_ENCODING", 16, True);
+ Atom fv = 0, rv = 0, ev = 0;
+ char *fp = 0;
+ char *rp = 0;
+ char *ep = 0;
+ char *encname;
+
+ for( i=0 ; i<nprops ; i++ )
+ {
+ if( props[i].name==fnt ) fv = props[i].value;
+ if( props[i].name==reg ) rv = props[i].value;
+ if( props[i].name==enc ) ev = props[i].value;
+ }
+ if( fv ) fp = NameForAtom(fv);
+ if( rv ) rp = NameForAtom(rv);
+ if( ev ) ep = NameForAtom(ev);
+
+ if( (!rp) || (!ep) || (!fp))
+ return(0);
+
+ encname = fp;
+ encname += strlen(encname) - (strlen(rp) + strlen(ep) + 1);
+
+ return encname;
+}
+
+/* strstr(), case-insensitive */
+static
+char *str_case_str(const char *s, const char *find)
+{
+ size_t len;
+ char c,
+ sc;
+
+ if ((c = tolower(*find++)) != '\0')
+ {
+ len = strlen(find);
+ do
+ {
+ do
+ {
+ if ((sc = tolower(*s++)) == '\0')
+ return NULL;
+ } while (sc != c);
+ } while (strncasecmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
+}
+
+/* Check if the font path element is a directory which can be examined
+ * (for example the font may be from a font server
+ * (e.g. pFont->fpe->name == "tcp/:7100"))
+ */
+static
+Bool IsFPEaReadableDir(FontPtr pFont)
+{
+ const char *fpe_name = pFont->fpe->name;
+ if (!fpe_name)
+ return False;
+
+#define MODEL_FONTPATH_PREFIX "PRINTER:"
+#define MODEL_FONTPATH_PREFIX_LEN 8
+ /* Strip model-specific font path prefix if there is one... */
+ if (!strncmp(fpe_name, MODEL_FONTPATH_PREFIX, MODEL_FONTPATH_PREFIX_LEN))
+ fpe_name += MODEL_FONTPATH_PREFIX_LEN;
+
+ if (access(fpe_name, F_OK) == 0)
+ {
+ return True;
+ }
+
+ return False;
+}
+
+static
+char *getFontFilename(FontPtr pFont)
+{
+ FontDirectoryPtr dir;
+ const char *dlfnam;
+ FILE *file;
+ struct stat statb;
+ char buf[512];
+ char *front, *fn;
+ char font_dir_fname[PATH_MAX], /* Full path of fonts.dir */
+ font_file_fname[PATH_MAX]; /* Name of font file (excluding path) */
+
+#ifdef XP_USE_FREETYPE
+ if( PsIsFreeTypeFont(pFont) )
+ {
+ const char *fontname = PsGetFTFontFileName(pFont);
+
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "getFontFilename: freetype font, file='%s'\n", fontname?fontname:"<NULL>");
+#endif /* DEBUG_gisburn */
+
+ if( !fontname )
+ return NULL;
+
+ return strdup(fontname);
+ }
+#endif /* XP_USE_FREETYPE */
+
+ if (!IsFPEaReadableDir(pFont))
+ {
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "getFontFilename: '%s' no valid font path on disk\n", pFont->fpe->name);
+#endif /* DEBUG_gisburn */
+ return NULL;
+ }
+
+ dir = pFont->fpe->private;
+ sprintf(font_dir_fname, "%s%s", dir->directory, "fonts.dir");
+
+ if (!(dlfnam = PsGetFontName(pFont)))
+ return NULL;
+
+ file = fopen(font_dir_fname, "r");
+ if (file)
+ {
+ if (fstat (fileno(file), &statb) == -1)
+ return NULL;
+
+ while( fgets(buf, sizeof(buf)-1, file) )
+ {
+ if ((fn = strstr(buf, " -")))
+ {
+ strcpy(font_file_fname, buf);
+ font_file_fname[fn - buf] = '\0';
+ fn++;
+ if ((front = str_case_str(fn, "normal-")))
+ {
+ fn[front - fn] = '\0';
+ if (str_case_str(dlfnam, fn))
+ {
+ char full_font_file_path[PATH_MAX];
+
+ fclose(file);
+
+ sprintf(full_font_file_path, "%s%s", dir->directory, font_file_fname);
+
+#ifdef xDEBUG_gisburn
+ fprintf(stderr, "getFontFilename: returning '%s'\n", full_font_file_path);
+#endif /* DEBUG_gisburn */
+ return strdup(full_font_file_path);
+ }
+ }
+ }
+ }
+ }
+ font_file_fname[0] = '\0';
+ fclose(file);
+
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "getFontFilename: returning NULL\n");
+#endif /* DEBUG_gisburn */
+
+ return NULL;
+}
+
+static
+PsFontTypeInfoRec *PsFindFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
+{
+ PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
+ PsFontTypeInfoRec *rec;
+ const char *psname;
+ char *font_filename;
+ char *encname;
+#ifdef XP_USE_FREETYPE
+ Bool is_freetypefont;
+#endif /* XP_USE_FREETYPE */
+
+#ifdef XP_USE_FREETYPE
+ is_freetypefont = PsIsFreeTypeFont(pFont);
+#endif /* XP_USE_FREETYPE */
+ encname = PsGetEncodingName(pFont);
+
+ /* First try: Search by PostScript font name */
+ psname = PsGetPSFontName(pFont);
+ if (psname)
+ {
+ for( rec = cPriv->fontTypeInfoRecords ; rec != NULL ; rec = rec->next )
+ {
+#ifdef XP_USE_FREETYPE
+ if (is_freetypefont)
+ {
+ if (rec->adobe_ps_name)
+ {
+ if ((rec->font_type == PSFTI_FONT_TYPE_FREETYPE) &&
+ (!strcmp(rec->adobe_ps_name, psname)) &&
+ (!strcmp(rec->ft_download_encoding, encname)))
+ {
+ return rec;
+ }
+ }
+ }
+ else
+#endif /* XP_USE_FREETYPE */
+ {
+ if (rec->adobe_ps_name)
+ {
+ if ((rec->font_type != PSFTI_FONT_TYPE_FREETYPE) &&
+ (!strcmp(rec->adobe_ps_name, psname)))
+ {
+ return rec;
+ }
+ }
+ }
+ }
+ }
+
+ /* Last attempt: Search by filename */
+ font_filename = getFontFilename(pFont);
+ if (font_filename)
+ {
+ for( rec = cPriv->fontTypeInfoRecords ; rec != NULL ; rec = rec->next )
+ {
+ if (rec->filename)
+ {
+#ifdef XP_USE_FREETYPE
+ if (is_freetypefont)
+ {
+ if ( (rec->font_type == PSFTI_FONT_TYPE_FREETYPE) &&
+ (!strcasecmp(rec->filename, font_filename)) &&
+ (!strcasecmp(rec->ft_download_encoding, encname)) )
+ {
+ free(font_filename);
+ return rec;
+ }
+ }
+ else
+#endif /* XP_USE_FREETYPE */
+ {
+ if ( (rec->font_type != PSFTI_FONT_TYPE_FREETYPE) &&
+ (!strcasecmp(rec->filename, font_filename)) )
+ {
+ free(font_filename);
+ return rec;
+ }
+ }
+ }
+ }
+
+ free(font_filename);
+ }
+
+ return NULL;
+}
+
+static
+void PsAddFontTypeInfoRec(DrawablePtr pDrawable, PsFontTypeInfoRec *add_rec)
+{
+ PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
+
+ /* ToDO: Always move the last used entry to the top that the list get's
+ * sorted in an efficient order... :-) */
+ add_rec->next = cPriv->fontTypeInfoRecords;
+ cPriv->fontTypeInfoRecords = add_rec;
+}
+
+static
+Bool strcaseendswith(const char *str, const char *suffix)
+{
+ const char *s;
+
+ s = str + strlen(str) - strlen(suffix);
+
+ if (!strcasecmp(s, suffix))
+ return True;
+
+ return False;
+}
+
+
+static
+int getFontFileType( const char *filename )
+{
+ int type;
+
+ /* Is this a Adobe PostScript Type 1 binary font (PFB) ? */
+ if( strcaseendswith(filename, ".pfb") )
+ {
+ type = PSFTI_FONT_TYPE_PS_TYPE1_PFB;
+ }
+ /* Is this a Adobe PostScript ASCII font (PFA) ? */
+ else if( strcaseendswith(filename, ".pfa") )
+ {
+ type = PSFTI_FONT_TYPE_PS_TYPE1_PFA;
+ }
+ /* Is this a PMF(=Printer Metrics File) ? */
+ else if( strcaseendswith(filename, ".pmf") )
+ {
+ type = PSFTI_FONT_TYPE_PMF;
+ }
+ /* Is this a TrueType font file ? */
+ else if( strcaseendswith(filename, ".ttf") ||
+ strcaseendswith(filename, ".ttc") ||
+ strcaseendswith(filename, ".otf") ||
+ strcaseendswith(filename, ".otc") )
+ {
+ type = PSFTI_FONT_TYPE_TRUETYPE;
+ }
+ else
+ {
+ type = PSFTI_FONT_TYPE_OTHER;
+ }
+
+#ifdef XP_USE_FREETYPE
+ {
+ XpContextPtr pCon;
+ char *downloadfonts;
+ pCon = XpGetPrintContext(requestingClient);
+ downloadfonts = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-psddx-download-fonts");
+ if( downloadfonts )
+ {
+ /* Should we download PS Type1 fonts as PS Type1||Type3 ? */
+ if( (type == PSFTI_FONT_TYPE_PS_TYPE1_PFA) &&
+ (strstr(downloadfonts, "pfa") != NULL) )
+ {
+ type = PSFTI_FONT_TYPE_FREETYPE;
+ }
+
+ if( (type == PSFTI_FONT_TYPE_PS_TYPE1_PFB) &&
+ (strstr(downloadfonts, "pfb") != NULL) )
+ {
+ type = PSFTI_FONT_TYPE_FREETYPE;
+ }
+
+ /* Should we download TrueType fonts as PS Type1||Type3 ? */
+ if( (type == PSFTI_FONT_TYPE_TRUETYPE) &&
+ ((strstr(downloadfonts, "ttf") != NULL) ||
+ (strstr(downloadfonts, "ttc") != NULL) ||
+ (strstr(downloadfonts, "otf") != NULL) ||
+ (strstr(downloadfonts, "otc") != NULL)) )
+ {
+ type = PSFTI_FONT_TYPE_FREETYPE;
+ }
+ }
+ }
+#endif /* XP_USE_FREETYPE */
+
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "getFontFileType: '%s' is %d\n", filename, (int)type);
+#endif /* DEBUG_gisburn */
+ return type;
+}
+
+PsFTDownloadFontType PsGetFTDownloadFontType(void)
+{
+ PsFTDownloadFontType downloadfonttype;
+ XpContextPtr pCon;
+ char *psfonttype;
+
+ pCon = XpGetPrintContext(requestingClient);
+ psfonttype = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-psddx-download-font-type");
+
+ if( !psfonttype || !strlen(psfonttype) )
+ {
+ return PsFontType1; /* Default download font type is PS Type1 */
+ }
+
+ if( !strcmp(psfonttype, "bitmap") )
+ {
+ downloadfonttype = PsFontBitmap;
+ }
+ else if( !strcmp(psfonttype, "pstype3") )
+ {
+ downloadfonttype = PsFontType3;
+ }
+ else if( !strcmp(psfonttype, "pstype1") )
+ {
+ downloadfonttype = PsFontType1;
+ }
+ else
+ {
+ FatalError("PS DDX: XPPrinterAttr/xp-psddx-download-freetype-font-type='%s' not implemented\n", psfonttype);
+ return 0; /* NO-OP, FatalError() will call |exit()| */
+ }
+
+ return downloadfonttype;
+}
+
+static
+PsFontTypeInfoRec *PsCreateFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
+{
+ char *dlfnam;
+ PsFontTypeInfoRec *rec;
+
+ if (!(dlfnam = PsGetFontName(pFont)))
+ return NULL;
+
+ if (!(rec = (PsFontTypeInfoRec *)xalloc(sizeof(PsFontTypeInfoRec))))
+ return NULL;
+ memset(rec, 0, sizeof(PsFontTypeInfoRec));
+
+ rec->next = NULL;
+
+ if ((rec->filename = getFontFilename(pFont)))
+ {
+ rec->font_type = getFontFileType(rec->filename);
+ }
+ else
+ {
+ rec->filename = NULL;
+ rec->font_type = PSFTI_FONT_TYPE_OTHER;
+ }
+
+ rec->adobe_ps_name = PsGetPSFontName(pFont);
+#ifdef XP_USE_FREETYPE
+ rec->ft_download_encoding = PsGetEncodingName(pFont);
+ rec->ft_download_font_type = PsGetFTDownloadFontType();
+#endif /* XP_USE_FREETYPE */
+ rec->download_ps_name = NULL;
+
+#define SET_FONT_DOWNLOAD_STATUS(rec, downloaded) { int i; for (i = 0 ; i < 256 ; i++) { (rec)->alreadyDownloaded[i]=(downloaded); } }
+
+ /* Set some flags based on the font type */
+ switch( rec->font_type )
+ {
+ case PSFTI_FONT_TYPE_PS_TYPE1_PFA:
+ case PSFTI_FONT_TYPE_PS_TYPE1_PFB:
+ rec->downloadableFont = True;
+ SET_FONT_DOWNLOAD_STATUS(rec, False);
+ rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
+ break;
+
+ case PSFTI_FONT_TYPE_PMF:
+ rec->downloadableFont = True; /* This font is in printer's ROM */
+ SET_FONT_DOWNLOAD_STATUS(rec, True);
+ rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
+ break;
+
+ case PSFTI_FONT_TYPE_TRUETYPE:
+ /* Note: TrueType font download not implemented */
+ rec->downloadableFont = False;
+ SET_FONT_DOWNLOAD_STATUS(rec, False);
+ rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
+ break;
+
+#ifdef XP_USE_FREETYPE
+ case PSFTI_FONT_TYPE_FREETYPE:
+ if( rec->ft_download_font_type == PsFontType1 ||
+ rec->ft_download_font_type == PsFontType3 )
+ {
+ rec->downloadableFont = True;
+ }
+ else
+ {
+ rec->downloadableFont = False;
+ }
+
+ SET_FONT_DOWNLOAD_STATUS(rec, False);
+ rec->is_iso_encoding = False; /* Freetype--->PS Type1/Type3 uses always non-iso PS encoding for now */
+ break;
+#endif /* XP_USE_FREETYPE */
+
+ case PSFTI_FONT_TYPE_OTHER:
+ default:
+ rec->downloadableFont = False;
+ SET_FONT_DOWNLOAD_STATUS(rec, False);
+ rec->is_iso_encoding = PsIsISOLatin1Encoding(pFont);
+ break;
+ }
+
+#ifdef XP_USE_FREETYPE
+ if( (rec->font_type == PSFTI_FONT_TYPE_FREETYPE) )
+ {
+ char *s;
+ register int c;
+
+ if( rec->adobe_ps_name )
+ {
+ rec->download_ps_name = malloc(strlen(rec->adobe_ps_name) + strlen(rec->ft_download_encoding) + 2);
+ sprintf(rec->download_ps_name, "%s_%s", rec->adobe_ps_name, rec->ft_download_encoding);
+ }
+ else
+ {
+ /* Unfortunately not all TTF fonts have a PostScript font name (like
+ * Solaris TTF fonts in /usr/openwin/lib/locale/ko.UTF-8/X11/fonts/TrueType,
+ * /usr/openwin/lib/locale/ko/X11/fonts/TrueType) - in this case we
+ * have to generate a font name
+ */
+ char ftfontname[64];
+ static long myfontindex = 0L;
+ sprintf(ftfontname, "psfont_%lx", myfontindex++);
+
+ rec->download_ps_name = malloc(strlen(ftfontname) + strlen(rec->ft_download_encoding) + 2);
+ sprintf(rec->download_ps_name, "%s_%s", ftfontname, rec->ft_download_encoding);
+
+ fprintf(stderr, "PsCreateFontTypeInfoRec: Note: '%s' has no PS font name, using '%s' for now.\n", dlfnam, rec->download_ps_name);
+ }
+
+ /* Make sure the font name we use for download is a valid PS font name */
+ for( s = rec->download_ps_name ; *s != '\0'; s++ )
+ {
+ c = *s;
+
+ /* Check for allowed chars, invalid ones are replaced with a '_'
+ * (and check that the first char is not a digit) */
+ if( !(isalnum(c) || c == '.' || c == '_' || c == '-') || (s==rec->download_ps_name && isdigit(c)) )
+ {
+ *s = '_';
+ }
+ }
+ }
+ else
+#endif /* XP_USE_FREETYPE */
+ {
+ if( rec->adobe_ps_name )
+ {
+ rec->download_ps_name = strdup(rec->adobe_ps_name);
+ }
+ else
+ {
+ rec->download_ps_name = NULL;
+ }
+ }
+
+ /* Safeguard - only treat font as downloadable when we have a PS font name!! */
+ if (!rec->download_ps_name && rec->downloadableFont)
+ {
+ /* XXX: Log this message to the log when the logging service has been hook'ed up */
+ fprintf(stderr, "PsCreateFontTypeInfoRec: Safeguard: No PS font name for '%s'!\n", dlfnam);
+ rec->downloadableFont = False;
+ }
+
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "PsCreateFontTypeInfoRec: Created PsFontTypeInfoRec '%s' ('%s'/'%s')\n",
+ ((rec->filename) ?(rec->filename) :("<null>")),
+ ((rec->adobe_ps_name) ?(rec->adobe_ps_name):("<null>")),
+ ((rec->download_ps_name)?(rec->download_ps_name):("<null>")));
+#endif /* DEBUG_gisburn */
+
+ return rec;
+}
+
+static
+PsFontTypeInfoRec *PsGetFontTypeInfoRec(DrawablePtr pDrawable, FontPtr pFont)
+{
+ PsFontTypeInfoRec *rec;
+ char *dlfnam;
+
+ if(!(dlfnam = PsGetFontName(pFont)))
+ return NULL;
+
+ rec = PsFindFontTypeInfoRec(pDrawable, pFont);
+ if (rec)
+ return rec;
+
+ rec = PsCreateFontTypeInfoRec(pDrawable, pFont);
+ if (!rec)
+ return NULL;
+
+ PsAddFontTypeInfoRec(pDrawable, rec);
+
+ return rec;
+}
+
+static
+void PsFreeFontTypeInfoRecords( PsContextPrivPtr priv )
+{
+ PsFontTypeInfoRec *curr, *next;
+ curr = priv->fontTypeInfoRecords;
+ while( curr != NULL )
+ {
+ if (curr->filename)
+ free(curr->filename); /* Free memory allocated by |strdup()| */
+
+ if (curr->download_ps_name)
+ free(curr->download_ps_name);
+
+ next = curr->next;
+ xfree(curr);
+ curr = next;
+ }
+}
+
+static
+PsFontInfoRec *PsFindFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
+{
+ PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
+ PsFontInfoRec *rec;
+
+ if (!pFont)
+ return NULL;
+
+ for( rec = cPriv->fontInfoRecords ; rec != NULL ; rec = rec->next )
+ {
+ if ((rec->font == pFont) &&
+ (rec->font_fontPrivate == pFont->fontPrivate))
+ return rec;
+ }
+
+ return NULL;
+}
+
+static
+void PsAddFontInfoRec(DrawablePtr pDrawable, PsFontInfoRec *add_rec)
+{
+ PsContextPrivRec *cPriv = PsGetPsContextPriv(pDrawable);
+
+ /* ToDO: Always move the last used entry to the top that the list get's
+ * sorted in an efficient order... :-) */
+ add_rec->next = cPriv->fontInfoRecords;
+ cPriv->fontInfoRecords = add_rec;
+}
+
+static
+PsFontInfoRec *PsCreateFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
+{
+ PsFontInfoRec *rec;
+ PsFontTypeInfoRec *ftir;
+
+ if (!(ftir = PsGetFontTypeInfoRec(pDrawable, pFont)))
+ return NULL;
+
+ if (!(rec = (PsFontInfoRec *)xalloc(sizeof(PsFontInfoRec))))
+ return NULL;
+ memset(rec, 0, sizeof(PsFontInfoRec));
+
+ rec->font = pFont;
+ rec->font_fontPrivate = pFont->fontPrivate;
+ rec->ftir = ftir;
+ rec->next = NULL;
+ rec->dfl_name = PsGetFontName(pFont);
+ rec->size = PsGetFontSize(pFont, rec->mtx);
+
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "PsCreateFontInfoRec: Created PsFontInfoRec '%s'\n",
+ ((rec->dfl_name)?(rec->dfl_name):("<null>")));
+#endif /* DEBUG_gisburn */
+
+ return rec;
+}
+
+PsFontInfoRec *PsGetFontInfoRec(DrawablePtr pDrawable, FontPtr pFont)
+{
+ PsFontInfoRec *rec;
+
+ rec = PsFindFontInfoRec(pDrawable, pFont);
+ if (rec)
+ return rec;
+
+ rec = PsCreateFontInfoRec(pDrawable, pFont);
+ if (!rec)
+ return NULL;
+
+ PsAddFontInfoRec(pDrawable, rec);
+
+ return rec;
+}
+
+void PsFreeFontInfoRecords( PsContextPrivPtr priv )
+{
+ PsFontInfoRec *curr, *next;
+ curr = priv->fontInfoRecords;
+ while( curr != NULL )
+ {
+ next = curr->next;
+ xfree(curr);
+ curr = next;
+ }
+
+ PsFreeFontTypeInfoRecords(priv);
+
+ priv->fontTypeInfoRecords = NULL;
+ priv->fontInfoRecords = NULL;
+}
diff --git a/hw/xprint/ps/PsGC.c b/hw/xprint/ps/PsGC.c
new file mode 100644
index 000000000..ada0b8c65
--- /dev/null
+++ b/hw/xprint/ps/PsGC.c
@@ -0,0 +1,415 @@
+/* $Xorg: PsGC.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsGC.c
+** *
+** * Contents: Graphics Context handling for the PS driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "migc.h"
+#include "scrnintstr.h"
+
+static GCOps PsGCOps =
+{
+ PsFillSpans,
+ PsSetSpans,
+ PsPutImage,
+ PsCopyArea,
+ PsCopyPlane,
+ PsPolyPoint,
+ PsPolyLine,
+ PsPolySegment,
+ PsPolyRectangle,
+ PsPolyArc,
+ PsFillPolygon,
+ PsPolyFillRect,
+ PsPolyFillArc,
+ PsPolyText8,
+ PsPolyText16,
+ PsImageText8,
+ PsImageText16,
+ PsImageGlyphBlt,
+ PsPolyGlyphBlt,
+ PsPushPixels
+};
+
+
+static GCFuncs PsGCFuncs =
+{
+ PsValidateGC,
+ PsChangeGC,
+ PsCopyGC,
+ PsDestroyGC,
+ PsChangeClip,
+ PsDestroyClip,
+ PsCopyClip
+};
+
+Bool
+PsCreateGC(pGC)
+ GCPtr pGC;
+{
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ pGC->ops = &PsGCOps;
+ pGC->funcs = &PsGCFuncs;
+
+ pGC->clientClip = (pointer)xalloc(sizeof(PsClipRec));
+ memset(pGC->clientClip, 0, sizeof(PsClipRec));
+ return TRUE;
+}
+
+static int
+PsGetDrawablePrivateStuff(
+ DrawablePtr pDrawable,
+ GC *gc,
+ unsigned long *valid,
+ PsOutPtr *psOut,
+ ColormapPtr *cMap)
+{
+ XpContextPtr pCon;
+ PsContextPrivPtr cPriv;
+ PsScreenPrivPtr sPriv;
+
+ switch(pDrawable->type)
+ {
+ case DRAWABLE_PIXMAP:
+ return FALSE;
+ case DRAWABLE_WINDOW:
+ pCon = PsGetContextFromWindow((WindowPtr)pDrawable);
+ if( pCon==NULL ) return FALSE;
+ else
+ {
+ Colormap c;
+ ColormapPtr cmap;
+
+ c = wColormap((WindowPtr)pDrawable);
+ cmap = (ColormapPtr)LookupIDByType(c, RT_COLORMAP);
+
+ cPriv = pCon->devPrivates[PsContextPrivateIndex].ptr;
+ sPriv = (PsScreenPrivPtr)
+ pDrawable->pScreen->devPrivates[PsScreenPrivateIndex].ptr;
+ *gc = cPriv->lastGC;
+ *valid = cPriv->validGC;
+ *psOut = cPriv->pPsOut;
+ *cMap = cmap;
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+PsContextPrivPtr
+PsGetPsContextPriv( DrawablePtr pDrawable )
+{
+ XpContextPtr pCon;
+
+ switch(pDrawable->type)
+ {
+ case DRAWABLE_PIXMAP:
+ return FALSE;
+ case DRAWABLE_WINDOW:
+ pCon = PsGetContextFromWindow((WindowPtr)pDrawable);
+ if (pCon != NULL)
+ {
+ return pCon->devPrivates[PsContextPrivateIndex].ptr;
+ }
+ }
+ return NULL;
+}
+
+int
+PsUpdateDrawableGC(
+ GCPtr pGC,
+ DrawablePtr pDrawable,
+ PsOutPtr *psOut,
+ ColormapPtr *cMap)
+{
+ GC dGC;
+ unsigned long valid;
+ int i;
+ PsContextPrivPtr cPriv;
+ BoxPtr boxes;
+
+ if (!PsGetDrawablePrivateStuff(pDrawable, &dGC, &valid, psOut, cMap))
+ return FALSE;
+
+ switch (pDrawable->type) {
+
+ case DRAWABLE_PIXMAP:
+ /* we don't support pixmaps yet! */
+ return FALSE;
+ break;
+ case DRAWABLE_WINDOW:
+ if( pGC )
+ {
+ RegionPtr pReg;
+ WindowPtr pWin = (WindowPtr)pDrawable;
+ Bool freeClip;
+ PsClipPtr clp = (PsClipPtr)pGC->clientClip;
+ if( clp->outterClips )
+ { xfree(clp->outterClips); clp->outterClips = 0; }
+ clp->nOutterClips = 0;
+ if( pGC->subWindowMode==IncludeInferiors )
+ {
+ pReg = NotClippedByChildren(pWin);
+ freeClip = TRUE;
+ }
+ else
+ {
+ pReg = &pWin->clipList;
+ freeClip = FALSE;
+ }
+
+ if( pReg->data )
+ {
+ boxes = (BoxPtr)((char *)pReg->data+sizeof(long)*2);
+ clp->nOutterClips = pReg->data->numRects;
+ clp->outterClips =
+ (PsRectPtr)xalloc(clp->nOutterClips*sizeof(PsRectRec));
+ for( i=0 ; i<clp->nOutterClips ; i++ )
+ {
+ clp->outterClips[i].x = boxes[i].x1;
+ clp->outterClips[i].y = boxes[i].y1;
+ clp->outterClips[i].w = (boxes[i].x2-boxes[i].x1)+1;
+ clp->outterClips[i].h = (boxes[i].y2-boxes[i].y1)+1;
+ }
+ }
+
+ if( freeClip ) REGION_DESTROY(pGC->pScreen, pReg);
+ PsOut_Offset(*psOut, pDrawable->x, pDrawable->y);
+ PsOut_Clip(*psOut, pGC->clientClipType, (PsClipPtr)pGC->clientClip);
+ }
+ cPriv = ( PsGetContextFromWindow( (WindowPtr)pDrawable ) )
+ ->devPrivates[PsContextPrivateIndex].ptr;
+ break;
+ }
+ return TRUE;
+}
+
+void
+PsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ pGC->ops = &PsGCOps;
+}
+
+void
+PsChangeGC(GCPtr pGC, unsigned long changes)
+{
+}
+
+void
+PsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+}
+
+void
+PsDestroyGC(GCPtr pGC)
+{
+ PsDestroyClip(pGC);
+ xfree(pGC->clientClip);
+}
+
+void
+PsChangeClip(GCPtr pGC, int type, pointer pValue, int nrects)
+{
+ int i;
+ PsClipPtr clp = (PsClipPtr)pGC->clientClip;
+ RegionPtr rgn;
+ BoxPtr boxes;
+ xRectangle *rects;
+
+ PsDestroyClip(pGC);
+ pGC->clientClipType = type;
+ switch(type)
+ {
+ case CT_NONE: break;
+ case CT_PIXMAP:
+ clp->elms = PsCreateFillElementList((PixmapPtr)pValue, &clp->nElms);
+ (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue);
+ break;
+ case CT_REGION:
+ rgn = (RegionPtr)pValue;
+ boxes = (BoxPtr)((char *)rgn->data+sizeof(long)*2);
+ clp->nRects = rgn->data->numRects;
+ clp->rects = (PsRectPtr)xalloc(clp->nRects*sizeof(PsRectRec));
+ for( i=0 ; i<clp->nRects ; i++ )
+ {
+ clp->rects[i].x = boxes[i].x1;
+ clp->rects[i].y = boxes[i].y1;
+ clp->rects[i].w = (boxes[i].x2-boxes[i].x1)+1;
+ clp->rects[i].h = (boxes[i].y2-boxes[i].y1)+1;
+ }
+ REGION_DESTROY(pGC->pScreen, (RegionPtr)pValue);
+ break;
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+ rects = (xRectangle *)pValue;
+ clp->nRects = nrects;
+ clp->rects = (PsRectPtr)xalloc(clp->nRects*sizeof(PsRectRec));
+ for( i=0 ; i<clp->nRects ; i++ )
+ {
+ clp->rects[i].x = rects[i].x;
+ clp->rects[i].y = rects[i].y;
+ clp->rects[i].w = rects[i].width;
+ clp->rects[i].h = rects[i].height;
+ }
+ xfree(pValue);
+ break;
+ }
+}
+
+void
+PsDestroyClip(GCPtr pGC)
+{
+ PsClipPtr clp = (PsClipPtr)pGC->clientClip;
+
+ if( clp->rects ) xfree(clp->rects);
+ if( clp->outterClips ) xfree(clp->outterClips);
+ clp->rects = (PsRectPtr)0;
+ clp->outterClips = (PsRectPtr)0;
+ clp->nRects = 0;
+ clp->nOutterClips = 0;
+ if( clp->elms ) PsDestroyFillElementList(clp->nElms, clp->elms);
+ clp->elms = (PsElmPtr)0;
+ clp->nElms = 0;
+ pGC->clientClipType = CT_NONE;
+}
+
+void
+PsCopyClip(GCPtr pDst, GCPtr pSrc)
+{
+ PsClipPtr src = (PsClipPtr)pSrc->clientClip;
+ PsClipPtr dst = (PsClipPtr)pDst->clientClip;
+
+ PsDestroyClip(pDst);
+ pDst->clientClipType = pSrc->clientClipType;
+ *dst = *src;
+ if( src->rects )
+ {
+ dst->rects = (PsRectPtr)xalloc(src->nRects*sizeof(PsRectRec));
+ memcpy(dst->rects, src->rects, src->nRects*sizeof(PsRectRec));
+ }
+ if( src->elms )
+ dst->elms = PsCloneFillElementList(src->nElms, src->elms);
+}
+
+
+GCPtr
+PsCreateAndCopyGC(DrawablePtr pDrawable, GCPtr pSrc)
+{
+ GCPtr pDst;
+
+ if (pSrc == NULL) {
+ /* https://freedesktop.org/bugzilla/show_bug.cgi?id=1416 ("'x11perf
+ * -copypixpix500' crashes Xprt's PostScript DDX [PsCreateAndCopyGC"):
+ * I have no clue whether this is the real fix or just wallpapering
+ * over the crash (that's why we warn here loudly when this
+ * happens) ... */
+ fprintf(stderr, "PsCreateAndCopyGC: pSrc == NULL\n");
+ return NULL;
+ }
+
+ if ((pDst =
+ CreateScratchGC(pDrawable->pScreen, pDrawable->depth)) == NULL)
+ {
+ return NULL;
+ }
+
+ if (CopyGC(pSrc, pDst,
+ GCFunction | GCPlaneMask | GCForeground | GCBackground |
+ GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle |
+ GCFillStyle | GCFillRule | GCTile | GCStipple |
+ GCTileStipXOrigin | GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList |
+ GCArcMode) != Success)
+ {
+ (void)FreeGC(pDst, (GContext)0);
+
+ return NULL;
+ }
+
+ return pDst;
+}
+
diff --git a/hw/xprint/ps/PsImageUtil.c b/hw/xprint/ps/PsImageUtil.c
new file mode 100644
index 000000000..f3052bebb
--- /dev/null
+++ b/hw/xprint/ps/PsImageUtil.c
@@ -0,0 +1,330 @@
+
+/* $Xorg: PsImageUtil.c,v 1.1 2005/03/25 1:19:56 gisburn Exp $ */
+/*
+Copyright (c) 2005 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+/* Please do not beat me for this ugly code - most of it has been stolen from
+ * xc/lib/X11/ImUtil.c */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "attributes.h"
+
+static unsigned char const _reverse_byte[0x100] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static
+int XReverse_Bytes(
+ register unsigned char *bpt,
+ register int nb)
+{
+ do {
+ *bpt = _reverse_byte[*bpt];
+ bpt++;
+ } while (--nb > 0);
+ return 0;
+}
+
+/*
+ * Data structure for "image" data, used by image manipulation routines.
+ */
+typedef struct {
+ int width, height; /* size of image */
+ int xoffset; /* number of pixels offset in X direction */
+ int format; /* XYBitmap, XYPixmap, ZPixmap */
+ char *data; /* pointer to image data */
+ int byte_order; /* data byte order, LSBFirst, MSBFirst */
+ int bitmap_unit; /* quant. of scanline 8, 16, 32 */
+ int bitmap_bit_order; /* LSBFirst, MSBFirst */
+ int depth; /* depth of image */
+ int bytes_per_line; /* accelarator to next line */
+ int bits_per_pixel; /* bits per pixel (ZPixmap) */
+} TmpImage;
+
+
+static void xynormalizeimagebits (
+ register unsigned char *bp,
+ register TmpImage *img)
+{
+ register unsigned char c;
+
+ if (img->byte_order != img->bitmap_bit_order) {
+ switch (img->bitmap_unit) {
+
+ case 16:
+ c = *bp;
+ *bp = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+
+ case 32:
+ c = *(bp + 3);
+ *(bp + 3) = *bp;
+ *bp = c;
+ c = *(bp + 2);
+ *(bp + 2) = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+ }
+ }
+ if (img->bitmap_bit_order == MSBFirst)
+ XReverse_Bytes (bp, img->bitmap_unit >> 3);
+}
+
+static void znormalizeimagebits (
+ register unsigned char *bp,
+ register TmpImage *img)
+{
+ register unsigned char c;
+ switch (img->bits_per_pixel) {
+
+ case 4:
+ *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
+ break;
+
+ case 16:
+ c = *bp;
+ *bp = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+
+ case 24:
+ c = *(bp + 2);
+ *(bp + 2) = *bp;
+ *bp = c;
+ break;
+
+ case 32:
+ c = *(bp + 3);
+ *(bp + 3) = *bp;
+ *bp = c;
+ c = *(bp + 2);
+ *(bp + 2) = *(bp + 1);
+ *(bp + 1) = c;
+ break;
+ }
+}
+
+/*
+ * Macros
+ *
+ * The ROUNDUP macro rounds up a quantity to the specified boundary,
+ * then truncates to bytes.
+ *
+ * The XYNORMALIZE macro determines whether XY format data requires
+ * normalization and calls a routine to do so if needed. The logic in
+ * this module is designed for LSBFirst byte and bit order, so
+ * normalization is done as required to present the data in this order.
+ *
+ * The ZNORMALIZE macro performs byte and nibble order normalization if
+ * required for Z format data.
+ *
+ * The XYINDEX macro computes the index to the starting byte (char) boundary
+ * for a bitmap_unit containing a pixel with coordinates x and y for image
+ * data in XY format.
+ *
+ * The ZINDEX macro computes the index to the starting byte (char) boundary
+ * for a pixel with coordinates x and y for image data in ZPixmap format.
+ *
+ */
+
+#if defined(Lynx) && defined(ROUNDUP)
+#undef ROUNDUP
+#endif
+
+#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
+
+#define XYNORMALIZE(bp, img) \
+ if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
+ xynormalizeimagebits((unsigned char *)(bp), img)
+
+#define ZNORMALIZE(bp, img) \
+ if (img->byte_order == MSBFirst) \
+ znormalizeimagebits((unsigned char *)(bp), img)
+
+#define XYINDEX(x, y, img) \
+ ((y) * img->bytes_per_line) + \
+ (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
+
+#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
+ (((x) * img->bits_per_pixel) >> 3)
+
+/*
+ * GetPixel
+ *
+ * Returns the specified pixel. The X and Y coordinates are relative to
+ * the origin (upper left [0,0]) of the image. The pixel value is returned
+ * in normalized format, i.e. the LSB of the long is the LSB of the pixel.
+ * The algorithm used is:
+ *
+ * copy the source bitmap_unit or Zpixel into temp
+ * normalize temp if needed
+ * extract the pixel bits into return value
+ *
+ */
+
+static unsigned long const low_bits_table[] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+ 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+ 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+ 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+ 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+ 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+ 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+ 0xffffffff
+};
+
+static unsigned long XGetPixel (TmpImage *ximage, int x, int y)
+{
+ unsigned long pixel, px;
+ register char *src;
+ register char *dst;
+ register int i, j;
+ int bits, nbytes;
+ long plane;
+
+ if ((ximage->bits_per_pixel | ximage->depth) == 1) {
+ src = &ximage->data[XYINDEX(x, y, ximage)];
+ dst = (char *)&pixel;
+ pixel = 0;
+ for (i = ximage->bitmap_unit >> 3; --i >= 0; ) *dst++ = *src++;
+ XYNORMALIZE(&pixel, ximage);
+ bits = (x + ximage->xoffset) % ximage->bitmap_unit;
+ pixel = ((((char *)&pixel)[bits>>3])>>(bits&7)) & 1;
+ } else if (ximage->format == XYPixmap) {
+ pixel = 0;
+ plane = 0;
+ nbytes = ximage->bitmap_unit >> 3;
+ for (i = ximage->depth; --i >= 0; ) {
+ src = &ximage->data[XYINDEX(x, y, ximage)+ plane];
+ dst = (char *)&px;
+ px = 0;
+ for (j = nbytes; --j >= 0; ) *dst++ = *src++;
+ XYNORMALIZE(&px, ximage);
+ bits = (x + ximage->xoffset) % ximage->bitmap_unit;
+ pixel = (pixel << 1) |
+ (((((char *)&px)[bits>>3])>>(bits&7)) & 1);
+ plane = plane + (ximage->bytes_per_line * ximage->height);
+ }
+ } else if (ximage->format == ZPixmap) {
+ src = &ximage->data[ZINDEX(x, y, ximage)];
+ dst = (char *)&px;
+ px = 0;
+ for (i = (ximage->bits_per_pixel + 7) >> 3; --i >= 0; )
+ *dst++ = *src++;
+ ZNORMALIZE(&px, ximage);
+ pixel = 0;
+ for (i=sizeof(unsigned long); --i >= 0; )
+ pixel = (pixel << 8) | ((unsigned char *)&px)[i];
+ if (ximage->bits_per_pixel == 4) {
+ if (x & 1)
+ pixel >>= 4;
+ else
+ pixel &= 0xf;
+ }
+ } else {
+ return 0; /* bad image */
+ }
+ if (ximage->bits_per_pixel == ximage->depth)
+ return pixel;
+ else
+ return (pixel & low_bits_table[ximage->depth]);
+}
+
+unsigned long
+PsGetImagePixel(char *pImage, int depth, int w, int h, int leftPad, int format,
+ int px, int py)
+{
+ TmpImage xi = {0};
+
+ xi.width = w;
+ xi.height = h;
+ xi.xoffset = 0/*leftPad*/;
+ xi.format = format;
+ xi.data = pImage;
+ xi.byte_order = IMAGE_BYTE_ORDER;
+ xi.bitmap_bit_order = BITMAP_BIT_ORDER;
+ xi.bitmap_unit = ((depth > 16)?(32):
+ ((depth > 8)?(16):
+ ((depth > 1)? (8):
+ (1))));
+ xi.depth = depth;
+ xi.bits_per_pixel = xi.bitmap_unit;
+
+ /*
+ * compute per line accelerator.
+ */
+ if (format == ZPixmap)
+ xi.bytes_per_line =
+ ROUNDUP((xi.bits_per_pixel * xi.width), 32);
+ else
+ xi.bytes_per_line =
+ ROUNDUP((xi.width + xi.xoffset), 32);
+
+ return XGetPixel(&xi, px, py);
+}
+
+
+
diff --git a/hw/xprint/ps/PsInit.c b/hw/xprint/ps/PsInit.c
new file mode 100644
index 000000000..06c5d11a8
--- /dev/null
+++ b/hw/xprint/ps/PsInit.c
@@ -0,0 +1,665 @@
+/* $Xorg: PsInit.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsInit.c
+** *
+** * Contents: Initialization code of Ps driver for the print server.
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include "Ps.h"
+#include "mi.h"
+#include "micmap.h"
+#include "AttrValid.h"
+#include "fb.h"
+
+#include "windowstr.h"
+#include "DiPrint.h"
+
+static void AllocatePsPrivates(ScreenPtr pScreen);
+static int PsInitContext(XpContextPtr pCon);
+static int PsDestroyContext(XpContextPtr pCon);
+
+int PsScreenPrivateIndex;
+int PsContextPrivateIndex;
+int PsPixmapPrivateIndex;
+int PsWindowPrivateIndex;
+
+#ifdef GLXEXT
+extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+#endif /* GLXEXT */
+
+Bool
+InitializePsDriver(ndx, pScreen, argc, argv)
+ int ndx;
+ ScreenPtr pScreen;
+ int argc;
+ char **argv;
+{
+#if 0
+ int maxXres, maxYres, maxWidth, maxHeight;
+ int maxRes, maxDim, numBytes;
+ PsScreenPrivPtr pPriv;
+#endif
+ int nv, /* total number of visuals */
+ nv_1bit, /* number of 8bit visuals */
+ nv_8bit, /* number of 8bit visuals */
+ nv_12bit, /* number of 12bit visuals */
+ nv_14bit, /* number of 14bit visuals */
+ nv_16bit, /* number of 16bit visuals */
+ nv_24bit, /* number of 24bit visuals*/
+ nv_30bit; /* number of 30bit visuals*/
+ int nd; /* number of depths */
+ int defaultVisualIndex = -1;
+ VisualID *vids_1bit,
+ *vids_8bit,
+ *vids_12bit,
+ *vids_14bit,
+ *vids_16bit,
+ *vids_24bit,
+ *vids_30bit;
+ VisualPtr visuals;
+ DepthPtr depths;
+ VisualID defaultVisual;
+ int rootDepth;
+
+/*
+ * Register this driver's InitContext function with the print
+ * extension.
+ */
+ XpRegisterInitFunc(pScreen, "XP-POSTSCRIPT", PsInitContext);
+
+/*
+ * Create and fill in the devPrivate for the PS driver.
+ */
+ AllocatePsPrivates(pScreen);
+
+#if 0
+ pPriv = (PsScreenPrivPtr)pScreen->devPrivates[PsScreenPrivateIndex].ptr;
+ pPriv->resDB = rmdb;
+#endif
+
+ pScreen->defColormap = (Colormap) FakeClientID(0);
+ pScreen->blackPixel = 1;
+ pScreen->whitePixel = 0;
+ pScreen->QueryBestSize = (QueryBestSizeProcPtr)PsQueryBestSize;
+ pScreen->SaveScreen = (SaveScreenProcPtr)_XpBoolNoop;
+ pScreen->GetImage = (GetImageProcPtr)_XpVoidNoop;
+ pScreen->GetSpans = (GetSpansProcPtr)_XpVoidNoop;
+ pScreen->CreateWindow = PsCreateWindow;
+ pScreen->DestroyWindow = PsDestroyWindow;
+ pScreen->PositionWindow = PsPositionWindow;
+ pScreen->ChangeWindowAttributes = PsChangeWindowAttributes;
+ pScreen->RealizeWindow = PsMapWindow;
+ pScreen->UnrealizeWindow = PsUnmapWindow;
+ pScreen->PaintWindowBackground = PsPaintWindow;
+ pScreen->PaintWindowBorder = PsPaintWindow;
+ pScreen->CloseScreen = PsCloseScreen;
+ pScreen->CopyWindow = PsCopyWindow;
+ /* XXX Hard routine to write! */
+
+/*
+ * These two are going to be VERY different...
+ */
+ pScreen->CreatePixmap = PsCreatePixmap;
+ pScreen->DestroyPixmap = PsDestroyPixmap;
+ pScreen->RealizeFont = PsRealizeFont;
+ pScreen->UnrealizeFont = PsUnrealizeFont;
+ pScreen->CreateGC = PsCreateGC;
+ pScreen->CreateColormap = PsCreateColormap;
+ pScreen->DestroyColormap = PsDestroyColormap;
+ pScreen->InstallColormap = PsInstallColormap;
+ pScreen->UninstallColormap = PsUninstallColormap;
+ pScreen->ListInstalledColormaps = PsListInstalledColormaps;
+ pScreen->StoreColors = PsStoreColors;
+ pScreen->ResolveColor = PsResolveColor;
+ /* Will BitmapToRegion make any difference at all? */
+ pScreen->BitmapToRegion = fbPixmapToRegion;
+
+ visuals = (VisualPtr) xalloc(16*sizeof(VisualRec));
+ depths = (DepthPtr) xalloc(16*sizeof(DepthRec));
+ vids_1bit = (VisualID *)xalloc(16*sizeof(VisualID));
+ vids_8bit = (VisualID *)xalloc(16*sizeof(VisualID));
+ vids_12bit = (VisualID *)xalloc(16*sizeof(VisualID));
+ vids_14bit = (VisualID *)xalloc(16*sizeof(VisualID));
+ vids_16bit = (VisualID *)xalloc(16*sizeof(VisualID));
+ vids_24bit = (VisualID *)xalloc(16*sizeof(VisualID));
+ vids_30bit = (VisualID *)xalloc(16*sizeof(VisualID));
+
+ nv = nv_1bit = nv_8bit = nv_12bit = nv_14bit = nv_16bit = nv_24bit = nv_30bit = nd = 0;
+
+#ifdef PSOUT_USE_DEEPCOLOR
+/* gisburn: 30bit TrueColor has been disabled for now since it causes problems
+ * with GLX - see https://bugs.freedesktop.org/show_bug.cgi?id=2868 ("Mesa
+ * seems to be unable to handle 30bit TrueColor visuals") for details...
+ */
+#ifdef DISABLED_FOR_NOW
+ /* TrueColor, 30bit, 10bit per R-,G-,B-gun */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = TrueColor;
+ visuals[nv].bitsPerRGBValue = 10;
+ visuals[nv].ColormapEntries = 1024;
+ visuals[nv].nplanes = 30;
+ visuals[nv].redMask = 0X3FF00000;
+ visuals[nv].greenMask = 0X000FFC00;
+ visuals[nv].blueMask = 0X000003FF;
+ visuals[nv].offsetRed = 20;
+ visuals[nv].offsetGreen = 10;
+ visuals[nv].offsetBlue = 0;
+ vids_30bit[nv_30bit] = visuals[nv].vid;
+ nv++; nv_30bit++;
+#endif /* DISABLED_FOR_NOW */
+#endif /* PSOUT_USE_DEEPCOLOR */
+
+ /* TrueColor, 24bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = TrueColor;
+ visuals[nv].bitsPerRGBValue = 8;
+ visuals[nv].ColormapEntries = 256;
+ visuals[nv].nplanes = 24;
+ visuals[nv].redMask = 0X00FF0000;
+ visuals[nv].greenMask = 0X0000FF00;
+ visuals[nv].blueMask = 0X000000FF;
+ visuals[nv].offsetRed = 16;
+ visuals[nv].offsetGreen = 8;
+ visuals[nv].offsetBlue = 0;
+ vids_24bit[nv_24bit] = visuals[nv].vid;
+ nv++; nv_24bit++;
+
+ /* TrueColor, 16bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = TrueColor;
+ visuals[nv].bitsPerRGBValue = 6;
+ visuals[nv].ColormapEntries = 64;
+ visuals[nv].nplanes = 16;
+ visuals[nv].redMask = 0x0000f800;
+ visuals[nv].greenMask = 0x000007e0;
+ visuals[nv].blueMask = 0x0000001f;
+ visuals[nv].offsetRed = 11;
+ visuals[nv].offsetGreen = 5;
+ visuals[nv].offsetBlue = 0;
+ vids_16bit[nv_16bit] = visuals[nv].vid;
+ nv++; nv_16bit++;
+
+#ifdef PSOUT_USE_DEEPCOLOR
+ /* PostScript Level 2 and above, colors can have 12 bits per component
+ * (36 bit for RGB) */
+
+ /* PseudoColor, 14bit (15bit won't work as |ColormapEntries==32768|
+ * is too large for a |signed short|... xx@@!!!... ;-( ) */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = PseudoColor;
+ visuals[nv].bitsPerRGBValue = 12;
+ visuals[nv].ColormapEntries = 16384;
+ visuals[nv].nplanes = 14;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_14bit[nv_14bit] = visuals[nv].vid;
+ nv++; nv_14bit++;
+
+ /* PseudoColor, 12bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = PseudoColor;
+ visuals[nv].bitsPerRGBValue = 12;
+ visuals[nv].ColormapEntries = 4096;
+ visuals[nv].nplanes = 12;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_12bit[nv_12bit] = visuals[nv].vid;
+ defaultVisualIndex = nv;
+ nv++; nv_12bit++;
+
+ /* GrayScale, 12bit, 12bit per R-,G-,B-gun */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = GrayScale;
+ visuals[nv].bitsPerRGBValue = 12;
+ visuals[nv].ColormapEntries = 4096;
+ visuals[nv].nplanes = 12;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_12bit[nv_12bit] = visuals[nv].vid;
+ nv++; nv_12bit++;
+
+ /* StaticGray, 12bit, 12bit per R-,G-,B-gun */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = StaticGray;
+ visuals[nv].bitsPerRGBValue = 12;
+ visuals[nv].ColormapEntries = 4096;
+ visuals[nv].nplanes = 12;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_12bit[nv_12bit] = visuals[nv].vid;
+ nv++; nv_12bit++;
+#endif /* PSOUT_USE_DEEPCOLOR */
+
+ /* PseudoColor, 8bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = PseudoColor;
+ visuals[nv].bitsPerRGBValue = 8;
+ visuals[nv].ColormapEntries = 256;
+ visuals[nv].nplanes = 8;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_8bit[nv_8bit] = visuals[nv].vid;
+#ifndef PSOUT_USE_DEEPCOLOR
+ defaultVisualIndex = nv;
+#endif /* !PSOUT_USE_DEEPCOLOR */
+ nv++; nv_8bit++;
+
+ /* GrayScale, 8bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = GrayScale;
+ visuals[nv].bitsPerRGBValue = 8;
+ visuals[nv].ColormapEntries = 256;
+ visuals[nv].nplanes = 8;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_8bit[nv_8bit] = visuals[nv].vid;
+ nv++; nv_8bit++;
+
+ /* StaticGray, 8bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = StaticGray;
+ visuals[nv].bitsPerRGBValue = 8;
+ visuals[nv].ColormapEntries = 256;
+ visuals[nv].nplanes = 8;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_8bit[nv_8bit] = visuals[nv].vid;
+ nv++; nv_8bit++;
+
+ /* StaticGray, 1bit */
+ visuals[nv].vid = FakeClientID(0);
+ visuals[nv].class = StaticGray;
+ visuals[nv].bitsPerRGBValue = 1;
+ visuals[nv].ColormapEntries = 2;
+ visuals[nv].nplanes = 1;
+ visuals[nv].redMask = 0x0;
+ visuals[nv].greenMask = 0x0;
+ visuals[nv].blueMask = 0x0;
+ visuals[nv].offsetRed = 0x0;
+ visuals[nv].offsetGreen = 0x0;
+ visuals[nv].offsetBlue = 0x0;
+ vids_1bit[nv_1bit] = visuals[nv].vid;
+ nv++; nv_1bit++;
+
+ if( nv_30bit > 0 )
+ {
+ depths[nd].depth = 30;
+ depths[nd].numVids = nv_30bit;
+ depths[nd].vids = vids_30bit;
+ nd++;
+ }
+
+ if( nv_24bit > 0 )
+ {
+ depths[nd].depth = 24;
+ depths[nd].numVids = nv_24bit;
+ depths[nd].vids = vids_24bit;
+ nd++;
+ }
+
+ if( nv_16bit > 0 )
+ {
+ depths[nd].depth = 16;
+ depths[nd].numVids = nv_16bit;
+ depths[nd].vids = vids_16bit;
+ nd++;
+ }
+
+ if( nv_14bit > 0 )
+ {
+ depths[nd].depth = 14;
+ depths[nd].numVids = nv_14bit;
+ depths[nd].vids = vids_14bit;
+ nd++;
+ }
+
+ if( nv_12bit > 0 )
+ {
+ depths[nd].depth = 12;
+ depths[nd].numVids = nv_12bit;
+ depths[nd].vids = vids_12bit;
+ nd++;
+ }
+
+ if( nv_8bit > 0 )
+ {
+ depths[nd].depth = 8;
+ depths[nd].numVids = nv_8bit;
+ depths[nd].vids = vids_8bit;
+ nd++;
+ }
+
+ if( nv_1bit > 0 )
+ {
+ depths[nd].depth = 1;
+ depths[nd].numVids = nv_1bit;
+ depths[nd].vids = vids_1bit;
+ nd++;
+ }
+
+ /* Defaul visual is 12bit PseudoColor */
+ defaultVisual = visuals[defaultVisualIndex].vid;
+ rootDepth = visuals[defaultVisualIndex].nplanes;
+
+#ifdef GLXEXT
+ {
+ miInitVisualsProcPtr proc = NULL;
+
+ GlxWrapInitVisuals(&proc);
+ /* GlxInitVisuals ignores the last three arguments. */
+ proc(&visuals, &depths, &nv, &nd,
+ &rootDepth, &defaultVisual, 0, 0, 0);
+ }
+#endif /* GLXEXT */
+
+ miScreenInit(pScreen, (pointer)0,
+ pScreen->width, pScreen->height,
+ (int) (pScreen->width / (pScreen->mmWidth / 25.40)),
+ (int) (pScreen->height / (pScreen->mmHeight / 25.40)),
+ 0, rootDepth, nd,
+ depths, defaultVisual, nv, visuals);
+
+ if( miCreateDefColormap(pScreen)==FALSE ) return FALSE;
+
+/*scalingScreenInit(pScreen);*/
+
+ return TRUE;
+}
+
+static void
+AllocatePsPrivates(ScreenPtr pScreen)
+{
+ static unsigned long PsGeneration = 0;
+
+ if((unsigned long)PsGeneration != serverGeneration)
+ {
+ PsScreenPrivateIndex = AllocateScreenPrivateIndex();
+
+ PsWindowPrivateIndex = AllocateWindowPrivateIndex();
+ AllocateWindowPrivate(pScreen, PsWindowPrivateIndex,
+ sizeof(PsWindowPrivRec));
+
+ PsContextPrivateIndex = XpAllocateContextPrivateIndex();
+ XpAllocateContextPrivate(PsContextPrivateIndex,
+ sizeof(PsContextPrivRec));
+
+ PsPixmapPrivateIndex = AllocatePixmapPrivateIndex();
+ AllocatePixmapPrivate(pScreen, PsPixmapPrivateIndex,
+ sizeof(PsPixmapPrivRec));
+
+ PsGeneration = serverGeneration;
+ }
+ pScreen->devPrivates[PsScreenPrivateIndex].ptr =
+ (pointer)xalloc(sizeof(PsScreenPrivRec));
+}
+
+/*
+ * PsInitContext
+ *
+ * Establish the appropriate values for a PrintContext used with the PS
+ * driver.
+ */
+
+static char DOC_ATT_SUPP[]="document-attributes-supported";
+static char DOC_ATT_VAL[]="document-format xp-listfonts-modes";
+static char JOB_ATT_SUPP[]="job-attributes-supported";
+static char JOB_ATT_VAL[]="";
+static char PAGE_ATT_SUPP[]="xp-page-attributes-supported";
+static char PAGE_ATT_VAL[]="content-orientation default-printer-resolution \
+default-input-tray default-medium plex xp-listfonts-modes";
+
+static int
+PsInitContext(pCon)
+ XpContextPtr pCon;
+{
+ XpDriverFuncsPtr pFuncs;
+ PsContextPrivPtr pConPriv;
+ char *server, *attrStr;
+
+ /*
+ * Initialize the attribute store for this printer.
+ */
+ XpInitAttributes(pCon);
+
+ /*
+ * Initialize the function pointers
+ */
+ pFuncs = &(pCon->funcs);
+ pFuncs->StartJob = PsStartJob;
+ pFuncs->EndJob = PsEndJob;
+ pFuncs->StartDoc = PsStartDoc;
+ pFuncs->EndDoc = PsEndDoc;
+ pFuncs->StartPage = PsStartPage;
+ pFuncs->EndPage = PsEndPage;
+ pFuncs->PutDocumentData = PsDocumentData;
+ pFuncs->GetDocumentData = PsGetDocumentData;
+ pFuncs->GetAttributes = PsGetAttributes;
+ pFuncs->SetAttributes = PsSetAttributes;
+ pFuncs->AugmentAttributes = PsAugmentAttributes;
+ pFuncs->GetOneAttribute = PsGetOneAttribute;
+ pFuncs->DestroyContext = PsDestroyContext;
+ pFuncs->GetMediumDimensions = PsGetMediumDimensions;
+ pFuncs->GetReproducibleArea = PsGetReproducibleArea;
+ pFuncs->SetImageResolution = PsSetImageResolution;
+
+ /*
+ * Set up the context privates
+ */
+ pConPriv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ memset(pConPriv, 0, sizeof(PsContextPrivRec));
+ pConPriv->jobFileName = (char *)NULL;
+ pConPriv->pJobFile = (FILE *)NULL;
+ pConPriv->dash = (unsigned char *)NULL;
+ pConPriv->validGC = 0;
+ pConPriv->getDocClient = (ClientPtr)NULL;
+ pConPriv->getDocBufSize = 0;
+ pConPriv->pPsOut = NULL;
+ pConPriv->fontInfoRecords = NULL;
+ pConPriv->fontTypeInfoRecords = NULL;
+
+ /*
+ * document-attributes-supported
+ */
+ server = XpGetOneAttribute( pCon, XPServerAttr, DOC_ATT_SUPP );
+ if ((attrStr = (char *) xalloc(strlen(server) +
+ strlen(DOC_ATT_SUPP) + strlen(DOC_ATT_VAL)
+ + strlen(PAGE_ATT_VAL) + 8)) == NULL)
+ {
+ return BadAlloc;
+ }
+ sprintf(attrStr, "*%s:\t%s %s %s",
+ DOC_ATT_SUPP, server, DOC_ATT_VAL, PAGE_ATT_VAL);
+ XpAugmentAttributes( pCon, XPPrinterAttr, attrStr);
+ xfree(attrStr);
+
+ /*
+ * job-attributes-supported
+ */
+ server = XpGetOneAttribute( pCon, XPServerAttr, JOB_ATT_SUPP );
+ if ((attrStr = (char *) xalloc(strlen(server) + strlen(JOB_ATT_SUPP) +
+ strlen(JOB_ATT_VAL) + 8)) == NULL)
+ {
+ return BadAlloc;
+ }
+ sprintf(attrStr, "*%s:\t%s %s", JOB_ATT_SUPP, server, JOB_ATT_VAL);
+ XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
+ xfree(attrStr);
+
+ /*
+ * xp-page-attributes-supported
+ */
+ server = XpGetOneAttribute( pCon, XPServerAttr, PAGE_ATT_SUPP );
+ if ((attrStr = (char *) xalloc(strlen(server) + strlen(PAGE_ATT_SUPP) +
+ strlen(PAGE_ATT_VAL) + 8)) == NULL)
+ {
+ return BadAlloc;
+ }
+ sprintf(attrStr, "*%s:\t%s %s", PAGE_ATT_SUPP, server, PAGE_ATT_VAL);
+ XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
+ xfree(attrStr);
+
+ /*
+ * Validate the attribute pools
+ */
+ XpValidateAttributePool(pCon, XPPrinterAttr, &PsValidatePoolsRec);
+ XpValidateAttributePool(pCon, XPDocAttr, &PsValidatePoolsRec);
+ XpValidateAttributePool(pCon, XPJobAttr, &PsValidatePoolsRec);
+ XpValidateAttributePool(pCon, XPPageAttr, &PsValidatePoolsRec);
+
+ return Success;
+}
+
+static Bool
+PsDestroyContext(pCon)
+ XpContextPtr pCon;
+{
+ PsContextPrivPtr pConPriv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ if( pConPriv->pJobFile!=(FILE *)NULL )
+ {
+ fclose(pConPriv->pJobFile);
+ pConPriv->pJobFile = NULL;
+ }
+ if( pConPriv->jobFileName!=(char *)NULL )
+ {
+ unlink(pConPriv->jobFileName);
+ xfree(pConPriv->jobFileName);
+ pConPriv->jobFileName = (char *)NULL;
+ }
+
+ PsFreeFontInfoRecords(pConPriv);
+
+ /* Reset context to make sure we do not use any stale/invalid/obsolete data */
+ memset(pConPriv, 0, sizeof(PsContextPrivRec));
+
+/*### free up visuals/depths ###*/
+
+ return Success;
+}
+
+XpContextPtr
+PsGetContextFromWindow(win)
+ WindowPtr win;
+{
+ PsWindowPrivPtr pPriv;
+
+ while( win )
+ {
+ pPriv = (PsWindowPrivPtr)win->devPrivates[PsWindowPrivateIndex].ptr;
+ if( pPriv->validContext ) return pPriv->context;
+ win = win->parent;
+ }
+
+ return NULL;
+}
diff --git a/hw/xprint/ps/PsLine.c b/hw/xprint/ps/PsLine.c
new file mode 100644
index 000000000..2524769c8
--- /dev/null
+++ b/hw/xprint/ps/PsLine.c
@@ -0,0 +1,192 @@
+/* $Xorg: PsLine.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsLine.c
+** *
+** * Contents: Line drawing routines for the PS driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PsPolyLine(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nPoints,
+ xPoint *pPoints)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolyLineCmd;
+ elm->gc = gc;
+ elm->c.polyPts.mode = mode;
+ elm->c.polyPts.nPoints = nPoints;
+ elm->c.polyPts.pPoints = (xPoint *)xalloc(nPoints*sizeof(xPoint));
+ memcpy(elm->c.polyPts.pPoints, pPoints, nPoints*sizeof(xPoint));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ PsPointPtr pts;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ PsLineAttrs(psOut, pGC, cMap);
+ pts = (PsPointPtr)xalloc(sizeof(PsPointRec)*nPoints);
+ if( mode==CoordModeOrigin )
+ {
+ for( i=0 ; i<nPoints ; i++ )
+ { pts[i].x = pPoints[i].x; pts[i].y = pPoints[i].y; }
+ }
+ else
+ {
+ pts[0].x = pPoints[0].x; pts[0].y = pPoints[0].y;
+ for( i=1 ; i<nPoints ; i++ )
+ {
+ pts[i].x = pts[i-1].x+pPoints[i].x;
+ pts[i].y = pts[i-1].y+pPoints[i].y;
+ }
+ }
+ PsOut_Lines(psOut, nPoints, pts);
+ xfree(pts);
+ }
+}
+
+void
+PsPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSegments,
+ xSegment *pSegments)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolySegmentCmd;
+ elm->gc = gc;
+ elm->c.segments.nSegments = nSegments;
+ elm->c.segments.pSegments = (xSegment *)xalloc(nSegments*sizeof(xSegment));
+ memcpy(elm->c.segments.pSegments, pSegments, nSegments*sizeof(xSegment));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ PsPointRec pts[2];
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ PsLineAttrs(psOut, pGC, cMap);
+ for( i=0 ; i<nSegments ; i++ )
+ {
+ pts[0].x = pSegments[i].x1;
+ pts[0].y = pSegments[i].y1;
+ pts[1].x = pSegments[i].x2;
+ pts[1].y = pSegments[i].y2;
+ PsOut_Lines(psOut, 2, pts);
+ }
+ }
+}
diff --git a/hw/xprint/ps/PsMisc.c b/hw/xprint/ps/PsMisc.c
new file mode 100644
index 000000000..b8a3ba854
--- /dev/null
+++ b/hw/xprint/ps/PsMisc.c
@@ -0,0 +1,324 @@
+/* $Xorg: PsMisc.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsMisc.c
+** *
+** * Contents: Miscellaneous code for Ps driver.
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/Xos.h> /* for SIGCLD on pre-POSIX systems */
+#include <stdio.h>
+#include "Ps.h"
+
+#include "cursor.h"
+#include "resource.h"
+
+#include "windowstr.h"
+#include "propertyst.h"
+
+
+/*ARGSUSED*/
+void
+PsQueryBestSize(
+ int type,
+ short *pwidth,
+ short *pheight,
+ ScreenPtr pScreen)
+{
+ unsigned width, highBit;
+
+ switch(type)
+ {
+ case CursorShape:
+ *pwidth = 0;
+ *pheight = 0;
+ break;
+ case TileShape:
+ case StippleShape:
+ width = *pwidth;
+ if (!width) break;
+ /* Return the nearest power of two >= what they gave us */
+ highBit = 0x80000000;
+ /* Find the highest 1 bit in the given width */
+ while(!(highBit & width))
+ highBit >>= 1;
+ /* If greater than that then return the next power of two */
+ if((highBit - 1) & width)
+ highBit <<= 1;
+ *pwidth = highBit;
+ /* height is a don't-care */
+ break;
+ }
+}
+
+/*
+ * PsGetMediumDimensions is installed in the GetMediumDimensions field
+ * of each Ps-initialized context.
+ */
+int
+PsGetMediumDimensions(XpContextPtr pCon, CARD16 *width, CARD16 *height)
+{
+ XpGetMediumDimensions(pCon, width, height);
+ return Success;
+}
+
+/*
+ * PsGetReproducibleArea is installed in the GetReproducibleArea field
+ * of each Ps-initialized context.
+ */
+int
+PsGetReproducibleArea(XpContextPtr pCon, xRectangle *pRect)
+{
+ XpGetReproductionArea(pCon, pRect);
+ return Success;
+}
+
+/*
+ * PsSetImageResolution is installed in the SetImageResolution field
+ * of each Ps-initialized context.
+ */
+int
+PsSetImageResolution(XpContextPtr pCon, int imageRes, Bool *status)
+{
+ pCon->imageRes = imageRes;
+ *status = True;
+ return Success;
+}
+
+/*
+ * GetPropString searches the window heirarchy from pWin up looking for
+ * a property by the name of propName. If found, returns the property's
+ * value. If not, it returns NULL.
+ */
+/*
+char *
+GetPropString(
+ WindowPtr pWin,
+ char *propName)
+{
+ Atom atom;
+ PropertyPtr pProp = (PropertyPtr)NULL;
+ char *retVal;
+
+ atom = MakeAtom(propName, strlen(propName), FALSE);
+ if(atom != BAD_RESOURCE)
+ {
+ WindowPtr pPropWin;
+ int n;
+*/
+
+ /*
+ * The atom has been defined, but it might only exist as a
+ * property on an unrelated window.
+ */
+/*
+ for(pPropWin = pWin; pPropWin != (WindowPtr)NULL;
+ pPropWin = pPropWin->parent)
+ {
+ for(pProp = (PropertyPtr)(wUserProps(pPropWin));
+ pProp != (PropertyPtr)NULL;
+ pProp = pProp->next)
+ {
+ if (pProp->propertyName == atom)
+ break;
+ }
+ if(pProp != (PropertyPtr)NULL)
+ break;
+ }
+ if(pProp == (PropertyPtr)NULL)
+ return (char *)NULL;
+
+ n = (pProp->format/8) * pProp->size; *//* size (bytes) of prop */
+/*
+ retVal = (char *)xalloc(n + 1);
+ (void)memcpy((void *)retVal, (void *)pProp->data, n);
+ retVal[n] = '\0';
+
+ return retVal;
+ }
+
+ return (char *)NULL;
+}
+
+#include <signal.h>
+
+*/
+/* ARGSUSED */
+/*
+static void SigchldHndlr (int dummy)
+{
+ int status, w;
+ struct sigaction act;
+ sigfillset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = SigchldHndlr;
+
+ w = wait (&status);
+
+*/
+ /*
+ * Is this really necessary?
+ */
+/*
+ sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
+}
+*/
+
+/*
+ * SystemCmd provides a wrapper for the 'system' library call. The call
+ * appears to be sensitive to the handling of SIGCHLD, so this wrapper
+ * sets the status to SIG_DFL, and then resets the established handler
+ * after system returns.
+ */
+/*
+int
+SystemCmd(char *cmdStr)
+{
+ int status;
+ struct sigaction newAct, oldAct;
+ sigfillset(&newAct.sa_mask);
+ newAct.sa_flags = 0;
+ newAct.sa_handler = SIG_DFL;
+ sigfillset(&oldAct.sa_mask);
+ oldAct.sa_flags = 0;
+ oldAct.sa_handler = SigchldHndlr;
+
+*/
+ /*
+ * get the old handler, and set the action to IGN
+ */
+/*
+ sigaction(SIGCHLD, &newAct, &oldAct);
+
+ status = system (cmdStr);
+
+ sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL);
+ return status;
+}
+*/
+
+Bool
+PsCloseScreen(
+ int index,
+ ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+void
+PsLineAttrs(
+ PsOutPtr psOut,
+ GCPtr pGC,
+ ColormapPtr cMap)
+{
+ int i;
+ int nDsh;
+ int dshOff;
+ int *dsh;
+ PsCapEnum cap;
+ PsJoinEnum join;
+
+ switch(pGC->capStyle) {
+ case CapButt: cap = PsCButt; break;
+ case CapRound: cap = PsCRound; break;
+ case CapProjecting: cap = PsCSquare; break;
+ default: cap = PsCButt; break; }
+ switch(pGC->joinStyle) {
+ case JoinMiter: join = PsJMiter; break;
+ case JoinRound: join = PsJRound; break;
+ case JoinBevel: join = PsJBevel; break;
+ default: join = PsJBevel; break; }
+ if( pGC->lineStyle==LineSolid ) { nDsh = dshOff = 0; dsh = (int *)0; }
+ else
+ {
+ nDsh = pGC->numInDashList;
+ dshOff = pGC->dashOffset;
+ if( !nDsh ) dsh = (int *)0;
+ else
+ {
+ dsh = (int *)xalloc(sizeof(int)*nDsh);
+ for( i=0 ; i<nDsh ; i++ ) dsh[i] = (int)pGC->dash[i]&0xFF;
+ }
+ }
+
+ if( pGC->lineStyle!=LineDoubleDash )
+ PsOut_LineAttrs(psOut, (int)pGC->lineWidth,
+ cap, join, nDsh, dsh, dshOff, -1);
+ else
+ PsOut_LineAttrs(psOut, (int)pGC->lineWidth,
+ cap, join, nDsh, dsh, dshOff,
+ PsGetPixelColor(cMap, pGC->bgPixel));
+ if( nDsh && dsh ) xfree(dsh);
+}
diff --git a/hw/xprint/ps/PsPixel.c b/hw/xprint/ps/PsPixel.c
new file mode 100644
index 000000000..2197f0ab9
--- /dev/null
+++ b/hw/xprint/ps/PsPixel.c
@@ -0,0 +1,157 @@
+/* $Xorg: PsPixel.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsPixel.c
+** *
+** * Contents: Pixel-drawing code for the PS DDX driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1995 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Ps.h"
+
+void
+PsPolyPoint(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int nPoints,
+ xPoint *pPoints)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolyPointCmd;
+ elm->gc = gc;
+ elm->c.polyPts.mode = mode;
+ elm->c.polyPts.nPoints = nPoints;
+ elm->c.polyPts.pPoints = (xPoint *)xalloc(nPoints*sizeof(xPoint));
+ memcpy(elm->c.polyPts.pPoints, pPoints, nPoints*sizeof(xPoint));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ PsPointPtr pts;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ pts = (PsPointPtr)xalloc(sizeof(PsPointRec)*nPoints);
+ if( mode==CoordModeOrigin )
+ {
+ for( i=0 ; i<nPoints ; i++ )
+ { pts[i].x = pPoints[i].x; pts[i].y = pPoints[i].y; }
+ }
+ else
+ {
+ pts[0].x = pPoints[0].x; pts[0].y = pPoints[0].y;
+ for( i=1 ; i<nPoints ; i++ )
+ {
+ pts[i].x = pts[i-1].x+pPoints[i].x;
+ pts[i].y = pts[i-1].y+pPoints[i].y;
+ }
+ }
+ PsOut_Points(psOut, nPoints, pts);
+ xfree(pts);
+ }
+}
+
+void
+PsPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int width,
+ int height,
+ int x,
+ int y)
+{
+}
diff --git a/hw/xprint/ps/PsPixmap.c b/hw/xprint/ps/PsPixmap.c
new file mode 100644
index 000000000..f2d05d023
--- /dev/null
+++ b/hw/xprint/ps/PsPixmap.c
@@ -0,0 +1,620 @@
+/* $Xorg: PsPixmap.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsPixmap.c
+** *
+** * Contents: Pixmap functions for the PS DDX driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1995 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Ps.h"
+
+#define _BitsPerPixel(d) (\
+ (1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \
+ (PixmapWidthPaddingInfo[d].padRoundUp+1))
+
+PixmapPtr
+PsCreatePixmap(
+ ScreenPtr pScreen,
+ int width,
+ int height,
+ int depth)
+{
+ PixmapPtr pPixmap;
+
+ pPixmap = (PixmapPtr)xcalloc(1, sizeof(PixmapRec));
+ if( !pPixmap) return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = _BitsPerPixel(depth);
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = 0;
+ pPixmap->refcnt = 1;
+
+ pPixmap->devPrivate.ptr = (PsPixmapPrivPtr)xcalloc(1, sizeof(PsPixmapPrivRec));
+ if( !pPixmap->devPrivate.ptr )
+ { xfree(pPixmap); return NullPixmap; }
+ return pPixmap;
+}
+
+/* PsScrubPixmap: Remove all content from a pixmap (used by
+ * |PsPolyFillRect()| when the "solid fill" operation covers
+ * the whole pixmap) */
+void
+PsScrubPixmap(PixmapPtr pPixmap)
+{
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pPixmap->devPrivate.ptr;
+ DisplayListPtr disp = priv->dispList;
+
+ while( disp )
+ {
+ int i;
+ DisplayListPtr oldDisp = disp;
+ disp = disp->next;
+ for( i=0 ; i<oldDisp->nelms ; i++ )
+ {
+ DisplayElmPtr elm = &oldDisp->elms[i];
+
+ switch(elm->type)
+ {
+ case PolyPointCmd:
+ case PolyLineCmd:
+ if( elm->c.polyPts.pPoints ) xfree(elm->c.polyPts.pPoints);
+ break;
+ case PolySegmentCmd:
+ if( elm->c.segments.pSegments ) xfree(elm->c.segments.pSegments);
+ break;
+ case PolyRectangleCmd:
+ if( elm->c.rects.pRects ) xfree(elm->c.rects.pRects);
+ break;
+ case FillPolygonCmd:
+ if( elm->c.polyPts.pPoints ) xfree(elm->c.polyPts.pPoints);
+ break;
+ case PolyFillRectCmd:
+ if( elm->c.rects.pRects ) xfree(elm->c.rects.pRects);
+ break;
+ case PolyArcCmd:
+ if( elm->c.arcs.pArcs ) xfree(elm->c.arcs.pArcs);
+ break;
+ case PolyFillArcCmd:
+ if( elm->c.arcs.pArcs ) xfree(elm->c.arcs.pArcs);
+ break;
+ case Text8Cmd:
+ case TextI8Cmd:
+ if( elm->c.text8.string ) xfree(elm->c.text8.string);
+ break;
+ case Text16Cmd:
+ case TextI16Cmd:
+ if( elm->c.text16.string ) xfree(elm->c.text16.string);
+ break;
+ case PutImageCmd:
+ if( elm->c.image.pData ) xfree(elm->c.image.pData);
+ break;
+ case BeginFrameCmd:
+ break;
+ case EndFrameCmd:
+ break;
+ }
+
+ if (elm->type != BeginFrameCmd && elm->type != EndFrameCmd) {
+ (void) FreeGC(elm->gc, (GContext) 0);
+ }
+ }
+ xfree(oldDisp);
+ }
+
+ priv->dispList = NULL;
+}
+
+Bool
+PsDestroyPixmap(PixmapPtr pPixmap)
+{
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pPixmap->devPrivate.ptr;
+
+ if( --pPixmap->refcnt ) return TRUE;
+
+ PsScrubPixmap(pPixmap);
+
+ xfree(priv);
+ xfree(pPixmap);
+ return TRUE;
+}
+
+DisplayListPtr
+PsGetFreeDisplayBlock(PsPixmapPrivPtr priv)
+{
+ DisplayListPtr disp = priv->dispList;
+
+ for(; disp ; disp=disp->next )
+ {
+ if( disp->nelms>=DPY_BLOCKSIZE && disp->next ) continue;
+ if( disp->nelms<DPY_BLOCKSIZE ) return(disp);
+ disp->next = (DisplayListPtr)xcalloc(1, sizeof(DisplayListRec));
+ disp->next->next = (DisplayListPtr)0;
+ disp->next->nelms = 0;
+ }
+ disp = (DisplayListPtr)xcalloc(1, sizeof(DisplayListRec));
+ disp->next = (DisplayListPtr)0;
+ disp->nelms = 0;
+ priv->dispList = disp;
+ return(disp);
+}
+
+void
+PsReplay(DisplayElmPtr elm, DrawablePtr pDrawable)
+{
+ switch(elm->type)
+ {
+ case PolyPointCmd:
+ PsPolyPoint(pDrawable, elm->gc, elm->c.polyPts.mode,
+ elm->c.polyPts.nPoints, elm->c.polyPts.pPoints);
+ break;
+ case PolyLineCmd:
+ PsPolyLine(pDrawable, elm->gc, elm->c.polyPts.mode,
+ elm->c.polyPts.nPoints, elm->c.polyPts.pPoints);
+ break;
+ case PolySegmentCmd:
+ PsPolySegment(pDrawable, elm->gc, elm->c.segments.nSegments,
+ elm->c.segments.pSegments);
+ break;
+ case PolyRectangleCmd:
+ PsPolyRectangle(pDrawable, elm->gc, elm->c.rects.nRects,
+ elm->c.rects.pRects);
+ break;
+ case FillPolygonCmd:
+ PsFillPolygon(pDrawable, elm->gc, 0, elm->c.polyPts.mode,
+ elm->c.polyPts.nPoints, elm->c.polyPts.pPoints);
+ break;
+ case PolyFillRectCmd:
+ PsPolyFillRect(pDrawable, elm->gc, elm->c.rects.nRects,
+ elm->c.rects.pRects);
+ break;
+ case PolyArcCmd:
+ PsPolyArc(pDrawable, elm->gc, elm->c.arcs.nArcs, elm->c.arcs.pArcs);
+ break;
+ case PolyFillArcCmd:
+ PsPolyFillArc(pDrawable, elm->gc, elm->c.arcs.nArcs, elm->c.arcs.pArcs);
+ break;
+ case Text8Cmd:
+ PsPolyText8(pDrawable, elm->gc, elm->c.text8.x, elm->c.text8.y,
+ elm->c.text8.count, elm->c.text8.string);
+ break;
+ case Text16Cmd:
+ PsPolyText16(pDrawable, elm->gc, elm->c.text16.x, elm->c.text16.y,
+ elm->c.text16.count, elm->c.text16.string);
+ break;
+ case TextI8Cmd:
+ PsImageText8(pDrawable, elm->gc, elm->c.text8.x, elm->c.text8.y,
+ elm->c.text8.count, elm->c.text8.string);
+ break;
+ case TextI16Cmd:
+ PsImageText16(pDrawable, elm->gc, elm->c.text16.x, elm->c.text16.y,
+ elm->c.text16.count, elm->c.text16.string);
+ break;
+ case PutImageCmd:
+ PsPutScaledImage(pDrawable, elm->gc, elm->c.image.depth,
+ elm->c.image.x, elm->c.image.y,
+ elm->c.image.w, elm->c.image.h, elm->c.image.leftPad,
+ elm->c.image.format, elm->c.image.res,
+ elm->c.image.pData);
+ break;
+ case BeginFrameCmd:
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ if( PsUpdateDrawableGC(NULL, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_BeginFrame(psOut, 0, 0, elm->c.frame.x, elm->c.frame.y,
+ elm->c.frame.w, elm->c.frame.h);
+ }
+ break;
+ case EndFrameCmd:
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ if( PsUpdateDrawableGC(NULL, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_EndFrame(psOut);
+ }
+ break;
+ }
+}
+
+void
+PsReplayPixmap(PixmapPtr pix, DrawablePtr pDrawable)
+{
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp = priv->dispList;
+ DisplayElmPtr elm;
+
+ for(; disp ; disp=disp->next )
+ {
+ int i;
+ for( i=0,elm=disp->elms ; i<disp->nelms ; i++,elm++ )
+ PsReplay(elm, pDrawable);
+ }
+}
+
+int
+PsCloneDisplayElm(PixmapPtr dst, DisplayElmPtr elm, DisplayElmPtr newElm,
+ int xoff, int yoff)
+{
+ int i;
+ int size;
+ int status = 0;
+
+ *newElm = *elm;
+
+ /* I think this is the correct return value */
+ if ((newElm->gc = PsCreateAndCopyGC(&dst->drawable, elm->gc)) == NULL) {
+ return 1;
+ }
+
+ switch(elm->type)
+ {
+ case PolyPointCmd:
+ case PolyLineCmd:
+ newElm->c.polyPts.pPoints =
+ (xPoint *)xalloc(elm->c.polyPts.nPoints*sizeof(xPoint));
+ for( i=0 ; i<elm->c.polyPts.nPoints ; i++ )
+ {
+ newElm->c.polyPts.pPoints[i].x = elm->c.polyPts.pPoints[i].x+xoff;
+ newElm->c.polyPts.pPoints[i].y = elm->c.polyPts.pPoints[i].y+yoff;
+ }
+ break;
+ case PolySegmentCmd:
+ newElm->c.segments.pSegments =
+ (xSegment *)xalloc(elm->c.segments.nSegments*sizeof(xSegment));
+ for( i=0 ; i<elm->c.segments.nSegments ; i++ )
+ {
+ newElm->c.segments.pSegments[i].x1 =
+ elm->c.segments.pSegments[i].x1+xoff;
+ newElm->c.segments.pSegments[i].y1 =
+ elm->c.segments.pSegments[i].y1+yoff;
+ newElm->c.segments.pSegments[i].x2 =
+ elm->c.segments.pSegments[i].x2+xoff;
+ newElm->c.segments.pSegments[i].y2 =
+ elm->c.segments.pSegments[i].y2+yoff;
+ }
+ break;
+ case PolyRectangleCmd:
+ newElm->c.rects.pRects =
+ (xRectangle *)xalloc(elm->c.rects.nRects*sizeof(xRectangle));
+ for( i=0 ; i<elm->c.rects.nRects ; i++ )
+ {
+ newElm->c.rects.pRects[i].x = elm->c.rects.pRects[i].x+xoff;
+ newElm->c.rects.pRects[i].y = elm->c.rects.pRects[i].y+yoff;
+ newElm->c.rects.pRects[i].width = elm->c.rects.pRects[i].width;
+ newElm->c.rects.pRects[i].height = elm->c.rects.pRects[i].height;
+ }
+ break;
+ case FillPolygonCmd:
+ newElm->c.polyPts.pPoints =
+ (xPoint *)xalloc(elm->c.polyPts.nPoints*sizeof(xPoint));
+ for( i=0 ; i<elm->c.polyPts.nPoints ; i++ )
+ {
+ newElm->c.polyPts.pPoints[i].x = elm->c.polyPts.pPoints[i].x+xoff;
+ newElm->c.polyPts.pPoints[i].y = elm->c.polyPts.pPoints[i].y+yoff;
+ }
+ break;
+ case PolyFillRectCmd:
+ newElm->c.rects.pRects =
+ (xRectangle *)xalloc(elm->c.rects.nRects*sizeof(xRectangle));
+ for( i=0 ; i<elm->c.rects.nRects ; i++ )
+ {
+ newElm->c.rects.pRects[i].x = elm->c.rects.pRects[i].x+xoff;
+ newElm->c.rects.pRects[i].y = elm->c.rects.pRects[i].y+yoff;
+ newElm->c.rects.pRects[i].width = elm->c.rects.pRects[i].width;
+ newElm->c.rects.pRects[i].height = elm->c.rects.pRects[i].height;
+ }
+ break;
+ case PolyArcCmd:
+ newElm->c.arcs.pArcs =
+ (xArc *)xalloc(elm->c.arcs.nArcs*sizeof(xArc));
+ for( i=0 ; i<elm->c.arcs.nArcs ; i++ )
+ {
+ newElm->c.arcs.pArcs[i].x = elm->c.arcs.pArcs[i].x+xoff;
+ newElm->c.arcs.pArcs[i].y = elm->c.arcs.pArcs[i].y+yoff;
+ newElm->c.arcs.pArcs[i].width = elm->c.arcs.pArcs[i].width;
+ newElm->c.arcs.pArcs[i].height = elm->c.arcs.pArcs[i].height;
+ newElm->c.arcs.pArcs[i].angle1 = elm->c.arcs.pArcs[i].angle1;
+ newElm->c.arcs.pArcs[i].angle2 = elm->c.arcs.pArcs[i].angle2;
+ }
+ break;
+ case PolyFillArcCmd:
+ newElm->c.arcs.pArcs =
+ (xArc *)xalloc(elm->c.arcs.nArcs*sizeof(xArc));
+ for( i=0 ; i<elm->c.arcs.nArcs ; i++ )
+ {
+ newElm->c.arcs.pArcs[i].x = elm->c.arcs.pArcs[i].x+xoff;
+ newElm->c.arcs.pArcs[i].y = elm->c.arcs.pArcs[i].y+yoff;
+ newElm->c.arcs.pArcs[i].width = elm->c.arcs.pArcs[i].width;
+ newElm->c.arcs.pArcs[i].height = elm->c.arcs.pArcs[i].height;
+ newElm->c.arcs.pArcs[i].angle1 = elm->c.arcs.pArcs[i].angle1;
+ newElm->c.arcs.pArcs[i].angle2 = elm->c.arcs.pArcs[i].angle2;
+ }
+ break;
+ case Text8Cmd:
+ case TextI8Cmd:
+ newElm->c.text8.string = (char *)xalloc(elm->c.text8.count);
+ memcpy(newElm->c.text8.string, elm->c.text8.string, elm->c.text8.count);
+ newElm->c.text8.x += xoff;
+ newElm->c.text8.y += yoff;
+ break;
+ case Text16Cmd:
+ case TextI16Cmd:
+ newElm->c.text16.string =
+ (unsigned short *)xalloc(elm->c.text16.count*sizeof(unsigned short));
+ memcpy(newElm->c.text16.string, elm->c.text16.string,
+ elm->c.text16.count*sizeof(unsigned short));
+ newElm->c.text16.x += xoff;
+ newElm->c.text16.y += yoff;
+ break;
+ case PutImageCmd:
+ size = PixmapBytePad(elm->c.image.w, elm->c.image.depth)*elm->c.image.h;
+ newElm->c.image.pData = (char *)xalloc(size);
+ memcpy(newElm->c.image.pData, elm->c.image.pData, size);
+ newElm->c.image.x += xoff;
+ newElm->c.image.y += yoff;
+ break;
+ case BeginFrameCmd:
+ case EndFrameCmd:
+ status = 1;
+ break;
+ }
+ return(status);
+}
+
+void
+PsCopyDisplayList(PixmapPtr src, PixmapPtr dst, int xoff, int yoff,
+ int x, int y, int w, int h)
+{
+ PsPixmapPrivPtr sPriv = (PsPixmapPrivPtr)src->devPrivate.ptr;
+ PsPixmapPrivPtr dPriv = (PsPixmapPrivPtr)dst->devPrivate.ptr;
+ DisplayListPtr sDisp;
+ DisplayListPtr dDisp = PsGetFreeDisplayBlock(dPriv);
+ DisplayElmPtr elm = &dDisp->elms[dDisp->nelms];
+
+ elm->type = BeginFrameCmd;
+ elm->c.frame.x = x;
+ elm->c.frame.y = y;
+ elm->c.frame.w = w;
+ elm->c.frame.h = h;
+ dDisp->nelms += 1;
+
+ sDisp = sPriv->dispList;
+ for(; sDisp ; sDisp=sDisp->next )
+ {
+ int i;
+ for( i=0,elm=sDisp->elms ; i<sDisp->nelms ; i++,elm++ )
+ {
+ dDisp = PsGetFreeDisplayBlock(dPriv);
+ if (PsCloneDisplayElm(dst, elm, &dDisp->elms[dDisp->nelms],
+ xoff, yoff)==0)
+ {
+ dDisp->nelms += 1;
+ }
+ }
+ }
+
+ dDisp = PsGetFreeDisplayBlock(dPriv);
+ elm = &dDisp->elms[dDisp->nelms];
+ elm->type = EndFrameCmd;
+ dDisp->nelms += 1;
+}
+
+PsElmPtr
+PsCreateFillElementList(PixmapPtr pix, int *nElms)
+{
+ PsElmPtr elms = (PsElmPtr)0;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp = priv->dispList;
+ PsArcEnum styl;
+
+ *nElms = 0;
+ for(; disp ; disp=disp->next )
+ {
+ int i;
+ DisplayElmPtr elm = disp->elms;
+
+ for( i=0 ; i<disp->nelms ; i++,elm++ )
+ {
+ if( !elm->gc ) continue; /* workaround for https://freedesktop.org/bugzilla/show_bug.cgi?id=1416 */
+ if( !elm->gc->fgPixel ) continue;
+ switch(elm->type)
+ {
+ case FillPolygonCmd:
+ *nElms += 1;
+ break;
+ case PolyFillRectCmd:
+ *nElms += elm->c.rects.nRects;
+ break;
+ case PolyFillArcCmd:
+ *nElms += elm->c.arcs.nArcs;
+ break;
+ default: /* keep the compiler happy with unhandled enums */
+ break;
+ }
+ }
+ }
+
+ if( (*nElms) )
+ {
+ elms = (PsElmPtr)xcalloc(1, (*nElms)*sizeof(PsElmRec));
+ if( elms )
+ {
+ disp = priv->dispList;
+ *nElms = 0;
+ for(; disp ; disp=disp->next )
+ {
+ int i, k;
+ DisplayElmPtr elm = disp->elms;
+
+ for( i=0 ; i<disp->nelms ; i++,elm++ )
+ {
+ if( !elm->gc->fgPixel ) continue;
+ switch(elm->type)
+ {
+ case FillPolygonCmd:
+ elms[*nElms].type = PSOUT_POINTS;
+ elms[*nElms].nPoints = elm->c.polyPts.nPoints;
+ elms[*nElms].c.points =
+ (PsPointPtr)xalloc(elms[*nElms].nPoints*sizeof(PsPointRec));
+ for( k=0 ; k<elms[*nElms].nPoints ; k++ )
+ {
+ elms[*nElms].c.points[k].x = elm->c.polyPts.pPoints[k].x;
+ elms[*nElms].c.points[k].y = elm->c.polyPts.pPoints[k].y;
+ }
+ *nElms += 1;
+ break;
+ case PolyFillRectCmd:
+ for( k=0 ; k<elm->c.rects.nRects ; k++ )
+ {
+ elms[*nElms].type = PSOUT_RECT;
+ elms[*nElms].nPoints = 0;
+ elms[*nElms].c.rect.x = elm->c.rects.pRects[k].x;
+ elms[*nElms].c.rect.y = elm->c.rects.pRects[k].y;
+ elms[*nElms].c.rect.w = elm->c.rects.pRects[k].width;
+ elms[*nElms].c.rect.h = elm->c.rects.pRects[k].height;
+ *nElms += 1;
+ }
+ break;
+ case PolyFillArcCmd:
+ if( elm->gc->arcMode==ArcChord ) styl = PsChord;
+ else styl = PsPieSlice;
+ for( k=0 ; k<elm->c.rects.nRects ; k++ )
+ {
+ elms[*nElms].type = PSOUT_ARC;
+ elms[*nElms].nPoints = 0;
+ elms[*nElms].c.arc.x = elm->c.arcs.pArcs[k].x;
+ elms[*nElms].c.arc.y = elm->c.arcs.pArcs[k].y;
+ elms[*nElms].c.arc.w = elm->c.arcs.pArcs[k].width;
+ elms[*nElms].c.arc.h = elm->c.arcs.pArcs[k].height;
+ elms[*nElms].c.arc.a1 = elm->c.arcs.pArcs[k].angle1;
+ elms[*nElms].c.arc.a2 = elm->c.arcs.pArcs[k].angle2;
+ elms[*nElms].c.arc.style = styl;
+ *nElms += 1;
+ }
+ break;
+ default: /* keep the compiler happy with unhandled enums */
+ break;
+ }
+ }
+ }
+ }
+ }
+ return(elms);
+}
+
+PsElmPtr
+PsCloneFillElementList(int nElms, PsElmPtr elms)
+{
+ int i;
+ PsElmPtr newElms;
+
+ newElms = (PsElmPtr)xcalloc(1, nElms*sizeof(PsElmRec));
+ if( !newElms ) return(newElms);
+ for( i=0 ; i<nElms ; i++ )
+ {
+ newElms[i] = elms[i];
+
+ if( elms[i].type==PSOUT_POINTS )
+ {
+ newElms[i].c.points =
+ (PsPointPtr)xalloc(elms[i].nPoints*sizeof(PsElmRec));
+ memcpy(newElms[i].c.points, elms[i].c.points,
+ elms[i].nPoints*sizeof(PsPointRec));
+ }
+ }
+ return(newElms);
+}
+
+void
+PsDestroyFillElementList(int nElms, PsElmPtr elms)
+{
+ int i;
+
+ for( i=0 ; i<nElms ; i++ )
+ { if( elms[i].type==PSOUT_POINTS ) xfree(elms[i].c.points); }
+
+ xfree(elms);
+}
diff --git a/hw/xprint/ps/PsPolygon.c b/hw/xprint/ps/PsPolygon.c
new file mode 100644
index 000000000..c4c30bc79
--- /dev/null
+++ b/hw/xprint/ps/PsPolygon.c
@@ -0,0 +1,260 @@
+/* $Xorg: PsPolygon.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsPolygon.c
+** *
+** * Contents: Draws Polygons and Rectangles for the PS DDX
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PsPolyRectangle(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolyRectangleCmd;
+ elm->gc = gc;
+ elm->c.rects.nRects = nRects;
+ elm->c.rects.pRects = (xRectangle *)xalloc(nRects*sizeof(xRectangle));
+ memcpy(elm->c.rects.pRects, pRects, nRects*sizeof(xRectangle));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ PsLineAttrs(psOut, pGC, cMap);
+ for( i=0 ; i<nRects ; i++ )
+ {
+ PsOut_DrawRect(psOut, (int)pRects[i].x, (int)pRects[i].y,
+ (int)pRects[i].width, (int)pRects[i].height);
+ }
+ }
+}
+
+void
+PsFillPolygon(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int nPoints,
+ DDXPointPtr pPoints)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = FillPolygonCmd;
+ elm->gc = gc;
+ elm->c.polyPts.mode = mode;
+ elm->c.polyPts.nPoints = nPoints;
+ elm->c.polyPts.pPoints = (xPoint *)xalloc(nPoints*sizeof(xPoint));
+ memcpy(elm->c.polyPts.pPoints, pPoints, nPoints*sizeof(xPoint));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ PsPointPtr pts;
+ PsRuleEnum rule;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsSetFillColor(pDrawable, pGC, psOut, cMap);
+ if( pGC->fillRule==EvenOddRule ) rule = PsEvenOdd;
+ else rule = PsNZWinding;
+ PsOut_FillRule(psOut, rule);
+ pts = (PsPointPtr)xalloc(sizeof(PsPointRec)*nPoints);
+ if( mode==CoordModeOrigin )
+ {
+ for( i=0 ; i<nPoints ; i++ )
+ { pts[i].x = pPoints[i].x; pts[i].y = pPoints[i].y; }
+ }
+ else
+ {
+ i = 0;
+ pts[0].x = pPoints[i].x; pts[0].y = pPoints[i].y;
+ for( i=1 ; i<nPoints ; i++ )
+ {
+ pts[i].x = pts[i-1].x+pPoints[i].x;
+ pts[i].y = pts[i-1].y+pPoints[i].y;
+ }
+ }
+ PsOut_Polygon(psOut, nPoints, pts);
+ xfree(pts);
+ }
+}
+
+void
+PsPolyFillRect(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+#ifdef DBE
+ /* Remove previous pixmap content if we render one single rect which
+ * covers the whole pixmap surface (this optimisation was added for
+ * the double-buffer extension ("DBE") which uses |PolyFillRect()|
+ * to clear the buffer - but it makes sense in other cases, too).
+ */
+ if (nRects == 1)
+ {
+ if ( (pRects[0].x==0) && (pRects[0].y==0) &&
+ (pRects[0].width==pDrawable->width) && (pRects[0].height==pDrawable->height) &&
+ (pGC->fillStyle == FillSolid) &&
+ (noDbeExtension == False))
+ {
+#ifdef DEBUG_gismobile
+ ErrorF("PsPolyFillRect: scrubbing pixmap...\n");
+#endif /* DEBUG_gismobile */
+ /* Remove all content from the pixmap as it would be covered
+ * by the whole rect anyway */
+ PsScrubPixmap((PixmapPtr)pDrawable);
+ }
+ }
+#endif /* DBE */
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = PolyFillRectCmd;
+ elm->gc = gc;
+ elm->c.rects.nRects = nRects;
+ elm->c.rects.pRects = (xRectangle *)xalloc(nRects*sizeof(xRectangle));
+ memcpy(elm->c.rects.pRects, pRects, nRects*sizeof(xRectangle));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsSetFillColor(pDrawable, pGC, psOut, cMap);
+ for( i=0 ; i<nRects ; i++ )
+ {
+ PsOut_FillRect(psOut, (int)pRects[i].x, (int)pRects[i].y,
+ (int)pRects[i].width, (int)pRects[i].height);
+ }
+ }
+}
diff --git a/hw/xprint/ps/PsPrint.c b/hw/xprint/ps/PsPrint.c
new file mode 100644
index 000000000..8a4f0ade8
--- /dev/null
+++ b/hw/xprint/ps/PsPrint.c
@@ -0,0 +1,459 @@
+/* $Xorg: PsPrint.c,v 1.7 2001/03/14 18:28:18 pookie Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All rights reserved.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsPrint.c
+** *
+** * Contents: Print extension code of Ps driver
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <X11/Xprotostr.h>
+
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#undef NEED_EVENTS
+
+#include "Ps.h"
+
+#include "windowstr.h"
+#include "attributes.h"
+#include "Oid.h"
+
+/* static utility function to get document/page attributes */
+static void
+S_GetPageAttributes(XpContextPtr pCon,int *iorient,int *icount, int *iplex,
+ int *ires, unsigned short *iwd, unsigned short *iht)
+{
+ char *count;
+ XpOid orient, plex;
+ /*
+ * Get the orientation
+ */
+ orient = XpGetContentOrientation(pCon);
+ switch (orient) {
+ case xpoid_val_content_orientation_landscape:
+ *iorient = 1;
+ break;
+ case xpoid_val_content_orientation_reverse_portrait:
+ *iorient = 2;
+ break;
+ case xpoid_val_content_orientation_reverse_landscape:
+ *iorient = 3;
+ break;
+ case xpoid_val_content_orientation_portrait:
+ default:
+ *iorient = 0;
+ break;
+ }
+
+ /*
+ * Get the count
+ */
+ count = XpGetOneAttribute(pCon, XPDocAttr, "copy-count");
+ if( count )
+ {
+ int ii = sscanf(count, "%d", icount);
+ if( ii!=1 ) *icount = 1;
+ }
+ else *icount = 1;
+
+ /*
+ * Get the plex
+ */
+ plex = XpGetPlex(pCon);
+ switch(plex)
+ {
+ case xpoid_val_plex_duplex:
+ *iplex = 1;
+ break;
+ case xpoid_val_plex_tumble:
+ *iplex = 2;
+ break;
+ default:
+ *iplex = 0;
+ break;
+ }
+
+ /*
+ * Get the resolution and media size
+ */
+ *ires = XpGetResolution(pCon);
+ XpGetMediumDimensions(pCon, iwd, iht);
+}
+
+
+int
+PsStartJob(
+ XpContextPtr pCon,
+ Bool sendClientData,
+ ClientPtr client)
+{
+ PsContextPrivPtr pConPriv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ /*
+ * Create a temporary file to store the printer output.
+ */
+ if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
+ return BadAlloc;
+
+ return Success;
+}
+
+
+
+/* I thought about making this following code into a set of routines
+ or using a goto, or something, but in the end decided not to,
+ because the plain old listing here makes the logic clearer. */
+int
+PsEndJob(
+ XpContextPtr pCon,
+ Bool cancel)
+{
+ int r;
+ struct stat buffer;
+ int error;
+
+ PsContextPrivPtr priv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ if (cancel == True) {
+ if (priv->getDocClient != (ClientPtr) NULL) {
+ (void) XpFinishDocData( priv->getDocClient );
+
+ priv->getDocClient = NULL;
+ priv->getDocBufSize = 0;
+ }
+
+ /* job is cancelled - do we really care if we're out of space? */
+ (void) fclose(priv->pJobFile);
+ priv->pJobFile = NULL;
+
+ unlink(priv->jobFileName);
+ xfree(priv->jobFileName);
+ priv->jobFileName = (char *)NULL;
+
+ PsFreeFontInfoRecords(priv);
+
+ return Success;
+ }
+
+ /*
+ * Append any trailing information here
+ */
+ PsOut_EndFile(priv->pPsOut, 0);
+ priv->pPsOut = NULL;
+
+ /* this is where we find out if we're out of space */
+ error = (fclose(priv->pJobFile) == EOF);
+ priv->pJobFile = NULL;
+
+ /* status to the client if we have ran out of space on the disk or
+ some other resource problem with the temporary file... */
+ if (error) {
+ if (priv->getDocClient != (ClientPtr) NULL) {
+ (void) XpFinishDocData( priv->getDocClient );
+
+ priv->getDocClient = NULL;
+ priv->getDocBufSize = 0;
+ }
+
+ unlink(priv->jobFileName);
+ xfree(priv->jobFileName);
+ priv->jobFileName = (char *)NULL;
+
+ PsFreeFontInfoRecords(priv);
+
+ return BadAlloc;
+ }
+
+ /* we have finished without incident & no cancel */
+
+ if (priv->getDocClient != NULL && priv->getDocBufSize > 0) {
+ FILE *file;
+
+ file = fopen(priv->jobFileName, "r");
+ if (!file || (fstat(fileno(file), &buffer) < 0))
+ r = BadAlloc;
+ else
+ r = XpSendDocumentData(priv->getDocClient, file, buffer.st_size,
+ priv->getDocBufSize);
+ if (file)
+ fclose(file);
+
+ (void) XpFinishDocData(priv->getDocClient);
+
+ priv->getDocClient = NULL;
+ priv->getDocBufSize = 0;
+ }
+ else {
+ XpSubmitJob(priv->jobFileName, pCon);
+
+ r = Success;
+ }
+
+ unlink(priv->jobFileName);
+ xfree(priv->jobFileName);
+ priv->jobFileName = (char *)NULL;
+
+ PsFreeFontInfoRecords(priv);
+
+#ifdef BM_CACHE
+ PsBmClearImageCache();
+#endif
+
+ return r;
+}
+
+/* StartPage
+ */
+int
+PsStartPage(
+ XpContextPtr pCon,
+ WindowPtr pWin)
+{
+ int iorient, iplex, icount, ires;
+ unsigned short iwd, iht;
+ PsContextPrivPtr pConPriv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+ PsWindowPrivPtr pWinPriv =
+ (PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr;
+
+/*
+ * Put a pointer to the context in the window private structure
+ */
+ pWinPriv->validContext = 1;
+ pWinPriv->context = pCon;
+
+ /* get page level attributes */
+ S_GetPageAttributes(pCon,&iorient,&icount,&iplex,&ires,&iwd,&iht);
+ /*
+ * Start the page
+ */
+ if (pConPriv->pPsOut == NULL) {
+ char *title;
+
+ /* get job level attributes */
+ title = XpGetOneAttribute(pCon, XPJobAttr, "job-name");
+
+ pConPriv->pPsOut = PsOut_BeginFile(pConPriv->pJobFile,
+ title, iorient, icount, iplex, ires,
+ (int)iwd, (int)iht, False);
+ pConPriv->fontInfoRecords = NULL;
+ pConPriv->fontTypeInfoRecords = NULL;
+ }
+ PsOut_BeginPage(pConPriv->pPsOut, iorient, icount, iplex, ires,
+ (int)iwd, (int)iht);
+
+ return Success;
+}
+
+
+/*
+ * EndPage:
+ *
+ * Write page trailer to page file
+ * Write page file to job file
+ */
+int
+PsEndPage(
+ XpContextPtr pCon,
+ WindowPtr pWin)
+{
+ PsWindowPrivPtr pWinPriv =
+ (PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr;
+ PsContextPrivPtr pConPriv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ PsOut_EndPage(pConPriv->pPsOut);
+
+ pWinPriv->validContext = 0;
+ pWinPriv->context = NULL;
+
+ /* status to the client if we have ran out of space on the disk or
+ some other resource problem with the temporary file... */
+/* if (ferror(pConPriv->pJobFile)) return BadAlloc; */
+
+ return Success;
+}
+
+/*
+ * The PsStartDoc() and PsEndDoc() functions serve basically as NOOP
+ * placeholders. This driver doesn't deal with the notion of multiple
+ * documents per page.
+ */
+
+int
+PsStartDoc(XpContextPtr pCon, XPDocumentType type)
+{
+ int iorient, iplex, icount, ires;
+ unsigned short iwd, iht;
+ char *title;
+ PsContextPrivPtr pConPriv =
+ (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ /* get job level attributes */
+ title = XpGetOneAttribute(pCon, XPJobAttr, "job-name");
+
+ /* get document level attributes */
+ S_GetPageAttributes(pCon,&iorient,&icount,&iplex,&ires,&iwd,&iht);
+
+ pConPriv->pPsOut = PsOut_BeginFile(pConPriv->pJobFile,
+ title, iorient, icount, iplex, ires,
+ (int)iwd, (int)iht, (Bool)(type == XPDocRaw));
+
+ pConPriv->fontInfoRecords = NULL;
+ pConPriv->fontTypeInfoRecords = NULL;
+
+ return Success;
+}
+
+int
+PsEndDoc(
+ XpContextPtr pCon,
+ Bool cancel)
+{
+ return Success;
+}
+
+/*
+ * PsDocumentData()
+ *
+ * Hand any pre-generated PDL down to the spool files, formatting it
+ * as necessary to fit the given window.
+ */
+
+int
+PsDocumentData(
+ XpContextPtr pCon,
+ DrawablePtr pDraw,
+ char *pData,
+ int len_data,
+ char *pFmt,
+ int len_fmt,
+ char *pOpt,
+ int len_opt,
+ ClientPtr client)
+{
+ PsContextPrivPtr cPriv;
+ PsOutPtr psOut;
+
+ if (len_fmt != 12 ||
+ strncasecmp(pFmt, "PostScript 2", len_fmt) != 0 ||
+ len_opt)
+ return BadValue;
+
+ cPriv = pCon->devPrivates[PsContextPrivateIndex].ptr;
+ psOut = cPriv->pPsOut;
+
+ if (pDraw)
+ PsOut_BeginFrame(psOut, 0, 0, pDraw->x, pDraw->y,
+ pDraw->width, pDraw->height);
+ PsOut_RawData(psOut, pData, len_data);
+ if (pDraw)
+ PsOut_EndFrame(psOut);
+
+ return Success;
+}
+
+/*
+ *
+ * PsGetDocumentData()
+ *
+ * This function allows the driver to send the generated PS back to
+ * the client.
+ */
+
+int
+PsGetDocumentData(
+ XpContextPtr pCon,
+ ClientPtr client,
+ int maxBufferSize)
+{
+ PsContextPrivPtr pPriv = (PsContextPrivPtr)
+ pCon->devPrivates[PsContextPrivateIndex].ptr;
+
+ pPriv->getDocClient = client;
+ pPriv->getDocBufSize = maxBufferSize;
+
+ return Success;
+}
+
diff --git a/hw/xprint/ps/PsSpans.c b/hw/xprint/ps/PsSpans.c
new file mode 100644
index 000000000..d7652f8fb
--- /dev/null
+++ b/hw/xprint/ps/PsSpans.c
@@ -0,0 +1,166 @@
+/* $Xorg: PsSpans.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsSpans.c
+** *
+** * Contents: Code to set and fill spans in the PS DDX
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+/* $XFree86: xc/programs/Xserver/Xprint/ps/PsSpans.c,v 1.8 2001/10/28 03:32:56 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+PsFillSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSpans,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int fSorted)
+{
+ PsOutPtr psOut;
+ int xoffset, yoffset;
+ xRectangle *rects, *r;
+ RegionPtr fillRegion, region = 0;
+ int i;
+ int nbox;
+ BoxPtr pbox;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+
+ /*
+ * Build a region out of the spans
+ */
+ rects = (xRectangle *)xalloc(nSpans*sizeof(xRectangle));
+ xoffset = pDrawable->x;
+ yoffset = pDrawable->y;
+
+ for( i = 0, r = rects; i < nSpans; i++, r++ )
+ {
+ r->x = pPoints[i].x + xoffset;
+ r->y = pPoints[i].y + yoffset;
+ r->width = pWidths[i];
+ r->height = 1;
+ }
+ fillRegion = RECTS_TO_REGION(pGC->pScreen, nSpans, rects,
+ (fSorted)?CT_YSORTED:CT_UNSORTED);
+
+ /*
+ * Intersect this region with the clip region. Whatever's left,
+ * should be filled.
+ */
+/*REGION_INTERSECT(pGC->pScreen, region, fillRegion, pGC->clientClip);*/
+
+ pbox = REGION_RECTS(region);
+ nbox = REGION_NUM_RECTS(region);
+
+ /* Enter HP-GL/2 */
+ /*###SEND_PCL( outFile, "\27%0B" );*/
+
+ while( nbox )
+ {
+/*###
+ sprintf( t, "PU%d,%d;RR%d,%d;", pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ SEND_PCL( outFile, t );
+*/
+ nbox--;
+ pbox++;
+ }
+
+ /* Go back to PCL */
+ /*###SEND_PCL( outFile, "\27%0A" );*/
+
+ /*
+ * Clean up the temporary regions
+ */
+ REGION_DESTROY(pGC->pScreen, fillRegion);
+ REGION_DESTROY(pGC->pScreen, region);
+ xfree(rects);
+}
+
+void
+PsSetSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pSrc,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int nSpans,
+ int fSorted)
+{
+}
diff --git a/hw/xprint/ps/PsText.c b/hw/xprint/ps/PsText.c
new file mode 100644
index 000000000..37463ba1a
--- /dev/null
+++ b/hw/xprint/ps/PsText.c
@@ -0,0 +1,582 @@
+/* $Xorg: PsText.c,v 1.7 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsText.c
+** *
+** * Contents: Character-drawing routines for the PS DDX
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "Ps.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include <X11/fonts/fntfil.h>
+#include <X11/fonts/fntfilst.h>
+#include <limits.h>
+
+int
+PsPolyText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *string)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return x;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = Text8Cmd;
+ elm->gc = gc;
+ elm->c.text8.x = x;
+ elm->c.text8.y = y;
+ elm->c.text8.count = count;
+ elm->c.text8.string = (char *)xalloc(count);
+ memcpy(elm->c.text8.string, string, count);
+ disp->nelms += 1;
+
+ return x;
+ }
+ else
+ {
+ PsFontInfoRec *firec;
+
+ /* We need a context for rendering... */
+ if (PsGetPsContextPriv(pDrawable) == NULL)
+ return x;
+
+ firec = PsGetFontInfoRec(pDrawable, pGC->font);
+ if (!firec)
+ return x;
+
+#ifdef XP_USE_FREETYPE
+ if (firec->ftir->downloadableFont &&
+ (firec->ftir->font_type == PSFTI_FONT_TYPE_FREETYPE))
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
+ return x;
+
+ if (firec->ftir->alreadyDownloaded[0] == False)
+ {
+ PsOut_DownloadFreeType(psOut,
+ firec->ftir->ft_download_font_type,
+ firec->ftir->download_ps_name, pGC->font, 0);
+ firec->ftir->alreadyDownloaded[0] = True;
+ }
+
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ if (!firec->size)
+ PsOut_TextAttrsMtx(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
+ else
+ PsOut_TextAttrs(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
+ PsOut_FreeType_Text(pGC->font, psOut, x, y, string, count);
+
+ return x;
+ }
+ else
+#endif /* XP_USE_FREETYPE */
+ if (firec->ftir->downloadableFont &&
+ (firec->ftir->font_type != PSFTI_FONT_TYPE_FREETYPE))
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
+ return x;
+
+ if (firec->ftir->alreadyDownloaded[0] == False)
+ {
+ PsOut_DownloadType1(psOut, "PsPolyText8",
+ firec->ftir->download_ps_name, firec->ftir->filename);
+ firec->ftir->alreadyDownloaded[0] = True;
+ }
+
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ if (!firec->size)
+ PsOut_TextAttrsMtx(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
+ else
+ PsOut_TextAttrs(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
+ PsOut_Text(psOut, x, y, string, count, -1);
+
+ return x;
+ }
+
+ /* Render glyphs as bitmaps */
+ {
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255];
+
+ GetGlyphs(pGC->font, (unsigned long)count,
+ (unsigned char *)string, Linear8Bit, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++)
+ w += charinfo[i]->metrics.characterWidth;
+
+ if (n != 0)
+ PsPolyGlyphBlt(pDrawable, pGC, x, y, n,
+ charinfo, FONTGLYPHS(pGC->font));
+ x += w;
+
+ return x;
+ }
+ }
+ return x;
+}
+
+int
+PsPolyText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *string)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return x;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = Text16Cmd;
+ elm->gc = gc;
+ elm->c.text16.x = x;
+ elm->c.text16.y = y;
+ elm->c.text16.count = count;
+ elm->c.text16.string =
+ (unsigned short *)xalloc(count*sizeof(unsigned short));
+ memcpy(elm->c.text16.string, string, count*sizeof(unsigned short));
+ disp->nelms += 1;
+
+ return x;
+ }
+ else
+ {
+ PsFontInfoRec *firec;
+
+ /* We need a context for rendering... */
+ if (PsGetPsContextPriv(pDrawable) == NULL)
+ return x;
+
+ firec = PsGetFontInfoRec(pDrawable, pGC->font);
+ if (!firec)
+ return x;
+
+#ifdef XP_USE_FREETYPE
+ if (firec->ftir->downloadableFont &&
+ (firec->ftir->font_type == PSFTI_FONT_TYPE_FREETYPE))
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ unsigned short c,
+ c_hiByte,
+ c_lowByte,
+ fontPage;
+ int i;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
+ return x;
+
+ /* Scan the string we want to render and download all neccesary parts
+ * of the font (one part(="font page") has 256 glyphs)
+ */
+ for( i = 0 ; i < count ; i++ )
+ {
+ c = string[i];
+#if IMAGE_BYTE_ORDER == LSBFirst
+ c_hiByte = c & 0x00FF;
+ c_lowByte = (c >> 8) & 0x00FF;
+#elif IMAGE_BYTE_ORDER == MSBFirst
+ c_hiByte = (c >> 8) & 0x00FF;
+ c_lowByte = c & 0x00FF;
+#else
+#error Unsupported byte order
+#endif
+ fontPage = c_hiByte;
+
+ if (firec->ftir->alreadyDownloaded[fontPage] == False)
+ {
+ char buffer[256];
+ const char *ps_name;
+
+ if (fontPage > 0)
+ {
+ sprintf(buffer, "%s_%x", firec->ftir->download_ps_name, (int)fontPage);
+ ps_name = buffer;
+ }
+ else
+ {
+ ps_name = firec->ftir->download_ps_name;
+ }
+
+ PsOut_DownloadFreeType(psOut,
+ firec->ftir->ft_download_font_type,
+ ps_name, pGC->font, (fontPage * 0x100)); /* same as (fontPage << 8) */
+
+ firec->ftir->alreadyDownloaded[fontPage] = True;
+ }
+ }
+
+
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ if (!firec->size)
+ PsOut_FreeType_TextAttrsMtx16(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
+ else
+ PsOut_FreeType_TextAttrs16(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
+ PsOut_FreeType_Text16(pGC->font, psOut, x, y, string, count);
+
+ return x;
+ }
+ else
+#endif /* XP_USE_FREETYPE */
+ if (firec->ftir->downloadableFont &&
+ (firec->ftir->font_type != PSFTI_FONT_TYPE_FREETYPE))
+ {
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+ unsigned short fontPage;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE )
+ return x;
+
+ PsOut_DownloadType1(psOut, "PsPolyText16",
+ firec->ftir->download_ps_name, firec->ftir->filename);
+ firec->ftir->alreadyDownloaded[fontPage] = True;
+
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ if (!firec->size)
+ PsOut_TextAttrsMtx(psOut, firec->ftir->download_ps_name, firec->mtx, firec->ftir->is_iso_encoding);
+ else
+ PsOut_TextAttrs(psOut, firec->ftir->download_ps_name, firec->size, firec->ftir->is_iso_encoding);
+ PsOut_Text16(psOut, x, y, string, count, -1);
+
+ return x;
+ }
+
+ /* Render glyphs as bitmaps */
+ {
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++)
+ w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ PsPolyGlyphBlt(pDrawable, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ x += w;
+
+ return x;
+ }
+ }
+ return x;
+}
+
+void
+PsImageText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *string)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = TextI8Cmd;
+ elm->gc = gc;
+ elm->c.text8.x = x;
+ elm->c.text8.y = y;
+ elm->c.text8.count = count;
+ elm->c.text8.string = (char *)xalloc(count);
+ memcpy(elm->c.text8.string, string, count);
+ disp->nelms += 1;
+ }
+ else
+ {
+ int iso;
+ int siz;
+ float mtx[4];
+ char *fnam;
+ PsOutPtr psOut;
+ ColormapPtr cMap;
+
+ if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return;
+ PsOut_Offset(psOut, pDrawable->x, pDrawable->y);
+ PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel));
+ fnam = PsGetPSFontName(pGC->font);
+ if( !fnam ) fnam = "Times-Roman";
+ siz = PsGetFontSize(pGC->font, mtx);
+ iso = PsIsISOLatin1Encoding(pGC->font);
+ if( !siz ) PsOut_TextAttrsMtx(psOut, fnam, mtx, iso);
+ else PsOut_TextAttrs(psOut, fnam, siz, iso);
+ PsOut_Text(psOut, x, y, string, count, PsGetPixelColor(cMap, pGC->bgPixel));
+ }
+}
+
+void
+PsImageText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *string)
+{
+ if( pDrawable->type==DRAWABLE_PIXMAP )
+ {
+ DisplayElmPtr elm;
+ PixmapPtr pix = (PixmapPtr)pDrawable;
+ PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr;
+ DisplayListPtr disp;
+ GCPtr gc;
+
+ if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return;
+
+ disp = PsGetFreeDisplayBlock(priv);
+
+ elm = &disp->elms[disp->nelms];
+ elm->type = TextI16Cmd;
+ elm->gc = gc;
+ elm->c.text16.x = x;
+ elm->c.text16.y = y;
+ elm->c.text16.count = count;
+ elm->c.text16.string =
+ (unsigned short *)xalloc(count*sizeof(unsigned short));
+ memcpy(elm->c.text16.string, string, count*sizeof(unsigned short));
+ disp->nelms += 1;
+ }
+ else
+ {
+ int i;
+ char *str;
+ if( !count ) return;
+ str = (char *)xalloc(count);
+ for( i=0 ; i<count ; i++ ) str[i] = string[i];
+ PsImageText8(pDrawable, pGC, x, y, count, str);
+ free(str);
+ }
+}
+
+void
+PsImageGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyphs,
+ CharInfoPtr *pCharInfo,
+ pointer pGlyphBase)
+{
+ /* NOT TO BE IMPLEMENTED */
+}
+
+void
+PsPolyGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyphs,
+ CharInfoPtr *pCharInfo,
+ pointer pGlyphBase)
+{
+ int width, height;
+ PixmapPtr pPixmap;
+ int nbyLine; /* bytes per line of padded pixmap */
+ FontPtr pfont;
+ GCPtr pGCtmp;
+ register int i;
+ register int j;
+ unsigned char *pbits; /* buffer for PutImage */
+ register unsigned char *pb; /* temp pointer into buffer */
+ register CharInfoPtr pci; /* currect char info */
+ register unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ register int nbyGlyphWidth; /* bytes per scanline of glyph */
+ int nbyPadGlyph; /* server padded line of glyph */
+ int w, tmpx;
+ XID gcvals[3];
+
+ pfont = pGC->font;
+ width = FONTMAXBOUNDS(pfont,rightSideBearing) -
+ FONTMINBOUNDS(pfont,leftSideBearing);
+ height = FONTMAXBOUNDS(pfont,ascent) +
+ FONTMAXBOUNDS(pfont,descent);
+
+ if ((width == 0) || (height == 0) )
+ return;
+ {
+ int i;
+ w = 0;
+ for (i=0; i < nGlyphs; i++) w += pCharInfo[i]->metrics.characterWidth;
+ }
+ pGCtmp = GetScratchGC(1, pDrawable->pScreen);
+ if (!pGCtmp)
+ {
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ return;
+ }
+
+ gcvals[0] = GXcopy;
+ gcvals[1] = pGC->fgPixel;
+ gcvals[2] = pGC->bgPixel;
+
+ DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);
+
+
+ nbyLine = BitmapBytePad(width);
+ pbits = (unsigned char *)ALLOCATE_LOCAL(height*nbyLine);
+ if (!pbits){
+ PsDestroyPixmap(pPixmap);
+ return;
+ }
+ tmpx = 0;
+ while(nGlyphs--)
+ {
+ pci = *pCharInfo++;
+ pglyph = FONTGLYPHBITS(pGlyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
+ nbyPadGlyph = BitmapBytePad(gWidth);
+
+ if (nbyGlyphWidth == nbyPadGlyph
+#if GLYPHPADBYTES != 4
+ && (((int) pglyph) & 3) == 0
+#endif
+ )
+ {
+ pb = pglyph;
+ }
+ else
+ {
+ for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
+ for (j = 0; j < nbyGlyphWidth; j++)
+ *pb++ = *pglyph++;
+ pb = pbits;
+ }
+
+ PsPutImageMask((DrawablePtr)pDrawable, pGCtmp,
+ 1, x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent, gWidth, gHeight,
+ 0, XYBitmap, (char *)pb);
+ }
+
+ x += pci->metrics.characterWidth;
+ }
+ DEALLOCATE_LOCAL(pbits);
+ FreeScratchGC(pGCtmp);
+}
diff --git a/hw/xprint/ps/PsWindow.c b/hw/xprint/ps/PsWindow.c
new file mode 100644
index 000000000..d889dda9a
--- /dev/null
+++ b/hw/xprint/ps/PsWindow.c
@@ -0,0 +1,460 @@
+/* $Xorg: PsWindow.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: PsWindow.c
+** *
+** * Contents: Window code for PS driver.
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include "mistruct.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Ps.h"
+
+/*
+ * The following list of strings defines the properties which will be
+ * placed on the screen's root window if the property was defined in
+ * the start-up configuration resource database.
+ */
+#if 0
+static char *propStrings[] = {
+ DT_PRINT_JOB_HEADER,
+ DT_PRINT_JOB_TRAILER,
+ DT_PRINT_JOB_COMMAND,
+ DT_PRINT_JOB_EXEC_COMMAND,
+ DT_PRINT_JOB_EXEC_OPTIONS,
+ DT_PRINT_PAGE_HEADER,
+ DT_PRINT_PAGE_TRAILER,
+ DT_PRINT_PAGE_COMMAND,
+ (char *)NULL
+};
+#endif
+
+/*
+ * PsCreateWindow - watch for the creation of the root window.
+ * When it's created, register the screen with the print extension,
+ * and put the default command/header properties on it.
+ */
+/*ARGSUSED*/
+
+Bool
+PsCreateWindow(WindowPtr pWin)
+{
+ PsWindowPrivPtr pPriv;
+
+#if 0
+ Bool status = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PsScreenPrivPtr pScreenPriv = (PsScreenPrivPtr)
+ pScreen->devPrivates[PsScreenPrivateIndex].ptr;
+ PsWindowPrivPtr pWinPriv = (PsWindowPrivPtr)
+ pWin->devPrivates[PsWindowPrivateIndex].ptr;
+
+ /*
+ * Initialize this window's private struct.
+ */
+ pWinPriv->jobFileName = (char *)NULL;
+ pWinPriv->pJobFile = (FILE *)NULL;
+ pWinPriv->pageFileName = (char *)NULL;
+ pWinPriv->pPageFile = (FILE *)NULL;
+
+ if(pWin->parent == (WindowPtr)NULL) /* root window? */
+ {
+ Atom propName; /* type = XA_STRING */
+ char *propVal;
+ int i;
+ XrmDatabase rmdb = pScreenPriv->resDB;
+
+ /*
+ * Put the defaults spec'd in the config files in properties on this
+ * screen's root window.
+ */
+ for(i = 0; propStrings[i] != (char *)NULL; i++)
+ {
+ if((propVal = _DtPrintGetPrinterResource(pWin, rmdb,
+ propStrings[i])) !=
+ (char *)NULL)
+ {
+ propName = MakeAtom(propStrings[i], strlen(propStrings[i]),
+ TRUE);
+ ChangeWindowProperty(pWin, propName, XA_STRING, 8,
+ PropModeReplace, strlen(propVal),
+ (pointer)propVal, FALSE);
+ xfree(propVal);
+ }
+ }
+ }
+
+ return status;
+#endif
+
+ pPriv = (PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr;
+ pPriv->validContext = 0;
+
+ return TRUE;
+}
+
+
+/*ARGSUSED*/
+Bool PsMapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+/*ARGSUSED*/
+Bool
+PsPositionWindow(
+ WindowPtr pWin,
+ int x,
+ int y)
+{
+ return TRUE;
+}
+
+/*ARGSUSED*/
+Bool
+PsUnmapWindow(WindowPtr pWindow)
+{
+ return TRUE;
+}
+
+/*ARGSUSED*/
+void
+PsCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+}
+
+/*ARGSUSED*/
+Bool
+PsChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask)
+{
+ return TRUE;
+}
+
+
+void
+PsPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what)
+{
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ pointer gcval[7];
+ pointer newValues [COUNT_BITS];
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+ gcmask = 0;
+
+ /*
+ * We don't want to paint a window that has no place to put the
+ * PS output.
+ */
+ if( PsGetContextFromWindow(pWin)==(XpContextPtr)NULL ) return;
+
+ if( what==PW_BACKGROUND )
+ {
+ switch(pWin->backgroundState)
+ {
+ case None: return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)
+ (pWin->parent, pRegion, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND] = (pointer)pWin->background.pixel;
+ newValues[FILLSTYLE] = (pointer)FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE] = (pointer)pWin->background.pixmap;
+ newValues[FILLSTYLE] = (pointer)FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if( pWin->borderIsPixel )
+ {
+ newValues[FOREGROUND] = (pointer)pWin->border.pixel;
+ newValues[FILLSTYLE] = (pointer)FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE] = (pointer)pWin->border.pixmap;
+ newValues[FILLSTYLE] = (pointer)FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(pRegion) *
+ sizeof(xRectangle));
+ if( !prect ) return;
+
+ newValues[FUNCTION] = (pointer)GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = WindowTable[i];
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while( pBgWin->backgroundState==ParentRelative ) pBgWin = pBgWin->parent;
+ }
+
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if( !pGC )
+ {
+ DEALLOCATE_LOCAL(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if( what==PW_BORDER )
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX] = (pointer)(long)pBgWin->drawable.x;
+ newValues[ABSY] = (pointer)(long)pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX] = (pointer)0;
+ newValues[ABSY] = (pointer)0;
+ }
+
+/*
+ * XXX Backing store is turned off for the PS driver
+
+ if( pWin->backStorage )
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+ */
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while( mask )
+ {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch(index)
+ {
+ case GCFunction:
+ if( (pointer)(long)pGC->alu!=newValues[FUNCTION] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[FUNCTION];
+ }
+ break;
+ case GCTileStipXOrigin:
+ if( (pointer)(long)pGC->patOrg.x!=newValues[ABSX] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[ABSX];
+ }
+ break;
+ case GCTileStipYOrigin:
+ if( (pointer)(long)pGC->patOrg.y!=newValues[ABSY] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[ABSY];
+ }
+ break;
+ case GCClipMask:
+ if( (pointer)pGC->clientClipType!=(pointer)CT_NONE )
+ {
+ gcmask |= index;
+ gcval[i++] = (pointer)CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if( (pointer)pGC->subWindowMode!=newValues[SUBWINDOW] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[SUBWINDOW];
+ }
+ break;
+ case GCTile:
+ if( pGC->tileIsPixel || (pointer)pGC->tile.pixmap!=newValues[TILE] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[TILE];
+ }
+ break;
+ case GCFillStyle:
+ if( (pointer)pGC->fillStyle!=newValues[FILLSTYLE] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[FILLSTYLE];
+ }
+ break;
+ case GCForeground:
+ if( (pointer)pGC->fgPixel!=newValues[FOREGROUND] )
+ {
+ gcmask |= index;
+ gcval[i++] = newValues[FOREGROUND];
+ }
+ break;
+ }
+ }
+
+ if( gcmask ) DoChangeGC(pGC, gcmask, (XID *)gcval, 1);
+
+ if( pWin->drawable.serialNumber!=pGC->serialNumber )
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = REGION_NUM_RECTS(pRegion);
+ pbox = REGION_RECTS(pRegion);
+ for( i=numRects ; --i >= 0 ; pbox++,prect++ )
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ DEALLOCATE_LOCAL(prect);
+
+/*
+ * XXX Backing store is turned off for the PS driver
+
+ if( pWin->backStorage )
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+ */
+
+ if( what==PW_BORDER )
+ {
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+}
+
+/*ARGSUSED*/
+Bool
+PsDestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
diff --git a/hw/xprint/ps/psout.c b/hw/xprint/ps/psout.c
new file mode 100644
index 000000000..dccd692ba
--- /dev/null
+++ b/hw/xprint/ps/psout.c
@@ -0,0 +1,1790 @@
+/* $Xorg: psout.c,v 1.9 2001/03/26 15:25:12 coskrey Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: psout.c
+** *
+** * Contents: Code to output PostScript to file
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "os.h"
+#define USE_PSOUT_PRIVATE 1
+#include "Ps.h"
+#include "psout.h"
+#ifdef XP_USE_FREETYPE
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#endif /* XP_USE_FREETYPE */
+/* For VENDOR_STRING and VENDOR_RELEASE */
+#include "site.h"
+
+/*
+ * Standard definitions
+ */
+
+static char *S_StandardDefs = "\
+/d{def}bind def\
+/b{bind}bind d\
+/bd{b d}b d\
+/x{exch}bd\
+/xd{x d}bd\
+/dp{dup}bd\
+/t{true}bd\
+/f{false}bd\
+/p{pop}bd\
+/r{roll}bd\
+/c{copy}bd\
+/i{index}bd\
+/rp{repeat}bd\
+/n{newpath}bd\
+/w{setlinewidth}bd\
+/lc{setlinecap}bd\
+/lj{setlinejoin}bd\
+/sml{setmiterlimit}bd\
+/ds{setdash}bd\
+/ie{ifelse}bd\
+/len{length}bd\
+/m{moveto}bd\
+/rm{rmoveto}bd\
+/l{lineto}bd\
+/rl{rlineto}bd\
+/a{arc}bd\
+/an{arcn}bd\
+/st{stroke}bd\
+/fl{fill}bd\
+/ef{eofill}bd\
+/sp{showpage}bd\
+/cp{closepath}bd\
+/clp{clippath}bd\
+/cl{clip}bd\
+/pb{pathbbox}bd\
+/tr{translate}bd\
+/rt{rotate}bd\
+/dv{div}bd\
+/ml{mul}bd\
+/ad{add}bd\
+/ng{neg}bd\
+/scl{scale}bd\
+/sc{setrgbcolor}bd\
+/g{setgray}bd\
+/gs{gsave}bd\
+/gr{grestore}bd\
+/sv{save}bd\
+/rs{restore}bd\
+/mx{matrix}bd\
+/cm{currentmatrix}bd\
+/sm{setmatrix}bd\
+/ccm{concatmatrix}bd\
+/cc{concat}bd\
+/ff{findfont}bd\
+/mf{makefont}bd\
+/sf{setfont}bd\
+/cft{currentfont}bd\
+/fd{FontDirectory}bd\
+/sh{show}bd\
+/stw{stringwidth}bd\
+/ci{colorimage}bd\
+/ig{image}bd\
+/im{imagemask}bd\
+/cf{currentfile}bd\
+/rh{readhexstring}bd\
+/str{string}bd\
+/al{aload}bd\
+/wh{where}bd\
+/kn{known}bd\
+/stp{stopped}bd\
+/bg{begin}bd\
+/ed{end}bd\
+/fa{forall}bd\
+/pi{putinterval}bd\
+/mk{mark}bd\
+/ctm{cleartomark}bd\
+/df{definefont}bd\
+/cd{currentdict}bd\
+/db{20 dict dp bg}bd\
+/de{ed}bd\
+/languagelevel wh{p languagelevel}{1}ie\
+ 1 eq{/makepattern{p}bd/setpattern{p}bd/setpagedevice{p}bd}if\
+/mp{makepattern}bd\
+/spt{setpattern}bd\
+/spd{setpagedevice}bd\
+"
+#ifdef XP_USE_FREETYPE
+"/trmoveto{currentfont /FontMatrix get transform rm}d"
+#endif /* XP_USE_FREETYPE */
+;
+
+/*
+ * Composite definitions
+ *
+ *
+ * XYr - Return X/Y dpi for device
+ *
+ * XYr <xdpi> <ydpi>
+ *
+ * Cs - Coordinate setup (for origin upper left)
+ *
+ * <orient(0,1,2,3)> Cs
+ *
+ * P - Draw a point
+ *
+ * <x> <y> P
+ *
+ * R - Add rectangle to path
+ *
+ * <x> <y> <w> <h> R
+ *
+ * Ac - Add arc to path
+ *
+ * <x> <y> <w> <h> <ang1> <ang2> Ac
+ *
+ * An - Add arc to path (counterclockwise)
+ *
+ * <x> <y> <w> <h> <ang1> <ang2> An
+ *
+ * Tf - Set font
+ *
+ * <font_name> <size> <iso> Tf
+ *
+ * Tfm - Set font with matrix
+ *
+ * <font_name> <matrix> <iso> Tfm
+ *
+ * T - Draw text
+ *
+ * <text> <x> <y> T
+ *
+ * Tb - Draw text with background color
+ *
+ * <text> <x> <y> <bg_red> <bg_green> <bg_blue> Tb
+ *
+ * Im1 - Image 1 bit monochrome imagemask
+ *
+ * <x> <y> <w> <h> <sw> <sh> Im1
+ *
+ * Im24 - Image 24 bit RGB color
+ *
+ * <x> <y> <w> <h> <sw> <sh> Im24
+ *
+ * Im1t - Image 1 bit monochrome imagemask (in tile)
+ *
+ * <data> <x> <y> <w> <h> <sw> <sh> Im1t
+ *
+ * Im24t - Image 24 bit RGB color (in tile)
+ *
+ * <data> <x> <y> <w> <h> <sw> <sh> Im24t
+ */
+
+static char *S_CompositeDefs = "\
+/XYr{/currentpagedevice wh\
+ {p currentpagedevice dp /HWResolution kn\
+ {/HWResolution get al p}{p 300 300}ie}{300 300}ie}bd\
+/Cs{dp 0 eq{0 pHt tr XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\
+ dp 1 eq{90 rt XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\
+ dp 2 eq{pWd 0 tr XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if\
+ 3 eq{pHt pWd tr 90 rt XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if}bd\
+/P{gs 1 w [] 0 ds 2 c m .1 ad x .1 ad x l st gr}bd\
+/R{4 2 r m 1 i 0 rl 0 x rl ng 0 rl cp}bd\
+/Ac{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r a mx_ sm}bd\
+/An{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r an mx_ sm}bd\
+/ISO{dp len dict bg{1 i/FID ne{d}{p p}ie}fa\
+ /Encoding ISOLatin1Encoding d cd ed df}bd\
+/iN{dp len str cvs dp len x 1 i 3 ad str 2 c c p x p dp 3 -1 r(ISO)pi}bd\
+/Tp{{x dp iN dp fd x kn{x p dp/f_ x d ff}{dp/f_ x d x ff ISO}ie x}\
+ {x dp/f_ x d ff x}ie}bd\
+/Tf{Tp[x 0 0 2 i ng 0 0] dp/fm_ x d mf sf}bd\
+/Tfm{Tp 1 -1 tm1_ scl tm2_ ccm dp/fm_ x d mf sf}bd\
+/T{m sh}bd\
+/Tb{gs sc f_ ff sf cft/FontMatrix get 3 get\
+ cft/FontBBox get dp 1 get x 3 get 2 i ml 3 1 r ml\
+ 0 0 m 4 i stw p 4 i 4 i m fm_ cc\
+ 0 2 i rl dp 0 rl 0 2 i ng rl 0 3 i rl ng 0 rl cp fl p p\
+ gr T}bd\
+/Im1{6 4 r tr scl t [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\
+/Im1rev{6 4 r tr scl f [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\
+/Im24{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{cf str3 rh p} f 3 ci}bd\
+/Im1t{6 4 r tr scl t [3 i 0 0 5 i 0 0]{} im}bd\
+/Im24t{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{} f 3 ci}bd\
+/ck2{/currentpagedevice wh \
+{p dp currentpagedevice dp 3 -1 r kn \
+{x get al p 3 -1 r eq 3 1 r eq and } \
+{p p p p t}ie} \
+{p p p t}ie}bd \
+/ck1{/currentpagedevice wh \
+{p dp currentpagedevice dp 3 -1 r kn \
+{x get eq} {p p p t}ie} \
+{p p t}ie}bd \
+/mtx{scl t [3 i 0 0 5 i 0 0]}bd \
+";
+
+char *pg_orient[] = {"Portrait","Landscape","Reverse Portrait","Reverse Landscape"};
+/*
+ * Setup definitions
+ */
+
+static char *S_SetupDefs = "\
+ /mx_ mx d\
+ /im_ mx d\
+ /tm1_ mx d\
+ /tm2_ mx d\
+ /str3 3 str d\
+ /str1 1 str d\
+";
+
+/*******************************************************************
+ * PRIVATE FUNCTIONS *
+ *******************************************************************/
+
+void
+S_Flush(PsOutPtr self)
+{
+ int len;
+
+ if( self->Buf[0] == '\0' )
+ return;
+
+ len = strlen(self->Buf);
+
+ /* Append a newline char ('\n') if there isn't one there already */
+ if( self->Buf[len-1] != '\n' )
+ {
+ self->Buf[len++] = '\n';
+ self->Buf[len] = '\0';
+ }
+
+ (void)fwrite(self->Buf, len, 1, self->Fp);
+
+ self->Buf[0] = '\0';
+}
+
+static void
+S_Comment(PsOutPtr self, char *comment)
+{
+ S_Flush(self);
+ strcpy(self->Buf, comment);
+ S_Flush(self);
+}
+
+static void
+S_OutDefs(PsOutPtr self, char *defs)
+{
+ int i, k=0;
+ S_Flush(self);
+ memset(self->Buf, 0, sizeof(self->Buf));
+ for( i=0 ; defs[i]!='\0' ;)
+ {
+ if( k>70 && (i==0 || (i && defs[i-1]!='/')) &&
+ (defs[i]==' ' || defs[i]=='/' || defs[i]=='{') )
+ {
+ S_Flush(self);
+ k = 0;
+ memset(self->Buf, 0, sizeof(self->Buf));
+ }
+ if( k && self->Buf[k-1]==' ' && defs[i]==' ' ) { i++; continue; }
+ self->Buf[k] = defs[i];
+ k++; i++;
+ }
+ S_Flush(self);
+}
+
+void
+S_OutNum(PsOutPtr self, float num)
+{
+ int i;
+ char buf[64];
+ int len;
+
+ sprintf(buf, "%.3f", num);
+
+ /* Remove any zeros at the end */
+ for( i=strlen(buf)-1 ; buf[i]=='0' ; i-- ); buf[i+1] = '\0';
+ /* Remove '.' if it is the last character */
+ i = strlen(buf)-1; if( buf[i]=='.' ) buf[i] = '\0';
+
+ len = strlen(self->Buf);
+ if( len > 0 )
+ {
+ self->Buf[len++] = ' ';
+ self->Buf[len] = '\0';
+ }
+ strcpy(&self->Buf[len], buf);
+ if( (len+i)>70 ) S_Flush(self);
+}
+
+static void
+S_OutStr(PsOutPtr self, char *txt, int txtl)
+{
+ int i, k;
+ char buf[1024];
+ for( i=0,k=0 ; i<txtl ; i++ )
+ {
+ if( (txt[i]>=' ' && txt[i]<='~') &&
+ txt[i]!='(' && txt[i]!=')' && txt[i]!='\\' )
+ { buf[k] = txt[i]; k++; continue; }
+ buf[k] = '\\'; k++;
+ sprintf(&buf[k], "%03o", txt[i]&0xFF);
+ /* Skip to the end of the buffer */
+ while( buf[k] != '\0' )
+ k++;
+ }
+ strcat(self->Buf, "(");
+ i = strlen(self->Buf);
+ memcpy(&self->Buf[i], buf, k);
+ self->Buf[i+k] = '\0';
+ strcat(self->Buf, ")");
+ if( strlen(self->Buf)>70 ) S_Flush(self);
+}
+
+/* Same as S_OutStr() but takes |short *| instead of |char *| */
+static void
+S_OutStr16(PsOutPtr self, unsigned short *txt, int txtl)
+{
+ int i, k;
+ char buf[2048];
+ for( i=0,k=0 ; i<txtl ; i++ )
+ {
+ if( (txt[i]>=' ' && txt[i]<='~') &&
+ txt[i]!='(' && txt[i]!=')' && txt[i]!='\\' )
+ { buf[k] = txt[i]; k++; continue; }
+ buf[k] = '\\'; k++;
+ sprintf(&buf[k], "%03o", txt[i]&0xFFFF);
+ /* Skip to the end of the buffer */
+ while( buf[k] != '\0' )
+ k++;
+ }
+ strcat(self->Buf, "(");
+ i = strlen(self->Buf);
+ memcpy(&self->Buf[i], buf, k);
+ self->Buf[i+k] = '\0';
+ strcat(self->Buf, ")");
+ if( strlen(self->Buf)>70 ) S_Flush(self);
+}
+
+void
+S_OutTok(PsOutPtr self, char *tok, int cr)
+{
+ int len = strlen(self->Buf);
+ if( len > 0 )
+ {
+ self->Buf[len++] = ' ';
+ self->Buf[len] = '\0';
+ }
+ strcpy(&self->Buf[len], tok);
+ if( cr ) S_Flush(self);
+}
+
+static void
+S_Color(PsOutPtr self, PsOutColor clr)
+{
+ int ir, ig, ib;
+ ir = PSOUTCOLOR_TO_REDBITS(clr);
+ ig = PSOUTCOLOR_TO_GREENBITS(clr);
+ ib = PSOUTCOLOR_TO_BLUEBITS(clr);
+ if( ir==ig && ig==ib )
+ { S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ir)); S_OutTok(self, "g", 1); }
+ else
+ {
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ir));
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ig));
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ib));
+ S_OutTok(self, "sc", 1);
+ }
+}
+
+static void
+S_SetPageDevice(PsOutPtr self, int orient, int count, int plex, int res,
+ int wd, int ht, int isPage)
+{
+ float fwd = ((float)wd/(float)res)*72.;
+ float fht = ((float)ht/(float)res)*72.;
+
+#define USE_WORKAROUND_COPY_COUNT_BUG 1
+
+#ifdef USE_WORKAROUND_COPY_COUNT_BUG
+ /* Workaround (see http://xprint.mozdev.org/bugs/show_bug.cgi?id=1861 -
+ * 'Need workaround for bug 1378 ...') to avoid that we print n^2 copies
+ * instead of n copies.
+ * The problem is that we use both /NumCopies here but pass the
+ * %copy-count% to the spooler, too.
+ * But we only have to use _one_ way...
+ *
+ * The final fix for bug 1378 (http://xprint.mozdev.org/bugs/show_bug.cgi?id=1378 -
+ * "PS DDX creates n^2 copies of a job instead of n copies") will back this
+ * workaround out and replace it with a better solution.
+ * (see mozilla.org bug 140030
+ * (http://bugzilla.mozilla.org/show_bug.cgi?id=140030 - "Setting number
+ * of copies causes too many copies to print") for the initial report for
+ * this issue...)
+ */
+ count = 1;
+#endif /* USE_WORKAROUND_COPY_COUNT_BUG */
+
+ S_OutTok(self, "/pWd", 0);
+ S_OutNum(self, fwd);
+ S_OutTok(self, "d /pHt", 0);
+ S_OutNum(self, fht);
+ S_OutTok(self, "d", 1);
+
+ /*
+ * if these are page attributes, have PostScript check to see if they
+ * have changed. If not, don't do setpagedevice, since it will cause
+ * a page flush and screw up duplex printing. Having PostScript check
+ * means we don't have to keep track ourselves.
+ */
+ if(isPage) {
+ S_OutNum(self, (float) orient);
+ S_OutTok(self, "/Orientation ck1", 0);
+ S_OutTok(self, "pWd pHt /PageSize ck2 and not {", 1);
+ }
+ S_OutTok(self, "{db", 0);
+
+ S_OutTok(self, "/Orientation", 0);
+ S_OutNum(self, (float) orient);
+ S_OutTok(self, " d ", 0);
+ S_OutTok(self, "/PageSize [pWd pHt] d", 0);
+
+ S_OutTok(self, " de spd", 0);
+ /*
+ * save a flag to show if we failed to set orientation... determined
+ * by both/either Orientation and/or PageSize, use this
+ * later to set/not set orientation using Cs command.
+ */
+ S_OutTok(self,"}stp /orientationFailed x d", 1);
+ /*
+ * if these are page attributes, have PostScript check to see if they
+ * have changed. If not, don't do setpagedevice, since it will cause
+ * a page flush and screw up duplex printing. Having PostScript check
+ * means we don't have to keep track ourselves.
+ */
+ if(isPage)
+ {
+ S_OutTok(self,"}if",1);
+
+ S_OutTok(self, (plex==0)?"f":"t", 0);
+ S_OutTok(self, "/Duplex ck1 ", 0);
+
+ S_OutTok(self, (plex==2)?"t":"f", 0);
+ S_OutTok(self, "/Tumble ck1 and ", 0);
+
+
+ S_OutNum(self, (float)res);
+ S_OutNum(self, (float)res);
+ S_OutTok(self, " /HWResolution ck2 and", 0);
+
+ if( count>1 )
+ {
+ S_OutNum(self, (float)count);
+ S_OutTok(self, " /NumCopies", 0);
+ S_OutTok(self, " ck1 and ", 0);
+ }
+ S_OutTok(self," not {",1);
+ }
+ S_OutTok(self, "{db", 0);
+
+ S_OutTok(self, "/Duplex ", 0);
+ S_OutTok(self, (plex==0)?"f":"t", 0);
+ S_OutTok(self, " d ", 0);
+
+ S_OutTok(self, "/Tumble ", 0);
+ S_OutTok(self, (plex==2)?"t":"f", 0);
+ S_OutTok(self, " d ", 0);
+
+ S_OutTok(self, " /HWResolution [", 0);
+ S_OutNum(self, (float)res);
+ S_OutNum(self, (float)res);
+ S_OutTok(self, "] d ", 0);
+
+ if( count>1 )
+ {
+ S_OutTok(self, " /NumCopies", 0);
+ S_OutNum(self, (float)count);
+ S_OutTok(self, " d ", 0);
+ }
+ S_OutTok(self, " de spd}stp p", 1);
+
+ if(isPage)
+ {
+ S_OutTok(self, "}if", 1);
+ }
+}
+
+/*******************************************************************
+ * PUBLIC FUNCTIONS *
+ *******************************************************************/
+
+FILE *
+PsOut_ChangeFile(PsOutPtr self, FILE *fp)
+{
+ FILE *nfp;
+
+ nfp = self->Fp;
+
+ self->Fp = fp;
+
+ return nfp;
+}
+
+PsOutPtr
+PsOut_BeginFile(FILE *fp, char *title, int orient, int count, int plex, int res,
+ int wd, int ht, Bool raw)
+{
+ int i;
+ char buffer[256+32]; /* enougth space for a title with 256 chars... */
+/*
+ * Get ready to output PostScript header
+ */
+ PsOutPtr psout;
+ psout = (PsOutPtr)xalloc(sizeof(PsOutRec));
+ memset(psout, 0, sizeof(PsOutRec));
+ psout->Fp = fp;
+ psout->isRaw = raw;
+ psout->pagenum = 0;
+
+ if (!raw) {
+/*
+ * Output PostScript header
+ */
+ /* GhostScript will rant about the missing BoundingBox if we use
+ * "%!PS-Adobe-3.0 EPSF-3.0" here... */
+ S_Comment(psout, "%!PS-Adobe-3.0");
+#ifdef XP_USE_FREETYPE
+ {
+ FT_Int ftmajor = 0,
+ ftminor = 0,
+ ftpatch = 0;
+ extern FT_Library ftypeLibrary; /* defined in xc/lib/font/FreeType/ftfuncs.c */
+
+ FT_Library_Version(ftypeLibrary, &ftmajor, &ftminor, &ftpatch);
+ sprintf(buffer,
+ "%%%%Creator: The X Print Server's PostScript DDX "
+ "(%s, release %d, FreeType version %d.%d.%d)",
+ VENDOR_STRING, VENDOR_RELEASE,
+ (int)ftmajor, (int)ftminor, (int)ftpatch);
+ }
+#else
+ sprintf(buffer,
+ "%%%%Creator: The X Print Server's PostScript DDX (%s, release %d)",
+ VENDOR_STRING, VENDOR_RELEASE);
+#endif /* XP_USE_FREETYPE */
+ S_Comment(psout, buffer);
+
+ if (title)
+ {
+ sprintf(buffer, "%%%%Title: %.256s", title);
+ S_Comment(psout, buffer);
+ }
+ S_Comment(psout, "%%EndComments");
+ S_Comment(psout, "%%BeginProlog");
+ S_Comment(psout, "%%BeginProcSet: XServer_PS_Functions");
+ S_OutDefs(psout, S_StandardDefs);
+ S_OutDefs(psout, S_CompositeDefs);
+ S_Comment(psout, "%%EndProcSet");
+ S_Comment(psout, "%%EndProlog");
+ S_Comment(psout, "%%BeginSetup");
+ /* set document level page attributes */
+ S_SetPageDevice(psout, orient, count, plex, res, wd, ht, 0);
+ S_Comment(psout, "%%Pages: atend");
+ S_OutDefs(psout, S_SetupDefs);
+ S_Comment(psout, "%%EndSetup");
+ }
+/*
+ * Initialize the structure
+ */
+ psout->CurColor = PSOUTCOLOR_NOCOLOR;
+ psout->LineWidth = 1;
+ psout->LineCap = PsCButt;
+ psout->LineJoin = PsJMiter;
+ psout->NDashes = 0;
+ psout->Dashes = (int *)0;
+ psout->FontName = (char *)0;
+ psout->FontSize = 0;
+ psout->start_image = 0;
+ for( i=0 ; i<4 ; i++ ) psout->FontMtx[i] = 0.;
+ psout->ImageFormat = 0;
+ return(psout);
+}
+
+void
+PsOut_EndFile(PsOutPtr self, int closeFile)
+{
+ char coms[50];
+
+ if (!self)
+ return;
+
+ if (!self->isRaw) {
+ S_Comment(self,"%%Trailer");
+ sprintf(coms,"%%%%Pages: %d", self->pagenum);
+ S_Comment(self, coms);
+ S_Comment(self, "%%EOF");
+ }
+ if( self->NDashes && self->Dashes ) xfree(self->Dashes);
+ if( self->FontName ) xfree(self->FontName);
+ if( self->Patterns ) xfree(self->Patterns);
+ if( self->Clip.rects ) xfree(self->Clip.rects);
+ if( closeFile ) fclose(self->Fp);
+ xfree(self);
+}
+
+void
+PsOut_BeginPage(PsOutPtr self, int orient, int count, int plex, int res,
+ int wd, int ht)
+{
+ char coms[50];
+
+/*** comment for pagenumbers *****/
+
+ S_Comment(self,"%%PageHeader");
+ self->pagenum++;
+ sprintf(coms,"%%%%Page: %d %d", self->pagenum, self->pagenum);
+ S_Comment(self, coms);
+ sprintf(coms,"%%%%PageOrientation: %s",pg_orient[orient]);
+ S_Comment(self, coms);
+
+/*** end comment *****************/
+
+ /* set page level page attributes */
+ S_SetPageDevice(self, orient, count, plex, res, wd, ht, 1);
+
+ S_OutTok(self, "gs ", 0);
+ /*
+ * check to see if we set orientation already; if it wasn't set,
+ * use Cs to set orientation here.
+ */
+ S_OutNum(self, (float)orient);
+ S_OutTok(self, "orientationFailed { ", 0);
+ S_OutNum(self, (float)orient);
+ S_OutTok(self, " } { 0 }ie Cs 100 sml gs", 1);
+}
+
+void
+PsOut_EndPage(PsOutPtr self)
+{
+ S_OutTok(self, "gr gr sp", 1);
+
+ /* did grestore: mark attributes 'dirty' so they will be re-sent */
+ PsOut_DirtyAttributes(self);
+
+/*** comment for pagenumbers *****/
+
+ S_Comment(self,"%%PageTrailer");
+
+/*** end comment *****************/
+}
+
+void
+PsOut_DirtyAttributes(PsOutPtr self)
+{
+ int i;
+ self->CurColor = PSOUTCOLOR_NOCOLOR;
+ self->LineWidth = -1;
+ self->LineCap = (PsCapEnum)-1;
+ self->LineJoin = (PsJoinEnum)-1;
+ self->NDashes = -1;
+ self->FontSize = -1;
+ for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.;
+ if( self->Dashes ) { xfree(self->Dashes); self->Dashes = (int *)0; }
+ if( self->FontName ) { xfree(self->FontName); self->FontName = (char *)0; }
+}
+
+void
+PsOut_Comment(PsOutPtr self, char *comment)
+{
+ S_Comment(self, comment);
+}
+
+void
+PsOut_Offset(PsOutPtr self, int x, int y)
+{
+ self->XOff = x;
+ self->YOff = y;
+}
+
+void
+PsOut_Clip(PsOutPtr self, int clpTyp, PsClipPtr clpinf)
+{
+ int i, k;
+ int changed = 0;
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InTile ) return;
+ if( self->InFrame ) xo = yo = 0;
+ if( clpTyp!=self->ClipType ) changed = 1;
+ else
+ {
+ if( clpinf->nRects!=self->Clip.nRects ) changed = 1;
+ else
+ {
+ if( clpinf->nOutterClips!=self->Clip.nOutterClips ) changed = 1;
+ else
+ {
+ for( i=0 ; i<clpinf->nOutterClips ; i++ )
+ {
+ if( memcmp(&clpinf->outterClips[i], &self->Clip.outterClips[i],
+ sizeof(PsRectRec))!=0 ) break;
+ }
+ if( i<clpinf->nOutterClips ) changed = 1;
+ else
+ {
+ for( i=0 ; i<clpinf->nRects ; i++ )
+ {
+ if( memcmp(&clpinf->rects[i], &self->Clip.rects[i],
+ sizeof(PsRectRec))!=0 ) { changed = 1; break; }
+ }
+ }
+ }
+ }
+ if( clpinf->nElms!=self->Clip.nElms ) changed = 1;
+ else
+ {
+ for( i=0 ; i<clpinf->nElms ; i++ )
+ {
+ if( clpinf->elms[i].type!=PSOUT_POINTS )
+ {
+ if( memcmp(&clpinf->elms[i], &self->Clip.elms[i],
+ sizeof(PsElmRec))!=0 ) { changed = 1; break; }
+ }
+ else
+ {
+ if( clpinf->elms[i].type!=self->Clip.elms[i].type ||
+ clpinf->elms[i].nPoints!=self->Clip.elms[i].nPoints )
+ { changed = 1; break; }
+ else
+ {
+ for( k=0 ; k<clpinf->elms[i].nPoints ; k++ )
+ {
+ if( memcmp(&clpinf->elms[i].c.points[k],
+ &self->Clip.elms[i].c.points[k], sizeof(PsPointRec)) )
+ { changed = 1; break; }
+ }
+ if( changed ) break;
+ }
+ }
+ }
+ }
+ }
+
+ if( self->Clip.rects ) xfree(self->Clip.rects);
+ if( self->Clip.outterClips ) xfree(self->Clip.outterClips);
+ if( self->Clip.elms )
+ PsDestroyFillElementList(self->Clip.nElms, self->Clip.elms);
+ self->ClipType = clpTyp;
+ self->Clip.nRects = clpinf->nRects;
+ self->Clip.nElms = clpinf->nElms;
+ self->Clip.nOutterClips = clpinf->nOutterClips;
+ if( clpinf->nRects )
+ {
+ self->Clip.rects = (PsRectPtr)xalloc(clpinf->nRects*sizeof(PsRectRec));
+ memcpy(self->Clip.rects, clpinf->rects, clpinf->nRects*sizeof(PsRectRec));
+ }
+ else self->Clip.rects = 0;
+ if( clpinf->nOutterClips )
+ {
+ self->Clip.outterClips = (PsRectPtr)xalloc(clpinf->nOutterClips*
+ sizeof(PsRectRec));
+ memcpy(self->Clip.outterClips, clpinf->outterClips,
+ clpinf->nOutterClips*sizeof(PsRectRec));
+ }
+ else self->Clip.outterClips = 0;
+ if( clpinf->nElms )
+ self->Clip.elms = PsCloneFillElementList(clpinf->nElms, clpinf->elms);
+ else self->Clip.elms = 0;
+
+ PsOut_DirtyAttributes(self);
+ S_OutTok(self, "gr gs", 1);
+ if( self->Clip.nOutterClips )
+ {
+ for( i=0 ; i<self->Clip.nOutterClips ; i++ )
+ {
+ S_OutNum(self, (float)(self->Clip.outterClips[i].x));
+ S_OutNum(self, (float)(self->Clip.outterClips[i].y));
+ S_OutNum(self, (float)self->Clip.outterClips[i].w);
+ S_OutNum(self, (float)self->Clip.outterClips[i].h);
+ S_OutTok(self, "R", 1);
+ }
+ S_OutTok(self, "cl n", 1);
+ }
+ if( self->Clip.nRects )
+ {
+ for( i=0 ; i<self->Clip.nRects ; i++ )
+ {
+ S_OutNum(self, (float)(self->Clip.rects[i].x+xo));
+ S_OutNum(self, (float)(self->Clip.rects[i].y+yo));
+ S_OutNum(self, (float)self->Clip.rects[i].w);
+ S_OutNum(self, (float)self->Clip.rects[i].h);
+ S_OutTok(self, "R", 1);
+ }
+ S_OutTok(self, "cl n", 1);
+ }
+ if( self->Clip.nElms )
+ {
+ PsElmPtr elm = self->Clip.elms;
+ for( i=0 ; i<self->Clip.nElms ; i++,elm++ )
+ {
+ switch(elm->type)
+ {
+ case PSOUT_POINTS:
+ for( k=0 ; k<elm->nPoints ; k++ )
+ {
+ S_OutNum(self, (float)elm->c.points[k].x+xo);
+ S_OutNum(self, (float)elm->c.points[k].y+yo);
+ if( k==0 ) S_OutTok(self, "m", 0);
+ else S_OutTok(self, "l", 0);
+ }
+ S_OutTok(self, "cp", 1);
+ break;
+ case PSOUT_RECT:
+ S_OutNum(self, (float)elm->c.rect.x+xo);
+ S_OutNum(self, (float)elm->c.rect.y+yo);
+ S_OutNum(self, (float)elm->c.rect.w);
+ S_OutNum(self, (float)elm->c.rect.h);
+ S_OutTok(self, "R", 1);
+ break;
+ case PSOUT_ARC:
+ if( elm->c.arc.style==PsPieSlice )
+ {
+ S_OutNum(self, (float)elm->c.arc.x+xo+(float)elm->c.arc.w/2.);
+ S_OutNum(self, (float)elm->c.arc.y+yo+(float)elm->c.arc.h/2.);
+ S_OutTok(self, "m", 0);
+ }
+ S_OutNum(self, (float)elm->c.arc.x+xo+(float)elm->c.arc.w/2.);
+ S_OutNum(self, (float)elm->c.arc.y+yo+(float)elm->c.arc.h/2.);
+ S_OutNum(self, (float)elm->c.arc.w);
+ S_OutNum(self, (float)elm->c.arc.h);
+ S_OutNum(self, (float)elm->c.arc.a1/64.);
+ S_OutNum(self, (float)elm->c.arc.a1/64.+(float)elm->c.arc.a2/64.);
+ if( elm->c.arc.a2<0 ) S_OutTok(self, "An cp", 1);
+ else S_OutTok(self, "Ac cp", 1);
+ break;
+ }
+ }
+ S_OutTok(self, "cl n", 1);
+ }
+}
+
+void
+PsOut_Color(PsOutPtr self, PsOutColor clr)
+{
+ if( clr==self->CurColor || self->InTile>=PsStip ) return;
+ self->CurColor = clr;
+ S_Color(self, clr);
+}
+
+void
+PsOut_FillRule(PsOutPtr self, PsRuleEnum rule)
+{
+ self->FillRule = rule;
+}
+
+void
+PsOut_LineAttrs(PsOutPtr self, int wd, PsCapEnum cap, PsJoinEnum join,
+ int nDsh, int *dsh, int dshOff, PsOutColor bclr)
+{
+ int i;
+ int same = 1;
+
+ if( wd!=self->LineWidth && wd>=0 )
+ {
+ if( wd==0 ) wd = 1;
+ self->LineWidth = wd;
+ S_OutNum(self, (float)wd); S_OutTok(self, "w", 1);
+ }
+ if( cap!=self->LineCap )
+ {
+ self->LineCap = cap;
+ S_OutNum(self, (float)cap); S_OutTok(self, "lc", 1);
+ }
+ if( join!=self->LineJoin )
+ {
+ self->LineJoin = join;
+ S_OutNum(self, (float)join); S_OutTok(self, "lj", 1);
+ }
+ if( nDsh!=self->NDashes ) same = 0;
+ else if( dshOff!=self->DashOffset ) same = 0;
+ else if( nDsh )
+ {
+ for( i=0 ; i<nDsh ; i++ )
+ { if( dsh[i]!=self->Dashes[i] ) break; }
+ if( i<nDsh ) same = 0;
+ }
+ if( !same )
+ {
+ if( self->NDashes && self->Dashes )
+ { xfree(self->Dashes); self->Dashes = (int *)0; }
+ self->NDashes = nDsh;
+ self->DashOffset = dshOff;
+ if( nDsh ) self->Dashes = (int *)xalloc(sizeof(int)*nDsh);
+ S_OutTok(self, "[", 0);
+ for( i=0 ; i<nDsh ; i++ )
+ {
+ self->Dashes[i] = dsh[i];
+ S_OutNum(self, (float)dsh[i]);
+ }
+ S_OutTok(self, "]", 0);
+ S_OutNum(self, (float)dshOff);
+ S_OutTok(self, "ds", 1);
+ }
+
+ if( nDsh )
+ self->LineBClr = bclr;
+ else
+ bclr = PSOUTCOLOR_NOCOLOR;
+}
+
+void
+PsOut_TextAttrs(PsOutPtr self, char *fnam, int siz, int iso)
+{
+ int i;
+ char buf[256];
+ if( self->FontName && strcmp(fnam, self->FontName)==0 &&
+ siz==self->FontSize ) return;
+ if( self->FontName ) xfree(self->FontName);
+ self->FontName = (char *)xalloc(strlen(fnam)+1);
+ strcpy(self->FontName, fnam);
+ self->FontSize = siz;
+ for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.;
+ strcpy(buf, "/"); strcat(buf, fnam);
+ S_OutTok(self, buf, 0);
+ S_OutNum(self, (float)siz);
+ if( iso ) S_OutTok(self, "t", 0);
+ else S_OutTok(self, "f", 0);
+ S_OutTok(self, "Tf", 1);
+}
+
+void
+PsOut_TextAttrsMtx(PsOutPtr self, char *fnam, float *mtx, int iso)
+{
+ int i;
+ char buf[256];
+ if( self->FontName && strcmp(fnam, self->FontName)==0 &&
+ mtx[0]==self->FontMtx[0] && mtx[1]==self->FontMtx[1] &&
+ mtx[2]==self->FontMtx[2] && mtx[3]==self->FontMtx[3] ) return;
+ if( self->FontName ) xfree(self->FontName);
+ self->FontName = (char *)xalloc(strlen(fnam)+1);
+ strcpy(self->FontName, fnam);
+ for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = mtx[i];
+ self->FontSize = -1;
+ strcpy(buf, "/"); strcat(buf, fnam); strcat(buf, " [");
+ S_OutTok(self, buf, 0);
+ for( i=0 ; i<4 ; i++ ) S_OutNum(self, mtx[i]);
+ S_OutTok(self, "0 0]", 0);
+ if( iso ) S_OutTok(self, "t", 0);
+ else S_OutTok(self, "f", 0);
+ S_OutTok(self, "Tfm", 1);
+}
+
+void
+PsOut_Polygon(PsOutPtr self, int nPts, PsPointPtr pts)
+{
+ int i;
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ if( nPts<=2 ) return;
+ for( i=0 ; i<nPts ; i++ )
+ {
+ S_OutNum(self, (float)(pts[i].x+xo));
+ S_OutNum(self, (float)(pts[i].y+yo));
+ if( i==0 ) S_OutTok(self, "m", 0);
+ else S_OutTok(self, "l", 0);
+ }
+ if( self->FillRule==PsEvenOdd ) S_OutTok(self, "cp ef", 1);
+ else S_OutTok(self, "cp fl", 1);
+}
+
+void
+PsOut_FillRect(PsOutPtr self, int x, int y, int w, int h)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutTok(self, "R fl", 1);
+}
+
+void
+PsOut_FillArc(PsOutPtr self, int x, int y, int w, int h,
+ float ang1, float ang2, PsArcEnum style)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ if( style==PsPieSlice )
+ {
+ S_OutNum(self, (float)x+(float)w/2.);
+ S_OutNum(self, (float)y+(float)h/2.);
+ S_OutTok(self, "m", 0);
+ }
+ S_OutNum(self, (float)x+(float)w/2.);
+ S_OutNum(self, (float)y+(float)h/2.);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutNum(self, ang1);
+ S_OutNum(self, ang1+ang2);
+ if( ang2<0 ) S_OutTok(self, "An cp fl", 1);
+ else S_OutTok(self, "Ac cp fl", 1);
+}
+
+void
+PsOut_Lines(PsOutPtr self, int nPts, PsPointPtr pts)
+{
+ int i;
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ if( nPts<1 ) return;
+ for( i=0 ; i<nPts ; i++ )
+ {
+ S_OutNum(self, (float)(pts[i].x+xo));
+ S_OutNum(self, (float)(pts[i].y+yo));
+ if( i==0 ) S_OutTok(self, "m", 0);
+ else S_OutTok(self, "l", 0);
+ }
+ if( self->LineBClr != PSOUTCOLOR_NOCOLOR )
+ {
+ S_OutTok(self, "gs", 0);
+ S_Color(self, self->LineBClr);
+ S_OutTok(self, "[] 0 ds st gr", 0);
+ }
+ S_OutTok(self, "st", 1);
+}
+
+void
+PsOut_Points(PsOutPtr self, int nPts, PsPointPtr pts)
+{
+ int i;
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ if( nPts<1 ) return;
+ for( i=0 ; i<nPts ; i++ )
+ {
+ S_OutNum(self, (float)(pts[i].x+xo));
+ S_OutNum(self, (float)(pts[i].y+yo));
+ S_OutTok(self, "P", 1);
+ }
+}
+
+void
+PsOut_DrawRect(PsOutPtr self, int x, int y, int w, int h)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutTok(self, "R", 0);
+ if( self->LineBClr != PSOUTCOLOR_NOCOLOR )
+ {
+ S_OutTok(self, "gs", 0);
+ S_Color(self, self->LineBClr);
+ S_OutTok(self, "[] 0 ds st gr", 0);
+ }
+ S_OutTok(self, "st", 1);
+}
+
+void
+PsOut_DrawArc(PsOutPtr self, int x, int y, int w, int h,
+ float ang1, float ang2)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ S_OutNum(self, (float)x+(float)w/2.);
+ S_OutNum(self, (float)y+(float)h/2.);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutNum(self, ang1);
+ S_OutNum(self, ang1+ang2);
+ if( ang2<0 ) S_OutTok(self, "An", 0);
+ else S_OutTok(self, "Ac", 0);
+ if( self->LineBClr != PSOUTCOLOR_NOCOLOR )
+ {
+ S_OutTok(self, "gs", 0);
+ S_Color(self, self->LineBClr);
+ S_OutTok(self, "[] 0 ds st gr", 0);
+ }
+ S_OutTok(self, "st", 1);
+}
+
+void
+PsOut_Text(PsOutPtr self, int x, int y, char *text, int textl, PsOutColor bclr)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ S_OutStr(self, text, textl);
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ if( bclr == PSOUTCOLOR_NOCOLOR )
+ S_OutTok(self, "T", 1);
+ else
+ {
+ int ir = PSOUTCOLOR_TO_REDBITS(bclr);
+ int ig = PSOUTCOLOR_TO_GREENBITS(bclr);
+ int ib = PSOUTCOLOR_TO_BLUEBITS(bclr);
+
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ir));
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ig));
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ib));
+ S_OutTok(self, "Tb", 1);
+ }
+}
+
+void
+PsOut_Text16(PsOutPtr self, int x, int y, unsigned short *text, int textl, PsOutColor bclr)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ S_OutStr16(self, text, textl);
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ if( bclr == PSOUTCOLOR_NOCOLOR )
+ S_OutTok(self, "T", 1);
+ else
+ {
+ int ir = PSOUTCOLOR_TO_REDBITS(bclr);
+ int ig = PSOUTCOLOR_TO_GREENBITS(bclr);
+ int ib = PSOUTCOLOR_TO_BLUEBITS(bclr);
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ir));
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ig));
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ib));
+ S_OutTok(self, "Tb", 1);
+ }
+}
+
+#ifdef BM_CACHE
+void /* new */
+PsOut_ImageCache(PsOutPtr self, int x, int y, long cache_id, PsOutColor bclr, PsOutColor fclr)
+{
+ char cacheID[10];
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ sprintf(cacheID, "c%di", cache_id);
+
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+
+ if( fclr==PSOUTCOLOR_WHITE )
+ {
+ int ir = PSOUTCOLOR_TO_REDBITS(bclr);
+ int ig = PSOUTCOLOR_TO_GREENBITS(bclr);
+ int ib = PSOUTCOLOR_TO_BLUEBITS(bclr);
+
+ if( ir==ig && ig==ib )
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ir));
+ else
+ S_OutNum(self, (float)0);
+ self->RevImage = 1;
+ }
+ else
+ {
+ int ir = PSOUTCOLOR_TO_REDBITS(fclr);
+ int ig = PSOUTCOLOR_TO_GREENBITS(fclr);
+ int ib = PSOUTCOLOR_TO_BLUEBITS(fclr);
+
+ if( ir==ig && ig==ib )
+ S_OutNum(self, PSOUTCOLOR_BITS_TO_PSFLOAT(ir));
+ else
+ S_OutNum(self, (float)0);
+ }
+
+ S_OutTok(self, cacheID, 1);
+} /* new */
+
+void /* new */
+PsOut_BeginImageCache(PsOutPtr self, long cache_id)
+{
+ char cacheID[10];
+
+ sprintf(cacheID, "/c%di {", cache_id);
+
+ S_OutTok(self, cacheID, 0);
+} /* new */
+
+void /* new */
+PsOut_EndImageCache(PsOutPtr self)
+{
+ S_OutTok(self, "}bd", 1);
+} /* new */
+#endif
+
+void
+PsOut_BeginImage(PsOutPtr self, PsOutColor bclr, PsOutColor fclr, int x, int y,
+ int w, int h, int sw, int sh, int format)
+{
+ PsOutColor savClr = self->CurColor;
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ if( self->InTile )
+ {
+ if( self->InTile>=PsStip && format!=1 ) { self->ImgSkip = 1; return; }
+ self->ImgBClr = bclr; self->ImgFClr = fclr;
+ self->ImgX = x; self->ImgY = y;
+ self->ImgW = w; self->ImgH = h;
+ self->SclW = sw; self->SclH = sh;
+ S_OutTok(self, "<", 0);
+ self->ImageFormat = format;
+ self->RevImage = 0;
+ if( self->InTile==PsTile && format==1 && fclr==PSOUTCOLOR_WHITE )
+ self->RevImage = 1;
+ return;
+ }
+
+ self->RevImage = 0;
+ if( format==1 )
+ {
+ S_OutTok(self, "gs", 0);
+ if( fclr==PSOUTCOLOR_WHITE )
+ {
+ PsOut_Color(self, fclr);
+ PsOut_FillRect(self, x, y, sw, sh);
+ PsOut_Color(self, bclr);
+ self->RevImage = 1;
+ }
+ else
+ {
+ PsOut_Color(self, bclr);
+ PsOut_FillRect(self, x, y, sw, sh);
+ PsOut_Color(self, fclr);
+ }
+ }
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutNum(self, (float)sw);
+ S_OutNum(self, (float)sh);
+ if( format==1 ) {
+ if(self->RevImage)
+ S_OutTok(self, "Im1rev", 1);
+ else
+ S_OutTok(self, "Im1", 1);
+ }
+ else S_OutTok(self, "Im24", 1);
+ self->ImageFormat = format;
+ self->CurColor = savClr;
+}
+
+void
+PsOut_BeginImageIM(PsOutPtr self, PsOutColor bclr, PsOutColor fclr, int x, int y,
+ int w, int h, int sw, int sh, int format)
+{
+ PsOutColor savClr = self->CurColor;
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+ if( self->InTile )
+ {
+ if( self->InTile>=PsStip && format!=1 ) { self->ImgSkip = 1; return; }
+ self->ImgBClr = bclr; self->ImgFClr = fclr;
+ self->ImgX = x; self->ImgY = y;
+ self->ImgW = w; self->ImgH = h;
+ self->SclW = sw; self->SclH = sh;
+ S_OutTok(self, "<", 0);
+ self->ImageFormat = format;
+ self->RevImage = 0;
+ if( self->InTile==PsTile && format==1 && fclr==PSOUTCOLOR_WHITE )
+ self->RevImage = 1;
+ return;
+ }
+
+ self->RevImage = 0;
+ if( format==1 )
+ {
+ S_OutTok(self, "gs", 0);
+#ifdef BM_CACHE
+ S_OutTok(self, "g", 1);
+#else
+ if( fclr==PSOUTCOLOR_WHITE )
+ {
+ PsOut_Color(self, bclr);
+ self->RevImage = 1;
+ }
+ else
+ {
+ PsOut_Color(self, fclr);
+ }
+#endif
+ }
+
+#ifdef BM_CACHE
+ S_OutTok(self, "tr", 0); /* new */
+#else
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+#endif
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutNum(self, (float)sw);
+ S_OutNum(self, (float)sh);
+#ifdef BM_CACHE
+ S_OutTok(self, "mtx", 1); /* new */
+ S_OutTok(self, "<", 0); /* new */
+ self->start_image = 1;
+#else
+ if( format==1 ){
+ if(self->RevImage)
+ S_OutTok(self, "Im1rev", 1);
+ else
+ S_OutTok(self, "Im1", 1);
+ }
+ else S_OutTok(self, "Im24", 1);
+#endif
+ self->ImageFormat = format;
+ self->CurColor = savClr;
+}
+
+void
+PsOut_EndImage(PsOutPtr self)
+{
+ if( self->ImgSkip ) { self->ImgSkip = 0; return; }
+ if( self->InTile )
+ {
+ S_OutTok(self, ">", 1);
+ if( self->ImageFormat==1 && self->InTile==PsTile )
+ {
+ if( self->ImgFClr==PSOUTCOLOR_WHITE )
+ {
+ PsOut_Color(self, self->ImgFClr);
+ PsOut_FillRect(self, self->ImgX, self->ImgY, self->SclW, self->SclH);
+ PsOut_Color(self, self->ImgBClr);
+ }
+ else
+ {
+ PsOut_Color(self, self->ImgBClr);
+ PsOut_FillRect(self, self->ImgX, self->ImgY, self->SclW, self->SclH);
+ PsOut_Color(self, self->ImgFClr);
+ }
+ }
+ S_OutNum(self, (float)self->ImgX);
+ S_OutNum(self, (float)self->ImgY);
+ S_OutNum(self, (float)self->ImgW);
+ S_OutNum(self, (float)self->ImgH);
+ S_OutNum(self, (float)self->SclW);
+ S_OutNum(self, (float)self->SclH);
+ if( self->ImageFormat==1 ) S_OutTok(self, "Im1t", 1);
+ else S_OutTok(self, "Im24t", 1);
+ self->ImageFormat = 0;
+ self->RevImage = 0;
+ return;
+ }
+ /*
+ * Bug 4639307: Move flush before "> im" to get all of bitmap into ps file.
+ */
+ S_Flush(self);
+#ifdef BM_CACHE
+ if(self->start_image)
+ S_OutTok(self, "> im", 1); /* new */
+#endif
+ self->ImageFormat = 0;
+ self->RevImage = 0;
+#ifdef BM_CACHE
+ if(self->start_image)
+ {
+ self->start_image = 0;
+ S_OutTok(self, "gr", 0);
+ }
+ else
+ S_OutTok(self, "gr", 1);
+#else
+ S_OutTok(self, "gr", 1);
+#endif
+}
+
+void
+PsOut_OutImageBytes(PsOutPtr self, int nBytes, char *bytes)
+{
+ int i;
+ int b;
+ int len;
+ const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ if( (!self->ImageFormat) || self->ImgSkip ) return;
+
+ len = strlen(self->Buf);
+
+ for( i=0 ; i<nBytes ; i++ )
+ {
+ if( self->RevImage ) b = (int)((bytes[i]^0xFF)&0xFF);
+ else b = (int)(bytes[i]&0xFF);
+
+ self->Buf[len++] = hex[(b&0xF0) >> 4];
+ self->Buf[len++] = hex[(b&0x0F)];
+ self->Buf[len] = '\0';
+
+ if( len>70 )
+ {
+ S_Flush(self);
+ len = 0;
+ }
+ }
+}
+
+void
+PsOut_BeginFrame(PsOutPtr self, int xoff, int yoff, int x, int y,
+ int w, int h)
+{
+ int xo = self->XOff;
+ int yo = self->YOff;
+
+ if( self->InFrame ) xo = yo = 0;
+ S_OutTok(self, "gs", 0);
+ S_OutNum(self, (float)(x+xo));
+ S_OutNum(self, (float)(y+yo));
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutTok(self, "R cl n", 0);
+ xoff += xo; yoff += yo;
+ if( xoff || yoff )
+ {
+ S_OutNum(self, (float)xoff);
+ S_OutNum(self, (float)yoff);
+ S_OutTok(self, "tr", 0);
+ }
+ S_OutTok(self, "gs", 1);
+ self->InFrame += 1;
+}
+
+void
+PsOut_EndFrame(PsOutPtr self)
+{
+ self->InFrame -= 1;
+ if( self->InFrame<0 ) self->InFrame = 0;
+ S_OutTok(self, "gr gr", 1);
+ PsOut_DirtyAttributes(self);
+}
+
+int
+PsOut_BeginPattern(PsOutPtr self, void *tag, int w, int h, PsFillEnum type,
+ PsOutColor bclr, PsOutColor fclr)
+{
+ int i;
+ char key[64];
+
+ for( i=0 ; i<self->NPatterns ; i++ )
+ { if( self->Patterns[i].tag==tag && self->Patterns[i].type==type ) break; }
+ if( i<self->NPatterns ) return(1);
+ if( (self->NPatterns+1)>self->MxPatterns )
+ {
+ if( self->Patterns )
+ {
+ self->MxPatterns *= 2;
+ self->Patterns =
+ (PsPatPtr)xrealloc(self->Patterns, sizeof(PsPatRec)*self->MxPatterns);
+ }
+ else
+ {
+ self->MxPatterns = 64;
+ self->Patterns = (PsPatPtr)xalloc(sizeof(PsPatRec)*self->MxPatterns);
+ }
+ }
+ self->Patterns[self->NPatterns].tag = tag;
+ self->Patterns[self->NPatterns].type = type;
+ sprintf(key, "/ %d", (int)tag);
+ switch(type) {
+ case PsTile: key[1] = 't'; break;
+ case PsStip: key[1] = 's'; break;
+ case PsOpStip: key[1] = 'o'; break;
+ default: break; }
+ S_OutTok(self, key, 0);
+ S_OutTok(self, "db/PatternType 1 d/PaintType 1 d", 0);
+ S_OutTok(self, "/TilingType 1 d/BBox[0 0", 0);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutTok(self, "]d/XStep", 0);
+ S_OutNum(self, (float)w);
+ S_OutTok(self, "d/YStep", 0);
+ S_OutNum(self, (float)h);
+ S_OutTok(self, "d/PaintProc{bg sv", 1);
+ if( type==PsOpStip )
+ {
+ S_Color(self, bclr);
+ S_OutTok(self, "0 0", 0);
+ S_OutNum(self, (float)w);
+ S_OutNum(self, (float)h);
+ S_OutTok(self, "R fl", 1);
+ }
+ if( type!=PsTile ) S_Color(self, fclr);
+ self->NPatterns += 1;
+ self->InTile = type;
+ return(0);
+}
+
+void
+PsOut_EndPattern(PsOutPtr self)
+{
+ self->InTile = PsSolid;
+ S_OutTok(self, "rs ed}d de im_ mp d", 1);
+}
+
+void
+PsOut_SetPattern(PsOutPtr self, void *tag, PsFillEnum type)
+{
+ int i;
+ char key[64];
+
+ for( i=0 ; i<self->NPatterns ; i++ )
+ { if( tag==self->Patterns[i].tag && type==self->Patterns[i].type ) break; }
+ if( i>=self->NPatterns ) return;
+ sprintf(key, " %d", (int)tag);
+ switch(type) {
+ case PsTile: key[0] = 't'; break;
+ case PsStip: key[0] = 's'; break;
+ case PsOpStip: key[0] = 'o'; break;
+ default: break; }
+ S_OutTok(self, key, 0);
+ S_OutTok(self, "spt", 1);
+ self->CurColor = PSOUTCOLOR_NOCOLOR;
+}
+
+void
+PsOut_RawData(PsOutPtr self, char *data, int len)
+{
+ S_Flush(self);
+ if (!ferror(self->Fp)) {
+ (void) fwrite(data, 1, len, self->Fp);
+ }
+}
+
+typedef enum PsDownfontFontType_
+{
+ PsDFT_Type1PFA=0,
+ PsDFT_Type1PFB,
+ PsDFT_TrueType /* not implemented yet */
+} PsDownfontFontType;
+
+/* Download a PS Type1 font */
+int
+PsOut_DownloadType1(PsOutPtr self, const char *auditmsg, const char *name, const char *fname)
+{
+ int stt;
+ char buf[256];
+ FILE *fp;
+ PsDownfontFontType type;
+
+ fp = fopen(fname, "r");
+ if( !fp )
+ return 0;
+
+#ifdef DEBUG_gisburn
+ /* This should be log-able! */
+ fprintf(stderr, "PsOut_DownloadType1: %s: Downloading '%s' from '%s'\n", auditmsg, name, fname);
+#endif /* DEBUG_gisburn */
+
+ fread(buf, 32, 1, fp);
+ fseek(fp, (long)0, 0);
+
+ /* Is this a Adobe PostScript Type 1 binary font (PFB) ? */
+ if( (buf[0]&0xFF)==0x80 && (buf[1]&0xFF)==0x01 )
+ {
+ type = PsDFT_Type1PFB;
+ }
+ /* Is this a Adobe PostScript ASCII font (PFA) ? */
+ else if (!strncmp(buf, "%!PS-AdobeFont", 14))
+ {
+ type = PsDFT_Type1PFA;
+ }
+ else
+ {
+ /* This should be log-able! */
+ fprintf(stderr, "PsOut_DownloadType1: Unknown font type for '%s'\n", fname);
+ return 0;
+ }
+
+ S_Flush(self);
+ sprintf(buf, "%%%%BeginFont: %s", name);
+ S_Comment(self, buf);
+
+ if( type == PsDFT_Type1PFB )
+ {
+ char *buf,
+ *pt;
+ int len,
+ ch,
+ stype;
+
+ ch = fgetc(fp);
+ /* Strip out the binary headers and de-binary it */
+ while( (ch&0xFF) == 0x80 )
+ {
+ stype = fgetc(fp);
+ if( stype==3 ) /* eof mark */
+ break;
+ len = fgetc(fp);
+ len |= fgetc(fp)<<8;
+ len |= fgetc(fp)<<16;
+ len |= fgetc(fp)<<24;
+ buf = (char *)xalloc(len+1);
+ if( stype==1 )
+ {
+ /* Process ASCII section */
+ len = fread(buf, 1, len, fp);
+ /* convert any lone CRs (ie Mac eol) to LFs */
+ for( pt = buf ; (pt = memchr(pt, '\r', len-(pt-buf))) != NULL ; pt++ )
+ {
+ if ( pt[1]!='\n' )
+ *pt = '\n';
+ }
+ fwrite(buf, 1, len, self->Fp);
+ }
+ else if( stype==2 )
+ {
+ int i;
+
+ /* Process binary section */
+ len = fread(buf, 1, len, fp);
+ for( i=0 ; i<len ; i++ )
+ {
+ ch = buf[i];
+ if( ((ch>>4)&0xf) <= 9 )
+ fputc('0'+((ch>>4)&0xf), self->Fp);
+ else
+ fputc('A'-10+((ch>>4)&0xf), self->Fp);
+
+ if( (ch&0xf) <= 9 )
+ fputc('0'+(ch&0xf), self->Fp);
+ else
+ fputc('A'-10+(ch&0xf), self->Fp);
+
+ if( (i&0x1f)==0x1f )
+ fputc('\n', self->Fp);
+ }
+ }
+ xfree(buf);
+
+ /* Next block... */
+ ch = fgetc(fp);
+ }
+ }
+ /* Is this a Adobe PostScript ASCII font (PFA) ? */
+ else if (type == PsDFT_Type1PFA)
+ {
+ for(;;)
+ {
+ stt = fread(buf, 1, 256, fp);
+ if( stt<=0 ) break;
+ if (!ferror(self->Fp)) {
+ (void) fwrite(buf, 1, stt, self->Fp);
+ }
+ if( stt<256 )
+ break;
+ }
+ }
+ fclose(fp);
+ S_Flush(self);
+ S_Comment(self, "%%EndFont");
+
+ /* Success... */
+ return 1;
+}
+
+
+
+
+
+
diff --git a/hw/xprint/ps/psout.h b/hw/xprint/ps/psout.h
new file mode 100644
index 000000000..d998e2a09
--- /dev/null
+++ b/hw/xprint/ps/psout.h
@@ -0,0 +1,336 @@
+/* $Xorg: psout.h,v 1.6 2001/02/09 02:04:37 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/*
+ * (c) Copyright 1996 Hewlett-Packard Company
+ * (c) Copyright 1996 International Business Machines Corp.
+ * (c) Copyright 1996 Sun Microsystems, Inc.
+ * (c) Copyright 1996 Novell, Inc.
+ * (c) Copyright 1996 Digital Equipment Corp.
+ * (c) Copyright 1996 Fujitsu Limited
+ * (c) Copyright 1996 Hitachi, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the copyright holders
+ * shall not be used in advertising or otherwise to promote the sale, use
+ * or other dealings in this Software without prior written authorization
+ * from said copyright holders.
+ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: psout.h
+** *
+** * Contents: Include file for psout.c
+** *
+** * Created By: Roger Helmendach (Liberty Systems)
+** *
+** * Copyright: Copyright 1996 The Open Group, Inc.
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _psout_
+#define _psout_
+
+#include <stdio.h>
+
+typedef enum PsCapEnum_ { PsCButt=0, PsCRound, PsCSquare } PsCapEnum;
+typedef enum PsJoinEnum_ { PsJMiter=0, PsJRound, PsJBevel } PsJoinEnum;
+typedef enum PsArcEnum_ { PsChord, PsPieSlice } PsArcEnum;
+typedef enum PsRuleEnum_ { PsEvenOdd, PsNZWinding } PsRuleEnum;
+typedef enum PsFillEnum_ { PsSolid=0, PsTile, PsStip, PsOpStip } PsFillEnum;
+
+typedef struct PsPointRec_
+{
+ int x;
+ int y;
+} PsPointRec;
+
+typedef PsPointRec *PsPointPtr;
+
+typedef struct PsRectRec_
+{
+ int x;
+ int y;
+ int w;
+ int h;
+} PsRectRec;
+
+typedef PsRectRec *PsRectPtr;
+
+typedef struct PsArcRec_
+{
+ int x;
+ int y;
+ int w;
+ int h;
+ int a1;
+ int a2;
+ PsArcEnum style;
+} PsArcRec;
+
+typedef PsArcRec *PsArcPtr;
+
+#define PSOUT_RECT 0
+#define PSOUT_ARC 1
+#define PSOUT_POINTS 2
+
+typedef struct PsElmRec_
+{
+ int type;
+ int nPoints;
+ union
+ {
+ PsRectRec rect;
+ PsArcRec arc;
+ PsPointPtr points;
+ } c;
+} PsElmRec;
+
+typedef PsElmRec *PsElmPtr;
+
+typedef struct PsClipRec_
+{
+ int nRects;
+ PsRectPtr rects;
+ int nElms;
+ PsElmPtr elms;
+ int nOutterClips;
+ PsRectPtr outterClips;
+} PsClipRec;
+
+typedef PsClipRec *PsClipPtr;
+
+typedef enum PsFTDownloadFontType_
+{
+ PsFontBitmap=0,
+ PsFontType1,
+ PsFontType3
+} PsFTDownloadFontType;
+
+/* Define |PsOutColor| color type which can hold one RGB value
+ * (note: this needs to be |signed| long/long long to represent
+ * special values such as |PSOUTCOLOR_NOCOLOR|)
+ */
+#ifdef PSOUT_USE_DEEPCOLOR
+/* 64bit |PsOutColor| which can hold 16bit R-,G-,B-values */
+#ifdef WIN32
+typedef signed __int64 PsOutColor;
+#else
+# if defined(__alpha__) || defined(__alpha) || \
+ defined(ia64) || defined(__ia64__) || \
+ defined(__sparc64__) || defined(_LP64) || \
+ defined(__s390x__) || \
+ defined(amd64) || defined (__amd64__) || \
+ defined (__powerpc64__) || \
+ (defined(sgi) && (_MIPS_SZLONG == 64))
+typedef signed long PsOutColor;
+# else
+typedef signed long long PsOutColor;
+# endif /* native 64bit platform */
+#endif /* WIN32 */
+
+#define PSOUTCOLOR_TO_REDBITS(clr) ((clr) >> 32)
+#define PSOUTCOLOR_TO_GREENBITS(clr) (((clr) >> 16) & 0xFFFF)
+#define PSOUTCOLOR_TO_BLUEBITS(clr) ((clr) & 0xFFFF)
+#define PSOUTCOLOR_BITS_TO_PSFLOAT(b) ((float)(b) / 65535.)
+#define PSOUTCOLOR_WHITE (0xFFFFFFFFFFFFLL)
+#define PSOUTCOLOR_NOCOLOR (-1LL)
+#define PSOUTCOLOR_TO_RGB24BIT(clr) (((PSOUTCOLOR_TO_REDBITS(clr) >> 8) << 16) | \
+ ((PSOUTCOLOR_TO_GREENBITS(clr) >> 8) << 8) | \
+ ((PSOUTCOLOR_TO_BLUEBITS(clr) >> 8) << 0))
+#else
+/* 32bit |PsOutColor| which can hold 8bit R-,G-,B-values */
+typedef signed long PsOutColor;
+#define PSOUTCOLOR_TO_REDBITS(clr) ((clr) >> 16)
+#define PSOUTCOLOR_TO_GREENBITS(clr) (((clr) >> 8) & 0xFF)
+#define PSOUTCOLOR_TO_BLUEBITS(clr) ((clr) & 0xFF)
+#define PSOUTCOLOR_BITS_TO_PSFLOAT(b) ((float)(b) / 255.)
+#define PSOUTCOLOR_WHITE (0xFFFFFF)
+#define PSOUTCOLOR_NOCOLOR (-1)
+#define PSOUTCOLOR_TO_RGB24BIT(clr) ((PSOUTCOLOR_TO_REDBITS(clr) << 16) | \
+ (PSOUTCOLOR_TO_GREENBITS(clr) << 8) | \
+ (PSOUTCOLOR_TO_BLUEBITS(clr) << 0))
+#endif /* PSOUT_USE_DEEPCOLOR */
+
+#ifdef USE_PSOUT_PRIVATE
+typedef void *voidPtr;
+
+typedef struct PsPatRec_
+{
+ PsFillEnum type;
+ voidPtr tag;
+} PsPatRec;
+
+typedef PsPatRec *PsPatPtr;
+
+typedef struct PsOutRec_
+{
+ FILE *Fp;
+ char Buf[16384];
+ PsOutColor CurColor;
+ int LineWidth;
+ PsCapEnum LineCap;
+ PsJoinEnum LineJoin;
+ int NDashes;
+ int *Dashes;
+ int DashOffset;
+ PsOutColor LineBClr;
+ PsRuleEnum FillRule;
+ char *FontName;
+ int FontSize;
+ float FontMtx[4];
+ int ImageFormat;
+ int RevImage;
+ int NPatterns;
+ int MxPatterns;
+ PsPatPtr Patterns;
+ int ClipType;
+ PsClipRec Clip;
+ int InFrame;
+ int XOff;
+ int YOff;
+
+ PsFillEnum InTile;
+ int ImgSkip;
+ PsOutColor ImgBClr;
+ PsOutColor ImgFClr;
+ int ImgX;
+ int ImgY;
+ int ImgW;
+ int ImgH;
+ int SclW;
+ int SclH;
+
+ Bool isRaw;
+
+ int pagenum;
+
+ int start_image;
+} PsOutRec;
+
+typedef struct PsOutRec_ *PsOutPtr;
+
+extern void S_Flush(PsOutPtr self);
+extern void S_OutNum(PsOutPtr self, float num);
+extern void S_OutTok(PsOutPtr self, char *tok, int cr);
+#else
+typedef struct PsOutRec_ *PsOutPtr;
+#endif /* USE_PSOUT_PRIVATE */
+
+extern FILE * PsOut_ChangeFile(PsOutPtr self, FILE *fp);
+extern PsOutPtr PsOut_BeginFile(FILE *fp, char *title, int orient, int count, int plex,
+ int res, int wd, int ht, Bool raw);
+extern void PsOut_EndFile(PsOutPtr self, int closeFile);
+extern void PsOut_BeginPage(PsOutPtr self, int orient, int count, int plex,
+ int res, int wd, int ht);
+extern void PsOut_EndPage(PsOutPtr self);
+extern void PsOut_DirtyAttributes(PsOutPtr self);
+extern void PsOut_Comment(PsOutPtr self, char *comment);
+extern void PsOut_Offset(PsOutPtr self, int x, int y);
+
+extern void PsOut_Clip(PsOutPtr self, int clpTyp, PsClipPtr clpinf);
+
+extern void PsOut_Color(PsOutPtr self, PsOutColor clr);
+extern void PsOut_FillRule(PsOutPtr self, PsRuleEnum rule);
+extern void PsOut_LineAttrs(PsOutPtr self, int wd, PsCapEnum cap,
+ PsJoinEnum join, int nDsh, int *dsh, int dshOff,
+ PsOutColor bclr);
+extern void PsOut_TextAttrs(PsOutPtr self, char *fnam, int siz, int iso);
+extern void PsOut_TextAttrsMtx(PsOutPtr self, char *fnam, float *mtx, int iso);
+
+extern void PsOut_Polygon(PsOutPtr self, int nPts, PsPointPtr pts);
+extern void PsOut_FillRect(PsOutPtr self, int x, int y, int w, int h);
+extern void PsOut_FillArc(PsOutPtr self, int x, int y, int w, int h,
+ float ang1, float ang2, PsArcEnum style);
+
+extern void PsOut_Lines(PsOutPtr self, int nPts, PsPointPtr pts);
+extern void PsOut_Points(PsOutPtr self, int nPts, PsPointPtr pts);
+extern void PsOut_DrawRect(PsOutPtr self, int x, int y, int w, int h);
+extern void PsOut_DrawArc(PsOutPtr self, int x, int y, int w, int h,
+ float ang1, float ang2);
+
+extern void PsOut_Text(PsOutPtr self, int x, int y, char *text, int textl,
+ PsOutColor bclr);
+extern void PsOut_Text16(PsOutPtr self, int x, int y, unsigned short *text, int textl, PsOutColor bclr);
+
+extern void PsOut_BeginImage(PsOutPtr self, PsOutColor bclr, PsOutColor fclr, int x, int y,
+ int w, int h, int sw, int sh, int format);
+extern void PsOut_BeginImageIM(PsOutPtr self, PsOutColor bclr, PsOutColor fclr, int x, int y,
+ int w, int h, int sw, int sh, int format);
+extern void PsOut_EndImage(PsOutPtr self);
+extern void PsOut_OutImageBytes(PsOutPtr self, int nBytes, char *bytes);
+
+extern void PsOut_BeginFrame(PsOutPtr self, int xoff, int yoff, int x, int y,
+ int w, int h);
+extern void PsOut_EndFrame(PsOutPtr self);
+
+extern int PsOut_BeginPattern(PsOutPtr self, void *tag, int w, int h,
+ PsFillEnum type, PsOutColor bclr, PsOutColor fclr);
+extern void PsOut_EndPattern(PsOutPtr self);
+extern void PsOut_SetPattern(PsOutPtr self, void *tag, PsFillEnum type);
+
+extern void PsOut_RawData(PsOutPtr self, char *data, int len);
+
+extern int PsOut_DownloadType1(PsOutPtr self, const char *auditmsg, const char *name, const char *fname);
+
+extern int PsOut_DownloadFreeType1(PsOutPtr self, const char *psfontname, FontPtr pFont, long block_offset);
+extern int PsOut_DownloadFreeType3(PsOutPtr self, const char *psfontname, FontPtr pFont, long block_offset);
+
+extern int PsOut_DownloadFreeType(PsOutPtr self, PsFTDownloadFontType downloadfonttype, const char *psfontname, FontPtr pFont, long block_offset);
+extern void PsOut_Get_FreeType_Glyph_Name( char *destbuf, FontPtr pFont, unsigned long x11fontindex);
+extern void PsOut_FreeType_Text(FontPtr pFont, PsOutPtr self, int x, int y, char *text, int textl);
+extern void PsOut_FreeType_Text16(FontPtr pFont, PsOutPtr self, int x, int y, unsigned short *text, int textl);
+
+extern void PsOut_FreeType_TextAttrs16(PsOutPtr self, char *fnam, int siz, int iso);
+extern void PsOut_FreeType_TextAttrsMtx16(PsOutPtr self, char *fnam, float *mtx, int iso);
+#endif
diff --git a/hw/xprint/ps/psout_ft.c b/hw/xprint/ps/psout_ft.c
new file mode 100644
index 000000000..b10d9e592
--- /dev/null
+++ b/hw/xprint/ps/psout_ft.c
@@ -0,0 +1,335 @@
+
+/*
+Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "os.h"
+#define USE_PSOUT_PRIVATE 1
+#include "psout.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TYPE1_TABLES_H
+
+#include <X11/Xproto.h>
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/fontenc.h>
+#include <X11/fonts/ft.h>
+#define NOT_IN_FTFUNCS
+#include <X11/fonts/ftfuncs.h>
+#include "servermd.h" /* needed for endian test (IMAGE_BYTE_ORDER) */
+
+#define USE_FT_PS_NAMES 1
+
+#ifdef USE_FT_PS_NAMES
+void PsOut_Get_FreeType_Glyph_Name( char *destbuf, FontPtr pFont, unsigned long x11fontindex)
+{
+ FTFontPtr tf = (FTFontPtr)pFont->fontPrivate;
+ FT_Face ttface = tf->instance->face->face;
+ FT_Error error;
+ char buf[256];
+ unsigned long ftindex;
+
+ /* Remap X11 font index to FreeType font index */
+ ftindex = FTRemap(ttface, &tf->mapping, x11fontindex);
+
+ if( FT_Has_PS_Glyph_Names(ttface) )
+ {
+ error = FT_Get_Glyph_Name(ttface, ftindex, buf, 64);
+ }
+ else
+ {
+ error = 1;
+ }
+
+ if( error )
+ {
+ /* Check for unicode mapping
+ * See Adobe document "Unicode and Glyph Names"
+ * (http://partners.adobe.com/asn/tech/type/unicodegn.jsp)
+ */
+ if( (tf->mapping.mapping->type == FONT_ENCODING_UNICODE) &&
+ (ftindex < 0xFFFE) )
+ {
+ sprintf(buf, "uni%04lx", ftindex);
+ }
+ else
+ {
+ sprintf(buf, "ch%02lx", ftindex);
+ }
+ }
+
+ strcpy(destbuf, buf);
+}
+#endif /* USE_FT_PS_NAMES */
+
+int PsOut_DownloadFreeType(PsOutPtr self, PsFTDownloadFontType downloadfonttype, const char *psfontname, FontPtr pFont, long block_offset)
+{
+ switch(downloadfonttype)
+ {
+ case PsFontType3:
+ return PsOut_DownloadFreeType3(self, psfontname, pFont, block_offset);
+ case PsFontType1:
+ return PsOut_DownloadFreeType1(self, psfontname, pFont, block_offset);
+ default:
+ FatalError("PS DDX: PsOut_DownloadFreeType(downloadfonttype='%d' not implemented\n",
+ (int)downloadfonttype);
+ return 0; /* NO-OP, FatalError() will call |exit()| */
+ }
+}
+
+/* cloned from |PsOut_TextAttrs16| */
+void
+PsOut_FreeType_TextAttrs16(PsOutPtr self, char *fnam, int siz, int iso)
+{
+ int i;
+ if( self->FontName && strcmp(fnam, self->FontName)==0 &&
+ siz==self->FontSize ) return;
+ if( self->FontName ) xfree(self->FontName);
+ self->FontName = (char *)xalloc(strlen(fnam)+1);
+ strcpy(self->FontName, fnam);
+ self->FontSize = siz;
+ for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.;
+}
+
+/* cloned from |PsOut_TextAttrsMtx16| */
+void
+PsOut_FreeType_TextAttrsMtx16(PsOutPtr self, char *fnam, float *mtx, int iso)
+{
+ int i;
+ if( self->FontName && strcmp(fnam, self->FontName)==0 &&
+ mtx[0]==self->FontMtx[0] && mtx[1]==self->FontMtx[1] &&
+ mtx[2]==self->FontMtx[2] && mtx[3]==self->FontMtx[3] ) return;
+ if( self->FontName ) xfree(self->FontName);
+ self->FontName = (char *)xalloc(strlen(fnam)+1);
+ strcpy(self->FontName, fnam);
+ for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = mtx[i];
+ self->FontSize = -1;
+}
+
+static
+int FT_Get_CharcellMetricsCharacterHeight(FontPtr pFont)
+{
+ FTFontPtr ftfont = (FTFontPtr)pFont->fontPrivate;
+
+ return ftfont->instance->charcellMetrics->ascent +
+ ftfont->instance->charcellMetrics->descent;
+}
+
+static
+int FT_Get_CharcellMetricsCharacterWidth(FontPtr pFont)
+{
+ FTFontPtr ftfont = (FTFontPtr)pFont->fontPrivate;
+
+ if( ftfont->instance->spacing != FT_PROPORTIONAL )
+ {
+ int width = ftfont->instance->charcellMetrics->characterWidth;
+
+ /* If the font uses a matrix make sure we transform the |characterWidth|
+ * back to it's original value since we download the untransformed font
+ * and use a PostScript transformation matrix to transform the font when
+ * rendering the text
+ */
+ if( ftfont->instance->transformation.nonIdentity )
+ {
+ FT_Vector v;
+
+ FT_Matrix m = ftfont->instance->transformation.matrix;
+ (void)FT_Matrix_Invert(&m); /* FixMe: We should check the return code */
+ v.x = width;
+ v.y = FT_Get_CharcellMetricsCharacterHeight(pFont);
+ FT_Vector_Transform(&v, &m);
+ width = v.x;
+ }
+
+ return width;
+ }
+
+ return 0;
+}
+
+void
+PsOut_FreeType_Text(FontPtr pFont, PsOutPtr self, int x, int y, char *text, int textl)
+{
+ int i;
+ int xo = self->XOff,
+ yo = self->YOff;
+ char buf[256];
+ int cwidth = FT_Get_CharcellMetricsCharacterWidth(pFont);
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ S_OutTok(self, "moveto", 1);
+
+ S_OutTok(self, "[ ", 0);
+
+ for( i = 0 ; i < textl ; i++ )
+ {
+#ifdef USE_FT_PS_NAMES
+ char namebuf[256];
+ unsigned int ch = text[i]&0xFF;
+ unsigned long block_offset = 0;
+ PsOut_Get_FreeType_Glyph_Name(namebuf, pFont, ch+block_offset);
+
+ sprintf(buf, "/%s ", namebuf);
+#else
+ sprintf(buf, "/ch%02x ", text[i]&0xFF);
+#endif /* USE_FT_PS_NAMES */
+ S_OutTok(self, buf, 0);
+ }
+
+ /* Check whether we have any special spacing requirements (e.g. non-proportional fonts) ... */
+ if( cwidth != 0 )
+ {
+ /* If the we use a matrix to render the font (instead of using |self->FontSize|)
+ * we must apply the matrix to the "rmoveto" which is used to force the exact
+ * character width. The "trmoveto" macro will do that for us...
+ */
+ if( self->FontSize == -1 )
+ {
+ sprintf(buf, "]{gs glyphshow gr %d 0 trmoveto}fa", cwidth);
+ }
+ else
+ {
+ sprintf(buf, "]{gs glyphshow gr %d 0 rm}fa", cwidth);
+ }
+ }
+ else
+ {
+ sprintf(buf, "]{glyphshow}fa");
+ }
+ S_OutTok(self, buf, 0);
+}
+
+/* XXX: |PsOut_FreeType_Text16| should be rewritten - currently it uses lame,
+ * slow hacks and makes some risky assumtions about how |PsOut_Text16|
+ * allocates memory */
+void
+PsOut_FreeType_Text16(FontPtr pFont, PsOutPtr self, int x, int y, unsigned short *text, int textl)
+{
+ int i;
+ int xo = self->XOff,
+ yo = self->YOff;
+ unsigned short c,
+ c_hiByte,
+ c_lowByte,
+ fontPage;
+ long lastFontPage = -1;
+ char baseFontName[256];
+ char buf[256];
+
+ if( self->InFrame || self->InTile ) xo = yo = 0;
+ x += xo; y += yo;
+
+ strcpy(baseFontName, self->FontName);
+
+ S_OutNum(self, (float)x);
+ S_OutNum(self, (float)y);
+ S_OutTok(self, "moveto", 1);
+
+ for( i = 0 ; i < textl ; i++ )
+ {
+ c = text[i];
+#if IMAGE_BYTE_ORDER == LSBFirst
+ c_hiByte = c & 0x00FF;
+ c_lowByte = (c >> 8) & 0x00FF;
+#elif IMAGE_BYTE_ORDER == MSBFirst
+ c_hiByte = (c >> 8) & 0x00FF;
+ c_lowByte = c & 0x00FF;
+#else
+#error Unsupported byte order
+#endif
+ fontPage = c_hiByte;
+
+ if( fontPage != lastFontPage )
+ {
+ if( fontPage > 0 )
+ {
+ sprintf(buf, "%s_%x", baseFontName, fontPage);
+ }
+ else
+ {
+ sprintf(buf, "%s", baseFontName);
+ }
+
+ if( self->FontSize == -1 )
+ {
+ PsOut_TextAttrsMtx(self, buf, self->FontMtx, FALSE);
+ }
+ else
+ {
+ PsOut_TextAttrs(self, buf, self->FontSize, FALSE);
+ }
+ lastFontPage = fontPage;
+ }
+
+#ifdef USE_FT_PS_NAMES
+ {
+ char namebuf[256];
+ unsigned int ch = c_lowByte;
+ unsigned long block_offset = c_hiByte * 0x100 /* same as c_hiByte << 8 */;
+ int cwidth = FT_Get_CharcellMetricsCharacterWidth(pFont);
+ PsOut_Get_FreeType_Glyph_Name(namebuf, pFont, ch+block_offset);
+
+ /* Check whether we have any special spacing requirements (e.g. non-proportional fonts) ... */
+ if( cwidth != 0 )
+ {
+ /* If the we use a matrix to render the font (instead of using |self->FontSize|)
+ * we must apply the matrix to the "rmoveto" which is used to force the exact
+ * character width. The "trmoveto" macro will do that for us...
+ */
+ if( self->FontSize == -1 )
+ {
+ sprintf(buf, "gs /%s glyphshow gr %d 0 trmoveto", namebuf, cwidth);
+ }
+ else
+ {
+ sprintf(buf, "gs /%s glyphshow gr %d 0 rm", namebuf, cwidth);
+ }
+ }
+ else
+ {
+ sprintf(buf, "/%s glyphshow", namebuf);
+ }
+ }
+#else
+ sprintf(buf, "/ch%02x glyphshow", c_lowByte);
+#endif /* USE_FT_PS_NAMES */
+ S_OutTok(self, buf, 1);
+ }
+
+ if( self->FontName ) xfree(self->FontName);
+ self->FontName = (char *)xalloc(strlen(baseFontName)+1);
+ strcpy(self->FontName, baseFontName);
+}
+
diff --git a/hw/xprint/ps/psout_ftpstype1.c b/hw/xprint/ps/psout_ftpstype1.c
new file mode 100644
index 000000000..2d40c186a
--- /dev/null
+++ b/hw/xprint/ps/psout_ftpstype1.c
@@ -0,0 +1,185 @@
+
+/*
+Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#include "os.h"
+#define USE_PSOUT_PRIVATE 1
+#include "psout.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include <X11/Xproto.h>
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/fontenc.h>
+#include <X11/fonts/ft.h>
+#define NOT_IN_FTFUNCS
+#include <X11/fonts/ftfuncs.h>
+
+int do_debug_ft2pt1 = FALSE;
+int do_enable_ft2pt1_optimizer = FALSE;
+
+/* Defined in ttf2pt1.c */
+int ft2pt1_main(int argc, char **argv,
+ FTFontPtr tf, const char *download_psfontname, unsigned long download_font_block_offset);
+
+/* Download FreeType outlines as PS Type1 font */
+int PsOut_DownloadFreeType1(PsOutPtr self, const char *psfontname, FontPtr pFont, long block_offset)
+{
+ FTFontPtr tf;
+ FT_Face face;
+ int ft2pt1_numargs = 0;
+ char *ft2pt1_args[40];
+ char *pstype1filename_prefix;
+ char pstype1filename[PATH_MAX+1];
+ int ft2pt1_main_retval;
+ pid_t childpid;
+
+ tf = (FTFontPtr)pFont->fontPrivate;
+ face = tf->instance->face->face;
+
+ /* Set debugging flags */
+ do_debug_ft2pt1 = (getenv("XPRT_PSDDX_DO_DEBUG_FT2PT1") != NULL);
+ do_enable_ft2pt1_optimizer = (getenv("XPRT_PSDDX_DO_ENABLE_FT2PT1_OPTIMIZER") != NULL);
+
+ if( do_debug_ft2pt1 )
+ {
+ fprintf(stderr, "# Converting FT2 font to PS Type1 filename='%s', ttface=%lx\n", tf->instance->face->filename, (long)face);
+ }
+
+ pstype1filename_prefix = tempnam(NULL, "Xprt_");
+
+ ft2pt1_args[ft2pt1_numargs] = "ft2pt1"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-Ob"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-e"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-a"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-Ga"; ft2pt1_numargs++;
+ if( do_enable_ft2pt1_optimizer )
+ {
+ /* Scale fonts to a 1000x1000 matrix */
+ ft2pt1_args[ft2pt1_numargs] = "-Ot"; ft2pt1_numargs++;
+ }
+ else
+ {
+ /* Disable the ttf2pt1 optimisations */
+ ft2pt1_args[ft2pt1_numargs] = "-Ou"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-Oo"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-Os"; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = "-Oh"; ft2pt1_numargs++;
+ }
+
+ if( !do_debug_ft2pt1 )
+ {
+ ft2pt1_args[ft2pt1_numargs] = "-W 0"; ft2pt1_numargs++;
+ }
+ ft2pt1_args[ft2pt1_numargs] = tf->instance->face->filename; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = pstype1filename_prefix; ft2pt1_numargs++;
+ ft2pt1_args[ft2pt1_numargs] = NULL;
+
+/* XXX: ttf2pt1 has lots of leaks and global vars which are not cleaned-up
+ * As long this problem exists we will simply fork() and call the converter
+ * from the child process (all resources are free'ed when the child process
+ * exists) as a workaround.
+ */
+#define FT2PT1_NEEDS_SEPERATE_PROCESS 1
+
+#ifdef FT2PT1_NEEDS_SEPERATE_PROCESS
+ /* Flush internal buffer and then the stdio stream before fork()! */
+ S_Flush(self);
+ fflush(self->Fp);
+
+ childpid = fork();
+ switch(childpid)
+ {
+ case -1:
+ FatalError("PS DDX internal error: Cannot fork() converter child process, errno=%d\n", (int)errno);
+ break;
+ case 0: /* child */
+ fclose(self->Fp);
+ self->Fp = NULL;
+
+ ft2pt1_main_retval = ft2pt1_main(ft2pt1_numargs, ft2pt1_args, tf, psfontname, block_offset);
+ if( do_debug_ft2pt1 )
+ {
+ fprintf(stderr, "## ft2pt1_main returned %d (child)\n", ft2pt1_main_retval);
+ }
+ exit(ft2pt1_main_retval);
+ break;
+ default: /* parent */
+ waitpid(childpid, &ft2pt1_main_retval, 0);
+ break;
+ }
+
+ if( do_debug_ft2pt1 )
+ {
+ fprintf(stderr, "## ft2pt1_main returned %d (parent)\n", ft2pt1_main_retval);
+ }
+#else
+ S_Flush(self);
+
+ ft2pt1_main_retval = ft2pt1_main(ft2pt1_numargs, ft2pt1_args, tf, psfontname, block_offset);
+ if( do_debug_ft2pt1 )
+ {
+ fprintf(stderr, "## ft2pt1_main returned %d (child)\n", ft2pt1_main_retval);
+ }
+#endif /* FT2PT1_NEEDS_SEPERATE_PROCESS */
+
+ if( ft2pt1_main_retval != EXIT_SUCCESS )
+ {
+ FatalError("PS DDX internal error while converting FreeType font '%s' to PS Type1, error=%d\n",
+ tf->instance->face->filename, ft2pt1_main_retval);
+ }
+
+ sprintf(pstype1filename, "%s.pfa", pstype1filename_prefix);
+ if( do_debug_ft2pt1 )
+ {
+ fprintf(stderr, "# Downloading converted FT2/PS Type1 filename='%s'\n", pstype1filename);
+ }
+
+ PsOut_DownloadType1(self, "PsOut_DownloadFreeType1", psfontname, pstype1filename);
+
+ if( !do_debug_ft2pt1 )
+ {
+ unlink(pstype1filename);
+ }
+
+ free(pstype1filename_prefix);
+
+ S_Flush(self);
+
+ return 0;
+}
+
+
diff --git a/hw/xprint/ps/psout_ftpstype3.c b/hw/xprint/ps/psout_ftpstype3.c
new file mode 100644
index 000000000..733b5386b
--- /dev/null
+++ b/hw/xprint/ps/psout_ftpstype3.c
@@ -0,0 +1,439 @@
+
+/*
+Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "os.h"
+#define USE_PSOUT_PRIVATE 1
+#include "psout.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_BBOX_H
+#include FT_GLYPH_H
+
+#include FT_CONFIG_CONFIG_H
+#include FT_CONFIG_OPTIONS_H
+#include FT_ERRORS_H
+#include FT_SYSTEM_H
+#include FT_IMAGE_H
+#include FT_TYPES_H
+#include FT_OUTLINE_H
+#include FT_MODULE_H
+#include FT_RENDER_H
+#include FT_TYPE1_TABLES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_CACHE_H
+#include FT_CACHE_IMAGE_H
+#include FT_CACHE_SMALL_BITMAPS_H
+#include FT_MULTIPLE_MASTERS_H
+#include FT_SFNT_NAMES_H
+
+#include <X11/Xproto.h>
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#include <X11/fonts/fntfilst.h>
+#include <X11/fonts/fontutil.h>
+#include <X11/fonts/fontenc.h>
+#include <X11/fonts/ft.h>
+#define NOT_IN_FTFUNCS
+#include <X11/fonts/ftfuncs.h>
+
+struct ft2info
+{
+ FontPtr pFont;
+ FTFontPtr tf;
+ FT_Face ttface;
+ struct
+ {
+ char *full_name;
+ char *copyright;
+ char *family;
+ char *subfamily;
+ char *version;
+ } nameid;
+ TT_Postscript *ttpostscript;
+ TT_Header *ttheader;
+};
+
+/* Local prototypes */
+static FT_Error PSType3_createOutlineGlyphs(FILE *out, struct ft2info *ti, unsigned long unicode, const char *psglyphname);
+static int PSType3_generateOutlineFont(FILE *out, const char *psfontname, struct ft2info *ti, long block_offset);
+
+extern FT_Library ftypeLibrary; /* defined in xc/lib/font/FreeType/ftfuncs.c */
+
+#define USE_FT_PS_NAMES 1
+
+static
+FT_Error PSType3_createOutlineGlyphs( FILE *out, struct ft2info *ti, unsigned long x11fontindex, const char *psglyphname )
+{
+ unsigned long ftindex;
+ FT_BBox bbox;
+ FT_Error error;
+ FT_Outline outline;
+
+ /* Remap X11 font index to FreeType font index */
+ ftindex = FTRemap(ti->ttface, &ti->tf->mapping, x11fontindex);
+
+ error = FT_Load_Glyph(ti->ttface, ftindex, (FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING));
+ if( error )
+ {
+ fprintf(stderr, "PSType3_createOutlineGlyphs: FT_Load_Glyph() failure, error=%d\n", (int)error);
+ return error;
+ }
+
+ outline = ti->ttface->glyph->outline;
+
+ FT_Outline_Get_CBox(&outline, &bbox);
+
+ fprintf(out, "/%s {\n", psglyphname);
+ fprintf(out, "%ld 0 %ld %ld %ld %ld setcachedevice\n",
+ (signed long)ti->ttface->glyph->metrics.horiAdvance,
+ (long)bbox.xMin,
+ (long)bbox.yMin,
+ (long)bbox.xMax,
+ (long)bbox.yMax);
+
+ if( outline.n_contours > 0 )
+ {
+ long i,
+ j,
+ k, k1,
+ cs, ce,
+ nguide,
+ contour_start,
+ contour_end,
+ last_point;
+ Bool first;
+ FT_Vector *vec;
+
+ contour_start = ce = 0;
+
+ vec = outline.points;
+ last_point = outline.n_points;
+
+ i = j = k = 0;
+ first = TRUE;
+
+ while( i <= outline.contours[outline.n_contours - 1] )
+ {
+ contour_end = outline.contours[j];
+
+ if( first )
+ {
+ fprintf(out, "%ld %ld moveto\n", vec[i].x, vec[i].y);
+ contour_start = i;
+ first = FALSE;
+ }
+ else if( outline.tags[i] & FT_CURVE_TAG_ON )
+ {
+ fprintf(out, "%ld %ld lineto\n", vec[i].x, vec[i].y);
+ }
+ else
+ {
+ Bool finished = FALSE;
+
+ cs = i-1;
+ nguide = 0;
+ while( !finished )
+ {
+ if( i == contour_end+1 )
+ {
+ ce = contour_start;
+ finished = TRUE;
+ }
+ else if( outline.tags[i] & FT_CURVE_TAG_ON )
+ {
+ ce = i;
+ finished = TRUE;
+ }
+ else
+ {
+ i++;
+ nguide++;
+ }
+ }
+
+ switch( nguide )
+ {
+ case 0:
+ fprintf(out, "%ld %ld lineto\n", vec[ce].x, vec[ce].y);
+ break;
+
+ case 1:
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[cs].x+2*vec[cs+1].x)/3,
+ (vec[cs].y+2*vec[cs+1].y)/3,
+ (2*vec[cs+1].x+vec[ce].x)/3,
+ (2*vec[cs+1].y+vec[ce].y)/3,
+ vec[ce].x, vec[ce].y);
+ break;
+
+ case 2:
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (-vec[cs].x+4*vec[cs+1].x)/3,
+ (-vec[cs].y+4*vec[cs+1].y)/3,
+ (4*vec[cs+2].x-vec[ce].x)/3,
+ (4*vec[cs+2].y-vec[ce].y)/3,
+ vec[ce].x, vec[ce].y);
+ break;
+
+ case 3:
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[cs].x+2*vec[cs+1].x)/3,
+ (vec[cs].y+2*vec[cs+1].y)/3,
+ (5*vec[cs+1].x+vec[cs+2].x)/6,
+ (5*vec[cs+1].y+vec[cs+2].y)/6,
+ (vec[cs+1].x+vec[cs+2].x)/2,
+ (vec[cs+1].y+vec[cs+2].y)/2);
+
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[cs+1].x+5*vec[cs+2].x)/6,
+ (vec[cs+1].y+5*vec[cs+2].y)/6,
+ (5*vec[cs+2].x+vec[cs+3].x)/6,
+ (5*vec[cs+2].y+vec[cs+3].y)/6,
+ (vec[cs+3].x+vec[cs+2].x)/2,
+ (vec[cs+3].y+vec[cs+2].y)/2);
+
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[cs+2].x+5*vec[cs+3].x)/6,
+ (vec[cs+2].y+5*vec[cs+3].y)/6,
+ (2*vec[cs+3].x+vec[ce].x)/3,
+ (2*vec[cs+3].y+vec[ce].y)/3,
+ vec[ce].x, vec[ce].y);
+ break;
+
+ default: /* anything |nguide > 3| */
+ k1 = cs + nguide;
+
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[cs].x+2*vec[cs+1].x)/3,
+ (vec[cs].y+2*vec[cs+1].y)/3,
+ (5*vec[cs+1].x+vec[cs+2].x)/6,
+ (5*vec[cs+1].y+vec[cs+2].y)/6,
+ (vec[cs+1].x+vec[cs+2].x)/2,
+ (vec[cs+1].y+vec[cs+2].y)/2);
+
+ for( k = cs+2 ; k <= k1-1 ; k++ )
+ {
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[k-1].x+5*vec[k].x)/6,
+ (vec[k-1].y+5*vec[k].y)/6,
+ (5*vec[k].x+vec[k+1].x)/6,
+ (5*vec[k].y+vec[k+1].y)/6,
+ (vec[k].x+vec[k+1].x)/2,
+ (vec[k].y+vec[k+1].y)/2);
+ }
+
+ fprintf(out, "%ld %ld %ld %ld %ld %ld curveto\n",
+ (vec[k1-1].x+5*vec[k1].x)/6,
+ (vec[k1-1].y+5*vec[k1].y)/6,
+ (2*vec[k1].x+vec[ce].x)/3,
+ (2*vec[k1].y+vec[ce].y)/3,
+ vec[ce].x, vec[ce].y);
+ break;
+ }
+ }
+
+ if( i >= contour_end )
+ {
+ fprintf(out, "closepath\n");
+ first = TRUE;
+ i = contour_end + 1;
+ j++;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+
+ fprintf(out, "fill } bind def\n");
+
+ return 0;
+}
+
+static
+int PSType3_generateOutlineFont(FILE *out, const char *psfontname, struct ft2info *ti, long block_offset)
+{
+ long i;
+ double scaler;
+ const int numchars = 256;
+#ifdef USE_FT_PS_NAMES
+ int linewidth = 0;
+#endif /* USE_FT_PS_NAMES */
+
+ fprintf(out, "%%%%BeginFont: %s\n", psfontname);
+ fprintf(out, "22 dict begin\n");
+ fprintf(out, "/FontType 3 def\n");
+ fprintf(out, "/StrokeWidth 0 def\n");
+ fprintf(out, "/PaintType 0 def\n");
+ fprintf(out, "/FontName (%s) def\n", psfontname);
+ fprintf(out, "/FontInfo 9 dict dup begin\n");
+ fprintf(out, " /FullName (%s) def\n", ti->nameid.full_name?ti->nameid.full_name:psfontname);
+ fprintf(out, " /Notice (%s) def\n", ti->nameid.copyright?ti->nameid.copyright:"nothing here");
+ fprintf(out, " /FamilyName (%s) def\n", ti->nameid.family?ti->nameid.family:psfontname);
+ fprintf(out, " /Weight (%s) def\n", ti->nameid.subfamily?ti->nameid.subfamily:"Regular");
+ fprintf(out, " /version (%s) def\n", ti->nameid.version?ti->nameid.version:"0.1");
+
+ if( ti->ttpostscript )
+ {
+ fprintf(out, " /italicAngle %.9g def\n", (double)ti->ttpostscript->italicAngle);
+ fprintf(out, " /underlineThickness %d def\n", (int)ti->ttpostscript->underlineThickness);
+ fprintf(out, " /underlinePosition %d def\n", (int)ti->ttpostscript->underlinePosition);
+ fprintf(out, " /isFixedPitch %s def\n", ((ti->ttpostscript->isFixedPitch)?("true"):("false")));
+ }
+ else
+ {
+ fprintf(out, " /italicAngle %.9g def\n", 0.0);
+ fprintf(out, " /underlineThickness %d def\n", 100);
+ fprintf(out, " /underlinePosition %d def\n", 0);
+ fprintf(out, " /isFixedPitch false def\n");
+ }
+
+ fprintf(out, "end def\n");
+
+ scaler = (1000.0 / (double)ti->ttface->units_per_EM) / 1000.0;
+ fprintf(out, "/FontMatrix [%.9g 0 0 %.9g 0 0] def\n", scaler, scaler);
+
+ if( ti->ttheader )
+ {
+ fprintf(out, "/FontBBox [%d %d %d %d] def\n",
+ (int)ti->ttheader->xMin,
+ (int)ti->ttheader->yMin,
+ (int)ti->ttheader->xMax,
+ (int)ti->ttheader->yMax);
+ }
+ else
+ {
+ fprintf(out, "/FontBBox [%ld %ld %ld %ld] def\n",
+ ti->ttface->bbox.xMin,
+ ti->ttface->bbox.yMin,
+ ti->ttface->bbox.xMax,
+ ti->ttface->bbox.yMax);
+
+ }
+
+ fprintf(out, "/Encoding [\n");
+ for( i = 0 ; i < 256 ; i++ )
+ {
+#ifdef USE_FT_PS_NAMES
+ char namebuf[256];
+ PsOut_Get_FreeType_Glyph_Name(namebuf, ti->pFont, i+block_offset);
+ linewidth += strlen(namebuf) + 2;
+ fprintf(out, "/%s%s", namebuf, (linewidth > 70)?(linewidth = 0, "\n"):(" "));
+#else
+ fprintf(out, "/ch%02x%s", i, (((i % 10) == 9)?("\n"):(" ")));
+#endif /* USE_FT_PS_NAMES */
+ }
+ fprintf(out, "] def\n");
+
+ fprintf(out, "/CharProcs %d dict def CharProcs begin\n", (int)(numchars + 1));
+ fprintf(out, "/.notdef {\n"
+ "1000 0 0 0 0 0 setcachedevice\n"
+ "fill } bind def\n");
+ for( i = 0 ; i < numchars ; i++ )
+ {
+ char buf[32];
+#ifdef USE_FT_PS_NAMES
+ char namebuf[256];
+ PsOut_Get_FreeType_Glyph_Name(namebuf, ti->pFont, i+block_offset);
+ sprintf(buf, "%s ", namebuf);
+#else
+ sprintf(buf, "ch%02lx ", i);
+#endif /* USE_FT_PS_NAMES */
+ PSType3_createOutlineGlyphs(out, ti, i+block_offset, buf);
+ }
+ fprintf(out, "end\n"
+ "/BuildGlyph {\n"
+ " exch /CharProcs get exch\n"
+ " 2 copy known not {pop /.notdef} if get exec } bind def\n"
+ "/BuildChar { 1 index /Encoding get exch get\n"
+ " 1 index /Encoding get exec } bind def\n");
+ fprintf(out, "currentdict end /%s exch definefont pop\n", psfontname);
+ fprintf(out, "%%EndFont\n");
+
+ return 0;
+}
+
+static
+char *FT_Get_TT_NAME_ID(FT_Face ttface, int index)
+{
+ FT_SfntName name;
+ char *s;
+
+ if( index >= FT_Get_Sfnt_Name_Count(ttface) )
+ return NULL;
+
+ FT_Get_Sfnt_Name(ttface, index, &name);
+ s = (char *)malloc(name.string_len+2);
+ if( !s )
+ return NULL;
+ memcpy(s, (char *)name.string, name.string_len);
+ s[name.string_len] = '\0';
+ return s;
+}
+
+int PsOut_DownloadFreeType3(PsOutPtr self, const char *psfontname, FontPtr pFont, long block_offset)
+{
+ struct ft2info cft2info = { 0 };
+ struct ft2info *ti = &cft2info;
+
+ S_Flush(self);
+
+ ti->tf = (FTFontPtr)pFont->fontPrivate;
+ ti->ttface = ti->tf->instance->face->face;
+ ti->pFont = pFont;
+#ifdef DEBUG_gisburn
+ fprintf(stderr, "# Downloading FT2 font filename='%s', ttface=%lx\n", ti->tf->instance->face->filename, (long)ti->ttface);
+#endif /* DEBUG_gisburn */
+
+ ti->nameid.full_name = FT_Get_TT_NAME_ID(ti->ttface, TT_NAME_ID_FULL_NAME);
+ ti->nameid.copyright = FT_Get_TT_NAME_ID(ti->ttface, TT_NAME_ID_COPYRIGHT);
+ ti->nameid.family = FT_Get_TT_NAME_ID(ti->ttface, TT_NAME_ID_FONT_FAMILY);
+ ti->nameid.subfamily = FT_Get_TT_NAME_ID(ti->ttface, TT_NAME_ID_FONT_SUBFAMILY);
+ ti->nameid.version = FT_Get_TT_NAME_ID(ti->ttface, TT_NAME_ID_VERSION_STRING);
+
+ ti->ttheader = (TT_Header *)FT_Get_Sfnt_Table(ti->ttface, ft_sfnt_head);
+ ti->ttpostscript = (TT_Postscript *)FT_Get_Sfnt_Table(ti->ttface, ft_sfnt_post);
+
+ PSType3_generateOutlineFont(self->Fp, psfontname, ti, block_offset);
+
+ free(ti->nameid.full_name);
+ free(ti->nameid.copyright);
+ free(ti->nameid.family);
+ free(ti->nameid.subfamily);
+ free(ti->nameid.version);
+
+ S_Flush(self);
+
+ return 0;
+}
+
diff --git a/hw/xprint/ps/ttf2pt1wrap.c b/hw/xprint/ps/ttf2pt1wrap.c
new file mode 100644
index 000000000..57bb777d2
--- /dev/null
+++ b/hw/xprint/ps/ttf2pt1wrap.c
@@ -0,0 +1,14 @@
+/*
+ * Wrapper to add missing symbol to externally supplied code
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef Lynx
+extern int optind;
+extern char *optarg;
+#endif
+
+#include "ttf2pt1.c"
diff --git a/hw/xprint/raster/Makefile.am b/hw/xprint/raster/Makefile.am
new file mode 100644
index 000000000..fcd1e7334
--- /dev/null
+++ b/hw/xprint/raster/Makefile.am
@@ -0,0 +1,11 @@
+noinst_LTLIBRARIES = libraster.la
+
+INCLUDES = -I$(top_srcdir)/hw/xprint
+
+AM_CFLAGS = @SERVER_DEFINES@ @DIX_CFLAGS@ @XPRINT_CFLAGS@ \
+ -D_XP_PRINT_SERVER_ -DPSZ=8
+
+libraster_la_SOURCES = \
+ RasterAttVal.c \
+ Raster.c \
+ Raster.h
diff --git a/hw/xprint/raster/Raster.c b/hw/xprint/raster/Raster.c
new file mode 100644
index 000000000..7ad30b446
--- /dev/null
+++ b/hw/xprint/raster/Raster.c
@@ -0,0 +1,1573 @@
+/* $Xorg: Raster.c,v 1.4 2001/03/14 18:46:12 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+/* $XFree86: xc/programs/Xserver/Xprint/raster/Raster.c,v 1.11tsi Exp $ */
+
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: printer/Raster.c
+** *
+** * Contents:
+** * Raster driver for the print server.
+** *
+** * Copyright: Copyright 1993, 1995 Hewlett-Packard Company
+** *
+** *********************************************************
+**
+********************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <X11/X.h>
+#include <X11/Xos.h> /* for SIGCLD on pre-POSIX systems */
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#undef NEED_EVENTS
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "screenint.h"
+#include "colormapst.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "servermd.h" /* needed for IMAGE_BUFSIZE */
+#include "fb.h"
+#include "mi.h"
+
+#include <X11/extensions/Print.h>
+#include "Raster.h"
+
+#include "attributes.h"
+#include "AttrValid.h"
+#include "DiPrint.h"
+
+static void AllocateRasterPrivates(
+ ScreenPtr pScreen);
+static Bool RasterChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask);
+static int StartJob(
+ XpContextPtr pCon,
+ Bool sendClientData,
+ ClientPtr client);
+static int StartPage(
+ XpContextPtr pCon,
+ WindowPtr pWin);
+static int StartDoc(
+ XpContextPtr pCon,
+ XPDocumentType type);
+static int EndDoc(
+ XpContextPtr pCon,
+ Bool cancel);
+static int EndJob(
+ XpContextPtr pCon,
+ Bool cancel);
+static int EndPage(
+ XpContextPtr pCon,
+ WindowPtr pWin);
+static int DocumentData(
+ XpContextPtr pCon,
+ DrawablePtr pDraw,
+ char *pData,
+ int len_data,
+ char *pDoc_fmt,
+ int len_fmt,
+ char *pOptions,
+ int len_options,
+ ClientPtr client);
+static int GetDocumentData(
+ XpContextPtr pContext,
+ ClientPtr client,
+ int maxBufferSize);
+static void FreePageFiles(
+ RasterContextPrivPtr pWinPriv);
+static int SystemCmd(
+ char *pCommand);
+static Bool RasterCloseScreen(
+ int index,
+ ScreenPtr pScreen);
+static int RasterInitContext(XpContextPtr pCon);
+static Bool RasterDestroyContext(XpContextPtr pCon);
+static char *RasterGetAttributes(
+ XpContextPtr pContext,
+ XPAttributes class);
+static char *RasterGetOneAttribute(XpContextPtr pCon,
+ XPAttributes class,
+ char *attribute);
+static int RasterSetAttributes(XpContextPtr pCon,
+ XPAttributes class,
+ char *attributes);
+static int RasterAugmentAttributes(XpContextPtr pCon,
+ XPAttributes class,
+ char *attributes);
+static int RasterMediumDimensions(XpContextPtr pCon,
+ CARD16 *width,
+ CARD16 *height);
+static int RasterReproducibleArea(XpContextPtr pCon,
+ xRectangle *pRect);
+
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define DOC_PCL 1
+#define DOC_RASTER 2
+
+static int RasterScreenPrivateIndex, RasterContextPrivateIndex;
+static int RasterGeneration = 0;
+static char RASTER_DRIV_NAME[] = "XP-RASTER";
+static int doc_type = DOC_RASTER;
+
+#define ABSOLUTE_PCLCOMP_PATH1 "/usr/openwin/bin/pclcomp"
+#define ABSOLUTE_PCLCOMP_PATH2 "/usr/X11/bin/pclcomp"
+
+static char *pcl3_output_cmds[] = {
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -01 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -02 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -03 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -012 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -013 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -023 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0123 > %(OutFile)%",
+ "xpr -device ljet -rv -landscape < %(InFile)% > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -0 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -01 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -02 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -03 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -012 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -013 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -023 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% | pclcomp -0123 > %(OutFile)%",
+ "xpr -device ljet -rv < %(InFile)% > %(OutFile)%"};
+
+Bool
+InitializeRasterDriver(
+ int ndx,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv)
+{
+ int xRes, yRes;
+ int maxRes, maxDim, numBytes;
+ RasterScreenPrivPtr pPriv;
+
+ /*
+ * Register this driver's InitContext function with the print extension.
+ * This is a bit
+ * sleazy, as the extension hasn't yet been initialized, but the
+ * extension needs to know this, and this seems the best time to
+ * provide the information.
+ */
+ XpRegisterInitFunc( pScreen, RASTER_DRIV_NAME, RasterInitContext );
+
+ /*
+ * Create and load the devPrivate for the printer layer.
+ */
+ AllocateRasterPrivates(pScreen);
+
+ pPriv = (RasterScreenPrivPtr)
+ pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
+
+ maxDim = MAX( pScreen->height, pScreen->width );
+ numBytes = maxDim + BITMAP_SCANLINE_PAD - 1; /* pixels per row */
+ numBytes *= maxDim;
+ numBytes /= 8; /* bytes per row */
+ xRes = pScreen->width / (pScreen->mmWidth / 25.4);
+ yRes = pScreen->height / (pScreen->mmHeight / 25.4);
+ maxRes = MAX( xRes, yRes );
+
+ pPriv->pBits = (char *)xalloc(numBytes);
+
+ /*
+ * Have to allocate maxDim X maxDim to allow for landscape mode.
+ */
+ fbScreenInit(pScreen, pPriv->pBits, maxDim, maxDim, maxRes,
+ maxRes, maxDim, 1);
+ miInitializeBackingStore(pScreen);
+ pScreen->blackPixel = 1;
+ pScreen->whitePixel = 0;
+ if(fbCreateDefColormap(pScreen) == FALSE)
+ ; /* XXX what do I do if it fails? */
+
+ pScreen->SaveScreen = (SaveScreenProcPtr)_XpBoolNoop;
+ pPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes;
+ pPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = RasterCloseScreen;
+
+ return TRUE;
+}
+
+/*
+ * GetPropString searches the context's config database for a property
+ * by the name of propName. If found, it returns the property's
+ * value, otherwise it returns NULL unless the requested attribute
+ * is RASTER_PRINT_PAGE_COMMAND, in which case it returns a hard-coded
+ * default string to invoke xpr to produce a PostScript(tm) formatted
+ * raster.
+ */
+
+static char *
+GetPropString(
+ XpContextPtr pCon,
+ char *propName)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+ char *type;
+ XrmValue val;
+ struct stat status;
+ int pclcomp_exists = 0;
+
+ if( XrmGetResource(pConPriv->config, propName, propName, &type, &val) ==
+ True )
+ return (char *)val.addr;
+
+ if( !strcmp( propName, RASTER_PRINT_PAGE_COMMAND ) )
+ if( doc_type == DOC_RASTER )
+ return "xpr -device ps %(InFile)% > %(OutFile)%";
+ else
+ {
+ XpOid orientation;
+ XpOid compression;
+ int pcl3_output_index = 0;
+
+ orientation = XpGetContentOrientation(pCon);
+ compression = XpGetAvailableCompression(pCon);
+
+ switch(orientation) {
+ case xpoid_val_content_orientation_landscape:
+ pcl3_output_index = 0;
+ break;
+ default:
+ pcl3_output_index += 9;
+ break;
+ }
+
+ if(stat(ABSOLUTE_PCLCOMP_PATH1, &status) != -1)
+ pclcomp_exists = 1;
+ else if(stat(ABSOLUTE_PCLCOMP_PATH2, &status) != -1)
+ pclcomp_exists = 1;
+
+ if(pclcomp_exists)
+ switch(compression) {
+ case xpoid_val_available_compressions_0:
+ pcl3_output_index += 0;
+ break;
+ case xpoid_val_available_compressions_01:
+ pcl3_output_index += 1;
+ break;
+ case xpoid_val_available_compressions_02:
+ pcl3_output_index += 2;
+ break;
+ case xpoid_val_available_compressions_03:
+ pcl3_output_index += 3;
+ break;
+ case xpoid_val_available_compressions_012:
+ pcl3_output_index += 4;
+ break;
+ case xpoid_val_available_compressions_013:
+ pcl3_output_index += 5;
+ break;
+ case xpoid_val_available_compressions_023:
+ pcl3_output_index += 6;
+ break;
+ default:
+ pcl3_output_index += 7;
+ break;
+ }
+ else
+ pcl3_output_index += 8;
+
+ return pcl3_output_cmds[pcl3_output_index];
+ }
+ else
+ return NULL;
+}
+
+static void
+SetDocumentType(
+ XpContextPtr pCon)
+{
+ XpOidList* attrs_supported;
+
+ /*
+ * only validate attributes found in document-attributes-supported
+ */
+ attrs_supported =
+ XpGetListAttr(pCon, XPPrinterAttr,
+ xpoid_att_document_attributes_supported,
+ (const XpOidList*)NULL);
+
+ if(XpOidListHasOid(attrs_supported, xpoid_att_document_format))
+ {
+ const char* value_in;
+ XpOidDocFmt *f;
+
+ value_in = XpGetStringAttr(pCon, XPDocAttr, xpoid_att_document_format);
+
+ f = XpOidDocFmtNew( value_in );
+
+ if( f != NULL )
+ {
+ if( !strcmp( f->format, "PCL" ) )
+ doc_type = DOC_PCL;
+ else
+ doc_type = DOC_RASTER;
+
+ XpOidDocFmtDelete( f );
+ }
+ }
+
+ /*
+ * clean up
+ */
+ XpOidListDelete(attrs_supported);
+}
+
+static int
+StartJob(
+ XpContextPtr pCon,
+ Bool sendClientData,
+ ClientPtr client)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+
+ SetDocumentType( pCon );
+
+ /*
+ * Check for existing page file, and delete it if it exists.
+ */
+ if(pConPriv->pageFileName != (char *)NULL)
+ {
+ if(pConPriv->pPageFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ }
+ unlink(pConPriv->pageFileName);
+ Xfree(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+ }
+
+ /*
+ * Create a temporary file to store the printer output.
+ */
+ if(!sendClientData)
+ {
+ /*
+ * Create a temporary file to store the printer output.
+ */
+ if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+/*
+ * StartDoc and EndDoc are just no-ops in this implementation, since
+ * our view of the spooler really doesn't recognize documents.
+ */
+
+static int
+StartDoc(
+ XpContextPtr pCon,
+ XPDocumentType type)
+{
+ return Success;
+}
+
+static int EndDoc(
+ XpContextPtr pCon,
+ Bool cancel)
+{
+ return Success;
+}
+
+#if 0
+
+/* XXX Not used. */
+
+/*
+ * BuidArgVector takes a pointer to a comma-separated list of command
+ * options and splits it out into an array of argument pointers. The
+ * caller must not free the optionList after calling this function until
+ * the returned arg vector is no longer needed, at which time the arg
+ * vector should also be freed.
+ */
+
+#define SEPARATOR_CHAR (char)','
+
+static char **
+BuildArgVector(
+ char *optionList,
+ char **argVector,
+ int argCount)
+{
+ char *curArg, *lastChar, *endArg;
+
+ curArg = optionList;
+ lastChar = optionList + strlen(optionList); /* includes final NULL */
+
+ while(curArg != (char *)NULL && curArg < lastChar)
+ {
+ /* strip leading white space */
+ while(curArg < lastChar && isascii((int)*curArg) &&
+ isspace((int)*curArg))
+ curArg++;
+
+ if(curArg < lastChar)
+ {
+ argVector = (char **)Xrealloc(argVector,
+ sizeof(char *) * (argCount + 2));
+ argVector[argCount] = curArg;
+ argVector[++argCount] = (char *)NULL;
+
+ endArg = strchr(curArg, SEPARATOR_CHAR);
+
+ /* Should I strip trailing white space ??? */
+
+ if(endArg != (char *)NULL)
+ {
+ *endArg = (char)'\0';
+ curArg = endArg + 1;
+ }
+ else
+ curArg = (char *)NULL;
+ }
+ }
+
+ return argVector;
+}
+#endif
+
+static int
+EndJob(
+ XpContextPtr pCon,
+ Bool cancel)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+
+ if( cancel == True )
+ {
+ if(pConPriv->getDocClient != (ClientPtr)NULL) {
+ XpFinishDocData(pConPriv->getDocClient);
+
+ pConPriv->getDocClient = (ClientPtr)NULL;
+ pConPriv->getDocBufSize = 0;
+ }
+
+ if(pConPriv->jobFileName != (char *)NULL)
+ {
+ unlink(pConPriv->jobFileName);
+ Xfree(pConPriv->jobFileName);
+ pConPriv->jobFileName = (char *)NULL;
+ }
+
+ return Success;
+ }
+
+ if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0)
+ {
+ XpFinishDocData(pConPriv->getDocClient);
+
+ pConPriv->getDocClient = (ClientPtr)NULL;
+ pConPriv->getDocBufSize = 0;
+
+ return Success;
+ }
+
+ if(pConPriv->pJobFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pJobFile);
+ pConPriv->pJobFile = (FILE *)NULL;
+
+ if(pConPriv->jobFileName != (char *)NULL)
+ {
+ XpSubmitJob( pConPriv->jobFileName, pCon );
+ unlink(pConPriv->jobFileName);
+ Xfree(pConPriv->jobFileName);
+ pConPriv->jobFileName = (char *)NULL;
+ }
+ }
+
+ return Success;
+}
+
+/* StartPage
+ *
+ * If page file exists
+ * close page file
+ * set page file pointer = NULL
+ * unlink page file
+ */
+static int
+StartPage(
+ XpContextPtr pCon,
+ WindowPtr pWin)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+
+ if(pConPriv->pPageFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ }
+ if(pConPriv->pageFileName != (char *)NULL)
+ {
+ unlink(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+ }
+
+ return Success;
+}
+
+#include "X11/XWDFile.h"
+
+
+#define lowbit(x) ((x) & (~(x) + 1))
+
+/*
+ * Get the XWDColors of all pixels in colormap - returns # of colors
+ */
+static XWDColor *
+Get_XWDColors(
+ ColormapPtr pCmap)
+{
+ int i, ncolors;
+ xrgb *prgbList;
+ Pixel *pPixels;
+ XWDColor *colors;
+
+ ncolors = pCmap->pVisual->ColormapEntries;
+ if (!(colors = (XWDColor *) malloc (sizeof(XWDColor) * ncolors)))
+ return (XWDColor *) NULL;
+ if (!(prgbList = (xrgb*) malloc(sizeof(xrgb) * ncolors)))
+ {
+ Xfree(colors);
+ return (XWDColor *) NULL;
+ }
+ if (!(pPixels = (Pixel*) malloc(sizeof(Pixel) * ncolors)))
+ {
+ Xfree(colors);
+ Xfree(prgbList);
+ return (XWDColor *) NULL;
+ }
+
+ if (pCmap->pVisual->class == DirectColor ||
+ pCmap->pVisual->class == TrueColor) {
+ Pixel red, green, blue, red1, green1, blue1;
+
+ red = green = blue = 0;
+ red1 = lowbit(pCmap->pVisual->redMask);
+ green1 = lowbit(pCmap->pVisual->greenMask);
+ blue1 = lowbit(pCmap->pVisual->blueMask);
+ for (i=0; i<ncolors; i++) {
+ colors[i].pixel = red|green|blue;
+ colors[i].pad = 0;
+ red += red1;
+ if (red > pCmap->pVisual->redMask)
+ red = 0;
+ green += green1;
+ if (green > pCmap->pVisual->greenMask)
+ green = 0;
+ blue += blue1;
+ if (blue > pCmap->pVisual->blueMask)
+ blue = 0;
+ }
+ } else {
+ for (i=0; i<ncolors; i++) {
+ colors[i].pixel = i;
+ colors[i].pad = 0;
+ }
+ }
+
+ for(i = 0; i < ncolors; i++)
+ pPixels[i] = colors[i].pixel;
+
+ QueryColors(pCmap, ncolors, pPixels, prgbList);
+ Xfree(pPixels);
+
+ for(i = 0; i < ncolors; i++)
+ {
+ colors[i].red = prgbList[i].red;
+ colors[i].green = prgbList[i].green;
+ colors[i].blue = prgbList[i].blue;
+ }
+ Xfree(prgbList);
+
+ return(colors);
+}
+
+static void
+_swapshort (
+ register char *bp,
+ register unsigned n)
+{
+ register char c;
+ register char *ep = bp + n;
+
+ while (bp < ep) {
+ c = *bp;
+ *bp = *(bp + 1);
+ bp++;
+ *bp++ = c;
+ }
+}
+
+static void
+_swaplong (
+ register char *bp,
+ register unsigned n)
+{
+ register char c;
+ register char *ep = bp + n;
+ register char *sp;
+
+ while (bp < ep) {
+ sp = bp + 3;
+ c = *sp;
+ *sp = *bp;
+ *bp++ = c;
+ sp = bp + 1;
+ c = *sp;
+ *sp = *bp;
+ *bp++ = c;
+ bp += 2;
+ }
+}
+static int
+WriteWindowRaster(
+ WindowPtr pWin,
+ FILE *pRasterFile)
+{
+ long widthBytesLine, length;
+ int nlines, linesPerBuf, height, linesDone;
+ char *pBuf;
+ DrawablePtr pDraw = &pWin->drawable;
+ XWDFileHeader header;
+ int win_name_size;
+ int header_size;
+ int ncolors, i;
+ char *win_name;
+ VisualPtr pVisual;
+ ColormapPtr pCmap;
+ XWDColor *pColors;
+ unsigned long swaptest = 1;
+
+ widthBytesLine = PixmapBytePad(pWin->drawable.width, pWin->drawable.depth);
+ length = widthBytesLine * pWin->drawable.height;
+ height = pWin->drawable.height;
+
+ if(length <= 0)
+ return Success;
+
+ if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) && (length & 3))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & 3)
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = (char *) Xalloc(length)))
+ return (BadAlloc);
+
+ /*
+ * Start of Xwd header code.
+ */
+
+ /*
+ * XXX - Should we use the real window name???
+ */
+ win_name = "xwdump";
+ /* sizeof(char) is included for the null string terminator. */
+ win_name_size = strlen(win_name) + sizeof(char);
+
+ pCmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP);
+ pVisual = pCmap->pVisual;
+ if((pColors = Get_XWDColors(pCmap)) == (XWDColor *)NULL)
+ {
+ Xfree(pBuf);
+ return (BadAlloc);
+ }
+
+ /*
+ * Write out header information.
+ */
+ header_size = sizeof(header) + win_name_size;
+ header.header_size = (CARD32) header_size;
+ header.file_version = (CARD32) XWD_FILE_VERSION;
+ header.pixmap_format = (CARD32) ZPixmap; /* Must match GetImage below */
+ header.pixmap_depth = (CARD32) pDraw->depth;
+ header.pixmap_width = (CARD32) pDraw->width;
+ header.pixmap_height = (CARD32) pDraw->height;
+ header.xoffset = (CARD32) 0;
+ header.byte_order = (CARD32) screenInfo.imageByteOrder;
+ header.bitmap_unit = (CARD32) screenInfo.bitmapScanlineUnit;
+ header.bitmap_bit_order = (CARD32) screenInfo.bitmapBitOrder;
+ header.bitmap_pad = (CARD32) screenInfo.bitmapScanlinePad;
+ header.bits_per_pixel = (CARD32) pDraw->bitsPerPixel;
+ header.bytes_per_line = (CARD32) widthBytesLine;
+ header.visual_class = (CARD32) pVisual->class;
+ header.red_mask = (CARD32) pVisual->redMask;
+ header.green_mask = (CARD32) pVisual->greenMask;
+ header.blue_mask = (CARD32) pVisual->blueMask;
+ header.bits_per_rgb = (CARD32) pVisual->bitsPerRGBValue;
+ header.colormap_entries = (CARD32) pVisual->ColormapEntries;
+ header.ncolors = ncolors = (CARD32) pVisual->ColormapEntries;
+ header.window_width = (CARD32) pDraw->width;
+ header.window_height = (CARD32) pDraw->height;
+ header.window_x = 0;
+ header.window_y = 0;
+ header.window_bdrwidth = (CARD32) 0;
+
+ if (*(char *) &swaptest) {
+ _swaplong((char *) &header, sizeof(header));
+ for (i = 0; i < ncolors; i++) {
+ _swaplong((char *) &pColors[i].pixel, sizeof(long));
+ _swapshort((char *) &pColors[i].red, 3 * sizeof(short));
+ }
+ }
+
+ (void) fwrite((char *)&header, sizeof(header), 1, pRasterFile);
+ (void) fwrite(win_name, win_name_size, 1, pRasterFile);
+ (void) fwrite((char *) pColors, sizeof(XWDColor), ncolors, pRasterFile);
+
+ Xfree(pColors);
+
+ /*
+ * End of Xwd header code.
+ */
+
+ linesDone = 0;
+ while(height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ 0,
+ linesDone,
+ pWin->drawable.width,
+ nlines,
+ ZPixmap,
+ ~0,
+ pBuf);
+
+ if(fwrite(pBuf, sizeof(char), (size_t)(nlines * widthBytesLine),
+ pRasterFile) !=
+ (size_t)(nlines * widthBytesLine))
+ {
+ Xfree(pBuf);
+ return BadAlloc;
+ }
+ linesDone += nlines;
+ }
+ Xfree(pBuf);
+ return Success;
+}
+
+
+static int
+SendPage( XpContextPtr pCon )
+{
+ struct stat statBuf;
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+
+ if(stat(pConPriv->pageFileName, &statBuf) < 0)
+ return BadAlloc;
+
+ return XpSendDocumentData(pConPriv->getDocClient,
+ pConPriv->pPageFile, (int)statBuf.st_size,
+ pConPriv->getDocBufSize);
+}
+
+/*
+ * EndPage:
+ *
+ * If page file doesn't exist:
+ * {
+ * Create page file
+ * Open page file
+ * Write page header to page file
+ * if(preRasterFile exists)
+ * copy preRasterFile contents to page file
+ * if(noRasterFile exists)
+ * write noRasterFile contents to page file
+ * else
+ * Create raster image file
+ * Open raster image file
+ * GetImage data
+ * Write Image data to raster image file
+ * invoke page_command on raster image file
+ * Write raster image file contents to page file
+ * Unlink tempPage file
+ * if(postRasterFile exists)
+ * write postRasterFile contents to page file
+ * Write page trailer to page file
+ * }
+ * Write page file to job file
+ */
+static int
+EndPage(
+ XpContextPtr pCon,
+ WindowPtr pWin)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+ struct stat statBuf;
+ char *rasterFileName = (char *)NULL, *pCommand = (char *)NULL;
+ FILE *pRasterFile = (FILE *)NULL;
+
+ if(pConPriv->pageFileName == (char *)NULL)
+ {
+ /*
+ * Open the page file.
+ */
+ if (!XpOpenTmpFile("w+", &pConPriv->pageFileName,
+ &pConPriv->pPageFile))
+ goto BAD_PAGE_ALLOC;
+
+ /*
+ * Copy any pre-raster document data to the page file.
+ */
+ if(pConPriv->pPreRasterFile != (FILE *)NULL)
+ {
+ if(CopyContentsAndDelete(&pConPriv->pPreRasterFile,
+ &pConPriv->preRasterFileName,
+ pConPriv->pPageFile) == FALSE)
+ goto BAD_PAGE_ALLOC;
+ }
+
+ /*
+ * Copy either the no-raster document data, or the raster
+ * data itself to the page file.
+ * If the no-raster file exists, then we don't process the
+ * actual window raster bits.
+ */
+ if(pConPriv->pNoRasterFile != (FILE *)NULL)
+ {
+ if(CopyContentsAndDelete(&pConPriv->pNoRasterFile,
+ &pConPriv->noRasterFileName,
+ pConPriv->pPageFile) == FALSE)
+ goto BAD_PAGE_ALLOC;
+ }
+ else
+ {
+ /*
+ * Open the raster image file.
+ */
+ if (!XpOpenTmpFile("w", &rasterFileName, &pRasterFile))
+ goto BAD_PAGE_ALLOC;
+
+ /*
+ * Write the page image data to the raster image file.
+ */
+ if(WriteWindowRaster(pWin, pRasterFile) != Success)
+ goto BAD_PAGE_ALLOC;
+
+ /*
+ * Invoke the page_command on the raster image file.
+ */
+ if((pCommand = GetPropString(pCon, RASTER_PRINT_PAGE_COMMAND)) !=
+ (char *)NULL)
+ {
+ char *outFileName;
+ FILE *pOutFile;
+
+ if (!XpOpenTmpFile("w", &outFileName, &pOutFile))
+ goto BAD_PAGE_ALLOC;
+ fclose(pOutFile);
+
+ pCommand = ReplaceFileString(strdup(pCommand), rasterFileName,
+ outFileName);
+ fclose(pRasterFile);
+ SystemCmd(pCommand);
+ free(pCommand);
+ /*
+ * Delete the unprocessed raster file.
+ */
+ unlink(rasterFileName);
+ Xfree(rasterFileName);
+ rasterFileName = outFileName;
+ if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL)
+ goto BAD_PAGE_ALLOC;
+ }
+ else
+ {
+ fclose(pRasterFile);
+ if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL)
+ goto BAD_PAGE_ALLOC;
+ }
+
+ /*
+ * Copy the raster image file contents to the page file.
+ * Note that pRasterFile must be set to the start of the
+ * raster file.
+ */
+ if(CopyContentsAndDelete(&pRasterFile,
+ &rasterFileName,
+ pConPriv->pPageFile) == FALSE)
+ goto BAD_PAGE_ALLOC;
+ }
+
+ /*
+ * Copy any post-raster document data to the page file.
+ */
+ if(pConPriv->pPostRasterFile != (FILE *)NULL)
+ {
+ if(CopyContentsAndDelete(&pConPriv->pPostRasterFile,
+ &pConPriv->postRasterFileName,
+ pConPriv->pPageFile) == FALSE)
+ goto BAD_PAGE_ALLOC;
+ }
+
+ }
+
+ /*
+ * Write the page file contents to the job file or to the client
+ * performing GetDocumentData.
+ * pConPriv->pPageFile must first be set to the start of the page file.
+ */
+ rewind(pConPriv->pPageFile);
+ if(stat(pConPriv->pageFileName, &statBuf) < 0)
+ goto BAD_PAGE_ALLOC;
+
+ /*
+ * Send the page data to whatever client has called GetDocumentData.
+ */
+ if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0)
+ {
+ int retval;
+ /*
+ * We should do something like the following: suspend the
+ * caller until we can gracefully write all the data in small
+ * chunks to the receiver, but for now we'll just call WriteToClient
+ * on the huge chunk
+ */
+ retval = SendPage(pCon);
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ unlink(pConPriv->pageFileName);
+ free(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+ return retval;
+ }
+
+ if(pConPriv->pJobFile == (FILE *)NULL)
+ {
+ /*
+ * This shouldn't be necessary. I believe we only get here if
+ * someone calls "EndPage" prior to "StartJob". This error
+ * condition should probably be trapped at a higher level.
+ */
+
+ if(pConPriv->jobFileName != (char *)NULL)
+ Xfree(pConPriv->jobFileName);
+ /*
+ * Create a temporary file to store the printer output.
+ */
+ if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
+ goto BAD_PAGE_ALLOC;
+ }
+
+ if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile,
+ (int)statBuf.st_size) != (int)statBuf.st_size)
+ goto BAD_PAGE_ALLOC;
+
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ unlink(pConPriv->pageFileName);
+ free(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+
+ return Success;
+
+ BAD_PAGE_ALLOC:
+
+ FreePageFiles(pConPriv);
+
+ if(pRasterFile != (FILE *)NULL)
+ fclose(pRasterFile);
+ if(rasterFileName != (char *)NULL)
+ {
+ unlink(rasterFileName);
+ Xfree(rasterFileName);
+ }
+ return BadAlloc;
+}
+
+static int
+DocumentData(
+ XpContextPtr pCon,
+ DrawablePtr pDraw,
+ char *pData,
+ int len_data,
+ char *pDoc_fmt,
+ int len_fmt,
+ char *pOptions,
+ int len_options,
+ ClientPtr client)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+ char *preRasterStr = PRE_RASTER, *postRasterStr = POST_RASTER,
+ *noRasterStr = NO_RASTER;
+
+ /*
+ * Check that options equals either PRE_RASTER or POST_RASTER.
+ */
+ if(len_options == strlen(preRasterStr) &&
+ strncmp(pOptions, preRasterStr, strlen(preRasterStr)) == 0)
+ {
+ if(pConPriv->pPreRasterFile == (FILE *)NULL)
+ {
+ if (!XpOpenTmpFile("w+", &pConPriv->preRasterFileName,
+ &pConPriv->pPreRasterFile))
+ return BadAlloc;
+ }
+ if(fwrite(pData, sizeof(char), (size_t)len_data,
+ pConPriv->pPreRasterFile) != (size_t)len_data)
+ return BadAlloc;
+ fflush(pConPriv->pPreRasterFile);
+ }
+ else if(len_options == strlen(postRasterStr) &&
+ strncmp(pOptions, postRasterStr, strlen(postRasterStr)) == 0)
+ {
+ if(pConPriv->pPostRasterFile == (FILE *)NULL)
+ {
+ if (!XpOpenTmpFile("w+", &pConPriv->postRasterFileName,
+ &pConPriv->pPostRasterFile))
+ return BadAlloc;
+ }
+ if(fwrite(pData, sizeof(char), (size_t)len_data,
+ pConPriv->pPostRasterFile) != (size_t)len_data)
+ return BadAlloc;
+ fflush(pConPriv->pPostRasterFile);
+ }
+ else if(len_options == strlen(noRasterStr) &&
+ strncmp(pOptions, noRasterStr, strlen(noRasterStr)) == 0)
+ {
+ if(pConPriv->pNoRasterFile == (FILE *)NULL)
+ {
+ if (!XpOpenTmpFile("w+", &pConPriv->noRasterFileName,
+ &pConPriv->pNoRasterFile))
+ return BadAlloc;
+ }
+ if(fwrite(pData, sizeof(char), (size_t)len_data,
+ pConPriv->pNoRasterFile) != (size_t)len_data)
+ return BadAlloc;
+ fflush(pConPriv->pNoRasterFile);
+ }
+ else
+ return BadValue;
+
+ return Success;
+}
+
+/*
+ * GetDocumentData notes which client is requesting the document data for
+ * a particular context. The Raster driver's EndPage function causes the
+ * data to be written to the proper client.
+ */
+static int
+GetDocumentData(
+ XpContextPtr pContext,
+ ClientPtr client,
+ int maxBufferSize)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pContext->devPrivates[RasterContextPrivateIndex].ptr;
+
+ pConPriv->getDocClient = client;
+ pConPriv->getDocBufSize = maxBufferSize;
+ return Success;
+}
+
+static void
+AllocateRasterPrivates(
+ ScreenPtr pScreen)
+{
+ if(RasterGeneration != serverGeneration)
+ {
+ RasterScreenPrivateIndex = AllocateScreenPrivateIndex();
+ RasterContextPrivateIndex = XpAllocateContextPrivateIndex();
+ XpAllocateContextPrivate( RasterContextPrivateIndex,
+ sizeof( RasterContextPrivRec ) );
+
+ RasterGeneration = serverGeneration;
+ }
+ pScreen->devPrivates[RasterScreenPrivateIndex].ptr = (pointer)Xalloc(
+ sizeof(RasterScreenPrivRec));
+}
+
+/*
+ * RasterChangeWindowAttributes - Make sure that the window's backing
+ * store is turned on.
+ */
+static Bool
+RasterChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask)
+{
+ Bool status = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr)
+ pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
+
+ if(pWin->backingStore == NotUseful)
+ {
+ pWin->backingStore = WhenMapped;
+ mask |= CWBackingStore;
+ }
+
+ if(pScreenPriv->ChangeWindowAttributes != NULL)
+ {
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+ status = pScreen->ChangeWindowAttributes(pWin, mask);
+ pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes;
+ }
+ return status;
+}
+
+/*
+ * RasterValidateDocFormats - Inspects the files available in the
+ * ddx-config/XP-RASTER directory to find the names of PDLs for which
+ * we have processing commands. These names are then intersected with
+ * the contents of the printer's document-formats-supported attribute,
+ * and the result is stored back into document-formats-supported.
+ * We have hard-coded knowledge of how to produce PS, so we always
+ * leave that in, if it's listed in document-formats-supported,
+ * even if we don't have a configuration file. If there is a
+ * configuration file for PS, then its contents will override our default.
+ */
+static void
+RasterValidateDocFormats(
+ XpContextPtr pCon)
+{
+}
+
+/*
+ * RasterValidateAttrs - Inspects and Corrects the attribute values
+ * in the specified context.
+ */
+static void
+RasterValidateAttrs(
+ XpContextPtr pCon)
+{
+ RasterValidateDocFormats(pCon);
+ XpValidatePrinterPool(pCon, &RasterValidatePoolsRec);
+ XpValidateJobPool(pCon, &RasterValidatePoolsRec);
+ XpValidateDocumentPool(pCon, &RasterValidatePoolsRec);
+}
+
+/*
+ * RasterInitContext - Establish the appropriate values for a
+ * PrintContext used with the Raster Driver.
+ */
+static char DOC_ATT_SUPP[]="document-attributes-supported:\tdefault-medium document-format";
+static char JOB_ATT_SUPP[]="job-attributes-supported:\t";
+static char DDX_DIR[]="ddx-config";
+
+static int
+RasterInitContext(
+ XpContextPtr pCon)
+{
+ char *configFileName, *val, *attrStr;
+ RasterContextPrivPtr pConPriv;
+ XpDriverFuncsPtr pFuncs;
+
+ /*
+ * Initialize the attribute store for this printer.
+ */
+ XpInitAttributes( pCon );
+
+ /*
+ * Validate the attributes
+ */
+ RasterValidateAttrs( pCon );
+
+
+ /*
+ * Initialize the function pointers
+ */
+ pFuncs = &( pCon->funcs );
+ pFuncs->StartJob = StartJob;
+ pFuncs->EndJob = EndJob;
+ pFuncs->StartDoc = StartDoc;
+ pFuncs->EndDoc = EndDoc;
+ pFuncs->StartPage = StartPage;
+ pFuncs->EndPage = EndPage;
+ pFuncs->PutDocumentData = DocumentData;
+ pFuncs->GetDocumentData = GetDocumentData;
+ pFuncs->DestroyContext = RasterDestroyContext;
+ pFuncs->GetAttributes = RasterGetAttributes;
+ pFuncs->GetOneAttribute = RasterGetOneAttribute;
+ pFuncs->SetAttributes = RasterSetAttributes;
+ pFuncs->AugmentAttributes = RasterAugmentAttributes;
+ pFuncs->GetMediumDimensions = RasterMediumDimensions;
+ pFuncs->GetReproducibleArea = RasterReproducibleArea;
+
+ /*
+ * Set up the context privates
+ */
+ pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+
+ pConPriv->jobFileName = (char *)NULL;
+ pConPriv->pageFileName = (char *)NULL;
+ pConPriv->preRasterFileName = (char *)NULL;
+ pConPriv->postRasterFileName = (char *)NULL;
+ pConPriv->noRasterFileName = (char *)NULL;
+ pConPriv->pJobFile = (FILE *)NULL;
+ pConPriv->pPageFile = (FILE *)NULL;
+ pConPriv->pPreRasterFile = (FILE *)NULL;
+ pConPriv->pPostRasterFile = (FILE *)NULL;
+ pConPriv->pNoRasterFile = (FILE *)NULL;
+
+ pConPriv->getDocClient = (ClientPtr)NULL;
+ pConPriv->getDocBufSize = 0;
+
+ /*
+ * Get the configuration information for the context's printer
+ */
+ configFileName = XpGetOneAttribute( pCon, XPPrinterAttr,
+ "xp-ddx-config-file-name" );
+ if(configFileName && strlen(configFileName))
+ {
+ if( configFileName[0] == '/' )
+ pConPriv->config = XrmGetFileDatabase( configFileName );
+ else
+ {
+ char *configDir, *configFilePath;
+
+ configDir = XpGetConfigDir(FALSE);
+ configFilePath = (char *)malloc((strlen(configDir) +
+ strlen(DDX_DIR) +
+ strlen(RASTER_DRIV_NAME) +
+ strlen(configFileName) +
+ 4)* sizeof(char));
+ sprintf(configFilePath, "%s/%s/%s/%s", configDir, DDX_DIR,
+ RASTER_DRIV_NAME, configFileName);
+ pConPriv->config = XrmGetFileDatabase(configFilePath);
+ free(configDir);
+ free(configFilePath);
+ }
+ }
+ else
+ pConPriv->config = (XrmDatabase)NULL;
+
+ /*
+ * Add our own attribute initialization
+ */
+ /*
+ * document-attributes-supported
+ */
+ val = XpGetOneAttribute(pCon, XPServerAttr, "document-attributes-supported");
+ if((attrStr = (char *)xalloc(strlen(val) + strlen(DOC_ATT_SUPP) + 4)) ==
+ (char *)NULL)
+ return BadAlloc;
+ sprintf(attrStr, "*%s %s", DOC_ATT_SUPP, val);
+ XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
+ xfree(attrStr);
+
+ /*
+ * job-attributes-supported
+ */
+ val = XpGetOneAttribute(pCon, XPServerAttr, "job-attributes-supported");
+ if((attrStr = (char *)xalloc(strlen(val) + strlen(JOB_ATT_SUPP) + 4)) ==
+ (char *)NULL)
+ return BadAlloc;
+ sprintf(attrStr, "*%s %s", JOB_ATT_SUPP, val);
+ XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
+ xfree(attrStr);
+
+ /*
+ * PageAttributesSupported
+ */
+ XpAugmentAttributes(pCon, XPPrinterAttr, "*xp-page-attributes-supported:");
+
+ return Success;
+}
+
+
+
+static Bool
+RasterDestroyContext(
+ XpContextPtr pCon)
+{
+ RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
+ pCon->devPrivates[RasterContextPrivateIndex].ptr;
+
+ /*
+ * Clean up the temporary files
+ */
+ FreePageFiles( pConPriv );
+
+ if( pConPriv->pJobFile != (FILE *)NULL )
+ {
+ fclose( pConPriv->pJobFile );
+ pConPriv->pJobFile = (FILE *)NULL;
+ }
+ if( pConPriv->jobFileName != (char *)NULL )
+ {
+ unlink( pConPriv->jobFileName );
+ Xfree( pConPriv->jobFileName );
+ }
+ if(pConPriv->config)
+ {
+ XrmDestroyDatabase(pConPriv->config);
+ pConPriv->config = (XrmDatabase)NULL;
+ }
+
+ XpDestroyAttributes( pCon );
+ return Success;
+}
+
+static char *
+RasterGetAttributes(
+ XpContextPtr pContext,
+ XPAttributes class)
+{
+ return XpGetAttributes( pContext, class );
+}
+
+static char *
+RasterGetOneAttribute(
+ XpContextPtr pContext,
+ XPAttributes class,
+ char *attr)
+{
+ return XpGetOneAttribute( pContext, class, attr );
+}
+
+static int
+RasterSetAttributes(XpContextPtr pCon,
+ XPAttributes class,
+ char *attributes)
+{
+ return XpSetAttributes( pCon, class, attributes );
+}
+
+static int
+RasterAugmentAttributes(
+ XpContextPtr pCon,
+ XPAttributes class,
+ char *attributes)
+{
+ return XpAugmentAttributes( pCon, class, attributes );
+}
+
+static void
+FreePageFiles(
+ RasterContextPrivPtr pConPriv)
+{
+ if(pConPriv->pPageFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPageFile);
+ pConPriv->pPageFile = (FILE *)NULL;
+ }
+ if(pConPriv->pageFileName != (char *)NULL)
+ {
+ unlink(pConPriv->pageFileName);
+ Xfree(pConPriv->pageFileName);
+ pConPriv->pageFileName = (char *)NULL;
+ }
+ if(pConPriv->pPreRasterFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPreRasterFile);
+ pConPriv->pPreRasterFile = (FILE *)NULL;
+ }
+ if(pConPriv->preRasterFileName != (char *)NULL)
+ {
+ unlink(pConPriv->preRasterFileName);
+ Xfree(pConPriv->preRasterFileName);
+ pConPriv->preRasterFileName = (char *)NULL;
+ }
+ if(pConPriv->pPostRasterFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pPostRasterFile);
+ pConPriv->pPostRasterFile = (FILE *)NULL;
+ }
+ if(pConPriv->postRasterFileName != (char *)NULL)
+ {
+ unlink(pConPriv->postRasterFileName);
+ Xfree(pConPriv->postRasterFileName);
+ pConPriv->postRasterFileName = (char *)NULL;
+ }
+ if(pConPriv->pNoRasterFile != (FILE *)NULL)
+ {
+ fclose(pConPriv->pNoRasterFile);
+ pConPriv->pNoRasterFile = (FILE *)NULL;
+ }
+ if(pConPriv->noRasterFileName != (char *)NULL)
+ {
+ unlink(pConPriv->noRasterFileName);
+ Xfree(pConPriv->noRasterFileName);
+ pConPriv->noRasterFileName = (char *)NULL;
+ }
+}
+
+/*
+ * RasterCloseScreen - Call any wrapped CloseScreen function,
+ * and free the screen memory.
+ */
+static Bool
+RasterCloseScreen(
+ int index,
+ ScreenPtr pScreen)
+{
+ Bool status = Success;
+ RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr)
+ pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
+
+ /*
+ * Call any wrapped CloseScreen proc.
+ */
+ if(pScreenPriv->CloseScreen != NULL)
+ {
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ status = pScreen->CloseScreen(index, pScreen);
+ pScreen->CloseScreen = RasterCloseScreen;
+ }
+
+ Xfree(pScreenPriv->pBits);
+ Xfree(pScreenPriv);
+
+ return status;
+}
+
+#include <signal.h>
+
+/* ARGSUSED */
+static void SigchldHndlr (int dummy)
+{
+ int status;
+ int olderrno = errno;
+ struct sigaction act;
+ sigfillset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = SigchldHndlr;
+
+ (void) wait (&status);
+
+ /*
+ * Is this really necessary?
+ */
+ sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
+ errno = olderrno;
+}
+
+/*
+ * SystemCmd provides a wrapper for the 'system' library call. The call
+ * appears to be sensitive to the handling of SIGCHLD, so this wrapper
+ * sets the status to SIG_DFL, and then resets the established handler
+ * after system returns.
+ */
+static int
+SystemCmd(char *cmdStr)
+{
+ int status;
+ struct sigaction newAct, oldAct;
+ sigfillset(&newAct.sa_mask);
+ newAct.sa_flags = 0;
+ newAct.sa_handler = SIG_DFL;
+ sigfillset(&oldAct.sa_mask);
+ oldAct.sa_flags = 0;
+ oldAct.sa_handler = SigchldHndlr;
+
+ /*
+ * get the old handler, and set the action to IGN
+ */
+ sigaction(SIGCHLD, &newAct, &oldAct);
+
+ status = system (cmdStr);
+
+ sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL);
+ return status;
+}
+
+/*
+ * RasterMediumDimensions is installed in the GetMediumDimensions field
+ * of each raster-initialized context.
+ */
+static int
+RasterMediumDimensions(XpContextPtr pCon,
+ CARD16 *width,
+ CARD16 *height)
+{
+ XpGetMediumDimensions(pCon, width, height);
+ return Success;
+}
+
+/*
+ * RasterReproducibleArea is installed in the GetReproducibleArea field
+ * of each raster-initialized context.
+ */
+static int
+RasterReproducibleArea(XpContextPtr pCon,
+ xRectangle *pRect)
+{
+ XpGetReproductionArea(pCon, pRect);
+ return Success;
+}
diff --git a/hw/xprint/raster/Raster.h b/hw/xprint/raster/Raster.h
new file mode 100644
index 000000000..25da756e5
--- /dev/null
+++ b/hw/xprint/raster/Raster.h
@@ -0,0 +1,118 @@
+/* $Xorg: Raster.h,v 1.3 2000/08/17 19:48:12 cpqbld Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/*******************************************************************
+**
+** *********************************************************
+** *
+** * File: printer/Raster.h
+** *
+** * Contents: defines and includes for the raster layer
+** * for a printing X server.
+** *
+** * Copyright: Copyright 1993 Hewlett-Packard Company
+** *
+** *********************************************************
+**
+********************************************************************/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _RASTER_H_
+#define _RASTER_H_
+
+/*
+ * Some sleazes to force the XrmDB stuff into the server
+ */
+#ifndef HAVE_XPointer
+#define HAVE_XPointer 1
+typedef char *XPointer;
+#endif
+#define Status int
+#define True 1
+#define False 0
+#include "misc.h"
+#include <X11/Xfuncproto.h>
+#include <X11/Xresource.h>
+#include "attributes.h"
+
+#include <X11/extensions/Printstr.h>
+
+#define MAX_TOKEN_LEN 512
+
+#define RASTER_PRINT_PAGE_COMMAND "_XP_RASTER_PAGE_PROC_COMMAND"
+
+#define RASTER_IN_FILE_STRING "%(InFile)%"
+#define RASTER_OUT_FILE_STRING "%(OutFile)%"
+
+#define RASTER_ALLOWED_COMMANDS_FILE "printCommands"
+
+/*
+ * Defines for the "options" in DtPrintDocumentData.
+ */
+#define PRE_RASTER "PRE-RASTER"
+#define POST_RASTER "POST-RASTER"
+#define NO_RASTER "NO-RASTER"
+
+
+typedef struct {
+ char *pBits;
+ CreateWindowProcPtr CreateWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ DestroyWindowProcPtr DestroyWindow;
+ CloseScreenProcPtr CloseScreen;
+} RasterScreenPrivRec, *RasterScreenPrivPtr;
+
+typedef struct {
+ XrmDatabase config;
+ char *jobFileName;
+ FILE *pJobFile;
+ char *pageFileName;
+ FILE *pPageFile;
+ char *preRasterFileName; /* Pre-raster document data */
+ FILE *pPreRasterFile;
+ char *noRasterFileName; /* Raster replacement document data */
+ FILE *pNoRasterFile;
+ char *postRasterFileName; /* Post-raster document data */
+ FILE *pPostRasterFile;
+ ClientPtr getDocClient;
+ int getDocBufSize;
+} RasterContextPrivRec, *RasterContextPrivPtr;
+
+
+extern XpValidatePoolsRec RasterValidatePoolsRec;
+
+extern Bool InitializeRasterDriver(int ndx, ScreenPtr pScreen, int argc,
+ char **argv);
+
+#endif /* _RASTER_H_ */
diff --git a/hw/xprint/raster/RasterAttVal.c b/hw/xprint/raster/RasterAttVal.c
new file mode 100644
index 000000000..fc00cde5a
--- /dev/null
+++ b/hw/xprint/raster/RasterAttVal.c
@@ -0,0 +1,269 @@
+/* $Xorg: RasterAttVal.c,v 1.4 2001/03/14 18:46:34 pookie Exp $ */
+/*
+(c) Copyright 1996 Hewlett-Packard Company
+(c) Copyright 1996 International Business Machines Corp.
+(c) Copyright 1996 Sun Microsystems, Inc.
+(c) Copyright 1996 Novell, Inc.
+(c) Copyright 1996 Digital Equipment Corp.
+(c) Copyright 1996 Fujitsu Limited
+(c) Copyright 1996 Hitachi, Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+/* $XFree86: xc/programs/Xserver/Xprint/raster/RasterAttVal.c,v 1.3 2001/10/31 22:50:29 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "screenint.h"
+#include <X11/extensions/Print.h>
+#include "Raster.h"
+
+#include "attributes.h"
+#include "AttrValid.h"
+
+/*
+ * define valid values and defaults for Printer pool
+ */
+static XpOid ValidContentOrientationsOids[] = {
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape
+};
+static XpOidList ValidContentOrientations = {
+ ValidContentOrientationsOids, XpNumber(ValidContentOrientationsOids)
+};
+
+static XpOid DefaultContentOrientationsOids[] = {
+ xpoid_val_content_orientation_portrait,
+ xpoid_val_content_orientation_landscape
+};
+static XpOidList DefaultContentOrientations = {
+ DefaultContentOrientationsOids, XpNumber(DefaultContentOrientationsOids)
+};
+
+static XpOid ValidPlexesOids[] = {
+ xpoid_val_plex_simplex
+};
+static XpOidList ValidPlexes = {
+ ValidPlexesOids, XpNumber(ValidPlexesOids)
+};
+
+static XpOid DefaultPlexesOids[] = {
+ xpoid_val_plex_simplex
+};
+static XpOidList DefaultPlexes = {
+ DefaultPlexesOids, XpNumber(DefaultPlexesOids)
+};
+
+static unsigned long ValidPrinterResolutionsCards[] = {
+ 150, 300, 600
+};
+static XpOidCardList ValidPrinterResolutions = {
+ ValidPrinterResolutionsCards, XpNumber(ValidPrinterResolutionsCards)
+};
+
+static unsigned long DefaultPrinterResolutionsCards[] = {
+ 300
+};
+static XpOidCardList DefaultPrinterResolutions = {
+ DefaultPrinterResolutionsCards, XpNumber(DefaultPrinterResolutionsCards)
+};
+
+static XpOid ValidListfontsModesOids[] = {
+ xpoid_val_xp_list_glyph_fonts
+};
+static XpOidList ValidListfontsModes = {
+ ValidListfontsModesOids, XpNumber(ValidListfontsModesOids)
+};
+
+static XpOid DefaultListfontsModesOids[] = {
+ xpoid_val_xp_list_glyph_fonts
+};
+static XpOidList DefaultListfontsModes = {
+ DefaultListfontsModesOids, XpNumber(DefaultListfontsModesOids)
+};
+
+static XpOid ValidSetupProvisoOids[] = {
+ xpoid_val_xp_setup_mandatory, xpoid_val_xp_setup_optional
+};
+static XpOidList ValidSetupProviso = {
+ ValidSetupProvisoOids, XpNumber(ValidSetupProvisoOids)
+};
+
+static XpOidDocFmt ValidDocFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL },
+ { "PCL", "3", NULL }
+};
+static XpOidDocFmtList ValidDocFormatsSupported = {
+ ValidDocFormatsSupportedFmts, XpNumber(ValidDocFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultDocFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList DefaultDocFormatsSupported = {
+ DefaultDocFormatsSupportedFmts, XpNumber(DefaultDocFormatsSupportedFmts)
+};
+
+static XpOidDocFmtList ValidEmbeddedFormatsSupported = {
+ (XpOidDocFmt *)NULL, 0
+};
+
+static XpOidDocFmtList DefaultEmbeddedFormatsSupported = {
+ (XpOidDocFmt *)NULL, 0
+};
+
+static XpOidDocFmt ValidRawFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL },
+ { "PCL", "3", NULL }
+};
+static XpOidDocFmtList ValidRawFormatsSupported = {
+ ValidRawFormatsSupportedFmts, XpNumber(ValidRawFormatsSupportedFmts)
+};
+
+static XpOidDocFmt DefaultRawFormatsSupportedFmts[] = {
+ { "Postscript", "2", NULL }
+};
+static XpOidDocFmtList DefaultRawFormatsSupported = {
+ DefaultRawFormatsSupportedFmts, XpNumber(DefaultRawFormatsSupportedFmts)
+};
+
+static XpOidList ValidInputTrays = {
+ (XpOid *)NULL, 0
+};
+
+static XpOid ValidMediumSizesOids[] = {
+ xpoid_val_medium_size_iso_a0,
+ xpoid_val_medium_size_iso_a1,
+ xpoid_val_medium_size_iso_a2,
+ xpoid_val_medium_size_iso_a3,
+ xpoid_val_medium_size_iso_a4,
+ xpoid_val_medium_size_iso_a5,
+ xpoid_val_medium_size_iso_a6,
+ xpoid_val_medium_size_iso_a7,
+ xpoid_val_medium_size_iso_a8,
+ xpoid_val_medium_size_iso_a9,
+ xpoid_val_medium_size_iso_a10,
+ xpoid_val_medium_size_iso_b0,
+ xpoid_val_medium_size_iso_b1,
+ xpoid_val_medium_size_iso_b2,
+ xpoid_val_medium_size_iso_b3,
+ xpoid_val_medium_size_iso_b4,
+ xpoid_val_medium_size_iso_b5,
+ xpoid_val_medium_size_iso_b6,
+ xpoid_val_medium_size_iso_b7,
+ xpoid_val_medium_size_iso_b8,
+ xpoid_val_medium_size_iso_b9,
+ xpoid_val_medium_size_iso_b10,
+ xpoid_val_medium_size_na_letter,
+ xpoid_val_medium_size_na_legal,
+ xpoid_val_medium_size_executive,
+ xpoid_val_medium_size_folio,
+ xpoid_val_medium_size_invoice,
+ xpoid_val_medium_size_ledger,
+ xpoid_val_medium_size_quarto,
+ xpoid_val_medium_size_iso_c3,
+ xpoid_val_medium_size_iso_c4,
+ xpoid_val_medium_size_iso_c5,
+ xpoid_val_medium_size_iso_c6,
+ xpoid_val_medium_size_iso_designated_long,
+ xpoid_val_medium_size_na_10x13_envelope,
+ xpoid_val_medium_size_na_9x12_envelope,
+ xpoid_val_medium_size_na_number_10_envelope,
+ xpoid_val_medium_size_na_7x9_envelope,
+ xpoid_val_medium_size_na_9x11_envelope,
+ xpoid_val_medium_size_na_10x14_envelope,
+ xpoid_val_medium_size_na_number_9_envelope,
+ xpoid_val_medium_size_monarch_envelope,
+ xpoid_val_medium_size_a,
+ xpoid_val_medium_size_b,
+ xpoid_val_medium_size_c,
+ xpoid_val_medium_size_d,
+ xpoid_val_medium_size_e,
+ xpoid_val_medium_size_jis_b0,
+ xpoid_val_medium_size_jis_b1,
+ xpoid_val_medium_size_jis_b2,
+ xpoid_val_medium_size_jis_b3,
+ xpoid_val_medium_size_jis_b4,
+ xpoid_val_medium_size_jis_b5,
+ xpoid_val_medium_size_jis_b6,
+ xpoid_val_medium_size_jis_b7,
+ xpoid_val_medium_size_jis_b8,
+ xpoid_val_medium_size_jis_b9,
+ xpoid_val_medium_size_jis_b10
+};
+static XpOidList ValidMediumSizes = {
+ ValidMediumSizesOids, XpNumber(ValidMediumSizesOids)
+};
+
+static XpOidDocFmt DefaultDocumentFormat = {
+ "Postscript", "2", NULL
+};
+
+static XpOid ValidAvailableCompressionsOids[] = {
+ xpoid_val_available_compressions_0,
+ xpoid_val_available_compressions_01,
+ xpoid_val_available_compressions_02,
+ xpoid_val_available_compressions_03,
+ xpoid_val_available_compressions_012,
+ xpoid_val_available_compressions_013,
+ xpoid_val_available_compressions_023,
+ xpoid_val_available_compressions_0123
+};
+
+static XpOidList ValidAvailableCompressions = {
+ ValidAvailableCompressionsOids, XpNumber(ValidAvailableCompressionsOids)
+};
+
+static XpOid DefaultAvailableCompressionsOids[] = {
+ xpoid_val_available_compressions_0123,
+ xpoid_val_available_compressions_0
+};
+
+static XpOidList DefaultAvailableCompressions = {
+ DefaultAvailableCompressionsOids, XpNumber(DefaultAvailableCompressionsOids)
+};
+
+
+/*
+ * init struct for XpValidate*Pool
+ */
+XpValidatePoolsRec RasterValidatePoolsRec = {
+ &ValidContentOrientations, &DefaultContentOrientations,
+ &ValidDocFormatsSupported, &DefaultDocFormatsSupported,
+ &ValidInputTrays, &ValidMediumSizes,
+ &ValidPlexes, &DefaultPlexes,
+ &ValidPrinterResolutions, &DefaultPrinterResolutions,
+ &ValidEmbeddedFormatsSupported, &DefaultEmbeddedFormatsSupported,
+ &ValidListfontsModes, &DefaultListfontsModes,
+ &ValidRawFormatsSupported, &DefaultRawFormatsSupported,
+ &ValidSetupProviso,
+ &DefaultDocumentFormat,
+ &ValidAvailableCompressions, &DefaultAvailableCompressions
+};
diff --git a/hw/xprint/spooler.c b/hw/xprint/spooler.c
new file mode 100644
index 000000000..f709c57ab
--- /dev/null
+++ b/hw/xprint/spooler.c
@@ -0,0 +1,204 @@
+
+/* $Xorg: spooler.c,v 1.1 2003/09/14 1:19:56 gisburn Exp $ */
+/*
+Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+Copyright (c) 2004 Sun Microsystems, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#ifdef __hpux
+#include <sys/sysmacros.h>
+#endif
+
+#include "spooler.h"
+
+/*
+ * The string LIST_QUEUES_* is fed to a shell to generate an ordered
+ * list of available printers on the system. These string definitions
+ * are taken from the file PrintSubSys.C within the code for the
+ * dtprintinfo program.
+ */
+#define LIST_QUEUES_AIX4 \
+ "lsallq | grep -v '^bsh$' | sort | uniq"
+
+#define LIST_QUEUES_HPUX \
+ "LANG=C lpstat -v | " \
+ "awk '" \
+ " $2 == \"for\" " \
+ " { " \
+ " x = match($3, /:/); " \
+ " print substr($3, 1, x-1)" \
+ " }' | sort | uniq"
+
+#define LIST_QUEUES_OSF \
+ "LANG=C lpstat -v | " \
+ "nawk '" \
+ " $2 == \"for\" " \
+ " { print $4 }' " \
+ " | sort | uniq"
+
+#define LIST_QUEUES_UXP \
+ "LANG=C lpstat -v |" \
+ "nawk '" \
+ " $4 == \"for\" " \
+ " { " \
+ " x = match($5, /:/); " \
+ " print substr($5, 1, x-1)" \
+ " }' | sort | uniq"
+
+/* Support both normal and LPRng output of "lpc status" */
+#define LIST_QUEUES_BSD \
+ "PATH=\"${PATH}:/usr/bin:/usr/sbin:/bin:/sbin\"\n" \
+ "export PATH\n" \
+ \
+ "which_tool()\n" \
+ "{\n" \
+ " echo \"${PATH}\" | tr \":\" \"\n\" | while read i ; do ls -1ad \"${i}/${1}\" 2>/dev/null ; done\n" \
+ "}\n" \
+ \
+ "(\n" \
+ "WHICH_LPC=\"`which_tool lpc`\"\n" \
+ \
+ "if [ \"`which_tool nawk`\" != \"\" ] ; then\n" \
+ " NAWK=\"nawk\"\n" \
+ "else\n" \
+ " NAWK=\"awk\"\n" \
+ "fi\n" \
+ \
+ "[ \"${WHICH_LPC}\" != \"\" ] && (LANG=C lpc status | ${NAWK} '/^[^ ]*:$/ && !/@/ && !/ / { print $1 }' | sed -e /:/s///)\n" \
+ "[ \"${WHICH_LPC}\" != \"\" ] && (LANG=C lpc -a status | ${NAWK} '/^[^ ]*@[^ ]/ && !/:$/ { split( $1, name, \"@\" ); print name[1]; }')\n" \
+ ") | egrep -v -i \" |^all$\" | sort | uniq"
+
+#define LIST_QUEUES_SYSV \
+ "PATH=\"${PATH}:/usr/bin:/usr/sbin:/bin:/sbin\"\n" \
+ "export PATH\n" \
+ \
+ "which_tool()\n" \
+ "{\n" \
+ " echo \"${PATH}\" | tr \":\" \"\n\" | while read i ; do ls -1ad \"${i}/${1}\" 2>/dev/null ; done\n" \
+ "}\n" \
+ \
+ "(\n" \
+ "WHICH_LPSTAT=\"`which_tool lpstat`\"\n" \
+ \
+ "if [ \"`which_tool nawk`\" != \"\" ] ; then\n" \
+ " NAWK=\"nawk\"\n" \
+ "else\n" \
+ " NAWK=\"awk\"\n" \
+ "fi\n" \
+ \
+ "[ \"${WHICH_LPSTAT}\" != \"\" ] && (LANG=C lpstat -v | ${NAWK} ' $2 == \"for\" { x = match($3, /:/); print substr($3, 1, x-1) }')\n" \
+ ") | egrep -v -i \" |^all$\" | sort | uniq"
+
+#define LIST_QUEUES_SOLARIS "LANG=C lpget -k description " \
+ "`lpstat -v " \
+ "| nawk '$2 == \"for\" { x = match($3, /:/); print substr($3, 1,x-1) }' " \
+ "| sort -u` " \
+ "| nawk -F: ' NF == 2 { name=$1 } " \
+ " NF == 1 { sub(\"^.*description\\( - undefined|=\\)\",\"\"); " \
+ " printf \"%s\txp-printerattr.descriptor=%s\\n\", name, $1 } '"
+
+#define LIST_QUEUES_OTHER \
+ "LANG=C lpstat -v | " \
+ "nawk '" \
+ " $2 == \"for\" " \
+ " { " \
+ " x = match($3, /:/); " \
+ " print substr($3, 1, x-1)" \
+ " }' | sort | uniq"
+
+#define DEFAULT_SPOOL_COMMAND_HPUX "/usr/bin/lp -d %printer-name% -o raw -n %copy-count% -t %job-name% %options%"
+#define DEFAULT_SPOOL_COMMAND_BSD "/usr/bin/lpr -P %printer-name% -#%copy-count% -T %job-name% %options%"
+#define DEFAULT_SPOOL_COMMAND_SYSV "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"
+#define DEFAULT_SPOOL_COMMAND_SOLARIS "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"
+#define DEFAULT_SPOOL_COMMAND_OTHER "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"
+
+
+/* List of spooler types and the commands used to enumerate
+ * print queues and submit print jobs */
+XpSpoolerType xpstm[] =
+{
+ /* OS-specific spoolers */
+ { "aix", LIST_QUEUES_AIX4, DEFAULT_SPOOL_COMMAND_OTHER },
+ { "aix4", LIST_QUEUES_AIX4, DEFAULT_SPOOL_COMMAND_OTHER },
+ { "bsd", LIST_QUEUES_BSD, DEFAULT_SPOOL_COMMAND_BSD },
+ { "osf", LIST_QUEUES_OSF, DEFAULT_SPOOL_COMMAND_OTHER },
+ { "solaris", LIST_QUEUES_SOLARIS, DEFAULT_SPOOL_COMMAND_SOLARIS },
+ { "sysv", LIST_QUEUES_SYSV, DEFAULT_SPOOL_COMMAND_SYSV },
+ { "uxp", LIST_QUEUES_UXP, DEFAULT_SPOOL_COMMAND_OTHER },
+ /* crossplatform spoolers */
+ { "cups", LIST_QUEUES_SYSV, DEFAULT_SPOOL_COMMAND_SYSV },
+ { "lprng", LIST_QUEUES_BSD, DEFAULT_SPOOL_COMMAND_BSD },
+ /* misc */
+ { "other", LIST_QUEUES_OTHER, DEFAULT_SPOOL_COMMAND_OTHER },
+ { "none", NULL, NULL },
+ { NULL, NULL, NULL }
+};
+
+/* Used by Init.c and attributes.c */
+XpSpoolerTypePtr spooler_type = NULL;
+
+XpSpoolerTypePtr XpSpoolerNameToXpSpoolerType(char *name)
+{
+ XpSpoolerTypePtr curr = xpstm;
+
+ while( curr->name != NULL )
+ {
+ if( !strcasecmp(name, curr->name) )
+ return curr;
+
+ curr++;
+ }
+
+ return NULL;
+}
+
+static char *spooler_namelist = NULL;
+
+char *XpGetSpoolerTypeNameList(void)
+{
+ if( spooler_namelist )
+ return spooler_namelist;
+
+ return XPDEFAULTSPOOLERNAMELIST;
+}
+
+void XpSetSpoolerTypeNameList(char *namelist)
+{
+ spooler_namelist = namelist;
+}
+
+
diff --git a/hw/xprint/spooler.h b/hw/xprint/spooler.h
new file mode 100644
index 000000000..4e9b4aefc
--- /dev/null
+++ b/hw/xprint/spooler.h
@@ -0,0 +1,76 @@
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef SPOOLER_H
+#define SPOOLER_H 1
+
+/* $Xorg: spooler.h,v 1.1 2003/09/14 1:19:56 gisburn Exp $ */
+/*
+Copyright (c) 2003-2004 Roland Mainz <roland.mainz@nrubsig.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the names of the copyright holders shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from said
+copyright holders.
+*/
+
+/*
+ * Define platform-specific default spooler type
+ */
+#if defined(sun)
+#define XPDEFAULTSPOOLERNAMELIST "solaris"
+#elif defined(AIXV4)
+#define XPDEFAULTSPOOLERNAMELIST "aix4"
+#elif defined(hpux)
+#define XPDEFAULTSPOOLERNAMELIST "hpux"
+#elif defined(__osf__)
+#define XPDEFAULTSPOOLERNAMELIST "osf"
+#elif defined(__uxp__)
+#define XPDEFAULTSPOOLERNAMELIST "uxp"
+#elif defined(CSRG_BASED) || defined(linux)
+/* ToDo: This should be "cups:bsd" in the future, but for now
+ * the search order first-bsd-then-cups is better for backwards
+ * compatibility.
+ */
+#define XPDEFAULTSPOOLERNAMELIST "bsd:cups"
+#else
+#define XPDEFAULTSPOOLERNAMELIST "other"
+#endif
+
+typedef struct
+{
+ const char *name;
+ const char *list_queues_command;
+ const char *spool_command;
+} XpSpoolerType, *XpSpoolerTypePtr;
+
+/* prototypes */
+extern XpSpoolerTypePtr XpSpoolerNameToXpSpoolerType(char *name);
+extern void XpSetSpoolerTypeNameList(char *namelist);
+extern char *XpGetSpoolerTypeNameList(void);
+
+/* global vars */
+extern XpSpoolerTypePtr spooler_type;
+extern XpSpoolerType xpstm[];
+
+#endif /* !SPOOLER_H */
+