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

« back to all changes in this revision

Viewing changes to hw/xfree86/ramdac/xf86HWCurs.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/hw/xfree86/ramdac/xf86HWCurs.c,v 1.12 2003/02/13 20:28:41 tsi Exp $ */
 
2
 
 
3
#ifdef HAVE_XORG_CONFIG_H
 
4
#include <xorg-config.h>
 
5
#endif
 
6
 
 
7
#include "misc.h"
 
8
#include "xf86.h"
 
9
#include "xf86_ansic.h"
 
10
#include "xf86_OSproc.h"
 
11
 
 
12
#include <X11/X.h>
 
13
#include "scrnintstr.h"
 
14
#include "pixmapstr.h"
 
15
#include "windowstr.h"
 
16
#include "xf86str.h"
 
17
#include "cursorstr.h"
 
18
#include "mi.h"
 
19
#include "mipointer.h"
 
20
#include "xf86CursorPriv.h"
 
21
 
 
22
#include "servermd.h"
 
23
 
 
24
#if BITMAP_SCANLINE_PAD == 64
 
25
 
 
26
#if 1
 
27
/* Cursors might be only 32 wide. Give'em a chance */
 
28
#define SCANLINE CARD32
 
29
#define CUR_BITMAP_SCANLINE_PAD 32
 
30
#define CUR_LOG2_BITMAP_PAD 5
 
31
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
 
32
#else
 
33
#define SCANLINE CARD64
 
34
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
 
35
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
 
36
#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
 
37
static CARD64 xf86CARD64ReverseBits(CARD64 w);
 
38
 
 
39
static CARD64
 
40
xf86CARD64ReverseBits(CARD64 w)
 
41
{
 
42
  unsigned char *p = (unsigned char *)&w;
 
43
 
 
44
  p[0] = byte_reversed[p[0]];
 
45
  p[1] = byte_reversed[p[1]];
 
46
  p[2] = byte_reversed[p[2]];
 
47
  p[3] = byte_reversed[p[3]];
 
48
  p[4] = byte_reversed[p[4]];
 
49
  p[5] = byte_reversed[p[5]];
 
50
  p[6] = byte_reversed[p[6]];
 
51
  p[7] = byte_reversed[p[7]];
 
52
 
 
53
  return w;
 
54
}
 
55
#endif
 
56
 
 
57
#else
 
58
 
 
59
#define SCANLINE CARD32
 
60
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
 
61
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
 
62
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
 
63
 
 
64
#endif /* BITMAP_SCANLINE_PAD == 64 */
 
65
 
 
66
static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
 
67
static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
 
68
static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
 
69
static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
 
70
static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
 
71
static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
 
72
 
 
73
Bool
 
74
xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
 
75
{
 
76
    if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
 
77
        return FALSE;
 
78
 
 
79
    /* These are required for now */
 
80
    if (!infoPtr->SetCursorPosition ||
 
81
        !infoPtr->LoadCursorImage ||
 
82
        !infoPtr->HideCursor ||
 
83
        !infoPtr->ShowCursor ||
 
84
        !infoPtr->SetCursorColors)
 
85
        return FALSE;
 
86
 
 
87
    if (infoPtr->RealizeCursor) {
 
88
        /* Don't overwrite a driver provided Realize Cursor function */
 
89
    } else
 
90
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
 
91
        infoPtr->RealizeCursor = RealizeCursorInterleave1;
 
92
    } else
 
93
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
 
94
        infoPtr->RealizeCursor = RealizeCursorInterleave8;
 
95
    } else
 
96
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
 
97
        infoPtr->RealizeCursor = RealizeCursorInterleave16;
 
98
    } else
 
99
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
 
100
        infoPtr->RealizeCursor = RealizeCursorInterleave32;
 
101
    } else
 
102
    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
 
103
        infoPtr->RealizeCursor = RealizeCursorInterleave64;
 
104
    } else {    /* not interleaved */
 
105
        infoPtr->RealizeCursor = RealizeCursorInterleave0;
 
106
    }
 
107
 
 
108
    infoPtr->pScrn = xf86Screens[pScreen->myNum];
 
109
 
 
110
    return TRUE;
 
111
}
 
112
 
 
113
void
 
114
xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
 
