--- .empty Thu Jan 1 00:00:00 1970 +++ NEW/xc/programs/Xserver/hw/cg14/cg14curs.c Thu Jan 1 00:00:00 1970 @@ -0,0 +1,799 @@ +/* This file contains much code copied fairly directly from + mi/midispcur.c, atrocious (IMO) coding style and all. + The copyright notice/license below applies to only those portions; + my modifications I place in the public domain. */ + +/* + +Copyright 1989, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +*/ + +/* + * There is some ugliness here. We want to wrap the methods pointer + * miSpriteInitialize passes to miPointerInitialize. However, + * miPointerInitialize saves it in a screen private. While the + * definition of the structure used (miPointerScreenRec) is available + * in mi/mipointrst.h, the screen-private index it's kept under, + * miPointerScreenIndex, is kept in a file-scope static variable, + * private to mipointer.c. We need to do something similar with + * miSpriteInitialize's BlockHandler procedure. + * + * It's gross, but we cheat. We go under the hood of + * AllocateScreenPrivateIndex to deduce what screen private indices + * mipointer.c and misprite.c got, so we can get hold of the + * structures to wrap the routines. I consider this slightly (but + * only slightly) less gross than patching mipointer.c and misprite.c + * to export their screen indices, which is the only other solution + * I've come up with short of duplicating large quantities of code to + * no end other than wrapping those functions. Even the code + * duplication I'm already doing in this file feels ugly.... + */ +extern int screenPrivateCount; +static int mi_psi; +static int mi_ssi; + +#define NEED_EVENTS +#include "X.h" +#include "misc.h" +#include "input.h" +#include "servermd.h" +#include "misprite.h" +#include "gcstruct.h" +#include "mipointer.h" +#include "cursorstr.h" +#include "windowstr.h" +#include "regionstr.h" +#include "dixstruct.h" +#include "mispritest.h" +#include "scrnintstr.h" +#include "mipointrst.h" + +#include "os.h" +#include "cg14.h" +#include "vars.h" +#include "cg14-24.h" + +#define TRUECOLOR_HIGHBITS 0x00000000 + +/* WTF isn't xalloc already returning void *?! */ +#define vxalloc(s) ((void *)xalloc((s))) +#define vxfree(p) xfree((void *)p); + +/* per-screen private data */ + +static int cg14cursScreenIndex; +static unsigned long cg14cursGeneration = 0; + +typedef struct { + CursorRec *curcurs; + miPointerSpriteFuncRec *sprite_funcs; + miPointerScreenRec *mi_pp; + miSpriteScreenRec *mi_sp; + ScreenBlockHandlerProcPtr block_handler; + GCPtr pSourceGC, pMaskGC; + GCPtr pSaveGC, pRestoreGC; + GCPtr pMoveGC; + GCPtr pPixSourceGC, pPixMaskGC; + CloseScreenProcPtr CloseScreen; + PixmapPtr pSave, pTemp; +} cg14cursScreenRec, *cg14cursScreenPtr; + +/* per-cursor per-screen private data */ +typedef struct { + PixmapPtr sourceBits; /* source bits */ + PixmapPtr maskBits; /* mask bits */ +} cg14cursCursorRec, *cg14cursCursorPtr; + +#define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0) +#define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE) + +static Bool +cg14cursCloseScreen (index, pScreen) + ScreenPtr pScreen; +{ + cg14cursScreenPtr pScreenPriv; + + pScreenPriv = (cg14cursScreenPtr) pScreen->devPrivates[cg14cursScreenIndex].ptr; + pScreen->CloseScreen = pScreenPriv->CloseScreen; + tossGC (pScreenPriv->pSourceGC); + tossGC (pScreenPriv->pMaskGC); + tossGC (pScreenPriv->pSaveGC); + tossGC (pScreenPriv->pRestoreGC); + tossGC (pScreenPriv->pMoveGC); + tossGC (pScreenPriv->pPixSourceGC); + tossGC (pScreenPriv->pPixMaskGC); + tossPix (pScreenPriv->pSave); + tossPix (pScreenPriv->pTemp); + xfree ((pointer) pScreenPriv); + return (*pScreen->CloseScreen) (index, pScreen); +} + +static Bool +cg14cursRealizeCursor (pScreen, pCursor) + ScreenPtr pScreen; + CursorPtr pCursor; +{ + if (pCursor->bits->refcnt <= 1) + pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL; + return TRUE; +} + +static Bool +cg14cursUnrealizeCursor (pScreen, pCursor) + ScreenPtr pScreen; + CursorPtr pCursor; +{ + cg14cursCursorPtr pPriv; + + pPriv = (cg14cursCursorPtr) pCursor->bits->devPriv[pScreen->myNum]; + if (pPriv && (pCursor->bits->refcnt <= 1)) + { + (*pScreen->DestroyPixmap) (pPriv->sourceBits); + (*pScreen->DestroyPixmap) (pPriv->maskBits); + xfree ((pointer) pPriv); + pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL; + } + return TRUE; +} + +static cg14cursCursorPtr +cg14cursRealize (pScreen, pCursor) + ScreenPtr pScreen; + CursorPtr pCursor; +{ + cg14cursCursorPtr pPriv; + GCPtr pGC; + XID gcvals[3]; + + pPriv = (cg14cursCursorPtr) xalloc (sizeof (cg14cursCursorRec)); + if (!pPriv) + return (cg14cursCursorPtr)NULL; + pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1); + if (!pPriv->sourceBits) + { + xfree ((pointer) pPriv); + return (cg14cursCursorPtr)NULL; + } + pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1); + if (!pPriv->maskBits) + { + (*pScreen->DestroyPixmap) (pPriv->sourceBits); + xfree ((pointer) pPriv); + return (cg14cursCursorPtr)NULL; + } + pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv; + + /* create the two sets of bits, clipping as appropriate */ + + pGC = GetScratchGC (1, pScreen); + if (!pGC) + { + (void) cg14cursUnrealizeCursor (pScreen, pCursor); + return (cg14cursCursorPtr)NULL; + } + + ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *)pCursor->bits->source); + gcvals[0] = GXand; + ChangeGC (pGC, GCFunction, gcvals); + ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *)pCursor->bits->mask); + + /* mask bits -- pCursor->mask & ~pCursor->source */ + gcvals[0] = GXcopy; + ChangeGC (pGC, GCFunction, gcvals); + ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *)pCursor->bits->mask); + gcvals[0] = GXandInverted; + ChangeGC (pGC, GCFunction, gcvals); + ValidateGC ((DrawablePtr)pPriv->maskBits, pGC); + (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1, + 0, 0, pCursor->bits->width, pCursor->bits->height, + 0, XYPixmap, (char *)pCursor->bits->source); + FreeScratchGC (pGC); + return pPriv; +} + +static void +cg14cursPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask) + DrawablePtr pDrawable; + GCPtr sourceGC, maskGC; + int x, y; + unsigned w, h; + cg14cursCursorPtr pPriv; + unsigned long source, mask; +{ + XID gcvals[1]; + + if (sourceGC->fgPixel != source) + { + gcvals[0] = source; + DoChangeGC (sourceGC, GCForeground, gcvals, 0); + } + if (sourceGC->serialNumber != pDrawable->serialNumber) + ValidateGC (pDrawable, sourceGC); + (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y); + if (maskGC->fgPixel != mask) + { + gcvals[0] = mask; + DoChangeGC (maskGC, GCForeground, gcvals, 0); + } + if (maskGC->serialNumber != pDrawable->serialNumber) + ValidateGC (pDrawable, maskGC); + (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y); +} + +#define EnsureGC(gc,win) (gc || cg14cursMakeGC(&gc, win)) + +static GC *cg14cursMakeGC(GC **ppGC, DrawableRec *d) +{ + GCPtr pGC; + int status; + XID gcvals[2]; + + gcvals[0] = IncludeInferiors; + gcvals[1] = FALSE; + pGC = CreateGC(d, GCSubwindowMode|GCGraphicsExposures, gcvals, &status); + *ppGC = pGC; + return pGC; +} + +static Bool +cg14cursPutUpCursor (pScreen, pCursor, x, y, source, mask) + ScreenPtr pScreen; + CursorPtr pCursor; + int x, y; + unsigned long source, mask; +{ + cg14cursScreenPtr pScreenPriv; + cg14cursCursorPtr pPriv; + + pPriv = (cg14cursCursorPtr) pCursor->bits->devPriv[pScreen->myNum]; + if (!pPriv) + { + pPriv = cg14cursRealize(pScreen, pCursor); + if (!pPriv) + return FALSE; + } + pScreenPriv = (cg14cursScreenPtr) pScreen->devPrivates[cg14cursScreenIndex].ptr; + if (!EnsureGC(pScreenPriv->pSourceGC, &cg14_deepfb->drawable)) + return FALSE; + if (!EnsureGC(pScreenPriv->pMaskGC, &cg14_deepfb->drawable)) + { + FreeGC (pScreenPriv->pSourceGC, (GContext) 0); + pScreenPriv->pSourceGC = 0; + return FALSE; + } + cg14cursPutBits (cg14_deepfb, pPriv, + pScreenPriv->pSourceGC, pScreenPriv->pMaskGC, + x, y, pCursor->bits->width, pCursor->bits->height, + ((pCursor->foreRed >> 8) << 0) | + ((pCursor->foreGreen >> 8) << 8) | + ((pCursor->foreBlue >> 8) << 16) | + TRUECOLOR_HIGHBITS, + ((pCursor->backRed >> 8) << 0) | + ((pCursor->backGreen >> 8) << 8) | + ((pCursor->backBlue >> 8) << 16) | + TRUECOLOR_HIGHBITS ); + return TRUE; +} + +static Bool +cg14cursSaveUnderCursor (pScreen, x, y, w, h) + ScreenPtr pScreen; + int x, y, w, h; +{ + cg14cursScreenPtr pScreenPriv; + PixmapPtr pSave; + GCPtr pGC; + + pScreenPriv = (cg14cursScreenPtr) pScreen->devPrivates[cg14cursScreenIndex].ptr; + pSave = pScreenPriv->pSave; + if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h) + { + if (pSave) + (*pScreen->DestroyPixmap) (pSave); + pScreenPriv->pSave = pSave = + (*pScreen->CreatePixmap) (pScreen, w, h, 32); + if (!pSave) + return FALSE; + } + if (!EnsureGC(pScreenPriv->pSaveGC, &cg14_deepfb->drawable)) + return FALSE; + pGC = pScreenPriv->pSaveGC; + if (pSave->drawable.serialNumber != pGC->serialNumber) + ValidateGC (&pSave->drawable, pGC); + (*pGC->ops->CopyArea) (&cg14_deepfb->drawable, &pSave->drawable, pGC, + x, y, w, h, 0, 0); + return TRUE; +} + +static Bool +cg14cursRestoreUnderCursor (pScreen, x, y, w, h) + ScreenPtr pScreen; + int x, y, w, h; +{ + cg14cursScreenPtr pScreenPriv; + PixmapPtr pSave; + GCPtr pGC; + + pScreenPriv = (cg14cursScreenPtr) pScreen->devPrivates[cg14cursScreenIndex].ptr; + pSave = pScreenPriv->pSave; + if (!pSave) + return FALSE; + if (!EnsureGC(pScreenPriv->pRestoreGC, &cg14_deepfb->drawable)) + return FALSE; + pGC = pScreenPriv->pRestoreGC; + if (cg14_deepfb->drawable.serialNumber != pGC->serialNumber) + ValidateGC (&cg14_deepfb->drawable, pGC); + (*pGC->ops->CopyArea) (&pSave->drawable, &cg14_deepfb->drawable, pGC, + 0, 0, w, h, x, y); + return TRUE; +} + +static Bool +cg14cursChangeSave (pScreen, x, y, w, h, dx, dy) + ScreenPtr pScreen; + int x, y, w, h, dx, dy; +{ + cg14cursScreenPtr pScreenPriv; + PixmapPtr pSave; + GCPtr pGC; + int sourcex, sourcey, destx, desty, copyw, copyh; + + pScreenPriv = (cg14cursScreenPtr) pScreen->devPrivates[cg14cursScreenIndex].ptr; + pSave = pScreenPriv->pSave; + /* + * restore the bits which are about to get trashed + */ + if (!pSave) + return FALSE; + if (!EnsureGC(pScreenPriv->pRestoreGC, &cg14_deepfb->drawable)) + return FALSE; + pGC = pScreenPriv->pRestoreGC; + if (cg14_deepfb->drawable.serialNumber != pGC->serialNumber) + ValidateGC (&cg14_deepfb->drawable, pGC); + /* + * copy the old bits to the screen. + */ + if (dy > 0) + { + (*pGC->ops->CopyArea) (&pSave->drawable, &cg14_deepfb->drawable, pGC, + 0, h - dy, w, dy, x + dx, y + h); + } + else if (dy < 0) + { + (*pGC->ops->CopyArea) (&pSave->drawable, &cg14_deepfb->drawable, pGC, + 0, 0, w, -dy, x + dx, y + dy); + } + if (dy >= 0) + { + desty = y + dy; + sourcey = 0; + copyh = h - dy; + } + else + { + desty = y; + sourcey = - dy; + copyh = h + dy; + } + if (dx > 0) + { + (*pGC->ops->CopyArea) ((DrawablePtr) pSave, &cg14_deepfb->drawable, pGC, + w - dx, sourcey, dx, copyh, x + w, desty); + } + else if (dx < 0) + { + (*pGC->ops->CopyArea) ((DrawablePtr) pSave, &cg14_deepfb->drawable, pGC, + 0, sourcey, -dx, copyh, x + dx, desty); + } + if (!EnsureGC(pScreenPriv->pSaveGC, &cg14_deepfb->drawable)) + return FALSE; + pGC = pScreenPriv->pSaveGC; + if (pSave->drawable.serialNumber != pGC->serialNumber) + ValidateGC ((DrawablePtr) pSave, pGC); + /* + * move the bits that are still valid within the pixmap + */ + if (dx >= 0) + { + sourcex = 0; + destx = dx; + copyw = w - dx; + } + else + { + destx = 0; + sourcex = - dx; + copyw = w + dx; + } + if (dy >= 0) + { + sourcey = 0; + desty = dy; + copyh = h - dy; + } + else + { + desty = 0; + sourcey = -dy; + copyh = h + dy; + } + (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC, + sourcex, sourcey, copyw, copyh, destx, desty); + /* + * copy the new bits from the screen into the remaining areas of the + * pixmap + */ + if (dy > 0) + { + (*pGC->ops->CopyArea) (&cg14_deepfb->drawable, (DrawablePtr) pSave, pGC, + x, y, w, dy, 0, 0); + } + else if (dy < 0) + { + (*pGC->ops->CopyArea) (&cg14_deepfb->drawable, (DrawablePtr) pSave, pGC, + x, y + h + dy, w, -dy, 0, h + dy); + } + if (dy >= 0) + { + desty = dy; + sourcey = y + dy; + copyh = h - dy; + } + else + { + desty = 0; + sourcey = y; + copyh = h + dy; + } + if (dx > 0) + { + (*pGC->ops->CopyArea) (&cg14_deepfb->drawable, (DrawablePtr) pSave, pGC, + x, sourcey, dx, copyh, 0, desty); + } + else if (dx < 0) + { + (*pGC->ops->CopyArea) (&cg14_deepfb->drawable, (DrawablePtr) pSave, pGC, + x + w + dx, sourcey, -dx, copyh, w + dx, desty); + } + return TRUE; +} + +static Bool +cg14cursMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask) + ScreenPtr pScreen; + CursorPtr pCursor; + int x, y, w, h, dx, dy; + unsigned long source, mask; +{ + cg14cursCursorPtr pPriv; + cg14cursScreenPtr pScreenPriv; + int status; + GCPtr pGC; + XID gcval = FALSE; + PixmapPtr pTemp; + + pPriv = (cg14cursCursorPtr) pCursor->bits->devPriv[pScreen->myNum]; + if (!pPriv) + { + pPriv = cg14cursRealize(pScreen, pCursor); + if (!pPriv) + return FALSE; + } + pScreenPriv = (cg14cursScreenPtr) pScreen->devPrivates[cg14cursScreenIndex].ptr; + pTemp = pScreenPriv->pTemp; + if (!pTemp || + pTemp->drawable.width != pScreenPriv->pSave->drawable.width || + pTemp->drawable.height != pScreenPriv->pSave->drawable.height) + { + if (pTemp) + (*pScreen->DestroyPixmap) (pTemp); + pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap) + (pScreen, w, h, 32); + if (!pTemp) + return FALSE; + } + if (!pScreenPriv->pMoveGC) + { + pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp, + GCGraphicsExposures, &gcval, &status); + if (!pScreenPriv->pMoveGC) + return FALSE; + } + /* + * copy the saved area to a temporary pixmap + */ + pGC = pScreenPriv->pMoveGC; + if (pGC->serialNumber != pTemp->drawable.serialNumber) + ValidateGC ((DrawablePtr) pTemp, pGC); + (*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave, + (DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0); + + /* + * draw the cursor in the temporary pixmap + */ + if (!pScreenPriv->pPixSourceGC) + { + pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp, + GCGraphicsExposures, &gcval, &status); + if (!pScreenPriv->pPixSourceGC) + return FALSE; + } + if (!pScreenPriv->pPixMaskGC) + { + pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp, + GCGraphicsExposures, &gcval, &status); + if (!pScreenPriv->pPixMaskGC) + return FALSE; + } + cg14cursPutBits ((DrawablePtr)pTemp, pPriv, + pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC, + dx, dy, pCursor->bits->width, pCursor->bits->height, + ((pCursor->foreRed >> 8) << 0) | + ((pCursor->foreGreen >> 8) << 8) | + ((pCursor->foreBlue >> 8) << 16) | + TRUECOLOR_HIGHBITS, + ((pCursor->backRed >> 8) << 0) | + ((pCursor->backGreen >> 8) << 8) | + ((pCursor->backBlue >> 8) << 16) | + TRUECOLOR_HIGHBITS ); + + /* + * copy the temporary pixmap onto the screen + */ + + if (!EnsureGC(pScreenPriv->pRestoreGC, &cg14_deepfb->drawable)) + return FALSE; + pGC = pScreenPriv->pRestoreGC; + if (cg14_deepfb->drawable.serialNumber != pGC->serialNumber) + ValidateGC (&cg14_deepfb->drawable, pGC); + + (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, &cg14_deepfb->drawable, + pGC, + 0, 0, w, h, x, y); + return TRUE; +} + +static miSpriteCursorFuncRec cg14cursFuncs + = { cg14cursRealizeCursor, + cg14cursUnrealizeCursor, + cg14cursPutUpCursor, + cg14cursSaveUnderCursor, + cg14cursRestoreUnderCursor, + cg14cursMoveCursor, + cg14cursChangeSave }; + +typedef struct wcpriv WCPRIV; + +struct wcpriv { + void *priv; + int usehw; + } ; + +#define HW_MAXW 32 +#define HW_MAXH 32 + +static Bool realize_wrapper(ScreenRec *s, CursorRec *c) +{ + WCPRIV *p; + cg14cursScreenRec *sp; + + if (c->bits->refcnt > 1) return(TRUE); + sp = s->devPrivates[cg14cursScreenIndex].ptr; + p = vxalloc(sizeof(WCPRIV)); + if (p == 0) return(FALSE); + p->usehw = (c->bits->width <= HW_MAXW) && (c->bits->height <= HW_MAXH); + if (p->usehw) + { c->bits->devPriv[s->myNum] = p; + return(TRUE); + } + if (! (*sp->sprite_funcs->RealizeCursor)(s,c)) + { vxfree(p); + return(FALSE); + } + p->priv = c->bits->devPriv[s->myNum]; + c->bits->devPriv[s->myNum] = p; + return(TRUE); +} + +static void set_wrapper(ScreenRec *s, CursorRec *c, int x, int y) +{ + WCPRIV *pc; + WCPRIV *pcur; + cg14cursScreenRec *sp; + + sp = s->devPrivates[cg14cursScreenIndex].ptr; + pc = c ? c->bits->devPriv[s->myNum] : 0; + pcur = sp->curcurs ? sp->curcurs->bits->devPriv[s->myNum] : 0; + /* + * If we're setting a nil cursor, or we're changing cursors and they + * aren't both use-hardware cursors, we explicitly take down the + * currently-displayed cursor first. (We could do it when they're + * both use-hardware, too, if the cursor vanishing briefly is + * considered better than there being a brief time during which it + * may be displayed partially reloaded.) But do this only if we have + * a cursor currently set! + */ + if ( sp->curcurs && + ( (c == 0) || + ( (c != sp->curcurs) && + !(pc->usehw && pcur->usehw) ) ) ) + { if (pcur) + { if (pcur->usehw) + { curs->ctl = 0; + } + else + { sp->curcurs->bits->devPriv[s->myNum] = pcur->priv; + (*sp->sprite_funcs->SetCursor)(s,0,x,y); + pcur->priv = sp->curcurs->bits->devPriv[s->myNum]; + sp->curcurs->bits->devPriv[s->myNum] = pcur; + } + } + } + if (pc) + { if (pc->usehw) + { unsigned int wm; + int i; + wm = (c->bits->width < 32) ? ~((~0U) >> c->bits->width) : ~0U; + for (i=0;ibits->height;i++) + { curs->plane0[i] = ((unsigned int *)c->bits->mask)[i] & wm; + curs->plane1[i] = ((unsigned int *)c->bits->source)[i]; + } + for (;i<32;i++) curs->plane0[i] = 0; + curs->color0 = ((c->backRed >> 8) * 0x00000001) | + ((c->backGreen >> 8) * 0x00000100) | + ((c->backBlue >> 8) * 0x00010000); + curs->color1 = ((c->foreRed >> 8) * 0x00000001) | + ((c->foreGreen >> 8) * 0x00000100) | + ((c->foreBlue >> 8) * 0x00010000); + curs->x = x - c->bits->xhot; + curs->y = y - c->bits->yhot; + curs->ctl = CG14_CURS_ENABLE; + } + else + { c->bits->devPriv[s->myNum] = pc->priv; + (*sp->sprite_funcs->SetCursor)(s,c,x,y); + pc->priv = c->bits->devPriv[s->myNum]; + c->bits->devPriv[s->myNum] = pc; + } + } + sp->curcurs = c; +} + +static Bool unrealize_wrapper(ScreenRec *s, CursorRec *c) +{ + WCPRIV *p; + cg14cursScreenRec *sp; + Bool rv; + + if (c->bits->refcnt > 1) return(TRUE); + p = c->bits->devPriv[s->myNum]; + sp = s->devPrivates[cg14cursScreenIndex].ptr; + if (sp->curcurs == c) set_wrapper(s,0,0,0); + if (! p->usehw) + { c->bits->devPriv[s->myNum] = p->priv; + rv = (*sp->sprite_funcs->UnrealizeCursor)(s,c); + /* Does FALSE from UnrealizeCursor mean the cursor still exists?? + Assume not. XXX */ + } + else + { rv = TRUE; + } + vxfree(p); + c->bits->devPriv[s->myNum] = 0; + return(rv); +} + +static void move_wrapper(ScreenRec *s, int x, int y) +{ + WCPRIV *p; + cg14cursScreenRec *sp; + __typeof__(sp->curcurs->bits) bits; + + sp = s->devPrivates[cg14cursScreenIndex].ptr; + if (! sp->curcurs) return; + bits = sp->curcurs->bits; + p = bits->devPriv[s->myNum]; + if (p->usehw) + { curs->x = x - bits->xhot; + curs->y = y - bits->yhot; + } + else + { bits->devPriv[s->myNum] = p->priv; + (*sp->sprite_funcs->MoveCursor)(s,x,y); + p->priv = bits->devPriv[s->myNum]; + bits->devPriv[s->myNum] = p; + } +} + +static miPointerSpriteFuncRec cg14_sprite_funcs + = { realize_wrapper, unrealize_wrapper, set_wrapper, move_wrapper }; + +static void block_wrapper(int sno, void *data, struct timeval **timeout, void *readmask) +{ + ScreenRec *s; + cg14cursScreenRec *sp; + WCPRIV *p; + ScreenBlockHandlerProcPtr h; + + s = screenInfo.screens[sno]; + sp = s->devPrivates[cg14cursScreenIndex].ptr; + p = sp->curcurs ? sp->curcurs->bits->devPriv[sno] : 0; + if (p && !p->usehw) + { h = s->BlockHandler; + s->BlockHandler = sp->block_handler; + } + else + { h = s->BlockHandler; + s->BlockHandler = sp->mi_sp->BlockHandler; + } + if (p) sp->curcurs->bits->devPriv[sno] = p->priv; + (*s->BlockHandler)(sno,data,timeout,readmask); + if (p) + { p->priv = sp->curcurs->bits->devPriv[sno]; + sp->curcurs->bits->devPriv[sno] = p; + } + s->BlockHandler = h; +} + +cg14_pointer_setup(ScreenRec *s) +{ + cg14cursScreenRec *psp; + + if (cg14cursGeneration != serverGeneration) + { cg14cursScreenIndex = AllocateScreenPrivateIndex(); + if (cg14cursScreenIndex < 0) FatalError("can't allocate screen private index for pointer"); + cg14cursGeneration = serverGeneration; + } + psp = vxalloc(sizeof(cg14cursScreenRec)); + if (! psp) FatalError("can't allocate screen private structure pointer"); + psp->curcurs = 0; + psp->pSourceGC = 0; + psp->pMaskGC = 0; + psp->pSaveGC = 0; + psp->pRestoreGC = 0; + psp->pMoveGC = 0; + psp->pPixSourceGC = 0; + psp->pPixMaskGC = 0; + psp->pSave = 0; + psp->pTemp = 0; + psp->CloseScreen = s->CloseScreen; + s->CloseScreen = cg14cursCloseScreen; + s->devPrivates[cg14cursScreenIndex].ptr = psp; + mi_ssi = screenPrivateCount; + if (! miSpriteInitialize(s,&cg14cursFuncs,&cg14_ptrscrfuncs)) + { xfree(psp); + FatalError("can't miSpriteInitialize"); + } + mi_psi = screenPrivateCount - 1; + psp->mi_sp = s->devPrivates[mi_ssi].ptr; + psp->mi_pp = s->devPrivates[mi_psi].ptr; + psp->sprite_funcs = psp->mi_pp->spriteFuncs; + psp->block_handler = s->BlockHandler; + psp->mi_pp->spriteFuncs = &cg14_sprite_funcs; + s->BlockHandler = block_wrapper; +}