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

« back to all changes in this revision

Viewing changes to iplan2p4/iplbitblt.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
/* $XFree86: xc/programs/Xserver/iplan2p4/iplbitblt.c,v 3.1tsi Exp $ */
 
2
/*
 
3
 * ipl copy area
 
4
 */
 
5
 
 
6
/*
 
7
 
 
8
Copyright (c) 1989  X Consortium
 
9
 
 
10
Permission is hereby granted, free of charge, to any person obtaining a copy
 
11
of this software and associated documentation files (the "Software"), to deal
 
12
in the Software without restriction, including without limitation the rights
 
13
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
14
copies of the Software, and to permit persons to whom the Software is
 
15
furnished to do so, subject to the following conditions:
 
16
 
 
17
The above copyright notice and this permission notice shall be included in
 
18
all copies or substantial portions of the Software.
 
19
 
 
20
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
21
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
22
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
23
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
24
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
25
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
26
 
 
27
Except as contained in this notice, the name of the X Consortium shall not be
 
28
used in advertising or otherwise to promote the sale, use or other dealings
 
29
in this Software without prior written authorization from the X Consortium.
 
30
 
 
31
Author: Keith Packard
 
32
 
 
33
*/
 
34
/* $XConsortium: iplbitblt.c,v 5.51 94/05/27 11:00:56 dpw Exp $ */
 
35
 
 
36
/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
 
37
interleaved planes */
 
38
 
 
39
#ifdef HAVE_DIX_CONFIG_H
 
40
#include <dix-config.h>
 
41
#endif
 
42
 
 
43
#include        <X11/X.h>
 
44
#include        <X11/Xmd.h>
 
45
#include        <X11/Xproto.h>
 
46
#include        "gcstruct.h"
 
47
#include        "windowstr.h"
 
48
#include        "scrnintstr.h"
 
49
#include        "pixmapstr.h"
 
50
#include        "regionstr.h"
 
51
#include        "ipl.h"
 
52
#include        "fastblt.h"
 
53
#define MFB_CONSTS_ONLY
 
54
#include        "maskbits.h"
 
55
 
 
56
#include        "iplmskbits.h"
 
57
 
 
58
RegionPtr
 
59
iplBitBlt (pSrcDrawable, pDstDrawable,
 
60
            pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane)
 
61
    register DrawablePtr pSrcDrawable;
 
62
    register DrawablePtr pDstDrawable;
 
63
    GC *pGC;
 
64
    int srcx, srcy;
 
65
    int width, height;
 
66
    int dstx, dsty;
 
67
    void (*doBitBlt)();
 
68
    unsigned long bitPlane;
 
