diff -burN orig/Xvnc/include/extensions/Imakefile new/Xvnc/include/extensions/Imakefile
--- orig/Xvnc/include/extensions/Imakefile	2000-06-11 08:00:52.000000000 -0400
+++ new/Xvnc/include/extensions/Imakefile	2007-02-13 15:49:49.000000000 -0500
@@ -1,3 +1,6 @@
+## Copyright (c) H. Andres Lagar-Cavilla, University of Toronto, 2006-2007
+## Modifications to XVnc code made in the context of the vmgl project
+
 XCOMM $XConsortium: Imakefile /main/46 1996/09/28 16:17:59 rws $
 XCOMM $XFree86: xc/include/extensions/Imakefile,v 3.13 1997/01/12 10:39:14 dawes Exp $
 
@@ -20,10 +23,10 @@
 #if BuildDPMSLibrary
 DPMSHEADERS = dpms.h dpmsstr.h
 #endif
-
-EXTRAHEADERS = $(SCREENSAVERHEADERS) $(XF86VIDMODEHEADERS) $(XF86DGAHEADERS) $(XF86MISCHEADERS) $(LBXHEADERS) $(DPMSHEADERS)
+VMGLHEADERS = vmgl_ext.h vmgl_extproto.h
 
 
+EXTRAHEADERS = $(SCREENSAVERHEADERS) $(XF86VIDMODEHEADERS) $(XF86DGAHEADERS) $(XF86MISCHEADERS) $(LBXHEADERS) $(DPMSHEADERS) $(VMGLHEADERS)
 
 HEADERS = Xext.h multibuf.h shape.h XShm.h MITMisc.h XI.h XInput.h XIproto.h \
 	XTest.h xtestext1.h XIE.h XIEproto.h XIEprotost.h sync.h \
