1
/* $Xorg: Raster.c,v 1.4 2001/03/14 18:46:12 pookie Exp $ */
3
(c) Copyright 1996 Hewlett-Packard Company
4
(c) Copyright 1996 International Business Machines Corp.
5
(c) Copyright 1996 Sun Microsystems, Inc.
6
(c) Copyright 1996 Novell, Inc.
7
(c) Copyright 1996 Digital Equipment Corp.
8
(c) Copyright 1996 Fujitsu Limited
9
(c) Copyright 1996 Hitachi, Ltd.
11
Permission is hereby granted, free of charge, to any person obtaining a copy
12
of this software and associated documentation files (the "Software"), to deal
13
in the Software without restriction, including without limitation the rights
14
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
copies of the Software, and to permit persons to whom the Software is
16
furnished to do so, subject to the following conditions:
18
The above copyright notice and this permission notice shall be included in
19
all copies or substantial portions of the Software.
21
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
Except as contained in this notice, the names of the copyright holders shall
29
not be used in advertising or otherwise to promote the sale, use or other
30
dealings in this Software without prior written authorization from said
34
/* $XFree86: xc/programs/Xserver/Xprint/raster/Raster.c,v 1.11tsi Exp $ */
36
/*******************************************************************
38
** *********************************************************
40
** * File: printer/Raster.c
43
** * Raster driver for the print server.
45
** * Copyright: Copyright 1993, 1995 Hewlett-Packard Company
47
** *********************************************************
49
********************************************************************/
51
#ifdef HAVE_DIX_CONFIG_H
52
#include <dix-config.h>
61
#include <sys/types.h>
64
#include <X11/Xos.h> /* for SIGCLD on pre-POSIX systems */
66
#include <X11/Xproto.h>
68
#include <X11/Xatom.h>
70
#include "dixstruct.h"
71
#include "scrnintstr.h"
72
#include "screenint.h"
73
#include "colormapst.h"
74
#include "windowstr.h"
75
#include "propertyst.h"
76
#include "servermd.h" /* needed for IMAGE_BUFSIZE */
80
#include <X11/extensions/Print.h>
83
#include "attributes.h"
84
#include "AttrValid.h"
87
static void AllocateRasterPrivates(
89
static Bool RasterChangeWindowAttributes(
101
XPDocumentType type);
111
static int DocumentData(
121
static int GetDocumentData(
122
XpContextPtr pContext,
125
static void FreePageFiles(
126
RasterContextPrivPtr pWinPriv);
127
static int SystemCmd(
129
static Bool RasterCloseScreen(
132
static int RasterInitContext(XpContextPtr pCon);
133
static Bool RasterDestroyContext(XpContextPtr pCon);
134
static char *RasterGetAttributes(
135
XpContextPtr pContext,
137
static char *RasterGetOneAttribute(XpContextPtr pCon,
140
static int RasterSetAttributes(XpContextPtr pCon,
143
static int RasterAugmentAttributes(XpContextPtr pCon,
146
static int RasterMediumDimensions(XpContextPtr pCon,
149
static int RasterReproducibleArea(XpContextPtr pCon,
152
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
156
static int RasterScreenPrivateIndex, RasterContextPrivateIndex;
157
static int RasterGeneration = 0;
158
static char RASTER_DRIV_NAME[] = "XP-RASTER";
159
static int doc_type = DOC_RASTER;
161
#define ABSOLUTE_PCLCOMP_PATH1 "/usr/openwin/bin/pclcomp"
162
#define ABSOLUTE_PCLCOMP_PATH2 "/usr/X11/bin/pclcomp"
164
static char *pcl3_output_cmds[] = {
165
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0 > %(OutFile)%",
166
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -01 > %(OutFile)%",
167
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -02 > %(OutFile)%",
168
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -03 > %(OutFile)%",
169
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -012 > %(OutFile)%",
170
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -013 > %(OutFile)%",
171
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -023 > %(OutFile)%",
172
"xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0123 > %(OutFile)%",
173
"xpr -device ljet -rv -landscape < %(InFile)% > %(OutFile)%",
174
"xpr -device ljet -rv < %(InFile)% | pclcomp -0 > %(OutFile)%",
175
"xpr -device ljet -rv < %(InFile)% | pclcomp -01 > %(OutFile)%",
176
"xpr -device ljet -rv < %(InFile)% | pclcomp -02 > %(OutFile)%",
177
"xpr -device ljet -rv < %(InFile)% | pclcomp -03 > %(OutFile)%",
178
"xpr -device ljet -rv < %(InFile)% | pclcomp -012 > %(OutFile)%",
179
"xpr -device ljet -rv < %(InFile)% | pclcomp -013 > %(OutFile)%",
180
"xpr -device ljet -rv < %(InFile)% | pclcomp -023 > %(OutFile)%",
181
"xpr -device ljet -rv < %(InFile)% | pclcomp -0123 > %(OutFile)%",
182
"xpr -device ljet -rv < %(InFile)% > %(OutFile)%"};
185
InitializeRasterDriver(
192
int maxRes, maxDim, numBytes;
193
RasterScreenPrivPtr pPriv;
196
* Register this driver's InitContext function with the print extension.
198
* sleazy, as the extension hasn't yet been initialized, but the
199
* extension needs to know this, and this seems the best time to
200
* provide the information.
202
XpRegisterInitFunc( pScreen, RASTER_DRIV_NAME, RasterInitContext );
205
* Create and load the devPrivate for the printer layer.
207
AllocateRasterPrivates(pScreen);
209
pPriv = (RasterScreenPrivPtr)
210
pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
212
maxDim = MAX( pScreen->height, pScreen->width );
213
numBytes = maxDim + BITMAP_SCANLINE_PAD - 1; /* pixels per row */
215
numBytes /= 8; /* bytes per row */
216
xRes = pScreen->width / (pScreen->mmWidth / 25.4);
217
yRes = pScreen->height / (pScreen->mmHeight / 25.4);
218
maxRes = MAX( xRes, yRes );
220
pPriv->pBits = (char *)xalloc(numBytes);
223
* Have to allocate maxDim X maxDim to allow for landscape mode.
225
mfbScreenInit(pScreen, pPriv->pBits, maxDim, maxDim, maxRes,
227
miInitializeBackingStore(pScreen);
228
pScreen->blackPixel = 1;
229
pScreen->whitePixel = 0;
230
if(mfbCreateDefColormap(pScreen) == FALSE)
231
; /* XXX what do I do if it fails? */
234
cfbScreenInit(pScreen, pPriv->pBits, maxWidth, maxHeight, maxXres,
236
miInitializeBackingStore(pScreen);
237
scalingScreenInit(pScreen);
240
pScreen->SaveScreen = (SaveScreenProcPtr)_XpBoolNoop;
241
pPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
242
pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes;
243
pPriv->CloseScreen = pScreen->CloseScreen;
244
pScreen->CloseScreen = RasterCloseScreen;
250
* GetPropString searches the context's config database for a property
251
* by the name of propName. If found, it returns the property's
252
* value, otherwise it returns NULL unless the requested attribute
253
* is RASTER_PRINT_PAGE_COMMAND, in which case it returns a hard-coded
254
* default string to invoke xpr to produce a PostScript(tm) formatted
263
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
264
pCon->devPrivates[RasterContextPrivateIndex].ptr;
268
int pclcomp_exists = 0;
270
if( XrmGetResource(pConPriv->config, propName, propName, &type, &val) ==
272
return (char *)val.addr;
274
if( !strcmp( propName, RASTER_PRINT_PAGE_COMMAND ) )
275
if( doc_type == DOC_RASTER )
276
return "xpr -device ps %(InFile)% > %(OutFile)%";
281
int pcl3_output_index = 0;
283
orientation = XpGetContentOrientation(pCon);
284
compression = XpGetAvailableCompression(pCon);
286
switch(orientation) {
287
case xpoid_val_content_orientation_landscape:
288
pcl3_output_index = 0;
291
pcl3_output_index += 9;
295
if(stat(ABSOLUTE_PCLCOMP_PATH1, &status) != -1)
297
else if(stat(ABSOLUTE_PCLCOMP_PATH2, &status) != -1)
301
switch(compression) {
302
case xpoid_val_available_compressions_0:
303
pcl3_output_index += 0;
305
case xpoid_val_available_compressions_01:
306
pcl3_output_index += 1;
308
case xpoid_val_available_compressions_02:
309
pcl3_output_index += 2;
311
case xpoid_val_available_compressions_03:
312
pcl3_output_index += 3;
314
case xpoid_val_available_compressions_012:
315
pcl3_output_index += 4;
317
case xpoid_val_available_compressions_013:
318
pcl3_output_index += 5;
320
case xpoid_val_available_compressions_023:
321
pcl3_output_index += 6;
324
pcl3_output_index += 7;
328
pcl3_output_index += 8;
330
return pcl3_output_cmds[pcl3_output_index];
340
XpOidList* attrs_supported;
343
* only validate attributes found in document-attributes-supported
346
XpGetListAttr(pCon, XPPrinterAttr,
347
xpoid_att_document_attributes_supported,
348
(const XpOidList*)NULL);
350
if(XpOidListHasOid(attrs_supported, xpoid_att_document_format))
352
const char* value_in;
355
value_in = XpGetStringAttr(pCon, XPDocAttr, xpoid_att_document_format);
357
f = XpOidDocFmtNew( value_in );
361
if( !strcmp( f->format, "PCL" ) )
364
doc_type = DOC_RASTER;
366
XpOidDocFmtDelete( f );
373
XpOidListDelete(attrs_supported);
382
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
383
pCon->devPrivates[RasterContextPrivateIndex].ptr;
385
SetDocumentType( pCon );
388
* Check for existing page file, and delete it if it exists.
390
if(pConPriv->pageFileName != (char *)NULL)
392
if(pConPriv->pPageFile != (FILE *)NULL)
394
fclose(pConPriv->pPageFile);
395
pConPriv->pPageFile = (FILE *)NULL;
397
unlink(pConPriv->pageFileName);
398
Xfree(pConPriv->pageFileName);
399
pConPriv->pageFileName = (char *)NULL;
403
* Create a temporary file to store the printer output.
408
* Create a temporary file to store the printer output.
410
if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
418
* StartDoc and EndDoc are just no-ops in this implementation, since
419
* our view of the spooler really doesn't recognize documents.
442
* BuidArgVector takes a pointer to a comma-separated list of command
443
* options and splits it out into an array of argument pointers. The
444
* caller must not free the optionList after calling this function until
445
* the returned arg vector is no longer needed, at which time the arg
446
* vector should also be freed.
449
#define SEPARATOR_CHAR (char)','
457
char *curArg, *lastChar, *endArg;
460
lastChar = optionList + strlen(optionList); /* includes final NULL */
462
while(curArg != (char *)NULL && curArg < lastChar)
464
/* strip leading white space */
465
while(curArg < lastChar && isascii((int)*curArg) &&
466
isspace((int)*curArg))
469
if(curArg < lastChar)
471
argVector = (char **)Xrealloc(argVector,
472
sizeof(char *) * (argCount + 2));
473
argVector[argCount] = curArg;
474
argVector[++argCount] = (char *)NULL;
476
endArg = strchr(curArg, SEPARATOR_CHAR);
478
/* Should I strip trailing white space ??? */
480
if(endArg != (char *)NULL)
482
*endArg = (char)'\0';
486
curArg = (char *)NULL;
499
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
500
pCon->devPrivates[RasterContextPrivateIndex].ptr;
504
if(pConPriv->getDocClient != (ClientPtr)NULL) {
505
XpFinishDocData(pConPriv->getDocClient);
507
pConPriv->getDocClient = (ClientPtr)NULL;
508
pConPriv->getDocBufSize = 0;
511
if(pConPriv->jobFileName != (char *)NULL)
513
unlink(pConPriv->jobFileName);
514
Xfree(pConPriv->jobFileName);
515
pConPriv->jobFileName = (char *)NULL;
521
if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0)
523
XpFinishDocData(pConPriv->getDocClient);
525
pConPriv->getDocClient = (ClientPtr)NULL;
526
pConPriv->getDocBufSize = 0;
531
if(pConPriv->pJobFile != (FILE *)NULL)
533
fclose(pConPriv->pJobFile);
534
pConPriv->pJobFile = (FILE *)NULL;
536
if(pConPriv->jobFileName != (char *)NULL)
538
XpSubmitJob( pConPriv->jobFileName, pCon );
539
unlink(pConPriv->jobFileName);
540
Xfree(pConPriv->jobFileName);
541
pConPriv->jobFileName = (char *)NULL;
550
* If page file exists
552
* set page file pointer = NULL
560
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
561
pCon->devPrivates[RasterContextPrivateIndex].ptr;
563
if(pConPriv->pPageFile != (FILE *)NULL)
565
fclose(pConPriv->pPageFile);
566
pConPriv->pPageFile = (FILE *)NULL;
568
if(pConPriv->pageFileName != (char *)NULL)
570
unlink(pConPriv->pageFileName);
571
pConPriv->pageFileName = (char *)NULL;
577
#include "X11/XWDFile.h"
580
#define lowbit(x) ((x) & (~(x) + 1))
583
* Get the XWDColors of all pixels in colormap - returns # of colors
594
ncolors = pCmap->pVisual->ColormapEntries;
595
if (!(colors = (XWDColor *) malloc (sizeof(XWDColor) * ncolors)))
596
return (XWDColor *) NULL;
597
if (!(prgbList = (xrgb*) malloc(sizeof(xrgb) * ncolors)))
600
return (XWDColor *) NULL;
602
if (!(pPixels = (Pixel*) malloc(sizeof(Pixel) * ncolors)))
606
return (XWDColor *) NULL;
609
if (pCmap->pVisual->class == DirectColor ||
610
pCmap->pVisual->class == TrueColor) {
611
Pixel red, green, blue, red1, green1, blue1;
613
red = green = blue = 0;
614
red1 = lowbit(pCmap->pVisual->redMask);
615
green1 = lowbit(pCmap->pVisual->greenMask);
616
blue1 = lowbit(pCmap->pVisual->blueMask);
617
for (i=0; i<ncolors; i++) {
618
colors[i].pixel = red|green|blue;
621
if (red > pCmap->pVisual->redMask)
624
if (green > pCmap->pVisual->greenMask)
627
if (blue > pCmap->pVisual->blueMask)
631
for (i=0; i<ncolors; i++) {
637
for(i = 0; i < ncolors; i++)
638
pPixels[i] = colors[i].pixel;
640
QueryColors(pCmap, ncolors, pPixels, prgbList);
643
for(i = 0; i < ncolors; i++)
645
colors[i].red = prgbList[i].red;
646
colors[i].green = prgbList[i].green;
647
colors[i].blue = prgbList[i].blue;
660
register char *ep = bp + n;
676
register char *ep = bp + n;
696
long widthBytesLine, length;
697
int nlines, linesPerBuf, height, linesDone;
699
DrawablePtr pDraw = &pWin->drawable;
700
XWDFileHeader header;
708
unsigned long swaptest = 1;
710
widthBytesLine = PixmapBytePad(pWin->drawable.width, pWin->drawable.depth);
711
length = widthBytesLine * pWin->drawable.height;
712
height = pWin->drawable.height;
717
if (widthBytesLine >= IMAGE_BUFSIZE)
721
linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
722
if (linesPerBuf > height)
723
linesPerBuf = height;
725
length = linesPerBuf * widthBytesLine;
726
if (linesPerBuf < height)
728
/* we have to make sure intermediate buffers don't need padding */
729
while ((linesPerBuf > 1) && (length & 3))
732
length -= widthBytesLine;
737
length += widthBytesLine;
740
if(!(pBuf = (char *) Xalloc(length)))
744
* Start of Xwd header code.
748
* XXX - Should we use the real window name???
751
/* sizeof(char) is included for the null string terminator. */
752
win_name_size = strlen(win_name) + sizeof(char);
754
pCmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP);
755
pVisual = pCmap->pVisual;
756
if((pColors = Get_XWDColors(pCmap)) == (XWDColor *)NULL)
763
* Write out header information.
765
header_size = sizeof(header) + win_name_size;
766
header.header_size = (CARD32) header_size;
767
header.file_version = (CARD32) XWD_FILE_VERSION;
768
header.pixmap_format = (CARD32) ZPixmap; /* Must match GetImage below */
769
header.pixmap_depth = (CARD32) pDraw->depth;
770
header.pixmap_width = (CARD32) pDraw->width;
771
header.pixmap_height = (CARD32) pDraw->height;
772
header.xoffset = (CARD32) 0;
773
header.byte_order = (CARD32) screenInfo.imageByteOrder;
774
header.bitmap_unit = (CARD32) screenInfo.bitmapScanlineUnit;
775
header.bitmap_bit_order = (CARD32) screenInfo.bitmapBitOrder;
776
header.bitmap_pad = (CARD32) screenInfo.bitmapScanlinePad;
777
header.bits_per_pixel = (CARD32) pDraw->bitsPerPixel;
778
header.bytes_per_line = (CARD32) widthBytesLine;
779
header.visual_class = (CARD32) pVisual->class;
780
header.red_mask = (CARD32) pVisual->redMask;
781
header.green_mask = (CARD32) pVisual->greenMask;
782
header.blue_mask = (CARD32) pVisual->blueMask;
783
header.bits_per_rgb = (CARD32) pVisual->bitsPerRGBValue;
784
header.colormap_entries = (CARD32) pVisual->ColormapEntries;
785
header.ncolors = ncolors = (CARD32) pVisual->ColormapEntries;
786
header.window_width = (CARD32) pDraw->width;
787
header.window_height = (CARD32) pDraw->height;
790
header.window_bdrwidth = (CARD32) 0;
792
if (*(char *) &swaptest) {
793
_swaplong((char *) &header, sizeof(header));
794
for (i = 0; i < ncolors; i++) {
795
_swaplong((char *) &pColors[i].pixel, sizeof(long));
796
_swapshort((char *) &pColors[i].red, 3 * sizeof(short));
800
(void) fwrite((char *)&header, sizeof(header), 1, pRasterFile);
801
(void) fwrite(win_name, win_name_size, 1, pRasterFile);
802
(void) fwrite((char *) pColors, sizeof(XWDColor), ncolors, pRasterFile);
807
* End of Xwd header code.
811
while(height - linesDone > 0)
813
nlines = min(linesPerBuf, height - linesDone);
814
(*pDraw->pScreen->GetImage) (pDraw,
817
pWin->drawable.width,
823
if(fwrite(pBuf, sizeof(char), (size_t)(nlines * widthBytesLine),
825
(size_t)(nlines * widthBytesLine))
838
SendPage( XpContextPtr pCon )
841
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
842
pCon->devPrivates[RasterContextPrivateIndex].ptr;
844
if(stat(pConPriv->pageFileName, &statBuf) < 0)
847
return XpSendDocumentData(pConPriv->getDocClient,
848
pConPriv->pPageFile, (int)statBuf.st_size,
849
pConPriv->getDocBufSize);
855
* If page file doesn't exist:
859
* Write page header to page file
860
* if(preRasterFile exists)
861
* copy preRasterFile contents to page file
862
* if(noRasterFile exists)
863
* write noRasterFile contents to page file
865
* Create raster image file
866
* Open raster image file
868
* Write Image data to raster image file
869
* invoke page_command on raster image file
870
* Write raster image file contents to page file
871
* Unlink tempPage file
872
* if(postRasterFile exists)
873
* write postRasterFile contents to page file
874
* Write page trailer to page file
876
* Write page file to job file
883
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
884
pCon->devPrivates[RasterContextPrivateIndex].ptr;
886
char *rasterFileName = (char *)NULL, *pCommand = (char *)NULL;
887
FILE *pRasterFile = (FILE *)NULL;
889
if(pConPriv->pageFileName == (char *)NULL)
892
* Open the page file.
894
if (!XpOpenTmpFile("w+", &pConPriv->pageFileName,
895
&pConPriv->pPageFile))
899
* Copy any pre-raster document data to the page file.
901
if(pConPriv->pPreRasterFile != (FILE *)NULL)
903
if(CopyContentsAndDelete(&pConPriv->pPreRasterFile,
904
&pConPriv->preRasterFileName,
905
pConPriv->pPageFile) == FALSE)
910
* Copy either the no-raster document data, or the raster
911
* data itself to the page file.
912
* If the no-raster file exists, then we don't process the
913
* actual window raster bits.
915
if(pConPriv->pNoRasterFile != (FILE *)NULL)
917
if(CopyContentsAndDelete(&pConPriv->pNoRasterFile,
918
&pConPriv->noRasterFileName,
919
pConPriv->pPageFile) == FALSE)
925
* Open the raster image file.
927
if (!XpOpenTmpFile("w", &rasterFileName, &pRasterFile))
931
* Write the page image data to the raster image file.
933
if(WriteWindowRaster(pWin, pRasterFile) != Success)
937
* Invoke the page_command on the raster image file.
939
if((pCommand = GetPropString(pCon, RASTER_PRINT_PAGE_COMMAND)) !=
945
if (!XpOpenTmpFile("w", &outFileName, &pOutFile))
949
pCommand = ReplaceFileString(strdup(pCommand), rasterFileName,
955
* Delete the unprocessed raster file.
957
unlink(rasterFileName);
958
Xfree(rasterFileName);
959
rasterFileName = outFileName;
960
if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL)
966
if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL)
971
* Copy the raster image file contents to the page file.
972
* Note that pRasterFile must be set to the start of the
975
if(CopyContentsAndDelete(&pRasterFile,
977
pConPriv->pPageFile) == FALSE)
982
* Copy any post-raster document data to the page file.
984
if(pConPriv->pPostRasterFile != (FILE *)NULL)
986
if(CopyContentsAndDelete(&pConPriv->pPostRasterFile,
987
&pConPriv->postRasterFileName,
988
pConPriv->pPageFile) == FALSE)
995
* Write the page file contents to the job file or to the client
996
* performing GetDocumentData.
997
* pConPriv->pPageFile must first be set to the start of the page file.
999
rewind(pConPriv->pPageFile);
1000
if(stat(pConPriv->pageFileName, &statBuf) < 0)
1001
goto BAD_PAGE_ALLOC;
1004
* Send the page data to whatever client has called GetDocumentData.
1006
if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0)
1010
* We should do something like the following: suspend the
1011
* caller until we can gracefully write all the data in small
1012
* chunks to the receiver, but for now we'll just call WriteToClient
1015
retval = SendPage(pCon);
1016
fclose(pConPriv->pPageFile);
1017
pConPriv->pPageFile = (FILE *)NULL;
1018
unlink(pConPriv->pageFileName);
1019
free(pConPriv->pageFileName);
1020
pConPriv->pageFileName = (char *)NULL;
1024
if(pConPriv->pJobFile == (FILE *)NULL)
1027
* This shouldn't be necessary. I believe we only get here if
1028
* someone calls "EndPage" prior to "StartJob". This error
1029
* condition should probably be trapped at a higher level.
1032
if(pConPriv->jobFileName != (char *)NULL)
1033
Xfree(pConPriv->jobFileName);
1035
* Create a temporary file to store the printer output.
1037
if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
1038
goto BAD_PAGE_ALLOC;
1041
if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile,
1042
(int)statBuf.st_size) != (int)statBuf.st_size)
1043
goto BAD_PAGE_ALLOC;
1045
fclose(pConPriv->pPageFile);
1046
pConPriv->pPageFile = (FILE *)NULL;
1047
unlink(pConPriv->pageFileName);
1048
free(pConPriv->pageFileName);
1049
pConPriv->pageFileName = (char *)NULL;
1055
FreePageFiles(pConPriv);
1057
if(pRasterFile != (FILE *)NULL)
1058
fclose(pRasterFile);
1059
if(rasterFileName != (char *)NULL)
1061
unlink(rasterFileName);
1062
Xfree(rasterFileName);
1079
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
1080
pCon->devPrivates[RasterContextPrivateIndex].ptr;
1081
char *preRasterStr = PRE_RASTER, *postRasterStr = POST_RASTER,
1082
*noRasterStr = NO_RASTER;
1085
* Check that options equals either PRE_RASTER or POST_RASTER.
1087
if(len_options == strlen(preRasterStr) &&
1088
strncmp(pOptions, preRasterStr, strlen(preRasterStr)) == 0)
1090
if(pConPriv->pPreRasterFile == (FILE *)NULL)
1092
if (!XpOpenTmpFile("w+", &pConPriv->preRasterFileName,
1093
&pConPriv->pPreRasterFile))
1096
if(fwrite(pData, sizeof(char), (size_t)len_data,
1097
pConPriv->pPreRasterFile) != (size_t)len_data)
1099
fflush(pConPriv->pPreRasterFile);
1101
else if(len_options == strlen(postRasterStr) &&
1102
strncmp(pOptions, postRasterStr, strlen(postRasterStr)) == 0)
1104
if(pConPriv->pPostRasterFile == (FILE *)NULL)
1106
if (!XpOpenTmpFile("w+", &pConPriv->postRasterFileName,
1107
&pConPriv->pPostRasterFile))
1110
if(fwrite(pData, sizeof(char), (size_t)len_data,
1111
pConPriv->pPostRasterFile) != (size_t)len_data)
1113
fflush(pConPriv->pPostRasterFile);
1115
else if(len_options == strlen(noRasterStr) &&
1116
strncmp(pOptions, noRasterStr, strlen(noRasterStr)) == 0)
1118
if(pConPriv->pNoRasterFile == (FILE *)NULL)
1120
if (!XpOpenTmpFile("w+", &pConPriv->noRasterFileName,
1121
&pConPriv->pNoRasterFile))
1124
if(fwrite(pData, sizeof(char), (size_t)len_data,
1125
pConPriv->pNoRasterFile) != (size_t)len_data)
1127
fflush(pConPriv->pNoRasterFile);
1136
* GetDocumentData notes which client is requesting the document data for
1137
* a particular context. The Raster driver's EndPage function causes the
1138
* data to be written to the proper client.
1142
XpContextPtr pContext,
1146
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
1147
pContext->devPrivates[RasterContextPrivateIndex].ptr;
1149
pConPriv->getDocClient = client;
1150
pConPriv->getDocBufSize = maxBufferSize;
1155
AllocateRasterPrivates(
1158
if(RasterGeneration != serverGeneration)
1160
RasterScreenPrivateIndex = AllocateScreenPrivateIndex();
1161
RasterContextPrivateIndex = XpAllocateContextPrivateIndex();
1162
XpAllocateContextPrivate( RasterContextPrivateIndex,
1163
sizeof( RasterContextPrivRec ) );
1165
RasterGeneration = serverGeneration;
1167
pScreen->devPrivates[RasterScreenPrivateIndex].ptr = (pointer)Xalloc(
1168
sizeof(RasterScreenPrivRec));
1172
* RasterChangeWindowAttributes - Make sure that the window's backing
1173
* store is turned on.
1176
RasterChangeWindowAttributes(
1180
Bool status = Success;
1181
ScreenPtr pScreen = pWin->drawable.pScreen;
1182
RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr)
1183
pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
1185
if(pWin->backingStore == NotUseful)
1187
pWin->backingStore = WhenMapped;
1188
mask |= CWBackingStore;
1191
if(pScreenPriv->ChangeWindowAttributes != NULL)
1193
pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
1194
status = pScreen->ChangeWindowAttributes(pWin, mask);
1195
pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes;
1201
* RasterValidateDocFormats - Inspects the files available in the
1202
* ddx-config/XP-RASTER directory to find the names of PDLs for which
1203
* we have processing commands. These names are then intersected with
1204
* the contents of the printer's document-formats-supported attribute,
1205
* and the result is stored back into document-formats-supported.
1206
* We have hard-coded knowledge of how to produce PS, so we always
1207
* leave that in, if it's listed in document-formats-supported,
1208
* even if we don't have a configuration file. If there is a
1209
* configuration file for PS, then its contents will override our default.
1212
RasterValidateDocFormats(
1218
* RasterValidateAttrs - Inspects and Corrects the attribute values
1219
* in the specified context.
1222
RasterValidateAttrs(
1225
RasterValidateDocFormats(pCon);
1226
XpValidatePrinterPool(pCon, &RasterValidatePoolsRec);
1227
XpValidateJobPool(pCon, &RasterValidatePoolsRec);
1228
XpValidateDocumentPool(pCon, &RasterValidatePoolsRec);
1232
* RasterInitContext - Establish the appropriate values for a
1233
* PrintContext used with the Raster Driver.
1235
static char DOC_ATT_SUPP[]="document-attributes-supported:\tdefault-medium document-format";
1236
static char JOB_ATT_SUPP[]="job-attributes-supported:\t";
1237
static char DDX_DIR[]="ddx-config";
1243
char *configFileName, *val, *attrStr;
1244
RasterContextPrivPtr pConPriv;
1245
XpDriverFuncsPtr pFuncs;
1248
* Initialize the attribute store for this printer.
1250
XpInitAttributes( pCon );
1253
* Validate the attributes
1255
RasterValidateAttrs( pCon );
1259
* Initialize the function pointers
1261
pFuncs = &( pCon->funcs );
1262
pFuncs->StartJob = StartJob;
1263
pFuncs->EndJob = EndJob;
1264
pFuncs->StartDoc = StartDoc;
1265
pFuncs->EndDoc = EndDoc;
1266
pFuncs->StartPage = StartPage;
1267
pFuncs->EndPage = EndPage;
1268
pFuncs->PutDocumentData = DocumentData;
1269
pFuncs->GetDocumentData = GetDocumentData;
1270
pFuncs->DestroyContext = RasterDestroyContext;
1271
pFuncs->GetAttributes = RasterGetAttributes;
1272
pFuncs->GetOneAttribute = RasterGetOneAttribute;
1273
pFuncs->SetAttributes = RasterSetAttributes;
1274
pFuncs->AugmentAttributes = RasterAugmentAttributes;
1275
pFuncs->GetMediumDimensions = RasterMediumDimensions;
1276
pFuncs->GetReproducibleArea = RasterReproducibleArea;
1279
* Set up the context privates
1281
pConPriv = (RasterContextPrivPtr)
1282
pCon->devPrivates[RasterContextPrivateIndex].ptr;
1284
pConPriv->jobFileName = (char *)NULL;
1285
pConPriv->pageFileName = (char *)NULL;
1286
pConPriv->preRasterFileName = (char *)NULL;
1287
pConPriv->postRasterFileName = (char *)NULL;
1288
pConPriv->noRasterFileName = (char *)NULL;
1289
pConPriv->pJobFile = (FILE *)NULL;
1290
pConPriv->pPageFile = (FILE *)NULL;
1291
pConPriv->pPreRasterFile = (FILE *)NULL;
1292
pConPriv->pPostRasterFile = (FILE *)NULL;
1293
pConPriv->pNoRasterFile = (FILE *)NULL;
1295
pConPriv->getDocClient = (ClientPtr)NULL;
1296
pConPriv->getDocBufSize = 0;
1299
* Get the configuration information for the context's printer
1301
configFileName = XpGetOneAttribute( pCon, XPPrinterAttr,
1302
"xp-ddx-config-file-name" );
1303
if(configFileName && strlen(configFileName))
1305
if( configFileName[0] == '/' )
1306
pConPriv->config = XrmGetFileDatabase( configFileName );
1309
char *configDir, *configFilePath;
1311
configDir = XpGetConfigDir(FALSE);
1312
configFilePath = (char *)malloc((strlen(configDir) +
1314
strlen(RASTER_DRIV_NAME) +
1315
strlen(configFileName) +
1317
sprintf(configFilePath, "%s/%s/%s/%s", configDir, DDX_DIR,
1318
RASTER_DRIV_NAME, configFileName);
1319
pConPriv->config = XrmGetFileDatabase(configFilePath);
1321
free(configFilePath);
1325
pConPriv->config = (XrmDatabase)NULL;
1328
* Add our own attribute initialization
1331
* document-attributes-supported
1333
val = XpGetOneAttribute(pCon, XPServerAttr, "document-attributes-supported");
1334
if((attrStr = (char *)xalloc(strlen(val) + strlen(DOC_ATT_SUPP) + 4)) ==
1337
sprintf(attrStr, "*%s %s", DOC_ATT_SUPP, val);
1338
XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
1342
* job-attributes-supported
1344
val = XpGetOneAttribute(pCon, XPServerAttr, "job-attributes-supported");
1345
if((attrStr = (char *)xalloc(strlen(val) + strlen(JOB_ATT_SUPP) + 4)) ==
1348
sprintf(attrStr, "*%s %s", JOB_ATT_SUPP, val);
1349
XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
1353
* PageAttributesSupported
1355
XpAugmentAttributes(pCon, XPPrinterAttr, "*xp-page-attributes-supported:");
1363
RasterDestroyContext(
1366
RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
1367
pCon->devPrivates[RasterContextPrivateIndex].ptr;
1370
* Clean up the temporary files
1372
FreePageFiles( pConPriv );
1374
if( pConPriv->pJobFile != (FILE *)NULL )
1376
fclose( pConPriv->pJobFile );
1377
pConPriv->pJobFile = (FILE *)NULL;
1379
if( pConPriv->jobFileName != (char *)NULL )
1381
unlink( pConPriv->jobFileName );
1382
Xfree( pConPriv->jobFileName );
1384
if(pConPriv->config)
1386
XrmDestroyDatabase(pConPriv->config);
1387
pConPriv->config = (XrmDatabase)NULL;
1390
XpDestroyAttributes( pCon );
1395
RasterGetAttributes(
1396
XpContextPtr pContext,
1399
return XpGetAttributes( pContext, class );
1403
RasterGetOneAttribute(
1404
XpContextPtr pContext,
1408
return XpGetOneAttribute( pContext, class, attr );
1412
RasterSetAttributes(XpContextPtr pCon,
1416
return XpSetAttributes( pCon, class, attributes );
1420
RasterAugmentAttributes(
1425
return XpAugmentAttributes( pCon, class, attributes );
1430
RasterContextPrivPtr pConPriv)
1432
if(pConPriv->pPageFile != (FILE *)NULL)
1434
fclose(pConPriv->pPageFile);
1435
pConPriv->pPageFile = (FILE *)NULL;
1437
if(pConPriv->pageFileName != (char *)NULL)
1439
unlink(pConPriv->pageFileName);
1440
Xfree(pConPriv->pageFileName);
1441
pConPriv->pageFileName = (char *)NULL;
1443
if(pConPriv->pPreRasterFile != (FILE *)NULL)
1445
fclose(pConPriv->pPreRasterFile);
1446
pConPriv->pPreRasterFile = (FILE *)NULL;
1448
if(pConPriv->preRasterFileName != (char *)NULL)
1450
unlink(pConPriv->preRasterFileName);
1451
Xfree(pConPriv->preRasterFileName);
1452
pConPriv->preRasterFileName = (char *)NULL;
1454
if(pConPriv->pPostRasterFile != (FILE *)NULL)
1456
fclose(pConPriv->pPostRasterFile);
1457
pConPriv->pPostRasterFile = (FILE *)NULL;
1459
if(pConPriv->postRasterFileName != (char *)NULL)
1461
unlink(pConPriv->postRasterFileName);
1462
Xfree(pConPriv->postRasterFileName);
1463
pConPriv->postRasterFileName = (char *)NULL;
1465
if(pConPriv->pNoRasterFile != (FILE *)NULL)
1467
fclose(pConPriv->pNoRasterFile);
1468
pConPriv->pNoRasterFile = (FILE *)NULL;
1470
if(pConPriv->noRasterFileName != (char *)NULL)
1472
unlink(pConPriv->noRasterFileName);
1473
Xfree(pConPriv->noRasterFileName);
1474
pConPriv->noRasterFileName = (char *)NULL;
1479
* RasterCloseScreen - Call any wrapped CloseScreen function,
1480
* and free the screen memory.
1487
Bool status = Success;
1488
RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr)
1489
pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
1492
* Call any wrapped CloseScreen proc.
1494
if(pScreenPriv->CloseScreen != NULL)
1496
pScreen->CloseScreen = pScreenPriv->CloseScreen;
1497
status = pScreen->CloseScreen(index, pScreen);
1498
pScreen->CloseScreen = RasterCloseScreen;
1501
Xfree(pScreenPriv->pBits);
1510
static void SigchldHndlr (int dummy)
1513
int olderrno = errno;
1514
struct sigaction act;
1515
sigfillset(&act.sa_mask);
1517
act.sa_handler = SigchldHndlr;
1519
(void) wait (&status);
1522
* Is this really necessary?
1524
sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
1529
* SystemCmd provides a wrapper for the 'system' library call. The call
1530
* appears to be sensitive to the handling of SIGCHLD, so this wrapper
1531
* sets the status to SIG_DFL, and then resets the established handler
1532
* after system returns.
1535
SystemCmd(char *cmdStr)
1538
struct sigaction newAct, oldAct;
1539
sigfillset(&newAct.sa_mask);
1540
newAct.sa_flags = 0;
1541
newAct.sa_handler = SIG_DFL;
1542
sigfillset(&oldAct.sa_mask);
1543
oldAct.sa_flags = 0;
1544
oldAct.sa_handler = SigchldHndlr;
1547
* get the old handler, and set the action to IGN
1549
sigaction(SIGCHLD, &newAct, &oldAct);
1551
status = system (cmdStr);
1553
sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL);
1558
* RasterMediumDimensions is installed in the GetMediumDimensions field
1559
* of each raster-initialized context.
1562
RasterMediumDimensions(XpContextPtr pCon,
1566
XpGetMediumDimensions(pCon, width, height);
1571
* RasterReproducibleArea is installed in the GetReproducibleArea field
1572
* of each raster-initialized context.
1575
RasterReproducibleArea(XpContextPtr pCon,
1578
XpGetReproductionArea(pCon, pRect);