2 (c) Copyright 1996 Hewlett-Packard Company
3 (c) Copyright 1996 International Business Machines Corp.
4 (c) Copyright 1996 Sun Microsystems, Inc.
5 (c) Copyright 1996 Novell, Inc.
6 (c) Copyright 1996 Digital Equipment Corp.
7 (c) Copyright 1996 Fujitsu Limited
8 (c) Copyright 1996 Hitachi, Ltd.
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 Except as contained in this notice, the names of the copyright holders shall
28 not be used in advertising or otherwise to promote the sale, use or other
29 dealings in this Software without prior written authorization from said
32 /*******************************************************************
34 ** *********************************************************
38 ** * Copyright: Copyright 1993, 1995 Hewlett-Packard Company
40 ** * Copyright 1989 by The Massachusetts Institute of Technology
42 ** * Permission to use, copy, modify, and distribute this
43 ** * software and its documentation for any purpose and without
44 ** * fee is hereby granted, provided that the above copyright
45 ** * notice appear in all copies and that both that copyright
46 ** * notice and this permission notice appear in supporting
47 ** * documentation, and that the name of MIT not be used in
48 ** * advertising or publicity pertaining to distribution of the
49 ** * software without specific prior written permission.
50 ** * M.I.T. makes no representation about the suitability of
51 ** * this software for any purpose. It is provided "as is"
52 ** * without any express or implied warranty.
54 ** * MIT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
55 ** * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
56 ** * NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MIT BE LI-
57 ** * ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
58 ** * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
59 ** * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
60 ** * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
61 ** * THE USE OR PERFORMANCE OF THIS SOFTWARE.
63 ** *********************************************************
65 ********************************************************************/
67 #define _XP_PRINT_SERVER_
68 #ifdef HAVE_DIX_CONFIG_H
69 #include <dix-config.h>
75 #include <X11/Xproto.h>
78 #include "windowstr.h"
79 #include "scrnintstr.h"
80 #include "pixmapstr.h"
81 #include "extnsionst.h"
82 #include "dixstruct.h"
83 #include <X11/Xatom.h>
84 #include <X11/extensions/Print.h>
85 #include <X11/extensions/Printstr.h>
86 #include "../hw/xprint/DiPrint.h"
87 #include "../hw/xprint/attributes.h"
90 static void XpResetProc(ExtensionEntry
*);
92 static int ProcXpDispatch(ClientPtr
);
93 static int ProcXpSwappedDispatch(ClientPtr
);
95 static int ProcXpQueryVersion(ClientPtr
);
96 static int ProcXpGetPrinterList(ClientPtr
);
97 static int ProcXpCreateContext(ClientPtr
);
98 static int ProcXpSetContext(ClientPtr
);
99 static int ProcXpGetContext(ClientPtr
);
100 static int ProcXpDestroyContext(ClientPtr
);
101 static int ProcXpGetContextScreen(ClientPtr
);
102 static int ProcXpStartJob(ClientPtr
);
103 static int ProcXpEndJob(ClientPtr
);
104 static int ProcXpStartDoc(ClientPtr
);
105 static int ProcXpEndDoc(ClientPtr
);
106 static int ProcXpStartPage(ClientPtr
);
107 static int ProcXpEndPage(ClientPtr
);
108 static int ProcXpSelectInput(ClientPtr
);
109 static int ProcXpInputSelected(ClientPtr
);
110 static int ProcXpPutDocumentData(ClientPtr
);
111 static int ProcXpGetDocumentData(ClientPtr
);
112 static int ProcXpGetAttributes(ClientPtr
);
113 static int ProcXpGetOneAttribute(ClientPtr
);
114 static int ProcXpSetAttributes(ClientPtr
);
115 static int ProcXpRehashPrinterList(ClientPtr
);
116 static int ProcXpQueryScreens(ClientPtr
);
117 static int ProcXpGetPageDimensions(ClientPtr
);
118 static int ProcXpSetImageResolution(ClientPtr
);
119 static int ProcXpGetImageResolution(ClientPtr
);
121 static void SwapXpNotifyEvent(xPrintPrintEvent
*, xPrintPrintEvent
*);
122 static void SwapXpAttributeEvent(xPrintAttributeEvent
*, xPrintAttributeEvent
*);
124 static int SProcXpGetPrinterList(ClientPtr
);
125 static int SProcXpCreateContext(ClientPtr
);
126 static int SProcXpSetContext(ClientPtr
);
127 static int SProcXpGetContext(ClientPtr
);
128 static int SProcXpDestroyContext(ClientPtr
);
129 static int SProcXpGetContextScreen(ClientPtr
);
130 static int SProcXpStartJob(ClientPtr
);
131 static int SProcXpEndJob(ClientPtr
);
132 static int SProcXpStartDoc(ClientPtr
);
133 static int SProcXpEndDoc(ClientPtr
);
134 static int SProcXpStartPage(ClientPtr
);
135 static int SProcXpEndPage(ClientPtr
);
136 static int SProcXpSelectInput(ClientPtr
);
137 static int SProcXpInputSelected(ClientPtr
);
138 static int SProcXpPutDocumentData(ClientPtr
);
139 static int SProcXpGetDocumentData(ClientPtr
);
140 static int SProcXpGetAttributes(ClientPtr
);
141 static int SProcXpGetOneAttribute(ClientPtr
);
142 static int SProcXpSetAttributes(ClientPtr
);
143 static int SProcXpRehashPrinterList(ClientPtr
);
144 static int SProcXpGetPageDimensions(ClientPtr
);
145 static int SProcXpSetImageResolution(ClientPtr
);
146 static int SProcXpGetImageResolution(ClientPtr
);
148 static void SendXpNotify(XpContextPtr
, int, int);
149 static void SendAttributeNotify(XpContextPtr
, int);
150 static int XpFreeClient(pointer
, XID
);
151 static int XpFreeContext(pointer
, XID
);
152 static int XpFreePage(pointer
, XID
);
153 static Bool
XpCloseScreen(int, ScreenPtr
);
154 static CARD32
GetAllEventMasks(XpContextPtr
);
155 static struct _XpClient
*CreateXpClient(ClientPtr
);
156 static void InitContextPrivates(XpContextPtr
);
157 static void ResetContextPrivates(void);
158 static struct _XpClient
*FindClient(XpContextPtr
, ClientPtr
);
159 static struct _XpClient
*AcquireClient(XpContextPtr
, ClientPtr
);
161 typedef struct _driver
{
162 struct _driver
*next
;
164 int (* CreateContext
)(XpContextPtr
);
165 } XpDriverRec
, *XpDriverPtr
;
167 typedef struct _xpScreen
{
168 Bool (* CloseScreen
)(int, ScreenPtr
);
169 struct _driver
*drivers
;
170 } XpScreenRec
, *XpScreenPtr
;
173 * Each context has a list of XpClients indicating which clients have
174 * associated this context with their connection.
175 * Each such client has a RTclient resource allocated for it,
176 * and this per-client
177 * resource is used to delete the XpClientRec if/when the client closes
179 * The list of XpClients is also walked if/when the context is destroyed
180 * so that the ContextPtr can be removed from the client's devPrivates.
182 typedef struct _XpClient
{
183 struct _XpClient
*pNext
;
185 XpContextPtr context
;
187 XID contextClientID
; /* unneeded sanity check? */
188 } XpClientRec
, *XpClientPtr
;
190 static void FreeXpClient(XpClientPtr
, Bool
);
193 * Each StartPage request specifies a window which forms the top level
194 * window of the page. One of the following structs is created as a
195 * RTpage resource with the same ID as the window itself. This enables
196 * us to clean up when/if the window is destroyed, and to prevent the
197 * same window from being simultaneously referenced in multiple contexts.
198 * The page resource is created at the first StartPage on a given window,
199 * and is only destroyed when/if the window is destroyed. When the
200 * EndPage is recieved (or an EndDoc or EndJob) the context field is
201 * set to NULL, but the resource remains alive.
203 typedef struct _XpPage
{
204 XpContextPtr context
;
205 } XpPageRec
, *XpPagePtr
;
207 typedef struct _XpStPageRec
{
208 XpContextPtr pContext
;
212 } XpStPageRec
, *XpStPagePtr
;
214 typedef struct _XpStDocRec
{
215 XpContextPtr pContext
;
218 } XpStDocRec
, *XpStDocPtr
;
220 #define QUADPAD(x) ((((x)+3)>>2)<<2)
223 * Possible bit-mask values in the "state" field of a XpContextRec.
225 #define JOB_STARTED (1 << 0)
226 #define DOC_RAW_STARTED (1 << 1)
227 #define DOC_COOKED_STARTED (1 << 2)
228 #define PAGE_STARTED (1 << 3)
229 #define GET_DOC_DATA_STARTED (1 << 4)
230 #define JOB_GET_DATA (1 << 5)
232 static XpScreenPtr XpScreens
[MAXSCREENS
];
233 static unsigned char XpReqCode
;
234 static int XpEventBase
;
235 static int XpErrorBase
;
236 static unsigned long XpGeneration
= 0;
237 static int XpClientPrivateIndex
;
239 /* Variables for the context private machinery.
240 * These must be initialized at compile time because
241 * main() calls InitOutput before InitExtensions, and the
242 * output drivers are likely to call AllocateContextPrivate.
243 * These variables are reset at CloseScreen time. CloseScreen
244 * is used because it occurs after FreeAllResources, and before
245 * the next InitOutput cycle.
247 static int contextPrivateCount
= 0;
248 static int contextPrivateLen
= 0;
249 static unsigned *contextPrivateSizes
= (unsigned *)NULL
;
250 static unsigned totalContextSize
= sizeof(XpContextRec
);
253 * There are three types of resources involved. One is the resource associated
254 * with the context itself, with an ID specified by a printing client. The
255 * next is a resource created by us on the client's behalf (and unknown to
256 * the client) when a client inits or sets a context which allows us to
257 * track each client's interest in events
258 * on a particular context, and also allows us to clean up this interest
259 * record when/if the client's connection is closed. Finally, there is
260 * a resource created for each window that's specified in a StartPage. This
261 * resource carries the same ID as the window itself, and enables us to
262 * easily prevent the same window being referenced in multiple contexts
263 * simultaneously, and enables us to clean up if the window is destroyed
264 * before the EndPage.
266 static RESTYPE RTclient
, RTcontext
, RTpage
;
269 * allEvents is the OR of all the legal event mask bits.
271 static CARD32 allEvents
= XPPrintMask
| XPAttributeMask
;
274 /*******************************************************************************
276 * ExtensionInit, Driver Init functions, QueryVersion, and Dispatch procs
278 ******************************************************************************/
283 * Called from InitExtensions in main() usually through miinitextension
288 XpExtensionInit(INITARGS
)
290 ExtensionEntry
*extEntry
;
293 RTclient
= CreateNewResourceType(XpFreeClient
);
294 RTcontext
= CreateNewResourceType(XpFreeContext
);
295 RTpage
= CreateNewResourceType(XpFreePage
);
296 if (RTclient
&& RTcontext
&& RTpage
&&
297 (extEntry
= AddExtension(XP_PRINTNAME
, XP_EVENTS
, XP_ERRORS
,
298 ProcXpDispatch
, ProcXpSwappedDispatch
,
299 XpResetProc
, StandardMinorOpcode
)))
301 XpReqCode
= (unsigned char)extEntry
->base
;
302 XpEventBase
= extEntry
->eventBase
;
303 XpErrorBase
= extEntry
->errorBase
;
304 EventSwapVector
[XpEventBase
] = (EventSwapPtr
) SwapXpNotifyEvent
;
305 EventSwapVector
[XpEventBase
+1] = (EventSwapPtr
) SwapXpAttributeEvent
;
308 if(XpGeneration
!= serverGeneration
)
310 XpClientPrivateIndex
= AllocateClientPrivateIndex();
312 * We allocate 0 length & simply stuff a pointer to the
313 * ContextRec in the DevUnion.
315 if(AllocateClientPrivate(XpClientPrivateIndex
, 0) != TRUE
)
317 /* we can't alloc a client private, should we bail??? XXX */
319 XpGeneration
= serverGeneration
;
322 for(i
= 0; i
< MAXSCREENS
; i
++)
325 * If a screen has registered with our extension, then we
326 * wrap the screen's CloseScreen function to allow us to
327 * reset our ContextPrivate stuff. Note that this
328 * requires a printing DDX to call XpRegisterInitFunc
329 * _before_ this extension is initialized - i.e. at screen init
330 * time, _not_ at root window creation time.
332 if(XpScreens
[i
] != (XpScreenPtr
)NULL
)
334 XpScreens
[i
]->CloseScreen
= screenInfo
.screens
[i
]->CloseScreen
;
335 screenInfo
.screens
[i
]->CloseScreen
= XpCloseScreen
;
338 DeclareExtensionSecurity(XP_PRINTNAME
, TRUE
);
342 XpResetProc(ExtensionEntry
*extEntry
)
345 * We can't free up the XpScreens recs here, because extensions are
346 * closed before screens, and our CloseScreen function uses the XpScreens
351 for(i = 0; i < MAXSCREENS; i++)
353 if(XpScreens[i] != (XpScreenPtr)NULL)
355 XpScreens[i] = (XpScreenPtr)NULL;
361 XpCloseScreen(int index
, ScreenPtr pScreen
)
363 Bool (* CloseScreen
)(int, ScreenPtr
);
365 CloseScreen
= XpScreens
[index
]->CloseScreen
;
366 if(XpScreens
[index
] != (XpScreenPtr
)NULL
)
368 XpDriverPtr pDriv
, nextDriv
;
370 pDriv
= XpScreens
[index
]->drivers
;
371 while(pDriv
!= (XpDriverPtr
)NULL
)
373 nextDriv
= pDriv
->next
;
377 Xfree(XpScreens
[index
]);
379 XpScreens
[index
] = (XpScreenPtr
)NULL
;
382 * It's wasteful to call ResetContextPrivates() at every CloseScreen,
383 * but it's the best we know how to do for now. We do this because we
384 * have to wait until after all resources have been freed (so we know
385 * how to free the ContextRecs), and before the next InitOutput cycle.
386 * See dix/main.c for the order of initialization and reset.
388 ResetContextPrivates();
389 return (*CloseScreen
)(index
, pScreen
);
394 FreeScreenEntry(XpScreenPtr pScreenEntry
)
398 pDriver
= pScreenEntry
->drivers
;
399 while(pDriver
!= (XpDriverPtr
)NULL
)
412 * XpRegisterInitFunc tells the print extension which screens
413 * are printers as opposed to displays, and what drivers are
414 * supported on each screen. This eliminates the need of
415 * allocating print-related private structures on windows on _all_ screens.
416 * It also hands the extension a pointer to the routine to be called
417 * whenever a context gets created for a particular driver on this screen.
420 XpRegisterInitFunc(ScreenPtr pScreen
, char *driverName
, int (*initContext
)(struct _XpContext
*))
424 if(XpScreens
[pScreen
->myNum
] == 0)
426 if((XpScreens
[pScreen
->myNum
] =
427 (XpScreenPtr
) Xalloc(sizeof(XpScreenRec
))) == 0)
429 XpScreens
[pScreen
->myNum
]->CloseScreen
= 0;
430 XpScreens
[pScreen
->myNum
]->drivers
= 0;
433 if((pDriver
= (XpDriverPtr
)Xalloc(sizeof(XpDriverRec
))) == 0)
435 pDriver
->next
= XpScreens
[pScreen
->myNum
]->drivers
;
436 pDriver
->name
= driverName
;
437 pDriver
->CreateContext
= initContext
;
438 XpScreens
[pScreen
->myNum
]->drivers
= pDriver
;
442 ProcXpDispatch(ClientPtr client
)
448 case X_PrintQueryVersion
:
449 return ProcXpQueryVersion(client
);
450 case X_PrintGetPrinterList
:
451 return ProcXpGetPrinterList(client
);
452 case X_PrintCreateContext
:
453 return ProcXpCreateContext(client
);
454 case X_PrintSetContext
:
455 return ProcXpSetContext(client
);
456 case X_PrintGetContext
:
457 return ProcXpGetContext(client
);
458 case X_PrintDestroyContext
:
459 return ProcXpDestroyContext(client
);
460 case X_PrintGetContextScreen
:
461 return ProcXpGetContextScreen(client
);
462 case X_PrintStartJob
:
463 return ProcXpStartJob(client
);
465 return ProcXpEndJob(client
);
466 case X_PrintStartDoc
:
467 return ProcXpStartDoc(client
);
469 return ProcXpEndDoc(client
);
470 case X_PrintStartPage
:
471 return ProcXpStartPage(client
);
473 return ProcXpEndPage(client
);
474 case X_PrintSelectInput
:
475 return ProcXpSelectInput(client
);
476 case X_PrintInputSelected
:
477 return ProcXpInputSelected(client
);
478 case X_PrintPutDocumentData
:
479 return ProcXpPutDocumentData(client
);
480 case X_PrintGetDocumentData
:
481 return ProcXpGetDocumentData(client
);
482 case X_PrintSetAttributes
:
483 return ProcXpSetAttributes(client
);
484 case X_PrintGetAttributes
:
485 return ProcXpGetAttributes(client
);
486 case X_PrintGetOneAttribute
:
487 return ProcXpGetOneAttribute(client
);
488 case X_PrintRehashPrinterList
:
489 return ProcXpRehashPrinterList(client
);
490 case X_PrintQueryScreens
:
491 return ProcXpQueryScreens(client
);
492 case X_PrintGetPageDimensions
:
493 return ProcXpGetPageDimensions(client
);
494 case X_PrintSetImageResolution
:
495 return ProcXpSetImageResolution(client
);
496 case X_PrintGetImageResolution
:
497 return ProcXpGetImageResolution(client
);
504 ProcXpSwappedDispatch(ClientPtr client
)
511 case X_PrintQueryVersion
:
512 swaps(&stuff
->length
, temp
);
513 return ProcXpQueryVersion(client
);
514 case X_PrintGetPrinterList
:
515 return SProcXpGetPrinterList(client
);
516 case X_PrintCreateContext
:
517 return SProcXpCreateContext(client
);
518 case X_PrintSetContext
:
519 return SProcXpSetContext(client
);
520 case X_PrintGetContext
:
521 return SProcXpGetContext(client
);
522 case X_PrintDestroyContext
:
523 return SProcXpDestroyContext(client
);
524 case X_PrintGetContextScreen
:
525 return SProcXpGetContextScreen(client
);
526 case X_PrintStartJob
:
527 return SProcXpStartJob(client
);
529 return SProcXpEndJob(client
);
530 case X_PrintStartDoc
:
531 return SProcXpStartDoc(client
);
533 return SProcXpEndDoc(client
);
534 case X_PrintStartPage
:
535 return SProcXpStartPage(client
);
537 return SProcXpEndPage(client
);
538 case X_PrintSelectInput
:
539 return SProcXpSelectInput(client
);
540 case X_PrintInputSelected
:
541 return SProcXpInputSelected(client
);
542 case X_PrintPutDocumentData
:
543 return SProcXpPutDocumentData(client
);
544 case X_PrintGetDocumentData
:
545 return SProcXpGetDocumentData(client
);
546 case X_PrintSetAttributes
:
547 return SProcXpSetAttributes(client
);
548 case X_PrintGetAttributes
:
549 return SProcXpGetAttributes(client
);
550 case X_PrintGetOneAttribute
:
551 return SProcXpGetOneAttribute(client
);
552 case X_PrintRehashPrinterList
:
553 return SProcXpRehashPrinterList(client
);
554 case X_PrintQueryScreens
:
555 swaps(&stuff
->length
, temp
);
556 return ProcXpQueryScreens(client
);
557 case X_PrintGetPageDimensions
:
558 return SProcXpGetPageDimensions(client
);
559 case X_PrintSetImageResolution
:
560 return SProcXpSetImageResolution(client
);
561 case X_PrintGetImageResolution
:
562 return SProcXpGetImageResolution(client
);
569 ProcXpQueryVersion(ClientPtr client
)
571 /* REQUEST(xPrintQueryVersionReq); */
572 xPrintQueryVersionReply rep
;
576 REQUEST_SIZE_MATCH(xPrintQueryVersionReq
);
579 rep
.sequenceNumber
= client
->sequence
;
580 rep
.majorVersion
= XP_MAJOR_VERSION
;
581 rep
.minorVersion
= XP_MINOR_VERSION
;
582 if (client
->swapped
) {
583 swaps(&rep
.sequenceNumber
, n
);
584 swapl(&rep
.length
, l
);
585 swaps(&rep
.majorVersion
, n
);
586 swaps(&rep
.minorVersion
, n
);
588 WriteToClient(client
, sz_xPrintQueryVersionReply
, (char *)&rep
);
589 return client
->noClientException
;
592 /*******************************************************************************
594 * GetPrinterList : Return a list of all printers associated with this
595 * server. Calls XpDiGetPrinterList, which is defined in
596 * the device-independent code in Xserver/Xprint.
598 ******************************************************************************/
601 ProcXpGetPrinterList(ClientPtr client
)
603 REQUEST(xPrintGetPrinterListReq
);
606 XpDiListEntry
**pList
;
607 xPrintGetPrinterListReply
*rep
;
608 int n
, i
, totalBytes
;
612 REQUEST_AT_LEAST_SIZE(xPrintGetPrinterListReq
);
614 totalSize
= ((sz_xPrintGetPrinterListReq
) >> 2) +
615 ((stuff
->printerNameLen
+ 3) >> 2) +
616 ((stuff
->localeLen
+ 3) >> 2);
617 if(totalSize
!= client
->req_len
)
620 pList
= XpDiGetPrinterList(stuff
->printerNameLen
, (char *)(stuff
+ 1),
621 stuff
->localeLen
, (char *)((stuff
+ 1) +
622 QUADPAD(stuff
->printerNameLen
)));
624 for(numEntries
= 0, totalBytes
= sz_xPrintGetPrinterListReply
;
625 pList
[numEntries
] != (XpDiListEntry
*)NULL
;
628 totalBytes
+= 2 * sizeof(CARD32
);
629 totalBytes
+= QUADPAD(strlen(pList
[numEntries
]->name
));
630 totalBytes
+= QUADPAD(strlen(pList
[numEntries
]->description
));
633 if((rep
= (xPrintGetPrinterListReply
*)xalloc(totalBytes
)) ==
634 (xPrintGetPrinterListReply
*)NULL
)
638 rep
->length
= (totalBytes
- sz_xPrintGetPrinterListReply
) >> 2;
639 rep
->sequenceNumber
= client
->sequence
;
640 rep
->listCount
= numEntries
;
641 if (client
->swapped
) {
642 swaps(&rep
->sequenceNumber
, n
);
643 swapl(&rep
->length
, l
);
644 swapl(&rep
->listCount
, l
);
647 for(i
= 0, curByte
= (char *)(rep
+ 1); i
< numEntries
; i
++)
652 pCrd
= (CARD32
*)curByte
;
653 len
= strlen(pList
[i
]->name
);
656 swapl((long *)curByte
, l
);
657 curByte
+= sizeof(CARD32
);
658 strncpy(curByte
, pList
[i
]->name
, len
);
659 curByte
+= QUADPAD(len
);
661 pCrd
= (CARD32
*)curByte
;
662 len
= strlen(pList
[i
]->description
);
665 swapl((long *)curByte
, l
);
666 curByte
+= sizeof(CARD32
);
667 strncpy(curByte
, pList
[i
]->description
, len
);
668 curByte
+= QUADPAD(len
);
671 XpDiFreePrinterList(pList
);
673 WriteToClient(client
, totalBytes
, (char *)rep
);
675 return client
->noClientException
;
678 /*******************************************************************************
680 * QueryScreens: Returns the list of screens which are associated with
683 ******************************************************************************/
686 ProcXpQueryScreens(ClientPtr client
)
688 /* REQUEST(xPrintQueryScreensReq); */
689 int i
, numPrintScreens
, totalSize
;
691 xPrintQueryScreensReply
*rep
;
694 REQUEST_SIZE_MATCH(xPrintQueryScreensReq
);
696 rep
= (xPrintQueryScreensReply
*)xalloc(sz_xPrintQueryScreensReply
);
697 pWinId
= (WINDOW
*)(rep
+ 1);
699 for(i
= 0, numPrintScreens
= 0, totalSize
= sz_xPrintQueryScreensReply
;
703 * If a screen has registered with our extension, then it's
706 if(XpScreens
[i
] != (XpScreenPtr
)NULL
)
709 totalSize
+= sizeof(WINDOW
);
710 rep
= (xPrintQueryScreensReply
*)xrealloc(rep
, totalSize
);
711 /* fix of bug: pWinId should be set again after reallocate rep */
712 pWinId
= (WINDOW
*)(rep
+ 1);
713 *pWinId
= WindowTable
[i
]->drawable
.id
;
715 swapl((long *)pWinId
, l
);
720 rep
->sequenceNumber
= client
->sequence
;
721 rep
->length
= (totalSize
- sz_xPrintQueryScreensReply
) >> 2;
722 rep
->listCount
= numPrintScreens
;
727 swaps(&rep
->sequenceNumber
, n
);
728 swapl(&rep
->length
, l
);
729 swapl(&rep
->listCount
, l
);
732 WriteToClient(client
, totalSize
, (char *)rep
);
734 return client
->noClientException
;
738 ProcXpGetPageDimensions(ClientPtr client
)
740 REQUEST(xPrintGetPageDimensionsReq
);
741 CARD16 width
, height
;
743 xPrintGetPageDimensionsReply rep
;
744 XpContextPtr pContext
;
747 REQUEST_SIZE_MATCH(xPrintGetPageDimensionsReq
);
749 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
753 == (XpContextPtr
)NULL
)
755 client
->errorValue
= stuff
->printContext
;
756 return XpErrorBase
+XPBadContext
;
759 if((pContext
->funcs
.GetMediumDimensions
== 0) ||
760 (pContext
->funcs
.GetReproducibleArea
== 0))
761 return BadImplementation
;
763 result
= pContext
->funcs
.GetMediumDimensions(pContext
, &width
, &height
);
764 if(result
!= Success
)
767 result
= pContext
->funcs
.GetReproducibleArea(pContext
, &rect
);
768 if(result
!= Success
)
772 rep
.sequenceNumber
= client
->sequence
;
778 rep
.rwidth
= rect
.width
;
779 rep
.rheight
= rect
.height
;
786 swaps(&rep
.sequenceNumber
, n
);
787 swapl(&rep
.length
, l
);
788 swaps(&rep
.width
, n
);
789 swaps(&rep
.height
, n
);
792 swaps(&rep
.rwidth
, n
);
793 swaps(&rep
.rheight
, n
);
796 WriteToClient(client
, sz_xPrintGetPageDimensionsReply
, (char *)&rep
);
797 return client
->noClientException
;
801 ProcXpSetImageResolution(ClientPtr client
)
803 REQUEST(xPrintSetImageResolutionReq
);
804 xPrintSetImageResolutionReply rep
;
805 XpContextPtr pContext
;
809 REQUEST_SIZE_MATCH(xPrintSetImageResolutionReq
);
811 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
815 == (XpContextPtr
)NULL
)
817 client
->errorValue
= stuff
->printContext
;
818 return XpErrorBase
+XPBadContext
;
821 rep
.prevRes
= pContext
->imageRes
;
822 if(pContext
->funcs
.SetImageResolution
!= 0) {
823 result
= pContext
->funcs
.SetImageResolution(pContext
,
824 (int)stuff
->imageRes
,
826 if(result
!= Success
)
832 rep
.sequenceNumber
= client
->sequence
;
841 swaps(&rep
.sequenceNumber
, n
);
842 swapl(&rep
.length
, l
);
843 swaps(&rep
.prevRes
, n
);
846 WriteToClient(client
, sz_xPrintSetImageResolutionReply
, (char *)&rep
);
847 return client
->noClientException
;
851 ProcXpGetImageResolution(ClientPtr client
)
853 REQUEST(xPrintGetImageResolutionReq
);
854 xPrintGetImageResolutionReply rep
;
855 XpContextPtr pContext
;
857 REQUEST_SIZE_MATCH(xPrintGetImageResolutionReq
);
859 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
863 == (XpContextPtr
)NULL
)
865 client
->errorValue
= stuff
->printContext
;
866 return XpErrorBase
+XPBadContext
;
870 rep
.sequenceNumber
= client
->sequence
;
872 rep
.imageRes
= pContext
->imageRes
;
879 swaps(&rep
.sequenceNumber
, n
);
880 swapl(&rep
.length
, l
);
881 swaps(&rep
.imageRes
, n
);
884 WriteToClient(client
, sz_xPrintGetImageResolutionReply
, (char *)&rep
);
885 return client
->noClientException
;
888 /*******************************************************************************
890 * RehashPrinterList : Cause the server's list of printers to be rebuilt.
891 * This allows new printers to be added, or old ones
892 * deleted without needing to restart the server.
894 ******************************************************************************/
897 ProcXpRehashPrinterList(ClientPtr client
)
899 /* REQUEST(xPrintRehashPrinterListReq); */
901 REQUEST_SIZE_MATCH(xPrintRehashPrinterListReq
);
903 return XpRehashPrinterList();
906 /******************************************************************************
908 * Context functions: Init, Set, Destroy, FreeContext
909 * AllocateContextPrivateIndex, AllocateContextPrivate
910 * and supporting functions.
912 * Init creates a context, creates a XpClientRec for the calling
913 * client, and stores the contextPtr in the client's devPrivates.
915 * Set creates a XpClientRec for the calling client, and stores the
916 * contextPtr in the client's devPrivates unless the context is None.
917 * If the context is None, then the client's connection association
918 * with any context is removed.
920 * Destroy frees any and all XpClientRecs associated with the context,
921 * frees the context itself, and removes the contextPtr from any
922 * relevant client devPrivates.
924 * FreeContext is called by FreeResource to free up a context.
926 ******************************************************************************/
929 * CreateContext creates and initializes the memory for the context itself.
930 * The driver's CreateContext function
934 ProcXpCreateContext(ClientPtr client
)
936 REQUEST(xPrintCreateContextReq
);
937 XpScreenPtr pPrintScreen
;
940 XpContextPtr pContext
;
941 int result
= Success
;
944 REQUEST_AT_LEAST_SIZE(xPrintCreateContextReq
);
946 LEGAL_NEW_RESOURCE(stuff
->contextID
, client
);
949 * Check to see if the printer name is valid.
951 if((pRoot
= XpDiValidatePrinter((char *)(stuff
+ 1), stuff
->printerNameLen
)) ==
955 pPrintScreen
= XpScreens
[pRoot
->drawable
.pScreen
->myNum
];
958 * Allocate and add the context resource.
960 if((pContext
= (XpContextPtr
) xalloc(totalContextSize
)) ==
964 InitContextPrivates(pContext
);
966 if(AddResource(stuff
->contextID
, RTcontext
, (pointer
) pContext
)
973 pContext
->contextID
= stuff
->contextID
;
974 pContext
->clientHead
= (XpClientPtr
)NULL
;
975 pContext
->screenNum
= pRoot
->drawable
.pScreen
->myNum
;
977 pContext
->clientSlept
= (ClientPtr
)NULL
;
978 pContext
->imageRes
= 0;
980 pContext
->funcs
.DestroyContext
= 0;
981 pContext
->funcs
.StartJob
= 0;
982 pContext
->funcs
.EndJob
= 0;
983 pContext
->funcs
.StartDoc
= 0;
984 pContext
->funcs
.EndDoc
= 0;
985 pContext
->funcs
.StartPage
= 0;
986 pContext
->funcs
.EndPage
= 0;
987 pContext
->funcs
.PutDocumentData
= 0;
988 pContext
->funcs
.GetDocumentData
= 0;
989 pContext
->funcs
.GetAttributes
= 0;
990 pContext
->funcs
.GetOneAttribute
= 0;
991 pContext
->funcs
.SetAttributes
= 0;
992 pContext
->funcs
.AugmentAttributes
= 0;
993 pContext
->funcs
.GetMediumDimensions
= 0;
994 pContext
->funcs
.GetReproducibleArea
= 0;
995 pContext
->funcs
.SetImageResolution
= 0;
997 if((pContext
->printerName
= (char *)xalloc(stuff
->printerNameLen
+ 1)) ==
1000 /* Freeing the context also causes the XpClients to be freed. */
1001 FreeResource(stuff
->contextID
, RT_NONE
);
1004 strncpy(pContext
->printerName
, (char *)(stuff
+ 1), stuff
->printerNameLen
);
1005 pContext
->printerName
[stuff
->printerNameLen
] = (char)'\0';
1007 driverName
= XpDiGetDriverName(pRoot
->drawable
.pScreen
->myNum
,
1008 pContext
->printerName
);
1010 for(pDriver
= pPrintScreen
->drivers
;
1011 pDriver
!= (XpDriverPtr
)NULL
;
1012 pDriver
= pDriver
->next
)
1014 if(!strcmp(driverName
, pDriver
->name
))
1016 if(pDriver
->CreateContext
!= 0)
1017 pDriver
->CreateContext(pContext
);
1019 return BadImplementation
;
1024 if (client
->noClientException
!= Success
)
1025 return client
->noClientException
;
1031 * SetContext creates the calling client's contextClient resource,
1032 * and stashes the contextID in the client's devPrivate.
1035 ProcXpSetContext(ClientPtr client
)
1037 REQUEST(xPrintSetContextReq
);
1039 XpContextPtr pContext
;
1040 XpClientPtr pPrintClient
;
1041 int result
= Success
;
1043 REQUEST_AT_LEAST_SIZE(xPrintSetContextReq
);
1045 if((pContext
= client
->devPrivates
[XpClientPrivateIndex
].ptr
) !=
1049 * Erase this client's knowledge of its old context, if any.
1051 if((pPrintClient
= FindClient(pContext
, client
)) != (XpClientPtr
)NULL
)
1053 XpUnsetFontResFunc(client
);
1055 if(pPrintClient
->eventMask
== 0)
1056 FreeXpClient(pPrintClient
, TRUE
);
1059 client
->devPrivates
[XpClientPrivateIndex
].ptr
= (pointer
)NULL
;
1061 if(stuff
->printContext
== None
)
1065 * Check to see that the supplied XID is really a valid print context
1068 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
1069 stuff
->printContext
,
1072 == (XpContextPtr
)NULL
)
1074 client
->errorValue
= stuff
->printContext
;
1075 return XpErrorBase
+XPBadContext
;
1078 if((pPrintClient
= AcquireClient(pContext
, client
)) == (XpClientPtr
)NULL
)
1081 client
->devPrivates
[XpClientPrivateIndex
].ptr
= pContext
;
1083 XpSetFontResFunc(client
);
1085 if (client
->noClientException
!= Success
)
1086 return client
->noClientException
;
1092 XpGetPrintContext(ClientPtr client
)
1094 return (client
->devPrivates
[XpClientPrivateIndex
].ptr
);
1098 ProcXpGetContext(ClientPtr client
)
1100 /* REQUEST(xPrintGetContextReq); */
1101 xPrintGetContextReply rep
;
1103 XpContextPtr pContext
;
1107 REQUEST_SIZE_MATCH(xPrintGetContextReq
);
1109 if((pContext
= client
->devPrivates
[XpClientPrivateIndex
].ptr
) ==
1111 rep
.printContext
= None
;
1113 rep
.printContext
= pContext
->contextID
;
1116 rep
.sequenceNumber
= client
->sequence
;
1117 if (client
->swapped
) {
1118 swaps(&rep
.sequenceNumber
, n
);
1119 swapl(&rep
.length
, l
);
1120 swapl(&rep
.printContext
, l
);
1122 WriteToClient(client
, sz_xPrintGetContextReply
, (char *)&rep
);
1123 return client
->noClientException
;
1128 * DestroyContext frees the context associated with the calling client.
1129 * It operates by freeing the context resource ID, thus causing XpFreeContext
1133 ProcXpDestroyContext(ClientPtr client
)
1135 REQUEST(xPrintDestroyContextReq
);
1137 XpContextPtr pContext
;
1139 REQUEST_SIZE_MATCH(xPrintDestroyContextReq
);
1141 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
1142 stuff
->printContext
,
1145 == (XpContextPtr
)NULL
)
1147 client
->errorValue
= stuff
->printContext
;
1148 return XpErrorBase
+XPBadContext
;
1151 XpUnsetFontResFunc(client
);
1153 FreeResource(pContext
->contextID
, RT_NONE
);
1159 ProcXpGetContextScreen(ClientPtr client
)
1161 REQUEST(xPrintGetContextScreenReq
);
1162 xPrintGetContextScreenReply rep
;
1163 XpContextPtr pContext
;
1167 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
1168 stuff
->printContext
,
1171 == (XpContextPtr
)NULL
)
1172 return XpErrorBase
+XPBadContext
;
1175 rep
.sequenceNumber
= client
->sequence
;
1177 rep
.rootWindow
= WindowTable
[pContext
->screenNum
]->drawable
.id
;
1179 if (client
->swapped
) {
1180 swaps(&rep
.sequenceNumber
, n
);
1181 swapl(&rep
.length
, l
);
1182 swapl(&rep
.rootWindow
, l
);
1185 WriteToClient(client
, sz_xPrintGetContextScreenReply
, (char *)&rep
);
1186 return client
->noClientException
;
1190 * XpFreeContext is the routine called by dix:FreeResource when a context
1191 * resource ID is freed.
1192 * It checks to see if there's a partial job pending on the context, and
1193 * if so it calls the appropriate End procs with the cancel flag set.
1194 * It calls the driver's DestroyContext routine to allow the driver to clean
1195 * up any context-related memory or state.
1196 * It calls FreeXpClient to free all the
1197 * associated XpClientRecs and to set all the client->devPrivates to NULL.
1198 * It frees the printer name string, and frees the context
1202 XpFreeContext(pointer data
, XID id
)
1204 XpContextPtr pContext
= (XpContextPtr
)data
;
1206 /* Clean up any pending job on this context */
1207 if(pContext
->state
!= 0)
1209 if(pContext
->state
& PAGE_STARTED
)
1211 WindowPtr pWin
= (WindowPtr
)LookupIDByType(
1212 pContext
->pageWin
, RT_WINDOW
);
1213 XpPagePtr pPage
= (XpPagePtr
)LookupIDByType(
1214 pContext
->pageWin
, RTpage
);
1216 pContext
->funcs
.EndPage(pContext
, pWin
);
1217 SendXpNotify(pContext
, XPEndPageNotify
, TRUE
);
1218 pContext
->state
&= ~PAGE_STARTED
;
1220 pPage
->context
= (XpContextPtr
)NULL
;
1222 if((pContext
->state
& DOC_RAW_STARTED
) ||
1223 (pContext
->state
& DOC_COOKED_STARTED
))
1225 pContext
->funcs
.EndDoc(pContext
, TRUE
);
1226 SendXpNotify(pContext
, XPEndDocNotify
, TRUE
);
1227 pContext
->state
&= ~DOC_RAW_STARTED
;
1228 pContext
->state
&= ~DOC_COOKED_STARTED
;
1230 if(pContext
->funcs
.EndJob
!= 0)
1232 pContext
->funcs
.EndJob(pContext
, TRUE
);
1233 SendXpNotify(pContext
, XPEndJobNotify
, TRUE
);
1234 pContext
->state
&= ~JOB_STARTED
;
1235 pContext
->state
&= ~GET_DOC_DATA_STARTED
;
1240 * Tell the driver we're destroying the context
1241 * This allows the driver to free and ContextPrivate data
1243 if(pContext
->funcs
.DestroyContext
!= 0)
1244 pContext
->funcs
.DestroyContext(pContext
);
1246 /* Free up all the XpClientRecs */
1247 while(pContext
->clientHead
!= (XpClientPtr
)NULL
)
1249 FreeXpClient(pContext
->clientHead
, TRUE
);
1252 xfree(pContext
->printerName
);
1254 return Success
; /* ??? */
1258 * XpFreeClient is the routine called by dix:FreeResource when a RTclient
1259 * is freed. It simply calls the FreeXpClient routine to do the work.
1262 XpFreeClient(pointer data
, XID id
)
1264 FreeXpClient((XpClientPtr
)data
, TRUE
);
1270 * frees the ClientRec passed in, and sets the client->devPrivates to NULL
1271 * if the client->devPrivates points to the same context as the XpClient.
1272 * Called from XpFreeContext(from FreeResource), and
1273 * XpFreeClient. The boolean freeResource specifies whether or not to call
1274 * FreeResource for the XpClientRec's XID. We should free it except if we're
1275 * called from XpFreeClient (which is itself called from FreeResource for the
1276 * XpClientRec's XID).
1279 FreeXpClient(XpClientPtr pXpClient
, Bool freeResource
)
1281 XpClientPtr pCurrent
, pPrev
;
1282 XpContextPtr pContext
= pXpClient
->context
;
1285 * If we're freeing the clientRec associated with the context tied
1286 * to the client's devPrivates, then we need to clear the devPrivates.
1288 if(pXpClient
->client
->devPrivates
[XpClientPrivateIndex
].ptr
==
1291 pXpClient
->client
->devPrivates
[XpClientPrivateIndex
].ptr
=
1295 for(pPrev
= (XpClientPtr
)NULL
, pCurrent
= pContext
->clientHead
;
1296 pCurrent
!= (XpClientPtr
)NULL
;
1297 pCurrent
= pCurrent
->pNext
)
1299 if(pCurrent
== pXpClient
)
1301 if(freeResource
== TRUE
)
1302 FreeResource (pCurrent
->contextClientID
, RTclient
);
1304 if (pPrev
!= (XpClientPtr
)NULL
)
1305 pPrev
->pNext
= pCurrent
->pNext
;
1307 pContext
->clientHead
= pCurrent
->pNext
;
1317 * CreateXpClient takes a ClientPtr and returns a pointer to a
1318 * XpClientRec which it allocates. It also initializes the Rec,
1319 * including adding a resource on behalf of the client to enable the
1320 * freeing of the Rec when the client's connection is closed.
1323 CreateXpClient(ClientPtr client
)
1325 XpClientPtr pNewPrintClient
;
1328 if((pNewPrintClient
= (XpClientPtr
)xalloc(sizeof(XpClientRec
))) ==
1330 return (XpClientPtr
)NULL
;
1332 clientResource
= FakeClientID(client
->index
);
1333 if(!AddResource(clientResource
, RTclient
, (pointer
)pNewPrintClient
))
1335 xfree (pNewPrintClient
);
1336 return (XpClientPtr
)NULL
;
1339 pNewPrintClient
->pNext
= (XpClientPtr
)NULL
;
1340 pNewPrintClient
->client
= client
;
1341 pNewPrintClient
->context
= (XpContextPtr
)NULL
;
1342 pNewPrintClient
->eventMask
= 0;
1343 pNewPrintClient
->contextClientID
= clientResource
;
1345 return pNewPrintClient
;
1349 * XpFreePage is the routine called by dix:FreeResource to free the page
1350 * resource built with the same ID as a page window. It checks to see
1351 * if we're in the middle of a page, and if so calls the driver's EndPage
1352 * function with 'cancel' set TRUE. It frees the memory associated with
1353 * the page resource.
1356 XpFreePage(pointer data
, XID id
)
1358 XpPagePtr page
= (XpPagePtr
)data
;
1359 int result
= Success
;
1360 WindowPtr pWin
= (WindowPtr
)LookupIDByType(id
, RT_WINDOW
);
1362 /* Check to see if the window's being deleted in the middle of a page */
1363 if(page
->context
!= (XpContextPtr
)NULL
&&
1364 page
->context
->state
& PAGE_STARTED
)
1366 if(page
->context
->funcs
.EndPage
!= 0)
1367 result
= page
->context
->funcs
.EndPage(page
->context
, pWin
);
1368 SendXpNotify(page
->context
, XPEndPageNotify
, (int)TRUE
);
1369 page
->context
->pageWin
= 0; /* None, NULL??? XXX */
1377 * ContextPrivate machinery.
1378 * Context privates are intended for use by the drivers, allowing the
1379 * drivers to maintain context-specific data. The driver should free
1380 * the associated data at DestroyContext time.
1384 InitContextPrivates(XpContextPtr context
)
1388 register unsigned *sizes
;
1389 register unsigned size
;
1392 if (totalContextSize
== sizeof(XpContextRec
))
1393 ppriv
= (DevUnion
*)NULL
;
1395 ppriv
= (DevUnion
*)(context
+ 1);
1397 context
->devPrivates
= ppriv
;
1398 sizes
= contextPrivateSizes
;
1399 ptr
= (char *)(ppriv
+ contextPrivateLen
);
1400 for (i
= contextPrivateLen
; --i
>= 0; ppriv
++, sizes
++)
1402 if ( (size
= *sizes
) )
1404 ppriv
->ptr
= (pointer
)ptr
;
1408 ppriv
->ptr
= (pointer
)NULL
;
1413 ResetContextPrivates(void)
1415 contextPrivateCount
= 0;
1416 contextPrivateLen
= 0;
1417 xfree(contextPrivateSizes
);
1418 contextPrivateSizes
= (unsigned *)NULL
;
1419 totalContextSize
= sizeof(XpContextRec
);
1424 XpAllocateContextPrivateIndex(void)
1426 return contextPrivateCount
++;
1430 XpAllocateContextPrivate(int index
, unsigned amount
)
1434 if (index
>= contextPrivateLen
)
1437 nsizes
= (unsigned *)xrealloc(contextPrivateSizes
,
1438 (index
+ 1) * sizeof(unsigned));
1441 while (contextPrivateLen
<= index
)
1443 nsizes
[contextPrivateLen
++] = 0;
1444 totalContextSize
+= sizeof(DevUnion
);
1446 contextPrivateSizes
= nsizes
;
1448 oldamount
= contextPrivateSizes
[index
];
1449 if (amount
> oldamount
)
1451 contextPrivateSizes
[index
] = amount
;
1452 totalContextSize
+= (amount
- oldamount
);
1458 AcquireClient(XpContextPtr pContext
, ClientPtr client
)
1460 XpClientPtr pXpClient
;
1462 if((pXpClient
= FindClient(pContext
, client
)) != (XpClientPtr
)NULL
)
1465 if((pXpClient
= CreateXpClient(client
)) == (XpClientPtr
)NULL
)
1466 return (XpClientPtr
)NULL
;
1468 pXpClient
->context
= pContext
;
1469 pXpClient
->pNext
= pContext
->clientHead
;
1470 pContext
->clientHead
= pXpClient
;
1476 FindClient(XpContextPtr pContext
, ClientPtr client
)
1478 XpClientPtr pXpClient
;
1480 for(pXpClient
= pContext
->clientHead
; pXpClient
!= (XpClientPtr
)NULL
;
1481 pXpClient
= pXpClient
->pNext
)
1483 if(pXpClient
->client
== client
) return pXpClient
;
1485 return (XpClientPtr
)NULL
;
1489 /******************************************************************************
1491 * Start/End Functions: StartJob, EndJob, StartDoc, EndDoc, StartPage, EndPage
1493 ******************************************************************************/
1496 ProcXpStartJob(ClientPtr client
)
1498 REQUEST(xPrintStartJobReq
);
1499 XpContextPtr pContext
;
1500 int result
= Success
;
1502 REQUEST_SIZE_MATCH(xPrintStartJobReq
);
1504 /* Check to see that a context has been established by this client. */
1505 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1506 == (XpContextPtr
)NULL
)
1507 return XpErrorBase
+XPBadContext
;
1509 if(pContext
->state
!= 0)
1510 return XpErrorBase
+XPBadSequence
;
1512 if(stuff
->saveData
!= XPSpool
&& stuff
->saveData
!= XPGetData
)
1514 client
->errorValue
= stuff
->saveData
;
1518 if(pContext
->funcs
.StartJob
!= 0)
1519 result
= pContext
->funcs
.StartJob(pContext
,
1520 (stuff
->saveData
== XPGetData
)? TRUE
:FALSE
,
1523 return BadImplementation
;
1525 pContext
->state
= JOB_STARTED
;
1526 if(stuff
->saveData
== XPGetData
)
1527 pContext
->state
|= JOB_GET_DATA
;
1529 SendXpNotify(pContext
, XPStartJobNotify
, FALSE
);
1531 if (client
->noClientException
!= Success
)
1532 return client
->noClientException
;
1538 ProcXpEndJob(ClientPtr client
)
1540 REQUEST(xPrintEndJobReq
);
1541 int result
= Success
;
1542 XpContextPtr pContext
;
1544 REQUEST_SIZE_MATCH(xPrintEndJobReq
);
1546 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1547 == (XpContextPtr
)NULL
)
1548 return XpErrorBase
+XPBadSequence
;
1550 if(!(pContext
->state
& JOB_STARTED
))
1551 return XpErrorBase
+XPBadSequence
;
1553 /* Check for missing EndDoc */
1554 if((pContext
->state
& DOC_RAW_STARTED
) ||
1555 (pContext
->state
& DOC_COOKED_STARTED
))
1557 if(pContext
->state
& PAGE_STARTED
)
1559 WindowPtr pWin
= (WindowPtr
)LookupIDByType(
1560 pContext
->pageWin
, RT_WINDOW
);
1561 XpPagePtr pPage
= (XpPagePtr
)LookupIDByType(
1562 pContext
->pageWin
, RTpage
);
1564 if(stuff
->cancel
!= TRUE
)
1565 return XpErrorBase
+XPBadSequence
;
1567 if(pContext
->funcs
.EndPage
!= 0)
1568 result
= pContext
->funcs
.EndPage(pContext
, pWin
);
1570 return BadImplementation
;
1572 SendXpNotify(pContext
, XPEndPageNotify
, TRUE
);
1574 pContext
->state
&= ~PAGE_STARTED
;
1577 pPage
->context
= (XpContextPtr
)NULL
;
1579 if(result
!= Success
) return result
;
1582 if(pContext
->funcs
.EndDoc
!= 0)
1583 result
= pContext
->funcs
.EndDoc(pContext
, stuff
->cancel
);
1585 return BadImplementation
;
1587 SendXpNotify(pContext
, XPEndDocNotify
, stuff
->cancel
);
1590 if(pContext
->funcs
.EndJob
!= 0)
1591 result
= pContext
->funcs
.EndJob(pContext
, stuff
->cancel
);
1593 return BadImplementation
;
1595 pContext
->state
= 0;
1597 SendXpNotify(pContext
, XPEndJobNotify
, stuff
->cancel
);
1599 if (client
->noClientException
!= Success
)
1600 return client
->noClientException
;
1606 DoStartDoc(ClientPtr client
, XpStDocPtr c
)
1608 XpContextPtr pContext
= c
->pContext
;
1610 if(c
->pContext
->state
& JOB_GET_DATA
&&
1611 !(c
->pContext
->state
& GET_DOC_DATA_STARTED
))
1616 ClientSleep(client
, (ClientSleepProcPtr
)DoStartDoc
, (pointer
) c
);
1617 c
->pContext
->clientSlept
= client
;
1622 if(pContext
->funcs
.StartDoc
!= 0)
1623 (void) pContext
->funcs
.StartDoc(pContext
, c
->type
);
1626 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0,
1631 if(c
->type
== XPDocNormal
)
1632 pContext
->state
|= DOC_COOKED_STARTED
;
1634 pContext
->state
|= DOC_RAW_STARTED
;
1636 SendXpNotify(pContext
, XPStartDocNotify
, (int)FALSE
);
1643 ProcXpStartDoc(ClientPtr client
)
1645 REQUEST(xPrintStartDocReq
);
1646 int result
= Success
;
1647 XpContextPtr pContext
;
1650 REQUEST_SIZE_MATCH(xPrintStartDocReq
);
1652 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1653 == (XpContextPtr
)NULL
)
1654 return XpErrorBase
+XPBadSequence
;
1656 if(!(pContext
->state
& JOB_STARTED
) ||
1657 pContext
->state
& DOC_RAW_STARTED
||
1658 pContext
->state
& DOC_COOKED_STARTED
)
1659 return XpErrorBase
+XPBadSequence
;
1661 if(stuff
->type
!= XPDocNormal
&& stuff
->type
!= XPDocRaw
)
1663 client
->errorValue
= stuff
->type
;
1667 c
= (XpStDocPtr
)xalloc(sizeof(XpStDocRec
));
1668 c
->pContext
= pContext
;
1669 c
->type
= stuff
->type
;
1671 (void)DoStartDoc(client
, c
);
1673 if (client
->noClientException
!= Success
)
1674 return client
->noClientException
;
1680 ProcXpEndDoc(ClientPtr client
)
1682 REQUEST(xPrintEndDocReq
);
1683 XpContextPtr pContext
;
1684 int result
= Success
;
1686 REQUEST_SIZE_MATCH(xPrintEndDocReq
);
1688 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1689 == (XpContextPtr
)NULL
)
1690 return XpErrorBase
+XPBadSequence
;
1692 if(!(pContext
->state
& DOC_RAW_STARTED
) &&
1693 !(pContext
->state
& DOC_COOKED_STARTED
))
1694 return XpErrorBase
+XPBadSequence
;
1696 if(pContext
->state
& PAGE_STARTED
)
1698 if(stuff
->cancel
== TRUE
)
1700 WindowPtr pWin
= (WindowPtr
)LookupIDByType(
1701 pContext
->pageWin
, RT_WINDOW
);
1702 XpPagePtr pPage
= (XpPagePtr
)LookupIDByType(
1703 pContext
->pageWin
, RTpage
);
1705 if(pContext
->funcs
.EndPage
!= 0)
1706 result
= pContext
->funcs
.EndPage(pContext
, pWin
);
1708 return BadImplementation
;
1710 SendXpNotify(pContext
, XPEndPageNotify
, TRUE
);
1713 pPage
->context
= (XpContextPtr
)NULL
;
1716 return XpErrorBase
+XPBadSequence
;
1717 if(result
!= Success
)
1721 if(pContext
->funcs
.EndDoc
!= 0)
1722 result
= pContext
->funcs
.EndDoc(pContext
, stuff
->cancel
);
1724 return BadImplementation
;
1726 pContext
->state
&= ~DOC_RAW_STARTED
;
1727 pContext
->state
&= ~DOC_COOKED_STARTED
;
1729 SendXpNotify(pContext
, XPEndDocNotify
, stuff
->cancel
);
1731 if (client
->noClientException
!= Success
)
1732 return client
->noClientException
;
1742 WindowPtr pWin
= c
->pWin
;
1743 int result
= Success
;
1744 XpContextPtr pContext
= c
->pContext
;
1747 if(c
->pContext
->state
& JOB_GET_DATA
&&
1748 !(c
->pContext
->state
& GET_DOC_DATA_STARTED
))
1753 ClientSleep(client
, (ClientSleepProcPtr
)DoStartPage
, (pointer
) c
);
1754 c
->pContext
->clientSlept
= client
;
1759 if(!(pContext
->state
& DOC_COOKED_STARTED
))
1761 /* Implied StartDoc if it was omitted */
1762 if(pContext
->funcs
.StartDoc
!= 0)
1763 result
= pContext
->funcs
.StartDoc(pContext
, XPDocNormal
);
1766 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0,
1771 if(result
!= Success
)
1773 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0, result
);
1777 pContext
->state
|= DOC_COOKED_STARTED
;
1778 SendXpNotify(pContext
, XPStartDocNotify
, (int)FALSE
);
1781 /* ensure the window's not already being used as a page */
1782 if((pPage
= (XpPagePtr
)LookupIDByType(c
->pWin
->drawable
.id
, RTpage
)) !=
1785 if(pPage
->context
!= (XpContextPtr
)NULL
)
1787 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0,
1794 if((pPage
= (XpPagePtr
)xalloc(sizeof(XpPageRec
))) == (XpPagePtr
)NULL
)
1796 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0,
1800 if(AddResource(c
->pWin
->drawable
.id
, RTpage
, pPage
) == FALSE
)
1803 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0,
1809 pPage
->context
= pContext
;
1810 pContext
->pageWin
= c
->pWin
->drawable
.id
;
1812 if(pContext
->funcs
.StartPage
!= 0)
1813 result
= pContext
->funcs
.StartPage(pContext
, pWin
);
1816 SendErrorToClient(client
, XpReqCode
, X_PrintStartPage
, 0,
1821 pContext
->state
|= PAGE_STARTED
;
1823 (void)MapWindow(pWin
, client
);
1825 SendXpNotify(pContext
, XPStartPageNotify
, (int)FALSE
);
1831 ProcXpStartPage(ClientPtr client
)
1833 REQUEST(xPrintStartPageReq
);
1835 int result
= Success
;
1836 XpContextPtr pContext
;
1839 REQUEST_SIZE_MATCH(xPrintStartPageReq
);
1841 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1842 == (XpContextPtr
)NULL
)
1843 return XpErrorBase
+XPBadSequence
;
1845 if(!(pContext
->state
& JOB_STARTED
))
1846 return XpErrorBase
+XPBadSequence
;
1848 /* can't have pages in a raw documented */
1849 if(pContext
->state
& DOC_RAW_STARTED
)
1850 return XpErrorBase
+XPBadSequence
;
1852 if(pContext
->state
& PAGE_STARTED
)
1853 return XpErrorBase
+XPBadSequence
;
1855 result
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixWriteAccess
);
1856 if (result
!= Success
)
1858 if (pWin
->drawable
.pScreen
->myNum
!= pContext
->screenNum
)
1861 if((c
= (XpStPagePtr
)xalloc(sizeof(XpStPageRec
))) == (XpStPagePtr
)NULL
)
1863 c
->pContext
= pContext
;
1867 (void)DoStartPage(client
, c
);
1869 if (client
->noClientException
!= Success
)
1870 return client
->noClientException
;
1876 ProcXpEndPage(ClientPtr client
)
1878 REQUEST(xPrintEndPageReq
);
1879 int result
= Success
;
1880 XpContextPtr pContext
;
1884 REQUEST_SIZE_MATCH(xPrintEndPageReq
);
1886 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1887 == (XpContextPtr
)NULL
)
1888 return XpErrorBase
+XPBadSequence
;
1890 if(!(pContext
->state
& PAGE_STARTED
))
1891 return XpErrorBase
+XPBadSequence
;
1893 pWin
= (WindowPtr
)LookupIDByType(pContext
->pageWin
, RT_WINDOW
);
1895 /* Call the ddx's EndPage proc. */
1896 if(pContext
->funcs
.EndPage
!= 0)
1897 result
= pContext
->funcs
.EndPage(pContext
, pWin
);
1899 return BadImplementation
;
1901 if((page
= (XpPagePtr
)LookupIDByType(pContext
->pageWin
, RTpage
)) !=
1903 page
->context
= (XpContextPtr
)NULL
;
1905 pContext
->state
&= ~PAGE_STARTED
;
1906 pContext
->pageWin
= 0; /* None, NULL??? XXX */
1908 (void)UnmapWindow(pWin
, FALSE
);
1910 SendXpNotify(pContext
, XPEndPageNotify
, stuff
->cancel
);
1912 if (client
->noClientException
!= Success
)
1913 return client
->noClientException
;
1918 /*******************************************************************************
1920 * Document Data Functions: PutDocumentData, GetDocumentData
1922 ******************************************************************************/
1925 ProcXpPutDocumentData(ClientPtr client
)
1927 REQUEST(xPrintPutDocumentDataReq
);
1928 XpContextPtr pContext
;
1930 int result
= Success
;
1932 char *pData
, *pDoc_fmt
, *pOptions
;
1934 REQUEST_AT_LEAST_SIZE(xPrintPutDocumentDataReq
);
1936 if((pContext
= (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
)
1937 == (XpContextPtr
)NULL
)
1938 return XpErrorBase
+XPBadSequence
;
1940 if(!(pContext
->state
& DOC_RAW_STARTED
) &&
1941 !(pContext
->state
& DOC_COOKED_STARTED
))
1942 return XpErrorBase
+XPBadSequence
;
1944 if (stuff
->drawable
) {
1945 if (pContext
->state
& DOC_RAW_STARTED
)
1947 result
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0,
1949 if (result
!= Success
)
1951 if (pDraw
->pScreen
->myNum
!= pContext
->screenNum
)
1954 if (pContext
->state
& DOC_COOKED_STARTED
)
1959 pData
= (char *)(&stuff
[1]);
1961 totalSize
= (stuff
->len_data
+ 3) >> 2;
1962 pDoc_fmt
= pData
+ (totalSize
<< 2);
1964 totalSize
+= (stuff
->len_fmt
+ 3) >> 2;
1965 pOptions
= pData
+ (totalSize
<< 2);
1967 totalSize
+= (stuff
->len_options
+ 3) >> 2;
1968 if((totalSize
+ (sz_xPrintPutDocumentDataReq
>> 2)) != client
->req_len
)
1971 if(pContext
->funcs
.PutDocumentData
!= 0)
1973 result
= (*pContext
->funcs
.PutDocumentData
)(pContext
, pDraw
,
1974 pData
, stuff
->len_data
,
1975 pDoc_fmt
, stuff
->len_fmt
,
1976 pOptions
, stuff
->len_options
,
1980 return BadImplementation
;
1982 if (client
->noClientException
!= Success
)
1983 return client
->noClientException
;
1989 ProcXpGetDocumentData(ClientPtr client
)
1991 REQUEST(xPrintGetDocumentDataReq
);
1992 xPrintGetDocumentDataReply rep
;
1993 XpContextPtr pContext
;
1994 int result
= Success
;
1996 REQUEST_SIZE_MATCH(xPrintGetDocumentDataReq
);
1998 if((pContext
= (XpContextPtr
)SecurityLookupIDByType(client
,
1999 stuff
->printContext
,
2002 == (XpContextPtr
)NULL
)
2004 client
->errorValue
= stuff
->printContext
;
2005 return XpErrorBase
+XPBadContext
;
2008 if(pContext
->funcs
.GetDocumentData
== 0)
2009 return BadImplementation
;
2011 if(!(pContext
->state
& JOB_GET_DATA
) ||
2012 pContext
->state
& GET_DOC_DATA_STARTED
)
2013 return XpErrorBase
+XPBadSequence
;
2015 if(stuff
->maxBufferSize
<= 0)
2017 client
->errorValue
= stuff
->maxBufferSize
;
2018 return BadValue
; /* gotta have a positive buffer size */
2021 result
= (*pContext
->funcs
.GetDocumentData
)(pContext
, client
,
2022 stuff
->maxBufferSize
);
2023 if(result
!= Success
)
2026 rep
.sequenceNumber
= client
->sequence
;
2030 rep
.finishedFlag
= TRUE
;
2031 if (client
->swapped
) {
2035 swaps(&rep
.sequenceNumber
, n
);
2036 swapl(&rep
.statusCode
, l
); /* XXX Why are these longs??? */
2037 swapl(&rep
.finishedFlag
, l
); /* XXX Why are these longs??? */
2039 (void)WriteToClient(client
,sz_xPrintGetDocumentDataReply
,(char *)&rep
);
2042 pContext
->state
|= GET_DOC_DATA_STARTED
;
2044 if(pContext
->clientSlept
!= (ClientPtr
)NULL
)
2046 ClientSignal(pContext
->clientSlept
);
2047 ClientWakeup(pContext
->clientSlept
);
2048 pContext
->clientSlept
= (ClientPtr
)NULL
;
2054 /*******************************************************************************
2056 * Attribute requests: GetAttributes, SetAttributes, GetOneAttribute
2058 ******************************************************************************/
2061 ProcXpGetAttributes(ClientPtr client
)
2063 REQUEST(xPrintGetAttributesReq
);
2064 XpContextPtr pContext
;
2066 xPrintGetAttributesReply
*pRep
;
2070 REQUEST_SIZE_MATCH(xPrintGetAttributesReq
);
2072 if(stuff
->type
< XPJobAttr
|| stuff
->type
> XPServerAttr
)
2074 client
->errorValue
= stuff
->type
;
2078 if(stuff
->type
!= XPServerAttr
)
2080 if((pContext
= (XpContextPtr
)SecurityLookupIDByType(
2082 stuff
->printContext
,
2085 == (XpContextPtr
)NULL
)
2087 client
->errorValue
= stuff
->printContext
;
2088 return XpErrorBase
+XPBadContext
;
2091 if(pContext
->funcs
.GetAttributes
== 0)
2092 return BadImplementation
;
2093 if((attrs
= (*pContext
->funcs
.GetAttributes
)(pContext
, stuff
->type
)) ==
2099 if((attrs
= XpGetAttributes((XpContextPtr
)NULL
, XPServerAttr
)) ==
2104 totalSize
= sz_xPrintGetAttributesReply
+ QUADPAD(strlen(attrs
));
2105 if((pRep
= (xPrintGetAttributesReply
*)malloc(totalSize
)) ==
2106 (xPrintGetAttributesReply
*)NULL
)
2109 pRep
->type
= X_Reply
;
2110 pRep
->length
= (totalSize
- sz_xPrintGetAttributesReply
) >> 2;
2111 pRep
->sequenceNumber
= client
->sequence
;
2112 pRep
->stringLen
= strlen(attrs
);
2114 if (client
->swapped
) {
2115 swaps(&pRep
->sequenceNumber
, n
);
2116 swapl(&pRep
->length
, l
);
2117 swapl(&pRep
->stringLen
, l
);
2120 strncpy((char*)(pRep
+ 1), attrs
, strlen(attrs
));
2123 WriteToClient(client
, totalSize
, (char *)pRep
);
2127 return client
->noClientException
;
2131 ProcXpSetAttributes(ClientPtr client
)
2133 REQUEST(xPrintSetAttributesReq
);
2134 int result
= Success
;
2135 XpContextPtr pContext
;
2138 REQUEST_AT_LEAST_SIZE(xPrintSetAttributesReq
);
2140 if(stuff
->type
< XPJobAttr
|| stuff
->type
> XPServerAttr
)
2142 client
->errorValue
= stuff
->type
;
2147 * Disallow changing of read-only attribute pools
2149 if(stuff
->type
== XPPrinterAttr
|| stuff
->type
== XPServerAttr
)
2152 if((pContext
= (XpContextPtr
)SecurityLookupIDByType(
2154 stuff
->printContext
,
2157 == (XpContextPtr
)NULL
)
2159 client
->errorValue
= stuff
->printContext
;
2160 return XpErrorBase
+XPBadContext
;
2163 if(pContext
->funcs
.SetAttributes
== 0)
2164 return BadImplementation
;
2167 * Check for attributes being set after their relevant phase
2168 * has already begun (e.g. Job attributes set after StartJob).
2170 if((pContext
->state
& JOB_STARTED
) && stuff
->type
== XPJobAttr
)
2171 return XpErrorBase
+XPBadSequence
;
2172 if(((pContext
->state
& DOC_RAW_STARTED
) ||
2173 (pContext
->state
& DOC_COOKED_STARTED
)) && stuff
->type
== XPDocAttr
)
2174 return XpErrorBase
+XPBadSequence
;
2175 if((pContext
->state
& PAGE_STARTED
) && stuff
->type
== XPPageAttr
)
2176 return XpErrorBase
+XPBadSequence
;
2178 if((attr
= (char *)malloc(stuff
->stringLen
+ 1)) == (char *)NULL
)
2181 strncpy(attr
, (char *)(stuff
+ 1), stuff
->stringLen
);
2182 attr
[stuff
->stringLen
] = (char)'\0';
2184 if(stuff
->rule
== XPAttrReplace
)
2185 (*pContext
->funcs
.SetAttributes
)(pContext
, stuff
->type
, attr
);
2186 else if(stuff
->rule
== XPAttrMerge
)
2187 (*pContext
->funcs
.AugmentAttributes
)(pContext
, stuff
->type
, attr
);
2190 client
->errorValue
= stuff
->rule
;
2196 SendAttributeNotify(pContext
, stuff
->type
);
2202 ProcXpGetOneAttribute(ClientPtr client
)
2204 REQUEST(xPrintGetOneAttributeReq
);
2205 XpContextPtr pContext
;
2206 char *value
, *attrName
;
2207 xPrintGetOneAttributeReply
*pRep
;
2212 REQUEST_AT_LEAST_SIZE(xPrintGetOneAttributeReq
);
2214 totalSize
= ((sz_xPrintGetOneAttributeReq
) >> 2) +
2215 ((stuff
->nameLen
+ 3) >> 2);
2216 if(totalSize
!= client
->req_len
)
2219 if(stuff
->type
< XPJobAttr
|| stuff
->type
> XPServerAttr
)
2221 client
->errorValue
= stuff
->type
;
2225 if((attrName
= (char *)malloc(stuff
->nameLen
+ 1)) == (char *)NULL
)
2227 strncpy(attrName
, (char *)(stuff
+1), stuff
->nameLen
);
2228 attrName
[stuff
->nameLen
] = (char)'\0';
2230 if(stuff
->type
!= XPServerAttr
)
2232 if((pContext
= (XpContextPtr
)SecurityLookupIDByType(
2234 stuff
->printContext
,
2237 == (XpContextPtr
)NULL
)
2239 client
->errorValue
= stuff
->printContext
;
2240 return XpErrorBase
+XPBadContext
;
2243 if(pContext
->funcs
.GetOneAttribute
== 0)
2244 return BadImplementation
;
2245 if((value
= (*pContext
->funcs
.GetOneAttribute
)(pContext
, stuff
->type
,
2246 attrName
)) == (char *)NULL
)
2251 if((value
= XpGetOneAttribute((XpContextPtr
)NULL
, XPServerAttr
,
2252 attrName
)) == (char *)NULL
)
2258 totalSize
= sz_xPrintGetOneAttributeReply
+ QUADPAD(strlen(value
));
2259 if((pRep
= (xPrintGetOneAttributeReply
*)malloc(totalSize
)) ==
2260 (xPrintGetOneAttributeReply
*)NULL
)
2263 pRep
->type
= X_Reply
;
2264 pRep
->length
= (totalSize
- sz_xPrintGetOneAttributeReply
) >> 2;
2265 pRep
->sequenceNumber
= client
->sequence
;
2266 pRep
->valueLen
= strlen(value
);
2268 if (client
->swapped
) {
2269 swaps(&pRep
->sequenceNumber
, n
);
2270 swapl(&pRep
->length
, l
);
2271 swapl(&pRep
->valueLen
, l
);
2274 strncpy((char*)(pRep
+ 1), value
, strlen(value
));
2276 WriteToClient(client
, totalSize
, (char *)pRep
);
2280 return client
->noClientException
;
2283 /*******************************************************************************
2285 * Print Event requests: SelectInput InputSelected, SendXpNotify
2287 ******************************************************************************/
2291 ProcXpSelectInput(ClientPtr client
)
2293 REQUEST(xPrintSelectInputReq
);
2294 int result
= Success
;
2295 XpContextPtr pContext
;
2296 XpClientPtr pPrintClient
;
2298 REQUEST_SIZE_MATCH(xPrintSelectInputReq
);
2301 * Check to see that the supplied XID is really a valid print context
2304 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
2305 stuff
->printContext
,
2308 == (XpContextPtr
)NULL
)
2310 client
->errorValue
= stuff
->printContext
;
2311 return XpErrorBase
+XPBadContext
;
2314 if(stuff
->eventMask
& ~allEvents
)
2316 client
->errorValue
= stuff
->eventMask
;
2317 return BadValue
; /* bogus event mask bits */
2320 if((pPrintClient
= AcquireClient(pContext
, client
)) == (XpClientPtr
)NULL
)
2323 pPrintClient
->eventMask
= stuff
->eventMask
;
2329 ProcXpInputSelected(ClientPtr client
)
2331 REQUEST(xPrintInputSelectedReq
);
2332 xPrintInputSelectedReply rep
;
2335 XpClientPtr pXpClient
;
2336 XpContextPtr pContext
;
2338 REQUEST_SIZE_MATCH(xPrintInputSelectedReq
);
2340 if((pContext
=(XpContextPtr
)SecurityLookupIDByType(client
,
2341 stuff
->printContext
,
2344 == (XpContextPtr
)NULL
)
2346 client
->errorValue
= stuff
->printContext
;
2347 return XpErrorBase
+XPBadContext
;
2350 pXpClient
= FindClient(pContext
, client
);
2354 rep
.sequenceNumber
= client
->sequence
;
2355 rep
.eventMask
= (pXpClient
!= (XpClientPtr
)NULL
)? pXpClient
->eventMask
: 0;
2356 rep
.allEventsMask
= GetAllEventMasks(pContext
);
2358 if (client
->swapped
) {
2359 swaps(&rep
.sequenceNumber
, n
);
2360 swapl(&rep
.length
, l
);
2361 swapl(&rep
.eventMask
, l
);
2362 swapl(&rep
.allEventsMask
, l
);
2365 WriteToClient(client
, sz_xPrintInputSelectedReply
, (char *)&rep
);
2366 return client
->noClientException
;
2370 SendAttributeNotify(XpContextPtr pContext
, int which
)
2372 XpClientPtr pXpClient
;
2373 xPrintAttributeEvent ae
;
2376 pXpClient
= pContext
->clientHead
;
2377 if(pXpClient
== (XpClientPtr
)NULL
)
2378 return; /* Nobody's interested in the events (or this context). */
2380 for (pXpClient
= pContext
->clientHead
;
2381 pXpClient
!= (XpClientPtr
)NULL
;
2382 pXpClient
= pXpClient
->pNext
)
2384 client
= pXpClient
->client
;
2385 if (client
== serverClient
|| client
->clientGone
||
2386 !(pXpClient
->eventMask
& XPAttributeMask
))
2388 ae
.type
= XPAttributeNotify
+ XpEventBase
;
2390 ae
.printContext
= pContext
->contextID
;
2391 ae
.sequenceNumber
= client
->sequence
;
2392 WriteEventsToClient (client
, 1, (xEvent
*) &ae
);
2397 SendXpNotify(XpContextPtr pContext
, int which
, int val
)
2399 XpClientPtr pXpClient
;
2400 xPrintPrintEvent pe
;
2403 pXpClient
= pContext
->clientHead
;
2404 if(pXpClient
== (XpClientPtr
)NULL
)
2405 return; /* Nobody's interested in the events (or this context). */
2407 for (pXpClient
= pContext
->clientHead
;
2408 pXpClient
!= (XpClientPtr
)NULL
;
2409 pXpClient
= pXpClient
->pNext
)
2411 client
= pXpClient
->client
;
2412 if (client
== serverClient
|| client
->clientGone
||
2413 !(pXpClient
->eventMask
& XPPrintMask
))
2415 pe
.type
= XPPrintNotify
+ XpEventBase
;
2417 pe
.printContext
= pContext
->contextID
;
2418 pe
.cancel
= (Bool
)val
;
2419 pe
.sequenceNumber
= client
->sequence
;
2420 WriteEventsToClient (client
, 1, (xEvent
*) &pe
);
2425 GetAllEventMasks(XpContextPtr pContext
)
2427 XpClientPtr pPrintClient
;
2428 CARD32 totalMask
= (CARD32
)0;
2430 for (pPrintClient
= pContext
->clientHead
;
2431 pPrintClient
!= (XpClientPtr
)NULL
;
2432 pPrintClient
= pPrintClient
->pNext
)
2434 totalMask
|= pPrintClient
->eventMask
;
2440 * XpContextOfClient - returns the XpContextPtr to the context
2441 * associated with the specified client, or NULL if the client
2442 * does not currently have a context set.
2445 XpContextOfClient(ClientPtr client
)
2447 return (XpContextPtr
)client
->devPrivates
[XpClientPrivateIndex
].ptr
;
2451 /*******************************************************************************
2453 * Swap-request functions
2455 ******************************************************************************/
2458 SProcXpCreateContext(ClientPtr client
)
2463 REQUEST(xPrintCreateContextReq
);
2465 swaps(&stuff
->length
, i
);
2466 swapl(&stuff
->contextID
, n
);
2467 swapl(&stuff
->printerNameLen
, n
);
2468 swapl(&stuff
->localeLen
, n
);
2469 return ProcXpCreateContext(client
);
2473 SProcXpGetPrinterList(ClientPtr client
)
2478 REQUEST(xPrintGetPrinterListReq
);
2480 swaps(&stuff
->length
, i
);
2481 swapl(&stuff
->printerNameLen
, n
);
2482 swapl(&stuff
->localeLen
, n
);
2483 return ProcXpGetPrinterList(client
);
2487 SProcXpRehashPrinterList(ClientPtr client
)
2491 REQUEST(xPrintRehashPrinterListReq
);
2492 swaps(&stuff
->length
, i
);
2493 return ProcXpRehashPrinterList(client
);
2497 SProcXpSetContext(ClientPtr client
)
2501 REQUEST(xPrintSetContextReq
);
2502 swaps(&stuff
->length
, i
);
2503 swapl(&stuff
->printContext
, i
);
2504 return ProcXpSetContext(client
);
2508 SProcXpGetContext(ClientPtr client
)
2512 REQUEST(xPrintGetContextReq
);
2513 swaps(&stuff
->length
, i
);
2514 return ProcXpGetContext(client
);
2518 SProcXpDestroyContext(ClientPtr client
)
2523 REQUEST(xPrintDestroyContextReq
);
2524 swaps(&stuff
->length
, i
);
2525 swapl(&stuff
->printContext
, n
);
2526 return ProcXpDestroyContext(client
);
2530 SProcXpGetContextScreen(ClientPtr client
)
2535 REQUEST(xPrintGetContextScreenReq
);
2536 swaps(&stuff
->length
, i
);
2537 swapl(&stuff
->printContext
, n
);
2538 return ProcXpGetContextScreen(client
);
2542 SProcXpInputSelected(ClientPtr client
)
2547 REQUEST(xPrintInputSelectedReq
);
2548 swaps(&stuff
->length
, i
);
2549 swapl(&stuff
->printContext
, n
);
2550 return ProcXpInputSelected(client
);
2554 SProcXpStartJob(ClientPtr client
)
2558 REQUEST(xPrintStartJobReq
);
2559 swaps(&stuff
->length
, i
);
2560 return ProcXpStartJob(client
);
2564 SProcXpEndJob(ClientPtr client
)
2568 REQUEST(xPrintEndJobReq
);
2569 swaps(&stuff
->length
, i
);
2570 return ProcXpEndJob(client
);
2574 SProcXpStartDoc(ClientPtr client
)
2578 REQUEST(xPrintStartDocReq
);
2579 swaps(&stuff
->length
, i
);
2580 return ProcXpStartDoc(client
);
2584 SProcXpEndDoc(ClientPtr client
)
2588 REQUEST(xPrintEndDocReq
);
2589 swaps(&stuff
->length
, i
);
2590 return ProcXpEndDoc(client
);
2594 SProcXpStartPage(ClientPtr client
)
2599 REQUEST(xPrintStartPageReq
);
2600 swaps(&stuff
->length
, i
);
2601 swapl(&stuff
->window
, n
);
2602 return ProcXpStartPage(client
);
2606 SProcXpEndPage(ClientPtr client
)
2610 REQUEST(xPrintEndPageReq
);
2611 swaps(&stuff
->length
, i
);
2612 return ProcXpEndPage(client
);
2616 SProcXpPutDocumentData(ClientPtr client
)
2621 REQUEST(xPrintPutDocumentDataReq
);
2622 swaps(&stuff
->length
, i
);
2623 swapl(&stuff
->drawable
, n
);
2624 swapl(&stuff
->len_data
, n
);
2625 swaps(&stuff
->len_fmt
, i
);
2626 swaps(&stuff
->len_options
, i
);
2627 return ProcXpPutDocumentData(client
);
2631 SProcXpGetDocumentData(ClientPtr client
)
2636 REQUEST(xPrintGetDocumentDataReq
);
2637 swaps(&stuff
->length
, i
);
2638 swapl(&stuff
->printContext
, n
);
2639 swapl(&stuff
->maxBufferSize
, n
);
2640 return ProcXpGetDocumentData(client
);
2644 SProcXpGetAttributes(ClientPtr client
)
2649 REQUEST(xPrintGetAttributesReq
);
2650 swaps(&stuff
->length
, i
);
2651 swapl(&stuff
->printContext
, n
);
2652 return ProcXpGetAttributes(client
);
2656 SProcXpSetAttributes(ClientPtr client
)
2661 REQUEST(xPrintSetAttributesReq
);
2662 swaps(&stuff
->length
, i
);
2663 swapl(&stuff
->printContext
, n
);
2664 swapl(&stuff
->stringLen
, n
);
2665 return ProcXpSetAttributes(client
);
2669 SProcXpGetOneAttribute(ClientPtr client
)
2674 REQUEST(xPrintGetOneAttributeReq
);
2675 swaps(&stuff
->length
, i
);
2676 swapl(&stuff
->printContext
, n
);
2677 swapl(&stuff
->nameLen
, n
);
2678 return ProcXpGetOneAttribute(client
);
2682 SProcXpSelectInput(ClientPtr client
)
2687 REQUEST(xPrintSelectInputReq
);
2688 swaps(&stuff
->length
, i
);
2689 swapl(&stuff
->eventMask
, n
);
2690 swapl(&stuff
->printContext
, n
);
2691 return ProcXpSelectInput(client
);
2695 SProcXpGetPageDimensions(ClientPtr client
)
2700 REQUEST(xPrintGetPageDimensionsReq
);
2701 swaps(&stuff
->length
, i
);
2702 swapl(&stuff
->printContext
, n
);
2703 return ProcXpGetPageDimensions(client
);
2707 SProcXpSetImageResolution(ClientPtr client
)
2712 REQUEST(xPrintSetImageResolutionReq
);
2713 swaps(&stuff
->length
, i
);
2714 swapl(&stuff
->printContext
, n
);
2715 swaps(&stuff
->imageRes
, i
);
2716 return ProcXpSetImageResolution(client
);
2720 SProcXpGetImageResolution(ClientPtr client
)
2725 REQUEST(xPrintGetImageResolutionReq
);
2726 swaps(&stuff
->length
, i
);
2727 swapl(&stuff
->printContext
, n
);
2728 return ProcXpGetImageResolution(client
);
2732 SwapXpNotifyEvent(xPrintPrintEvent
*src
, xPrintPrintEvent
*dst
)
2735 * Swap the sequence number and context fields.
2737 cpswaps(src
->sequenceNumber
, dst
->sequenceNumber
);
2738 cpswapl(src
->printContext
, dst
->printContext
);
2741 * Copy the byte-long fields.
2743 dst
->type
= src
->type
;
2744 dst
->detail
= src
->detail
;
2745 dst
->cancel
= src
->cancel
;
2749 SwapXpAttributeEvent(xPrintAttributeEvent
*src
, xPrintAttributeEvent
*dst
)
2752 * Swap the sequence number and context fields.
2754 cpswaps(src
->sequenceNumber
, dst
->sequenceNumber
);
2755 cpswapl(src
->printContext
, dst
->printContext
);
2758 * Copy the byte-long fields.
2760 dst
->type
= src
->type
;
2761 dst
->detail
= src
->detail
;