#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 <errno.h>
#include <X11/Xprotostr.h>
#define NEED_EVENTS
#include <X11/Xproto.h>
#undef NEED_EVENTS
#include "Ps.h"
#include "windowstr.h"
#include "attributes.h"
#include "Oid.h"
static void
S_GetPageAttributes(XpContextPtr pCon,int *iorient,int *icount, int *iplex,
int *ires, unsigned short *iwd, unsigned short *iht)
{
char *count;
XpOid orient, plex;
orient = XpGetContentOrientation(pCon);
switch (orient) {
case xpoid_val_content_orientation_landscape:
*iorient = 1;
break;
case xpoid_val_content_orientation_reverse_portrait:
*iorient = 2;
break;
case xpoid_val_content_orientation_reverse_landscape:
*iorient = 3;
break;
case xpoid_val_content_orientation_portrait:
default:
*iorient = 0;
break;
}
count = XpGetOneAttribute(pCon, XPDocAttr, "copy-count");
if( count )
{
int ii = sscanf(count, "%d", icount);
if( ii!=1 ) *icount = 1;
}
else *icount = 1;
plex = XpGetPlex(pCon);
switch(plex)
{
case xpoid_val_plex_duplex:
*iplex = 1;
break;
case xpoid_val_plex_tumble:
*iplex = 2;
break;
default:
*iplex = 0;
break;
}
*ires = XpGetResolution(pCon);
XpGetMediumDimensions(pCon, iwd, iht);
}
int
PsStartJob(
XpContextPtr pCon,
Bool sendClientData,
ClientPtr client)
{
PsContextPrivPtr pConPriv =
(PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
return BadAlloc;
return Success;
}
int
PsEndJob(
XpContextPtr pCon,
Bool cancel)
{
int r;
struct stat buffer;
int error;
PsContextPrivPtr priv =
(PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
if (cancel == True) {
if (priv->getDocClient != (ClientPtr) NULL) {
(void) XpFinishDocData( priv->getDocClient );
priv->getDocClient = NULL;
priv->getDocBufSize = 0;
}
(void) fclose(priv->pJobFile);
priv->pJobFile = NULL;
unlink(priv->jobFileName);
xfree(priv->jobFileName);
priv->jobFileName = (char *)NULL;
PsFreeFontInfoRecords(priv);
return Success;
}
PsOut_EndFile(priv->pPsOut, 0);
priv->pPsOut = NULL;
error = (fclose(priv->pJobFile) == EOF);
priv->pJobFile = NULL;
if (error) {
if (priv->getDocClient != (ClientPtr) NULL) {
(void) XpFinishDocData( priv->getDocClient );
priv->getDocClient = NULL;
priv->getDocBufSize = 0;
}
unlink(priv->jobFileName);
xfree(priv->jobFileName);
priv->jobFileName = (char *)NULL;
PsFreeFontInfoRecords(priv);
return BadAlloc;
}
if (priv->getDocClient != NULL && priv->getDocBufSize > 0) {
FILE *file;
file = fopen(priv->jobFileName, "r");
if (!file || (fstat(fileno(file), &buffer) < 0))
r = BadAlloc;
else
r = XpSendDocumentData(priv->getDocClient, file, buffer.st_size,
priv->getDocBufSize);
if (file)
fclose(file);
(void) XpFinishDocData(priv->getDocClient);
priv->getDocClient = NULL;
priv->getDocBufSize = 0;
}
else {
XpSubmitJob(priv->jobFileName, pCon);
r = Success;
}
unlink(priv->jobFileName);
xfree(priv->jobFileName);
priv->jobFileName = (char *)NULL;
PsFreeFontInfoRecords(priv);
#ifdef BM_CACHE
PsBmClearImageCache();
#endif
return r;
}
int
PsStartPage(
XpContextPtr pCon,
WindowPtr pWin)
{
int iorient, iplex, icount, ires;
unsigned short iwd, iht;
PsContextPrivPtr pConPriv =
(PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
PsWindowPrivPtr pWinPriv =
(PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr;
pWinPriv->validContext = 1;
pWinPriv->context = pCon;
S_GetPageAttributes(pCon,&iorient,&icount,&iplex,&ires,&iwd,&iht);
if (pConPriv->pPsOut == NULL) {
char *title;
title = XpGetOneAttribute(pCon, XPJobAttr, "job-name");
pConPriv->pPsOut = PsOut_BeginFile(pConPriv->pJobFile,
title, iorient, icount, iplex, ires,
(int)iwd, (int)iht, False);
pConPriv->fontInfoRecords = NULL;
pConPriv->fontTypeInfoRecords = NULL;
}
PsOut_BeginPage(pConPriv->pPsOut, iorient, icount, iplex, ires,
(int)iwd, (int)iht);
return Success;
}
int
PsEndPage(
XpContextPtr pCon,
WindowPtr pWin)
{
PsWindowPrivPtr pWinPriv =
(PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr;
PsContextPrivPtr pConPriv =
(PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
PsOut_EndPage(pConPriv->pPsOut);
pWinPriv->validContext = 0;
pWinPriv->context = NULL;
return Success;
}
int
PsStartDoc(XpContextPtr pCon, XPDocumentType type)
{
int iorient, iplex, icount, ires;
unsigned short iwd, iht;
char *title;
PsContextPrivPtr pConPriv =
(PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr;
title = XpGetOneAttribute(pCon, XPJobAttr, "job-name");
S_GetPageAttributes(pCon,&iorient,&icount,&iplex,&ires,&iwd,&iht);
pConPriv->pPsOut = PsOut_BeginFile(pConPriv->pJobFile,
title, iorient, icount, iplex, ires,
(int)iwd, (int)iht, (Bool)(type == XPDocRaw));
pConPriv->fontInfoRecords = NULL;
pConPriv->fontTypeInfoRecords = NULL;
return Success;
}
int
PsEndDoc(
XpContextPtr pCon,
Bool cancel)
{
return Success;
}
int
PsDocumentData(
XpContextPtr pCon,
DrawablePtr pDraw,
char *pData,
int len_data,
char *pFmt,
int len_fmt,
char *pOpt,
int len_opt,
ClientPtr client)
{
PsContextPrivPtr cPriv;
PsOutPtr psOut;
if (len_fmt != 12 ||
strncasecmp(pFmt, "PostScript 2", len_fmt) != 0 ||
len_opt)
return BadValue;
cPriv = pCon->devPrivates[PsContextPrivateIndex].ptr;
psOut = cPriv->pPsOut;
if (pDraw)
PsOut_BeginFrame(psOut, 0, 0, pDraw->x, pDraw->y,
pDraw->width, pDraw->height);
PsOut_RawData(psOut, pData, len_data);
if (pDraw)
PsOut_EndFrame(psOut);
return Success;
}
int
PsGetDocumentData(
XpContextPtr pCon,
ClientPtr client,
int maxBufferSize)
{
PsContextPrivPtr pPriv = (PsContextPrivPtr)
pCon->devPrivates[PsContextPrivateIndex].ptr;
pPriv->getDocClient = client;
pPriv->getDocBufSize = maxBufferSize;
return Success;
}