~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to Xprint/raster/Raster.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: Raster.c,v 1.4 2001/03/14 18:46:12 pookie Exp $ */
 
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
/* $XFree86: xc/programs/Xserver/Xprint/raster/Raster.c,v 1.11tsi Exp $ */
 
35
 
 
36
/*******************************************************************
 
37
**
 
38
**    *********************************************************
 
39
**    *
 
40
**    *  File:          printer/Raster.c
 
41
**    *
 
42
**    *  Contents:
 
43
**    *                 Raster driver for the print server.
 
44
**    *
 
45
**    *  Copyright:     Copyright 1993, 1995 Hewlett-Packard Company
 
46
**    *
 
47
**    *********************************************************
 
48
** 
 
49
********************************************************************/
 
50
 
 
51
#ifdef HAVE_DIX_CONFIG_H
 
52
#include <dix-config.h>
 
53
#endif
 
54
 
 
55
#include <errno.h>
 
56
#include <stdio.h>
 
57
#include <string.h>
 
58
#include <sys/stat.h>
 
59
#include <sys/wait.h>
 
60
#include <unistd.h>
 
61
#include <sys/types.h>
 
62
#include <sys/stat.h>
 
63
#include <X11/X.h>
 
64
#include <X11/Xos.h>    /* for SIGCLD on pre-POSIX systems */
 
65
#define NEED_EVENTS
 
66
#include <X11/Xproto.h>
 
67
#undef NEED_EVENTS
 
68
#include <X11/Xatom.h>
 
69
#include "misc.h"
 
70
#include "dixstruct.h"
 
71
#include "scrnintstr.h"
 
72
#include "screenint.h"
 
73
#include "colormapst.h"
 
74
#include "windowstr.h"
 
75
#include "propertyst.h"
 
76
#include "servermd.h"   /* needed for IMAGE_BUFSIZE */
 
77
#include "mfb.h"
 
78
#include "mi.h"
 
79
 
 
80
#include <X11/extensions/Print.h>
 
81
#include "Raster.h"
 
82
 
 
83
#include "attributes.h"
 
84
#include "AttrValid.h"
 
85
#include "DiPrint.h"
 
86
 
 
87
static void AllocateRasterPrivates(
 
88
    ScreenPtr pScreen);
 
89
static Bool RasterChangeWindowAttributes(
 
90
    WindowPtr pWin,
 
91
    unsigned long   mask);
 
92
static int StartJob(
 
93
    XpContextPtr pCon,
 
94
    Bool sendClientData,
 
95
    ClientPtr client);
 
96
static int StartPage(
 
97
    XpContextPtr pCon,
 
98
    WindowPtr pWin);
 
99
static int StartDoc(
 
100
    XpContextPtr pCon,
 
101
    XPDocumentType type);
 
102
static int EndDoc(
 
103
    XpContextPtr pCon,
 
104
    Bool cancel);
 
105
static int EndJob(
 
106
    XpContextPtr pCon,
 
107
    Bool cancel);
 
108
static int EndPage(
 
109
    XpContextPtr pCon,
 
110
    WindowPtr pWin);
 
111
static int DocumentData(
 
112
    XpContextPtr pCon,
 
113
    DrawablePtr pDraw,
 
114
    char *pData,
 
115
    int len_data,
 
116
    char *pDoc_fmt,
 
117
    int len_fmt,
 
118
    char *pOptions,
 
119
    int len_options,
 
120
    ClientPtr client);
 
121
static int GetDocumentData(
 
122
    XpContextPtr pContext,
 
123
    ClientPtr client,
 
124
    int maxBufferSize);
 
125
static void FreePageFiles(
 
126
    RasterContextPrivPtr pWinPriv);
 
127
static int SystemCmd(
 
128
    char *pCommand);
 
129
static Bool RasterCloseScreen(
 
130
    int index,
 
131
    ScreenPtr pScreen);
 
132
static int RasterInitContext(XpContextPtr pCon);
 
133
static Bool RasterDestroyContext(XpContextPtr pCon);
 
134
static char *RasterGetAttributes(
 
135
                XpContextPtr pContext,
 
136
                XPAttributes class);
 
137
static char *RasterGetOneAttribute(XpContextPtr pCon,
 
138
                           XPAttributes class, 
 
139
                           char *attribute);
 
140
static int RasterSetAttributes(XpContextPtr pCon,
 
141
                          XPAttributes class,
 
142
                          char *attributes);
 
143
static int RasterAugmentAttributes(XpContextPtr pCon,
 
144
                              XPAttributes class,
 
145
                              char *attributes);
 
146
static int RasterMediumDimensions(XpContextPtr pCon,
 
147
                              CARD16 *width,
 
148
                              CARD16 *height);
 
149
static int RasterReproducibleArea(XpContextPtr pCon,
 
150
                              xRectangle *pRect);
 
151
 
 
152
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
 
153
#define DOC_PCL         1
 
154
#define DOC_RASTER      2
 
155
 
 
156
static int RasterScreenPrivateIndex, RasterContextPrivateIndex;
 
157
static int RasterGeneration = 0;
 
158
static char RASTER_DRIV_NAME[] = "XP-RASTER";
 
159
static int doc_type = DOC_RASTER;
 
160
 
 
161
#define ABSOLUTE_PCLCOMP_PATH1 "/usr/openwin/bin/pclcomp"
 
162
#define ABSOLUTE_PCLCOMP_PATH2 "/usr/X11/bin/pclcomp"
 
163
 
 
164
static char *pcl3_output_cmds[] = {
 
165
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0 > %(OutFile)%",
 
166
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -01 > %(OutFile)%",
 
167
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -02 > %(OutFile)%",
 
168
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -03 > %(OutFile)%",
 
169
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -012 > %(OutFile)%",
 
170
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -013 > %(OutFile)%",
 
171
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -023 > %(OutFile)%",
 
172
        "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0123 > %(OutFile)%",
 
173
        "xpr -device ljet -rv -landscape < %(InFile)% > %(OutFile)%",
 
174
        "xpr -device ljet -rv < %(InFile)% | pclcomp -0 > %(OutFile)%",
 
175
        "xpr -device ljet -rv < %(InFile)% | pclcomp -01 > %(OutFile)%",
 
176
        "xpr -device ljet -rv < %(InFile)% | pclcomp -02 > %(OutFile)%",
 
177
        "xpr -device ljet -rv < %(InFile)% | pclcomp -03 > %(OutFile)%",
 
178
        "xpr -device ljet -rv < %(InFile)% | pclcomp -012 > %(OutFile)%",
 
179
        "xpr -device ljet -rv < %(InFile)% | pclcomp -013 > %(OutFile)%",
 
180
        "xpr -device ljet -rv < %(InFile)% | pclcomp -023 > %(OutFile)%",
 
181
        "xpr -device ljet -rv < %(InFile)% | pclcomp -0123 > %(OutFile)%",
 
182
        "xpr -device ljet -rv < %(InFile)% > %(OutFile)%"};
 
183
 
 
184
Bool
 
185
InitializeRasterDriver(
 
186
     int ndx,
 
187
     ScreenPtr pScreen,
 
188
     int argc,
 
189
     char **argv)
 
