1 /* $XConsortium: xprint.c /main/3 1996/11/23 17:11:55 rws $ */
2 /*
3 (c) Copyright 1996 Hewlett-Packard Company
4 (c) Copyright 1996 International Business Machines Corp.
5 (c) Copyright 1996 Sun Microsystems, Inc.
6 (c) Copyright 1996 Novell, Inc.
7 (c) Copyright 1996 Digital Equipment Corp.
8 (c) Copyright 1996 Fujitsu Limited
9 (c) Copyright 1996 Hitachi, Ltd.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 Except as contained in this notice, the names of the copyright holders shall
29 not be used in advertising or otherwise to promote the sale, use or other
30 dealings in this Software without prior written authorization from said
31 copyright holders.
32 */
33 /*******************************************************************
34 **
35 ** *********************************************************
36 ** *
37 ** * File: xprint.c
38 ** *
39 ** * Copyright: Copyright 1993, 1995 Hewlett-Packard Company
40 ** *
41 ** * Copyright 1989 by The Massachusetts Institute of Technology
42 ** *
43 ** * Permission to use, copy, modify, and distribute this
44 ** * software and its documentation for any purpose and without
45 ** * fee is hereby granted, provided that the above copyright
46 ** * notice appear in all copies and that both that copyright
47 ** * notice and this permission notice appear in supporting
48 ** * documentation, and that the name of MIT not be used in
49 ** * advertising or publicity pertaining to distribution of the
50 ** * software without specific prior written permission.
51 ** * M.I.T. makes no representation about the suitability of
52 ** * this software for any purpose. It is provided "as is"
53 ** * without any express or implied warranty.
54 ** *
55 ** * MIT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
56 ** * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
57 ** * NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MIT BE LI-
58 ** * ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
59 ** * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
60 ** * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
61 ** * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
62 ** * THE USE OR PERFORMANCE OF THIS SOFTWARE.
63 ** *
64 ** *********************************************************
65 **
66 ********************************************************************/
67 /* $XFree86: xc/programs/Xserver/Xext/xprint.c,v 1.4 1997/01/02 04:05:05 dawes Exp $ */
68
69 #include "X.h"
70 #define NEED_EVENTS
71 #include "Xproto.h"
72 #undef NEED_EVENTS
73 #include "misc.h"
74 #include "windowstr.h"
75 #include "scrnintstr.h"
76 #include "pixmapstr.h"
77 #include "extnsionst.h"
78 #include "dixstruct.h"
79 #include "Xatom.h"
80 #define _XP_PRINT_SERVER_
81 #include "Print.h"
82 #include "Printstr.h"
83 #undef _XP_PRINT_SERVER_
84 #include "../Xprint/DiPrint.h"
85
86 extern WindowPtr *WindowTable; /* declared in dix:globals.c */
87
88 extern WindowPtr XpDiValidatePrinter();
89 extern char *XpDiGetDriverName();
90 extern char *XpGetAttributes();
91 extern char *XpGetOneAttribute();
92 extern int XpRehashPrinterList();
93 extern void XpSetFontResFunc();
94
95 static void XpResetProc();
96
97 static int ProcXpDispatch();
98 static int ProcXpSwappedDispatch();
99
100 static int ProcXpQueryVersion();
101 static int ProcXpGetPrinterList();
102 static int ProcXpCreateContext();
103 static int ProcXpSetContext();
104 static int ProcXpGetContext();
105 static int ProcXpDestroyContext();
106 static int ProcXpGetContextScreen();
107 static int ProcXpStartJob();
108 static int ProcXpEndJob();
109 static int ProcXpStartDoc();
110 static int ProcXpEndDoc();
111 static int ProcXpStartPage();
112 static int ProcXpEndPage();
113 static int ProcXpSelectInput();
114 static int ProcXpInputSelected();
115 static int ProcXpPutDocumentData();
116 static int ProcXpGetDocumentData();
117 static int ProcXpGetAttributes();
118 static int ProcXpGetOneAttribute();
119 static int ProcXpSetAttributes();
120 static int ProcXpRehashPrinterList();
121 static int ProcXpQueryScreens();
122 static int ProcXpGetPageDimensions();
123 static int ProcXpSetImageResolution();
124 static int ProcXpGetImageResolution();
125
126 static void SwapXpNotifyEvent();
127 static void SwapXpAttributeEvent();
128
129 static int SProcXpGetPrinterList();
130 static int SProcXpCreateContext();
131 static int SProcXpSetContext();
132 static int SProcXpGetContext();
133 static int SProcXpDestroyContext();
134 static int SProcXpGetContextScreen();
135 static int SProcXpStartJob();
136 static int SProcXpEndJob();
137 static int SProcXpStartDoc();
138 static int SProcXpEndDoc();
139 static int SProcXpStartPage();
140 static int SProcXpEndPage();
141 static int SProcXpSelectInput();
142 static int SProcXpInputSelected();
143 static int SProcXpPutDocumentData();
144 static int SProcXpGetDocumentData();
145 static int SProcXpGetAttributes();
146 static int SProcXpGetOneAttribute();
147 static int SProcXpSetAttributes();
148 static int SProcXpRehashPrinterList();
149 static int SProcXpGetPageDimensions();
150 static int SProcXpSetImageResolution();
151 static int SProcXpGetImageResolution();
152
153 static void SendXpNotify();
154 static void SendAttributeNotify();
155 static int XpFreeClient();
156 static int XpFreeContext();
157 static int XpFreePage();
158 static int XpFreeEvents();
159 static Bool XpCloseScreen();
160 static CARD32 GetAllEventMasks();
161 static struct _XpEvent *AddEventRec();
162 static void DeleteEventRec();
163 static struct _XpEvent *FindEventRec();
164 static struct _XpClient *CreateXpClient();
165 static void FreeXpClient();
166 static void InitContextPrivates();
167 static void ResetContextPrivates();
168 static struct _XpClient *FindClient();
169 static struct _XpClient *AcquireClient();
170
171 typedef struct _driver {
172 struct _driver *next;
173 char *name;
174 int (* CreateContext)();
175 } XpDriverRec, *XpDriverPtr;
176
177 typedef struct _xpScreen {
178 Bool (* CloseScreen)();
179 struct _driver *drivers;
180 } XpScreenRec, *XpScreenPtr;
181
182 /*
183 * Each context has a list of XpClients indicating which clients have
184 * associated this context with their connection.
185 * Each such client has a RTclient resource allocated for it,
186 * and this per-client
187 * resource is used to delete the XpClientRec if/when the client closes
188 * its connection.
189 * The list of XpClients is also walked if/when the context is destroyed
190 * so that the ContextPtr can be removed from the client's devPrivates.
191 */
192 typedef struct _XpClient {
193 struct _XpClient *pNext;
194 ClientPtr client;
195 XpContextPtr context;
196 CARD32 eventMask;
197 XID contextClientID; /* unneeded sanity check? */
198 } XpClientRec, *XpClientPtr;
199
200 /*
201 * Each StartPage request specifies a window which forms the top level
202 * window of the page. One of the following structs is created as a
203 * RTpage resource with the same ID as the window itself. This enables
204 * us to clean up when/if the window is destroyed, and to prevent the
205 * same window from being simultaneously referenced in multiple contexts.
206 * The page resource is created at the first StartPage on a given window,
207 * and is only destroyed when/if the window is destroyed. When the
208 * EndPage is recieved (or an EndDoc or EndJob) the context field is
209 * set to NULL, but the resource remains alive.
210 */
211 typedef struct _XpPage {
212 XpContextPtr context;
213 } XpPageRec, *XpPagePtr;
214
215 typedef struct _XpStPageRec {
216 XpContextPtr pContext;
217 Bool slept;
218 XpPagePtr pPage;
219 WindowPtr pWin;
220 } XpStPageRec, *XpStPagePtr;
221
222 typedef struct _XpStDocRec {
223 XpContextPtr pContext;
224 Bool slept;
225 CARD8 type;
226 } XpStDocRec, *XpStDocPtr;
227
228 #define QUADPAD(x) ((((x)+3)>>2)<<2)
229
230 /*
231 * Possible bit-mask values in the "state" field of a XpContextRec.
232 */
233 #define JOB_STARTED (1 << 0)
234 #define DOC_RAW_STARTED (1 << 1)
235 #define DOC_COOKED_STARTED (1 << 2)
236 #define PAGE_STARTED (1 << 3)
237 #define GET_DOC_DATA_STARTED (1 << 4)
238 #define JOB_GET_DATA (1 << 5)
239
240 static XpScreenPtr XpScreens[MAXSCREENS];
241 static unsigned char XpReqCode;
242 static int XpEventBase;
243 static int XpErrorBase;
244 static int XpGeneration = 0;
245 static int XpWindowPrivateIndex;
246 static int XpClientPrivateIndex;
247
248 /* Variables for the context private machinery.
249 * These must be initialized at compile time because
250 * main() calls InitOutput before InitExtensions, and the
251 * output drivers are likely to call AllocateContextPrivate.
252 * These variables are reset at CloseScreen time. CloseScreen
253 * is used because it occurs after FreeAllResources, and before
254 * the next InitOutput cycle.
255 */
256 static int contextPrivateCount = 0;
257 static int contextPrivateLen = 0;
258 static unsigned *contextPrivateSizes = (unsigned *)NULL;
259 static unsigned totalContextSize = sizeof(XpContextRec);
260
261 /*
262 * There are three types of resources involved. One is the resource associated
263 * with the context itself, with an ID specified by a printing client. The
264 * next is a resource created by us on the client's behalf (and unknown to
265 * the client) when a client inits or sets a context which allows us to
266 * track each client's interest in events
267 * on a particular context, and also allows us to clean up this interest
268 * record when/if the client's connection is closed. Finally, there is
269 * a resource created for each window that's specified in a StartPage. This
270 * resource carries the same ID as the window itself, and enables us to
271 * easily prevent the same window being referenced in multiple contexts
272 * simultaneously, and enables us to clean up if the window is destroyed
273 * before the EndPage.
274 */
275 static RESTYPE RTclient, RTcontext, RTpage;
276
277 /*
278 * allEvents is the OR of all the legal event mask bits.
279 */
280 static CARD32 allEvents = XPPrintMask | XPAttributeMask;
281
282
283 /*******************************************************************************
284 *
285 * ExtensionInit, Driver Init functions, QueryVersion, and Dispatch procs
286 *
287 ******************************************************************************/
288
289 /*
290 * XpExtensionInit
291 *
292 * Called from InitExtensions in main() usually through miinitextension
293 *
294 */
295
296 void
XpExtensionInit()297 XpExtensionInit()
298 {
299 ExtensionEntry *extEntry, *AddExtension();
300 int i;
301
302 RTclient = CreateNewResourceType(XpFreeClient);
303 RTcontext = CreateNewResourceType(XpFreeContext);
304 RTpage = CreateNewResourceType(XpFreePage);
305 if (RTclient && RTcontext && RTpage &&
306 (extEntry = AddExtension(XP_PRINTNAME, XP_EVENTS, XP_ERRORS,
307 ProcXpDispatch, ProcXpSwappedDispatch,
308 XpResetProc, StandardMinorOpcode)))
309 {
310 XpReqCode = (unsigned char)extEntry->base;
311 XpEventBase = extEntry->eventBase;
312 XpErrorBase = extEntry->errorBase;
313 EventSwapVector[XpEventBase] = SwapXpNotifyEvent;
314 EventSwapVector[XpEventBase+1] = SwapXpAttributeEvent;
315 }
316
317 if(XpGeneration != serverGeneration)
318 {
319 XpClientPrivateIndex = AllocateClientPrivateIndex();
320 /*
321 * We allocate 0 length & simply stuff a pointer to the
322 * ContextRec in the DevUnion.
323 */
324 if(AllocateClientPrivate(XpClientPrivateIndex, 0) != TRUE)
325 {
326 /* we can't alloc a client private, should we bail??? XXX */
327 }
328 XpGeneration = serverGeneration;
329 }
330
331 for(i = 0; i < MAXSCREENS; i++)
332 {
333 /*
334 * If a screen has registered with our extension, then we
335 * wrap the screen's CloseScreen function to allow us to
336 * reset our ContextPrivate stuff. Note that this
337 * requires a printing DDX to call XpRegisterInitFunc
338 * _before_ this extension is initialized - i.e. at screen init
339 * time, _not_ at root window creation time.
340 */
341 if(XpScreens[i] != (XpScreenPtr)NULL)
342 {
343 XpScreens[i]->CloseScreen = screenInfo.screens[i]->CloseScreen;
344 screenInfo.screens[i]->CloseScreen = XpCloseScreen;
345 }
346 }
347 DeclareExtensionSecurity(XP_PRINTNAME, TRUE);
348 }
349
350 static void
XpResetProc(extEntry)351 XpResetProc(extEntry)
352 ExtensionEntry extEntry;
353 {
354 int i;
355
356 /*
357 * We can't free up the XpScreens recs here, because extensions are
358 * closed before screens, and our CloseScreen function uses the XpScreens
359 * recs.
360 for(i = 0; i < MAXSCREENS; i++)
361 {
362 if(XpScreens[i] != (XpScreenPtr)NULL)
363 Xfree(XpScreens[i]);
364 XpScreens[i] = (XpScreenPtr)NULL;
365 }
366 */
367 }
368
369 static Bool
XpCloseScreen(index,pScreen)370 XpCloseScreen(index, pScreen)
371 int index;
372 ScreenPtr pScreen;
373 {
374 Bool (* CloseScreen)();
375
376 CloseScreen = XpScreens[index]->CloseScreen;
377 if(XpScreens[index] != (XpScreenPtr)NULL)
378 {
379 XpDriverPtr pDriv, nextDriv;
380
381 pDriv = XpScreens[index]->drivers;
382 while(pDriv != (XpDriverPtr)NULL)
383 {
384 nextDriv = pDriv->next;
385 Xfree(pDriv);
386 pDriv = nextDriv;
387 }
388 Xfree(XpScreens[index]);
389 }
390 XpScreens[index] = (XpScreenPtr)NULL;
391
392 /*
393 * It's wasteful to call ResetContextPrivates() at every CloseScreen,
394 * but it's the best we know how to do for now. We do this because we
395 * have to wait until after all resources have been freed (so we know
396 * how to free the ContextRecs), and before the next InitOutput cycle.
397 * See dix/main.c for the order of initialization and reset.
398 */
399 ResetContextPrivates();
400 return (*CloseScreen)(index, pScreen);
401 }
402
403 static void
FreeScreenEntry(pScreenEntry)404 FreeScreenEntry(pScreenEntry)
405 XpScreenPtr pScreenEntry;
406 {
407 XpDriverPtr pDriver;
408
409 pDriver = pScreenEntry->drivers;
410 while(pDriver != (XpDriverPtr)NULL)
411 {
412 XpDriverPtr tmp;
413
414 tmp = pDriver->next;
415 xfree(pDriver);
416 pDriver = tmp;
417 }
418 xfree(pScreenEntry);
419 }
420
421 /*
422 * XpRegisterInitFunc tells the print extension which screens
423 * are printers as opposed to displays, and what drivers are
424 * supported on each screen. This eliminates the need of
425 * allocating print-related private structures on windows on _all_ screens.
426 * It also hands the extension a pointer to the routine to be called
427 * whenever a context gets created for a particular driver on this screen.
428 */
429 void
XpRegisterInitFunc(pScreen,driverName,initContext)430 XpRegisterInitFunc(pScreen, driverName, initContext)
431 ScreenPtr pScreen;
432 char *driverName;
433 int (*initContext)();
434 {
435 XpDriverPtr pDriver;
436
437 if(XpScreens[pScreen->myNum] == (XpScreenPtr)NULL)
438 {
439 if((XpScreens[pScreen->myNum] =
440 (XpScreenPtr) Xalloc(sizeof(XpScreenRec))) == (XpScreenPtr)NULL)
441 return;
442 XpScreens[pScreen->myNum]->CloseScreen = (Bool(*)())NULL;
443 XpScreens[pScreen->myNum]->drivers = (XpDriverPtr)NULL;
444 }
445
446 if((pDriver = (XpDriverPtr)Xalloc(sizeof(XpDriverRec))) ==
447 (XpDriverPtr)NULL)
448 return;
449 pDriver->next = XpScreens[pScreen->myNum]->drivers;
450 pDriver->name = driverName;
451 pDriver->CreateContext = initContext;
452 XpScreens[pScreen->myNum]->drivers = pDriver;
453 }
454
455 static int
ProcXpDispatch(client)456 ProcXpDispatch(client)
457 ClientPtr client;
458 {
459 REQUEST(xReq);
460
461 switch(stuff->data)
462 {
463 case X_PrintQueryVersion:
464 return ProcXpQueryVersion(client);
465 case X_PrintGetPrinterList:
466 return ProcXpGetPrinterList(client);
467 case X_PrintCreateContext:
468 return ProcXpCreateContext(client);
469 case X_PrintSetContext:
470 return ProcXpSetContext(client);
471 case X_PrintGetContext:
472 return ProcXpGetContext(client);
473 case X_PrintDestroyContext:
474 return ProcXpDestroyContext(client);
475 case X_PrintGetContextScreen:
476 return ProcXpGetContextScreen(client);
477 case X_PrintStartJob:
478 return ProcXpStartJob(client);
479 case X_PrintEndJob:
480 return ProcXpEndJob(client);
481 case X_PrintStartDoc:
482 return ProcXpStartDoc(client);
483 case X_PrintEndDoc:
484 return ProcXpEndDoc(client);
485 case X_PrintStartPage:
486 return ProcXpStartPage(client);
487 case X_PrintEndPage:
488 return ProcXpEndPage(client);
489 case X_PrintSelectInput:
490 return ProcXpSelectInput(client);
491 case X_PrintInputSelected:
492 return ProcXpInputSelected(client);
493 case X_PrintPutDocumentData:
494 return ProcXpPutDocumentData(client);
495 case X_PrintGetDocumentData:
496 return ProcXpGetDocumentData(client);
497 case X_PrintSetAttributes:
498 return ProcXpSetAttributes(client);
499 case X_PrintGetAttributes:
500 return ProcXpGetAttributes(client);
501 case X_PrintGetOneAttribute:
502 return ProcXpGetOneAttribute(client);
503 case X_PrintRehashPrinterList:
504 return ProcXpRehashPrinterList(client);
505 case X_PrintQueryScreens:
506 return ProcXpQueryScreens(client);
507 case X_PrintGetPageDimensions:
508 return ProcXpGetPageDimensions(client);
509 case X_PrintSetImageResolution:
510 return ProcXpSetImageResolution(client);
511 case X_PrintGetImageResolution:
512 return ProcXpGetImageResolution(client);
513 default:
514 return BadRequest;
515 }
516 }
517
518 static int
ProcXpSwappedDispatch(client)519 ProcXpSwappedDispatch(client)
520 ClientPtr client;
521 {
522 int temp;
523 REQUEST(xReq);
524
525 switch(stuff->data)
526 {
527 case X_PrintQueryVersion:
528 swaps(&stuff->length, temp);
529 return ProcXpQueryVersion(client);
530 case X_PrintGetPrinterList:
531 return SProcXpGetPrinterList(client);
532 case X_PrintCreateContext:
533 return SProcXpCreateContext(client);
534 case X_PrintSetContext:
535 return SProcXpSetContext(client);
536 case X_PrintGetContext:
537 return SProcXpGetContext(client);
538 case X_PrintDestroyContext:
539 return SProcXpDestroyContext(client);
540 case X_PrintGetContextScreen:
541 return SProcXpGetContextScreen(client);
542 case X_PrintStartJob:
543 return SProcXpStartJob(client);
544 case X_PrintEndJob:
545 return SProcXpEndJob(client);
546 case X_PrintStartDoc:
547 return SProcXpStartDoc(client);
548 case X_PrintEndDoc:
549 return SProcXpEndDoc(client);
550 case X_PrintStartPage:
551 return SProcXpStartPage(client);
552 case X_PrintEndPage:
553 return SProcXpEndPage(client);
554 case X_PrintSelectInput:
555 return SProcXpSelectInput(client);
556 case X_PrintInputSelected:
557 return SProcXpInputSelected(client);
558 case X_PrintPutDocumentData:
559 return SProcXpPutDocumentData(client);
560 case X_PrintGetDocumentData:
561 return SProcXpGetDocumentData(client);
562 case X_PrintSetAttributes:
563 return SProcXpSetAttributes(client);
564 case X_PrintGetAttributes:
565 return SProcXpGetAttributes(client);
566 case X_PrintGetOneAttribute:
567 return SProcXpGetOneAttribute(client);
568 case X_PrintRehashPrinterList:
569 return SProcXpRehashPrinterList(client);
570 case X_PrintQueryScreens:
571 swaps(&stuff->length, temp);
572 return ProcXpQueryScreens(client);
573 case X_PrintGetPageDimensions:
574 return SProcXpGetPageDimensions(client);
575 case X_PrintSetImageResolution:
576 return SProcXpSetImageResolution(client);
577 case X_PrintGetImageResolution:
578 return SProcXpGetImageResolution(client);
579 default:
580 return BadRequest;
581 }
582 }
583
584 static int
ProcXpQueryVersion(client)585 ProcXpQueryVersion(client)
586 ClientPtr client;
587 {
588 REQUEST(xPrintQueryVersionReq);
589 xPrintQueryVersionReply rep;
590 register int n;
591 long l;
592
593 REQUEST_SIZE_MATCH(xPrintQueryVersionReq);
594 rep.type = X_Reply;
595 rep.length = 0;
596 rep.sequenceNumber = client->sequence;
597 rep.majorVersion = XP_MAJOR_VERSION;
598 rep.minorVersion = XP_MINOR_VERSION;
599 if (client->swapped) {
600 swaps(&rep.sequenceNumber, n);
601 swapl(&rep.length, l);
602 swaps(&rep.majorVersion, n);
603 swaps(&rep.minorVersion, n);
604 }
605 WriteToClient(client, sz_xPrintQueryVersionReply, (char *)&rep);
606 return client->noClientException;
607 }
608
609 /*******************************************************************************
610 *
611 * GetPrinterList : Return a list of all printers associated with this
612 * server. Calls XpDiGetPrinterList, which is defined in
613 * the device-independent code in Xserver/Xprint.
614 *
615 ******************************************************************************/
616
617 static int
ProcXpGetPrinterList(client)618 ProcXpGetPrinterList(client)
619 ClientPtr client;
620 {
621 REQUEST(xPrintGetPrinterListReq);
622 int totalSize, numEntries;
623 XpDiListEntry **pList, *pEntry;
624 xPrintGetPrinterListReply *rep;
625 int n, i, totalBytes;
626 long l;
627 char *curByte;
628
629 REQUEST_AT_LEAST_SIZE(xPrintGetPrinterListReq);
630
631 totalSize = ((sz_xPrintGetPrinterListReq) >> 2) +
632 ((stuff->printerNameLen + 3) >> 2) +
633 ((stuff->localeLen + 3) >> 2);
634 if(totalSize != client->req_len)
635 return BadLength;
636
637 pList = XpDiGetPrinterList(stuff->printerNameLen, (char *)(stuff + 1),
638 stuff->localeLen, (char *)((stuff + 1) +
639 QUADPAD(stuff->printerNameLen)));
640
641 for(numEntries = 0, totalBytes = sz_xPrintGetPrinterListReply;
642 pList[numEntries] != (XpDiListEntry *)NULL;
643 numEntries++)
644 {
645 totalBytes += 2 * sizeof(CARD32);
646 totalBytes += QUADPAD(strlen(pList[numEntries]->name));
647 totalBytes += QUADPAD(strlen(pList[numEntries]->description));
648 }
649
650 if((rep = (xPrintGetPrinterListReply *)xalloc(totalBytes)) ==
651 (xPrintGetPrinterListReply *)NULL)
652 return BadAlloc;
653
654 rep->type = X_Reply;
655 rep->length = (totalBytes - sz_xPrintGetPrinterListReply) >> 2;
656 rep->sequenceNumber = client->sequence;
657 rep->listCount = numEntries;
658 if (client->swapped) {
659 swaps(&rep->sequenceNumber, n);
660 swapl(&rep->length, l);
661 swapl(&rep->listCount, l);
662 }
663
664 for(i = 0, curByte = (char *)(rep + 1); i < numEntries; i++)
665 {
666 CARD32 *pCrd;
667 int len;
668
669 pCrd = (CARD32 *)curByte;
670 len = strlen(pList[i]->name);
671 *pCrd = len;
672 if (client->swapped)
673 swapl((long *)curByte, l);
674 curByte += sizeof(CARD32);
675 strncpy(curByte, pList[i]->name, len);
676 curByte += QUADPAD(len);
677
678 pCrd = (CARD32 *)curByte;
679 len = strlen(pList[i]->description);
680 *pCrd = len;
681 if (client->swapped)
682 swapl((long *)curByte, l);
683 curByte += sizeof(CARD32);
684 strncpy(curByte, pList[i]->description, len);
685 curByte += QUADPAD(len);
686 }
687
688 XpDiFreePrinterList(pList);
689
690 WriteToClient(client, totalBytes, (char *)rep);
691 xfree(rep);
692 return client->noClientException;
693 }
694
695 /*******************************************************************************
696 *
697 * QueryScreens: Returns the list of screens which are associated with
698 * print drivers.
699 *
700 ******************************************************************************/
701
702 static int
ProcXpQueryScreens(client)703 ProcXpQueryScreens(client)
704 ClientPtr client;
705 {
706 REQUEST(xPrintQueryScreensReq);
707 int i, numPrintScreens, totalSize;
708 WINDOW *pWinId;
709 xPrintQueryScreensReply *rep;
710 long l;
711
712 REQUEST_SIZE_MATCH(xPrintQueryScreensReq);
713
714 rep = (xPrintQueryScreensReply *)xalloc(sz_xPrintQueryScreensReply);
715 pWinId = (WINDOW *)(rep + 1);
716
717 for(i = 0, numPrintScreens = 0, totalSize = sz_xPrintQueryScreensReply;
718 i < MAXSCREENS; i++)
719 {
720 /*
721 * If a screen has registered with our extension, then it's
722 * a printer screen.
723 */
724 if(XpScreens[i] != (XpScreenPtr)NULL)
725 {
726 numPrintScreens++;
727 totalSize += sizeof(WINDOW);
728 rep = (xPrintQueryScreensReply *)xrealloc(rep, totalSize);
729 *pWinId = WindowTable[i]->drawable.id;
730 if (client->swapped)
731 swapl((long *)pWinId, l);
732 pWinId++;
733 }
734 }
735
736 rep->type = X_Reply;
737 rep->sequenceNumber = client->sequence;
738 rep->length = (totalSize - sz_xPrintQueryScreensReply) >> 2;
739 rep->listCount = numPrintScreens;
740 if (client->swapped)
741 {
742 int n;
743
744 swaps(&rep->sequenceNumber, n);
745 swapl(&rep->length, l);
746 swapl(&rep->listCount, l);
747 }
748
749 WriteToClient(client, totalSize, (char *)rep);
750 xfree(rep);
751 return client->noClientException;
752 }
753
754 static int
ProcXpGetPageDimensions(client)755 ProcXpGetPageDimensions(client)
756 ClientPtr client;
757 {
758 REQUEST(xPrintGetPageDimensionsReq);
759 CARD16 width, height;
760 xRectangle rect;
761 xPrintGetPageDimensionsReply rep;
762 XpContextPtr pContext;
763 int result;
764
765 REQUEST_SIZE_MATCH(xPrintGetPageDimensionsReq);
766
767 if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
768 stuff->printContext,
769 RTcontext,
770 SecurityReadAccess))
771 == (XpContextPtr)NULL)
772 {
773 client->errorValue = stuff->printContext;
774 return XpErrorBase+XPBadContext;
775 }
776
777 if(pContext->funcs.GetMediumDimensions != (int (*)())NULL)
778 result = pContext->funcs.GetMediumDimensions(pContext, &width, &height);
779 else
780 return BadImplementation;
781
782 if(pContext->funcs.GetReproducibleArea != (int (*)())NULL)
783 result = pContext->funcs.GetReproducibleArea(pContext, &rect);
784 else
785 return BadImplementation;
786
787 rep.type = X_Reply;
788 rep.sequenceNumber = client->sequence;
789 rep.length = 0;
790 rep.width = width;
791 rep.height = height;
792 rep.rx = rect.x;
793 rep.ry = rect.y;
794 rep.rwidth = rect.width;
795 rep.rheight = rect.height;
796
797 if(client->swapped)
798 {
799 int n;
800 long l;
801
802 swaps(&rep.sequenceNumber, n);
803 swapl(&rep.length, l);
804 swaps(&rep.width, n);
805 swaps(&rep.height, n);
806 swaps(&rep.rx, n);
807 swaps(&rep.ry, n);
808 swaps(&rep.rwidth, n);
809 swaps(&rep.rheight, n);
810 }
811
812 WriteToClient(client, sz_xPrintGetPageDimensionsReply, (char *)&rep);
813 return client->noClientException;
814 }
815
816 static int
ProcXpSetImageResolution(client)817 ProcXpSetImageResolution(client)
818 ClientPtr client;
819 {
820 REQUEST(xPrintSetImageResolutionReq);
821 xPrintSetImageResolutionReply rep;
822 XpContextPtr pContext;
823 Bool status;
824 int result;
825
826 REQUEST_SIZE_MATCH(xPrintSetImageResolutionReq);
827
828 if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
829 stuff->printContext,
830 RTcontext,
831 SecurityWriteAccess))
832 == (XpContextPtr)NULL)
833 {
834 client->errorValue = stuff->printContext;
835 return XpErrorBase+XPBadContext;
836 }
837
838 rep.prevRes = pContext->imageRes;
839 if(pContext->funcs.SetImageResolution != (int (*)())NULL)
840 result = pContext->funcs.SetImageResolution(pContext,
841 (int)stuff->imageRes,
842 &status);
843 else
844 status = FALSE;
845
846 rep.type = X_Reply;
847 rep.sequenceNumber = client->sequence;
848 rep.length = 0;
849 rep.status = status;
850
851 if(client->swapped)
852 {
853 int n;
854 long l;
855
856 swaps(&rep.sequenceNumber, n);
857 swapl(&rep.length, l);
858 swaps(&rep.prevRes, n);
859 }
860
861 WriteToClient(client, sz_xPrintSetImageResolutionReply, (char *)&rep);
862 return client->noClientException;
863 }
864
865 static int
ProcXpGetImageResolution(client)866 ProcXpGetImageResolution(client)
867 ClientPtr client;
868 {
869 REQUEST(xPrintGetImageResolutionReq);
870 xPrintGetImageResolutionReply rep;
871 XpContextPtr pContext;
872 Bool status;
873 int result;
874
875 REQUEST_SIZE_MATCH(xPrintGetImageResolutionReq);
876
877 if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
878 stuff->printContext,
879 RTcontext,
880 SecurityReadAccess))
881 == (XpContextPtr)NULL)
882 {
883 client->errorValue = stuff->printContext;
884 return XpErrorBase+XPBadContext;
885 }
886
887 rep.type = X_Reply;
888 rep.sequenceNumber = client->sequence;
889 rep.length = 0;
890 rep.imageRes = pContext->imageRes;
891
892 if(client->swapped)
893 {
894 int n;
895 long l;
896
897 swaps(&rep.sequenceNumber, n);
898 swapl(&rep.length, l);
899 swaps(&rep.imageRes, n);
900 }
901
902 WriteToClient(client, sz_xPrintGetImageResolutionReply, (char *)&rep);
903 return client->noClientException;
904 }
905
906 /*******************************************************************************
907 *
908 * RehashPrinterList : Cause the server's list of printers to be rebuilt.
909 * This allows new printers to be added, or old ones
910 * deleted without needing to restart the server.
911 *
912 ******************************************************************************/
913
914 static int
ProcXpRehashPrinterList(client)915 ProcXpRehashPrinterList(client)
916 ClientPtr client;
917 {
918 REQUEST(xPrintRehashPrinterListReq);
919
920 REQUEST_SIZE_MATCH(xPrintRehashPrinterListReq);
921
922 return XpRehashPrinterList();
923 }
924
925 /******************************************************************************
926 *
927 * Context functions: Init, Set, Destroy, FreeContext
928 * AllocateContextPrivateIndex, AllocateContextPrivate
929 * and supporting functions.
930 *
931 * Init creates a context, creates a XpClientRec for the calling
932 * client, and stores the contextPtr in the client's devPrivates.
933 *
934 * Set creates a XpClientRec for the calling client, and stores the
935 * contextPtr in the client's devPrivates unless the context is None.
936 * If the context is None, then the client's connection association
937 * with any context is removed.
938 *
939 * Destroy frees any and all XpClientRecs associated with the context,
940 * frees the context itself, and removes the contextPtr from any
941 * relevant client devPrivates.
942 *
943 * FreeContext is called by FreeResource to free up a context.
944 *
945 ******************************************************************************/
946
947 /*
948 * CreateContext creates and initializes the memory for the context itself.
949 * The driver's CreateContext function
950 * is then called.
951 */
952 static int
ProcXpCreateContext(client)953 ProcXpCreateContext(client)
954 ClientPtr client;
955 {
956 REQUEST(xPrintCreateContextReq);
957 XpScreenPtr pPrintScreen;
958 WindowPtr pRoot;
959 char *printerName, *driverName;
960 XpContextPtr pContext;
961 XpClientPtr pNewPrintClient;
962 int result = Success;
963 XpDriverPtr pDriver;
964
965 REQUEST_AT_LEAST_SIZE(xPrintCreateContextReq);
966
967 LEGAL_NEW_RESOURCE(stuff->contextID, client);
968
969 /*
970 * Check to see if the printer name is valid.
971 */
972 if((pRoot = XpDiValidatePrinter(stuff + 1, stuff->printerNameLen)) ==
973 (WindowPtr)NULL)
974 return BadMatch;
975
976 pPrintScreen = XpScreens[pRoot->drawable.pScreen->myNum];
977
978 /*
979 * Allocate and add the context resource.
980 */
981 if((pContext = (XpContextPtr) xalloc(totalContextSize)) ==
982 (XpContextPtr) NULL)
983 return BadAlloc;
984
985 InitContextPrivates(pContext);
986
987 if(AddResource(stuff->contextID, RTcontext, (pointer) pContext)
988 != TRUE)
989 {
990 xfree(pContext);
991 return BadAlloc;
992 }
993
994 pContext->contextID = stuff->contextID;
995 pContext->clientHead = (XpClientPtr)NULL;
996 pContext->screenNum = pRoot->drawable.pScreen->myNum;
997 pContext->state = 0;
998 pContext->clientSlept = (ClientPtr)NULL;
999 pContext->imageRes = 0;
1000
1001 pContext->funcs.DestroyContext = (int (*)())NULL;
1002 pContext->funcs.StartJob = (int (*)())NULL;
1003 pContext->funcs.EndJob = (int (*)())NULL;
1004 pContext->funcs.StartDoc = (int (*)())NULL;
1005 pContext->funcs.EndDoc = (int (*)())NULL;
1006 pContext->funcs.StartPage = (int (*)())NULL;
1007 pContext->funcs.EndPage = (int (*)())NULL;
1008 pContext->funcs.PutDocumentData = (int (*)())NULL;
1009 pContext->funcs.GetDocumentData = (int (*)())NULL;
1010 pContext->funcs.GetAttributes = (char * (*)())NULL;
1011 pContext->funcs.GetOneAttribute = (char * (*)())NULL;
1012 pContext->funcs.SetAttributes = (int (*)())NULL;
1013 pContext->funcs.AugmentAttributes = (int (*)())NULL;
1014 pContext->funcs.GetMediumDimensions = (int (*)())NULL;
1015 pContext->funcs.GetReproducibleArea = (int (*)())NULL;
1016 pContext->funcs.SetImageResolution = (int (*)())NULL;
1017
1018 if((pContext->printerName = (char *)xalloc(stuff->printerNameLen + 1)) ==
1019 (char *)NULL)
1020 {
1021 /* Freeing the context also causes the XpClients to be freed. */
1022 FreeResource(stuff->contextID, RT_NONE);
1023 return BadAlloc;
1024 }
1025 strncpy(pContext->printerName, (char *)(stuff + 1), stuff->printerNameLen);
1026 pContext->printerName[stuff->printerNameLen] = (char)'\0';
1027
1028 driverName = XpDiGetDriverName(pRoot->drawable.pScreen->myNum,
1029 pContext->printerName);
1030
1031 for(pDriver = pPrintScreen->drivers;
1032 pDriver != (XpDriverPtr)NULL;
1033 pDriver = pDriver->next)
1034 {
1035 if(!strcmp(driverName, pDriver->name))
1036 {
1037 if(pDriver->CreateContext != (Bool (*)())NULL)
1038 pDriver->CreateContext(pContext);
1039 else
1040 return BadImplementation;
1041 break;
1042 }
1043 }
1044
1045 if (client->noClientException != Success)
1046 return client->noClientException;
1047 else
1048 return result;
1049 }
1050
1051 /*
1052 * SetContext creates the calling client's contextClient resource,
1053 * and stashes the contextID in the client's devPrivate.
1054 */
1055 static int
ProcXpSetContext(client)1056 ProcXpSetContext(client)
1057 ClientPtr client;
1058 {
1059 REQUEST(xPrintSetContextReq);
1060
1061 XpContextPtr pContext;
1062 XpClientPtr pPrintClient;
1063 int result = Success;
1064
1065 REQUEST_AT_LEAST_SIZE(xPrintSetContextReq);
1066
1067 if((pContext = client->devPrivates[XpClientPrivateIndex].ptr) !=
1068 (pointer)NULL)
1069 {
1070 /*
1071 * Erase this client's knowledge of its old context, if any.
1072 */
1073 if((pPrintClient = FindClient(pContext, client)) != (XpClientPtr)NULL)
1074 {
1075 XpUnsetFontResFunc(client);
1076
1077 if(pPrintClient->eventMask == 0)
1078 FreeXpClient(pPrintClient, TRUE);
1079 }
1080
1081 client->devPrivates[XpClientPrivateIndex].ptr = (pointer)NULL;
1082 }
1083 if(stuff->printContext == None)
1084 return Success;
1085
1086 /*
1087 * Check to see that the supplied XID is really a valid print context
1088 * in this server.
1089 */
1090 if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
1091 stuff->printContext,
1092 RTcontext,
1093 SecurityWriteAccess))
1094 == (XpContextPtr)NULL)
1095 {
1096 client->errorValue = stuff->printContext;
1097 return XpErrorBase+XPBadContext;
1098 }
1099
1100 if((pPrintClient = AcquireClient(pContext, client)) == (XpClientPtr)NULL)
1101 return BadAlloc;
1102
1103 client->devPrivates[XpClientPrivateIndex].ptr = pContext;
1104
1105 XpSetFontResFunc(client);
1106
1107 if (client->noClientException != Success)
1108 return client->noClientException;
1109 else
1110 return result;
1111 }
1112
1113 XpContextPtr
XpGetPrintContext(client)1114 XpGetPrintContext(client)
1115 ClientPtr client;
1116 {
1117 return (client->devPrivates[XpClientPrivateIndex].ptr);
1118 }
1119
1120 static int
ProcXpGetContext(client)1121 ProcXpGetContext(client)
1122 ClientPtr client;
1123 {
1124 REQUEST(xPrintGetContextReq);
1125 xPrintGetContextReply rep;
1126
1127 XpContextPtr pContext;
1128 XpClientPtr pNewPrintClient;
1129 int result = Success;
1130 register int n;
1131 register long l;
1132
1133 REQUEST_SIZE_MATCH(xPrintGetContextReq);
1134
1135 if((pContext = client->devPrivates[XpClientPrivateIndex].ptr) ==
1136 (pointer)NULL)
1137 rep.printContext = None;
1138 else
1139 rep.printContext = pContext->contextID;
1140 rep.type = X_Reply;
1141 rep.length = 0;
1142 rep.sequenceNumber = client->sequence;
1143 if (client->swapped) {
1144 swaps(&rep.sequenceNumber, n);
1145 swapl(&rep.length, l);
1146 swapl(&rep.printContext, l);
1147 }
1148 WriteToClient(client, sz_xPrintGetContextReply, (char *)&rep);
1149 return client->noClientException;
1150 }
1151
1152
1153 /*
1154 * DestroyContext frees the context associated with the calling client.
1155 * It operates by freeing the context resource ID, thus causing XpFreeContext
1156 * to be called.
1157 */
1158 static int
ProcXpDestroyContext(client)1159 ProcXpDestroyContext(client)
1160 ClientPtr client;
1161 {
1162 REQUEST(xPrintDestroyContextReq);
1163
1164 XpContextPtr pContext;
1165 XpClientPtr pXpClient;
1166 ClientPtr curClient;
1167
1168 REQUEST_SIZE_MATCH(xPrintDestroyContextReq);
1169
1170 if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
1171 stuff->printContext,
1172 RTcontext,
1173 SecurityDestroyAccess))
1174 == (XpContextPtr)NULL)
1175 {
1176 client->errorValue = stuff->printContext;
1177 return XpErrorBase+XPBadContext;
1178 }
1179
1180 XpUnsetFontResFunc(client);
1181
1182 FreeResource(pContext->contextID, RT_NONE);
1183
1184 return Success;
1185 }
1186
1187 static int
ProcXpGetContextScreen(client)1188 ProcXpGetContextScreen(client)
1189 ClientPtr client;
1190 {
1191 REQUEST(xPrintGetContextScreenReq);
1192 xPrintGetContextScreenReply rep;
1193 XpContextPtr pContext;
1194 int n;
1195 long l;
1196
1197 if((pContext =(XpContextPtr)SecurityLookupIDByType(client,
1198 stuff->printContext,
1199 RTcontext,
1200 SecurityReadAccess))
1201 == (XpContextPtr)NULL)
1202 return XpErrorBase+XPBadContext;
1203
1204 rep.type = X_Reply;
1205 rep.sequenceNumber = client->sequence;
1206 rep.length = 0;
1207 rep.rootWindow = WindowTable[pContext->screenNum]->drawable.id;
1208
1209 if (client->swapped) {
1210 swaps(&rep.sequenceNumber, n);
1211 swapl(&rep.length, l);
1212 swapl(&rep.rootWindow, l);
1213 }
1214
1215 WriteToClient(client, sz_xPrintGetContextScreenReply, (char *)&rep);
1216 return client->noClientException;
1217 }
1218
1219 /*
1220 * XpFreeContext is the routine called by dix:FreeResource when a context
1221 * resource ID is freed.
1222 * It checks to see if there's a partial job pending on the context, and
1223 * if so it calls the appropriate End procs with the cancel flag set.
1224 * It calls the driver's DestroyContext routine to allow the driver to clean
1225 * up any context-related memory or state.
1226 * It calls FreeXpClient to free all the
1227 * associated XpClientRecs and to set all the client->devPrivates to NULL.
1228 * It frees the printer name string, and frees the context
1229 * itself.
1230 */
1231 static int
XpFreeContext(data,id)1232 XpFreeContext(data, id)
1233 pointer data;
1234 XID id;
1235 {
1236 XpContextPtr pContext = (XpContextPtr)data;
1237
1238 /* Clean up any pending job on this context */
1239 if(pContext->state != 0)
1240 {
1241 if(pContext->state & PAGE_STARTED)
1242 {
1243 WindowPtr pWin = (WindowPtr )LookupIDByType(
1244 pContext->pageWin, RT_WINDOW);
1245 XpPagePtr pPage = (XpPagePtr)LookupIDByType(
1246 pContext->pageWin, RTpage);
1247
1248 pContext->funcs.EndPage(pContext, pWin, TRUE);
1249 SendXpNotify(pContext, XPEndPageNotify, TRUE);
1250 pContext->state &= ~PAGE_STARTED;
1251 if(pPage)
1252 pPage->context = (XpContextPtr)NULL;
1253 }
1254 if((pContext->state & DOC_RAW_STARTED) ||
1255 (pContext->state & DOC_COOKED_STARTED))
1256 {
1257 pContext->funcs.EndDoc(pContext, TRUE);
1258 SendXpNotify(pContext, XPEndDocNotify, TRUE);
1259 pContext->state &= ~DOC_RAW_STARTED;
1260 pContext->state &= ~DOC_COOKED_STARTED;
1261 }
1262 if(pContext->funcs.EndJob != (int (*)())NULL)
1263 {
1264 pContext->funcs.EndJob(pContext, TRUE);
1265 SendXpNotify(pContext, XPEndJobNotify, TRUE);
1266 pContext->state &= ~JOB_STARTED;
1267 pContext->state &= ~GET_DOC_DATA_STARTED;
1268 }
1269 }
1270
1271 /*
1272 * Tell the driver we're destroying the context
1273 * This allows the driver to free and ContextPrivate data
1274 */
1275 if(pContext->funcs.DestroyContext != (int (*)())NULL)
1276 pContext->funcs.DestroyContext(pContext);
1277
1278 /* Free up all the XpClientRecs */
1279 while(pContext->clientHead != (XpClientPtr)NULL)
1280 {
1281 FreeXpClient(pContext->clientHead, TRUE);
1282 }
1283
1284 xfree(pContext->printerName);
1285 xfree(pContext);
1286 return Success; /* ??? */
1287 }
1288
1289 /*
1290 * XpFreeClient is the routine called by dix:FreeResource when a RTclient
1291 * is freed. It simply calls the FreeXpClient routine to do the work.
1292 */
1293 static int
XpFreeClient(data,id)1294 XpFreeClient(data, id)
1295 pointer data;
1296 XID id;
1297 {
1298 FreeXpClient((XpClientPtr)data, FALSE);
1299
1300 return Success;
1301 }
1302
1303 /*
1304 * FreeXpClient
1305 * frees the ClientRec passed in, and sets the client->devPrivates to NULL
1306 * if the client->devPrivates points to the same context as the XpClient.
1307 * Called from XpFreeContext(from FreeResource), and
1308 * XpFreeClient. The boolean freeResource specifies whether or not to call
1309 * FreeResource for the XpClientRec's XID. We should free it except if we're
1310 * called from XpFreeClient (which is itself called from FreeResource for the
1311 * XpClientRec's XID).
1312 */
1313 static void
FreeXpClient(pXpClient,freeResource)1314 FreeXpClient(pXpClient, freeResource)
1315 XpClientPtr pXpClient;
1316 Bool freeResource;
1317 {
1318 XpClientPtr pCurrent, pPrev;
1319 XpContextPtr pContext = pXpClient->context;
1320
1321 /*
1322 * If we're freeing the clientRec associated with the context tied
1323 * to the client's devPrivates, then we need to clear the devPrivates.
1324 */
1325 if(pXpClient->client->devPrivates[XpClientPrivateIndex].ptr ==
1326 pXpClient->context)
1327 {
1328 pXpClient->client->devPrivates[XpClientPrivateIndex].ptr =
1329 (pointer)NULL;
1330 }
1331
1332 for(pPrev = (XpClientPtr)NULL, pCurrent = pContext->clientHead;
1333 pCurrent != (XpClientPtr)NULL;
1334 pCurrent = pCurrent->pNext)
1335 {
1336 if(pCurrent == pXpClient)
1337 {
1338 if(freeResource == TRUE)
1339 FreeResource (pCurrent->contextClientID, RTclient);
1340
1341 if (pPrev != (XpClientPtr)NULL)
1342 pPrev->pNext = pCurrent->pNext;
1343 else
1344 pContext->clientHead = pCurrent->pNext;
1345
1346 xfree (pCurrent);
1347 break;
1348 }
1349 pPrev = pCurrent;
1350 }
1351 }
1352
1353 /*
1354 * CreateXpClient takes a ClientPtr and returns a pointer to a
1355 * XpClientRec which it allocates. It also initializes the Rec,
1356 * including adding a resource on behalf of the client to enable the
1357 * freeing of the Rec when the client's connection is closed.
1358 */
1359 static XpClientPtr
CreateXpClient(client)1360 CreateXpClient(client)
1361 ClientPtr client;
1362 {
1363 XpClientPtr pNewPrintClient;
1364 XID clientResource;
1365
1366 if((pNewPrintClient = (XpClientPtr)xalloc(sizeof(XpClientRec))) ==
1367 (XpClientPtr)NULL)
1368 return (XpClientPtr)NULL;
1369
1370 clientResource = FakeClientID(client->index);
1371 if(!AddResource(clientResource, RTclient, (pointer)pNewPrintClient))
1372 {
1373 xfree (pNewPrintClient);
1374 return (XpClientPtr)NULL;
1375 }
1376
1377 pNewPrintClient->pNext = (XpClientPtr)NULL;
1378 pNewPrintClient->client = client;
1379 pNewPrintClient->context = (XpContextPtr)NULL;
1380 pNewPrintClient->eventMask = 0;
1381 pNewPrintClient->contextClientID = clientResource;
1382
1383 return pNewPrintClient;
1384 }
1385
1386 /*
1387 * XpFreePage is the routine called by dix:FreeResource to free the page
1388 * resource built with the same ID as a page window. It checks to see
1389 * if we're in the middle of a page, and if so calls the driver's EndPage
1390 * function with 'cancel' set TRUE. It frees the memory associated with
1391 * the page resource.
1392 */
1393 static int
XpFreePage(data,id)1394 XpFreePage(data, id)
1395 pointer data;
1396 XID id;
1397 {
1398 XpPagePtr page = (XpPagePtr)data;
1399 int result = Success;
1400 WindowPtr pWin = (WindowPtr )LookupIDByType(id, RT_WINDOW);
1401
1402 /* Check to see if the window's being deleted in the middle of a page */
1403 if(page->context != (XpContextPtr)NULL &&
1404 page->context->state & PAGE_STARTED)
1405 {
1406 XpScreenPtr pPrintScreen = XpScreens[page->context->screenNum];
1407 if(page->context->funcs.EndPage != (int (*)())NULL)
1408 result = page->context->funcs.EndPage(page->context, pWin, TRUE);
1409 SendXpNotify(page->context, XPEndPageNotify, (int)TRUE);
1410 page->context->pageWin = 0; /* None, NULL??? XXX */
1411 }
1412
1413 xfree(page);
1414 return result;
1415 }
1416
1417 /*
1418 * ContextPrivate machinery.
1419 * Context privates are intended for use by the drivers, allowing the
1420 * drivers to maintain context-specific data. The driver should free
1421 * the associated data at DestroyContext time.
1422 */
1423
1424 static void
InitContextPrivates(context)1425 InitContextPrivates(context)
1426 XpContextPtr context;
1427 {
1428 register char *ptr;
1429 DevUnion *ppriv;
1430 register unsigned *sizes;
1431 register unsigned size;
1432 register int i;
1433
1434 if (totalContextSize == sizeof(XpContextRec))
1435 ppriv = (DevUnion *)NULL;
1436 else
1437 ppriv = (DevUnion *)(context + 1);
1438
1439 context->devPrivates = ppriv;
1440 sizes = contextPrivateSizes;
1441 ptr = (char *)(ppriv + contextPrivateLen);
1442 for (i = contextPrivateLen; --i >= 0; ppriv++, sizes++)
1443 {
1444 if ( (size = *sizes) )
1445 {
1446 ppriv->ptr = (pointer)ptr;
1447 ptr += size;
1448 }
1449 else
1450 ppriv->ptr = (pointer)NULL;
1451 }
1452 }
1453
1454 static void
ResetContextPrivates()1455 ResetContextPrivates()
1456 {
1457 contextPrivateCount = 0;
1458 contextPrivateLen = 0;
1459 xfree(contextPrivateSizes);
1460 contextPrivateSizes = (unsigned *)NULL;
1461 totalContextSize = sizeof(XpContextRec);
1462
1463 }
1464
1465 int
XpAllocateContextPrivateIndex()1466 XpAllocateContextPrivateIndex()
1467 {
1468 return contextPrivateCount++;
1469 }
1470
1471 Bool
XpAllocateContextPrivate(index,amount)1472 XpAllocateContextPrivate(index, amount)
1473 int index;
1474 unsigned amount;
1475 {
1476 unsigned oldamount;
1477
1478 if (index >= contextPrivateLen)
1479 {
1480 unsigned *nsizes;
1481 nsizes = (unsigned *)xrealloc(contextPrivateSizes,
1482 (index + 1) * sizeof(unsigned));
1483 if (!nsizes)
1484 return FALSE;
1485 while (contextPrivateLen <= index)
1486 {
1487 nsizes[contextPrivateLen++] = 0;
1488 totalContextSize += sizeof(DevUnion);
1489 }
1490 contextPrivateSizes = nsizes;
1491 }
1492 oldamount = contextPrivateSizes[index];
1493 if (amount > oldamount)
1494 {
1495 contextPrivateSizes[index] = amount;
1496 totalContextSize += (amount - oldamount);
1497 }
1498 return TRUE;
1499 }
1500
1501 static XpClientPtr
AcquireClient(pContext,client)1502 AcquireClient(pContext, client)
1503 XpContextPtr pContext;
1504 ClientPtr client;
1505 {
1506 XpClientPtr pXpClient;
1507
1508 if((pXpClient = FindClient(pContext, client)) != (XpClientPtr)NULL)
1509 return pXpClient;
1510
1511 if((pXpClient = CreateXpClient(client)) == (XpClientPtr)NULL)
1512 return (XpClientPtr)NULL;
1513
1514 pXpClient->context = pContext;
1515 pXpClient->pNext = pContext->clientHead;
1516 pContext->clientHead = pXpClient;
1517
1518 return pXpClient;
1519 }
1520
1521 static XpClientPtr
FindClient(pContext,client)1522 FindClient(pContext, client)
1523 XpContextPtr pContext;
1524 ClientPtr client;
1525 {
1526 XpClientPtr pXpClient;
1527
1528 for(pXpClient = pContext->clientHead; pXpClient != (XpClientPtr)NULL;
1529 pXpClient = pXpClient->pNext)
1530 {
1531 if(pXpClient->client == client) return pXpClient;
1532 }
1533 return (XpClientPtr)NULL;
1534 }
1535
1536
1537 /******************************************************************************
1538 *
1539 * Start/End Functions: StartJob, EndJob, StartDoc, EndDoc, StartPage, EndPage
1540 *
1541 ******************************************************************************/
1542
1543 static int
ProcXpStartJob(client)1544 ProcXpStartJob(client)
1545 ClientPtr client;
1546 {
1547 REQUEST(xPrintStartJobReq);
1548 XpContextPtr pContext;
1549 int result = Success;
1550 XpScreenPtr pPrintScreen;
1551
1552 REQUEST_SIZE_MATCH(xPrintStartJobReq);
1553
1554 /* Check to see that a context has been established by this client. */
1555 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
1556 == (XpContextPtr)NULL)
1557 return XpErrorBase+XPBadContext;
1558
1559 if(pContext->state != 0)
1560 return XpErrorBase+XPBadSequence;
1561
1562 if(stuff->saveData != XPSpool && stuff->saveData != XPGetData)
1563 {
1564 client->errorValue = stuff->saveData;
1565 return BadValue;
1566 }
1567
1568 pPrintScreen = XpScreens[pContext->screenNum];
1569 if(pContext->funcs.StartJob != (int (*)())NULL)
1570 result = pContext->funcs.StartJob(pContext,
1571 (stuff->saveData == XPGetData)? TRUE:FALSE);
1572 else
1573 return BadImplementation;
1574
1575 pContext->state = JOB_STARTED;
1576 if(stuff->saveData == XPGetData)
1577 pContext->state |= JOB_GET_DATA;
1578
1579 SendXpNotify(pContext, XPStartJobNotify, FALSE);
1580
1581 if (client->noClientException != Success)
1582 return client->noClientException;
1583 else
1584 return result;
1585 }
1586
1587 static int
ProcXpEndJob(client)1588 ProcXpEndJob(client)
1589 ClientPtr client;
1590 {
1591 REQUEST(xPrintEndJobReq);
1592 XpScreenPtr pPrintScreen;
1593 WindowPtr pWin;
1594 int result = Success;
1595 XpContextPtr pContext;
1596
1597 REQUEST_SIZE_MATCH(xPrintEndJobReq);
1598
1599 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
1600 == (XpContextPtr)NULL)
1601 return XpErrorBase+XPBadSequence;
1602
1603 pPrintScreen = XpScreens[pContext->screenNum];
1604
1605 if(!(pContext->state & JOB_STARTED))
1606 return XpErrorBase+XPBadSequence;
1607
1608 /* Check for missing EndDoc */
1609 if((pContext->state & DOC_RAW_STARTED) ||
1610 (pContext->state & DOC_COOKED_STARTED))
1611 {
1612 if(pContext->state & PAGE_STARTED)
1613 {
1614 WindowPtr pWin = (WindowPtr )LookupIDByType(
1615 pContext->pageWin, RT_WINDOW);
1616 XpPagePtr pPage = (XpPagePtr)LookupIDByType(
1617 pContext->pageWin, RTpage);
1618
1619 if(stuff->cancel != TRUE)
1620 return XpErrorBase+XPBadSequence;
1621
1622 if(pContext->funcs.EndPage != (int (*)())NULL)
1623 result = pContext->funcs.EndPage(pContext, pWin, TRUE);
1624 else
1625 return BadImplementation;
1626
1627 SendXpNotify(pContext, XPEndPageNotify, TRUE);
1628
1629 pContext->state &= ~PAGE_STARTED;
1630
1631 if(pPage)
1632 pPage->context = (XpContextPtr)NULL;
1633
1634 if(result != Success) return result;
1635 }
1636
1637 if(pContext->funcs.EndDoc != (int (*)())NULL)
1638 result = pContext->funcs.EndDoc(pContext, stuff->cancel);
1639 else
1640 return BadImplementation;
1641
1642 SendXpNotify(pContext, XPEndDocNotify, stuff->cancel);
1643 }
1644
1645 if(pContext->funcs.EndJob != (int (*)())NULL)
1646 result = pContext->funcs.EndJob(pContext, stuff->cancel);
1647 else
1648 return BadImplementation;
1649
1650 pContext->state = 0;
1651
1652 SendXpNotify(pContext, XPEndJobNotify, stuff->cancel);
1653
1654 if (client->noClientException != Success)
1655 return client->noClientException;
1656 else
1657 return result;
1658 }
1659
1660 static Bool
DoStartDoc(client,c)1661 DoStartDoc(client, c)
1662 ClientPtr client;
1663 XpStDocPtr c;
1664 {
1665 XpScreenPtr pPrintScreen;
1666 int result = Success;
1667 XpContextPtr pContext = c->pContext;
1668
1669 if(c->pContext->state & JOB_GET_DATA &&
1670 !(c->pContext->state & GET_DOC_DATA_STARTED))
1671 {
1672 if(!c->slept)
1673 {
1674 c->slept = TRUE;
1675 ClientSleep(client, (ClientSleepProcPtr)DoStartDoc, (pointer) c);
1676 c->pContext->clientSlept = client;
1677 }
1678 return TRUE;
1679 }
1680
1681 pPrintScreen = XpScreens[pContext->screenNum];
1682
1683 if(pContext->funcs.StartDoc != (int (*)())NULL)
1684 result = pContext->funcs.StartDoc(pContext, c->type);
1685 else
1686 {
1687 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
1688 BadImplementation);
1689 return TRUE;
1690 }
1691
1692 if(c->type == XPDocNormal)
1693 pContext->state |= DOC_COOKED_STARTED;
1694 else
1695 pContext->state |= DOC_RAW_STARTED;
1696
1697 SendXpNotify(pContext, XPStartDocNotify, (int)FALSE);
1698
1699 xfree(c);
1700 return TRUE;
1701 }
1702
1703 static int
ProcXpStartDoc(client)1704 ProcXpStartDoc(client)
1705 ClientPtr client;
1706 {
1707 REQUEST(xPrintStartDocReq);
1708 XpScreenPtr pPrintScreen;
1709 int result = Success;
1710 XpContextPtr pContext;
1711 XpStDocPtr c;
1712
1713 REQUEST_SIZE_MATCH(xPrintStartDocReq);
1714
1715 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
1716 == (XpContextPtr)NULL)
1717 return XpErrorBase+XPBadSequence;
1718
1719 if(!(pContext->state & JOB_STARTED) ||
1720 pContext->state & DOC_RAW_STARTED ||
1721 pContext->state & DOC_COOKED_STARTED)
1722 return XpErrorBase+XPBadSequence;
1723
1724 if(stuff->type != XPDocNormal && stuff->type != XPDocRaw)
1725 {
1726 client->errorValue = stuff->type;
1727 return BadValue;
1728 }
1729
1730 c = (XpStDocPtr)xalloc(sizeof(XpStDocRec));
1731 c->pContext = pContext;
1732 c->type = stuff->type;
1733 c->slept = FALSE;
1734 (void)DoStartDoc(client, c);
1735
1736 if (client->noClientException != Success)
1737 return client->noClientException;
1738 else
1739 return result;
1740 }
1741
1742 static int
ProcXpEndDoc(client)1743 ProcXpEndDoc(client)
1744 ClientPtr client;
1745 {
1746 REQUEST(xPrintEndDocReq);
1747 XpScreenPtr pPrintScreen;
1748 XpContextPtr pContext;
1749 int result = Success;
1750
1751 REQUEST_SIZE_MATCH(xPrintEndDocReq);
1752
1753 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
1754 == (XpContextPtr)NULL)
1755 return XpErrorBase+XPBadSequence;
1756
1757 pPrintScreen = XpScreens[pContext->screenNum];
1758
1759 if(!(pContext->state & DOC_RAW_STARTED) &&
1760 !(pContext->state & DOC_COOKED_STARTED))
1761 return XpErrorBase+XPBadSequence;
1762
1763 if(pContext->state & PAGE_STARTED)
1764 {
1765 if(stuff->cancel == TRUE)
1766 {
1767 WindowPtr pWin = (WindowPtr )LookupIDByType(
1768 pContext->pageWin, RT_WINDOW);
1769 XpPagePtr pPage = (XpPagePtr)LookupIDByType(
1770 pContext->pageWin, RTpage);
1771
1772 if(pContext->funcs.EndPage != (int (*)())NULL)
1773 result = pContext->funcs.EndPage(pContext, pWin, TRUE);
1774 else
1775 return BadImplementation;
1776
1777 SendXpNotify(pContext, XPEndPageNotify, TRUE);
1778
1779 if(pPage)
1780 pPage->context = (XpContextPtr)NULL;
1781 }
1782 else
1783 return XpErrorBase+XPBadSequence;
1784 if(result != Success)
1785 return result;
1786 }
1787
1788 if(pContext->funcs.EndDoc != (int (*)())NULL)
1789 result = pContext->funcs.EndDoc(pContext, stuff->cancel);
1790 else
1791 return BadImplementation;
1792
1793 pContext->state &= ~DOC_RAW_STARTED;
1794 pContext->state &= ~DOC_COOKED_STARTED;
1795
1796 SendXpNotify(pContext, XPEndDocNotify, stuff->cancel);
1797
1798 if (client->noClientException != Success)
1799 return client->noClientException;
1800 else
1801 return result;
1802 }
1803
1804 static Bool
DoStartPage(client,c)1805 DoStartPage(client, c)
1806 ClientPtr client;
1807 XpStPagePtr c;
1808 {
1809 XpScreenPtr pPrintScreen;
1810 WindowPtr pWin = c->pWin;
1811 int result = Success;
1812 XpContextPtr pContext = c->pContext;
1813 XpPagePtr pPage;
1814
1815 if(c->pContext->state & JOB_GET_DATA &&
1816 !(c->pContext->state & GET_DOC_DATA_STARTED))
1817 {
1818 if(!c->slept)
1819 {
1820 c->slept = TRUE;
1821 ClientSleep(client, (ClientSleepProcPtr)DoStartPage, (pointer) c);
1822 c->pContext->clientSlept = client;
1823 }
1824 return TRUE;
1825 }
1826
1827 if(!(pContext->state & DOC_COOKED_STARTED))
1828 {
1829 /* Implied StartDoc if it was omitted */
1830 if(pContext->funcs.StartDoc != (int (*)())NULL)
1831 result = pContext->funcs.StartDoc(pContext, XPDocNormal);
1832 else
1833 {
1834 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
1835 BadImplementation);
1836 return TRUE;
1837 }
1838
1839 if(result != Success)
1840 {
1841 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0, result);
1842 return TRUE;
1843 }
1844
1845 pContext->state |= DOC_COOKED_STARTED;
1846 SendXpNotify(pContext, XPStartDocNotify, (int)FALSE);
1847 }
1848
1849 /* ensure the window's not already being used as a page */
1850 if((pPage = (XpPagePtr)LookupIDByType(c->pWin->drawable.id, RTpage)) !=
1851 (XpPagePtr)NULL)
1852 {
1853 if(pPage->context != (XpContextPtr)NULL)
1854 {
1855 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
1856 BadWindow);
1857 return TRUE;
1858 }
1859 }
1860 else
1861 {
1862 if((pPage = (XpPagePtr)xalloc(sizeof(XpPageRec))) == (XpPagePtr)NULL)
1863 {
1864 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
1865 BadAlloc);
1866 return TRUE;
1867 }
1868 if(AddResource(c->pWin->drawable.id, RTpage, pPage) == FALSE)
1869 {
1870 xfree(pPage);
1871 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
1872 BadAlloc);
1873 return TRUE;
1874 }
1875 }
1876
1877 pPage->context = pContext;
1878 pContext->pageWin = c->pWin->drawable.id;
1879
1880 pPrintScreen = XpScreens[pContext->screenNum];
1881
1882
1883 if(pContext->funcs.StartPage != (int (*)())NULL)
1884 result = pContext->funcs.StartPage(pContext, pWin);
1885 else
1886 {
1887 SendErrorToClient(client, XpReqCode, X_PrintStartPage, 0,
1888 BadImplementation);
1889 return TRUE;
1890 }
1891
1892 pContext->state |= PAGE_STARTED;
1893
1894 (void)MapWindow(pWin, client);
1895
1896 SendXpNotify(pContext, XPStartPageNotify, (int)FALSE);
1897
1898 return TRUE;
1899 }
1900
1901 static int
ProcXpStartPage(client)1902 ProcXpStartPage(client)
1903 ClientPtr client;
1904 {
1905 REQUEST(xPrintStartPageReq);
1906 XpScreenPtr pPrintScreen;
1907 WindowPtr pWin;
1908 int result = Success;
1909 XpContextPtr pContext;
1910 XpPagePtr pPage;
1911 XpStPagePtr c;
1912
1913 REQUEST_SIZE_MATCH(xPrintStartPageReq);
1914
1915 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
1916 == (XpContextPtr)NULL)
1917 return XpErrorBase+XPBadSequence;
1918
1919 if(!(pContext->state & JOB_STARTED))
1920 return XpErrorBase+XPBadSequence;
1921
1922 /* can't have pages in a raw documented */
1923 if(pContext->state & DOC_RAW_STARTED)
1924 return XpErrorBase+XPBadSequence;
1925
1926 if(pContext->state & PAGE_STARTED)
1927 return XpErrorBase+XPBadSequence;
1928
1929 pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
1930 SecurityWriteAccess);
1931 if (!pWin || pWin->drawable.pScreen->myNum != pContext->screenNum)
1932 return BadWindow;
1933
1934 if((c = (XpStPagePtr)xalloc(sizeof(XpStPageRec))) == (XpStPagePtr)NULL)
1935 return BadAlloc;
1936 c->pContext = pContext;
1937 c->slept = FALSE;
1938 c->pWin = pWin;
1939
1940 (void)DoStartPage(client, c);
1941
1942 if (client->noClientException != Success)
1943 return client->noClientException;
1944 else
1945 return result;
1946 }
1947
1948 static int
ProcXpEndPage(client)1949 ProcXpEndPage(client)
1950 ClientPtr client;
1951 {
1952 REQUEST(xPrintEndPageReq);
1953 XpScreenPtr pPrintScreen;
1954 int result = Success;
1955 XpContextPtr pContext;
1956 XpPagePtr page;
1957 WindowPtr pWin;
1958
1959 REQUEST_SIZE_MATCH(xPrintEndPageReq);
1960
1961 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
1962 == (XpContextPtr)NULL)
1963 return XpErrorBase+XPBadSequence;
1964
1965 if(!(pContext->state & PAGE_STARTED))
1966 return XpErrorBase+XPBadSequence;
1967
1968 pPrintScreen = XpScreens[pContext->screenNum];
1969 pWin = (WindowPtr )LookupIDByType(pContext->pageWin, RT_WINDOW);
1970
1971 /* Call the ddx's EndPage proc. */
1972 if(pContext->funcs.EndPage != (int (*)())NULL)
1973 result = pContext->funcs.EndPage(pContext, pWin, stuff->cancel);
1974 else
1975 return BadImplementation;
1976
1977 if((page = (XpPagePtr)LookupIDByType(pContext->pageWin, RTpage)) !=
1978 (XpPagePtr)NULL)
1979 page->context = (XpContextPtr)NULL;
1980
1981 pContext->state &= ~PAGE_STARTED;
1982 pContext->pageWin = 0; /* None, NULL??? XXX */
1983
1984 (void)UnmapWindow(pWin, FALSE);
1985
1986 SendXpNotify(pContext, XPEndPageNotify, stuff->cancel);
1987
1988 if (client->noClientException != Success)
1989 return client->noClientException;
1990 else
1991 return result;
1992 }
1993
1994 /*******************************************************************************
1995 *
1996 * Document Data Functions: PutDocumentData, GetDocumentData
1997 *
1998 ******************************************************************************/
1999
2000 static int
ProcXpPutDocumentData(client)2001 ProcXpPutDocumentData(client)
2002 ClientPtr client;
2003 {
2004 REQUEST(xPrintPutDocumentDataReq);
2005 XpContextPtr pContext;
2006 DrawablePtr pDraw;
2007 int result = Success;
2008 int len, totalSize;
2009 char *pData, *pDoc_fmt, *pOptions;
2010
2011 REQUEST_AT_LEAST_SIZE(xPrintPutDocumentDataReq);
2012
2013 if((pContext = (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr)
2014 == (XpContextPtr)NULL)
2015 return XpErrorBase+XPBadSequence;
2016
2017 if(!(pContext->state & DOC_RAW_STARTED) &&
2018 !(pContext->state & DOC_COOKED_STARTED))
2019 return XpErrorBase+XPBadSequence;
2020
2021 if (stuff->drawable) {
2022 if (pContext->state & DOC_RAW_STARTED)
2023 return BadDrawable;
2024 pDraw = (DrawablePtr)LookupDrawable(stuff->drawable, client);
2025 if (!pDraw || pDraw->pScreen->myNum != pContext->screenNum)
2026 return BadDrawable;
2027 } else {
2028 if (pContext->state & DOC_COOKED_STARTED)
2029 return BadDrawable;
2030 pDraw = NULL;
2031 }
2032
2033 pData = (char *)(&stuff[1]);
2034
2035 totalSize = (stuff->len_data + 3) >> 2;
2036 pDoc_fmt = pData + (totalSize << 2);
2037
2038 totalSize += (stuff->len_fmt + 3) >> 2;
2039 pOptions = pData + (totalSize << 2);
2040
2041 totalSize += (stuff->len_options + 3) >> 2;
2042 if((totalSize + (sz_xPrintPutDocumentDataReq >> 2)) != client->req_len)
2043 return BadLength;
2044
2045 if(pContext->funcs.PutDocumentData != (int (*)())NULL)
2046 {
2047 result = (*pContext->funcs.PutDocumentData)(pContext, pDraw,
2048 pData, stuff->len_data,
2049 pDoc_fmt, stuff->len_fmt,
2050 pOptions, stuff->len_options,
2051 client);
2052 }
2053 else
2054 return BadImplementation;
2055
2056 if (client->noClientException != Success)
2057 return client->noClientException;
2058 else
2059 return result;
2060 }
2061
2062 static int
ProcXpGetDocumentData(client)2063 ProcXpGetDocumentData(client)
2064 ClientPtr client;
2065 {
2066 REQUEST(xPrintGetDocumentDataReq);
2067 xPrintGetDocumentDataReply rep;
2068 XpScreenPtr pPrintScreen;
2069 XpContextPtr pContext;
2070 int result = Success;
2071
2072 REQUEST_SIZE_MATCH(xPrintGetDocumentDataReq);
2073
2074 if((pContext = (XpContextPtr)SecurityLookupIDByType(client,
2075 stuff->printContext,
2076 RTcontext,
2077 SecurityWriteAccess))
2078 == (XpContextPtr)NULL)
2079 {
2080 client->errorValue = stuff->printContext;
2081 return XpErrorBase+XPBadContext;
2082 }
2083
2084 if(pContext->funcs.GetDocumentData == (int (*)())NULL)
2085 return BadImplementation;
2086
2087 if(!(pContext->state & JOB_GET_DATA) ||
2088 pContext->state & GET_DOC_DATA_STARTED)
2089 return XpErrorBase+XPBadSequence;
2090
2091 if(stuff->maxBufferSize <= 0)
2092 {
2093 client->errorValue = stuff->maxBufferSize;
2094 return BadValue; /* gotta have a positive buffer size */
2095 }
2096
2097 result = (*pContext->funcs.GetDocumentData)(pContext, client,
2098 stuff->maxBufferSize);
2099 if(result != Success)
2100 {
2101 rep.type = X_Reply;
2102 rep.sequenceNumber = client->sequence;
2103 rep.length = 0;
2104 rep.dataLen = 0;
2105 rep.statusCode = 1;
2106 rep.finishedFlag = TRUE;
2107 if (client->swapped) {
2108 int n;
2109 long l;
2110
2111 swaps(&rep.sequenceNumber, n);
2112 swapl(&rep.statusCode, l); /* XXX Why are these longs??? */
2113 swapl(&rep.finishedFlag, l); /* XXX Why are these longs??? */
2114 }
2115 (void)WriteToClient(client,sz_xPrintGetDocumentDataReply,(char *)&rep);
2116 }
2117 else
2118 pContext->state |= GET_DOC_DATA_STARTED;
2119
2120 if(pContext->clientSlept != (ClientPtr)NULL)
2121 {
2122 ClientSignal(pContext->clientSlept);
2123 ClientWakeup(pContext->clientSlept);
2124 pContext->clientSlept = (ClientPtr)NULL;
2125 }
2126
2127 return result;
2128 }
2129
2130 /*******************************************************************************
2131 *
2132 * Attribute requests: GetAttributes, SetAttributes, GetOneAttribute
2133 *
2134 ******************************************************************************/
2135
2136 static int
ProcXpGetAttributes(client)2137 ProcXpGetAttributes(client)
2138 ClientPtr client;
2139 {
2140 REQUEST(xPrintGetAttributesReq);
2141 XpContextPtr pContext;
2142 char *attrs;
2143 xPrintGetAttributesReply *pRep;
2144 int totalSize, n;
2145 unsigned long l;
2146
2147 REQUEST_SIZE_MATCH(xPrintGetAttributesReq);
2148
2149 if(stuff->type < XPJobAttr || stuff->type > XPServerAttr)
2150 {
2151 client->errorValue = stuff->type;
2152 return BadValue;
2153 }
2154
2155 if(stuff->type != XPServerAttr)
2156 {
2157 if((pContext = (XpContextPtr)SecurityLookupIDByType(
2158 client,
2159 stuff->printContext,
2160 RTcontext,
2161 SecurityReadAccess))
2162 == (XpContextPtr)NULL)
2163 {
2164 client->errorValue = stuff->printContext;
2165 return XpErrorBase+XPBadContext;
2166 }
2167
2168 if(pContext->funcs.GetAttributes == (char *(*)())NULL)
2169 return BadImplementation;
2170 if((attrs = (*pContext->funcs.GetAttributes)(pContext, stuff->type)) ==
2171 (char *)NULL)
2172 return BadAlloc;
2173 }
2174 else
2175 {
2176 if((attrs = XpGetAttributes((XpContextPtr)NULL, XPServerAttr)) ==
2177 (char *)NULL)
2178 return BadAlloc;
2179 }
2180
2181 totalSize = sz_xPrintGetAttributesReply + QUADPAD(strlen(attrs));
2182 if((pRep = (xPrintGetAttributesReply *)malloc(totalSize)) ==
2183 (xPrintGetAttributesReply *)NULL)
2184 return BadAlloc;
2185
2186 pRep->type = X_Reply;
2187 pRep->length = (totalSize - sz_xPrintGetAttributesReply) >> 2;
2188 pRep->sequenceNumber = client->sequence;
2189 pRep->stringLen = strlen(attrs);
2190
2191 if (client->swapped) {
2192 swaps(&pRep->sequenceNumber, n);
2193 swapl(&pRep->length, l);
2194 swapl(&pRep->stringLen, l);
2195 }
2196
2197 strncpy((char*)(pRep + 1), attrs, strlen(attrs));
2198 xfree(attrs);
2199
2200 WriteToClient(client, totalSize, (char *)pRep);
2201
2202 xfree(pRep);
2203
2204 return client->noClientException;
2205 }
2206
2207 static int
ProcXpSetAttributes(client)2208 ProcXpSetAttributes(client)
2209 ClientPtr client;
2210 {
2211 REQUEST(xPrintSetAttributesReq);
2212 int result = Success;
2213 XpContextPtr pContext;
2214 char *attr;
2215
2216 REQUEST_AT_LEAST_SIZE(xPrintSetAttributesReq);
2217
2218 if(stuff->type < XPJobAttr || stuff->type > XPServerAttr)
2219 {
2220 client->errorValue = stuff->type;
2221 return BadValue;
2222 }
2223
2224 /*
2225 * Disallow changing of read-only attribute pools
2226 */
2227 if(stuff->type == XPPrinterAttr || stuff->type == XPServerAttr)
2228 return BadMatch;
2229
2230 if((pContext = (XpContextPtr)SecurityLookupIDByType(
2231 client,
2232 stuff->printContext,
2233 RTcontext,
2234 SecurityWriteAccess))
2235 == (XpContextPtr)NULL)
2236 {
2237 client->errorValue = stuff->printContext;
2238 return XpErrorBase+XPBadContext;
2239 }
2240
2241 if(pContext->funcs.SetAttributes == (int (*)())NULL)
2242 return BadImplementation;
2243
2244 /*
2245 * Check for attributes being set after their relevant phase
2246 * has already begun (e.g. Job attributes set after StartJob).
2247 */
2248 if((pContext->state & JOB_STARTED) && stuff->type == XPJobAttr)
2249 return XpErrorBase+XPBadSequence;
2250 if(((pContext->state & DOC_RAW_STARTED) ||
2251 (pContext->state & DOC_COOKED_STARTED)) && stuff->type == XPDocAttr)
2252 return XpErrorBase+XPBadSequence;
2253 if((pContext->state & PAGE_STARTED) && stuff->type == XPPageAttr)
2254 return XpErrorBase+XPBadSequence;
2255
2256 if((attr = (char *)malloc(stuff->stringLen + 1)) == (char *)NULL)
2257 return BadAlloc;
2258
2259 strncpy(attr, (char *)(stuff + 1), stuff->stringLen);
2260 attr[stuff->stringLen] = (char)'\0';
2261
2262 if(stuff->rule == XPAttrReplace)
2263 (*pContext->funcs.SetAttributes)(pContext, stuff->type, attr);
2264 else if(stuff->rule == XPAttrMerge)
2265 (*pContext->funcs.AugmentAttributes)(pContext, stuff->type, attr);
2266 else
2267 {
2268 client->errorValue = stuff->rule;
2269 result = BadValue;
2270 }
2271
2272 xfree(attr);
2273
2274 SendAttributeNotify(pContext, stuff->type);
2275
2276 return result;
2277 }
2278
2279 static int
ProcXpGetOneAttribute(client)2280 ProcXpGetOneAttribute(client)
2281 ClientPtr client;
2282 {
2283 REQUEST(xPrintGetOneAttributeReq);
2284 XpContextPtr pContext;
2285 char *value, *attrName;
2286 xPrintGetOneAttributeReply *pRep;
2287 int totalSize, n;
2288 unsigned long l;
2289
2290 REQUEST_AT_LEAST_SIZE(xPrintGetOneAttributeReq);
2291
2292 totalSize = ((sz_xPrintGetOneAttributeReq) >> 2) +
2293 ((stuff->nameLen + 3) >> 2);
2294 if(totalSize != client->req_len)
2295 return BadLength;
2296
2297 if(stuff->type < XPJobAttr || stuff->type > XPServerAttr)
2298 {
2299 client->errorValue = stuff->type;
2300 return BadValue;
2301 }
2302
2303 if((attrName = (char *)malloc(stuff->nameLen + 1)) == (char *)NULL)
2304 return BadAlloc;
2305 strncpy(attrName, (char *)(stuff+1), stuff->nameLen);
2306 attrName[stuff->nameLen] = (char)'\0';
2307
2308 if(stuff->type != XPServerAttr)
2309 {
2310 if((pContext = (XpContextPtr)SecurityLookupIDByType(
2311 client,
2312 stuff->printContext,
2313 RTcontext,
2314 SecurityReadAccess))
2315 == (XpContextPtr)NULL)
2316 {
2317 client->errorValue = stuff->printContext;
2318 return XpErrorBase+XPBadContext;
2319 }
2320
2321 if(pContext->funcs.GetOneAttribute == (char *(*)())NULL)
2322 return BadImplementation;
2323 if((value = (*pContext->funcs.GetOneAttribute)(pContext, stuff->type,
2324 attrName)) == (char *)NULL)
2325 return BadAlloc;
2326 }
2327 else
2328 {
2329 if((value = XpGetOneAttribute((XpContextPtr)NULL, XPServerAttr,
2330 attrName)) == (char *)NULL)
2331 return BadAlloc;
2332 }
2333
2334 free(attrName);
2335
2336 totalSize = sz_xPrintGetOneAttributeReply + QUADPAD(strlen(value));
2337 if((pRep = (xPrintGetOneAttributeReply *)malloc(totalSize)) ==
2338 (xPrintGetOneAttributeReply *)NULL)
2339 return BadAlloc;
2340
2341 pRep->type = X_Reply;
2342 pRep->length = (totalSize - sz_xPrintGetOneAttributeReply) >> 2;
2343 pRep->sequenceNumber = client->sequence;
2344 pRep->valueLen = strlen(value);
2345
2346 if (client->swapped) {
2347 swaps(&pRep->sequenceNumber, n);
2348 swapl(&pRep->length, l);
2349 swapl(&pRep->valueLen, l);
2350 }
2351
2352 strncpy((char*)(pRep + 1), value, strlen(value));
2353
2354 WriteToClient(client, totalSize, (char *)pRep);
2355
2356 xfree(pRep);
2357
2358 return client->noClientException;
2359 }
2360
2361 /*******************************************************************************
2362 *
2363 * Print Event requests: SelectInput InputSelected, SendXpNotify
2364 *
2365 ******************************************************************************/
2366
2367
2368 static int
ProcXpSelectInput(client)2369 ProcXpSelectInput(client)
2370 ClientPtr client;
2371 {
2372 REQUEST(xPrintSelectInputReq);
2373 int result = Success;
2374 XpContextPtr pContext;
2375 XpClientPtr pPrintClient;
2376
2377 REQUEST_SIZE_MATCH(xPrintSelectInputReq);
2378
2379 /*
2380 * Check to see that the supplied XID is really a valid print context
2381 * in this server.
2382 */
2383 if((pContext=(XpContextPtr)SecurityLookupIDByType(client,
2384 stuff->printContext,
2385 RTcontext,
2386 SecurityWriteAccess))
2387 == (XpContextPtr)NULL)
2388 {
2389 client->errorValue = stuff->printContext;
2390 return XpErrorBase+XPBadContext;
2391 }
2392
2393 if(stuff->eventMask & ~allEvents)
2394 {
2395 client->errorValue = stuff->eventMask;
2396 return BadValue; /* bogus event mask bits */
2397 }
2398
2399 if((pPrintClient = AcquireClient(pContext, client)) == (XpClientPtr)NULL)
2400 return BadAlloc;
2401
2402 pPrintClient->eventMask = stuff->eventMask;
2403
2404 return result;
2405 }
2406
2407 static int
ProcXpInputSelected(client)2408 ProcXpInputSelected(client)
2409 ClientPtr client;
2410 {
2411 REQUEST(xPrintInputSelectedReq);
2412 xPrintInputSelectedReply rep;
2413 register int n;
2414 long l, allMask;
2415 WindowPtr pWin;
2416 XpClientPtr pXpClient;
2417 XpContextPtr pContext;
2418
2419 REQUEST_SIZE_MATCH(xPrintInputSelectedReq);
2420
2421 if((pContext=(XpContextPtr)SecurityLookupIDByType(client,
2422 stuff->printContext,
2423 RTcontext,
2424 SecurityReadAccess))
2425 == (XpContextPtr)NULL)
2426 {
2427 client->errorValue = stuff->printContext;
2428 return XpErrorBase+XPBadContext;
2429 }
2430
2431 pXpClient = FindClient(pContext, client);
2432
2433 rep.type = X_Reply;
2434 rep.length = 0;
2435 rep.sequenceNumber = client->sequence;
2436 rep.eventMask = (pXpClient != (XpClientPtr)NULL)? pXpClient->eventMask : 0;
2437 rep.allEventsMask = GetAllEventMasks(pContext);
2438
2439 if (client->swapped) {
2440 swaps(&rep.sequenceNumber, n);
2441 swapl(&rep.length, l);
2442 swapl(&rep.eventMask, l);
2443 swapl(&rep.allEventsMask, l);
2444 }
2445
2446 WriteToClient(client, sz_xPrintInputSelectedReply, (char *)&rep);
2447 return client->noClientException;
2448 }
2449
2450 static void
SendAttributeNotify(pContext,which)2451 SendAttributeNotify(pContext, which)
2452 XpContextPtr pContext;
2453 int which;
2454 {
2455 XpClientPtr pXpClient;
2456 xPrintAttributeEvent ae;
2457 ClientPtr client;
2458
2459 pXpClient = pContext->clientHead;
2460 if(pXpClient == (XpClientPtr)NULL)
2461 return; /* Nobody's interested in the events (or this context). */
2462
2463 for (pXpClient = pContext->clientHead;
2464 pXpClient != (XpClientPtr)NULL;
2465 pXpClient = pXpClient->pNext)
2466 {
2467 client = pXpClient->client;
2468 if (client == serverClient || client->clientGone ||
2469 !(pXpClient->eventMask & XPAttributeMask))
2470 continue;
2471 ae.type = XPAttributeNotify + XpEventBase;
2472 ae.detail = which;
2473 ae.printContext = pContext->contextID;
2474 ae.sequenceNumber = client->sequence;
2475 WriteEventsToClient (client, 1, (xEvent *) &ae);
2476 }
2477 }
2478 static void
SendXpNotify(pContext,which,val)2479 SendXpNotify(pContext, which, val)
2480 XpContextPtr pContext;
2481 int which;
2482 int val;
2483 {
2484 XpClientPtr pXpClient;
2485 xPrintPrintEvent pe;
2486 ClientPtr client;
2487
2488 pXpClient = pContext->clientHead;
2489 if(pXpClient == (XpClientPtr)NULL)
2490 return; /* Nobody's interested in the events (or this context). */
2491
2492 for (pXpClient = pContext->clientHead;
2493 pXpClient != (XpClientPtr)NULL;
2494 pXpClient = pXpClient->pNext)
2495 {
2496 client = pXpClient->client;
2497 if (client == serverClient || client->clientGone ||
2498 !(pXpClient->eventMask & XPPrintMask))
2499 continue;
2500 pe.type = XPPrintNotify + XpEventBase;
2501 pe.detail = which;
2502 pe.printContext = pContext->contextID;
2503 pe.cancel = (Bool)val;
2504 pe.sequenceNumber = client->sequence;
2505 WriteEventsToClient (client, 1, (xEvent *) &pe);
2506 }
2507 }
2508
2509 static CARD32
GetAllEventMasks(pContext)2510 GetAllEventMasks(pContext)
2511 XpContextPtr pContext;
2512 {
2513 XpClientPtr pPrintClient;
2514 CARD32 totalMask = (CARD32)0;
2515
2516 for (pPrintClient = pContext->clientHead;
2517 pPrintClient != (XpClientPtr)NULL;
2518 pPrintClient = pPrintClient->pNext)
2519 {
2520 totalMask |= pPrintClient->eventMask;
2521 }
2522 return totalMask;
2523 }
2524
2525 /*
2526 * XpContextOfClient - returns the XpContextPtr to the context
2527 * associated with the specified client, or NULL if the client
2528 * does not currently have a context set.
2529 */
2530 XpContextPtr
XpContextOfClient(client)2531 XpContextOfClient(client)
2532 ClientPtr client;
2533 {
2534 XpContextPtr pContext;
2535
2536 return (XpContextPtr)client->devPrivates[XpClientPrivateIndex].ptr;
2537 }
2538
2539
2540 /*******************************************************************************
2541 *
2542 * Swap-request functions
2543 *
2544 ******************************************************************************/
2545
2546 static int
SProcXpCreateContext(client)2547 SProcXpCreateContext(client)
2548 ClientPtr client;
2549 {
2550 int i;
2551 long n;
2552
2553 REQUEST(xPrintCreateContextReq);
2554
2555 swaps(&stuff->length, i);
2556 swapl(&stuff->contextID, n);
2557 swapl(&stuff->printerNameLen, n);
2558 swapl(&stuff->localeLen, n);
2559 return ProcXpCreateContext(client);
2560 }
2561
2562 static int
SProcXpGetPrinterList(client)2563 SProcXpGetPrinterList(client)
2564 ClientPtr client;
2565 {
2566 int i;
2567 long n;
2568
2569 REQUEST(xPrintGetPrinterListReq);
2570
2571 swaps(&stuff->length, i);
2572 swapl(&stuff->printerNameLen, n);
2573 swapl(&stuff->localeLen, n);
2574 return ProcXpGetPrinterList(client);
2575 }
2576
2577 static int
SProcXpRehashPrinterList(client)2578 SProcXpRehashPrinterList(client)
2579 ClientPtr client;
2580 {
2581 int i;
2582 long n;
2583
2584 REQUEST(xPrintRehashPrinterListReq);
2585 swaps(&stuff->length, i);
2586 return ProcXpRehashPrinterList(client);
2587 }
2588
2589 static int
SProcXpSetContext(client)2590 SProcXpSetContext(client)
2591 ClientPtr client;
2592 {
2593 int i;
2594 long n;
2595
2596 REQUEST(xPrintSetContextReq);
2597 swaps(&stuff->length, i);
2598 swapl(&stuff->printContext, i);
2599 return ProcXpSetContext(client);
2600 }
2601
2602 static int
SProcXpGetContext(client)2603 SProcXpGetContext(client)
2604 ClientPtr client;
2605 {
2606 int i;
2607
2608 REQUEST(xPrintGetContextReq);
2609 swaps(&stuff->length, i);
2610 return ProcXpGetContext(client);
2611 }
2612
2613 static int
SProcXpDestroyContext(client)2614 SProcXpDestroyContext(client)
2615 ClientPtr client;
2616 {
2617 int i;
2618 long n;
2619
2620 REQUEST(xPrintDestroyContextReq);
2621 swaps(&stuff->length, i);
2622 swapl(&stuff->printContext, n);
2623 return ProcXpDestroyContext(client);
2624 }
2625
2626 static int
SProcXpGetContextScreen(client)2627 SProcXpGetContextScreen(client)
2628 ClientPtr client;
2629 {
2630 int i;
2631 long n;
2632
2633 REQUEST(xPrintGetContextScreenReq);
2634 swaps(&stuff->length, i);
2635 swapl(&stuff->printContext, n);
2636 return ProcXpGetContextScreen(client);
2637 }
2638
2639 static int
SProcXpInputSelected(client)2640 SProcXpInputSelected(client)
2641 ClientPtr client;
2642 {
2643 int i;
2644 long n;
2645
2646 REQUEST(xPrintInputSelectedReq);
2647 swaps(&stuff->length, i);
2648 swapl(&stuff->printContext, n);
2649 return ProcXpInputSelected(client);
2650 }
2651
2652 static int
SProcXpStartJob(client)2653 SProcXpStartJob(client)
2654 ClientPtr client;
2655 {
2656 int i;
2657
2658 REQUEST(xPrintStartJobReq);
2659 swaps(&stuff->length, i);
2660 return ProcXpStartJob(client);
2661 }
2662
2663 static int
SProcXpEndJob(client)2664 SProcXpEndJob(client)
2665 ClientPtr client;
2666 {
2667 int i;
2668
2669 REQUEST(xPrintEndJobReq);
2670 swaps(&stuff->length, i);
2671 return ProcXpEndJob(client);
2672 }
2673
2674 static int
SProcXpStartDoc(client)2675 SProcXpStartDoc(client)
2676 ClientPtr client;
2677 {
2678 int i;
2679
2680 REQUEST(xPrintStartDocReq);
2681 swaps(&stuff->length, i);
2682 return ProcXpStartDoc(client);
2683 }
2684
2685 static int
SProcXpEndDoc(client)2686 SProcXpEndDoc(client)
2687 ClientPtr client;
2688 {
2689 int i;
2690
2691 REQUEST(xPrintEndDocReq);
2692 swaps(&stuff->length, i);
2693 return ProcXpEndDoc(client);
2694 }
2695
2696 static int
SProcXpStartPage(client)2697 SProcXpStartPage(client)
2698 ClientPtr client;
2699 {
2700 int i;
2701 long n;
2702
2703 REQUEST(xPrintStartPageReq);
2704 swaps(&stuff->length, i);
2705 swapl(&stuff->window, n);
2706 return ProcXpStartPage(client);
2707 }
2708
2709 static int
SProcXpEndPage(client)2710 SProcXpEndPage(client)
2711 ClientPtr client;
2712 {
2713 int i;
2714
2715 REQUEST(xPrintEndPageReq);
2716 swaps(&stuff->length, i);
2717 return ProcXpEndPage(client);
2718 }
2719
2720 static int
SProcXpPutDocumentData(client)2721 SProcXpPutDocumentData(client)
2722 ClientPtr client;
2723 {
2724 long n;
2725 int i;
2726
2727 REQUEST(xPrintPutDocumentDataReq);
2728 swaps(&stuff->length, i);
2729 swapl(&stuff->drawable, n);
2730 swapl(&stuff->len_data, n);
2731 swaps(&stuff->len_fmt, i);
2732 swaps(&stuff->len_options, i);
2733 return ProcXpPutDocumentData(client);
2734 }
2735
2736 static int
SProcXpGetDocumentData(client)2737 SProcXpGetDocumentData(client)
2738 ClientPtr client;
2739 {
2740 long n;
2741 int i;
2742
2743 REQUEST(xPrintGetDocumentDataReq);
2744 swaps(&stuff->length, i);
2745 swapl(&stuff->printContext, n);
2746 swapl(&stuff->maxBufferSize, n);
2747 return ProcXpGetDocumentData(client);
2748 }
2749
2750 static int
SProcXpGetAttributes(client)2751 SProcXpGetAttributes(client)
2752 ClientPtr client;
2753 {
2754 long n;
2755 int i;
2756
2757 REQUEST(xPrintGetAttributesReq);
2758 swaps(&stuff->length, i);
2759 swapl(&stuff->printContext, n);
2760 return ProcXpGetAttributes(client);
2761 }
2762
2763 static int
SProcXpSetAttributes(client)2764 SProcXpSetAttributes(client)
2765 ClientPtr client;
2766 {
2767 long n;
2768 int i;
2769
2770 REQUEST(xPrintSetAttributesReq);
2771 swaps(&stuff->length, i);
2772 swapl(&stuff->printContext, n);
2773 swapl(&stuff->stringLen, n);
2774 return ProcXpSetAttributes(client);
2775 }
2776
2777 static int
SProcXpGetOneAttribute(client)2778 SProcXpGetOneAttribute(client)
2779 ClientPtr client;
2780 {
2781 long n;
2782 int i;
2783
2784 REQUEST(xPrintGetOneAttributeReq);
2785 swaps(&stuff->length, i);
2786 swapl(&stuff->printContext, n);
2787 swapl(&stuff->nameLen, n);
2788 return ProcXpGetOneAttribute(client);
2789 }
2790
2791 static int
SProcXpSelectInput(client)2792 SProcXpSelectInput(client)
2793 ClientPtr client;
2794 {
2795 long n;
2796 int i;
2797
2798 REQUEST(xPrintSelectInputReq);
2799 swaps(&stuff->length, i);
2800 swapl(&stuff->eventMask, n);
2801 swapl(&stuff->printContext, n);
2802 return ProcXpSelectInput(client);
2803 }
2804 static int
SProcXpGetPageDimensions(client)2805 SProcXpGetPageDimensions(client)
2806 ClientPtr client;
2807 {
2808 long n;
2809 int i;
2810
2811 REQUEST(xPrintGetPageDimensionsReq);
2812 swaps(&stuff->length, i);
2813 swapl(&stuff->printContext, n);
2814 return ProcXpGetPageDimensions(client);
2815 }
2816 static int
SProcXpSetImageResolution(client)2817 SProcXpSetImageResolution(client)
2818 ClientPtr client;
2819 {
2820 long n;
2821 int i;
2822
2823 REQUEST(xPrintSetImageResolutionReq);
2824 swaps(&stuff->length, i);
2825 swapl(&stuff->printContext, n);
2826 swaps(&stuff->imageRes, i);
2827 return ProcXpSetImageResolution(client);
2828 }
2829 static int
SProcXpGetImageResolution(client)2830 SProcXpGetImageResolution(client)
2831 ClientPtr client;
2832 {
2833 long n;
2834 int i;
2835
2836 REQUEST(xPrintGetImageResolutionReq);
2837 swaps(&stuff->length, i);
2838 swapl(&stuff->printContext, n);
2839 return ProcXpGetImageResolution(client);
2840 }
2841
2842 static void
SwapXpNotifyEvent(src,dst)2843 SwapXpNotifyEvent(src, dst)
2844 xPrintPrintEvent *src, *dst;
2845 {
2846 /*
2847 * Swap the sequence number and context fields.
2848 */
2849 cpswaps(src->sequenceNumber, dst->sequenceNumber);
2850 cpswapl(src->printContext, dst->printContext);
2851
2852 /*
2853 * Copy the byte-long fields.
2854 */
2855 dst->type = src->type;
2856 dst->detail = src->detail;
2857 dst->cancel = src->cancel;
2858 }
2859
2860 static void
SwapXpAttributeEvent(src,dst)2861 SwapXpAttributeEvent(src, dst)
2862 xPrintAttributeEvent *src, *dst;
2863 {
2864 /*
2865 * Swap the sequence number and context fields.
2866 */
2867 cpswaps(src->sequenceNumber, dst->sequenceNumber);
2868 cpswapl(src->printContext, dst->printContext);
2869
2870 /*
2871 * Copy the byte-long fields.
2872 */
2873 dst->type = src->type;
2874 dst->detail = src->detail;
2875 }
2876