xf86HWCurs.c 19.1 KB
Newer Older
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
1

2 3 4 5
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif

6 7
#include <string.h>

8
#include "misc.h"
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
9 10 11
#include "xf86.h"
#include "xf86_OSproc.h"

12
#include <X11/X.h>
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
13 14 15 16 17 18 19
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "xf86str.h"
#include "cursorstr.h"
#include "mi.h"
#include "mipointer.h"
20
#include "randrstr.h"
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
21 22 23 24
#include "xf86CursorPriv.h"

#include "servermd.h"

25 26 27
static void
xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs);

Daniel Stone's avatar
Daniel Stone committed
28 29 30 31 32 33 34 35 36
static CARD32
xf86ReverseBitOrder(CARD32 v)
{
    return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) |
            ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) |
            ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) |
            ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7));
}

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
#if BITMAP_SCANLINE_PAD == 64

#if 1
/* Cursors might be only 32 wide. Give'em a chance */
#define SCANLINE CARD32
#define CUR_BITMAP_SCANLINE_PAD 32
#define CUR_LOG2_BITMAP_PAD 5
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
#else
#define SCANLINE CARD64
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
static CARD64 xf86CARD64ReverseBits(CARD64 w);

static CARD64
xf86CARD64ReverseBits(CARD64 w)
{
55 56 57 58 59 60 61 62 63 64 65 66
    unsigned char *p = (unsigned char *) &w;

    p[0] = byte_reversed[p[0]];
    p[1] = byte_reversed[p[1]];
    p[2] = byte_reversed[p[2]];
    p[3] = byte_reversed[p[3]];
    p[4] = byte_reversed[p[4]];
    p[5] = byte_reversed[p[5]];
    p[6] = byte_reversed[p[6]];
    p[7] = byte_reversed[p[7]];

    return w;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
67 68 69 70 71 72 73 74 75 76
}
#endif

#else

#define SCANLINE CARD32
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)

77
#endif                          /* BITMAP_SCANLINE_PAD == 64 */
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
78

79 80 81 82 83 84
static unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
static unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
static unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
static unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
static unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
static unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
85 86 87 88 89

Bool
xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
{
    if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
90
        return FALSE;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
91 92 93

    /* These are required for now */
    if (!infoPtr->SetCursorPosition ||
94
        !xf86DriverHasLoadCursorImage(infoPtr) ||
95
        !infoPtr->HideCursor ||
96 97
        !xf86DriverHasShowCursor(infoPtr) ||
        !infoPtr->SetCursorColors)
98
        return FALSE;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
99 100

    if (infoPtr->RealizeCursor) {
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
        /* Don't overwrite a driver provided Realize Cursor function */
    }
    else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
        infoPtr->RealizeCursor = RealizeCursorInterleave1;
    }
    else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
        infoPtr->RealizeCursor = RealizeCursorInterleave8;
    }
    else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
        infoPtr->RealizeCursor = RealizeCursorInterleave16;
    }
    else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
        infoPtr->RealizeCursor = RealizeCursorInterleave32;
    }
    else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
        infoPtr->RealizeCursor = RealizeCursorInterleave64;
    }
    else {                      /* not interleaved */
        infoPtr->RealizeCursor = RealizeCursorInterleave0;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
120 121
    }

122
    infoPtr->pScrn = xf86ScreenToScrn(pScreen);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
123 124 125 126

    return TRUE;
}

127 128
static Bool
xf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
129 130 131 132 133 134 135 136 137 138
{
    return
        (cursor->bits->argb && infoPtr->UseHWCursorARGB &&
         infoPtr->UseHWCursorARGB(pScreen, cursor)) ||
        (cursor->bits->argb == 0 &&
         cursor->bits->height <= infoPtr->MaxHeight &&
         cursor->bits->width <= infoPtr->MaxWidth &&
         (!infoPtr->UseHWCursor || infoPtr->UseHWCursor(pScreen, cursor)));
}

139
Bool
140 141 142
xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
{
    ScreenPtr pSlave;
143
    Bool use_hw_cursor = TRUE;
144

145 146 147 148 149 150
    input_lock();

    if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) {
        use_hw_cursor = FALSE;
	goto unlock;
    }
151 152 153 154 155 156 157 158 159

    /* ask each driver consuming a pixmap if it can support HW cursor */
    xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
        xf86CursorScreenPtr sPriv;

        if (!RRHasScanoutPixmap(pSlave))
            continue;

        sPriv = dixLookupPrivate(&pSlave->devPrivates, xf86CursorScreenKey);
160 161 162 163
        if (!sPriv) { /* NULL if Option "SWCursor", possibly other conditions */
            use_hw_cursor = FALSE;
	    break;
	}
164 165

        /* FALSE if HWCursor not supported by slave */
