[xserver-commit] xserver/xfixes Makefile.am,1.1,1.1.2.1 cursor.c,1.4,1.4.2.1 xfixes.c,1.3,1.3.2.1 xfixesint.h,1.3,1.3.2.1

Keith Packard xserver-commit@pdx.freedesktop.org
Sun, 19 Oct 2003 13:34:22 -0700


Committed by: keithp

Update of /cvs/xserver/xserver/xfixes
In directory pdx:/tmp/cvs-serv31522/xfixes

Modified Files:
      Tag: xfixes_2_branch
	Makefile.am cursor.c xfixes.c xfixesint.h 
Log Message:
	* Xext/shape.c: (ShapeExtensionInit), (SendShapeNotify):
	* Xext/shapeint.h:
	* dix/cursor.c:
	* dix/window.c:
	* include/cursorstr.h:
	* include/picture.h:
	* include/window.h:
	* xfixes/Makefile.am:
	* xfixes/cursor.c: (CursorDisplayCursor),
	(SProcXFixesSelectCursorInput), (SXFixesCursorNotifyEvent),
	(CopyCursorToImage), (ProcXFixesGetCursorImage),
	(SProcXFixesGetCursorImage), (ProcXFixesSetCursorName),
	(SProcXFixesSetCursorName), (ProcXFixesGetCursorName),
	(SProcXFixesGetCursorName), (ProcXFixesGetCursorImageAndName),
	(SProcXFixesGetCursorImageAndName), (ReplaceCursorLookup),
	(ReplaceCursor), (TestForCursor), (ProcXFixesChangeCursor),
	(SProcXFixesChangeCursor), (TestForCursorName),
	(ProcXFixesChangeCursorByName), (SProcXFixesChangeCursorByName):
	* xfixes/xfixes.c: (ProcXFixesQueryVersion),
	(XFixesNumberRequests), (ProcXFixesDispatch),
	(SProcXFixesQueryVersion), (SProcXFixesDispatch),
	(XFixesClientCallback), (XFixesExtensionInit):
	* xfixes/xfixesint.h:
	Add cursor name and region requests to XFixes extension for
	version 2 support


Index: Makefile.am
===================================================================
RCS file: /cvs/xserver/xserver/xfixes/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -u -d -r1.1 -r1.1.2.1
--- Makefile.am	9 Oct 2003 01:52:14 -0000	1.1
+++ Makefile.am	19 Oct 2003 20:34:20 -0000	1.1.2.1
@@ -1,10 +1,12 @@
 INCLUDES = 			\
-	$(XSERVER_CFLAGS)
+	$(XSERVER_CFLAGS)	\
+	-I${top_srcdir}/Xext
 
 noinst_LIBRARIES = libxfixes.a
 
 libxfixes_a_SOURCES = 	\
 	cursor.c	\
+	region.c	\
 	saveset.c	\
 	select.c	\
 	xfixes.c	\

Index: cursor.c
===================================================================
RCS file: /cvs/xserver/xserver/xfixes/cursor.c,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -d -r1.4 -r1.4.2.1
--- cursor.c	9 Oct 2003 01:52:14 -0000	1.4
+++ cursor.c	19 Oct 2003 20:34:20 -0000	1.4.2.1
@@ -30,6 +30,8 @@
 #include "cursorstr.h"
 #include "dixevents.h"
 #include "servermd.h"
+#include "inputstr.h"
+#include "windowstr.h"
 
 static RESTYPE		CursorClientType;
 static RESTYPE		CursorWindowType;
@@ -37,6 +39,15 @@
 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
  */
@@ -93,6 +104,7 @@
 		ev.window = e->pWindow->drawable.id;
 		ev.cursorSerial = pCursor->serialNumber;
 		ev.timestamp = currentTime.milliseconds;
+		ev.name = pCursor->name;
 		WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
 	    }
 	}
@@ -207,6 +219,7 @@
 	return 1;
     return 0;
 }
+
 int
 SProcXFixesSelectCursorInput (ClientPtr client)
 {
@@ -216,7 +229,7 @@
     swaps(&stuff->length, n);
     swapl(&stuff->window, n);
     swapl(&stuff->eventMask, n);
-    return ProcXFixesSelectCursorInput(client);
+    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
 }
     
 void
@@ -228,48 +241,21 @@
     cpswapl (from->window, to->window);
     cpswapl (from->cursorSerial, to->cursorSerial);
     cpswapl (from->timestamp, to->timestamp);
+    cpswapl (from->name, to->name);
 }
 
