~sbeattie/ubuntu/lucid/vnc4/lp556147

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/fb/fbblt.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Id: fbblt.c,v 1.1 1999/11/02 03:54:45 keithp Exp $
 
3
 *
 
4
 * Copyright � 1998 Keith Packard
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of Keith Packard not be used in
 
11
 * advertising or publicity pertaining to distribution of the software without
 
12
 * specific, written prior permission.  Keith Packard makes no
 
13
 * representations about the suitability of this software for any purpose.  It
 
14
 * is provided "as is" without express or implied warranty.
 
15
 *
 
16
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
18
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
20
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
21
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
22
 * PERFORMANCE OF THIS SOFTWARE.
 
23
 */
 
24
/* $XFree86: xc/programs/Xserver/fb/fbblt.c,v 1.8 2000/09/28 00:47:22 keithp Exp $ */
 
25
 
 
26
#include "fb.h"
 
27
 
 
28
#define InitializeShifts(sx,dx,ls,rs) { \
 
29
    if (sx != dx) { \
 
30
        if (sx > dx) { \
 
31
            ls = sx - dx; \
 
32
            rs = FB_UNIT - ls; \
 
33
        } else { \
 
34
            rs = dx - sx; \
 
35
            ls = FB_UNIT - rs; \
 
36
        } \
 
37
    } \
 
38
}
 
39
 
 
40
void
 
41
fbBlt (FbBits   *srcLine,
 
42
       FbStride srcStride,
 
43
       int      srcX,
 
44
       
 
45
       FbBits   *dstLine,
 
46
       FbStride dstStride,
 
47
       int      dstX,
 
48
       
 
49
       int      width, 
 
50
       int      height,
 
51
       
 
52
       int      alu,
 
53
       FbBits   pm,
 
54
       int      bpp,
 
55
       
 
56
       Bool     reverse,
 
57
       Bool     upsidedown)
 
58
{
 
59
    FbBits  *src, *dst;
 
60
    int     leftShift, rightShift;
 
61
    FbBits  startmask, endmask;
 
62
    FbBits  bits, bits1;
 
63
    int     n, nmiddle;
 
64
    Bool    destInvarient;
 
65
    int     startbyte, endbyte;
 
66
    FbDeclareMergeRop ();
 
67
 
 
68
#ifdef FB_24BIT
 
69
    if (bpp == 24 && !FbCheck24Pix (pm))
 
70
    {
 
71
        fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
 
72
                 width, height, alu, pm, reverse, upsidedown);
 
73
        return;
 
74
    }
 
75
#endif
 
76
    FbInitializeMergeRop(alu, pm);
 
77
    destInvarient = FbDestInvarientMergeRop();
 
78
    if (upsidedown)
 
79
    {
 
80
        srcLine += (height - 1) * (srcStride);
 
81
        dstLine += (height - 1) * (dstStride);
 
82
        srcStride = -srcStride;
 
83
        dstStride = -dstStride;
 
84
    }
 
85
    FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
 
86
                     nmiddle, endmask, endbyte);
 
87
    if (reverse)
 
88
    {
 
89
        srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
 
90
        dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
 
91
        srcX = (srcX + width - 1) & FB_MASK;
 
92
        dstX = (dstX + width - 1) & FB_MASK;
 
93
    }
 
94
    else
 
95
    {
 
96
        srcLine += srcX >> FB_SHIFT;
 
97
        dstLine += dstX >> FB_SHIFT;
 
98
        srcX &= FB_MASK;
 
99
        dstX &= FB_MASK;
 
100
    }
 
101
    if (srcX == dstX)
 
