summaryrefslogtreecommitdiff
path: root/xfixes
diff options
context:
space:
mode:
authorStuart Kreitman <stuart.kreitman@sun.com>2004-07-29 14:33:43 +0000
committerStuart Kreitman <stuart.kreitman@sun.com>2004-07-29 14:33:43 +0000
commit6ed1c3845517c7731dcc74baa51bb801838afaff (patch)
tree36b4ef8bf8a3806d11af6024883925d5491f9873 /xfixes
parent736e511824c4f5e77e637c680a4e45f0b7631644 (diff)
bugzilla 859 -merging DAMAGE-XFIXES into trunk
Diffstat (limited to 'xfixes')
-rwxr-xr-xxfixes/cursor.c752
-rwxr-xr-xxfixes/region.c796
-rwxr-xr-xxfixes/saveset.c78
-rwxr-xr-xxfixes/select.c278
-rwxr-xr-xxfixes/xfixes.c225
-rwxr-xr-xxfixes/xfixes.h50
-rwxr-xr-xxfixes/xfixesint.h233
7 files changed, 2412 insertions, 0 deletions
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
new file mode 100755
index 000000000..2464f1abb
--- /dev/null
+++ b/xfixes/cursor.c
@@ -0,0 +1,752 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xfixesint.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixevents.h"
+#include "servermd.h"
+#include "inputstr.h"
+#include "windowstr.h"
+
+static RESTYPE CursorClientType;
+static RESTYPE CursorWindowType;
+static int CursorScreenPrivateIndex = -1;
+static int CursorGeneration;
+static CursorPtr CursorCurrent;
+
+#define VERIFY_CURSOR(pCursor, cursor, client, access) { \
+ pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \
+ RT_CURSOR, (access)); \
+ if (!pCursor) { \
+ (client)->errorValue = (cursor); \
+ return BadCursor; \
+ } \
+}
+
+/*
+ * There is a global list of windows selecting for cursor events
+ */
+
+typedef struct _CursorEvent *CursorEventPtr;
+
+typedef struct _CursorEvent {
+ CursorEventPtr next;
+ CARD32 eventMask;
+ ClientPtr pClient;
+ WindowPtr pWindow;
+ XID clientResource;
+} CursorEventRec;
+
+static CursorEventPtr cursorEvents;
+
+/*
+ * Wrap DisplayCursor to catch cursor change events
+ */
+
+typedef struct _CursorScreen {
+ DisplayCursorProcPtr DisplayCursor;
+ CloseScreenProcPtr CloseScreen;
+} CursorScreenRec, *CursorScreenPtr;
+
+#define GetCursorScreen(s) ((CursorScreenPtr) ((s)->devPrivates[CursorScreenPrivateIndex].ptr))
+#define GetCursorScreenIfSet(s) ((CursorScreenPrivateIndex != -1) ? GetCursorScreen(s) : NULL)
+#define SetCursorScreen(s,p) ((s)->devPrivates[CursorScreenPrivateIndex].ptr = (pointer) (p))
+#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
+#define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
+
+static Bool
+CursorDisplayCursor (ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ Bool ret;
+
+ Unwrap (cs, pScreen, DisplayCursor);
+ ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
+ if (pCursor != CursorCurrent)
+ {
+ CursorEventPtr e;
+
+ CursorCurrent = pCursor;
+ for (e = cursorEvents; e; e = e->next)
+ {
+ if (e->eventMask & XFixesDisplayCursorNotifyMask)
+ {
+ xXFixesCursorNotifyEvent ev;
+ ev.type = XFixesEventBase + XFixesCursorNotify;
+ ev.subtype = XFixesDisplayCursorNotify;
+ ev.sequenceNumber = e->pClient->sequence;
+ ev.window = e->pWindow->drawable.id;
+ ev.cursorSerial = pCursor->serialNumber;
+ ev.timestamp = currentTime.milliseconds;
+ ev.name = pCursor->name;
+ WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
+ }
+ }
+ }
+ Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
+ return ret;
+}
+
+static Bool
+CursorCloseScreen (int index, ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen (pScreen);
+ Bool ret;
+
+ Unwrap (cs, pScreen, CloseScreen);
+ Unwrap (cs, pScreen, DisplayCursor);
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ xfree (cs);
+ if (index == 0)
+ CursorScreenPrivateIndex = -1;
+ return ret;
+}
+
+#define CursorAllEvents (XFixesDisplayCursorNotifyMask)
+
+static int
+XFixesSelectCursorInput (ClientPtr pClient,
+ WindowPtr pWindow,
+ CARD32 eventMask)
+{
+ CursorEventPtr *prev, e;
+
+ for (prev = &cursorEvents; (e = *prev); prev = &e->next)
+ {
+ if (e->pClient == pClient &&
+ e->pWindow == pWindow)
+ {
+ break;
+ }
+ }
+ if (!eventMask)
+ {
+ if (e)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ return Success;
+ }
+ if (!e)
+ {
+ e = (CursorEventPtr) xalloc (sizeof (CursorEventRec));
+ if (!e)
+ return BadAlloc;
+
+ e->next = 0;
+ e->pClient = pClient;
+ e->pWindow = pWindow;
+ e->clientResource = FakeClientID(pClient->index);
+
+ /*
+ * Add a resource hanging from the window to
+ * catch window destroy
+ */
+ if (!LookupIDByType(pWindow->drawable.id, CursorWindowType))
+ if (!AddResource (pWindow->drawable.id, CursorWindowType,
+ (pointer) pWindow))
+ {
+ xfree (e);
+ return BadAlloc;
+ }
+
+ if (!AddResource (e->clientResource, CursorClientType, (pointer) e))
+ return BadAlloc;
+
+ *prev = e;
+ }
+ e->eventMask = eventMask;
+ return Success;
+}
+
+int
+ProcXFixesSelectCursorInput (ClientPtr client)
+{
+ REQUEST (xXFixesSelectCursorInputReq);
+ WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (stuff->eventMask & ~CursorAllEvents)
+ {
+ client->errorValue = stuff->eventMask;
+ return( BadValue );
+ }
+ return XFixesSelectCursorInput (client, pWin, stuff->eventMask);
+}
+
+static int
+GetBit (unsigned char *line, int x)
+{
+ unsigned char mask;
+
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ mask = (1 << (x & 7));
+ else
+ mask = (0x80 >> (x & 7));
+ /* XXX assumes byte order is host byte order */
+ line += (x >> 3);
+ if (*line & mask)
+ return 1;
+ return 0;
+}
+
+int
+SProcXFixesSelectCursorInput (ClientPtr client)
+{
+ register int n;
+ REQUEST(xXFixesSelectCursorInputReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->eventMask, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+void
+SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
+ xXFixesCursorNotifyEvent *to)
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->window, to->window);
+ cpswapl (from->cursorSerial, to->cursorSerial);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->name, to->name);
+}
+
+static void
+CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
+{
+ int width = pCursor->bits->width;
+ int height = pCursor->bits->height;
+ int npixels = width * height;
+
+#ifdef ARGB_CURSOR
+ if (pCursor->bits->argb)
+ memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32));
+ else
+#endif
+ {
+ unsigned char *srcLine = pCursor->bits->source;
+ unsigned char *mskLine = pCursor->bits->mask;
+ int stride = BitmapBytePad (width);
+ int x, y;
+ CARD32 fg, bg;
+
+ fg = (0xff000000 |
+ ((pCursor->foreRed & 0xff00) << 8) |
+ (pCursor->foreGreen & 0xff00) |
+ (pCursor->foreBlue >> 8));
+ bg = (0xff000000 |
+ ((pCursor->backRed & 0xff00) << 8) |
+ (pCursor->backGreen & 0xff00) |
+ (pCursor->backBlue >> 8));
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ if (GetBit (mskLine, x))
+ {
+ if (GetBit (srcLine, x))
+ *image++ = fg;
+ else
+ *image++ = bg;
+ }
+ else
+ *image++ = 0;
+ }
+ srcLine += stride;
+ mskLine += stride;
+ }
+ }
+}
+
+int
+ProcXFixesGetCursorImage (ClientPtr client)
+{
+/* REQUEST(xXFixesGetCursorImageReq); */
+ xXFixesGetCursorImageReply *rep;
+ CursorPtr pCursor;
+ CARD32 *image;
+ int npixels;
+ int width, height;
+ int x, y;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq);
+ pCursor = CursorCurrent;
+ if (!pCursor)
+ return BadCursor;
+ GetSpritePosition (&x, &y);
+ width = pCursor->bits->width;
+ height = pCursor->bits->height;
+ npixels = width * height;
+ rep = xalloc (sizeof (xXFixesGetCursorImageReply) +
+ npixels * sizeof (CARD32));
+ if (!rep)
+ return BadAlloc;
+
+ rep->type = X_Reply;
+ rep->sequenceNumber = client->sequence;
+ rep->length = npixels;
+ rep->width = width;
+ rep->height = height;
+ rep->x = x;
+ rep->y = y;
+ rep->xhot = pCursor->bits->xhot;
+ rep->yhot = pCursor->bits->yhot;
+ rep->cursorSerial = pCursor->serialNumber;
+
+ image = (CARD32 *) (rep + 1);
+ CopyCursorToImage (pCursor, image);
+ if (client->swapped)
+ {
+ int n;
+ swaps (&rep->sequenceNumber, n);
+ swapl (&rep->length, n);
+ swaps (&rep->x, n);
+ swaps (&rep->y, n);
+ swaps (&rep->width, n);
+ swaps (&rep->height, n);
+ swaps (&rep->xhot, n);
+ swaps (&rep->yhot, n);
+ swapl (&rep->cursorSerial, n);
+ SwapLongs (image, npixels);
+ }
+ (void) WriteToClient(client, sizeof (xXFixesGetCursorImageReply) +
+ (npixels << 2), (char *) rep);
+ xfree (rep);
+ return client->noClientException;
+}
+
+int
+SProcXFixesGetCursorImage (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesGetCursorImageReq);
+ swaps (&stuff->length, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetCursorName (ClientPtr client)
+{
+ CursorPtr pCursor;
+ char *tchar;
+ REQUEST(xXFixesSetCursorNameReq);
+ Atom atom;
+
+ REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
+ VERIFY_CURSOR(pCursor, stuff->cursor, client, SecurityWriteAccess);
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom (tchar, stuff->nbytes, TRUE);
+ if (atom == BAD_RESOURCE)
+ return BadAlloc;
+
+ pCursor->name = atom;
+ return(client->noClientException);
+}
+
+int
+SProcXFixesSetCursorName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesSetCursorNameReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
+ swapl (&stuff->cursor, n);
+ swaps (&stuff->nbytes, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesGetCursorName (ClientPtr client)
+{
+ CursorPtr pCursor;
+ xXFixesGetCursorNameReply reply;
+ REQUEST(xXFixesGetCursorNameReq);
+ char *str;
+ int len;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
+ VERIFY_CURSOR(pCursor, stuff->cursor, client, SecurityReadAccess);
+ if (pCursor->name)
+ str = NameForAtom (pCursor->name);
+ else
+ str = "";
+ len = strlen (str);
+
+ reply.type = X_Reply;
+ reply.length = (len + 3) >> 2;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = pCursor->name;
+ reply.nbytes = len;
+ if (client->swapped)
+ {
+ int n;
+ swaps (&reply.sequenceNumber, n);
+ swapl (&reply.length, n);
+ swapl (&reply.atom, n);
+ swaps (&reply.nbytes, n);
+ }
+ WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply);
+ (void)WriteToClient(client, len, str);
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesGetCursorName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesSetCursorNameReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
+ swapl (&stuff->cursor, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesGetCursorImageAndName (ClientPtr client)
+{
+/* REQUEST(xXFixesGetCursorImageAndNameReq); */
+ xXFixesGetCursorImageAndNameReply *rep;
+ CursorPtr pCursor;
+ CARD32 *image;
+ int npixels;
+ char *name;
+ int nbytes, nbytesRound;
+ int width, height;
+ int x, y;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq);
+ pCursor = CursorCurrent;
+ if (!pCursor)
+ return BadCursor;
+ GetSpritePosition (&x, &y);
+ width = pCursor->bits->width;
+ height = pCursor->bits->height;
+ npixels = width * height;
+ name = pCursor->name ? NameForAtom (pCursor->name) : "";
+ nbytes = strlen (name);
+ nbytesRound = (nbytes + 3) & ~3;
+ rep = xalloc (sizeof (xXFixesGetCursorImageAndNameReply) +
+ npixels * sizeof (CARD32) + nbytesRound);
+ if (!rep)
+ return BadAlloc;
+
+ rep->type = X_Reply;
+ rep->sequenceNumber = client->sequence;
+ rep->length = npixels + (nbytesRound >> 2);
+ rep->width = width;
+ rep->height = height;
+ rep->x = x;
+ rep->y = y;
+ rep->xhot = pCursor->bits->xhot;
+ rep->yhot = pCursor->bits->yhot;
+ rep->cursorSerial = pCursor->serialNumber;
+ rep->cursorName = pCursor->name;
+ rep->nbytes = nbytes;
+
+ image = (CARD32 *) (rep + 1);
+ CopyCursorToImage (pCursor, image);
+ memcpy ((image + npixels), name, nbytes);
+ if (client->swapped)
+ {
+ int n;
+ swaps (&rep->sequenceNumber, n);
+ swapl (&rep->length, n);
+ swaps (&rep->x, n);
+ swaps (&rep->y, n);
+ swaps (&rep->width, n);
+ swaps (&rep->height, n);
+ swaps (&rep->xhot, n);
+ swaps (&rep->yhot, n);
+ swapl (&rep->cursorSerial, n);
+ swapl (&rep->cursorName, n);
+ swaps (&rep->nbytes, n);
+ SwapLongs (image, npixels);
+ }
+ (void) WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) +
+ (npixels << 2) + nbytesRound, (char *) rep);
+ xfree (rep);
+ return client->noClientException;
+}
+
+int
+SProcXFixesGetCursorImageAndName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesGetCursorImageAndNameReq);
+ swaps (&stuff->length, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+/*
+ * Find every cursor reference in the system, ask testCursor
+ * whether it should be replaced with a reference to pCursor.
+ */
+
+typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure);
+
+typedef struct {
+ RESTYPE type;
+ TestCursorFunc testCursor;
+ CursorPtr pNew;
+ pointer closure;
+} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr;
+
+static const RESTYPE CursorRestypes[] = {
+ RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR
+};
+
+#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0]))
+
+static Bool
+ReplaceCursorLookup (pointer value, XID id, pointer closure)
+{
+ ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure;
+ WindowPtr pWin;
+ GrabPtr pGrab;
+ CursorPtr pCursor = 0, *pCursorRef = 0;
+ XID cursor = 0;
+
+ switch (rcl->type) {
+ case RT_WINDOW:
+ pWin = (WindowPtr) value;
+ if (pWin->optional)
+ {
+ pCursorRef = &pWin->optional->cursor;
+ pCursor = *pCursorRef;
+ }
+ break;
+ case RT_PASSIVEGRAB:
+ pGrab = (GrabPtr) value;
+ pCursorRef = &pGrab->cursor;
+ pCursor = *pCursorRef;
+ break;
+ case RT_CURSOR:
+ pCursorRef = 0;
+ pCursor = (CursorPtr) value;
+ cursor = id;
+ break;
+ }
+ if (pCursor && pCursor != rcl->pNew)
+ {
+ if ((*rcl->testCursor) (pCursor, rcl->closure))
+ {
+ rcl->pNew->refcnt++;
+ /* either redirect reference or update resource database */
+ if (pCursorRef)
+ *pCursorRef = rcl->pNew;
+ else
+ ChangeResourceValue (id, RT_CURSOR, rcl->pNew);
+ FreeCursor (pCursor, cursor);
+ }
+ }
+ return FALSE; /* keep walking */
+}
+
+static void
+ReplaceCursor (CursorPtr pCursor,
+ TestCursorFunc testCursor,
+ pointer closure)
+{
+ int clientIndex;
+ int resIndex;
+ ReplaceCursorLookupRec rcl;
+
+ /*
+ * Cursors exist only in the resource database, windows and grabs.
+ * All of these are always pointed at by the resource database. Walk
+ * the whole thing looking for cursors
+ */
+ rcl.testCursor = testCursor;
+ rcl.pNew = pCursor;
+ rcl.closure = closure;
+
+ /* for each client */
+ for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++)
+ {
+ if (!clients[clientIndex])
+ continue;
+ for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++)
+ {
+ rcl.type = CursorRestypes[resIndex];
+ /*
+ * This function walks the entire client resource database
+ */
+ LookupClientResourceComplex (clients[clientIndex],
+ rcl.type,
+ ReplaceCursorLookup,
+ (pointer) &rcl);
+ }
+ }
+ /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
+ WindowHasNewCursor (WindowTable[0]);
+}
+
+static Bool
+TestForCursor (CursorPtr pCursor, pointer closure)
+{
+ return (pCursor == (CursorPtr) closure);
+}
+
+int
+ProcXFixesChangeCursor (ClientPtr client)
+{
+ CursorPtr pSource, pDestination;
+ REQUEST(xXFixesChangeCursorReq);
+
+ REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
+ VERIFY_CURSOR (pSource, stuff->source, client, SecurityReadAccess);
+ VERIFY_CURSOR (pDestination, stuff->destination, client, SecurityWriteAccess);
+
+ ReplaceCursor (pSource, TestForCursor, (pointer) pDestination);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesChangeCursor (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesChangeCursorReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
+ swapl (&stuff->source, n);
+ swapl (&stuff->destination, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static Bool
+TestForCursorName (CursorPtr pCursor, pointer closure)
+{
+ return (pCursor->name == (Atom) closure);
+}
+
+int
+ProcXFixesChangeCursorByName (ClientPtr client)
+{
+ CursorPtr pSource;
+ Atom name;
+ char *tchar;
+ REQUEST(xXFixesChangeCursorByNameReq);
+
+ REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes);
+ VERIFY_CURSOR(pSource, stuff->source, client, SecurityReadAccess);
+ tchar = (char *) &stuff[1];
+ name = MakeAtom (tchar, stuff->nbytes, FALSE);
+ if (name)
+ ReplaceCursor (pSource, TestForCursorName, (pointer) name);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesChangeCursorByName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesChangeCursorByNameReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq);
+ swapl (&stuff->source, n);
+ swaps (&stuff->nbytes, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static int
+CursorFreeClient (pointer data, XID id)
+{
+ CursorEventPtr old = (CursorEventPtr) data;
+ CursorEventPtr *prev, e;
+
+ for (prev = &cursorEvents; (e = *prev); prev = &e->next)
+ {
+ if (e == old)
+ {
+ *prev = e->next;
+ xfree (e);
+ break;
+ }
+ }
+ return 1;
+}
+
+static int
+CursorFreeWindow (pointer data, XID id)
+{
+ WindowPtr pWindow = (WindowPtr) data;
+ CursorEventPtr e, next;
+
+ for (e = cursorEvents; e; e = next)
+ {
+ next = e->next;
+ if (e->pWindow == pWindow)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ }
+ return 1;
+}
+
+Bool
+XFixesCursorInit (void)
+{
+ int i;
+
+ if (CursorGeneration != serverGeneration)
+ {
+ CursorScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (CursorScreenPrivateIndex < 0)
+ return FALSE;
+ CursorGeneration = serverGeneration;
+ }
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ CursorScreenPtr cs;
+
+ cs = (CursorScreenPtr) xalloc (sizeof (CursorScreenRec));
+ if (!cs)
+ return FALSE;
+ Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
+ Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
+ SetCursorScreen (pScreen, cs);
+ }
+ CursorClientType = CreateNewResourceType(CursorFreeClient);
+ CursorWindowType = CreateNewResourceType(CursorFreeWindow);
+ return CursorClientType && CursorWindowType;
+}
+
diff --git a/xfixes/region.c b/xfixes/region.c
new file mode 100755
index 000000000..6deef4b95
--- /dev/null
+++ b/xfixes/region.c
@@ -0,0 +1,796 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xfixesint.h"
+#include "scrnintstr.h"
+#ifdef RENDER
+#include <picturestr.h>
+extern int RenderErrBase;
+#endif
+#include <regionstr.h>
+#include <gcstruct.h>
+#include <window.h>
+#ifdef SKK
+#ifdef SHAPE
+#include <shapeint.h>
+#endif
+#endif
+
+RESTYPE RegionResType;
+
+static int
+RegionResFree (pointer data, XID id)
+{
+ RegionPtr pRegion = (RegionPtr) data;
+
+ REGION_DESTROY (0, pRegion);
+ return Success;
+}
+
+RegionPtr
+XFixesRegionCopy (RegionPtr pRegion)
+{
+ RegionPtr pNew = REGION_CREATE (0, REGION_EXTENTS(0, pRegion),
+ REGION_NUM_RECTS(pRegion));
+ if (!pNew)
+ return 0;
+ if (!REGION_COPY (0, pNew, pRegion))
+ {
+ REGION_DESTROY (0, pNew);
+ return 0;
+ }
+ return pNew;
+}
+
+Bool
+XFixesRegionInit (void)
+{
+ RegionResType = CreateNewResourceType(RegionResFree);
+ return TRUE;
+}
+
+int
+ProcXFixesCreateRegion (ClientPtr client)
+{
+ int things;
+ RegionPtr pRegion;
+ REQUEST (xXFixesCreateRegionReq);
+
+ REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq);
+ if (things & 4)
+ return BadLength;
+ things >>= 3;
+
+ pRegion = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED);
+ if (!pRegion)
+ return BadAlloc;
+ if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegion (ClientPtr client)
+{
+ register int n;
+ REQUEST(xXFixesCreateRegionReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq);
+ swapl(&stuff->region, n);
+ SwapRestS(stuff);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromBitmap (ClientPtr client)
+{
+ RegionPtr pRegion;
+ PixmapPtr pPixmap;
+ REQUEST (xXFixesCreateRegionFromBitmapReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ pPixmap = (PixmapPtr) SecurityLookupIDByType (client, stuff->bitmap,
+ RT_PIXMAP,
+ SecurityReadAccess);
+ if (!pPixmap)
+ {
+ client->errorValue = stuff->bitmap;
+ return BadPixmap;
+ }
+ if (pPixmap->drawable.depth != 1)
+ return BadMatch;
+
+ pRegion = BITMAP_TO_REGION(pPixmap->drawable.pScreen, pPixmap);
+
+ if (!pRegion)
+ return BadAlloc;
+
+ if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegionFromBitmap (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesCreateRegionFromBitmapReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromBitmapReq);
+ swapl(&stuff->region, n);
+ swapl(&stuff->bitmap, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+
+int
+ProcXFixesCreateRegionFromWindow (ClientPtr client)
+{
+ RegionPtr pRegion;
+ Bool copy = TRUE;
+ WindowPtr pWin;
+ REQUEST (xXFixesCreateRegionFromWindowReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+ pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->window;
+ return BadWindow;
+ }
+ switch (stuff->kind) {
+ case WindowRegionBounding:
+#ifdef SHAPE
+ pRegion = wBoundingShape(pWin);
+ if (!pRegion)
+#endif
+ {
+ pRegion = CreateBoundingShape (pWin);
+ copy = FALSE;
+ }
+ break;
+ case WindowRegionClip:
+#ifdef SHAPE
+ pRegion = wClipShape(pWin);
+ if (!pRegion)
+#endif
+ {
+ pRegion = CreateClipShape (pWin);
+ copy = FALSE;
+ }
+ break;
+ default:
+ client->errorValue = stuff->kind;
+ return BadValue;
+ }
+ if (copy && pRegion)
+ pRegion = XFixesRegionCopy (pRegion);
+ if (!pRegion)
+ return BadAlloc;
+ if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegionFromWindow (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesCreateRegionFromWindowReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromWindowReq);
+ swapl(&stuff->region, n);
+ swapl(&stuff->window, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromGC (ClientPtr client)
+{
+ RegionPtr pRegion, pClip;
+ GCPtr pGC;
+ REQUEST (xXFixesCreateRegionFromGCReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityReadAccess);
+
+ switch (pGC->clientClipType) {
+ case CT_PIXMAP:
+ pRegion = BITMAP_TO_REGION(pGC->pScreen, (PixmapPtr) pGC->clientClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ case CT_REGION:
+ pClip = (RegionPtr) pGC->clientClip;
+ pRegion = XFixesRegionCopy (pClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ default:
+ return BadImplementation; /* assume sane server bits */
+ }
+
+ if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCreateRegionFromGC (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesCreateRegionFromGCReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromGCReq);
+ swapl(&stuff->region, n);
+ swapl(&stuff->gc, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCreateRegionFromPicture (ClientPtr client)
+{
+#ifdef RENDER
+ RegionPtr pRegion;
+ PicturePtr pPicture;
+ REQUEST (xXFixesCreateRegionFromPictureReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ VERIFY_PICTURE(pPicture, stuff->picture, client, SecurityReadAccess,
+ RenderErrBase + BadPicture);
+
+ switch (pPicture->clientClipType) {
+ case CT_PIXMAP:
+ pRegion = BITMAP_TO_REGION(pPicture->pDrawable->pScreen,
+ (PixmapPtr) pPicture->clientClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ case CT_REGION:
+ pRegion = XFixesRegionCopy ((RegionPtr) pPicture->clientClip);
+ if (!pRegion)
+ return BadAlloc;
+ break;
+ default:
+ return BadImplementation; /* assume sane server bits */
+ }
+
+ if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
+ return BadAlloc;
+
+ return(client->noClientException);
+#else
+ return BadRequest;
+#endif
+}
+
+int
+SProcXFixesCreateRegionFromPicture (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesCreateRegionFromPictureReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesCreateRegionFromPictureReq);
+ swapl(&stuff->region, n);
+ swapl(&stuff->picture, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesDestroyRegion (ClientPtr client)
+{
+ REQUEST (xXFixesDestroyRegionReq);
+ RegionPtr pRegion;
+
+ REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, SecurityWriteAccess);
+ FreeResource (stuff->region, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+SProcXFixesDestroyRegion (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesDestroyRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq);
+ swapl (&stuff->region, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetRegion (ClientPtr client)
+{
+ int things;
+ RegionPtr pRegion, pNew;
+ REQUEST (xXFixesSetRegionReq);
+
+ REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, SecurityWriteAccess);
+
+ things = (client->req_len << 2) - sizeof (xXFixesCreateRegionReq);
+ if (things & 4)
+ return BadLength;
+ things >>= 3;
+
+ pNew = RECTS_TO_REGION(0, things, (xRectangle *) (stuff + 1), CT_UNSORTED);
+ if (!pNew)
+ return BadAlloc;
+ if (!REGION_COPY (0, pRegion, pNew))
+ {
+ REGION_DESTROY (0, pNew);
+ return BadAlloc;
+ }
+ REGION_DESTROY (0, pNew);
+ return(client->noClientException);
+}
+
+int
+SProcXFixesSetRegion (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesSetRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq);
+ swapl (&stuff->region, n);
+ SwapRestS(stuff);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCopyRegion (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ REQUEST (xXFixesCopyRegionReq);
+
+ VERIFY_REGION(pSource, stuff->source, client, SecurityReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, SecurityWriteAccess);
+
+ if (!REGION_COPY(pScreen, pDestination, pSource))
+ return BadAlloc;
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesCopyRegion (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesCopyRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq);
+ swapl (&stuff->source, n);
+ swapl (&stuff->destination, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesCombineRegion (ClientPtr client)
+{
+ RegionPtr pSource1, pSource2, pDestination;
+ int ret = Success;
+ REQUEST (xXFixesCombineRegionReq);
+
+ REQUEST_SIZE_MATCH (xXFixesCombineRegionReq);
+ VERIFY_REGION(pSource1, stuff->source1, client, SecurityReadAccess);
+ VERIFY_REGION(pSource2, stuff->source2, client, SecurityReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, SecurityWriteAccess);
+
+ switch (stuff->xfixesReqType) {
+ case X_XFixesUnionRegion:
+ if (!REGION_UNION (0, pDestination, pSource1, pSource2))
+ ret = BadAlloc;
+ break;
+ case X_XFixesIntersectRegion:
+ if (!REGION_INTERSECT (0, pDestination, pSource1, pSource2))
+ ret = BadAlloc;
+ break;
+ case X_XFixesSubtractRegion:
+ if (!REGION_SUBTRACT (0, pDestination, pSource1, pSource2))
+ ret = BadAlloc;
+ break;
+ }
+
+ if (ret == Success)
+ ret = client->noClientException;
+ return ret;
+}
+
+int
+SProcXFixesCombineRegion (ClientPtr client)
+{
+ int n;
+ REQUEST (xXFixesCombineRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesCombineRegionReq);
+ swapl (&stuff->source1, n);
+ swapl (&stuff->source2, n);
+ swapl (&stuff->destination, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesInvertRegion (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ BoxRec bounds;
+ int ret = Success;
+ REQUEST(xXFixesInvertRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
+ VERIFY_REGION(pSource, stuff->source, client, SecurityReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, SecurityWriteAccess);
+
+ /* Compute bounds, limit to 16 bits */
+ bounds.x1 = stuff->x;
+ bounds.y1 = stuff->y;
+ if ((int) stuff->x + (int) stuff->width > MAXSHORT)
+ bounds.x2 = MAXSHORT;
+ else
+ bounds.x2 = stuff->x + stuff->width;
+
+ if ((int) stuff->y + (int) stuff->height > MAXSHORT)
+ bounds.y2 = MAXSHORT;
+ else
+ bounds.y2 = stuff->y + stuff->height;
+
+ if (!REGION_INVERSE(0, pDestination, pSource, &bounds))
+ ret = BadAlloc;
+
+ if (ret == Success)
+ ret = client->noClientException;
+ return ret;
+}
+
+int
+SProcXFixesInvertRegion (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesInvertRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesInvertRegionReq);
+ swapl (&stuff->source, n);
+ swaps (&stuff->x, n);
+ swaps (&stuff->y, n);
+ swaps (&stuff->width, n);
+ swaps (&stuff->height, n);
+ swapl (&stuff->destination, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesTranslateRegion (ClientPtr client)
+{
+ RegionPtr pRegion;
+ REQUEST(xXFixesTranslateRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, SecurityWriteAccess);
+
+ REGION_TRANSLATE(pScreen, pRegion, stuff->dx, stuff->dy);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesTranslateRegion (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesTranslateRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq);
+ swapl (&stuff->region, n);
+ swaps (&stuff->dx, n);
+ swaps (&stuff->dy, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesRegionExtents (ClientPtr client)
+{
+ RegionPtr pSource, pDestination;
+ REQUEST(xXFixesRegionExtentsReq);
+
+ REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
+ VERIFY_REGION(pSource, stuff->source, client, SecurityReadAccess);
+ VERIFY_REGION(pDestination, stuff->destination, client, SecurityWriteAccess);
+
+ REGION_RESET (0, pDestination, REGION_EXTENTS (0, pSource));
+
+ return (client->noClientException);
+}
+
+int
+SProcXFixesRegionExtents (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesRegionExtentsReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq);
+ swapl (&stuff->source, n);
+ swapl (&stuff->destination, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesFetchRegion (ClientPtr client)
+{
+ RegionPtr pRegion;
+ xXFixesFetchRegionReply *reply;
+ xRectangle *pRect;
+ BoxPtr pExtent;
+ BoxPtr pBox;
+ int i, nBox;
+ REQUEST(xXFixesFetchRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
+ VERIFY_REGION(pRegion, stuff->region, client, SecurityReadAccess);
+
+ pExtent = REGION_EXTENTS (0, pRegion);
+ pBox = REGION_RECTS (pRegion);
+ nBox = REGION_NUM_RECTS (pRegion);
+
+ reply = xalloc (sizeof (xXFixesFetchRegionReply) +
+ nBox * sizeof (xRectangle));
+ if (!reply)
+ return BadAlloc;
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = nBox << 1;
+ reply->x = pExtent->x1;
+ reply->y = pExtent->y1;
+ reply->width = pExtent->x2 - pExtent->x1;
+ reply->height = pExtent->y2 - pExtent->y1;
+
+ pRect = (xRectangle *) (reply + 1);
+ for (i = 0; i < nBox; i++)
+ {
+ pRect[i].x = pBox[i].x1;
+ pRect[i].y = pBox[i].y1;
+ pRect[i].width = pBox[i].x2 - pBox[i].x1;
+ pRect[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+ if (client->swapped)
+ {
+ int n;
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ swaps (&reply->x, n);
+ swaps (&reply->y, n);
+ swaps (&reply->width, n);
+ swaps (&reply->height, n);
+ SwapShorts ((INT16 *) pRect, nBox * 4);
+ }
+ (void) WriteToClient(client, sizeof (xXFixesFetchRegionReply) +
+ nBox * sizeof (xRectangle), (char *) reply);
+ xfree (reply);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesFetchRegion (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesFetchRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesFetchRegionReq);
+ swapl (&stuff->region, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetGCClipRegion (ClientPtr client)
+{
+ GCPtr pGC;
+ RegionPtr pRegion;
+ XID vals[2];
+ REQUEST(xXFixesSetGCClipRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+ VERIFY_REGION_OR_NONE (pRegion, stuff->region, client, SecurityReadAccess);
+
+ if (pRegion)
+ {
+ pRegion = XFixesRegionCopy (pRegion);
+ if (!pRegion)
+ return BadAlloc;
+ }
+
+ vals[0] = stuff->xOrigin;
+ vals[1] = stuff->yOrigin;
+ DoChangeGC (pGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
+ (*pGC->funcs->ChangeClip)(pGC, pRegion ? CT_REGION : CT_NONE, (pointer)pRegion, 0);
+
+ return (client->noClientException);
+}
+
+int
+SProcXFixesSetGCClipRegion (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesSetGCClipRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq);
+ swapl (&stuff->gc, n);
+ swapl (&stuff->region, n);
+ swaps (&stuff->xOrigin, n);
+ swaps (&stuff->yOrigin, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+typedef RegionPtr (*CreateDftPtr)(WindowPtr pWin);
+
+int
+ProcXFixesSetWindowShapeRegion (ClientPtr client)
+{
+#ifdef SHAPE
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ RegionPtr pRegion;
+ RegionPtr *pDestRegion;
+ int destBounding;
+ REQUEST(xXFixesSetWindowShapeRegionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
+ pWin = (WindowPtr) LookupIDByType (stuff->dest, RT_WINDOW);
+ if (!pWin)
+ {
+ client->errorValue = stuff->dest;
+ return BadWindow;
+ }
+ VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, SecurityWriteAccess);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destBounding = 1;
+ break;
+ case ShapeClip:
+ destBounding = 0;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (pRegion)
+ {
+ pRegion = XFixesRegionCopy (pRegion);
+ if (!pRegion)
+ return BadAlloc;
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ if (destBounding)
+ pDestRegion = &pWin->optional->boundingShape;
+ else
+ pDestRegion = &pWin->optional->clipShape;
+ if (stuff->xOff || stuff->yOff)
+ REGION_TRANSLATE (0, pRegion, stuff->xOff, stuff->yOff);
+ }
+ else
+ {
+ if (pWin->optional)
+ {
+ if (destBounding)
+ pDestRegion = &pWin->optional->boundingShape;
+ else
+ pDestRegion = &pWin->optional->clipShape;
+ }
+ else
+ pDestRegion = &pRegion; /* a NULL region pointer */
+ }
+ if (*pDestRegion)
+ REGION_DESTROY(pScreen, *pDestRegion);
+ *pDestRegion = pRegion;
+ (*pScreen->SetShape) (pWin);
+ SendShapeNotify (pWin, stuff->destKind);
+ return (client->noClientException);
+#else
+ return BadRequest;
+#endif
+}
+
+int
+SProcXFixesSetWindowShapeRegion (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesSetWindowShapeRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ swapl (&stuff->region, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetPictureClipRegion (ClientPtr client)
+{
+#ifdef RENDER
+ PicturePtr pPicture;
+ RegionPtr pRegion;
+ ScreenPtr pScreen;
+ PictureScreenPtr ps;
+ REQUEST(xXFixesSetPictureClipRegionReq);
+
+ REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq);
+ VERIFY_PICTURE(pPicture, stuff->picture, client, SecurityWriteAccess,
+ RenderErrBase + BadPicture);
+ pScreen = pPicture->pDrawable->pScreen;
+ ps = GetPictureScreen (pScreen);
+ VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, SecurityReadAccess);
+
+ return SetPictureClipRegion (pPicture, stuff->xOrigin, stuff->yOrigin,
+ pRegion);
+#else
+ return BadRequest;
+#endif
+}
+
+int
+SProcXFixesSetPictureClipRegion (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesSetPictureClipRegionReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesSetPictureClipRegionReq);
+ swapl (&stuff->picture, n);
+ swapl (&stuff->region, n);
+ swaps (&stuff->xOrigin, n);
+ swaps (&stuff->yOrigin, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
diff --git a/xfixes/saveset.c b/xfixes/saveset.c
new file mode 100755
index 000000000..83d8c12f1
--- /dev/null
+++ b/xfixes/saveset.c
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xfixesint.h"
+
+int
+ProcXFixesChangeSaveSet(ClientPtr client)
+{
+ Bool toRoot, remap;
+ int result;
+ WindowPtr pWin;
+ REQUEST(xXFixesChangeSaveSetReq);
+
+ REQUEST_SIZE_MATCH(xXFixesChangeSaveSetReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode != SetModeInsert) && (stuff->mode != SetModeDelete))
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+ if ((stuff->target != SaveSetNearest) && (stuff->target != SaveSetRoot))
+ {
+ client->errorValue = stuff->target;
+ return( BadValue );
+ }
+ if ((stuff->map != SaveSetMap) && (stuff->map != SaveSetUnmap))
+ {
+ client->errorValue = stuff->map;
+ return( BadValue );
+ }
+ toRoot = (stuff->target == SaveSetRoot);
+ remap = (stuff->map == SaveSetMap);
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, toRoot, remap);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+SProcXFixesChangeSaveSet(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXFixesChangeSaveSetReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ return ProcXFixesChangeSaveSet(client);
+}
diff --git a/xfixes/select.c b/xfixes/select.c
new file mode 100755
index 000000000..6cccfa504
--- /dev/null
+++ b/xfixes/select.c
@@ -0,0 +1,278 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xfixesint.h"
+
+static RESTYPE SelectionClientType, SelectionWindowType;
+static Bool SelectionCallbackRegistered = FALSE;
+
+/*
+ * There is a global list of windows selecting for selection events
+ * on every selection. This should be plenty efficient for the
+ * expected usage, if it does become a problem, it should be easily
+ * replaced with a hash table of some kind keyed off the selection atom
+ */
+
+typedef struct _SelectionEvent *SelectionEventPtr;
+
+typedef struct _SelectionEvent {
+ SelectionEventPtr next;
+ Atom selection;
+ CARD32 eventMask;
+ ClientPtr pClient;
+ WindowPtr pWindow;
+ XID clientResource;
+} SelectionEventRec;
+
+static SelectionEventPtr selectionEvents;
+
+static void
+XFixesSelectionCallback (CallbackListPtr *callbacks, pointer data, pointer args)
+{
+ SelectionEventPtr e;
+ SelectionInfoRec *info = (SelectionInfoRec *) args;
+ Selection *selection = info->selection;
+ int subtype;
+ CARD32 eventMask;
+
+ switch (info->kind) {
+ case SelectionSetOwner:
+ subtype = XFixesSetSelectionOwnerNotify;
+ eventMask = XFixesSetSelectionOwnerNotifyMask;
+ break;
+ case SelectionWindowDestroy:
+ subtype = XFixesSelectionWindowDestroyNotify;
+ eventMask = XFixesSelectionWindowDestroyNotifyMask;
+ break;
+ case SelectionClientClose:
+ subtype = XFixesSelectionClientCloseNotify;
+ eventMask = XFixesSelectionClientCloseNotifyMask;
+ break;
+ default:
+ return;
+ }
+ for (e = selectionEvents; e; e = e->next)
+ {
+ if (e->selection == selection->selection && (e->eventMask & eventMask))
+ {
+ xXFixesSelectionNotifyEvent ev;
+
+ ev.type = XFixesEventBase + XFixesSelectionNotify;
+ ev.subtype = subtype;
+ ev.sequenceNumber = e->pClient->sequence;
+ ev.window = e->pWindow->drawable.id;
+ if (subtype == XFixesSetSelectionOwnerNotify)
+ ev.owner = selection->window;
+ else
+ ev.owner = 0;
+ ev.selection = e->selection;
+ ev.timestamp = currentTime.milliseconds;
+ ev.selectionTimestamp = selection->lastTimeChanged.milliseconds;
+ WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
+ }
+ }
+}
+
+static Bool
+CheckSelectionCallback (void)
+{
+ if (selectionEvents)
+ {
+ if (!SelectionCallbackRegistered)
+ {
+ if (!AddCallback (&SelectionCallback, XFixesSelectionCallback, NULL))
+ return FALSE;
+ SelectionCallbackRegistered = TRUE;
+ }
+ }
+ else
+ {
+ if (SelectionCallbackRegistered)
+ {
+ DeleteCallback (&SelectionCallback, XFixesSelectionCallback, NULL);
+ SelectionCallbackRegistered = FALSE;
+ }
+ }
+ return TRUE;
+}
+
+#define SelectionAllEvents (XFixesSetSelectionOwnerNotifyMask |\
+ XFixesSelectionWindowDestroyNotifyMask |\
+ XFixesSelectionClientCloseNotifyMask)
+
+static int
+XFixesSelectSelectionInput (ClientPtr pClient,
+ Atom selection,
+ WindowPtr pWindow,
+ CARD32 eventMask)
+{
+ SelectionEventPtr *prev, e;
+
+ for (prev = &selectionEvents; (e = *prev); prev = &e->next)
+ {
+ if (e->selection == selection &&
+ e->pClient == pClient &&
+ e->pWindow == pWindow)
+ {
+ break;
+ }
+ }
+ if (!eventMask)
+ {
+ if (e)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ return Success;
+ }
+ if (!e)
+ {
+ e = (SelectionEventPtr) xalloc (sizeof (SelectionEventRec));
+ if (!e)
+ return BadAlloc;
+
+ e->next = 0;
+ e->selection = selection;
+ e->pClient = pClient;
+ e->pWindow = pWindow;
+ e->clientResource = FakeClientID(pClient->index);
+
+ /*
+ * Add a resource hanging from the window to
+ * catch window destroy
+ */
+ if (!LookupIDByType(pWindow->drawable.id, SelectionWindowType))
+ if (!AddResource (pWindow->drawable.id, SelectionWindowType,
+ (pointer) pWindow))
+ {
+ xfree (e);
+ return BadAlloc;
+ }
+
+ if (!AddResource (e->clientResource, SelectionClientType, (pointer) e))
+ return BadAlloc;
+
+ *prev = e;
+ if (!CheckSelectionCallback ())
+ {
+ FreeResource (e->clientResource, 0);
+ return BadAlloc;
+ }
+ }
+ e->eventMask = eventMask;
+ return Success;
+}
+
+int
+ProcXFixesSelectSelectionInput (ClientPtr client)
+{
+ REQUEST (xXFixesSelectSelectionInputReq);
+ WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH (xXFixesSelectSelectionInputReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ if (stuff->eventMask & ~SelectionAllEvents)
+ {
+ client->errorValue = stuff->eventMask;
+ return( BadValue );
+ }
+ return XFixesSelectSelectionInput (client, stuff->selection,
+ pWin, stuff->eventMask);
+}
+
+int
+SProcXFixesSelectSelectionInput (ClientPtr client)
+{
+ register int n;
+ REQUEST(xXFixesSelectSelectionInputReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->selection, n);
+ swapl(&stuff->eventMask, n);
+ return ProcXFixesSelectSelectionInput(client);
+}
+
+void
+SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from,
+ xXFixesSelectionNotifyEvent *to)
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->window, to->window);
+ cpswapl (from->owner, to->owner);
+ cpswapl (from->selection, to->selection);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->selectionTimestamp, to->selectionTimestamp);
+}
+
+static int
+SelectionFreeClient (pointer data, XID id)
+{
+ SelectionEventPtr old = (SelectionEventPtr) data;
+ SelectionEventPtr *prev, e;
+
+ for (prev = &selectionEvents; (e = *prev); prev = &e->next)
+ {
+ if (e == old)
+ {
+ *prev = e->next;
+ xfree (e);
+ CheckSelectionCallback ();
+ break;
+ }
+ }
+ return 1;
+}
+
+static int
+SelectionFreeWindow (pointer data, XID id)
+{
+ WindowPtr pWindow = (WindowPtr) data;
+ SelectionEventPtr e, next;
+
+ for (e = selectionEvents; e; e = next)
+ {
+ next = e->next;
+ if (e->pWindow == pWindow)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ }
+ return 1;
+}
+
+Bool
+XFixesSelectionInit (void)
+{
+ SelectionClientType = CreateNewResourceType(SelectionFreeClient);
+ SelectionWindowType = CreateNewResourceType(SelectionFreeWindow);
+ return SelectionClientType && SelectionWindowType;
+}
diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c
new file mode 100755
index 000000000..6aa2007ed
--- /dev/null
+++ b/xfixes/xfixes.c
@@ -0,0 +1,225 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xfixesint.h"
+
+unsigned char XFixesReqCode;
+int XFixesEventBase;
+int XFixesErrorBase;
+int XFixesClientPrivateIndex;
+
+static int
+ProcXFixesQueryVersion(ClientPtr client)
+{
+ XFixesClientPtr pXFixesClient = GetXFixesClient (client);
+ xXFixesQueryVersionReply rep;
+ register int n;
+ REQUEST(xXFixesQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->majorVersion < XFIXES_MAJOR) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ } else {
+ rep.majorVersion = XFIXES_MAJOR;
+ if (stuff->majorVersion == XFIXES_MAJOR &&
+ stuff->minorVersion < XFIXES_MINOR)
+ rep.minorVersion = stuff->minorVersion;
+ else
+ rep.minorVersion = XFIXES_MINOR;
+ }
+ pXFixesClient->major_version = rep.majorVersion;
+ pXFixesClient->minor_version = rep.minorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xXFixesQueryVersionReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+/* Major version controls available requests */
+static const int version_requests[] = {
+ X_XFixesQueryVersion, /* before client sends QueryVersion */
+ X_XFixesGetCursorImage, /* Version 1 */
+ X_XFixesChangeCursorByName, /* Version 2 */
+};
+
+#define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
+
+int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
+/*************** Version 1 ******************/
+ ProcXFixesQueryVersion,
+ ProcXFixesChangeSaveSet,
+ ProcXFixesSelectSelectionInput,
+ ProcXFixesSelectCursorInput,
+ ProcXFixesGetCursorImage,
+/*************** Version 2 ******************/
+ ProcXFixesCreateRegion,
+ ProcXFixesCreateRegionFromBitmap,
+ ProcXFixesCreateRegionFromWindow,
+ ProcXFixesCreateRegionFromGC,
+ ProcXFixesCreateRegionFromPicture,
+ ProcXFixesDestroyRegion,
+ ProcXFixesSetRegion,
+ ProcXFixesCopyRegion,
+ ProcXFixesCombineRegion,
+ ProcXFixesCombineRegion,
+ ProcXFixesCombineRegion,
+ ProcXFixesInvertRegion,
+ ProcXFixesTranslateRegion,
+ ProcXFixesRegionExtents,
+ ProcXFixesFetchRegion,
+ ProcXFixesSetGCClipRegion,
+ ProcXFixesSetWindowShapeRegion,
+ ProcXFixesSetPictureClipRegion,
+ ProcXFixesSetCursorName,
+ ProcXFixesGetCursorName,
+ ProcXFixesGetCursorImageAndName,
+ ProcXFixesChangeCursor,
+ ProcXFixesChangeCursorByName,
+};
+
+static int
+ProcXFixesDispatch (ClientPtr client)
+{
+ REQUEST(xXFixesReq);
+ XFixesClientPtr pXFixesClient = GetXFixesClient (client);
+
+ if (pXFixesClient->major_version > NUM_VERSION_REQUESTS)
+ return BadRequest;
+ if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
+ return BadRequest;
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static int
+SProcXFixesQueryVersion(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXFixesQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
+/*************** Version 1 ******************/
+ SProcXFixesQueryVersion,
+ SProcXFixesChangeSaveSet,
+ SProcXFixesSelectSelectionInput,
+ SProcXFixesSelectCursorInput,
+ SProcXFixesGetCursorImage,
+/*************** Version 2 ******************/
+ SProcXFixesCreateRegion,
+ SProcXFixesCreateRegionFromBitmap,
+ SProcXFixesCreateRegionFromWindow,
+ SProcXFixesCreateRegionFromGC,
+ SProcXFixesCreateRegionFromPicture,
+ SProcXFixesDestroyRegion,
+ SProcXFixesSetRegion,
+ SProcXFixesCopyRegion,
+ SProcXFixesCombineRegion,
+ SProcXFixesCombineRegion,
+ SProcXFixesCombineRegion,
+ SProcXFixesInvertRegion,
+ SProcXFixesTranslateRegion,
+ SProcXFixesRegionExtents,
+ SProcXFixesFetchRegion,
+ SProcXFixesSetGCClipRegion,
+ SProcXFixesSetWindowShapeRegion,
+ SProcXFixesSetPictureClipRegion,
+ SProcXFixesSetCursorName,
+ SProcXFixesGetCursorName,
+ SProcXFixesGetCursorImageAndName,
+ SProcXFixesChangeCursor,
+ SProcXFixesChangeCursorByName,
+};
+
+static int
+SProcXFixesDispatch (ClientPtr client)
+{
+ REQUEST(xXFixesReq);
+ if (stuff->xfixesReqType >= XFixesNumberRequests)
+ return BadRequest;
+ return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static void
+XFixesClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ XFixesClientPtr pXFixesClient = GetXFixesClient (pClient);
+
+ pXFixesClient->major_version = 0;
+ pXFixesClient->minor_version = 0;
+}
+
+/*ARGSUSED*/
+static void
+XFixesResetProc (ExtensionEntry *extEntry)
+{
+ DeleteCallback (&ClientStateCallback, XFixesClientCallback, 0);
+}
+
+void
+XFixesExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ XFixesClientPrivateIndex = AllocateClientPrivateIndex ();
+ if (!AllocateClientPrivate (XFixesClientPrivateIndex,
+ sizeof (XFixesClientRec)))
+ return;
+ if (!AddCallback (&ClientStateCallback, XFixesClientCallback, 0))
+ return;
+
+ if (XFixesSelectionInit() && XFixesCursorInit () && XFixesRegionInit () &&
+ (extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents,
+ XFixesNumberErrors,
+ ProcXFixesDispatch, SProcXFixesDispatch,
+ XFixesResetProc, StandardMinorOpcode)) != 0)
+ {
+ XFixesReqCode = (unsigned char)extEntry->base;
+ XFixesEventBase = extEntry->eventBase;
+ XFixesErrorBase = extEntry->errorBase;
+ EventSwapVector[XFixesEventBase + XFixesSelectionNotify] =
+ (EventSwapPtr) SXFixesSelectionNotifyEvent;
+ EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
+ (EventSwapPtr) SXFixesCursorNotifyEvent;
+ }
+}
diff --git a/xfixes/xfixes.h b/xfixes/xfixes.h
new file mode 100755
index 000000000..d03b57c64
--- /dev/null
+++ b/xfixes/xfixes.h
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _XFIXES_H_
+#define _XFIXES_H_
+
+#include "resource.h"
+
+extern RESTYPE RegionResType;
+extern int XFixesErrorBase;
+
+#define VERIFY_REGION(pRegion, rid, client, mode) { \
+ pRegion = SecurityLookupIDByType (client, rid, RegionResType, mode); \
+ if (!pRegion) { \
+ client->errorValue = rid; \
+ return XFixesErrorBase + BadRegion; \
+ } \
+}
+
+#define VERIFY_REGION_OR_NONE(pRegion, rid, client, mode) { \
+ pRegion = 0; \
+ if (rid) VERIFY_REGION(pRegion, rid, client, mode); \
+}
+
+RegionPtr
+XFixesRegionCopy (RegionPtr pRegion);
+
+
+#endif /* _XFIXES_H_ */
diff --git a/xfixes/xfixesint.h b/xfixes/xfixesint.h
new file mode 100755
index 000000000..565df62a2
--- /dev/null
+++ b/xfixes/xfixesint.h
@@ -0,0 +1,233 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2002 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _XFIXESINT_H_
+#define _XFIXESINT_H_
+
+#define NEED_EVENTS
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include <X11/extensions/xfixesproto.h>
+#include "windowstr.h"
+#include "selection.h"
+#include "xfixes.h"
+
+extern unsigned char XFixesReqCode;
+extern int XFixesEventBase;
+extern int XFixesClientPrivateIndex;
+
+typedef struct _XFixesClient {
+ CARD32 major_version;
+ CARD32 minor_version;
+} XFixesClientRec, *XFixesClientPtr;
+
+#define GetXFixesClient(pClient) ((XFixesClientPtr) (pClient)->devPrivates[XFixesClientPrivateIndex].ptr)
+
+extern int (*ProcXFixesVector[XFixesNumberRequests])(ClientPtr);
+extern int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr);
+
+/* Initialize extension at server startup time */
+
+void
+XFixesExtensionInit(void);
+
+/* Save set */
+int
+ProcXFixesChangeSaveSet(ClientPtr client);
+
+int
+SProcXFixesChangeSaveSet(ClientPtr client);
+
+/* Selection events */
+int
+ProcXFixesSelectSelectionInput (ClientPtr client);
+
+int
+SProcXFixesSelectSelectionInput (ClientPtr client);
+
+void
+SXFixesSelectionNotifyEvent (xXFixesSelectionNotifyEvent *from,
+ xXFixesSelectionNotifyEvent *to);
+Bool
+XFixesSelectionInit (void);
+
+/* Cursor notification */
+Bool
+XFixesCursorInit (void);
+
+int
+ProcXFixesSelectCursorInput (ClientPtr client);
+
+int
+SProcXFixesSelectCursorInput (ClientPtr client);
+
+void
+SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
+ xXFixesCursorNotifyEvent *to);
+
+int
+ProcXFixesGetCursorImage (ClientPtr client);
+
+int
+SProcXFixesGetCursorImage (ClientPtr client);
+
+/* Cursor names (Version 2) */
+
+int
+ProcXFixesSetCursorName (ClientPtr client);
+
+int
+SProcXFixesSetCursorName (ClientPtr client);
+
+int
+ProcXFixesGetCursorName (ClientPtr client);
+
+int
+SProcXFixesGetCursorName (ClientPtr client);
+
+int
+ProcXFixesGetCursorImageAndName (ClientPtr client);
+
+int
+SProcXFixesGetCursorImageAndName (ClientPtr client);
+
+/* Cursor replacement (Version 2) */
+
+int
+ProcXFixesChangeCursor (ClientPtr client);
+
+int
+SProcXFixesChangeCursor (ClientPtr client);
+
+int
+ProcXFixesChangeCursorByName (ClientPtr client);
+
+int
+SProcXFixesChangeCursorByName (ClientPtr client);
+
+/* Region objects (Version 2* */
+Bool
+XFixesRegionInit (void);
+
+int
+ProcXFixesCreateRegion (ClientPtr client);
+
+int
+SProcXFixesCreateRegion (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromBitmap (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromBitmap (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromWindow (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromWindow (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromGC (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromGC (ClientPtr client);
+
+int
+ProcXFixesCreateRegionFromPicture (ClientPtr client);
+
+int
+SProcXFixesCreateRegionFromPicture (ClientPtr client);
+
+int
+ProcXFixesDestroyRegion (ClientPtr client);
+
+int
+SProcXFixesDestroyRegion (ClientPtr client);
+
+int
+ProcXFixesSetRegion (ClientPtr client);
+
+int
+SProcXFixesSetRegion (ClientPtr client);
+
+int
+ProcXFixesCopyRegion (ClientPtr client);
+
+int
+SProcXFixesCopyRegion (ClientPtr client);
+
+int
+ProcXFixesCombineRegion (ClientPtr client);
+
+int
+SProcXFixesCombineRegion (ClientPtr client);
+
+int
+ProcXFixesInvertRegion (ClientPtr client);
+
+int
+SProcXFixesInvertRegion (ClientPtr client);
+
+int
+ProcXFixesTranslateRegion (ClientPtr client);
+
+int
+SProcXFixesTranslateRegion (ClientPtr client);
+
+int
+ProcXFixesRegionExtents (ClientPtr client);
+
+int
+SProcXFixesRegionExtents (ClientPtr client);
+
+int
+ProcXFixesFetchRegion (ClientPtr client);
+
+int
+SProcXFixesFetchRegion (ClientPtr client);
+
+int
+ProcXFixesSetGCClipRegion (ClientPtr client);
+
+int
+SProcXFixesSetGCClipRegion (ClientPtr client);
+
+int
+ProcXFixesSetWindowShapeRegion (ClientPtr client);
+
+int
+SProcXFixesSetWindowShapeRegion (ClientPtr client);
+
+int
+ProcXFixesSetPictureClipRegion (ClientPtr client);
+
+int
+SProcXFixesSetPictureClipRegion (ClientPtr client);
+
+#endif /* _XFIXESINT_H_ */