115
{
 
116
    xf86CursorScreenPtr ScreenPriv =
 
117
        pScreen->devPrivates[xf86CursorScreenIndex].ptr;
 
118
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
119
    unsigned char *bits;
 
120
 
 
121
    if (pCurs == NullCursor) {
 
122
        (*infoPtr->HideCursor)(infoPtr->pScrn);
 
123
        return;
 
124
    }
 
125
 
 
126
    bits = pCurs->devPriv[pScreen->myNum];
 
127
 
 
128
    x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
 
129
    y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
 
130
 
 
131
#ifdef ARGB_CURSOR
 
132
    if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
 
133
#endif
 
134
    if (!bits) {
 
135
        bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
 
136
        pCurs->devPriv[pScreen->myNum] = bits;
 
137
    }
 
138
 
 
139
    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
 
140
        (*infoPtr->HideCursor)(infoPtr->pScrn);
 
141
 
 
142
#ifdef ARGB_CURSOR
 
143
    if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
 
144
        (*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
 
145
    else
 
146
#endif
 
147
    if (bits)
 
148
        (*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
 
149
 
 
150
    xf86RecolorCursor(pScreen, pCurs, 1);
 
151
 
 
152
    (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
 
153
 
 
154
    (*infoPtr->ShowCursor)(infoPtr->pScrn);
 
155
}
 
156
 
 
157
void
 
158
xf86SetTransparentCursor(ScreenPtr pScreen)
 
159
{
 
160
    xf86CursorScreenPtr ScreenPriv =
 
161
        pScreen->devPrivates[xf86CursorScreenIndex].ptr;
 
162
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
163
 
 
164
    if (!ScreenPriv->transparentData)
 
165
        ScreenPriv->transparentData =
 
166
            (*infoPtr->RealizeCursor)(infoPtr, NullCursor);
 
167
 
 
168
    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
 
169
        (*infoPtr->HideCursor)(infoPtr->pScrn);
 
170
 
 
171
    if (ScreenPriv->transparentData)
 
172
        (*infoPtr->LoadCursorImage)(infoPtr->pScrn,
 
173
                                    ScreenPriv->transparentData);
 
174
 
 
175
    (*infoPtr->ShowCursor)(infoPtr->pScrn);
 
176
}
 
177
 
 
178
void
 
179
xf86MoveCursor(ScreenPtr pScreen, int x, int y)
 
180
{
 
181
    xf86CursorScreenPtr ScreenPriv =
 
182
        pScreen->devPrivates[xf86CursorScreenIndex].ptr;
 
183
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
184
 
 
185
    x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
 
186
    y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
 
187
 
 
188
    (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
 
189
}
 
190
 
 
191
void
 
192
xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
 
193
{
 
194
    xf86CursorScreenPtr ScreenPriv =
 
195
        pScreen->devPrivates[xf86CursorScreenIndex].ptr;
 
196
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
197
 
 
198
#ifdef ARGB_CURSOR
 
199
    /* recoloring isn't applicable to ARGB cursors and drivers 
 
200
       shouldn't have to ignore SetCursorColors requests */
 
201
    if (pCurs->bits->argb)
 
202
        return;
 
203
#endif
 
204
 
 
205
    if (ScreenPriv->PalettedCursor) {
 
206
        xColorItem sourceColor, maskColor;
 
207
        ColormapPtr pmap = ScreenPriv->pInstalledMap;
 
208
        
 
209
        if (!pmap)
 
210
            return;
 
211
 
 
212
        sourceColor.red = pCurs->foreRed;
 
213
        sourceColor.green = pCurs->foreGreen;
 
214
        sourceColor.blue = pCurs->foreBlue;
 
215
        FakeAllocColor(pmap, &sourceColor);
 
216
        maskColor.red = pCurs->backRed;
 
217
        maskColor.green = pCurs->backGreen;
 
218
        maskColor.blue = pCurs->backBlue;
 
219
        FakeAllocColor(pmap, &maskColor);
 
220
        FakeFreeColor(pmap, sourceColor.pixel);
 
221
        FakeFreeColor(pmap, maskColor.pixel);
 
222
        (*infoPtr->SetCursorColors)(infoPtr->pScrn,
 
223
                maskColor.pixel, sourceColor.pixel);
 
224
    } else {    /* Pass colors in 8-8-8 RGB format */
 
225
        (*infoPtr->SetCursorColors)(infoPtr->pScrn,
 
226
            (pCurs->backBlue >> 8) |
 
227
            ((pCurs->backGreen >> 8) << 8) |
 
228
            ((pCurs->backRed >> 8) << 16),
 
229
            (pCurs->foreBlue >> 8) |
 
230
            ((pCurs->foreGreen >> 8) << 8) |
 
231
            ((pCurs->foreRed >> 8) << 16)
 
232
        );
 
233
    }
 
234
}
 
235
 
 
236
/* These functions assume that MaxWidth is a multiple of 32 */
 
237
static unsigned char*
 
238
RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
 
239
{
 
240
 
 
241
    SCANLINE *SrcS, *SrcM, *DstS, *DstM;
 
242
    SCANLINE *pSrc, *pMsk;
 
243
    unsigned char *mem;
 
244
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
 
245
    int SrcPitch, DstPitch, Pitch, y, x;
 
246
    /* how many words are in the source or mask */
 
247
    int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
 
248
 
 
249
 
 
250
    if (!(mem = xcalloc(1, size)))
 
251
        return NULL;
 
252
 
 
253
    if (pCurs == NullCursor) {
 
254
        if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
 
255
            DstM = (SCANLINE*)mem;
 
256
            if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
 
257
                DstM += words;
 
258
            (void)memset(DstM, -1, words * sizeof(SCANLINE));
 
259
        }
 
260
        return mem;
 
261
    }
 
262
 
 
263
    /* SrcPitch == the number of scanlines wide the cursor image is */
 
264
    SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
 
265
      CUR_LOG2_BITMAP_PAD;
 
266
 
 
267
    /* DstPitch is the width of the hw cursor in scanlines */
 
268
    DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
 
269
    Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
 
270
 
 
271
    SrcS = (SCANLINE*)pCurs->bits->source;
 
272
    SrcM = (SCANLINE*)pCurs->bits->mask;
 
273
    DstS = (SCANLINE*)mem;
 
274
    DstM = DstS + words;
 
275
 
 
276
    if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
 
277
        SCANLINE *tmp;
 
278
        tmp = DstS; DstS = DstM; DstM = tmp;
 
279
    }
 
280
 
 
281
    if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
 
282
        for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
 
283
            y--;
 
284
            pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
 
285
            for(x = 0; x < Pitch; x++) {
 
286
                pSrc[x] = SrcS[x] & SrcM[x];
 
287
                pMsk[x] = SrcM[x];
 
288
            }
 
289
        }
 
290
    } else {
 
291
        for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
 
292
            y--;
 
293
            pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
 
294
            for(x = 0; x < Pitch; x++) {
 
295
                pSrc[x] = SrcS[x];
 
296
                pMsk[x] = SrcM[x];
 
297
            }
 
298
        }
 
299
    }
 