190
{
 
191
    int xRes, yRes;
 
192
    int maxRes, maxDim, numBytes;
 
193
    RasterScreenPrivPtr pPriv;
 
194
    
 
195
    /*
 
196
     * Register this driver's InitContext function with the print extension.
 
197
     * This is a bit
 
198
     * sleazy, as the extension hasn't yet been initialized, but the
 
199
     * extension needs to know this, and this seems the best time to
 
200
     * provide the information.
 
201
     */
 
202
    XpRegisterInitFunc( pScreen, RASTER_DRIV_NAME, RasterInitContext );
 
203
 
 
204
    /*
 
205
     * Create and load the devPrivate for the printer layer.
 
206
     */
 
207
    AllocateRasterPrivates(pScreen);
 
208
   
 
209
    pPriv = (RasterScreenPrivPtr)
 
210
      pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
 
211
 
 
212
    maxDim = MAX( pScreen->height, pScreen->width );
 
213
    numBytes = maxDim + BITMAP_SCANLINE_PAD - 1; /* pixels per row */
 
214
    numBytes *= maxDim;
 
215
    numBytes /=  8; /* bytes per row */
 
216
    xRes = pScreen->width / (pScreen->mmWidth / 25.4);
 
217
    yRes = pScreen->height / (pScreen->mmHeight / 25.4);
 
218
    maxRes = MAX( xRes, yRes );
 
219
 
 
220
    pPriv->pBits = (char *)xalloc(numBytes);
 
221
 
 
222
    /*
 
223
     * Have to allocate maxDim X maxDim to allow for landscape mode.
 
224
     */
 
225
    mfbScreenInit(pScreen, pPriv->pBits, maxDim, maxDim, maxRes,
 
226
                  maxRes, maxDim);
 
227
    miInitializeBackingStore(pScreen);
 
228
    pScreen->blackPixel = 1;
 
229
    pScreen->whitePixel = 0;
 
230
    if(mfbCreateDefColormap(pScreen) == FALSE)
 
231
        ; /* XXX what do I do if it fails? */
 
232
    
 
233
    /*
 
234
    cfbScreenInit(pScreen, pPriv->pBits, maxWidth, maxHeight, maxXres,
 
235
                  maxYres, maxWidth);
 
236
    miInitializeBackingStore(pScreen);
 
237
    scalingScreenInit(pScreen);
 
238
    */
 
239
 
 
240
    pScreen->SaveScreen = (SaveScreenProcPtr)_XpBoolNoop;
 
241
    pPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
 
242
    pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes;
 
243
    pPriv->CloseScreen = pScreen->CloseScreen;
 
244
    pScreen->CloseScreen = RasterCloseScreen;
 
245
 
 
246
    return TRUE;
 
247
}
 
248
 
 
249
/*
 
250
 * GetPropString searches the context's config database for a property
 
251
 * by the name of propName.  If found, it returns the property's
 
252
 * value, otherwise it returns NULL unless the requested attribute
 
253
 * is RASTER_PRINT_PAGE_COMMAND, in which case it returns a hard-coded
 
254
 * default string to invoke xpr to produce a PostScript(tm) formatted
 
255
 * raster.
 
256
 */
 
257
 
 
258
static char *
 
259
GetPropString(
 
260
     XpContextPtr pCon,
 
261
     char *propName)
 
262
{
 
263
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
264
      pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
265
    char *type;
 
266
    XrmValue val;
 
267
    struct stat status;
 
268
    int pclcomp_exists = 0;
 
269
 
 
270
    if( XrmGetResource(pConPriv->config, propName, propName, &type, &val) == 
 
271
       True )
 
272
        return (char *)val.addr;
 
273
 
 
274
    if( !strcmp( propName, RASTER_PRINT_PAGE_COMMAND ) )
 
275
      if( doc_type == DOC_RASTER )
 
276
        return "xpr -device ps %(InFile)% > %(OutFile)%";
 
277
      else
 
278
      {
 
279
        XpOid orientation;
 
280
        XpOid compression;
 
281
        int   pcl3_output_index = 0;
 
282
 
 
283
        orientation = XpGetContentOrientation(pCon);
 
284
        compression = XpGetAvailableCompression(pCon);
 
285
 
 
286
        switch(orientation) {
 
287
        case xpoid_val_content_orientation_landscape:
 
288
           pcl3_output_index = 0;
 
289
           break;
 
290
        default:
 
291
           pcl3_output_index += 9;
 
292
           break;
 
293
        }
 
294
 
 
295
        if(stat(ABSOLUTE_PCLCOMP_PATH1, &status) != -1)
 
296
           pclcomp_exists = 1;
 
297
        else if(stat(ABSOLUTE_PCLCOMP_PATH2, &status) != -1)
 
298
           pclcomp_exists = 1;
 
299
 
 
300
        if(pclcomp_exists)
 
301
           switch(compression) {
 
302
           case xpoid_val_available_compressions_0:
 
303
              pcl3_output_index += 0;
 
304
              break;
 
305
           case xpoid_val_available_compressions_01:
 
306
              pcl3_output_index += 1;
 
307
              break;
 
308
           case xpoid_val_available_compressions_02:
 
309
              pcl3_output_index += 2;
 
310
              break;
 
311
           case xpoid_val_available_compressions_03:
 
312
              pcl3_output_index += 3;
 
313
              break;
 
314
           case xpoid_val_available_compressions_012:
 
315
              pcl3_output_index += 4;
 
316
              break;
 
317
           case xpoid_val_available_compressions_013:
 
318
              pcl3_output_index += 5;
 
319
              break;
 
320
           case xpoid_val_available_compressions_023:
 
321
              pcl3_output_index += 6;
 
322
              break;
 
323
           default:
 
324
              pcl3_output_index += 7;
 
325
              break;
 
326
           }
 
327
        else
 
328
           pcl3_output_index += 8;
 
329
 
 
330
        return pcl3_output_cmds[pcl3_output_index];
 
331
      }
 
332
    else
 
333
      return NULL;
 
334
}
 
335
 
 
336
static void
 
337
SetDocumentType(
 
338
     XpContextPtr pCon)
 
339
{
 
340
    XpOidList* attrs_supported;
 
341
 
 
342
    /*
 
343
     * only validate attributes found in document-attributes-supported
 
344
     */
 
345
    attrs_supported =
 
346
        XpGetListAttr(pCon, XPPrinterAttr,
 
347
                      xpoid_att_document_attributes_supported,
 
348
                      (const XpOidList*)NULL);
 
349
 
 
350
    if(XpOidListHasOid(attrs_supported, xpoid_att_document_format))
 
351
    {
 
352
        const char* value_in;
 
353
        XpOidDocFmt *f;
 
354
 
 
355
        value_in = XpGetStringAttr(pCon, XPDocAttr, xpoid_att_document_format);
 
356
 
 
357
        f = XpOidDocFmtNew( value_in );
 
358
 
 
359
        if( f != NULL )
 
360
        {
 
361
            if( !strcmp( f->format, "PCL" ) )
 
362
                doc_type = DOC_PCL;
 
363
            else
 
364
                doc_type = DOC_RASTER;
 
365
 
 
366
            XpOidDocFmtDelete( f );
 
367
        }
 
368
    }
 
369
 
 
370
    /*
 
371
     * clean up
 
372
     */
 
373
    XpOidListDelete(attrs_supported);
 
374
}
 
375
 
 
376
static int
 
377
StartJob(
 
378
     XpContextPtr pCon,
 
379
     Bool sendClientData,
 
380
     ClientPtr client)
 
381
{
 
382
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
383
                         pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
384
 
 
385
    SetDocumentType( pCon );
 
386
 
 
387
    /*
 
388
     * Check for existing page file, and delete it if it exists.
 
389
     */
 
390
    if(pConPriv->pageFileName != (char *)NULL)
 
391
    {
 
392
        if(pConPriv->pPageFile != (FILE *)NULL)
 
393
        {
 
394
            fclose(pConPriv->pPageFile);
 
395
            pConPriv->pPageFile = (FILE *)NULL;
 
396
        }
 
397
        unlink(pConPriv->pageFileName);
 
398
        Xfree(pConPriv->pageFileName);
 
399
        pConPriv->pageFileName = (char *)NULL;
 
400
    }
 
401
 
 
402
    /* 
 
403
     * Create a temporary file to store the printer output.
 
404
     */
 
405
    if(!sendClientData)
 
406
    {
 
407
        /* 
 
408
         * Create a temporary file to store the printer output.
 
409
         */
 
410
        if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
 
411
            return BadAlloc;
 
412
    }
 
413
 
 
414
    return Success;
 
415
}
 