102
    {
 
103
        while (height--)
 
104
        {
 
105
            src = srcLine;
 
106
            srcLine += srcStride;
 
107
            dst = dstLine;
 
108
            dstLine += dstStride;
 
109
            if (reverse)
 
110
            {
 
111
                if (endmask)
 
112
                {
 
113
                    bits = *--src;
 
114
                    --dst;
 
115
                    FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
 
116
                }
 
117
                n = nmiddle;
 
118
                if (destInvarient)
 
119
                {
 
120
                    while (n--)
 
121
                        *--dst = FbDoDestInvarientMergeRop(*--src);
 
122
                }
 
123
                else
 
124
                {
 
125
                    while (n--)
 
126
                    {
 
127
                        bits = *--src;
 
128
                        --dst;
 
129
                        *dst = FbDoMergeRop (bits, *dst);
 
130
                    }
 
131
                }
 
132
                if (startmask)
 
133
                {
 
134
                    bits = *--src;
 
135
                    --dst;
 
136
                    FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
 
137
                }
 
138
            }
 
139
            else
 
140
            {
 
141
                if (startmask)
 
142
                {
 
143
                    bits = *src++;
 
144
                    FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
 
145
                    dst++;
 
146
                }
 
147
                n = nmiddle;
 
148
                if (destInvarient)
 
149
                {
 
150
#if 0
 
151
                    /*
 
152
                     * This provides some speedup on screen->screen blts
 
153
                     * over the PCI bus, usually about 10%.  But fb
 
154
                     * isn't usually used for this operation...
 
155
                     */
 
156
                    if (_ca2 + 1 == 0 && _cx2 == 0)
 
157
                    {
 
158
                        FbBits  t1, t2, t3, t4;
 
159
                        while (n >= 4)
 
160
                        {
 
161
                            t1 = *src++;
 
162
                            t2 = *src++;
 
163
                            t3 = *src++;
 
164
                            t4 = *src++;
 
165
                            *dst++ = t1;
 
166
                            *dst++ = t2;
 
167
                            *dst++ = t3;
 
168
                            *dst++ = t4;
 
169
                            n -= 4;
 
170
                        }
 
171
                    }
 
172
#endif
 
173
                    while (n--)
 
174
                        *dst++ = FbDoDestInvarientMergeRop(*src++);
 
175
                }
 
176
                else
 
177
                {
 
178
                    while (n--)
 
179
                    {
 
180
                        bits = *src++;
 
181
                        *dst = FbDoMergeRop (bits, *dst);
 
182
                        dst++;
 
183
                    }
 
184
                }
 
185
                if (endmask)
 
186
                {
 
187
                    bits = *src;
 
188
                    FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
 
189
                }
 
190
            }
 
191
        }
 
192
    }
 
193
    else
 
