home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / mi / midispcur.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-26  |  15.8 KB  |  601 lines

  1. /*
  2.  * midispcur.c
  3.  *
  4.  * machine independent cursor display routines
  5.  */
  6.  
  7. /* $XConsortium: midispcur.c,v 5.11 91/04/26 21:45:56 keith Exp $ */
  8.  
  9. /*
  10. Copyright 1989 by the Massachusetts Institute of Technology
  11.  
  12. Permission to use, copy, modify, and distribute this software and its
  13. documentation for any purpose and without fee is hereby granted,
  14. provided that the above copyright notice appear in all copies and that
  15. both that copyright notice and this permission notice appear in
  16. supporting documentation, and that the name of M.I.T. not be used in
  17. advertising or publicity pertaining to distribution of the software
  18. without specific, written prior permission.  M.I.T. makes no
  19. representations about the suitability of this software for any
  20. purpose.  It is provided "as is" without express or implied warranty.
  21. */
  22.  
  23. #define NEED_EVENTS
  24. # include   "X.h"
  25. # include   "misc.h"
  26. # include   "input.h"
  27. # include   "cursorstr.h"
  28. # include   "windowstr.h"
  29. # include   "regionstr.h"
  30. # include   "dixstruct.h"
  31. # include   "scrnintstr.h"
  32. # include   "servermd.h"
  33. # include   "misprite.h"
  34. # include   "mipointer.h"
  35. # include   "gcstruct.h"
  36.  
  37. extern WindowPtr    *WindowTable;
  38.  
  39. /* per-screen private data */
  40.  
  41. static int    miDCScreenIndex;
  42. static unsigned long miDCGeneration = 0;
  43.  
  44. static Bool    miDCCloseScreen();
  45.  
  46. typedef struct {
  47.     GCPtr        pSourceGC, pMaskGC;
  48.     GCPtr        pSaveGC, pRestoreGC;
  49.     GCPtr        pMoveGC;
  50.     GCPtr        pPixSourceGC, pPixMaskGC;
  51.     Bool        (*CloseScreen)();
  52.     PixmapPtr        pSave, pTemp;
  53. } miDCScreenRec, *miDCScreenPtr;
  54.  
  55. /* per-cursor per-screen private data */
  56. typedef struct {
  57.     PixmapPtr        sourceBits;        /* source bits */
  58.     PixmapPtr        maskBits;        /* mask bits */
  59. } miDCCursorRec, *miDCCursorPtr;
  60.  
  61. /*
  62.  * sprite/cursor method table
  63.  */
  64.  
  65. static Bool    miDCRealizeCursor(),        miDCUnrealizeCursor();
  66. static Bool    miDCPutUpCursor(),        miDCSaveUnderCursor();
  67. static Bool    miDCRestoreUnderCursor(),   miDCMoveCursor();
  68. static Bool    miDCChangeSave();
  69.  
  70. static miSpriteCursorFuncRec miDCFuncs = {
  71.     miDCRealizeCursor,
  72.     miDCUnrealizeCursor,
  73.     miDCPutUpCursor,
  74.     miDCSaveUnderCursor,
  75.     miDCRestoreUnderCursor,
  76.     miDCMoveCursor,
  77.     miDCChangeSave,
  78. };
  79.  
  80. Bool
  81. miDCInitialize (pScreen, screenFuncs)
  82.     ScreenPtr            pScreen;
  83.     miPointerScreenFuncPtr  screenFuncs;
  84. {
  85.     miDCScreenPtr   pScreenPriv;
  86.  
  87.     if (miDCGeneration != serverGeneration)
  88.     {
  89.     miDCScreenIndex = AllocateScreenPrivateIndex ();
  90.     if (miDCScreenIndex < 0)
  91.         return FALSE;
  92.     miDCGeneration = serverGeneration;
  93.     }
  94.     pScreenPriv = (miDCScreenPtr) xalloc (sizeof (miDCScreenRec));
  95.     if (!pScreenPriv)
  96.     return FALSE;
  97.  
  98.     /*
  99.      * initialize the entire private structure to zeros
  100.      */
  101.  
  102.     pScreenPriv->pSourceGC =
  103.     pScreenPriv->pMaskGC =
  104.     pScreenPriv->pSaveGC =
  105.      pScreenPriv->pRestoreGC =
  106.      pScreenPriv->pMoveGC =
  107.      pScreenPriv->pPixSourceGC =
  108.     pScreenPriv->pPixMaskGC = NULL;
  109.     
  110.     pScreenPriv->pSave = pScreenPriv->pTemp = NULL;
  111.  
  112.     pScreenPriv->CloseScreen = pScreen->CloseScreen;
  113.     pScreen->CloseScreen = miDCCloseScreen;
  114.     
  115.     pScreen->devPrivates[miDCScreenIndex].ptr = (pointer) pScreenPriv;
  116.  
  117.     if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs))
  118.     {
  119.     xfree ((pointer) pScreenPriv);
  120.     return FALSE;
  121.     }
  122.     return TRUE;
  123. }
  124.  
  125. #define tossGC(gc)  (gc ? FreeGC (gc, (GContext) 0) : 0)
  126. #define tossPix(pix)    (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
  127.  
  128. static Bool
  129. miDCCloseScreen (index, pScreen)
  130.     ScreenPtr    pScreen;
  131. {
  132.     miDCScreenPtr   pScreenPriv;
  133.  
  134.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  135.     pScreen->CloseScreen = pScreenPriv->CloseScreen;
  136.     tossGC (pScreenPriv->pSourceGC);
  137.     tossGC (pScreenPriv->pMaskGC);
  138.     tossGC (pScreenPriv->pSaveGC);
  139.     tossGC (pScreenPriv->pRestoreGC);
  140.     tossGC (pScreenPriv->pMoveGC);
  141.     tossGC (pScreenPriv->pPixSourceGC);
  142.     tossGC (pScreenPriv->pPixMaskGC);
  143.     tossPix (pScreenPriv->pSave);
  144.     tossPix (pScreenPriv->pTemp);
  145.     xfree ((pointer) pScreenPriv);
  146.     return (*pScreen->CloseScreen) (index, pScreen);
  147. }
  148.  
  149. static Bool
  150. miDCRealizeCursor (pScreen, pCursor)
  151.     ScreenPtr    pScreen;
  152.     CursorPtr    pCursor;
  153. {
  154.     if (pCursor->bits->refcnt <= 1)
  155.     pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
  156.     return TRUE;
  157. }
  158.  
  159. static miDCCursorPtr
  160. miDCRealize (pScreen, pCursor)
  161.     ScreenPtr    pScreen;
  162.     CursorPtr    pCursor;
  163. {
  164.     miDCCursorPtr   pPriv;
  165.     GCPtr        pGC;
  166.     XID            gcvals[3];
  167.  
  168.     pPriv = (miDCCursorPtr) xalloc (sizeof (miDCCursorRec));
  169.     if (!pPriv)
  170.     return (miDCCursorPtr)NULL;
  171.     pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
  172.     if (!pPriv->sourceBits)
  173.     {
  174.     xfree ((pointer) pPriv);
  175.     return (miDCCursorPtr)NULL;
  176.     }
  177.     pPriv->maskBits =  (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
  178.     if (!pPriv->maskBits)
  179.     {
  180.     (*pScreen->DestroyPixmap) (pPriv->sourceBits);
  181.     xfree ((pointer) pPriv);
  182.     return (miDCCursorPtr)NULL;
  183.     }
  184.     pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv;
  185.  
  186.     /* create the two sets of bits, clipping as appropriate */
  187.  
  188.     pGC = GetScratchGC (1, pScreen);
  189.     if (!pGC)
  190.     {
  191.     (void) miDCUnrealizeCursor (pScreen, pCursor);
  192.     return (miDCCursorPtr)NULL;
  193.     }
  194.  
  195.     ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
  196.     (*pGC->ops->PutImage) (pPriv->sourceBits, pGC, 1,
  197.                0, 0, pCursor->bits->width, pCursor->bits->height,
  198.                 0, XYPixmap, pCursor->bits->source);
  199.     gcvals[0] = GXand;
  200.     ChangeGC (pGC, GCFunction, gcvals);
  201.     ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
  202.     (*pGC->ops->PutImage) (pPriv->sourceBits, pGC, 1,
  203.                0, 0, pCursor->bits->width, pCursor->bits->height,
  204.                 0, XYPixmap, pCursor->bits->mask);
  205.  
  206.     /* mask bits -- pCursor->mask & ~pCursor->source */
  207.     gcvals[0] = GXcopy;
  208.     ChangeGC (pGC, GCFunction, gcvals);
  209.     ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
  210.     (*pGC->ops->PutImage) (pPriv->maskBits, pGC, 1,
  211.                0, 0, pCursor->bits->width, pCursor->bits->height,
  212.                 0, XYPixmap, pCursor->bits->mask);
  213.     gcvals[0] = GXandInverted;
  214.     ChangeGC (pGC, GCFunction, gcvals);
  215.     ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
  216.     (*pGC->ops->PutImage) (pPriv->maskBits, pGC, 1,
  217.                0, 0, pCursor->bits->width, pCursor->bits->height,
  218.                 0, XYPixmap, pCursor->bits->source);
  219.     FreeScratchGC (pGC);
  220.     return pPriv;
  221. }
  222.  
  223. static Bool
  224. miDCUnrealizeCursor (pScreen, pCursor)
  225.     ScreenPtr    pScreen;
  226.     CursorPtr    pCursor;
  227. {
  228.     miDCCursorPtr   pPriv;
  229.  
  230.     pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
  231.     if (pPriv && (pCursor->bits->refcnt <= 1))
  232.     {
  233.     (*pScreen->DestroyPixmap) (pPriv->sourceBits);
  234.     (*pScreen->DestroyPixmap) (pPriv->maskBits);
  235.     xfree ((pointer) pPriv);
  236.     pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
  237.     }
  238.     return TRUE;
  239. }
  240.  
  241. static void
  242. miDCPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask)
  243.     DrawablePtr        pDrawable;
  244.     GCPtr        sourceGC, maskGC;
  245.     int             x, y;
  246.     unsigned        w, h;
  247.     miDCCursorPtr   pPriv;
  248.     unsigned long   source, mask;
  249. {
  250.     XID        gcvals[1];
  251.  
  252.     if (sourceGC->fgPixel != source)
  253.     {
  254.     gcvals[0] = source;
  255.     DoChangeGC (sourceGC, GCForeground, gcvals, 0);
  256.     }
  257.     if (sourceGC->serialNumber != pDrawable->serialNumber)
  258.     ValidateGC (pDrawable, sourceGC);
  259.     (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
  260.     if (maskGC->fgPixel != mask)
  261.     {
  262.     gcvals[0] = mask;
  263.     DoChangeGC (maskGC, GCForeground, gcvals, 0);
  264.     }
  265.     if (maskGC->serialNumber != pDrawable->serialNumber)
  266.     ValidateGC (pDrawable, maskGC);
  267.     (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
  268. }
  269.  
  270. #define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win))
  271.  
  272. static GCPtr
  273. miDCMakeGC(ppGC, pWin)
  274.     GCPtr    *ppGC;
  275.     WindowPtr    pWin;
  276. {
  277.     GCPtr pGC;
  278.     int   status;
  279.     XID   gcvals[2];
  280.  
  281.     gcvals[0] = IncludeInferiors;
  282.     gcvals[1] = FALSE;
  283.     pGC = CreateGC((DrawablePtr)pWin,
  284.            GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  285.     if (pGC)
  286.     (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
  287.     *ppGC = pGC;
  288.     return pGC;
  289. }
  290.  
  291. static Bool
  292. miDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
  293.     ScreenPtr        pScreen;
  294.     CursorPtr        pCursor;
  295.     unsigned long   source, mask;
  296. {
  297.     miDCScreenPtr   pScreenPriv;
  298.     miDCCursorPtr   pPriv;
  299.     WindowPtr        pWin;
  300.  
  301.     pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
  302.     if (!pPriv)
  303.     {
  304.     pPriv = miDCRealize(pScreen, pCursor);
  305.     if (!pPriv)
  306.         return FALSE;
  307.     }
  308.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  309.     pWin = WindowTable[pScreen->myNum];
  310.     if (!EnsureGC(pScreenPriv->pSourceGC, pWin))
  311.     return FALSE;
  312.     if (!EnsureGC(pScreenPriv->pMaskGC, pWin))
  313.     {
  314.     FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
  315.     pScreenPriv->pSourceGC = 0;
  316.     return FALSE;
  317.     }
  318.     miDCPutBits ((DrawablePtr)pWin, pPriv,
  319.          pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
  320.          x, y, pCursor->bits->width, pCursor->bits->height,
  321.          source, mask);
  322.     return TRUE;
  323. }
  324.  
  325. static Bool
  326. miDCSaveUnderCursor (pScreen, x, y, w, h)
  327.     ScreenPtr    pScreen;
  328.     int        x, y, w, h;
  329. {
  330.     miDCScreenPtr   pScreenPriv;
  331.     PixmapPtr        pSave;
  332.     WindowPtr        pWin;
  333.     GCPtr        pGC;
  334.  
  335.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  336.     pSave = pScreenPriv->pSave;
  337.     pWin = WindowTable[pScreen->myNum];
  338.     if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
  339.     {
  340.     if (pSave)
  341.         (*pScreen->DestroyPixmap) (pSave);
  342.     pScreenPriv->pSave = pSave =
  343.         (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth);
  344.     if (!pSave)
  345.         return FALSE;
  346.     }
  347.     if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
  348.     return FALSE;
  349.     pGC = pScreenPriv->pSaveGC;
  350.     if (pSave->drawable.serialNumber != pGC->serialNumber)
  351.     ValidateGC ((DrawablePtr) pSave, pGC);
  352.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  353.                 x, y, w, h, 0, 0);
  354.     return TRUE;
  355. }
  356.  
  357. static Bool
  358. miDCRestoreUnderCursor (pScreen, x, y, w, h)
  359.     ScreenPtr    pScreen;
  360.     int        x, y, w, h;
  361. {
  362.     miDCScreenPtr   pScreenPriv;
  363.     PixmapPtr        pSave;
  364.     WindowPtr        pWin;
  365.     GCPtr        pGC;
  366.  
  367.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  368.     pSave = pScreenPriv->pSave;
  369.     pWin = WindowTable[pScreen->myNum];
  370.     if (!pSave)
  371.     return FALSE;
  372.     if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
  373.     return FALSE;
  374.     pGC = pScreenPriv->pRestoreGC;
  375.     if (pWin->drawable.serialNumber != pGC->serialNumber)
  376.     ValidateGC ((DrawablePtr) pWin, pGC);
  377.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  378.                 0, 0, w, h, x, y);
  379.     return TRUE;
  380. }
  381.  
  382. static Bool
  383. miDCChangeSave (pScreen, x, y, w, h, dx, dy)
  384.     ScreenPtr        pScreen;
  385. {
  386.     miDCScreenPtr   pScreenPriv;
  387.     PixmapPtr        pSave;
  388.     WindowPtr        pWin;
  389.     GCPtr        pGC;
  390.     int            sourcex, sourcey, destx, desty, copyw, copyh;
  391.  
  392.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  393.     pSave = pScreenPriv->pSave;
  394.     pWin = WindowTable[pScreen->myNum];
  395.     /*
  396.      * restore the bits which are about to get trashed
  397.      */
  398.     if (!pSave)
  399.     return FALSE;
  400.     if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
  401.     return FALSE;
  402.     pGC = pScreenPriv->pRestoreGC;
  403.     if (pWin->drawable.serialNumber != pGC->serialNumber)
  404.     ValidateGC ((DrawablePtr) pWin, pGC);
  405.     /*
  406.      * copy the old bits to the screen.
  407.      */
  408.     if (dy > 0)
  409.     {
  410.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  411.                    0, h - dy, w, dy, x + dx, y + h);
  412.     }
  413.     else if (dy < 0)
  414.     {
  415.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  416.                    0, 0, w, -dy, x + dx, y + dy);
  417.     }
  418.     if (dy >= 0)
  419.     {
  420.     desty = y + dy;
  421.     sourcey = 0;
  422.     copyh = h - dy;
  423.     }
  424.     else
  425.     {
  426.     desty = y;
  427.     sourcey = - dy;
  428.     copyh = h + dy;
  429.     }
  430.     if (dx > 0)
  431.     {
  432.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  433.                    w - dx, sourcey, dx, copyh, x + w, desty);
  434.     }
  435.     else if (dx < 0)
  436.     {
  437.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  438.                    0, sourcey, -dx, copyh, x + dx, desty);
  439.     }
  440.     if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
  441.     return FALSE;
  442.     pGC = pScreenPriv->pSaveGC;
  443.     if (pSave->drawable.serialNumber != pGC->serialNumber)
  444.     ValidateGC ((DrawablePtr) pSave, pGC);
  445.     /*
  446.      * move the bits that are still valid within the pixmap
  447.      */
  448.     if (dx >= 0)
  449.     {
  450.     sourcex = 0;
  451.     destx = dx;
  452.     copyw = w - dx;
  453.     }
  454.     else
  455.     {
  456.     destx = 0;
  457.     sourcex = - dx;
  458.     copyw = w + dx;
  459.     }
  460.     if (dy >= 0)
  461.     {
  462.     sourcey = 0;
  463.     desty = dy;
  464.     copyh = h - dy;
  465.     }
  466.     else
  467.     {
  468.     desty = 0;
  469.     sourcey = -dy;
  470.     copyh = h + dy;
  471.     }
  472.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC,
  473.                sourcex, sourcey, copyw, copyh, destx, desty);
  474.     /*
  475.      * copy the new bits from the screen into the remaining areas of the
  476.      * pixmap
  477.      */
  478.     if (dy > 0)
  479.     {
  480.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  481.                    x, y, w, dy, 0, 0);
  482.     }
  483.     else if (dy < 0)
  484.     {
  485.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  486.                    x, y + h + dy, w, -dy, 0, h + dy);
  487.     }
  488.     if (dy >= 0)
  489.     {
  490.     desty = dy;
  491.     sourcey = y + dy;
  492.     copyh = h - dy;
  493.     }
  494.     else
  495.     {
  496.     desty = 0;
  497.     sourcey = y;
  498.     copyh = h + dy;
  499.     }
  500.     if (dx > 0)
  501.     {
  502.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  503.                    x, sourcey, dx, copyh, 0, desty);
  504.     }
  505.     else if (dx < 0)
  506.     {
  507.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  508.                    x + w + dx, sourcey, -dx, copyh, w + dx, desty);
  509.     }
  510.     return TRUE;
  511. }
  512.  
  513. static Bool
  514. miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
  515.     ScreenPtr        pScreen;
  516.     CursorPtr        pCursor;
  517.     unsigned long   source, mask;
  518. {
  519.     miDCCursorPtr   pPriv;
  520.     miDCScreenPtr   pScreenPriv;
  521.     int            status;
  522.     WindowPtr        pWin;
  523.     GCPtr        pGC;
  524.     XID            gcval = FALSE;
  525.     PixmapPtr        pTemp;
  526.  
  527.     pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
  528.     if (!pPriv)
  529.     {
  530.     pPriv = miDCRealize(pScreen, pCursor);
  531.     if (!pPriv)
  532.         return FALSE;
  533.     }
  534.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  535.     pWin = WindowTable[pScreen->myNum];
  536.     pTemp = pScreenPriv->pTemp;
  537.     if (!pTemp ||
  538.     pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
  539.     pTemp->drawable.height != pScreenPriv->pSave->drawable.height)
  540.     {
  541.     if (pTemp)
  542.         (*pScreen->DestroyPixmap) (pTemp);
  543.     pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap)
  544.         (pScreen, w, h, pScreenPriv->pSave->drawable.depth);
  545.     if (!pTemp)
  546.         return FALSE;
  547.     }
  548.     if (!pScreenPriv->pMoveGC)
  549.     {
  550.     pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp,
  551.         GCGraphicsExposures, &gcval, &status);
  552.     if (!pScreenPriv->pMoveGC)
  553.         return FALSE;
  554.     }
  555.     /*
  556.      * copy the saved area to a temporary pixmap
  557.      */
  558.     pGC = pScreenPriv->pMoveGC;
  559.     if (pGC->serialNumber != pTemp->drawable.serialNumber)
  560.     ValidateGC ((DrawablePtr) pTemp, pGC);
  561.     (*pGC->ops->CopyArea)
  562.     (pScreenPriv->pSave, pTemp, pGC, 0, 0, w, h, 0, 0);
  563.     
  564.     /*
  565.      * draw the cursor in the temporary pixmap
  566.      */
  567.     if (!pScreenPriv->pPixSourceGC)
  568.     {
  569.     pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
  570.         GCGraphicsExposures, &gcval, &status);
  571.     if (!pScreenPriv->pPixSourceGC)
  572.         return FALSE;
  573.     }
  574.     if (!pScreenPriv->pPixMaskGC)
  575.     {
  576.     pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
  577.         GCGraphicsExposures, &gcval, &status);
  578.     if (!pScreenPriv->pPixMaskGC)
  579.         return FALSE;
  580.     }
  581.     miDCPutBits ((DrawablePtr)pTemp, pPriv,
  582.          pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC,
  583.           dx, dy, pCursor->bits->width, pCursor->bits->height,
  584.          source, mask);
  585.  
  586.     /*
  587.      * copy the temporary pixmap onto the screen
  588.      */
  589.  
  590.     if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
  591.     return FALSE;
  592.     pGC = pScreenPriv->pRestoreGC;
  593.     if (pWin->drawable.serialNumber != pGC->serialNumber)
  594.     ValidateGC ((DrawablePtr) pWin, pGC);
  595.  
  596.     (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin,
  597.                 pGC,
  598.                 0, 0, w, h, x, y);
  599.     return TRUE;
  600. }
  601.