69
{
 
70
    RegionPtr prgnSrcClip;      /* may be a new region, or just a copy */
 
71
    Bool freeSrcClip = FALSE;
 
72
 
 
73
    RegionPtr prgnExposed;
 
74
    RegionRec rgnDst;
 
75
    DDXPointPtr pptSrc;
 
76
    register DDXPointPtr ppt;
 
77
    register BoxPtr pbox;
 
78
    int i;
 
79
    register int dx;
 
80
    register int dy;
 
81
    xRectangle origSource;
 
82
    DDXPointRec origDest;
 
83
    int numRects;
 
84
    BoxRec fastBox;
 
85
    int fastClip = 0;           /* for fast clipping with pixmap source */
 
86
    int fastExpose = 0;         /* for fast exposures with pixmap source */
 
87
 
 
88
    origSource.x = srcx;
 
89
    origSource.y = srcy;
 
90
    origSource.width = width;
 
91
    origSource.height = height;
 
92
    origDest.x = dstx;
 
93
    origDest.y = dsty;
 
94
 
 
95
    if ((pSrcDrawable != pDstDrawable) &&
 
96
        pSrcDrawable->pScreen->SourceValidate)
 
97
    {
 
98
        (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
 
99
    }
 
100
 
 
101
    srcx += pSrcDrawable->x;
 
102
    srcy += pSrcDrawable->y;
 
103
 
 
104
    /* clip the source */
 
105
 
 
106
    if (pSrcDrawable->type == DRAWABLE_PIXMAP)
 
107
    {
 
108
        if ((pSrcDrawable == pDstDrawable) &&
 
109
            (pGC->clientClipType == CT_NONE))
 
110
        {
 
111
            prgnSrcClip = iplGetCompositeClip(pGC);
 
112
        }
 
113
        else
 
114
        {
 
115
            fastClip = 1;
 
116
        }
 
117
    }
 
118
    else
 
119
    {
 
120
        if (pGC->subWindowMode == IncludeInferiors)
 
121
        {
 
122
            if (!((WindowPtr) pSrcDrawable)->parent)
 
123
            {
 
124
                /*
 
125
                 * special case bitblt from root window in
 
126
                 * IncludeInferiors mode; just like from a pixmap
 
127
                 */
 
128
                fastClip = 1;
 
129
            }
 
130
            else if ((pSrcDrawable == pDstDrawable) &&
 
131
                (pGC->clientClipType == CT_NONE))
 
132
            {
 
133
                prgnSrcClip = iplGetCompositeClip(pGC);
 
134
            }
 
135
            else
 
136
            {
 
137
                prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
 
138
                freeSrcClip = TRUE;
 
139
            }
 
140
        }
 
141
        else
 
142
        {
 
143
            prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
 
144
        }
 
145
    }
 
146
 
 
147
    fastBox.x1 = srcx;
 
148
    fastBox.y1 = srcy;
 
149
    fastBox.x2 = srcx + width;
 
150
    fastBox.y2 = srcy + height;
 
151
 
 
152
    /* Don't create a source region if we are doing a fast clip */
 
153
    if (fastClip)
 
154
    {
 
155
        fastExpose = 1;
 
156
        /*
 
157
         * clip the source; if regions extend beyond the source size,
 
158
         * make sure exposure events get sent
 
159
         */
 
160
        if (fastBox.x1 < pSrcDrawable->x)
 
161
        {
 
162
            fastBox.x1 = pSrcDrawable->x;
 
163
            fastExpose = 0;
 
164
        }
 
165
        if (fastBox.y1 < pSrcDrawable->y)
 
166
        {
 
167
            fastBox.y1 = pSrcDrawable->y;
 
168
            fastExpose = 0;
 
169
        }
 
170
        if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
 
171
        {
 
172
            fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
 
173
            fastExpose = 0;
 
174
        }
 
175
        if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
 
176
        {
 
177
            fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
 
178
            fastExpose = 0;
 
179
        }
 
180
    }
 
181
    else
 
182
    {
 
183
        REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
 
184
        REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
 
185
    }
 
186
 
 
187
    dstx += pDstDrawable->x;
 
188
    dsty += pDstDrawable->y;
 
189
 
 
190
    if (pDstDrawable->type == DRAWABLE_WINDOW)
 
191
    {
 
192
        if (!((WindowPtr)pDstDrawable)->realized)
 
193
        {
 
194
            if (!fastClip)
 
195
                REGION_UNINIT(pGC->pScreen, &rgnDst);
 
196
            if (freeSrcClip)
 
197
                REGION_DESTROY(pGC->pScreen, prgnSrcClip);
 
198
            return NULL;
 
199
        }
 
200
    }
 
201
 
 
202
    dx = srcx - dstx;
 
203
    dy = srcy - dsty;
 
204
 
 
205
    /* Translate and clip the dst to the destination composite clip */
 
206
    if (fastClip)
 
207
    {
 
208
        RegionPtr cclip;
 
209
 
 
210
        /* Translate the region directly */
 
211
        fastBox.x1 -= dx;
 
212
        fastBox.x2 -= dx;
 
213
        fastBox.y1 -= dy;
 
214
        fastBox.y2 -= dy;
 
215
 
 
216
        /* If the destination composite clip is one rectangle we can
 
217
           do the clip directly.  Otherwise we have to create a full
 
218
           blown region and call intersect */
 
219
 
 
220
        /* XXX because CopyPlane uses this routine for 8-to-1 bit
 
221
         * copies, this next line *must* also correctly fetch the
 
222
         * composite clip from an mfb gc
 
223
         */
 
224
 
 
225
        cclip = iplGetCompositeClip(pGC);
 
226
        if (REGION_NUM_RECTS(cclip) == 1)
 
227
        {
 
228
            BoxPtr pBox = REGION_RECTS(cclip);
 
229
 
 
230
            if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
 
231
            if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
 
232
            if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
 
233
            if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
 
234
 
 
235
            /* Check to see if the region is empty */
 
236
            if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
 
237
            {
 
238
                REGION_NULL(pGC->pScreen, &rgnDst);
 
239
            }
 
240
            else
 
241
            {
 
242
                REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
 
243
            }
 
244
        }
 
245
        else
 
246
        {
 
247
            /* We must turn off fastClip now, since we must create
 
248
               a full blown region.  It is intersected with the
 
249
               composite clip below. */
 
250
            fastClip = 0;
 
251
            REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
 
252
        }
 
253
    }
 
254
    else
 
255
    {
 
256
        REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
 
257
    }
 
258
 
 
259
    if (!fastClip)
 
260
    {
 
261
        REGION_INTERSECT(pGC->pScreen, &rgnDst,
 
262
                                   &rgnDst,
 
263
                                   iplGetCompositeClip(pGC));
 
264
    }
 
265
 
 
266
    /* Do bit blitting */
 
267
    numRects = REGION_NUM_RECTS(&rgnDst);
 
268
    if (numRects && width && height)
 
269
    {
 
270
        if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
 
271
                                                  sizeof(DDXPointRec))))
 
