xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xf86CursorRD.c (17163B)


      1 
      2 #ifdef HAVE_XORG_CONFIG_H
      3 #include <xorg-config.h>
      4 #endif
      5 
      6 #include "xf86.h"
      7 #include "xf86CursorPriv.h"
      8 #include "colormapst.h"
      9 #include "cursorstr.h"
     10 
     11 /* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
     12  * MPX.
     13  * inputInfo is needed to pass the core pointer as the default argument into
     14  * the cursor functions.
     15  *
     16  * Externing inputInfo is not the nice way to do it but it works.
     17  */
     18 #include "inputstr.h"
     19 
     20 DevPrivateKeyRec xf86CursorScreenKeyRec;
     21 
     22 /* sprite functions */
     23 
     24 static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
     25 static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
     26 static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
     27 static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
     28 static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
     29 static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
     30 
     31 static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
     32     xf86CursorRealizeCursor,
     33     xf86CursorUnrealizeCursor,
     34     xf86CursorSetCursor,
     35     xf86CursorMoveCursor,
     36     xf86DeviceCursorInitialize,
     37     xf86DeviceCursorCleanup
     38 };
     39 
     40 /* Screen functions */
     41 
     42 static void xf86CursorInstallColormap(ColormapPtr);
     43 static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr,
     44                                     Bool);
     45 static Bool xf86CursorCloseScreen(ScreenPtr);
     46 static void xf86CursorQueryBestSize(int, unsigned short *, unsigned short *,
     47                                     ScreenPtr);
     48 
     49 /* ScrnInfoRec functions */
     50 
     51 static void xf86CursorEnableDisableFBAccess(ScrnInfoPtr, Bool);
     52 static Bool xf86CursorSwitchMode(ScrnInfoPtr, DisplayModePtr);
     53 
     54 Bool
     55 xf86InitCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
     56 {
     57     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
     58     xf86CursorScreenPtr ScreenPriv;
     59     miPointerScreenPtr PointPriv;
     60 
     61     if (!xf86InitHardwareCursor(pScreen, infoPtr))
     62         return FALSE;
     63 
     64     if (!dixRegisterPrivateKey(&xf86CursorScreenKeyRec, PRIVATE_SCREEN, 0))
     65         return FALSE;
     66 
     67     ScreenPriv = calloc(1, sizeof(xf86CursorScreenRec));
     68     if (!ScreenPriv)
     69         return FALSE;
     70 
     71     dixSetPrivate(&pScreen->devPrivates, xf86CursorScreenKey, ScreenPriv);
     72 
     73     ScreenPriv->SWCursor = TRUE;
     74     ScreenPriv->isUp = FALSE;
     75     ScreenPriv->CurrentCursor = NULL;
     76     ScreenPriv->CursorInfoPtr = infoPtr;
     77     ScreenPriv->PalettedCursor = FALSE;
     78     ScreenPriv->pInstalledMap = NULL;
     79 
     80     ScreenPriv->CloseScreen = pScreen->CloseScreen;
     81     pScreen->CloseScreen = xf86CursorCloseScreen;
     82     ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
     83     pScreen->QueryBestSize = xf86CursorQueryBestSize;
     84     ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
     85     pScreen->RecolorCursor = xf86CursorRecolorCursor;
     86 
     87     if ((infoPtr->pScrn->bitsPerPixel == 8) &&
     88         !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
     89         ScreenPriv->InstallColormap = pScreen->InstallColormap;
     90         pScreen->InstallColormap = xf86CursorInstallColormap;
     91         ScreenPriv->PalettedCursor = TRUE;
     92     }
     93 
     94     PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
     95 
     96     ScreenPriv->showTransparent = PointPriv->showTransparent;
     97     if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
     98         PointPriv->showTransparent = TRUE;
     99     else
    100         PointPriv->showTransparent = FALSE;
    101     ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
    102     PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
    103 
    104     ScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
    105     ScreenPriv->SwitchMode = pScrn->SwitchMode;
    106 
    107     ScreenPriv->ForceHWCursorCount = 0;
    108     ScreenPriv->HWCursorForced = FALSE;
    109 
    110     pScrn->EnableDisableFBAccess = xf86CursorEnableDisableFBAccess;
    111     if (pScrn->SwitchMode)
    112         pScrn->SwitchMode = xf86CursorSwitchMode;
    113 
    114     return TRUE;
    115 }
    116 
    117 /***** Screen functions *****/
    118 
    119 static Bool
    120 xf86CursorCloseScreen(ScreenPtr pScreen)
    121 {
    122     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
    123     miPointerScreenPtr PointPriv =
    124         (miPointerScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    125                                               miPointerScreenKey);
    126     xf86CursorScreenPtr ScreenPriv =
    127         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    128                                                xf86CursorScreenKey);
    129 
    130     if (ScreenPriv->isUp && pScrn->vtSema)
    131         xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
    132 
    133     if (ScreenPriv->CurrentCursor)
    134         FreeCursor(ScreenPriv->CurrentCursor, None);
    135 
    136     pScreen->CloseScreen = ScreenPriv->CloseScreen;
    137     pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
    138     pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
    139     if (ScreenPriv->InstallColormap)
    140         pScreen->InstallColormap = ScreenPriv->InstallColormap;
    141 
    142     PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
    143     PointPriv->showTransparent = ScreenPriv->showTransparent;
    144 
    145     pScrn->EnableDisableFBAccess = ScreenPriv->EnableDisableFBAccess;
    146     pScrn->SwitchMode = ScreenPriv->SwitchMode;
    147 
    148     free(ScreenPriv->transparentData);
    149     free(ScreenPriv);
    150 
    151     return (*pScreen->CloseScreen) (pScreen);
    152 }
    153 
    154 static void
    155 xf86CursorQueryBestSize(int class,
    156                         unsigned short *width,
    157                         unsigned short *height, ScreenPtr pScreen)
    158 {
    159     xf86CursorScreenPtr ScreenPriv =
    160         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    161                                                xf86CursorScreenKey);
    162 
    163     if (class == CursorShape) {
    164         if (*width > ScreenPriv->CursorInfoPtr->MaxWidth)
    165             *width = ScreenPriv->CursorInfoPtr->MaxWidth;
    166         if (*height > ScreenPriv->CursorInfoPtr->MaxHeight)
    167             *height = ScreenPriv->CursorInfoPtr->MaxHeight;
    168     }
    169     else
    170         (*ScreenPriv->QueryBestSize) (class, width, height, pScreen);
    171 }
    172 
    173 static void
    174 xf86CursorInstallColormap(ColormapPtr pMap)
    175 {
    176     xf86CursorScreenPtr ScreenPriv =
    177         (xf86CursorScreenPtr) dixLookupPrivate(&pMap->pScreen->devPrivates,
    178                                                xf86CursorScreenKey);
    179 
    180     ScreenPriv->pInstalledMap = pMap;
    181 
    182     (*ScreenPriv->InstallColormap) (pMap);
    183 }
    184 
    185 static void
    186 xf86CursorRecolorCursor(DeviceIntPtr pDev,
    187                         ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
    188 {
    189     xf86CursorScreenPtr ScreenPriv =
    190         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    191                                                xf86CursorScreenKey);
    192 
    193     if (!displayed)
    194         return;
    195 
    196     if (ScreenPriv->SWCursor)
    197         (*ScreenPriv->RecolorCursor) (pDev, pScreen, pCurs, displayed);
    198     else
    199         xf86RecolorCursor(pScreen, pCurs, displayed);
    200 }
    201 
    202 /***** ScrnInfoRec functions *********/
    203 
    204 static void
    205 xf86CursorEnableDisableFBAccess(ScrnInfoPtr pScrn, Bool enable)
    206 {
    207     DeviceIntPtr pDev = inputInfo.pointer;
    208 
    209     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
    210     xf86CursorScreenPtr ScreenPriv =
    211         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    212                                                xf86CursorScreenKey);
    213 
    214     if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
    215         CursorPtr currentCursor = RefCursor(ScreenPriv->CurrentCursor);
    216 
    217         xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
    218                             ScreenPriv->y);
    219         ScreenPriv->isUp = FALSE;
    220         ScreenPriv->SWCursor = TRUE;
    221         ScreenPriv->SavedCursor = currentCursor;
    222     }
    223 
    224     if (ScreenPriv->EnableDisableFBAccess)
    225         (*ScreenPriv->EnableDisableFBAccess) (pScrn, enable);
    226 
    227     if (enable && ScreenPriv->SavedCursor) {
    228         /*
    229          * Re-set current cursor so drivers can react to FB access having been
    230          * temporarily disabled.
    231          */
    232         xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
    233                             ScreenPriv->x, ScreenPriv->y);
    234         UnrefCursor(ScreenPriv->SavedCursor);
    235         ScreenPriv->SavedCursor = NULL;
    236     }
    237 }
    238 
    239 static Bool
    240 xf86CursorSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
    241 {
    242     Bool ret;
    243     ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
    244     xf86CursorScreenPtr ScreenPriv =
    245         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    246                                                xf86CursorScreenKey);
    247 
    248     if (ScreenPriv->isUp) {
    249         xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
    250         ScreenPriv->isUp = FALSE;
    251     }
    252 
    253     ret = (*ScreenPriv->SwitchMode) (pScrn, mode);
    254 
    255     /*
    256      * Cannot restore cursor here because the new frame[XY][01] haven't been
    257      * calculated yet.  However, because the hardware cursor was removed above,
    258      * ensure the cursor is repainted by miPointerWarpCursor().
    259      */
    260     ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
    261     miPointerSetWaitForUpdate(pScreen, FALSE);  /* Force cursor repaint */
    262 
    263     return ret;
    264 }
    265 
    266 /****** miPointerSpriteFunctions *******/
    267 
    268 static Bool
    269 xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
    270 {
    271     xf86CursorScreenPtr ScreenPriv =
    272         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    273                                                xf86CursorScreenKey);
    274 
    275     if (CursorRefCount(pCurs) <= 1)
    276         dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
    277                             NULL);
    278 
    279     return (*ScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCurs);
    280 }
    281 
    282 static Bool
    283 xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
    284 {
    285     xf86CursorScreenPtr ScreenPriv =
    286         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    287                                                xf86CursorScreenKey);
    288 
    289     if (CursorRefCount(pCurs) <= 1) {
    290         free(dixLookupScreenPrivate
    291              (&pCurs->devPrivates, CursorScreenKey, pScreen));
    292         dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
    293                             NULL);
    294     }
    295 
    296     return (*ScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCurs);
    297 }
    298 
    299 static void
    300 xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
    301                     int x, int y)
    302 {
    303     xf86CursorScreenPtr ScreenPriv =
    304         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    305                                                xf86CursorScreenKey);
    306     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
    307 
    308     if (pCurs == NullCursor) {  /* means we're supposed to remove the cursor */
    309         if (ScreenPriv->SWCursor ||
    310             !(GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer))
    311             (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, NullCursor, x,
    312                                                    y);
    313         else if (ScreenPriv->isUp) {
    314             xf86SetCursor(pScreen, NullCursor, x, y);
    315             ScreenPriv->isUp = FALSE;
    316         }
    317         if (ScreenPriv->CurrentCursor)
    318             FreeCursor(ScreenPriv->CurrentCursor, None);
    319         ScreenPriv->CurrentCursor = NullCursor;
    320         return;
    321     }
    322 
    323     /* only update for VCP, otherwise we get cursor jumps when removing a
    324        sprite. The second cursor is never HW rendered anyway. */
    325     if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
    326         CursorPtr cursor = RefCursor(pCurs);
    327         if (ScreenPriv->CurrentCursor)
    328             FreeCursor(ScreenPriv->CurrentCursor, None);
    329         ScreenPriv->CurrentCursor = cursor;
    330         ScreenPriv->x = x;
    331         ScreenPriv->y = y;
    332         ScreenPriv->CursorToRestore = NULL;
    333         ScreenPriv->HotX = cursor->bits->xhot;
    334         ScreenPriv->HotY = cursor->bits->yhot;
    335 
    336         if (!infoPtr->pScrn->vtSema) {
    337             cursor = RefCursor(cursor);
    338             if (ScreenPriv->SavedCursor)
    339                 FreeCursor(ScreenPriv->SavedCursor, None);
    340             ScreenPriv->SavedCursor = cursor;
    341             return;
    342         }
    343 
    344         if (infoPtr->pScrn->vtSema &&
    345             (ScreenPriv->ForceHWCursorCount ||
    346              xf86CheckHWCursor(pScreen, cursor, infoPtr))) {
    347 
    348             if (ScreenPriv->SWCursor)   /* remove the SW cursor */
    349                 (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
    350                                                        NullCursor, x, y);
    351 
    352             if (xf86SetCursor(pScreen, cursor, x, y)) {
    353                 ScreenPriv->SWCursor = FALSE;
    354                 ScreenPriv->isUp = TRUE;
    355 
    356                 miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse);
    357                 return;
    358             }
    359         }
    360 
    361         miPointerSetWaitForUpdate(pScreen, TRUE);
    362 
    363         if (ScreenPriv->isUp) {
    364             /* Remove the HW cursor, or make it transparent */
    365             if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
    366                 xf86SetTransparentCursor(pScreen);
    367             }
    368             else {
    369                 xf86SetCursor(pScreen, NullCursor, x, y);
    370                 ScreenPriv->isUp = FALSE;
    371             }
    372         }
    373 
    374         if (!ScreenPriv->SWCursor)
    375             ScreenPriv->SWCursor = TRUE;
    376 
    377     }
    378 
    379     if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
    380         pCurs = NullCursor;
    381 
    382     (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCurs, x, y);
    383 }
    384 
    385 /* Re-set the current cursor. This will switch between hardware and software
    386  * cursor depending on whether hardware cursor is currently supported
    387  * according to the driver.
    388  */
    389 void
    390 xf86CursorResetCursor(ScreenPtr pScreen)
    391 {
    392     xf86CursorScreenPtr ScreenPriv;
    393 
    394     if (!inputInfo.pointer)
    395         return;
    396 
    397     if (!dixPrivateKeyRegistered(xf86CursorScreenKey))
    398         return;
    399 
    400     ScreenPriv = (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    401                                                         xf86CursorScreenKey);
    402     if (!ScreenPriv)
    403         return;
    404 
    405     xf86CursorSetCursor(inputInfo.pointer, pScreen, ScreenPriv->CurrentCursor,
    406                         ScreenPriv->x, ScreenPriv->y);
    407 }
    408 
    409 static void
    410 xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
    411 {
    412     xf86CursorScreenPtr ScreenPriv =
    413         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    414                                                xf86CursorScreenKey);
    415 
    416     /* only update coordinate state for first sprite, otherwise we get jumps
    417        when removing a sprite. The second sprite is never HW rendered anyway */
    418     if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
    419         ScreenPriv->x = x;
    420         ScreenPriv->y = y;
    421 
    422         if (ScreenPriv->CursorToRestore)
    423             xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x,
    424                                 y);
    425         else if (ScreenPriv->SWCursor)
    426             (*ScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
    427         else if (ScreenPriv->isUp)
    428             xf86MoveCursor(pScreen, x, y);
    429     }
    430     else
    431         (*ScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
    432 }
    433 
    434 void
    435 xf86ForceHWCursor(ScreenPtr pScreen, Bool on)
    436 {
    437     DeviceIntPtr pDev = inputInfo.pointer;
    438     xf86CursorScreenPtr ScreenPriv =
    439         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    440                                                xf86CursorScreenKey);
    441 
    442     if (on) {
    443         if (ScreenPriv->ForceHWCursorCount++ == 0) {
    444             if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor) {
    445                 ScreenPriv->HWCursorForced = TRUE;
    446                 xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CurrentCursor,
    447                                     ScreenPriv->x, ScreenPriv->y);
    448             }
    449             else
    450                 ScreenPriv->HWCursorForced = FALSE;
    451         }
    452     }
    453     else {
    454         if (--ScreenPriv->ForceHWCursorCount == 0) {
    455             if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
    456                 xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CurrentCursor,
    457                                     ScreenPriv->x, ScreenPriv->y);
    458         }
    459     }
    460 }
    461 
    462 CursorPtr
    463 xf86CurrentCursor(ScreenPtr pScreen)
    464 {
    465     xf86CursorScreenPtr ScreenPriv;
    466 
    467     if (pScreen->is_output_secondary)
    468         pScreen = pScreen->current_primary;
    469 
    470     ScreenPriv = dixLookupPrivate(&pScreen->devPrivates, xf86CursorScreenKey);
    471     return ScreenPriv->CurrentCursor;
    472 }
    473 
    474 xf86CursorInfoPtr
    475 xf86CreateCursorInfoRec(void)
    476 {
    477     return calloc(1, sizeof(xf86CursorInfoRec));
    478 }
    479 
    480 void
    481 xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
    482 {
    483     free(infoPtr);
    484 }
    485 
    486 /**
    487  * New cursor has been created. Do your initalizations here.
    488  */
    489 static Bool
    490 xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
    491 {
    492     int ret;
    493     xf86CursorScreenPtr ScreenPriv =
    494         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    495                                                xf86CursorScreenKey);
    496 
    497     /* Init SW cursor */
    498     ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize) (pDev, pScreen);
    499 
    500     return ret;
    501 }
    502 
    503 /**
    504  * Cursor has been removed. Clean up after yourself.
    505  */
    506 static void
    507 xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
    508 {
    509     xf86CursorScreenPtr ScreenPriv =
    510         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
    511                                                xf86CursorScreenKey);
    512 
    513     /* Clean up SW cursor */
    514     (*ScreenPriv->spriteFuncs->DeviceCursorCleanup) (pDev, pScreen);
    515 }