300
 
 
301
    if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
 
302
        int count = size;
 
303
        unsigned char* pntr1 = (unsigned char *)DstS;
 
304
        unsigned char* pntr2 = (unsigned char *)DstM;
 
305
        unsigned char a, b;
 
306
        while (count) {
 
307
 
 
308
           a = *pntr1;
 
309
           b = *pntr2;
 
310
           *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
 
311
           *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
 
312
           pntr1++; pntr2++;
 
313
           count-=2;
 
314
        }
 
315
    }
 
316
 
 
317
    /*
 
318
     * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
 
319
     * out entire source mask.
 
320
     */
 
321
    if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
 
322
        int count = words;
 
323
        SCANLINE* pntr = DstM;
 
324
        while (count--) {
 
325
           *pntr = ~(*pntr);
 
326
            pntr++;
 
327
        }
 
328
    }
 
329
 
 
330
    if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
 
331
        for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
 
332
            y--;
 
333
            pSrc+=DstPitch, pMsk+=DstPitch) {
 
334
            for(x = 0; x < Pitch; x++) {
 
335
                pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
 
336
                pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
 
337
            }
 
338
        }
 
339
    }
 
340
 
 
341
    return mem;
 
342
}
 
343
 
 
344
static unsigned char*
 
345
RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
 
346
{
 
347
    unsigned char *DstS, *DstM;
 
348
    unsigned char *pntr;
 
349
    unsigned char *mem, *mem2;
 
350
    int count;
 
351
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
 
352
 
 
353
    /* Realize the cursor without interleaving */
 
354
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
 
355
        return NULL;
 
356
 
 
357
    if (!(mem = xcalloc(1, size))) {
 
358
        xfree(mem2);
 
359
        return NULL;
 
360
    }
 
361
 
 
362
     /* 1 bit interleave */
 
363
    DstS = mem2;
 
364
    DstM = DstS + (size >> 1);
 
365
    pntr = mem;
 
366
    count = size;
 
367
    while (count) {
 
368
        *pntr++ = ((*DstS&0x01)     ) | ((*DstM&0x01) << 1) |
 
369
                  ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
 
370
                  ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
 
371
                  ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
 
372
        *pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
 
373
                  ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
 
374
                  ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
 
375
                  ((*DstS&0x80) >> 1) | ((*DstM&0x80)     );
 
376
        DstS++;
 
377
        DstM++;
 
378
        count-=2;
 
379
    }
 
380
 
 
381
    /* Free the uninterleaved cursor */
 
382
    xfree(mem2);
 
383
 
 
384
    return mem;
 
385
}
 
