#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <X11/Xprotostr.h>
#define NEED_EVENTS
#include <X11/Xproto.h>
#undef NEED_EVENTS
#include "Pcl.h"
#include "windowstr.h"
#include "attributes.h"
#include "AttrValid.h"
#include "Oid.h"
int
PclStartJob(
XpContextPtr pCon,
Bool sendClientData,
ClientPtr client)
{
PclContextPrivPtr pConPriv =
(PclContextPrivPtr)pCon->devPrivates[PclContextPrivateIndex].ptr;
PclPaletteMap *pal;
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;
}
if (!XpOpenTmpFile("w+", &pConPriv->jobFileName, &pConPriv->pJobFile))
return BadAlloc;
pConPriv->pSoftFontInfo = PclCreateSoftFontInfo();
pConPriv->palettes = NULL;
pConPriv->nextPaletteId = 4;
pConPriv->currentPalette = 0;
pal = &( pConPriv->staticGrayPalette );
pal->paletteId = 1;
pal->downloaded = 0;
pal = &( pConPriv->trueColorPalette );
pal->paletteId = 2;
pal->downloaded = 0;
pal = &( pConPriv->specialTrueColorPalette );
pal->paletteId = 3;
pal->downloaded = 0;
return Success;
}
int
PclEndJob(
XpContextPtr pCon,
Bool cancel)
{
PclContextPrivPtr priv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
#ifdef CCP_DEBUG
FILE *xpoutput;
#endif
FILE *fp;
int retVal;
char *fileName, *trailer;
struct stat statBuf;
PclPaletteMapPtr p;
trailer = "\033%-12345X@PJL RESET\n";
if( cancel == True )
{
if( priv->getDocClient != (ClientPtr)NULL ) {
XpFinishDocData( priv->getDocClient );
priv->getDocClient = NULL;
priv->getDocBufSize = 0;
}
return Success;
}
if( priv->getDocClient != (ClientPtr)NULL && priv->getDocBufSize > 0 )
{
if (!XpOpenTmpFile("w+", &fileName, &fp))
return BadAlloc;
#ifndef XP_PCL_LJ3
SEND_PCL( fp, trailer );
rewind( fp );
retVal = XpSendDocumentData( priv->getDocClient, fp,
strlen( trailer ),
priv->getDocBufSize );
#endif
fclose( fp );
unlink( fileName );
xfree( fileName );
if( priv->getDocClient != (ClientPtr)NULL ) {
XpFinishDocData( priv->getDocClient );
priv->getDocClient = NULL;
priv->getDocBufSize = 0;
}
return retVal;
}
#ifndef XP_PCL_LJ3
SEND_PCL( priv->pJobFile, trailer );
#endif
fflush( priv->pJobFile );
rewind( priv->pJobFile );
stat( priv->jobFileName, &statBuf );
#ifdef CCP_DEBUG
unlink( "/users/prince/XpOutput" );
xpoutput = fopen( "/users/prince/XpOutput", "w" );
rewind( priv->pJobFile );
TransferBytes( priv->pJobFile, xpoutput,
(int)statBuf.st_size );
fclose( xpoutput );
#endif
XpSubmitJob( priv->jobFileName, pCon );
fclose( priv->pJobFile );
unlink( priv->jobFileName );
xfree( priv->jobFileName );
priv->jobFileName = NULL;
PclDestroySoftFontInfo(priv->pSoftFontInfo);
priv->pSoftFontInfo = (PclSoftFontInfoPtr) NULL;
p = priv->palettes;
while( p )
{
p->downloaded = 0;
p = p->next;
}
return Success;
}
int
PclStartPage(
XpContextPtr pCon,
WindowPtr pWin)
{
PclContextPrivPtr pConPriv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
PclWindowPrivPtr pWinPriv =
(PclWindowPrivPtr)pWin->devPrivates[PclWindowPrivateIndex].ptr;
xRectangle repro;
char t[80];
XpOid orient, plex, tray, medium;
int dir, plexNum, num;
pWinPriv->validContext = 1;
pWinPriv->context = pCon;
if(pConPriv->pPageFile != (FILE *)NULL)
{
fclose(pConPriv->pPageFile);
pConPriv->pPageFile = (FILE *)NULL;
}
if(pConPriv->pageFileName != (char *)NULL)
{
unlink(pConPriv->pageFileName);
pConPriv->pageFileName = (char *)NULL;
}
if (!XpOpenTmpFile("w+", &pConPriv->pageFileName, &pConPriv->pPageFile))
return BadAlloc;
pConPriv->validGC = 0;
orient = XpGetContentOrientation( pCon );
switch( orient )
{
case xpoid_val_content_orientation_landscape:
dir = 1;
break;
case xpoid_val_content_orientation_reverse_portrait:
dir = 2;
break;
case xpoid_val_content_orientation_reverse_landscape:
dir = 3;
break;
case xpoid_val_content_orientation_portrait:
default:
dir = 0;
break;
}
sprintf( t, "\033&l%dO", dir );
SEND_PCL( pConPriv->pPageFile, t );
plex = XpGetPlex( pCon );
if( plex == xpoid_val_plex_duplex )
{
if( dir == 0 || dir == 2 )
plexNum = 1;
else
plexNum = 2;
}
else if( plex == xpoid_val_plex_tumble )
{
if( dir == 0 || dir == 2 )
plexNum = 2;
else
plexNum = 1;
}
else
plexNum = 0;
sprintf( t, "\033&l%dS", plexNum );
SEND_PCL( pConPriv->pPageFile, t );
medium = XpGetPageSize( pCon, &tray, NULL );
if( medium != xpoid_none )
{
switch( medium )
{
case xpoid_val_medium_size_na_legal:
num = 3;
break;
case xpoid_val_medium_size_iso_a3:
num = 27;
break;
case xpoid_val_medium_size_iso_a4:
num = 26;
break;
case xpoid_val_medium_size_executive:
num = 1;
break;
case xpoid_val_medium_size_ledger:
num = 6;
break;
case xpoid_val_medium_size_monarch_envelope:
num = 80;
break;
case xpoid_val_medium_size_na_number_10_envelope:
num = 81;
break;
case xpoid_val_medium_size_iso_designated_long:
num = 90;
break;
case xpoid_val_medium_size_iso_c5:
num = 91;
break;
case xpoid_val_medium_size_iso_b5:
num = 100;
break;
case xpoid_val_medium_size_jis_b5:
num = 45;
break;
case xpoid_val_medium_size_na_letter:
default:
num = 2;
break;
}
sprintf( t, "\033&l%dA", num );
SEND_PCL( pConPriv->pPageFile, t );
}
else
{
switch( tray )
{
case xpoid_val_input_tray_manual:
num = 2;
break;
case xpoid_val_input_tray_envelope:
num = 3;
break;
case xpoid_val_input_tray_large_capacity:
num = 5;
break;
case xpoid_val_input_tray_bottom:
num = 4;
break;
case xpoid_val_input_tray_main:
default:
num = 1;
break;
}
sprintf( t, "\033&l%dH", num );
SEND_PCL( pConPriv->pPageFile, t );
}
XpGetReproductionArea( pCon, &repro );
sprintf( t, "\033&l0E\033*p%dx%dY", repro.x - 75, repro.y );
SEND_PCL( pConPriv->pPageFile, t );
sprintf( t, "\033*c%dx%dY\033*c0T", (int)(repro.width / 300.0 * 720.0),
(int)(repro.height / 300.0 * 720.0) );
SEND_PCL( pConPriv->pPageFile, t );
sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, repro.x +
repro.width, repro.y + repro.height, repro.y );
SEND_PCL( pConPriv->pPageFile, t );
return Success;
}
static int
SendDocData( PclContextPrivPtr pPriv )
{
struct stat statBuf;
int ret;
rewind( pPriv->pJobFile );
if( stat( pPriv->jobFileName, &statBuf ) < 0 )
return BadAlloc;
ret = XpSendDocumentData( pPriv->getDocClient, pPriv->pJobFile,
(int)statBuf.st_size, pPriv->getDocBufSize );
fclose( pPriv->pJobFile );
unlink( pPriv->jobFileName );
xfree(pPriv->jobFileName);
if (!XpOpenTmpFile("w+", &pPriv->jobFileName, &pPriv->pJobFile))
return BadAlloc;
return ret;
}
int
PclEndPage(
XpContextPtr pCon,
WindowPtr pWin)
{
PclContextPrivPtr pConPriv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
struct stat statBuf;
SEND_PCL( pConPriv->pPageFile, "\014" );
fflush( pConPriv->pPageFile );
rewind(pConPriv->pPageFile);
if(stat(pConPriv->pageFileName, &statBuf) < 0)
return BadAlloc;
if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile,
(int)statBuf.st_size) != (int)statBuf.st_size)
return BadAlloc;
if( pConPriv->getDocClient != (ClientPtr)NULL &&
pConPriv->getDocBufSize > 0 )
{
return SendDocData( pConPriv );
}
return Success;
}
int
PclStartDoc(XpContextPtr pCon,
XPDocumentType type)
{
PclContextPrivPtr pConPriv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
#ifndef XP_PCL_LJ3
SEND_PCL( pConPriv->pJobFile,
"\033%-12345X@PJL SET RESOLUTION = 300\r\n" );
#endif
SEND_PCL( pConPriv->pJobFile, "\033E\033%0BIN,SP1,TR0;\033%0A" );
pConPriv->isRaw = (type == XPDocRaw);
return Success;
}
int
PclEndDoc(
XpContextPtr pCon,
Bool cancel)
{
return Success;
}
#define DOC_PCL 1
#define DOC_HPGL 2
int
PclDocumentData(
XpContextPtr pCon,
DrawablePtr pDraw,
char *pData,
int len_data,
char *pFmt,
int len_fmt,
char *pOpt,
int len_opt,
ClientPtr client)
{
int type = 0;
PclContextPrivPtr pPriv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
XpOidDocFmtList *formats;
XpOidDocFmt *f;
char t[80];
xRectangle repro;
formats = XpGetDocFmtListAttr( pCon, XPPrinterAttr,
(pPriv->isRaw) ?
xpoid_att_xp_raw_formats_supported :
xpoid_att_xp_embedded_formats_supported,
NULL );
f = XpOidDocFmtNew( pFmt );
if( !XpOidDocFmtListHasFmt( formats, f ) )
{
XpOidDocFmtListDelete( formats );
XpOidDocFmtDelete( f );
return BadMatch;
}
XpOidDocFmtListDelete( formats );
if( !(pPriv->isRaw) )
{
if( !strcmp( f->format, "PCL" ) )
type = DOC_PCL;
else if( !strcmp( f->format, "HPGL" ) )
type = DOC_HPGL;
else
{
XpOidDocFmtDelete( f );
return BadMatch;
}
switch( type )
{
case DOC_HPGL:
sprintf( t, "\033&l0E\033*p%dx%dY",
pDraw->x - 75,
pDraw->y );
SEND_PCL( pPriv->pPageFile, t );
sprintf( t, "\033*c%dx%dY\033*coT",
(int)( pDraw->width / 300.0 * 720.0 ),
(int)( pDraw->height / 300.0 * 720.0 ) );
SEND_PCL( pPriv->pPageFile, t );
break;
}
}
SEND_PCL_COUNT( pPriv->pPageFile, pData, len_data );
if( !(pPriv->isRaw) )
switch( type )
{
case DOC_HPGL:
XpGetReproductionArea( pCon, &repro );
sprintf( t, "\033&l0E\033*p%dx%dY", repro.x - 75, repro.y );
SEND_PCL( pPriv->pPageFile, t );
sprintf( t, "\033*c%dx%dY\033*c0T",
(int)(repro.width / 300.0 * 720.0),
(int)(repro.height / 300.0 * 720.0) );
SEND_PCL( pPriv->pPageFile, t );
sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, repro.x +
repro.width, repro.y + repro.height, repro.y );
SEND_PCL( pPriv->pPageFile, t );
break;
}
XpOidDocFmtDelete( f );
return Success;
}
int
PclGetDocumentData(
XpContextPtr pCon,
ClientPtr client,
int maxBufferSize)
{
PclContextPrivPtr pPriv = (PclContextPrivPtr)
pCon->devPrivates[PclContextPrivateIndex].ptr;
pPriv->getDocClient = client;
pPriv->getDocBufSize = maxBufferSize;
return Success;
}