diff options
Diffstat (limited to 'xserver/hw/xfree86/ramdac/xf86HWCurs.c')
-rw-r--r-- | xserver/hw/xfree86/ramdac/xf86HWCurs.c | 158 |
1 files changed, 149 insertions, 9 deletions
diff --git a/xserver/hw/xfree86/ramdac/xf86HWCurs.c b/xserver/hw/xfree86/ramdac/xf86HWCurs.c index 84febe0df..7043a9c72 100644 --- a/xserver/hw/xfree86/ramdac/xf86HWCurs.c +++ b/xserver/hw/xfree86/ramdac/xf86HWCurs.c @@ -17,10 +17,14 @@ #include "cursorstr.h" #include "mi.h" #include "mipointer.h" +#include "randrstr.h" #include "xf86CursorPriv.h" #include "servermd.h" +static void +xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs); + static CARD32 xf86ReverseBitOrder(CARD32 v) { @@ -119,8 +123,59 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) return TRUE; } +static Bool +xf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) +{ + 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))); +} + Bool -xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) +xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) +{ + ScreenPtr pSlave; + Bool use_hw_cursor = TRUE; + + input_lock(); + + if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) { + use_hw_cursor = FALSE; + goto unlock; + } + + /* 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); + if (!sPriv) { /* NULL if Option "SWCursor", possibly other conditions */ + use_hw_cursor = FALSE; + break; + } + + /* FALSE if HWCursor not supported by slave */ + if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) { + use_hw_cursor = FALSE; + break; + } + } + +unlock: + input_unlock(); + + return use_hw_cursor; +} + +static Bool +xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) { xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, @@ -133,11 +188,19 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) return TRUE; } + /* + * 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; + bits = dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen); - x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX; - y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY; + x -= infoPtr->pScrn->frameX0; + y -= infoPtr->pScrn->frameY0; if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr)) if (!bits) { @@ -157,7 +220,7 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) if (!xf86DriverLoadCursorImage (infoPtr, bits)) return FALSE; - xf86RecolorCursor(pScreen, pCurs, 1); + xf86RecolorCursor_locked (ScreenPriv, pCurs); (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); @@ -165,6 +228,44 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) return TRUE; } +Bool +xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) +{ + xf86CursorScreenPtr ScreenPriv = + (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, + xf86CursorScreenKey); + ScreenPtr pSlave; + Bool ret = FALSE; + + input_lock(); + + x -= ScreenPriv->HotX; + y -= ScreenPriv->HotY; + + if (!xf86ScreenSetCursor(pScreen, pCurs, x, y)) + goto out; + + /* 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); + goto out; + } + } + ret = TRUE; + + out: + input_unlock(); + return ret; +} + void xf86SetTransparentCursor(ScreenPtr pScreen) { @@ -173,6 +274,8 @@ xf86SetTransparentCursor(ScreenPtr pScreen) xf86CursorScreenKey); xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; + input_lock(); + if (!ScreenPriv->transparentData) ScreenPriv->transparentData = (*infoPtr->RealizeCursor) (infoPtr, NullCursor); @@ -185,28 +288,53 @@ xf86SetTransparentCursor(ScreenPtr pScreen) ScreenPriv->transparentData); (*infoPtr->ShowCursor) (infoPtr->pScrn); + + input_unlock(); } -void -xf86MoveCursor(ScreenPtr pScreen, int x, int y) +static void +xf86ScreenMoveCursor(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; + x -= infoPtr->pScrn->frameX0; + y -= infoPtr->pScrn->frameY0; (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); } void -xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) +xf86MoveCursor(ScreenPtr pScreen, int x, int y) { xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, xf86CursorScreenKey); + ScreenPtr pSlave; + + input_lock(); + + x -= ScreenPriv->HotX; + y -= ScreenPriv->HotY; + + 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); + } + + input_unlock(); +} + +static void +xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs) +{ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr; /* recoloring isn't applicable to ARGB cursors and drivers @@ -246,6 +374,18 @@ xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) } } +void +xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) +{ + xf86CursorScreenPtr ScreenPriv = + (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, + xf86CursorScreenKey); + + input_lock(); + xf86RecolorCursor_locked (ScreenPriv, pCurs); + input_unlock(); +} + /* These functions assume that MaxWidth is a multiple of 32 */ static unsigned char * RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) |