11b5d61b8Smrg
21b5d61b8Smrg#ifdef HAVE_XORG_CONFIG_H
31b5d61b8Smrg#include <xorg-config.h>
41b5d61b8Smrg#endif
51b5d61b8Smrg
61b5d61b8Smrg#include "xf86.h"
71b5d61b8Smrg#include "xf86CursorPriv.h"
81b5d61b8Smrg#include "colormapst.h"
91b5d61b8Smrg#include "cursorstr.h"
101b5d61b8Smrg
111b5d61b8Smrg/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
121b5d61b8Smrg * MPX.
131b5d61b8Smrg * inputInfo is needed to pass the core pointer as the default argument into
141b5d61b8Smrg * the cursor functions.
151b5d61b8Smrg *
161b5d61b8Smrg * Externing inputInfo is not the nice way to do it but it works.
171b5d61b8Smrg */
181b5d61b8Smrg#include "inputstr.h"
191b5d61b8Smrg
201b5d61b8SmrgDevPrivateKeyRec xf86CursorScreenKeyRec;
211b5d61b8Smrg
221b5d61b8Smrg/* sprite functions */
231b5d61b8Smrg
241b5d61b8Smrgstatic Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
251b5d61b8Smrgstatic Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
261b5d61b8Smrgstatic void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
271b5d61b8Smrgstatic void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
281b5d61b8Smrgstatic Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
291b5d61b8Smrgstatic void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
301b5d61b8Smrg
311b5d61b8Smrgstatic miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
321b5d61b8Smrg    xf86CursorRealizeCursor,
331b5d61b8Smrg    xf86CursorUnrealizeCursor,
341b5d61b8Smrg    xf86CursorSetCursor,
351b5d61b8Smrg    xf86CursorMoveCursor,
361b5d61b8Smrg    xf86DeviceCursorInitialize,
371b5d61b8Smrg    xf86DeviceCursorCleanup
381b5d61b8Smrg};
391b5d61b8Smrg
401b5d61b8Smrg/* Screen functions */
411b5d61b8Smrg
421b5d61b8Smrgstatic void xf86CursorInstallColormap(ColormapPtr);
431b5d61b8Smrgstatic void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr,
441b5d61b8Smrg                                    Bool);
451b5d61b8Smrgstatic Bool xf86CursorCloseScreen(ScreenPtr);
461b5d61b8Smrgstatic void xf86CursorQueryBestSize(int, unsigned short *, unsigned short *,
471b5d61b8Smrg                                    ScreenPtr);
481b5d61b8Smrg
491b5d61b8Smrg/* ScrnInfoRec functions */
501b5d61b8Smrg
511b5d61b8Smrgstatic void xf86CursorEnableDisableFBAccess(ScrnInfoPtr, Bool);
521b5d61b8Smrgstatic Bool xf86CursorSwitchMode(ScrnInfoPtr, DisplayModePtr);
531b5d61b8Smrg
541b5d61b8SmrgBool
551b5d61b8Smrgxf86InitCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
561b5d61b8Smrg{
571b5d61b8Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
581b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv;
591b5d61b8Smrg    miPointerScreenPtr PointPriv;
601b5d61b8Smrg
611b5d61b8Smrg    if (!xf86InitHardwareCursor(pScreen, infoPtr))
621b5d61b8Smrg        return FALSE;
631b5d61b8Smrg
641b5d61b8Smrg    if (!dixRegisterPrivateKey(&xf86CursorScreenKeyRec, PRIVATE_SCREEN, 0))
651b5d61b8Smrg        return FALSE;
661b5d61b8Smrg
671b5d61b8Smrg    ScreenPriv = calloc(1, sizeof(xf86CursorScreenRec));
681b5d61b8Smrg    if (!ScreenPriv)
691b5d61b8Smrg        return FALSE;
701b5d61b8Smrg
711b5d61b8Smrg    dixSetPrivate(&pScreen->devPrivates, xf86CursorScreenKey, ScreenPriv);
721b5d61b8Smrg
731b5d61b8Smrg    ScreenPriv->SWCursor = TRUE;
741b5d61b8Smrg    ScreenPriv->isUp = FALSE;
751b5d61b8Smrg    ScreenPriv->CurrentCursor = NULL;
761b5d61b8Smrg    ScreenPriv->CursorInfoPtr = infoPtr;
771b5d61b8Smrg    ScreenPriv->PalettedCursor = FALSE;
781b5d61b8Smrg    ScreenPriv->pInstalledMap = NULL;
791b5d61b8Smrg
801b5d61b8Smrg    ScreenPriv->CloseScreen = pScreen->CloseScreen;
811b5d61b8Smrg    pScreen->CloseScreen = xf86CursorCloseScreen;
821b5d61b8Smrg    ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
831b5d61b8Smrg    pScreen->QueryBestSize = xf86CursorQueryBestSize;
841b5d61b8Smrg    ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
851b5d61b8Smrg    pScreen->RecolorCursor = xf86CursorRecolorCursor;
861b5d61b8Smrg
871b5d61b8Smrg    if ((infoPtr->pScrn->bitsPerPixel == 8) &&
881b5d61b8Smrg        !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
891b5d61b8Smrg        ScreenPriv->InstallColormap = pScreen->InstallColormap;
901b5d61b8Smrg        pScreen->InstallColormap = xf86CursorInstallColormap;
911b5d61b8Smrg        ScreenPriv->PalettedCursor = TRUE;
921b5d61b8Smrg    }
931b5d61b8Smrg
941b5d61b8Smrg    PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
951b5d61b8Smrg
961b5d61b8Smrg    ScreenPriv->showTransparent = PointPriv->showTransparent;
971b5d61b8Smrg    if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
981b5d61b8Smrg        PointPriv->showTransparent = TRUE;
991b5d61b8Smrg    else
1001b5d61b8Smrg        PointPriv->showTransparent = FALSE;
1011b5d61b8Smrg    ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
1021b5d61b8Smrg    PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
1031b5d61b8Smrg
1041b5d61b8Smrg    ScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
1051b5d61b8Smrg    ScreenPriv->SwitchMode = pScrn->SwitchMode;
1061b5d61b8Smrg
1071b5d61b8Smrg    ScreenPriv->ForceHWCursorCount = 0;
1081b5d61b8Smrg    ScreenPriv->HWCursorForced = FALSE;
1091b5d61b8Smrg
1101b5d61b8Smrg    pScrn->EnableDisableFBAccess = xf86CursorEnableDisableFBAccess;
1111b5d61b8Smrg    if (pScrn->SwitchMode)
1121b5d61b8Smrg        pScrn->SwitchMode = xf86CursorSwitchMode;
1131b5d61b8Smrg
1141b5d61b8Smrg    return TRUE;
1151b5d61b8Smrg}
1161b5d61b8Smrg
1171b5d61b8Smrg/***** Screen functions *****/
1181b5d61b8Smrg
1191b5d61b8Smrgstatic Bool
1201b5d61b8Smrgxf86CursorCloseScreen(ScreenPtr pScreen)
1211b5d61b8Smrg{
1221b5d61b8Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1231b5d61b8Smrg    miPointerScreenPtr PointPriv =
1241b5d61b8Smrg        (miPointerScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1251b5d61b8Smrg                                              miPointerScreenKey);
1261b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
1271b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1281b5d61b8Smrg                                               xf86CursorScreenKey);
1291b5d61b8Smrg
1301b5d61b8Smrg    if (ScreenPriv->isUp && pScrn->vtSema)
1311b5d61b8Smrg        xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
1321b5d61b8Smrg
1331b5d61b8Smrg    if (ScreenPriv->CurrentCursor)
1341b5d61b8Smrg        FreeCursor(ScreenPriv->CurrentCursor, None);
1351b5d61b8Smrg
1361b5d61b8Smrg    pScreen->CloseScreen = ScreenPriv->CloseScreen;
1371b5d61b8Smrg    pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
1381b5d61b8Smrg    pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
1391b5d61b8Smrg    if (ScreenPriv->InstallColormap)
1401b5d61b8Smrg        pScreen->InstallColormap = ScreenPriv->InstallColormap;
1411b5d61b8Smrg
1421b5d61b8Smrg    PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
1431b5d61b8Smrg    PointPriv->showTransparent = ScreenPriv->showTransparent;
1441b5d61b8Smrg
1451b5d61b8Smrg    pScrn->EnableDisableFBAccess = ScreenPriv->EnableDisableFBAccess;
1461b5d61b8Smrg    pScrn->SwitchMode = ScreenPriv->SwitchMode;
1471b5d61b8Smrg
1481b5d61b8Smrg    free(ScreenPriv->transparentData);
1491b5d61b8Smrg    free(ScreenPriv);
1501b5d61b8Smrg
1511b5d61b8Smrg    return (*pScreen->CloseScreen) (pScreen);
1521b5d61b8Smrg}
1531b5d61b8Smrg
1541b5d61b8Smrgstatic void
1551b5d61b8Smrgxf86CursorQueryBestSize(int class,
1561b5d61b8Smrg                        unsigned short *width,
1571b5d61b8Smrg                        unsigned short *height, ScreenPtr pScreen)
1581b5d61b8Smrg{
1591b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
1601b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1611b5d61b8Smrg                                               xf86CursorScreenKey);
1621b5d61b8Smrg
1631b5d61b8Smrg    if (class == CursorShape) {
1641b5d61b8Smrg        if (*width > ScreenPriv->CursorInfoPtr->MaxWidth)
1651b5d61b8Smrg            *width = ScreenPriv->CursorInfoPtr->MaxWidth;
1661b5d61b8Smrg        if (*height > ScreenPriv->CursorInfoPtr->MaxHeight)
1671b5d61b8Smrg            *height = ScreenPriv->CursorInfoPtr->MaxHeight;
1681b5d61b8Smrg    }
1691b5d61b8Smrg    else
1701b5d61b8Smrg        (*ScreenPriv->QueryBestSize) (class, width, height, pScreen);
1711b5d61b8Smrg}
1721b5d61b8Smrg
1731b5d61b8Smrgstatic void
1741b5d61b8Smrgxf86CursorInstallColormap(ColormapPtr pMap)
1751b5d61b8Smrg{
1761b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
1771b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pMap->pScreen->devPrivates,
1781b5d61b8Smrg                                               xf86CursorScreenKey);
1791b5d61b8Smrg
1801b5d61b8Smrg    ScreenPriv->pInstalledMap = pMap;
1811b5d61b8Smrg
1821b5d61b8Smrg    (*ScreenPriv->InstallColormap) (pMap);
1831b5d61b8Smrg}
1841b5d61b8Smrg
1851b5d61b8Smrgstatic void
1861b5d61b8Smrgxf86CursorRecolorCursor(DeviceIntPtr pDev,
1871b5d61b8Smrg                        ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
1881b5d61b8Smrg{
1891b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
1901b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1911b5d61b8Smrg                                               xf86CursorScreenKey);
1921b5d61b8Smrg
1931b5d61b8Smrg    if (!displayed)
1941b5d61b8Smrg        return;
1951b5d61b8Smrg
1961b5d61b8Smrg    if (ScreenPriv->SWCursor)
1971b5d61b8Smrg        (*ScreenPriv->RecolorCursor) (pDev, pScreen, pCurs, displayed);
1981b5d61b8Smrg    else
1991b5d61b8Smrg        xf86RecolorCursor(pScreen, pCurs, displayed);
2001b5d61b8Smrg}
2011b5d61b8Smrg
2021b5d61b8Smrg/***** ScrnInfoRec functions *********/
2031b5d61b8Smrg
2041b5d61b8Smrgstatic void
2051b5d61b8Smrgxf86CursorEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable)
2061b5d61b8Smrg{
2071b5d61b8Smrg    DeviceIntPtr pDev = inputInfo.pointer;
2081b5d61b8Smrg
2091b5d61b8Smrg    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
2101b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
2111b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
2121b5d61b8Smrg                                               xf86CursorScreenKey);
2131b5d61b8Smrg
2141b5d61b8Smrg    if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
2155a7dfde8Smrg        CursorPtr currentCursor = RefCursor(ScreenPriv->CurrentCursor);
2161b5d61b8Smrg
2171b5d61b8Smrg        xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
2181b5d61b8Smrg                            ScreenPriv->y);
2191b5d61b8Smrg        ScreenPriv->isUp = FALSE;
2201b5d61b8Smrg        ScreenPriv->SWCursor = TRUE;
2211b5d61b8Smrg        ScreenPriv->SavedCursor = currentCursor;
2221b5d61b8Smrg    }
2231b5d61b8Smrg
2241b5d61b8Smrg    if (ScreenPriv->EnableDisableFBAccess)
2251b5d61b8Smrg        (*ScreenPriv->EnableDisableFBAccess) (pScrn, enable);
2261b5d61b8Smrg
2271b5d61b8Smrg    if (enable && ScreenPriv->SavedCursor) {
2281b5d61b8Smrg        /*
2291b5d61b8Smrg         * Re-set current cursor so drivers can react to FB access having been
2301b5d61b8Smrg         * temporarily disabled.
2311b5d61b8Smrg         */
2321b5d61b8Smrg        xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
2331b5d61b8Smrg                            ScreenPriv->x, ScreenPriv->y);
2345a7dfde8Smrg        UnrefCursor(ScreenPriv->SavedCursor);
2351b5d61b8Smrg        ScreenPriv->SavedCursor = NULL;
2361b5d61b8Smrg    }
2371b5d61b8Smrg}
2381b5d61b8Smrg
2391b5d61b8Smrgstatic Bool
2401b5d61b8Smrgxf86CursorSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
2411b5d61b8Smrg{
2421b5d61b8Smrg    Bool ret;
2431b5d61b8Smrg    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
2441b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
2451b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
2461b5d61b8Smrg                                               xf86CursorScreenKey);
2471b5d61b8Smrg
2481b5d61b8Smrg    if (ScreenPriv->isUp) {
2491b5d61b8Smrg        xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
2501b5d61b8Smrg        ScreenPriv->isUp = FALSE;
2511b5d61b8Smrg    }
2521b5d61b8Smrg
2531b5d61b8Smrg    ret = (*ScreenPriv->SwitchMode) (pScrn, mode);
2541b5d61b8Smrg
2551b5d61b8Smrg    /*
2561b5d61b8Smrg     * Cannot restore cursor here because the new frame[XY][01] haven't been
2571b5d61b8Smrg     * calculated yet.  However, because the hardware cursor was removed above,
2581b5d61b8Smrg     * ensure the cursor is repainted by miPointerWarpCursor().
2591b5d61b8Smrg     */
2601b5d61b8Smrg    ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
2611b5d61b8Smrg    miPointerSetWaitForUpdate(pScreen, FALSE);  /* Force cursor repaint */
2621b5d61b8Smrg
2631b5d61b8Smrg    return ret;
2641b5d61b8Smrg}
2651b5d61b8Smrg
2661b5d61b8Smrg/****** miPointerSpriteFunctions *******/
2671b5d61b8Smrg
2681b5d61b8Smrgstatic Bool
2691b5d61b8Smrgxf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
2701b5d61b8Smrg{
2711b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
2721b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
2731b5d61b8Smrg                                               xf86CursorScreenKey);
2741b5d61b8Smrg
2751b5d61b8Smrg    if (CursorRefCount(pCurs) <= 1)
2761b5d61b8Smrg        dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
2771b5d61b8Smrg                            NULL);
2781b5d61b8Smrg
2791b5d61b8Smrg    return (*ScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCurs);
2801b5d61b8Smrg}
2811b5d61b8Smrg
2821b5d61b8Smrgstatic Bool
2831b5d61b8Smrgxf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
2841b5d61b8Smrg{
2851b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
2861b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
2871b5d61b8Smrg                                               xf86CursorScreenKey);
2881b5d61b8Smrg
2891b5d61b8Smrg    if (CursorRefCount(pCurs) <= 1) {
2901b5d61b8Smrg        free(dixLookupScreenPrivate
2911b5d61b8Smrg             (&pCurs->devPrivates, CursorScreenKey, pScreen));
2921b5d61b8Smrg        dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
2931b5d61b8Smrg                            NULL);
2941b5d61b8Smrg    }
2951b5d61b8Smrg
2961b5d61b8Smrg    return (*ScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCurs);
2971b5d61b8Smrg}
2981b5d61b8Smrg
2991b5d61b8Smrgstatic void
3001b5d61b8Smrgxf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
3011b5d61b8Smrg                    int x, int y)
3021b5d61b8Smrg{
3031b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
3041b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
3051b5d61b8Smrg                                               xf86CursorScreenKey);
3061b5d61b8Smrg    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
3071b5d61b8Smrg
3081b5d61b8Smrg    if (pCurs == NullCursor) {  /* means we're supposed to remove the cursor */
3091b5d61b8Smrg        if (ScreenPriv->SWCursor ||
3101b5d61b8Smrg            !(GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer))
3111b5d61b8Smrg            (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, NullCursor, x,
3121b5d61b8Smrg                                                   y);
3131b5d61b8Smrg        else if (ScreenPriv->isUp) {
3141b5d61b8Smrg            xf86SetCursor(pScreen, NullCursor, x, y);
3151b5d61b8Smrg            ScreenPriv->isUp = FALSE;
3161b5d61b8Smrg        }
3171b5d61b8Smrg        if (ScreenPriv->CurrentCursor)
3181b5d61b8Smrg            FreeCursor(ScreenPriv->CurrentCursor, None);
3191b5d61b8Smrg        ScreenPriv->CurrentCursor = NullCursor;
3201b5d61b8Smrg        return;
3211b5d61b8Smrg    }
3221b5d61b8Smrg
3231b5d61b8Smrg    /* only update for VCP, otherwise we get cursor jumps when removing a
3241b5d61b8Smrg       sprite. The second cursor is never HW rendered anyway. */
3251b5d61b8Smrg    if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
3261b5d61b8Smrg        CursorPtr cursor = RefCursor(pCurs);
3271b5d61b8Smrg        if (ScreenPriv->CurrentCursor)
3281b5d61b8Smrg            FreeCursor(ScreenPriv->CurrentCursor, None);
3291b5d61b8Smrg        ScreenPriv->CurrentCursor = cursor;
3301b5d61b8Smrg        ScreenPriv->x = x;
3311b5d61b8Smrg        ScreenPriv->y = y;
3321b5d61b8Smrg        ScreenPriv->CursorToRestore = NULL;
3331b5d61b8Smrg        ScreenPriv->HotX = cursor->bits->xhot;
3341b5d61b8Smrg        ScreenPriv->HotY = cursor->bits->yhot;
3351b5d61b8Smrg
3361b5d61b8Smrg        if (!infoPtr->pScrn->vtSema) {
3375a7dfde8Smrg            cursor = RefCursor(cursor);
3385a7dfde8Smrg            if (ScreenPriv->SavedCursor)
3395a7dfde8Smrg                FreeCursor(ScreenPriv->SavedCursor, None);
3401b5d61b8Smrg            ScreenPriv->SavedCursor = cursor;
3411b5d61b8Smrg            return;
3421b5d61b8Smrg        }
3431b5d61b8Smrg
3441b5d61b8Smrg        if (infoPtr->pScrn->vtSema &&
3451b5d61b8Smrg            (ScreenPriv->ForceHWCursorCount ||
3461b5d61b8Smrg             xf86CheckHWCursor(pScreen, cursor, infoPtr))) {
3471b5d61b8Smrg
3481b5d61b8Smrg            if (ScreenPriv->SWCursor)   /* remove the SW cursor */
3491b5d61b8Smrg                (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
3501b5d61b8Smrg                                                       NullCursor, x, y);
3511b5d61b8Smrg
3521b5d61b8Smrg            if (xf86SetCursor(pScreen, cursor, x, y)) {
3531b5d61b8Smrg                ScreenPriv->SWCursor = FALSE;
3541b5d61b8Smrg                ScreenPriv->isUp = TRUE;
3551b5d61b8Smrg
3561b5d61b8Smrg                miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse);
3571b5d61b8Smrg                return;
3581b5d61b8Smrg            }
3591b5d61b8Smrg        }
3601b5d61b8Smrg
3611b5d61b8Smrg        miPointerSetWaitForUpdate(pScreen, TRUE);
3621b5d61b8Smrg
3631b5d61b8Smrg        if (ScreenPriv->isUp) {
3641b5d61b8Smrg            /* Remove the HW cursor, or make it transparent */
3651b5d61b8Smrg            if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
3661b5d61b8Smrg                xf86SetTransparentCursor(pScreen);
3671b5d61b8Smrg            }
3681b5d61b8Smrg            else {
3691b5d61b8Smrg                xf86SetCursor(pScreen, NullCursor, x, y);
3701b5d61b8Smrg                ScreenPriv->isUp = FALSE;
3711b5d61b8Smrg            }
3721b5d61b8Smrg        }
3731b5d61b8Smrg
3741b5d61b8Smrg        if (!ScreenPriv->SWCursor)
3751b5d61b8Smrg            ScreenPriv->SWCursor = TRUE;
3761b5d61b8Smrg
3771b5d61b8Smrg    }
3781b5d61b8Smrg
3791b5d61b8Smrg    if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
3801b5d61b8Smrg        pCurs = NullCursor;
3811b5d61b8Smrg
3821b5d61b8Smrg    (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCurs, x, y);
3831b5d61b8Smrg}
3841b5d61b8Smrg
3851b5d61b8Smrg/* Re-set the current cursor. This will switch between hardware and software
3861b5d61b8Smrg * cursor depending on whether hardware cursor is currently supported
3871b5d61b8Smrg * according to the driver.
3881b5d61b8Smrg */
3891b5d61b8Smrgvoid
3901b5d61b8Smrgxf86CursorResetCursor(ScreenPtr pScreen)
3911b5d61b8Smrg{
3921b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv;
3931b5d61b8Smrg
3941b5d61b8Smrg    if (!inputInfo.pointer)
3951b5d61b8Smrg        return;
3961b5d61b8Smrg
3971b5d61b8Smrg    if (!dixPrivateKeyRegistered(xf86CursorScreenKey))
3981b5d61b8Smrg        return;
3991b5d61b8Smrg
4001b5d61b8Smrg    ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
4011b5d61b8Smrg                                                        xf86CursorScreenKey);
4021b5d61b8Smrg    if (!ScreenPriv)
4031b5d61b8Smrg        return;
4041b5d61b8Smrg
4051b5d61b8Smrg    xf86CursorSetCursor(inputInfo.pointer, pScreen, ScreenPriv->CurrentCursor,
4061b5d61b8Smrg                        ScreenPriv->x, ScreenPriv->y);
4071b5d61b8Smrg}
4081b5d61b8Smrg
4091b5d61b8Smrgstatic void
4101b5d61b8Smrgxf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
4111b5d61b8Smrg{
4121b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
4131b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
4141b5d61b8Smrg                                               xf86CursorScreenKey);
4151b5d61b8Smrg
4161b5d61b8Smrg    /* only update coordinate state for first sprite, otherwise we get jumps
4171b5d61b8Smrg       when removing a sprite. The second sprite is never HW rendered anyway */
4181b5d61b8Smrg    if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
4191b5d61b8Smrg        ScreenPriv->x = x;
4201b5d61b8Smrg        ScreenPriv->y = y;
4211b5d61b8Smrg
4221b5d61b8Smrg        if (ScreenPriv->CursorToRestore)
4231b5d61b8Smrg            xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x,
4241b5d61b8Smrg                                y);
4251b5d61b8Smrg        else if (ScreenPriv->SWCursor)
4261b5d61b8Smrg            (*ScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
4271b5d61b8Smrg        else if (ScreenPriv->isUp)
4281b5d61b8Smrg            xf86MoveCursor(pScreen, x, y);
4291b5d61b8Smrg    }
4301b5d61b8Smrg    else
4311b5d61b8Smrg        (*ScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
4321b5d61b8Smrg}
4331b5d61b8Smrg
4341b5d61b8Smrgvoid
4351b5d61b8Smrgxf86ForceHWCursor(ScreenPtr pScreen, Bool on)
4361b5d61b8Smrg{
4371b5d61b8Smrg    DeviceIntPtr pDev = inputInfo.pointer;
4381b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
4391b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
4401b5d61b8Smrg                                               xf86CursorScreenKey);
4411b5d61b8Smrg
4421b5d61b8Smrg    if (on) {
4431b5d61b8Smrg        if (ScreenPriv->ForceHWCursorCount++ == 0) {
4441b5d61b8Smrg            if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor) {
4451b5d61b8Smrg                ScreenPriv->HWCursorForced = TRUE;
4461b5d61b8Smrg                xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CurrentCursor,
4471b5d61b8Smrg                                    ScreenPriv->x, ScreenPriv->y);
4481b5d61b8Smrg            }
4491b5d61b8Smrg            else
4501b5d61b8Smrg                ScreenPriv->HWCursorForced = FALSE;
4511b5d61b8Smrg        }
4521b5d61b8Smrg    }
4531b5d61b8Smrg    else {
4541b5d61b8Smrg        if (--ScreenPriv->ForceHWCursorCount == 0) {
4551b5d61b8Smrg            if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
4561b5d61b8Smrg                xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CurrentCursor,
4571b5d61b8Smrg                                    ScreenPriv->x, ScreenPriv->y);
4581b5d61b8Smrg        }
4591b5d61b8Smrg    }
4601b5d61b8Smrg}
4611b5d61b8Smrg
4621b5d61b8SmrgCursorPtr
4631b5d61b8Smrgxf86CurrentCursor(ScreenPtr pScreen)
4641b5d61b8Smrg{
4651b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv;
4661b5d61b8Smrg
467ed6184dfSmrg    if (pScreen->is_output_secondary)
468ed6184dfSmrg        pScreen = pScreen->current_primary;
4691b5d61b8Smrg
4701b5d61b8Smrg    ScreenPriv = dixLookupPrivate(&pScreen->devPrivates, xf86CursorScreenKey);
4711b5d61b8Smrg    return ScreenPriv->CurrentCursor;
4721b5d61b8Smrg}
4731b5d61b8Smrg
4741b5d61b8Smrgxf86CursorInfoPtr
4751b5d61b8Smrgxf86CreateCursorInfoRec(void)
4761b5d61b8Smrg{
4771b5d61b8Smrg    return calloc(1, sizeof(xf86CursorInfoRec));
4781b5d61b8Smrg}
4791b5d61b8Smrg
4801b5d61b8Smrgvoid
4811b5d61b8Smrgxf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
4821b5d61b8Smrg{
4831b5d61b8Smrg    free(infoPtr);
4841b5d61b8Smrg}
4851b5d61b8Smrg
4861b5d61b8Smrg/**
4871b5d61b8Smrg * New cursor has been created. Do your initalizations here.
4881b5d61b8Smrg */
4891b5d61b8Smrgstatic Bool
4901b5d61b8Smrgxf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
4911b5d61b8Smrg{
4921b5d61b8Smrg    int ret;
4931b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
4941b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
4951b5d61b8Smrg                                               xf86CursorScreenKey);
4961b5d61b8Smrg
4971b5d61b8Smrg    /* Init SW cursor */
4981b5d61b8Smrg    ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize) (pDev, pScreen);
4991b5d61b8Smrg
5001b5d61b8Smrg    return ret;
5011b5d61b8Smrg}
5021b5d61b8Smrg
5031b5d61b8Smrg/**
5041b5d61b8Smrg * Cursor has been removed. Clean up after yourself.
5051b5d61b8Smrg */
5061b5d61b8Smrgstatic void
5071b5d61b8Smrgxf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
5081b5d61b8Smrg{
5091b5d61b8Smrg    xf86CursorScreenPtr ScreenPriv =
5101b5d61b8Smrg        (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
5111b5d61b8Smrg                                               xf86CursorScreenKey);
5121b5d61b8Smrg
5131b5d61b8Smrg    /* Clean up SW cursor */
5141b5d61b8Smrg    (*ScreenPriv->spriteFuncs->DeviceCursorCleanup) (pDev, pScreen);
5151b5d61b8Smrg}
516