416
 
 
417
/*
 
418
 * StartDoc and EndDoc are just no-ops in this implementation, since
 
419
 * our view of the spooler really doesn't recognize documents.
 
420
 */
 
421
 
 
422
static int 
 
423
StartDoc(
 
424
     XpContextPtr pCon,
 
425
     XPDocumentType type)
 
426
{
 
427
    return Success;
 
428
}
 
429
 
 
430
static int EndDoc(
 
431
     XpContextPtr pCon,
 
432
     Bool cancel)
 
433
{
 
434
    return Success;
 
435
}
 
436
 
 
437
#if 0
 
438
 
 
439
/* XXX Not used. */
 
440
 
 
441
/*
 
442
 * BuidArgVector takes a pointer to a comma-separated list of command
 
443
 * options and splits it out into an array of argument pointers.  The
 
444
 * caller must not free the optionList after calling this function until
 
445
 * the returned arg vector is no longer needed, at which time the arg
 
446
 * vector should also be freed.
 
447
 */
 
448
 
 
449
#define SEPARATOR_CHAR (char)','
 
450
 
 
451
static char **
 
452
BuildArgVector(
 
453
    char *optionList,
 
454
    char **argVector,
 
455
    int argCount)
 
456
{
 
457
    char *curArg, *lastChar, *endArg;
 
458
 
 
459
    curArg = optionList;
 
460
    lastChar = optionList + strlen(optionList); /* includes final NULL */
 
461
 
 
462
    while(curArg != (char *)NULL && curArg < lastChar)
 
463
    {
 
464
        /* strip leading white space */
 
465
        while(curArg < lastChar && isascii((int)*curArg) && 
 
466
              isspace((int)*curArg))
 
467
            curArg++;
 
468
 
 
469
        if(curArg < lastChar)
 
470
        {
 
471
            argVector = (char **)Xrealloc(argVector, 
 
472
                                          sizeof(char *) * (argCount + 2));
 
473
            argVector[argCount] = curArg;
 
474
            argVector[++argCount] = (char *)NULL;
 
475
 
 
476
            endArg = strchr(curArg, SEPARATOR_CHAR);
 
477
 
 
478
            /* Should I strip trailing white space ??? */
 
479
 
 
480
            if(endArg != (char *)NULL)
 
481
            {
 
482
                *endArg = (char)'\0';
 
483
                curArg = endArg + 1;
 
484
            }
 
485
            else
 
486
                curArg = (char *)NULL;
 
487
        }
 
488
    }
 
489
 
 
490
    return argVector;
 
491
}
 
492
#endif
 
493
 
 
494
static int
 
495
EndJob(
 
496
     XpContextPtr pCon,
 
497
     Bool cancel)
 
498
{
 
499
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
500
                         pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
501
 
 
502
    if( cancel == True )
 
503
    {
 
504
        if(pConPriv->getDocClient != (ClientPtr)NULL) {
 
505
            XpFinishDocData(pConPriv->getDocClient);
 
506
            
 
507
            pConPriv->getDocClient = (ClientPtr)NULL;
 
508
            pConPriv->getDocBufSize = 0;
 
509
        }
 
510
            
 
511
        if(pConPriv->jobFileName != (char *)NULL)
 
512
        {
 
513
            unlink(pConPriv->jobFileName);
 
514
            Xfree(pConPriv->jobFileName);
 
515
            pConPriv->jobFileName = (char *)NULL;
 
516
        }
 
517
 
 
518
        return Success;
 
519
    }
 
520
 
 
521
    if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0)
 
522
    {
 
523
        XpFinishDocData(pConPriv->getDocClient);
 
524
            
 
525
        pConPriv->getDocClient = (ClientPtr)NULL;
 
526
        pConPriv->getDocBufSize = 0;
 
527
 
 
528
        return Success;
 
529
    }
 
530
    
 
531
    if(pConPriv->pJobFile != (FILE *)NULL)
 
532
    {
 
533
        fclose(pConPriv->pJobFile);
 
534
        pConPriv->pJobFile = (FILE *)NULL;
 
535
        
 
536
        if(pConPriv->jobFileName != (char *)NULL)
 
537
        {
 
538
              XpSubmitJob( pConPriv->jobFileName, pCon );
 
539
              unlink(pConPriv->jobFileName);
 
540
              Xfree(pConPriv->jobFileName);
 
541
              pConPriv->jobFileName = (char *)NULL;
 
542
        }
 
543
    }
 
544
 
 
545
    return Success;
 
546
}
 
547
 
 
548
/* StartPage 
 
549
 *
 
550
 * If page file exists
 
551
 *     close page file
 
552
 *     set page file pointer = NULL
 
553
 *     unlink page file
 
554
 */
 
555
static int
 
556
StartPage(
 
557
     XpContextPtr pCon,
 
558
     WindowPtr pWin)
 
559
{
 
560
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
561
                         pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
562
 
 
563
    if(pConPriv->pPageFile != (FILE *)NULL)
 
564
    {
 
565
        fclose(pConPriv->pPageFile);
 
566
        pConPriv->pPageFile = (FILE *)NULL;
 
567
    }
 
568
    if(pConPriv->pageFileName != (char *)NULL)
 
569
    {
 
570
        unlink(pConPriv->pageFileName);
 
571
        pConPriv->pageFileName = (char *)NULL;
 
572
    }
 
573
 
 
574
    return Success;
 
575
}
 
576
 
 
577
#include "X11/XWDFile.h"
 
578
 
 
579
 
 
580
#define lowbit(x) ((x) & (~(x) + 1))
 
581
 
 
582
/*
 
583
 * Get the XWDColors of all pixels in colormap - returns # of colors
 
584
 */
 
585
static XWDColor *
 
586
Get_XWDColors(
 
587
     ColormapPtr pCmap)
 
588
{
 
589
    int i, ncolors;
 
590
    xrgb *prgbList;
 
591
    Pixel *pPixels;
 
592
    XWDColor *colors;
 
593
 
 
594
    ncolors = pCmap->pVisual->ColormapEntries;
 
595
    if (!(colors = (XWDColor *) malloc (sizeof(XWDColor) * ncolors)))
 
596
        return (XWDColor *) NULL;
 
597
    if (!(prgbList = (xrgb*) malloc(sizeof(xrgb) * ncolors)))
 
598
    {
 
599
        Xfree(colors);
 
600
        return (XWDColor *) NULL;
 
601
    }
 
602
    if (!(pPixels = (Pixel*) malloc(sizeof(Pixel) * ncolors)))
 
603
    {
 
604
        Xfree(colors);
 
605
        Xfree(prgbList);
 
606
        return (XWDColor *) NULL;
 
607
    }
 
608
 
 
609
    if (pCmap->pVisual->class == DirectColor ||
 
610
        pCmap->pVisual->class == TrueColor) {
 
611
        Pixel red, green, blue, red1, green1, blue1;
 
612
 
 
613
        red = green = blue = 0;
 
614
        red1 = lowbit(pCmap->pVisual->redMask);
 
615
        green1 = lowbit(pCmap->pVisual->greenMask);
 
616
        blue1 = lowbit(pCmap->pVisual->blueMask);
 
617
        for (i=0; i<ncolors; i++) {
 
618
          colors[i].pixel = red|green|blue;
 
619
          colors[i].pad = 0;
 
620
          red += red1;
 
621
          if (red > pCmap->pVisual->redMask)
 
622
            red = 0;
 
623
          green += green1;
 
624
          if (green > pCmap->pVisual->greenMask)
 
625
            green = 0;
 
626
          blue += blue1;
 
627
          if (blue > pCmap->pVisual->blueMask)
 
628
            blue = 0;
 
629
        }
 
630
    } else {
 
631
        for (i=0; i<ncolors; i++) {
 
632
          colors[i].pixel = i;
 
633
          colors[i].pad = 0;
 
634
        }
 
635
    }
 
636
 
 
637
    for(i = 0; i < ncolors; i++)
 
638
        pPixels[i] = colors[i].pixel;
 
639
 
 
640
    QueryColors(pCmap, ncolors, pPixels, prgbList);
 
641
    Xfree(pPixels);
 
642
 
 
643
    for(i = 0; i < ncolors; i++)
 
644
    {
 
645
        colors[i].red = prgbList[i].red;
 
646
        colors[i].green = prgbList[i].green;
 
647
        colors[i].blue = prgbList[i].blue;
 
648
    }
 
649
    Xfree(prgbList);
 
650
 
 
651
    return(colors);
 
652
}
 
