diff options
-rw-r--r-- | dix/dispatch.c | 10 | ||||
-rw-r--r-- | hw/xfree86/ramdac/xf86Cursor.c | 2 | ||||
-rw-r--r-- | hw/xfree86/ramdac/xf86HWCurs.c | 82 |
3 files changed, 88 insertions, 6 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c index a3c2fbb31..0edcfeea8 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -3965,6 +3965,16 @@ AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ , update_desktop_dimensions(); + /* + * We cannot register the Screen PRIVATE_CURSOR key if cursors are already + * created, because dix/privates.c does not have relocation code for + * PRIVATE_CURSOR. Once this is fixed the if() can be removed and we can + * register the Screen PRIVATE_CURSOR key unconditionally. + */ + if (!dixPrivatesCreated(PRIVATE_CURSOR)) + dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, + PRIVATE_CURSOR, 0); + return i; } diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c index 623a65b33..afcce5353 100644 --- a/hw/xfree86/ramdac/xf86Cursor.c +++ b/hw/xfree86/ramdac/xf86Cursor.c @@ -337,7 +337,7 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, return; } - if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) && + if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || xf86CheckHWCursor(pScreen, cursor, infoPtr))) { diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c index 1b85e6346..e8966ed35 100644 --- a/hw/xfree86/ramdac/xf86HWCurs.c +++ b/hw/xfree86/ramdac/xf86HWCurs.c @@ -17,6 +17,7 @@ #include "cursorstr.h" #include "mi.h" #include "mipointer.h" +#include "randrstr.h" #include "xf86CursorPriv.h" #include "servermd.h" @@ -119,8 +120,8 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) return TRUE; } -Bool -xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) +static Bool +xf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) { return (cursor->bits->argb && infoPtr->UseHWCursorARGB && @@ -132,7 +133,29 @@ xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr } Bool -xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) +xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr) +{ + ScreenPtr pSlave; + + if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) + return FALSE; + + /* 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 (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) + return FALSE; + } + return TRUE; +} + +static Bool +xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) { xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, @@ -145,6 +168,14 @@ 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); @@ -177,6 +208,31 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) return TRUE; } +Bool +xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) +{ + ScreenPtr pSlave; + + if (!xf86ScreenSetCursor(pScreen, pCurs, x, y)) + return FALSE; + + /* 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); + return FALSE; + } + } + return TRUE; +} + void xf86SetTransparentCursor(ScreenPtr pScreen) { @@ -199,8 +255,8 @@ xf86SetTransparentCursor(ScreenPtr pScreen) (*infoPtr->ShowCursor) (infoPtr->pScrn); } -void -xf86MoveCursor(ScreenPtr pScreen, int x, int y) +static void +xf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y) { xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, @@ -214,6 +270,22 @@ xf86MoveCursor(ScreenPtr pScreen, int x, int y) } void +xf86MoveCursor(ScreenPtr pScreen, int x, int y) +{ + ScreenPtr pSlave; + + 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); + } +} + +void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed) { xf86CursorScreenPtr ScreenPriv = |