cursor.c revision 4642e01f
105b261ecSmrg/* 205b261ecSmrg * Copyright © 2006 Sun Microsystems 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Sun Microsystems not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Sun Microsystems makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg * 2205b261ecSmrg * Copyright © 2002 Keith Packard 2305b261ecSmrg * 2405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 2505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 2605b261ecSmrg * the above copyright notice appear in all copies and that both that 2705b261ecSmrg * copyright notice and this permission notice appear in supporting 2805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 2905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 3005b261ecSmrg * specific, written prior permission. Keith Packard makes no 3105b261ecSmrg * representations about the suitability of this software for any purpose. It 3205b261ecSmrg * is provided "as is" without express or implied warranty. 3305b261ecSmrg * 3405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 3505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 3605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 3705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 3805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 3905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 4005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 4105b261ecSmrg */ 4205b261ecSmrg 4305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 4405b261ecSmrg#include <dix-config.h> 4505b261ecSmrg#endif 4605b261ecSmrg 4705b261ecSmrg#include "xfixesint.h" 4805b261ecSmrg#include "scrnintstr.h" 4905b261ecSmrg#include "cursorstr.h" 5005b261ecSmrg#include "dixevents.h" 5105b261ecSmrg#include "servermd.h" 5205b261ecSmrg#include "inputstr.h" 5305b261ecSmrg#include "windowstr.h" 544642e01fSmrg#include "xace.h" 5505b261ecSmrg 5605b261ecSmrgstatic RESTYPE CursorClientType; 5705b261ecSmrgstatic RESTYPE CursorHideCountType; 5805b261ecSmrgstatic RESTYPE CursorWindowType; 5905b261ecSmrgstatic CursorPtr CursorCurrent; 6005b261ecSmrgstatic CursorPtr pInvisibleCursor = NULL; 6105b261ecSmrg 624642e01fSmrgstatic int CursorScreenPrivateKeyIndex; 634642e01fSmrgstatic DevPrivateKey CursorScreenPrivateKey = &CursorScreenPrivateKeyIndex; 644642e01fSmrg 6505b261ecSmrgstatic void deleteCursorHideCountsForScreen (ScreenPtr pScreen); 6605b261ecSmrg 6705b261ecSmrg#define VERIFY_CURSOR(pCursor, cursor, client, access) { \ 6805b261ecSmrg pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \ 6905b261ecSmrg RT_CURSOR, (access)); \ 7005b261ecSmrg if (!pCursor) { \ 7105b261ecSmrg (client)->errorValue = (cursor); \ 7205b261ecSmrg return BadCursor; \ 7305b261ecSmrg } \ 7405b261ecSmrg} 754642e01fSmrg 7605b261ecSmrg/* 7705b261ecSmrg * There is a global list of windows selecting for cursor events 7805b261ecSmrg */ 7905b261ecSmrg 8005b261ecSmrgtypedef struct _CursorEvent *CursorEventPtr; 8105b261ecSmrg 8205b261ecSmrgtypedef struct _CursorEvent { 8305b261ecSmrg CursorEventPtr next; 8405b261ecSmrg CARD32 eventMask; 8505b261ecSmrg ClientPtr pClient; 8605b261ecSmrg WindowPtr pWindow; 8705b261ecSmrg XID clientResource; 8805b261ecSmrg} CursorEventRec; 8905b261ecSmrg 9005b261ecSmrgstatic CursorEventPtr cursorEvents; 9105b261ecSmrg 9205b261ecSmrg/* 9305b261ecSmrg * Each screen has a list of clients which have requested 9405b261ecSmrg * that the cursor be hid, and the number of times each 9505b261ecSmrg * client has requested. 9605b261ecSmrg*/ 9705b261ecSmrg 9805b261ecSmrgtypedef struct _CursorHideCountRec *CursorHideCountPtr; 9905b261ecSmrg 10005b261ecSmrgtypedef struct _CursorHideCountRec { 10105b261ecSmrg CursorHideCountPtr pNext; 10205b261ecSmrg ClientPtr pClient; 10305b261ecSmrg ScreenPtr pScreen; 10405b261ecSmrg int hideCount; 10505b261ecSmrg XID resource; 10605b261ecSmrg} CursorHideCountRec; 10705b261ecSmrg 10805b261ecSmrg/* 10905b261ecSmrg * Wrap DisplayCursor to catch cursor change events 11005b261ecSmrg */ 11105b261ecSmrg 11205b261ecSmrgtypedef struct _CursorScreen { 11305b261ecSmrg DisplayCursorProcPtr DisplayCursor; 11405b261ecSmrg CloseScreenProcPtr CloseScreen; 11505b261ecSmrg CursorHideCountPtr pCursorHideCounts; 11605b261ecSmrg} CursorScreenRec, *CursorScreenPtr; 11705b261ecSmrg 1184642e01fSmrg#define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey)) 1194642e01fSmrg#define GetCursorScreenIfSet(s) GetCursorScreen(s) 1204642e01fSmrg#define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p) 12105b261ecSmrg#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) 12205b261ecSmrg#define Unwrap(as,s,elt) ((s)->elt = (as)->elt) 12305b261ecSmrg 1244642e01fSmrg/* The cursor doesn't show up until the first XDefineCursor() */ 1254642e01fSmrgstatic Bool CursorVisible = FALSE; 1264642e01fSmrg 12705b261ecSmrgstatic Bool 1284642e01fSmrgCursorDisplayCursor (DeviceIntPtr pDev, 1294642e01fSmrg ScreenPtr pScreen, 13005b261ecSmrg CursorPtr pCursor) 13105b261ecSmrg{ 13205b261ecSmrg CursorScreenPtr cs = GetCursorScreen(pScreen); 13305b261ecSmrg Bool ret; 13405b261ecSmrg 13505b261ecSmrg Unwrap (cs, pScreen, DisplayCursor); 13605b261ecSmrg 1374642e01fSmrg /* 1384642e01fSmrg * Have to check ConnectionInfo to distinguish client requests from 1394642e01fSmrg * initial root window setup. Not a great way to do it, I admit. 1404642e01fSmrg */ 1414642e01fSmrg if (ConnectionInfo) 1424642e01fSmrg CursorVisible = TRUE; 1434642e01fSmrg 1444642e01fSmrg if (cs->pCursorHideCounts != NULL || !CursorVisible) { 1454642e01fSmrg ret = ((*pScreen->RealizeCursor)(pDev, pScreen, pInvisibleCursor) && 1464642e01fSmrg (*pScreen->DisplayCursor) (pDev, pScreen, pInvisibleCursor)); 14705b261ecSmrg } else { 1484642e01fSmrg ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); 14905b261ecSmrg } 15005b261ecSmrg 15105b261ecSmrg if (pCursor != CursorCurrent) 15205b261ecSmrg { 15305b261ecSmrg CursorEventPtr e; 15405b261ecSmrg 15505b261ecSmrg CursorCurrent = pCursor; 15605b261ecSmrg for (e = cursorEvents; e; e = e->next) 15705b261ecSmrg { 15805b261ecSmrg if ((e->eventMask & XFixesDisplayCursorNotifyMask) && 15905b261ecSmrg !e->pClient->clientGone) 16005b261ecSmrg { 16105b261ecSmrg xXFixesCursorNotifyEvent ev; 16205b261ecSmrg ev.type = XFixesEventBase + XFixesCursorNotify; 16305b261ecSmrg ev.subtype = XFixesDisplayCursorNotify; 16405b261ecSmrg ev.sequenceNumber = e->pClient->sequence; 16505b261ecSmrg ev.window = e->pWindow->drawable.id; 16605b261ecSmrg ev.cursorSerial = pCursor->serialNumber; 16705b261ecSmrg ev.timestamp = currentTime.milliseconds; 16805b261ecSmrg ev.name = pCursor->name; 16905b261ecSmrg WriteEventsToClient (e->pClient, 1, (xEvent *) &ev); 17005b261ecSmrg } 17105b261ecSmrg } 17205b261ecSmrg } 17305b261ecSmrg Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); 17405b261ecSmrg return ret; 17505b261ecSmrg} 17605b261ecSmrg 17705b261ecSmrgstatic Bool 17805b261ecSmrgCursorCloseScreen (int index, ScreenPtr pScreen) 17905b261ecSmrg{ 18005b261ecSmrg CursorScreenPtr cs = GetCursorScreen (pScreen); 18105b261ecSmrg Bool ret; 18205b261ecSmrg 18305b261ecSmrg Unwrap (cs, pScreen, CloseScreen); 18405b261ecSmrg Unwrap (cs, pScreen, DisplayCursor); 18505b261ecSmrg deleteCursorHideCountsForScreen(pScreen); 18605b261ecSmrg ret = (*pScreen->CloseScreen) (index, pScreen); 18705b261ecSmrg xfree (cs); 18805b261ecSmrg return ret; 18905b261ecSmrg} 19005b261ecSmrg 19105b261ecSmrg#define CursorAllEvents (XFixesDisplayCursorNotifyMask) 19205b261ecSmrg 19305b261ecSmrgstatic int 19405b261ecSmrgXFixesSelectCursorInput (ClientPtr pClient, 19505b261ecSmrg WindowPtr pWindow, 19605b261ecSmrg CARD32 eventMask) 19705b261ecSmrg{ 19805b261ecSmrg CursorEventPtr *prev, e; 19905b261ecSmrg 20005b261ecSmrg for (prev = &cursorEvents; (e = *prev); prev = &e->next) 20105b261ecSmrg { 20205b261ecSmrg if (e->pClient == pClient && 20305b261ecSmrg e->pWindow == pWindow) 20405b261ecSmrg { 20505b261ecSmrg break; 20605b261ecSmrg } 20705b261ecSmrg } 20805b261ecSmrg if (!eventMask) 20905b261ecSmrg { 21005b261ecSmrg if (e) 21105b261ecSmrg { 21205b261ecSmrg FreeResource (e->clientResource, 0); 21305b261ecSmrg } 21405b261ecSmrg return Success; 21505b261ecSmrg } 21605b261ecSmrg if (!e) 21705b261ecSmrg { 21805b261ecSmrg e = (CursorEventPtr) xalloc (sizeof (CursorEventRec)); 21905b261ecSmrg if (!e) 22005b261ecSmrg return BadAlloc; 22105b261ecSmrg 22205b261ecSmrg e->next = 0; 22305b261ecSmrg e->pClient = pClient; 22405b261ecSmrg e->pWindow = pWindow; 22505b261ecSmrg e->clientResource = FakeClientID(pClient->index); 22605b261ecSmrg 22705b261ecSmrg /* 22805b261ecSmrg * Add a resource hanging from the window to 22905b261ecSmrg * catch window destroy 23005b261ecSmrg */ 23105b261ecSmrg if (!LookupIDByType(pWindow->drawable.id, CursorWindowType)) 23205b261ecSmrg if (!AddResource (pWindow->drawable.id, CursorWindowType, 23305b261ecSmrg (pointer) pWindow)) 23405b261ecSmrg { 23505b261ecSmrg xfree (e); 23605b261ecSmrg return BadAlloc; 23705b261ecSmrg } 23805b261ecSmrg 23905b261ecSmrg if (!AddResource (e->clientResource, CursorClientType, (pointer) e)) 24005b261ecSmrg return BadAlloc; 24105b261ecSmrg 24205b261ecSmrg *prev = e; 24305b261ecSmrg } 24405b261ecSmrg e->eventMask = eventMask; 24505b261ecSmrg return Success; 24605b261ecSmrg} 24705b261ecSmrg 24805b261ecSmrgint 24905b261ecSmrgProcXFixesSelectCursorInput (ClientPtr client) 25005b261ecSmrg{ 25105b261ecSmrg REQUEST (xXFixesSelectCursorInputReq); 25205b261ecSmrg WindowPtr pWin; 25305b261ecSmrg int rc; 25405b261ecSmrg 25505b261ecSmrg REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq); 2564642e01fSmrg rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 25705b261ecSmrg if (rc != Success) 25805b261ecSmrg return rc; 25905b261ecSmrg if (stuff->eventMask & ~CursorAllEvents) 26005b261ecSmrg { 26105b261ecSmrg client->errorValue = stuff->eventMask; 26205b261ecSmrg return( BadValue ); 26305b261ecSmrg } 26405b261ecSmrg return XFixesSelectCursorInput (client, pWin, stuff->eventMask); 26505b261ecSmrg} 26605b261ecSmrg 26705b261ecSmrgstatic int 26805b261ecSmrgGetBit (unsigned char *line, int x) 26905b261ecSmrg{ 27005b261ecSmrg unsigned char mask; 27105b261ecSmrg 27205b261ecSmrg if (screenInfo.bitmapBitOrder == LSBFirst) 27305b261ecSmrg mask = (1 << (x & 7)); 27405b261ecSmrg else 27505b261ecSmrg mask = (0x80 >> (x & 7)); 27605b261ecSmrg /* XXX assumes byte order is host byte order */ 27705b261ecSmrg line += (x >> 3); 27805b261ecSmrg if (*line & mask) 27905b261ecSmrg return 1; 28005b261ecSmrg return 0; 28105b261ecSmrg} 28205b261ecSmrg 28305b261ecSmrgint 28405b261ecSmrgSProcXFixesSelectCursorInput (ClientPtr client) 28505b261ecSmrg{ 28605b261ecSmrg register int n; 28705b261ecSmrg REQUEST(xXFixesSelectCursorInputReq); 28805b261ecSmrg 28905b261ecSmrg swaps(&stuff->length, n); 29005b261ecSmrg swapl(&stuff->window, n); 29105b261ecSmrg swapl(&stuff->eventMask, n); 29205b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 29305b261ecSmrg} 29405b261ecSmrg 29505b261ecSmrgvoid 29605b261ecSmrgSXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from, 29705b261ecSmrg xXFixesCursorNotifyEvent *to) 29805b261ecSmrg{ 29905b261ecSmrg to->type = from->type; 30005b261ecSmrg cpswaps (from->sequenceNumber, to->sequenceNumber); 30105b261ecSmrg cpswapl (from->window, to->window); 30205b261ecSmrg cpswapl (from->cursorSerial, to->cursorSerial); 30305b261ecSmrg cpswapl (from->timestamp, to->timestamp); 30405b261ecSmrg cpswapl (from->name, to->name); 30505b261ecSmrg} 30605b261ecSmrg 30705b261ecSmrgstatic void 30805b261ecSmrgCopyCursorToImage (CursorPtr pCursor, CARD32 *image) 30905b261ecSmrg{ 31005b261ecSmrg int width = pCursor->bits->width; 31105b261ecSmrg int height = pCursor->bits->height; 31205b261ecSmrg int npixels = width * height; 31305b261ecSmrg 31405b261ecSmrg#ifdef ARGB_CURSOR 31505b261ecSmrg if (pCursor->bits->argb) 31605b261ecSmrg memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32)); 31705b261ecSmrg else 31805b261ecSmrg#endif 31905b261ecSmrg { 32005b261ecSmrg unsigned char *srcLine = pCursor->bits->source; 32105b261ecSmrg unsigned char *mskLine = pCursor->bits->mask; 32205b261ecSmrg int stride = BitmapBytePad (width); 32305b261ecSmrg int x, y; 32405b261ecSmrg CARD32 fg, bg; 32505b261ecSmrg 32605b261ecSmrg fg = (0xff000000 | 32705b261ecSmrg ((pCursor->foreRed & 0xff00) << 8) | 32805b261ecSmrg (pCursor->foreGreen & 0xff00) | 32905b261ecSmrg (pCursor->foreBlue >> 8)); 33005b261ecSmrg bg = (0xff000000 | 33105b261ecSmrg ((pCursor->backRed & 0xff00) << 8) | 33205b261ecSmrg (pCursor->backGreen & 0xff00) | 33305b261ecSmrg (pCursor->backBlue >> 8)); 33405b261ecSmrg for (y = 0; y < height; y++) 33505b261ecSmrg { 33605b261ecSmrg for (x = 0; x < width; x++) 33705b261ecSmrg { 33805b261ecSmrg if (GetBit (mskLine, x)) 33905b261ecSmrg { 34005b261ecSmrg if (GetBit (srcLine, x)) 34105b261ecSmrg *image++ = fg; 34205b261ecSmrg else 34305b261ecSmrg *image++ = bg; 34405b261ecSmrg } 34505b261ecSmrg else 34605b261ecSmrg *image++ = 0; 34705b261ecSmrg } 34805b261ecSmrg srcLine += stride; 34905b261ecSmrg mskLine += stride; 35005b261ecSmrg } 35105b261ecSmrg } 35205b261ecSmrg} 35305b261ecSmrg 35405b261ecSmrgint 35505b261ecSmrgProcXFixesGetCursorImage (ClientPtr client) 35605b261ecSmrg{ 35705b261ecSmrg/* REQUEST(xXFixesGetCursorImageReq); */ 35805b261ecSmrg xXFixesGetCursorImageReply *rep; 35905b261ecSmrg CursorPtr pCursor; 36005b261ecSmrg CARD32 *image; 3614642e01fSmrg int npixels, width, height, rc, x, y; 36205b261ecSmrg 36305b261ecSmrg REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq); 36405b261ecSmrg pCursor = CursorCurrent; 36505b261ecSmrg if (!pCursor) 36605b261ecSmrg return BadCursor; 3674642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, 3684642e01fSmrg pCursor, RT_NONE, NULL, DixReadAccess); 3694642e01fSmrg if (rc != Success) 3704642e01fSmrg return rc; 3714642e01fSmrg GetSpritePosition (PickPointer(client), &x, &y); 37205b261ecSmrg width = pCursor->bits->width; 37305b261ecSmrg height = pCursor->bits->height; 37405b261ecSmrg npixels = width * height; 37505b261ecSmrg rep = xalloc (sizeof (xXFixesGetCursorImageReply) + 37605b261ecSmrg npixels * sizeof (CARD32)); 37705b261ecSmrg if (!rep) 37805b261ecSmrg return BadAlloc; 37905b261ecSmrg 38005b261ecSmrg rep->type = X_Reply; 38105b261ecSmrg rep->sequenceNumber = client->sequence; 38205b261ecSmrg rep->length = npixels; 38305b261ecSmrg rep->width = width; 38405b261ecSmrg rep->height = height; 38505b261ecSmrg rep->x = x; 38605b261ecSmrg rep->y = y; 38705b261ecSmrg rep->xhot = pCursor->bits->xhot; 38805b261ecSmrg rep->yhot = pCursor->bits->yhot; 38905b261ecSmrg rep->cursorSerial = pCursor->serialNumber; 39005b261ecSmrg 39105b261ecSmrg image = (CARD32 *) (rep + 1); 39205b261ecSmrg CopyCursorToImage (pCursor, image); 39305b261ecSmrg if (client->swapped) 39405b261ecSmrg { 39505b261ecSmrg int n; 39605b261ecSmrg swaps (&rep->sequenceNumber, n); 39705b261ecSmrg swapl (&rep->length, n); 39805b261ecSmrg swaps (&rep->x, n); 39905b261ecSmrg swaps (&rep->y, n); 40005b261ecSmrg swaps (&rep->width, n); 40105b261ecSmrg swaps (&rep->height, n); 40205b261ecSmrg swaps (&rep->xhot, n); 40305b261ecSmrg swaps (&rep->yhot, n); 40405b261ecSmrg swapl (&rep->cursorSerial, n); 40505b261ecSmrg SwapLongs (image, npixels); 40605b261ecSmrg } 40705b261ecSmrg (void) WriteToClient(client, sizeof (xXFixesGetCursorImageReply) + 40805b261ecSmrg (npixels << 2), (char *) rep); 40905b261ecSmrg xfree (rep); 41005b261ecSmrg return client->noClientException; 41105b261ecSmrg} 41205b261ecSmrg 41305b261ecSmrgint 41405b261ecSmrgSProcXFixesGetCursorImage (ClientPtr client) 41505b261ecSmrg{ 41605b261ecSmrg int n; 41705b261ecSmrg REQUEST(xXFixesGetCursorImageReq); 41805b261ecSmrg swaps (&stuff->length, n); 41905b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 42005b261ecSmrg} 42105b261ecSmrg 42205b261ecSmrgint 42305b261ecSmrgProcXFixesSetCursorName (ClientPtr client) 42405b261ecSmrg{ 42505b261ecSmrg CursorPtr pCursor; 42605b261ecSmrg char *tchar; 42705b261ecSmrg REQUEST(xXFixesSetCursorNameReq); 42805b261ecSmrg Atom atom; 42905b261ecSmrg 43005b261ecSmrg REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); 4314642e01fSmrg VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess); 43205b261ecSmrg tchar = (char *) &stuff[1]; 43305b261ecSmrg atom = MakeAtom (tchar, stuff->nbytes, TRUE); 43405b261ecSmrg if (atom == BAD_RESOURCE) 43505b261ecSmrg return BadAlloc; 43605b261ecSmrg 43705b261ecSmrg pCursor->name = atom; 43805b261ecSmrg return(client->noClientException); 43905b261ecSmrg} 44005b261ecSmrg 44105b261ecSmrgint 44205b261ecSmrgSProcXFixesSetCursorName (ClientPtr client) 44305b261ecSmrg{ 44405b261ecSmrg int n; 44505b261ecSmrg REQUEST(xXFixesSetCursorNameReq); 44605b261ecSmrg 44705b261ecSmrg swaps (&stuff->length, n); 44805b261ecSmrg REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); 44905b261ecSmrg swapl (&stuff->cursor, n); 45005b261ecSmrg swaps (&stuff->nbytes, n); 45105b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 45205b261ecSmrg} 45305b261ecSmrg 45405b261ecSmrgint 45505b261ecSmrgProcXFixesGetCursorName (ClientPtr client) 45605b261ecSmrg{ 45705b261ecSmrg CursorPtr pCursor; 45805b261ecSmrg xXFixesGetCursorNameReply reply; 45905b261ecSmrg REQUEST(xXFixesGetCursorNameReq); 46005b261ecSmrg char *str; 46105b261ecSmrg int len; 46205b261ecSmrg 46305b261ecSmrg REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); 4644642e01fSmrg VERIFY_CURSOR(pCursor, stuff->cursor, client, DixGetAttrAccess); 46505b261ecSmrg if (pCursor->name) 46605b261ecSmrg str = NameForAtom (pCursor->name); 46705b261ecSmrg else 46805b261ecSmrg str = ""; 46905b261ecSmrg len = strlen (str); 47005b261ecSmrg 47105b261ecSmrg reply.type = X_Reply; 47205b261ecSmrg reply.length = (len + 3) >> 2; 47305b261ecSmrg reply.sequenceNumber = client->sequence; 47405b261ecSmrg reply.atom = pCursor->name; 47505b261ecSmrg reply.nbytes = len; 47605b261ecSmrg if (client->swapped) 47705b261ecSmrg { 47805b261ecSmrg int n; 47905b261ecSmrg swaps (&reply.sequenceNumber, n); 48005b261ecSmrg swapl (&reply.length, n); 48105b261ecSmrg swapl (&reply.atom, n); 48205b261ecSmrg swaps (&reply.nbytes, n); 48305b261ecSmrg } 48405b261ecSmrg WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply); 48505b261ecSmrg (void)WriteToClient(client, len, str); 48605b261ecSmrg 48705b261ecSmrg return(client->noClientException); 48805b261ecSmrg} 48905b261ecSmrg 49005b261ecSmrgint 49105b261ecSmrgSProcXFixesGetCursorName (ClientPtr client) 49205b261ecSmrg{ 49305b261ecSmrg int n; 49405b261ecSmrg REQUEST(xXFixesGetCursorNameReq); 49505b261ecSmrg 49605b261ecSmrg swaps (&stuff->length, n); 49705b261ecSmrg REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); 49805b261ecSmrg swapl (&stuff->cursor, n); 49905b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 50005b261ecSmrg} 50105b261ecSmrg 50205b261ecSmrgint 50305b261ecSmrgProcXFixesGetCursorImageAndName (ClientPtr client) 50405b261ecSmrg{ 50505b261ecSmrg/* REQUEST(xXFixesGetCursorImageAndNameReq); */ 50605b261ecSmrg xXFixesGetCursorImageAndNameReply *rep; 50705b261ecSmrg CursorPtr pCursor; 50805b261ecSmrg CARD32 *image; 50905b261ecSmrg int npixels; 51005b261ecSmrg char *name; 51105b261ecSmrg int nbytes, nbytesRound; 51205b261ecSmrg int width, height; 5134642e01fSmrg int rc, x, y; 51405b261ecSmrg 51505b261ecSmrg REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq); 51605b261ecSmrg pCursor = CursorCurrent; 51705b261ecSmrg if (!pCursor) 51805b261ecSmrg return BadCursor; 5194642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, 5204642e01fSmrg pCursor, RT_NONE, NULL, DixReadAccess|DixGetAttrAccess); 5214642e01fSmrg if (rc != Success) 5224642e01fSmrg return rc; 5234642e01fSmrg GetSpritePosition (PickPointer(client), &x, &y); 52405b261ecSmrg width = pCursor->bits->width; 52505b261ecSmrg height = pCursor->bits->height; 52605b261ecSmrg npixels = width * height; 52705b261ecSmrg name = pCursor->name ? NameForAtom (pCursor->name) : ""; 52805b261ecSmrg nbytes = strlen (name); 52905b261ecSmrg nbytesRound = (nbytes + 3) & ~3; 53005b261ecSmrg rep = xalloc (sizeof (xXFixesGetCursorImageAndNameReply) + 53105b261ecSmrg npixels * sizeof (CARD32) + nbytesRound); 53205b261ecSmrg if (!rep) 53305b261ecSmrg return BadAlloc; 53405b261ecSmrg 53505b261ecSmrg rep->type = X_Reply; 53605b261ecSmrg rep->sequenceNumber = client->sequence; 53705b261ecSmrg rep->length = npixels + (nbytesRound >> 2); 53805b261ecSmrg rep->width = width; 53905b261ecSmrg rep->height = height; 54005b261ecSmrg rep->x = x; 54105b261ecSmrg rep->y = y; 54205b261ecSmrg rep->xhot = pCursor->bits->xhot; 54305b261ecSmrg rep->yhot = pCursor->bits->yhot; 54405b261ecSmrg rep->cursorSerial = pCursor->serialNumber; 54505b261ecSmrg rep->cursorName = pCursor->name; 54605b261ecSmrg rep->nbytes = nbytes; 54705b261ecSmrg 54805b261ecSmrg image = (CARD32 *) (rep + 1); 54905b261ecSmrg CopyCursorToImage (pCursor, image); 55005b261ecSmrg memcpy ((image + npixels), name, nbytes); 55105b261ecSmrg if (client->swapped) 55205b261ecSmrg { 55305b261ecSmrg int n; 55405b261ecSmrg swaps (&rep->sequenceNumber, n); 55505b261ecSmrg swapl (&rep->length, n); 55605b261ecSmrg swaps (&rep->x, n); 55705b261ecSmrg swaps (&rep->y, n); 55805b261ecSmrg swaps (&rep->width, n); 55905b261ecSmrg swaps (&rep->height, n); 56005b261ecSmrg swaps (&rep->xhot, n); 56105b261ecSmrg swaps (&rep->yhot, n); 56205b261ecSmrg swapl (&rep->cursorSerial, n); 56305b261ecSmrg swapl (&rep->cursorName, n); 56405b261ecSmrg swaps (&rep->nbytes, n); 56505b261ecSmrg SwapLongs (image, npixels); 56605b261ecSmrg } 56705b261ecSmrg (void) WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) + 56805b261ecSmrg (npixels << 2) + nbytesRound, (char *) rep); 56905b261ecSmrg xfree (rep); 57005b261ecSmrg return client->noClientException; 57105b261ecSmrg} 57205b261ecSmrg 57305b261ecSmrgint 57405b261ecSmrgSProcXFixesGetCursorImageAndName (ClientPtr client) 57505b261ecSmrg{ 57605b261ecSmrg int n; 57705b261ecSmrg REQUEST(xXFixesGetCursorImageAndNameReq); 57805b261ecSmrg swaps (&stuff->length, n); 57905b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 58005b261ecSmrg} 58105b261ecSmrg 58205b261ecSmrg/* 58305b261ecSmrg * Find every cursor reference in the system, ask testCursor 58405b261ecSmrg * whether it should be replaced with a reference to pCursor. 58505b261ecSmrg */ 58605b261ecSmrg 58705b261ecSmrgtypedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure); 58805b261ecSmrg 58905b261ecSmrgtypedef struct { 59005b261ecSmrg RESTYPE type; 59105b261ecSmrg TestCursorFunc testCursor; 59205b261ecSmrg CursorPtr pNew; 59305b261ecSmrg pointer closure; 59405b261ecSmrg} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr; 59505b261ecSmrg 59605b261ecSmrgstatic const RESTYPE CursorRestypes[] = { 59705b261ecSmrg RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR 59805b261ecSmrg}; 59905b261ecSmrg 60005b261ecSmrg#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0])) 60105b261ecSmrg 60205b261ecSmrgstatic Bool 60305b261ecSmrgReplaceCursorLookup (pointer value, XID id, pointer closure) 60405b261ecSmrg{ 60505b261ecSmrg ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure; 60605b261ecSmrg WindowPtr pWin; 60705b261ecSmrg GrabPtr pGrab; 60805b261ecSmrg CursorPtr pCursor = 0, *pCursorRef = 0; 60905b261ecSmrg XID cursor = 0; 61005b261ecSmrg 61105b261ecSmrg switch (rcl->type) { 61205b261ecSmrg case RT_WINDOW: 61305b261ecSmrg pWin = (WindowPtr) value; 61405b261ecSmrg if (pWin->optional) 61505b261ecSmrg { 61605b261ecSmrg pCursorRef = &pWin->optional->cursor; 61705b261ecSmrg pCursor = *pCursorRef; 61805b261ecSmrg } 61905b261ecSmrg break; 62005b261ecSmrg case RT_PASSIVEGRAB: 62105b261ecSmrg pGrab = (GrabPtr) value; 62205b261ecSmrg pCursorRef = &pGrab->cursor; 62305b261ecSmrg pCursor = *pCursorRef; 62405b261ecSmrg break; 62505b261ecSmrg case RT_CURSOR: 62605b261ecSmrg pCursorRef = 0; 62705b261ecSmrg pCursor = (CursorPtr) value; 62805b261ecSmrg cursor = id; 62905b261ecSmrg break; 63005b261ecSmrg } 63105b261ecSmrg if (pCursor && pCursor != rcl->pNew) 63205b261ecSmrg { 63305b261ecSmrg if ((*rcl->testCursor) (pCursor, rcl->closure)) 63405b261ecSmrg { 63505b261ecSmrg rcl->pNew->refcnt++; 63605b261ecSmrg /* either redirect reference or update resource database */ 63705b261ecSmrg if (pCursorRef) 63805b261ecSmrg *pCursorRef = rcl->pNew; 63905b261ecSmrg else 64005b261ecSmrg ChangeResourceValue (id, RT_CURSOR, rcl->pNew); 64105b261ecSmrg FreeCursor (pCursor, cursor); 64205b261ecSmrg } 64305b261ecSmrg } 64405b261ecSmrg return FALSE; /* keep walking */ 64505b261ecSmrg} 64605b261ecSmrg 64705b261ecSmrgstatic void 64805b261ecSmrgReplaceCursor (CursorPtr pCursor, 64905b261ecSmrg TestCursorFunc testCursor, 65005b261ecSmrg pointer closure) 65105b261ecSmrg{ 65205b261ecSmrg int clientIndex; 65305b261ecSmrg int resIndex; 65405b261ecSmrg ReplaceCursorLookupRec rcl; 65505b261ecSmrg 65605b261ecSmrg /* 65705b261ecSmrg * Cursors exist only in the resource database, windows and grabs. 65805b261ecSmrg * All of these are always pointed at by the resource database. Walk 65905b261ecSmrg * the whole thing looking for cursors 66005b261ecSmrg */ 66105b261ecSmrg rcl.testCursor = testCursor; 66205b261ecSmrg rcl.pNew = pCursor; 66305b261ecSmrg rcl.closure = closure; 66405b261ecSmrg 66505b261ecSmrg /* for each client */ 66605b261ecSmrg for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++) 66705b261ecSmrg { 66805b261ecSmrg if (!clients[clientIndex]) 66905b261ecSmrg continue; 67005b261ecSmrg for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++) 67105b261ecSmrg { 67205b261ecSmrg rcl.type = CursorRestypes[resIndex]; 67305b261ecSmrg /* 67405b261ecSmrg * This function walks the entire client resource database 67505b261ecSmrg */ 67605b261ecSmrg LookupClientResourceComplex (clients[clientIndex], 67705b261ecSmrg rcl.type, 67805b261ecSmrg ReplaceCursorLookup, 67905b261ecSmrg (pointer) &rcl); 68005b261ecSmrg } 68105b261ecSmrg } 68205b261ecSmrg /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */ 68305b261ecSmrg WindowHasNewCursor (WindowTable[0]); 68405b261ecSmrg} 68505b261ecSmrg 68605b261ecSmrgstatic Bool 68705b261ecSmrgTestForCursor (CursorPtr pCursor, pointer closure) 68805b261ecSmrg{ 68905b261ecSmrg return (pCursor == (CursorPtr) closure); 69005b261ecSmrg} 69105b261ecSmrg 69205b261ecSmrgint 69305b261ecSmrgProcXFixesChangeCursor (ClientPtr client) 69405b261ecSmrg{ 69505b261ecSmrg CursorPtr pSource, pDestination; 69605b261ecSmrg REQUEST(xXFixesChangeCursorReq); 69705b261ecSmrg 69805b261ecSmrg REQUEST_SIZE_MATCH(xXFixesChangeCursorReq); 6994642e01fSmrg VERIFY_CURSOR (pSource, stuff->source, client, 7004642e01fSmrg DixReadAccess|DixGetAttrAccess); 7014642e01fSmrg VERIFY_CURSOR (pDestination, stuff->destination, client, 7024642e01fSmrg DixWriteAccess|DixSetAttrAccess); 70305b261ecSmrg 70405b261ecSmrg ReplaceCursor (pSource, TestForCursor, (pointer) pDestination); 70505b261ecSmrg return (client->noClientException); 70605b261ecSmrg} 70705b261ecSmrg 70805b261ecSmrgint 70905b261ecSmrgSProcXFixesChangeCursor (ClientPtr client) 71005b261ecSmrg{ 71105b261ecSmrg int n; 71205b261ecSmrg REQUEST(xXFixesChangeCursorReq); 71305b261ecSmrg 71405b261ecSmrg swaps (&stuff->length, n); 71505b261ecSmrg REQUEST_SIZE_MATCH(xXFixesChangeCursorReq); 71605b261ecSmrg swapl (&stuff->source, n); 71705b261ecSmrg swapl (&stuff->destination, n); 71805b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 71905b261ecSmrg} 72005b261ecSmrg 72105b261ecSmrgstatic Bool 72205b261ecSmrgTestForCursorName (CursorPtr pCursor, pointer closure) 72305b261ecSmrg{ 7244642e01fSmrg Atom *pName = closure; 7254642e01fSmrg return (pCursor->name == *pName); 72605b261ecSmrg} 72705b261ecSmrg 72805b261ecSmrgint 72905b261ecSmrgProcXFixesChangeCursorByName (ClientPtr client) 73005b261ecSmrg{ 73105b261ecSmrg CursorPtr pSource; 73205b261ecSmrg Atom name; 73305b261ecSmrg char *tchar; 73405b261ecSmrg REQUEST(xXFixesChangeCursorByNameReq); 73505b261ecSmrg 73605b261ecSmrg REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes); 7374642e01fSmrg VERIFY_CURSOR(pSource, stuff->source, client, 7384642e01fSmrg DixReadAccess|DixGetAttrAccess); 73905b261ecSmrg tchar = (char *) &stuff[1]; 74005b261ecSmrg name = MakeAtom (tchar, stuff->nbytes, FALSE); 74105b261ecSmrg if (name) 7424642e01fSmrg ReplaceCursor (pSource, TestForCursorName, &name); 74305b261ecSmrg return (client->noClientException); 74405b261ecSmrg} 74505b261ecSmrg 74605b261ecSmrgint 74705b261ecSmrgSProcXFixesChangeCursorByName (ClientPtr client) 74805b261ecSmrg{ 74905b261ecSmrg int n; 75005b261ecSmrg REQUEST(xXFixesChangeCursorByNameReq); 75105b261ecSmrg 75205b261ecSmrg swaps (&stuff->length, n); 75305b261ecSmrg REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq); 75405b261ecSmrg swapl (&stuff->source, n); 75505b261ecSmrg swaps (&stuff->nbytes, n); 75605b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 75705b261ecSmrg} 75805b261ecSmrg 75905b261ecSmrg/* 76005b261ecSmrg * Routines for manipulating the per-screen hide counts list. 76105b261ecSmrg * This list indicates which clients have requested cursor hiding 76205b261ecSmrg * for that screen. 76305b261ecSmrg */ 76405b261ecSmrg 76505b261ecSmrg/* Return the screen's hide-counts list element for the given client */ 76605b261ecSmrgstatic CursorHideCountPtr 76705b261ecSmrgfindCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) 76805b261ecSmrg{ 76905b261ecSmrg CursorScreenPtr cs = GetCursorScreen(pScreen); 77005b261ecSmrg CursorHideCountPtr pChc; 77105b261ecSmrg 77205b261ecSmrg for (pChc = cs->pCursorHideCounts; pChc != NULL; pChc = pChc->pNext) { 77305b261ecSmrg if (pChc->pClient == pClient) { 77405b261ecSmrg return pChc; 77505b261ecSmrg } 77605b261ecSmrg } 77705b261ecSmrg 77805b261ecSmrg return NULL; 77905b261ecSmrg} 78005b261ecSmrg 78105b261ecSmrgstatic int 78205b261ecSmrgcreateCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) 78305b261ecSmrg{ 78405b261ecSmrg CursorScreenPtr cs = GetCursorScreen(pScreen); 78505b261ecSmrg CursorHideCountPtr pChc; 78605b261ecSmrg 78705b261ecSmrg pChc = (CursorHideCountPtr) xalloc(sizeof(CursorHideCountRec)); 78805b261ecSmrg if (pChc == NULL) { 78905b261ecSmrg return BadAlloc; 79005b261ecSmrg } 79105b261ecSmrg pChc->pClient = pClient; 79205b261ecSmrg pChc->pScreen = pScreen; 79305b261ecSmrg pChc->hideCount = 1; 79405b261ecSmrg pChc->resource = FakeClientID(pClient->index); 79505b261ecSmrg pChc->pNext = cs->pCursorHideCounts; 79605b261ecSmrg cs->pCursorHideCounts = pChc; 79705b261ecSmrg 79805b261ecSmrg /* 79905b261ecSmrg * Create a resource for this element so it can be deleted 80005b261ecSmrg * when the client goes away. 80105b261ecSmrg */ 80205b261ecSmrg if (!AddResource (pChc->resource, CursorHideCountType, 80305b261ecSmrg (pointer) pChc)) { 80405b261ecSmrg xfree(pChc); 80505b261ecSmrg return BadAlloc; 80605b261ecSmrg } 80705b261ecSmrg 80805b261ecSmrg return Success; 80905b261ecSmrg} 81005b261ecSmrg 81105b261ecSmrg/* 81205b261ecSmrg * Delete the given hide-counts list element from its screen list. 81305b261ecSmrg */ 81405b261ecSmrgstatic void 81505b261ecSmrgdeleteCursorHideCount (CursorHideCountPtr pChcToDel, ScreenPtr pScreen) 81605b261ecSmrg{ 81705b261ecSmrg CursorScreenPtr cs = GetCursorScreen(pScreen); 81805b261ecSmrg CursorHideCountPtr pChc, pNext; 81905b261ecSmrg CursorHideCountPtr pChcLast = NULL; 82005b261ecSmrg 82105b261ecSmrg pChc = cs->pCursorHideCounts; 82205b261ecSmrg while (pChc != NULL) { 82305b261ecSmrg pNext = pChc->pNext; 82405b261ecSmrg if (pChc == pChcToDel) { 82505b261ecSmrg xfree(pChc); 82605b261ecSmrg if (pChcLast == NULL) { 82705b261ecSmrg cs->pCursorHideCounts = pNext; 82805b261ecSmrg } else { 82905b261ecSmrg pChcLast->pNext = pNext; 83005b261ecSmrg } 83105b261ecSmrg return; 83205b261ecSmrg } 83305b261ecSmrg pChcLast = pChc; 83405b261ecSmrg pChc = pNext; 83505b261ecSmrg } 83605b261ecSmrg} 83705b261ecSmrg 83805b261ecSmrg/* 83905b261ecSmrg * Delete all the hide-counts list elements for this screen. 84005b261ecSmrg */ 84105b261ecSmrgstatic void 84205b261ecSmrgdeleteCursorHideCountsForScreen (ScreenPtr pScreen) 84305b261ecSmrg{ 84405b261ecSmrg CursorScreenPtr cs = GetCursorScreen(pScreen); 84505b261ecSmrg CursorHideCountPtr pChc, pTmp; 84605b261ecSmrg 84705b261ecSmrg pChc = cs->pCursorHideCounts; 84805b261ecSmrg while (pChc != NULL) { 84905b261ecSmrg pTmp = pChc->pNext; 85005b261ecSmrg FreeResource(pChc->resource, 0); 85105b261ecSmrg pChc = pTmp; 85205b261ecSmrg } 85305b261ecSmrg cs->pCursorHideCounts = NULL; 85405b261ecSmrg} 85505b261ecSmrg 85605b261ecSmrgint 85705b261ecSmrgProcXFixesHideCursor (ClientPtr client) 85805b261ecSmrg{ 85905b261ecSmrg WindowPtr pWin; 86005b261ecSmrg CursorHideCountPtr pChc; 86105b261ecSmrg REQUEST(xXFixesHideCursorReq); 86205b261ecSmrg int ret; 86305b261ecSmrg 86405b261ecSmrg REQUEST_SIZE_MATCH (xXFixesHideCursorReq); 86505b261ecSmrg 8664642e01fSmrg ret = dixLookupResource((pointer *)&pWin, stuff->window, RT_WINDOW, 8674642e01fSmrg client, DixGetAttrAccess); 8684642e01fSmrg if (ret != Success) { 86905b261ecSmrg client->errorValue = stuff->window; 8704642e01fSmrg return (ret == BadValue) ? BadWindow : ret; 87105b261ecSmrg } 87205b261ecSmrg 87305b261ecSmrg /* 87405b261ecSmrg * Has client hidden the cursor before on this screen? 87505b261ecSmrg * If so, just increment the count. 87605b261ecSmrg */ 87705b261ecSmrg 87805b261ecSmrg pChc = findCursorHideCount(client, pWin->drawable.pScreen); 87905b261ecSmrg if (pChc != NULL) { 88005b261ecSmrg pChc->hideCount++; 88105b261ecSmrg return client->noClientException; 88205b261ecSmrg } 88305b261ecSmrg 88405b261ecSmrg /* 88505b261ecSmrg * This is the first time this client has hid the cursor 88605b261ecSmrg * for this screen. 88705b261ecSmrg */ 8884642e01fSmrg ret = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 8894642e01fSmrg DixHideAccess); 8904642e01fSmrg if (ret != Success) 8914642e01fSmrg return ret; 8924642e01fSmrg 89305b261ecSmrg ret = createCursorHideCount(client, pWin->drawable.pScreen); 89405b261ecSmrg 89505b261ecSmrg if (ret == Success) { 8964642e01fSmrg (void) CursorDisplayCursor(PickPointer(client), pWin->drawable.pScreen, CursorCurrent); 89705b261ecSmrg } 89805b261ecSmrg 89905b261ecSmrg return ret; 90005b261ecSmrg} 90105b261ecSmrg 90205b261ecSmrgint 90305b261ecSmrgSProcXFixesHideCursor (ClientPtr client) 90405b261ecSmrg{ 90505b261ecSmrg int n; 90605b261ecSmrg REQUEST(xXFixesHideCursorReq); 90705b261ecSmrg 90805b261ecSmrg swaps (&stuff->length, n); 90905b261ecSmrg REQUEST_SIZE_MATCH (xXFixesHideCursorReq); 91005b261ecSmrg swapl (&stuff->window, n); 91105b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 91205b261ecSmrg} 91305b261ecSmrg 91405b261ecSmrgint 91505b261ecSmrgProcXFixesShowCursor (ClientPtr client) 91605b261ecSmrg{ 91705b261ecSmrg WindowPtr pWin; 91805b261ecSmrg CursorHideCountPtr pChc; 9194642e01fSmrg int rc; 92005b261ecSmrg REQUEST(xXFixesShowCursorReq); 92105b261ecSmrg 92205b261ecSmrg REQUEST_SIZE_MATCH (xXFixesShowCursorReq); 92305b261ecSmrg 9244642e01fSmrg rc = dixLookupResource((pointer *)&pWin, stuff->window, RT_WINDOW, 9254642e01fSmrg client, DixGetAttrAccess); 9264642e01fSmrg if (rc != Success) { 92705b261ecSmrg client->errorValue = stuff->window; 9284642e01fSmrg return (rc == BadValue) ? BadWindow : rc; 92905b261ecSmrg } 93005b261ecSmrg 93105b261ecSmrg /* 93205b261ecSmrg * Has client hidden the cursor on this screen? 93305b261ecSmrg * If not, generate an error. 93405b261ecSmrg */ 93505b261ecSmrg pChc = findCursorHideCount(client, pWin->drawable.pScreen); 93605b261ecSmrg if (pChc == NULL) { 93705b261ecSmrg return BadMatch; 93805b261ecSmrg } 93905b261ecSmrg 9404642e01fSmrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 9414642e01fSmrg DixShowAccess); 9424642e01fSmrg if (rc != Success) 9434642e01fSmrg return rc; 9444642e01fSmrg 94505b261ecSmrg pChc->hideCount--; 94605b261ecSmrg if (pChc->hideCount <= 0) { 94705b261ecSmrg FreeResource(pChc->resource, 0); 94805b261ecSmrg } 94905b261ecSmrg 95005b261ecSmrg return (client->noClientException); 95105b261ecSmrg} 95205b261ecSmrg 95305b261ecSmrgint 95405b261ecSmrgSProcXFixesShowCursor (ClientPtr client) 95505b261ecSmrg{ 95605b261ecSmrg int n; 95705b261ecSmrg REQUEST(xXFixesShowCursorReq); 95805b261ecSmrg 95905b261ecSmrg swaps (&stuff->length, n); 96005b261ecSmrg REQUEST_SIZE_MATCH (xXFixesShowCursorReq); 96105b261ecSmrg swapl (&stuff->window, n); 96205b261ecSmrg return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 96305b261ecSmrg} 96405b261ecSmrg 96505b261ecSmrgstatic int 96605b261ecSmrgCursorFreeClient (pointer data, XID id) 96705b261ecSmrg{ 96805b261ecSmrg CursorEventPtr old = (CursorEventPtr) data; 96905b261ecSmrg CursorEventPtr *prev, e; 97005b261ecSmrg 97105b261ecSmrg for (prev = &cursorEvents; (e = *prev); prev = &e->next) 97205b261ecSmrg { 97305b261ecSmrg if (e == old) 97405b261ecSmrg { 97505b261ecSmrg *prev = e->next; 97605b261ecSmrg xfree (e); 97705b261ecSmrg break; 97805b261ecSmrg } 97905b261ecSmrg } 98005b261ecSmrg return 1; 98105b261ecSmrg} 98205b261ecSmrg 98305b261ecSmrgstatic int 98405b261ecSmrgCursorFreeHideCount (pointer data, XID id) 98505b261ecSmrg{ 98605b261ecSmrg CursorHideCountPtr pChc = (CursorHideCountPtr) data; 98705b261ecSmrg ScreenPtr pScreen = pChc->pScreen; 98805b261ecSmrg 98905b261ecSmrg deleteCursorHideCount(pChc, pChc->pScreen); 9904642e01fSmrg (void) CursorDisplayCursor(inputInfo.pointer, pScreen, CursorCurrent); 99105b261ecSmrg 99205b261ecSmrg return 1; 99305b261ecSmrg} 99405b261ecSmrg 99505b261ecSmrgstatic int 99605b261ecSmrgCursorFreeWindow (pointer data, XID id) 99705b261ecSmrg{ 99805b261ecSmrg WindowPtr pWindow = (WindowPtr) data; 99905b261ecSmrg CursorEventPtr e, next; 100005b261ecSmrg 100105b261ecSmrg for (e = cursorEvents; e; e = next) 100205b261ecSmrg { 100305b261ecSmrg next = e->next; 100405b261ecSmrg if (e->pWindow == pWindow) 100505b261ecSmrg { 100605b261ecSmrg FreeResource (e->clientResource, 0); 100705b261ecSmrg } 100805b261ecSmrg } 100905b261ecSmrg return 1; 101005b261ecSmrg} 101105b261ecSmrg 101205b261ecSmrgstatic CursorPtr 101305b261ecSmrgcreateInvisibleCursor (void) 101405b261ecSmrg{ 101505b261ecSmrg CursorPtr pCursor; 101605b261ecSmrg static unsigned int *psrcbits, *pmaskbits; 101705b261ecSmrg CursorMetricRec cm; 10184642e01fSmrg int rc; 101905b261ecSmrg 102005b261ecSmrg psrcbits = (unsigned int *) xalloc(4); 102105b261ecSmrg pmaskbits = (unsigned int *) xalloc(4); 102205b261ecSmrg if (psrcbits == NULL || pmaskbits == NULL) { 102305b261ecSmrg return NULL; 102405b261ecSmrg } 102505b261ecSmrg *psrcbits = 0; 102605b261ecSmrg *pmaskbits = 0; 102705b261ecSmrg 102805b261ecSmrg cm.width = 1; 102905b261ecSmrg cm.height = 1; 103005b261ecSmrg cm.xhot = 0; 103105b261ecSmrg cm.yhot = 0; 103205b261ecSmrg 10334642e01fSmrg rc = AllocARGBCursor( 103405b261ecSmrg (unsigned char *)psrcbits, 103505b261ecSmrg (unsigned char *)pmaskbits, 10364642e01fSmrg NULL, &cm, 10374642e01fSmrg 0, 0, 0, 103805b261ecSmrg 0, 0, 0, 10394642e01fSmrg &pCursor, serverClient, (XID)0); 104005b261ecSmrg 104105b261ecSmrg return pCursor; 104205b261ecSmrg} 104305b261ecSmrg 104405b261ecSmrgBool 104505b261ecSmrgXFixesCursorInit (void) 104605b261ecSmrg{ 104705b261ecSmrg int i; 10484642e01fSmrg 10494642e01fSmrg if (party_like_its_1989) 10504642e01fSmrg CursorVisible = TRUE; 105105b261ecSmrg 105205b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) 105305b261ecSmrg { 105405b261ecSmrg ScreenPtr pScreen = screenInfo.screens[i]; 105505b261ecSmrg CursorScreenPtr cs; 105605b261ecSmrg 105705b261ecSmrg cs = (CursorScreenPtr) xalloc (sizeof (CursorScreenRec)); 105805b261ecSmrg if (!cs) 105905b261ecSmrg return FALSE; 106005b261ecSmrg Wrap (cs, pScreen, CloseScreen, CursorCloseScreen); 106105b261ecSmrg Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); 106205b261ecSmrg cs->pCursorHideCounts = NULL; 106305b261ecSmrg SetCursorScreen (pScreen, cs); 106405b261ecSmrg } 106505b261ecSmrg CursorClientType = CreateNewResourceType(CursorFreeClient); 106605b261ecSmrg CursorHideCountType = CreateNewResourceType(CursorFreeHideCount); 106705b261ecSmrg CursorWindowType = CreateNewResourceType(CursorFreeWindow); 106805b261ecSmrg 106905b261ecSmrg if (pInvisibleCursor == NULL) { 107005b261ecSmrg pInvisibleCursor = createInvisibleCursor(); 107105b261ecSmrg if (pInvisibleCursor == NULL) { 107205b261ecSmrg return BadAlloc; 107305b261ecSmrg } 107405b261ecSmrg } 107505b261ecSmrg 107605b261ecSmrg return CursorClientType && CursorWindowType; 107705b261ecSmrg} 107805b261ecSmrg 1079