653
 
 
654
static void
 
655
_swapshort (
 
656
    register char *bp,
 
657
    register unsigned n)
 
658
{
 
659
    register char c;
 
660
    register char *ep = bp + n;
 
661
 
 
662
    while (bp < ep) {
 
663
        c = *bp;
 
664
        *bp = *(bp + 1);
 
665
        bp++;
 
666
        *bp++ = c;
 
667
    }
 
668
}
 
669
 
 
670
static void
 
671
_swaplong (
 
672
    register char *bp,
 
673
    register unsigned n)
 
674
{
 
675
    register char c;
 
676
    register char *ep = bp + n;
 
677
    register char *sp;
 
678
 
 
679
    while (bp < ep) {
 
680
        sp = bp + 3;
 
681
        c = *sp;
 
682
        *sp = *bp;
 
683
        *bp++ = c;
 
684
        sp = bp + 1;
 
685
        c = *sp;
 
686
        *sp = *bp;
 
687
        *bp++ = c;
 
688
        bp += 2;
 
689
    }
 
690
}
 
691
static int
 
692
WriteWindowRaster(
 
693
    WindowPtr pWin,
 
694
    FILE *pRasterFile)
 
695
{
 
696
    long widthBytesLine, length;
 
697
    int nlines, linesPerBuf, height, linesDone;
 
698
    char *pBuf;
 
699
    DrawablePtr pDraw = &pWin->drawable;
 
700
    XWDFileHeader header;
 
701
    int win_name_size;
 
702
    int header_size;
 
703
    int ncolors, i;
 
704
    char *win_name;
 
705
    VisualPtr pVisual;
 
706
    ColormapPtr pCmap;
 
707
    XWDColor *pColors;
 
708
    unsigned long swaptest = 1;
 
709
 
 
710
    widthBytesLine = PixmapBytePad(pWin->drawable.width, pWin->drawable.depth);
 
711
    length = widthBytesLine * pWin->drawable.height;
 
712
    height = pWin->drawable.height;
 
713
 
 
714
    if(length <= 0)
 
715
        return Success;
 
716
 
 
717
    if (widthBytesLine >= IMAGE_BUFSIZE)
 
718
        linesPerBuf = 1;
 
719
    else
 
720
    {
 
721
        linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
 
722
        if (linesPerBuf > height)
 
723
            linesPerBuf = height;
 
724
    }
 
725
    length = linesPerBuf * widthBytesLine;
 
726
    if (linesPerBuf < height)
 
727
    {
 
728
        /* we have to make sure intermediate buffers don't need padding */
 
729
        while ((linesPerBuf > 1) && (length & 3))
 
730
        {
 
731
            linesPerBuf--;
 
732
            length -= widthBytesLine;
 
733
        }
 
734
        while (length & 3)
 
735
        {
 
736
            linesPerBuf++;
 
737
            length += widthBytesLine;
 
738
        }
 
739
    }
 
740
    if(!(pBuf = (char *) Xalloc(length)))
 
741
        return (BadAlloc);
 
742
 
 
743
    /*
 
744
     * Start of Xwd header code.
 
745
     */
 
746
 
 
747
    /*
 
748
     * XXX - Should we use the real window name???
 
749
     */
 
750
    win_name = "xwdump";
 
751
    /* sizeof(char) is included for the null string terminator. */
 
752
    win_name_size = strlen(win_name) + sizeof(char);
 
753
    
 
754
    pCmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP);
 
755
    pVisual = pCmap->pVisual;
 
756
    if((pColors = Get_XWDColors(pCmap)) == (XWDColor *)NULL)
 
757
    {
 
758
        Xfree(pBuf);
 
759
        return (BadAlloc);
 
760
    }
 
761
 
 
762
    /*
 
763
     * Write out header information.
 
764
     */
 
765
    header_size = sizeof(header) + win_name_size;
 
766
    header.header_size = (CARD32) header_size;
 
767
    header.file_version = (CARD32) XWD_FILE_VERSION;
 
768
    header.pixmap_format = (CARD32) ZPixmap; /* Must match GetImage below */
 
769
    header.pixmap_depth = (CARD32) pDraw->depth;
 
770
    header.pixmap_width = (CARD32) pDraw->width;
 
771
    header.pixmap_height = (CARD32) pDraw->height;
 
772
    header.xoffset = (CARD32) 0;
 
773
    header.byte_order = (CARD32) screenInfo.imageByteOrder;
 
774
    header.bitmap_unit = (CARD32) screenInfo.bitmapScanlineUnit;
 
775
    header.bitmap_bit_order = (CARD32) screenInfo.bitmapBitOrder;
 
776
    header.bitmap_pad = (CARD32) screenInfo.bitmapScanlinePad;
 
777
    header.bits_per_pixel = (CARD32) pDraw->bitsPerPixel;
 
778
    header.bytes_per_line = (CARD32) widthBytesLine;
 
779
    header.visual_class = (CARD32) pVisual->class;
 
780
    header.red_mask = (CARD32) pVisual->redMask;
 
781
    header.green_mask = (CARD32) pVisual->greenMask;
 
782
    header.blue_mask = (CARD32) pVisual->blueMask;
 
783
    header.bits_per_rgb = (CARD32) pVisual->bitsPerRGBValue;
 
784
    header.colormap_entries = (CARD32) pVisual->ColormapEntries;
 
785
    header.ncolors = ncolors = (CARD32) pVisual->ColormapEntries;
 
786
    header.window_width = (CARD32) pDraw->width;
 
787
    header.window_height = (CARD32) pDraw->height;
 
788
    header.window_x = 0;
 
789
    header.window_y = 0;
 
790
    header.window_bdrwidth = (CARD32) 0;
 
791
 
 
792
    if (*(char *) &swaptest) {
 
793
        _swaplong((char *) &header, sizeof(header));
 
794
        for (i = 0; i < ncolors; i++) {
 
795
            _swaplong((char *) &pColors[i].pixel, sizeof(long));
 
796
            _swapshort((char *) &pColors[i].red, 3 * sizeof(short));
 
797
        }
 
798
    }
 
799
 
 
800
    (void) fwrite((char *)&header, sizeof(header), 1, pRasterFile);
 
801
    (void) fwrite(win_name, win_name_size, 1, pRasterFile);
 
802
    (void) fwrite((char *) pColors, sizeof(XWDColor), ncolors, pRasterFile);
 
803
 
 
804
    Xfree(pColors);
 
805
 
 
806
    /*
 
807
     * End of Xwd header code.
 
808
     */
 
809
 
 
810
    linesDone = 0;
 
811
    while(height - linesDone > 0)
 
812
    {
 
813
        nlines = min(linesPerBuf, height - linesDone);
 
814
        (*pDraw->pScreen->GetImage) (pDraw,
 
815
                                     0,
 
816
                                     linesDone,
 
817
                                     pWin->drawable.width,
 
818
                                     nlines,
 
819
                                     ZPixmap,
 
820
                                     ~0,
 
821
                                     pBuf);
 
822
 
 
823
        if(fwrite(pBuf, sizeof(char), (size_t)(nlines * widthBytesLine),
 
824
           pRasterFile) != 
 
825
           (size_t)(nlines * widthBytesLine))
 
826
        {
 
827
            Xfree(pBuf);
 
828
            return BadAlloc;
 
829
        }
 
830
        linesDone += nlines;
 
831
    }
 
832
    Xfree(pBuf);
 
833
    return Success;
 
834
}
 
