xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xf86HWCurs.c (19671B)


      1 
      2 #ifdef HAVE_XORG_CONFIG_H
      3 #include <xorg-config.h>
      4 #endif
      5 
      6 #include <string.h>
      7 
      8 #include "misc.h"
      9 #include "xf86.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 "randrstr.h"
     21 #include "xf86CursorPriv.h"
     22 
     23 #include "servermd.h"
     24 
     25 static void
     26 xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs);
     27 
     28 static CARD32
     29 xf86ReverseBitOrder(CARD32 v)
     30 {
     31     return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) |
     32             ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) |
     33             ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) |
     34             ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7));
     35 }
     36 
     37 #if BITMAP_SCANLINE_PAD == 64
     38 
     39 #if 1
     40 /* Cursors might be only 32 wide. Give'em a chance */
     41 #define SCANLINE CARD32
     42 #define CUR_BITMAP_SCANLINE_PAD 32
     43 #define CUR_LOG2_BITMAP_PAD 5
     44 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
     45 #else
     46 #define SCANLINE CARD64
     47 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
     48 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
     49 #define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
     50 static CARD64 xf86CARD64ReverseBits(CARD64 w);
     51 
     52 static CARD64
     53 xf86CARD64ReverseBits(CARD64 w)
     54 {
     55     unsigned char *p = (unsigned char *) &w;
     56 
     57     p[0] = byte_reversed[p[0]];
     58     p[1] = byte_reversed[p[1]];
     59     p[2] = byte_reversed[p[2]];
     60     p[3] = byte_reversed[p[3]];
     61     p[4] = byte_reversed[p[4]];
     62     p[5] = byte_reversed[p[5]];
     63     p[6] = byte_reversed[p[6]];
     64     p[7] = byte_reversed[p[7]];
     65 
     66     return w;
     67 }
     68 #endif
     69 
     70 #else
     71 
     72 #define SCANLINE CARD32
     73 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
     74 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
     75 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
     76 
     77 #endif                          /* BITMAP_SCANLINE_PAD == 64 */
     78 
     79 static unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
     80 static unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
     81 static unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
     82 static unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
     83 static unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
     84 static unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
     85 
     86 Bool
     87 xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
     88 {
     89     if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
     90         return FALSE;
     91 
     92     /* These are required for now */
     93     if (!infoPtr->SetCursorPosition ||
     94         !xf86DriverHasLoadCursorImage(infoPtr) ||
     95         !infoPtr->HideCursor ||
     96         !xf86DriverHasShowCursor(infoPtr) ||
     97         !infoPtr->SetCursorColors)
     98         return FALSE;
     99 
    100     if (infoPtr->RealizeCursor) {
    101         /* Don't overwrite a driver provided Realize Cursor function */
    102     }
    103     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
    104         infoPtr->RealizeCursor = RealizeCursorInterleave1;
    105     }
    106     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
    107         infoPtr->RealizeCursor = RealizeCursorInterleave8;
    108     }
    109     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
    110         infoPtr->RealizeCursor = RealizeCursorInterleave16;
    111     }
    112     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
    113         infoPtr->RealizeCursor = RealizeCursorInterleave32;
    114     }
    115     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
    116         infoPtr->RealizeCursor = RealizeCursorInterleave64;
    117     }
    118     else {                      /* not interleaved */
    119         infoPtr->RealizeCursor = RealizeCursorInterleave0;
    120     }
    121 
    122     infoPtr->pScrn = xf86ScreenToScrn(pScreen);
    123 
    124     return TRUE;
    125 }
    126 
    127 static Bool
    128 xf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
    129 {
    130     return
    131         (cursor->bits->argb && infoPtr->UseHWCursorARGB &&
    132          infoPtr->UseHWCursorARGB(pScreen, cursor)) ||
    133         (cursor->bits->argb == 0 &&
    134          cursor->bits->height <= infoPtr->MaxHeight &&
    135          cursor->bits->width <= infoPtr->MaxWidth &&
    136          (!infoPtr->UseHWCursor || infoPtr->UseHWCursor(pScreen, cursor)));
    137 }
    138 
    139 Bool
    140 xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
    141 {
    142     ScreenPtr pSlave;
    143     Bool use_hw_cursor = TRUE;
    144 
    145     input_lock();
    146 
    147     if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) {
    148         use_hw_cursor = FALSE;
    149 	goto unlock;
    150     }
    151 
    152     /* ask each driver consuming a pixmap if it can support HW cursor */
    153     xorg_list_for_each_entry(pSlave, &pScreen->secondary_list, secondary_head) {
    154         xf86CursorScreenPtr sPriv;
    155 
    156         if (!RRHasScanoutPixmap(pSlave))
    157             continue;
    158 
    159         sPriv = dixLookupPrivate(&pSlave->devPrivates, xf86CursorScreenKey);
    160         if (!sPriv) { /* NULL if Option "SWCursor", possibly other conditions */
    161             use_hw_cursor = FALSE;
    162 	    break;
    163 	}
    164 
    165         /* FALSE if HWCursor not supported by secondary */
    166         if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) {
    167             use_hw_cursor = FALSE;
    168 	    break;
    169 	}
    170     }
    171 
    172 unlock:
    173     input_unlock();
    174 
    175     return use_hw_cursor;
    176 }
    177 
    178 static Bool
    179 xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
    180 {
    181     xf86CursorScreenPtr ScreenPriv =
    182         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    183                                                xf86CursorScreenKey);
    184 
    185     xf86CursorInfoPtr infoPtr;
    186     unsigned char *bits;
    187 
    188     if (!ScreenPriv) { /* NULL if Option "SWCursor" */
    189         return (pCurs == NullCursor);
    190     }
    191 
    192     infoPtr = ScreenPriv->CursorInfoPtr;
    193 
    194     if (pCurs == NullCursor) {
    195         (*infoPtr->HideCursor) (infoPtr->pScrn);
    196         return TRUE;
    197     }
    198 
    199     /*
    200      * Hot plugged GPU's do not have a CursorScreenKey, force sw cursor.
    201      * This check can be removed once dix/privates.c gets relocation code for
    202      * PRIVATE_CURSOR. Also see the related comment in AddGPUScreen().
    203      */
    204     if (!_dixGetScreenPrivateKey(CursorScreenKey, pScreen))
    205         return FALSE;
    206 
    207     bits =
    208         dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen);
    209 
    210     x -= infoPtr->pScrn->frameX0;
    211     y -= infoPtr->pScrn->frameY0;
    212 
    213     if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr))
    214         if (!bits) {
    215             bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs);
    216             dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
    217                                 bits);
    218         }
    219 
    220     if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
    221         (*infoPtr->HideCursor) (infoPtr->pScrn);
    222 
    223     if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) {
    224         if (!xf86DriverLoadCursorARGB (infoPtr, pCurs))
    225             return FALSE;
    226     } else
    227     if (bits)
    228         if (!xf86DriverLoadCursorImage (infoPtr, bits))
    229             return FALSE;
    230 
    231     xf86RecolorCursor_locked (ScreenPriv, pCurs);
    232 
    233     (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
    234 
    235     return xf86DriverShowCursor(infoPtr);
    236 }
    237 
    238 Bool
    239 xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
    240 {
    241     xf86CursorScreenPtr ScreenPriv =
    242         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    243                                                xf86CursorScreenKey);
    244     ScreenPtr pSlave;
    245     Bool ret = FALSE;
    246 
    247     input_lock();
    248 
    249     x -= ScreenPriv->HotX;
    250     y -= ScreenPriv->HotY;
    251 
    252     if (!xf86ScreenSetCursor(pScreen, pCurs, x, y))
    253         goto out;
    254 
    255     /* ask each secondary driver to set the cursor. */
    256     xorg_list_for_each_entry(pSlave, &pScreen->secondary_list, secondary_head) {
    257         if (!RRHasScanoutPixmap(pSlave))
    258             continue;
    259 
    260         if (!xf86ScreenSetCursor(pSlave, pCurs, x, y)) {
    261             /*
    262              * hide the primary (and successfully set secondary) cursors,
    263              * otherwise both the hw and sw cursor will show.
    264              */
    265             xf86SetCursor(pScreen, NullCursor, x, y);
    266             goto out;
    267         }
    268     }
    269     ret = TRUE;
    270 
    271  out:
    272     input_unlock();
    273     return ret;
    274 }
    275 
    276 void
    277 xf86SetTransparentCursor(ScreenPtr pScreen)
    278 {
    279     xf86CursorScreenPtr ScreenPriv =
    280         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    281                                                xf86CursorScreenKey);
    282     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    283 
    284     input_lock();
    285 
    286     if (!ScreenPriv->transparentData)
    287         ScreenPriv->transparentData =
    288             (*infoPtr->RealizeCursor) (infoPtr, NullCursor);
    289 
    290     if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
    291         (*infoPtr->HideCursor) (infoPtr->pScrn);
    292 
    293     if (ScreenPriv->transparentData)
    294         xf86DriverLoadCursorImage (infoPtr,
    295                                    ScreenPriv->transparentData);
    296 
    297     xf86DriverShowCursor(infoPtr);
    298 
    299     input_unlock();
    300 }
    301 
    302 static void
    303 xf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y)
    304 {
    305     xf86CursorScreenPtr ScreenPriv =
    306         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    307                                                xf86CursorScreenKey);
    308     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    309 
    310     x -= infoPtr->pScrn->frameX0;
    311     y -= infoPtr->pScrn->frameY0;
    312 
    313     (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
    314 }
    315 
    316 void
    317 xf86MoveCursor(ScreenPtr pScreen, int x, int y)
    318 {
    319     xf86CursorScreenPtr ScreenPriv =
    320         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    321                                                xf86CursorScreenKey);
    322     ScreenPtr pSlave;
    323 
    324     input_lock();
    325 
    326     x -= ScreenPriv->HotX;
    327     y -= ScreenPriv->HotY;
    328 
    329     xf86ScreenMoveCursor(pScreen, x, y);
    330 
    331     /* ask each secondary driver to move the cursor */
    332     xorg_list_for_each_entry(pSlave, &pScreen->secondary_list, secondary_head) {
    333         if (!RRHasScanoutPixmap(pSlave))
    334             continue;
    335 
    336         xf86ScreenMoveCursor(pSlave, x, y);
    337     }
    338 
    339     input_unlock();
    340 }
    341 
    342 static void
    343 xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs)
    344 {
    345     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    346 
    347     /* recoloring isn't applicable to ARGB cursors and drivers
    348        shouldn't have to ignore SetCursorColors requests */
    349     if (pCurs->bits->argb)
    350         return;
    351 
    352     if (ScreenPriv->PalettedCursor) {
    353         xColorItem sourceColor, maskColor;
    354         ColormapPtr pmap = ScreenPriv->pInstalledMap;
    355 
    356         if (!pmap)
    357             return;
    358 
    359         sourceColor.red = pCurs->foreRed;
    360         sourceColor.green = pCurs->foreGreen;
    361         sourceColor.blue = pCurs->foreBlue;
    362         FakeAllocColor(pmap, &sourceColor);
    363         maskColor.red = pCurs->backRed;
    364         maskColor.green = pCurs->backGreen;
    365         maskColor.blue = pCurs->backBlue;
    366         FakeAllocColor(pmap, &maskColor);
    367         FakeFreeColor(pmap, sourceColor.pixel);
    368         FakeFreeColor(pmap, maskColor.pixel);
    369         (*infoPtr->SetCursorColors) (infoPtr->pScrn,
    370                                      maskColor.pixel, sourceColor.pixel);
    371     }
    372     else {                      /* Pass colors in 8-8-8 RGB format */
    373         (*infoPtr->SetCursorColors) (infoPtr->pScrn,
    374                                      (pCurs->backBlue >> 8) |
    375                                      ((pCurs->backGreen >> 8) << 8) |
    376                                      ((pCurs->backRed >> 8) << 16),
    377                                      (pCurs->foreBlue >> 8) |
    378                                      ((pCurs->foreGreen >> 8) << 8) |
    379                                      ((pCurs->foreRed >> 8) << 16)
    380             );
    381     }
    382 }
    383 
    384 void
    385 xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
    386 {
    387     xf86CursorScreenPtr ScreenPriv =
    388         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    389                                                xf86CursorScreenKey);
    390 
    391     input_lock();
    392     xf86RecolorCursor_locked (ScreenPriv, pCurs);
    393     input_unlock();
    394 }
    395 
    396 /* These functions assume that MaxWidth is a multiple of 32 */
    397 static unsigned char *
    398 RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
    399 {
    400 
    401     SCANLINE *SrcS, *SrcM, *DstS, *DstM;
    402     SCANLINE *pSrc, *pMsk;
    403     unsigned char *mem;
    404     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    405     int SrcPitch, DstPitch, Pitch, y, x;
    406 
    407     /* how many words are in the source or mask */
    408     int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
    409 
    410     if (!(mem = calloc(1, size)))
    411         return NULL;
    412 
    413     if (pCurs == NullCursor) {
    414         if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
    415             DstM = (SCANLINE *) mem;
    416             if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
    417                 DstM += words;
    418             memset(DstM, -1, words * sizeof(SCANLINE));
    419         }
    420         return mem;
    421     }
    422 
    423     /* SrcPitch == the number of scanlines wide the cursor image is */
    424     SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
    425         CUR_LOG2_BITMAP_PAD;
    426 
    427     /* DstPitch is the width of the hw cursor in scanlines */
    428     DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
    429     Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
    430 
    431     SrcS = (SCANLINE *) pCurs->bits->source;
    432     SrcM = (SCANLINE *) pCurs->bits->mask;
    433     DstS = (SCANLINE *) mem;
    434     DstM = DstS + words;
    435 
    436     if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
    437         SCANLINE *tmp;
    438 
    439         tmp = DstS;
    440         DstS = DstM;
    441         DstM = tmp;
    442     }
    443 
    444     if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
    445         for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
    446              y--;
    447              pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
    448              SrcPitch) {
    449             for (x = 0; x < Pitch; x++) {
    450                 pSrc[x] = SrcS[x] & SrcM[x];
    451                 pMsk[x] = SrcM[x];
    452             }
    453         }
    454     }
    455     else {
    456         for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
    457              y--;
    458              pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
    459              SrcPitch) {
    460             for (x = 0; x < Pitch; x++) {
    461                 pSrc[x] = SrcS[x];
    462                 pMsk[x] = SrcM[x];
    463             }
    464         }
    465     }
    466 
    467     if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
    468         int count = size;
    469         unsigned char *pntr1 = (unsigned char *) DstS;
    470         unsigned char *pntr2 = (unsigned char *) DstM;
    471         unsigned char a, b;
    472 
    473         while (count) {
    474 
    475             a = *pntr1;
    476             b = *pntr2;
    477             *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
    478             *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
    479             pntr1++;
    480             pntr2++;
    481             count -= 2;
    482         }
    483     }
    484 
    485     /*
    486      * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
    487      * out entire source mask.
    488      */
    489     if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
    490         int count = words;
    491         SCANLINE *pntr = DstM;
    492 
    493         while (count--) {
    494             *pntr = ~(*pntr);
    495             pntr++;
    496         }
    497     }
    498 
    499     if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
    500         for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
    501              y--; pSrc += DstPitch, pMsk += DstPitch) {
    502             for (x = 0; x < Pitch; x++) {
    503                 pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
    504                 pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
    505             }
    506         }
    507     }
    508 
    509     return mem;
    510 }
    511 
    512 static unsigned char *
    513 RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
    514 {
    515     unsigned char *DstS, *DstM;
    516     unsigned char *pntr;
    517     unsigned char *mem, *mem2;
    518     int count;
    519     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    520 
    521     /* Realize the cursor without interleaving */
    522     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
    523         return NULL;
    524 
    525     if (!(mem = calloc(1, size))) {
    526         free(mem2);
    527         return NULL;
    528     }
    529 
    530     /* 1 bit interleave */
    531     DstS = mem2;
    532     DstM = DstS + (size >> 1);
    533     pntr = mem;
    534     count = size;
    535     while (count) {
    536         *pntr++ = ((*DstS & 0x01)) | ((*DstM & 0x01) << 1) |
    537             ((*DstS & 0x02) << 1) | ((*DstM & 0x02) << 2) |
    538             ((*DstS & 0x04) << 2) | ((*DstM & 0x04) << 3) |
    539             ((*DstS & 0x08) << 3) | ((*DstM & 0x08) << 4);
    540         *pntr++ = ((*DstS & 0x10) >> 4) | ((*DstM & 0x10) >> 3) |
    541             ((*DstS & 0x20) >> 3) | ((*DstM & 0x20) >> 2) |
    542             ((*DstS & 0x40) >> 2) | ((*DstM & 0x40) >> 1) |
    543             ((*DstS & 0x80) >> 1) | ((*DstM & 0x80));
    544         DstS++;
    545         DstM++;
    546         count -= 2;
    547     }
    548 
    549     /* Free the uninterleaved cursor */
    550     free(mem2);
    551 
    552     return mem;
    553 }
    554 
    555 static unsigned char *
    556 RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
    557 {
    558     unsigned char *DstS, *DstM;
    559     unsigned char *pntr;
    560     unsigned char *mem, *mem2;
    561     int count;
    562     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    563 
    564     /* Realize the cursor without interleaving */
    565     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
    566         return NULL;
    567 
    568     if (!(mem = calloc(1, size))) {
    569         free(mem2);
    570         return NULL;
    571     }
    572 
    573     /* 8 bit interleave */
    574     DstS = mem2;
    575     DstM = DstS + (size >> 1);
    576     pntr = mem;
    577     count = size;
    578     while (count) {
    579         *pntr++ = *DstS++;
    580         *pntr++ = *DstM++;
    581         count -= 2;
    582     }
    583 
    584     /* Free the uninterleaved cursor */
    585     free(mem2);
    586 
    587     return mem;
    588 }
    589 
    590 static unsigned char *
    591 RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
    592 {
    593     unsigned short *DstS, *DstM;
    594     unsigned short *pntr;
    595     unsigned char *mem, *mem2;
    596     int count;
    597     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    598 
    599     /* Realize the cursor without interleaving */
    600     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
    601         return NULL;
    602 
    603     if (!(mem = calloc(1, size))) {
    604         free(mem2);
    605         return NULL;
    606     }
    607 
    608     /* 16 bit interleave */
    609     DstS = (void *) mem2;
    610     DstM = DstS + (size >> 2);
    611     pntr = (void *) mem;
    612     count = (size >> 1);
    613     while (count) {
    614         *pntr++ = *DstS++;
    615         *pntr++ = *DstM++;
    616         count -= 2;
    617     }
    618 
    619     /* Free the uninterleaved cursor */
    620     free(mem2);
    621 
    622     return mem;
    623 }
    624 
    625 static unsigned char *
    626 RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
    627 {
    628     CARD32 *DstS, *DstM;
    629     CARD32 *pntr;
    630     unsigned char *mem, *mem2;
    631     int count;
    632     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    633 
    634     /* Realize the cursor without interleaving */
    635     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
    636         return NULL;
    637 
    638     if (!(mem = calloc(1, size))) {
    639         free(mem2);
    640         return NULL;
    641     }
    642 
    643     /* 32 bit interleave */
    644     DstS = (void *) mem2;
    645     DstM = DstS + (size >> 3);
    646     pntr = (void *) mem;
    647     count = (size >> 2);
    648     while (count) {
    649         *pntr++ = *DstS++;
    650         *pntr++ = *DstM++;
    651         count -= 2;
    652     }
    653 
    654     /* Free the uninterleaved cursor */
    655     free(mem2);
    656 
    657     return mem;
    658 }
    659 
    660 static unsigned char *
    661 RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
    662 {
    663     CARD32 *DstS, *DstM;
    664     CARD32 *pntr;
    665     unsigned char *mem, *mem2;
    666     int count;
    667     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    668 
    669     /* Realize the cursor without interleaving */
    670     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
    671         return NULL;
    672 
    673     if (!(mem = calloc(1, size))) {
    674         free(mem2);
    675         return NULL;
    676     }
    677 
    678     /* 64 bit interleave */
    679     DstS = (void *) mem2;
    680     DstM = DstS + (size >> 3);
    681     pntr = (void *) mem;
    682     count = (size >> 2);
    683     while (count) {
    684         *pntr++ = *DstS++;
    685         *pntr++ = *DstS++;
    686         *pntr++ = *DstM++;
    687         *pntr++ = *DstM++;
    688         count -= 4;
    689     }
    690 
    691     /* Free the uninterleaved cursor */
    692     free(mem2);
    693 
    694     return mem;
    695 }