194
    {
 
195
        if (srcX > dstX)
 
196
        {
 
197
            leftShift = srcX - dstX;
 
198
            rightShift = FB_UNIT - leftShift;
 
199
        }
 
200
        else
 
201
        {
 
202
            rightShift = dstX - srcX;
 
203
            leftShift = FB_UNIT - rightShift;
 
204
        }
 
205
        while (height--)
 
206
        {
 
207
            src = srcLine;
 
208
            srcLine += srcStride;
 
209
            dst = dstLine;
 
210
            dstLine += dstStride;
 
211
            
 
212
            bits1 = 0;
 
213
            if (reverse)
 
214
            {
 
215
                if (srcX < dstX)
 
216
                    bits1 = *--src;
 
217
                if (endmask)
 
218
                {
 
219
                    bits = FbScrRight(bits1, rightShift); 
 
220
                    if (FbScrRight(endmask, leftShift))
 
221
                    {
 
222
                        bits1 = *--src;
 
223
                        bits |= FbScrLeft(bits1, leftShift);
 
224
                    }
 
225
                    --dst;
 
226
                    FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
 
227
                }
 
228
                n = nmiddle;
 
229
                if (destInvarient)
 
230
                {
 
231
                    while (n--)
 
232
                    {
 
233
                        bits = FbScrRight(bits1, rightShift); 
 
234
                        bits1 = *--src;
 
235
                        bits |= FbScrLeft(bits1, leftShift);
 
236
                        --dst;
 
237
                        *dst = FbDoDestInvarientMergeRop(bits);
 
238
                    }
 
239
                }
 
240
                else
 
241
                {
 
242
                    while (n--)
 
243
                    {
 
244
                        bits = FbScrRight(bits1, rightShift); 
 
245
                        bits1 = *--src;
 
246
                        bits |= FbScrLeft(bits1, leftShift);
 
247
                        --dst;
 
248
                        *dst = FbDoMergeRop(bits, *dst);
 
249
                    }
 
250
                }
 
251
                if (startmask)
 
252
                {
 
253
                    bits = FbScrRight(bits1, rightShift); 
 
254
                    if (FbScrRight(startmask, leftShift))
 
255
                    {
 
256
                        bits1 = *--src;
 
257
                        bits |= FbScrLeft(bits1, leftShift);
 
258
                    }
 
259
                    --dst;
 
260
                    FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
 
261
                }
 
262
            }
 
263
            else
 
264
            {
 
265
                if (srcX > dstX)
 
266
                    bits1 = *src++;
 
267
                if (startmask)
 
268
                {
 
269
                    bits = FbScrLeft(bits1, leftShift); 
 
270
                    bits1 = *src++;
 
271
                    bits |= FbScrRight(bits1, rightShift);
 
272
                    FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
 
273
                    dst++;
 
274
                }
 
275
                n = nmiddle;
 
276
                if (destInvarient)
 
277
                {
 
278
                    while (n--)
 
279
                    {
 
280
                        bits = FbScrLeft(bits1, leftShift); 
 
281
                        bits1 = *src++;
 
282
                        bits |= FbScrRight(bits1, rightShift);
 
283
                        *dst = FbDoDestInvarientMergeRop(bits);
 
284
                        dst++;
 
285
                    }
 
286
                }
 
287
                else
 
288
                {
 
289
                    while (n--)
 
290
                    {
 
291
                        bits = FbScrLeft(bits1, leftShift); 
 
292
                        bits1 = *src++;
 
293
                        bits |= FbScrRight(bits1, rightShift);
 
294
                        *dst = FbDoMergeRop(bits, *dst);
 
295
                        dst++;
 
296
                    }
 
297
                }
 
298
                if (endmask)
 
299
                {
 
300
                    bits = FbScrLeft(bits1, leftShift); 
 
301
                    if (FbScrLeft(endmask, rightShift))
 
302
                    {
 
303
                        bits1 = *src;
 
304
                        bits |= FbScrRight(bits1, rightShift);
 
305
                    }
 
306
                    FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
 
307
                }
 
308
            }
 
309
        }
 
310
    }
 
311
}
 
312
 
 
313
#ifdef FB_24BIT
 
314
 
 
315
#undef DEBUG_BLT24
 
316
#ifdef DEBUG_BLT24
 
317
 
 
318
static unsigned long
 
319
getPixel (char *src, int x)
 
320
{
 
321
    unsigned long   l;
 
322
 
 
323
    l = 0;
 
324
    memcpy (&l, src + x * 3, 3);
 
325
    return l;
 
326
}
 
327
#endif
 
328
 
 
329
static void
 
330
fbBlt24Line (FbBits         *src,
 
331
             int            srcX,
 
332
 
 
333
             FbBits         *dst,
 
334
             int            dstX,
 
335
 
 
336
             int            width,
 
337
 
 
338
             int            alu,
 
339
             FbBits         pm,
 
340
         
 
341
             Bool           reverse)
 
342
{
 
343
#ifdef DEBUG_BLT24
 
344
    char    *origDst = (char *) dst;
 
345
    FbBits  *origLine = dst + ((dstX >> FB_SHIFT) - 1);
 
346
    int     origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
 
347
    int     origX = dstX / 24;
 
348
#endif
 
349
    
 
350
    int     leftShift, rightShift;
 
351
    FbBits  startmask, endmask;
 
352
    int     n;
 
353
    
 
354
    FbBits  bits, bits1;
 
355
    FbBits  mask;
 
356
 
 
357
    int     rot;
 
358
    FbDeclareMergeRop ();
 
359
    
 
360
    FbInitializeMergeRop (alu, FB_ALLONES);
 
361
    FbMaskBits(dstX, width, startmask, n, endmask);
 
362
#ifdef DEBUG_BLT24
 
363
    ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse);
 
