diff options
Diffstat (limited to 'xorg-server/xfixes/cursor.c')
-rw-r--r-- | xorg-server/xfixes/cursor.c | 140 |
1 files changed, 85 insertions, 55 deletions
diff --git a/xorg-server/xfixes/cursor.c b/xorg-server/xfixes/cursor.c index fc83f0a4b..bd2856500 100644 --- a/xorg-server/xfixes/cursor.c +++ b/xorg-server/xfixes/cursor.c @@ -1,23 +1,30 @@ /* - * Copyright © 2006 Sun Microsystems + * Copyright © 2006 Sun Microsystems, Inc. All rights reserved. * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Sun Microsystems not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Sun Microsystems makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. * - * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS 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 + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. * * Copyright © 2002 Keith Packard * @@ -58,7 +65,7 @@ static RESTYPE CursorClientType; static RESTYPE CursorHideCountType; static RESTYPE CursorWindowType; -static CursorPtr CursorCurrent; +static CursorPtr CursorCurrent[MAXDEVICES]; static CursorPtr pInvisibleCursor = NULL; static int CursorScreenPrivateKeyIndex; @@ -66,14 +73,19 @@ static DevPrivateKey CursorScreenPrivateKey = &CursorScreenPrivateKeyIndex; static void deleteCursorHideCountsForScreen (ScreenPtr pScreen); -#define VERIFY_CURSOR(pCursor, cursor, client, access) { \ - pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \ - RT_CURSOR, (access)); \ - if (!pCursor) { \ - (client)->errorValue = (cursor); \ - return BadCursor; \ - } \ -} +#define VERIFY_CURSOR(pCursor, cursor, client, access) \ + do { \ + int err; \ + err = dixLookupResourceByType((pointer *) &pCursor, cursor, \ + RT_CURSOR, client, access); \ + if (err == BadValue) { \ + client->errorValue = cursor; \ + return BadCursor; \ + } else if (err != Success) { \ + client->errorValue = cursor; \ + return err; \ + } \ + } while (0) /* * There is a global list of windows selecting for cursor events @@ -121,11 +133,13 @@ typedef struct _CursorScreen { #define GetCursorScreenIfSet(s) GetCursorScreen(s) #define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p) #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) -#define Unwrap(as,s,elt) ((s)->elt = (as)->elt) +#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt) /* The cursor doesn't show up until the first XDefineCursor() */ static Bool CursorVisible = FALSE; +Bool EnableCursor = TRUE; + static Bool CursorDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, @@ -133,15 +147,16 @@ CursorDisplayCursor (DeviceIntPtr pDev, { CursorScreenPtr cs = GetCursorScreen(pScreen); Bool ret; + DisplayCursorProcPtr backupProc; - Unwrap (cs, pScreen, DisplayCursor); + Unwrap (cs, pScreen, DisplayCursor, backupProc); /* * Have to check ConnectionInfo to distinguish client requests from * initial root window setup. Not a great way to do it, I admit. */ if (ConnectionInfo) - CursorVisible = TRUE; + CursorVisible = EnableCursor; if (cs->pCursorHideCounts != NULL || !CursorVisible) { ret = ((*pScreen->RealizeCursor)(pDev, pScreen, pInvisibleCursor) && @@ -150,11 +165,11 @@ CursorDisplayCursor (DeviceIntPtr pDev, ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); } - if (pCursor != CursorCurrent) + if (pCursor != CursorCurrent[pDev->id]) { CursorEventPtr e; - CursorCurrent = pCursor; + CursorCurrent[pDev->id] = pCursor; for (e = cursorEvents; e; e = e->next) { if ((e->eventMask & XFixesDisplayCursorNotifyMask) && @@ -172,7 +187,8 @@ CursorDisplayCursor (DeviceIntPtr pDev, } } } - Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); + Wrap (cs, pScreen, DisplayCursor, backupProc); + return ret; } @@ -181,9 +197,11 @@ CursorCloseScreen (int index, ScreenPtr pScreen) { CursorScreenPtr cs = GetCursorScreen (pScreen); Bool ret; + CloseScreenProcPtr close_proc; + DisplayCursorProcPtr display_proc; - Unwrap (cs, pScreen, CloseScreen); - Unwrap (cs, pScreen, DisplayCursor); + Unwrap (cs, pScreen, CloseScreen, close_proc); + Unwrap (cs, pScreen, DisplayCursor, display_proc); deleteCursorHideCountsForScreen(pScreen); ret = (*pScreen->CloseScreen) (index, pScreen); xfree (cs); @@ -198,6 +216,8 @@ XFixesSelectCursorInput (ClientPtr pClient, CARD32 eventMask) { CursorEventPtr *prev, e; + pointer val; + int rc; for (prev = &cursorEvents; (e = *prev); prev = &e->next) { @@ -230,7 +250,10 @@ XFixesSelectCursorInput (ClientPtr pClient, * Add a resource hanging from the window to * catch window destroy */ - if (!LookupIDByType(pWindow->drawable.id, CursorWindowType)) + rc = dixLookupResourceByType( &val, pWindow->drawable.id, + CursorWindowType, serverClient, + DixGetAttrAccess); + if (rc != Success) if (!AddResource (pWindow->drawable.id, CursorWindowType, (pointer) pWindow)) { @@ -363,7 +386,7 @@ ProcXFixesGetCursorImage (ClientPtr client) int npixels, width, height, rc, x, y; REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq); - pCursor = CursorCurrent; + pCursor = CursorCurrent[PickPointer(client)->id]; if (!pCursor) return BadCursor; rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, @@ -406,7 +429,7 @@ ProcXFixesGetCursorImage (ClientPtr client) swapl (&rep->cursorSerial, n); SwapLongs (image, npixels); } - (void) WriteToClient(client, sizeof (xXFixesGetCursorImageReply) + + WriteToClient(client, sizeof (xXFixesGetCursorImageReply) + (npixels << 2), (char *) rep); xfree (rep); return client->noClientException; @@ -459,7 +482,7 @@ ProcXFixesGetCursorName (ClientPtr client) CursorPtr pCursor; xXFixesGetCursorNameReply reply; REQUEST(xXFixesGetCursorNameReq); - char *str; + const char *str; int len; REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); @@ -471,7 +494,7 @@ ProcXFixesGetCursorName (ClientPtr client) len = strlen (str); reply.type = X_Reply; - reply.length = (len + 3) >> 2; + reply.length = bytes_to_int32(len); reply.sequenceNumber = client->sequence; reply.atom = pCursor->name; reply.nbytes = len; @@ -484,7 +507,7 @@ ProcXFixesGetCursorName (ClientPtr client) swaps (&reply.nbytes, n); } WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply); - (void)WriteToClient(client, len, str); + WriteToClient(client, len, str); return(client->noClientException); } @@ -509,13 +532,13 @@ ProcXFixesGetCursorImageAndName (ClientPtr client) CursorPtr pCursor; CARD32 *image; int npixels; - char *name; + const char *name; int nbytes, nbytesRound; int width, height; int rc, x, y; REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq); - pCursor = CursorCurrent; + pCursor = CursorCurrent[PickPointer(client)->id]; if (!pCursor) return BadCursor; rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, @@ -528,7 +551,7 @@ ProcXFixesGetCursorImageAndName (ClientPtr client) npixels = width * height; name = pCursor->name ? NameForAtom (pCursor->name) : ""; nbytes = strlen (name); - nbytesRound = (nbytes + 3) & ~3; + nbytesRound = pad_to_int32(nbytes); rep = xalloc (sizeof (xXFixesGetCursorImageAndNameReply) + npixels * sizeof (CARD32) + nbytesRound); if (!rep) @@ -536,7 +559,7 @@ ProcXFixesGetCursorImageAndName (ClientPtr client) rep->type = X_Reply; rep->sequenceNumber = client->sequence; - rep->length = npixels + (nbytesRound >> 2); + rep->length = npixels + bytes_to_int32(nbytesRound); rep->width = width; rep->height = height; rep->x = x; @@ -566,7 +589,7 @@ ProcXFixesGetCursorImageAndName (ClientPtr client) swaps (&rep->nbytes, n); SwapLongs (image, npixels); } - (void) WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) + + WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) + (npixels << 2) + nbytesRound, (char *) rep); xfree (rep); return client->noClientException; @@ -895,7 +918,12 @@ ProcXFixesHideCursor (ClientPtr client) ret = createCursorHideCount(client, pWin->drawable.pScreen); if (ret == Success) { - (void) CursorDisplayCursor(PickPointer(client), pWin->drawable.pScreen, CursorCurrent); + DeviceIntPtr dev; + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) && IsPointerDevice(dev)) + CursorDisplayCursor(dev, pWin->drawable.pScreen, CursorCurrent[dev->id]); + } } return ret; @@ -987,9 +1015,14 @@ CursorFreeHideCount (pointer data, XID id) { CursorHideCountPtr pChc = (CursorHideCountPtr) data; ScreenPtr pScreen = pChc->pScreen; + DeviceIntPtr dev; deleteCursorHideCount(pChc, pChc->pScreen); - (void) CursorDisplayCursor(inputInfo.pointer, pScreen, CursorCurrent); + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) && IsPointerDevice(dev)) + CursorDisplayCursor(dev, pScreen, CursorCurrent[dev->id]); + } return 1; } @@ -1015,12 +1048,11 @@ static CursorPtr createInvisibleCursor (void) { CursorPtr pCursor; - static unsigned int *psrcbits, *pmaskbits; + unsigned char *psrcbits, *pmaskbits; CursorMetricRec cm; - int rc; - psrcbits = (unsigned int *) xalloc(4); - pmaskbits = (unsigned int *) xalloc(4); + psrcbits = (unsigned char *) xalloc(4); + pmaskbits = (unsigned char *) xalloc(4); if (psrcbits == NULL || pmaskbits == NULL) { return NULL; } @@ -1032,9 +1064,7 @@ createInvisibleCursor (void) cm.xhot = 0; cm.yhot = 0; - rc = AllocARGBCursor( - (unsigned char *)psrcbits, - (unsigned char *)pmaskbits, + AllocARGBCursor(psrcbits, pmaskbits, NULL, &cm, 0, 0, 0, 0, 0, 0, @@ -1049,7 +1079,7 @@ XFixesCursorInit (void) int i; if (party_like_its_1989) - CursorVisible = TRUE; + CursorVisible = EnableCursor; for (i = 0; i < screenInfo.numScreens; i++) { |