@@ -3965,6 +3965,10 @@ AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
update_desktop_dimensions();
+ if (!dixPrivatesCreated(PRIVATE_CURSOR))
+ dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen,
+ PRIVATE_CURSOR, 0);
+
return i;
}
@@ -783,3 +783,12 @@ dixResetPrivates(void)
global_keys[t].allocated = 0;
}
}
+
+Bool
+dixPrivatesCreated(DevPrivateType type)
+{
+ if (global_keys[type].created)
+ return TRUE;
+ else
+ return FALSE;
+}
@@ -337,16 +337,9 @@ 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 ||
- ((
- 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)))))) {
+ xf86CheckHWCursor(pScreen, cursor, infoPtr))) {
if (ScreenPriv->SWCursor) /* remove the SW cursor */
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
@@ -465,9 +458,12 @@ xf86ForceHWCursor(ScreenPtr pScreen, Bool on)
CursorPtr
xf86CurrentCursor(ScreenPtr pScreen)
{
- xf86CursorScreenPtr ScreenPriv =
- (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
- xf86CursorScreenKey);
+ xf86CursorScreenPtr ScreenPriv;
+
+ if (pScreen->is_output_slave)
+ pScreen = pScreen->current_master;
+
+ ScreenPriv = dixLookupPrivate(&pScreen->devPrivates, xf86CursorScreenKey);
return ScreenPriv->CurrentCursor;
}
@@ -43,6 +43,7 @@ void xf86MoveCursor(ScreenPtr pScreen, int x, int y);
void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed);
Bool xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr);
+Bool xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr);
extern _X_EXPORT DevPrivateKeyRec xf86CursorScreenKeyRec;
#define xf86CursorScreenKey (&xf86CursorScreenKeyRec)
@@ -17,6 +17,7 @@
#include "cursorstr.h"
#include "mi.h"
#include "mipointer.h"
+#include "randrstr.h"
#include "xf86CursorPriv.h"
#include "servermd.h"
@@ -129,8 +130,42 @@ xf86ShowCursor(xf86CursorInfoPtr infoPtr)
return TRUE;
}
+static Bool
+xf86CursorScreenCheckHW(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;
+
+ if (!xf86CursorScreenCheckHW(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 (!xf86CursorScreenCheckHW(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,
@@ -175,6 +210,31 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
}
+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)
{
@@ -197,8 +257,8 @@ xf86SetTransparentCursor(ScreenPtr pScreen)
xf86ShowCursor(infoPtr);
}
-void
-xf86MoveCursor(ScreenPtr pScreen, int x, int y)
+static void
+xf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y)
{
xf86CursorScreenPtr ScreenPriv =
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
@@ -212,6 +272,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 =
@@ -252,6 +252,9 @@ dixFreeScreenSpecificPrivates(ScreenPtr pScreen);
extern void
dixInitScreenSpecificPrivates(ScreenPtr pScreen);
+/* is this private created - so hotplug can avoid crashing */
+Bool dixPrivatesCreated(DevPrivateType type);
+
extern _X_EXPORT void *
_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
unsigned size,
@@ -726,6 +726,12 @@ extern _X_EXPORT Bool
RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable);
/*
+ * Return if the screen has any scanout_pixmap's attached
+ */
+extern _X_EXPORT Bool
+ RRHasScanoutPixmap(ScreenPtr pScreen);
+
+/*
* Crtc dispatch
*/
@@ -1945,3 +1945,22 @@ RRReplaceScanoutPixmap(DrawablePtr pDrawable, PixmapPtr pPixmap, Bool enable)
return ret;
}
+
+Bool
+RRHasScanoutPixmap(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ int i;
+
+ if (!pScreen->is_output_slave)
+ return FALSE;
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+ if (crtc->scanout_pixmap)
+ return TRUE;
+ }
+
+ return FALSE;
+}