2761 lines
		
	
	
		
			74 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			2761 lines
		
	
	
		
			74 KiB
		
	
	
	
		
			C
		
	
	
	
/* $Xorg: xprint.c,v 1.5 2001/03/05 20:42:26 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.
 | 
						|
*/
 | 
						|
/*******************************************************************
 | 
						|
**
 | 
						|
**    *********************************************************
 | 
						|
**    *
 | 
						|
**    *  File:          xprint.c
 | 
						|
**    *
 | 
						|
**    *  Copyright:     Copyright 1993, 1995 Hewlett-Packard Company
 | 
						|
**    *
 | 
						|
**    *		Copyright 1989 by The Massachusetts Institute of Technology
 | 
						|
**    *
 | 
						|
**    *		Permission to use, copy, modify, and distribute this
 | 
						|
**    *		software and its documentation for any purpose and without
 | 
						|
**    *		fee is hereby granted, provided that the above copyright
 | 
						|
**    *		notice appear in all copies and that both that copyright
 | 
						|
**    *		notice and this permission notice appear in supporting
 | 
						|
**    *		documentation, and that the name of MIT not be used in
 | 
						|
**    *		advertising or publicity pertaining to distribution of the
 | 
						|
**    *		software without specific prior written permission.
 | 
						|
**    *		M.I.T. makes no representation about the suitability of
 | 
						|
**    *		this software for any purpose. It is provided "as is"
 | 
						|
**    *		without any express or implied warranty.
 | 
						|
**    *
 | 
						|
**    *		MIT DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
 | 
						|
**    *		INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 | 
						|
**    *		NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MIT BE  LI-
 | 
						|
**    *		ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 | 
						|
**    *		ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
 | 
						|
**    *		PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
 | 
						|
**    *		OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
 | 
						|
**    *		THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
**    *
 | 
						|
**    *********************************************************
 | 
						|
**
 | 
						|
********************************************************************/
 | 
						|
/* $XFree86: xc/programs/Xserver/Xext/xprint.c,v 1.14tsi Exp $ */
 | 
						|
 | 
						|
#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 "Print.h"
 | 
						|
#include "Printstr.h"
 | 
						|
#include "../Xprint/DiPrint.h"
 | 
						|
#include "../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;
 | 
						|
 | 
						|
/*
 | 
						|
 * Each context has a list of XpClients indicating which clients have
 | 
						|
 * associated this context with their connection.
 | 
						|
 * Each such client has a RTclient resource allocated for it,
 | 
						|
 * and this per-client
 | 
						|
 * resource is used to delete the XpClientRec if/when the client closes
 | 
						|
 * its connection.
 | 
						|
 * The list of XpClients is also walked if/when the context is destroyed
 | 
						|
 * so that the ContextPtr can be removed from the client's devPrivates.
 | 
						|
 */
 | 
						|
typedef struct _XpClient {
 | 
						|
	struct _XpClient *pNext;
 | 
						|
	ClientPtr	client;
 | 
						|
	XpContextPtr	context;
 | 
						|
	CARD32		eventMask;
 | 
						|
	XID		contextClientID; /* unneeded sanity check? */
 | 
						|
} XpClientRec, *XpClientPtr;
 | 
						|
 | 
						|
static void FreeXpClient(XpClientPtr, Bool);
 | 
						|
 | 
						|
/*
 | 
						|
 * Each StartPage request specifies a window which forms the top level
 | 
						|
 * window of the page.  One of the following structs is created as a
 | 
						|
 * RTpage resource with the same ID as the window itself.  This enables 
 | 
						|
 * us to clean up when/if the window is destroyed, and to prevent the
 | 
						|
 * same window from being simultaneously referenced in multiple contexts.
 | 
						|
 * The page resource is created at the first StartPage on a given window,
 | 
						|
 * and is only destroyed when/if the window is destroyed.  When the
 | 
						|
 * EndPage is recieved (or an EndDoc or EndJob) the context field is
 | 
						|
 * set to NULL, but the resource remains alive.
 | 
						|
 */
 | 
						|
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)
 | 
						|
 | 
						|
