aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/xfixes/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/xfixes/cursor.c')
-rw-r--r--xorg-server/xfixes/cursor.c140
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++)
{