835
 
 
836
 
 
837
static int
 
838
SendPage( XpContextPtr pCon )
 
839
{
 
840
    struct stat statBuf;
 
841
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
842
                         pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
843
 
 
844
    if(stat(pConPriv->pageFileName, &statBuf) < 0)
 
845
        return BadAlloc;
 
846
 
 
847
    return XpSendDocumentData(pConPriv->getDocClient, 
 
848
                              pConPriv->pPageFile, (int)statBuf.st_size, 
 
849
                              pConPriv->getDocBufSize);
 
850
}
 
851
 
 
852
/*
 
853
 * EndPage:
 
854
 *
 
855
 * If page file doesn't exist:
 
856
 * {
 
857
 *     Create page file
 
858
 *     Open page file
 
859
 *     Write page header to page file
 
860
 *     if(preRasterFile exists)
 
861
 *         copy preRasterFile contents to page file
 
862
 *     if(noRasterFile exists)
 
863
 *         write noRasterFile contents to page file
 
864
 *     else
 
865
 *         Create raster image file
 
866
 *         Open raster image file
 
867
 *         GetImage data
 
868
 *         Write Image data to raster image file
 
869
 *         invoke page_command on raster image file
 
870
 *         Write raster image file contents to page file
 
871
 *         Unlink tempPage file
 
872
 *     if(postRasterFile exists)
 
873
 *         write postRasterFile contents to page file
 
874
 *     Write page trailer to page file
 
875
 * }
 
876
 * Write page file to job file
 
877
 */
 
878
static int
 
879
EndPage(
 
880
     XpContextPtr pCon,
 
881
     WindowPtr pWin)
 
882
{
 
883
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
884
                         pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
885
    struct stat statBuf;
 
886
    char *rasterFileName = (char *)NULL, *pCommand = (char *)NULL;
 
887
    FILE *pRasterFile = (FILE *)NULL;
 
888
 
 
889
    if(pConPriv->pageFileName == (char *)NULL)
 
890
    {
 
891
        /*
 
892
         * Open the page file.
 
893
         */
 
894
        if (!XpOpenTmpFile("w+", &pConPriv->pageFileName,
 
895
                           &pConPriv->pPageFile))
 
896
            goto BAD_PAGE_ALLOC;
 
897
 
 
898
        /*
 
899
         * Copy any pre-raster document data to the page file.
 
900
         */
 
901
        if(pConPriv->pPreRasterFile != (FILE *)NULL)
 
902
        {
 
903
            if(CopyContentsAndDelete(&pConPriv->pPreRasterFile, 
 
904
                                     &pConPriv->preRasterFileName,
 
905
                                     pConPriv->pPageFile) == FALSE)
 
906
                goto BAD_PAGE_ALLOC;
 
907
        }
 
908
 
 
909
        /*
 
910
         * Copy either the no-raster document data, or the raster 
 
911
         * data itself to the page file.
 
912
         * If the no-raster file exists, then we don't process the
 
913
         * actual window raster bits.
 
914
         */
 
915
        if(pConPriv->pNoRasterFile != (FILE *)NULL)
 
916
        {
 
917
            if(CopyContentsAndDelete(&pConPriv->pNoRasterFile, 
 
918
                                     &pConPriv->noRasterFileName,
 
919
                                     pConPriv->pPageFile) == FALSE)
 
920
                goto BAD_PAGE_ALLOC;
 
921
        }
 
922
        else
 
923
        {
 
924
            /*
 
925
             * Open the raster image file.
 
926
             */
 
927
            if (!XpOpenTmpFile("w", &rasterFileName, &pRasterFile))
 
928
                goto BAD_PAGE_ALLOC;
 
929
    
 
930
            /*
 
931
             * Write the page image data to the raster image file.
 
932
             */
 
933
            if(WriteWindowRaster(pWin, pRasterFile) != Success)
 
934
                goto BAD_PAGE_ALLOC;
 
935
 
 
936
            /*
 
937
             * Invoke the page_command on the raster image file.
 
938
             */
 
939
            if((pCommand = GetPropString(pCon, RASTER_PRINT_PAGE_COMMAND)) !=
 
940
               (char *)NULL)
 
941
            {
 
942
                char *outFileName;
 
943
                FILE *pOutFile;
 
944
 
 
945
                if (!XpOpenTmpFile("w", &outFileName, &pOutFile))
 
946
                    goto BAD_PAGE_ALLOC;
 
947
                fclose(pOutFile);
 
948
 
 
949
                pCommand = ReplaceFileString(strdup(pCommand), rasterFileName,
 
950
                                             outFileName);
 
951
                fclose(pRasterFile);
 
952
                SystemCmd(pCommand);
 
953
                free(pCommand);
 
954
                /*
 
955
                 * Delete the unprocessed raster file.
 
956
                 */
 
957
                unlink(rasterFileName);
 
958
                Xfree(rasterFileName);
 
959
                rasterFileName = outFileName;
 
960
                if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL)
 
961
                    goto BAD_PAGE_ALLOC;
 
962
            }
 
963
            else
 
964
            {
 
965
                fclose(pRasterFile);
 
966
                if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL)
 
967
                    goto BAD_PAGE_ALLOC;
 
968
            }
 
969
 
 
970
            /*
 
971
             * Copy the raster image file contents to the page file.
 
972
             * Note that pRasterFile must be set to the start of the
 
973
             * raster file.
 
974
             */
 
975
            if(CopyContentsAndDelete(&pRasterFile,
 
976
                                     &rasterFileName,
 
977
                                     pConPriv->pPageFile) == FALSE)
 
978
                goto BAD_PAGE_ALLOC;
 
979
        }
 
980
 
 
981
        /*
 
982
         * Copy any post-raster document data to the page file.
 
983
         */
 
984
        if(pConPriv->pPostRasterFile != (FILE *)NULL)
 
985
        {
 
986
            if(CopyContentsAndDelete(&pConPriv->pPostRasterFile, 
 
987
                                     &pConPriv->postRasterFileName,
 
988
                                     pConPriv->pPageFile) == FALSE)
 
989
                goto BAD_PAGE_ALLOC;
 
990
        }
 
991
 
 
992
    }
 
993
 
 
994
    /*
 
995
     * Write the page file contents to the job file or to the client
 
996
     * performing GetDocumentData.
 
997
     * pConPriv->pPageFile must first be set to the start of the page file.
 
998
     */
 
999
    rewind(pConPriv->pPageFile);
 
1000
    if(stat(pConPriv->pageFileName, &statBuf) < 0)
 
1001
        goto BAD_PAGE_ALLOC;
 
1002
 
 
1003
    /*
 
1004
     * Send the page data to whatever client has called GetDocumentData.
 
1005
     */
 
1006
    if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0)
 
1007
    {
 
1008
        int retval;
 
1009
        /*
 
1010
         * We should do something like the following: suspend the 
 
1011
         * caller until we can gracefully write all the data in small
 
1012
         * chunks to the receiver, but for now we'll just call WriteToClient
 
1013
         * on the huge chunk
 
1014
         */
 
1015
        retval = SendPage(pCon);
 
1016
        fclose(pConPriv->pPageFile);
 
1017
        pConPriv->pPageFile = (FILE *)NULL;
 
1018
        unlink(pConPriv->pageFileName);
 
1019
        free(pConPriv->pageFileName);
 
1020
        pConPriv->pageFileName = (char *)NULL;
 
1021
        return retval;
 
1022
    }
 
1023
 
 
1024
    if(pConPriv->pJobFile == (FILE *)NULL)
 
1025
    {
 
1026
        /*
 
1027
         * This shouldn't be necessary.  I believe we only get here if
 
1028
         * someone calls "EndPage" prior to "StartJob".  This error 
 
1029
         * condition should probably be trapped at a higher level.
 
1030
         */
 
1031
 
 
1032
        if(pConPriv->jobFileName != (char *)NULL)
 
1033
            Xfree(pConPriv->jobFileName);
 
1034
        /*
 
1035
         * Create a temporary file to store the printer output.
 
1036
         */
 
1037
        if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile))
 