166 167 168 169
        if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) {
            use_hw_cursor = FALSE;
	    break;
	}
170
    }
171 172 173 174 175

unlock:
    input_unlock();

    return use_hw_cursor;
176 177 178 179
}

static Bool
xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
180
{
181 182 183
    xf86CursorScreenPtr ScreenPriv =
        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                               xf86CursorScreenKey);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
184 185 186 187
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    unsigned char *bits;

    if (pCurs == NullCursor) {
188
        (*infoPtr->HideCursor) (infoPtr->pScrn);
189
        return TRUE;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
190 191
    }

192 193 194 195 196 197 198 199
    /*
     * Hot plugged GPU's do not have a CursorScreenKey, force sw cursor.
     * This check can be removed once dix/privates.c gets relocation code for
     * PRIVATE_CURSOR. Also see the related comment in AddGPUScreen().
     */
    if (!_dixGetScreenPrivateKey(CursorScreenKey, pScreen))
        return FALSE;

200 201
    bits =
        dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
202

203 204
    x -= infoPtr->pScrn->frameX0;
    y -= infoPtr->pScrn->frameY0;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
205

206
    if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr))
207 208 209 210 211
        if (!bits) {
            bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs);
            dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
                                bits);
        }
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
212 213

    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
214
        (*infoPtr->HideCursor) (infoPtr->pScrn);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
215

216 217
    if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) {
        if (!xf86DriverLoadCursorARGB (infoPtr, pCurs))
218 219
            return FALSE;
    } else
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
220
    if (bits)
221
        if (!xf86DriverLoadCursorImage (infoPtr, bits))
222
            return FALSE;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
223

224
    xf86RecolorCursor_locked (ScreenPriv, pCurs);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
225

226
    (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
227

228
    return xf86DriverShowCursor(infoPtr);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
229 230
}

231 232 233
Bool
xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
{
234 235 236
    xf86CursorScreenPtr ScreenPriv =
        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                               xf86CursorScreenKey);
237
    ScreenPtr pSlave;
238 239 240
    Bool ret = FALSE;

    input_lock();
241

242 243 244
    x -= ScreenPriv->HotX;
    y -= ScreenPriv->HotY;

245
    if (!xf86ScreenSetCursor(pScreen, pCurs, x, y))
246
        goto out;
247 248 249 250 251 252 253 254 255 256 257 258

    /* ask each slave driver to set the cursor. */
    xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
        if (!RRHasScanoutPixmap(pSlave))
            continue;

        if (!xf86ScreenSetCursor(pSlave, pCurs, x, y)) {
            /*
             * hide the master (and successfully set slave) cursors,
             * otherwise both the hw and sw cursor will show.
             */
            xf86SetCursor(pScreen, NullCursor, x, y);
259
            goto out;
260 261
        }
    }
262 263 264 265 266
    ret = TRUE;

 out:
    input_unlock();
    return ret;
267 268
}

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
269 270 271
void
xf86SetTransparentCursor(ScreenPtr pScreen)
{
272 273 274
    xf86CursorScreenPtr ScreenPriv =
        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                               xf86CursorScreenKey);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
275 276
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;

277 278
    input_lock();

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
279
    if (!ScreenPriv->transparentData)
280 281
        ScreenPriv->transparentData =
            (*infoPtr->RealizeCursor) (infoPtr, NullCursor);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
282 283

    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
284
        (*infoPtr->HideCursor) (infoPtr->pScrn);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
285 286

    if (ScreenPriv->transparentData)
287 288
        xf86DriverLoadCursorImage (infoPtr,
                                   ScreenPriv->transparentData);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
289

290
    xf86DriverShowCursor(infoPtr);
291 292

    input_unlock();
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
293 294
}

295 296
static void
xf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y)
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
297
{
298 299 300
    xf86CursorScreenPtr ScreenPriv =
        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                               xf86CursorScreenKey);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
301 302
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;

303 304
    x -= infoPtr->pScrn->frameX0;
    y -= infoPtr->pScrn->frameY0;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
305

306
    (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
307 308
}

309 310 311
void
xf86MoveCursor(ScreenPtr pScreen, int x, int y)
{
312 313 314
    xf86CursorScreenPtr ScreenPriv =
        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                               xf86CursorScreenKey);
315 316
    ScreenPtr pSlave;

317 318
    input_lock();

319 320 321
    x -= ScreenPriv->HotX;
    y -= ScreenPriv->HotY;

322 323 324 325 326 327 328 329 330
    xf86ScreenMoveCursor(pScreen, x, y);

    /* ask each slave driver to move the cursor */
    xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
        if (!RRHasScanoutPixmap(pSlave))
            continue;

        xf86ScreenMoveCursor(pSlave, x, y);
    }
331 332

    input_unlock();
333 334
}

