aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/ramdac/xf86Cursor.c')
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.c227
1 files changed, 147 insertions, 80 deletions
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
index 5b1ce5e1f..896ed3700 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
@@ -8,26 +8,41 @@
#include "colormapst.h"
#include "cursorstr.h"
-DevPrivateKey xf86CursorScreenKey = &xf86CursorScreenKey;
+/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
+ * MPX.
+ * inputInfo is needed to pass the core pointer as the default argument into
+ * the cursor functions.
+ *
+ * Externing inputInfo is not the nice way to do it but it works.
+ */
+#include "inputstr.h"
+extern InputInfo inputInfo;
+
+static int xf86CursorScreenKeyIndex;
+DevPrivateKey xf86CursorScreenKey = &xf86CursorScreenKeyIndex;
/* sprite functions */
-static Bool xf86CursorRealizeCursor(ScreenPtr, CursorPtr);
-static Bool xf86CursorUnrealizeCursor(ScreenPtr, CursorPtr);
-static void xf86CursorSetCursor(ScreenPtr, CursorPtr, int, int);
-static void xf86CursorMoveCursor(ScreenPtr, int, int);
+static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
+static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
+static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
+static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
+static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
+static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
xf86CursorRealizeCursor,
xf86CursorUnrealizeCursor,
xf86CursorSetCursor,
- xf86CursorMoveCursor
+ xf86CursorMoveCursor,
+ xf86DeviceCursorInitialize,
+ xf86DeviceCursorCleanup
};
/* Screen functions */
static void xf86CursorInstallColormap(ColormapPtr);
-static void xf86CursorRecolorCursor(ScreenPtr, CursorPtr, Bool);
+static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr, Bool);
static Bool xf86CursorCloseScreen(int, ScreenPtr);
static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
ScreenPtr);
@@ -164,6 +179,7 @@ xf86CursorInstallColormap(ColormapPtr pMap)
static void
xf86CursorRecolorCursor(
+ DeviceIntPtr pDev,
ScreenPtr pScreen,
CursorPtr pCurs,
Bool displayed)
@@ -175,7 +191,7 @@ xf86CursorRecolorCursor(
return;
if (ScreenPriv->SWCursor)
- (*ScreenPriv->RecolorCursor)(pScreen, pCurs, displayed);
+ (*ScreenPriv->RecolorCursor)(pDev, pScreen, pCurs, displayed);
else
xf86RecolorCursor(pScreen, pCurs, displayed);
}
@@ -187,14 +203,17 @@ xf86CursorEnableDisableFBAccess(
int index,
Bool enable)
{
+ DeviceIntPtr pDev = inputInfo.pointer;
+
ScreenPtr pScreen = screenInfo.screens[index];
xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
&pScreen->devPrivates, xf86CursorScreenKey);
if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
- CursorPtr currentCursor = ScreenPriv->CurrentCursor;
- xf86CursorSetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
- ScreenPriv->isUp = FALSE;
+ CursorPtr currentCursor = ScreenPriv->CurrentCursor;
+ xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
+ ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
ScreenPriv->SWCursor = TRUE;
ScreenPriv->SavedCursor = currentCursor;
}
@@ -208,7 +227,7 @@ xf86CursorEnableDisableFBAccess(
* Re-set current cursor so drivers can react to FB access having been
* temporarily disabled.
*/
- xf86CursorSetCursor(pScreen, ScreenPriv->SavedCursor,
+ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
ScreenPriv->x, ScreenPriv->y);
ScreenPriv->SavedCursor = NULL;
}
@@ -245,123 +264,141 @@ xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
/****** miPointerSpriteFunctions *******/
static Bool
-xf86CursorRealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
+xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
{
xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
&pScreen->devPrivates, xf86CursorScreenKey);
if (pCurs->refcnt <= 1)
- dixSetPrivate(&pCurs->devPrivates, pScreen, NULL);
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
- return (*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCurs);
+ return (*ScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs);
}
static Bool
-xf86CursorUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
+xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+ CursorPtr pCurs)
{
xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
&pScreen->devPrivates, xf86CursorScreenKey);
if (pCurs->refcnt <= 1) {
- xfree(dixLookupPrivate(&pCurs->devPrivates, pScreen));
- dixSetPrivate(&pCurs->devPrivates, pScreen, NULL);
+ xfree(dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen)));
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
}
- return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCurs);
+ return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs);
}
static void
-xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
+ int x, int y)
{
xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
&pScreen->devPrivates, xf86CursorScreenKey);
xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- miPointerScreenPtr PointPriv;
-
- ScreenPriv->CurrentCursor = pCurs;
- ScreenPriv->x = x;
- ScreenPriv->y = y;
- ScreenPriv->CursorToRestore = NULL;
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
- if (!infoPtr->pScrn->vtSema)
- ScreenPriv->SavedCursor = pCurs;
if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */
- if (ScreenPriv->SWCursor)
- (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, NullCursor, x, y);
- else if (ScreenPriv->isUp) {
- xf86SetCursor(pScreen, NullCursor, x, y);
- ScreenPriv->isUp = FALSE;
- }
- return;
+ if (ScreenPriv->SWCursor ||
+ !(pDev == inputInfo.pointer || !pDev->isMaster && pDev->u.master == inputInfo.pointer))
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
+ else if (ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, NullCursor, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ return;
}
- ScreenPriv->HotX = pCurs->bits->xhot;
- ScreenPriv->HotY = pCurs->bits->yhot;
+ /* only update for VCP, otherwise we get cursor jumps when removing a
+ sprite. The second cursor is never HW rendered anyway. */
+ if (pDev == inputInfo.pointer ||
+ (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+ {
+ ScreenPriv->CurrentCursor = pCurs;
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+ ScreenPriv->CursorToRestore = NULL;
+ ScreenPriv->HotX = pCurs->bits->xhot;
+ ScreenPriv->HotY = pCurs->bits->yhot;
- PointPriv = (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- miPointerScreenKey);
- if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
+ if (!infoPtr->pScrn->vtSema)
+ ScreenPriv->SavedCursor = pCurs;
+
+ if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
#ifdef ARGB_CURSOR
- pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
- (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
- pCurs->bits->argb == 0 &&
+ pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
+ (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
+ pCurs->bits->argb == 0 &&
#endif
- (pCurs->bits->height <= infoPtr->MaxHeight) &&
- (pCurs->bits->width <= infoPtr->MaxWidth) &&
- (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
- {
+ (pCurs->bits->height <= infoPtr->MaxHeight) &&
+ (pCurs->bits->width <= infoPtr->MaxWidth) &&
+ (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
+ {
- if (ScreenPriv->SWCursor) /* remove the SW cursor */
- (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, NullCursor, x, y);
+ if (ScreenPriv->SWCursor) /* remove the SW cursor */
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
- xf86SetCursor(pScreen, pCurs, x, y);
- ScreenPriv->SWCursor = FALSE;
- ScreenPriv->isUp = TRUE;
- PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse;
- return;
- }
+ xf86SetCursor(pScreen, pCurs, x, y);
+ ScreenPriv->SWCursor = FALSE;
+ ScreenPriv->isUp = TRUE;
+ PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse;
+ return;
+ }
- PointPriv->waitForUpdate = TRUE;
+ PointPriv->waitForUpdate = TRUE;
- if (ScreenPriv->isUp) {
- /* Remove the HW cursor, or make it transparent */
- if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
- xf86SetTransparentCursor(pScreen);
- } else {
- xf86SetCursor(pScreen, NullCursor, x, y);
- ScreenPriv->isUp = FALSE;
- }
- }
+ if (ScreenPriv->isUp) {
+ /* Remove the HW cursor, or make it transparent */
+ if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
+ xf86SetTransparentCursor(pScreen);
+ } else {
+ xf86SetCursor(pScreen, NullCursor, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ }
- ScreenPriv->SWCursor = TRUE;
+ if (!ScreenPriv->SWCursor)
+ ScreenPriv->SWCursor = TRUE;
+
+ }
if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
pCurs = NullCursor;
- (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCurs, x, y);
+
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y);
}
static void
-xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y)
+xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
{
xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
&pScreen->devPrivates, xf86CursorScreenKey);
- ScreenPriv->x = x;
- ScreenPriv->y = y;
-
- if (ScreenPriv->CursorToRestore)
- xf86CursorSetCursor(pScreen, ScreenPriv->CursorToRestore,
- ScreenPriv->x, ScreenPriv->y);
- else if (ScreenPriv->SWCursor)
- (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
- else if (ScreenPriv->isUp)
- xf86MoveCursor(pScreen, x, y);
+ /* only update coordinate state for first sprite, otherwise we get jumps
+ when removing a sprite. The second sprite is never HW rendered anyway */
+ if (pDev == inputInfo.pointer ||
+ (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+ {
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+
+ if (ScreenPriv->CursorToRestore)
+ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x, y);
+ else if (ScreenPriv->SWCursor)
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
+ else if (ScreenPriv->isUp)
+ xf86MoveCursor(pScreen, x, y);
+ } else
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
}
void
xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
{
+ DeviceIntPtr pDev = inputInfo.pointer;
xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
&pScreen->devPrivates, xf86CursorScreenKey);
@@ -372,7 +409,7 @@ xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor)
{
ScreenPriv->HWCursorForced = TRUE;
- xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor,
+ xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
ScreenPriv->x, ScreenPriv->y);
}
else
@@ -384,7 +421,7 @@ xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
if (--ScreenPriv->ForceHWCursorCount == 0)
{
if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
- xf86CursorSetCursor (pScreen, ScreenPriv->CurrentCursor,
+ xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
ScreenPriv->x, ScreenPriv->y);
}
}
@@ -401,3 +438,33 @@ xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
{
xfree(infoPtr);
}
+
+/**
+ * New cursor has been created. Do your initalizations here.
+ */
+static Bool
+xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ int ret;
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* Init SW cursor */
+ ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
+
+ return ret;
+}
+
+/**
+ * Cursor has been removed. Clean up after yourself.
+ */
+static void
+xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* Clean up SW cursor */
+ (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+}
+