364
#endif
 
365
    if (reverse)
 
366
    {
 
367
        src += ((srcX + width - 1) >> FB_SHIFT) + 1;
 
368
        dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
 
369
        rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK));
 
370
        rot = FbPrev24Rot(rot);
 
371
#ifdef DEBUG_BLT24
 
372
        ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot);
 
373
#endif
 
374
        srcX = (srcX + width - 1) & FB_MASK;
 
375
        dstX = (dstX + width - 1) & FB_MASK;
 
376
    }
 
377
    else
 
378
    {
 
379
        src += srcX >> FB_SHIFT;
 
380
        dst += dstX >> FB_SHIFT;
 
381
        srcX &= FB_MASK;
 
382
        dstX &= FB_MASK;
 
383
        rot = FbFirst24Rot (dstX);
 
384
#ifdef DEBUG_BLT24
 
385
        ErrorF ("dstX: %d rot: %d\n", dstX, rot);
 
386
#endif
 
387
    }
 
388
    mask = FbRot24(pm,rot);
 
389
#ifdef DEBUG_BLT24
 
390
    ErrorF ("pm 0x%x mask 0x%x\n", pm, mask);
 
391
#endif
 
392
    if (srcX == dstX)
 
393
    {
 
394
        if (reverse)
 
395
        {
 
396
            if (endmask)
 
397
            {
 
398
                bits = *--src;
 
399
                --dst;
 
400
                *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
 
401
                mask = FbPrev24Pix (mask);
 
402
            }
 
403
            while (n--)
 
404
            {
 
405
                bits = *--src;
 
406
                --dst;
 
407
                *dst = FbDoMaskMergeRop (bits, *dst, mask);
 
408
                mask = FbPrev24Pix (mask);
 
409
            }
 
410
            if (startmask)
 
411
            {
 
412
                bits = *--src;
 
413
                --dst;
 
414
                *dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
 
415
            }
 
416
        }
 
417
        else
 
418
        {
 
419
            if (startmask)
 
420
            {
 
421
                bits = *src++;
 
422
                *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
 
423
                dst++;
 
424
                mask = FbNext24Pix(mask);
 
425
            }
 
426
            while (n--)
 
427
            {
 
428
                bits = *src++;
 
429
                *dst = FbDoMaskMergeRop (bits, *dst, mask);
 
430
                dst++;
 
431
                mask = FbNext24Pix(mask);
 
432
            }
 
433
            if (endmask)
 
434
            {
 
435
                bits = *src;
 
436
                *dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
 
437
            }
 
438
        }
 
439
    }
 
440
    else
 