335 336
static void
xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs)
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
337 338 339
{
    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;

Peter Hutterer's avatar
Peter Hutterer committed
340
    /* recoloring isn't applicable to ARGB cursors and drivers
341 342 343 344
       shouldn't have to ignore SetCursorColors requests */
    if (pCurs->bits->argb)
        return;

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
345
    if (ScreenPriv->PalettedCursor) {
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
        xColorItem sourceColor, maskColor;
        ColormapPtr pmap = ScreenPriv->pInstalledMap;

        if (!pmap)
            return;

        sourceColor.red = pCurs->foreRed;
        sourceColor.green = pCurs->foreGreen;
        sourceColor.blue = pCurs->foreBlue;
        FakeAllocColor(pmap, &sourceColor);
        maskColor.red = pCurs->backRed;
        maskColor.green = pCurs->backGreen;
        maskColor.blue = pCurs->backBlue;
        FakeAllocColor(pmap, &maskColor);
        FakeFreeColor(pmap, sourceColor.pixel);
        FakeFreeColor(pmap, maskColor.pixel);
        (*infoPtr->SetCursorColors) (infoPtr->pScrn,
                                     maskColor.pixel, sourceColor.pixel);
    }
    else {                      /* Pass colors in 8-8-8 RGB format */
        (*infoPtr->SetCursorColors) (infoPtr->pScrn,
                                     (pCurs->backBlue >> 8) |
                                     ((pCurs->backGreen >> 8) << 8) |
                                     ((pCurs->backRed >> 8) << 16),
                                     (pCurs->foreBlue >> 8) |
                                     ((pCurs->foreGreen >> 8) << 8) |
                                     ((pCurs->foreRed >> 8) << 16)
            );
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
374 375 376
    }
}

377 378 379 380 381 382 383 384 385 386 387 388
void
xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
{
    xf86CursorScreenPtr ScreenPriv =
        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
                                               xf86CursorScreenKey);

    input_lock();
    xf86RecolorCursor_locked (ScreenPriv, pCurs);
    input_unlock();
}

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
389
/* These functions assume that MaxWidth is a multiple of 32 */
390
static unsigned char *
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
391 392 393 394 395 396 397 398
RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{

    SCANLINE *SrcS, *SrcM, *DstS, *DstM;
    SCANLINE *pSrc, *pMsk;
    unsigned char *mem;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
    int SrcPitch, DstPitch, Pitch, y, x;
399

Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
400 401 402
    /* how many words are in the source or mask */
    int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);

403
    if (!(mem = calloc(1, size)))
404
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
405 406

    if (pCurs == NullCursor) {
407 408 409 410 411 412 413
        if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
            DstM = (SCANLINE *) mem;
            if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
                DstM += words;
            memset(DstM, -1, words * sizeof(SCANLINE));
        }
        return mem;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
414 415 416 417
    }

    /* SrcPitch == the number of scanlines wide the cursor image is */
    SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
418
        CUR_LOG2_BITMAP_PAD;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
419 420 421 422 423

    /* DstPitch is the width of the hw cursor in scanlines */
    DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
    Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;

424 425 426
    SrcS = (SCANLINE *) pCurs->bits->source;
    SrcM = (SCANLINE *) pCurs->bits->mask;
    DstS = (SCANLINE *) mem;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
427 428 429
    DstM = DstS + words;

    if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
430 431 432 433 434
        SCANLINE *tmp;

        tmp = DstS;
        DstS = DstM;
        DstM = tmp;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
435 436 437
    }

    if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
        for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
             y--;
             pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
             SrcPitch) {
            for (x = 0; x < Pitch; x++) {
                pSrc[x] = SrcS[x] & SrcM[x];
                pMsk[x] = SrcM[x];
            }
        }
    }
    else {
        for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
             y--;
             pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
             SrcPitch) {
            for (x = 0; x < Pitch; x++) {
                pSrc[x] = SrcS[x];
                pMsk[x] = SrcM[x];
            }
        }
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
458 459 460
    }

    if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
        int count = size;
        unsigned char *pntr1 = (unsigned char *) DstS;
        unsigned char *pntr2 = (unsigned char *) DstM;
        unsigned char a, b;

        while (count) {

            a = *pntr1;
            b = *pntr2;
            *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
            *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
            pntr1++;
            pntr2++;
            count -= 2;
        }
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
476 477 478 479 480 481 482
    }

    /*
     * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
     * out entire source mask.
     */
    if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
483 484 485 486 487 488 489
        int count = words;
        SCANLINE *pntr = DstM;

        while (count--) {
            *pntr = ~(*pntr);
            pntr++;
        }
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
490 491 492
    }

    if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
493 494 495 496 497 498 499
        for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
             y--; pSrc += DstPitch, pMsk += DstPitch) {
            for (x = 0; x < Pitch; x++) {
                pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
                pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
            }
        }
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
500 501 502 503 504
    }

    return mem;
}

