~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

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