diff -burN orig/Xvnc/include/extensions/vmgl_ext.h new/Xvnc/include/extensions/vmgl_ext.h
--- orig/Xvnc/include/extensions/vmgl_ext.h	1969-12-31 19:00:00.000000000 -0500
+++ new/Xvnc/include/extensions/vmgl_ext.h	2007-02-13 15:49:50.000000000 -0500
@@ -0,0 +1,99 @@
+/*
+* Copyright (c) 2006-2007 H. Andres Lagar-Cavilla <andreslc@cs.toronto.edu>
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+*   1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*   3. The name of the author may not be used to endorse or promote
+* products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* vmgl project */
+
+#ifndef _VMGLEXT_H
+#define _VMGLEXT_H
+
+#include <netinet/in.h>
+
+/* Constants */
+#define VMGL_EXTENSION_NAME	"VMGLExt"
+#define VMGL_MAJOR_VERSION		1
+#define VMGL_MINOR_VERSION		0
+
+#define X_VMGLInit			0
+#define X_VMGLWatchWindow		1
+#define X_VMGLReset			2
+
+/* X internal structs */
+#define sz_xVMGLInitReq 12
+typedef struct xVMGLInitReq_struct{
+    CARD8       reqType;
+    CARD8       VMGLRequestType;
+    CARD16      length B16;
+    CARD32      address B32;
+    CARD16      port B16;
+    CARD16      pad0 B16;
+} xVMGLInitReq;
+
+#define sz_XVMGLInitReply 32
+typedef struct XVMGLInitReply_struct {
+    CARD8   	type;
+    CARD8   	retVal;
+    CARD16  	sequenceNumber B16;
+    CARD32  	length B32;
+    CARD32      pad1 B32;
+    CARD32	pad2 B32;
+    CARD32  	pad3 B32;
+    CARD32  	pad4 B32;
+    CARD32  	pad5 B32;
+    CARD32  	pad6 B32;
+} XVMGLInitReply;
+
+#define sz_xVMGLWatchWindowReq 20
+typedef struct xVMGLWatchWindowReq_struct {
+    CARD8       reqType;
+    CARD8       VMGLRequestType;
+    CARD16      length B16;
+    CARD32      XWindow B32;
+    CARD32	glWindow B32;
+    CARD32      address B32;
+    CARD16      port B16;
+    CARD16      pad0 B16;
+} xVMGLWatchWindowReq;
+
+#define sz_XVMGLWatchWindowReply 32
+typedef struct XVMGLWatchWindowReply_struct {
+    CARD8   	type;
+    CARD8   	retVal;
+    CARD16  	sequenceNumber B16;
+    CARD32  	length B32;
+    CARD32  	pad1 B32;
+    CARD32  	pad2 B32;
+    CARD32  	pad3 B32;
+    CARD32  	pad4 B32;
+    CARD32  	pad5 B32;
+    CARD32  	pad6 B32;
+} XVMGLWatchWindowReply;
+
+#endif /* _VMGLEXT_H */
+
diff -burN orig/Xvnc/include/extensions/vmgl_extproto.h new/Xvnc/include/extensions/vmgl_extproto.h
--- orig/Xvnc/include/extensions/vmgl_extproto.h	1969-12-31 19:00:00.000000000 -0500
+++ new/Xvnc/include/extensions/vmgl_extproto.h	2007-02-13 15:49:50.000000000 -0500
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2006-2007 H. Andres Lagar-Cavilla <andreslc@cs.toronto.edu>
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+*   1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*   3. The name of the author may not be used to endorse or promote
+* products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* vmgl project */
+
+#ifndef _VMGLEXT_PROTO_H
+#define _VMGLEXT_PROTO_H
+
+/* Network proto between X server and gl stub */
+
+typedef struct XVMGLWindowingCommand_struct {
+    unsigned int	length;
+    unsigned int	glWindow;
+    int			x;
+    int			y;
+    unsigned int	width;
+    unsigned int	height;
+} XVMGLWindowingCommand;
+
+#endif /* _VMGLEXT_PROTO_H */
+
diff -burN orig/Xvnc/programs/Xserver/mi/miinitext.c new/Xvnc/programs/Xserver/mi/miinitext.c
--- orig/Xvnc/programs/Xserver/mi/miinitext.c	2000-06-11 08:00:52.000000000 -0400
+++ new/Xvnc/programs/Xserver/mi/miinitext.c	2007-02-13 15:49:54.000000000 -0500
@@ -1,3 +1,6 @@
+/* Copyright (c) H. Andres Lagar-Cavilla, University of Toronto, 2006-2007
+ * Modifications to XVnc code made in the context of the vmgl project
+ */
 /***********************************************************
 
 Copyright (c) 1987  X Consortium
@@ -165,6 +168,7 @@
 InitExtension GlxExtensionInitPtr = NULL;
 #endif
 #endif
+extern void VMGLExtensionInit(void);
 
 /*ARGSUSED*/
 void
@@ -277,4 +281,5 @@
     }
 #endif
 #endif
+    VMGLExtensionInit();
 }
diff -burN orig/Xvnc/programs/Xserver/Xext/Imakefile new/Xvnc/programs/Xserver/Xext/Imakefile
--- orig/Xvnc/programs/Xserver/Xext/Imakefile	2000-06-11 08:00:51.000000000 -0400
+++ new/Xvnc/programs/Xserver/Xext/Imakefile	2007-02-13 15:49:50.000000000 -0500
@@ -1,3 +1,6 @@
+## Copyright (c) H. Andres Lagar-Cavilla, University of Toronto, 2006-2007
+## Modifications to XVnc code made in the context of the vmgl project
+
 XCOMM $XConsortium: Imakefile /main/56 1996/11/26 16:07:54 swick $
 XCOMM $XFree86: xc/programs/Xserver/Xext/Imakefile,v 3.11.2.1 1998/01/23 12:35:11 dawes Exp $
 #include <Server.tmpl>
