diff --git a/xc/programs/Xserver/Xvnc.man b/xc/programs/Xserver/Xvnc.man
new file mode 100644
index 0000000..1852f4d
--- /dev/null
+++ b/xc/programs/Xserver/Xvnc.man
@@ -0,0 +1,258 @@
+.TH Xvnc 1 "18 May 2004" "RealVNC Ltd" "Virtual Network Computing"
+.SH NAME
+Xvnc \- the X VNC server 
+.SH SYNOPSIS
+.B Xvnc
+.RI [ options ] 
+.RI : display#
+.SH DESCRIPTION
+.B Xvnc
+is the X VNC (Virtual Network Computing) server.  It is based on a standard X
+server, but it has a "virtual" screen rather than a physical one.  X
+applications display themselves on it as if it were a normal X display, but
+they can only be accessed via a VNC viewer - see \fBvncviewer\fP(1).
+
+So Xvnc is really two servers in one. To the applications it is an X server,
+and to the remote VNC users it is a VNC server. By convention we have arranged
+that the VNC server display number will be the same as the X server display
+number, which means you can use eg. snoopy:2 to refer to display 2 on machine
+"snoopy" in both the X world and the VNC world.
+
+The best way of starting \fBXvnc\fP is via the \fBvncserver\fP script.  This
+sets up the environment appropriately and runs some X applications to get you
+going.  See the manual page for \fBvncserver\fP(1) for more information.
+
+.SH OPTIONS
+.B Xvnc
+takes lots of options - running \fBXvnc -help\fP gives a list.  Many of these
+are standard X server options, which are described in the \fBXserver\fP(1)
+manual page.  In addition to options which can only be set via the
+command-line, there are also "parameters" which can be set both via the
+command-line and through the \fBvncconfig\fP(1) program.
+
+.TP
+.B \-geometry \fIwidth\fPx\fIheight\fP
+Specify the size of the desktop to be created. Default is 1024x768.
+
+.TP
+.B \-depth \fIdepth\fP
+Specify the pixel depth in bits of the desktop to be created. Default is 16,
+other possible values are 8, 15, and 24 - anything else is likely to cause
+strange behaviour by applications.
+
+.TP
+.B \-pixelformat \fIformat\fP
+Specify pixel format for server to use (BGRnnn or RGBnnn).  The default for
+depth 8 is BGR233 (meaning the most significant two bits represent blue, the
+next three green, and the least significant three represent red), the default
+for depth 16 is RGB565 and for depth 24 is RGB888.
+
+.TP
+.B \-cc 3
+As an alternative to the default TrueColor visual, this allows you to run an
+Xvnc server with a PseudoColor visual (i.e. one which uses a colour map or
+palette), which can be useful for running some old X applications which only
+work on such a display.  Values other than 3 (PseudoColor) and 4 (TrueColor)
+for the \-cc option may result in strange behaviour, and PseudoColor desktops
+must be 8 bits deep (i.e. \fB-depth 8\fP).
+
+.TP
+.B \-inetd 
+This significantly changes Xvnc's behaviour so that it can be launched from
+inetd.  See the section below on usage with inetd.
+
+.TP
+.B \-help
+List all the options and parameters
+
+.SH PARAMETERS
+VNC parameters can be set both via the command-line and through the
+\fBvncconfig\fP(1) program, and with a VNC-enabled XFree86 server via Options
+entries in the XF86Config file.
+
+Parameters can be turned on with -\fIparam\fP or off with
+-\fIparam\fP=0.  Parameters which take a value can be specified as
+-\fIparam\fP \fIvalue\fP.  Other valid forms are \fIparam\fP\fB=\fP\fIvalue\fP
+-\fIparam\fP=\fIvalue\fP --\fIparam\fP=\fIvalue\fP.  Parameter names are
+case-insensitive.
+
+.TP
+.B \-desktop \fIdesktop-name\fP
+Each desktop has a name which may be displayed by the viewer. It defaults to
+"x11".
+
+.TP
+.B \-rfbport \fIport\fP
+Specifies the TCP port on which Xvnc listens for connections from viewers (the
+protocol used in VNC is called RFB - "remote framebuffer").  The default is
+5900 plus the display number.
+
+.TP
+.B \-rfbwait \fItime\fP, \-ClientWaitTimeMillis \fItime\fP
+
+Time in milliseconds to wait for a viewer which is blocking Xvnc.  This is
+necessary because Xvnc is single-threaded and sometimes blocks until the viewer
+has finished sending or receiving a message - note that this does not mean an
+update will be aborted after this time.  Default is 20000 (20 seconds).
+
+.TP
+.B \-httpd \fIdirectory\fP
+Run a mini-HTTP server which serves files from the given directory.  Normally
+the directory will contain the classes for the Java viewer.  In addition, files
+with a .vnc extension will have certain substitutions made so that a single
+installation of the Java VNC viewer can be served by separate instances of
+Xvnc.
+
+.TP
+.B \-httpPort \fIport\fP
+Specifies the port on which the mini-HTTP server runs.  Default is 5800 plus
+the display number.
+
+.TP
+.B \-rfbauth \fIpasswd-file\fP, \-PasswordFile \fIpasswd-file\fP
+Specifies the file containing the password used to authenticate viewers.  The
+file is accessed each time a connection comes in, so it can be changed on the
+fly via \fBvncpasswd\fP(1).
+
+.TP
+.B \-deferUpdate \fItime\fP
+Xvnc uses a "deferred update" mechanism which enhances performance in many
+cases. After any change to the framebuffer, Xvnc waits for this number of
+milliseconds (default 40) before sending an update to any waiting clients. This
+means that more changes tend to get coalesced together in a single
+update. Setting it to 0 results in the same behaviour as earlier versions of
+Xvnc, where the first change to the framebuffer causes an immediate update to
+any waiting clients.
+
+.TP
+.B \-SendCutText
+Send clipboard changes to clients (default is on).  Note that you must also run
+\fBvncconfig\fP(1) to get the clipboard to work.
+
+.TP
+.B \-AcceptCutText
+Accept clipboard updates from clients (default is on).  Note that you must also
+run \fBvncconfig\fP(1) to get the clipboard to work.
+
+.TP
+.B \-AcceptPointerEvents
+Accept pointer press and release events from clients (default is on).
+
+.TP
+.B \-AcceptKeyEvents
+Accept key press and release events from clients (default is on).
+
+.TP
+.B \-DisconnectClients
+Disconnect existing clients if an incoming connection is non-shared (default is
+on). If \fBDisconnectClients\fP is false, then a new non-shared connection will
+be refused while there is a client active.  When combined with
+\fBNeverShared\fP this means only one client is allowed at a time.
+
+.TP
+.B \-NeverShared
+Never treat incoming connections as shared, regardless of the client-specified
+setting (default is off).
+
+.TP
+.B \-AlwaysShared
+Always treat incoming connections as shared, regardless of the client-specified
+setting (default is off).
+
+.TP
+.B \-Protocol3.3
+Always use protocol version 3.3 for backwards compatibility with badly-behaved
+clients (default is off).
+
+.TP
+.B \-CompareFB
+Perform pixel comparison on framebuffer to reduce unnecessary updates (default
+is on).
+
+.TP
+.B \-SecurityTypes \fIsec-types\fP
+Specify which security schemes to use separated by commas.  At present only
+"None" and "VncAuth" are supported.  The default is "VncAuth" - note that if
+you want a server which does not require a password, you must set this
+parameter to "None".
+
+.TP
+.B \-IdleTimeout \fIseconds\fP
+The number of seconds after which an idle VNC connection will be dropped
+(default is 3600 i.e. an hour).
+
+.TP
+.B \-localhost
+Only allow connections from the same machine. Useful if you use SSH and want to
+stop non-SSH connections from any other hosts. See the guide to using VNC with
+SSH on the web site.
+
+.TP
+.B \-log \fIlogname\fP:\fIdest\fP:\fIlevel\fP
+Configures the debug log settings.  \fIdest\fP can currently be \fBstderr\fP or
+\fBstdout\fP, and \fIlevel\fP is between 0 and 100, 100 meaning most verbose
+output.  \fIlogname\fP is usually \fB*\fP meaning all, but you can target a
+specific source file if you know the name of its "LogWriter".  Default is
+\fB*:stderr:30\fP.
+
+.SH USAGE WITH INETD
+By configuring the \fBinetd\fP(1) service appropriately, Xvnc can be launched
+on demand when a connection comes in, rather than having to be started
+manually.  When given the \fB-inetd\fP option, instead of listening for TCP
+connections on a given port it uses its standard input and standard output.
+There are two modes controlled by the wait/nowait entry in the inetd.conf file.
+
+In the nowait mode, Xvnc uses its standard input and output directly as the
+connection to a viewer.  It never has a listening socket, so cannot accept
+further connections from viewers (it can however connect out to listening
+viewers by use of the vncconfig program).  Further viewer connections to the
+same TCP port result in inetd spawning off a new Xvnc to deal with each
+connection.  When the connection to the viewer dies, the Xvnc and any
+associated X clients die.  This behaviour is most useful when combined with the
+XDMCP options -query and -once.  An typical example in inetd.conf might be (all
+on one line):
+
+5950   stream   tcp nowait nobody  /usr/local/bin/Xvnc Xvnc -inetd -query
+localhost -once securitytypes=none
+
+In this example a viewer connection to :50 will result in a new Xvnc for that
+connection which should display the standard XDM login screen on that machine.
+Because the user needs to login via XDM, it is usually OK to accept connections
+without a VNC password in this case.
+
+In the wait mode, when the first connection comes in, inetd gives the listening
+socket to Xvnc.  This means that for a given TCP port, there is only ever one
+Xvnc at a time.  Further viewer connections to the same port are accepted by
+the same Xvnc in the normal way.  Even when the original connection is broken,
+the Xvnc will continue to run.  If this is used with the XDMCP options -query
+and -once, the Xvnc and associated X clients will die when the user logs out of
+the X session in the normal way.  It is important to use a VNC password in this
+case.  A typical entry in inetd.conf might be:
+
+5951   stream   tcp wait   james     /usr/local/bin/Xvnc Xvnc -inetd -query localhost -once passwordFile=/home/james/.vnc/passwd
+
+In fact typically, you would have one entry for each user who uses VNC
+regularly, each of whom has their own dedicated TCP port which they use.  In
+this example, when user "james" connects to :51, he enters his VNC password,
+then gets the XDM login screen where he logs in in the normal way.  However,
+unlike the previous example, if he disconnects, the session remains persistent,
+and when he reconnects he will get the same session back again.  When he logs
+out of the X session, the Xvnc will die, but of course a new one will be
+created automatically the next time he connects.
+
+.SH SEE ALSO
+.BR vncconfig (1),
+.BR vncpasswd (1),
+.BR vncserver (1),
+.BR vncviewer (1),
+.BR Xserver (1),
+.BR inetd (1)
+.br
+http://www.realvnc.com
+
+.SH AUTHOR
+Tristan Richardson, RealVNC Ltd.
+
+VNC was originally developed by the RealVNC team while at Olivetti Research Ltd
+/ AT&T Laboratories Cambridge.  It is now being maintained by RealVNC Ltd.  See
+http://www.realvnc.com for details.
diff --git a/xc/programs/Xserver/vnc/Imakefile b/xc/programs/Xserver/vnc/Imakefile
new file mode 100644
index 0000000..982233a
--- /dev/null
+++ b/xc/programs/Xserver/vnc/Imakefile
@@ -0,0 +1,44 @@
+XCOMM CDEBUGFLAGS = -g
+XCOMM CXXDEBUGFLAGS = -g
+
+       VNCTOP = $(TOP)/..
+   VNCINCLUDE = -I$(VNCTOP) -I$(VNCTOP)/vncconfig
+
+#define CplusplusSource
+
+#if DoLoadableServer
+#define IHaveSubdirs
+#endif
+
+#include <Server.tmpl>
+
+#if DoLoadableServer
+       MODULE_SUBDIRS = module
+#endif
+         SRCS = vncExtInit.cc vncHooks.cc XserverDesktop.cc
+         OBJS = vncExtInit.o vncHooks.o XserverDesktop.o
+     INCLUDES = -I../include -I$(EXTINCSRC) -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+                -I../mfb -I../mi $(VNCINCLUDE)
+#if defined(XFree86Version) && XFree86Version >= 4000
+   VNCDEFINES = -DGC_HAS_COMPOSITE_CLIP
+#endif
+#if defined(ProjectX) && (ProjectX >= 604)
+   VNCDEFINES = -DGC_HAS_COMPOSITE_CLIP
+#endif
+      DEFINES = $(STD_DEFINES) $(VNCDEFINES) -UXFree86LOADER
+
+#define IHaveSubdirs
+SUBDIRS = Xvnc $(MODULE_SUBDIRS)
+
+NormalLibraryTarget(vnc,$(OBJS))
+LintLibraryTarget(vnc,$(SRCS))
+NormalLintTarget($(SRCS))
+
+NormalLibraryObjectRule()
+NormalCplusplusObjectRule()
+
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+
+DependTarget()
diff --git a/xc/programs/Xserver/vnc/RegionHelper.h b/xc/programs/Xserver/vnc/RegionHelper.h
new file mode 100644
index 0000000..640d558
--- /dev/null
+++ b/xc/programs/Xserver/vnc/RegionHelper.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+#ifndef __REGIONHELPER_H__
+#define __REGIONHELPER_H__
+
+// RegionHelper is a class which helps in using X server regions by
+// automatically freeing them in the destructor.  It also fixes a problem with
+// REGION_INIT when given an empty rectangle.
+
+class RegionHelper {
+public:
+
+  // constructor from a single rect
+  RegionHelper(ScreenPtr pScreen_, BoxPtr rect, int size)
+    : pScreen(pScreen_), reg(0)
+  {
+    init(rect, size);
+  }
+
+  // constructor from an existing X server region
+  RegionHelper(ScreenPtr pScreen_, RegionPtr pRegion)
+    : pScreen(pScreen_), reg(&regRec)
+  {
+    REGION_INIT(pScreen, reg, NullBox, 0);
+    REGION_COPY(pScreen, reg, pRegion);
+  }
+
+  // constructor from an array of rectangles
+  RegionHelper(ScreenPtr pScreen_, int nrects, xRectanglePtr rects,
+               int ctype=CT_NONE)
+    : pScreen(pScreen_)
+  {
+    reg = RECTS_TO_REGION(pScreen, nrects, rects, ctype);
+  }
+
+  // constructor for calling init() later
+  RegionHelper(ScreenPtr pScreen_) : pScreen(pScreen_), reg(0) {
+  }
+
+  void init(BoxPtr rect, int size) {
+    reg = &regRec;
+    if (rect && (rect->x2 == rect->x1 || rect->y2 == rect->y1)) {
+      REGION_INIT(pScreen, reg, NullBox, 0);
+    } else {
+      REGION_INIT(pScreen, reg, rect, size);
+    }
+  }
+
+  // destructor frees as appropriate
+  ~RegionHelper() {
+    if (reg == &regRec) {
+      REGION_UNINIT(pScreen, reg);
+    } else if (reg) {
+      REGION_DESTROY(pScreen, reg);
+    }
+  }
+  ScreenPtr pScreen;
+  RegionRec regRec;
+  RegionPtr reg;
+};
+
+#endif
diff --git a/xc/programs/Xserver/vnc/XserverDesktop.cc b/xc/programs/Xserver/vnc/XserverDesktop.cc
new file mode 100644
index 0000000..9b5294e
--- /dev/null
+++ b/xc/programs/Xserver/vnc/XserverDesktop.cc
@@ -0,0 +1,1079 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+//
+// XserverDesktop.cxx
+//
+
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/utsname.h>
+#include <network/TcpSocket.h>
+#include <rfb/Exception.h>
+#include <rfb/VNCServerST.h>
+#include <rfb/HTTPServer.h>
+#include <rfb/LogWriter.h>
+#include <rfb/Configuration.h>
+#include "XserverDesktop.h"
+#include "vncExtInit.h"
+
+extern "C" {
+#define public c_public
+#define class c_class
+
+  // windowTable is in globals.h in XFree 4, but not in XFree 3 unfortunately
+extern WindowPtr *WindowTable;
+extern char *display;
+
+#include "inputstr.h"
+#include "servermd.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "cursorstr.h"
+#include "windowstr.h"
+#define XK_CYRILLIC
+#include "keysym.h"
+#undef public
+#undef class
+}
+
+using namespace rfb;
+using namespace network;
+
+static LogWriter vlog("XserverDesktop");
+
+rfb::IntParameter deferUpdateTime("DeferUpdate",
+                                  "Time in milliseconds to defer updates",40);
+
+rfb::BoolParameter alwaysSetDeferUpdateTimer("AlwaysSetDeferUpdateTimer",
+                  "Always reset the defer update timer on every change",false);
+
+static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col);
+
+static rdr::U8 reverseBits[] = {
+  0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
+  0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+  0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
+  0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+  0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
+  0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+  0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
+  0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+  0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
+  0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+  0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
+  0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+  0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
+  0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+  0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
+  0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+  0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
+  0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+  0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
+  0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+  0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
+  0x3f, 0xbf, 0x7f, 0xff
+};
+
+
+class MyHTTPServer : public rfb::HTTPServer {
+public:
+  MyHTTPServer(XserverDesktop* d) : desktop(d) {}
+  virtual ~MyHTTPServer() {}
+
+  virtual rdr::InStream* getFile(const char* name, const char** contentType) {
+    if (name[0] != '/' || strstr(name, "..") != 0) {
+      vlog.info("http request was for invalid file name");
+      return 0;
+    }
+
+    if (strcmp(name, "/") == 0) name = "/index.vnc";
+
+    CharArray httpDirStr(httpDir.getData());
+    CharArray fname(strlen(httpDirStr.buf)+strlen(name)+1);
+    sprintf(fname.buf, "%s%s", httpDirStr.buf, name);
+    int fd = open(fname.buf, O_RDONLY);
+    if (fd < 0) return 0;
+
+    rdr::InStream* is = new rdr::FdInStream(fd, -1, 0, true);
+    *contentType = guessContentType(name, *contentType);
+    if (strlen(name) > 4 && strcasecmp(&name[strlen(name)-4], ".vnc") == 0) {
+      is = new rdr::SubstitutingInStream(is, desktop, 20);
+      *contentType = "text/html";
+    }
+    return is;
+  }
+
+  XserverDesktop* desktop;
+};
+
+
+XserverDesktop::XserverDesktop(ScreenPtr pScreen_,
+                               network::TcpListener* listener_,
+                               network::TcpListener* httpListener_,
+                               const char* name, void* fbptr)
+  : pScreen(pScreen_), deferredUpdateTimer(0), dummyTimer(0),
+    server(0), httpServer(0),
+    listener(listener_), httpListener(httpListener_),
+    cmap(0), deferredUpdateTimerSet(false),
+    grabbing(false), ignoreHooks_(false), directFbptr(fbptr != 0),
+    oldButtonMask(0), cursorX(0), cursorY(0),
+    oldCursorX(0), oldCursorY(0)
+{
+  int i;
+  format.depth = pScreen->rootDepth;
+  for (i = 0; i < screenInfo.numPixmapFormats; i++) {
+    if (screenInfo.formats[i].depth == format.depth) {
+      format.bpp = screenInfo.formats[i].bitsPerPixel;
+      break;
+    }
+  }
+  if (i == screenInfo.numPixmapFormats) {
+    fprintf(stderr,"no pixmap format for root depth???\n");
+    abort();
+  }
+  format.bigEndian = (screenInfo.imageByteOrder == MSBFirst);
+
+  VisualPtr vis;
+  for (i = 0; i < pScreen->numVisuals; i++) {
+    if (pScreen->visuals[i].vid == pScreen->rootVisual) {
+      vis = &pScreen->visuals[i];
+      break;
+    }
+  }
+  if (i == pScreen->numVisuals) {
+    fprintf(stderr,"no visual rec for root visual???\n");
+    abort();
+  }
+  format.trueColour = (vis->c_class == TrueColor);
+  if (!format.trueColour && format.bpp != 8)
+    throw rfb::Exception("X server uses unsupported visual");
+  format.redShift   = ffs(vis->redMask) - 1;
+  format.greenShift = ffs(vis->greenMask) - 1;
+  format.blueShift  = ffs(vis->blueMask) - 1;
+  format.redMax     = vis->redMask   >> format.redShift;
+  format.greenMax   = vis->greenMask >> format.greenShift;
+  format.blueMax    = vis->blueMask  >> format.blueShift;
+
+  width_ = pScreen->width;
+  height_ = pScreen->height;
+  if (fbptr)
+    data = (rdr::U8*)fbptr;
+  else
+    data = new rdr::U8[pScreen->width * pScreen->height * (format.bpp/8)];
+  colourmap = this;
+
+  serverReset(pScreen);
+
+  server = new VNCServerST(name, this);
+  server->setPixelBuffer(this);
+
+  if (httpListener)
+    httpServer = new MyHTTPServer(this);
+}
+
+XserverDesktop::~XserverDesktop()
+{
+  if (!directFbptr)
+    delete [] data;
+  TimerFree(deferredUpdateTimer);
+  TimerFree(dummyTimer);
+  delete httpServer;
+  delete server;
+}
+
+void XserverDesktop::serverReset(ScreenPtr pScreen_)
+{
+  pScreen = pScreen_;
+  XID* ids = new XID[pScreen->maxInstalledCmaps];
+  int nmaps = (*pScreen->ListInstalledColormaps)(pScreen, ids);
+  cmap = (ColormapPtr)LookupIDByType(ids[0], RT_COLORMAP);
+  delete [] ids;
+}
+
+char* XserverDesktop::substitute(const char* varName)
+{
+  if (strcmp(varName, "$$") == 0) {
+    return rfb::strDup("$");
+  }
+  if (strcmp(varName, "$PORT") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", listener ? listener->getMyPort() : 0);
+    return str;
+  }
+  if (strcmp(varName, "$WIDTH") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", width());
+    return str;
+  }
+  if (strcmp(varName, "$HEIGHT") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", height());
+    return str;
+  }
+  if (strcmp(varName, "$APPLETWIDTH") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", width());
+    return str;
+  }
+  if (strcmp(varName, "$APPLETHEIGHT") == 0) {
+    char* str = new char[10];
+    sprintf(str, "%d", height() + 32);
+    return str;
+  }
+  if (strcmp(varName, "$DESKTOP") == 0) {
+    return rfb::strDup(server->getName());
+  }
+  if (strcmp(varName, "$DISPLAY") == 0) {
+    struct utsname uts;
+    uname(&uts);
+    char* str = new char[256];
+    strncat(str, uts.nodename, 240);
+    strcat(str, ":");
+    strncat(str, display, 10);
+    return str;
+  }
+  if (strcmp(varName, "$USER") == 0) {
+    struct passwd* user = getpwuid(getuid());
+    return rfb::strDup(user ? user->pw_name : "?");
+  }
+  return 0;
+}
+
+void XserverDesktop::setColormap(ColormapPtr cmap_)
+{
+  if (cmap != cmap_) {
+    cmap = cmap_;
+    setColourMapEntries(0, 0);
+  }
+}
+
+void XserverDesktop::setColourMapEntries(ColormapPtr pColormap, int ndef,
+                                         xColorItem* pdef)
+{
+  if (cmap != pColormap || ndef <= 0) return;
+
+  int first = pdef[0].pixel;
+  int n = 1;
+
+  for (int i = 1; i < ndef; i++) {
+    if (first + n == pdef[i].pixel) {
+      n++;
+    } else {
+      setColourMapEntries(first, n);
+      first = pdef[i].pixel;
+      n = 1;
+    }
+  }
+  setColourMapEntries(first, n);
+}
+
+void XserverDesktop::setColourMapEntries(int firstColour, int nColours)
+{
+  try {
+    server->setColourMapEntries(firstColour, nColours);
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::setColourMapEntries: %s",e.str());
+  }
+}
+
+void XserverDesktop::bell()
+{
+  server->bell();
+}
+
+void XserverDesktop::serverCutText(const char* str, int len)
+{
+  try {
+    server->serverCutText(str, len);
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::serverCutText: %s",e.str());
+  }
+}
+
+void XserverDesktop::setCursor(CursorPtr cursor)
+{
+  try {
+    int w = cursor->bits->width;
+    int h = cursor->bits->height;
+    rdr::U8* cursorData = new rdr::U8[w * h * (getPF().bpp / 8)];
+
+    xColorItem fg, bg;
+    fg.red   = cursor->foreRed;
+    fg.green = cursor->foreGreen;
+    fg.blue  = cursor->foreBlue;
+    FakeAllocColor(cmap, &fg);
+    bg.red   = cursor->backRed;
+    bg.green = cursor->backGreen;
+    bg.blue  = cursor->backBlue;
+    FakeAllocColor(cmap, &bg);
+    FakeFreeColor(cmap, fg.pixel);
+    FakeFreeColor(cmap, bg.pixel);
+
+    int xMaskBytesPerRow = BitmapBytePad(w);
+
+    for (int y = 0; y < h; y++) {
+      for (int x = 0; x < w; x++) {
+        int byte = y * xMaskBytesPerRow + x / 8;
+#if (BITMAP_BIT_ORDER == MSBFirst)
+        int bit = 7 - x % 8;
+#else
+        int bit = x % 8;
+#endif
+        switch (getPF().bpp) {
+        case 8:
+          ((rdr::U8*)cursorData)[y * w + x]
+            = (cursor->bits->source[byte] & (1 << bit)) ? fg.pixel : bg.pixel;
+          break;
+        case 16:
+          ((rdr::U16*)cursorData)[y * w + x]
+            = (cursor->bits->source[byte] & (1 << bit)) ? fg.pixel : bg.pixel;
+          break;
+        case 32:
+          ((rdr::U32*)cursorData)[y * w + x]
+            = (cursor->bits->source[byte] & (1 << bit)) ? fg.pixel : bg.pixel;
+          break;
+        }
+      }
+    }
+
+    int rfbMaskBytesPerRow = (w + 7) / 8;
+
+    rdr::U8* cursorMask = new rdr::U8[rfbMaskBytesPerRow * h];
+
+    for (int j = 0; j < h; j++) {
+      for (int i = 0; i < rfbMaskBytesPerRow; i++)
+#if (BITMAP_BIT_ORDER == MSBFirst)
+        cursorMask[j * rfbMaskBytesPerRow + i]
+          = cursor->bits->mask[j * xMaskBytesPerRow + i];
+#else
+        cursorMask[j * rfbMaskBytesPerRow + i]
+          = reverseBits[cursor->bits->mask[j * xMaskBytesPerRow + i]];
+#endif
+    }
+
+    server->setCursor(cursor->bits->width, cursor->bits->height,
+                      cursor->bits->xhot, cursor->bits->yhot,
+                      cursorData, cursorMask);
+    server->tryUpdate();
+    delete [] cursorData;
+    delete [] cursorMask;
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::setCursor: %s",e.str());
+  }
+}
+
+static void printRegion(RegionPtr reg)
+{
+  int nrects = REGION_NUM_RECTS(reg);
+
+  fprintf(stderr,"Region num rects %2d extents %3d,%3d %3dx%3d\n",nrects,
+          (REGION_EXTENTS(pScreen,reg))->x1,
+          (REGION_EXTENTS(pScreen,reg))->y1,
+          (REGION_EXTENTS(pScreen,reg))->x2-(REGION_EXTENTS(pScreen,reg))->x1,
+          (REGION_EXTENTS(pScreen,reg))->y2-(REGION_EXTENTS(pScreen,reg))->y1);
+
+  for (int i = 0; i < nrects; i++) {
+    fprintf(stderr,"    rect %3d,%3d %3dx%3d\n",
+            REGION_RECTS(reg)[i].x1,
+            REGION_RECTS(reg)[i].y1,
+            REGION_RECTS(reg)[i].x2-REGION_RECTS(reg)[i].x1,
+            REGION_RECTS(reg)[i].y2-REGION_RECTS(reg)[i].y1);
+  }
+}
+
+CARD32 XserverDesktop::deferredUpdateTimerCallback(OsTimerPtr timer,
+                                                   CARD32 now, pointer arg)
+{
+  XserverDesktop* desktop = (XserverDesktop*)arg;
+  desktop->deferredUpdateTimerSet = false;
+  try {
+    desktop->server->tryUpdate();
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::deferredUpdateTimerCallback: %s",e.str());
+  }
+  return 0;
+}
+
+void XserverDesktop::add_changed(RegionPtr reg)
+{
+  if (ignoreHooks_) return;
+  if (grabbing) return;
+  try {
+    rfb::Region rfbReg;
+    rfbReg.setExtentsAndOrderedRects((ShortRect*)REGION_EXTENTS(pScreen, reg),
+                                     REGION_NUM_RECTS(reg),
+                                     (ShortRect*)REGION_RECTS(reg));
+    server->add_changed(rfbReg);
+    if (!deferredUpdateTimerSet || alwaysSetDeferUpdateTimer) {
+      deferredUpdateTimer = TimerSet(deferredUpdateTimer, 0,
+                                     deferUpdateTime,
+                                     deferredUpdateTimerCallback, this);
+      deferredUpdateTimerSet = true;
+    }
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::add_changed: %s",e.str());
+  }
+}
+
+void XserverDesktop::add_copied(RegionPtr dst, int dx, int dy)
+{
+  if (ignoreHooks_) return;
+  if (grabbing) return;
+  try {
+    rfb::Region rfbReg;
+    rfbReg.setExtentsAndOrderedRects((ShortRect*)REGION_EXTENTS(pScreen, dst),
+                                     REGION_NUM_RECTS(dst),
+                                     (ShortRect*)REGION_RECTS(dst));
+    server->add_copied(rfbReg, rfb::Point(dx, dy));
+    if (!deferredUpdateTimerSet || alwaysSetDeferUpdateTimer) {
+      deferredUpdateTimer = TimerSet(deferredUpdateTimer, 0,
+                                     deferUpdateTime,
+                                     deferredUpdateTimerCallback, this);
+      deferredUpdateTimerSet = true;
+    }
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::add_copied: %s",e.str());
+  }
+}
+
+void XserverDesktop::positionCursor()
+{
+  if (cursorX != oldCursorX || cursorY != oldCursorY) {
+    oldCursorX = cursorX;
+    oldCursorY = cursorY;
+    (*pScreen->SetCursorPosition) (pScreen, cursorX, cursorY, FALSE);
+    server->setCursorPos(cursorX, cursorY);
+    server->tryUpdate();
+  }
+}
+
+void XserverDesktop::blockHandler(fd_set* fds)
+{
+  try {
+    ScreenPtr screenWithCursor = GetCurrentRootWindow()->drawable.pScreen;
+    if (screenWithCursor == pScreen) {
+      int x, y;
+      GetSpritePosition(&x, &y);
+      if (x != cursorX || y != cursorY) {
+        cursorX = oldCursorX = x;
+        cursorY = oldCursorY = y;
+        server->setCursorPos(x, y);
+        server->tryUpdate();
+      }
+    }
+
+    if (listener)
+      FD_SET(listener->getFd(), fds);
+    if (httpListener)
+      FD_SET(httpListener->getFd(), fds);
+
+    std::list<Socket*> sockets;
+    server->getSockets(&sockets);
+    std::list<Socket*>::iterator i;
+    for (i = sockets.begin(); i != sockets.end(); i++) {
+      FD_SET((*i)->getFd(), fds);
+    }
+    if (httpServer) {
+      httpServer->getSockets(&sockets);
+      for (i = sockets.begin(); i != sockets.end(); i++) {
+        FD_SET((*i)->getFd(), fds);
+      }
+    }
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::blockHandler: %s",e.str());
+  }
+}
+
+static CARD32 dummyTimerCallback(OsTimerPtr timer, CARD32 now, pointer arg) {
+  return 0;
+}
+
+void XserverDesktop::wakeupHandler(fd_set* fds, int nfds)
+{
+  try {
+    if (nfds >= 1) {
+
+      if (listener) {
+        if (FD_ISSET(listener->getFd(), fds)) {
+          FD_CLR(listener->getFd(), fds);
+          Socket* sock = listener->accept();
+          server->addClient(sock);
+          vlog.debug("new client, sock %d",sock->getFd());
+        }
+      }
+
+      if (httpListener) {
+        if (FD_ISSET(httpListener->getFd(), fds)) {
+          FD_CLR(httpListener->getFd(), fds);
+          Socket* sock = httpListener->accept();
+          httpServer->addClient(sock);
+          vlog.debug("new http client, sock %d",sock->getFd());
+        }
+      }
+
+      std::list<Socket*> sockets;
+      server->getSockets(&sockets);
+      std::list<Socket*>::iterator i;
+      for (i = sockets.begin(); i != sockets.end(); i++) {
+        int fd = (*i)->getFd();
+        if (FD_ISSET(fd, fds)) {
+          FD_CLR(fd, fds);
+          if (!server->processSocketEvent(*i)) {
+            vlog.debug("client gone, sock %d",fd);
+            vncClientGone(fd);
+          }
+        }
+      }
+
+      if (httpServer) {
+        httpServer->getSockets(&sockets);
+        for (i = sockets.begin(); i != sockets.end(); i++) {
+          int fd = (*i)->getFd();
+          if (FD_ISSET(fd, fds)) {
+            FD_CLR(fd, fds);
+            if (!httpServer->processSocketEvent(*i)) {
+              vlog.debug("http client gone, sock %d",fd);
+            }
+          }
+        }
+      }
+
+      positionCursor();
+    }
+
+    int timeout = server->checkTimeouts();
+    if (timeout > 0) {
+      // set a dummy timer just so we are guaranteed be called again next time.
+      dummyTimer = TimerSet(dummyTimer, 0, timeout,
+                            dummyTimerCallback, 0);
+    }
+
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::wakeupHandler: %s",e.str());
+  }
+}
+
+void XserverDesktop::addClient(Socket* sock, bool reverse)
+{
+  vlog.debug("new client, sock %d reverse %d",sock->getFd(),reverse);
+  server->addClient(sock, reverse);
+}
+
+void XserverDesktop::disconnectClients()
+{
+  vlog.debug("disconnecting all clients");
+  return server->closeClients("Disconnection from server end");
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// SDesktop callbacks
+
+
+void XserverDesktop::pointerEvent(const Point& pos, rdr::U8 buttonMask)
+{
+  xEvent ev;
+  DevicePtr dev = LookupPointerDevice();
+
+  // SetCursorPosition seems to be very expensive (at least on XFree86 3.3.6
+  // for S3), so we delay calling it until positionCursor() is called at the
+  // end of processing a load of RFB.
+  //(*pScreen->SetCursorPosition) (pScreen, pos.x, pos.y, FALSE);
+
+  NewCurrentScreen(pScreen, pos.x, pos.y);
+
+  ev.u.u.type = MotionNotify;
+  ev.u.u.detail = 0;
+  ev.u.keyButtonPointer.rootX = pos.x;
+  ev.u.keyButtonPointer.rootY = pos.y;
+  ev.u.keyButtonPointer.time = GetTimeInMillis();
+
+  if (pos.x != cursorX || pos.y != cursorY)
+    (*dev->processInputProc)(&ev, (DeviceIntPtr)dev, 1);
+
+  for (int i = 0; i < 5; i++) {
+    if ((buttonMask ^ oldButtonMask) & (1<<i)) {
+#ifdef XINPUT
+      // God knows why but some idiot decided to conditionally move the pointer
+      // mapping out of DIX, so we guess here that if XINPUT is defined we have
+      // to do it ourselves...
+      ev.u.u.detail = ((DeviceIntPtr)dev)->button->map[i + 1];
+#else
+      ev.u.u.detail = i + 1;
+#endif
+      ev.u.u.type = (buttonMask & (1<<i)) ? ButtonPress : ButtonRelease;
+      (*dev->processInputProc)(&ev, (DeviceIntPtr)dev, 1);
+    }
+  }
+
+  cursorX = pos.x;
+  cursorY = pos.y;
+  oldButtonMask = buttonMask;
+}
+
+void XserverDesktop::clientCutText(const char* str, int len)
+{
+  vncClientCutText(str, len);
+}
+
+void XserverDesktop::grabRegion(const rfb::Region& region)
+{
+  if (directFbptr) return;
+  if (!pScreen->GetImage) {
+    vlog.error("VNC error: pScreen->GetImage == 0");
+    return;
+  }
+
+  grabbing = true;
+
+  int bytesPerPixel = format.bpp/8;
+  int bytesPerRow = pScreen->width * bytesPerPixel;
+
+  std::vector<rfb::Rect> rects;
+  std::vector<rfb::Rect>::iterator i;
+  region.get_rects(&rects);
+  for (i = rects.begin(); i != rects.end(); i++) {
+    for (int y = i->tl.y; y < i->br.y; y++) {
+      (*pScreen->GetImage) ((DrawablePtr)WindowTable[pScreen->myNum],
+                            i->tl.x, y, i->width(), 1,
+                            ZPixmap, (unsigned long)~0L,
+                            ((char*)data
+                             + y * bytesPerRow + i->tl.x * bytesPerPixel));
+    }
+  }
+  grabbing = false;
+}
+
+void XserverDesktop::lookup(int index, int* r, int* g, int* b)
+{
+  EntryPtr pent;
+  pent = (EntryPtr)&cmap->red[index];
+  if (pent->fShared) {
+    *r = pent->co.shco.red->color;
+    *g = pent->co.shco.green->color;
+    *b = pent->co.shco.blue->color;
+  } else {
+    *r = pent->co.local.red;
+    *g = pent->co.local.green;
+    *b = pent->co.local.blue;
+  }
+}
+
+//
+// Keyboard handling
+//
+
+#define IS_PRESSED(keyc, keycode) \
+  ((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
+
+// ModifierState is a class which helps simplify generating a "fake" press
+// or release of shift, ctrl, alt, etc.  An instance of the class is created
+// for every modifier which may need to be pressed or released.  Then either
+// press() or release() may be called to make sure that the corresponding keys
+// are in the right state.  The destructor of the class automatically reverts
+// to the previous state.  Each modifier may have multiple keys associated with
+// it, so in the case of a fake release, this may involve releasing more than
+// one key.
+
+class ModifierState {
+public:
+  ModifierState(DeviceIntPtr dev_, int modIndex_)
+    : dev(dev_), modIndex(modIndex_), nKeys(0), keys(0), pressed(false)
+  {
+  }
+  ~ModifierState() {
+    for (int i = 0; i < nKeys; i++)
+      generateXKeyEvent(keys[i], !pressed);
+    delete [] keys;
+  }
+  void press() {
+    KeyClassPtr keyc = dev->key;
+    if (!(keyc->state & (1<<modIndex))) {
+      tempKeyEvent(keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier],
+                   true);
+      pressed = true;
+    }
+  }
+  void release() {
+    KeyClassPtr keyc = dev->key;
+    if (keyc->state & (1<<modIndex)) {
+      for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
+        int keycode
+          = keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier + k];
+        if (keycode && IS_PRESSED(keyc, keycode))
+          tempKeyEvent(keycode, false);
+      }
+    }
+  }
+private:
+  void tempKeyEvent(int keycode, bool down) {
+    if (keycode) {
+      if (!keys) keys = new int[dev->key->maxKeysPerModifier];
+      keys[nKeys++] = keycode;
+      generateXKeyEvent(keycode, down);
+    }
+  }
+  void generateXKeyEvent(int keycode, bool down) {
+    xEvent ev;
+    ev.u.u.type = down ? KeyPress : KeyRelease;
+    ev.u.u.detail = keycode;
+    ev.u.keyButtonPointer.time = GetTimeInMillis();
+    (*dev->c_public.processInputProc)(&ev, dev, 1);
+    vlog.debug("fake keycode %d %s", keycode, down ? "down" : "up");
+  }
+  DeviceIntPtr dev;
+  int modIndex;
+  int nKeys;
+  int* keys;
+  bool pressed;
+};
+
+
+// altKeysym is a table of alternative keysyms which have the same meaning.
+
+struct altKeysym_t {
+  KeySym a, b;
+};
+
+altKeysym_t altKeysym[] = {
+  { XK_Shift_L,        XK_Shift_R },
+  { XK_Control_L,      XK_Control_R },
+  { XK_Meta_L,         XK_Meta_R },
+  { XK_Alt_L,          XK_Alt_R },
+  { XK_Super_L,        XK_Super_R },
+  { XK_Hyper_L,        XK_Hyper_R },
+  { XK_KP_Space,       XK_space },
+  { XK_KP_Tab,         XK_Tab },
+  { XK_KP_Enter,       XK_Return },
+  { XK_KP_F1,          XK_F1 },
+  { XK_KP_F2,          XK_F2 },
+  { XK_KP_F3,          XK_F3 },
+  { XK_KP_F4,          XK_F4 },
+  { XK_KP_Home,        XK_Home },
+  { XK_KP_Left,        XK_Left },
+  { XK_KP_Up,          XK_Up },
+  { XK_KP_Right,       XK_Right },
+  { XK_KP_Down,        XK_Down },
+  { XK_KP_Page_Up,     XK_Page_Up },
+  { XK_KP_Page_Down,   XK_Page_Down },
+  { XK_KP_End,         XK_End },
+  { XK_KP_Begin,       XK_Begin },
+  { XK_KP_Insert,      XK_Insert },
+  { XK_KP_Delete,      XK_Delete },
+  { XK_KP_Equal,       XK_equal },
+  { XK_KP_Multiply,    XK_asterisk },
+  { XK_KP_Add,         XK_plus },
+  { XK_KP_Separator,   XK_comma },
+  { XK_KP_Subtract,    XK_minus },
+  { XK_KP_Decimal,     XK_period },
+  { XK_KP_Divide,      XK_slash },
+  { XK_KP_0,           XK_0 },
+  { XK_KP_1,           XK_1 },
+  { XK_KP_2,           XK_2 },
+  { XK_KP_3,           XK_3 },
+  { XK_KP_4,           XK_4 },
+  { XK_KP_5,           XK_5 },
+  { XK_KP_6,           XK_6 },
+  { XK_KP_7,           XK_7 },
+  { XK_KP_8,           XK_8 },
+  { XK_KP_9,           XK_9 },
+};
+
+// keyEvent() - work out the best keycode corresponding to the keysym sent by
+// the viewer.  This is non-trivial because we can't assume much about the
+// local keyboard layout.  We must also find out which column of the keyboard
+// mapping the keysym is in, and alter the shift state appropriately.  Column 0
+// means both shift and "mode_switch" (AltGr) must be released, column 1 means
+// shift must be pressed and mode_switch released, column 2 means shift must be
+// released and mode_switch pressed, and column 3 means both shift and
+// mode_switch must be pressed.
+
+void XserverDesktop::keyEvent(rdr::U32 keysym, bool down)
+{
+  if (keysym == XK_Caps_Lock) {
+    vlog.debug("Ignoring caps lock");
+    return;
+  }
+  DeviceIntPtr dev = (DeviceIntPtr)LookupKeyboardDevice();
+  KeyClassPtr keyc = dev->key;
+  KeySymsPtr keymap = &keyc->curKeySyms;
+
+  // find which modifier Mode_switch is on.
+  int modeSwitchMapIndex = 0;
+  for (int i = 3; i < 8; i++) {
+    for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
+      int keycode = keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k];
+      for (int j = 0; j < keymap->mapWidth; j++) {
+        if (keycode != 0 &&
+            keymap->map[(keycode - keymap->minKeyCode)
+                        * keymap->mapWidth + j] == XK_Mode_switch)
+        {
+          modeSwitchMapIndex = i;
+          break;
+        }
+      }
+    }
+  }
+
+  int col = 0;
+  if (keyc->state & (1<<ShiftMapIndex)) col |= 1;
+  if (modeSwitchMapIndex && (keyc->state & (1<<modeSwitchMapIndex))) col |= 2;
+
+  int kc = KeysymToKeycode(keymap, keysym, &col);
+
+  // Sort out the "shifted Tab" mess.  If we are sent a shifted Tab, generate a
+  // local shifted Tab regardless of what the "shifted Tab" keysym is on the
+  // local keyboard (it might be Tab, ISO_Left_Tab or HP's private BackTab
+  // keysym, and quite possibly some others too).  We never get ISO_Left_Tab
+  // here because it's already been translated in VNCSConnectionST.
+  if (keysym == XK_Tab && (keyc->state & (1<<ShiftMapIndex)))
+    col |= 1;
+
+  if (kc == 0) {
+    // Not a direct match in the local keyboard mapping.  Check for alternative
+    // keysyms with the same meaning.
+    for (int i = 0; i < sizeof(altKeysym) / sizeof(altKeysym_t); i++) {
+      if (keysym == altKeysym[i].a)
+        kc = KeysymToKeycode(keymap, altKeysym[i].b, &col);
+      else if (keysym == altKeysym[i].b)
+        kc = KeysymToKeycode(keymap, altKeysym[i].a, &col);
+      if (kc) break;
+    }
+  }
+
+  if (kc == 0) {
+    // Last resort - dynamically add a new key to the keyboard mapping.
+    for (kc = keymap->maxKeyCode; kc >= keymap->minKeyCode; kc--) {
+      if (!keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth]) {
+        keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth] = keysym;
+        col = 0;
+        SendMappingNotify(MappingKeyboard, kc, 1, serverClient);
+        vlog.info("Added unknown keysym 0x%x to keycode %d",keysym,kc);
+        break;
+      }
+    }
+    if (kc < keymap->minKeyCode) {
+      vlog.info("Keyboard mapping full - ignoring unknown keysym 0x%x",keysym);
+      return;
+    }
+  }
+
+  // See if it's a modifier key.  If so, then don't do any auto-repeat, because
+  // the X server will translate each press into a release followed by a press.
+  for (int i = 0; i < 8; i++) {
+    for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
+      if (kc == keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k] &&
+          IS_PRESSED(keyc,kc) && down)
+        return;
+    }
+  }
+
+  ModifierState shift(dev, ShiftMapIndex);
+  ModifierState modeSwitch(dev, modeSwitchMapIndex);
+  if (down) {
+    if (col & 1)
+      shift.press();
+    else
+      shift.release();
+    if (modeSwitchMapIndex) {
+      if (col & 2)
+        modeSwitch.press();
+      else
+        modeSwitch.release();
+    }
+  }
+  vlog.debug("keycode %d %s", kc, down ? "down" : "up");
+  xEvent ev;
+  ev.u.u.type = down ? KeyPress : KeyRelease;
+  ev.u.u.detail = kc;
+  ev.u.keyButtonPointer.time = GetTimeInMillis();
+  (*dev->c_public.processInputProc)(&ev, dev, 1);
+}
+
+
+void XConvertCase(KeySym sym, KeySym *lower, KeySym *upper)
+{
+    *lower = sym;
+    *upper = sym;
+    switch(sym >> 8) {
+    case 0: /* Latin 1 */
+	if ((sym >= XK_A) && (sym <= XK_Z))
+	    *lower += (XK_a - XK_A);
+	else if ((sym >= XK_a) && (sym <= XK_z))
+	    *upper -= (XK_a - XK_A);
+	else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+	    *lower += (XK_agrave - XK_Agrave);
+	else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
+	    *upper -= (XK_agrave - XK_Agrave);
+	else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
+	    *lower += (XK_oslash - XK_Ooblique);
+	else if ((sym >= XK_oslash) && (sym <= XK_thorn))
+	    *upper -= (XK_oslash - XK_Ooblique);
+	break;
+    case 1: /* Latin 2 */
+	/* Assume the KeySym is a legal value (ignore discontinuities) */
+	if (sym == XK_Aogonek)
+	    *lower = XK_aogonek;
+	else if (sym >= XK_Lstroke && sym <= XK_Sacute)
+	    *lower += (XK_lstroke - XK_Lstroke);
+	else if (sym >= XK_Scaron && sym <= XK_Zacute)
+	    *lower += (XK_scaron - XK_Scaron);
+	else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
+	    *lower += (XK_zcaron - XK_Zcaron);
+	else if (sym == XK_aogonek)
+	    *upper = XK_Aogonek;
+	else if (sym >= XK_lstroke && sym <= XK_sacute)
+	    *upper -= (XK_lstroke - XK_Lstroke);
+	else if (sym >= XK_scaron && sym <= XK_zacute)
+	    *upper -= (XK_scaron - XK_Scaron);
+	else if (sym >= XK_zcaron && sym <= XK_zabovedot)
+	    *upper -= (XK_zcaron - XK_Zcaron);
+	else if (sym >= XK_Racute && sym <= XK_Tcedilla)
+	    *lower += (XK_racute - XK_Racute);
+	else if (sym >= XK_racute && sym <= XK_tcedilla)
+	    *upper -= (XK_racute - XK_Racute);
+	break;
+    case 2: /* Latin 3 */
+	/* Assume the KeySym is a legal value (ignore discontinuities) */
+	if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
+	    *lower += (XK_hstroke - XK_Hstroke);
+	else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
+	    *lower += (XK_gbreve - XK_Gbreve);
+	else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
+	    *upper -= (XK_hstroke - XK_Hstroke);
+	else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
+	    *upper -= (XK_gbreve - XK_Gbreve);
+	else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
+	    *lower += (XK_cabovedot - XK_Cabovedot);
+	else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
+	    *upper -= (XK_cabovedot - XK_Cabovedot);
+	break;
+    case 3: /* Latin 4 */
+	/* Assume the KeySym is a legal value (ignore discontinuities) */
+	if (sym >= XK_Rcedilla && sym <= XK_Tslash)
+	    *lower += (XK_rcedilla - XK_Rcedilla);
+	else if (sym >= XK_rcedilla && sym <= XK_tslash)
+	    *upper -= (XK_rcedilla - XK_Rcedilla);
+	else if (sym == XK_ENG)
+	    *lower = XK_eng;
+	else if (sym == XK_eng)
+	    *upper = XK_ENG;
+	else if (sym >= XK_Amacron && sym <= XK_Umacron)
+	    *lower += (XK_amacron - XK_Amacron);
+	else if (sym >= XK_amacron && sym <= XK_umacron)
+	    *upper -= (XK_amacron - XK_Amacron);
+	break;
+    case 6: /* Cyrillic */
+	/* Assume the KeySym is a legal value (ignore discontinuities) */
+	if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
+	    *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
+	else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
+	    *upper += (XK_Serbian_DJE - XK_Serbian_dje);
+	else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
+	    *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
+	else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
+	    *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
+        break;
+    case 7: /* Greek */
+	/* Assume the KeySym is a legal value (ignore discontinuities) */
+	if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
+	    *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+	else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
+		 sym != XK_Greek_iotaaccentdieresis &&
+		 sym != XK_Greek_upsilonaccentdieresis)
+	    *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+	else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
+	    *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
+	else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
+		 sym != XK_Greek_finalsmallsigma)
+	    *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
+        break;
+    }
+}
+
+static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)
+{
+  register int per = keymap->mapWidth;
+  register KeySym *syms;
+  KeySym lsym, usym;
+
+  if ((col < 0) || ((col >= per) && (col > 3)) ||
+      (keycode < keymap->minKeyCode) || (keycode > keymap->maxKeyCode))
+    return NoSymbol;
+
+  syms = &keymap->map[(keycode - keymap->minKeyCode) * per];
+  if (col < 4) {
+    if (col > 1) {
+      while ((per > 2) && (syms[per - 1] == NoSymbol))
+        per--;
+      if (per < 3)
+        col -= 2;
+    }
+    if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
+      XConvertCase(syms[col&~1], &lsym, &usym);
+      if (!(col & 1))
+        return lsym;
+      // I'm commenting out this logic because it's incorrect even though it
+      // was copied from the Xlib sources.  The X protocol book quite clearly
+      // states that where a group consists of element 1 being a non-alphabetic
+      // keysym and element 2 being NoSymbol that you treat the second element
+      // as being the same as the first.  This also tallies with the behaviour
+      // produced by the installed Xlib on my linux box (I believe this is
+      // because it uses some XKB code rather than the original Xlib code -
+      // compare XKBBind.c with KeyBind.c in lib/X11).
+      // else if (usym == lsym)
+      //   return NoSymbol;
+      else
+        return usym;
+    }
+  }
+  return syms[col];
+}
+
+// KeysymToKeycode() - find the keycode and column corresponding to the given
+// keysym.  The value of col passed in should be the column determined from the
+// current shift state.  If the keysym can be found in that column we prefer
+// that to finding it in a different column (which would require fake events to
+// alter the shift state).
+
+static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col)
+{
+  register int i, j;
+
+  j = *col;
+  for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
+    if (KeyCodetoKeySym(keymap, i, j) == ks)
+      return i;
+  }
+
+  for (j = 0; j < keymap->mapWidth; j++) {
+    for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
+      if (KeyCodetoKeySym(keymap, i, j) == ks) {
+        *col = j;
+        return i;
+      }
+    }
+  }
+  return 0;
+}
diff --git a/xc/programs/Xserver/vnc/XserverDesktop.h b/xc/programs/Xserver/vnc/XserverDesktop.h
new file mode 100644
index 0000000..c983ece
--- /dev/null
+++ b/xc/programs/Xserver/vnc/XserverDesktop.h
@@ -0,0 +1,102 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+//
+// XserverDesktop.h
+//
+
+#ifndef __XSERVERDESKTOP_H__
+#define __XSERVERDESKTOP_H__
+
+#include <rfb/SDesktop.h>
+#include <rfb/PixelBuffer.h>
+#include <rfb/Configuration.h>
+#include <rdr/SubstitutingInStream.h>
+
+extern "C" {
+#define class c_class;
+#include <scrnintstr.h>
+#include <os.h>
+#undef class
+}
+
+namespace rfb {
+  class VNCServerST;
+}
+
+namespace network { class TcpListener; class Socket; }
+class MyHTTPServer;
+
+class XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
+                       public rfb::ColourMap, public rdr::Substitutor {
+public:
+
+  XserverDesktop(ScreenPtr pScreen, network::TcpListener* listener,
+                 network::TcpListener* httpListener_,
+                 const char* name, void* fbptr);
+  virtual ~XserverDesktop();
+
+  // methods called from X server code
+  void serverReset(ScreenPtr pScreen);
+  void setColormap(ColormapPtr cmap);
+  void setColourMapEntries(ColormapPtr pColormap, int ndef, xColorItem* pdef);
+  void bell();
+  void serverCutText(const char* str, int len);
+  void setCursor(CursorPtr cursor);
+  void add_changed(RegionPtr reg);
+  void add_copied(RegionPtr dst, int dx, int dy);
+  void positionCursor();
+  void ignoreHooks(bool b) { ignoreHooks_ = b; }
+  void blockHandler(fd_set* fds);
+  void wakeupHandler(fd_set* fds, int nfds);
+  void addClient(network::Socket* sock, bool reverse);
+  void disconnectClients();
+
+  // rfb::SDesktop callbacks
+  virtual void pointerEvent(const rfb::Point& pos, rdr::U8 buttonMask);
+  virtual void keyEvent(rdr::U32 key, bool down);
+  virtual void clientCutText(const char* str, int len);
+  virtual rfb::Point getFbSize() { return rfb::Point(width(), height()); }
+
+  // rfb::PixelBuffer callbacks
+  virtual void grabRegion(const rfb::Region& r);
+
+  // rfb::ColourMap callbacks
+  virtual void lookup(int index, int* r, int* g, int* b);
+
+  // rdr::Substitutor callback
+  virtual char* substitute(const char* varName);
+
+private:
+  void setColourMapEntries(int firstColour, int nColours);
+  static CARD32 deferredUpdateTimerCallback(OsTimerPtr timer, CARD32 now,
+                                            pointer arg);
+  ScreenPtr pScreen;
+  OsTimerPtr deferredUpdateTimer, dummyTimer;
+  rfb::VNCServerST* server;
+  MyHTTPServer* httpServer;
+  network::TcpListener* listener;
+  network::TcpListener* httpListener;
+  ColormapPtr cmap;
+  bool deferredUpdateTimerSet;
+  bool grabbing;
+  bool ignoreHooks_;
+  bool directFbptr;
+  int oldButtonMask;
+  int cursorX, cursorY, oldCursorX, oldCursorY;
+};
+#endif
diff --git a/xc/programs/Xserver/vnc/Xvnc/Imakefile b/xc/programs/Xserver/vnc/Xvnc/Imakefile
new file mode 100644
index 0000000..d948887
--- /dev/null
+++ b/xc/programs/Xserver/vnc/Xvnc/Imakefile
@@ -0,0 +1,74 @@
+
+       VNCTOP = $(TOP)/..
+      VNCLIBS = VncExtLibs
+   VNCINCLUDE = -I$(VNCTOP) -I$(VNCTOP)/vncconfig
+
+#define CplusplusSource
+
+#include <Server.tmpl>
+
+#ifdef XVendorString
+VENDORSTRING = XVendorString
+#else
+VENDORSTRING = "unknown"
+#endif
+
+#ifdef XVendorRelease
+VENDORRELEASE = XVendorRelease
+#else
+VENDORRELEASE = 0
+#endif
+
+   VENDOR_STRING = -DVENDOR_STRING=\"$(VENDORSTRING)\"
+   VENDOR_RELEASE = -DVENDOR_RELEASE="$(VENDORRELEASE)"
+
+#ifdef OS2Architecture
+SRCS1 = os2_stubs.c
+OBJS1 = os2_stubs.o
+#endif
+
+SRCSA =	xvnc.cc stubs.c $(SRCS1) miinitext.c $(SRCS2)
+
+OBJSA =	xvnc.o stubs.o $(OBJS1) miinitext.o $(OBJS2)
+
+INCLUDES = -I. -I.. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+	   -I../../cfb -I../../mfb -I../../mi -I../../include -I../../os  \
+           -I$(EXTINCSRC) -I$(XINCLUDESRC)  -I$(SERVERSRC)/render $(VNCINCLUDE)
+
+DEFINES = $(OS_DEFINES) $(SHMDEF) $(MMAPDEF) \
+          $(VENDOR_STRING) $(VENDOR_RELEASE) $(STD_DEFINES) ServerOSDefines \
+          -UXFree86LOADER
+
+#ifdef XFree86Version
+/* 
+ * Make sure XINPUT, XF86VidTune, etc arent defined for the miinitext.o 
+ * used by Xvnc 
+ */
+EXT_DEFINES = ExtensionDefines -UXINPUT -UXF86VIDMODE -UXFreeXDGA -UXF86MISC
+#endif
+
+
+SRCS =	$(SRCSA) $(SRCSB) $(SRCSC)
+OBJS =	$(OBJSA) $(OBJSB) $(OBJSC)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(xvnc,$(OBJS) buildtime.o)
+
+#ifdef OS2Architecture
+LinkSourceFile(os2_stubs.c,../xfree86/os-support/os2)
+SpecialCObjectRule(os2_stubs,$(ICONFIGFILES),-DOS2NULLSELECT)
+#endif
+
+#ifdef HasGcc
+NO_OPERATOR_NAMES = -fno-operator-names
+#endif
+LinkSourceFile(stubs.c,../../Xi)
+SpecialCplusplusObjectRule(xvnc,$(ICONFIGFILES) xvnc,$(EXT_DEFINES) $(NO_OPERATOR_NAMES))
+
+LinkSourceFile(miinitext.c,$(SERVERSRC)/mi)
+SpecialCObjectRule(miinitext,$(ICONFIGFILES),$(EXT_DEFINES) $(PAN_DEFINES) -DNO_HW_ONLY_EXTS -DNO_MODULE_EXTS $(EXT_MODULE_DEFINES) -UXFree86LOADER)
+
+/* InstallManPage(Xvfb,$(MANDIR)) */
+DependTarget()
+
+buildtime.o: $(OBJS) ../LibraryTargetName(vnc) $(VNCLIBS)
diff --git a/xc/programs/Xserver/vnc/Xvnc/buildtime.c b/xc/programs/Xserver/vnc/Xvnc/buildtime.c
new file mode 100644
index 0000000..a96031c
--- /dev/null
+++ b/xc/programs/Xserver/vnc/Xvnc/buildtime.c
@@ -0,0 +1,18 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+char buildtime[] = __DATE__ " " __TIME__;
diff --git a/xc/programs/Xserver/vnc/Xvnc/xvnc.cc b/xc/programs/Xserver/vnc/Xvnc/xvnc.cc
new file mode 100644
index 0000000..cf8fdf9
--- /dev/null
+++ b/xc/programs/Xserver/vnc/Xvnc/xvnc.cc
@@ -0,0 +1,1221 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+/*
+
+Copyright (c) 1993  X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+
+#include <rfb/Configuration.h>
+#include <rfb/Logger_stdio.h>
+#include <rfb/LogWriter.h>
+#include <network/TcpSocket.h>
+#include "vncExtInit.h"
+
+extern "C" {
+#define class c_class
+#define public c_public
+#define xor c_xor
+#define and c_and
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+#include <stdio.h>
+#include "X11/X.h"
+#define NEED_EVENTS
+#include "X11/Xproto.h"
+#include "X11/Xos.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define PSZ 8
+#include "cfb.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#ifndef WIN32
+#include <sys/param.h>
+#endif
+#include <X11/XWDFile.h>
+#include "dix.h"
+#include "miline.h"
+#include "inputstr.h"
+#include "keysym.h"
+  extern int defaultColorVisualClass;
+  extern char buildtime[];
+#undef class
+#undef public
+#undef xor
+#undef and
+  extern Bool cfb16ScreenInit(ScreenPtr, pointer, int, int, int, int, int);
+  extern Bool cfb32ScreenInit(ScreenPtr, pointer, int, int, int, int, int);
+  extern Bool cfb16CreateGC(GCPtr);
+  extern Bool cfb32CreateGC(GCPtr);
+  extern void cfb16GetSpans(DrawablePtr, int, DDXPointPtr, int*, int, char*);
+  extern void cfb32GetSpans(DrawablePtr, int, DDXPointPtr, int*, int, char*);
+  extern void cfb16GetImage(DrawablePtr, int, int, int, int, unsigned int,
+                            unsigned long, char*);
+  extern void cfb32GetImage(DrawablePtr, int, int, int, int, unsigned int,
+                            unsigned long, char*);
+}
+
+#define XVNCVERSION "4.0"
+
+extern char *display;
+extern int monitorResolution;
+
+#define VFB_DEFAULT_WIDTH  1024
+#define VFB_DEFAULT_HEIGHT 768
+#define VFB_DEFAULT_DEPTH  16
+#define VFB_DEFAULT_WHITEPIXEL 0xffff
+#define VFB_DEFAULT_BLACKPIXEL 0
+#define VFB_DEFAULT_LINEBIAS 0
+#define XWD_WINDOW_NAME_LEN 60
+
+typedef struct
+{
+  int scrnum;
+  int width;
+  int paddedWidth;
+  int paddedWidthInBytes;
+  int height;
+  int depth;
+  int bitsPerPixel;
+  int sizeInBytes;
+  int ncolors;
+  char *pfbMemory;
+  XWDColor *pXWDCmap;
+  XWDFileHeader *pXWDHeader;
+  Pixel blackPixel;
+  Pixel whitePixel;
+  unsigned int lineBias;
+  Bool pixelFormatDefined;
+  Bool rgbNotBgr;
+  int redBits, greenBits, blueBits;
+
+} vfbScreenInfo, *vfbScreenInfoPtr;
+
+static int vfbNumScreens;
+static vfbScreenInfo vfbScreens[MAXSCREENS];
+static Bool vfbPixmapDepths[33];
+static char needswap = 0;
+static int lastScreen = -1;
+
+static bool displaySpecified = false;
+static bool wellKnownSocketsCreated = false;
+static char displayNumStr[16];
+
+#define swapcopy16(_dst, _src) \
+    if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
+    else _dst = _src;
+
+#define swapcopy32(_dst, _src) \
+    if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
+    else _dst = _src;
+
+
+static void vfbInitializePixmapDepths()
+{
+  int i;
+  vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
+  for (i = 2; i <= 32; i++)
+    vfbPixmapDepths[i] = FALSE;
+}
+
+static void vfbInitializeDefaultScreens()
+{
+  int i;
+
+  for (i = 0; i < MAXSCREENS; i++)
+  {
+    vfbScreens[i].scrnum = i;
+    vfbScreens[i].width  = VFB_DEFAULT_WIDTH;
+    vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
+    vfbScreens[i].depth  = VFB_DEFAULT_DEPTH;
+    vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
+    vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
+    vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
+    vfbScreens[i].pixelFormatDefined = FALSE;
+    vfbScreens[i].pfbMemory = NULL;
+  }
+  vfbNumScreens = 1;
+}
+
+static int vfbBitsPerPixel(int depth)
+{
+  if (depth == 1) return 1;
+  else if (depth <= 8) return 8;
+  else if (depth <= 16) return 16;
+  else return 32;
+}
+
+extern "C" {
+  void ddxGiveUp()
+  {
+    int i;
+
+    /* clean up the framebuffers */
+
+    for (i = 0; i < vfbNumScreens; i++)
+    {
+      Xfree(vfbScreens[i].pXWDHeader);
+    }
+
+    // Remove any unix domain sockets left behind.  I think these should
+    // already have been cleaned up but it doesn't hurt to try again.
+    if (wellKnownSocketsCreated) {
+      char sockName[64];
+      sprintf(sockName,"/tmp/.X11-unix/X%s",display);
+      unlink(sockName);
+      sprintf(sockName,"/usr/spool/sockets/X11/%s",display);
+      unlink(sockName);
+    }
+  }
+
+  void AbortDDX() { ddxGiveUp(); }
+  void OsVendorInit() {}
+  void OsVendorFatalError() {}
+
+  void ddxUseMsg()
+  {
+    ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
+    ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
+           VENDOR_STRING);
+    ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
+    ErrorF("-pixdepths list-of-int support given pixmap depths\n");
+    ErrorF("-linebias n            adjust thin line pixelization\n");
+    ErrorF("-blackpixel n          pixel value for black\n");
+    ErrorF("-whitepixel n          pixel value for white\n");
+    ErrorF("-geometry WxH          set screen 0's width, height\n");
+    ErrorF("-depth D               set screen 0's depth\n");
+    ErrorF("-pixelformat fmt       set pixel format (rgbNNN or bgrNNN)\n");
+    ErrorF("-inetd                 has been launched from inetd\n");
+    ErrorF("\nVNC parameters:\n");
+
+    fprintf(stderr,"\n"
+            "Parameters can be turned on with -<param> or off with -<param>=0\n"
+            "Parameters which take a value can be specified as "
+            "-<param> <value>\n"
+            "Other valid forms are <param>=<value> -<param>=<value> "
+            "--<param>=<value>\n"
+            "Parameter names are case-insensitive.  The parameters are:\n\n");
+    rfb::Configuration::listParams(79, 14);
+  }
+}
+
+static bool displayNumFree(int num)
+{
+  try {
+    network::TcpListener l(6000+num);
+  } catch (rdr::Exception& e) {
+    return false;
+  }
+  char file[256];
+  sprintf(file, "/tmp/.X%d-lock", num);
+  if (access(file, F_OK) == 0) return false;
+  sprintf(file, "/tmp/.X11-unix/X%d", num);
+  if (access(file, F_OK) == 0) return false;
+  sprintf(file, "/usr/spool/sockets/X11/%d", num);
+  if (access(file, F_OK) == 0) return false;
+  return true;
+}
+
+int ddxProcessArgument(int argc, char *argv[], int i)
+{
+  static Bool firstTime = TRUE;
+
+  if (firstTime)
+  {
+    vfbInitializeDefaultScreens();
+    vfbInitializePixmapDepths();
+    firstTime = FALSE;
+    rfb::initStdIOLoggers();
+    rfb::LogWriter::setLogParams("*:stderr:30");
+  }
+
+  if (argv[i][0] ==  ':')
+    displaySpecified = true;
+
+  if (strcmp (argv[i], "-screen") == 0)	/* -screen n WxHxD */
+  {
+    int screenNum;
+    if (i + 2 >= argc) UseMsg();
+    screenNum = atoi(argv[i+1]);
+    if (screenNum < 0 || screenNum >= MAXSCREENS)
+    {
+      ErrorF("Invalid screen number %d\n", screenNum);
+      UseMsg();
+    }
+    if (3 != sscanf(argv[i+2], "%dx%dx%d",
+                    &vfbScreens[screenNum].width,
+                    &vfbScreens[screenNum].height,
+                    &vfbScreens[screenNum].depth))
+    {
+      ErrorF("Invalid screen configuration %s\n", argv[i+2]);
+      UseMsg();
+    }
+
+    if (screenNum >= vfbNumScreens)
+      vfbNumScreens = screenNum + 1;
+    lastScreen = screenNum;
+    return 3;
+  }
+
+  if (strcmp (argv[i], "-pixdepths") == 0)	/* -pixdepths list-of-depth */
+  {
+    int depth, ret = 1;
+
+    if (++i >= argc) UseMsg();
+    while ((i < argc) && (depth = atoi(argv[i++])) != 0)
+    {
+      if (depth < 0 || depth > 32)
+      {
+        ErrorF("Invalid pixmap depth %d\n", depth);
+        UseMsg();
+      }
+      vfbPixmapDepths[depth] = TRUE;
+      ret++;
+    }
+    return ret;
+  }
+
+  if (strcmp (argv[i], "-blackpixel") == 0)	/* -blackpixel n */
+  {
+    Pixel pix;
+    if (++i >= argc) UseMsg();
+    pix = atoi(argv[i]);
+    if (-1 == lastScreen)
+    {
+      int i;
+      for (i = 0; i < MAXSCREENS; i++)
+      {
+        vfbScreens[i].blackPixel = pix;
+      }
+    }
+    else
+    {
+      vfbScreens[lastScreen].blackPixel = pix;
+    }
+    return 2;
+  }
+
+  if (strcmp (argv[i], "-whitepixel") == 0)	/* -whitepixel n */
+  {
+    Pixel pix;
+    if (++i >= argc) UseMsg();
+    pix = atoi(argv[i]);
+    if (-1 == lastScreen)
+    {
+      int i;
+      for (i = 0; i < MAXSCREENS; i++)
+      {
+        vfbScreens[i].whitePixel = pix;
+      }
+    }
+    else
+    {
+      vfbScreens[lastScreen].whitePixel = pix;
+    }
+    return 2;
+  }
+
+  if (strcmp (argv[i], "-linebias") == 0)	/* -linebias n */
+  {
+    unsigned int linebias;
+    if (++i >= argc) UseMsg();
+    linebias = atoi(argv[i]);
+    if (-1 == lastScreen)
+    {
+      int i;
+      for (i = 0; i < MAXSCREENS; i++)
+      {
+        vfbScreens[i].lineBias = linebias;
+      }
+    }
+    else
+    {
+      vfbScreens[lastScreen].lineBias = linebias;
+    }
+    return 2;
+  }
+
+  if (strcmp(argv[i], "-geometry") == 0)
+  {
+    if (++i >= argc) UseMsg();
+    if (sscanf(argv[i],"%dx%d",&vfbScreens[0].width,
+               &vfbScreens[0].height) != 2) {
+      ErrorF("Invalid geometry %s\n", argv[i]);
+      UseMsg();
+    }
+    return 2;
+  }
+
+  if (strcmp(argv[i], "-depth") == 0)
+  {
+    if (++i >= argc) UseMsg();
+    vfbScreens[0].depth = atoi(argv[i]);
+    return 2;
+  }
+
+  if (strcmp(argv[i], "-pixelformat") == 0)
+  {
+    char rgbbgr[4];
+    int bits1, bits2, bits3;
+    if (++i >= argc) UseMsg();
+    if (sscanf(argv[i], "%3s%1d%1d%1d", rgbbgr,&bits1,&bits2,&bits3) < 4) {
+      ErrorF("Invalid pixel format %s\n", argv[i]);
+      UseMsg();
+    }
+
+#define SET_PIXEL_FORMAT(vfbScreen)                     \
+    (vfbScreen).pixelFormatDefined = TRUE;              \
+    (vfbScreen).depth = bits1 + bits2 + bits3;          \
+    (vfbScreen).greenBits = bits2;                      \
+    if (strcasecmp(rgbbgr, "bgr") == 0) {               \
+        (vfbScreen).rgbNotBgr = FALSE;                  \
+        (vfbScreen).redBits = bits3;                    \
+        (vfbScreen).blueBits = bits1;                   \
+    } else if (strcasecmp(rgbbgr, "rgb") == 0) {        \
+        (vfbScreen).rgbNotBgr = TRUE;                   \
+        (vfbScreen).redBits = bits1;                    \
+        (vfbScreen).blueBits = bits3;                   \
+    } else {                                            \
+        ErrorF("Invalid pixel format %s\n", argv[i]);   \
+        UseMsg();                                       \
+    }
+
+    if (-1 == lastScreen)
+    {
+      int i;
+      for (i = 0; i < MAXSCREENS; i++)
+      {
+        SET_PIXEL_FORMAT(vfbScreens[i]);
+      }
+    }
+    else
+    {
+      SET_PIXEL_FORMAT(vfbScreens[lastScreen]);
+    }
+
+    return 2;
+  }
+
+  if (strcmp(argv[i], "-inetd") == 0)
+  {
+    dup2(0,3);
+    vncInetdSock = 3;
+    close(2);
+
+    if (!displaySpecified) {
+      int port = network::TcpSocket::getSockPort(vncInetdSock);
+      int displayNum = port - 5900;
+      if (displayNum < 0 || displayNum > 99 || !displayNumFree(displayNum)) {
+        for (displayNum = 1; displayNum < 100; displayNum++)
+          if (displayNumFree(displayNum)) break;
+
+        if (displayNum == 100)
+          FatalError("Xvnc error: no free display number for -inetd");
+      }
+
+      display = displayNumStr;
+      sprintf(displayNumStr, "%d", displayNum);
+    }
+
+    return 1;
+  }
+
+  if (rfb::Configuration::setParam(argv[i]))
+    return 1;
+
+  if (argv[i][0] == '-' && i+1 < argc) {
+    if (rfb::Configuration::setParam(&argv[i][1], argv[i+1]))
+      return 2;
+  }
+
+  return 0;
+}
+
+#ifdef DDXTIME /* from ServerOSDefines */
+CARD32 GetTimeInMillis()
+{
+  struct timeval  tp;
+
+  X_GETTIMEOFDAY(&tp);
+  return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
+#endif
+
+
+static Bool vfbMultiDepthCreateGC(GCPtr   pGC)
+{
+  switch (vfbBitsPerPixel(pGC->depth))
+  {
+  case 1:  return mfbCreateGC (pGC);
+  case 8:  return cfbCreateGC (pGC);
+  case 16: return cfb16CreateGC (pGC);
+  case 32: return cfb32CreateGC (pGC);
+  default: return FALSE;
+  }
+}
+
+static void vfbMultiDepthGetSpans(
+                                  DrawablePtr		pDrawable,	/* drawable from which to get bits */
+                                  int			wMax,		/* largest value of all *pwidths */
+                                  register DDXPointPtr ppt,		/* points to start copying from */
+                                  int			*pwidth,	/* list of number of bits to copy */
+                                  int			nspans,		/* number of scanlines to copy */
+                                  char		*pdstStart)	/* where to put the bits */
+{
+  switch (pDrawable->bitsPerPixel) {
+  case 1:
+    mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+    break;
+  case 8:
+    cfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+    break;
+  case 16:
+    cfb16GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+    break;
+  case 32:
+    cfb32GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+    break;
+  }
+  return;
+}
+
+static void
+vfbMultiDepthGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+                      unsigned int format, unsigned long planeMask,
+                      char *pdstLine)
+{
+  switch (pDrawable->bitsPerPixel)
+  {
+  case 1:
+    mfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+    break;
+  case 8:
+    cfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+    break;
+  case 16:
+    cfb16GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+    break;
+  case 32:
+    cfb32GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+    break;
+  }
+}
+
+static ColormapPtr InstalledMaps[MAXSCREENS];
+
+static int vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+  /* By the time we are processing requests, we can guarantee that there
+   * is always a colormap installed */
+  *pmaps = InstalledMaps[pScreen->myNum]->mid;
+  return (1);
+}
+
+
+static void vfbInstallColormap(ColormapPtr pmap)
+{
+  int index = pmap->pScreen->myNum;
+  ColormapPtr oldpmap = InstalledMaps[index];
+
+  if (pmap != oldpmap)
+  {
+    int entries;
+    XWDFileHeader *pXWDHeader;
+    XWDColor *pXWDCmap;
+    VisualPtr pVisual;
+    Pixel *     ppix;
+    xrgb *      prgb;
+    xColorItem *defs;
+    int i;
+
+    if(oldpmap != (ColormapPtr)None)
+      WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+    /* Install pmap */
+    InstalledMaps[index] = pmap;
+    WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+
+    entries = pmap->pVisual->ColormapEntries;
+    pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
+    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
+    pVisual = pmap->pVisual;
+
+    swapcopy32(pXWDHeader->visual_class, pVisual->c_class);
+    swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
+    swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
+    swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
+    swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
+    swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
+
+    ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
+    prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
+    defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
+
+    for (i = 0; i < entries; i++)  ppix[i] = i;
+    /* XXX truecolor */
+    QueryColors(pmap, entries, ppix, prgb);
+
+    for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
+      defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
+      defs[i].red = prgb[i].red;
+      defs[i].green = prgb[i].green;
+      defs[i].blue = prgb[i].blue;
+      defs[i].flags =  DoRed|DoGreen|DoBlue;
+    }
+    (*pmap->pScreen->StoreColors)(pmap, entries, defs);
+
+    DEALLOCATE_LOCAL(ppix);
+    DEALLOCATE_LOCAL(prgb);
+    DEALLOCATE_LOCAL(defs);
+  }
+}
+
+static void vfbUninstallColormap(ColormapPtr pmap)
+{
+  ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
+
+  if(pmap == curpmap)
+  {
+    if (pmap->mid != pmap->pScreen->defColormap)
+    {
+      curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
+                                             RT_COLORMAP);
+      (*pmap->pScreen->InstallColormap)(curpmap);
+    }
+  }
+}
+
+static void vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
+{
+  XWDColor *pXWDCmap;
+  int i;
+
+  if (pmap != InstalledMaps[pmap->pScreen->myNum]) return;
+
+  pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
+
+  if ((pmap->pVisual->c_class | DynamicClass) == DirectColor)
+    return;
+
+  for (i = 0; i < ndef; i++)
+  {
+    if (pdefs[i].flags & DoRed) {
+      swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
+    }
+    if (pdefs[i].flags & DoGreen) {
+      swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
+    }
+    if (pdefs[i].flags & DoBlue) {
+      swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
+    }
+  }
+}
+
+static Bool vfbSaveScreen(ScreenPtr pScreen, int on)
+{
+  return TRUE;
+}
+
+static char* vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
+{
+  if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
+
+  pvfb->sizeInBytes = pvfb->paddedWidthInBytes * pvfb->height;
+
+  /* Calculate how many entries in colormap.  This is rather bogus, because
+   * the visuals haven't even been set up yet, but we need to know because we
+   * have to allocate space in the file for the colormap.  The number 10
+   * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
+   */
+
+  if (pvfb->depth <= 10)
+  { /* single index colormaps */
+    pvfb->ncolors = 1 << pvfb->depth;
+  }
+  else
+  { /* decomposed colormaps */
+    int nplanes_per_color_component = pvfb->depth / 3;
+    if (pvfb->depth % 3) nplanes_per_color_component++;
+    pvfb->ncolors = 1 << nplanes_per_color_component;
+  }
+
+  /* add extra bytes for XWDFileHeader, window name, and colormap */
+
+  pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
+    pvfb->ncolors * SIZEOF(XWDColor);
+
+  pvfb->pXWDHeader = NULL; 
+  pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
+
+  if (pvfb->pXWDHeader)
+  {
+    pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
+                                  + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
+    pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
+    memset(pvfb->pfbMemory, 0, pvfb->paddedWidthInBytes * pvfb->height);
+    return pvfb->pfbMemory;
+  }
+  else
+    return NULL;
+}
+
+
+static void vfbWriteXWDFileHeader(ScreenPtr pScreen)
+{
+  vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
+  XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
+  char hostname[XWD_WINDOW_NAME_LEN];
+  VisualPtr	pVisual;
+  unsigned long swaptest = 1;
+  int i;
+
+  needswap = *(char *) &swaptest;
+
+  pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
+  pXWDHeader->file_version = XWD_FILE_VERSION;
+
+  pXWDHeader->pixmap_format = ZPixmap;
+  pXWDHeader->pixmap_depth = pvfb->depth;
+  pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
+  pXWDHeader->xoffset = 0;
+  pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
+  pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
+#ifndef INTERNAL_VS_EXTERNAL_PADDING
+  pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
+  pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
+  pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
+#else
+  pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
+  pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
+  pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
+#endif
+  pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
+  pXWDHeader->bytes_per_line = pvfb->paddedWidthInBytes;
+  pXWDHeader->ncolors = pvfb->ncolors;
+
+  /* visual related fields are written when colormap is installed */
+
+  pXWDHeader->window_x = pXWDHeader->window_y = 0;
+  pXWDHeader->window_bdrwidth = 0;
+
+  /* write xwd "window" name: Xvfb hostname:server.screen */
+
+  hostname[0] = 0;
+  sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
+          pScreen->myNum);
+
+  /* write colormap pixel slot values */
+
+  for (i = 0; i < pvfb->ncolors; i++)
+  {
+    pvfb->pXWDCmap[i].pixel = i;
+  }
+
+  /* byte swap to most significant byte first */
+
+  if (needswap)
+  {
+    SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
+    for (i = 0; i < pvfb->ncolors; i++)
+    {
+      register char n;
+      swapl(&pvfb->pXWDCmap[i].pixel, n);
+    }
+  }
+}
+
+
+static Bool vfbCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) {
+  return FALSE;
+}
+static void vfbCrossScreen (ScreenPtr pScreen, Bool entering) {}
+static Bool vfbRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
+  return TRUE;
+}
+static Bool vfbUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) {
+  return TRUE;
+}
+static void vfbSetCursor(ScreenPtr pScreen, CursorPtr pCursor,
+                               int x, int y) {}
+static void vfbMoveCursor(ScreenPtr pScreen, int x, int y) {}
+
+static miPointerSpriteFuncRec vfbPointerSpriteFuncs = {
+  vfbRealizeCursor,
+  vfbUnrealizeCursor,
+  vfbSetCursor,
+  vfbMoveCursor
+};
+
+static miPointerScreenFuncRec vfbPointerScreenFuncs = {
+  vfbCursorOffScreen,
+  vfbCrossScreen,
+  miPointerWarpCursor
+};
+
+static Bool vfbScreenInit(int index, ScreenPtr pScreen, int argc, char** argv)
+{
+  vfbScreenInfoPtr pvfb = &vfbScreens[index];
+  int dpi = 100;
+  int ret;
+  char *pbits;
+
+  if (monitorResolution) dpi = monitorResolution;
+
+  pvfb->paddedWidthInBytes = PixmapBytePad(pvfb->width, pvfb->depth);
+  pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
+  pvfb->paddedWidth = pvfb->paddedWidthInBytes * 8 / pvfb->bitsPerPixel;
+  pbits = vfbAllocateFramebufferMemory(pvfb);
+  if (!pbits) return FALSE;
+  vncFbptr[index] = pbits;
+
+  defaultColorVisualClass
+    = (pvfb->bitsPerPixel > 8) ? TrueColor : PseudoColor;
+
+  switch (pvfb->bitsPerPixel)
+  {
+  case 1:
+    ret = mfbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
+                        dpi, dpi, pvfb->paddedWidth);
+    break;
+  case 8:
+    ret = cfbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
+                        dpi, dpi, pvfb->paddedWidth);
+    break;
+  case 16:
+    ret = cfb16ScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
+                          dpi, dpi, pvfb->paddedWidth);
+    break;
+  case 32:
+    ret = cfb32ScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
+                          dpi, dpi, pvfb->paddedWidth);
+    break;
+  default:
+    return FALSE;
+  }
+
+  if (!ret) return FALSE;
+
+  pScreen->CreateGC = vfbMultiDepthCreateGC;
+  pScreen->GetImage = vfbMultiDepthGetImage;
+  pScreen->GetSpans = vfbMultiDepthGetSpans;
+
+  pScreen->InstallColormap = vfbInstallColormap;
+  pScreen->UninstallColormap = vfbUninstallColormap;
+  pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
+
+  pScreen->SaveScreen = vfbSaveScreen;
+  pScreen->StoreColors = vfbStoreColors;
+
+  miPointerInitialize(pScreen, &vfbPointerSpriteFuncs, &vfbPointerScreenFuncs,
+                      FALSE);
+
+  vfbWriteXWDFileHeader(pScreen);
+
+  pScreen->blackPixel = pvfb->blackPixel;
+  pScreen->whitePixel = pvfb->whitePixel;
+
+  if (!pvfb->pixelFormatDefined && pvfb->depth == 16) {
+    pvfb->pixelFormatDefined = TRUE;
+    pvfb->rgbNotBgr = TRUE;
+    pvfb->blueBits = pvfb->redBits = 5;
+    pvfb->greenBits = 6;
+  }
+
+  if (pvfb->pixelFormatDefined) {
+    VisualPtr vis;
+    for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
+      ;
+
+    if (pvfb->rgbNotBgr) {
+      vis->offsetBlue = 0;
+      vis->blueMask = (1 << pvfb->blueBits) - 1;
+      vis->offsetGreen = pvfb->blueBits;
+      vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
+      vis->offsetRed = vis->offsetGreen + pvfb->greenBits;
+      vis->redMask = ((1 << pvfb->redBits) - 1) << vis->offsetRed;
+    } else {
+      vis->offsetRed = 0;
+      vis->redMask = (1 << pvfb->redBits) - 1;
+      vis->offsetGreen = pvfb->redBits;
+      vis->greenMask = ((1 << pvfb->greenBits) - 1) << vis->offsetGreen;
+      vis->offsetBlue = vis->offsetGreen + pvfb->greenBits;
+      vis->blueMask = ((1 << pvfb->blueBits) - 1) << vis->offsetBlue;
+    }
+  }
+
+  if (pvfb->bitsPerPixel == 1)
+  {
+    ret = mfbCreateDefColormap(pScreen);
+  }
+  else
+  {
+    ret = cfbCreateDefColormap(pScreen);
+  }
+
+  miSetZeroLineBias(pScreen, pvfb->lineBias);
+
+  return ret;
+
+} /* end vfbScreenInit */
+
+
+static void vfbClientStateChange(CallbackListPtr*, pointer, pointer) {
+  dispatchException &= ~DE_RESET;
+}
+
+void InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
+{
+  ErrorF("\nXvnc version %s - built %s\n", XVNCVERSION, buildtime);
+  ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
+         VENDOR_STRING);
+  wellKnownSocketsCreated = true;
+
+  int i;
+  int NumFormats = 0;
+
+  /* initialize pixmap formats */
+
+  /* must have a pixmap depth to match every screen depth */
+  for (i = 0; i < vfbNumScreens; i++)
+  {
+    vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
+  }
+
+  for (i = 1; i <= 32; i++)
+  {
+    if (vfbPixmapDepths[i])
+    {
+      if (NumFormats >= MAXFORMATS)
+        FatalError ("MAXFORMATS is too small for this server\n");
+      screenInfo->formats[NumFormats].depth = i;
+      screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
+      screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
+      NumFormats++;
+    }
+  }
+
+  screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+  screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+  screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+  screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+  screenInfo->numPixmapFormats = NumFormats;
+
+  /* initialize screens */
+
+  for (i = 0; i < vfbNumScreens; i++)
+  {
+    if (-1 == AddScreen(vfbScreenInit, argc, argv))
+    {
+      FatalError("Couldn't add screen %d", i);
+    }
+  }
+
+  if (!AddCallback(&ClientStateCallback, vfbClientStateChange, 0)) {
+    FatalError("AddCallback failed\n");
+  }
+
+} /* end InitOutput */
+
+#ifdef DPMSExtension
+extern "C" {
+#if NeedFunctionPrototypes
+  void DPMSSet(CARD16 level)
+#else
+    void DPMSSet(level)
+    CARD16 level;
+#endif
+  {
+    return;
+  }
+
+  Bool DPMSSupported()
+  {
+    return FALSE;
+  }
+}
+#endif
+
+/* this is just to get the server to link on AIX */
+#ifdef AIXV3
+int SelectWaitTime = 10000; /* usec */
+#endif
+
+Bool LegalModifier(unsigned int key, DevicePtr pDev)
+{
+  return TRUE;
+}
+
+void ProcessInputEvents()
+{
+  mieqProcessInputEvents();
+  miPointerUpdate();
+}
+
+/* Fairly standard US PC Keyboard */
+
+#define VFB_MIN_KEY 8
+#define VFB_MAX_KEY 255
+#define VFB_MAP_LEN (VFB_MAX_KEY - VFB_MIN_KEY + 1)
+#define KEYSYMS_PER_KEY 2
+KeySym keyboardMap[VFB_MAP_LEN * KEYSYMS_PER_KEY] = {
+  NoSymbol, NoSymbol,
+  XK_Escape, NoSymbol,
+  XK_1, XK_exclam,
+  XK_2, XK_at,
+  XK_3, XK_numbersign,
+  XK_4, XK_dollar,
+  XK_5, XK_percent,
+  XK_6, XK_asciicircum,
+  XK_7, XK_ampersand,
+  XK_8, XK_asterisk,
+  XK_9, XK_parenleft,
+  XK_0, XK_parenright,
+  XK_minus, XK_underscore,
+  XK_equal, XK_plus,
+  XK_BackSpace, NoSymbol,
+  XK_Tab, NoSymbol,
+  XK_q, XK_Q,
+  XK_w, XK_W,
+  XK_e, XK_E,
+  XK_r, XK_R,
+  XK_t, XK_T,
+  XK_y, XK_Y,
+  XK_u, XK_U,
+  XK_i, XK_I,
+  XK_o, XK_O,
+  XK_p, XK_P,
+  XK_bracketleft, XK_braceleft,
+  XK_bracketright, XK_braceright,
+  XK_Return, NoSymbol,
+  XK_Control_L, NoSymbol,
+  XK_a, XK_A,
+  XK_s, XK_S,
+  XK_d, XK_D,
+  XK_f, XK_F,
+  XK_g, XK_G,
+  XK_h, XK_H,
+  XK_j, XK_J,
+  XK_k, XK_K,
+  XK_l, XK_L,
+  XK_semicolon, XK_colon,
+  XK_apostrophe, XK_quotedbl,
+  XK_grave, XK_asciitilde,
+  XK_Shift_L, NoSymbol,
+  XK_backslash, XK_bar,
+  XK_z, XK_Z,
+  XK_x, XK_X,
+  XK_c, XK_C,
+  XK_v, XK_V,
+  XK_b, XK_B,
+  XK_n, XK_N,
+  XK_m, XK_M,
+  XK_comma, XK_less,
+  XK_period, XK_greater,
+  XK_slash, XK_question,
+  XK_Shift_R, NoSymbol,
+  XK_KP_Multiply, NoSymbol,
+  XK_Alt_L, XK_Meta_L,
+  XK_space, NoSymbol,
+  /*XK_Caps_Lock*/ NoSymbol, NoSymbol,
+  XK_F1, NoSymbol,
+  XK_F2, NoSymbol,
+  XK_F3, NoSymbol,
+  XK_F4, NoSymbol,
+  XK_F5, NoSymbol,
+  XK_F6, NoSymbol,
+  XK_F7, NoSymbol,
+  XK_F8, NoSymbol,
+  XK_F9, NoSymbol,
+  XK_F10, NoSymbol,
+  XK_Num_Lock, XK_Pointer_EnableKeys,
+  XK_Scroll_Lock, NoSymbol,
+  XK_KP_Home, XK_KP_7,
+  XK_KP_Up, XK_KP_8,
+  XK_KP_Prior, XK_KP_9,
+  XK_KP_Subtract, NoSymbol,
+  XK_KP_Left, XK_KP_4,
+  XK_KP_Begin, XK_KP_5,
+  XK_KP_Right, XK_KP_6,
+  XK_KP_Add, NoSymbol,
+  XK_KP_End, XK_KP_1,
+  XK_KP_Down, XK_KP_2,
+  XK_KP_Next, XK_KP_3,
+  XK_KP_Insert, XK_KP_0,
+  XK_KP_Delete, XK_KP_Decimal,
+  NoSymbol, NoSymbol,
+  NoSymbol, NoSymbol,
+  NoSymbol, NoSymbol,
+  XK_F11, NoSymbol,
+  XK_F12, NoSymbol,
+  XK_Home, NoSymbol,
+  XK_Up, NoSymbol,
+  XK_Prior, NoSymbol,
+  XK_Left, NoSymbol,
+  NoSymbol, NoSymbol,
+  XK_Right, NoSymbol,
+  XK_End, NoSymbol,
+  XK_Down, NoSymbol,
+  XK_Next, NoSymbol,
+  XK_Insert, NoSymbol,
+  XK_Delete, NoSymbol,
+  XK_KP_Enter, NoSymbol,
+  XK_Control_R, NoSymbol,
+  XK_Pause, XK_Break,
+  XK_Print, XK_Execute,
+  XK_KP_Divide, NoSymbol,
+  XK_Alt_R, XK_Meta_R,
+};
+
+static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
+{
+  int i;
+
+  for (i = 0; i < MAP_LENGTH; i++)
+    pModMap[i] = NoSymbol;
+
+  for (i = 0; i < VFB_MAP_LEN; i++) {
+    if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
+      pModMap[i + VFB_MIN_KEY] = LockMask;
+    else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
+             keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
+      pModMap[i + VFB_MIN_KEY] = ShiftMask;
+    else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
+             keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R) {
+      pModMap[i + VFB_MIN_KEY] = ControlMask;
+    }
+    else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
+             keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
+      pModMap[i + VFB_MIN_KEY] = Mod1Mask;
+  }
+
+  pKeySyms->minKeyCode = VFB_MIN_KEY;
+  pKeySyms->maxKeyCode = VFB_MAX_KEY;
+  pKeySyms->mapWidth = KEYSYMS_PER_KEY;
+  pKeySyms->map = keyboardMap;
+
+  return TRUE;
+}
+
+static void vfbBell(int percent, DeviceIntPtr device, pointer ctrl, int class_)
+{
+  if (percent > 0)
+    vncBell();
+}
+
+static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff)
+{
+  KeySymsRec		keySyms;
+  CARD8 		modMap[MAP_LENGTH];
+  DevicePtr pDev = (DevicePtr)pDevice;
+
+  switch (onoff)
+  {
+  case DEVICE_INIT: 
+    GetMappings(&keySyms, modMap);
+    InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
+                             (BellProcPtr)vfbBell, (KbdCtrlProcPtr)NoopDDA);
+    break;
+  case DEVICE_ON: 
+    pDev->on = TRUE;
+    break;
+  case DEVICE_OFF: 
+    pDev->on = FALSE;
+    break;
+  case DEVICE_CLOSE:
+    break;
+  }
+  return Success;
+}
+
+static int vfbMouseProc(DeviceIntPtr pDevice, int onoff)
+{
+  BYTE map[6];
+  DevicePtr pDev = (DevicePtr)pDevice;
+
+  switch (onoff)
+  {
+  case DEVICE_INIT:
+    map[1] = 1;
+    map[2] = 2;
+    map[3] = 3;
+    map[4] = 4;
+    map[5] = 5;
+    InitPointerDeviceStruct(pDev, map, 5, miPointerGetMotionEvents,
+                            (PtrCtrlProcPtr)NoopDDA, miPointerGetMotionBufferSize());
+    break;
+
+  case DEVICE_ON:
+    pDev->on = TRUE;
+    break;
+
+  case DEVICE_OFF:
+    pDev->on = FALSE;
+    break;
+
+  case DEVICE_CLOSE:
+    break;
+  }
+  return Success;
+}
+
+// InitInput is called after InitExtensions, so we're guaranteed that
+// vncExtensionInit() has already been called.
+
+void InitInput(int argc, char *argv[])
+{
+  DeviceIntPtr p, k;
+  p = AddInputDevice(vfbMouseProc, TRUE);
+  k = AddInputDevice(vfbKeybdProc, TRUE);
+  RegisterPointerDevice(p);
+  RegisterKeyboardDevice(k);
+  miRegisterPointerDevice(screenInfo.screens[0], p);
+  (void)mieqInit ((DevicePtr)k, (DevicePtr)p);
+}
diff --git a/xc/programs/Xserver/vnc/module/Imakefile b/xc/programs/Xserver/vnc/module/Imakefile
new file mode 100644
index 0000000..46e548f
--- /dev/null
+++ b/xc/programs/Xserver/vnc/module/Imakefile
@@ -0,0 +1,54 @@
+
+       VNCTOP = $(TOP)/..
+      VNCLIBS = VncExtLibs
+   VNCINCLUDE = -I$(VNCTOP) -I$(VNCTOP)/vncconfig
+
+#define CplusplusSource
+
+#define IHaveModules
+#include <Server.tmpl>
+
+    SRCS = vncExtInit.cc vncHooks.cc xf86vncModule.cc XserverDesktop.cc
+    OBJS = vncExtInit.o vncHooks.o xf86vncModule.o XserverDesktop.o
+INCLUDES = -I.. -I../../include -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+           -I$(FONTINCSRC) -I$(XF86COMSRC) \
+           $(VNCINCLUDE)
+ DEFINES = $(STD_DEFINES) -DGC_HAS_COMPOSITE_CLIP -DXFree86LOADER
+
+LinkSourceFile(vncExtInit.cc,..)
+LinkSourceFile(vncHooks.cc,..)
+LinkSourceFile(xf86vncModule.cc,..)
+LinkSourceFile(XserverDesktop.cc,..)
+
+ModuleObjectRule()
+/*
+ LibraryModuleTarget(vnc,$(OBJS) $(VNCLIBS))
+ InstallLibraryModule(vnc,$(MODULEDIR),extensions)
+*/
+
+
+/*
+ * CplusplusDynamicModuleTarget - build a module to be dynamically loaded
+ */
+#ifndef CplusplusDynamicModuleTarget
+#define CplusplusDynamicModuleTarget(module,modlist)			@@\
+AllTarget(module)							@@\
+									@@\
+module: modlist								@@\
+	RemoveFile($@)							@@\
+	$(CXX) -o $@ $(SHLIBLDFLAGS) modlist				@@\
+									@@\
+clean::									@@\
+	RemoveFile(module)
+#endif /* CplusplusDynamicModuleTarget */
+
+
+
+CplusplusDynamicModuleTarget(vnc.so,$(OBJS) $(VNCLIBS))
+InstallDynamicModule(vnc.so,$(MODULEDIR),extensions)
+
+DependTarget()
+
+/*
+ InstallDriverSDKLibraryModule(vnc,$(DRIVERSDKMODULEDIR),extensions)
+*/
diff --git a/xc/programs/Xserver/vnc/vncExtInit.cc b/xc/programs/Xserver/vnc/vncExtInit.cc
new file mode 100644
index 0000000..ccaf5b8
--- /dev/null
+++ b/xc/programs/Xserver/vnc/vncExtInit.cc
@@ -0,0 +1,714 @@
+/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#include <stdio.h>
+
+extern "C" {
+#define class c_class
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "scrnintstr.h"
+#include "selection.h"
+#define _VNCEXT_SERVER_
+#define _VNCEXT_PROTO_
+#include "vncExt.h"
+#undef class
+#undef xalloc
+}
+
+#include <rfb/Configuration.h>
+#include <rfb/Logger_stdio.h>
+#include <rfb/LogWriter.h>
+#include <rfb/util.h>
+#include <rfb/ServerCore.h>
+#include <rfb/SSecurityFactoryStandard.h>
+#include <rdr/HexOutStream.h>
+#include <rfb/LogWriter.h>
+#undef max
+#undef min
+#include <network/TcpSocket.h>
+
+#include "XserverDesktop.h"
+#include "vncHooks.h"
+#include "vncExtInit.h"
+
+extern "C" {
+
+  extern void vncExtensionInit();
+  static void vncResetProc(ExtensionEntry* extEntry);
+  static void vncBlockHandler(pointer data, OSTimePtr t, pointer readmask);
+  static void vncWakeupHandler(pointer data, int nfds, pointer readmask);
+  static void vncClientStateChange(CallbackListPtr*, pointer, pointer);
+  static void SendSelectionChangeEvent(Atom selection);
+  static int ProcVncExtDispatch(ClientPtr client);
+  static int SProcVncExtDispatch(ClientPtr client);
+
+  extern char *display;
+
+  extern Selection *CurrentSelections;
+  extern int NumCurrentSelections;
+}
+
+using namespace rfb;
+
+static rfb::LogWriter vlog("vncext");
+
+static unsigned long vncExtGeneration = 0;
+static bool initialised = false;
+static XserverDesktop* desktop[MAXSCREENS] = { 0, };
+void* vncFbptr[MAXSCREENS] = { 0, };
+
+static char* clientCutText = 0;
+static int clientCutTextLen = 0;
+
+static struct VncInputSelect* vncInputSelectHead = 0;
+struct VncInputSelect {
+  VncInputSelect(ClientPtr c, Window w, int m) : client(c), window(w), mask(m)
+  {
+    next = vncInputSelectHead;
+    vncInputSelectHead = this;
+  }
+  ClientPtr client;
+  Window window;
+  int mask;
+  VncInputSelect* next;
+};
+
+static int nPrevSelections = 0;
+static TimeStamp* prevSelectionTimes = 0;
+
+static int vncErrorBase = 0;
+static int vncEventBase = 0;
+static char* vncPasswdFile = 0;
+int vncInetdSock = -1;
+
+rfb::VncAuthPasswdFileParameter vncAuthPasswdFile;
+rfb::AliasParameter rfbauth("rfbauth", "Alias for PasswordFile",
+                            &vncAuthPasswdFile.param);
+rfb::StringParameter httpDir("httpd",
+                             "Directory containing files to serve via HTTP",
+                             "");
+rfb::IntParameter httpPort("httpPort", "TCP port to listen for HTTP",0);
+rfb::AliasParameter rfbwait("rfbwait", "Alias for ClientWaitTimeMillis",
+                            &rfb::Server::clientWaitTimeMillis);
+rfb::IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol",0);
+rfb::StringParameter desktopName("desktop", "Name of VNC desktop","x11");
+rfb::BoolParameter localhostOnly("localhost",
+                                 "Only allow connections from localhost",
+                                 false);
+
+void vncExtensionInit()
+{
+  if (vncExtGeneration == serverGeneration) {
+    vlog.error("vncExtensionInit: called twice in same generation?");
+    return;
+  }
+  vncExtGeneration = serverGeneration;
+
+  ExtensionEntry* extEntry
+    = AddExtension(VNCEXTNAME, VncExtNumberEvents, VncExtNumberErrors,
+                   ProcVncExtDispatch, SProcVncExtDispatch, vncResetProc,
+                   StandardMinorOpcode);
+  if (!extEntry) {
+    ErrorF("vncExtInit: AddExtension failed\n");
+    return;
+  }
+
+  vncErrorBase = extEntry->errorBase;
+  vncEventBase = extEntry->eventBase;
+
+  vlog.info("VNC extension running!");
+
+  if (!AddCallback(&ClientStateCallback, vncClientStateChange, 0)) {
+    FatalError("AddCallback failed\n");
+  }
+
+  try {
+    if (!initialised) {
+      rfb::initStdIOLoggers();
+      initialised = true;
+    }
+
+    for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+
+      if (!desktop[scr]) {
+        network::TcpListener* listener = 0;
+        network::TcpListener* httpListener = 0;
+        if (scr == 0 && vncInetdSock != -1) {
+          if (network::TcpSocket::isSocket(vncInetdSock) &&
+              !network::TcpSocket::isConnected(vncInetdSock))
+          {
+            listener = new network::TcpListener(0, 0, vncInetdSock, true);
+            vlog.info("inetd wait");
+          }
+        } else {
+          int port = rfbport;
+          if (port == 0) port = 5900 + atoi(display);
+          port += 1000 * scr;
+          listener = new network::TcpListener(port, localhostOnly);
+          vlog.info("Listening for VNC connections on port %d",port);
+          CharArray httpDirStr(httpDir.getData());
+          if (httpDirStr.buf[0]) {
+            port = httpPort;
+            if (port == 0) port = 5800 + atoi(display);
+            port += 1000 * scr;
+            httpListener = new network::TcpListener(port, localhostOnly);
+            vlog.info("Listening for HTTP connections on port %d",port);
+          }
+        }
+
+        CharArray desktopNameStr(desktopName.getData());
+        desktop[scr] = new XserverDesktop(screenInfo.screens[scr], listener,
+                                          httpListener,
+                                          desktopNameStr.buf,
+                                          vncFbptr[scr]);
+        vlog.info("created VNC server for screen %d", scr);
+
+        if (scr == 0 && vncInetdSock != -1 && !listener) {
+          network::Socket* sock = new network::TcpSocket(vncInetdSock);
+          desktop[scr]->addClient(sock, false);
+          vlog.info("added inetd sock");
+        }
+
+      } else {
+        desktop[scr]->serverReset(screenInfo.screens[scr]);
+      }
+
+      vncHooksInit(screenInfo.screens[scr], desktop[scr]);
+    }
+
+    RegisterBlockAndWakeupHandlers(vncBlockHandler, vncWakeupHandler, 0);
+
+  } catch (rdr::Exception& e) {
+    vlog.error("vncExtInit: %s",e.str());
+  }
+}
+
+static void vncResetProc(ExtensionEntry* extEntry)
+{
+}
+
+//
+// vncBlockHandler - called just before the X server goes into select().  Call
+// on to the block handler for each desktop.  Then check whether any of the
+// selections have changed, and if so, notify any interested X clients.
+//
+
+static void vncBlockHandler(pointer data, OSTimePtr timeout, pointer readmask)
+{
+  fd_set* fds = (fd_set*)readmask;
+
+  for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+    if (desktop[scr]) {
+      desktop[scr]->blockHandler(fds);
+    }
+  }
+
+  if (nPrevSelections != NumCurrentSelections) {
+    prevSelectionTimes
+      = (TimeStamp*)xnfrealloc(prevSelectionTimes,
+                               NumCurrentSelections * sizeof(TimeStamp));
+    for (int i = nPrevSelections; i < NumCurrentSelections; i++) {
+      prevSelectionTimes[i].months = 0;
+      prevSelectionTimes[i].milliseconds = 0;
+    }
+    nPrevSelections = NumCurrentSelections;
+  }
+  for (int i = 0; i < NumCurrentSelections; i++) {
+    if (CurrentSelections[i].lastTimeChanged.months
+        != prevSelectionTimes[i].months ||
+        CurrentSelections[i].lastTimeChanged.milliseconds
+        != prevSelectionTimes[i].milliseconds)
+    {
+      SendSelectionChangeEvent(CurrentSelections[i].selection);
+      prevSelectionTimes[i] = CurrentSelections[i].lastTimeChanged;
+    }
+  }
+}
+
+static void vncWakeupHandler(pointer data, int nfds, pointer readmask)
+{
+  fd_set* fds = (fd_set*)readmask;
+
+  for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+    if (desktop[scr]) {
+      desktop[scr]->wakeupHandler(fds, nfds);
+    }
+  }
+}
+
+static void vncClientStateChange(CallbackListPtr*, pointer, pointer p)
+{
+  ClientPtr client = ((NewClientInfoRec*)p)->client;
+  if (client->clientState == ClientStateGone) {
+    VncInputSelect** nextPtr = &vncInputSelectHead;
+    for (VncInputSelect* cur = vncInputSelectHead; cur; cur = *nextPtr) {
+      if (cur->client == client) {
+        *nextPtr = cur->next;
+        delete cur;
+        continue;
+      }
+      nextPtr = &cur->next;
+    }
+  }
+}
+
+void vncBell()
+{
+  for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+    if (desktop[scr]) {
+      desktop[scr]->bell();
+    }
+  }
+}
+
+void vncClientGone(int fd)
+{
+  if (fd == vncInetdSock) {
+    fprintf(stderr,"inetdSock client gone\n");
+    GiveUp(0);
+  }
+}
+
+void vncClientCutText(const char* str, int len)
+{
+  delete [] clientCutText;
+  clientCutText = new char[len];
+  memcpy(clientCutText, str, len);
+  clientCutTextLen = len;
+  xVncExtClientCutTextNotifyEvent ev;
+  ev.type = vncEventBase + VncExtClientCutTextNotify;
+  for (VncInputSelect* cur = vncInputSelectHead; cur; cur = cur->next) {
+    if (cur->mask & VncExtClientCutTextMask) {
+      ev.sequenceNumber = cur->client->sequence;
+      ev.window = cur->window;
+      ev.time = GetTimeInMillis();
+      if (cur->client->swapped) {
+        int n;
+        swaps(&ev.sequenceNumber, n);
+        swapl(&ev.window, n);
+        swapl(&ev.time, n);
+      }
+      WriteToClient(cur->client, sizeof(xVncExtClientCutTextNotifyEvent),
+                    (char *)&ev);
+    }
+  }
+}
+
+static void SendSelectionChangeEvent(Atom selection)
+{
+  xVncExtSelectionChangeNotifyEvent ev;
+  ev.type = vncEventBase + VncExtSelectionChangeNotify;
+  for (VncInputSelect* cur = vncInputSelectHead; cur; cur = cur->next) {
+    if (cur->mask & VncExtSelectionChangeMask) {
+      ev.sequenceNumber = cur->client->sequence;
+      ev.window = cur->window;
+      ev.selection = selection;
+      if (cur->client->swapped) {
+        int n;
+        swaps(&ev.sequenceNumber, n);
+        swapl(&ev.window, n);
+        swapl(&ev.selection, n);
+      }
+      WriteToClient(cur->client, sizeof(xVncExtSelectionChangeNotifyEvent),
+                    (char *)&ev);
+    }
+  }
+}
+
+static int ProcVncExtSetParam(ClientPtr client)
+{
+  REQUEST(xVncExtSetParamReq);
+  REQUEST_FIXED_SIZE(xVncExtSetParamReq, stuff->paramLen);
+  CharArray param(stuff->paramLen+1);
+  strncpy(param.buf, (char*)&stuff[1], stuff->paramLen);
+  param.buf[stuff->paramLen] = 0;
+
+  xVncExtSetParamReply rep;
+  int n;
+  rep.type = X_Reply;
+  rep.length = 0;
+  rep.sequenceNumber = client->sequence;
+  rep.success = rfb::Configuration::setParam(param.buf);
+  if (client->swapped) {
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.length, n);
+  }
+  WriteToClient(client, sizeof(xVncExtSetParamReply), (char *)&rep);
+  return (client->noClientException);
+}
+
+static int SProcVncExtSetParam(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtSetParamReq);
+  swaps(&stuff->length, n);
+  REQUEST_AT_LEAST_SIZE(xVncExtSetParamReq);
+  return ProcVncExtSetParam(client);
+}
+
+static int ProcVncExtGetParam(ClientPtr client)
+{
+  REQUEST(xVncExtGetParamReq);
+  REQUEST_FIXED_SIZE(xVncExtGetParamReq, stuff->paramLen);
+  CharArray param(stuff->paramLen+1);
+  strncpy(param.buf, (char*)&stuff[1], stuff->paramLen);
+  param.buf[stuff->paramLen] = 0;
+
+  xVncExtGetParamReply rep;
+  int n;
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.success = 0;
+  int len = 0;
+  char* value = 0;
+  rfb::VoidParameter* p = rfb::Configuration::getParam(param.buf);
+  // Hack to avoid exposing password!
+  if (strcasecmp(param.buf, "Password") == 0)
+    p = 0;
+  if (p) {
+    value = p->getValueStr();
+    rep.success = 1;
+    len = value ? strlen(value) : 0;
+  }
+  rep.length = (len + 3) >> 2;
+  rep.valueLen = len;
+  if (client->swapped) {
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.length, n);
+    swaps(&rep.valueLen, n);
+  }
+  WriteToClient(client, sizeof(xVncExtGetParamReply), (char *)&rep);
+  if (value)
+    WriteToClient(client, len, value);
+  delete [] value;
+  return (client->noClientException);
+}
+
+static int SProcVncExtGetParam(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtGetParamReq);
+  swaps(&stuff->length, n);
+  REQUEST_AT_LEAST_SIZE(xVncExtGetParamReq);
+  return ProcVncExtGetParam(client);
+}
+
+static int ProcVncExtGetParamDesc(ClientPtr client)
+{
+  REQUEST(xVncExtGetParamDescReq);
+  REQUEST_FIXED_SIZE(xVncExtGetParamDescReq, stuff->paramLen);
+  CharArray param(stuff->paramLen+1);
+  strncpy(param.buf, (char*)&stuff[1], stuff->paramLen);
+  param.buf[stuff->paramLen] = 0;
+
+  xVncExtGetParamDescReply rep;
+  int n;
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.success = 0;
+  int len = 0;
+  const char* desc = 0;
+  rfb::VoidParameter* p = rfb::Configuration::getParam(param.buf);
+  if (p) {
+    desc = p->getDescription();
+    rep.success = 1;
+    len = desc ? strlen(desc) : 0;
+  }
+  rep.length = (len + 3) >> 2;
+  rep.descLen = len;
+  if (client->swapped) {
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.length, n);
+    swaps(&rep.descLen, n);
+  }
+  WriteToClient(client, sizeof(xVncExtGetParamDescReply), (char *)&rep);
+  if (desc)
+    WriteToClient(client, len, (char*)desc);
+  return (client->noClientException);
+}
+
+static int SProcVncExtGetParamDesc(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtGetParamDescReq);
+  swaps(&stuff->length, n);
+  REQUEST_AT_LEAST_SIZE(xVncExtGetParamDescReq);
+  return ProcVncExtGetParamDesc(client);
+}
+
+static int ProcVncExtListParams(ClientPtr client)
+{
+  REQUEST(xVncExtListParamsReq);
+  REQUEST_SIZE_MATCH(xVncExtListParamsReq);
+
+  xVncExtListParamsReply rep;
+  int n;
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+
+  int nParams = 0;
+  int len = 0;
+  rfb::VoidParameter* current = rfb::Configuration::head;
+  while (current) {
+    int l = strlen(current->getName());
+    if (l <= 255) {
+      nParams++;
+      len += l + 1;
+    }
+    current = current->_next;
+  }
+  rep.length = (len + 3) >> 2;
+  rep.nParams = nParams;
+  if (client->swapped) {
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.length, n);
+    swaps(&rep.nParams, n);
+  }
+  WriteToClient(client, sizeof(xVncExtListParamsReply), (char *)&rep);
+  rdr::U8* data = new rdr::U8[len];
+  rdr::U8* ptr = data;
+  current = rfb::Configuration::head;
+  while (current) {
+    int l = strlen(current->getName());
+    if (l <= 255) {
+      *ptr++ = l;
+      memcpy(ptr, current->getName(), l);
+      ptr += l;
+    }
+    current = current->_next;
+  }
+  WriteToClient(client, len, (char*)data);
+  delete [] data;
+  return (client->noClientException);
+}
+
+static int SProcVncExtListParams(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtListParamsReq);
+  swaps(&stuff->length, n);
+  REQUEST_SIZE_MATCH(xVncExtListParamsReq);
+  return ProcVncExtListParams(client);
+}
+
+static int ProcVncExtSetServerCutText(ClientPtr client)
+{
+  REQUEST(xVncExtSetServerCutTextReq);
+  REQUEST_FIXED_SIZE(xVncExtSetServerCutTextReq, stuff->textLen);
+  char* str = new char[stuff->textLen+1];
+  strncpy(str, (char*)&stuff[1], stuff->textLen);
+  str[stuff->textLen] = 0;
+  for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+    if (desktop[scr]) {
+      desktop[scr]->serverCutText(str, stuff->textLen);
+    }
+  }
+  delete [] str;
+  return (client->noClientException);
+}
+
+static int SProcVncExtSetServerCutText(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtSetServerCutTextReq);
+  swaps(&stuff->length, n);
+  REQUEST_AT_LEAST_SIZE(xVncExtSetServerCutTextReq);
+  swapl(&stuff->textLen, n);
+  return ProcVncExtSetServerCutText(client);
+}
+
+static int ProcVncExtGetClientCutText(ClientPtr client)
+{
+  REQUEST(xVncExtGetClientCutTextReq);
+  REQUEST_SIZE_MATCH(xVncExtGetClientCutTextReq);
+
+  xVncExtGetClientCutTextReply rep;
+  int n;
+  rep.type = X_Reply;
+  rep.length = (clientCutTextLen + 3) >> 2;
+  rep.sequenceNumber = client->sequence;
+  rep.textLen = clientCutTextLen;
+  if (client->swapped) {
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.length, n);
+    swapl(&rep.textLen, n);
+  }
+  WriteToClient(client, sizeof(xVncExtGetClientCutTextReply), (char *)&rep);
+  if (clientCutText)
+    WriteToClient(client, clientCutTextLen, clientCutText);
+  return (client->noClientException);
+}
+
+static int SProcVncExtGetClientCutText(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtGetClientCutTextReq);
+  swaps(&stuff->length, n);
+  REQUEST_SIZE_MATCH(xVncExtGetClientCutTextReq);
+  return ProcVncExtGetClientCutText(client);
+}
+
+static int ProcVncExtSelectInput(ClientPtr client)
+{
+  REQUEST(xVncExtSelectInputReq);
+  REQUEST_SIZE_MATCH(xVncExtSelectInputReq);
+  VncInputSelect** nextPtr = &vncInputSelectHead;
+  VncInputSelect* cur;
+  for (cur = vncInputSelectHead; cur; cur = *nextPtr) {
+    if (cur->client == client && cur->window == stuff->window) {
+      cur->mask = stuff->mask;
+      if (!cur->mask) {
+        *nextPtr = cur->next;
+        delete cur;
+      }
+      break;
+    }
+    nextPtr = &cur->next;
+  }
+  if (!cur) {
+    cur = new VncInputSelect(client, stuff->window, stuff->mask);
+  }
+  return (client->noClientException);
+}
+
+static int SProcVncExtSelectInput(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtSelectInputReq);
+  swaps(&stuff->length, n);
+  REQUEST_SIZE_MATCH(xVncExtSelectInputReq);
+  swapl(&stuff->window, n);
+  swapl(&stuff->mask, n);
+  return ProcVncExtSelectInput(client);
+}
+
+static int ProcVncExtConnect(ClientPtr client)
+{
+  REQUEST(xVncExtConnectReq);
+  REQUEST_FIXED_SIZE(xVncExtConnectReq, stuff->strLen);
+  CharArray str(stuff->strLen+1);
+  strncpy(str.buf, (char*)&stuff[1], stuff->strLen);
+  str.buf[stuff->strLen] = 0;
+
+  xVncExtConnectReply rep;
+  rep.success = 0;
+  if (desktop[0]) {
+    if (stuff->strLen == 0) {
+      try {
+        desktop[0]->disconnectClients();
+        rep.success = 1;
+      } catch (rdr::Exception& e) {
+        vlog.error("Disconnecting all clients: %s",e.str());
+      }
+    } else {
+      int port = 5500;
+      for (int i = 0; i < stuff->strLen; i++) {
+        if (str.buf[i] == ':') {
+          port = atoi(&str.buf[i+1]);
+          str.buf[i] = 0;
+          break;
+        }
+      }
+
+      try {
+        network::Socket* sock = new network::TcpSocket(str.buf, port);
+        desktop[0]->addClient(sock, true);
+	rep.success = 1;
+      } catch (rdr::Exception& e) {
+        vlog.error("Reverse connection: %s",e.str());
+      }
+    }
+  }
+
+  rep.type = X_Reply;
+  rep.length = 0;
+  rep.sequenceNumber = client->sequence;
+  if (client->swapped) {
+    int n;
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.length, n);
+  }
+  WriteToClient(client, sizeof(xVncExtConnectReply), (char *)&rep);
+  return (client->noClientException);
+}
+
+static int SProcVncExtConnect(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtConnectReq);
+  swaps(&stuff->length, n);
+  REQUEST_AT_LEAST_SIZE(xVncExtConnectReq);
+  return ProcVncExtConnect(client);
+}
+
+static int ProcVncExtDispatch(ClientPtr client)
+{
+  REQUEST(xReq);
+  switch (stuff->data) {
+  case X_VncExtSetParam:
+    return ProcVncExtSetParam(client);
+  case X_VncExtGetParam:
+    return ProcVncExtGetParam(client);
+  case X_VncExtGetParamDesc:
+    return ProcVncExtGetParamDesc(client);
+  case X_VncExtListParams:
+    return ProcVncExtListParams(client);
+  case X_VncExtSetServerCutText:
+    return ProcVncExtSetServerCutText(client);
+  case X_VncExtGetClientCutText:
+    return ProcVncExtGetClientCutText(client);
+  case X_VncExtSelectInput:
+    return ProcVncExtSelectInput(client);
+  case X_VncExtConnect:
+    return ProcVncExtConnect(client);
+  default:
+    return BadRequest;
+  }
+}
+
+static int SProcVncExtDispatch(ClientPtr client)
+{
+  REQUEST(xReq);
+  switch (stuff->data) {
+  case X_VncExtSetParam:
+    return SProcVncExtSetParam(client);
+  case X_VncExtGetParam:
+    return SProcVncExtGetParam(client);
+  case X_VncExtGetParamDesc:
+    return SProcVncExtGetParamDesc(client);
+  case X_VncExtListParams:
+    return SProcVncExtListParams(client);
+  case X_VncExtSetServerCutText:
+    return SProcVncExtSetServerCutText(client);
+  case X_VncExtGetClientCutText:
+    return SProcVncExtGetClientCutText(client);
+  case X_VncExtSelectInput:
+    return SProcVncExtSelectInput(client);
+  case X_VncExtConnect:
+    return SProcVncExtConnect(client);
+  default:
+    return BadRequest;
+  }
+}
+
diff --git a/xc/programs/Xserver/vnc/vncExtInit.h b/xc/programs/Xserver/vnc/vncExtInit.h
new file mode 100644
index 0000000..947f34d
--- /dev/null
+++ b/xc/programs/Xserver/vnc/vncExtInit.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+#ifndef __VNCEXTINIT_H__
+#define __VNCEXTINIT_H__
+
+#include <rfb/Configuration.h>
+
+extern void vncClientCutText(const char* str, int len);
+extern void vncClientGone(int fd);
+extern void vncBell();
+extern void* vncFbptr[];
+extern int vncInetdSock;
+extern rfb::StringParameter httpDir;
+
+#endif
diff --git a/xc/programs/Xserver/vnc/vncHooks.cc b/xc/programs/Xserver/vnc/vncHooks.cc
new file mode 100644
index 0000000..d52a497
--- /dev/null
+++ b/xc/programs/Xserver/vnc/vncHooks.cc
@@ -0,0 +1,1475 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+
+#include <stdio.h>
+#include "XserverDesktop.h"
+#include "vncHooks.h"
+
+extern "C" {
+#define class c_class
+#define private c_private
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "dixfontstr.h"
+#include "colormapst.h"
+
+#ifdef GC_HAS_COMPOSITE_CLIP
+#define COMPOSITE_CLIP(gc) ((gc)->pCompositeClip)
+#else
+#include "mfb.h"
+#define COMPOSITE_CLIP(gc) \
+  (((mfbPrivGCPtr)((gc)->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip)
+#endif
+
+#undef class
+#undef private
+}
+
+#include "RegionHelper.h"
+
+#define DBGPRINT(x) //(fprintf x)
+
+// MAX_RECTS_PER_OP is the maximum number of rectangles we generate from
+// operations like Polylines and PolySegment.  If the operation is more complex
+// than this, we simply use the bounding box.  Ideally it would be a
+// command-line option, but that would involve an extra malloc each time, so we
+// fix it here.
+#define MAX_RECTS_PER_OP 5
+
+static unsigned long vncHooksGeneration = 0;
+
+// vncHooksScreenRec and vncHooksGCRec contain pointers to the original
+// functions which we "wrap" in order to hook the screen changes.  The screen
+// functions are each wrapped individually, while the GC "funcs" and "ops" are
+// wrapped as a unit.
+
+typedef struct {
+  XserverDesktop* desktop;
+
+  CloseScreenProcPtr           CloseScreen;
+  CreateGCProcPtr              CreateGC;
+  PaintWindowBackgroundProcPtr PaintWindowBackground;
+  PaintWindowBorderProcPtr     PaintWindowBorder;
+  CopyWindowProcPtr            CopyWindow;
+  ClearToBackgroundProcPtr     ClearToBackground;
+  RestoreAreasProcPtr          RestoreAreas;
+  InstallColormapProcPtr       InstallColormap;
+  StoreColorsProcPtr           StoreColors;
+  DisplayCursorProcPtr         DisplayCursor;
+  ScreenBlockHandlerProcPtr    BlockHandler;
+} vncHooksScreenRec, *vncHooksScreenPtr;
+
+typedef struct {
+    GCFuncs *wrappedFuncs;
+    GCOps *wrappedOps;
+} vncHooksGCRec, *vncHooksGCPtr;
+
+static int vncHooksScreenIndex;
+static int vncHooksGCIndex;
+
+
+// screen functions
+
+static Bool vncHooksCloseScreen(int i, ScreenPtr pScreen);
+static Bool vncHooksCreateGC(GCPtr pGC);
+static void vncHooksPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion,
+                                          int what);
+static void vncHooksPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion,
+                                      int what);
+static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+                               RegionPtr pOldRegion);
+static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
+                                      int h, Bool generateExposures);
+static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr prgnExposed);
+static void vncHooksInstallColormap(ColormapPtr pColormap);
+static void vncHooksStoreColors(ColormapPtr pColormap, int ndef,
+                                xColorItem* pdef);
+static Bool vncHooksDisplayCursor(ScreenPtr pScreen, CursorPtr cursor);
+static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
+                                 pointer pReadmask);
+
+// GC "funcs"
+
+static void vncHooksValidateGC(GCPtr pGC, unsigned long changes,
+                               DrawablePtr pDrawable);
+static void vncHooksChangeGC(GCPtr pGC, unsigned long mask);
+static void vncHooksCopyGC(GCPtr src, unsigned long mask, GCPtr dst);
+static void vncHooksDestroyGC(GCPtr pGC);
+static void vncHooksChangeClip(GCPtr pGC, int type, pointer pValue,int nrects);
+static void vncHooksDestroyClip(GCPtr pGC);
+static void vncHooksCopyClip(GCPtr dst, GCPtr src);
+
+static GCFuncs vncHooksGCFuncs = {
+  vncHooksValidateGC, vncHooksChangeGC, vncHooksCopyGC, vncHooksDestroyGC,
+  vncHooksChangeClip, vncHooksDestroyClip, vncHooksCopyClip,
+};
+
+// GC "ops"
+
+static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+                              DDXPointPtr pptInit, int *pwidthInit,
+                              int fSorted);
+static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+                             DDXPointPtr ppt, int *pwidth, int nspans,
+                             int fSorted);
+static void vncHooksPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                             int x, int y, int w, int h, int leftPad,
+                             int format, char *pBits);
+static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+                                  GCPtr pGC, int srcx, int srcy, int w, int h,
+                                  int dstx, int dsty);
+static RegionPtr vncHooksCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+                                   GCPtr pGC, int srcx, int srcy, int w, int h,
+                                   int dstx, int dsty, unsigned long plane);
+static void vncHooksPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                              int npt, xPoint *pts);
+static void vncHooksPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                              int npt, DDXPointPtr ppts);
+static void vncHooksPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+                                xSegment *segs);
+static void vncHooksPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+                                  xRectangle *rects);
+static void vncHooksPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+                            xArc *arcs);
+static void vncHooksFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+                                int mode, int count, DDXPointPtr pts);
+static void vncHooksPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+                                 xRectangle *rects);
+static void vncHooksPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+                                xArc *arcs);
+static int vncHooksPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                             int count, char *chars);
+static int vncHooksPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                              int count, unsigned short *chars);
+static void vncHooksImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                               int count, char *chars);
+static void vncHooksImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                                int count, unsigned short *chars);
+static void vncHooksImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
+                                  int y, unsigned int nglyph,
+                                  CharInfoPtr *ppci, pointer pglyphBase);
+static void vncHooksPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
+                                 int y, unsigned int nglyph,
+                                 CharInfoPtr *ppci, pointer pglyphBase);
+static void vncHooksPushPixels(GCPtr pGC, PixmapPtr pBitMap,
+                               DrawablePtr pDrawable, int w, int h, int x,
+                               int y);
+
+static GCOps vncHooksGCOps = {
+  vncHooksFillSpans, vncHooksSetSpans, vncHooksPutImage, vncHooksCopyArea,
+  vncHooksCopyPlane, vncHooksPolyPoint, vncHooksPolylines, vncHooksPolySegment,
+  vncHooksPolyRectangle, vncHooksPolyArc, vncHooksFillPolygon,
+  vncHooksPolyFillRect, vncHooksPolyFillArc, vncHooksPolyText8,
+  vncHooksPolyText16, vncHooksImageText8, vncHooksImageText16,
+  vncHooksImageGlyphBlt, vncHooksPolyGlyphBlt, vncHooksPushPixels
+};
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// vncHooksInit() is called at initialisation time and every time the server
+// resets.  It is called once for each screen, but the indexes are only
+// allocated once for each server generation.
+
+Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop)
+{
+  vncHooksScreenPtr vncHooksScreen;
+
+  if (vncHooksGeneration != serverGeneration) {
+    vncHooksGeneration = serverGeneration;
+
+    vncHooksScreenIndex = AllocateScreenPrivateIndex();
+    if (vncHooksScreenIndex < 0) {
+      ErrorF("vncHooksInit: AllocateScreenPrivateIndex failed\n");
+      return FALSE;
+    }
+
+    vncHooksGCIndex = AllocateGCPrivateIndex();
+    if (vncHooksGCIndex < 0) {
+      ErrorF("vncHooksInit: AllocateGCPrivateIndex failed\n");
+      return FALSE;
+    }
+  }
+
+  if (!AllocateGCPrivate(pScreen, vncHooksGCIndex, sizeof(vncHooksGCRec))) {
+    ErrorF("vncHooksInit: AllocateGCPrivate failed\n");
+    return FALSE;
+  }
+
+  vncHooksScreen = (vncHooksScreenPtr)xnfalloc(sizeof(vncHooksScreenRec));
+  pScreen->devPrivates[vncHooksScreenIndex].ptr = (pointer)vncHooksScreen;
+
+  vncHooksScreen->desktop = desktop;
+
+  vncHooksScreen->CloseScreen = pScreen->CloseScreen;
+  vncHooksScreen->CreateGC = pScreen->CreateGC;
+  vncHooksScreen->PaintWindowBackground = pScreen->PaintWindowBackground;
+  vncHooksScreen->PaintWindowBorder = pScreen->PaintWindowBorder;
+  vncHooksScreen->CopyWindow = pScreen->CopyWindow;
+  vncHooksScreen->ClearToBackground = pScreen->ClearToBackground;
+  vncHooksScreen->RestoreAreas = pScreen->RestoreAreas;
+  vncHooksScreen->InstallColormap = pScreen->InstallColormap;
+  vncHooksScreen->StoreColors = pScreen->StoreColors;
+  vncHooksScreen->DisplayCursor = pScreen->DisplayCursor;
+  vncHooksScreen->BlockHandler = pScreen->BlockHandler;
+
+  pScreen->CloseScreen = vncHooksCloseScreen;
+  pScreen->CreateGC = vncHooksCreateGC;
+  pScreen->PaintWindowBackground = vncHooksPaintWindowBackground;
+  pScreen->PaintWindowBorder = vncHooksPaintWindowBorder;
+  pScreen->CopyWindow = vncHooksCopyWindow;
+  pScreen->ClearToBackground = vncHooksClearToBackground;
+  pScreen->RestoreAreas = vncHooksRestoreAreas;
+  pScreen->InstallColormap = vncHooksInstallColormap;
+  pScreen->StoreColors = vncHooksStoreColors;
+  pScreen->DisplayCursor = vncHooksDisplayCursor;
+  pScreen->BlockHandler = vncHooksBlockHandler;
+
+  return TRUE;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// screen functions
+//
+
+// SCREEN_UNWRAP and SCREEN_REWRAP unwrap and rewrap the given screen function.
+// It would be nice to do this with a C++ class, but each function is of a
+// distinct type, so it would have to use templates, and it's not worth that
+// much pain.
+
+#define SCREEN_UNWRAP(scrn,field)                                         \
+  ScreenPtr pScreen = scrn;                                               \
+  vncHooksScreenPtr vncHooksScreen                                        \
+    = ((vncHooksScreenPtr)pScreen->devPrivates[vncHooksScreenIndex].ptr); \
+  pScreen->field = vncHooksScreen->field;                                 \
+  DBGPRINT((stderr,"vncHooks" #field " called\n"));
+
+#define SCREEN_REWRAP(field) pScreen->field = vncHooks##field;
+
+
+// CloseScreen - unwrap the screen functions and call the original CloseScreen
+// function
+
+static Bool vncHooksCloseScreen(int i, ScreenPtr pScreen_)
+{
+  SCREEN_UNWRAP(pScreen_, CloseScreen);
+
+  pScreen->CreateGC = vncHooksScreen->CreateGC;
+  pScreen->PaintWindowBackground = vncHooksScreen->PaintWindowBackground;
+  pScreen->PaintWindowBorder = vncHooksScreen->PaintWindowBorder;
+  pScreen->CopyWindow = vncHooksScreen->CopyWindow;
+  pScreen->ClearToBackground = vncHooksScreen->ClearToBackground;
+  pScreen->RestoreAreas = vncHooksScreen->RestoreAreas;
+  pScreen->InstallColormap = vncHooksScreen->InstallColormap;
+  pScreen->StoreColors = vncHooksScreen->StoreColors;
+  pScreen->DisplayCursor = vncHooksScreen->DisplayCursor;
+  pScreen->BlockHandler = vncHooksScreen->BlockHandler;
+
+  xfree((pointer)vncHooksScreen);
+
+  DBGPRINT((stderr,"vncHooksCloseScreen: unwrapped screen functions\n"));
+
+  return (*pScreen->CloseScreen)(i, pScreen);
+}
+
+// CreateGC - wrap the "GC funcs"
+
+static Bool vncHooksCreateGC(GCPtr pGC)
+{
+  SCREEN_UNWRAP(pGC->pScreen, CreateGC);
+    
+  vncHooksGCPtr vncHooksGC
+    = (vncHooksGCPtr)pGC->devPrivates[vncHooksGCIndex].ptr;
+
+  Bool ret = (*pScreen->CreateGC) (pGC);
+
+  vncHooksGC->wrappedOps = 0;
+  vncHooksGC->wrappedFuncs = pGC->funcs;
+  pGC->funcs = &vncHooksGCFuncs;
+
+  SCREEN_REWRAP(CreateGC);
+
+  return ret;
+}
+
+// PaintWindowBackground - changed region is the given region
+
+static void vncHooksPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion,
+                                          int what)
+{
+  SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBackground);
+
+  RegionHelper changed(pScreen, pRegion);
+
+  (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+
+  SCREEN_REWRAP(PaintWindowBackground);
+}
+
+// PaintWindowBorder - changed region is the given region
+
+static void vncHooksPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion,
+                                      int what)
+{
+  SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBorder);
+
+  RegionHelper changed(pScreen, pRegion);
+
+  (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+
+  SCREEN_REWRAP(PaintWindowBorder);
+}
+
+// CopyWindow - destination of the copy is the old region, clipped by
+// borderClip, translated by the delta.  This call only does the copy - it
+// doesn't affect any other bits.
+
+static void vncHooksCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+                               RegionPtr pOldRegion)
+{
+  SCREEN_UNWRAP(pWin->drawable.pScreen, CopyWindow);
+
+  RegionHelper copied(pScreen, pOldRegion);
+  int dx = pWin->drawable.x - ptOldOrg.x;
+  int dy = pWin->drawable.y - ptOldOrg.y;
+  REGION_TRANSLATE(pScreen, copied.reg, dx, dy);
+  REGION_INTERSECT(pWin->drawable.pScreen, copied.reg, copied.reg,
+                   &pWin->borderClip);
+
+  (*pScreen->CopyWindow) (pWin, ptOldOrg, pOldRegion);
+
+  vncHooksScreen->desktop->add_copied(copied.reg, dx, dy);
+
+  SCREEN_REWRAP(CopyWindow);
+}
+
+// ClearToBackground - changed region is the given rectangle, clipped by
+// clipList, but only if generateExposures is false.
+
+static void vncHooksClearToBackground(WindowPtr pWin, int x, int y, int w,
+                                      int h, Bool generateExposures)
+{
+  SCREEN_UNWRAP(pWin->drawable.pScreen, ClearToBackground);
+
+  BoxRec box;
+  box.x1 = x + pWin->drawable.x;
+  box.y1 = y + pWin->drawable.y;
+  box.x2 = w ? (box.x1 + w) : (pWin->drawable.x + pWin->drawable.width);
+  box.y2 = h ? (box.y1 + h) : (pWin->drawable.y + pWin->drawable.height);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, &pWin->clipList);
+
+  (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+
+  if (!generateExposures) {
+    vncHooksScreen->desktop->add_changed(changed.reg);
+  }
+
+  SCREEN_REWRAP(ClearToBackground);
+}
+
+// RestoreAreas - changed region is the given region
+
+static RegionPtr vncHooksRestoreAreas(WindowPtr pWin, RegionPtr pRegion)
+{
+  SCREEN_UNWRAP(pWin->drawable.pScreen, RestoreAreas);
+
+  RegionHelper changed(pScreen, pRegion);
+
+  RegionPtr result = (*pScreen->RestoreAreas) (pWin, pRegion);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+
+  SCREEN_REWRAP(RestoreAreas);
+
+  return result;
+}
+
+// InstallColormap - get the new colormap
+
+static void vncHooksInstallColormap(ColormapPtr pColormap)
+{
+  SCREEN_UNWRAP(pColormap->pScreen, InstallColormap);
+
+  (*pScreen->InstallColormap) (pColormap);
+
+  vncHooksScreen->desktop->setColormap(pColormap);
+
+  SCREEN_REWRAP(InstallColormap);
+}
+
+// StoreColors - get the colormap changes
+
+static void vncHooksStoreColors(ColormapPtr pColormap, int ndef,
+                                xColorItem* pdef)
+{
+  SCREEN_UNWRAP(pColormap->pScreen, StoreColors);
+
+  (*pScreen->StoreColors) (pColormap, ndef, pdef);
+
+  vncHooksScreen->desktop->setColourMapEntries(pColormap, ndef, pdef);
+
+  SCREEN_REWRAP(StoreColors);
+}
+
+// DisplayCursor - get the cursor shape
+
+static Bool vncHooksDisplayCursor(ScreenPtr pScreen_, CursorPtr cursor)
+{
+  SCREEN_UNWRAP(pScreen_, DisplayCursor);
+
+  Bool ret = (*pScreen->DisplayCursor) (pScreen, cursor);
+
+  vncHooksScreen->desktop->setCursor(cursor);
+
+  SCREEN_REWRAP(DisplayCursor);
+
+  return ret;
+}
+
+// BlockHandler - ignore any changes during the block handler - it's likely
+// these are just drawing the cursor.
+
+static void vncHooksBlockHandler(int i, pointer blockData, pointer pTimeout,
+                                 pointer pReadmask)
+{
+  SCREEN_UNWRAP(screenInfo.screens[i], BlockHandler);
+
+  vncHooksScreen->desktop->ignoreHooks(true);
+
+  (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+
+  vncHooksScreen->desktop->ignoreHooks(false);
+
+  SCREEN_REWRAP(BlockHandler);
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// GC "funcs"
+//
+
+// GCFuncUnwrapper is a helper class which unwraps the GC funcs and ops in its
+// constructor and rewraps them in its destructor.
+
+class GCFuncUnwrapper {
+public:
+  GCFuncUnwrapper(GCPtr pGC_) : pGC(pGC_) {
+    vncHooksGC = (vncHooksGCPtr)pGC->devPrivates[vncHooksGCIndex].ptr;
+    pGC->funcs = vncHooksGC->wrappedFuncs;
+    if (vncHooksGC->wrappedOps)
+      pGC->ops = vncHooksGC->wrappedOps;
+  }
+  ~GCFuncUnwrapper() {
+    vncHooksGC->wrappedFuncs = pGC->funcs;
+    pGC->funcs = &vncHooksGCFuncs;
+    if (vncHooksGC->wrappedOps) {
+      vncHooksGC->wrappedOps = pGC->ops;
+      pGC->ops = &vncHooksGCOps;
+    }
+  }
+  GCPtr pGC;
+  vncHooksGCPtr vncHooksGC;
+};
+
+
+// ValidateGC - wrap the "ops" if a viewable window
+
+static void vncHooksValidateGC(GCPtr pGC, unsigned long changes,
+                               DrawablePtr pDrawable)
+{
+  GCFuncUnwrapper u(pGC);
+
+  DBGPRINT((stderr,"vncHooksValidateGC called\n"));
+
+  (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
+    
+  u.vncHooksGC->wrappedOps = 0;
+  if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr)pDrawable)->viewable) {
+    WindowPtr pWin = (WindowPtr)pDrawable;
+    RegionPtr pRegion = &pWin->clipList;
+
+    if (pGC->subWindowMode == IncludeInferiors)
+      pRegion = &pWin->borderClip;
+    if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion)) {
+      u.vncHooksGC->wrappedOps = pGC->ops;
+      DBGPRINT((stderr,"vncHooksValidateGC: wrapped GC ops\n"));
+    }
+  }
+}
+
+// Other GC funcs - just unwrap and call on
+
+static void vncHooksChangeGC(GCPtr pGC, unsigned long mask) {
+  GCFuncUnwrapper u(pGC);
+  (*pGC->funcs->ChangeGC) (pGC, mask);
+}
+static void vncHooksCopyGC(GCPtr src, unsigned long mask, GCPtr dst) {
+  GCFuncUnwrapper u(dst);
+  (*dst->funcs->CopyGC) (src, mask, dst);
+}
+static void vncHooksDestroyGC(GCPtr pGC) {
+  GCFuncUnwrapper u(pGC);
+  (*pGC->funcs->DestroyGC) (pGC);
+}
+static void vncHooksChangeClip(GCPtr pGC, int type, pointer pValue, int nrects)
+{
+  GCFuncUnwrapper u(pGC);
+  (*pGC->funcs->ChangeClip) (pGC, type, pValue, nrects);
+}
+static void vncHooksDestroyClip(GCPtr pGC) {
+  GCFuncUnwrapper u(pGC);
+  (*pGC->funcs->DestroyClip) (pGC);
+}
+static void vncHooksCopyClip(GCPtr dst, GCPtr src) {
+  GCFuncUnwrapper u(dst);
+  (*dst->funcs->CopyClip) (dst, src);
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// GC "ops"
+//
+
+// GCOpUnwrapper is a helper class which unwraps the GC funcs and ops in its
+// constructor and rewraps them in its destructor.
+
+class GCOpUnwrapper {
+public:
+  GCOpUnwrapper(DrawablePtr pDrawable, GCPtr pGC_)
+    : pGC(pGC_), pScreen(pDrawable->pScreen)
+  {
+    vncHooksGC = (vncHooksGCPtr)pGC->devPrivates[vncHooksGCIndex].ptr;
+    oldFuncs = pGC->funcs;
+    pGC->funcs = vncHooksGC->wrappedFuncs;
+    pGC->ops = vncHooksGC->wrappedOps;
+  }
+  ~GCOpUnwrapper() {
+    vncHooksGC->wrappedOps = pGC->ops;
+    pGC->funcs = oldFuncs;
+    pGC->ops = &vncHooksGCOps;
+  }
+  GCPtr pGC;
+  vncHooksGCPtr vncHooksGC;
+  GCFuncs* oldFuncs;
+  ScreenPtr pScreen;
+};
+
+#define GC_OP_UNWRAPPER(pDrawable, pGC, name)                             \
+  GCOpUnwrapper u(pDrawable, pGC);                                        \
+  ScreenPtr pScreen = (pDrawable)->pScreen;                               \
+  vncHooksScreenPtr vncHooksScreen                                        \
+    = ((vncHooksScreenPtr)pScreen->devPrivates[vncHooksScreenIndex].ptr); \
+  DBGPRINT((stderr,"vncHooks" #name " called\n"));
+
+
+// FillSpans - changed region is the whole of borderClip.  This is pessimistic,
+// but I believe this function is rarely used so it doesn't matter.
+
+static void vncHooksFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nInit,
+                              DDXPointPtr pptInit, int *pwidthInit,
+                              int fSorted)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, FillSpans);
+
+  RegionHelper changed(pScreen, &((WindowPtr)pDrawable)->borderClip);
+
+  (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// SetSpans - changed region is the whole of borderClip.  This is pessimistic,
+// but I believe this function is rarely used so it doesn't matter.
+
+static void vncHooksSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+                             DDXPointPtr ppt, int *pwidth, int nspans,
+                             int fSorted)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, SetSpans);
+
+  RegionHelper changed(pScreen, &((WindowPtr)pDrawable)->borderClip);
+
+  (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PutImage - changed region is the given rectangle, clipped by pCompositeClip
+
+static void vncHooksPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                             int x, int y, int w, int h, int leftPad,
+                             int format, char *pBits)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PutImage);
+
+  BoxRec box;
+  box.x1 = x + pDrawable->x;
+  box.y1 = y + pDrawable->y;
+  box.x2 = box.x1 + w;
+  box.y2 = box.y1 + h;
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+                         pBits);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// CopyArea - destination of the copy is the dest rectangle, clipped by
+// pCompositeClip.  Any parts of the destination which cannot be copied from
+// the source (could be all of it) go into the changed region.
+
+static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+                                  GCPtr pGC, int srcx, int srcy, int w, int h,
+                                  int dstx, int dsty)
+{
+  GC_OP_UNWRAPPER(pDst, pGC, CopyArea);
+
+  BoxRec box;
+  box.x1 = dstx + pDst->x;
+  box.y1 = dsty + pDst->y;
+  box.x2 = box.x1 + w;
+  box.y2 = box.y1 + h;
+
+  RegionHelper dst(pScreen, &box, 0);
+  REGION_INTERSECT(pScreen, dst.reg, dst.reg, COMPOSITE_CLIP(pGC));
+
+  RegionHelper src(pScreen);
+
+  if ((pSrc->type == DRAWABLE_WINDOW) && (pSrc->pScreen == pScreen)) {
+    box.x1 = srcx + pSrc->x;
+    box.y1 = srcy + pSrc->y;
+    box.x2 = box.x1 + w;
+    box.y2 = box.y1 + h;
+
+    src.init(&box, 0);
+    REGION_INTERSECT(pScreen, src.reg, src.reg, &((WindowPtr)pSrc)->clipList);
+    REGION_TRANSLATE(pScreen, src.reg,
+                     dstx + pDst->x - srcx - pSrc->x,
+                     dsty + pDst->y - srcy - pSrc->y);
+  } else {
+    src.init(NullBox, 0);
+  }
+
+  RegionHelper changed(pScreen, NullBox, 0);
+  REGION_SUBTRACT(pScreen, changed.reg, dst.reg, src.reg);
+  REGION_INTERSECT(pScreen, dst.reg, dst.reg, src.reg);
+
+  RegionPtr rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
+                                         dstx, dsty);
+
+  if (REGION_NOTEMPTY(pScreen, dst.reg))
+    vncHooksScreen->desktop->add_copied(dst.reg,
+                                        dstx + pDst->x - srcx - pSrc->x,
+                                        dsty + pDst->y - srcy - pSrc->y);
+
+  if (REGION_NOTEMPTY(pScreen, changed.reg))
+    vncHooksScreen->desktop->add_changed(changed.reg);
+
+  return rgn;
+}
+
+
+// CopyPlane - changed region is the destination rectangle, clipped by
+// pCompositeClip
+
+static RegionPtr vncHooksCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+                                   GCPtr pGC, int srcx, int srcy, int w, int h,
+                                   int dstx, int dsty, unsigned long plane)
+{
+  GC_OP_UNWRAPPER(pDst, pGC, CopyPlane);
+
+  BoxRec box;
+  box.x1 = dstx + pDst->x;
+  box.y1 = dsty + pDst->y;
+  box.x2 = box.x1 + w;
+  box.y2 = box.y1 + h;
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  RegionPtr rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
+                                          dstx, dsty, plane);
+  vncHooksScreen->desktop->add_changed(changed.reg);
+
+  return rgn;
+}
+
+// PolyPoint - changed region is the bounding rect, clipped by pCompositeClip
+
+static void vncHooksPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                              int npt, xPoint *pts)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyPoint);
+
+  if (npt == 0) {
+    (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
+    return;
+  }
+
+  int minX = pts[0].x;
+  int maxX = pts[0].x;
+  int minY = pts[0].y;
+  int maxY = pts[0].y;
+
+  if (mode == CoordModePrevious) {
+    int x = pts[0].x;
+    int y = pts[0].y;
+
+    for (int i = 1; i < npt; i++) {
+      x += pts[i].x;
+      y += pts[i].y;
+      if (x < minX) minX = x;
+      if (x > maxX) maxX = x;
+      if (y < minY) minY = y;
+      if (y > maxY) maxY = y;
+    }
+  } else {
+    for (int i = 1; i < npt; i++) {
+      if (pts[i].x < minX) minX = pts[i].x;
+      if (pts[i].x > maxX) maxX = pts[i].x;
+      if (pts[i].y < minY) minY = pts[i].y;
+      if (pts[i].y > maxY) maxY = pts[i].y;
+    }
+  }
+
+  BoxRec box;
+  box.x1 = minX + pDrawable->x;
+  box.y1 = minY + pDrawable->y;
+  box.x2 = maxX + 1 + pDrawable->x;
+  box.y2 = maxY + 1 + pDrawable->y;
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pts);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// Polylines - changed region is the union of the bounding rects of each line,
+// clipped by pCompositeClip.  If there are more than MAX_RECTS_PER_OP lines,
+// just use the bounding rect of all the lines.
+
+static void vncHooksPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                              int npt, DDXPointPtr ppts)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, Polylines);
+
+  if (npt == 0) {
+    (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
+    return;
+  }
+
+  int nRegRects = npt - 1;
+  xRectangle regRects[MAX_RECTS_PER_OP];
+
+  int lw = pGC->lineWidth;
+  if (lw == 0) lw = 1;
+
+  if (npt == 1)
+  {
+    // a single point
+    nRegRects = 1;
+    regRects[0].x = pDrawable->x + ppts[0].x - lw;
+    regRects[0].y = pDrawable->y + ppts[0].y - lw;
+    regRects[0].width = 2*lw;
+    regRects[0].height = 2*lw;
+  }
+  else
+  {
+    /*
+     * mitered joins can project quite a way from
+     * the line end; the 11 degree miter limit limits
+     * this extension to lw / (2 * tan(11/2)), rounded up
+     * and converted to int yields 6 * lw
+     */
+
+    int extra = lw / 2;
+    if (pGC->joinStyle == JoinMiter) {
+      extra = 6 * lw;
+    }
+
+    int prevX, prevY, curX, curY;
+    int rectX1, rectY1, rectX2, rectY2;
+    int minX, minY, maxX, maxY;
+
+    prevX = ppts[0].x + pDrawable->x;
+    prevY = ppts[0].y + pDrawable->y;
+    minX = maxX = prevX;
+    minY = maxY = prevY;
+
+    for (int i = 0; i < nRegRects; i++) {
+      if (mode == CoordModeOrigin) {
+        curX = pDrawable->x + ppts[i+1].x;
+        curY = pDrawable->y + ppts[i+1].y;
+      } else {
+        curX = prevX + ppts[i+1].x;
+        curY = prevY + ppts[i+1].y;
+      }
+
+      if (prevX > curX) {
+        rectX1 = curX - extra;
+        rectX2 = prevX + extra + 1;
+      } else {
+        rectX1 = prevX - extra;
+        rectX2 = curX + extra + 1;
+      }
+
+      if (prevY > curY) {
+        rectY1 = curY - extra;
+        rectY2 = prevY + extra + 1;
+      } else {
+        rectY1 = prevY - extra;
+        rectY2 = curY + extra + 1;
+      }
+
+      if (nRegRects <= MAX_RECTS_PER_OP) {
+        regRects[i].x = rectX1;
+        regRects[i].y = rectY1;
+        regRects[i].width = rectX2 - rectX1;
+        regRects[i].height = rectY2 - rectY1;
+      } else {
+        if (rectX1 < minX) minX = rectX1;
+        if (rectY1 < minY) minY = rectY1;
+        if (rectX2 > maxX) maxX = rectX2;
+        if (rectY2 > maxY) maxY = rectY2;
+      }
+
+      prevX = curX;
+      prevY = curY;
+    }
+
+    if (nRegRects > MAX_RECTS_PER_OP) {
+      regRects[0].x = minX;
+      regRects[0].y = minY;
+      regRects[0].width = maxX - minX;
+      regRects[0].height = maxY - minY;
+      nRegRects = 1;
+    }
+  }
+
+  RegionHelper changed(pScreen, nRegRects, regRects);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppts);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PolySegment - changed region is the union of the bounding rects of each
+// segment, clipped by pCompositeClip.  If there are more than MAX_RECTS_PER_OP
+// segments, just use the bounding rect of all the segments.
+
+static void vncHooksPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+                                xSegment *segs)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolySegment);
+
+  if (nseg == 0) {
+    (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
+    return;
+  }
+
+  xRectangle regRects[MAX_RECTS_PER_OP];
+  int nRegRects = nseg;
+
+  int lw = pGC->lineWidth;
+  int extra = lw / 2;
+
+  int rectX1, rectY1, rectX2, rectY2;
+  int minX, minY, maxX, maxY;
+
+  minX = maxX = segs[0].x1;
+  minY = maxY = segs[0].y1;
+
+  for (int i = 0; i < nseg; i++) {
+    if (segs[i].x1 > segs[i].x2) {
+      rectX1 = pDrawable->x + segs[i].x2 - extra;
+      rectX2 = pDrawable->x + segs[i].x1 + extra + 1;
+    } else {
+      rectX1 = pDrawable->x + segs[i].x1 - extra;
+      rectX2 = pDrawable->x + segs[i].x2 + extra + 1;
+    }
+
+    if (segs[i].y1 > segs[i].y2) {
+      rectY1 = pDrawable->y + segs[i].y2 - extra;
+      rectY2 = pDrawable->y + segs[i].y1 + extra + 1;
+    } else {
+      rectY1 = pDrawable->y + segs[i].y1 - extra;
+      rectY2 = pDrawable->y + segs[i].y2 + extra + 1;
+    }
+
+    if (nseg <= MAX_RECTS_PER_OP) {
+      regRects[i].x = rectX1;
+      regRects[i].y = rectY1;
+      regRects[i].width = rectX2 - rectX1;
+      regRects[i].height = rectY2 - rectY1;
+    } else {
+      if (rectX1 < minX) minX = rectX1;
+      if (rectY1 < minY) minY = rectY1;
+      if (rectX2 > maxX) maxX = rectX2;
+      if (rectY2 > maxY) maxY = rectY2;
+    }
+  }
+
+  if (nseg > MAX_RECTS_PER_OP) {
+    regRects[0].x = minX;
+    regRects[0].y = minY;
+    regRects[0].width = maxX - minX;
+    regRects[0].height = maxY - minY;
+    nRegRects = 1;
+  }
+
+  RegionHelper changed(pScreen, nRegRects, regRects);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, segs);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PolyRectangle - changed region is the union of the bounding rects around
+// each side of the outline rectangles, clipped by pCompositeClip.  If there
+// are more than MAX_RECTS_PER_OP rectangles, just use the bounding rect of all
+// the rectangles.
+
+static void vncHooksPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+                                  xRectangle *rects)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyRectangle);
+
+  if (nrects == 0) {
+    (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
+    return;
+  }
+
+  xRectangle regRects[MAX_RECTS_PER_OP*4];
+  int nRegRects = nrects * 4;
+
+  int lw = pGC->lineWidth;
+  int extra = lw / 2;
+
+  int rectX1, rectY1, rectX2, rectY2;
+  int minX, minY, maxX, maxY;
+
+  minX = maxX = rects[0].x;
+  minY = maxY = rects[0].y;
+
+  for (int i = 0; i < nrects; i++) {
+    if (nrects <= MAX_RECTS_PER_OP) {
+      regRects[i*4].x = rects[i].x - extra + pDrawable->x;
+      regRects[i*4].y = rects[i].y - extra + pDrawable->y;
+      regRects[i*4].width = rects[i].width + 1 + 2 * extra;
+      regRects[i*4].height = 1 + 2 * extra;
+
+      regRects[i*4+1].x = rects[i].x - extra + pDrawable->x;
+      regRects[i*4+1].y = rects[i].y - extra + pDrawable->y;
+      regRects[i*4+1].width = 1 + 2 * extra;
+      regRects[i*4+1].height = rects[i].height + 1 + 2 * extra;
+
+      regRects[i*4+2].x = rects[i].x + rects[i].width - extra + pDrawable->x;
+      regRects[i*4+2].y = rects[i].y - extra + pDrawable->y;
+      regRects[i*4+2].width = 1 + 2 * extra;
+      regRects[i*4+2].height = rects[i].height + 1 + 2 * extra;
+
+      regRects[i*4+3].x = rects[i].x - extra + pDrawable->x;
+      regRects[i*4+3].y = rects[i].y + rects[i].height - extra + pDrawable->y;
+      regRects[i*4+3].width = rects[i].width + 1 + 2 * extra;
+      regRects[i*4+3].height = 1 + 2 * extra;
+    } else {
+      rectX1 = pDrawable->x + rects[i].x - extra;
+      rectY1 = pDrawable->y + rects[i].y - extra;
+      rectX2 = pDrawable->x + rects[i].x + rects[i].width + extra+1;
+      rectY2 = pDrawable->y + rects[i].y + rects[i].height + extra+1;
+      if (rectX1 < minX) minX = rectX1;
+      if (rectY1 < minY) minY = rectY1;
+      if (rectX2 > maxX) maxX = rectX2;
+      if (rectY2 > maxY) maxY = rectY2;
+    }
+  }
+
+  if (nrects > MAX_RECTS_PER_OP) {
+    regRects[0].x = minX;
+    regRects[0].y = minY;
+    regRects[0].width = maxX - minX;
+    regRects[0].height = maxY - minY;
+    nRegRects = 1;
+  }
+
+  RegionHelper changed(pScreen, nRegRects, regRects);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, rects);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PolyArc - changed region is the union of bounding rects around each arc,
+// clipped by pCompositeClip.  If there are more than MAX_RECTS_PER_OP
+// arcs, just use the bounding rect of all the arcs.
+
+static void vncHooksPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+                            xArc *arcs)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyArc);
+
+  if (narcs == 0) {
+    (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
+    return;
+  }
+
+  xRectangle regRects[MAX_RECTS_PER_OP];
+  int nRegRects = narcs;
+
+  int lw = pGC->lineWidth;
+  if (lw == 0) lw = 1;
+  int extra = lw / 2;
+
+  int rectX1, rectY1, rectX2, rectY2;
+  int minX, minY, maxX, maxY;
+
+  minX = maxX = arcs[0].x;
+  minY = maxY = arcs[0].y;
+
+  for (int i = 0; i < narcs; i++) {
+    if (narcs <= MAX_RECTS_PER_OP) {
+      regRects[i].x = arcs[i].x - extra + pDrawable->x;
+      regRects[i].y = arcs[i].y - extra + pDrawable->y;
+      regRects[i].width = arcs[i].width + lw;
+      regRects[i].height = arcs[i].height + lw;
+    } else {
+      rectX1 = pDrawable->x + arcs[i].x - extra;
+      rectY1 = pDrawable->y + arcs[i].y - extra;
+      rectX2 = pDrawable->x + arcs[i].x + arcs[i].width + lw;
+      rectY2 = pDrawable->y + arcs[i].y + arcs[i].height + lw;
+      if (rectX1 < minX) minX = rectX1;
+      if (rectY1 < minY) minY = rectY1;
+      if (rectX2 > maxX) maxX = rectX2;
+      if (rectY2 > maxY) maxY = rectY2;
+    }
+  }
+
+  if (narcs > MAX_RECTS_PER_OP) {
+    regRects[0].x = minX;
+    regRects[0].y = minY;
+    regRects[0].width = maxX - minX;
+    regRects[0].height = maxY - minY;
+    nRegRects = 1;
+  }
+
+  RegionHelper changed(pScreen, nRegRects, regRects);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, arcs);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+
+// FillPolygon - changed region is the bounding rect around the polygon,
+// clipped by pCompositeClip
+
+static void vncHooksFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+                                int mode, int count, DDXPointPtr pts)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, FillPolygon);
+
+  if (count == 0) {
+    (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
+    return;
+  }
+
+  int minX = pts[0].x;
+  int maxX = pts[0].x;
+  int minY = pts[0].y;
+  int maxY = pts[0].y;
+
+  if (mode == CoordModePrevious) {
+    int x = pts[0].x;
+    int y = pts[0].y;
+
+    for (int i = 1; i < count; i++) {
+      x += pts[i].x;
+      y += pts[i].y;
+      if (x < minX) minX = x;
+      if (x > maxX) maxX = x;
+      if (y < minY) minY = y;
+      if (y > maxY) maxY = y;
+    }
+  } else {
+    for (int i = 1; i < count; i++) {
+      if (pts[i].x < minX) minX = pts[i].x;
+      if (pts[i].x > maxX) maxX = pts[i].x;
+      if (pts[i].y < minY) minY = pts[i].y;
+      if (pts[i].y > maxY) maxY = pts[i].y;
+    }
+  }
+
+  BoxRec box;
+  box.x1 = minX + pDrawable->x;
+  box.y1 = minY + pDrawable->y;
+  box.x2 = maxX + 1 + pDrawable->x;
+  box.y2 = maxY + 1 + pDrawable->y;
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pts);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PolyFillRect - changed region is the union of the rectangles, clipped by
+// pCompositeClip.  If there are more than MAX_RECTS_PER_OP rectangles, just
+// use the bounding rect of all the rectangles.
+
+static void vncHooksPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrects,
+                                 xRectangle *rects)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyFillRect);
+
+  if (nrects == 0) {
+    (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
+    return;
+  }
+
+  xRectangle regRects[MAX_RECTS_PER_OP];
+  int nRegRects = nrects;
+  int rectX1, rectY1, rectX2, rectY2;
+  int minX, minY, maxX, maxY;
+  minX = maxX = rects[0].x;
+  minY = maxY = rects[0].y;
+
+  for (int i = 0; i < nrects; i++) {
+    if (nrects <= MAX_RECTS_PER_OP) {
+      regRects[i].x = rects[i].x + pDrawable->x;
+      regRects[i].y = rects[i].y + pDrawable->y;
+      regRects[i].width = rects[i].width;
+      regRects[i].height = rects[i].height;
+    } else {
+      rectX1 = pDrawable->x + rects[i].x;
+      rectY1 = pDrawable->y + rects[i].y;
+      rectX2 = pDrawable->x + rects[i].x + rects[i].width;
+      rectY2 = pDrawable->y + rects[i].y + rects[i].height;
+      if (rectX1 < minX) minX = rectX1;
+      if (rectY1 < minY) minY = rectY1;
+      if (rectX2 > maxX) maxX = rectX2;
+      if (rectY2 > maxY) maxY = rectY2;
+    }
+  }
+
+  if (nrects > MAX_RECTS_PER_OP) {
+    regRects[0].x = minX;
+    regRects[0].y = minY;
+    regRects[0].width = maxX - minX;
+    regRects[0].height = maxY - minY;
+    nRegRects = 1;
+  }
+
+  RegionHelper changed(pScreen, nRegRects, regRects);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, rects);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PolyFillArc - changed region is the union of bounding rects around each arc,
+// clipped by pCompositeClip.  If there are more than MAX_RECTS_PER_OP arcs,
+// just use the bounding rect of all the arcs.
+
+static void vncHooksPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int narcs,
+                                xArc *arcs)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyFillArc);
+
+  if (narcs == 0) {
+    (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
+    return;
+  }
+
+  xRectangle regRects[MAX_RECTS_PER_OP];
+  int nRegRects = narcs;
+
+  int lw = pGC->lineWidth;
+  if (lw == 0) lw = 1;
+  int extra = lw / 2;
+
+  int rectX1, rectY1, rectX2, rectY2;
+  int minX, minY, maxX, maxY;
+
+  minX = maxX = arcs[0].x;
+  minY = maxY = arcs[0].y;
+
+  for (int i = 0; i < narcs; i++) {
+    if (narcs <= MAX_RECTS_PER_OP) {
+      regRects[i].x = arcs[i].x - extra + pDrawable->x;
+      regRects[i].y = arcs[i].y - extra + pDrawable->y;
+      regRects[i].width = arcs[i].width + lw;
+      regRects[i].height = arcs[i].height + lw;
+    } else {
+      rectX1 = pDrawable->x + arcs[i].x - extra;
+      rectY1 = pDrawable->y + arcs[i].y - extra;
+      rectX2 = pDrawable->x + arcs[i].x + arcs[i].width + lw;
+      rectY2 = pDrawable->y + arcs[i].y + arcs[i].height + lw;
+      if (rectX1 < minX) minX = rectX1;
+      if (rectY1 < minY) minY = rectY1;
+      if (rectX2 > maxX) maxX = rectX2;
+      if (rectY2 > maxY) maxY = rectY2;
+    }
+  }
+
+  if (narcs > MAX_RECTS_PER_OP) {
+    regRects[0].x = minX;
+    regRects[0].y = minY;
+    regRects[0].width = maxX - minX;
+    regRects[0].height = maxY - minY;
+    nRegRects = 1;
+  }
+
+  RegionHelper changed(pScreen, nRegRects, regRects);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, arcs);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// GetTextBoundingRect - calculate a bounding rectangle around n chars of a
+// font.  Not particularly accurate, but good enough.
+
+static void GetTextBoundingRect(DrawablePtr pDrawable, FontPtr font, int x,
+                                int y, int nchars, BoxPtr box)
+{
+  int ascent = max(FONTASCENT(font), FONTMAXBOUNDS(font, ascent));
+  int descent = max(FONTDESCENT(font), FONTMAXBOUNDS(font, descent));
+  int charWidth = max(FONTMAXBOUNDS(font,rightSideBearing),
+                      FONTMAXBOUNDS(font,characterWidth));
+
+  box->x1 = pDrawable->x + x;
+  box->y1 = pDrawable->y + y - ascent;
+  box->x2 = box->x1 + charWidth * nchars;
+  box->y2 = box->y1 + ascent + descent;
+
+  if (FONTMINBOUNDS(font,leftSideBearing) < 0)
+    box->x1 += FONTMINBOUNDS(font,leftSideBearing);
+}
+
+// PolyText8 - changed region is bounding rect around count chars, clipped by
+// pCompositeClip
+
+static int vncHooksPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                             int count, char *chars)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyText8);
+
+  if (count == 0)
+    return (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
+
+  BoxRec box;
+  GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  int ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+
+  return ret;
+}
+
+// PolyText16 - changed region is bounding rect around count chars, clipped by
+// pCompositeClip
+
+static int vncHooksPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                              int count, unsigned short *chars)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyText16);
+
+  if (count == 0)
+    return (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
+
+  BoxRec box;
+  GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  int ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+
+  return ret;
+}
+
+// ImageText8 - changed region is bounding rect around count chars, clipped by
+// pCompositeClip
+
+static void vncHooksImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                               int count, char *chars)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, ImageText8);
+
+  if (count == 0) {
+    (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
+    return;
+  }
+
+  BoxRec box;
+  GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// ImageText16 - changed region is bounding rect around count chars, clipped by
+// pCompositeClip
+
+static void vncHooksImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                                int count, unsigned short *chars)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, ImageText16);
+
+  if (count == 0) {
+    (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
+    return;
+  }
+
+  BoxRec box;
+  GetTextBoundingRect(pDrawable, pGC->font, x, y, count, &box);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// ImageGlyphBlt - changed region is bounding rect around nglyph chars, clipped
+// by pCompositeClip
+
+static void vncHooksImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
+                                  int y, unsigned int nglyph,
+                                  CharInfoPtr *ppci, pointer pglyphBase)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, ImageGlyphBlt);
+
+  if (nglyph == 0) {
+    (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,pglyphBase);
+    return;
+  }
+
+  BoxRec box;
+  GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PolyGlyphBlt - changed region is bounding rect around nglyph chars, clipped
+// by pCompositeClip
+
+static void vncHooksPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x,
+                                 int y, unsigned int nglyph,
+                                 CharInfoPtr *ppci, pointer pglyphBase)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PolyGlyphBlt);
+
+  if (nglyph == 0) {
+    (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,pglyphBase);
+    return;
+  }
+
+  BoxRec box;
+  GetTextBoundingRect(pDrawable, pGC->font, x, y, nglyph, &box);
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
+
+// PushPixels - changed region is the given rectangle, clipped by
+// pCompositeClip
+
+static void vncHooksPushPixels(GCPtr pGC, PixmapPtr pBitMap,
+                               DrawablePtr pDrawable, int w, int h, int x,
+                               int y)
+{
+  GC_OP_UNWRAPPER(pDrawable, pGC, PushPixels);
+
+  BoxRec box;
+  box.x1 = x + pDrawable->x;
+  box.y1 = y + pDrawable->y;
+  box.x2 = box.x1 + w;
+  box.y2 = box.y1 + h;
+
+  RegionHelper changed(pScreen, &box, 0);
+
+  REGION_INTERSECT(pScreen, changed.reg, changed.reg, COMPOSITE_CLIP(pGC));
+
+  (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
+
+  vncHooksScreen->desktop->add_changed(changed.reg);
+}
diff --git a/xc/programs/Xserver/vnc/vncHooks.h b/xc/programs/Xserver/vnc/vncHooks.h
new file mode 100644
index 0000000..c2ca825
--- /dev/null
+++ b/xc/programs/Xserver/vnc/vncHooks.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+#ifndef __VNCHOOKS_H__
+#define __VNCHOOKS_H__
+
+extern "C" {
+#include <screenint.h>
+  extern Bool vncHooksInit(ScreenPtr pScreen, XserverDesktop* desktop);
+}
+
+#endif
diff --git a/xc/programs/Xserver/vnc/xf86vncModule.cc b/xc/programs/Xserver/vnc/xf86vncModule.cc
new file mode 100644
index 0000000..3504c6a
--- /dev/null
+++ b/xc/programs/Xserver/vnc/xf86vncModule.cc
@@ -0,0 +1,96 @@
+/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
+ *    
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ */
+/*  This is the xf86 module code for the vnc extension.
+ */
+
+#include <rfb/Configuration.h>
+#include <rfb/Logger_stdio.h>
+#include <rfb/LogWriter.h>
+
+extern "C" {
+#define class c_class
+#define private c_private
+#define bool c_bool
+#define new c_new
+#include "xf86.h"
+#include "xf86Module.h"
+#undef class
+#undef private
+#undef bool
+#undef new
+
+extern void vncExtensionInit();
+static void vncExtensionInitWithParams(INITARGS);
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(vncSetup);
+
+ExtensionModule vncExt =
+{
+    vncExtensionInitWithParams,
+    "VNC",
+    NULL,
+    NULL,
+    NULL
+};
+
+static XF86ModuleVersionInfo vncVersRec =
+{
+    "vnc",
+    "RealVNC Ltd",
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XF86_VERSION_CURRENT,
+    1, 0, 0,
+    ABI_CLASS_EXTENSION,         /* needs the server extension ABI */
+    ABI_EXTENSION_VERSION,
+    MOD_CLASS_EXTENSION,
+    {0,0,0,0}
+};
+
+XF86ModuleData vncModuleData = { &vncVersRec, vncSetup, NULL };
+
+static pointer
+vncSetup(pointer module, pointer opts, int *errmaj, int *errmin) {
+    LoadExtension(&vncExt, FALSE);
+    /* Need a non-NULL return value to indicate success */
+    return (pointer)1;
+}
+
+static void vncExtensionInitWithParams(INITARGS)
+{
+  rfb::initStdIOLoggers();
+  rfb::LogWriter::setLogParams("*:stderr:30");
+
+  for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+    ScrnInfoPtr pScrn = xf86Screens[scr];
+
+    rfb::VoidParameter* p;
+    for (p = rfb::Configuration::head; p; p = p->_next) {
+      char* val = xf86FindOptionValue(pScrn->options, p->getName());
+      if (val)
+        p->setParam(val);
+    }
+  }
+
+  vncExtensionInit();
+}
+
+#endif /* XFree86LOADER */
+}