386
 
 
387
static unsigned char*
 
388
RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
 
389
{
 
390
    unsigned char *DstS, *DstM;
 
391
    unsigned char *pntr;
 
392
    unsigned char *mem, *mem2;
 
393
    int count;
 
394
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
 
395
 
 
396
    /* Realize the cursor without interleaving */
 
397
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
 
398
        return NULL;
 
399
 
 
400
    if (!(mem = xcalloc(1, size))) {
 
401
        xfree(mem2);
 
402
        return NULL;
 
403
    }
 
404
 
 
405
    /* 8 bit interleave */
 
406
    DstS = mem2;
 
407
    DstM = DstS + (size >> 1);
 
408
    pntr = mem;
 
409
    count = size;
 
410
    while (count) {
 
411
        *pntr++ = *DstS++;
 
412
        *pntr++ = *DstM++;
 
413
        count-=2;
 
414
    }
 
415
 
 
416
    /* Free the uninterleaved cursor */
 
417
    xfree(mem2);
 
418
 
 
419
    return mem;
 
420
}
 
421
 
 
422
static unsigned char*
 
423
RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
 
424
{
 
425
    unsigned short *DstS, *DstM;
 
426
    unsigned short *pntr;
 
427
    unsigned char *mem, *mem2;
 
428
    int count;
 
429
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
 
430
 
 
431
    /* Realize the cursor without interleaving */
 
432
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
 
433
        return NULL;
 
434
 
 
435
    if (!(mem = xcalloc(1, size))) {
 
436
        xfree(mem2);
 
437
        return NULL;
 
438
    }
 
439
 
 
440
    /* 16 bit interleave */
 
441
    DstS = (pointer)mem2;
 
442
    DstM = DstS + (size >> 2);
 
443
    pntr = (pointer)mem;
 
444
    count = (size >> 1);
 
445
    while (count) {
 
446
        *pntr++ = *DstS++;
 
447
        *pntr++ = *DstM++;
 
448
        count-=2;
 
449
    }
 
450
 
 
451
    /* Free the uninterleaved cursor */
 
452
    xfree(mem2);
 
453
 
 
454
    return mem;
 
455
}
 
456
 
 
457
static unsigned char*
 
458
RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
 
459
{
 
460
    CARD32 *DstS, *DstM;
 
461
    CARD32 *pntr;
 
462
    unsigned char *mem, *mem2;
 
463
    int count;
 
464
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
 
465
 
 
466
    /* Realize the cursor without interleaving */
 
467
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
 
468
        return NULL;
 
469
 
 
470
    if (!(mem = xcalloc(1, size))) {
 
471
        xfree(mem2);
 
472
        return NULL;
 
473
    }
 
474
 
 
475
    /* 32 bit interleave */
 
476
    DstS = (pointer)mem2;
 
477
    DstM = DstS + (size >> 3);
 
478
    pntr = (pointer)mem;
 
479
    count = (size >> 2);
 
480
    while (count) {
 
481
        *pntr++ = *DstS++;
 
482
        *pntr++ = *DstM++;
 
483
        count-=2;
 
484
    }
 
485
 
 
486
    /* Free the uninterleaved cursor */
 
487
    xfree(mem2);
 
488
 
 
489
    return mem;
 
490
}
 
491
 
 
492
static unsigned char*
 
493
RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
 
494
{
 
495
    CARD32 *DstS, *DstM;
 
496
    CARD32 *pntr;
 
497
    unsigned char *mem, *mem2;
 
498
    int count;
 
499
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
 
500
 
 
501
    /* Realize the cursor without interleaving */
 
502
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
 
503
        return NULL;
 
504
 
 
505
    if (!(mem = xcalloc(1, size))) {
 
506
        xfree(mem2);
 
507
        return NULL;
 
508
    }
 
509
 
 
510
    /* 64 bit interleave */
 
511
    DstS = (pointer)mem2;
 
512
    DstM = DstS + (size >> 3);
 
513
    pntr = (pointer)mem;
 
514
    count = (size >> 2);
 
515
    while (count) {
 
516
        *pntr++ = *DstS++;
 
517
        *pntr++ = *DstS++;
 
518
        *pntr++ = *DstM++;
 
519
        *pntr++ = *DstM++;
 
520
        count-=4;
 
521
    }
 
522
 
 
523
    /* Free the uninterleaved cursor */
 
524
    xfree(mem2);
 
525
 
 
526
    return mem;
 
527
}