441
    {
 
442
        if (srcX > dstX)
 
443
        {
 
444
            leftShift = srcX - dstX;
 
445
            rightShift = FB_UNIT - leftShift;
 
446
        }
 
447
        else
 
448
        {
 
449
            rightShift = dstX - srcX;
 
450
            leftShift = FB_UNIT - rightShift;
 
451
        }
 
452
        
 
453
        bits1 = 0;
 
454
        if (reverse)
 
455
        {
 
456
            if (srcX < dstX)
 
457
                bits1 = *--src;
 
458
            if (endmask)
 
459
            {
 
460
                bits = FbScrRight(bits1, rightShift); 
 
461
                if (FbScrRight(endmask, leftShift))
 
462
                {
 
463
                    bits1 = *--src;
 
464
                    bits |= FbScrLeft(bits1, leftShift);
 
465
                }
 
466
                --dst;
 
467
                *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
 
468
                mask = FbPrev24Pix(mask);
 
469
            }
 
470
            while (n--)
 
471
            {
 
472
                bits = FbScrRight(bits1, rightShift); 
 
473
                bits1 = *--src;
 
474
                bits |= FbScrLeft(bits1, leftShift);
 
475
                --dst;
 
476
                *dst = FbDoMaskMergeRop(bits, *dst, mask);
 
477
                mask = FbPrev24Pix(mask);
 
478
            }
 
479
            if (startmask)
 
480
            {
 
481
                bits = FbScrRight(bits1, rightShift); 
 
482
                if (FbScrRight(startmask, leftShift))
 
483
                {
 
484
                    bits1 = *--src;
 
485
                    bits |= FbScrLeft(bits1, leftShift);
 
486
                }
 
487
                --dst;
 
488
                *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
 
489
            }
 
490
        }
 
491
        else
 
492
        {
 
493
            if (srcX > dstX)
 
494
                bits1 = *src++;
 
495
            if (startmask)
 
496
            {
 
497
                bits = FbScrLeft(bits1, leftShift); 
 
498
                bits1 = *src++;
 
499
                bits |= FbScrRight(bits1, rightShift);
 
500
                *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
 
501
                dst++;
 
502
                mask = FbNext24Pix(mask);
 
503
            }
 
504
            while (n--)
 
505
            {
 
506
                bits = FbScrLeft(bits1, leftShift); 
 
507
                bits1 = *src++;
 
508
                bits |= FbScrRight(bits1, rightShift);
 
509
                *dst = FbDoMaskMergeRop(bits, *dst, mask);
 
510
                dst++;
 
511
                mask = FbNext24Pix(mask);
 
512
            }
 
513
            if (endmask)
 
514
            {
 
515
                bits = FbScrLeft(bits1, leftShift); 
 
516
                if (FbScrLeft(endmask, rightShift))
 
517
                {
 
518
                    bits1 = *src;
 
519
                    bits |= FbScrRight(bits1, rightShift);
 
520
                }
 
521
                *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
 
522
            }
 
523
        }
 
524
    }
 
525
#ifdef DEBUG_BLT24
 
526
    {
 
527
        int firstx, lastx, x;
 
528
 
 
529
        firstx = origX;
 
530
        if (firstx)
 
531
            firstx--;
 
532
        lastx = origX + width/24 + 1;
 
533
        for (x = firstx; x <= lastx; x++)
 
534
            ErrorF ("%06x ", getPixel (origDst, x));
 
535
        ErrorF ("\n");
 
536
        while (origNlw--)
 
537
            ErrorF ("%08x ", *origLine++);
 
538
        ErrorF ("\n");
 
539
    }
 
540
#endif
 
541
}
 
542
 
 
543
void
 
544
fbBlt24 (FbBits     *srcLine,
 
545
         FbStride   srcStride,
 
546
         int        srcX,
 
547
 
 
548
         FbBits     *dstLine,
 
549
         FbStride   dstStride,
 
550
         int        dstX,
 
551
 
 
552
         int        width, 
 
553
         int        height,
 
554
 
 
555
         int        alu,
 
556
         FbBits     pm,
 
557
 
 
558
         Bool       reverse,
 
559
         Bool       upsidedown)
 
560
{
 
561
    if (upsidedown)
 
562
    {
 
563
        srcLine += (height-1) * srcStride;
 
564
        dstLine += (height-1) * dstStride;
 
565
        srcStride = -srcStride;
 
566
        dstStride = -dstStride;
 
567
    }
 
568
    while (height--)
 
569
    {
 
570
        fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
 
571
        srcLine += srcStride;
 
572
        dstLine += dstStride;
 
573
    }
 
574
#ifdef DEBUG_BLT24
 
575
    ErrorF ("\n");
 
576
#endif
 
577
}
 
578
#endif /* FB_24BIT */
 
579
 
 
580
#if FB_SHIFT == FB_STIP_SHIFT + 1
 
581
 
 
582
/*
 
583
 * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
 
584
 * creating an ring of values stepped through for each line
 
585
 */
 
586
 
 
587
void
 
