2 (c) Copyright 1996 Hewlett-Packard Company
3 (c) Copyright 1996 International Business Machines Corp.
4 (c) Copyright 1996 Sun Microsystems, Inc.
5 (c) Copyright 1996 Novell, Inc.
6 (c) Copyright 1996 Digital Equipment Corp.
7 (c) Copyright 1996 Fujitsu Limited
8 (c) Copyright 1996 Hitachi, Ltd.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 Except as contained in this notice, the names of the copyright holders shall
28 not be used in advertising or otherwise to promote the sale, use or other
29 dealings in this Software without prior written authorization from said
34 /*******************************************************************
36 ** *********************************************************
38 ** * File: printer/Raster.c
41 ** * Raster driver for the print server.
43 ** * Copyright: Copyright 1993, 1995 Hewlett-Packard Company
45 ** *********************************************************
47 ********************************************************************/
49 #ifdef HAVE_DIX_CONFIG_H
50 #include <dix-config.h>
59 #include <sys/types.h>
62 #include <X11/Xos.h> /* for SIGCLD on pre-POSIX systems */
64 #include <X11/Xproto.h>
66 #include <X11/Xatom.h>
68 #include "dixstruct.h"
69 #include "scrnintstr.h"
70 #include "screenint.h"
71 #include "colormapst.h"
72 #include "windowstr.h"
73 #include "propertyst.h"
74 #include "servermd.h" /* needed for IMAGE_BUFSIZE */
78 #include <X11/extensions/Print.h>
81 #include "attributes.h"
82 #include "AttrValid.h"
85 static void AllocateRasterPrivates(
87 static Bool
RasterChangeWindowAttributes(
109 static int DocumentData(
119 static int GetDocumentData(
120 XpContextPtr pContext
,
123 static void FreePageFiles(
124 RasterContextPrivPtr pWinPriv
);
125 static int SystemCmd(
127 static Bool
RasterCloseScreen(
130 static int RasterInitContext(XpContextPtr pCon
);
131 static Bool
RasterDestroyContext(XpContextPtr pCon
);
132 static char *RasterGetAttributes(
133 XpContextPtr pContext
,
135 static char *RasterGetOneAttribute(XpContextPtr pCon
,
138 static int RasterSetAttributes(XpContextPtr pCon
,
141 static int RasterAugmentAttributes(XpContextPtr pCon
,
144 static int RasterMediumDimensions(XpContextPtr pCon
,
147 static int RasterReproducibleArea(XpContextPtr pCon
,
150 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
154 static int RasterScreenPrivateIndex
, RasterContextPrivateIndex
;
155 static int RasterGeneration
= 0;
156 static char RASTER_DRIV_NAME
[] = "XP-RASTER";
157 static int doc_type
= DOC_RASTER
;
159 #define ABSOLUTE_PCLCOMP_PATH1 "/usr/openwin/bin/pclcomp"
160 #define ABSOLUTE_PCLCOMP_PATH2 "/usr/X11/bin/pclcomp"
162 static char *pcl3_output_cmds
[] = {
163 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0 > %(OutFile)%",
164 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -01 > %(OutFile)%",
165 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -02 > %(OutFile)%",
166 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -03 > %(OutFile)%",
167 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -012 > %(OutFile)%",
168 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -013 > %(OutFile)%",
169 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -023 > %(OutFile)%",
170 "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0123 > %(OutFile)%",
171 "xpr -device ljet -rv -landscape < %(InFile)% > %(OutFile)%",
172 "xpr -device ljet -rv < %(InFile)% | pclcomp -0 > %(OutFile)%",
173 "xpr -device ljet -rv < %(InFile)% | pclcomp -01 > %(OutFile)%",
174 "xpr -device ljet -rv < %(InFile)% | pclcomp -02 > %(OutFile)%",
175 "xpr -device ljet -rv < %(InFile)% | pclcomp -03 > %(OutFile)%",
176 "xpr -device ljet -rv < %(InFile)% | pclcomp -012 > %(OutFile)%",
177 "xpr -device ljet -rv < %(InFile)% | pclcomp -013 > %(OutFile)%",
178 "xpr -device ljet -rv < %(InFile)% | pclcomp -023 > %(OutFile)%",
179 "xpr -device ljet -rv < %(InFile)% | pclcomp -0123 > %(OutFile)%",
180 "xpr -device ljet -rv < %(InFile)% > %(OutFile)%"};
183 InitializeRasterDriver(
190 int maxRes
, maxDim
, numBytes
;
191 RasterScreenPrivPtr pPriv
;
194 * Register this driver's InitContext function with the print extension.
196 * sleazy, as the extension hasn't yet been initialized, but the
197 * extension needs to know this, and this seems the best time to
198 * provide the information.
200 XpRegisterInitFunc( pScreen
, RASTER_DRIV_NAME
, RasterInitContext
);
203 * Create and load the devPrivate for the printer layer.
205 AllocateRasterPrivates(pScreen
);
207 pPriv
= (RasterScreenPrivPtr
)
208 pScreen
->devPrivates
[RasterScreenPrivateIndex
].ptr
;
210 maxDim
= MAX( pScreen
->height
, pScreen
->width
);
211 numBytes
= maxDim
+ BITMAP_SCANLINE_PAD
- 1; /* pixels per row */
213 numBytes
/= 8; /* bytes per row */
214 xRes
= pScreen
->width
/ (pScreen
->mmWidth
/ 25.4);
215 yRes
= pScreen
->height
/ (pScreen
->mmHeight
/ 25.4);
216 maxRes
= MAX( xRes
, yRes
);
218 pPriv
->pBits
= (char *)xalloc(numBytes
);
221 * Have to allocate maxDim X maxDim to allow for landscape mode.
223 fbScreenInit(pScreen
, pPriv
->pBits
, maxDim
, maxDim
, maxRes
,
225 miInitializeBackingStore(pScreen
);
226 pScreen
->blackPixel
= 1;
227 pScreen
->whitePixel
= 0;
228 if(fbCreateDefColormap(pScreen
) == FALSE
)
229 ; /* XXX what do I do if it fails? */
231 pScreen
->SaveScreen
= (SaveScreenProcPtr
)_XpBoolNoop
;
232 pPriv
->ChangeWindowAttributes
= pScreen
->ChangeWindowAttributes
;
233 pScreen
->ChangeWindowAttributes
= RasterChangeWindowAttributes
;
234 pPriv
->CloseScreen
= pScreen
->CloseScreen
;
235 pScreen
->CloseScreen
= RasterCloseScreen
;
241 * GetPropString searches the context's config database for a property
242 * by the name of propName. If found, it returns the property's
243 * value, otherwise it returns NULL unless the requested attribute
244 * is RASTER_PRINT_PAGE_COMMAND, in which case it returns a hard-coded
245 * default string to invoke xpr to produce a PostScript(tm) formatted
254 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
255 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
259 int pclcomp_exists
= 0;
261 if( XrmGetResource(pConPriv
->config
, propName
, propName
, &type
, &val
) ==
263 return (char *)val
.addr
;
265 if( !strcmp( propName
, RASTER_PRINT_PAGE_COMMAND
) )
266 if( doc_type
== DOC_RASTER
)
267 return "xpr -device ps %(InFile)% > %(OutFile)%";
272 int pcl3_output_index
= 0;
274 orientation
= XpGetContentOrientation(pCon
);
275 compression
= XpGetAvailableCompression(pCon
);
277 switch(orientation
) {
278 case xpoid_val_content_orientation_landscape
:
279 pcl3_output_index
= 0;
282 pcl3_output_index
+= 9;
286 if(stat(ABSOLUTE_PCLCOMP_PATH1
, &status
) != -1)
288 else if(stat(ABSOLUTE_PCLCOMP_PATH2
, &status
) != -1)
292 switch(compression
) {
293 case xpoid_val_available_compressions_0
:
294 pcl3_output_index
+= 0;
296 case xpoid_val_available_compressions_01
:
297 pcl3_output_index
+= 1;
299 case xpoid_val_available_compressions_02
:
300 pcl3_output_index
+= 2;
302 case xpoid_val_available_compressions_03
:
303 pcl3_output_index
+= 3;
305 case xpoid_val_available_compressions_012
:
306 pcl3_output_index
+= 4;
308 case xpoid_val_available_compressions_013
:
309 pcl3_output_index
+= 5;
311 case xpoid_val_available_compressions_023
:
312 pcl3_output_index
+= 6;
315 pcl3_output_index
+= 7;
319 pcl3_output_index
+= 8;
321 return pcl3_output_cmds
[pcl3_output_index
];
331 XpOidList
* attrs_supported
;
334 * only validate attributes found in document-attributes-supported
337 XpGetListAttr(pCon
, XPPrinterAttr
,
338 xpoid_att_document_attributes_supported
,
339 (const XpOidList
*)NULL
);
341 if(XpOidListHasOid(attrs_supported
, xpoid_att_document_format
))
343 const char* value_in
;
346 value_in
= XpGetStringAttr(pCon
, XPDocAttr
, xpoid_att_document_format
);
348 f
= XpOidDocFmtNew( value_in
);
352 if( !strcmp( f
->format
, "PCL" ) )
355 doc_type
= DOC_RASTER
;
357 XpOidDocFmtDelete( f
);
364 XpOidListDelete(attrs_supported
);
373 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
374 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
376 SetDocumentType( pCon
);
379 * Check for existing page file, and delete it if it exists.
381 if(pConPriv
->pageFileName
!= (char *)NULL
)
383 if(pConPriv
->pPageFile
!= (FILE *)NULL
)
385 fclose(pConPriv
->pPageFile
);
386 pConPriv
->pPageFile
= (FILE *)NULL
;
388 unlink(pConPriv
->pageFileName
);
389 Xfree(pConPriv
->pageFileName
);
390 pConPriv
->pageFileName
= (char *)NULL
;
394 * Create a temporary file to store the printer output.
399 * Create a temporary file to store the printer output.
401 if (!XpOpenTmpFile("w", &pConPriv
->jobFileName
, &pConPriv
->pJobFile
))
409 * StartDoc and EndDoc are just no-ops in this implementation, since
410 * our view of the spooler really doesn't recognize documents.
433 * BuidArgVector takes a pointer to a comma-separated list of command
434 * options and splits it out into an array of argument pointers. The
435 * caller must not free the optionList after calling this function until
436 * the returned arg vector is no longer needed, at which time the arg
437 * vector should also be freed.
440 #define SEPARATOR_CHAR (char)','
448 char *curArg
, *lastChar
, *endArg
;
451 lastChar
= optionList
+ strlen(optionList
); /* includes final NULL */
453 while(curArg
!= (char *)NULL
&& curArg
< lastChar
)
455 /* strip leading white space */
456 while(curArg
< lastChar
&& isascii((int)*curArg
) &&
457 isspace((int)*curArg
))
460 if(curArg
< lastChar
)
462 argVector
= (char **)Xrealloc(argVector
,
463 sizeof(char *) * (argCount
+ 2));
464 argVector
[argCount
] = curArg
;
465 argVector
[++argCount
] = (char *)NULL
;
467 endArg
= strchr(curArg
, SEPARATOR_CHAR
);
469 /* Should I strip trailing white space ??? */
471 if(endArg
!= (char *)NULL
)
473 *endArg
= (char)'\0';
477 curArg
= (char *)NULL
;
490 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
491 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
495 if(pConPriv
->getDocClient
!= (ClientPtr
)NULL
) {
496 XpFinishDocData(pConPriv
->getDocClient
);
498 pConPriv
->getDocClient
= (ClientPtr
)NULL
;
499 pConPriv
->getDocBufSize
= 0;
502 if(pConPriv
->jobFileName
!= (char *)NULL
)
504 unlink(pConPriv
->jobFileName
);
505 Xfree(pConPriv
->jobFileName
);
506 pConPriv
->jobFileName
= (char *)NULL
;
512 if(pConPriv
->getDocClient
!= (ClientPtr
)NULL
&&pConPriv
->getDocBufSize
> 0)
514 XpFinishDocData(pConPriv
->getDocClient
);
516 pConPriv
->getDocClient
= (ClientPtr
)NULL
;
517 pConPriv
->getDocBufSize
= 0;
522 if(pConPriv
->pJobFile
!= (FILE *)NULL
)
524 fclose(pConPriv
->pJobFile
);
525 pConPriv
->pJobFile
= (FILE *)NULL
;
527 if(pConPriv
->jobFileName
!= (char *)NULL
)
529 XpSubmitJob( pConPriv
->jobFileName
, pCon
);
530 unlink(pConPriv
->jobFileName
);
531 Xfree(pConPriv
->jobFileName
);
532 pConPriv
->jobFileName
= (char *)NULL
;
541 * If page file exists
543 * set page file pointer = NULL
551 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
552 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
554 if(pConPriv
->pPageFile
!= (FILE *)NULL
)
556 fclose(pConPriv
->pPageFile
);
557 pConPriv
->pPageFile
= (FILE *)NULL
;
559 if(pConPriv
->pageFileName
!= (char *)NULL
)
561 unlink(pConPriv
->pageFileName
);
562 pConPriv
->pageFileName
= (char *)NULL
;
568 #include "X11/XWDFile.h"
571 #define lowbit(x) ((x) & (~(x) + 1))
574 * Get the XWDColors of all pixels in colormap - returns # of colors
585 ncolors
= pCmap
->pVisual
->ColormapEntries
;
586 if (!(colors
= (XWDColor
*) malloc (sizeof(XWDColor
) * ncolors
)))
587 return (XWDColor
*) NULL
;
588 if (!(prgbList
= (xrgb
*) malloc(sizeof(xrgb
) * ncolors
)))
591 return (XWDColor
*) NULL
;
593 if (!(pPixels
= (Pixel
*) malloc(sizeof(Pixel
) * ncolors
)))
597 return (XWDColor
*) NULL
;
600 if (pCmap
->pVisual
->class == DirectColor
||
601 pCmap
->pVisual
->class == TrueColor
) {
602 Pixel red
, green
, blue
, red1
, green1
, blue1
;
604 red
= green
= blue
= 0;
605 red1
= lowbit(pCmap
->pVisual
->redMask
);
606 green1
= lowbit(pCmap
->pVisual
->greenMask
);
607 blue1
= lowbit(pCmap
->pVisual
->blueMask
);
608 for (i
=0; i
<ncolors
; i
++) {
609 colors
[i
].pixel
= red
|green
|blue
;
612 if (red
> pCmap
->pVisual
->redMask
)
615 if (green
> pCmap
->pVisual
->greenMask
)
618 if (blue
> pCmap
->pVisual
->blueMask
)
622 for (i
=0; i
<ncolors
; i
++) {
628 for(i
= 0; i
< ncolors
; i
++)
629 pPixels
[i
] = colors
[i
].pixel
;
631 QueryColors(pCmap
, ncolors
, pPixels
, prgbList
);
634 for(i
= 0; i
< ncolors
; i
++)
636 colors
[i
].red
= prgbList
[i
].red
;
637 colors
[i
].green
= prgbList
[i
].green
;
638 colors
[i
].blue
= prgbList
[i
].blue
;
651 register char *ep
= bp
+ n
;
667 register char *ep
= bp
+ n
;
687 long widthBytesLine
, length
;
688 int nlines
, linesPerBuf
, height
, linesDone
;
690 DrawablePtr pDraw
= &pWin
->drawable
;
691 XWDFileHeader header
;
699 unsigned long swaptest
= 1;
701 widthBytesLine
= PixmapBytePad(pWin
->drawable
.width
, pWin
->drawable
.depth
);
702 length
= widthBytesLine
* pWin
->drawable
.height
;
703 height
= pWin
->drawable
.height
;
708 if (widthBytesLine
>= IMAGE_BUFSIZE
)
712 linesPerBuf
= IMAGE_BUFSIZE
/ widthBytesLine
;
713 if (linesPerBuf
> height
)
714 linesPerBuf
= height
;
716 length
= linesPerBuf
* widthBytesLine
;
717 if (linesPerBuf
< height
)
719 /* we have to make sure intermediate buffers don't need padding */
720 while ((linesPerBuf
> 1) && (length
& 3))
723 length
-= widthBytesLine
;
728 length
+= widthBytesLine
;
731 if(!(pBuf
= (char *) Xalloc(length
)))
735 * Start of Xwd header code.
739 * XXX - Should we use the real window name???
742 /* sizeof(char) is included for the null string terminator. */
743 win_name_size
= strlen(win_name
) + sizeof(char);
745 pCmap
= (ColormapPtr
)LookupIDByType(wColormap (pWin
), RT_COLORMAP
);
746 pVisual
= pCmap
->pVisual
;
747 if((pColors
= Get_XWDColors(pCmap
)) == (XWDColor
*)NULL
)
754 * Write out header information.
756 header_size
= sizeof(header
) + win_name_size
;
757 header
.header_size
= (CARD32
) header_size
;
758 header
.file_version
= (CARD32
) XWD_FILE_VERSION
;
759 header
.pixmap_format
= (CARD32
) ZPixmap
; /* Must match GetImage below */
760 header
.pixmap_depth
= (CARD32
) pDraw
->depth
;
761 header
.pixmap_width
= (CARD32
) pDraw
->width
;
762 header
.pixmap_height
= (CARD32
) pDraw
->height
;
763 header
.xoffset
= (CARD32
) 0;
764 header
.byte_order
= (CARD32
) screenInfo
.imageByteOrder
;
765 header
.bitmap_unit
= (CARD32
) screenInfo
.bitmapScanlineUnit
;
766 header
.bitmap_bit_order
= (CARD32
) screenInfo
.bitmapBitOrder
;
767 header
.bitmap_pad
= (CARD32
) screenInfo
.bitmapScanlinePad
;
768 header
.bits_per_pixel
= (CARD32
) pDraw
->bitsPerPixel
;
769 header
.bytes_per_line
= (CARD32
) widthBytesLine
;
770 header
.visual_class
= (CARD32
) pVisual
->class;
771 header
.red_mask
= (CARD32
) pVisual
->redMask
;
772 header
.green_mask
= (CARD32
) pVisual
->greenMask
;
773 header
.blue_mask
= (CARD32
) pVisual
->blueMask
;
774 header
.bits_per_rgb
= (CARD32
) pVisual
->bitsPerRGBValue
;
775 header
.colormap_entries
= (CARD32
) pVisual
->ColormapEntries
;
776 header
.ncolors
= ncolors
= (CARD32
) pVisual
->ColormapEntries
;
777 header
.window_width
= (CARD32
) pDraw
->width
;
778 header
.window_height
= (CARD32
) pDraw
->height
;
781 header
.window_bdrwidth
= (CARD32
) 0;
783 if (*(char *) &swaptest
) {
784 _swaplong((char *) &header
, sizeof(header
));
785 for (i
= 0; i
< ncolors
; i
++) {
786 _swaplong((char *) &pColors
[i
].pixel
, sizeof(long));
787 _swapshort((char *) &pColors
[i
].red
, 3 * sizeof(short));
791 (void) fwrite((char *)&header
, sizeof(header
), 1, pRasterFile
);
792 (void) fwrite(win_name
, win_name_size
, 1, pRasterFile
);
793 (void) fwrite((char *) pColors
, sizeof(XWDColor
), ncolors
, pRasterFile
);
798 * End of Xwd header code.
802 while(height
- linesDone
> 0)
804 nlines
= min(linesPerBuf
, height
- linesDone
);
805 (*pDraw
->pScreen
->GetImage
) (pDraw
,
808 pWin
->drawable
.width
,
814 if(fwrite(pBuf
, sizeof(char), (size_t)(nlines
* widthBytesLine
),
816 (size_t)(nlines
* widthBytesLine
))
829 SendPage( XpContextPtr pCon
)
832 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
833 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
835 if(stat(pConPriv
->pageFileName
, &statBuf
) < 0)
838 return XpSendDocumentData(pConPriv
->getDocClient
,
839 pConPriv
->pPageFile
, (int)statBuf
.st_size
,
840 pConPriv
->getDocBufSize
);
846 * If page file doesn't exist:
850 * Write page header to page file
851 * if(preRasterFile exists)
852 * copy preRasterFile contents to page file
853 * if(noRasterFile exists)
854 * write noRasterFile contents to page file
856 * Create raster image file
857 * Open raster image file
859 * Write Image data to raster image file
860 * invoke page_command on raster image file
861 * Write raster image file contents to page file
862 * Unlink tempPage file
863 * if(postRasterFile exists)
864 * write postRasterFile contents to page file
865 * Write page trailer to page file
867 * Write page file to job file
874 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
875 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
877 char *rasterFileName
= (char *)NULL
, *pCommand
= (char *)NULL
;
878 FILE *pRasterFile
= (FILE *)NULL
;
880 if(pConPriv
->pageFileName
== (char *)NULL
)
883 * Open the page file.
885 if (!XpOpenTmpFile("w+", &pConPriv
->pageFileName
,
886 &pConPriv
->pPageFile
))
890 * Copy any pre-raster document data to the page file.
892 if(pConPriv
->pPreRasterFile
!= (FILE *)NULL
)
894 if(CopyContentsAndDelete(&pConPriv
->pPreRasterFile
,
895 &pConPriv
->preRasterFileName
,
896 pConPriv
->pPageFile
) == FALSE
)
901 * Copy either the no-raster document data, or the raster
902 * data itself to the page file.
903 * If the no-raster file exists, then we don't process the
904 * actual window raster bits.
906 if(pConPriv
->pNoRasterFile
!= (FILE *)NULL
)
908 if(CopyContentsAndDelete(&pConPriv
->pNoRasterFile
,
909 &pConPriv
->noRasterFileName
,
910 pConPriv
->pPageFile
) == FALSE
)
916 * Open the raster image file.
918 if (!XpOpenTmpFile("w", &rasterFileName
, &pRasterFile
))
922 * Write the page image data to the raster image file.
924 if(WriteWindowRaster(pWin
, pRasterFile
) != Success
)
928 * Invoke the page_command on the raster image file.
930 if((pCommand
= GetPropString(pCon
, RASTER_PRINT_PAGE_COMMAND
)) !=
936 if (!XpOpenTmpFile("w", &outFileName
, &pOutFile
))
940 pCommand
= ReplaceFileString(strdup(pCommand
), rasterFileName
,
946 * Delete the unprocessed raster file.
948 unlink(rasterFileName
);
949 Xfree(rasterFileName
);
950 rasterFileName
= outFileName
;
951 if((pRasterFile
= fopen(rasterFileName
, "r")) == (FILE *)NULL
)
957 if((pRasterFile
= fopen(rasterFileName
, "r")) == (FILE *)NULL
)
962 * Copy the raster image file contents to the page file.
963 * Note that pRasterFile must be set to the start of the
966 if(CopyContentsAndDelete(&pRasterFile
,
968 pConPriv
->pPageFile
) == FALSE
)
973 * Copy any post-raster document data to the page file.
975 if(pConPriv
->pPostRasterFile
!= (FILE *)NULL
)
977 if(CopyContentsAndDelete(&pConPriv
->pPostRasterFile
,
978 &pConPriv
->postRasterFileName
,
979 pConPriv
->pPageFile
) == FALSE
)
986 * Write the page file contents to the job file or to the client
987 * performing GetDocumentData.
988 * pConPriv->pPageFile must first be set to the start of the page file.
990 rewind(pConPriv
->pPageFile
);
991 if(stat(pConPriv
->pageFileName
, &statBuf
) < 0)
995 * Send the page data to whatever client has called GetDocumentData.
997 if(pConPriv
->getDocClient
!= (ClientPtr
)NULL
&&pConPriv
->getDocBufSize
> 0)
1001 * We should do something like the following: suspend the
1002 * caller until we can gracefully write all the data in small
1003 * chunks to the receiver, but for now we'll just call WriteToClient
1006 retval
= SendPage(pCon
);
1007 fclose(pConPriv
->pPageFile
);
1008 pConPriv
->pPageFile
= (FILE *)NULL
;
1009 unlink(pConPriv
->pageFileName
);
1010 free(pConPriv
->pageFileName
);
1011 pConPriv
->pageFileName
= (char *)NULL
;
1015 if(pConPriv
->pJobFile
== (FILE *)NULL
)
1018 * This shouldn't be necessary. I believe we only get here if
1019 * someone calls "EndPage" prior to "StartJob". This error
1020 * condition should probably be trapped at a higher level.
1023 if(pConPriv
->jobFileName
!= (char *)NULL
)
1024 Xfree(pConPriv
->jobFileName
);
1026 * Create a temporary file to store the printer output.
1028 if (!XpOpenTmpFile("w", &pConPriv
->jobFileName
, &pConPriv
->pJobFile
))
1029 goto BAD_PAGE_ALLOC
;
1032 if(TransferBytes(pConPriv
->pPageFile
, pConPriv
->pJobFile
,
1033 (int)statBuf
.st_size
) != (int)statBuf
.st_size
)
1034 goto BAD_PAGE_ALLOC
;
1036 fclose(pConPriv
->pPageFile
);
1037 pConPriv
->pPageFile
= (FILE *)NULL
;
1038 unlink(pConPriv
->pageFileName
);
1039 free(pConPriv
->pageFileName
);
1040 pConPriv
->pageFileName
= (char *)NULL
;
1046 FreePageFiles(pConPriv
);
1048 if(pRasterFile
!= (FILE *)NULL
)
1049 fclose(pRasterFile
);
1050 if(rasterFileName
!= (char *)NULL
)
1052 unlink(rasterFileName
);
1053 Xfree(rasterFileName
);
1070 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
1071 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
1072 char *preRasterStr
= PRE_RASTER
, *postRasterStr
= POST_RASTER
,
1073 *noRasterStr
= NO_RASTER
;
1076 * Check that options equals either PRE_RASTER or POST_RASTER.
1078 if(len_options
== strlen(preRasterStr
) &&
1079 strncmp(pOptions
, preRasterStr
, strlen(preRasterStr
)) == 0)
1081 if(pConPriv
->pPreRasterFile
== (FILE *)NULL
)
1083 if (!XpOpenTmpFile("w+", &pConPriv
->preRasterFileName
,
1084 &pConPriv
->pPreRasterFile
))
1087 if(fwrite(pData
, sizeof(char), (size_t)len_data
,
1088 pConPriv
->pPreRasterFile
) != (size_t)len_data
)
1090 fflush(pConPriv
->pPreRasterFile
);
1092 else if(len_options
== strlen(postRasterStr
) &&
1093 strncmp(pOptions
, postRasterStr
, strlen(postRasterStr
)) == 0)
1095 if(pConPriv
->pPostRasterFile
== (FILE *)NULL
)
1097 if (!XpOpenTmpFile("w+", &pConPriv
->postRasterFileName
,
1098 &pConPriv
->pPostRasterFile
))
1101 if(fwrite(pData
, sizeof(char), (size_t)len_data
,
1102 pConPriv
->pPostRasterFile
) != (size_t)len_data
)
1104 fflush(pConPriv
->pPostRasterFile
);
1106 else if(len_options
== strlen(noRasterStr
) &&
1107 strncmp(pOptions
, noRasterStr
, strlen(noRasterStr
)) == 0)
1109 if(pConPriv
->pNoRasterFile
== (FILE *)NULL
)
1111 if (!XpOpenTmpFile("w+", &pConPriv
->noRasterFileName
,
1112 &pConPriv
->pNoRasterFile
))
1115 if(fwrite(pData
, sizeof(char), (size_t)len_data
,
1116 pConPriv
->pNoRasterFile
) != (size_t)len_data
)
1118 fflush(pConPriv
->pNoRasterFile
);
1127 * GetDocumentData notes which client is requesting the document data for
1128 * a particular context. The Raster driver's EndPage function causes the
1129 * data to be written to the proper client.
1133 XpContextPtr pContext
,
1137 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
1138 pContext
->devPrivates
[RasterContextPrivateIndex
].ptr
;
1140 pConPriv
->getDocClient
= client
;
1141 pConPriv
->getDocBufSize
= maxBufferSize
;
1146 AllocateRasterPrivates(
1149 if(RasterGeneration
!= serverGeneration
)
1151 RasterScreenPrivateIndex
= AllocateScreenPrivateIndex();
1152 RasterContextPrivateIndex
= XpAllocateContextPrivateIndex();
1153 XpAllocateContextPrivate( RasterContextPrivateIndex
,
1154 sizeof( RasterContextPrivRec
) );
1156 RasterGeneration
= serverGeneration
;
1158 pScreen
->devPrivates
[RasterScreenPrivateIndex
].ptr
= (pointer
)Xalloc(
1159 sizeof(RasterScreenPrivRec
));
1163 * RasterChangeWindowAttributes - Make sure that the window's backing
1164 * store is turned on.
1167 RasterChangeWindowAttributes(
1171 Bool status
= Success
;
1172 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1173 RasterScreenPrivPtr pScreenPriv
= (RasterScreenPrivPtr
)
1174 pScreen
->devPrivates
[RasterScreenPrivateIndex
].ptr
;
1176 if(pWin
->backingStore
== NotUseful
)
1178 pWin
->backingStore
= WhenMapped
;
1179 mask
|= CWBackingStore
;
1182 if(pScreenPriv
->ChangeWindowAttributes
!= NULL
)
1184 pScreen
->ChangeWindowAttributes
= pScreenPriv
->ChangeWindowAttributes
;
1185 status
= pScreen
->ChangeWindowAttributes(pWin
, mask
);
1186 pScreen
->ChangeWindowAttributes
= RasterChangeWindowAttributes
;
1192 * RasterValidateDocFormats - Inspects the files available in the
1193 * ddx-config/XP-RASTER directory to find the names of PDLs for which
1194 * we have processing commands. These names are then intersected with
1195 * the contents of the printer's document-formats-supported attribute,
1196 * and the result is stored back into document-formats-supported.
1197 * We have hard-coded knowledge of how to produce PS, so we always
1198 * leave that in, if it's listed in document-formats-supported,
1199 * even if we don't have a configuration file. If there is a
1200 * configuration file for PS, then its contents will override our default.
1203 RasterValidateDocFormats(
1209 * RasterValidateAttrs - Inspects and Corrects the attribute values
1210 * in the specified context.
1213 RasterValidateAttrs(
1216 RasterValidateDocFormats(pCon
);
1217 XpValidatePrinterPool(pCon
, &RasterValidatePoolsRec
);
1218 XpValidateJobPool(pCon
, &RasterValidatePoolsRec
);
1219 XpValidateDocumentPool(pCon
, &RasterValidatePoolsRec
);
1223 * RasterInitContext - Establish the appropriate values for a
1224 * PrintContext used with the Raster Driver.
1226 static char DOC_ATT_SUPP
[]="document-attributes-supported:\tdefault-medium document-format";
1227 static char JOB_ATT_SUPP
[]="job-attributes-supported:\t";
1228 static char DDX_DIR
[]="ddx-config";
1234 char *configFileName
, *val
, *attrStr
;
1235 RasterContextPrivPtr pConPriv
;
1236 XpDriverFuncsPtr pFuncs
;
1239 * Initialize the attribute store for this printer.
1241 XpInitAttributes( pCon
);
1244 * Validate the attributes
1246 RasterValidateAttrs( pCon
);
1250 * Initialize the function pointers
1252 pFuncs
= &( pCon
->funcs
);
1253 pFuncs
->StartJob
= StartJob
;
1254 pFuncs
->EndJob
= EndJob
;
1255 pFuncs
->StartDoc
= StartDoc
;
1256 pFuncs
->EndDoc
= EndDoc
;
1257 pFuncs
->StartPage
= StartPage
;
1258 pFuncs
->EndPage
= EndPage
;
1259 pFuncs
->PutDocumentData
= DocumentData
;
1260 pFuncs
->GetDocumentData
= GetDocumentData
;
1261 pFuncs
->DestroyContext
= RasterDestroyContext
;
1262 pFuncs
->GetAttributes
= RasterGetAttributes
;
1263 pFuncs
->GetOneAttribute
= RasterGetOneAttribute
;
1264 pFuncs
->SetAttributes
= RasterSetAttributes
;
1265 pFuncs
->AugmentAttributes
= RasterAugmentAttributes
;
1266 pFuncs
->GetMediumDimensions
= RasterMediumDimensions
;
1267 pFuncs
->GetReproducibleArea
= RasterReproducibleArea
;
1270 * Set up the context privates
1272 pConPriv
= (RasterContextPrivPtr
)
1273 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
1275 pConPriv
->jobFileName
= (char *)NULL
;
1276 pConPriv
->pageFileName
= (char *)NULL
;
1277 pConPriv
->preRasterFileName
= (char *)NULL
;
1278 pConPriv
->postRasterFileName
= (char *)NULL
;
1279 pConPriv
->noRasterFileName
= (char *)NULL
;
1280 pConPriv
->pJobFile
= (FILE *)NULL
;
1281 pConPriv
->pPageFile
= (FILE *)NULL
;
1282 pConPriv
->pPreRasterFile
= (FILE *)NULL
;
1283 pConPriv
->pPostRasterFile
= (FILE *)NULL
;
1284 pConPriv
->pNoRasterFile
= (FILE *)NULL
;
1286 pConPriv
->getDocClient
= (ClientPtr
)NULL
;
1287 pConPriv
->getDocBufSize
= 0;
1290 * Get the configuration information for the context's printer
1292 configFileName
= XpGetOneAttribute( pCon
, XPPrinterAttr
,
1293 "xp-ddx-config-file-name" );
1294 if(configFileName
&& strlen(configFileName
))
1296 if( configFileName
[0] == '/' )
1297 pConPriv
->config
= XrmGetFileDatabase( configFileName
);
1300 char *configDir
, *configFilePath
;
1302 configDir
= XpGetConfigDir(FALSE
);
1303 configFilePath
= (char *)malloc((strlen(configDir
) +
1305 strlen(RASTER_DRIV_NAME
) +
1306 strlen(configFileName
) +
1308 sprintf(configFilePath
, "%s/%s/%s/%s", configDir
, DDX_DIR
,
1309 RASTER_DRIV_NAME
, configFileName
);
1310 pConPriv
->config
= XrmGetFileDatabase(configFilePath
);
1312 free(configFilePath
);
1316 pConPriv
->config
= (XrmDatabase
)NULL
;
1319 * Add our own attribute initialization
1322 * document-attributes-supported
1324 val
= XpGetOneAttribute(pCon
, XPServerAttr
, "document-attributes-supported");
1325 if((attrStr
= (char *)xalloc(strlen(val
) + strlen(DOC_ATT_SUPP
) + 4)) ==
1328 sprintf(attrStr
, "*%s %s", DOC_ATT_SUPP
, val
);
1329 XpAugmentAttributes(pCon
, XPPrinterAttr
, attrStr
);
1333 * job-attributes-supported
1335 val
= XpGetOneAttribute(pCon
, XPServerAttr
, "job-attributes-supported");
1336 if((attrStr
= (char *)xalloc(strlen(val
) + strlen(JOB_ATT_SUPP
) + 4)) ==
1339 sprintf(attrStr
, "*%s %s", JOB_ATT_SUPP
, val
);
1340 XpAugmentAttributes(pCon
, XPPrinterAttr
, attrStr
);
1344 * PageAttributesSupported
1346 XpAugmentAttributes(pCon
, XPPrinterAttr
, "*xp-page-attributes-supported:");
1354 RasterDestroyContext(
1357 RasterContextPrivPtr pConPriv
= (RasterContextPrivPtr
)
1358 pCon
->devPrivates
[RasterContextPrivateIndex
].ptr
;
1361 * Clean up the temporary files
1363 FreePageFiles( pConPriv
);
1365 if( pConPriv
->pJobFile
!= (FILE *)NULL
)
1367 fclose( pConPriv
->pJobFile
);
1368 pConPriv
->pJobFile
= (FILE *)NULL
;
1370 if( pConPriv
->jobFileName
!= (char *)NULL
)
1372 unlink( pConPriv
->jobFileName
);
1373 Xfree( pConPriv
->jobFileName
);
1375 if(pConPriv
->config
)
1377 XrmDestroyDatabase(pConPriv
->config
);
1378 pConPriv
->config
= (XrmDatabase
)NULL
;
1381 XpDestroyAttributes( pCon
);
1386 RasterGetAttributes(
1387 XpContextPtr pContext
,
1390 return XpGetAttributes( pContext
, class );
1394 RasterGetOneAttribute(
1395 XpContextPtr pContext
,
1399 return XpGetOneAttribute( pContext
, class, attr
);
1403 RasterSetAttributes(XpContextPtr pCon
,
1407 return XpSetAttributes( pCon
, class, attributes
);
1411 RasterAugmentAttributes(
1416 return XpAugmentAttributes( pCon
, class, attributes
);
1421 RasterContextPrivPtr pConPriv
)
1423 if(pConPriv
->pPageFile
!= (FILE *)NULL
)
1425 fclose(pConPriv
->pPageFile
);
1426 pConPriv
->pPageFile
= (FILE *)NULL
;
1428 if(pConPriv
->pageFileName
!= (char *)NULL
)
1430 unlink(pConPriv
->pageFileName
);
1431 Xfree(pConPriv
->pageFileName
);
1432 pConPriv
->pageFileName
= (char *)NULL
;
1434 if(pConPriv
->pPreRasterFile
!= (FILE *)NULL
)
1436 fclose(pConPriv
->pPreRasterFile
);
1437 pConPriv
->pPreRasterFile
= (FILE *)NULL
;
1439 if(pConPriv
->preRasterFileName
!= (char *)NULL
)
1441 unlink(pConPriv
->preRasterFileName
);
1442 Xfree(pConPriv
->preRasterFileName
);
1443 pConPriv
->preRasterFileName
= (char *)NULL
;
1445 if(pConPriv
->pPostRasterFile
!= (FILE *)NULL
)
1447 fclose(pConPriv
->pPostRasterFile
);
1448 pConPriv
->pPostRasterFile
= (FILE *)NULL
;
1450 if(pConPriv
->postRasterFileName
!= (char *)NULL
)
1452 unlink(pConPriv
->postRasterFileName
);
1453 Xfree(pConPriv
->postRasterFileName
);
1454 pConPriv
->postRasterFileName
= (char *)NULL
;
1456 if(pConPriv
->pNoRasterFile
!= (FILE *)NULL
)
1458 fclose(pConPriv
->pNoRasterFile
);
1459 pConPriv
->pNoRasterFile
= (FILE *)NULL
;
1461 if(pConPriv
->noRasterFileName
!= (char *)NULL
)
1463 unlink(pConPriv
->noRasterFileName
);
1464 Xfree(pConPriv
->noRasterFileName
);
1465 pConPriv
->noRasterFileName
= (char *)NULL
;
1470 * RasterCloseScreen - Call any wrapped CloseScreen function,
1471 * and free the screen memory.
1478 Bool status
= Success
;
1479 RasterScreenPrivPtr pScreenPriv
= (RasterScreenPrivPtr
)
1480 pScreen
->devPrivates
[RasterScreenPrivateIndex
].ptr
;
1483 * Call any wrapped CloseScreen proc.
1485 if(pScreenPriv
->CloseScreen
!= NULL
)
1487 pScreen
->CloseScreen
= pScreenPriv
->CloseScreen
;
1488 status
= pScreen
->CloseScreen(index
, pScreen
);
1489 pScreen
->CloseScreen
= RasterCloseScreen
;
1492 Xfree(pScreenPriv
->pBits
);
1501 static void SigchldHndlr (int dummy
)
1504 int olderrno
= errno
;
1505 struct sigaction act
;
1506 sigfillset(&act
.sa_mask
);
1508 act
.sa_handler
= SigchldHndlr
;
1510 (void) wait (&status
);
1513 * Is this really necessary?
1515 sigaction(SIGCHLD
, &act
, (struct sigaction
*)NULL
);
1520 * SystemCmd provides a wrapper for the 'system' library call. The call
1521 * appears to be sensitive to the handling of SIGCHLD, so this wrapper
1522 * sets the status to SIG_DFL, and then resets the established handler
1523 * after system returns.
1526 SystemCmd(char *cmdStr
)
1529 struct sigaction newAct
, oldAct
;
1530 sigfillset(&newAct
.sa_mask
);
1531 newAct
.sa_flags
= 0;
1532 newAct
.sa_handler
= SIG_DFL
;
1533 sigfillset(&oldAct
.sa_mask
);
1534 oldAct
.sa_flags
= 0;
1535 oldAct
.sa_handler
= SigchldHndlr
;
1538 * get the old handler, and set the action to IGN
1540 sigaction(SIGCHLD
, &newAct
, &oldAct
);
1542 status
= system (cmdStr
);
1544 sigaction(SIGCHLD
, &oldAct
, (struct sigaction
*)NULL
);
1549 * RasterMediumDimensions is installed in the GetMediumDimensions field
1550 * of each raster-initialized context.
1553 RasterMediumDimensions(XpContextPtr pCon
,
1557 XpGetMediumDimensions(pCon
, width
, height
);
1562 * RasterReproducibleArea is installed in the GetReproducibleArea field
1563 * of each raster-initialized context.
1566 RasterReproducibleArea(XpContextPtr pCon
,
1569 XpGetReproductionArea(pCon
, pRect
);