1038
            goto BAD_PAGE_ALLOC;
 
1039
    }
 
1040
 
 
1041
    if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile, 
 
1042
       (int)statBuf.st_size) != (int)statBuf.st_size)
 
1043
        goto BAD_PAGE_ALLOC;
 
1044
 
 
1045
    fclose(pConPriv->pPageFile);
 
1046
    pConPriv->pPageFile = (FILE *)NULL;
 
1047
    unlink(pConPriv->pageFileName);
 
1048
    free(pConPriv->pageFileName);
 
1049
    pConPriv->pageFileName = (char *)NULL;
 
1050
 
 
1051
    return Success;
 
1052
 
 
1053
  BAD_PAGE_ALLOC:
 
1054
 
 
1055
    FreePageFiles(pConPriv);
 
1056
 
 
1057
    if(pRasterFile != (FILE *)NULL)
 
1058
        fclose(pRasterFile);
 
1059
    if(rasterFileName != (char *)NULL)
 
1060
    {
 
1061
        unlink(rasterFileName);
 
1062
        Xfree(rasterFileName);
 
1063
    }
 
1064
    return BadAlloc;
 
1065
}
 
1066
 
 
1067
static int
 
1068
DocumentData(
 
1069
     XpContextPtr pCon,
 
1070
     DrawablePtr pDraw,
 
1071
     char *pData,
 
1072
     int len_data,
 
1073
     char *pDoc_fmt,
 
1074
     int len_fmt,
 
1075
     char *pOptions,
 
1076
     int len_options,
 
1077
     ClientPtr client)
 
1078
{
 
1079
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
1080
                         pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
1081
    char *preRasterStr = PRE_RASTER, *postRasterStr = POST_RASTER,
 
1082
         *noRasterStr = NO_RASTER;
 
1083
 
 
1084
    /*
 
1085
     * Check that options equals either PRE_RASTER or POST_RASTER.
 
1086
     */
 
1087
    if(len_options == strlen(preRasterStr) &&
 
1088
       strncmp(pOptions, preRasterStr, strlen(preRasterStr)) == 0)
 
1089
    {
 
1090
        if(pConPriv->pPreRasterFile == (FILE *)NULL)
 
1091
        {
 
1092
            if (!XpOpenTmpFile("w+", &pConPriv->preRasterFileName,
 
1093
                               &pConPriv->pPreRasterFile))
 
1094
                return BadAlloc;
 
1095
        }
 
1096
        if(fwrite(pData, sizeof(char), (size_t)len_data,
 
1097
           pConPriv->pPreRasterFile) != (size_t)len_data)
 
1098
            return BadAlloc;
 
1099
        fflush(pConPriv->pPreRasterFile);
 
1100
    }
 
1101
    else if(len_options == strlen(postRasterStr) &&
 
1102
            strncmp(pOptions, postRasterStr, strlen(postRasterStr)) == 0)
 
1103
    {
 
1104
        if(pConPriv->pPostRasterFile == (FILE *)NULL)
 
1105
        {
 
1106
            if (!XpOpenTmpFile("w+", &pConPriv->postRasterFileName,
 
1107
                               &pConPriv->pPostRasterFile))
 
1108
                return BadAlloc;
 
1109
        }
 
1110
        if(fwrite(pData, sizeof(char), (size_t)len_data,
 
1111
           pConPriv->pPostRasterFile) != (size_t)len_data)
 
1112
            return BadAlloc;
 
1113
        fflush(pConPriv->pPostRasterFile);
 
1114
    }
 
1115
    else if(len_options == strlen(noRasterStr) &&
 
1116
            strncmp(pOptions, noRasterStr, strlen(noRasterStr)) == 0)
 
1117
    {
 
1118
        if(pConPriv->pNoRasterFile == (FILE *)NULL)
 
1119
        {
 
1120
            if (!XpOpenTmpFile("w+", &pConPriv->noRasterFileName,
 
1121
                               &pConPriv->pNoRasterFile))
 
1122
                return BadAlloc;
 
1123
        }
 
1124
        if(fwrite(pData, sizeof(char), (size_t)len_data,
 
1125
           pConPriv->pNoRasterFile) != (size_t)len_data)
 
1126
            return BadAlloc;
 
1127
        fflush(pConPriv->pNoRasterFile);
 
1128
    }
 
1129
    else
 
1130
        return BadValue;
 
1131
 
 
1132
    return Success;
 
1133
}
 
1134
 
 
1135
/*
 
1136
 * GetDocumentData notes which client is requesting the document data for
 
1137
 * a particular context. The Raster driver's EndPage function causes the
 
1138
 * data to be written to the proper client.
 
1139
 */
 
1140
static int
 
1141
GetDocumentData(
 
1142
    XpContextPtr pContext, 
 
1143
    ClientPtr client,
 
1144
    int maxBufferSize)
 
1145
{
 
1146
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
1147
                         pContext->devPrivates[RasterContextPrivateIndex].ptr;
 
1148
 
 
1149
    pConPriv->getDocClient = client;
 
1150
    pConPriv->getDocBufSize = maxBufferSize;
 
1151
    return Success;
 
1152
}
 
1153
 
 
1154
static void
 
1155
AllocateRasterPrivates(
 
1156
    ScreenPtr pScreen)
 
1157
{
 
1158
    if(RasterGeneration != serverGeneration)
 
1159
    {
 
1160
        RasterScreenPrivateIndex = AllocateScreenPrivateIndex();
 
1161
        RasterContextPrivateIndex = XpAllocateContextPrivateIndex();
 
1162
        XpAllocateContextPrivate( RasterContextPrivateIndex, 
 
1163
                             sizeof( RasterContextPrivRec ) );
 
1164
 
 
1165
        RasterGeneration = serverGeneration;
 
1166
    }
 
1167
    pScreen->devPrivates[RasterScreenPrivateIndex].ptr = (pointer)Xalloc(
 
1168
                sizeof(RasterScreenPrivRec));
 
1169
}
 
1170
 
 
1171
/*
 
1172
 * RasterChangeWindowAttributes - Make sure that the window's backing
 
1173
 * store is turned on.
 
1174
 */
 
1175
static Bool 
 
1176
RasterChangeWindowAttributes(
 
1177
    WindowPtr pWin,
 
1178
    unsigned long mask)
 
1179
{
 
1180
    Bool status = Success;
 
1181
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
1182
    RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr) 
 
1183
                     pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
 
1184
 
 
1185
    if(pWin->backingStore == NotUseful)
 
1186
    {
 
1187
        pWin->backingStore = WhenMapped;
 
1188
        mask |= CWBackingStore;
 
1189
    }
 
1190
 
 
1191
    if(pScreenPriv->ChangeWindowAttributes != NULL)
 
1192
    {
 
1193
        pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
 
1194
        status = pScreen->ChangeWindowAttributes(pWin, mask);
 
1195
        pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes;
 
1196
    }
 
1197
    return status;
 
1198
}
 
1199
 
 
1200
/*
 
1201
 * RasterValidateDocFormats - Inspects the files available in the 
 
1202
 * ddx-config/XP-RASTER directory to find the names of PDLs for which
 
1203
 * we have processing commands.  These names are then intersected with
 
1204
 * the contents of the printer's document-formats-supported attribute,
 
1205
 * and the result is stored back into document-formats-supported.  
 
1206
 * We have hard-coded knowledge of how to produce PS, so we always 
 
1207
 * leave that in, if it's listed in document-formats-supported, 
 
1208
 * even if we don't have a configuration file.  If there is a 
 
1209
 * configuration file for PS, then its contents will override our default.
 
1210
 */
 
1211
static void
 
1212
RasterValidateDocFormats(
 
1213
     XpContextPtr pCon)
 
1214
{
 
1215
}
 