/*
 | 
						|
 * Possible bit-mask values in the "state" field of a XpContextRec.
 | 
						|
 */
 | 
						|
#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;
 | 
						|
 | 
						|
/* Variables for the context private machinery. 
 | 
						|
 * These must be initialized at compile time because
 | 
						|
 * main() calls InitOutput before InitExtensions, and the
 | 
						|
 * output drivers are likely to call AllocateContextPrivate.
 | 
						|
 * These variables are reset at CloseScreen time.  CloseScreen
 | 
						|
 * is used because it occurs after FreeAllResources, and before
 | 
						|
 * the next InitOutput cycle.
 | 
						|
 */
 | 
						|
static int  contextPrivateCount = 0;
 | 
						|
static int contextPrivateLen = 0;
 | 
						|
static unsigned *contextPrivateSizes = (unsigned *)NULL;
 | 
						|
static unsigned totalContextSize = sizeof(XpContextRec);
 | 
						|
 | 
						|
/*
 | 
						|
 * There are three types of resources involved.  One is the resource associated
 | 
						|
 * with the context itself, with an ID specified by a printing client.  The
 | 
						|
 * next is a resource created by us on the client's behalf (and unknown to
 | 
						|
 * the client) when a client inits or sets a context which allows us to 
 | 
						|
 * track each client's interest in events
 | 
						|
 * on a particular context, and also allows us to clean up this interest
 | 
						|
 * record when/if the client's connection is closed.  Finally, there is
 | 
						|
 * a resource created for each window that's specified in a StartPage.  This
 | 
						|
 * resource carries the same ID as the window itself, and enables us to
 | 
						|
 * easily prevent the same window being referenced in multiple contexts
 | 
						|
 * simultaneously, and enables us to clean up if the window is destroyed
 | 
						|
 * before the EndPage.
 | 
						|
 */
 | 
						|
static RESTYPE RTclient, RTcontext, RTpage;
 | 
						|
 | 
						|
/*
 | 
						|
 * allEvents is the OR of all the legal event mask bits.
 | 
						|
 */
 | 
						|
static CARD32 allEvents = XPPrintMask | XPAttributeMask;
 | 
						|
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * ExtensionInit, Driver Init functions, QueryVersion, and Dispatch procs
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 * XpExtensionInit
 | 
						|
 *
 | 
						|
 * Called from InitExtensions in main() usually through miinitextension
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
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();
 | 
						|
	/*
 | 
						|
	 * We allocate 0 length & simply stuff a pointer to the
 | 
						|
	 * ContextRec in the DevUnion.
 | 
						|
	 */
 | 
						|
	if(AllocateClientPrivate(XpClientPrivateIndex, 0) != TRUE)
 | 
						|
	{
 | 
						|
		/* we can't alloc a client private, should we bail??? XXX */
 | 
						|
	}
 | 
						|
	XpGeneration = serverGeneration;
 | 
						|
    }
 | 
						|
 | 
						|
    for(i = 0; i < MAXSCREENS; i++)
 | 
						|
    {
 | 
						|
	/*
 | 
						|
	 * If a screen has registered with our extension, then we
 | 
						|
	 * wrap the screen's CloseScreen function to allow us to
 | 
						|
	 * reset our ContextPrivate stuff.  Note that this
 | 
						|
	 * requires a printing DDX to call XpRegisterInitFunc
 | 
						|
	 * _before_ this extension is initialized - i.e. at screen init
 | 
						|
	 * time, _not_ at root window creation time.
 | 
						|
	 */
 | 
						|
	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)
 | 
						|
{
 | 
						|
    /*
 | 
						|
     * We can't free up the XpScreens recs here, because extensions are
 | 
						|
     * closed before screens, and our CloseScreen function uses the XpScreens
 | 
						|
     * recs.
 | 
						|
 | 
						|
    int i;
 | 
						|
 | 
						|
    for(i = 0; i < MAXSCREENS; i++)
 | 
						|
    {
 | 
						|
	if(XpScreens[i] != (XpScreenPtr)NULL)
 | 
						|
	    Xfree(XpScreens[i]);
 | 
						|
	XpScreens[i] = (XpScreenPtr)NULL;
 | 
						|
    }
 | 
						|
    */
 | 
						|
}
 | 
						|
 | 
						|
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;
 | 
						|
 | 
						|
    /*
 | 
						|
     * It's wasteful to call ResetContextPrivates() at every CloseScreen, 
 | 
						|
     * but it's the best we know how to do for now.  We do this because we
 | 
						|
     * have to wait until after all resources have been freed (so we know
 | 
						|
     * how to free the ContextRecs), and before the next InitOutput cycle.
 | 
						|
     * See dix/main.c for the order of initialization and reset.
 | 
						|
     */
 | 
						|
    ResetContextPrivates();
 | 
						|
    return (*CloseScreen)(index, pScreen);
 | 
						|
}
 | 
						|
 | 
						|