588
fbBltOdd (FbBits    *srcLine,
 
589
          FbStride  srcStrideEven,
 
590
          FbStride  srcStrideOdd,
 
591
          int       srcXEven,
 
592
          int       srcXOdd,
 
593
 
 
594
          FbBits    *dstLine,
 
595
          FbStride  dstStrideEven,
 
596
          FbStride  dstStrideOdd,
 
597
          int       dstXEven,
 
598
          int       dstXOdd,
 
599
 
 
600
          int       width,
 
601
          int       height,
 
602
 
 
603
          int       alu,
 
604
          FbBits    pm,
 
605
          int       bpp)
 
606
{
 
607
    FbBits  *src;
 
608
    int     leftShiftEven, rightShiftEven;
 
609
    FbBits  startmaskEven, endmaskEven;
 
610
    int     nmiddleEven;
 
611
    
 
612
    FbBits  *dst;
 
613
    int     leftShiftOdd, rightShiftOdd;
 
614
    FbBits  startmaskOdd, endmaskOdd;
 
615
    int     nmiddleOdd;
 
616
 
 
617
    int     leftShift, rightShift;
 
618
    FbBits  startmask, endmask;
 
619
    int     nmiddle;
 
620
    
 
621
    int     srcX, dstX;
 
622
    
 
623
    FbBits  bits, bits1;
 
624
    int     n;
 
625
    
 
626
    Bool    destInvarient;
 
627
    Bool    even;
 
628
    FbDeclareMergeRop ();
 
629
 
 
630
    FbInitializeMergeRop (alu, pm);
 
631
    destInvarient = FbDestInvarientMergeRop();
 
632
 
 
633
    srcLine += srcXEven >> FB_SHIFT;
 
634
    dstLine += dstXEven >> FB_SHIFT;
 
635
    srcXEven &= FB_MASK;
 
636
    dstXEven &= FB_MASK;
 
637
    srcXOdd &= FB_MASK;
 
638
    dstXOdd &= FB_MASK;
 
639
 
 
640
    FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
 
641
    FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
 
642
    
 
643
    even = TRUE;
 
644
    InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
 
645
    InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
 
646
    while (height--)
 
647
    {
 
648
        src = srcLine;
 
649
        dst = dstLine;
 
650
        if (even)
 
651
        {
 
652
            srcX = srcXEven;
 
653
            dstX = dstXEven;
 
654
            startmask = startmaskEven;
 
655
            endmask = endmaskEven;
 
656
            nmiddle = nmiddleEven;
 
657
            leftShift = leftShiftEven;
 
658
            rightShift = rightShiftEven;
 
659
            srcLine += srcStrideEven;
 
660
            dstLine += dstStrideEven;
 
661
            even = FALSE;
 
662
        }
 
663
        else
 
664
        {
 
665
            srcX = srcXOdd;
 
666
            dstX = dstXOdd;
 
667
            startmask = startmaskOdd;
 
668
            endmask = endmaskOdd;
 
669
            nmiddle = nmiddleOdd;
 
670
            leftShift = leftShiftOdd;
 
671
            rightShift = rightShiftOdd;
 
672
            srcLine += srcStrideOdd;
 
673
            dstLine += dstStrideOdd;
 
674
            even = TRUE;
 
675
        }
 
676
        if (srcX == dstX)
 
677
        {
 
678
            if (startmask)
 
679
            {
 
680
                bits = *src++;
 
681
                *dst = FbDoMaskMergeRop (bits, *dst, startmask);
 
682
                dst++;
 
683
            }
 
684
            n = nmiddle;
 
685
            if (destInvarient)
 
686
            {
 
687
                while (n--)
 
688
                {
 
689
                    bits = *src++;
 
690
                    *dst = FbDoDestInvarientMergeRop(bits);
 
691
                    dst++;
 
692
                }
 
693
            }
 
694
            else
 
695
            {
 
696
                while (n--)
 
697
                {
 
698
                    bits = *src++;
 
699
                    *dst = FbDoMergeRop (bits, *dst);
 
700
                    dst++;
 
701
                }
 
702
            }
 
703
            if (endmask)
 
704
            {
 
705
                bits = *src;
 
706
                *dst = FbDoMaskMergeRop(bits, *dst, endmask);
 
707
            }
 
708
        }
 
709
        else
 
710
        {
 
711
            bits = 0;
 
712
            if (srcX > dstX)
 
713
                bits = *src++;
 
714
            if (startmask)
 
715
            {
 
716
                bits1 = FbScrLeft(bits, leftShift);
 
717
                bits = *src++;
 
718
                bits1 |= FbScrRight(bits, rightShift);
 
719
                *dst = FbDoMaskMergeRop (bits1, *dst, startmask);
 
720
                dst++;
 
721
            }
 
722
            n = nmiddle;
 
723
            if (destInvarient)
 
724
            {
 
725
                while (n--)
 
726
                {
 
727
                    bits1 = FbScrLeft(bits, leftShift);
 
728
                    bits = *src++;
 
729
                    bits1 |= FbScrRight(bits, rightShift);
 
730
                    *dst = FbDoDestInvarientMergeRop(bits1);
 
731
                    dst++;
 
732
                }
 
733
            }
 
734
            else
 
735
            {
 
736
                while (n--)
 
737
                {
 
738
                    bits1 = FbScrLeft(bits, leftShift);
 
739
                    bits = *src++;
 
740
                    bits1 |= FbScrRight(bits, rightShift);
 
741
                    *dst = FbDoMergeRop(bits1, *dst);
 
742
                    dst++;
 
743
                }
 
744
            }
 
745
            if (endmask)
 
746
            {
 
747
                bits1 = FbScrLeft(bits, leftShift);
 
748
                if (FbScrLeft(endmask, rightShift))
 
749
                {
 
750
                    bits = *src;
 
751
                    bits1 |= FbScrRight(bits, rightShift);
 
752
                }
 
753
                *dst = FbDoMaskMergeRop (bits1, *dst, endmask);
 
754
            }
 
755
        }
 
756
    }
 
757
}
 
