xf86HWCurs.c revision 1b5d61b8
11.51Smsaitoh 21.1Sjdolecek#ifdef HAVE_XORG_CONFIG_H 31.1Sjdolecek#include <xorg-config.h> 41.1Sjdolecek#endif 51.40Smartin 61.1Sjdolecek#include <string.h> 71.1Sjdolecek 81.1Sjdolecek#include "misc.h" 91.1Sjdolecek#include "xf86.h" 101.1Sjdolecek#include "xf86_OSproc.h" 111.1Sjdolecek 121.1Sjdolecek#include <X11/X.h> 131.1Sjdolecek#include "scrnintstr.h" 141.1Sjdolecek#include "pixmapstr.h" 151.1Sjdolecek#include "windowstr.h" 161.1Sjdolecek#include "xf86str.h" 171.1Sjdolecek#include "cursorstr.h" 181.1Sjdolecek#include "mi.h" 191.40Smartin#include "mipointer.h" 201.40Smartin#include "randrstr.h" 211.40Smartin#include "xf86CursorPriv.h" 221.40Smartin 231.40Smartin#include "servermd.h" 241.40Smartin 251.40Smartinstatic void 261.40Smartinxf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs); 271.40Smartin 281.40Smartinstatic CARD32 291.40Smartinxf86ReverseBitOrder(CARD32 v) 301.1Sjdolecek{ 311.1Sjdolecek return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) | 321.1Sjdolecek ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) | 331.1Sjdolecek ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) | 341.1Sjdolecek ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7)); 351.1Sjdolecek} 361.1Sjdolecek 371.1Sjdolecek#if BITMAP_SCANLINE_PAD == 64 381.1Sjdolecek 391.1Sjdolecek#if 1 401.1Sjdolecek/* Cursors might be only 32 wide. Give'em a chance */ 411.11Sjdolecek#define SCANLINE CARD32 421.11Sjdolecek#define CUR_BITMAP_SCANLINE_PAD 32 431.1Sjdolecek#define CUR_LOG2_BITMAP_PAD 5 441.1Sjdolecek#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w) 451.1Sjdolecek#else 461.1Sjdolecek#define SCANLINE CARD64 471.10Slukem#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD 481.10Slukem#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD 491.51Smsaitoh#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w) 501.1Sjdolecekstatic CARD64 xf86CARD64ReverseBits(CARD64 w); 511.1Sjdolecek 521.1Sjdolecekstatic CARD64 531.26Syamtxf86CARD64ReverseBits(CARD64 w) 541.26Syamt{ 551.1Sjdolecek unsigned char *p = (unsigned char *) &w; 561.1Sjdolecek 571.1Sjdolecek p[0] = byte_reversed[p[0]]; 581.1Sjdolecek p[1] = byte_reversed[p[1]]; 591.1Sjdolecek p[2] = byte_reversed[p[2]]; 601.1Sjdolecek p[3] = byte_reversed[p[3]]; 611.1Sjdolecek p[4] = byte_reversed[p[4]]; 621.1Sjdolecek p[5] = byte_reversed[p[5]]; 631.1Sjdolecek p[6] = byte_reversed[p[6]]; 641.1Sjdolecek p[7] = byte_reversed[p[7]]; 651.11Sjdolecek 661.50Sriastrad return w; 671.1Sjdolecek} 681.38Sad#endif 691.38Sad 701.1Sjdolecek#else 711.1Sjdolecek 721.1Sjdolecek#define SCANLINE CARD32 731.1Sjdolecek#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD 741.1Sjdolecek#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD 751.1Sjdolecek#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w) 761.1Sjdolecek 771.1Sjdolecek#endif /* BITMAP_SCANLINE_PAD == 64 */ 781.1Sjdolecek 791.25Sdrochnerstatic unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr); 801.25Sdrochnerstatic unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr); 811.9Sjdolecekstatic unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr); 821.11Sjdolecekstatic unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr); 831.9Sjdolecekstatic unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr); 841.1Sjdolecekstatic unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr); 851.47Schs 861.1SjdolecekBool 871.1Sjdolecekxf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) 881.1Sjdolecek{ 891.1Sjdolecek if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0)) 901.11Sjdolecek return FALSE; 911.1Sjdolecek 921.11Sjdolecek /* These are required for now */ 931.1Sjdolecek if (!infoPtr->SetCursorPosition || 941.1Sjdolecek !xf86DriverHasLoadCursorImage(infoPtr) || 951.1Sjdolecek !infoPtr->HideCursor || 961.1Sjdolecek !xf86DriverHasShowCursor(infoPtr) || 971.1Sjdolecek !infoPtr->SetCursorColors) 981.11Sjdolecek return FALSE; 991.9Sjdolecek 1001.1Sjdolecek if (infoPtr->RealizeCursor) { 1011.11Sjdolecek /* Don't overwrite a driver provided Realize Cursor function */ 1021.11Sjdolecek } 1031.11Sjdolecek else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) { 1041.11Sjdolecek infoPtr->RealizeCursor = RealizeCursorInterleave1; 1051.16Sjdolecek } 1061.16Sjdolecek else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) { 1071.16Sjdolecek infoPtr->RealizeCursor = RealizeCursorInterleave8; 1081.16Sjdolecek } 1091.11Sjdolecek else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) { 1101.16Sjdolecek infoPtr->RealizeCursor = RealizeCursorInterleave16; 1111.16Sjdolecek } 1121.16Sjdolecek else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) { 1131.1Sjdolecek infoPtr->RealizeCursor = RealizeCursorInterleave32; 1141.1Sjdolecek } 1151.44Scegger else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) { 1161.44Scegger infoPtr->RealizeCursor = RealizeCursorInterleave64; 1171.1Sjdolecek } 1181.47Schs else { /* not interleaved */ 1191.20Sthorpej infoPtr->RealizeCursor = RealizeCursorInterleave0; 1201.1Sjdolecek } 1211.27Sperry 1221.27Sperry infoPtr->pScrn = xf86ScreenToScrn(pScreen); 1231.27Sperry 1241.27Sperry return TRUE; 1251.27Sperry} 1261.27Sperry 1271.1Sjdolecekstatic Bool 1281.1Sjdolecekxf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) 1291.47Schs{ 1301.1Sjdolecek return 1311.1Sjdolecek (cursor->bits->argb && infoPtr->UseHWCursorARGB && 1321.1Sjdolecek infoPtr->UseHWCursorARGB(pScreen, cursor)) || 1331.1Sjdolecek (cursor->bits->argb == 0 && 1341.1Sjdolecek cursor->bits->height <= infoPtr->MaxHeight && 1351.1Sjdolecek cursor->bits->width <= infoPtr->MaxWidth && 1361.1Sjdolecek (!infoPtr->UseHWCursor || infoPtr->UseHWCursor(pScreen, cursor))); 1371.1Sjdolecek} 1381.1Sjdolecek 1391.1SjdolecekBool 1401.1Sjdolecekxf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) 1411.1Sjdolecek{ 1421.1Sjdolecek ScreenPtr pSlave; 1431.44Scegger Bool use_hw_cursor = TRUE; 1441.1Sjdolecek 1451.33Sthorpej input_lock(); 1461.1Sjdolecek 1471.11Sjdolecek if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) { 1481.1Sjdolecek use_hw_cursor = FALSE; 1491.1Sjdolecek goto unlock; 1501.1Sjdolecek } 1511.11Sjdolecek 1521.29Sdrochner /* ask each driver consuming a pixmap if it can support HW cursor */ 1531.1Sjdolecek xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) { 1541.47Schs xf86CursorScreenPtr sPriv; 1551.47Schs 1561.1Sjdolecek if (!RRHasScanoutPixmap(pSlave)) 1571.1Sjdolecek continue; 1581.1Sjdolecek 1591.1Sjdolecek sPriv = dixLookupPrivate(&pSlave->devPrivates, xf86CursorScreenKey); 1601.1Sjdolecek if (!sPriv) { /* NULL if Option "SWCursor", possibly other conditions */ 1611.1Sjdolecek use_hw_cursor = FALSE; 1621.28Sperry break; 1631.1Sjdolecek } 1641.1Sjdolecek 1651.23Swiz /* FALSE if HWCursor not supported by slave */ 1661.1Sjdolecek if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) { 1671.1Sjdolecek use_hw_cursor = FALSE; 1681.1Sjdolecek break; 1691.1Sjdolecek } 1701.1Sjdolecek } 1711.1Sjdolecek 1721.28Sperryunlock: 1731.1Sjdolecek input_unlock(); 1741.1Sjdolecek 1751.1Sjdolecek return use_hw_cursor; 1761.1Sjdolecek} 1771.1Sjdolecek 1781.1Sjdolecekstatic Bool 1791.28Sperryxf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) 1801.1Sjdolecek{ 1811.1Sjdolecek xf86CursorScreenPtr ScreenPriv = 1821.1Sjdolecek (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 1831.1Sjdolecek xf86CursorScreenKey); 1841.1Sjdolecek 1851.1Sjdolecek xf86CursorInfoPtr infoPtr; 1861.1Sjdolecek unsigned char *bits; 1871.1Sjdolecek 1881.1Sjdolecek if (!ScreenPriv) { /* NULL if Option "SWCursor" */ 1891.1Sjdolecek return (pCurs == NullCursor); 1901.1Sjdolecek } 1911.1Sjdolecek 1921.1Sjdolecek infoPtr = ScreenPriv->CursorInfoPtr; 1931.1Sjdolecek 1941.1Sjdolecek if (pCurs == NullCursor) { 1951.22Schristos (*infoPtr->HideCursor) (infoPtr->pScrn); 1961.22Schristos return TRUE; 1971.1Sjdolecek } 1981.28Sperry 1991.1Sjdolecek /* 2001.1Sjdolecek * Hot plugged GPU's do not have a CursorScreenKey, force sw cursor. 2011.1Sjdolecek * This check can be removed once dix/privates.c gets relocation code for 2021.1Sjdolecek * PRIVATE_CURSOR. Also see the related comment in AddGPUScreen(). 2031.7Sjdolecek */ 2041.7Sjdolecek if (!_dixGetScreenPrivateKey(CursorScreenKey, pScreen)) 2051.6Sjdolecek return FALSE; 2061.1Sjdolecek 2071.1Sjdolecek bits = 2081.1Sjdolecek dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen); 2091.23Swiz 2101.1Sjdolecek x -= infoPtr->pScrn->frameX0; 2111.1Sjdolecek y -= infoPtr->pScrn->frameY0; 2121.51Smsaitoh 2131.51Smsaitoh if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr)) 2141.1Sjdolecek if (!bits) { 2151.1Sjdolecek bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs); 2161.1Sjdolecek dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen, 2171.1Sjdolecek bits); 2181.7Sjdolecek } 2191.47Schs 2201.1Sjdolecek if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) 2211.1Sjdolecek (*infoPtr->HideCursor) (infoPtr->pScrn); 2221.7Sjdolecek 2231.7Sjdolecek if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) { 2241.1Sjdolecek if (!xf86DriverLoadCursorARGB (infoPtr, pCurs)) 2251.1Sjdolecek return FALSE; 2261.1Sjdolecek } else 2271.1Sjdolecek if (bits) 2281.1Sjdolecek if (!xf86DriverLoadCursorImage (infoPtr, bits)) 2291.1Sjdolecek return FALSE; 2301.1Sjdolecek 2311.1Sjdolecek xf86RecolorCursor_locked (ScreenPriv, pCurs); 2321.1Sjdolecek 2331.1Sjdolecek (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); 2341.1Sjdolecek 2351.1Sjdolecek return xf86DriverShowCursor(infoPtr); 2361.47Schs} 2371.1Sjdolecek 2381.1SjdolecekBool 2391.1Sjdolecekxf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) 2401.11Sjdolecek{ 2411.11Sjdolecek xf86CursorScreenPtr ScreenPriv = 2421.51Smsaitoh (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 2431.51Smsaitoh xf86CursorScreenKey); 2441.1Sjdolecek ScreenPtr pSlave; 2451.1Sjdolecek Bool ret = FALSE; 2461.1Sjdolecek 2471.11Sjdolecek input_lock(); 2481.1Sjdolecek 2491.11Sjdolecek x -= ScreenPriv->HotX; 2501.14Sjdolecek y -= ScreenPriv->HotY; 2511.12Sjdolecek 2521.51Smsaitoh if (!xf86ScreenSetCursor(pScreen, pCurs, x, y)) 2531.51Smsaitoh goto out; 2541.1Sjdolecek 2551.1Sjdolecek /* ask each slave driver to set the cursor. */ 2561.1Sjdolecek xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) { 2571.1Sjdolecek if (!RRHasScanoutPixmap(pSlave)) 2581.1Sjdolecek continue; 2591.1Sjdolecek 2601.1Sjdolecek if (!xf86ScreenSetCursor(pSlave, pCurs, x, y)) { 2611.1Sjdolecek /* 2621.11Sjdolecek * hide the master (and successfully set slave) cursors, 2631.1Sjdolecek * otherwise both the hw and sw cursor will show. 2641.11Sjdolecek */ 2651.1Sjdolecek xf86SetCursor(pScreen, NullCursor, x, y); 2661.9Sjdolecek goto out; 2671.9Sjdolecek } 2681.9Sjdolecek } 2691.9Sjdolecek ret = TRUE; 2701.1Sjdolecek 2711.1Sjdolecek out: 2721.1Sjdolecek input_unlock(); 2731.1Sjdolecek return ret; 2741.1Sjdolecek} 2751.47Schs 2761.1Sjdolecekvoid 2771.1Sjdolecekxf86SetTransparentCursor(ScreenPtr pScreen) 2781.1Sjdolecek{ 2791.1Sjdolecek xf86CursorScreenPtr ScreenPriv = 2801.1Sjdolecek (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 2811.1Sjdolecek xf86CursorScreenKey); 2821.25Sdrochner xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; 2831.9Sjdolecek 2841.16Sjdolecek input_lock(); 2851.9Sjdolecek 2861.9Sjdolecek if (!ScreenPriv->transparentData) 2871.9Sjdolecek ScreenPriv->transparentData = 2881.25Sdrochner (*infoPtr->RealizeCursor) (infoPtr, NullCursor); 2891.9Sjdolecek 2901.9Sjdolecek if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) 2911.9Sjdolecek (*infoPtr->HideCursor) (infoPtr->pScrn); 2921.9Sjdolecek 2931.9Sjdolecek if (ScreenPriv->transparentData) 2941.1Sjdolecek xf86DriverLoadCursorImage (infoPtr, 2951.11Sjdolecek ScreenPriv->transparentData); 2961.1Sjdolecek 2971.1Sjdolecek xf86DriverShowCursor(infoPtr); 2981.1Sjdolecek 2991.25Sdrochner input_unlock(); 3001.11Sjdolecek} 3011.29Sdrochner 3021.47Schsstatic void 3031.47Schsxf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y) 3041.47Schs{ 3051.47Schs xf86CursorScreenPtr ScreenPriv = 3061.11Sjdolecek (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 3071.11Sjdolecek xf86CursorScreenKey); 3081.11Sjdolecek xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; 3091.11Sjdolecek 3101.11Sjdolecek x -= infoPtr->pScrn->frameX0; 3111.1Sjdolecek y -= infoPtr->pScrn->frameY0; 3121.1Sjdolecek 3131.1Sjdolecek (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); 3141.1Sjdolecek} 3151.1Sjdolecek 3161.9Sjdolecekvoid 3171.9Sjdolecekxf86MoveCursor(ScreenPtr pScreen, int x, int y) 3181.9Sjdolecek{ 3191.9Sjdolecek xf86CursorScreenPtr ScreenPriv = 3201.25Sdrochner (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 3211.11Sjdolecek xf86CursorScreenKey); 3221.9Sjdolecek ScreenPtr pSlave; 3231.9Sjdolecek 3241.11Sjdolecek input_lock(); 3251.11Sjdolecek 3261.9Sjdolecek x -= ScreenPriv->HotX; 3271.47Schs y -= ScreenPriv->HotY; 3281.9Sjdolecek 3291.11Sjdolecek xf86ScreenMoveCursor(pScreen, x, y); 3301.9Sjdolecek 3311.11Sjdolecek /* ask each slave driver to move the cursor */ 3321.11Sjdolecek xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) { 3331.11Sjdolecek if (!RRHasScanoutPixmap(pSlave)) 3341.11Sjdolecek continue; 3351.48Schristos 3361.36Sad xf86ScreenMoveCursor(pSlave, x, y); 3371.47Schs } 3381.51Smsaitoh 3391.51Smsaitoh input_unlock(); 3401.36Sad} 3411.36Sad 3421.1Sjdolecekstatic void 3431.1Sjdolecekxf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs) 3441.1Sjdolecek{ 3451.34Schristos xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; 3461.1Sjdolecek 3471.11Sjdolecek /* recoloring isn't applicable to ARGB cursors and drivers 3481.1Sjdolecek shouldn't have to ignore SetCursorColors requests */ 3491.1Sjdolecek if (pCurs->bits->argb) 3501.1Sjdolecek return; 3511.34Schristos 3521.1Sjdolecek if (ScreenPriv->PalettedCursor) { 3531.1Sjdolecek xColorItem sourceColor, maskColor; 3541.1Sjdolecek ColormapPtr pmap = ScreenPriv->pInstalledMap; 3551.1Sjdolecek 3561.51Smsaitoh if (!pmap) 3571.1Sjdolecek return; 3581.1Sjdolecek 3591.1Sjdolecek sourceColor.red = pCurs->foreRed; 3601.1Sjdolecek sourceColor.green = pCurs->foreGreen; 3611.1Sjdolecek sourceColor.blue = pCurs->foreBlue; 3621.1Sjdolecek FakeAllocColor(pmap, &sourceColor); 3631.1Sjdolecek maskColor.red = pCurs->backRed; 3641.1Sjdolecek maskColor.green = pCurs->backGreen; 3651.1Sjdolecek maskColor.blue = pCurs->backBlue; 3661.1Sjdolecek FakeAllocColor(pmap, &maskColor); 3671.1Sjdolecek FakeFreeColor(pmap, sourceColor.pixel); 3681.1Sjdolecek FakeFreeColor(pmap, maskColor.pixel); 3691.1Sjdolecek (*infoPtr->SetCursorColors) (infoPtr->pScrn, 3701.1Sjdolecek maskColor.pixel, sourceColor.pixel); 3711.1Sjdolecek } 3721.16Sjdolecek else { /* Pass colors in 8-8-8 RGB format */ 3731.1Sjdolecek (*infoPtr->SetCursorColors) (infoPtr->pScrn, 3741.47Schs (pCurs->backBlue >> 8) | 3751.1Sjdolecek ((pCurs->backGreen >> 8) << 8) | 3761.1Sjdolecek ((pCurs->backRed >> 8) << 16), 3771.1Sjdolecek (pCurs->foreBlue >> 8) | 3781.1Sjdolecek ((pCurs->foreGreen >> 8) << 8) | 3791.1Sjdolecek ((pCurs->foreRed >> 8) << 16) 3801.1Sjdolecek ); 3811.1Sjdolecek } 3821.1Sjdolecek} 3831.1Sjdolecek 3841.1Sjdolecekvoid 3851.1Sjdolecekxf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) 3861.1Sjdolecek{ 3871.1Sjdolecek xf86CursorScreenPtr ScreenPriv = 3881.1Sjdolecek (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 3891.9Sjdolecek xf86CursorScreenKey); 3901.1Sjdolecek 3911.1Sjdolecek input_lock(); 3921.1Sjdolecek xf86RecolorCursor_locked (ScreenPriv, pCurs); 3931.1Sjdolecek input_unlock(); 3941.1Sjdolecek} 3951.9Sjdolecek 3961.13Ssommerfe/* These functions assume that MaxWidth is a multiple of 32 */ 3971.9Sjdolecekstatic unsigned char * 3981.47SchsRealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 3991.13Ssommerfe{ 4001.9Sjdolecek 4011.1Sjdolecek SCANLINE *SrcS, *SrcM, *DstS, *DstM; 4021.1Sjdolecek SCANLINE *pSrc, *pMsk; 4031.1Sjdolecek unsigned char *mem; 4041.1Sjdolecek int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 4051.1Sjdolecek int SrcPitch, DstPitch, Pitch, y, x; 4061.16Sjdolecek 4071.1Sjdolecek /* how many words are in the source or mask */ 4081.1Sjdolecek int words = size / (CUR_BITMAP_SCANLINE_PAD / 4); 4091.1Sjdolecek 4101.16Sjdolecek if (!(mem = calloc(1, size))) 4111.1Sjdolecek return NULL; 4121.16Sjdolecek 4131.1Sjdolecek if (pCurs == NullCursor) { 4141.1Sjdolecek if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) { 4151.16Sjdolecek DstM = (SCANLINE *) mem; 4161.16Sjdolecek if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)) 4171.16Sjdolecek DstM += words; 4181.16Sjdolecek memset(DstM, -1, words * sizeof(SCANLINE)); 4191.16Sjdolecek } 4201.1Sjdolecek return mem; 4211.1Sjdolecek } 4221.1Sjdolecek 4231.1Sjdolecek /* SrcPitch == the number of scanlines wide the cursor image is */ 4241.1Sjdolecek SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >> 4251.11Sjdolecek CUR_LOG2_BITMAP_PAD; 4261.11Sjdolecek 4271.1Sjdolecek /* DstPitch is the width of the hw cursor in scanlines */ 4281.11Sjdolecek DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD; 4291.11Sjdolecek Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch; 4301.1Sjdolecek 4311.16Sjdolecek SrcS = (SCANLINE *) pCurs->bits->source; 4321.1Sjdolecek SrcM = (SCANLINE *) pCurs->bits->mask; 4331.1Sjdolecek DstS = (SCANLINE *) mem; 4341.1Sjdolecek DstM = DstS + words; 4351.1Sjdolecek 4361.11Sjdolecek if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) { 4371.11Sjdolecek SCANLINE *tmp; 4381.11Sjdolecek 4391.11Sjdolecek tmp = DstS; 4401.11Sjdolecek DstS = DstM; 4411.16Sjdolecek DstM = tmp; 4421.11Sjdolecek } 4431.11Sjdolecek 4441.11Sjdolecek if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) { 4451.16Sjdolecek for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM; 4461.1Sjdolecek y--; 4471.16Sjdolecek pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM += 4481.1Sjdolecek SrcPitch) { 4491.1Sjdolecek for (x = 0; x < Pitch; x++) { 4501.1Sjdolecek pSrc[x] = SrcS[x] & SrcM[x]; 4511.1Sjdolecek pMsk[x] = SrcM[x]; 4521.16Sjdolecek } 4531.16Sjdolecek } 4541.16Sjdolecek } 4551.16Sjdolecek else { 4561.28Sperry for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM; 4571.16Sjdolecek y--; 4581.16Sjdolecek pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM += 4591.16Sjdolecek SrcPitch) { 4601.47Schs for (x = 0; x < Pitch; x++) { 4611.16Sjdolecek pSrc[x] = SrcS[x]; 4621.16Sjdolecek pMsk[x] = SrcM[x]; 4631.16Sjdolecek } 4641.16Sjdolecek } 4651.1Sjdolecek } 4661.1Sjdolecek 4671.16Sjdolecek if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) { 4681.1Sjdolecek int count = size; 4691.16Sjdolecek unsigned char *pntr1 = (unsigned char *) DstS; 4701.1Sjdolecek unsigned char *pntr2 = (unsigned char *) DstM; 4711.1Sjdolecek unsigned char a, b; 4721.28Sperry 4731.1Sjdolecek while (count) { 4741.1Sjdolecek 4751.1Sjdolecek a = *pntr1; 4761.1Sjdolecek b = *pntr2; 4771.1Sjdolecek *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4); 4781.1Sjdolecek *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4); 4791.1Sjdolecek pntr1++; 4801.1Sjdolecek pntr2++; 4811.1Sjdolecek count -= 2; 4821.1Sjdolecek } 4831.16Sjdolecek } 4841.16Sjdolecek 4851.16Sjdolecek /* 4861.45Srmind * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping 4871.1Sjdolecek * out entire source mask. 4881.1Sjdolecek */ 4891.1Sjdolecek if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) { 4901.1Sjdolecek int count = words; 4911.1Sjdolecek SCANLINE *pntr = DstM; 4921.1Sjdolecek 4931.1Sjdolecek while (count--) { 4941.1Sjdolecek *pntr = ~(*pntr); 4951.28Sperry pntr++; 4961.1Sjdolecek } 4971.34Schristos } 4981.1Sjdolecek 4991.1Sjdolecek if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) { 5001.1Sjdolecek for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM; 5011.1Sjdolecek y--; pSrc += DstPitch, pMsk += DstPitch) { 5021.1Sjdolecek for (x = 0; x < Pitch; x++) { 5031.1Sjdolecek pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]); 5041.9Sjdolecek pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]); 5051.9Sjdolecek } 5061.9Sjdolecek } 5071.9Sjdolecek } 5081.1Sjdolecek 5091.16Sjdolecek return mem; 5101.16Sjdolecek} 5111.16Sjdolecek 5121.16Sjdolecekstatic unsigned char * 5131.47SchsRealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 5141.16Sjdolecek{ 5151.16Sjdolecek unsigned char *DstS, *DstM; 5161.9Sjdolecek unsigned char *pntr; 5171.1Sjdolecek unsigned char *mem, *mem2; 5181.16Sjdolecek int count; 5191.1Sjdolecek int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 5201.1Sjdolecek 5211.1Sjdolecek /* Realize the cursor without interleaving */ 5221.9Sjdolecek if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 5231.51Smsaitoh return NULL; 5241.51Smsaitoh 5251.51Smsaitoh if (!(mem = calloc(1, size))) { 5261.16Sjdolecek free(mem2); 5271.1Sjdolecek return NULL; 5281.1Sjdolecek } 5291.1Sjdolecek 5301.1Sjdolecek /* 1 bit interleave */ 5311.1Sjdolecek DstS = mem2; 5321.28Sperry DstM = DstS + (size >> 1); 5331.16Sjdolecek pntr = mem; 5341.1Sjdolecek count = size; 5351.1Sjdolecek while (count) { 5361.1Sjdolecek *pntr++ = ((*DstS & 0x01)) | ((*DstM & 0x01) << 1) | 5371.1Sjdolecek ((*DstS & 0x02) << 1) | ((*DstM & 0x02) << 2) | 5381.1Sjdolecek ((*DstS & 0x04) << 2) | ((*DstM & 0x04) << 3) | 5391.1Sjdolecek ((*DstS & 0x08) << 3) | ((*DstM & 0x08) << 4); 5401.1Sjdolecek *pntr++ = ((*DstS & 0x10) >> 4) | ((*DstM & 0x10) >> 3) | 5411.1Sjdolecek ((*DstS & 0x20) >> 3) | ((*DstM & 0x20) >> 2) | 5421.1Sjdolecek ((*DstS & 0x40) >> 2) | ((*DstM & 0x40) >> 1) | 5431.1Sjdolecek ((*DstS & 0x80) >> 1) | ((*DstM & 0x80)); 5441.1Sjdolecek DstS++; 5451.1Sjdolecek DstM++; 5461.1Sjdolecek count -= 2; 5471.1Sjdolecek } 5481.16Sjdolecek 5491.34Schristos /* Free the uninterleaved cursor */ 5501.1Sjdolecek free(mem2); 5511.16Sjdolecek 5521.1Sjdolecek return mem; 5531.11Sjdolecek} 5541.16Sjdolecek 5551.11Sjdolecekstatic unsigned char * 5561.11SjdolecekRealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 5571.11Sjdolecek{ 5581.11Sjdolecek unsigned char *DstS, *DstM; 5591.16Sjdolecek unsigned char *pntr; 5601.16Sjdolecek unsigned char *mem, *mem2; 5611.16Sjdolecek int count; 5621.16Sjdolecek int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 5631.11Sjdolecek 5641.11Sjdolecek /* Realize the cursor without interleaving */ 5651.16Sjdolecek if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 5661.16Sjdolecek return NULL; 5671.16Sjdolecek 5681.16Sjdolecek if (!(mem = calloc(1, size))) { 5691.16Sjdolecek free(mem2); 5701.1Sjdolecek return NULL; 5711.1Sjdolecek } 5721.28Sperry 5731.16Sjdolecek /* 8 bit interleave */ 5741.16Sjdolecek DstS = mem2; 5751.16Sjdolecek DstM = DstS + (size >> 1); 5761.1Sjdolecek pntr = mem; 5771.34Schristos count = size; 5781.34Schristos while (count) { 5791.1Sjdolecek *pntr++ = *DstS++; 5801.9Sjdolecek *pntr++ = *DstM++; 5811.1Sjdolecek count -= 2; 5821.1Sjdolecek } 5831.16Sjdolecek 5841.1Sjdolecek /* Free the uninterleaved cursor */ 5851.1Sjdolecek free(mem2); 5861.1Sjdolecek 5871.1Sjdolecek return mem; 5881.1Sjdolecek} 5891.1Sjdolecek 5901.1Sjdolecekstatic unsigned char * 5911.1SjdolecekRealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 5921.1Sjdolecek{ 5931.28Sperry unsigned short *DstS, *DstM; 5941.1Sjdolecek unsigned short *pntr; 5951.1Sjdolecek unsigned char *mem, *mem2; 5961.1Sjdolecek int count; 5971.1Sjdolecek int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 5981.1Sjdolecek 5991.1Sjdolecek /* Realize the cursor without interleaving */ 6001.1Sjdolecek if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 6011.1Sjdolecek return NULL; 6021.1Sjdolecek 6031.1Sjdolecek if (!(mem = calloc(1, size))) { 6041.1Sjdolecek free(mem2); 6051.1Sjdolecek return NULL; 6061.28Sperry } 6071.1Sjdolecek 6081.1Sjdolecek /* 16 bit interleave */ 6091.1Sjdolecek DstS = (void *) mem2; 6101.11Sjdolecek DstM = DstS + (size >> 2); 6111.16Sjdolecek pntr = (void *) mem; 6121.1Sjdolecek count = (size >> 1); 6131.1Sjdolecek while (count) { 6141.1Sjdolecek *pntr++ = *DstS++; 6151.1Sjdolecek *pntr++ = *DstM++; 6161.28Sperry count -= 2; 6171.16Sjdolecek } 6181.9Sjdolecek 6191.11Sjdolecek /* Free the uninterleaved cursor */ 6201.16Sjdolecek free(mem2); 6211.9Sjdolecek 6221.16Sjdolecek return mem; 6231.1Sjdolecek} 6241.16Sjdolecek 6251.16Sjdolecekstatic unsigned char * 6261.16SjdolecekRealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 6271.51Smsaitoh{ 6281.51Smsaitoh CARD32 *DstS, *DstM; 6291.16Sjdolecek CARD32 *pntr; 6301.11Sjdolecek unsigned char *mem, *mem2; 6311.1Sjdolecek int count; 6321.1Sjdolecek int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 6331.1Sjdolecek 6341.16Sjdolecek /* Realize the cursor without interleaving */ 6351.1Sjdolecek if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 6361.16Sjdolecek return NULL; 6371.1Sjdolecek 6381.1Sjdolecek if (!(mem = calloc(1, size))) { 6391.11Sjdolecek free(mem2); 6401.1Sjdolecek return NULL; 6411.1Sjdolecek } 6421.1Sjdolecek 6431.1Sjdolecek /* 32 bit interleave */ 6441.1Sjdolecek DstS = (void *) mem2; 6451.1Sjdolecek DstM = DstS + (size >> 3); 6461.1Sjdolecek pntr = (void *) mem; 6471.1Sjdolecek count = (size >> 2); 6481.1Sjdolecek while (count) { 6491.1Sjdolecek *pntr++ = *DstS++; 6501.1Sjdolecek *pntr++ = *DstM++; 6511.1Sjdolecek count -= 2; 6521.1Sjdolecek } 6531.1Sjdolecek 6541.1Sjdolecek /* Free the uninterleaved cursor */ 6551.1Sjdolecek free(mem2); 6561.1Sjdolecek 6571.1Sjdolecek return mem; 6581.1Sjdolecek} 6591.1Sjdolecek 6601.1Sjdolecekstatic unsigned char * 6611.1SjdolecekRealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 6621.1Sjdolecek{ 6631.1Sjdolecek CARD32 *DstS, *DstM; 6641.1Sjdolecek CARD32 *pntr; 6651.1Sjdolecek unsigned char *mem, *mem2; 6661.1Sjdolecek int count; 6671.1Sjdolecek int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 6681.1Sjdolecek 6691.1Sjdolecek /* Realize the cursor without interleaving */ 6701.1Sjdolecek if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 6711.1Sjdolecek return NULL; 6721.1Sjdolecek 6731.1Sjdolecek if (!(mem = calloc(1, size))) { 6741.1Sjdolecek free(mem2); 6751.1Sjdolecek return NULL; 6761.1Sjdolecek } 6771.1Sjdolecek 6781.1Sjdolecek /* 64 bit interleave */ 6791.1Sjdolecek DstS = (void *) mem2; 6801.1Sjdolecek DstM = DstS + (size >> 3); 6811.1Sjdolecek pntr = (void *) mem; 6821.1Sjdolecek count = (size >> 2); 6831.1Sjdolecek while (count) { 6841.1Sjdolecek *pntr++ = *DstS++; 6851.1Sjdolecek *pntr++ = *DstS++; 6861.1Sjdolecek *pntr++ = *DstM++; 6871.1Sjdolecek *pntr++ = *DstM++; 6881.1Sjdolecek count -= 4; 6891.1Sjdolecek } 6901.1Sjdolecek 6911.1Sjdolecek /* Free the uninterleaved cursor */ 6921.1Sjdolecek free(mem2); 6931.1Sjdolecek 6941.1Sjdolecek return mem; 6951.1Sjdolecek} 6961.1Sjdolecek