123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- #ifdef HAVE_XORG_CONFIG_H
- #include <xorg-config.h>
- #endif
- #include <string.h>
- #include "misc.h"
- #include "xf86.h"
- #include "xf86_OSproc.h"
- #include <X11/X.h>
- #include "scrnintstr.h"
- #include "pixmapstr.h"
- #include "windowstr.h"
- #include "xf86str.h"
- #include "cursorstr.h"
- #include "mi.h"
- #include "mipointer.h"
- #include "xf86CursorPriv.h"
- #include "servermd.h"
- 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));
- }
- #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)
- {
- 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;
- }
- #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)
- #endif /* BITMAP_SCANLINE_PAD == 64 */
- 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);
- Bool
- xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
- {
- if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
- return FALSE;
- /* These are required for now */
- if (!infoPtr->SetCursorPosition ||
- !xf86DriverHasLoadCursorImage(infoPtr) ||
- !infoPtr->HideCursor ||
- !infoPtr->ShowCursor || !infoPtr->SetCursorColors)
- return FALSE;
- if (infoPtr->RealizeCursor) {
- /* 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;
- }
- infoPtr->pScrn = xf86ScreenToScrn(pScreen);
- return TRUE;
- }
- Bool
- xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
- {
- xf86CursorScreenPtr ScreenPriv =
- (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
- xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- unsigned char *bits;
- if (pCurs == NullCursor) {
- (*infoPtr->HideCursor) (infoPtr->pScrn);
- return TRUE;
- }
- bits =
- dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen);
- x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
- y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
- #ifdef ARGB_CURSOR
- if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr))
- #endif
- if (!bits) {
- bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs);
- dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
- bits);
- }
- if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
- (*infoPtr->HideCursor) (infoPtr->pScrn);
- #ifdef ARGB_CURSOR
- if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) {
- if (!xf86DriverLoadCursorARGB (infoPtr, pCurs))
- return FALSE;
- } else
- #endif
- if (bits)
- if (!xf86DriverLoadCursorImage (infoPtr, bits))
- return FALSE;
- xf86RecolorCursor(pScreen, pCurs, 1);
- (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
- (*infoPtr->ShowCursor) (infoPtr->pScrn);
- return TRUE;
- }
- void
- xf86SetTransparentCursor(ScreenPtr pScreen)
- {
- xf86CursorScreenPtr ScreenPriv =
- (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
- xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- if (!ScreenPriv->transparentData)
- ScreenPriv->transparentData =
- (*infoPtr->RealizeCursor) (infoPtr, NullCursor);
- if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
- (*infoPtr->HideCursor) (infoPtr->pScrn);
- if (ScreenPriv->transparentData)
- xf86DriverLoadCursorImage (infoPtr,
- ScreenPriv->transparentData);
- (*infoPtr->ShowCursor) (infoPtr->pScrn);
- }
- void
- xf86MoveCursor(ScreenPtr pScreen, int x, int y)
- {
- xf86CursorScreenPtr ScreenPriv =
- (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
- xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
- y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
- (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
- }
- void
- xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
- {
- xf86CursorScreenPtr ScreenPriv =
- (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
- xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- #ifdef ARGB_CURSOR
- /* recoloring isn't applicable to ARGB cursors and drivers
- shouldn't have to ignore SetCursorColors requests */
- if (pCurs->bits->argb)
- return;
- #endif
- if (ScreenPriv->PalettedCursor) {
- 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)
- );
- }
- }
- /* These functions assume that MaxWidth is a multiple of 32 */
- static unsigned char *
- 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;
- /* how many words are in the source or mask */
- int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
- if (!(mem = calloc(1, size)))
- return NULL;
- if (pCurs == NullCursor) {
- 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;
- }
- /* SrcPitch == the number of scanlines wide the cursor image is */
- SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
- CUR_LOG2_BITMAP_PAD;
- /* DstPitch is the width of the hw cursor in scanlines */
- DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
- Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
- SrcS = (SCANLINE *) pCurs->bits->source;
- SrcM = (SCANLINE *) pCurs->bits->mask;
- DstS = (SCANLINE *) mem;
- DstM = DstS + words;
- if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
- SCANLINE *tmp;
- tmp = DstS;
- DstS = DstM;
- DstM = tmp;
- }
- if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
- 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];
- }
- }
- }
- if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
- 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;
- }
- }
- /*
- * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
- * out entire source mask.
- */
- if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
- int count = words;
- SCANLINE *pntr = DstM;
- while (count--) {
- *pntr = ~(*pntr);
- pntr++;
- }
- }
- if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
- 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]);
- }
- }
- }
- return mem;
- }
- static unsigned char *
- 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)))
- return NULL;
- if (!(mem = calloc(1, size))) {
- free(mem2);
- return NULL;
- }
- /* 1 bit interleave */
- DstS = mem2;
- DstM = DstS + (size >> 1);
- pntr = mem;
- count = size;
- while (count) {
- *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;
- }
- /* Free the uninterleaved cursor */
- free(mem2);
- return mem;
- }
- static unsigned char *
- 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)))
- return NULL;
- if (!(mem = calloc(1, size))) {
- free(mem2);
- return NULL;
- }
- /* 8 bit interleave */
- DstS = mem2;
- DstM = DstS + (size >> 1);
- pntr = mem;
- count = size;
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- count -= 2;
- }
- /* Free the uninterleaved cursor */
- free(mem2);
- return mem;
- }
- static unsigned char *
- 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)))
- return NULL;
- if (!(mem = calloc(1, size))) {
- free(mem2);
- return NULL;
- }
- /* 16 bit interleave */
- DstS = (void *) mem2;
- DstM = DstS + (size >> 2);
- pntr = (void *) mem;
- count = (size >> 1);
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- count -= 2;
- }
- /* Free the uninterleaved cursor */
- free(mem2);
- return mem;
- }
- static unsigned char *
- 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)))
- return NULL;
- if (!(mem = calloc(1, size))) {
- free(mem2);
- return NULL;
- }
- /* 32 bit interleave */
- DstS = (void *) mem2;
- DstM = DstS + (size >> 3);
- pntr = (void *) mem;
- count = (size >> 2);
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- count -= 2;
- }
- /* Free the uninterleaved cursor */
- free(mem2);
- return mem;
- }
- static unsigned char *
- 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)))
- return NULL;
- if (!(mem = calloc(1, size))) {
- free(mem2);
- return NULL;
- }
- /* 64 bit interleave */
- DstS = (void *) mem2;
- DstM = DstS + (size >> 3);
- pntr = (void *) mem;
- count = (size >> 2);
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- *pntr++ = *DstM++;
- count -= 4;
- }
- /* Free the uninterleaved cursor */
- free(mem2);
- return mem;
- }
|