758
 
 
759
#ifdef FB_24BIT
 
760
void
 
761
fbBltOdd24 (FbBits      *srcLine,
 
762
            FbStride    srcStrideEven,
 
763
            FbStride    srcStrideOdd,
 
764
            int         srcXEven,
 
765
            int         srcXOdd,
 
766
 
 
767
            FbBits      *dstLine,
 
768
            FbStride    dstStrideEven,
 
769
            FbStride    dstStrideOdd,
 
770
            int         dstXEven,
 
771
            int         dstXOdd,
 
772
 
 
773
            int         width,
 
774
            int         height,
 
775
 
 
776
            int         alu,
 
777
            FbBits      pm)
 
778
{
 
779
    Bool    even = TRUE;
 
780
    
 
781
    while (height--)
 
782
    {
 
783
        if (even)
 
784
        {
 
785
            fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven,
 
786
                         width, alu, pm, FALSE);
 
787
            srcLine += srcStrideEven;
 
788
            dstLine += dstStrideEven;
 
789
            even = FALSE;
 
790
        }
 
791
        else
 
792
        {
 
793
            fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd,
 
794
                         width, alu, pm, FALSE);
 
795
            srcLine += srcStrideOdd;
 
796
            dstLine += dstStrideOdd;
 
797
            even = TRUE;
 
798
        }
 
799
    }
 
800
#if 0
 
801
    fprintf (stderr, "\n");
 
802
#endif
 
803
}
 
804
#endif
 
805
 
 
806
#endif
 
807
 
 
808
#if FB_STIP_SHIFT != FB_SHIFT
 
809
void
 
810
fbSetBltOdd (FbStip     *stip,
 
811
             FbStride   stipStride,
 
812
             int        srcX,
 
813
             FbBits     **bits,
 
814
             FbStride   *strideEven,
 
815
             FbStride   *strideOdd,
 
816
             int        *srcXEven,
 
817
             int        *srcXOdd)
 
