105b261ecSmrg 205b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 305b261ecSmrg#include <xorg-config.h> 405b261ecSmrg#endif 505b261ecSmrg 605b261ecSmrg#include <string.h> 705b261ecSmrg 805b261ecSmrg#include "misc.h" 905b261ecSmrg#include "xf86.h" 1005b261ecSmrg#include "xf86_OSproc.h" 1105b261ecSmrg 1205b261ecSmrg#include <X11/X.h> 1305b261ecSmrg#include "scrnintstr.h" 1405b261ecSmrg#include "pixmapstr.h" 1505b261ecSmrg#include "windowstr.h" 1605b261ecSmrg#include "xf86str.h" 1705b261ecSmrg#include "cursorstr.h" 1805b261ecSmrg#include "mi.h" 1905b261ecSmrg#include "mipointer.h" 201b5d61b8Smrg#include "randrstr.h" 2105b261ecSmrg#include "xf86CursorPriv.h" 2205b261ecSmrg 2305b261ecSmrg#include "servermd.h" 2405b261ecSmrg 251b5d61b8Smrgstatic void 261b5d61b8Smrgxf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs); 271b5d61b8Smrg 2835c4bbdfSmrgstatic CARD32 2935c4bbdfSmrgxf86ReverseBitOrder(CARD32 v) 3035c4bbdfSmrg{ 3135c4bbdfSmrg return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) | 3235c4bbdfSmrg ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) | 3335c4bbdfSmrg ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) | 3435c4bbdfSmrg ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7)); 3535c4bbdfSmrg} 3635c4bbdfSmrg 3705b261ecSmrg#if BITMAP_SCANLINE_PAD == 64 3805b261ecSmrg 3905b261ecSmrg#if 1 4005b261ecSmrg/* Cursors might be only 32 wide. Give'em a chance */ 4105b261ecSmrg#define SCANLINE CARD32 4205b261ecSmrg#define CUR_BITMAP_SCANLINE_PAD 32 4305b261ecSmrg#define CUR_LOG2_BITMAP_PAD 5 4405b261ecSmrg#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w) 4505b261ecSmrg#else 4605b261ecSmrg#define SCANLINE CARD64 4705b261ecSmrg#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD 4805b261ecSmrg#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD 4905b261ecSmrg#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w) 5005b261ecSmrgstatic CARD64 xf86CARD64ReverseBits(CARD64 w); 5105b261ecSmrg 5205b261ecSmrgstatic CARD64 5305b261ecSmrgxf86CARD64ReverseBits(CARD64 w) 5405b261ecSmrg{ 5535c4bbdfSmrg unsigned char *p = (unsigned char *) &w; 5635c4bbdfSmrg 5735c4bbdfSmrg p[0] = byte_reversed[p[0]]; 5835c4bbdfSmrg p[1] = byte_reversed[p[1]]; 5935c4bbdfSmrg p[2] = byte_reversed[p[2]]; 6035c4bbdfSmrg p[3] = byte_reversed[p[3]]; 6135c4bbdfSmrg p[4] = byte_reversed[p[4]]; 6235c4bbdfSmrg p[5] = byte_reversed[p[5]]; 6335c4bbdfSmrg p[6] = byte_reversed[p[6]]; 6435c4bbdfSmrg p[7] = byte_reversed[p[7]]; 6535c4bbdfSmrg 6635c4bbdfSmrg return w; 6705b261ecSmrg} 6805b261ecSmrg#endif 6905b261ecSmrg 7005b261ecSmrg#else 7105b261ecSmrg 7205b261ecSmrg#define SCANLINE CARD32 7305b261ecSmrg#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD 7405b261ecSmrg#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD 7505b261ecSmrg#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w) 7605b261ecSmrg 7735c4bbdfSmrg#endif /* BITMAP_SCANLINE_PAD == 64 */ 7805b261ecSmrg 7935c4bbdfSmrgstatic unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr); 8035c4bbdfSmrgstatic unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr); 8135c4bbdfSmrgstatic unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr); 8235c4bbdfSmrgstatic unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr); 8335c4bbdfSmrgstatic unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr); 8435c4bbdfSmrgstatic unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr); 8505b261ecSmrg 8605b261ecSmrgBool 8705b261ecSmrgxf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) 8805b261ecSmrg{ 8905b261ecSmrg if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0)) 9035c4bbdfSmrg return FALSE; 9105b261ecSmrg 9205b261ecSmrg /* These are required for now */ 9305b261ecSmrg if (!infoPtr->SetCursorPosition || 9435c4bbdfSmrg !xf86DriverHasLoadCursorImage(infoPtr) || 9535c4bbdfSmrg !infoPtr->HideCursor || 961b5d61b8Smrg !xf86DriverHasShowCursor(infoPtr) || 971b5d61b8Smrg !infoPtr->SetCursorColors) 9835c4bbdfSmrg return FALSE; 9905b261ecSmrg 10005b261ecSmrg if (infoPtr->RealizeCursor) { 10135c4bbdfSmrg /* Don't overwrite a driver provided Realize Cursor function */ 10235c4bbdfSmrg } 10335c4bbdfSmrg else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) { 10435c4bbdfSmrg infoPtr->RealizeCursor = RealizeCursorInterleave1; 10535c4bbdfSmrg } 10635c4bbdfSmrg else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) { 10735c4bbdfSmrg infoPtr->RealizeCursor = RealizeCursorInterleave8; 10835c4bbdfSmrg } 10935c4bbdfSmrg else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) { 11035c4bbdfSmrg infoPtr->RealizeCursor = RealizeCursorInterleave16; 11135c4bbdfSmrg } 11235c4bbdfSmrg else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) { 11335c4bbdfSmrg infoPtr->RealizeCursor = RealizeCursorInterleave32; 11435c4bbdfSmrg } 11535c4bbdfSmrg else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) { 11635c4bbdfSmrg infoPtr->RealizeCursor = RealizeCursorInterleave64; 11735c4bbdfSmrg } 11835c4bbdfSmrg else { /* not interleaved */ 11935c4bbdfSmrg infoPtr->RealizeCursor = RealizeCursorInterleave0; 12005b261ecSmrg } 12105b261ecSmrg 12235c4bbdfSmrg infoPtr->pScrn = xf86ScreenToScrn(pScreen); 12305b261ecSmrg 12405b261ecSmrg return TRUE; 12505b261ecSmrg} 12605b261ecSmrg 1271b5d61b8Smrgstatic Bool 1281b5d61b8Smrgxf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) 1291b5d61b8Smrg{ 1301b5d61b8Smrg return 1311b5d61b8Smrg (cursor->bits->argb && infoPtr->UseHWCursorARGB && 1321b5d61b8Smrg infoPtr->UseHWCursorARGB(pScreen, cursor)) || 1331b5d61b8Smrg (cursor->bits->argb == 0 && 1341b5d61b8Smrg cursor->bits->height <= infoPtr->MaxHeight && 1351b5d61b8Smrg cursor->bits->width <= infoPtr->MaxWidth && 1361b5d61b8Smrg (!infoPtr->UseHWCursor || infoPtr->UseHWCursor(pScreen, cursor))); 1371b5d61b8Smrg} 1381b5d61b8Smrg 13935c4bbdfSmrgBool 1401b5d61b8Smrgxf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) 1411b5d61b8Smrg{ 1421b5d61b8Smrg ScreenPtr pSlave; 1431b5d61b8Smrg Bool use_hw_cursor = TRUE; 1441b5d61b8Smrg 1451b5d61b8Smrg input_lock(); 1461b5d61b8Smrg 1471b5d61b8Smrg if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) { 1481b5d61b8Smrg use_hw_cursor = FALSE; 1491b5d61b8Smrg goto unlock; 1501b5d61b8Smrg } 1511b5d61b8Smrg 1521b5d61b8Smrg /* ask each driver consuming a pixmap if it can support HW cursor */ 153ed6184dfSmrg xorg_list_for_each_entry(pSlave, &pScreen->secondary_list, secondary_head) { 1541b5d61b8Smrg xf86CursorScreenPtr sPriv; 1551b5d61b8Smrg 1561b5d61b8Smrg if (!RRHasScanoutPixmap(pSlave)) 1571b5d61b8Smrg continue; 1581b5d61b8Smrg 1591b5d61b8Smrg sPriv = dixLookupPrivate(&pSlave->devPrivates, xf86CursorScreenKey); 1601b5d61b8Smrg if (!sPriv) { /* NULL if Option "SWCursor", possibly other conditions */ 1611b5d61b8Smrg use_hw_cursor = FALSE; 1621b5d61b8Smrg break; 1631b5d61b8Smrg } 1641b5d61b8Smrg 165ed6184dfSmrg /* FALSE if HWCursor not supported by secondary */ 1661b5d61b8Smrg if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) { 1671b5d61b8Smrg use_hw_cursor = FALSE; 1681b5d61b8Smrg break; 1691b5d61b8Smrg } 1701b5d61b8Smrg } 1711b5d61b8Smrg 1721b5d61b8Smrgunlock: 1731b5d61b8Smrg input_unlock(); 1741b5d61b8Smrg 1751b5d61b8Smrg return use_hw_cursor; 1761b5d61b8Smrg} 1771b5d61b8Smrg 1781b5d61b8Smrgstatic Bool 1791b5d61b8Smrgxf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) 18005b261ecSmrg{ 18135c4bbdfSmrg xf86CursorScreenPtr ScreenPriv = 18235c4bbdfSmrg (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 18335c4bbdfSmrg xf86CursorScreenKey); 1841b5d61b8Smrg 1851b5d61b8Smrg xf86CursorInfoPtr infoPtr; 18605b261ecSmrg unsigned char *bits; 18705b261ecSmrg 1881b5d61b8Smrg if (!ScreenPriv) { /* NULL if Option "SWCursor" */ 1891b5d61b8Smrg return (pCurs == NullCursor); 1901b5d61b8Smrg } 1911b5d61b8Smrg 1921b5d61b8Smrg infoPtr = ScreenPriv->CursorInfoPtr; 1931b5d61b8Smrg 19405b261ecSmrg if (pCurs == NullCursor) { 19535c4bbdfSmrg (*infoPtr->HideCursor) (infoPtr->pScrn); 19635c4bbdfSmrg return TRUE; 19705b261ecSmrg } 19805b261ecSmrg 1991b5d61b8Smrg /* 2001b5d61b8Smrg * Hot plugged GPU's do not have a CursorScreenKey, force sw cursor. 2011b5d61b8Smrg * This check can be removed once dix/privates.c gets relocation code for 2021b5d61b8Smrg * PRIVATE_CURSOR. Also see the related comment in AddGPUScreen(). 2031b5d61b8Smrg */ 2041b5d61b8Smrg if (!_dixGetScreenPrivateKey(CursorScreenKey, pScreen)) 2051b5d61b8Smrg return FALSE; 2061b5d61b8Smrg 20735c4bbdfSmrg bits = 20835c4bbdfSmrg dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen); 20905b261ecSmrg 2101b5d61b8Smrg x -= infoPtr->pScrn->frameX0; 2111b5d61b8Smrg y -= infoPtr->pScrn->frameY0; 21205b261ecSmrg 21335c4bbdfSmrg if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr)) 21435c4bbdfSmrg if (!bits) { 21535c4bbdfSmrg bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs); 21635c4bbdfSmrg dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen, 21735c4bbdfSmrg bits); 21835c4bbdfSmrg } 21905b261ecSmrg 22005b261ecSmrg if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) 22135c4bbdfSmrg (*infoPtr->HideCursor) (infoPtr->pScrn); 22205b261ecSmrg 22335c4bbdfSmrg if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) { 22435c4bbdfSmrg if (!xf86DriverLoadCursorARGB (infoPtr, pCurs)) 22535c4bbdfSmrg return FALSE; 22635c4bbdfSmrg } else 22705b261ecSmrg if (bits) 22835c4bbdfSmrg if (!xf86DriverLoadCursorImage (infoPtr, bits)) 22935c4bbdfSmrg return FALSE; 23005b261ecSmrg 2311b5d61b8Smrg xf86RecolorCursor_locked (ScreenPriv, pCurs); 23205b261ecSmrg 23335c4bbdfSmrg (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); 23405b261ecSmrg 2351b5d61b8Smrg return xf86DriverShowCursor(infoPtr); 2361b5d61b8Smrg} 2371b5d61b8Smrg 2381b5d61b8SmrgBool 2391b5d61b8Smrgxf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) 2401b5d61b8Smrg{ 2411b5d61b8Smrg xf86CursorScreenPtr ScreenPriv = 2421b5d61b8Smrg (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 2431b5d61b8Smrg xf86CursorScreenKey); 2441b5d61b8Smrg ScreenPtr pSlave; 2451b5d61b8Smrg Bool ret = FALSE; 2461b5d61b8Smrg 2471b5d61b8Smrg input_lock(); 2481b5d61b8Smrg 2491b5d61b8Smrg x -= ScreenPriv->HotX; 2501b5d61b8Smrg y -= ScreenPriv->HotY; 2511b5d61b8Smrg 2521b5d61b8Smrg if (!xf86ScreenSetCursor(pScreen, pCurs, x, y)) 2531b5d61b8Smrg goto out; 2541b5d61b8Smrg 255ed6184dfSmrg /* ask each secondary driver to set the cursor. */ 256ed6184dfSmrg xorg_list_for_each_entry(pSlave, &pScreen->secondary_list, secondary_head) { 2571b5d61b8Smrg if (!RRHasScanoutPixmap(pSlave)) 2581b5d61b8Smrg continue; 2591b5d61b8Smrg 2601b5d61b8Smrg if (!xf86ScreenSetCursor(pSlave, pCurs, x, y)) { 2611b5d61b8Smrg /* 262ed6184dfSmrg * hide the primary (and successfully set secondary) cursors, 2631b5d61b8Smrg * otherwise both the hw and sw cursor will show. 2641b5d61b8Smrg */ 2651b5d61b8Smrg xf86SetCursor(pScreen, NullCursor, x, y); 2661b5d61b8Smrg goto out; 2671b5d61b8Smrg } 2681b5d61b8Smrg } 2691b5d61b8Smrg ret = TRUE; 2701b5d61b8Smrg 2711b5d61b8Smrg out: 2721b5d61b8Smrg input_unlock(); 2731b5d61b8Smrg return ret; 27405b261ecSmrg} 27505b261ecSmrg 27605b261ecSmrgvoid 27705b261ecSmrgxf86SetTransparentCursor(ScreenPtr pScreen) 27805b261ecSmrg{ 27935c4bbdfSmrg xf86CursorScreenPtr ScreenPriv = 28035c4bbdfSmrg (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 28135c4bbdfSmrg xf86CursorScreenKey); 28205b261ecSmrg xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; 28305b261ecSmrg 2841b5d61b8Smrg input_lock(); 2851b5d61b8Smrg 28605b261ecSmrg if (!ScreenPriv->transparentData) 28735c4bbdfSmrg ScreenPriv->transparentData = 28835c4bbdfSmrg (*infoPtr->RealizeCursor) (infoPtr, NullCursor); 28905b261ecSmrg 29005b261ecSmrg if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN)) 29135c4bbdfSmrg (*infoPtr->HideCursor) (infoPtr->pScrn); 29205b261ecSmrg 29305b261ecSmrg if (ScreenPriv->transparentData) 29435c4bbdfSmrg xf86DriverLoadCursorImage (infoPtr, 29535c4bbdfSmrg ScreenPriv->transparentData); 29605b261ecSmrg 2971b5d61b8Smrg xf86DriverShowCursor(infoPtr); 2981b5d61b8Smrg 2991b5d61b8Smrg input_unlock(); 30005b261ecSmrg} 30105b261ecSmrg 3021b5d61b8Smrgstatic void 3031b5d61b8Smrgxf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y) 30405b261ecSmrg{ 30535c4bbdfSmrg xf86CursorScreenPtr ScreenPriv = 30635c4bbdfSmrg (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 30735c4bbdfSmrg xf86CursorScreenKey); 30805b261ecSmrg xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; 30905b261ecSmrg 3101b5d61b8Smrg x -= infoPtr->pScrn->frameX0; 3111b5d61b8Smrg y -= infoPtr->pScrn->frameY0; 31205b261ecSmrg 31335c4bbdfSmrg (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); 31405b261ecSmrg} 31505b261ecSmrg 31605b261ecSmrgvoid 3171b5d61b8Smrgxf86MoveCursor(ScreenPtr pScreen, int x, int y) 31805b261ecSmrg{ 31935c4bbdfSmrg xf86CursorScreenPtr ScreenPriv = 32035c4bbdfSmrg (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 32135c4bbdfSmrg xf86CursorScreenKey); 3221b5d61b8Smrg ScreenPtr pSlave; 3231b5d61b8Smrg 3241b5d61b8Smrg input_lock(); 3251b5d61b8Smrg 3261b5d61b8Smrg x -= ScreenPriv->HotX; 3271b5d61b8Smrg y -= ScreenPriv->HotY; 3281b5d61b8Smrg 3291b5d61b8Smrg xf86ScreenMoveCursor(pScreen, x, y); 3301b5d61b8Smrg 331ed6184dfSmrg /* ask each secondary driver to move the cursor */ 332ed6184dfSmrg xorg_list_for_each_entry(pSlave, &pScreen->secondary_list, secondary_head) { 3331b5d61b8Smrg if (!RRHasScanoutPixmap(pSlave)) 3341b5d61b8Smrg continue; 3351b5d61b8Smrg 3361b5d61b8Smrg xf86ScreenMoveCursor(pSlave, x, y); 3371b5d61b8Smrg } 3381b5d61b8Smrg 3391b5d61b8Smrg input_unlock(); 3401b5d61b8Smrg} 3411b5d61b8Smrg 3421b5d61b8Smrgstatic void 3431b5d61b8Smrgxf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs) 3441b5d61b8Smrg{ 34505b261ecSmrg xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; 34605b261ecSmrg 34735c4bbdfSmrg /* recoloring isn't applicable to ARGB cursors and drivers 34805b261ecSmrg shouldn't have to ignore SetCursorColors requests */ 34905b261ecSmrg if (pCurs->bits->argb) 35005b261ecSmrg return; 35105b261ecSmrg 35205b261ecSmrg if (ScreenPriv->PalettedCursor) { 35335c4bbdfSmrg xColorItem sourceColor, maskColor; 35435c4bbdfSmrg ColormapPtr pmap = ScreenPriv->pInstalledMap; 35535c4bbdfSmrg 35635c4bbdfSmrg if (!pmap) 35735c4bbdfSmrg return; 35835c4bbdfSmrg 35935c4bbdfSmrg sourceColor.red = pCurs->foreRed; 36035c4bbdfSmrg sourceColor.green = pCurs->foreGreen; 36135c4bbdfSmrg sourceColor.blue = pCurs->foreBlue; 36235c4bbdfSmrg FakeAllocColor(pmap, &sourceColor); 36335c4bbdfSmrg maskColor.red = pCurs->backRed; 36435c4bbdfSmrg maskColor.green = pCurs->backGreen; 36535c4bbdfSmrg maskColor.blue = pCurs->backBlue; 36635c4bbdfSmrg FakeAllocColor(pmap, &maskColor); 36735c4bbdfSmrg FakeFreeColor(pmap, sourceColor.pixel); 36835c4bbdfSmrg FakeFreeColor(pmap, maskColor.pixel); 36935c4bbdfSmrg (*infoPtr->SetCursorColors) (infoPtr->pScrn, 37035c4bbdfSmrg maskColor.pixel, sourceColor.pixel); 37135c4bbdfSmrg } 37235c4bbdfSmrg else { /* Pass colors in 8-8-8 RGB format */ 37335c4bbdfSmrg (*infoPtr->SetCursorColors) (infoPtr->pScrn, 37435c4bbdfSmrg (pCurs->backBlue >> 8) | 37535c4bbdfSmrg ((pCurs->backGreen >> 8) << 8) | 37635c4bbdfSmrg ((pCurs->backRed >> 8) << 16), 37735c4bbdfSmrg (pCurs->foreBlue >> 8) | 37835c4bbdfSmrg ((pCurs->foreGreen >> 8) << 8) | 37935c4bbdfSmrg ((pCurs->foreRed >> 8) << 16) 38035c4bbdfSmrg ); 38105b261ecSmrg } 38205b261ecSmrg} 38305b261ecSmrg 3841b5d61b8Smrgvoid 3851b5d61b8Smrgxf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) 3861b5d61b8Smrg{ 3871b5d61b8Smrg xf86CursorScreenPtr ScreenPriv = 3881b5d61b8Smrg (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, 3891b5d61b8Smrg xf86CursorScreenKey); 3901b5d61b8Smrg 3911b5d61b8Smrg input_lock(); 3921b5d61b8Smrg xf86RecolorCursor_locked (ScreenPriv, pCurs); 3931b5d61b8Smrg input_unlock(); 3941b5d61b8Smrg} 3951b5d61b8Smrg 39605b261ecSmrg/* These functions assume that MaxWidth is a multiple of 32 */ 39735c4bbdfSmrgstatic unsigned char * 39805b261ecSmrgRealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 39905b261ecSmrg{ 40005b261ecSmrg 40105b261ecSmrg SCANLINE *SrcS, *SrcM, *DstS, *DstM; 40205b261ecSmrg SCANLINE *pSrc, *pMsk; 40305b261ecSmrg unsigned char *mem; 40405b261ecSmrg int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 40505b261ecSmrg int SrcPitch, DstPitch, Pitch, y, x; 40635c4bbdfSmrg 40705b261ecSmrg /* how many words are in the source or mask */ 40805b261ecSmrg int words = size / (CUR_BITMAP_SCANLINE_PAD / 4); 40905b261ecSmrg 4106747b715Smrg if (!(mem = calloc(1, size))) 41135c4bbdfSmrg return NULL; 41205b261ecSmrg 41305b261ecSmrg if (pCurs == NullCursor) { 41435c4bbdfSmrg if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) { 41535c4bbdfSmrg DstM = (SCANLINE *) mem; 41635c4bbdfSmrg if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK)) 41735c4bbdfSmrg DstM += words; 41835c4bbdfSmrg memset(DstM, -1, words * sizeof(SCANLINE)); 41935c4bbdfSmrg } 42035c4bbdfSmrg return mem; 42105b261ecSmrg } 42205b261ecSmrg 42305b261ecSmrg /* SrcPitch == the number of scanlines wide the cursor image is */ 42405b261ecSmrg SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >> 42535c4bbdfSmrg CUR_LOG2_BITMAP_PAD; 42605b261ecSmrg 42705b261ecSmrg /* DstPitch is the width of the hw cursor in scanlines */ 42805b261ecSmrg DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD; 42905b261ecSmrg Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch; 43005b261ecSmrg 43135c4bbdfSmrg SrcS = (SCANLINE *) pCurs->bits->source; 43235c4bbdfSmrg SrcM = (SCANLINE *) pCurs->bits->mask; 43335c4bbdfSmrg DstS = (SCANLINE *) mem; 43405b261ecSmrg DstM = DstS + words; 43505b261ecSmrg 43605b261ecSmrg if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) { 43735c4bbdfSmrg SCANLINE *tmp; 43835c4bbdfSmrg 43935c4bbdfSmrg tmp = DstS; 44035c4bbdfSmrg DstS = DstM; 44135c4bbdfSmrg DstM = tmp; 44205b261ecSmrg } 44305b261ecSmrg 44405b261ecSmrg if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) { 44535c4bbdfSmrg for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM; 44635c4bbdfSmrg y--; 44735c4bbdfSmrg pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM += 44835c4bbdfSmrg SrcPitch) { 44935c4bbdfSmrg for (x = 0; x < Pitch; x++) { 45035c4bbdfSmrg pSrc[x] = SrcS[x] & SrcM[x]; 45135c4bbdfSmrg pMsk[x] = SrcM[x]; 45235c4bbdfSmrg } 45335c4bbdfSmrg } 45435c4bbdfSmrg } 45535c4bbdfSmrg else { 45635c4bbdfSmrg for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM; 45735c4bbdfSmrg y--; 45835c4bbdfSmrg pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM += 45935c4bbdfSmrg SrcPitch) { 46035c4bbdfSmrg for (x = 0; x < Pitch; x++) { 46135c4bbdfSmrg pSrc[x] = SrcS[x]; 46235c4bbdfSmrg pMsk[x] = SrcM[x]; 46335c4bbdfSmrg } 46435c4bbdfSmrg } 46505b261ecSmrg } 46605b261ecSmrg 46705b261ecSmrg if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) { 46835c4bbdfSmrg int count = size; 46935c4bbdfSmrg unsigned char *pntr1 = (unsigned char *) DstS; 47035c4bbdfSmrg unsigned char *pntr2 = (unsigned char *) DstM; 47135c4bbdfSmrg unsigned char a, b; 47235c4bbdfSmrg 47335c4bbdfSmrg while (count) { 47435c4bbdfSmrg 47535c4bbdfSmrg a = *pntr1; 47635c4bbdfSmrg b = *pntr2; 47735c4bbdfSmrg *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4); 47835c4bbdfSmrg *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4); 47935c4bbdfSmrg pntr1++; 48035c4bbdfSmrg pntr2++; 48135c4bbdfSmrg count -= 2; 48235c4bbdfSmrg } 48305b261ecSmrg } 48405b261ecSmrg 48505b261ecSmrg /* 48605b261ecSmrg * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping 48705b261ecSmrg * out entire source mask. 48805b261ecSmrg */ 48905b261ecSmrg if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) { 49035c4bbdfSmrg int count = words; 49135c4bbdfSmrg SCANLINE *pntr = DstM; 49235c4bbdfSmrg 49335c4bbdfSmrg while (count--) { 49435c4bbdfSmrg *pntr = ~(*pntr); 49535c4bbdfSmrg pntr++; 49635c4bbdfSmrg } 49705b261ecSmrg } 49805b261ecSmrg 49905b261ecSmrg if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) { 50035c4bbdfSmrg for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM; 50135c4bbdfSmrg y--; pSrc += DstPitch, pMsk += DstPitch) { 50235c4bbdfSmrg for (x = 0; x < Pitch; x++) { 50335c4bbdfSmrg pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]); 50435c4bbdfSmrg pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]); 50535c4bbdfSmrg } 50635c4bbdfSmrg } 50705b261ecSmrg } 50805b261ecSmrg 50905b261ecSmrg return mem; 51005b261ecSmrg} 51105b261ecSmrg 51235c4bbdfSmrgstatic unsigned char * 51305b261ecSmrgRealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 51405b261ecSmrg{ 51505b261ecSmrg unsigned char *DstS, *DstM; 51605b261ecSmrg unsigned char *pntr; 51705b261ecSmrg unsigned char *mem, *mem2; 51805b261ecSmrg int count; 51905b261ecSmrg int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 52005b261ecSmrg 52105b261ecSmrg /* Realize the cursor without interleaving */ 52205b261ecSmrg if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 52335c4bbdfSmrg return NULL; 52405b261ecSmrg 5256747b715Smrg if (!(mem = calloc(1, size))) { 52635c4bbdfSmrg free(mem2); 52735c4bbdfSmrg return NULL; 52805b261ecSmrg } 52905b261ecSmrg 53035c4bbdfSmrg /* 1 bit interleave */ 53105b261ecSmrg DstS = mem2; 53205b261ecSmrg DstM = DstS + (size >> 1); 53305b261ecSmrg pntr = mem; 53405b261ecSmrg count = size; 53505b261ecSmrg while (count) { 53635c4bbdfSmrg *pntr++ = ((*DstS & 0x01)) | ((*DstM & 0x01) << 1) | 53735c4bbdfSmrg ((*DstS & 0x02) << 1) | ((*DstM & 0x02) << 2) | 53835c4bbdfSmrg ((*DstS & 0x04) << 2) | ((*DstM & 0x04) << 3) | 53935c4bbdfSmrg ((*DstS & 0x08) << 3) | ((*DstM & 0x08) << 4); 54035c4bbdfSmrg *pntr++ = ((*DstS & 0x10) >> 4) | ((*DstM & 0x10) >> 3) | 54135c4bbdfSmrg ((*DstS & 0x20) >> 3) | ((*DstM & 0x20) >> 2) | 54235c4bbdfSmrg ((*DstS & 0x40) >> 2) | ((*DstM & 0x40) >> 1) | 54335c4bbdfSmrg ((*DstS & 0x80) >> 1) | ((*DstM & 0x80)); 54435c4bbdfSmrg DstS++; 54535c4bbdfSmrg DstM++; 54635c4bbdfSmrg count -= 2; 54705b261ecSmrg } 54805b261ecSmrg 54905b261ecSmrg /* Free the uninterleaved cursor */ 5506747b715Smrg free(mem2); 55105b261ecSmrg 55205b261ecSmrg return mem; 55305b261ecSmrg} 55405b261ecSmrg 55535c4bbdfSmrgstatic unsigned char * 55605b261ecSmrgRealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 55705b261ecSmrg{ 55805b261ecSmrg unsigned char *DstS, *DstM; 55905b261ecSmrg unsigned char *pntr; 56005b261ecSmrg unsigned char *mem, *mem2; 56105b261ecSmrg int count; 56205b261ecSmrg int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 56305b261ecSmrg 56405b261ecSmrg /* Realize the cursor without interleaving */ 56505b261ecSmrg if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 56635c4bbdfSmrg return NULL; 56705b261ecSmrg 5686747b715Smrg if (!(mem = calloc(1, size))) { 56935c4bbdfSmrg free(mem2); 57035c4bbdfSmrg return NULL; 57105b261ecSmrg } 57205b261ecSmrg 57305b261ecSmrg /* 8 bit interleave */ 57405b261ecSmrg DstS = mem2; 57505b261ecSmrg DstM = DstS + (size >> 1); 57605b261ecSmrg pntr = mem; 57705b261ecSmrg count = size; 57805b261ecSmrg while (count) { 57935c4bbdfSmrg *pntr++ = *DstS++; 58035c4bbdfSmrg *pntr++ = *DstM++; 58135c4bbdfSmrg count -= 2; 58205b261ecSmrg } 58305b261ecSmrg 58405b261ecSmrg /* Free the uninterleaved cursor */ 5856747b715Smrg free(mem2); 58605b261ecSmrg 58705b261ecSmrg return mem; 58805b261ecSmrg} 58905b261ecSmrg 59035c4bbdfSmrgstatic unsigned char * 59105b261ecSmrgRealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 59205b261ecSmrg{ 59305b261ecSmrg unsigned short *DstS, *DstM; 59405b261ecSmrg unsigned short *pntr; 59505b261ecSmrg unsigned char *mem, *mem2; 59605b261ecSmrg int count; 59705b261ecSmrg int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 59805b261ecSmrg 59905b261ecSmrg /* Realize the cursor without interleaving */ 60005b261ecSmrg if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 60135c4bbdfSmrg return NULL; 60205b261ecSmrg 6036747b715Smrg if (!(mem = calloc(1, size))) { 60435c4bbdfSmrg free(mem2); 60535c4bbdfSmrg return NULL; 60605b261ecSmrg } 60705b261ecSmrg 60805b261ecSmrg /* 16 bit interleave */ 60935c4bbdfSmrg DstS = (void *) mem2; 61005b261ecSmrg DstM = DstS + (size >> 2); 61135c4bbdfSmrg pntr = (void *) mem; 61205b261ecSmrg count = (size >> 1); 61305b261ecSmrg while (count) { 61435c4bbdfSmrg *pntr++ = *DstS++; 61535c4bbdfSmrg *pntr++ = *DstM++; 61635c4bbdfSmrg count -= 2; 61705b261ecSmrg } 61805b261ecSmrg 61905b261ecSmrg /* Free the uninterleaved cursor */ 6206747b715Smrg free(mem2); 62105b261ecSmrg 62205b261ecSmrg return mem; 62305b261ecSmrg} 62405b261ecSmrg 62535c4bbdfSmrgstatic unsigned char * 62605b261ecSmrgRealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 62705b261ecSmrg{ 62805b261ecSmrg CARD32 *DstS, *DstM; 62905b261ecSmrg CARD32 *pntr; 63005b261ecSmrg unsigned char *mem, *mem2; 63105b261ecSmrg int count; 63205b261ecSmrg int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 63305b261ecSmrg 63405b261ecSmrg /* Realize the cursor without interleaving */ 63505b261ecSmrg if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 63635c4bbdfSmrg return NULL; 63705b261ecSmrg 6386747b715Smrg if (!(mem = calloc(1, size))) { 63935c4bbdfSmrg free(mem2); 64035c4bbdfSmrg return NULL; 64105b261ecSmrg } 64205b261ecSmrg 64305b261ecSmrg /* 32 bit interleave */ 64435c4bbdfSmrg DstS = (void *) mem2; 64505b261ecSmrg DstM = DstS + (size >> 3); 64635c4bbdfSmrg pntr = (void *) mem; 64705b261ecSmrg count = (size >> 2); 64805b261ecSmrg while (count) { 64935c4bbdfSmrg *pntr++ = *DstS++; 65035c4bbdfSmrg *pntr++ = *DstM++; 65135c4bbdfSmrg count -= 2; 65205b261ecSmrg } 65305b261ecSmrg 65405b261ecSmrg /* Free the uninterleaved cursor */ 6556747b715Smrg free(mem2); 65605b261ecSmrg 65705b261ecSmrg return mem; 65805b261ecSmrg} 65905b261ecSmrg 66035c4bbdfSmrgstatic unsigned char * 66105b261ecSmrgRealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 66205b261ecSmrg{ 66305b261ecSmrg CARD32 *DstS, *DstM; 66405b261ecSmrg CARD32 *pntr; 66505b261ecSmrg unsigned char *mem, *mem2; 66605b261ecSmrg int count; 66705b261ecSmrg int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 66805b261ecSmrg 66905b261ecSmrg /* Realize the cursor without interleaving */ 67005b261ecSmrg if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs))) 67135c4bbdfSmrg return NULL; 67205b261ecSmrg 6736747b715Smrg if (!(mem = calloc(1, size))) { 67435c4bbdfSmrg free(mem2); 67535c4bbdfSmrg return NULL; 67605b261ecSmrg } 67705b261ecSmrg 67805b261ecSmrg /* 64 bit interleave */ 67935c4bbdfSmrg DstS = (void *) mem2; 68005b261ecSmrg DstM = DstS + (size >> 3); 68135c4bbdfSmrg pntr = (void *) mem; 68205b261ecSmrg count = (size >> 2); 68305b261ecSmrg while (count) { 68435c4bbdfSmrg *pntr++ = *DstS++; 68535c4bbdfSmrg *pntr++ = *DstS++; 68635c4bbdfSmrg *pntr++ = *DstM++; 68735c4bbdfSmrg *pntr++ = *DstM++; 68835c4bbdfSmrg count -= 4; 68905b261ecSmrg } 69005b261ecSmrg 69105b261ecSmrg /* Free the uninterleaved cursor */ 6926747b715Smrg free(mem2); 69305b261ecSmrg 69405b261ecSmrg return mem; 69505b261ecSmrg} 696