1577 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1577 lines
		
	
	
		
			42 KiB
		
	
	
	
		
			C
		
	
	
	
/* $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
 | 
						|
**    *
 | 
						|
**    *********************************************************
 | 
						|
** 
 | 
						|
********************************************************************/
 | 
						|
 | 
						|
#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 "X.h"
 | 
						|
#include "Xos.h"	/* for SIGCLD on pre-POSIX systems */
 | 
						|
#define NEED_EVENTS
 | 
						|
#include "Xproto.h"
 | 
						|
#undef NEED_EVENTS
 | 
						|
#include "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 "mfb.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.
 | 
						|
     */
 | 
						|
    mfbScreenInit(pScreen, pPriv->pBits, maxDim, maxDim, maxRes,
 | 
						|
		  maxRes, maxDim);
 | 
						|
    miInitializeBackingStore(pScreen);
 | 
						|
    pScreen->blackPixel = 1;
 | 
						|
    pScreen->whitePixel = 0;
 | 
						|
    if(mfbCreateDefColormap(pScreen) == FALSE)
 | 
						|
	; /* XXX what do I do if it fails? */
 | 
						|
    
 | 
						|
    /*
 | 
						|
    cfbScreenInit(pScreen, pPriv->pBits, maxWidth, maxHeight, maxXres,
 | 
						|
		  maxYres, maxWidth);
 | 
						|
    miInitializeBackingStore(pScreen);
 | 
						|
    scalingScreenInit(pScreen);
 | 
						|
    */
 | 
						|
 | 
						|
    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;
 | 
						|
}
 |