#if 0 /* NOT USED */
 | 
						|
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
 | 
						|
 | 
						|
/*
 | 
						|
 * XpRegisterInitFunc tells the print extension which screens
 | 
						|
 * are printers as opposed to displays, and what drivers are
 | 
						|
 * supported on each screen.  This eliminates the need of
 | 
						|
 * allocating print-related private structures on windows on _all_ screens.
 | 
						|
 * It also hands the extension a pointer to the routine to be called
 | 
						|
 * whenever a context gets created for a particular driver on this screen.
 | 
						|
 */
 | 
						|
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)
 | 
						|
{
 | 
						|
    /* REQUEST(xPrintQueryVersionReq); */
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * GetPrinterList : Return a list of all printers associated with this
 | 
						|
 *                  server.  Calls XpDiGetPrinterList, which is defined in
 | 
						|
 *		    the device-independent code in Xserver/Xprint.
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * QueryScreens: Returns the list of screens which are associated with
 | 
						|
 *               print drivers.
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
static int
 | 
						|
ProcXpQueryScreens(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xPrintQueryScreensReq); */
 | 
						|
    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 a screen has registered with our extension, then it's
 | 
						|
	 * a printer screen.
 | 
						|
	 */
 | 
						|
	if(XpScreens[i] != (XpScreenPtr)NULL)
 | 
						|
	{
 | 
						|
	    numPrintScreens++;
 | 
						|
	    totalSize += sizeof(WINDOW);
 | 
						|
	    rep = (xPrintQueryScreensReply *)xrealloc(rep, totalSize);
 | 
						|
	    /* fix of bug: pWinId should be set again after reallocate rep */
 | 
						|
	    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;
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * RehashPrinterList : Cause the server's list of printers to be rebuilt.
 | 
						|
 *                     This allows new printers to be added, or old ones
 | 
						|
 *		       deleted without needing to restart the server.
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
static int
 | 
						|
ProcXpRehashPrinterList(ClientPtr client)
 | 
						|
{
 | 
						|
    /* REQUEST(xPrintRehashPrinterListReq); */
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xPrintRehashPrinterListReq);
 | 
						|
 | 
						|
    return XpRehashPrinterList();
 | 
						|
}
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
 *
 | 
						|
 * Context functions: Init, Set, Destroy, FreeContext
 | 
						|
 *			AllocateContextPrivateIndex, AllocateContextPrivate
 | 
						|
 *			and supporting functions.
 | 
						|
 *
 | 
						|
 *     Init creates a context, creates a XpClientRec for the calling
 | 
						|
 *     client, and stores the contextPtr in the client's devPrivates.
 | 
						|
 *
 | 
						|
 *     Set creates a XpClientRec for the calling client, and stores the
 | 
						|
 *     contextPtr in the client's devPrivates unless the context is None.
 | 
						|
 *     If the context is None, then the client's connection association
 | 
						|
 *     with any context is removed.
 | 
						|
 *
 | 
						|
 *     Destroy frees any and all XpClientRecs associated with the context,
 | 
						|
 *     frees the context itself, and removes the contextPtr from any
 | 
						|
 *     relevant client devPrivates.
 | 
						|
 *
 | 
						|
 *     FreeContext is called by FreeResource to free up a context.
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 * CreateContext creates and initializes the memory for the context itself.
 | 
						|
 * The driver's CreateContext function
 | 
						|
 * is then called.
 | 
						|
 */
 | 
						|
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);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Check to see if the printer name is valid.
 | 
						|
     */
 | 
						|
    if((pRoot = XpDiValidatePrinter((char *)(stuff + 1), stuff->printerNameLen)) == 
 | 
						|
       (WindowPtr)NULL)
 | 
						|
	return BadMatch;
 | 
						|
 | 
						|
    pPrintScreen = XpScreens[pRoot->drawable.pScreen->myNum];
 | 
						|
 | 
						|
    /*
 | 
						|
     * Allocate and add the context resource.
 | 
						|
     */
 | 
						|
    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)
 | 
						|
    {
 | 
						|
	/* Freeing the context also causes the XpClients to be freed. */
 | 
						|
	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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * SetContext creates the calling client's contextClient resource,
 | 
						|
 * and stashes the contextID in the client's devPrivate.
 | 
						|
 */
 | 
						|
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)
 | 
						|
    {
 | 
						|
	/*
 | 
						|
	 * Erase this client's knowledge of its old context, if any.
 | 
						|
	 */
 | 
						|
        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;
 | 
						|
 | 
						|
    /*
 | 
						|
     * Check to see that the supplied XID is really a valid print context
 | 
						|
     * in this server.
 | 
						|
     */
 | 
						|
    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)
 | 
						|
{
 | 
						|
    /* REQUEST(xPrintGetContextReq); */
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * DestroyContext frees the context associated with the calling client.
 | 
						|
 * It operates by freeing the context resource ID, thus causing XpFreeContext
 | 
						|
 * to be called.
 | 
						|
 */
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XpFreeContext is the routine called by dix:FreeResource when a context
 | 
						|
 * resource ID is freed.
 | 
						|
 * It checks to see if there's a partial job pending on the context, and
 | 
						|
 * if so it calls the appropriate End procs with the cancel flag set.
 | 
						|
 * It calls the driver's DestroyContext routine to allow the driver to clean
 | 
						|
 * up any context-related memory or state.
 | 
						|
 * It calls FreeXpClient to free all the 
 | 
						|
 * associated XpClientRecs and to set all the client->devPrivates to NULL.
 | 
						|
 * It frees the printer name string, and frees the context
 | 
						|
 * itself.
 | 
						|
 */
 | 
						|
static int
 | 
						|
XpFreeContext(pointer data, XID id)
 | 
						|
{
 | 
						|
    XpContextPtr pContext = (XpContextPtr)data;
 | 
						|
 | 
						|
    /* Clean up any pending job on this context */
 | 
						|
    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;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /* 
 | 
						|
     * Tell the driver we're destroying the context
 | 
						|
     * This allows the driver to free and ContextPrivate data
 | 
						|
     */
 | 
						|
    if(pContext->funcs.DestroyContext != 0)
 | 
						|
	pContext->funcs.DestroyContext(pContext);
 | 
						|
 | 
						|
    /* Free up all the XpClientRecs */
 | 
						|
    while(pContext->clientHead != (XpClientPtr)NULL)
 | 
						|
    {
 | 
						|
	FreeXpClient(pContext->clientHead, TRUE);
 | 
						|
    }
 | 
						|
 | 
						|
    xfree(pContext->printerName);
 | 
						|
    xfree(pContext);
 | 
						|
    return Success; /* ??? */
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XpFreeClient is the routine called by dix:FreeResource when a RTclient
 | 
						|
 * is freed.  It simply calls the FreeXpClient routine to do the work.
 | 
						|
 */
 | 
						|
static int
 | 
						|
XpFreeClient(pointer data, XID id)
 | 
						|
{
 | 
						|
    FreeXpClient((XpClientPtr)data, TRUE);
 | 
						|
    return Success;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * FreeXpClient 
 | 
						|
 * frees the ClientRec passed in, and sets the client->devPrivates to NULL
 | 
						|
 * if the client->devPrivates points to the same context as the XpClient.
 | 
						|
 * Called from XpFreeContext(from FreeResource), and 
 | 
						|
 * XpFreeClient.  The boolean freeResource specifies whether or not to call
 | 
						|
 * FreeResource for the XpClientRec's XID.  We should free it except if we're
 | 
						|
 * called from XpFreeClient (which is itself called from FreeResource for the
 | 
						|
 * XpClientRec's XID).
 | 
						|
 */
 | 
						|
static void
 | 
						|
FreeXpClient(XpClientPtr pXpClient, Bool freeResource)
 | 
						|
{
 | 
						|
    XpClientPtr pCurrent, pPrev;
 | 
						|
    XpContextPtr pContext = pXpClient->context;
 | 
						|
 | 
						|
    /*
 | 
						|
     * If we're freeing the clientRec associated with the context tied
 | 
						|
     * to the client's devPrivates, then we need to clear the devPrivates.
 | 
						|
     */
 | 
						|
    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;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * CreateXpClient takes a ClientPtr and returns a pointer to a
 | 
						|
 * XpClientRec which it allocates.  It also initializes the Rec,
 | 
						|
 * including adding a resource on behalf of the client to enable the
 | 
						|
 * freeing of the Rec when the client's connection is closed.
 | 
						|
 */
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XpFreePage is the routine called by dix:FreeResource to free the page
 | 
						|
 * resource built with the same ID as a page window.  It checks to see
 | 
						|
 * if we're in the middle of a page, and if so calls the driver's EndPage
 | 
						|
 * function with 'cancel' set TRUE.  It frees the memory associated with
 | 
						|
 * the page resource.
 | 
						|
 */
 | 
						|
static int
 | 
						|
XpFreePage(pointer data, XID id)
 | 
						|
{
 | 
						|
    XpPagePtr page = (XpPagePtr)data;
 | 
						|
    int result = Success;
 | 
						|
    WindowPtr pWin = (WindowPtr )LookupIDByType(id, RT_WINDOW);
 | 
						|
 | 
						|
    /* Check to see if the window's being deleted in the middle of a page */
 | 
						|
    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; /* None, NULL??? XXX */
 | 
						|
    }
 | 
						|
 | 
						|
    xfree(page);
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * ContextPrivate machinery.
 | 
						|
 * Context privates are intended for use by the drivers, allowing the
 | 
						|
 * drivers to maintain context-specific data.  The driver should free
 | 
						|
 * the associated data at DestroyContext time.
 | 
						|
 */
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
 *
 | 
						|
 * Start/End Functions: StartJob, EndJob, StartDoc, EndDoc, StartPage, EndPage
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
static int
 | 
						|
ProcXpStartJob(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xPrintStartJobReq);
 | 
						|
    XpContextPtr pContext;
 | 
						|
    int result = Success;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xPrintStartJobReq);
 | 
						|
 | 
						|
    /* Check to see that a context has been established by this client. */
 | 
						|
    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;
 | 
						|
    
 | 
						|
    /* Check for missing EndDoc */
 | 
						|
    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))
 | 
						|
    {
 | 
						|
	/* Implied StartDoc if it was omitted */
 | 
						|
        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);
 | 
						|
    }
 | 
						|
 | 
						|
    /* ensure the window's not already being used as a page */
 | 
						|
    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;
 | 
						|
 | 
						|
    /* can't have pages in a raw documented */
 | 
						|
    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);
 | 
						|
 | 
						|
    /* Call the ddx's EndPage proc. */
 | 
						|
    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; /* None, NULL??? XXX */
 | 
						|
 | 
						|
    (void)UnmapWindow(pWin, FALSE);
 | 
						|
 | 
						|
    SendXpNotify(pContext, XPEndPageNotify, stuff->cancel);
 | 
						|
 | 
						|
    if (client->noClientException != Success)
 | 
						|
        return client->noClientException;
 | 
						|
    else
 | 
						|
        return result;
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * Document Data Functions: PutDocumentData, GetDocumentData
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
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; /* gotta have a positive buffer size */
 | 
						|
    }
 | 
						|
 | 
						|
    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); /* XXX Why are these longs??? */
 | 
						|
            swapl(&rep.finishedFlag, l); /* XXX Why are these longs??? */
 | 
						|
        }
 | 
						|
	(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;
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * Attribute requests: GetAttributes, SetAttributes, GetOneAttribute
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
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;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Disallow changing of read-only attribute pools
 | 
						|
     */
 | 
						|
    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;
 | 
						|
    
 | 
						|
    /* 
 | 
						|
     * Check for attributes being set after their relevant phase
 | 
						|
     * has already begun (e.g. Job attributes set after StartJob).
 | 
						|
     */
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * Print Event requests: SelectInput InputSelected, SendXpNotify
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
 | 
						|
static int
 | 
						|
ProcXpSelectInput(ClientPtr client)
 | 
						|
{
 | 
						|
    REQUEST(xPrintSelectInputReq);
 | 
						|
    int result = Success;
 | 
						|
    XpContextPtr pContext;
 | 
						|
    XpClientPtr pPrintClient;
 | 
						|
 | 
						|
    REQUEST_SIZE_MATCH(xPrintSelectInputReq);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Check to see that the supplied XID is really a valid print context
 | 
						|
     * in this server.
 | 
						|
     */
 | 
						|
    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; /* bogus event mask bits */
 | 
						|
    }
 | 
						|
 | 
						|
    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; /* Nobody's interested in the events (or this context). */
 | 
						|
 | 
						|
    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; /* Nobody's interested in the events (or this context). */
 | 
						|
 | 
						|
    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;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * XpContextOfClient - returns the XpContextPtr to the context
 | 
						|
 * associated with the specified client, or NULL if the client
 | 
						|
 * does not currently have a context set.
 | 
						|
 */
 | 
						|
XpContextPtr
 | 
						|
XpContextOfClient(ClientPtr client)
 | 
						|
{
 | 
						|
    return (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
 *
 | 
						|
 * Swap-request functions
 | 
						|
 *
 | 
						|
 ******************************************************************************/
 | 
						|
 | 
						|
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)
 | 
						|
{
 | 
						|
    /*
 | 
						|
     * Swap the sequence number and context fields.
 | 
						|
     */
 | 
						|
    cpswaps(src->sequenceNumber, dst->sequenceNumber);
 | 
						|
    cpswapl(src->printContext, dst->printContext);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Copy the byte-long fields.
 | 
						|
     */
 | 
						|
    dst->type = src->type;
 | 
						|
    dst->detail = src->detail;
 | 
						|
    dst->cancel = src->cancel;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
SwapXpAttributeEvent(xPrintAttributeEvent *src, xPrintAttributeEvent *dst)
 | 
						|
{
 | 
						|
    /*
 | 
						|
     * Swap the sequence number and context fields.
 | 
						|
     */
 | 
						|
    cpswaps(src->sequenceNumber, dst->sequenceNumber);
 | 
						|
    cpswapl(src->printContext, dst->printContext);
 | 
						|
 | 
						|
    /*
 | 
						|
     * Copy the byte-long fields.
 | 
						|
     */
 | 
						|
    dst->type = src->type;
 | 
						|
    dst->detail = src->detail;
 | 
						|
}
 |