272
        {
 
273
            REGION_UNINIT(pGC->pScreen, &rgnDst);
 
274
            if (freeSrcClip)
 
275
                REGION_DESTROY(pGC->pScreen, prgnSrcClip);
 
276
            return NULL;
 
277
        }
 
278
        pbox = REGION_RECTS(&rgnDst);
 
279
        ppt = pptSrc;
 
280
        for (i = numRects; --i >= 0; pbox++, ppt++)
 
281
        {
 
282
            ppt->x = pbox->x1 + dx;
 
283
            ppt->y = pbox->y1 + dy;
 
284
        }
 
285
 
 
286
        (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask, bitPlane);
 
287
        DEALLOCATE_LOCAL(pptSrc);
 
288
    }
 
289
 
 
290
    prgnExposed = NULL;
 
291
    if (pGC->fExpose)
 
292
    {
 
293
        extern RegionPtr    miHandleExposures();
 
294
 
 
295
        /* Pixmap sources generate a NoExposed (we return NULL to do this) */
 
296
        if (!fastExpose)
 
297
            prgnExposed =
 
298
                miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
 
299
                                  origSource.x, origSource.y,
 
300
                                  (int)origSource.width,
 
301
                                  (int)origSource.height,
 
302
                                  origDest.x, origDest.y, bitPlane);
 
303
    }
 
304
    REGION_UNINIT(pGC->pScreen, &rgnDst);
 
305
    if (freeSrcClip)
 
306
        REGION_DESTROY(pGC->pScreen, prgnSrcClip);
 
307
    return prgnExposed;
 
308
}
 
309
 
 
310
 
 
311
void
 
312
iplDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc, planemask)
 
313
    DrawablePtr     pSrc, pDst;
 
314
    int             alu;
 
315
    RegionPtr       prgnDst;
 
316
    DDXPointPtr     pptSrc;
 
317
    unsigned long   planemask;
 
318
{
 
319
    void (*blt)() = iplDoBitbltGeneral;
 
320
    if ((planemask & INTER_PMSK) == INTER_PMSK) {
 
321
        switch (alu) {
 
322
        case GXcopy:
 
323
            blt = iplDoBitbltCopy;
 
324
            break;
 
325
        case GXxor:
 
326
            blt = iplDoBitbltXor;
 
327
            break;
 
328
        case GXor:
 
329
            blt = iplDoBitbltOr;
 
330
            break;
 
331
        }
 
332
    }
 
333
    (*blt) (pSrc, pDst, alu, prgnDst, pptSrc, planemask);
 
334
}
 
335
 
 
336
RegionPtr
 
337
iplCopyArea(pSrcDrawable, pDstDrawable,
 
338
            pGC, srcx, srcy, width, height, dstx, dsty)
 
339
    register DrawablePtr pSrcDrawable;
 
340
    register DrawablePtr pDstDrawable;
 
341
    GC *pGC;
 
342
    int srcx, srcy;
 
343
    int width, height;
 
344
    int dstx, dsty;
 
345
{
 
346
    void (*doBitBlt) ();
 
347
    
 
348
    doBitBlt = iplDoBitbltCopy;
 
349
    if (pGC->alu != GXcopy || (pGC->planemask & INTER_PMSK) != INTER_PMSK)
 
350
    {
 
351
        doBitBlt = iplDoBitbltGeneral;
 
352
        if ((pGC->planemask & INTER_PMSK) == INTER_PMSK)
 
353
        {
 
354
            switch (pGC->alu) {
 
355
            case GXxor:
 
356
                doBitBlt = iplDoBitbltXor;
 
357
                break;
 
358
            case GXor:
 
359
                doBitBlt = iplDoBitbltOr;
 
360
                break;
 
361
            }
 
362
        }
 
363
    }
 
364
    return iplBitBlt (pSrcDrawable, pDstDrawable,
 
365
            pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0L);
 
366
}
 
367
 
 
368
/* shared among all different ipl depths through linker magic */
 
369
RegionPtr   (*iplPuntCopyPlane)();
 
370
 
 
371
RegionPtr iplCopyPlane(pSrcDrawable, pDstDrawable,
 
372
            pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
 
373
    DrawablePtr         pSrcDrawable;
 
374
    DrawablePtr         pDstDrawable;
 
375
    GCPtr               pGC;
 
376
    int                 srcx, srcy;
 
377
    int                 width, height;
 
378
    int                 dstx, dsty;
 
379
    unsigned long       bitPlane;
 
380
{
 
381
    RegionPtr   ret;
 
382
    extern RegionPtr    miHandleExposures();
 
383
    void                (*doBitBlt)();
 
384
 
 
385
    ret = (*iplPuntCopyPlane) (pSrcDrawable, pDstDrawable,
 
386
            pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
 
387
    return ret;
 
388
}