-
-int
-ProcXFixesGetCursorImage (ClientPtr client)
+static void
+CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
 {
-/*    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);
+    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;
@@ -302,8 +288,46 @@
 	    srcLine += stride;
 	    mskLine += stride;
 	}
-	image = (CARD32 *) (rep + 1);
     }
+}
+
+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;
@@ -330,7 +354,336 @@
     int n;
     REQUEST(xXFixesGetCursorImageReq);
     swaps (&stuff->length, n);
-    return ProcXFixesGetCursorImage (client);
+    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
@@ -396,3 +749,4 @@
     CursorWindowType = CreateNewResourceType(CursorFreeWindow);
     return CursorClientType && CursorWindowType;
 }
+

Index: xfixes.c
===================================================================
RCS file: /cvs/xserver/xserver/xfixes/xfixes.c,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -d -r1.3 -r1.3.2.1
--- xfixes.c	9 Oct 2003 01:52:14 -0000	1.3
+++ xfixes.c	19 Oct 2003 20:34:20 -0000	1.3.2.1
@@ -29,20 +29,34 @@
 
 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(xXFixesQueryVersionReq);
 
     REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
     rep.type = X_Reply;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
-    rep.majorVersion = XFIXES_MAJOR;
-    rep.minorVersion = XFIXES_MINOR;
+    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);
@@ -53,25 +67,57 @@
     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,
+    ProcXFixesCombineRegion,
+    ProcXFixesCombineRegion,
+    ProcXFixesCombineRegion,
+    ProcXFixesInvertRegion,
+    ProcXFixesRegionExtents,
+    ProcXFixesFetchRegion,
+    ProcXFixesSetGCClipRegion,
+    ProcXFixesSetWindowShapeRegion,
+    ProcXFixesSetPictureClipRegion,
+    ProcXFixesSetCursorName,
+    ProcXFixesGetCursorName,
+    ProcXFixesGetCursorImageAndName,
+    ProcXFixesChangeCursor,
+    ProcXFixesChangeCursorByName,
+};
+
 static int
 ProcXFixesDispatch (ClientPtr client)
 {
-    REQUEST(xReq);
-    switch (stuff->data)
-    {
-    case X_XFixesQueryVersion:
-	return ProcXFixesQueryVersion(client);
-    case X_XFixesChangeSaveSet:
-	return ProcXFixesChangeSaveSet(client);
-    case X_XFixesSelectSelectionInput:
-	return ProcXFixesSelectSelectionInput(client);
-    case X_XFixesSelectCursorInput:
-	return ProcXFixesSelectCursorInput (client);
-    case X_XFixesGetCursorImage:
-	return ProcXFixesGetCursorImage (client);
-    default:
+    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
@@ -83,28 +129,47 @@
     swaps(&stuff->length, n);
     swapl(&stuff->majorVersion, n);
     swapl(&stuff->minorVersion, n);
-    return ProcXFixesQueryVersion(client);
+    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,
+    SProcXFixesCombineRegion,
+    SProcXFixesCombineRegion,
+    SProcXFixesCombineRegion,
+    SProcXFixesInvertRegion,
+    SProcXFixesRegionExtents,
+    SProcXFixesFetchRegion,
+    SProcXFixesSetGCClipRegion,
+    SProcXFixesSetWindowShapeRegion,
+    SProcXFixesSetPictureClipRegion,
+    SProcXFixesSetCursorName,
+    SProcXFixesGetCursorName,
+    SProcXFixesGetCursorImageAndName,
+    SProcXFixesChangeCursor,
+    SProcXFixesChangeCursorByName,
+};
+
 static int
 SProcXFixesDispatch (ClientPtr client)
 {
-    REQUEST(xReq);
-    switch (stuff->data)
-    {
-    case X_XFixesQueryVersion:
-	return SProcXFixesQueryVersion(client);
-    case X_XFixesChangeSaveSet:
-	return SProcXFixesChangeSaveSet(client);
-    case X_XFixesSelectSelectionInput:
-	return SProcXFixesSelectSelectionInput(client);
-    case X_XFixesSelectCursorInput:
-	return SProcXFixesSelectCursorInput (client);
-    case X_XFixesGetCursorImage:
-	return SProcXFixesGetCursorImage (client);
-    default:
+    REQUEST(xXFixesReq);
+    if (stuff->xfixesReqType >= XFixesNumberRequests)
 	return BadRequest;
-    }
+    return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
 }
 
 /*ARGSUSED*/
@@ -113,18 +178,40 @@
 {
 }
 
+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;
+}
+
 void
 XFixesExtensionInit(void)
 {
     ExtensionEntry *extEntry;
 
-    if (XFixesSelectionInit() && XFixesCursorInit () &&
-	(extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents, 0,
+    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] =

Index: xfixesint.h
===================================================================
RCS file: /cvs/xserver/xserver/xfixes/xfixesint.h,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -u -d -r1.3 -r1.3.2.1
--- xfixesint.h	9 Oct 2003 01:52:14 -0000	1.3
+++ xfixesint.h	19 Oct 2003 20:34:20 -0000	1.3.2.1
@@ -38,13 +38,32 @@
 
 extern unsigned char	XFixesReqCode;
 extern int		XFixesEventBase;
+extern int		XFixesErrorBase;
+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);
 
@@ -57,9 +76,10 @@
 Bool
 XFixesSelectionInit (void);
 
-void
-XFixesExtensionInit(void);
-
+/* Cursor notification */
+Bool
+XFixesCursorInit (void);
+    
 int
 ProcXFixesSelectCursorInput (ClientPtr client);
 
@@ -76,7 +96,132 @@
 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
-XFixesCursorInit (void);
-    
+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
+ProcXFixesCombineRegion (ClientPtr client);
+
+int
+SProcXFixesCombineRegion (ClientPtr client);
+
+int
+ProcXFixesInvertRegion (ClientPtr client);
+
+int
+SProcXFixesInvertRegion (ClientPtr client);
+
+int
+ProcXFixesRegionExtents (ClientPtr client);
+
+int
+SProcXFixesRegionExtents (ClientPtr client);
+
+int
+ProcXFixesFetchRegion (ClientPtr client);
+
+int
+SProcXFixesFetchRegion (ClientPtr client);
+
+int
+ProcXFixesCreateRegion (ClientPtr client);
+
+int
+SProcXFixesCreateRegion (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_ */