"Fossies" - the Fresh Open Source Software Archive

Member "xorg-server-1.20.5/render/animcur.c" (30 May 2019, 11401 Bytes) of package /linux/misc/xorg-server-1.20.5.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "animcur.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *
    3  * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
    4  *
    5  * Permission to use, copy, modify, distribute, and sell this software and its
    6  * documentation for any purpose is hereby granted without fee, provided that
    7  * the above copyright notice appear in all copies and that both that
    8  * copyright notice and this permission notice appear in supporting
    9  * documentation, and that the name of Keith Packard not be used in
   10  * advertising or publicity pertaining to distribution of the software without
   11  * specific, written prior permission.  Keith Packard makes no
   12  * representations about the suitability of this software for any purpose.  It
   13  * is provided "as is" without express or implied warranty.
   14  *
   15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
   16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
   17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
   18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
   19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
   20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   21  * PERFORMANCE OF THIS SOFTWARE.
   22  */
   23 
   24 /*
   25  * Animated cursors for X.  Not specific to Render in any way, but
   26  * stuck there because Render has the other cool cursor extension.
   27  * Besides, everyone has Render.
   28  *
   29  * Implemented as a simple layer over the core cursor code; it
   30  * creates composite cursors out of a set of static cursors and
   31  * delta times between each image.
   32  */
   33 
   34 #ifdef HAVE_DIX_CONFIG_H
   35 #include <dix-config.h>
   36 #endif
   37 
   38 #include <X11/X.h>
   39 #include <X11/Xmd.h>
   40 #include "servermd.h"
   41 #include "scrnintstr.h"
   42 #include "dixstruct.h"
   43 #include "cursorstr.h"
   44 #include "dixfontstr.h"
   45 #include "opaque.h"
   46 #include "picturestr.h"
   47 #include "inputstr.h"
   48 #include "xace.h"
   49 
   50 typedef struct _AnimCurElt {
   51     CursorPtr pCursor;          /* cursor to show */
   52     CARD32 delay;               /* in ms */
   53 } AnimCurElt;
   54 
   55 typedef struct _AnimCur {
   56     int nelt;                   /* number of elements in the elts array */
   57     AnimCurElt *elts;           /* actually allocated right after the structure */
   58     OsTimerPtr timer;
   59 } AnimCurRec, *AnimCurPtr;
   60 
   61 typedef struct _AnimScrPriv {
   62     CloseScreenProcPtr CloseScreen;
   63     CursorLimitsProcPtr CursorLimits;
   64     DisplayCursorProcPtr DisplayCursor;
   65     SetCursorPositionProcPtr SetCursorPosition;
   66     RealizeCursorProcPtr RealizeCursor;
   67     UnrealizeCursorProcPtr UnrealizeCursor;
   68     RecolorCursorProcPtr RecolorCursor;
   69 } AnimCurScreenRec, *AnimCurScreenPtr;
   70 
   71 static unsigned char empty[4];
   72 
   73 static CursorBits animCursorBits = {
   74     empty, empty, 2, 1, 1, 0, 0, 1
   75 };
   76 
   77 static DevPrivateKeyRec AnimCurScreenPrivateKeyRec;
   78 
   79 #define IsAnimCur(c)        ((c) && ((c)->bits == &animCursorBits))
   80 #define GetAnimCur(c)       ((AnimCurPtr) ((((char *)(c) + CURSOR_REC_SIZE))))
   81 #define GetAnimCurScreen(s) ((AnimCurScreenPtr)dixLookupPrivate(&(s)->devPrivates, &AnimCurScreenPrivateKeyRec))
   82 
   83 #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
   84 #define Unwrap(as,s,elt)    ((s)->elt = (as)->elt)
   85 
   86 static Bool
   87 AnimCurCloseScreen(ScreenPtr pScreen)
   88 {
   89     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
   90     Bool ret;
   91 
   92     Unwrap(as, pScreen, CloseScreen);
   93 
   94     Unwrap(as, pScreen, CursorLimits);
   95     Unwrap(as, pScreen, DisplayCursor);
   96     Unwrap(as, pScreen, SetCursorPosition);
   97     Unwrap(as, pScreen, RealizeCursor);
   98     Unwrap(as, pScreen, UnrealizeCursor);
   99     Unwrap(as, pScreen, RecolorCursor);
  100     ret = (*pScreen->CloseScreen) (pScreen);
  101     return ret;
  102 }
  103 
  104 static void
  105 AnimCurCursorLimits(DeviceIntPtr pDev,
  106                     ScreenPtr pScreen,
  107                     CursorPtr pCursor, BoxPtr pHotBox, BoxPtr pTopLeftBox)
  108 {
  109     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  110 
  111     Unwrap(as, pScreen, CursorLimits);
  112     if (IsAnimCur(pCursor)) {
  113         AnimCurPtr ac = GetAnimCur(pCursor);
  114 
  115         (*pScreen->CursorLimits) (pDev, pScreen, ac->elts[0].pCursor,
  116                                   pHotBox, pTopLeftBox);
  117     }
  118     else {
  119         (*pScreen->CursorLimits) (pDev, pScreen, pCursor, pHotBox, pTopLeftBox);
  120     }
  121     Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
  122 }
  123 
  124 /*
  125  * The cursor animation timer has expired, go display any relevant cursor changes
  126  * and compute a new timeout value
  127  */
  128 
  129 static CARD32
  130 AnimCurTimerNotify(OsTimerPtr timer, CARD32 now, void *arg)
  131 {
  132     DeviceIntPtr dev = arg;
  133     ScreenPtr pScreen = dev->spriteInfo->anim.pScreen;
  134     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  135 
  136     AnimCurPtr ac = GetAnimCur(dev->spriteInfo->sprite->current);
  137     int elt = (dev->spriteInfo->anim.elt + 1) % ac->nelt;
  138     DisplayCursorProcPtr DisplayCursor = pScreen->DisplayCursor;
  139 
  140     /*
  141      * Not a simple Unwrap/Wrap as this isn't called along the DisplayCursor
  142      * wrapper chain.
  143      */
  144     pScreen->DisplayCursor = as->DisplayCursor;
  145     (void) (*pScreen->DisplayCursor) (dev, pScreen, ac->elts[elt].pCursor);
  146     as->DisplayCursor = pScreen->DisplayCursor;
  147     pScreen->DisplayCursor = DisplayCursor;
  148 
  149     dev->spriteInfo->anim.elt = elt;
  150     dev->spriteInfo->anim.pCursor = ac->elts[elt].pCursor;
  151 
  152     return ac->elts[elt].delay;
  153 }
  154 
  155 static void
  156 AnimCurCancelTimer(DeviceIntPtr pDev)
  157 {
  158     CursorPtr cur = pDev->spriteInfo->sprite ?
  159                     pDev->spriteInfo->sprite->current : NULL;
  160 
  161     if (IsAnimCur(cur))
  162         TimerCancel(GetAnimCur(cur)->timer);
  163 }
  164 
  165 static Bool
  166 AnimCurDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
  167 {
  168     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  169     Bool ret = TRUE;
  170 
  171     if (IsFloating(pDev))
  172         return FALSE;
  173 
  174     Unwrap(as, pScreen, DisplayCursor);
  175     if (IsAnimCur(pCursor)) {
  176         if (pCursor != pDev->spriteInfo->sprite->current) {
  177             AnimCurPtr ac = GetAnimCur(pCursor);
  178 
  179             AnimCurCancelTimer(pDev);
  180             ret = (*pScreen->DisplayCursor) (pDev, pScreen,
  181                                              ac->elts[0].pCursor);
  182 
  183             if (ret) {
  184                 pDev->spriteInfo->anim.elt = 0;
  185                 pDev->spriteInfo->anim.pCursor = pCursor;
  186                 pDev->spriteInfo->anim.pScreen = pScreen;
  187 
  188                 ac->timer = TimerSet(ac->timer, 0, ac->elts[0].delay,
  189                                      AnimCurTimerNotify, pDev);
  190             }
  191         }
  192     }
  193     else {
  194         AnimCurCancelTimer(pDev);
  195         pDev->spriteInfo->anim.pCursor = 0;
  196         pDev->spriteInfo->anim.pScreen = 0;
  197         ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
  198     }
  199     Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
  200     return ret;
  201 }
  202 
  203 static Bool
  204 AnimCurSetCursorPosition(DeviceIntPtr pDev,
  205                          ScreenPtr pScreen, int x, int y, Bool generateEvent)
  206 {
  207     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  208     Bool ret;
  209 
  210     Unwrap(as, pScreen, SetCursorPosition);
  211     if (pDev->spriteInfo->anim.pCursor) {
  212         pDev->spriteInfo->anim.pScreen = pScreen;
  213     }
  214     ret = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
  215     Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
  216     return ret;
  217 }
  218 
  219 static Bool
  220 AnimCurRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
  221 {
  222     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  223     Bool ret;
  224 
  225     Unwrap(as, pScreen, RealizeCursor);
  226     if (IsAnimCur(pCursor))
  227         ret = TRUE;
  228     else
  229         ret = (*pScreen->RealizeCursor) (pDev, pScreen, pCursor);
  230     Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor);
  231     return ret;
  232 }
  233 
  234 static Bool
  235 AnimCurUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
  236 {
  237     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  238     Bool ret;
  239 
  240     Unwrap(as, pScreen, UnrealizeCursor);
  241     if (IsAnimCur(pCursor)) {
  242         AnimCurPtr ac = GetAnimCur(pCursor);
  243         int i;
  244 
  245         if (pScreen->myNum == 0)
  246             for (i = 0; i < ac->nelt; i++)
  247                 FreeCursor(ac->elts[i].pCursor, 0);
  248         ret = TRUE;
  249     }
  250     else
  251         ret = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
  252     Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
  253     return ret;
  254 }
  255 
  256 static void
  257 AnimCurRecolorCursor(DeviceIntPtr pDev,
  258                      ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
  259 {
  260     AnimCurScreenPtr as = GetAnimCurScreen(pScreen);
  261 
  262     Unwrap(as, pScreen, RecolorCursor);
  263     if (IsAnimCur(pCursor)) {
  264         AnimCurPtr ac = GetAnimCur(pCursor);
  265         int i;
  266 
  267         for (i = 0; i < ac->nelt; i++)
  268             (*pScreen->RecolorCursor) (pDev, pScreen, ac->elts[i].pCursor,
  269                                        displayed &&
  270                                        pDev->spriteInfo->anim.elt == i);
  271     }
  272     else
  273         (*pScreen->RecolorCursor) (pDev, pScreen, pCursor, displayed);
  274     Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor);
  275 }
  276 
  277 Bool
  278 AnimCurInit(ScreenPtr pScreen)
  279 {
  280     AnimCurScreenPtr as;
  281 
  282     if (!dixRegisterPrivateKey(&AnimCurScreenPrivateKeyRec, PRIVATE_SCREEN,
  283                                sizeof(AnimCurScreenRec)))
  284         return FALSE;
  285 
  286     as = GetAnimCurScreen(pScreen);
  287 
  288     Wrap(as, pScreen, CloseScreen, AnimCurCloseScreen);
  289 
  290     Wrap(as, pScreen, CursorLimits, AnimCurCursorLimits);
  291     Wrap(as, pScreen, DisplayCursor, AnimCurDisplayCursor);
  292     Wrap(as, pScreen, SetCursorPosition, AnimCurSetCursorPosition);
  293     Wrap(as, pScreen, RealizeCursor, AnimCurRealizeCursor);
  294     Wrap(as, pScreen, UnrealizeCursor, AnimCurUnrealizeCursor);
  295     Wrap(as, pScreen, RecolorCursor, AnimCurRecolorCursor);
  296     return TRUE;
  297 }
  298 
  299 int
  300 AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
  301                  CursorPtr *ppCursor, ClientPtr client, XID cid)
  302 {
  303     CursorPtr pCursor;
  304     int rc = BadAlloc, i;
  305     AnimCurPtr ac;
  306 
  307     for (i = 0; i < screenInfo.numScreens; i++)
  308         if (!GetAnimCurScreen(screenInfo.screens[i]))
  309             return BadImplementation;
  310 
  311     for (i = 0; i < ncursor; i++)
  312         if (IsAnimCur(cursors[i]))
  313             return BadMatch;
  314 
  315     pCursor = (CursorPtr) calloc(CURSOR_REC_SIZE +
  316                                  sizeof(AnimCurRec) +
  317                                  ncursor * sizeof(AnimCurElt), 1);
  318     if (!pCursor)
  319         return rc;
  320     dixInitPrivates(pCursor, pCursor + 1, PRIVATE_CURSOR);
  321     pCursor->bits = &animCursorBits;
  322     pCursor->refcnt = 1;
  323 
  324     pCursor->foreRed = cursors[0]->foreRed;
  325     pCursor->foreGreen = cursors[0]->foreGreen;
  326     pCursor->foreBlue = cursors[0]->foreBlue;
  327 
  328     pCursor->backRed = cursors[0]->backRed;
  329     pCursor->backGreen = cursors[0]->backGreen;
  330     pCursor->backBlue = cursors[0]->backBlue;
  331 
  332     pCursor->id = cid;
  333 
  334     ac = GetAnimCur(pCursor);
  335     ac->timer = TimerSet(NULL, 0, 0, AnimCurTimerNotify, NULL);
  336 
  337     /* security creation/labeling check */
  338     if (ac->timer)
  339         rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, pCursor,
  340                       RT_NONE, NULL, DixCreateAccess);
  341 
  342     if (rc != Success) {
  343         TimerFree(ac->timer);
  344         dixFiniPrivates(pCursor, PRIVATE_CURSOR);
  345         free(pCursor);
  346         return rc;
  347     }
  348 
  349     /*
  350      * Fill in the AnimCurRec
  351      */
  352     animCursorBits.refcnt++;
  353     ac->nelt = ncursor;
  354     ac->elts = (AnimCurElt *) (ac + 1);
  355 
  356     for (i = 0; i < ncursor; i++) {
  357         ac->elts[i].pCursor = RefCursor(cursors[i]);
  358         ac->elts[i].delay = deltas[i];
  359     }
  360 
  361     *ppCursor = pCursor;
  362     return Success;
  363 }