#define _XP_PRINT_SERVER_
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xos.h>
#define NEED_EVENTS
#include <X11/Xproto.h>
#undef NEED_EVENTS
#include "misc.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "extnsionst.h"
#include "dixstruct.h"
#include <X11/Xatom.h>
#include <X11/extensions/Print.h>
#include <X11/extensions/Printstr.h>
#include "../hw/xprint/DiPrint.h"
#include "../hw/xprint/attributes.h"
#include "modinit.h"
static void XpResetProc(ExtensionEntry *);
static int ProcXpDispatch(ClientPtr);
static int ProcXpSwappedDispatch(ClientPtr);
static int ProcXpQueryVersion(ClientPtr);
static int ProcXpGetPrinterList(ClientPtr);
static int ProcXpCreateContext(ClientPtr);
static int ProcXpSetContext(ClientPtr);
static int ProcXpGetContext(ClientPtr);
static int ProcXpDestroyContext(ClientPtr);
static int ProcXpGetContextScreen(ClientPtr);
static int ProcXpStartJob(ClientPtr);
static int ProcXpEndJob(ClientPtr);
static int ProcXpStartDoc(ClientPtr);
static int ProcXpEndDoc(ClientPtr);
static int ProcXpStartPage(ClientPtr);
static int ProcXpEndPage(ClientPtr);
static int ProcXpSelectInput(ClientPtr);
static int ProcXpInputSelected(ClientPtr);
static int ProcXpPutDocumentData(ClientPtr);
static int ProcXpGetDocumentData(ClientPtr);
static int ProcXpGetAttributes(ClientPtr);
static int ProcXpGetOneAttribute(ClientPtr);
static int ProcXpSetAttributes(ClientPtr);
static int ProcXpRehashPrinterList(ClientPtr);
static int ProcXpQueryScreens(ClientPtr);
static int ProcXpGetPageDimensions(ClientPtr);
static int ProcXpSetImageResolution(ClientPtr);
static int ProcXpGetImageResolution(ClientPtr);
static void SwapXpNotifyEvent(xPrintPrintEvent *, xPrintPrintEvent *);
static void SwapXpAttributeEvent(xPrintAttributeEvent *, xPrintAttributeEvent *);
static int SProcXpGetPrinterList(ClientPtr);
static int SProcXpCreateContext(ClientPtr);
static int SProcXpSetContext(ClientPtr);
static int SProcXpGetContext(ClientPtr);
static int SProcXpDestroyContext(ClientPtr);
static int SProcXpGetContextScreen(ClientPtr);
static int SProcXpStartJob(ClientPtr);
static int SProcXpEndJob(ClientPtr);
static int SProcXpStartDoc(ClientPtr);
static int SProcXpEndDoc(ClientPtr);
static int SProcXpStartPage(ClientPtr);
static int SProcXpEndPage(ClientPtr);
static int SProcXpSelectInput(ClientPtr);
static int SProcXpInputSelected(ClientPtr);
static int SProcXpPutDocumentData(ClientPtr);
static int SProcXpGetDocumentData(ClientPtr);
static int SProcXpGetAttributes(ClientPtr);
static int SProcXpGetOneAttribute(ClientPtr);
static int SProcXpSetAttributes(ClientPtr);
static int SProcXpRehashPrinterList(ClientPtr);
static int SProcXpGetPageDimensions(ClientPtr);
static int SProcXpSetImageResolution(ClientPtr);
static int SProcXpGetImageResolution(ClientPtr);
static void SendXpNotify(XpContextPtr, int, int);
static void SendAttributeNotify(XpContextPtr, int);
static int XpFreeClient(pointer, XID);
static int XpFreeContext(pointer, XID);
static int XpFreePage(pointer, XID);
static Bool XpCloseScreen(int, ScreenPtr);
static CARD32 GetAllEventMasks(XpContextPtr);
static struct _XpClient *CreateXpClient(ClientPtr);
static void InitContextPrivates(XpContextPtr);
static void ResetContextPrivates(void);
static struct _XpClient *FindClient(XpContextPtr, ClientPtr);
static struct _XpClient *AcquireClient(XpContextPtr, ClientPtr);
typedef struct _driver {
struct _driver *next;
char *name;
int (* CreateContext)(XpContextPtr);
} XpDriverRec, *XpDriverPtr;
typedef struct _xpScreen {
Bool (* CloseScreen)(int, ScreenPtr);
struct _driver *drivers;
} XpScreenRec, *XpScreenPtr;
typedef struct _XpClient {
struct _XpClient *pNext;
ClientPtr client;
XpContextPtr context;
CARD32 eventMask;
XID contextClientID;
} XpClientRec, *XpClientPtr;
static void FreeXpClient(XpClientPtr, Bool);
typedef struct _XpPage {
XpContextPtr context;
} XpPageRec, *XpPagePtr;
typedef struct _XpStPageRec {
XpContextPtr pContext;
Bool slept;
XpPagePtr pPage;
WindowPtr pWin;
} XpStPageRec, *XpStPagePtr;
typedef struct _XpStDocRec {
XpContextPtr pContext;
Bool slept;
CARD8 type;
} XpStDocRec, *XpStDocPtr;
#define QUADPAD(x) ((((x)+3)>>2)<<2)
#define JOB_STARTED (1 << 0)
#define DOC_RAW_STARTED (1 << 1)
#define DOC_COOKED_STARTED (1 << 2)
#define PAGE_STARTED (1 << 3)
#define GET_DOC_DATA_STARTED (1 << 4)
#define JOB_GET_DATA (1 << 5)
static XpScreenPtr XpScreens[MAXSCREENS];
static unsigned char XpReqCode;
static int XpEventBase;
static int XpErrorBase;
static unsigned long XpGeneration = 0;
static int XpClientPrivateIndex;
static int contextPrivateCount = 0;
static int contextPrivateLen = 0;
static unsigned *contextPrivateSizes = (unsigned *)NULL;
static unsigned totalContextSize = sizeof(XpContextRec);
static RESTYPE RTclient, RTcontext, RTpage;
static CARD32 allEvents = XPPrintMask | XPAttributeMask;
void
XpExtensionInit(INITARGS)
{
ExtensionEntry *extEntry;
int i;
RTclient = CreateNewResourceType(XpFreeClient);
RTcontext = CreateNewResourceType(XpFreeContext);
RTpage = CreateNewResourceType(XpFreePage);
if (RTclient && RTcontext && RTpage &&
(extEntry = AddExtension(XP_PRINTNAME, XP_EVENTS, XP_ERRORS,
ProcXpDispatch, ProcXpSwappedDispatch,
XpResetProc, StandardMinorOpcode)))
{
XpReqCode = (unsigned char)extEntry->base;
XpEventBase = extEntry->eventBase;
XpErrorBase = extEntry->errorBase;
EventSwapVector[XpEventBase] = (EventSwapPtr) SwapXpNotifyEvent;
EventSwapVector[XpEventBase+1] = (EventSwapPtr) SwapXpAttributeEvent;
}
if(XpGeneration != serverGeneration)
{
XpClientPrivateIndex = AllocateClientPrivateIndex();
if(AllocateClientPrivate(XpClientPrivateIndex, 0) != TRUE)
{
}
XpGeneration = serverGeneration;
}
for(i = 0; i < MAXSCREENS; i++)
{
if(XpScreens[i] != (XpScreenPtr)NULL)
{
XpScreens[i]->CloseScreen = screenInfo.screens[i]->CloseScreen;
screenInfo.screens[i]->CloseScreen = XpCloseScreen;
}
}
DeclareExtensionSecurity(XP_PRINTNAME, TRUE);
}
static void
XpResetProc(ExtensionEntry *extEntry)
{
}
static Bool
XpCloseScreen(int index, ScreenPtr pScreen)
{
Bool (* CloseScreen)(int, ScreenPtr);
CloseScreen = XpScreens[index]->CloseScreen;
if(XpScreens[index] != (XpScreenPtr)NULL)
{
XpDriverPtr pDriv, nextDriv;
pDriv = XpScreens[index]->drivers;
while(pDriv != (XpDriverPtr)NULL)
{
nextDriv = pDriv->next;
Xfree(pDriv);
pDriv = nextDriv;
}
Xfree(XpScreens[index]);
}
XpScreens[index] = (XpScreenPtr)NULL;
ResetContextPrivates();
return (*CloseScreen)(index, pScreen);
}
#if 0
static void
FreeScreenEntry(XpScreenPtr pScreenEntry)
{
XpDriverPtr pDriver;
pDriver = pScreenEntry->drivers;
while(pDriver != (XpDriverPtr)NULL)
{
XpDriverPtr tmp;
tmp = pDriver->next;
xfree(pDriver);
pDriver = tmp;
}
xfree(pScreenEntry);
}
#endif
void
XpRegisterInitFunc(ScreenPtr pScreen, char *driverName, int (*initContext)(struct _XpContext *))
{
XpDriverPtr pDriver;
if(XpScreens[pScreen->myNum] == 0)
{
if((XpScreens[pScreen->myNum] =
(XpScreenPtr) Xalloc(sizeof(XpScreenRec))) == 0)
return;
XpScreens[pScreen->myNum]->CloseScreen = 0;
XpScreens[pScreen->myNum]->drivers = 0;
}
if((pDriver = (XpDriverPtr)Xalloc(sizeof(XpDriverRec))) == 0)
return;
pDriver->next = XpScreens[pScreen->myNum]->drivers;
pDriver->name = driverName;
pDriver->CreateContext = initContext;
XpScreens[pScreen->myNum]->drivers = pDriver;
}
static int
ProcXpDispatch(ClientPtr client)
{
REQUEST(xReq);
switch(stuff->data)
{
case X_PrintQueryVersion:
return ProcXpQueryVersion(client);
case X_PrintGetPrinterList:
return ProcXpGetPrinterList(client);
case X_PrintCreateContext:
return ProcXpCreateContext(client);
case X_PrintSetContext:
return ProcXpSetContext(client);
case X_PrintGetContext:
return ProcXpGetContext(client);
case X_PrintDestroyContext:
return ProcXpDestroyContext(client);
case X_PrintGetContextScreen:
return ProcXpGetContextScreen(client);
case X_PrintStartJob:
return ProcXpStartJob(client);
case X_PrintEndJob:
return ProcXpEndJob(client);
case X_PrintStartDoc:
return ProcXpStartDoc(client);
case X_PrintEndDoc:
return ProcXpEndDoc(client);
case X_PrintStartPage:
return ProcXpStartPage(client);
case X_PrintEndPage:
return ProcXpEndPage(client);
case X_PrintSelectInput:
return ProcXpSelectInput(client);
case X_PrintInputSelected:
return ProcXpInputSelected(client);
case X_PrintPutDocumentData:
return ProcXpPutDocumentData(client);
case X_PrintGetDocumentData:
return ProcXpGetDocumentData(client);
case X_PrintSetAttributes:
return ProcXpSetAttributes(client);
case X_PrintGetAttributes:
return ProcXpGetAttributes(client);
case X_PrintGetOneAttribute:
return ProcXpGetOneAttribute(client);
case X_PrintRehashPrinterList:
return ProcXpRehashPrinterList(client);
case X_PrintQueryScreens:
return ProcXpQueryScreens(client);
case X_PrintGetPageDimensions:
return ProcXpGetPageDimensions(client);
case X_PrintSetImageResolution:
return ProcXpSetImageResolution(client);
case X_PrintGetImageResolution:
return ProcXpGetImageResolution(client);
default:
return BadRequest;
}
}
static int
ProcXpSwappedDispatch(ClientPtr client)
{
int temp;
REQUEST(xReq);
switch(stuff->data)
{
case X_PrintQueryVersion:
swaps(&stuff->length, temp);
return ProcXpQueryVersion(client);
case X_PrintGetPrinterList:
return SProcXpGetPrinterList(client);
case X_PrintCreateContext:
return SProcXpCreateContext(client);
case X_PrintSetContext:
return SProcXpSetContext(client);
case X_PrintGetContext:
return SProcXpGetContext(client);
case X_PrintDestroyContext:
return SProcXpDestroyContext(client);
case X_PrintGetContextScreen:
return SProcXpGetContextScreen(client);
case X_PrintStartJob:
return SProcXpStartJob(client);
case X_PrintEndJob:
return SProcXpEndJob(client);
case X_PrintStartDoc:
return SProcXpStartDoc(client);
case X_PrintEndDoc:
return SProcXpEndDoc(client);
case X_PrintStartPage:
return SProcXpStartPage(client);
case X_PrintEndPage:
return SProcXpEndPage(client);
case X_PrintSelectInput:
return SProcXpSelectInput(client);
case X_PrintInputSelected:
return SProcXpInputSelected(client);
case X_PrintPutDocumentData:
return SProcXpPutDocumentData(client);
case X_PrintGetDocumentData:
return SProcXpGetDocumentData(client);
case X_PrintSetAttributes:
return SProcXpSetAttributes(client);
case X_PrintGetAttributes:
return SProcXpGetAttributes(client);
case X_PrintGetOneAttribute:
return SProcXpGetOneAttribute(client);
case X_PrintRehashPrinterList:
return SProcXpRehashPrinterList(client);
case X_PrintQueryScreens:
swaps(&stuff->length, temp);
return ProcXpQueryScreens(client);
case X_PrintGetPageDimensions:
return SProcXpGetPageDimensions(client);
case X_PrintSetImageResolution:
return SProcXpSetImageResolution(client);
case X_PrintGetImageResolution:
return SProcXpGetImageResolution(client);
default:
return BadRequest;
}
}
static int
ProcXpQueryVersion(ClientPtr client)
{
xPrintQueryVersionReply rep;
register int n;
long l;
REQUEST_SIZE_MATCH(xPrintQueryVersionReq);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.majorVersion = XP_MAJOR_VERSION;
rep.minorVersion = XP_MINOR_VERSION;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swaps(&rep.majorVersion, n);
swaps(&rep.minorVersion, n);
}
WriteToClient(client, sz_xPrintQueryVersionReply, (char *)&rep);
return client->noClientException;
}
static int
ProcXpGetPrinterList(ClientPtr client)
{
REQUEST(xPrintGetPrinterListReq);
int totalSize;
int numEntries;
XpDiListEntry **pList;
xPrintGetPrinterListReply *rep;
int n, i, totalBytes;
long l;
char *curByte;
REQUEST_AT_LEAST_SIZE(xPrintGetPrinterListReq);
totalSize = ((sz_xPrintGetPrinterListReq) >> 2) +
((stuff->printerNameLen + 3) >> 2) +
((stuff->localeLen + 3) >> 2);
if(totalSize != client->req_len)
return BadLength;
pList = XpDiGetPrinterList(stuff->printerNameLen, (char *)(stuff + 1),
stuff->localeLen, (char *)((stuff + 1) +
QUADPAD(stuff->printerNameLen)));
for(numEntries = 0, totalBytes = sz_xPrintGetPrinterListReply;
pList[numEntries] != (XpDiListEntry *)NULL;
numEntries++)
{
totalBytes += 2 * sizeof(CARD32);
totalBytes += QUADPAD(strlen(pList[numEntries]->name));
totalBytes += QUADPAD(strlen(pList[numEntries]->description));
}
if((rep = (xPrintGetPrinterListReply *)xalloc(totalBytes)) ==
(xPrintGetPrinterListReply *)NULL)
return BadAlloc;
rep->type = X_Reply;
rep->length = (totalBytes - sz_xPrintGetPrinterListReply) >> 2;
rep->sequenceNumber = client->sequence;
rep->listCount = numEntries;
if (client->swapped) {
swaps(&rep->sequenceNumber, n);
swapl(&rep->length, l);
swapl(&rep->listCount, l);
}
for(i = 0, curByte = (char *)(rep + 1); i < numEntries; i++)
{
CARD32 *pCrd;
int len;
pCrd = (CARD32 *)curByte;
len = strlen(pList[i]->name);
*pCrd = len;
if (client->swapped)
swapl((long *)curByte, l);
curByte += sizeof(CARD32);
strncpy(curByte, pList[i]->name, len);
curByte += QUADPAD(len);
pCrd = (CARD32 *)curByte;
len = strlen(pList[i]->description);
*pCrd = len;
if (client->swapped)
swapl((long *)curByte, l);
curByte += sizeof(CARD32);
strncpy(curByte, pList[i]->description, len);
curByte += QUADPAD(len);
}
XpDiFreePrinterList(pList);
WriteToClient(client, totalBytes, (char *)rep);
xfree(rep);
return client->noClientException;
}
static int
ProcXpQueryScreens(ClientPtr client)
{
int i, numPrintScreens, totalSize;
WINDOW *pWinId;
xPrintQueryScreensReply *rep;
long l;
REQUEST_SIZE_MATCH(xPrintQueryScreensReq);
rep = (xPrintQueryScreensReply *)xalloc(sz_xPrintQueryScreensReply);
pWinId = (WINDOW *)(rep + 1);
for(i = 0, numPrintScreens = 0, totalSize = sz_xPrintQueryScreensReply;
i < MAXSCREENS; i++)
{
if(XpScreens[i] != (XpScreenPtr)NULL)
{
numPrintScreens++;
totalSize += sizeof(WINDOW);
rep = (xPrintQueryScreensReply *)xrealloc(rep, totalSize);
pWinId = (WINDOW *)(rep + 1);
*pWinId = WindowTable[i]->drawable.id;
if (client->swapped)
swapl((long *)pWinId, l);
}
}
rep->type = X_Reply;
rep->sequenceNumber = client->sequence;
rep->length = (totalSize - sz_xPrintQueryScreensReply) >> 2;
rep->listCount = numPrintScreens;
if (client->swapped)
{
int n;
swaps(&rep->sequenceNumber, n);
swapl(&rep->length, l);
swapl(&rep->listCount, l);
}
WriteToClient(client, totalSize, (char *)rep);
xfree(rep);
return client->noClientException;
}
static int
ProcXpGetPageDimensions(ClientPtr client)
{
REQUEST(xPrintGetPageDimensionsReq);
CARD16 width, height;
xRectangle rect;
xPrintGetPageDimensionsReply rep;
XpContextPtr pContext;
int result;
REQUEST_SIZE_MATCH(xPrintGetPageDimensionsReq);
if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityReadAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if((pContext->funcs.GetMediumDimensions == 0) ||
(pContext->funcs.GetReproducibleArea == 0))
return BadImplementation;
result = pContext->funcs.GetMediumDimensions(pContext, &width, &height);
if(result != Success)
return result;
result = pContext->funcs.GetReproducibleArea(pContext, &rect);
if(result != Success)
return result;
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.width = width;
rep.height = height;
rep.rx = rect.x;
rep.ry = rect.y;
rep.rwidth = rect.width;
rep.rheight = rect.height;
if(client->swapped)
{
int n;
long l;
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swaps(&rep.width, n);
swaps(&rep.height, n);
swaps(&rep.rx, n);
swaps(&rep.ry, n);
swaps(&rep.rwidth, n);
swaps(&rep.rheight, n);
}
WriteToClient(client, sz_xPrintGetPageDimensionsReply, (char *)&rep);
return client->noClientException;
}
static int
ProcXpSetImageResolution(ClientPtr client)
{
REQUEST(xPrintSetImageResolutionReq);
xPrintSetImageResolutionReply rep;
XpContextPtr pContext;
Bool status;
int result;
REQUEST_SIZE_MATCH(xPrintSetImageResolutionReq);
if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityWriteAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
rep.prevRes = pContext->imageRes;
if(pContext->funcs.SetImageResolution != 0) {
result = pContext->funcs.SetImageResolution(pContext,
(int)stuff->imageRes,
&status);
if(result != Success)
status = FALSE;
} else
status = FALSE;
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
if(client->swapped)
{
int n;
long l;
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swaps(&rep.prevRes, n);
}
WriteToClient(client, sz_xPrintSetImageResolutionReply, (char *)&rep);
return client->noClientException;
}
static int
ProcXpGetImageResolution(ClientPtr client)
{
REQUEST(xPrintGetImageResolutionReq);
xPrintGetImageResolutionReply rep;
XpContextPtr pContext;
REQUEST_SIZE_MATCH(xPrintGetImageResolutionReq);
if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityReadAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.imageRes = pContext->imageRes;
if(client->swapped)
{
int n;
long l;
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swaps(&rep.imageRes, n);
}
WriteToClient(client, sz_xPrintGetImageResolutionReply, (char *)&rep);
return client->noClientException;
}
static int
ProcXpRehashPrinterList(ClientPtr client)
{
REQUEST_SIZE_MATCH(xPrintRehashPrinterListReq);
return XpRehashPrinterList();
}
static int
ProcXpCreateContext(ClientPtr client)
{
REQUEST(xPrintCreateContextReq);
XpScreenPtr pPrintScreen;
WindowPtr pRoot;
char *driverName;
XpContextPtr pContext;
int result = Success;
XpDriverPtr pDriver;
REQUEST_AT_LEAST_SIZE(xPrintCreateContextReq);
LEGAL_NEW_RESOURCE(stuff->contextID, client);
if((pRoot = XpDiValidatePrinter((char *)(stuff + 1), stuff->printerNameLen)) ==
(WindowPtr)NULL)
return BadMatch;
pPrintScreen = XpScreens[pRoot->drawable.pScreen->myNum];
if((pContext = (XpContextPtr) xalloc(totalContextSize)) ==
(XpContextPtr) NULL)
return BadAlloc;
InitContextPrivates(pContext);
if(AddResource(stuff->contextID, RTcontext, (pointer) pContext)
!= TRUE)
{
xfree(pContext);
return BadAlloc;
}
pContext->contextID = stuff->contextID;
pContext->clientHead = (XpClientPtr)NULL;
pContext->screenNum = pRoot->drawable.pScreen->myNum;
pContext->state = 0;
pContext->clientSlept = (ClientPtr)NULL;
pContext->imageRes = 0;
pContext->funcs.DestroyContext = 0;
pContext->funcs.StartJob = 0;
pContext->funcs.EndJob = 0;
pContext->funcs.StartDoc = 0;
pContext->funcs.EndDoc = 0;
pContext->funcs.StartPage = 0;
pContext->funcs.EndPage = 0;
pContext->funcs.PutDocumentData = 0;
pContext->funcs.GetDocumentData = 0;
pContext->funcs.GetAttributes = 0;
pContext->funcs.GetOneAttribute = 0;
pContext->funcs.SetAttributes = 0;
pContext->funcs.AugmentAttributes = 0;
pContext->funcs.GetMediumDimensions = 0;
pContext->funcs.GetReproducibleArea = 0;
pContext->funcs.SetImageResolution = 0;
if((pContext->printerName = (char *)xalloc(stuff->printerNameLen + 1)) ==
(char *)NULL)
{
FreeResource(stuff->contextID, RT_NONE);
return BadAlloc;
}
strncpy(pContext->printerName, (char *)(stuff + 1), stuff->printerNameLen);
pContext->printerName[stuff->printerNameLen] = (char)'\0';
driverName = XpDiGetDriverName(pRoot->drawable.pScreen->myNum,
pContext->printerName);
for(pDriver = pPrintScreen->drivers;
pDriver != (XpDriverPtr)NULL;
pDriver = pDriver->next)
{
if(!strcmp(driverName, pDriver->name))
{
if(pDriver->CreateContext != 0)
pDriver->CreateContext(pContext);
else
return BadImplementation;
break;
}
}
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static int
ProcXpSetContext(ClientPtr client)
{
REQUEST(xPrintSetContextReq);
XpContextPtr pContext;
XpClientPtr pPrintClient;
int result = Success;
REQUEST_AT_LEAST_SIZE(xPrintSetContextReq);
if((pContext = client->devPrivates[XpClientPrivateIndex].ptr) !=
(pointer)NULL)
{
if((pPrintClient = FindClient(pContext, client)) != (XpClientPtr)NULL)
{
XpUnsetFontResFunc(client);
if(pPrintClient->eventMask == 0)
FreeXpClient(pPrintClient, TRUE);
}
client->devPrivates[XpClientPrivateIndex].ptr = (pointer)NULL;
}
if(stuff->printContext == None)
return Success;
if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityWriteAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if((pPrintClient = AcquireClient(pContext, client)) == (XpClientPtr)NULL)
return BadAlloc;
client->devPrivates[XpClientPrivateIndex].ptr = pContext;
XpSetFontResFunc(client);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
XpContextPtr
XpGetPrintContext(ClientPtr client)
{
return (client->devPrivates[XpClientPrivateIndex].ptr);
}
static int
ProcXpGetContext(ClientPtr client)
{
xPrintGetContextReply rep;
XpContextPtr pContext;
register int n;
register long l;
REQUEST_SIZE_MATCH(xPrintGetContextReq);
if((pContext = client->devPrivates[XpClientPrivateIndex].ptr) ==
(pointer)NULL)
rep.printContext = None;
else
rep.printContext = pContext->contextID;
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swapl(&rep.printContext, l);
}
WriteToClient(client, sz_xPrintGetContextReply, (char *)&rep);
return client->noClientException;
}
static int
ProcXpDestroyContext(ClientPtr client)
{
REQUEST(xPrintDestroyContextReq);
XpContextPtr pContext;
REQUEST_SIZE_MATCH(xPrintDestroyContextReq);
if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityDestroyAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
XpUnsetFontResFunc(client);
FreeResource(pContext->contextID, RT_NONE);
return Success;
}
static int
ProcXpGetContextScreen(ClientPtr client)
{
REQUEST(xPrintGetContextScreenReq);
xPrintGetContextScreenReply rep;
XpContextPtr pContext;
int n;
long l;
if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityReadAccess))
== (XpContextPtr)NULL)
return XpErrorBase+XPBadContext;
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.rootWindow = WindowTable[pContext->screenNum]->drawable.id;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swapl(&rep.rootWindow, l);
}
WriteToClient(client, sz_xPrintGetContextScreenReply, (char *)&rep);
return client->noClientException;
}
static int
XpFreeContext(pointer data, XID id)
{
XpContextPtr pContext = (XpContextPtr)data;
if(pContext->state != 0)
{
if(pContext->state & PAGE_STARTED)
{
WindowPtr pWin = (WindowPtr )LookupIDByType(
pContext->pageWin, RT_WINDOW);
XpPagePtr pPage = (XpPagePtr)LookupIDByType(
pContext->pageWin, RTpage);
pContext->funcs.EndPage(pContext, pWin);
SendXpNotify(pContext, XPEndPageNotify, TRUE);
pContext->state &= ~PAGE_STARTED;
if(pPage)
pPage->context = (XpContextPtr)NULL;
}
if((pContext->state & DOC_RAW_STARTED) ||
(pContext->state & DOC_COOKED_STARTED))
{
pContext->funcs.EndDoc(pContext, TRUE);
SendXpNotify(pContext, XPEndDocNotify, TRUE);
pContext->state &= ~DOC_RAW_STARTED;
pContext->state &= ~DOC_COOKED_STARTED;
}
if(pContext->funcs.EndJob != 0)
{
pContext->funcs.EndJob(pContext, TRUE);
SendXpNotify(pContext, XPEndJobNotify, TRUE);
pContext->state &= ~JOB_STARTED;
pContext->state &= ~GET_DOC_DATA_STARTED;
}
}
if(pContext->funcs.DestroyContext != 0)
pContext->funcs.DestroyContext(pContext);
while(pContext->clientHead != (XpClientPtr)NULL)
{
FreeXpClient(pContext->clientHead, TRUE);
}
xfree(pContext->printerName);
xfree(pContext);
return Success;
}
static int
XpFreeClient(pointer data, XID id)
{
FreeXpClient((XpClientPtr)data, TRUE);
return Success;
}
static void
FreeXpClient(XpClientPtr pXpClient, Bool freeResource)
{
XpClientPtr pCurrent, pPrev;
XpContextPtr pContext = pXpClient->context;
if(pXpClient->client->devPrivates[XpClientPrivateIndex].ptr ==
pXpClient->context)
{
pXpClient->client->devPrivates[XpClientPrivateIndex].ptr =
(pointer)NULL;
}
for(pPrev = (XpClientPtr)NULL, pCurrent = pContext->clientHead;
pCurrent != (XpClientPtr)NULL;
pCurrent = pCurrent->pNext)
{
if(pCurrent == pXpClient)
{
if(freeResource == TRUE)
FreeResource (pCurrent->contextClientID, RTclient);
if (pPrev != (XpClientPtr)NULL)
pPrev->pNext = pCurrent->pNext;
else
pContext->clientHead = pCurrent->pNext;
xfree (pCurrent);
break;
}
pPrev = pCurrent;
}
}
static XpClientPtr
CreateXpClient(ClientPtr client)
{
XpClientPtr pNewPrintClient;
XID clientResource;
if((pNewPrintClient = (XpClientPtr)xalloc(sizeof(XpClientRec))) ==
(XpClientPtr)NULL)
return (XpClientPtr)NULL;
clientResource = FakeClientID(client->index);
if(!AddResource(clientResource, RTclient, (pointer)pNewPrintClient))
{
xfree (pNewPrintClient);
return (XpClientPtr)NULL;
}
pNewPrintClient->pNext = (XpClientPtr)NULL;
pNewPrintClient->client = client;
pNewPrintClient->context = (XpContextPtr)NULL;
pNewPrintClient->eventMask = 0;
pNewPrintClient->contextClientID = clientResource;
return pNewPrintClient;
}
static int
XpFreePage(pointer data, XID id)
{
XpPagePtr page = (XpPagePtr)data;
int result = Success;
WindowPtr pWin = (WindowPtr )LookupIDByType(id, RT_WINDOW);
if(page->context != (XpContextPtr)NULL &&
page->context->state & PAGE_STARTED)
{
if(page->context->funcs.EndPage != 0)
result = page->context->funcs.EndPage(page->context, pWin);
SendXpNotify(page->context, XPEndPageNotify, (int)TRUE);
page->context->pageWin = 0;
}
xfree(page);
return result;
}
static void
InitContextPrivates(XpContextPtr context)
{
register char *ptr;
DevUnion *ppriv;
register unsigned *sizes;
register unsigned size;
register int i;
if (totalContextSize == sizeof(XpContextRec))
ppriv = (DevUnion *)NULL;
else
ppriv = (DevUnion *)(context + 1);
context->devPrivates = ppriv;
sizes = contextPrivateSizes;
ptr = (char *)(ppriv + contextPrivateLen);
for (i = contextPrivateLen; --i >= 0; ppriv++, sizes++)
{
if ( (size = *sizes) )
{
ppriv->ptr = (pointer)ptr;
ptr += size;
}
else
ppriv->ptr = (pointer)NULL;
}
}
static void
ResetContextPrivates(void)
{
contextPrivateCount = 0;
contextPrivateLen = 0;
xfree(contextPrivateSizes);
contextPrivateSizes = (unsigned *)NULL;
totalContextSize = sizeof(XpContextRec);
}
int
XpAllocateContextPrivateIndex(void)
{
return contextPrivateCount++;
}
Bool
XpAllocateContextPrivate(int index, unsigned amount)
{
unsigned oldamount;
if (index >= contextPrivateLen)
{
unsigned *nsizes;
nsizes = (unsigned *)xrealloc(contextPrivateSizes,
(index + 1) * sizeof(unsigned));
if (!nsizes)
return FALSE;
while (contextPrivateLen <= index)
{
nsizes[contextPrivateLen++] = 0;
totalContextSize += sizeof(DevUnion);
}
contextPrivateSizes = nsizes;
}
oldamount = contextPrivateSizes[index];
if (amount > oldamount)
{
contextPrivateSizes[index] = amount;
totalContextSize += (amount - oldamount);
}
return TRUE;
}
static XpClientPtr
AcquireClient(XpContextPtr pContext, ClientPtr client)
{
XpClientPtr pXpClient;
if((pXpClient = FindClient(pContext, client)) != (XpClientPtr)NULL)
return pXpClient;
if((pXpClient = CreateXpClient(client)) == (XpClientPtr)NULL)
return (XpClientPtr)NULL;
pXpClient->context = pContext;
pXpClient->pNext = pContext->clientHead;
pContext->clientHead = pXpClient;
return pXpClient;
}
static XpClientPtr
FindClient(XpContextPtr pContext, ClientPtr client)
{
XpClientPtr pXpClient;
for(pXpClient = pContext->clientHead; pXpClient != (XpClientPtr)NULL;
pXpClient = pXpClient->pNext)
{
if(pXpClient->client == client) return pXpClient;
}
return (XpClientPtr)NULL;
}
static int
ProcXpStartJob(ClientPtr client)
{
REQUEST(xPrintStartJobReq);
XpContextPtr pContext;
int result = Success;
REQUEST_SIZE_MATCH(xPrintStartJobReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadContext;
if(pContext->state != 0)
return XpErrorBase+XPBadSequence;
if(stuff->saveData != XPSpool && stuff->saveData != XPGetData)
{
client->errorValue = stuff->saveData;
return BadValue;
}
if(pContext->funcs.StartJob != 0)
result = pContext->funcs.StartJob(pContext,
(stuff->saveData == XPGetData)? TRUE:FALSE,
client);
else
return BadImplementation;
pContext->state = JOB_STARTED;
if(stuff->saveData == XPGetData)
pContext->state |= JOB_GET_DATA;
SendXpNotify(pContext, XPStartJobNotify, FALSE);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static int
ProcXpEndJob(ClientPtr client)
{
REQUEST(xPrintEndJobReq);
int result = Success;
XpContextPtr pContext;
REQUEST_SIZE_MATCH(xPrintEndJobReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadSequence;
if(!(pContext->state & JOB_STARTED))
return XpErrorBase+XPBadSequence;
if((pContext->state & DOC_RAW_STARTED) ||
(pContext->state & DOC_COOKED_STARTED))
{
if(pContext->state & PAGE_STARTED)
{
WindowPtr pWin = (WindowPtr )LookupIDByType(
pContext->pageWin, RT_WINDOW);
XpPagePtr pPage = (XpPagePtr)LookupIDByType(
pContext->pageWin, RTpage);
if(stuff->cancel != TRUE)
return XpErrorBase+XPBadSequence;
if(pContext->funcs.EndPage != 0)
result = pContext->funcs.EndPage(pContext, pWin);
else
return BadImplementation;
SendXpNotify(pContext, XPEndPageNotify, TRUE);
pContext->state &= ~PAGE_STARTED;
if(pPage)
pPage->context = (XpContextPtr)NULL;
if(result != Success) return result;
}
if(pContext->funcs.EndDoc != 0)
result = pContext->funcs.EndDoc(pContext, stuff->cancel);
else
return BadImplementation;
SendXpNotify(pContext, XPEndDocNotify, stuff->cancel);
}
if(pContext->funcs.EndJob != 0)
result = pContext->funcs.EndJob(pContext, stuff->cancel);
else
return BadImplementation;
pContext->state = 0;
SendXpNotify(pContext, XPEndJobNotify, stuff->cancel);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static Bool
DoStartDoc(ClientPtr client, XpStDocPtr c)
{
XpContextPtr pContext = c->pContext;
if(c->pContext->state & JOB_GET_DATA &&
!(c->pContext->state & GET_DOC_DATA_STARTED))
{
if(!c->slept)
{
c->slept = TRUE;
ClientSleep(client, (ClientSleepProcPtr)DoStartDoc, (pointer) c);
c->pContext->clientSlept = client;
}
return TRUE;
}
if(pContext->funcs.StartDoc != 0)
(void) pContext->funcs.StartDoc(pContext, c->type);
else
{
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
BadImplementation);
return TRUE;
}
if(c->type == XPDocNormal)
pContext->state |= DOC_COOKED_STARTED;
else
pContext->state |= DOC_RAW_STARTED;
SendXpNotify(pContext, XPStartDocNotify, (int)FALSE);
xfree(c);
return TRUE;
}
static int
ProcXpStartDoc(ClientPtr client)
{
REQUEST(xPrintStartDocReq);
int result = Success;
XpContextPtr pContext;
XpStDocPtr c;
REQUEST_SIZE_MATCH(xPrintStartDocReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadSequence;
if(!(pContext->state & JOB_STARTED) ||
pContext->state & DOC_RAW_STARTED ||
pContext->state & DOC_COOKED_STARTED)
return XpErrorBase+XPBadSequence;
if(stuff->type != XPDocNormal && stuff->type != XPDocRaw)
{
client->errorValue = stuff->type;
return BadValue;
}
c = (XpStDocPtr)xalloc(sizeof(XpStDocRec));
c->pContext = pContext;
c->type = stuff->type;
c->slept = FALSE;
(void)DoStartDoc(client, c);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static int
ProcXpEndDoc(ClientPtr client)
{
REQUEST(xPrintEndDocReq);
XpContextPtr pContext;
int result = Success;
REQUEST_SIZE_MATCH(xPrintEndDocReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadSequence;
if(!(pContext->state & DOC_RAW_STARTED) &&
!(pContext->state & DOC_COOKED_STARTED))
return XpErrorBase+XPBadSequence;
if(pContext->state & PAGE_STARTED)
{
if(stuff->cancel == TRUE)
{
WindowPtr pWin = (WindowPtr )LookupIDByType(
pContext->pageWin, RT_WINDOW);
XpPagePtr pPage = (XpPagePtr)LookupIDByType(
pContext->pageWin, RTpage);
if(pContext->funcs.EndPage != 0)
result = pContext->funcs.EndPage(pContext, pWin);
else
return BadImplementation;
SendXpNotify(pContext, XPEndPageNotify, TRUE);
if(pPage)
pPage->context = (XpContextPtr)NULL;
}
else
return XpErrorBase+XPBadSequence;
if(result != Success)
return result;
}
if(pContext->funcs.EndDoc != 0)
result = pContext->funcs.EndDoc(pContext, stuff->cancel);
else
return BadImplementation;
pContext->state &= ~DOC_RAW_STARTED;
pContext->state &= ~DOC_COOKED_STARTED;
SendXpNotify(pContext, XPEndDocNotify, stuff->cancel);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static Bool
DoStartPage(
ClientPtr client,
XpStPagePtr c)
{
WindowPtr pWin = c->pWin;
int result = Success;
XpContextPtr pContext = c->pContext;
XpPagePtr pPage;
if(c->pContext->state & JOB_GET_DATA &&
!(c->pContext->state & GET_DOC_DATA_STARTED))
{
if(!c->slept)
{
c->slept = TRUE;
ClientSleep(client, (ClientSleepProcPtr)DoStartPage, (pointer) c);
c->pContext->clientSlept = client;
}
return TRUE;
}
if(!(pContext->state & DOC_COOKED_STARTED))
{
if(pContext->funcs.StartDoc != 0)
result = pContext->funcs.StartDoc(pContext, XPDocNormal);
else
{
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
BadImplementation);
return TRUE;
}
if(result != Success)
{
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0, result);
return TRUE;
}
pContext->state |= DOC_COOKED_STARTED;
SendXpNotify(pContext, XPStartDocNotify, (int)FALSE);
}
if((pPage = (XpPagePtr)LookupIDByType(c->pWin->drawable.id, RTpage)) !=
(XpPagePtr)NULL)
{
if(pPage->context != (XpContextPtr)NULL)
{
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
BadWindow);
return TRUE;
}
}
else
{
if((pPage = (XpPagePtr)xalloc(sizeof(XpPageRec))) == (XpPagePtr)NULL)
{
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
BadAlloc);
return TRUE;
}
if(AddResource(c->pWin->drawable.id, RTpage, pPage) == FALSE)
{
xfree(pPage);
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
BadAlloc);
return TRUE;
}
}
pPage->context = pContext;
pContext->pageWin = c->pWin->drawable.id;
if(pContext->funcs.StartPage != 0)
result = pContext->funcs.StartPage(pContext, pWin);
else
{
SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
BadImplementation);
return TRUE;
}
pContext->state |= PAGE_STARTED;
(void)MapWindow(pWin, client);
SendXpNotify(pContext, XPStartPageNotify, (int)FALSE);
return TRUE;
}
static int
ProcXpStartPage(ClientPtr client)
{
REQUEST(xPrintStartPageReq);
WindowPtr pWin;
int result = Success;
XpContextPtr pContext;
XpStPagePtr c;
REQUEST_SIZE_MATCH(xPrintStartPageReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadSequence;
if(!(pContext->state & JOB_STARTED))
return XpErrorBase+XPBadSequence;
if(pContext->state & DOC_RAW_STARTED)
return XpErrorBase+XPBadSequence;
if(pContext->state & PAGE_STARTED)
return XpErrorBase+XPBadSequence;
pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
SecurityWriteAccess);
if (!pWin || pWin->drawable.pScreen->myNum != pContext->screenNum)
return BadWindow;
if((c = (XpStPagePtr)xalloc(sizeof(XpStPageRec))) == (XpStPagePtr)NULL)
return BadAlloc;
c->pContext = pContext;
c->slept = FALSE;
c->pWin = pWin;
(void)DoStartPage(client, c);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static int
ProcXpEndPage(ClientPtr client)
{
REQUEST(xPrintEndPageReq);
int result = Success;
XpContextPtr pContext;
XpPagePtr page;
WindowPtr pWin;
REQUEST_SIZE_MATCH(xPrintEndPageReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadSequence;
if(!(pContext->state & PAGE_STARTED))
return XpErrorBase+XPBadSequence;
pWin = (WindowPtr )LookupIDByType(pContext->pageWin, RT_WINDOW);
if(pContext->funcs.EndPage != 0)
result = pContext->funcs.EndPage(pContext, pWin);
else
return BadImplementation;
if((page = (XpPagePtr)LookupIDByType(pContext->pageWin, RTpage)) !=
(XpPagePtr)NULL)
page->context = (XpContextPtr)NULL;
pContext->state &= ~PAGE_STARTED;
pContext->pageWin = 0;
(void)UnmapWindow(pWin, FALSE);
SendXpNotify(pContext, XPEndPageNotify, stuff->cancel);
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static int
ProcXpPutDocumentData(ClientPtr client)
{
REQUEST(xPrintPutDocumentDataReq);
XpContextPtr pContext;
DrawablePtr pDraw;
int result = Success;
unsigned totalSize;
char *pData, *pDoc_fmt, *pOptions;
REQUEST_AT_LEAST_SIZE(xPrintPutDocumentDataReq);
if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
== (XpContextPtr)NULL)
return XpErrorBase+XPBadSequence;
if(!(pContext->state & DOC_RAW_STARTED) &&
!(pContext->state & DOC_COOKED_STARTED))
return XpErrorBase+XPBadSequence;
if (stuff->drawable) {
if (pContext->state & DOC_RAW_STARTED)
return BadDrawable;
pDraw = (DrawablePtr)LookupDrawable(stuff->drawable, client);
if (!pDraw || pDraw->pScreen->myNum != pContext->screenNum)
return BadDrawable;
} else {
if (pContext->state & DOC_COOKED_STARTED)
return BadDrawable;
pDraw = NULL;
}
pData = (char *)(&stuff[1]);
totalSize = (stuff->len_data + 3) >> 2;
pDoc_fmt = pData + (totalSize << 2);
totalSize += (stuff->len_fmt + 3) >> 2;
pOptions = pData + (totalSize << 2);
totalSize += (stuff->len_options + 3) >> 2;
if((totalSize + (sz_xPrintPutDocumentDataReq >> 2)) != client->req_len)
return BadLength;
if(pContext->funcs.PutDocumentData != 0)
{
result = (*pContext->funcs.PutDocumentData)(pContext, pDraw,
pData, stuff->len_data,
pDoc_fmt, stuff->len_fmt,
pOptions, stuff->len_options,
client);
}
else
return BadImplementation;
if (client->noClientException != Success)
return client->noClientException;
else
return result;
}
static int
ProcXpGetDocumentData(ClientPtr client)
{
REQUEST(xPrintGetDocumentDataReq);
xPrintGetDocumentDataReply rep;
XpContextPtr pContext;
int result = Success;
REQUEST_SIZE_MATCH(xPrintGetDocumentDataReq);
if((pContext = (XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityWriteAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if(pContext->funcs.GetDocumentData == 0)
return BadImplementation;
if(!(pContext->state & JOB_GET_DATA) ||
pContext->state & GET_DOC_DATA_STARTED)
return XpErrorBase+XPBadSequence;
if(stuff->maxBufferSize <= 0)
{
client->errorValue = stuff->maxBufferSize;
return BadValue;
}
result = (*pContext->funcs.GetDocumentData)(pContext, client,
stuff->maxBufferSize);
if(result != Success)
{
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.dataLen = 0;
rep.statusCode = 1;
rep.finishedFlag = TRUE;
if (client->swapped) {
int n;
long l;
swaps(&rep.sequenceNumber, n);
swapl(&rep.statusCode, l);
swapl(&rep.finishedFlag, l);
}
(void)WriteToClient(client,sz_xPrintGetDocumentDataReply,(char *)&rep);
}
else
pContext->state |= GET_DOC_DATA_STARTED;
if(pContext->clientSlept != (ClientPtr)NULL)
{
ClientSignal(pContext->clientSlept);
ClientWakeup(pContext->clientSlept);
pContext->clientSlept = (ClientPtr)NULL;
}
return result;
}
static int
ProcXpGetAttributes(ClientPtr client)
{
REQUEST(xPrintGetAttributesReq);
XpContextPtr pContext;
char *attrs;
xPrintGetAttributesReply *pRep;
int totalSize, n;
unsigned long l;
REQUEST_SIZE_MATCH(xPrintGetAttributesReq);
if(stuff->type < XPJobAttr || stuff->type > XPServerAttr)
{
client->errorValue = stuff->type;
return BadValue;
}
if(stuff->type != XPServerAttr)
{
if((pContext = (XpContextPtr)SecurityLookupIDByType(
client,
stuff->printContext,
RTcontext,
SecurityReadAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if(pContext->funcs.GetAttributes == 0)
return BadImplementation;
if((attrs = (*pContext->funcs.GetAttributes)(pContext, stuff->type)) ==
(char *)NULL)
return BadAlloc;
}
else
{
if((attrs = XpGetAttributes((XpContextPtr)NULL, XPServerAttr)) ==
(char *)NULL)
return BadAlloc;
}
totalSize = sz_xPrintGetAttributesReply + QUADPAD(strlen(attrs));
if((pRep = (xPrintGetAttributesReply *)malloc(totalSize)) ==
(xPrintGetAttributesReply *)NULL)
return BadAlloc;
pRep->type = X_Reply;
pRep->length = (totalSize - sz_xPrintGetAttributesReply) >> 2;
pRep->sequenceNumber = client->sequence;
pRep->stringLen = strlen(attrs);
if (client->swapped) {
swaps(&pRep->sequenceNumber, n);
swapl(&pRep->length, l);
swapl(&pRep->stringLen, l);
}
strncpy((char*)(pRep + 1), attrs, strlen(attrs));
xfree(attrs);
WriteToClient(client, totalSize, (char *)pRep);
xfree(pRep);
return client->noClientException;
}
static int
ProcXpSetAttributes(ClientPtr client)
{
REQUEST(xPrintSetAttributesReq);
int result = Success;
XpContextPtr pContext;
char *attr;
REQUEST_AT_LEAST_SIZE(xPrintSetAttributesReq);
if(stuff->type < XPJobAttr || stuff->type > XPServerAttr)
{
client->errorValue = stuff->type;
return BadValue;
}
if(stuff->type == XPPrinterAttr || stuff->type == XPServerAttr)
return BadMatch;
if((pContext = (XpContextPtr)SecurityLookupIDByType(
client,
stuff->printContext,
RTcontext,
SecurityWriteAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if(pContext->funcs.SetAttributes == 0)
return BadImplementation;
if((pContext->state & JOB_STARTED) && stuff->type == XPJobAttr)
return XpErrorBase+XPBadSequence;
if(((pContext->state & DOC_RAW_STARTED) ||
(pContext->state & DOC_COOKED_STARTED)) && stuff->type == XPDocAttr)
return XpErrorBase+XPBadSequence;
if((pContext->state & PAGE_STARTED) && stuff->type == XPPageAttr)
return XpErrorBase+XPBadSequence;
if((attr = (char *)malloc(stuff->stringLen + 1)) == (char *)NULL)
return BadAlloc;
strncpy(attr, (char *)(stuff + 1), stuff->stringLen);
attr[stuff->stringLen] = (char)'\0';
if(stuff->rule == XPAttrReplace)
(*pContext->funcs.SetAttributes)(pContext, stuff->type, attr);
else if(stuff->rule == XPAttrMerge)
(*pContext->funcs.AugmentAttributes)(pContext, stuff->type, attr);
else
{
client->errorValue = stuff->rule;
result = BadValue;
}
xfree(attr);
SendAttributeNotify(pContext, stuff->type);
return result;
}
static int
ProcXpGetOneAttribute(ClientPtr client)
{
REQUEST(xPrintGetOneAttributeReq);
XpContextPtr pContext;
char *value, *attrName;
xPrintGetOneAttributeReply *pRep;
int totalSize;
int n;
unsigned long l;
REQUEST_AT_LEAST_SIZE(xPrintGetOneAttributeReq);
totalSize = ((sz_xPrintGetOneAttributeReq) >> 2) +
((stuff->nameLen + 3) >> 2);
if(totalSize != client->req_len)
return BadLength;
if(stuff->type < XPJobAttr || stuff->type > XPServerAttr)
{
client->errorValue = stuff->type;
return BadValue;
}
if((attrName = (char *)malloc(stuff->nameLen + 1)) == (char *)NULL)
return BadAlloc;
strncpy(attrName, (char *)(stuff+1), stuff->nameLen);
attrName[stuff->nameLen] = (char)'\0';
if(stuff->type != XPServerAttr)
{
if((pContext = (XpContextPtr)SecurityLookupIDByType(
client,
stuff->printContext,
RTcontext,
SecurityReadAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if(pContext->funcs.GetOneAttribute == 0)
return BadImplementation;
if((value = (*pContext->funcs.GetOneAttribute)(pContext, stuff->type,
attrName)) == (char *)NULL)
return BadAlloc;
}
else
{
if((value = XpGetOneAttribute((XpContextPtr)NULL, XPServerAttr,
attrName)) == (char *)NULL)
return BadAlloc;
}
free(attrName);
totalSize = sz_xPrintGetOneAttributeReply + QUADPAD(strlen(value));
if((pRep = (xPrintGetOneAttributeReply *)malloc(totalSize)) ==
(xPrintGetOneAttributeReply *)NULL)
return BadAlloc;
pRep->type = X_Reply;
pRep->length = (totalSize - sz_xPrintGetOneAttributeReply) >> 2;
pRep->sequenceNumber = client->sequence;
pRep->valueLen = strlen(value);
if (client->swapped) {
swaps(&pRep->sequenceNumber, n);
swapl(&pRep->length, l);
swapl(&pRep->valueLen, l);
}
strncpy((char*)(pRep + 1), value, strlen(value));
WriteToClient(client, totalSize, (char *)pRep);
xfree(pRep);
return client->noClientException;
}
static int
ProcXpSelectInput(ClientPtr client)
{
REQUEST(xPrintSelectInputReq);
int result = Success;
XpContextPtr pContext;
XpClientPtr pPrintClient;
REQUEST_SIZE_MATCH(xPrintSelectInputReq);
if((pContext=(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityWriteAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
if(stuff->eventMask & ~allEvents)
{
client->errorValue = stuff->eventMask;
return BadValue;
}
if((pPrintClient = AcquireClient(pContext, client)) == (XpClientPtr)NULL)
return BadAlloc;
pPrintClient->eventMask = stuff->eventMask;
return result;
}
static int
ProcXpInputSelected(ClientPtr client)
{
REQUEST(xPrintInputSelectedReq);
xPrintInputSelectedReply rep;
register int n;
long l;
XpClientPtr pXpClient;
XpContextPtr pContext;
REQUEST_SIZE_MATCH(xPrintInputSelectedReq);
if((pContext=(XpContextPtr)SecurityLookupIDByType(client,
stuff->printContext,
RTcontext,
SecurityReadAccess))
== (XpContextPtr)NULL)
{
client->errorValue = stuff->printContext;
return XpErrorBase+XPBadContext;
}
pXpClient = FindClient(pContext, client);
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.eventMask = (pXpClient != (XpClientPtr)NULL)? pXpClient->eventMask : 0;
rep.allEventsMask = GetAllEventMasks(pContext);
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, l);
swapl(&rep.eventMask, l);
swapl(&rep.allEventsMask, l);
}
WriteToClient(client, sz_xPrintInputSelectedReply, (char *)&rep);
return client->noClientException;
}
static void
SendAttributeNotify(XpContextPtr pContext, int which)
{
XpClientPtr pXpClient;
xPrintAttributeEvent ae;
ClientPtr client;
pXpClient = pContext->clientHead;
if(pXpClient == (XpClientPtr)NULL)
return;
for (pXpClient = pContext->clientHead;
pXpClient != (XpClientPtr)NULL;
pXpClient = pXpClient->pNext)
{
client = pXpClient->client;
if (client == serverClient || client->clientGone ||
!(pXpClient->eventMask & XPAttributeMask))
continue;
ae.type = XPAttributeNotify + XpEventBase;
ae.detail = which;
ae.printContext = pContext->contextID;
ae.sequenceNumber = client->sequence;
WriteEventsToClient (client, 1, (xEvent *) &ae);
}
}
static void
SendXpNotify(XpContextPtr pContext, int which, int val)
{
XpClientPtr pXpClient;
xPrintPrintEvent pe;
ClientPtr client;
pXpClient = pContext->clientHead;
if(pXpClient == (XpClientPtr)NULL)
return;
for (pXpClient = pContext->clientHead;
pXpClient != (XpClientPtr)NULL;
pXpClient = pXpClient->pNext)
{
client = pXpClient->client;
if (client == serverClient || client->clientGone ||
!(pXpClient->eventMask & XPPrintMask))
continue;
pe.type = XPPrintNotify + XpEventBase;
pe.detail = which;
pe.printContext = pContext->contextID;
pe.cancel = (Bool)val;
pe.sequenceNumber = client->sequence;
WriteEventsToClient (client, 1, (xEvent *) &pe);
}
}
static CARD32
GetAllEventMasks(XpContextPtr pContext)
{
XpClientPtr pPrintClient;
CARD32 totalMask = (CARD32)0;
for (pPrintClient = pContext->clientHead;
pPrintClient != (XpClientPtr)NULL;
pPrintClient = pPrintClient->pNext)
{
totalMask |= pPrintClient->eventMask;
}
return totalMask;
}
XpContextPtr
XpContextOfClient(ClientPtr client)
{
return (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr;
}
static int
SProcXpCreateContext(ClientPtr client)
{
int i;
long n;
REQUEST(xPrintCreateContextReq);
swaps(&stuff->length, i);
swapl(&stuff->contextID, n);
swapl(&stuff->printerNameLen, n);
swapl(&stuff->localeLen, n);
return ProcXpCreateContext(client);
}
static int
SProcXpGetPrinterList(ClientPtr client)
{
int i;
long n;
REQUEST(xPrintGetPrinterListReq);
swaps(&stuff->length, i);
swapl(&stuff->printerNameLen, n);
swapl(&stuff->localeLen, n);
return ProcXpGetPrinterList(client);
}
static int
SProcXpRehashPrinterList(ClientPtr client)
{
int i;
REQUEST(xPrintRehashPrinterListReq);
swaps(&stuff->length, i);
return ProcXpRehashPrinterList(client);
}
static int
SProcXpSetContext(ClientPtr client)
{
int i;
REQUEST(xPrintSetContextReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, i);
return ProcXpSetContext(client);
}
static int
SProcXpGetContext(ClientPtr client)
{
int i;
REQUEST(xPrintGetContextReq);
swaps(&stuff->length, i);
return ProcXpGetContext(client);
}
static int
SProcXpDestroyContext(ClientPtr client)
{
int i;
long n;
REQUEST(xPrintDestroyContextReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
return ProcXpDestroyContext(client);
}
static int
SProcXpGetContextScreen(ClientPtr client)
{
int i;
long n;
REQUEST(xPrintGetContextScreenReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
return ProcXpGetContextScreen(client);
}
static int
SProcXpInputSelected(ClientPtr client)
{
int i;
long n;
REQUEST(xPrintInputSelectedReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
return ProcXpInputSelected(client);
}
static int
SProcXpStartJob(ClientPtr client)
{
int i;
REQUEST(xPrintStartJobReq);
swaps(&stuff->length, i);
return ProcXpStartJob(client);
}
static int
SProcXpEndJob(ClientPtr client)
{
int i;
REQUEST(xPrintEndJobReq);
swaps(&stuff->length, i);
return ProcXpEndJob(client);
}
static int
SProcXpStartDoc(ClientPtr client)
{
int i;
REQUEST(xPrintStartDocReq);
swaps(&stuff->length, i);
return ProcXpStartDoc(client);
}
static int
SProcXpEndDoc(ClientPtr client)
{
int i;
REQUEST(xPrintEndDocReq);
swaps(&stuff->length, i);
return ProcXpEndDoc(client);
}
static int
SProcXpStartPage(ClientPtr client)
{
int i;
long n;
REQUEST(xPrintStartPageReq);
swaps(&stuff->length, i);
swapl(&stuff->window, n);
return ProcXpStartPage(client);
}
static int
SProcXpEndPage(ClientPtr client)
{
int i;
REQUEST(xPrintEndPageReq);
swaps(&stuff->length, i);
return ProcXpEndPage(client);
}
static int
SProcXpPutDocumentData(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintPutDocumentDataReq);
swaps(&stuff->length, i);
swapl(&stuff->drawable, n);
swapl(&stuff->len_data, n);
swaps(&stuff->len_fmt, i);
swaps(&stuff->len_options, i);
return ProcXpPutDocumentData(client);
}
static int
SProcXpGetDocumentData(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintGetDocumentDataReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
swapl(&stuff->maxBufferSize, n);
return ProcXpGetDocumentData(client);
}
static int
SProcXpGetAttributes(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintGetAttributesReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
return ProcXpGetAttributes(client);
}
static int
SProcXpSetAttributes(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintSetAttributesReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
swapl(&stuff->stringLen, n);
return ProcXpSetAttributes(client);
}
static int
SProcXpGetOneAttribute(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintGetOneAttributeReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
swapl(&stuff->nameLen, n);
return ProcXpGetOneAttribute(client);
}
static int
SProcXpSelectInput(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintSelectInputReq);
swaps(&stuff->length, i);
swapl(&stuff->eventMask, n);
swapl(&stuff->printContext, n);
return ProcXpSelectInput(client);
}
static int
SProcXpGetPageDimensions(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintGetPageDimensionsReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
return ProcXpGetPageDimensions(client);
}
static int
SProcXpSetImageResolution(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintSetImageResolutionReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
swaps(&stuff->imageRes, i);
return ProcXpSetImageResolution(client);
}
static int
SProcXpGetImageResolution(ClientPtr client)
{
long n;
int i;
REQUEST(xPrintGetImageResolutionReq);
swaps(&stuff->length, i);
swapl(&stuff->printContext, n);
return ProcXpGetImageResolution(client);
}
static void
SwapXpNotifyEvent(xPrintPrintEvent *src, xPrintPrintEvent *dst)
{
cpswaps(src->sequenceNumber, dst->sequenceNumber);
cpswapl(src->printContext, dst->printContext);
dst->type = src->type;
dst->detail = src->detail;
dst->cancel = src->cancel;
}
static void
SwapXpAttributeEvent(xPrintAttributeEvent *src, xPrintAttributeEvent *dst)
{
cpswaps(src->sequenceNumber, dst->sequenceNumber);
cpswapl(src->printContext, dst->printContext);
dst->type = src->type;
dst->detail = src->detail;
}