diff -burN old/proto/vmglproto/autogen.sh new/proto/vmglproto/autogen.sh
--- old/proto/vmglproto/autogen.sh	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/autogen.sh	2005-05-05 21:46:31.000000000 -0400
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff -burN old/proto/vmglproto/ChangeLog new/proto/vmglproto/ChangeLog
--- old/proto/vmglproto/ChangeLog	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/ChangeLog	2007-02-13 15:57:32.000000000 -0500
@@ -0,0 +1,9 @@
+2006-08-21  H. Andres Lagar-Cavilla <andreslc-at-cs-dot-toronto-edu>
+
+	* all files:
+	Initial check-in
+
+2007-02-13  H. Andres Lagar-Cavilla <andreslc-at-cs-dot-toronto-edu>
+
+	* all files:
+	New check-in
diff -burN old/proto/vmglproto/configure.ac new/proto/vmglproto/configure.ac
--- old/proto/vmglproto/configure.ac	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/configure.ac	2007-02-13 15:58:41.000000000 -0500
@@ -0,0 +1,8 @@
+AC_PREREQ([2.57])
+AC_INIT([VMGLProto], [0.1.0], [http://www.cs.toronto.edu/~andreslc/vmgl])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+
+XORG_RELEASE_VERSION
+
+AC_OUTPUT([Makefile
+           vmglproto.pc])
diff -burN old/proto/vmglproto/COPYING new/proto/vmglproto/COPYING
--- old/proto/vmglproto/COPYING	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/COPYING	2007-02-13 15:57:12.000000000 -0500
@@ -0,0 +1,31 @@
+/*
+* 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 */
+
diff -burN old/proto/vmglproto/Makefile.am new/proto/vmglproto/Makefile.am
--- old/proto/vmglproto/Makefile.am	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/Makefile.am	2007-02-13 15:58:16.000000000 -0500
@@ -0,0 +1,9 @@
+vmgldir = $(includedir)/X11/extensions
+vmgl_HEADERS = \
+	vmgl_ext.h \
+	vmgl_extproto.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = vmglproto.pc
+
+EXTRA_DIST = autogen.sh vmglproto.pc.in
diff -burN old/proto/vmglproto/vmgl_ext.h new/proto/vmglproto/vmgl_ext.h
--- old/proto/vmglproto/vmgl_ext.h	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/vmgl_ext.h	2007-02-13 16:04:27.000000000 -0500
@@ -0,0 +1,97 @@
+/*
+* 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
+
+/* 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 old/proto/vmglproto/vmgl_extproto.h new/proto/vmglproto/vmgl_extproto.h
--- old/proto/vmglproto/vmgl_extproto.h	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/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 old/proto/vmglproto/vmglproto.pc.in new/proto/vmglproto/vmglproto.pc.in
--- old/proto/vmglproto/vmglproto.pc.in	1969-12-31 19:00:00.000000000 -0500
+++ new/proto/vmglproto/vmglproto.pc.in	2007-02-13 15:59:03.000000000 -0500
@@ -0,0 +1,9 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+ 
+Name: VMGLProto
+Description: VMGL extension headers
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
diff -burN old/xserver/configure.ac new/xserver/configure.ac
--- old/xserver/configure.ac	2006-08-21 19:51:14.000000000 -0400
+++ new/xserver/configure.ac	2007-02-13 16:05:23.000000000 -0500
@@ -1,5 +1,8 @@
 dnl $Id$
 dnl
+dnl Copyright (c) H. Andres Lagar-Cavilla, University of Toronto, 2006-2007
+dnl Modifications to Xorg code done in the context of the vmgl project
+dnl
 dnl Copyright © 2003-2005 Keith Packard, Daniel Stone
 dnl
 dnl Permission to use, copy, modify, distribute, and sell this software and its
@@ -510,7 +513,7 @@
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
 dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto [kbproto >= 1.0.3]"
+REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto [kbproto >= 1.0.3] vmglproto"
 REQUIRED_LIBS="xfont xau fontenc"
 
 AM_CONDITIONAL(XV, [test "x$XV" = xyes])
diff -burN old/xserver/hw/xfree86/dixmods/Makefile.am new/xserver/hw/xfree86/dixmods/Makefile.am
--- old/xserver/hw/xfree86/dixmods/Makefile.am	2006-08-21 19:51:14.000000000 -0400
+++ new/xserver/hw/xfree86/dixmods/Makefile.am	2007-02-19 13:26:12.000000000 -0500
@@ -23,6 +23,7 @@
 
 extsmoduledir = $(moduledir)/extensions
 extsmodule_LTLIBRARIES = librecord.la \
+			 libvmglext.la \
 			 $(DBEMOD) \
                          $(GLXMODS) \
                          $(XTRAPMOD)
@@ -83,6 +84,9 @@
 librecord_la_LIBADD = $(top_builddir)/record/librecord.la
 librecord_la_SOURCES = recordmod.c
 
+libvmglext_la_LDFLAGS = -avoid-version
+libvmglext_la_SOURCES = vmglmod.c VMGLExtension.c
+
 libshadow_la_LDFLAGS = -avoid-version
 libshadow_la_LIBADD = $(top_builddir)/miext/shadow/libshadow.la
 libshadow_la_SOURCES = shmodule.c
diff -burN old/xserver/hw/xfree86/dixmods/VMGLExtension.c new/xserver/hw/xfree86/dixmods/VMGLExtension.c
--- old/xserver/hw/xfree86/dixmods/VMGLExtension.c	1969-12-31 19:00:00.000000000 -0500
+++ new/xserver/hw/xfree86/dixmods/VMGLExtension.c	2007-02-13 16:27:50.000000000 -0500
@@ -0,0 +1,512 @@
+/*
+* 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: Body of the loadable extension for the Xorg Server */
+
+#include "scrnintstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "windowstr.h"
+#include "xf86Module.h"
+#include "xf86.h"
+
+#include <X11/extensions/vmgl_ext.h>
+#include <X11/extensions/vmgl_extproto.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <unistd.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 */
+static 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 */
+static 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))
+	xf86ErrorF("Error writing on socket %d\n", sock);
+
+    writeLen = sizeof(BoxRec)*len;
+    if (writeLen)
+	if (write(sock, (void *) boxes, writeLen) != ((ssize_t) writeLen))
+    	    xf86ErrorF("Error writing on socket %d\n", sock);
+
+#ifdef VERBOSE_VMGLEXT
+    xf86ErrorF("SendWindowClipList for window %u on socket %d: %d %d %u %u -> %u\n",
+	    glWindow, sock, x, y, w, h, len);
+#endif
+}
+
+/* Windowing functions hooks */
+static 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;
+}
+
+static Bool VMGLDestroyWindow(WindowPtr pWin) {
+    GlWindowWatcher *tmp, *ptr = findWindow(pWin->drawable.id);
+    BOOL retVal = TRUE;
+    
+    if (ptr) {
+	xf86Msg(X_INFO, "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;
+}
+
+static 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);                		
+    /* Insist */
+    screenInfo.screens[pWin->drawable.pScreen->myNum]->ClipNotify = VMGLClipNotify;    
+}
+
+static 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))
+		xf86ErrorF("Error %s closing socket to GlStub on address %s:%hu\n", strerror(errno), 
+		        IP2String(address), (unsigned short) port);
+
+	    windowList = ptr->WindowWatchersList;
+	    if (windowList->next)
+		xf86Msg(X_WARNING, "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);
+	    xf86Msg(X_INFO, "GlStub for address %s:%hu removed\n",
+		    IP2String(address), (unsigned short) port);
+	    return TRUE;
+	}
+    
+    /* Never found it? */
+    xf86ErrorF("Couldn't find GlStub for address %s:%hu\n",
+	    IP2String(address), (unsigned short) port);
+    return FALSE;
+}
+
+/* These *are* the extension functions */
+static 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) {
+	xf86ErrorF("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) {
+	xf86ErrorF("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)) {
+	    xf86Msg(X_WARNING, "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;
+    xf86Msg(X_INFO, "Added GlStub for address %s:%hu\n", 
+	    IP2String(address), (unsigned short) port);
+    return TRUE;
+}
+
+/* Ugly ugly ugly helper */
+static 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;
+}
+
+static WindowPtr DepthSearch(unsigned int XWindow) {
+    int i;
+    WindowPtr tmp;
+    for (i=0;i<screenInfo.numScreens;i++)
+	if ((tmp = DepthSearchHelper(XWindow, WindowTable[i])))
+	    return tmp;
+	    
+    return NULL;
+}
+
+static 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) {
+	xf86ErrorF("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 ?!?! */
+	xf86ErrorF("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) {
+		xf86Msg(X_INFO, "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;
+    xf86ErrorF("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); 
+	xf86Msg(X_INFO, "ClipNotify sent for XID %u, glWindow %u\n", XWindow, glWindow);
+    } else xf86ErrorF("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(INITARGS)
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+    /* Initialize globals */
+    GlStubWatchersList = (GlStubWatcher *) xalloc(sizeof(GlStubWatcher));
+    if (!GlStubWatchersList) {
+	xf86ErrorF("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);
+	xf86ErrorF("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;
+    }
+
+    xf86Msg(X_INFO, "VMGL extension succesfully loaded\n");
+                                                                                 
+    return;
+}
diff -burN old/xserver/hw/xfree86/dixmods/vmglmod.c new/xserver/hw/xfree86/dixmods/vmglmod.c
--- old/xserver/hw/xfree86/dixmods/vmglmod.c	1969-12-31 19:00:00.000000000 -0500
+++ new/xserver/hw/xfree86/dixmods/vmglmod.c	2007-02-19 13:25:51.000000000 -0500
@@ -0,0 +1,75 @@
+/*
+* 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.
+*/
+
+/* Xfree86 loadable module interface for the vmgl extension to the X server
+ * vmgl project */
+ 
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(VMGLSetup);
+
+extern void VMGLExtensionInit(INITARGS);
+
+static ExtensionModule VMGLExt = {
+    VMGLExtensionInit,
+    "VMGL",
+    NULL,
+    NULL,
+    NULL
+};
+
+static XF86ModuleVersionInfo VersRec = {
+	"VMGL",
+	"VMGL, H. Andres Lagar-Cavilla",
+	MODINFOSTRING1,
+	MODINFOSTRING2,
+	XORG_VERSION_CURRENT,
+	0, 1, 0,
+	ABI_CLASS_EXTENSION,
+	ABI_EXTENSION_VERSION,
+	MOD_CLASS_EXTENSION,
+	{0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData vmglextModuleData = { &VersRec, VMGLSetup, NULL };
+
+static pointer
+VMGLSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    LoadExtension(&VMGLExt, FALSE);
+
+    /* Need a non-NULL return value to indicate success */
+    return (pointer)1;
+}
+
