diff --git a/unix/xc/programs/Xserver/Xvnc.man b/unix/xc/programs/Xserver/Xvnc.man
new file mode 100644
index 0000000..128bc93
--- /dev/null
+++ b/unix/xc/programs/Xserver/Xvnc.man
@@ -0,0 +1,284 @@
+.TH Xvnc 1 "17 Apr 2006" "TightVNC" "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 color 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 0, which means that idle connections will never be dropped).
+
+.TP
+.B \-QueryConnect
+Prompts the user of the desktop to explicitly accept or reject incoming
+connections.  This is most useful when using the vnc.so module or
+\fBx0vncserver\fP(1) program to access an existing X desktop via VNC.
+
+The \fBvncconfig\fP(1) program must be running on the desktop in order for
+QueryConnect to be supported by the \fBvnc.so\fP(1) module or
+\fBXvnc\fP(1) program.  The \fBx0vncserver\fP(1) program does not require
+\fBvncconfig\fP(1) to be running.
+
+.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.
+
+.TP
+.B \-RemapKeys \fImapping
+Sets up a keyboard mapping.
+.I mapping
+is a comma-separated string of character mappings, each of the form
+.IR char -> char ,
+or
+.IR char <> char ,
+where
+.I char
+is a hexadecimal keysym. For example, to exchange the " and @ symbols you would specify the following:
+.IP "" 10
+RemapKeys=0x22<>0x40
+
+.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.tightvnc.com
+
+.SH AUTHOR
+Tristan Richardson, RealVNC Ltd.
+
+VNC was originally developed by the RealVNC team while at Olivetti
+Research Ltd / AT&T Laboratories Cambridge.  TightVNC additions was
+implemented by Constantin Kaplinsky. Many other people participated in
+development, testing and support.
diff --git a/unix/xc/programs/Xserver/vnc/Imakefile b/unix/xc/programs/Xserver/vnc/Imakefile
new file mode 100644
index 0000000..1c8132d
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/Imakefile
@@ -0,0 +1,44 @@
+XCOMM CDEBUGFLAGS = -g
+XCOMM CXXDEBUGFLAGS = -g
+
+       VNCTOP = $(TOP)/..
+   VNCINCLUDE = -I$(VNCTOP) -I$(VNCTOP)/vncconfig_unix
+
+#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../render $(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/unix/xc/programs/Xserver/vnc/RegionHelper.h b/unix/xc/programs/Xserver/vnc/RegionHelper.h
new file mode 100644
index 0000000..61dc89f
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/RegionHelper.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 2002-2005 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.
+
+// REGION_NULL was introduced in the Xorg tree as the way to initialise an
+// empty region.  If it's not already defined do it the old way.  Note that the
+// old way causes a segfault in the new tree...
+#ifndef REGION_NULL
+#define REGION_NULL(pScreen,pReg) REGION_INIT(pScreen,pReg,NullBox,0)
+#endif
+
+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_NULL(pScreen, reg);
+    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 && (rect->x2 == rect->x1 || rect->y2 == rect->y1))) {
+      REGION_NULL(pScreen, reg);
+    } 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/unix/xc/programs/Xserver/vnc/XserverDesktop.cc b/unix/xc/programs/Xserver/vnc/XserverDesktop.cc
new file mode 100644
index 0000000..9e5ea0f
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/XserverDesktop.cc
@@ -0,0 +1,1147 @@
+/* Copyright (C) 2002-2005 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);
+
+IntParameter queryConnectTimeout("QueryConnectTimeout",
+                                 "Number of seconds to show the Accept Connection dialog before "
+                                 "rejecting the connection",
+                                 10);
+
+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 FileHTTPServer : public rfb::HTTPServer {
+public:
+  FileHTTPServer(XserverDesktop* d) : desktop(d) {}
+  virtual ~FileHTTPServer() {}
+
+  virtual rdr::InStream* getFile(const char* name, const char** contentType,
+                                 int* contentLength, time_t* lastModified)
+  {
+    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";
+    } else {
+      struct stat st;
+      if (fstat(fd, &st) == 0) {
+        *contentLength = st.st_size;
+        *lastModified = st.st_mtime;
+      }
+    }
+    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),
+    queryConnectId(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);
+  server->setQueryConnectionHandler(this);
+
+  if (httpListener)
+    httpServer = new FileHTTPServer(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;
+}
+
+rfb::VNCServerST::queryResult
+XserverDesktop::queryConnection(network::Socket* sock,
+                                const char* userName,
+                                char** reason) {
+  if (queryConnectId) {
+    *reason = strDup("Another connection is currently being queried.");
+    return rfb::VNCServerST::REJECT;
+  }
+  queryConnectAddress.replaceBuf(sock->getPeerAddress());
+  if (!userName)
+    userName = "(anonymous)";
+  queryConnectUsername.replaceBuf(strDup(userName));
+  queryConnectId = sock;
+  vncQueryConnect(this, sock);
+  return rfb::VNCServerST::PENDING;
+}
+
+
+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,
+                      Point(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::deferUpdate()
+{
+  if (deferUpdateTime != 0) {
+    if (!deferredUpdateTimerSet || alwaysSetDeferUpdateTimer) {
+      deferredUpdateTimerSet = true;
+      deferredUpdateTimer = TimerSet(deferredUpdateTimer, 0,
+                                     deferUpdateTime,
+                                     deferredUpdateTimerCallback, this);
+    }
+  } else {
+    server->tryUpdate();
+  }
+}
+
+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);
+    deferUpdate();
+  } 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));
+    deferUpdate();
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::add_copied: %s",e.str());
+  }
+}
+
+void XserverDesktop::positionCursor()
+{
+  if (!cursorPos.equals(oldCursorPos)) {
+    oldCursorPos = cursorPos;
+    (*pScreen->SetCursorPosition) (pScreen, cursorPos.x, cursorPos.y, FALSE);
+    server->setCursorPos(cursorPos);
+    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 != cursorPos.x || y != cursorPos.y) {
+        cursorPos = oldCursorPos = Point(x, y);
+        server->setCursorPos(cursorPos);
+        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++) {
+      int fd = (*i)->getFd();
+      if ((*i)->isShutdown()) {
+        vlog.debug("client gone, sock %d",fd);
+        server->removeSocket(*i);
+        vncClientGone(fd);
+        delete (*i);
+      } else {
+        FD_SET(fd, fds);
+      }
+    }
+    if (httpServer) {
+      httpServer->getSockets(&sockets);
+      for (i = sockets.begin(); i != sockets.end(); i++) {
+        int fd = (*i)->getFd();
+        if ((*i)->isShutdown()) {
+          vlog.debug("http client gone, sock %d",fd);
+          httpServer->removeSocket(*i);
+          delete (*i);
+        } else {
+          FD_SET(fd, 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->addSocket(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->addSocket(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);
+          server->processSocketEvent(*i);
+        }
+      }
+
+      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);
+            httpServer->processSocketEvent(*i);
+          }
+        }
+      }
+
+      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->addSocket(sock, reverse);
+}
+
+void XserverDesktop::disconnectClients()
+{
+  vlog.debug("disconnecting all clients");
+  return server->closeClients("Disconnection from server end");
+}
+
+
+int XserverDesktop::getQueryTimeout(void* opaqueId,
+                                    const char** address,
+                                    const char** username)
+{
+  if (opaqueId && queryConnectId == opaqueId) {
+    vlog.info("address=%s, username=%s, timeout=%d",
+              queryConnectAddress.buf, queryConnectUsername.buf,
+              (int)queryConnectTimeout);
+    if (address) *address = queryConnectAddress.buf;
+    if (username) *username = queryConnectUsername.buf;
+    return queryConnectTimeout;
+  }
+  return 0;
+}
+
+void XserverDesktop::approveConnection(void* opaqueId, bool accept,
+                                       const char* rejectMsg)
+{
+  if (queryConnectId == opaqueId) {
+    server->approveConnection((network::Socket*)opaqueId, accept, rejectMsg);
+    queryConnectId = 0;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// SDesktop callbacks
+
+
+void XserverDesktop::pointerEvent(const Point& pos, int 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.equals(cursorPos))
+    (*dev->processInputProc)(&ev, (DeviceIntPtr)dev, 1);
+
+  for (int i = 0; i < 5; i++) {
+    if ((buttonMask ^ oldButtonMask) & (1<<i)) {
+      // Do not use the pointer mapping. Treat VNC buttons as logical
+      // buttons.
+      ev.u.u.detail = i + 1;
+      ev.u.u.type = (buttonMask & (1<<i)) ? ButtonPress : ButtonRelease;
+      (*dev->processInputProc)(&ev, (DeviceIntPtr)dev, 1);
+    }
+  }
+
+  cursorPos = pos;
+  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)
+{
+  if ((cmap->c_class | DynamicClass) == DirectColor) {
+    VisualPtr v = cmap->pVisual;
+    *r = cmap->red  [(index & v->redMask  ) >> v->offsetRed  ].co.local.red;
+    *g = cmap->green[(index & v->greenMask) >> v->offsetGreen].co.local.green;
+    *b = cmap->blue [(index & v->blueMask ) >> v->offsetBlue ].co.local.blue;
+  } else {
+    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/unix/xc/programs/Xserver/vnc/XserverDesktop.h b/unix/xc/programs/Xserver/vnc/XserverDesktop.h
new file mode 100644
index 0000000..880acc2
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/XserverDesktop.h
@@ -0,0 +1,130 @@
+/* Copyright (C) 2002-2005 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/HTTPServer.h>
+#include <rfb/PixelBuffer.h>
+#include <rfb/Configuration.h>
+#include <rfb/VNCServerST.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 XserverDesktop : public rfb::SDesktop, public rfb::FullFramePixelBuffer,
+                       public rfb::ColourMap, public rdr::Substitutor,
+                       public rfb::VNCServerST::QueryConnectionHandler {
+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();
+
+  // QueryConnect methods called from X server code
+  // getQueryTimeout()
+  //   Returns the timeout associated with a particular
+  //   connection, identified by an opaque Id passed to the
+  //   X code earlier.  Also optionally gets the address and
+  //   name associated with that connection.
+  //   Returns zero if the Id is not recognised.
+  int getQueryTimeout(void* opaqueId,
+                      const char** address=0,
+                      const char** username=0);
+
+  // approveConnection()
+  //   Used by X server code to supply the result of a query.
+  void approveConnection(void* opaqueId, bool accept,
+                         const char* rejectMsg=0);
+
+  // rfb::SDesktop callbacks
+  virtual void pointerEvent(const rfb::Point& pos, int 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);
+
+  // rfb::VNCServerST::QueryConnectionHandler callback
+  virtual rfb::VNCServerST::queryResult queryConnection(network::Socket* sock,
+                                                        const char* userName,
+                                                        char** reason);
+
+private:
+  void setColourMapEntries(int firstColour, int nColours);
+  static CARD32 deferredUpdateTimerCallback(OsTimerPtr timer, CARD32 now,
+                                            pointer arg);
+  void deferUpdate();
+  ScreenPtr pScreen;
+  OsTimerPtr deferredUpdateTimer, dummyTimer;
+  rfb::VNCServerST* server;
+  rfb::HTTPServer* httpServer;
+  network::TcpListener* listener;
+  network::TcpListener* httpListener;
+  ColormapPtr cmap;
+  bool deferredUpdateTimerSet;
+  bool grabbing;
+  bool ignoreHooks_;
+  bool directFbptr;
+  int oldButtonMask;
+  rfb::Point cursorPos, oldCursorPos;
+
+  void* queryConnectId;
+  rfb::CharArray queryConnectAddress;
+  rfb::CharArray queryConnectUsername;
+};
+#endif
diff --git a/unix/xc/programs/Xserver/vnc/Xvnc/Imakefile b/unix/xc/programs/Xserver/vnc/Xvnc/Imakefile
new file mode 100644
index 0000000..93885ae
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/Xvnc/Imakefile
@@ -0,0 +1,95 @@
+
+       VNCTOP = $(TOP)/..
+      VNCLIBS = VncExtLibs
+   VNCINCLUDE = -I$(VNCTOP) -I$(VNCTOP)/vncconfig_unix
+
+#if defined(XFree86Version) && XFree86Version < 4000
+   VNCDEFINES = -DNO_INIT_BACKING_STORE
+#endif
+
+#define CplusplusSource
+
+#include <Server.tmpl>
+
+#if HasShm
+SHMDEF = -DHAS_SHM
+#endif
+
+XCOMM add more architectures here as we discover them
+#if defined(HPArchitecture) || \
+    (defined(SparcArchitecture) && !defined(LynxOSArchitecture)) || \
+    SystemV4 || \
+    defined(OSF1Architecture) || \
+    defined(i386BsdArchitecture) || \
+    defined(LinuxArchitecture) || \
+    defined(DarwinArchitecture)
+MMAPDEF = -DHAS_MMAP
+#endif
+
+#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
+
+FBINCLUDE = -I../../fb
+
+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) \
+           $(FBINCLUDE) -I../../mfb -I../../mi -I../../include -I../../os  \
+           -I$(EXTINCSRC) -I$(XINCLUDESRC)  -I$(SERVERSRC)/render $(VNCINCLUDE)
+
+DEFINES = $(OS_DEFINES) $(SHMDEF) $(MMAPDEF) $(FB_DEFINES) \
+          $(VENDOR_STRING) $(VENDOR_RELEASE) $(STD_DEFINES) ServerOSDefines \
+          $(VNCDEFINES) -UXFree86LOADER
+
+#ifdef XFree86Version
+/* 
+ * Make sure XINPUT, XF86VidTune, etc arent defined for the miinitext.o 
+ * used by Xvnc 
+ */
+EXT_DEFINES = ExtensionDefines -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_MODULE_EXTS $(EXT_MODULE_DEFINES) -UXFree86LOADER)
+
+/* InstallManPage(Xvfb,$(MANDIR)) */
+DependTarget()
+
+buildtime.o: $(OBJS) ../LibraryTargetName(vnc) $(VNCLIBS)
diff --git a/unix/xc/programs/Xserver/vnc/Xvnc/buildtime.c b/unix/xc/programs/Xserver/vnc/Xvnc/buildtime.c
new file mode 100644
index 0000000..3f4c369
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/Xvnc/buildtime.c
@@ -0,0 +1,18 @@
+/* Copyright (C) 2002-2005 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/unix/xc/programs/Xserver/vnc/Xvnc/xvnc.cc b/unix/xc/programs/Xserver/vnc/Xvnc/xvnc.cc
new file mode 100644
index 0000000..fcb73e6
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/Xvnc/xvnc.cc
@@ -0,0 +1,1475 @@
+/* Copyright (c) 1993  X Consortium
+   Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+
+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"
+#include "fb.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#define new New
+#include "micmap.h"
+#undef new
+#include <sys/types.h>
+#ifdef HAS_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+#endif /* HAS_MMAP */
+#include <sys/stat.h>
+#include <errno.h>
+#ifndef WIN32
+#include <sys/param.h>
+#endif
+#include <X11/XWDFile.h>
+#ifdef HAS_SHM
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* HAS_SHM */
+#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
+}
+
+#define XVNCVERSION "Free Edition 4.1.1"
+#define XVNCCOPYRIGHT ("Copyright (C) 2002-2005 RealVNC Ltd.\n" \
+                       "See http://www.realvnc.com for information on VNC.\n")
+
+
+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 paddedBytesWidth;
+    int paddedWidth;
+    int height;
+    int depth;
+    int bitsPerPixel;
+    int sizeInBytes;
+    int ncolors;
+    char *pfbMemory;
+    XWDColor *pXWDCmap;
+    XWDFileHeader *pXWDHeader;
+    Pixel blackPixel;
+    Pixel whitePixel;
+    unsigned int lineBias;
+    CloseScreenProcPtr closeScreen;
+
+#ifdef HAS_MMAP
+    int mmap_fd;
+    char mmap_file[MAXPATHLEN];
+#endif
+
+#ifdef HAS_SHM
+    int shmid;
+#endif
+
+    Bool pixelFormatDefined;
+    Bool rgbNotBgr;
+    int redBits, greenBits, blueBits;
+
+} vfbScreenInfo, *vfbScreenInfoPtr;
+
+static int vfbNumScreens;
+static vfbScreenInfo vfbScreens[MAXSCREENS];
+static Bool vfbPixmapDepths[33];
+#ifdef HAS_MMAP
+static char *pfbdir = NULL;
+#endif
+typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
+static fbMemType fbmemtype = NORMAL_MEMORY_FB;
+static char needswap = 0;
+static int lastScreen = -1;
+static Bool Render = TRUE;
+
+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(void)
+{
+    int i;
+    vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
+    for (i = 2; i <= 32; i++)
+	vfbPixmapDepths[i] = FALSE;
+}
+
+static void
+vfbInitializeDefaultScreens(void)
+{
+    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" {
+
+  /* ddxInitGlobals - called by |InitGlobals| from os/util.c in XOrg */
+  void ddxInitGlobals(void)
+  {
+  }
+
+  void ddxGiveUp()
+  {
+    int i;
+
+    /* clean up the framebuffers */
+
+    switch (fbmemtype)
+    {
+#ifdef HAS_MMAP
+    case MMAPPED_FILE_FB: 
+	for (i = 0; i < vfbNumScreens; i++)
+	{
+	    if (-1 == unlink(vfbScreens[i].mmap_file))
+	    {
+		perror("unlink");
+		ErrorF("unlink %s failed, errno %d",
+		       vfbScreens[i].mmap_file, errno);
+	    }
+	}
+	break;
+#else /* HAS_MMAP */
+    case MMAPPED_FILE_FB:
+        break;
+#endif /* HAS_MMAP */
+	
+#ifdef HAS_SHM
+    case SHARED_MEMORY_FB:
+	for (i = 0; i < vfbNumScreens; i++)
+	{
+	    if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
+	    {
+		perror("shmdt");
+		ErrorF("shmdt failed, errno %d", errno);
+	    }
+	}
+	break;
+#else /* HAS_SHM */
+    case SHARED_MEMORY_FB:
+        break;
+#endif /* HAS_SHM */
+	
+    case NORMAL_MEMORY_FB:
+	for (i = 0; i < vfbNumScreens; i++)
+	{
+	    Xfree(vfbScreens[i].pXWDHeader);
+	}
+	break;
+    }
+}
+
+void
+AbortDDX()
+{
+    ddxGiveUp();
+}
+
+#ifdef __DARWIN__
+void
+DarwinHandleGUI(int argc, char *argv[])
+{
+}
+
+void GlxExtensionInit();
+void GlxWrapInitVisuals(void *procPtr);
+
+void
+DarwinGlxExtensionInit()
+{
+    GlxExtensionInit();
+}
+
+void
+DarwinGlxWrapInitVisuals(
+    void *procPtr)
+{
+    GlxWrapInitVisuals(procPtr);
+}
+#endif
+
+void
+OsVendorInit()
+{
+}
+
+void
+OsVendorFatalError()
+{
+}
+
+void ddxBeforeReset(void)
+{
+    return;
+}
+
+void 
+ddxUseMsg()
+{
+    ErrorF("\nXvnc %s - built %s\n%s", XVNCVERSION, buildtime, XVNCCOPYRIGHT);
+    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");
+#ifdef RENDER
+    ErrorF("+/-render		   turn on/off RENDER extension support"
+	   "(default on)\n");
+#endif
+    ErrorF("-linebias n            adjust thin line pixelization\n");
+    ErrorF("-blackpixel n          pixel value for black\n");
+    ErrorF("-whitepixel n          pixel value for white\n");
+
+#ifdef HAS_MMAP
+    ErrorF("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
+#endif
+
+#ifdef HAS_SHM
+    ErrorF("-shmem                 put framebuffers in shared memory\n");
+#endif
+
+    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);
+  }
+}
+
+/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
+void ddxInitGlobals(void)
+{
+}
+
+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], "+render") == 0)	/* +render */
+    {
+	Render = TRUE;
+	return 1;
+    }
+  
+    if (strcmp (argv[i], "-render") == 0)	/* -render */
+    {
+	Render = FALSE;
+	return 1;
+    }
+
+    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;
+    }
+
+#ifdef HAS_MMAP
+    if (strcmp (argv[i], "-fbdir") == 0)	/* -fbdir directory */
+    {
+	if (++i >= argc) UseMsg();
+	pfbdir = argv[i];
+	fbmemtype = MMAPPED_FILE_FB;
+	return 2;
+    }
+#endif /* HAS_MMAP */
+
+#ifdef HAS_SHM
+    if (strcmp (argv[i], "-shmem") == 0)	/* -shmem */
+    {
+	fbmemtype = SHARED_MEMORY_FB;
+	return 1;
+    }
+#endif
+    
+    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 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;
+}
+
+#ifdef HAS_MMAP
+
+/* this flushes any changes to the screens out to the mmapped file */
+static void
+vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+{
+    int i;
+
+    for (i = 0; i < vfbNumScreens; i++)
+    {
+#ifdef MS_ASYNC
+	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
+			(size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
+#else
+	/* silly NetBSD and who else? */
+	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
+			(size_t)vfbScreens[i].sizeInBytes))
+#endif
+	{
+	    perror("msync");
+	    ErrorF("msync failed, errno %d", errno);
+	}
+    }
+}
+
+
+static void
+vfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
+{
+}
+
+
+static void
+vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
+{
+#define DUMMY_BUFFER_SIZE 65536
+    char dummyBuffer[DUMMY_BUFFER_SIZE];
+    int currentFileSize, writeThisTime;
+
+    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum);
+    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
+    {
+	perror("open");
+	ErrorF("open %s failed, errno %d", pvfb->mmap_file, errno);
+	return;
+    }
+
+    /* Extend the file to be the proper size */
+
+    bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
+    for (currentFileSize = 0;
+	 currentFileSize < pvfb->sizeInBytes;
+	 currentFileSize += writeThisTime)
+    {
+	writeThisTime = min(DUMMY_BUFFER_SIZE,
+			    pvfb->sizeInBytes - currentFileSize);
+	if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
+	{
+	    perror("write");
+	    ErrorF("write %s failed, errno %d", pvfb->mmap_file, errno);
+	    return;
+	}
+    }
+
+    /* try to mmap the file */
+
+    pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
+				    PROT_READ|PROT_WRITE,
+				    MAP_FILE|MAP_SHARED,
+				    pvfb->mmap_fd, 0);
+    if (-1 == (long)pvfb->pXWDHeader)
+    {
+	perror("mmap");
+	ErrorF("mmap %s failed, errno %d", pvfb->mmap_file, errno);
+	pvfb->pXWDHeader = NULL;
+	return;
+    }
+
+    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
+					NULL))
+    {
+	pvfb->pXWDHeader = NULL;
+    }
+}
+#endif /* HAS_MMAP */
+
+
+#ifdef HAS_SHM
+static void
+vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
+{
+    /* create the shared memory segment */
+
+    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
+    if (pvfb->shmid < 0)
+    {
+	perror("shmget");
+	ErrorF("shmget %d bytes failed, errno %d", pvfb->sizeInBytes, errno);
+	return;
+    }
+
+    /* try to attach it */
+
+    pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
+    if (-1 == (long)pvfb->pXWDHeader)
+    {
+	perror("shmat");
+	ErrorF("shmat failed, errno %d", errno);
+	pvfb->pXWDHeader = NULL; 
+	return;
+    }
+
+    ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid);
+}
+#endif /* HAS_SHM */
+
+
+static char *
+vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
+{
+    if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
+
+    pvfb->sizeInBytes = pvfb->paddedBytesWidth * 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; 
+    switch (fbmemtype)
+    {
+#ifdef HAS_MMAP
+    case MMAPPED_FILE_FB:  vfbAllocateMmappedFramebuffer(pvfb); break;
+#else
+    case MMAPPED_FILE_FB: break;
+#endif
+
+#ifdef HAS_SHM
+    case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
+#else
+    case SHARED_MEMORY_FB: break;
+#endif
+
+    case NORMAL_MEMORY_FB:
+	pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
+	break;
+    }
+
+    if (pvfb->pXWDHeader)
+    {
+	pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
+				+ SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
+	pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
+
+	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];
+    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->paddedBytesWidth;
+    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 */
+
+    if (-1 == gethostname(hostname, sizeof(hostname)))
+	hostname[0] = 0;
+    else
+	hostname[XWD_WINDOW_NAME_LEN-1] = 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 vfbPointerCursorFuncs = {
+    vfbCursorOffScreen,
+    vfbCrossScreen,
+    miPointerWarpCursor
+};
+
+static Bool
+vfbCloseScreen(int index, ScreenPtr pScreen)
+{
+    vfbScreenInfoPtr pvfb = &vfbScreens[index];
+    int i;
+ 
+    pScreen->CloseScreen = pvfb->closeScreen;
+
+    /*
+     * XXX probably lots of stuff to clean.  For now,
+     * clear InstalledMaps[] so that server reset works correctly.
+     */
+    for (i = 0; i < MAXSCREENS; i++)
+	InstalledMaps[i] = NULL;
+
+    return pScreen->CloseScreen(index, pScreen);
+}
+
+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->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
+    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
+    pvfb->paddedWidth = pvfb->paddedBytesWidth * 8 / pvfb->bitsPerPixel;
+    pbits = vfbAllocateFramebufferMemory(pvfb);
+    if (!pbits) return FALSE;
+    vncFbptr[index] = pbits;
+
+    defaultColorVisualClass
+	= (pvfb->bitsPerPixel > 8) ? TrueColor : PseudoColor;
+
+    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
+		       dpi, dpi, pvfb->paddedWidth, pvfb->bitsPerPixel);
+  
+#ifdef RENDER
+    if (ret && Render) 
+	fbPictureInit (pScreen, 0, 0);
+#endif
+
+    if (!ret) return FALSE;
+
+    /* miInitializeBackingStore(pScreen); */
+
+    /*
+     * Circumvent the backing store that was just initialised.  This amounts
+     * to a truely bizarre way of initialising SaveDoomedAreas and friends.
+     */
+
+    pScreen->InstallColormap = vfbInstallColormap;
+    pScreen->UninstallColormap = vfbUninstallColormap;
+    pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
+
+    pScreen->SaveScreen = vfbSaveScreen;
+    pScreen->StoreColors = vfbStoreColors;
+    
+    miPointerInitialize(pScreen, &vfbPointerSpriteFuncs, &vfbPointerCursorFuncs,
+			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 = pScreen->visuals;
+	for (int i = 0; i < pScreen->numVisuals; i++) {
+	    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;
+	    }
+	    vis++;
+	}
+    }
+    
+    ret = fbCreateDefColormap(pScreen);
+
+    miSetZeroLineBias(pScreen, pvfb->lineBias);
+
+    pvfb->closeScreen = pScreen->CloseScreen;
+    pScreen->CloseScreen = vfbCloseScreen;
+
+#ifndef NO_INIT_BACKING_STORE
+  miInitializeBackingStore(pScreen);
+  pScreen->backingStoreSupport = Always;
+#endif
+
+  return ret;
+
+} /* end vfbScreenInit */
+
+
+static void vfbClientStateChange(CallbackListPtr*, pointer, pointer) {
+  dispatchException &= ~DE_RESET;
+}
+
+void
+InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
+{
+  ErrorF("\nXvnc %s - built %s\n%s", XVNCVERSION, buildtime, XVNCCOPYRIGHT);
+  ErrorF("Underlying X server release %d, %s\n\n", VENDOR_RELEASE,
+         VENDOR_STRING);
+    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;
+    }
+
+    /* RENDER needs a good set of pixmaps. */
+    if (Render) {
+	vfbPixmapDepths[1] = TRUE;
+	vfbPixmapDepths[4] = TRUE;
+	vfbPixmapDepths[8] = TRUE;
+/*	vfbPixmapDepths[15] = TRUE; */
+	vfbPixmapDepths[16] = TRUE;
+	vfbPixmapDepths[24] = TRUE;
+	vfbPixmapDepths[32] = 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/unix/xc/programs/Xserver/vnc/module/Imakefile b/unix/xc/programs/Xserver/vnc/module/Imakefile
new file mode 100644
index 0000000..f279649
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/module/Imakefile
@@ -0,0 +1,60 @@
+
+       VNCTOP = $(TOP)/..
+      VNCLIBS = VncExtLibs
+   VNCINCLUDE = -I$(VNCTOP) -I$(VNCTOP)/vncconfig_unix
+
+#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) \
+           -I../../render $(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)
+*/
+
+/* *** The imake rules don't define a ModuleCplusplusObjectRule so
+       for now we just assume that NormalCplusplusObjectRule will
+       do the job.
+   NB: If we don't do this then make will assume CC is the C++ compiler!
+*/
+NormalCplusplusObjectRule()
+
+/*
+ * 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/unix/xc/programs/Xserver/vnc/vncExtInit.cc b/unix/xc/programs/Xserver/vnc/vncExtInit.cc
new file mode 100644
index 0000000..9cf9d21
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/vncExtInit.cc
@@ -0,0 +1,866 @@
+/* Copyright (C) 2002-2005 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 XserverDesktop* queryConnectDesktop = 0;
+static void* queryConnectId = 0;
+static int queryConnectTimeout = 0;
+static OsTimerPtr queryConnectTimer = 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::AliasParameter rfbauth("rfbauth", "Alias for PasswordFile",
+                            &SSecurityFactoryStandard::vncAuthPasswdFile);
+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 CARD32 queryConnectTimerCallback(OsTimerPtr timer,
+                                        CARD32 now, pointer arg)
+{
+  if (queryConnectTimeout)
+    queryConnectDesktop->approveConnection(queryConnectId, false, "The attempt to prompt the user to accept the connection failed");
+  // Re-notify clients, causing them to discover that we're done
+  vncQueryConnect(queryConnectDesktop, queryConnectId);
+  return 0;
+}
+
+void vncQueryConnect(XserverDesktop* desktop, void* opaqueId)
+{
+  // Only one query can be processed at any one time
+  if (queryConnectTimeout && ((desktop != queryConnectDesktop) ||
+                              (opaqueId != queryConnectId))) {
+    desktop->approveConnection(opaqueId, false,
+                               "Another connection is currently being queried.");
+    return;
+  }
+
+  // Get the query timeout.  If it's zero, there is no query.
+  queryConnectTimeout = desktop->getQueryTimeout(opaqueId);
+  queryConnectId = queryConnectTimeout ? opaqueId : 0;
+  queryConnectDesktop = queryConnectTimeout ? desktop : 0;
+
+  // Notify clients
+  bool notified = false;
+  xVncExtQueryConnectNotifyEvent ev;
+  ev.type = vncEventBase + VncExtQueryConnectNotify;
+  for (VncInputSelect* cur = vncInputSelectHead; cur; cur = cur->next) {
+    if (cur->mask & VncExtQueryConnectMask) {
+      ev.sequenceNumber = cur->client->sequence;
+      ev.window = cur->window;
+      if (cur->client->swapped) {
+        int n;
+        swaps(&ev.sequenceNumber, n);
+        swapl(&ev.window, n);
+      }
+      WriteToClient(cur->client, sizeof(xVncExtQueryConnectNotifyEvent),
+                    (char *)&ev);
+      notified = true;
+    }
+  }
+
+  // If we're being asked to query a connection (rather than to cancel
+  //   a query), and haven't been able to notify clients then reject it.
+  if (queryConnectTimeout && !notified) {
+    queryConnectTimeout = 0;
+    queryConnectId = 0;
+    queryConnectDesktop = 0;
+    desktop->approveConnection(opaqueId, false,
+                               "Unable to query the local user to accept the connection.");
+    return;
+  }    
+
+  // Set a timer so that if no-one ever responds, we will eventually 
+  //   reject the connection
+  //   NB: We don't set a timer if sock is null, since that indicates
+  //       that pending queries should be cancelled.
+  if (queryConnectDesktop)
+    queryConnectTimer = TimerSet(queryConnectTimer, 0,
+                                 queryConnectTimeout*2000,
+                                 queryConnectTimerCallback, 0);
+  else
+    TimerCancel(queryConnectTimer);
+}
+
+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;
+  for (ParameterIterator i(Configuration::global()); i.param; i.next()) {
+    int l = strlen(i.param->getName());
+    if (l <= 255) {
+      nParams++;
+      len += l + 1;
+    }
+  }
+  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;
+  for (ParameterIterator i(Configuration::global()); i.param; i.next()) {
+    int l = strlen(i.param->getName());
+    if (l <= 255) {
+      *ptr++ = l;
+      memcpy(ptr, i.param->getName(), l);
+      ptr += l;
+    }
+  }
+  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 ProcVncExtGetQueryConnect(ClientPtr client)
+{
+  REQUEST(xVncExtGetQueryConnectReq);
+  REQUEST_SIZE_MATCH(xVncExtGetQueryConnectReq);
+
+  const char *qcAddress=0, *qcUsername=0;
+  int qcTimeout;
+  if (queryConnectDesktop)
+    qcTimeout = queryConnectDesktop->getQueryTimeout(queryConnectId,
+                                                     &qcAddress, &qcUsername);
+  else
+    qcTimeout = 0;
+
+  xVncExtGetQueryConnectReply rep;
+  int n;
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.timeout = qcTimeout;
+  rep.addrLen = qcTimeout ? strlen(qcAddress) : 0;
+  rep.userLen = qcTimeout ? strlen(qcUsername) : 0;
+  rep.opaqueId = (CARD32)queryConnectId;
+  rep.length = (rep.userLen + rep.addrLen + 3) >> 2;
+  if (client->swapped) {
+    swaps(&rep.sequenceNumber, n);
+    swapl(&rep.userLen, n);
+    swapl(&rep.addrLen, n);
+    swapl(&rep.timeout, n);
+    swapl(&rep.opaqueId, n);
+  }
+  WriteToClient(client, sizeof(xVncExtGetQueryConnectReply), (char *)&rep);
+  if (qcTimeout)
+    WriteToClient(client, strlen(qcAddress), (char*)qcAddress);
+  if (qcTimeout)
+    WriteToClient(client, strlen(qcUsername), (char*)qcUsername);
+  return (client->noClientException);
+}
+
+static int SProcVncExtGetQueryConnect(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtGetQueryConnectReq);
+  swaps(&stuff->length, n);
+  REQUEST_SIZE_MATCH(xVncExtGetQueryConnectReq);
+  return ProcVncExtGetQueryConnect(client);
+}
+
+
+static int ProcVncExtApproveConnect(ClientPtr client)
+{
+  REQUEST(xVncExtApproveConnectReq);
+  REQUEST_SIZE_MATCH(xVncExtApproveConnectReq);
+  if (queryConnectId == (void*)stuff->opaqueId) {
+    for (int scr = 0; scr < screenInfo.numScreens; scr++) {
+      if (desktop[scr]) {
+        desktop[scr]->approveConnection(queryConnectId, stuff->approve,
+                                        "Connection rejected by local user");
+      }
+    }
+    // Inform other clients of the event and tidy up
+    vncQueryConnect(queryConnectDesktop, queryConnectId);
+  }
+  return (client->noClientException);
+}
+
+static int SProcVncExtApproveConnect(ClientPtr client)
+{
+  register char n;
+  REQUEST(xVncExtApproveConnectReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->opaqueId, n);
+  REQUEST_SIZE_MATCH(xVncExtApproveConnectReq);
+  return ProcVncExtApproveConnect(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);
+  case X_VncExtGetQueryConnect:
+    return ProcVncExtGetQueryConnect(client);
+  case X_VncExtApproveConnect:
+    return ProcVncExtApproveConnect(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);
+  case X_VncExtGetQueryConnect:
+    return SProcVncExtGetQueryConnect(client);
+  case X_VncExtApproveConnect:
+    return SProcVncExtApproveConnect(client);
+  default:
+    return BadRequest;
+  }
+}
+
diff --git a/unix/xc/programs/Xserver/vnc/vncExtInit.h b/unix/xc/programs/Xserver/vnc/vncExtInit.h
new file mode 100644
index 0000000..45453e1
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/vncExtInit.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002-2005 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>
+#include "XserverDesktop.h"
+
+extern void vncClientCutText(const char* str, int len);
+extern void vncQueryConnect(XserverDesktop* desktop, void* opaqueId);
+extern void vncClientGone(int fd);
+extern void vncBell();
+extern void* vncFbptr[];
+extern int vncInetdSock;
+extern rfb::StringParameter httpDir;
+
+#endif
diff --git a/unix/xc/programs/Xserver/vnc/vncHooks.cc b/unix/xc/programs/Xserver/vnc/vncHooks.cc
new file mode 100644
index 0000000..ce8e7f0
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/vncHooks.cc
@@ -0,0 +1,1533 @@
+/* Copyright (C) 2002-2005 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 RENDER
+#include "picturestr.h"
+#endif
+
+#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;
+#ifdef RENDER
+  CompositeProcPtr             Composite;
+#endif
+} 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);
+#ifdef RENDER
+static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, 
+			      PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, 
+			      INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+#endif
+
+// 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;
+#ifdef RENDER
+  PictureScreenPtr ps;
+  ps = GetPictureScreenIfSet(pScreen);
+  if (ps) {
+    vncHooksScreen->Composite = ps->Composite;
+  }
+#endif
+
+  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;
+#ifdef RENDER
+  if (ps) {
+    ps->Composite = vncHooksComposite;
+  }
+#endif
+
+  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);
+}
+
+// Composite - needed for RENDER
+
+#ifdef RENDER
+void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, 
+		       PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, 
+		       INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
+{
+  ScreenPtr pScreen = pDst->pDrawable->pScreen;
+  vncHooksScreenPtr vncHooksScreen = ((vncHooksScreenPtr)pScreen->devPrivates[vncHooksScreenIndex].ptr); 
+  BoxRec box;
+  PictureScreenPtr ps = GetPictureScreen(pScreen);
+  rfb::Rect rect1, rect2;
+
+  rect1.setXYWH(pDst->pDrawable->x + xDst,
+		pDst->pDrawable->y + yDst,
+		width,
+		height);
+      
+  rect2 = rect1.intersect(vncHooksScreen->desktop->getRect());
+  if (!rect2.is_empty()) {
+    box.x1 = rect2.tl.x;
+    box.y1 = rect2.tl.y;
+    box.x2 = rect2.br.x;
+    box.y2 = rect2.br.y;
+    RegionHelper changed(pScreen, &box, 0);
+    vncHooksScreen->desktop->add_changed(changed.reg);
+  }
+
+  ps->Composite = vncHooksScreen->Composite;
+  (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
+		   xMask, yMask, xDst, yDst, width, height);
+  ps->Composite = vncHooksComposite;
+}
+
+#endif /* RENDER */
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 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 = __rfbmax(FONTASCENT(font), FONTMAXBOUNDS(font, ascent));
+  int descent = __rfbmax(FONTDESCENT(font), FONTMAXBOUNDS(font, descent));
+  int charWidth = __rfbmax(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/unix/xc/programs/Xserver/vnc/vncHooks.h b/unix/xc/programs/Xserver/vnc/vncHooks.h
new file mode 100644
index 0000000..c556ef3
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/vncHooks.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2002-2005 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/unix/xc/programs/Xserver/vnc/xf86vncModule.cc b/unix/xc/programs/Xserver/vnc/xf86vncModule.cc
new file mode 100644
index 0000000..ef8ea50
--- /dev/null
+++ b/unix/xc/programs/Xserver/vnc/xf86vncModule.cc
@@ -0,0 +1,97 @@
+/* Copyright (C) 2002-2005 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
+
+using namespace rfb;
+
+extern void vncExtensionInit();
+static void vncExtensionInitWithParams(INITARGS);
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(vncSetup);
+
+ExtensionModule vncExt =
+{
+    vncExtensionInitWithParams,
+    "VNC",
+    NULL,
+    NULL,
+    NULL
+};
+
+static XF86ModuleVersionInfo vncVersRec =
+{
+    "vnc",
+    "Constantin Kaplinsky",
+    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];
+
+    for (ParameterIterator i(Configuration::global()); i.param; i.next()) {
+      char* val = xf86FindOptionValue(pScrn->options, i.param->getName());
+      if (val)
+        i.param->setParam(val);
+    }
+  }
+
+  vncExtensionInit();
+}
+
+#endif /* XFree86LOADER */
+}