1216
 
 
1217
/*
 
1218
 * RasterValidateAttrs - Inspects and Corrects the attribute values
 
1219
 * in the specified context.
 
1220
 */
 
1221
static void
 
1222
RasterValidateAttrs(
 
1223
     XpContextPtr pCon)
 
1224
{
 
1225
    RasterValidateDocFormats(pCon);
 
1226
    XpValidatePrinterPool(pCon, &RasterValidatePoolsRec);
 
1227
    XpValidateJobPool(pCon, &RasterValidatePoolsRec);
 
1228
    XpValidateDocumentPool(pCon, &RasterValidatePoolsRec);
 
1229
}
 
1230
    
 
1231
/*
 
1232
 * RasterInitContext - Establish the appropriate values for a
 
1233
 * PrintContext used with the Raster Driver.
 
1234
 */
 
1235
static char DOC_ATT_SUPP[]="document-attributes-supported:\tdefault-medium document-format";
 
1236
static char JOB_ATT_SUPP[]="job-attributes-supported:\t";
 
1237
static char DDX_DIR[]="ddx-config";
 
1238
 
 
1239
static int
 
1240
RasterInitContext(
 
1241
     XpContextPtr pCon)
 
1242
{
 
1243
    char *configFileName, *val, *attrStr;
 
1244
    RasterContextPrivPtr pConPriv;
 
1245
    XpDriverFuncsPtr pFuncs;
 
1246
    
 
1247
    /*
 
1248
     * Initialize the attribute store for this printer.
 
1249
     */
 
1250
    XpInitAttributes( pCon );
 
1251
 
 
1252
    /*
 
1253
     * Validate the attributes
 
1254
     */
 
1255
    RasterValidateAttrs( pCon );
 
1256
 
 
1257
 
 
1258
    /*
 
1259
     * Initialize the function pointers
 
1260
     */
 
1261
    pFuncs = &( pCon->funcs );
 
1262
    pFuncs->StartJob = StartJob;
 
1263
    pFuncs->EndJob = EndJob;
 
1264
    pFuncs->StartDoc = StartDoc;
 
1265
    pFuncs->EndDoc = EndDoc;
 
1266
    pFuncs->StartPage = StartPage;
 
1267
    pFuncs->EndPage = EndPage;
 
1268
    pFuncs->PutDocumentData = DocumentData;
 
1269
    pFuncs->GetDocumentData = GetDocumentData;
 
1270
    pFuncs->DestroyContext = RasterDestroyContext;
 
1271
    pFuncs->GetAttributes = RasterGetAttributes;
 
1272
    pFuncs->GetOneAttribute = RasterGetOneAttribute;
 
1273
    pFuncs->SetAttributes = RasterSetAttributes;
 
1274
    pFuncs->AugmentAttributes = RasterAugmentAttributes;
 
1275
    pFuncs->GetMediumDimensions = RasterMediumDimensions;
 
1276
    pFuncs->GetReproducibleArea = RasterReproducibleArea;
 
1277
    
 
1278
    /*
 
1279
     * Set up the context privates
 
1280
     */
 
1281
    pConPriv = (RasterContextPrivPtr)
 
1282
      pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
1283
    
 
1284
    pConPriv->jobFileName = (char *)NULL;
 
1285
    pConPriv->pageFileName = (char *)NULL;
 
1286
    pConPriv->preRasterFileName = (char *)NULL;
 
1287
    pConPriv->postRasterFileName = (char *)NULL;
 
1288
    pConPriv->noRasterFileName = (char *)NULL;
 
1289
    pConPriv->pJobFile = (FILE *)NULL;
 
1290
    pConPriv->pPageFile = (FILE *)NULL;
 
1291
    pConPriv->pPreRasterFile = (FILE *)NULL;
 
1292
    pConPriv->pPostRasterFile = (FILE *)NULL;
 
1293
    pConPriv->pNoRasterFile = (FILE *)NULL;
 
1294
 
 
1295
    pConPriv->getDocClient = (ClientPtr)NULL;
 
1296
    pConPriv->getDocBufSize = 0;
 
1297
 
 
1298
    /*
 
1299
     * Get the configuration information for the context's printer
 
1300
     */
 
1301
    configFileName = XpGetOneAttribute( pCon, XPPrinterAttr,
 
1302
                                       "xp-ddx-config-file-name" );
 
1303
    if(configFileName && strlen(configFileName))
 
1304
    {
 
1305
        if( configFileName[0] == '/' )
 
1306
            pConPriv->config = XrmGetFileDatabase( configFileName );
 
1307
        else
 
1308
        {
 
1309
            char *configDir, *configFilePath;
 
1310
 
 
1311
            configDir = XpGetConfigDir(FALSE);
 
1312
            configFilePath = (char *)malloc((strlen(configDir) +
 
1313
                                             strlen(DDX_DIR) +
 
1314
                                             strlen(RASTER_DRIV_NAME) +
 
1315
                                             strlen(configFileName) +
 
1316
                                             4)* sizeof(char));
 
1317
            sprintf(configFilePath, "%s/%s/%s/%s", configDir, DDX_DIR,
 
1318
                    RASTER_DRIV_NAME, configFileName);
 
1319
            pConPriv->config = XrmGetFileDatabase(configFilePath);
 
1320
            free(configDir);
 
1321
            free(configFilePath);
 
1322
        }
 
1323
    }
 
1324
    else
 
1325
        pConPriv->config = (XrmDatabase)NULL;
 
1326
 
 
1327
    /*
 
1328
     * Add our own attribute initialization
 
1329
     */
 
1330
    /*
 
1331
     * document-attributes-supported
 
1332
     */
 
1333
    val = XpGetOneAttribute(pCon, XPServerAttr, "document-attributes-supported");
 
1334
    if((attrStr = (char *)xalloc(strlen(val) + strlen(DOC_ATT_SUPP) + 4)) == 
 
1335
       (char *)NULL)
 
1336
        return BadAlloc;
 
1337
    sprintf(attrStr, "*%s %s", DOC_ATT_SUPP, val);
 
1338
    XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
 
1339
    xfree(attrStr);
 
1340
 
 
1341
    /*
 
1342
     * job-attributes-supported
 
1343
     */
 
1344
    val = XpGetOneAttribute(pCon, XPServerAttr, "job-attributes-supported");
 
1345
    if((attrStr = (char *)xalloc(strlen(val) + strlen(JOB_ATT_SUPP) + 4)) == 
 
1346
       (char *)NULL)
 
1347
        return BadAlloc;
 
1348
    sprintf(attrStr, "*%s %s", JOB_ATT_SUPP, val);
 
1349
    XpAugmentAttributes(pCon, XPPrinterAttr, attrStr);
 
1350
    xfree(attrStr);
 
1351
 
 
1352
    /*
 
1353
     * PageAttributesSupported
 
1354
     */
 
1355
    XpAugmentAttributes(pCon, XPPrinterAttr, "*xp-page-attributes-supported:");
 
1356
    
 
1357
    return Success;
 
1358
}
 
1359
 
 
1360
    
 
1361
 
 
1362
static Bool
 
1363
RasterDestroyContext(
 
1364
     XpContextPtr pCon)
 
1365
{
 
1366
    RasterContextPrivPtr pConPriv = (RasterContextPrivPtr)
 
1367
      pCon->devPrivates[RasterContextPrivateIndex].ptr;
 
1368
    
 
1369
    /*
 
1370
     * Clean up the temporary files
 
1371
     */
 
1372
    FreePageFiles( pConPriv );
 
1373
    
 
1374
    if( pConPriv->pJobFile != (FILE *)NULL )
 
1375
      {
 
1376
          fclose( pConPriv->pJobFile );
 
1377
          pConPriv->pJobFile = (FILE *)NULL;
 
1378
      }
 
1379
    if( pConPriv->jobFileName != (char *)NULL )
 
1380
      {
 
1381
          unlink( pConPriv->jobFileName );
 
1382
          Xfree( pConPriv->jobFileName );
 
1383
      }
 
1384
    if(pConPriv->config)
 
1385
    {
 
1386
        XrmDestroyDatabase(pConPriv->config);
 
1387
        pConPriv->config = (XrmDatabase)NULL;
 
1388
    }
 
1389
 
 
1390
    XpDestroyAttributes( pCon );
 
1391
    return Success;
 
1392
}
 