@@ -48,16 +51,17 @@
 	      bigreq.c sync.c $(SCRNSAVSRC) xcmisc.c $(VIDMODESRCS) \
 	      $(XF86MISCSRCS) $(XF86DGASRCS) $(SECURITYSRCS) \
 	      $(DPMSSRCS) \
-	      $(APPGROUPSRCS) xprint.c
+	      $(APPGROUPSRCS) xprint.c VMGLExtension.c
        OBJS = shape.o $(SHMOBJS) mbuf.o \
               mitmisc.o xtest.o xtest1di.o xtest1dd.o sleepuntil.o \
               bigreq.o sync.o $(SCRNSAVOBJ) xcmisc.o $(VIDMODEOBJS) \
 	      $(XF86MISCOBJS) $(XF86DGAOBJS) $(SECURITYOBJS) \
 	      $(DPMSOBJS) \
-	      $(APPGROUPOBJS) xprint.o
+	      $(APPGROUPOBJS) xprint.o VMGLExtension.o
 
 XF86INCLUDES = -I../hw/xfree86/common -I../hw/xfree86/os-support
     INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) $(XF86INCLUDES)
+               
     LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
 
 NormalLibraryObjectRule()
diff -burN orig/Xvnc/programs/Xserver/Xext/VMGLExtension.c new/Xvnc/programs/Xserver/Xext/VMGLExtension.c
--- orig/Xvnc/programs/Xserver/Xext/VMGLExtension.c	1969-12-31 19:00:00.000000000 -0500
+++ new/Xvnc/programs/Xserver/Xext/VMGLExtension.c	2007-02-13 15:49:51.000000000 -0500
@@ -0,0 +1,500 @@
+/*
+* Copyright (c) 2006-2007 H. Andres Lagar-Cavilla <andreslc@cs.toronto.edu>
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+*   1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*   2. Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*   3. The name of the author may not be used to endorse or promote
+* products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* vmgl */
+
+#include "scrnintstr.h"
+#include "extnsionst.h"
+#include "vmgl_ext.h"
+#include "vmgl_extproto.h"
+#include "dixstruct.h"
+#include "windowstr.h"
+
+#include <errno.h>
+#include <stdio.h>
+
+/* List of windows to watch on behalf of a gl stub */
+typedef struct GlWindowWatcher_struct {
+    unsigned int XWindow;
+    unsigned int glWindow;
+    int sock;
+    struct GlWindowWatcher_struct *next;
+} GlWindowWatcher;
+
+/* List of glStubs on behalf of whom we watch windows */
+typedef struct GlStubWatcher_struct {
+    int sock;
+    unsigned int address;
+    unsigned short port;
+    GlWindowWatcher *WindowWatchersList;
+    struct GlStubWatcher_struct *next;
+} GlStubWatcher;
+
+/* Globals */
+GlStubWatcher *GlStubWatchersList;
+void (*ClipNotify_wrap[MAXSCREENS])();
+Bool (*DestroyWindow_wrap[MAXSCREENS])();
+
+extern WindowPtr *WindowTable;
+
+/* Helper */
+char *IP2String(in_addr_t address) {
+    struct in_addr tmp;
+    tmp.s_addr= htonl(address);
+    return ((char *) inet_ntoa(tmp));
+}
+
+/* This function does the communication with a gl Stub */
+void SendWindowClipList(int sock, unsigned int glWindow, RegionRec *clipList,
+		         int x, int y, unsigned int w, unsigned int h) {
+    XVMGLWindowingCommand cmd;
+    BoxPtr boxes;
+    size_t writeLen;
+    unsigned int len = REGION_NUM_RECTS(clipList);
+
+    cmd.length = htonl(len);
+    cmd.glWindow = htonl(glWindow);
+    cmd.x = htonl(x);
+    cmd.y = htonl(y);
+    cmd.width = htonl(w);
+    cmd.height = htonl(h);
+    boxes = REGION_RECTS(clipList);
+
+    writeLen = sizeof(XVMGLWindowingCommand);
+    if (write(sock, (void *) &cmd, writeLen) != ((ssize_t) writeLen))
+	fprintf(stderr, "Error writing on socket %d\n", sock);
+
+    writeLen = sizeof(BoxRec)*len;
+    if (writeLen)
+	if (write(sock, (void *) boxes, writeLen) != ((ssize_t) writeLen))
+    	    fprintf(stderr, "Error writing on socket %d\n", sock);
+
+#ifdef VERBOSE_VMGLEXT
+    fprintf(stderr, "SendWindowClipList for window %u on socket %d: %d %d %u %u -> %u\n",
+	    glWindow, sock, x, y, w, h, len);
+#endif
+}
+
+/* Windowing functions hooks */
+GlWindowWatcher *findWindow(unsigned int XWindow) {
+    GlWindowWatcher *ptr;
+    GlStubWatcher *srvPtr;
+
+    for (srvPtr = GlStubWatchersList; srvPtr->next != NULL; srvPtr = srvPtr->next)
+        for (ptr = srvPtr->next->WindowWatchersList; ptr->next != NULL; ptr = ptr->next)
+            if (ptr->next->XWindow == XWindow)
+                return ptr;
+
+    return NULL;
+}
+
+Bool VMGLDestroyWindow(WindowPtr pWin) {
+    GlWindowWatcher *tmp, *ptr = findWindow(pWin->drawable.id);
+    BOOL retVal = TRUE;
+    
+    if (ptr) {
+	fprintf(stderr, "Destroy %u XID %u\n", ptr->next->glWindow, (unsigned int) pWin->drawable.id);
+	tmp = ptr->next;
+	ptr->next = tmp->next;
+	xfree(tmp);
+    }
+    if (DestroyWindow_wrap[pWin->drawable.pScreen->myNum])
+        retVal = (*DestroyWindow_wrap[pWin->drawable.pScreen->myNum])(pWin);
+    /* Insist */
+    screenInfo.screens[pWin->drawable.pScreen->myNum]->DestroyWindow = VMGLDestroyWindow;
+    return retVal;
+}
+
+void VMGLClipNotify(WindowPtr pWin, int x, int y) {
+    GlWindowWatcher *ptr = findWindow(pWin->drawable.id);
+    if (ptr) 
+	SendWindowClipList(ptr->next->sock, ptr->next->glWindow, &(pWin->clipList) /*RegionRec*/,
+    		pWin->drawable.x, pWin->drawable.y, pWin->drawable.width, pWin->drawable.height);
+    if (ClipNotify_wrap[pWin->drawable.pScreen->myNum])
+            (*ClipNotify_wrap[pWin->drawable.pScreen->myNum])(pWin, x, y);                		
+}
+
+Bool RemoveGlStub(in_addr_t address, in_addr_t port) {    
+    GlStubWatcher *tmp, *ptr;
+    GlWindowWatcher *windowList, *windowTmp;
+    for (tmp=GlStubWatchersList; tmp->next != NULL; tmp=tmp->next)
+	if ((tmp->next->address == address)&&(tmp->next->port == port)) {
+	    /* Removal */
+	    ptr = tmp->next;
+	    if (close(ptr->sock))
+		fprintf(stderr, "Error %s closing socket to GlStub on address %s:%hu\n", strerror(errno), 
+		        IP2String(address), (unsigned short) port);
+
+	    windowList = ptr->WindowWatchersList;
+	    if (windowList->next)
+		fprintf(stderr, "Removing GlStub with pending windows, address %s:%hu\n",
+			IP2String(address), (unsigned short) port);
+	    while (windowList) {
+		windowTmp = windowList;
+		windowList = windowList->next;
+		xfree(windowTmp);
+	    }
+
+	    tmp->next = ptr->next;
+	    xfree(ptr);
+	    fprintf(stderr, "GlStub for address %s:%hu removed\n",
+		    IP2String(address), (unsigned short) port);
+	    return TRUE;
+	}
+    
+    /* Never found it? */
+    fprintf(stderr, "Couldn't find GlStub for address %s:%hu\n",
+	    IP2String(address), (unsigned short) port);
+    return FALSE;
+}
+
+/* These *are* the extension functions */
+Bool AddGlStub(in_addr_t address, in_addr_t port) {
+    GlStubWatcher *tmp;
+    int sock;
+    struct sockaddr_in addr;
+    
+    /* Establish connection with listening part */		
+    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+	fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
+	return FALSE;
+    }
+    memset((void *) &addr, 0, sizeof(struct sockaddr_in));
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+    addr.sin_addr.s_addr = htonl(address);
+    if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) {
+	fprintf(stderr, "Failed to connect to address %s:%hu: %s\n",IP2String(address),
+		(unsigned short) port, strerror(errno));
+	return FALSE;
+    }
+
+    /* Check it hasn't been already added */
+    for (tmp=GlStubWatchersList; tmp->next != NULL; tmp=tmp->next)
+	if ((tmp->next->address == address)&&(tmp->next->port == port)) {
+	    fprintf(stderr, "GlStub for address %s:%hu already added\n", 
+		    IP2String(address), (unsigned short) port);
+	    close(tmp->next->sock);
+	    tmp->next->sock = sock;
+	    return TRUE;
+	}
+		
+    /* Now add server to list */
+    tmp = (GlStubWatcher *) xalloc(sizeof(GlStubWatcher));
+    if (!tmp) {
+	close(sock);
+	return FALSE;
+    }
+    tmp->sock = sock;
+    tmp->address = address;
+    tmp->port = port;
+    tmp->WindowWatchersList = (GlWindowWatcher *) xalloc(sizeof(GlWindowWatcher));
+    if (!(tmp->WindowWatchersList)) {
+	xfree(tmp);
+	close(sock);
+	return FALSE;
+    }
+    tmp->WindowWatchersList->next = NULL;
+    tmp->next = GlStubWatchersList->next;
+    GlStubWatchersList->next = tmp;
+    fprintf(stderr, "Added GlStub for address %s:%hu\n", 
+	    IP2String(address), (unsigned short) port);
+    return TRUE;
+}
+
+/* Ugly ugly ugly helper */
+WindowPtr DepthSearchHelper(unsigned int XWindow, WindowPtr root) {
+    WindowPtr pWin, tmp;
+    
+    for (pWin = root->firstChild; pWin; pWin = pWin->nextSib) 
+	if (pWin->drawable.id == XWindow) 
+	    return pWin;
+	else 
+	    if (tmp = DepthSearchHelper(XWindow, pWin))
+		return tmp;
+
+    return NULL;
+}
+
+WindowPtr DepthSearch(unsigned int XWindow) {
+    int i;
+    WindowPtr tmp;
+    for (i=0;i<screenInfo.numScreens;i++)
+	if (tmp = DepthSearchHelper(XWindow, WindowTable[i]))
+	    return tmp;
+}
+
+Bool AddWindowWatch(unsigned int XWindow, unsigned int glWindow, 
+		    in_addr_t address, in_port_t port)
+{
+    GlWindowWatcher *tmp, *ptr, *list;
+    GlStubWatcher *srvTmp;
+    WindowPtr thisWindow;
+    
+    if (!XWindow) {
+	fprintf(stderr, "Meaningless XID to watch for address %s:%hu\n",
+		IP2String(address), (unsigned short) port);
+	return FALSE;
+    }
+    
+    /* First find the server */
+    for (srvTmp=GlStubWatchersList; srvTmp->next != NULL; srvTmp=srvTmp->next)
+	if ((srvTmp->next->address == address)&&(srvTmp->next->port == port)) {
+		list = srvTmp->next->WindowWatchersList;
+		break;
+	}
+    if (!srvTmp->next) {
+	/* Didn't find server ?!?! */
+	fprintf(stderr, "Couldn't find gl stub for address %s:%hu\n",
+		IP2String(address), (unsigned short) port);
+	return FALSE;
+    }
+    
+    /* Are we unwatching a window? */
+    if (XWindow && !glWindow) {
+	for (ptr=list; ptr->next != NULL; ptr=ptr->next) 
+	    if (ptr->next->XWindow == XWindow) {
+		fprintf(stderr,"Removing window %u for address %s:%hu\n",
+			XWindow, IP2String(address), (unsigned short) port);
+		tmp = ptr->next;
+		ptr->next = tmp->next;
+		xfree(tmp);
+		/* Assume that once the list of windows is depleted
+		   we can safely destroy the gl stub entry. NO!! */
+/*		if (!(list->next))
+		    return RemoveGlStub(srvTmp->next->address, srvTmp->next->port);
+		else */
+		    return TRUE;
+	    }
+	/* Could not find it */
+	return FALSE;
+    }
+    
+    for (ptr=list; ptr->next != NULL; ptr=ptr->next) 
+	if (ptr->next->glWindow == glWindow) {
+	    /* We have this, updating XWindow... */
+	    ptr->next->XWindow = XWindow;
+	    return TRUE;
+	}
+    
+    /* We don't have this, add... */    
+    tmp = (GlWindowWatcher *) xalloc(sizeof(GlWindowWatcher));
+    if (!tmp) return FALSE;
+    tmp->XWindow = XWindow;
+    tmp->glWindow = glWindow;
+    tmp->sock = srvTmp->next->sock;
+    tmp->next = list->next;
+    list->next = tmp;
+    fprintf(stderr, "Watching window %u (XID %u) for GlStub address %s:%hu, socket %d\n", 
+	    glWindow, XWindow, IP2String(address), (unsigned short) port, tmp->sock);
+    if (thisWindow = DepthSearch(XWindow)) {
+	VMGLClipNotify(thisWindow, 0, 0); 
+	fprintf(stderr, "ClipNotify sent for XID %u, glWindow %u\n", XWindow, glWindow);
+    } else fprintf(stderr, "Odd, no window found for XID %u\n", XWindow);
+    return TRUE;
+}
+
+/* These are X proto wrappers for the extension functions */
+static int VMGLInitSrv(ClientPtr client)
+{
+    REQUEST(xVMGLInitReq);
+    XVMGLInitReply reply;
+
+    REQUEST_SIZE_MATCH(xVMGLInitReq);
+    reply.retVal = AddGlStub(stuff->address, stuff->port) ? 1:0;
+
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    if(client->swapped)
+    {
+	register char swapper;
+    	swaps(&reply.sequenceNumber, swapper);
+    }
+
+    WriteToClient(client, SIZEOF(XVMGLInitReply), (char *) &reply);
+    return (client->noClientException);
+}
+
+static int VMGLWatchWindowSrv(ClientPtr client)
+{
+    REQUEST(xVMGLWatchWindowReq);
+    XVMGLWatchWindowReply reply;
+
+    REQUEST_SIZE_MATCH(xVMGLWatchWindowReq);
+    reply.retVal = AddWindowWatch(stuff->XWindow, stuff->glWindow, 
+				  stuff->address, stuff->port) ? 1:0;
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    if(client->swapped)
+    {
+	register char swapper;
+    	swaps(&reply.sequenceNumber, swapper);
+    }
+
+    WriteToClient(client, SIZEOF(XVMGLWatchWindowReply), (char *) &reply);
+    return (client->noClientException);
+}
+
+static int VMGLResetSrv(ClientPtr client)
+{
+    REQUEST(xVMGLInitReq);
+    XVMGLInitReply reply;
+
+    REQUEST_SIZE_MATCH(xVMGLInitReq);
+    reply.retVal = RemoveGlStub(stuff->address, stuff->port) ? 1:0;
+
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    if(client->swapped)
+    {
+	register char swapper;
+    	swaps(&reply.sequenceNumber, swapper);
+    }
+
+    WriteToClient(client, SIZEOF(XVMGLInitReply), (char *) &reply);
+    return (client->noClientException);
+}
+
+/* Dispatching. Boring. Need to handle swapping/endiannes as well */
+static int NormalDispatcher(ClientPtr client)
+{
+    REQUEST(xReq);
+
+    switch (stuff->data)
+    {
+	case X_VMGLInit:
+	    return VMGLInitSrv(client);
+	case X_VMGLWatchWindow:
+	    return VMGLWatchWindowSrv(client);
+	case X_VMGLReset:
+	    return VMGLResetSrv(client);
+	default:
+	    return BadRequest;
+    }
+}
+
+static int SwappedVMGLInitSrv(ClientPtr client)
+{
+    REQUEST(xVMGLInitReq);
+    register char swapper;
+
+    swaps(&stuff->length, swapper);
+    REQUEST_SIZE_MATCH(xVMGLInitReq);
+    swaps(&stuff->address, swapper);
+    swaps(&stuff->port, swapper);
+    return VMGLInitSrv(client);
+}
+
+static int SwappedVMGLWatchWindowSrv(ClientPtr client)
+{
+    REQUEST(xVMGLWatchWindowReq);
+    register char swapper;
+
+    swaps(&stuff->length, swapper);
+    REQUEST_SIZE_MATCH(xVMGLWatchWindowReq);
+    swaps(&stuff->XWindow, swapper);
+    swaps(&stuff->glWindow, swapper);
+    swaps(&stuff->address, swapper);
+    swaps(&stuff->port, swapper);
+    return VMGLWatchWindowSrv(client);
+}
+
+static int SwappedVMGLResetSrv(ClientPtr client)
+{
+    REQUEST(xVMGLInitReq);
+    register char swapper;
+
+    swaps(&stuff->length, swapper);
+    REQUEST_SIZE_MATCH(xVMGLInitReq);
+    swaps(&stuff->address, swapper);
+    swaps(&stuff->port, swapper);
+    return VMGLInitSrv(client);
+}
+
+static int SwappedDispatcher(ClientPtr client)
+{
+    REQUEST(xReq);
+
+    switch (stuff->data)
+    {
+	case X_VMGLInit:
+	    return SwappedVMGLInitSrv(client);
+	case X_VMGLWatchWindow:
+	    return SwappedVMGLWatchWindowSrv(client);
+	case X_VMGLReset:
+	    return SwappedVMGLResetSrv(client);
+	default:
+	    return BadRequest;
+    }
+}
+
+/* Extension initialization */
+static void
+VMGLDummyReset(ExtensionEntry *extEntry)
+{
+}
+
+void VMGLExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+    /* Initialize globals */
+    GlStubWatchersList = (GlStubWatcher *) xalloc(sizeof(GlStubWatcher));
+    if (!GlStubWatchersList) {
+	fprintf(stderr, "Unable to start VMGL extension\n");
+	return;
+    }
+    GlStubWatchersList->next = NULL;
+
+    /* Initialize extension */
+    extEntry = AddExtension(VMGL_EXTENSION_NAME, 0, 0,
+			    NormalDispatcher, SwappedDispatcher,
+                            VMGLDummyReset, StandardMinorOpcode);
+    if (!extEntry) {
+	xfree(GlStubWatchersList);
+	fprintf(stderr, "Unable to start VMGL extension\n");
+	return;
+    }
+    
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+        ClipNotify_wrap[i] = screenInfo.screens[i]->ClipNotify;
+        screenInfo.screens[i]->ClipNotify = VMGLClipNotify;
+        DestroyWindow_wrap[i] = screenInfo.screens[i]->DestroyWindow;
+        screenInfo.screens[i]->DestroyWindow = VMGLDestroyWindow;
+    }
+                                                                                
+    return;
+}
