#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "Pcl.h"
#include "fb.h"
#include <X11/Xos.h>
#include "attributes.h"
#include "DiPrint.h"
#define MODELDIRNAME "/models"
static void AllocatePclPrivates(ScreenPtr pScreen);
static int PclInitContext(XpContextPtr pCon);
static Bool PclDestroyContext(XpContextPtr pCon);
int PclScreenPrivateIndex;
int PclContextPrivateIndex;
int PclPixmapPrivateIndex;
int PclWindowPrivateIndex;
int PclGCPrivateIndex;
#ifdef XP_PCL_COLOR
static VisualRec Visuals[] =
{
{ 1, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0 },
{ 2, PseudoColor, 8, 256, 8, 0, 0, 0, 0, 0, 0 },
{ 3, TrueColor, 8, 256, 24, 0xFF0000, 0xFF00, 0xFF, 16, 8, 0 }
};
static DepthRec Depths[] =
{
{ 1, 1, NULL },
{ 8, 1, NULL },
{ 24, 1, NULL }
};
#else
static VisualRec Visuals[] =
{
{ 1, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0}
};
static DepthRec Depths[] =
{
{ 1, 1, NULL }
};
#endif
#define NUM_VISUALS(visuals) (sizeof(visuals) / sizeof(VisualRec))
#define NUM_DEPTHS(depths) (sizeof(depths) / sizeof(DepthRec))
Bool
PclCloseScreen(int index,
ScreenPtr pScreen)
{
PclScreenPrivPtr pPriv = pScreen->devPrivates[PclScreenPrivateIndex].ptr;
pScreen->CloseScreen = pPriv->CloseScreen;
xfree( pPriv );
return (*pScreen->CloseScreen)(index, pScreen);
}
Bool
InitializePclDriver(
int ndx,
ScreenPtr pScreen,
int argc,
char **argv)
{
int maxRes, xRes, yRes, maxDim;
unsigned i;
PclScreenPrivPtr pPriv;
#ifdef XP_PCL_COLOR
XpRegisterInitFunc( pScreen, "XP-PCL-COLOR", PclInitContext );
#elif XP_PCL_MONO
XpRegisterInitFunc( pScreen, "XP-PCL-MONO", PclInitContext );
#else
XpRegisterInitFunc( pScreen, "XP-PCL-LJ3", PclInitContext );
#endif
AllocatePclPrivates(pScreen);
pPriv =
(PclScreenPrivPtr)pScreen->devPrivates[PclScreenPrivateIndex].ptr;
maxDim = MAX( pScreen->height, pScreen->width );
xRes = pScreen->width / ( pScreen->mmWidth / 25.4 );
yRes = pScreen->height / ( pScreen->mmHeight / 25.4 );
maxRes = MAX( xRes, yRes );
#ifdef XP_PCL_COLOR
fbScreenInit( pScreen, NULL, maxDim, maxDim, maxRes, maxRes,
maxRes, 8 );
for( i = 0; (int) i < pScreen->numDepths; i++ )
xfree( pScreen->allowedDepths[i].vids );
xfree( pScreen->allowedDepths );
xfree( pScreen->visuals );
#else
fbScreenInit( pScreen, NULL, maxDim, maxDim, maxRes, maxRes,
maxRes, 1 );
#endif
miInitializeBackingStore ( pScreen );
pScreen->defColormap = FakeClientID(0);
pScreen->blackPixel = 1;
pScreen->whitePixel = 0;
pPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = PclCloseScreen;
pScreen->QueryBestSize = (QueryBestSizeProcPtr)PclQueryBestSize;
pScreen->SaveScreen = (SaveScreenProcPtr)_XpBoolNoop;
pScreen->GetImage = (GetImageProcPtr)_XpVoidNoop;
pScreen->GetSpans = (GetSpansProcPtr)_XpVoidNoop;
pScreen->CreateWindow = PclCreateWindow;
pScreen->DestroyWindow = PclDestroyWindow;
pScreen->ChangeWindowAttributes = PclChangeWindowAttributes;
pScreen->PaintWindowBackground = PclPaintWindow;
pScreen->PaintWindowBorder = PclPaintWindow;
pScreen->CopyWindow = PclCopyWindow;
pScreen->CreatePixmap = fbCreatePixmap;
pScreen->DestroyPixmap = fbDestroyPixmap;
pScreen->RealizeFont = PclRealizeFont;
pScreen->UnrealizeFont = PclUnrealizeFont;
pScreen->CreateGC = PclCreateGC;
pScreen->CreateColormap = PclCreateColormap;
pScreen->DestroyColormap = PclDestroyColormap;
pScreen->InstallColormap = (InstallColormapProcPtr)NoopDDA;
pScreen->UninstallColormap = (UninstallColormapProcPtr)NoopDDA;
pScreen->ListInstalledColormaps = PclListInstalledColormaps;
pScreen->StoreColors = PclStoreColors;
pScreen->BitmapToRegion = fbPixmapToRegion;
pScreen->ConstrainCursor = PclConstrainCursor;
pScreen->CursorLimits = PclCursorLimits;
pScreen->DisplayCursor = PclDisplayCursor;
pScreen->RealizeCursor = PclRealizeCursor;
pScreen->UnrealizeCursor = PclUnrealizeCursor;
pScreen->RecolorCursor = PclRecolorCursor;
pScreen->SetCursorPosition = PclSetCursorPosition;
pScreen->visuals = Visuals;
pScreen->numVisuals = NUM_VISUALS( Visuals );
pScreen->allowedDepths = Depths;
pScreen->numDepths = NUM_DEPTHS( Depths );
for( i = 0; i < NUM_DEPTHS( Depths ); i++ )
{
pScreen->allowedDepths[i].vids =
(VisualID *)xalloc( sizeof(VisualID ) );
pScreen->allowedDepths[i].vids[0] = i + 1;
}
#ifdef XP_PCL_COLOR
pScreen->rootVisual = 2;
pScreen->rootDepth = 8;
#else
pScreen->rootVisual = 1;
pScreen->rootDepth = 1;
#endif
pPriv->colormaps = NULL;
PclCreateDefColormap( pScreen );
return TRUE;
}
static void
AllocatePclPrivates(ScreenPtr pScreen)
{
static unsigned long PclGeneration = 0;
if((unsigned long) PclGeneration != serverGeneration)
{
PclScreenPrivateIndex = AllocateScreenPrivateIndex();
PclWindowPrivateIndex = AllocateWindowPrivateIndex();
AllocateWindowPrivate( pScreen, PclWindowPrivateIndex,
sizeof( PclWindowPrivRec ) );
PclContextPrivateIndex = XpAllocateContextPrivateIndex();
XpAllocateContextPrivate( PclContextPrivateIndex,
sizeof( PclContextPrivRec ) );
PclGCPrivateIndex = AllocateGCPrivateIndex();
AllocateGCPrivate( pScreen, PclGCPrivateIndex,
sizeof( PclGCPrivRec ) );
PclPixmapPrivateIndex = AllocatePixmapPrivateIndex();
AllocatePixmapPrivate( pScreen, PclPixmapPrivateIndex,
sizeof( PclPixmapPrivRec ) );
PclGeneration = serverGeneration;
}
pScreen->devPrivates[PclScreenPrivateIndex].ptr = (pointer)xalloc(
sizeof(PclScreenPrivRec));
}
static char DOC_ATT_SUPP[]="document-attributes-supported";
static char DOC_ATT_VAL[]="document-format xp-listfonts-modes";
static char JOB_ATT_SUPP[]="job-attributes-supported";
static char JOB_ATT_VAL[]="";
static char PAGE_ATT_SUPP[]="xp-page-attributes-supported";
static char PAGE_ATT_VAL[]="content-orientation default-printer-resolution \
default-input-tray default-medium plex xp-listfonts-modes";
static int
PclInitContext(XpContextPtr pCon)
{
XpDriverFuncsPtr pFuncs;
PclContextPrivPtr pConPriv;
char *server, *attrStr;
char *modelID;
char *configDir;
char *pathName;
int i, j;
float width, height;
XpOidMediumDiscreteSizeList* ds_list;
XpOidArea* repro;
XpOid page_size;
XpOidMediumSS* m;
XpInitAttributes( pCon );
pFuncs = &( pCon->funcs );
pFuncs->StartJob = PclStartJob;
pFuncs->EndJob = PclEndJob;
pFuncs->StartDoc = PclStartDoc;
pFuncs->EndDoc = PclEndDoc;
pFuncs->StartPage = PclStartPage;
pFuncs->EndPage = PclEndPage;
pFuncs->PutDocumentData = PclDocumentData;
pFuncs->GetDocumentData = PclGetDocumentData;
pFuncs->GetAttributes = PclGetAttributes;
pFuncs->SetAttributes = PclSetAttributes;
pFuncs->AugmentAttributes = PclAugmentAttributes;
pFuncs->GetOneAttribute = PclGetOneAttribute;
pFuncs->DestroyContext = PclDestroyContext;
pFuncs->GetMediumDimensions = PclGetMediumDimensions;
pFuncs->GetReproducibleArea = PclGetReproducibleArea;
pConPriv =
(PclContextPrivPtr)pCon->devPrivates[PclContextPrivateIndex].ptr;
pConPriv->jobFileName = (char *)NULL;
pConPriv->pageFileName = (char *)NULL;
pConPriv->pJobFile = (FILE *)NULL;
pConPriv->pPageFile = (FILE *)NULL;
pConPriv->dash = NULL;
pConPriv->validGC = 0;
pConPriv->getDocClient = (ClientPtr)NULL;
pConPriv->getDocBufSize = 0;
modelID = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-model-identifier");
if ( (configDir = XpGetConfigDir(False)) != (char *) NULL ) {
pathName = (char *)xalloc(strlen(configDir) + strlen(MODELDIRNAME) +
strlen(modelID) + strlen("color.map") + 4);
if (pathName) {
sprintf(pathName, "%s/%s/%s/%s", configDir, MODELDIRNAME, modelID,
"color.map");
pConPriv->ctbl = PclReadMap(pathName, &pConPriv->ctbldim);
xfree(pathName);
} else
pConPriv->ctbl = NULL;
} else
pConPriv->ctbl = NULL;
#ifdef XP_PCL_LJ3
pConPriv->fcount = 0;
if ( !(pConPriv->figures = (char *)xalloc(1024)) )
pConPriv->fcount_max = 0;
else
pConPriv->fcount_max = 1024;
#endif
server = XpGetOneAttribute( pCon, XPServerAttr, DOC_ATT_SUPP );
if( ( attrStr = (char *)xalloc(strlen(server) + strlen(DOC_ATT_SUPP)
+ strlen(DOC_ATT_VAL) +
strlen(PAGE_ATT_VAL) + 8 ) )
== (char *)NULL )
return BadAlloc;
sprintf( attrStr, "*%s:\t%s %s %s", DOC_ATT_SUPP, server,
DOC_ATT_VAL, PAGE_ATT_VAL );
XpAugmentAttributes( pCon, XPPrinterAttr, attrStr );
xfree( attrStr );
server = XpGetOneAttribute( pCon, XPServerAttr, JOB_ATT_SUPP );
if( ( attrStr = (char *)xalloc(strlen(server) + strlen(JOB_ATT_SUPP)
+ strlen(JOB_ATT_VAL) + 8 ) )
== (char *)NULL )
return BadAlloc;
sprintf( attrStr, "*%s:\t%s %s", JOB_ATT_SUPP, server, JOB_ATT_VAL );
XpAugmentAttributes( pCon, XPPrinterAttr, attrStr );
xfree( attrStr );
server = XpGetOneAttribute( pCon, XPServerAttr, PAGE_ATT_SUPP );
if( ( attrStr = (char *)xalloc(strlen(server) + strlen(PAGE_ATT_SUPP)
+ strlen(PAGE_ATT_VAL) + 8 ) )
== (char *)NULL )
return BadAlloc;
sprintf( attrStr, "*%s:\t%s %s", PAGE_ATT_SUPP, server, PAGE_ATT_VAL );
XpAugmentAttributes( pCon, XPPrinterAttr, attrStr );
xfree( attrStr );
XpValidateAttributePool( pCon, XPPrinterAttr, &PclValidatePoolsRec );
m = XpGetMediumSSAttr( pCon, XPPrinterAttr,
xpoid_att_medium_source_sizes_supported,
(const XpOidList*) NULL,
(const XpOidList*) NULL );
for( i = 0; i < XpOidMediumSSCount( m ); i++ )
{
if( XpOidMediumSS_DISCRETE == (m->mss)[i].mstag )
{
ds_list = (m->mss)[i].ms.discrete;
for( j = 0; j < ds_list->count; j++ )
{
repro = &(ds_list->list)[j].assured_reproduction_area;
page_size = (ds_list->list)[j].page_size;
XpGetMediumMillimeters( page_size, &width, &height );
if( repro->minimum_x < 6.35 )
repro->minimum_x = 6.35;
if( width - repro->maximum_x < 6.35 )
repro->maximum_x = width - 6.35;
}
}
}
XpPutMediumSSAttr( pCon, XPPrinterAttr,
xpoid_att_medium_source_sizes_supported, m );
XpOidMediumSSDelete( m );
XpValidateAttributePool( pCon, XPDocAttr, &PclValidatePoolsRec );
XpValidateAttributePool( pCon, XPJobAttr, &PclValidatePoolsRec );
XpValidateAttributePool( pCon, XPPageAttr, &PclValidatePoolsRec );
pConPriv->palettes = NULL;
return Success;
}
static Bool
PclDestroyContext(XpContextPtr pCon)
{
PclContextPrivPtr pConPriv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
PclPaletteMapPtr p, t;
PclCmapToContexts *pCmap;
ScreenPtr screen;
PclScreenPrivPtr sPriv;
PclContextListPtr con, prevCon, temp;
if( pConPriv->pPageFile != (FILE *)NULL )
{
fclose( pConPriv->pPageFile );
pConPriv->pPageFile = (FILE *)NULL;
}
if( pConPriv->pageFileName != (char *)NULL )
{
unlink( pConPriv->pageFileName );
xfree( pConPriv->pageFileName );
pConPriv->pageFileName = (char *)NULL;
}
if( pConPriv->pJobFile != (FILE *)NULL )
{
fclose( pConPriv->pJobFile );
pConPriv->pJobFile = NULL;
}
if( pConPriv->jobFileName != (char *)NULL )
{
unlink( pConPriv->jobFileName );
xfree( pConPriv->jobFileName );
pConPriv->jobFileName = (char *)NULL;
}
xfree( pConPriv->dash );
xfree(pConPriv->ctbl);
pConPriv->ctbl = NULL;
#ifdef XP_PCL_LJ3
xfree( pConPriv->figures );
#endif
p = pConPriv->palettes;
while( p )
{
t = p;
p = p->next;
xfree( t );
}
pConPriv->palettes = NULL;
screen = screenInfo.screens[pCon->screenNum];
sPriv = (PclScreenPrivPtr)screen->devPrivates[PclScreenPrivateIndex].ptr;
pCmap = sPriv->colormaps;
while( pCmap )
{
con = pCmap->contexts;
prevCon = NULL;
while( con )
{
if( con->context->contextID == pCon->contextID )
{
if( prevCon )
{
temp = con;
prevCon->next = con = con->next;
}
else
{
temp = pCmap->contexts;
pCmap->contexts = con = con->next;
}
xfree( temp );
}
else
con = con->next;
}
pCmap = pCmap->next;
}
XpDestroyAttributes(pCon);
return Success;
}
XpContextPtr
PclGetContextFromWindow(WindowPtr win)
{
PclWindowPrivPtr pPriv;
while( win )
{
pPriv =
(PclWindowPrivPtr)win->devPrivates[PclWindowPrivateIndex].ptr;
if( pPriv->validContext )
return pPriv->context;
win = win->parent;
}
return NULL;
}