1393
 
 
1394
static char *
 
1395
RasterGetAttributes(
 
1396
     XpContextPtr pContext,
 
1397
     XPAttributes class)
 
1398
{
 
1399
    return XpGetAttributes( pContext, class );
 
1400
}
 
1401
 
 
1402
static char *
 
1403
RasterGetOneAttribute(
 
1404
     XpContextPtr pContext,
 
1405
     XPAttributes class,
 
1406
     char *attr)
 
1407
{
 
1408
    return XpGetOneAttribute( pContext, class, attr );
 
1409
}
 
1410
 
 
1411
static int 
 
1412
RasterSetAttributes(XpContextPtr pCon,
 
1413
    XPAttributes class,
 
1414
    char *attributes)
 
1415
{
 
1416
    return XpSetAttributes( pCon, class, attributes );
 
1417
}
 
1418
 
 
1419
static int
 
1420
RasterAugmentAttributes(
 
1421
     XpContextPtr pCon,
 
1422
     XPAttributes class,
 
1423
     char *attributes)
 
1424
{
 
1425
    return XpAugmentAttributes( pCon, class, attributes );
 
1426
}
 
1427
 
 
1428
static void
 
1429
FreePageFiles(
 
1430
    RasterContextPrivPtr pConPriv)
 
1431
{
 
1432
    if(pConPriv->pPageFile != (FILE *)NULL)
 
1433
    {
 
1434
        fclose(pConPriv->pPageFile);
 
1435
        pConPriv->pPageFile = (FILE *)NULL;
 
1436
    }
 
1437
    if(pConPriv->pageFileName != (char *)NULL)
 
1438
    {
 
1439
        unlink(pConPriv->pageFileName);
 
1440
        Xfree(pConPriv->pageFileName);
 
1441
        pConPriv->pageFileName = (char *)NULL;
 
1442
    }
 
1443
    if(pConPriv->pPreRasterFile != (FILE *)NULL)
 
1444
    {
 
1445
        fclose(pConPriv->pPreRasterFile);
 
1446
        pConPriv->pPreRasterFile = (FILE *)NULL;
 
1447
    }
 
1448
    if(pConPriv->preRasterFileName != (char *)NULL)
 
1449
    {
 
1450
        unlink(pConPriv->preRasterFileName);
 
1451
        Xfree(pConPriv->preRasterFileName);
 
1452
        pConPriv->preRasterFileName = (char *)NULL;
 
1453
    }
 
1454
    if(pConPriv->pPostRasterFile != (FILE *)NULL)
 
1455
    {
 
1456
        fclose(pConPriv->pPostRasterFile);
 
1457
        pConPriv->pPostRasterFile = (FILE *)NULL;
 
1458
    }
 
1459
    if(pConPriv->postRasterFileName != (char *)NULL)
 
1460
    {
 
1461
        unlink(pConPriv->postRasterFileName);
 
1462
        Xfree(pConPriv->postRasterFileName);
 
1463
        pConPriv->postRasterFileName = (char *)NULL;
 
1464
    }
 
1465
    if(pConPriv->pNoRasterFile != (FILE *)NULL)
 
1466
    {
 
1467
        fclose(pConPriv->pNoRasterFile);
 
1468
        pConPriv->pNoRasterFile = (FILE *)NULL;
 
1469
    }
 
1470
    if(pConPriv->noRasterFileName != (char *)NULL)
 
1471
    {
 
1472
        unlink(pConPriv->noRasterFileName);
 
1473
        Xfree(pConPriv->noRasterFileName);
 
1474
        pConPriv->noRasterFileName = (char *)NULL;
 
1475
    }
 
1476
}
 
1477
 
 
1478
/*
 
1479
 * RasterCloseScreen - Call any wrapped CloseScreen function,
 
1480
 * and free the screen memory.
 
1481
 */
 
1482
static Bool 
 
1483
RasterCloseScreen(
 
1484
    int index,
 
1485
    ScreenPtr pScreen)
 
1486
{
 
1487
    Bool status = Success;
 
1488
    RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr) 
 
1489
                     pScreen->devPrivates[RasterScreenPrivateIndex].ptr;
 
1490
    
 
1491
    /*
 
1492
     * Call any wrapped CloseScreen proc.
 
1493
     */
 
1494
    if(pScreenPriv->CloseScreen != NULL)
 
1495
    {
 
1496
        pScreen->CloseScreen = pScreenPriv->CloseScreen;
 
1497
        status = pScreen->CloseScreen(index, pScreen);
 
1498
        pScreen->CloseScreen = RasterCloseScreen;
 
1499
    }
 
1500
 
 
1501
    Xfree(pScreenPriv->pBits);
 
1502
    Xfree(pScreenPriv);
 
1503
 
 
1504
    return status;
 
1505
}
 
1506
 
 
1507
#include <signal.h>
 
1508
 
 
1509
/* ARGSUSED */
 
1510
static void SigchldHndlr (int dummy)
 
1511
{
 
1512
    int   status;
 
1513
    int   olderrno = errno;
 
1514
    struct sigaction act;
 
1515
    sigfillset(&act.sa_mask);
 
1516
    act.sa_flags = 0;
 
1517
    act.sa_handler = SigchldHndlr;
 
1518
 
 
1519
    (void) wait (&status);
 
1520
 
 
1521
    /*
 
1522
     * Is this really necessary?
 
1523
     */
 
1524
    sigaction(SIGCHLD, &act, (struct sigaction *)NULL);
 
1525
    errno = olderrno;
 
1526
}
 
1527
 
 
1528
/*
 
1529
 * SystemCmd provides a wrapper for the 'system' library call.  The call
 
1530
 * appears to be sensitive to the handling of SIGCHLD, so this wrapper
 
1531
 * sets the status to SIG_DFL, and then resets the established handler
 
1532
 * after system returns.
 
1533
 */
 
1534
static int
 
1535
SystemCmd(char *cmdStr)
 
1536
{
 
1537
    int status;
 
1538
    struct sigaction newAct, oldAct;
 
1539
    sigfillset(&newAct.sa_mask);
 
1540
    newAct.sa_flags = 0;
 
1541
    newAct.sa_handler = SIG_DFL;
 
1542
    sigfillset(&oldAct.sa_mask);
 
1543
    oldAct.sa_flags = 0;
 
1544
    oldAct.sa_handler = SigchldHndlr;
 
1545
 
 
1546
    /*
 
1547
     * get the old handler, and set the action to IGN
 
1548
     */
 
1549
    sigaction(SIGCHLD, &newAct, &oldAct);
 
1550
 
 
1551
    status = system (cmdStr);
 
1552
 
 
1553
    sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL);
 
1554
    return status;
 
1555
}
 
1556
 
 
1557
/*
 
1558
 * RasterMediumDimensions is installed in the GetMediumDimensions field
 
1559
 * of each raster-initialized context.
 
1560
 */
 
1561
static int
 
1562
RasterMediumDimensions(XpContextPtr pCon, 
 
1563
                       CARD16 *width,
 
1564
                       CARD16 *height)
 
1565
{
 
1566
    XpGetMediumDimensions(pCon, width, height);
 
1567
    return Success;
 
1568
}
 
1569
 
 
1570
/*
 
1571
 * RasterReproducibleArea is installed in the GetReproducibleArea field
 
1572
 * of each raster-initialized context.
 
1573
 */
 
1574
static int 
 
1575
RasterReproducibleArea(XpContextPtr pCon, 
 
1576
                       xRectangle *pRect)
 
1577
{
 
1578
    XpGetReproductionArea(pCon, pRect);
 
1579
    return Success;
 
1580
}