505
static unsigned char *
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
506 507 508 509 510 511 512 513 514 515
RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    unsigned char *DstS, *DstM;
    unsigned char *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
516
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
517

518
    if (!(mem = calloc(1, size))) {
519 520
        free(mem2);
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
521 522
    }

523
    /* 1 bit interleave */
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
524 525 526 527 528
    DstS = mem2;
    DstM = DstS + (size >> 1);
    pntr = mem;
    count = size;
    while (count) {
529 530 531 532 533 534 535 536 537 538 539
        *pntr++ = ((*DstS & 0x01)) | ((*DstM & 0x01) << 1) |
            ((*DstS & 0x02) << 1) | ((*DstM & 0x02) << 2) |
            ((*DstS & 0x04) << 2) | ((*DstM & 0x04) << 3) |
            ((*DstS & 0x08) << 3) | ((*DstM & 0x08) << 4);
        *pntr++ = ((*DstS & 0x10) >> 4) | ((*DstM & 0x10) >> 3) |
            ((*DstS & 0x20) >> 3) | ((*DstM & 0x20) >> 2) |
            ((*DstS & 0x40) >> 2) | ((*DstM & 0x40) >> 1) |
            ((*DstS & 0x80) >> 1) | ((*DstM & 0x80));
        DstS++;
        DstM++;
        count -= 2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
540 541 542
    }

    /* Free the uninterleaved cursor */
543
    free(mem2);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
544 545 546 547

    return mem;
}

548
static unsigned char *
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
549 550 551 552 553 554 555 556 557 558
RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    unsigned char *DstS, *DstM;
    unsigned char *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
559
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
560

561
    if (!(mem = calloc(1, size))) {
562 563
        free(mem2);
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
564 565 566 567 568 569 570 571
    }

    /* 8 bit interleave */
    DstS = mem2;
    DstM = DstS + (size >> 1);
    pntr = mem;
    count = size;
    while (count) {
572 573 574
        *pntr++ = *DstS++;
        *pntr++ = *DstM++;
        count -= 2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
575 576 577
    }

    /* Free the uninterleaved cursor */
578
    free(mem2);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
579 580 581 582

    return mem;
}

583
static unsigned char *
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
584 585 586 587 588 589 590 591 592 593
RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    unsigned short *DstS, *DstM;
    unsigned short *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
594
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
595

596
    if (!(mem = calloc(1, size))) {
597 598
        free(mem2);
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
599 600 601
    }

    /* 16 bit interleave */
602
    DstS = (void *) mem2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
603
    DstM = DstS + (size >> 2);
604
    pntr = (void *) mem;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
605 606
    count = (size >> 1);
    while (count) {
607 608 609
        *pntr++ = *DstS++;
        *pntr++ = *DstM++;
        count -= 2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
610 611 612
    }

    /* Free the uninterleaved cursor */
613
    free(mem2);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
614 615 616 617

    return mem;
}

618
static unsigned char *
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
619 620 621 622 623 624 625 626 627 628
RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    CARD32 *DstS, *DstM;
    CARD32 *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
629
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
630

631
    if (!(mem = calloc(1, size))) {
632 633
        free(mem2);
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
634 635 636
    }

    /* 32 bit interleave */
637
    DstS = (void *) mem2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
638
    DstM = DstS + (size >> 3);
639
    pntr = (void *) mem;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
640 641
    count = (size >> 2);
    while (count) {
642 643 644
        *pntr++ = *DstS++;
        *pntr++ = *DstM++;
        count -= 2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
645 646 647
    }

    /* Free the uninterleaved cursor */
648
    free(mem2);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
649 650 651 652

    return mem;
}

653
static unsigned char *
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
654 655 656 657 658 659 660 661 662 663
RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
    CARD32 *DstS, *DstM;
    CARD32 *pntr;
    unsigned char *mem, *mem2;
    int count;
    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;

    /* Realize the cursor without interleaving */
    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
664
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
665

666
    if (!(mem = calloc(1, size))) {
667 668
        free(mem2);
        return NULL;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
669 670 671
    }

    /* 64 bit interleave */
672
    DstS = (void *) mem2;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
673
    DstM = DstS + (size >> 3);
674
    pntr = (void *) mem;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
675 676
    count = (size >> 2);
    while (count) {
677 678 679 680 681
        *pntr++ = *DstS++;
        *pntr++ = *DstS++;
        *pntr++ = *DstM++;
        *pntr++ = *DstM++;
        count -= 4;
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
682 683 684
    }

    /* Free the uninterleaved cursor */
685
    free(mem2);
Kaleb Keithley Keithley's avatar
Kaleb Keithley Keithley committed
686 687 688

    return mem;
}