818
{
 
819
    int     srcAdjust;
 
820
    int     strideAdjust;
 
821
 
 
822
    /*
 
823
     * bytes needed to align source
 
824
     */
 
825
    srcAdjust = (((int) stip) & (FB_MASK >> 3));
 
826
    /*
 
827
     * FbStip units needed to align stride
 
828
     */
 
829
    strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
 
830
 
 
831
    *bits = (FbBits *) ((char *) stip - srcAdjust);
 
832
    if (srcAdjust)
 
833
    {
 
834
        *strideEven = FbStipStrideToBitsStride (stipStride + 1);
 
835
        *strideOdd = FbStipStrideToBitsStride (stipStride);
 
836
 
 
837
        *srcXEven = srcX + (srcAdjust << 3);
 
838
        *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
 
839
    }
 
840
    else
 
841
    {
 
842
        *strideEven = FbStipStrideToBitsStride (stipStride);
 
843
        *strideOdd = FbStipStrideToBitsStride (stipStride + 1);
 
844
        
 
845
        *srcXEven = srcX;
 
846
        *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
 
847
    }
 
848
}
 
849
#endif
 
850
 
 
851
void
 
852
fbBltStip (FbStip   *src,
 
853
           FbStride srcStride,      /* in FbStip units, not FbBits units */
 
854
           int      srcX,
 
855
           
 
856
           FbStip   *dst,
 
857
           FbStride dstStride,      /* in FbStip units, not FbBits units */
 
858
           int      dstX,
 
859
 
 
860
           int      width, 
 
861
           int      height,
 
862
 
 
863
           int      alu,
 
864
           FbBits   pm,
 
865
           int      bpp)
 
866
{
 
867
#if FB_STIP_SHIFT != FB_SHIFT
 
868
    if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
 
869
        FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst))
 
870
    {
 
871
        FbStride    srcStrideEven, srcStrideOdd;
 
872
        FbStride    dstStrideEven, dstStrideOdd;
 
873
        int         srcXEven, srcXOdd;
 
874
        int         dstXEven, dstXOdd;
 
875
        FbBits      *s, *d;
 
876
        int         sx, dx;
 
877
        
 
878
        src += srcX >> FB_STIP_SHIFT;
 
879
        srcX &= FB_STIP_MASK;
 
880
        dst += dstX >> FB_STIP_SHIFT;
 
881
        dstX &= FB_STIP_MASK;
 
882
        
 
883
        fbSetBltOdd (src, srcStride, srcX,
 
884
                     &s,
 
885
                     &srcStrideEven, &srcStrideOdd,
 
886
                     &srcXEven, &srcXOdd);
 
887
                     
 
888
        fbSetBltOdd (dst, dstStride, dstX,
 
889
                     &d,
 
890
                     &dstStrideEven, &dstStrideOdd,
 
891
                     &dstXEven, &dstXOdd);
 
892
                     
 
893
#ifdef FB_24BIT
 
894
        if (bpp == 24 && !FbCheck24Pix (pm))
 
895
        {
 
896
            fbBltOdd24  (s, srcStrideEven, srcStrideOdd,
 
897
                         srcXEven, srcXOdd,
 
898
 
 
899
                         d, dstStrideEven, dstStrideOdd,
 
900
                         dstXEven, dstXOdd,
 
901
 
 
902
                         width, height, alu, pm);
 
903
        }
 
904
        else
 
905
#endif
 
906
        {
 
907
            fbBltOdd (s, srcStrideEven, srcStrideOdd,
 
908
                      srcXEven, srcXOdd,
 
909
    
 
910
                      d, dstStrideEven, dstStrideOdd,
 
911
                      dstXEven, dstXOdd,
 
912
    
 
913
                      width, height, alu, pm, bpp);
 
914
        }
 
915
    }
 
916
    else
 
917
#endif
 
918
    {
 
919
        fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), 
 
920
               srcX, 
 
921
               (FbBits *) dst, FbStipStrideToBitsStride (dstStride), 
 
922
               dstX, 
 
923
               width, height,
 
924
               alu, pm, bpp, FALSE, FALSE);
 
925
    }
 
926
}