[X2Go-Commits] [nx-libs] 01/52: nx-X11 vs. X.Org 6.9 patches for further studying / documentation

git-admin at x2go.org git-admin at x2go.org
Sat Feb 14 17:47:00 CET 2015


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch 3.6.x
in repository nx-libs.

commit 1e5ee575d4912665dd2356681f0827d5229fa1f5
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Fri Feb 13 14:14:26 2015 +0100

    nx-X11 vs. X.Org 6.9 patches for further studying / documentation
    
      NoMachine kept all original X.Org 6.9 files in the nx-X11 source
      tree. These files have been removed in Feb 2015 during a major
      code cleanup.
    
      For later studying we provide all diffs of the changes that
      NoMachine employed on the original X.Org X11 code tree in the
      doc/nx-X11_vs_XOrg69_patches folder.
---
 doc/nx-X11_vs_XOrg69_patches/AuRead.c.NX.patch     |   62 +
 doc/nx-X11_vs_XOrg69_patches/CHANGELOG.NX.patch    | 1088 ++++++++
 doc/nx-X11_vs_XOrg69_patches/ChkIfEv.c.NX.patch    |   59 +
 doc/nx-X11_vs_XOrg69_patches/ConnDis.c.NX.patch    |  319 +++
 doc/nx-X11_vs_XOrg69_patches/Glyph.c.NX.patch      |  547 ++++
 doc/nx-X11_vs_XOrg69_patches/IfEvent.c.NX.patch    |   13 +
 doc/nx-X11_vs_XOrg69_patches/Imakefile.NX.patch    |   11 +
 doc/nx-X11_vs_XOrg69_patches/MaskEvent.c.NX.patch  |   13 +
 doc/nx-X11_vs_XOrg69_patches/NXdamage.c.NX.patch   |  138 +
 doc/nx-X11_vs_XOrg69_patches/NXdispatch.c.NX.patch | 1036 ++++++++
 doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch |  892 +++++++
 doc/nx-X11_vs_XOrg69_patches/NXevents.c.NX.patch   |  648 +++++
 .../NXextension.c.NX.patch                         |   70 +
 doc/nx-X11_vs_XOrg69_patches/NXglxext.c.NX.patch   |  118 +
 doc/nx-X11_vs_XOrg69_patches/NXglyph.c.NX.patch    |  160 ++
 .../NXglyphcurs.c.NX.patch                         |  121 +
 doc/nx-X11_vs_XOrg69_patches/NXglyphstr.h.NX.patch |   59 +
 doc/nx-X11_vs_XOrg69_patches/NXmiexpose.c.NX.patch |  116 +
 doc/nx-X11_vs_XOrg69_patches/NXmiglyph.c.NX.patch  |  156 ++
 doc/nx-X11_vs_XOrg69_patches/NXmitrap.c.NX.patch   |   65 +
 doc/nx-X11_vs_XOrg69_patches/NXmiwindow.c.NX.patch |   53 +
 doc/nx-X11_vs_XOrg69_patches/NXpicture.c.NX.patch  |  615 +++++
 .../NXpicturestr.h.NX.patch                        |   42 +
 doc/nx-X11_vs_XOrg69_patches/NXproperty.c.NX.patch |  358 +++
 doc/nx-X11_vs_XOrg69_patches/NXrender.c.NX.patch   |  948 +++++++
 doc/nx-X11_vs_XOrg69_patches/NXresource.c.NX.patch |  426 +++
 doc/nx-X11_vs_XOrg69_patches/NXshm.c.NX.patch      |  373 +++
 doc/nx-X11_vs_XOrg69_patches/NXwindow.c.NX.patch   |  561 ++++
 doc/nx-X11_vs_XOrg69_patches/NXxvdisp.c.NX.patch   |  266 ++
 doc/nx-X11_vs_XOrg69_patches/NextEvent.c.NX.patch  |   42 +
 doc/nx-X11_vs_XOrg69_patches/OpenDis.c.NX.patch    |   96 +
 doc/nx-X11_vs_XOrg69_patches/PeekIfEv.c.NX.patch   |   14 +
 doc/nx-X11_vs_XOrg69_patches/Pending.c.NX.patch    |   30 +
 doc/nx-X11_vs_XOrg69_patches/WaitFor.c.NX.patch    |  271 ++
 doc/nx-X11_vs_XOrg69_patches/XKBMAlloc.c.NX.patch  |   84 +
 doc/nx-X11_vs_XOrg69_patches/XKBsrv.h.NX.patch     |   14 +
 doc/nx-X11_vs_XOrg69_patches/Xlib.h.NX.patch       |   30 +
 doc/nx-X11_vs_XOrg69_patches/XlibAsync.c.NX.patch  |   41 +
 doc/nx-X11_vs_XOrg69_patches/XlibInt.c.NX.patch    | 1165 +++++++++
 doc/nx-X11_vs_XOrg69_patches/Xlibint.h.NX.patch    |   59 +
 doc/nx-X11_vs_XOrg69_patches/Xpoll.h.in.NX.patch   |   67 +
 doc/nx-X11_vs_XOrg69_patches/Xrender.h.NX.patch    |   39 +
 doc/nx-X11_vs_XOrg69_patches/Xtranssock.c.NX.patch | 1133 ++++++++
 doc/nx-X11_vs_XOrg69_patches/auth.c.NX.patch       |  271 ++
 doc/nx-X11_vs_XOrg69_patches/charproc.c.NX.patch   |   40 +
 doc/nx-X11_vs_XOrg69_patches/cmsProp.c.NX.patch    |   14 +
 doc/nx-X11_vs_XOrg69_patches/connection.c.NX.patch |   48 +
 doc/nx-X11_vs_XOrg69_patches/context.c.NX.patch    |  103 +
 doc/nx-X11_vs_XOrg69_patches/cross.def.NX.patch    |   33 +
 doc/nx-X11_vs_XOrg69_patches/cursor.c.NX.patch     |   12 +
 doc/nx-X11_vs_XOrg69_patches/ddxKillSrv.c.NX.patch |   21 +
 doc/nx-X11_vs_XOrg69_patches/ddxLoad.c.NX.patch    |  443 ++++
 doc/nx-X11_vs_XOrg69_patches/dixfonts.c.NX.patch   |   86 +
 doc/nx-X11_vs_XOrg69_patches/dixstruct.h.NX.patch  |   12 +
 doc/nx-X11_vs_XOrg69_patches/encparse.c.NX.patch   |   22 +
 doc/nx-X11_vs_XOrg69_patches/fbtrap.c.NX.patch     |   12 +
 .../glcontextmodes.c.NX.patch                      |   10 +
 doc/nx-X11_vs_XOrg69_patches/host.def.NX.patch     | 1023 ++++++++
 doc/nx-X11_vs_XOrg69_patches/iPAQH3600.cf.NX.patch |  112 +
 doc/nx-X11_vs_XOrg69_patches/log.c.NX.patch        |  136 +
 doc/nx-X11_vs_XOrg69_patches/main.c.NX.patch       |   42 +
 doc/nx-X11_vs_XOrg69_patches/oscolor.c.NX.patch    |  214 ++
 .../panoramiXproto.h.NX.patch                      |  195 ++
 doc/nx-X11_vs_XOrg69_patches/pixmap.c.NX.patch     |   18 +
 doc/nx-X11_vs_XOrg69_patches/randr.NX.patch        | 2704 ++++++++++++++++++++
 doc/nx-X11_vs_XOrg69_patches/randr.c.NX.patch      |   72 +
 doc/nx-X11_vs_XOrg69_patches/randr.h.NX.patch      |  144 ++
 doc/nx-X11_vs_XOrg69_patches/randrproto.h.NX.patch |  658 +++++
 doc/nx-X11_vs_XOrg69_patches/registry.h.NX.patch   |   67 +
 doc/nx-X11_vs_XOrg69_patches/render2.c.NX.patch    |   11 +
 .../render2swap.c.NX.patch                         |   11 +
 doc/nx-X11_vs_XOrg69_patches/renderedge.c.NX.patch |   10 +
 doc/nx-X11_vs_XOrg69_patches/rrcrtc.c.NX.patch     |   48 +
 doc/nx-X11_vs_XOrg69_patches/rrdispatch.c.NX.patch |   15 +
 doc/nx-X11_vs_XOrg69_patches/rrmode.c.NX.patch     |   39 +
 doc/nx-X11_vs_XOrg69_patches/rrscreen.c.NX.patch   |  107 +
 doc/nx-X11_vs_XOrg69_patches/rrxinerama.c.NX.patch |   72 +
 doc/nx-X11_vs_XOrg69_patches/security.c.NX.patch   |  315 +++
 doc/nx-X11_vs_XOrg69_patches/select.c.NX.patch     |   13 +
 doc/nx-X11_vs_XOrg69_patches/sun.cf.NX.patch       |   50 +
 doc/nx-X11_vs_XOrg69_patches/sunLib.tmpl.NX.patch  |  122 +
 doc/nx-X11_vs_XOrg69_patches/svr4.cf.NX.patch      |   24 +
 doc/nx-X11_vs_XOrg69_patches/utils.c.NX.patch      |  250 ++
 doc/nx-X11_vs_XOrg69_patches/xdmcp.c.NX.patch      |   59 +
 doc/nx-X11_vs_XOrg69_patches/xf86glx.c.NX.patch    |   70 +
 doc/nx-X11_vs_XOrg69_patches/xkbDflts.h.NX.patch   |   24 +
 doc/nx-X11_vs_XOrg69_patches/xprintf.c.NX.patch    |   75 +
 87 files changed, 20245 insertions(+)

diff --git a/doc/nx-X11_vs_XOrg69_patches/AuRead.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/AuRead.c.NX.patch
new file mode 100644
index 0000000..940a3fe
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/AuRead.c.NX.patch
@@ -0,0 +1,62 @@
+--- ./nx-X11/lib/Xau/AuRead.c.X.original	2015-02-13 14:03:44.624443872 +0100
++++ ./nx-X11/lib/Xau/AuRead.c	2015-02-10 19:13:12.488735202 +0100
+@@ -32,14 +32,29 @@
+ #endif
+ #include <X11/Xauth.h>
+ #include <stdlib.h>
++#include <errno.h>
+ 
+ static int
+ read_short (unsigned short *shortp, FILE *file)
+ {
+     unsigned char   file_short[2];
+ 
+-    if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
+-	return 0;
++    /*
++     * Added a check on EINTR to prevent the fread() call to be
++     * interrupted by any signal not blocked by OsBlockSignals().
++     */
++
++    for (;;) {
++        if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1) {
++            if (errno == EINTR && ferror (file)) {
++                perror ("Reading from auth file");
++                clearerr (file);
++                continue;
++            }
++            return 0;
++        }
++        break;
++    }
+     *shortp = file_short[0] * 256 + file_short[1];
+     return 1;
+ }
+@@ -58,11 +73,22 @@
+     	data = malloc ((unsigned) len);
+     	if (!data)
+ 	    return 0;
+-    	if (fread (data, (int) sizeof (char), (int) len, file) != len) {
+-	    bzero (data, len);
+-	    free (data);
+-	    return 0;
+-    	}
++        for (;;)
++        {
++            if (fread (data, (int) sizeof (char), (int) len, file) != len)
++            {
++                if (errno == EINTR && ferror (file))
++                {
++                    perror ("Reading from auth file");
++                    clearerr (file);
++                    continue;
++                }
++	        bzero (data, len);
++	        free (data);
++	        return 0;
++    	    }
++            break;
++        }
+     }
+     *stringp = data;
+     *countp = len;
diff --git a/doc/nx-X11_vs_XOrg69_patches/CHANGELOG.NX.patch b/doc/nx-X11_vs_XOrg69_patches/CHANGELOG.NX.patch
new file mode 100644
index 0000000..085401d
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/CHANGELOG.NX.patch
@@ -0,0 +1,1088 @@
+--- ./nx-X11/CHANGELOG.X.original	2015-02-13 14:03:44.392448449 +0100
++++ ./nx-X11/CHANGELOG	2015-02-10 19:13:14.668653602 +0100
+@@ -0,0 +1,1085 @@
++ChangeLog:
++
++nx-X11-3.5.0-2
++
++- Fixed TR0202420. XKB utility functions wrote out of bounds.
++
++- Upgraded RandR server extension to version 1.2.
++
++nx-X11-3.5.0-1
++
++- Opened the 3.5.0 branch based on nx-X11-3.4.0-4.
++
++- Updated copyright to year 2011.
++
++nx-X11-3.4.0-4
++
++- Fixed TR06H02359. Removed compiler warnings.
++
++nx-X11-3.4.0-3
++
++- Updated copyright to year 2010.
++
++nx-X11-3.4.0-2
++
++- Fixed TR04G02208. Added a path to rgb file.
++
++nx-X11-3.4.0-1
++
++- Opened the 3.4.0 branch based on nx-X11-3.3.0-7.
++
++- Updated copyright to year 2009.
++
++nx-X11-3.3.0-7
++
++- Fixed TR08G02257. The maximum client condition was reached because
++  available fd exhausted. This bug was caused by a function in font
++  library not closing the file before a return on error breaking the
++  flow of normal execution.
++
++- Fixed TR06G02225. The implementation of Xvprintf() has been reviewed
++  to work on more platforms. Previous implementation caused a failure
++  in the build of keyboard map on some platform like Solaris 8 and 9.
++
++nx-X11-3.3.0-6
++
++- Fixed TR03G02198. Reimplemented Xvprintf() in Xserver/os to handle
++  the case in which vsnprintf returned -1.
++
++- Returning from _XSeqSyncFunction() and _XReply() if an I/O error is
++  detected.
++
++nx-X11-3.3.0-5
++
++- Fixed TR01G02163. Signals need to be blocked before the call to
++  fork() in the Popen() utility.
++ 
++- Fixed TR01G02164. Trapezoid data need to be validated before use.
++  This issue was the same of CVE-2007-2437.
++
++nx-X11-3.3.0-4
++
++- Enabled the code resetting the Xlib buffer if an IO error occured.
++
++nx-X11-3.3.0-3
++
++- Fixed the search path for the XKB base directory.
++
++nx-X11-3.3.0-2
++
++- Fixed TR10F02116. The X11 agent could enter an indefinite wait state
++  if connection to X display is broken and libX11 output buffer is not
++  empty.
++
++nx-X11-3.3.0-1
++
++- Opened the 3.3.0 branch based on nx-X11-3.2.0-2.
++
++nx-X11-3.2.0-2
++
++- Imported patch fixing issues from  X.Org security advisory, June
++  11th, 2008: Multiple vulnerabilities in X server extensions. CVE
++  IDs: CVE-2008-1377, CVE-2008-1379, CVE-2008-2360, CVE-2008-2361,
++  CVE-2008-2362.
++
++nx-X11-3.2.0-1
++
++- Opened the 3.2.0 branch based on nx-X11-3.1.0-6.
++
++nx-X11-3.1.0-6
++
++- Modified Xserver Imakefile to link the Xfixes library.
++
++nx-X11-3.1.0-5
++
++- Disabled the terminate action, just in case the TerminateServer
++  symbol is binded to a non default key sequence.
++
++nx-X11-3.1.0-4
++
++- Imported patch fixing issues from  X.Org security advisory, January
++  17th, 2008: Multiple vulnerabilities in the X server.  CVE IDs:
++  CVE-2007-5760    CVE-2007-5958    CVE-2007-6427   CVE-2007-6428
++  CVE-2007-6429    CVE-2008-0006.
++
++nx-X11-3.1.0-3
++
++- Moved a variable definition placed in _mesa_make_current().
++
++nx-X11-3.1.0-2
++
++- Fixed TR10E01924. A crash could occur in _mesa_make_current().
++
++- Initialized after_ret variable in _XcmsGetProperty().
++
++nx-X11-3.1.0-1
++
++- Opened the 3.1.0 branch based on nx-X11-3.0.0-37.
++
++nx-X11-3.0.0-37
++
++- Changed the Xserver Imakefile to link against Xcomposite on the
++  Cygwin platform too.
++
++nx-X11-3.0.0-36
++
++- Fixed TR07E01806. Modified host.def to build GLX code with symbol
++  __GLX_ALIGN64 defined on Solaris platform.
++
++nx-X11-3.0.0-35
++
++- Flush explicitly the NX link before entering the select() in the
++  WaitForReadable() and WaitForWritable() routines.
++
++nx-X11-3.0.0-34
++
++- Changed the agent Imakefile to link to the Xcomposite library.
++
++nx-X11-3.0.0-33
++
++- Fix the NX_TRANS_WAKEUP stuff in WaitForSomething() to not over-
++  ride a valid timeout.
++
++- Check if the requesting client is gone in the XFixes functions
++  sending the cursor events.
++
++nx-X11-3.0.0-32
++
++- Define DDXOSVERRORF and DDXOSFATALERROR symbols on Sun.
++
++- Changed the copyright attribution from Medialogic to NoMachine.
++
++nx-X11-3.0.0-31
++
++- Make SmartScheduleStopTimer() visible outside Xserver/os/utils.c
++  so that it can be called by the agent. Export the declaration in
++  dixstruct.h. 
++
++nx-X11-3.0.0-30
++
++- The OsVendorVErrorFFatal flag is set to 1 if the function pointed
++  by OsVendorVErrorFProc is called due to a fatal error.
++
++- Give the possibility to the agent to redirect the standard error
++  during a Popen() or a System() by setting the OsVendorStartRedir-
++  ectErrorFProc and OsVendorEndRedirectErrorFProc function pointers.
++
++nx-X11-3.0.0-29
++
++- Changed the default message printed on a fatal server error. The
++  new message is:
++
++  Error: Aborting session with 'Error text...'.
++
++- Hacked LogVWrite() to force all fatal error messages to have an
++  uppercase initial. Also remove the trailing newline and the full-
++  stop, if present.
++
++nx-X11-3.0.0-28
++
++- Corrected the typos in the ChangeLog.
++
++nx-X11-3.0.0-27
++
++- Fixed the cleanup of the X_RenderCompositeText16 padding bytes.
++
++- More code cleanup in the NX changes to the Xrender library.
++
++- Changed host.def to build the freetype and fontconfig libraries
++  if the agent server is also built. Freetype is built as a shared
++  library: this avoids the link error on 64 bit platforms.
++
++nx-X11-3.0.0-26
++
++- Applied the following security patches, from the X.Org security
++  advisory, April 3rd, 2007 "Multiple vulnerability in X server,
++  libXfont and libX11":
++
++  xorg-xserver-1.2.0-xcmisc.diff
++  xorg-libXfont-1.2.7-bdf-fontdir.diff
++  xorg-libX11-1.1.1-xinitimage.diff
++
++nx-X11-3.0.0-25
++
++- Added the missing *.X.original file for ChkIfEv.c and Xlib.h.
++
++nx-X11-3.0.0-24
++
++- Changed Xrender to clean up the padding bytes in XRenderComposite-
++  Text functions.
++
++- Added function XRenderCleanGlyphs() cleaning the padding bytes in
++  the data section of RenderAddGlyphs requests.
++
++nx-X11-3.0.0-23
++
++- Removed the additional parameter from the call to NXTransFlush()
++  in _XReply().
++
++- Call NXTransExit() on AbortServer() (called by FatalError()) to
++  give the proxy a chance to shut down the NX transport.
++
++nx-X11-3.0.0-22
++
++- Moved the replacement of XCheckIfEvent() ChkIfEv.c with the name
++  XCheckIfEventNoFlush().
++
++nx-X11-3.0.0-21
++
++- Set BUFSIZE to 8192 bytes. While the output buffer size can be
++  configured by setting the XLIBBUFFERSIZE in the environment (see
++  OpenDis.c), this constant is still used when reading from the
++  socket.
++
++nx-X11-3.0.0-20
++
++- If set, the handler pointed by _NXDisplayWriteFunction is called
++  after that more data is written to the display connection.
++
++nx-X11-3.0.0-19
++
++- Added a RejectWellKnownSockets() stub to make possible to compile
++  the agent when the NX transport is disabled.
++
++- Added more useful logs to _XWaitForWritable().
++
++nx-X11-3.0.0-18
++
++- Changed Imakefile of X11 and Xserver in order to build nxcompshad
++  just before the NX agent server.
++
++- Changed Imakefile in Xserver to add NXdamage.o to NXAGENTOBJS.
++
++nx-X11-3.0.0-17
++
++- Changed host.def in order to build Xdamage and Xrandr libraries.
++
++- Changed host.def in order not to build NXWin.
++
++nx-X11-3.0.0-16
++
++- Changed host.def in order to build Xtst as a shared library.
++
++nx-X11-3.0.0-15
++
++- Changes to comply with nxcompshad library.
++
++- Changed configuration to statically build Xtst library.
++
++- Restored parser directory under Xserver/hw/xfree86.
++
++nx-X11-3.0.0-14
++
++- Changed the LICENSE file to state that the software is only made
++  available under the version 2 of the GPL.
++
++- Added file COPYING.
++
++- In nx-X11/programs and nx-X11/programs/Xserver/hw/xfree86, removed
++  files and directories not needed to build servers.
++
++nx-X11-3.0.0-13
++
++- Changes aimed to link servers with static versions of Xdmcp and Xau
++  libraries.
++
++nx-X11-3.0.0-12
++
++- Added references to implented FR in the ChangeLog.
++
++- Removed nx-X11/fonts and nx-X11/doc directories. They are not needed
++  for building the NX components.
++
++nx-X11-3.0.0-11
++
++- Updated the copyright notices to year 2007.
++
++nx-X11-3.0.0-10
++
++- Applied the following security patches:
++
++   x11r6.9.0-cidfonts.diff 
++   x11r6.9.0-dbe-render.diff
++   x11r6.9.0-geteuid.diff
++   x11r6.9.0-mitri.diff
++   x11r6.9.0-setuid.diff
++
++nx-X11-3.0.0-9
++
++- Merged the NX changes to X11 with the X11R6.9.0 version of X.org.
++
++nx-X11-3.0.0-8
++
++- Changes to build Xshadow library when building X11.
++
++- Changes to Xserver Imakefile to link Xshadow library.
++
++- Changes to host.def in order to build on old distributions.
++
++nx-X11-3.0.0-7
++
++- Imported changes up to nx-X11-2.1.0-2
++
++- Fixed TR08D01485. Updated rgb file paths validation in order to
++  support Ubuntu distribution.
++
++- Added Xtst to libraries to be linked by nxagent.
++
++- Changed Xpm Imakefile to build a shared library on Solaris.
++
++- Fixed build error on Solaris in xtrans.
++
++- Changed host.def not to build Xnest server.
++
++- Changed Xserver Imakefile to link nxaccess library.
++
++nx-X11-3.0.0-6
++
++- Added the path of nxaccess library to the server link command.
++
++nx-X11-3.0.0-5
++
++- Implemented FR10C01079 and FR10C01080. The merge of NX changes to
++  the X.org code is complete.
++
++- Merged changes in config/cf. The NX-*.def files have been dismissed.
++  Main platform dependent configurations have been moved to host.def.
++
++- Removed *.reference files from config/cf.
++
++- Fixed compilation for Cygwin platform.
++
++nx-X11-3.0.0-4
++
++- Imported all changes up to nx-X11-2.0.0-32.
++
++- Cleaned up lib/zlib directory.
++
++- Added missing file programs/Xserver/os/utils.c.NX.original.
++
++- Updated the copyright notice to year 2006.
++
++- The pointer to the display buffer is reset after an I/O error.
++  This prevents leaving the buffer in an inconsistent state if the
++  error occurs inside _XFlush().
++
++- Removed the modifications to the Xrender library. The cleanup of
++  the padding bytes is now performed by the NX transport.
++
++- NX uses the updated ZLIB from its build tree, so Imake.tmpl will
++  now assume that the platform as ZLIB unless otherwise stated.
++
++- The path of the SecurityPolicy file is searched and validated at
++  runtime.
++
++- Added the _X11TransSocketProxyConnInfo() function to Xtranssock.c
++  It returns the pointer to the XtransConnInfo private, if it is a
++  valid _NXProxyConnInfo structure.
++
++- The above function is used by OpenDis.c to detect if the NX trans-
++  port was requested on the display and avoid spurious error messa-
++  ges in the case of a connection failure.
++
++- Added NXmiwindow.o to the NXAGENTOBJS in the Xserver's Imakefile
++  and imported NXmiwindow.c in nxagent. This allows us to check the
++  pointer to the pOldClip region in miSetShape() before going on
++  freeing it.
++
++- The path of the XKB base directory and of the xkbcomp comand is
++  validated at runtime.
++
++- Also added a check to verify the validity of the rgb file path.
++
++- Added NXresource.o to NXAGENTOBJS in the Imakefile of nxagent. We
++  need this to a assign a resource to the pixmaps and other server
++  objects which need to be enumerated at reconnection. Some objects,
++  being created by the X server and not by the clients, don't pass
++  through the resource assignment process operated by the dix. To
++  ensure that all objects get a resource, we add a resource at the
++  time the object is created and temporarily assign the resource to
++  the server client. If the dix later assigns the resource to a va-
++  lid client, the resource is removed from the server client's list.
++  
++- The display block handler registered by the client is called in
++  WaitForReadable() and WaitForWritable() before every select(),
++  not only upon entering the function. The reason is that more
++  data can be possibly produced for the NX link by the proxy it-
++  self and, when setting the flush policy to deferred, the client
++  may not have the chance of flushing the NX link.
++
++- Fixed a bug in XkbUseExtension() that caused Xlib to query the
++  presence of the XKEYBOARD extension multiple times. This partial-
++  ly implents the FR01D01275. The complete implementation required
++  modifications to the X11 agent, implemented in nxagent-2.0.0-33.
++
++- Updated to comply with the new NXTransFlush() interface.
++
++- Both nxwin and nxagent now read the X authority file by using an
++  fopen() instead of the system command 'cat'.
++
++- Removed NXmiwindow.o from the NXAGENTOBJ list. The agent will now
++  use the original miwindow.c.
++
++- Added some additional logs in Xtranssock.c to follow the creation
++  and removal of the X server's Unix listener.
++
++- Avoided the sleep of 5 seconds forced by Xtransutil.c if the dir-
++  ectory where the Unix listener is created is not owned by root.
++  This sleep is not executed on Cygwin (where the X socket can be
++  hardly owned by root) but may delay the startup of the agent if
++  the user chose a different NX_TEMP directory. Furthermore, it is
++  unclear what real benefits such sleeps are intended to bring to
++  the security of the X server. This can be controlled by defining
++  the NX_TRANS_SLEEP directive in Xserver/os/Imakefile.
++
++- Added NXmiexpose.o to the NXAGENTOBJ.
++
++- Ensured that _X11TransSocketCloseConnInfo() now initiates the NX
++  shutdown by calling NXTransClose().
++
++- Corrected a misplaced #else that made SocketUNIXConnect() skip a
++  block if the connection was not to the NX transport.
++
++- Updated to comply with the new NX function prototypes introduced
++  in nxcomp-2.0.0-31.
++
++- Moved the most important Xtranssock.c modifications into separate
++  functions.
++
++- Ensured that the modifications enabling the internal connections
++  to the proxy are compiled only when the TRANS_CLIENT directive is
++  defined.
++
++- Solved a bug that prevented the X11 socket to be deleted at the X
++  server shutdown. This needs further tests.
++
++- Added nxcompext to the link of nxagent, now that the dependency
++  of libX11 from nxcompext is removed.
++
++- Improved the Xtranssock routines to never loop through the array
++  of connection info.
++
++- Added a congestion flag to the connection info structure and a
++  function querying the transport and reporting if a change in the
++  congestion state has occurred. The code is currently not enabled,
++  because instead of polling the transport, we let the proxy notify
++  the changes in congestion state by using the callback. The code
++  can be used in future to extend the library, for example, by add-
++  ing some counters tracking the bandwidth usage of the socket con-
++  nection, so that we can make the congestion notifications work
++  even with a plain X11 connection.
++
++- Profiled the routines in XlibInt.c to reduce the number of calls
++  to the error predicate function provided by the client.
++
++- Fixed the nxcompext build problem that caused make World to fail.
++
++- Added a 'CONF' target to the X11 and Xext Imakefiles so that the
++  configure script is not run if the config.status exists.
++
++- Added the _NXDisplayBlockHandler hook. The function is called by
++  Xlib before blocking. The parameter says if Xlib is going to wait
++  for more input or because it needs to write to the display  socket.
++  The client can use the hook to perform any internal operation that
++  may require some time to complete. The user, though, should not
++  try to read or write to the display inside the callback routine.
++
++- Removed the outdated NX_TRANS_PROCESS, NX_TRANS_THREAD and NX_TR-
++  ANS_INCLUDE defines.
++
++- Reverted the lib/Xext Imakefile to the original XF86 version and
++  moved the build of the nxcompext library among the libX11 depend-
++  encies.
++
++- Corrected the lib/X11 Imakefile so that a new build of nxcomp and
++  nxcompext is not attempted if the libraries are up-to-date.
++
++- Removed the unused display buffer and image cleanup functions.
++  
++- Reverted the PutImage.c file to the original XF86 version.
++  
++- Added the _NXDisplayErrorPredicate function in XlibInt.c. It is
++  actually a pointer to a function called whenever Xlib is going to
++  perform a network operation. If the function returns true, the
++  call will be aborted and Xlib will return the control to the ap-
++  plication. It is up to the application to set the XlibDisplayIO-
++  Error flag after the _NXDisplayErrorPredicate returns true. The
++  function can be used to activate additional checks, besides the
++  normal failures detected by Xlib on the display socket. For exam-
++  ple, the application can set the funciton to verify if an inter-
++  rupt was received or if any other event occurred mandating the
++  end of the session.
++
++- Modified XIfEvent(), XMaskEvent() and XPeekIfEvent() to check the
++  _NXDisplayErrorPredicate function and return immediately if the
++  function returns true.
++
++- Modified _XWaitForReadable() to never enter the loop if the dis-
++  play is broken.
++
++- Corrected a make problem on Windows that caused the nxcomp and
++  nxcompext libraries to be referred with the wrong name, with the
++  result that a new configure and make was attempted at each build
++  attempt.
++
++- Merged all the changes to os, Xext, xkb, dix.
++
++- Changed host.def to build only the agent server.
++
++- Merged the changes to Xtranssock.c
++
++nx-X11-3.0.0-3
++
++- Merged the changes to lib/X11. Restored original PutImage.c and
++  ClDisplay.c files.
++
++nx-X11-3.0.0-2
++
++- Created a directory named 'reference' to keep files that are chan-
++  ged during the development of nx-X11 since the 1.5.0-16 to 2.0.0-32
++  version. These files will be removed as long as the differences are
++  merged to the 3.0.0 version. When all differences are merged, this
++  directory will be removed.
++
++nx-X11-3.0.0-1
++
++- Opened the 3.0.0 branch based on the nx-X11-2.0.0-9. The 3.0.0
++  branch will now support the migration toward the X.org tree. Due
++  to time concerns, the 2.0.0 branch is going to be based on the
++  same nx-X11 as the 1.5.0.
++
++nx-X11-2.0.0-9
++
++- Modified the agent link arguments to explicitly include the NX
++  libraries.
++
++- Disabled the Xinerama extension to avoid further clashes with
++  the redefinition of GC in Xlib.
++
++- Added os/libos.a at the end of the agent link.
++
++nx-X11-2.0.0-8
++
++- Moved the declarations of _NXEnable* and related structures from
++  Xlibint.h to NXlibint.h.  
++
++- Added provision for building the agent. This can be controlled by
++  setting NXAgentServer to YES in host.def.
++
++- Setting the NXUpgradeAgentServer variable to YES in the host.def
++  file will make the agent assume that it is being built in the new
++  environment. This variable is normally unset when building in the
++  1.5.0 tree.
++
++nx-X11-2.0.0-7
++
++- Fixed a problem on AMD64 due to the size of the area pointed by
++  the argument of _X11TransBytesReadable(). BytesReadable_t is long,
++  at least on Linux, while the ioctl() requires a pointer to an int.
++  The original _X11TransBytesReadable() function simply calls the
++  ioctl() by passing the pointer that is provided. NXTransReadable(),
++  instead, was correctly returning the value assuming a pointer to
++  a long, but this crashes some applications, among them xterm. Now
++  NXTransReadable() follows the same schema of the ioctl() call and
++  stores the result assuming a pointer to an int.
++
++- Removed the outdated NX_TRANS_PROCESS and NX_TRANS_THREAD code.
++
++nx-X11-2.0.0-6
++
++- Made xterm work with the NX transport. This required small changes
++  to the Xt toolkit's and the xterm's files to let them use the NX
++  aware select(). This is useful to test the NX transport until the
++  nxagent server is integrated.
++
++- When the transport is gone _X11TransSocketBytesReadable() returns
++  EPIPE. This makes the client become aware of the closure of the
++  connection.
++
++- Added a call to NXTransDestroy() in XCloseDisplay().
++
++- The exit() function in XlibInt.c causes a call to NXTransExit().
++
++- Merged changes to dix/pixmap.c, xkb/xkbDflts.h, mi/Imakefile.
++
++- Removed unneeded changes and files containing patches already in
++  the latest X.org distribution: dix/dispatch.c, fb/fbcompose.c, fb/
++  fbgc.c, xkb/ddxList.c, font/fontfile/dirfile.c, font/fontfile/
++  encparse.c, font/fontfile/fontfile.c, font/FreeType/fttools.c,
++  Xrender/FillRect.c, Xrender/Picture.c.
++
++nx-X11-2.0.0-5
++
++- Changes to the lib/X11/Imakefile to cleanly build the tree. This
++  is obtained by creating a link to the Xcomp library in exports/lib
++  without having to modify the programs' Imakefiles.
++
++- Finished merging the NX changes in the lib/X11 files.
++
++- Merged the CHANGELOG with the one from the 1.5.0 tree.
++
++nx-X11-2.0.0-4
++
++- Merged the NX changes in most Xtrans and lib/X11 files.
++
++nx-X11-2.0.0-3
++
++- Temporarily disabled the use of the MMX extensions in the Xserver's
++  fb code to successfully compile with GCC 4.
++
++nx-X11-2.0.0-2
++
++- Imported the *.NX.reference and *.XF86.reference files that will
++  be needed for the merge. These files are the *.original from the
++  1.5.0 tree. They will be removed as long as the merge advances.
++
++nx-X11-2.0.0-1
++
++- Created the 2.0.0 branch based on X.org the 6.8.99.16 snapshot.
++
++nx-X11-1.5.0-16
++
++- Added the missing *.XF86.original and *.NX.original files.
++
++nx-X11-1.5.0-15
++
++- Made the nxagent server use select() instead of poll() on Solaris
++  so that it can leverage the new NX transport.
++
++- Moved the NXTransFlush() call to _XReply().
++
++nx-X11-1.5.0-14
++
++- Added the 'synchronous' parameter in the _XWaitForReadable() call
++  to NXTransFlush().
++
++nx-X11-1.5.0-13
++
++- Removed the log entry in XlibInt.c on calling the NXTransFlush().
++
++nx-X11-1.5.0-12
++
++- Changed XlibInt.c and utils.c to call NXTransExit().
++
++nx-X11-1.5.0-11
++
++- Changed XlibInt.c to comply with the new NXTransFlush() interfa-
++  ce introduced in nxcomp-1.5.0-42.
++
++- Cosmetic changes to messages printed for debug.
++
++nx-X11-1.5.0-10
++
++- Ensured that all calls to _XIOError() are followed by a return.
++
++- Put exiting the client program in the case of an I/O error under
++  the control of the _NXContinueOnDisplayError flag. If set, the
++  I/O error routine will simply return, leaving to the application
++  the responsibility of checking the state of the XlibDisplayIOEr-
++  ror flag.
++
++- Added some checks whenever a read or write is performed on the X
++  connection, so that we can exit the I/O loop if the X channel is
++  gone. It is likely that more work will be needed when trying to
++  support XTHREADS enabled connections. This should not be a pro-
++  blem for now, as the default is still to quit the application un-
++  less the _NXContinueOnDisplayError flag is explicitly set.
++
++nx-X11-1.5.0-9
++
++- Removed the references to the cygipc library in NXWin. Now use the
++  cygserver daemon to provide the MIT-SHM extension.
++
++- Fixed an error in the UseCygIPC definition.
++
++- Changed the cygwin.cf file to avoid redefinition of the BuildGlxExt,
++  XWinServer and BuildGlxExt symbols.
++
++nx-X11-1.5.0-8
++
++- Added provision for deferred writes in the NX transport. When en-
++  tering _XWaitForReadable() we must ensure that data is flushed to
++  the proxy link.
++
++- Added the UseCygIPC define to NX-Cygwin.def.
++
++- Updated the NoMachine copyright notice on the modified files.
++
++nx-X11-1.5.0-7
++
++- Added the GLX extension in NX-Sun.def.
++
++- Added some more logs in WaitFor.c.
++
++nx-X11-1.5.0-6
++
++- Modified Xlibint.h and XlibInt.c to remove the _NXFlushSize para-
++  meter. New agents run the NX transport in-process, so we don't get
++  any benefit from increasing the display buffer size.
++
++- Modified NX-Darwin.def to not build the NXDarwin server. Since the
++  1.4.0 version the NXDarwin server is unsupported and the NX client
++  for the Mac requires that the Apple X server is installed.
++
++- Changed NX-Linux.def to avoid the warning due to "SharedLibGLw"
++  being not defined.
++
++nx-X11-1.5.0-5
++
++- Modified the Xserver Imakefile to link nxagent with FbPostFbLibs
++  and avoid including mfb/libmfb.a.
++
++- Added the GLX extension in NX-Linux.def. This provides unaccelera-
++  ted support in nxagent, with GLX operations translated into core X
++  protocol primitives.
++
++- Fixed x-X11/programs/Xserver/GL/dri/Imakefile to look in ../../hw/
++  /xfree86/os-support/bus for includes.
++
++nx-X11-1.5.0-4
++
++- Avoid calling NXTransSelect() if the transport is gone, so that we
++  don't have to wait until the timeout.
++
++- Added the "-fno-strict-aliasing" option to linux.cf when compiling
++  with a GCC version >= 4. In the words of Stefan Dirsch: "The opt-
++  ion, which is default since gcc 3.1, can result in wrong code when
++  the gcc warnings related to it are ignored. And as there are seve-
++  ral warnings in X11 related to it, it has been disabled for X11
++  from the beginning. This didn't change for gcc4, so it still needs
++  to be used."
++
++- Added more logs in XlibInt.c and utils.c. A warning is printed if
++  the SmartScheduler is initialized.
++
++nx-X11-1.5.0-3
++
++- Started integration of nxcomp with the X libraries. The Xtrans
++  code creates an internal connection to the nxcomp library instead
++  of a child proxy process.
++
++- Changed Xpoll.h and XlibInt.c to replace the standard Select
++  with a version giving NX a chance to check its own descriptors.
++
++- Implemented the NXTransReadVector() and the NXTransWriteVector()
++  functions to replace READV() and WRITEV().
++
++- Implemented memory-to-memory communication with the NX proxy by
++  making use of the NXTransAgent() interface.
++
++nx-X11-1.5.0-2
++
++- We think that the way LoadAuthorization() is working is wrong.
++  It doesn't reset the list of stored authorizations before reading
++  the new cookies. Our take is that if a new auth file is to be
++  read, the only cookies that are to be accepted are those that are
++  in the new file, not those in the file -plus- those that have
++  been in the file in the past. Furthermore, if the list can't be
++  read or it is empty, it should assume that it ignores which co-
++  okies are valid and thus it should disable any access. Your mile-
++  age can vary. A less draconian approach could be to leave the old
++  cookies if the file can't be read and remove them only if the
++  file is empty.
++
++  Adding the cookies without removing the old values for the same
++  protocol has an important implication. If an user shares the co-
++  okie with somebody and later wants to revoke the access to the
++  display, changing the cookie will not work. This is especially
++  important with NX. For security reasons, after reconnecting the
++  session to a different display, it is advisable to generate a
++  new set of cookies, but doing that it is useless with the current
++  code, as the old cookies are going to be still accepted. On the
++  same topic, consider that once an user has got access to the X
++  server, he/she can freely enable host authentication from any
++  host, so the safe behaviour should be to reset the host based
++  authenthication at least at reconnection, and keep as valid only
++  the cookies that are actually in the file. This behaviour would
++  surely break many applications, among them a SSH connection run
++  inside a NX session, as ssh -X reads the cookie for the display
++  only at session startup and does not read the cookies again
++  when the auth file is changed.
++
++  Another bug (or feature, depending on how you want to consider
++  it) is that if the authority file contains entries for different
++  displays (as it is the norm when the authority file is the default
++  .Xauthority in the user's home), the X server will match -any- of
++  the cookies, even cookies that are not for its own display. This 
++  means that you have to be careful when passing an authority file
++  to nxagent and maybe keep separate files for letting nxagent find
++  the cookie to be used to connect to the remote display and for
++  letting it find what cookies to accept. If the file is the same,
++  clients will be able to connect to nxagent with both the cookies.
++  This bug obviously affects any X server, also the real X server
++  running on the workstation, so it is common to see nxagent being
++  able to connect to the X server even if no cookie matches the
++  real display.
++
++- Added a check in lib/Xau/AuRead.c to prevent the fread() call to
++  be interrupted by SIGCHLD while reading the auth file. Due to the
++  way the old code worked, this could lead to the server enabling
++  local host access to the display. This problem had been identified
++  in the past. We just found that all the code dealing with reading
++  the auth file was affected. The code calls sigprocmask() to block
++  the signal (though it leaves some other calls unprotected) but the
++  SIGCHLD was not included in the set.
++
++- Added SIGCHLD to the set of signals that are blocked when reading
++  the authorization file.
++
++- As I was at it, I changed the path to the SecurityPolicy file. A
++  few Linux ditributors ship the file in $LIBDIR/xserver, a few only
++  in /etc/X11/xserver, most others in both places. It seems that
++  those who ship in $LIBDIR/xserver do also in /etc/X11 but the op-
++  posite is not true, so I switched to /etc/X11.
++
++nx-X11-1.5.0-1
++
++- Opened the 1.5.0 branch.
++
++nx-X11-1.4.1-2
++
++- Set parameter UseCygIPC on cygwin conf file in order to force the
++  build of MIT-SHM estension.
++
++- Removed some spurius object file.
++
++nx-X11-1.4.1-1
++
++- Opened the 1.4.1 branch.
++
++nx-X11-1.4.0-8
++
++- Changed DefaultFontPath and DefaultRGBDatabase in 
++  NX-Cygwin.def.
++
++nx-X11-1.4.0-7
++
++- Imported dispatch in nxdarwin package, in order to let
++  nxdarwin being able to detect new client connection.
++
++- Changed the Xpm Imakefile to make also .a static library
++  on Solaris. To link nxviewer and nxdestkop staticaly.
++
++nx-X11-1.4.0-6
++
++- XInput extension enabled on MacOSX.
++
++- Added some missing backup files of the original XFree86
++  package.
++
++nx-X11-1.4.0-5
++
++- Changed the mi Imakefile in order to let xfree86 servers use
++  the normal mi extension initialization for the XInput exten-
++  sion.
++
++- XInput extension enabled on Solaris.
++
++nx-X11-1.4.0-4
++
++- Removed the RejectWellKnownSocket for the cygwin and
++  MacOSX environments that doesn't use the Xtransport library.
++
++nx-X11-1.4.0-3
++
++- Changed the implementation of the reject method in the
++  Xtransport library, now close any new incoming connection 
++  immediately without reading or writing to it.
++
++nx-X11-1.4.0-2
++
++- Implemented a reject method in the Xtransport library,
++  this function accept and close every connection attempt,
++  on the specified listening socket.
++
++- Added the new function RejectWellKnownSocket to the os
++  connection code.
++  This function use the new transport reject function on
++  all listening socket.
++
++nx-X11-1.4.0-1
++
++- Opened the 1.4.0 branch.
++
++- Removed forgotten nxagent-1.3.2-20 directory.
++
++nx-X11-1.3.2-9
++
++- Prevents NX Darwin server going through the reset. On Darwin
++  we found that the it is not possible to get the correct key-
++  board layout unless it is set on the local machine, before
++  the NX session is started, by using xmodmap. As we set the
++  keyboard locally, we must prevent the X server to reset, or
++  we would loose any local configuration.
++
++nx-X11-1.3.2-8
++
++- Removed action associated to keysym XK_Terminate_Server. This
++  could cause agent to be terminated when pressing shift + back-
++  space if using the default US keyboard mapping.
++
++- Disabled the remaining debug logs in lib/X11/PutImage.c
++
++nx-X11-1.3.2-7
++
++- Fixed the wrong programs/Xserver/Imakefile in 1.3.2-6 package.
++
++nx-X11-1.3.2-6
++
++- Changed the define from NX_CLEAN_IN_PLACE to NX_CLEAN_INPLACE.
++  Definition of symbol is now placed in the Imakefile.
++
++- The new _NXEnableCleanInplace Xlib variable does control which
++  algorithm is used to clean the images. Setting NX_IMAGEINPLACE
++  in the environment will activate the in-place cleanup.
++
++- The default value of _NXEnableCleanInplace is -1. Leaving it to
++  a value <= 0 disables use of CleanInplace.
++
++nx-X11-1.3.2-5
++
++- Patch in config/cf/sun.cf. Fix for libfontconfig compilation
++  during gmake Everything on Solaris.
++
++- Patch in lib/X11/Imakefile. Fix for nxcomp compilation during
++  gmake World on Solaris.
++
++nx-X11-1.3.2-4
++
++- Image cleanup is now performed by using NXCleanInPlaceImage from
++  nxcompext. This function saves a buffer copy by cleaning the
++  padding bytes in the same buffer provided by the caller. Note that
++  to prevent memory violations in the case the image was allocated
++  in a static buffer, the function will temporarily redefine the
++  SIGSEGV handler. The former handler is restored before returning
++  to the caller. This can potentially affect some multithreaded
++  clients. Is to be decided if the function is safe enough to be
++  included in the production release.
++
++nx-X11-1.3.2-3
++
++- More debug logs in programs/Xserver/xkb/ddxLoad.c.
++
++nx-X11-1.3.2-2
++
++- Added NXmiwindow.o to NXAGENTOBJS in programs/Xserver/Imakefile.
++  File was not linked into the resulting nxagent. This solves the
++  problem of missing repaints in CDE and other Xt applications.
++
++nx-X11-1.3.2-1
++
++- Added some debug logs in programs/Xserver/xkb/ddxLoad.c. Function
++  XkbDDXCompileKeymapByNames is called by OpenOffice to read the
++  keyboard configuration whenever a drop-down menu is accessed. It
++  seem to always fail with the following error:
++
++  The XKEYBOARD keymap compiler (xkbcomp) reports:
++  > Error:            Can't find file "unknown" for geometry include
++  >                   Exiting
++  >                   Abandoning geometry file "default"
++
++- Opened the 1.3.2 development branch.
++
++nx-X11-1.3.1-12
++
++- Fixed a problem in xkb/ddxLoad.c on Solaris where Pclose was
++  always returning an error code despite the fact that command
++  was executed properly.
++
++nx-X11-1.3.1-11
++
++- Changed default GCC flags from '-O2 -fno-strength-reduce' to
++  -O3. No platform where NX is targeted is currently using a
++  GCC 2.x affected by the -fno-strength-reduce bug. Note also
++  that nxcomp is already compiled with -O3 since 1.1.1, so it
++  can be considered safe.
++
++nx-X11-1.3.1-10
++
++- Imported an updated fbcompose.c file from XFree86-4.3.99.902.
++  This fixes "uninitialized value" problems reported by Valgrind.
++
++- Fixed further buffer overflows by updating the following file
++  with recent versions coming from the XFree86-4.3.99.902 tree.
++
++  nx-X11/lib/font/fontfile/dirfile.c
++  nx-X11/lib/font/fontfile/encparse.c
++  nx-X11/lib/font/fontfile/fontfile.c
++
++- Fixed a possible buffer overflow in lib/font/FreeType/fttools.c.
++  Verified that the change is already in the XFree86 4.4.0 CVS.
++
++nx-X11-1.3.1-9
++
++- Fixed Xserver/Imakefile which was still referencing NXpixmap.o.
++
++nx-X11-1.3.1-8
++
++- Imported an updated fbgc.c from XFree86-4.3.99.902. This fixes
++  some minor problems reported by Valgrind.
++
++- A major problem was reported by Valgrind about reading after
++  the block allocated in fbCreatePixmap from AllocatePixmap. The
++  file pixmap.c has been modified so that 4 bytes are added to
++  the pixmap buffer at any new allocation. This quick hack should
++  solve the problem for both nxagent and the NXWin server. Further
++  investigation is planned for the next release.
++
++- Fixed Xtranssock.c to compile on Solaris where struct sigaction
++  doesn't have the sa_restorer member.
++
++nx-X11-1.3.1-5
++
++- Renamed the NX-sun.def configuration file to NX-Sun.def.
++
++- Renamed the non-standard NX_iPAQ_XServer and NX_Zaurus_XServer
++  symbols to NXiPAQXServer and NXZaurusXServer.
++
++- Added the missing sun.cf.XF86.original file in config/cf.
++
++- Added the missing empty file host.def.XF86.original in the
++  same directory.
++
++- Added initialization of sa.sa_mask when setting sigaction()
++  for SIGCHLD. The problem was reported by Valgrind running
++  nxagent.
++
++- Removed an unused block of code from WaitFor.c. The code had
++  been commented out in previous versions.
++
++- Removed the non-standard colon at the end of version in this
++  CHANGELOG.
++
++- Removed the spurious spaces in this CHANGELOG.
++
++nx-X11-1.3.1-4
++
++- Added a little workaround to the top Imakefile intended to
++  hide the makedepend warnings about non portable whitespaces
++  in sources.
++
++nx-X11-1.3.1-3
++
++- Fixed compilation problem with nxagent-1.3.1-13.
++
++nx-X11-1.3.1-2
++
++- Changes in NX-sun.def configuration file for Solaris to allow
++  compilation of the XKB extension. 
++
++nx-X11-1.3.1-1
++
++- Opened the 1.3.1 development branch.
++
++nx-X11-1.3.0-6
++
++- Original output buffer size in stock XFree86 is 2048. We try
++  to reduce context switches and help stream compression by
++  increasing the maximum size of the buffer 8192. _NXFlushSize
++  determines when the display buffer is actually flushed. It is
++  set by default to 4096 but agents should set it to 0 if they
++  want to disable early flush.
++
++- Added the _NXLostSequenceFunction function pointer to let NX
++  agents suppress the error message and modify the default Xlib
++  behaviour when out-of-order sequence numbers are received.
diff --git a/doc/nx-X11_vs_XOrg69_patches/ChkIfEv.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/ChkIfEv.c.NX.patch
new file mode 100644
index 0000000..333838d
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/ChkIfEv.c.NX.patch
@@ -0,0 +1,59 @@
+--- ./nx-X11/lib/X11/ChkIfEv.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/ChkIfEv.c	2015-02-10 19:13:13.120711494 +0100
+@@ -83,3 +83,56 @@
+ 	UnlockDisplay(dpy);
+ 	return False;
+ }
++
++#ifdef NX_TRANS_SOCKET
++
++/*
++ * This is just like XCheckIfEvent() but doesn't
++ * flush the output buffer if it can't read new
++ * events.
++ */
++
++Bool XCheckIfEventNoFlush (dpy, event, predicate, arg)
++        register Display *dpy;
++	Bool (*predicate)(
++			  Display*			/* display */,
++			  XEvent*			/* event */,
++			  char*				/* arg */
++			  );		/* function to call */
++	register XEvent *event;		/* XEvent to be filled in. */
++	char *arg;
++{
++	register _XQEvent *prev, *qelt;
++	unsigned long qe_serial = 0;
++	int n;			/* time through count */
++
++        LockDisplay(dpy);
++	prev = NULL;
++	for (n = 2; --n >= 0;) {
++	    for (qelt = prev ? prev->next : dpy->head;
++		 qelt;
++		 prev = qelt, qelt = qelt->next) {
++		if(qelt->qserial_num > qe_serial
++		   && (*predicate)(dpy, &qelt->event, arg)) {
++		    *event = qelt->event;
++		    _XDeq(dpy, prev, qelt);
++		    UnlockDisplay(dpy);
++		    return True;
++		}
++	    }
++	    if (prev)
++		qe_serial = prev->qserial_num;
++	    switch (n) {
++	      case 1:
++		_XEventsQueued(dpy, QueuedAfterReading);
++		break;
++	    }
++	    if (prev && prev->qserial_num != qe_serial)
++		/* another thread has snatched this event */
++		prev = NULL;
++	}
++	UnlockDisplay(dpy);
++	return False;
++}
++
++#endif
diff --git a/doc/nx-X11_vs_XOrg69_patches/ConnDis.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/ConnDis.c.NX.patch
new file mode 100644
index 0000000..17f0549
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/ConnDis.c.NX.patch
@@ -0,0 +1,319 @@
+--- ./nx-X11/lib/X11/ConnDis.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/ConnDis.c	2015-02-10 19:13:13.008715687 +0100
+@@ -25,6 +25,24 @@
+ in this Software without prior written authorization from The Open Group.
+ 
+ */
++
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/lib/X11/ConnDis.c,v 3.28 2003/12/02 23:33:17 herrb Exp $ */
+ 
+ /* 
+@@ -162,6 +180,39 @@
+     saddrlen = 0;			/* set so that we can clear later */
+     saddr = NULL;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Called with display_name [%s].\n", display_name);
++#endif
++
++#ifdef NX_TRANS_SOCKET
++
++    /*
++     * Check if user selected the "nx"
++     * protocol or an "nx" hostname.
++     */
++
++    if (!strncasecmp(p, "nx/", 3) || !strcasecmp(p, "nx") ||
++            !strncasecmp(p, "nx:", 3) || !strncasecmp(p, "nx,", 3))
++    {
++        if (*(display_name + 2) == '/')
++        {
++          p += 3;
++        }
++
++        pprotocol = copystring ("nx", 2);
++
++        if (!pprotocol) goto bad;
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_X11TransConnectDisplay: Forced protocol to [%s].\n", pprotocol);
++#endif
++
++    }
++    else
++    {
++
++#endif
++
+     /*
+      * Step 0, find the protocol.  This is delimited by the optional 
+      * slash ('/').
+@@ -176,6 +227,60 @@
+     } else
+ 	p = display_name;		/* reset the pointer in
+ 					   case no protocol was given */
++#ifdef NX_TRANS_SOCKET
++
++    } /* End of step 0. */
++
++    /*
++     * Check if user specified the "nx" protocol or
++     * hostname is "nx" or in the form "nx,...".
++     */
++
++    if (pprotocol && !strcasecmp(pprotocol, "nx"))
++    {
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_X11TransConnectDisplay: Checking hostname [%s].\n", p);
++#endif
++
++        /*
++         * Options can include a "display=" tuple so
++         * need to scan right to left.
++         */
++
++        lastp = p;
++        lastc = NULL;
++
++        for (; *p; p++)
++            if (*p == ':')
++                lastc = p;
++
++        /*
++         * Don't complain if no screen was provided.
++         */
++
++        if (lastc)
++        {
++            phostname = copystring (lastp, lastc - lastp);
++
++            p = lastc;
++        }
++        else
++        {
++            phostname = copystring (lastp, strlen(lastp));
++        }
++
++        if (!phostname) goto bad;
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_X11TransConnectDisplay: Forced hostname [%s].\n", phostname);
++#endif
++
++    }
++    else
++    {
++
++#endif
+ 
+     /*
+      * Step 1, find the hostname.  This is delimited by either one colon,
+@@ -240,6 +345,20 @@
+     }
+ #endif
+ 
++#ifdef NX_TRANS_SOCKET
++
++    } /* End of step 1. */
++
++    /*
++     * Check if no display was specified. In this case
++     * search the "port=n" option in NX host string.
++     */
++
++    if (*p)
++    {
++
++#endif
++
+ 
+     /*
+      * Step 2, find the display number.  This field is required and is 
+@@ -254,6 +373,66 @@
+       goto bad;
+     idisplay = atoi (pdpynum);
+ 
++#ifdef NX_TRANS_SOCKET
++
++    }
++    else
++    {
++        char *host  = NULL;
++        char *name  = NULL;
++        char *value = NULL;
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_X11TransConnectDisplay: Searching port in port [%s].\n", phostname);
++#endif
++
++        if (!strncasecmp(phostname, "nx,", 3))
++        {
++            host = copystring(phostname + 3, strlen(phostname) - 3);
++        }
++
++        if (!host) goto bad;
++
++        idisplay = -1;
++
++        name = strtok(host, "=");
++
++        while (name)
++        {
++            value = strtok(NULL, ",");
++
++            if (value == NULL || strstr(value, "=") != NULL ||
++                    strstr(name, ",") != NULL || strlen(value) >= 128)
++            {
++                Xfree(host);
++
++                goto bad;
++            }
++            else if (strcasecmp(name, "port") == 0)
++            {
++                idisplay = atoi(value);
++
++                pdpynum = copystring(value, strlen(value));
++
++                if (!pdpynum) goto bad;
++
++                break;
++            }
++
++            name = strtok(NULL, "=");
++        }
++
++        Xfree(host);
++
++        if (idisplay == -1)
++        {
++            goto bad;
++        }
++
++    } /* End of step 2. */
++
++#endif
++
+ 
+     /*
+      * Step 3, find the screen number.  This field is optional.  It is 
+@@ -286,6 +465,27 @@
+      * is "unix", then choose BSD UNIX domain sockets (if configured).
+      */
+ 
++#ifdef NX_TRANS_SOCKET
++
++    /*
++     * If user selected the "nx" protocol
++     * force "local" transport.
++     */
++
++    if (pprotocol && !strcasecmp(pprotocol, "nx"))
++    {
++        pprotocol = copystring ("local", 5);
++
++        if (!pprotocol) goto bad;
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_X11TransConnectDisplay: Converted protocol to [%s].\n", pprotocol);
++#endif
++
++    }
++
++#endif
++
+ #if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) || defined(MNX_TCPCONN) || defined(OS2PIPECONN)
+     if (!pprotocol) {
+ 	if (!phostname) {
+@@ -358,14 +558,26 @@
+      * being a server listening at all, which is why we have to not retry
+      * too many times).
+      */
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Entering connection loop.\n");
++#endif
+     for(retry=X_CONNECTION_RETRIES; retry>=0; retry-- )
+ 	{
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransOpenCOTSClient(address) with address [%s].\n", address);
++#endif
+ 	if ( (trans_conn = _X11TransOpenCOTSClient(address)) == NULL )
+ 	    {
+ 	    break;
+ 	    }
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransConnect(trans_conn,address).\n");
++#endif
+ 	if ((connect_stat = _X11TransConnect(trans_conn,address)) < 0 )
+ 	    {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++            fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransClose(trans_conn).\n");
++#endif
+ 	    _X11TransClose(trans_conn);
+ 	    trans_conn = NULL;
+ 
+@@ -378,6 +590,9 @@
+ 		break;
+ 	    }
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransGetPeerAddr(trans_conn, &family, &saddrlen, &saddr).\n");
++#endif
+ 	_X11TransGetPeerAddr(trans_conn, &family, &saddrlen, &saddr);
+ 
+ 	/*
+@@ -386,6 +601,9 @@
+ 	 * X protocol (ie FamilyInternet).
+ 	 */
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Going to call _X11TransConvertAddress(&family, &saddrlen, &saddr).\n");
++#endif
+ 	if( _X11TransConvertAddress(&family, &saddrlen, &saddr) < 0 )
+ 	    {
+ 	    _X11TransClose(trans_conn);
+@@ -402,6 +620,9 @@
+ 	break;
+ 	}
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "_X11TransConnectDisplay: Out of connection loop.\n");
++#endif
+     if (address != addrbuf) Xfree (address);
+     address = addrbuf;
+ 
+@@ -570,6 +791,17 @@
+ 
+     if (len != 0)
+ 	return -1;
++#ifdef NX_TRANS_SOCKET
++    if (_NXDisplayWriteFunction != NULL) {
++        (*_NXDisplayWriteFunction)(dpy, len);
++    }
++#ifdef NX_TRANS_CHANGE
++    if (_NXDisplayCongestionFunction != NULL &&
++            _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++        (*_NXDisplayCongestionFunction)(dpy, congestion);
++    }
++#endif
++#endif
+ 
+ #ifdef K5AUTH
+     if (auth_length == 14 &&
diff --git a/doc/nx-X11_vs_XOrg69_patches/Glyph.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Glyph.c.NX.patch
new file mode 100644
index 0000000..6dd036e
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Glyph.c.NX.patch
@@ -0,0 +1,547 @@
+--- ./nx-X11/lib/Xrender/Glyph.c.X.original	2015-02-13 14:03:44.652443320 +0100
++++ ./nx-X11/lib/Xrender/Glyph.c	2015-02-10 19:13:12.580731749 +0100
+@@ -27,6 +27,26 @@
+ #endif
+ #include "Xrenderint.h"
+ 
++/* 
++ * NX_RENDER_CLEANUP enables cleaning of padding bytes
++ */
++
++#define NX_RENDER_CLEANUP
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++#undef  DUMP
++
++#ifdef NX_RENDER_CLEANUP
++
++#include <stdio.h>
++
++#define ROUNDUP(nbits, pad) ((((nbits) + ((pad)-1)) / (pad)) * ((pad)>>3))
++
++#endif /* NX_RENDER_CLEANUP */
++
+ GlyphSet
+ XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format)
+ {
+@@ -81,6 +101,248 @@
+     SyncHandle();
+ }
+ 
++#ifdef NX_RENDER_CLEANUP
++
++void
++XRenderCleanGlyphs(xGlyphInfo  *gi,
++                        int         nglyphs,
++                        CARD8       *images,
++                        int         depth,
++                        Display     *dpy)
++{
++
++  int widthInBits;
++  int bytesPerLine;
++  int bytesToClean;
++  int bitsToClean;
++  int widthInBytes;
++  int height = gi -> height;
++  register int i;
++  int j;
++
++  #ifdef DEBUG
++  fprintf(stderr, "nxagentCleanGlyphs: Found a Glyph with Depth %d, width %d, pad %d.\n",
++          depth, gi -> width, dpy -> bitmap_pad);
++  #endif
++
++  while (nglyphs > 0)
++  {
++    if (depth == 24)
++    {
++      widthInBits = gi -> width * 32;
++
++      bytesPerLine = ROUNDUP(widthInBits, dpy -> bitmap_pad);
++
++      bytesToClean = bytesPerLine * height;
++
++      #ifdef DUBUG
++      fprintf(stderr, "nxagentCleanGlyphs: Found glyph with depth 24, bytes to clean is %d"
++              "width in bits is %d bytes per line [%d] height [%d].\n", bytesToClean,
++                      widthInBits, bytesPerLine, height);
++      #endif
++
++      if (dpy -> byte_order == LSBFirst)
++      {
++        for (i = 3; i < bytesToClean; i += 4)
++        {
++          images[i] = 0x00;
++        }
++      }
++      else
++      {
++        for (i = 0; i < bytesToClean; i += 4)
++        {
++          images[i] = 0x00;
++        }
++      }
++
++      #ifdef DUMP
++      fprintf(stderr, "nxagentCleanGlyphs: depth %d, bytesToClean %d, scanline: ", depth, bytesToClean);
++      for (i = 0; i < bytesPerLine; i++)
++      {
++        fprintf(stderr, "[%d]", images[i]);
++      }
++      fprintf(stderr,"\n");
++      #endif
++
++      images += bytesToClean;
++
++      gi++;
++
++      nglyphs--;
++    }
++    else if (depth == 1)
++    {
++      widthInBits = gi -> width;
++
++      bytesPerLine = ROUNDUP(widthInBits, dpy -> bitmap_pad);
++
++      bitsToClean = (bytesPerLine << 3) - (gi -> width);
++
++      #ifdef DEBUG
++      fprintf(stderr, "nxagentCleanGlyphs: Found glyph with depth 1, width [%d], height [%d], bitsToClean [%d]," 
++              " bytesPerLine [%d].\n", gi -> width, height, bitsToClean, bytesPerLine);
++      #endif
++
++      bytesToClean = bitsToClean >> 3;
++
++      bitsToClean &= 7;
++
++      #ifdef DEBUG
++      fprintf(stderr, "nxagentCleanGlyphs: bitsToClean &=7 is %d, bytesToCLean is %d."
++              " byte_order is %d, bitmap_bit_order is %d.\n", bitsToClean, bytesToClean,
++              dpy -> byte_order, dpy -> bitmap_bit_order);
++      #endif
++
++      for (i = 1; i <= height; i++)
++      {
++        if (dpy -> byte_order == dpy -> bitmap_bit_order)
++        {
++          for (j = 1; j <= bytesToClean; j++)
++          {
++            images[i * bytesPerLine - j] = 0x00;
++
++            #ifdef DEBUG
++            fprintf(stderr, "nxagentCleanGlyphs: byte_order = bitmap_bit_orde, cleaning %d, i=%d, j=%d.\n"
++                    , (i * bytesPerLine - j), i, j);
++            #endif
++
++          }
++        }
++        else
++        {
++          for (j = bytesToClean; j >= 1; j--)
++          {
++            images[i * bytesPerLine - j] = 0x00;
++
++            #ifdef DEBUG
++            fprintf(stderr, "nxagentCleanGlyphs: byte_order %d, bitmap_bit_order %d, cleaning %d, i=%d, j=%d.\n"
++                    , dpy -> byte_order, dpy -> bitmap_bit_order, (i * bytesPerLine - j), i, j);
++            #endif
++
++          }
++        }
++
++        if (dpy -> bitmap_bit_order == MSBFirst)
++        {
++          images[i * bytesPerLine - j] &= 0xff << bitsToClean;
++
++          #ifdef DEBUG
++          fprintf(stderr, "nxagentCleanGlyphs: byte_order MSBFirst, cleaning %d, i=%d, j=%d.\n"
++                  , (i * bytesPerLine - j), i, j);
++          #endif
++        }
++        else
++        {
++          images[i * bytesPerLine - j] &= 0xff >> bitsToClean;
++
++          #ifdef DEBUG
++          fprintf(stderr, "nxagentCleanGlyphs: byte_order LSBFirst, cleaning %d, i=%d, j=%d.\n"
++                  , (i * bytesPerLine - j), i, j);
++          #endif
++        }
++      }
++  
++      #ifdef DUMP
++      fprintf(stderr, "nxagentCleanGlyphs: depth %d, bytesToClean %d, scanline: ", depth, bytesToClean);
++      for (i = 0; i < bytesPerLine; i++)
++      {
++        fprintf(stderr, "[%d]", images[i]);
++      }
++      fprintf(stderr,"\n");
++      #endif
++
++      images += bytesPerLine * height;
++
++      gi++;
++
++      nglyphs--;
++    }
++    else if ((depth == 8) || (depth == 16) )
++    {
++      widthInBits = gi -> width * depth;
++
++      bytesPerLine = ROUNDUP(widthInBits, dpy -> bitmap_pad);
++
++      widthInBytes = (widthInBits >> 3);
++
++      bytesToClean = bytesPerLine - widthInBytes;
++
++      #ifdef DEBUG
++      fprintf(stderr, "nxagentCleanGlyphs: nglyphs is %d, width of glyph in bits is %d, in bytes is %d.\n",
++              nglyphs, widthInBits, widthInBytes);
++
++      fprintf(stderr, "nxagentCleanGlyphs: bytesPerLine is %d bytes, there are %d scanlines.\n", bytesPerLine, height);
++
++      fprintf(stderr, "nxagentCleanGlyphs: Bytes to clean for each scanline are %d.\n", bytesToClean);
++      #endif
++
++      if (bytesToClean > 0)
++      {
++        while (height > 0)
++        {
++          i = bytesToClean;
++
++          while (i > 0)
++          {
++            *(images + (bytesPerLine - i)) = 0;
++
++            #ifdef DEBUG
++            fprintf(stderr, "nxagentCleanGlyphs: cleaned a byte.\n");
++            #endif
++
++            i--;
++          }
++
++          #ifdef DUMP
++          fprintf(stderr, "nxagentCleanGlyphs: depth %d, bytesToClean %d, scanline: ", depth, bytesToClean);
++          for (i = 0; i < bytesPerLine; i++)
++          {
++            fprintf(stderr, "[%d]", images[i]);
++          }
++          fprintf(stderr,"\n");
++          #endif
++
++          images += bytesPerLine;
++
++          height--;
++        }
++      }
++
++      gi++;
++
++      nglyphs--;
++
++      #ifdef DEBUG
++      fprintf(stderr, "nxagentCleanGlyphs: Breaking Out.\n");
++      #endif
++    }
++    else if (depth == 32)
++    {
++      #ifdef DEBUG
++      fprintf(stderr, "nxagentCleanGlyphs: Found glyph with depth 32.\n");
++      #endif
++
++      gi++;
++
++      nglyphs--;
++    }
++    else
++    {
++      #ifdef WARNING
++      fprintf(stderr, "nxagentCleanGlyphs: Unrecognized glyph, depth is not 8/16/24/32, it appears to be %d.\n",
++              depth);
++      #endif
++
++      gi++;
++
++      nglyphs--;
++    }
++  }
++}
++
++#endif /* #ifdef NX_RENDER_CLEANUP */
++
+ void
+ XRenderAddGlyphs (Display	*dpy,
+ 		  GlyphSet	glyphset,
+@@ -404,6 +666,14 @@
+     _Xconst char		*chars;
+     int				nchars;
+ 
++    #ifdef NX_RENDER_CLEANUP
++
++    char 			tmpChar[4];
++    int				bytes_to_clean;
++    int				bytes_to_write;
++
++    #endif /* NX_RENDER_CLEANUP */
++
+     if (!nelt)
+ 	return;
+     
+@@ -464,6 +734,14 @@
+ 	{
+ 	    glyphset = elts[i].glyphset;
+ 	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
++
++	    #ifdef NX_RENDER_CLEANUP
++
++	    elt->pad1 = 0;
++	    elt->pad2 = 0;
++
++	    #endif /* NX_RENDER_CLEANUP */
++
+ 	    elt->len = 0xff;
+ 	    elt->deltax = 0;
+ 	    elt->deltay = 0;
+@@ -478,11 +756,88 @@
+ 	    int this_chars = nchars > MAX_8 ? MAX_8 : nchars;
+ 
+ 	    BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
++
++	    #ifdef NX_RENDER_CLEANUP
++
++	    elt->pad1 = 0;
++	    elt->pad2 = 0;
++
++	    #endif /* NX_RENDER_CLEANUP */
++
+ 	    elt->len = this_chars;
+ 	    elt->deltax = xDst;
+ 	    elt->deltay = yDst;
+ 	    xDst = 0;
+ 	    yDst = 0;
++
++            #ifdef NX_RENDER_CLEANUP
++
++            bytes_to_write = this_chars & ~3;
++
++            bytes_to_clean = ((this_chars + 3) & ~3) - this_chars;
++
++            #ifdef DEBUG
++            fprintf(stderr, "XRenderCompositeText8: bytes_to_write %d, bytes_to_clean are %d,"
++                        " this_chars %d.\n", bytes_to_write, bytes_to_clean, this_chars);
++            #endif
++
++            if (bytes_to_clean > 0)
++            {
++              if (bytes_to_write > 0)
++               {
++                #ifdef DEBUG
++                fprintf(stderr, "XRenderCompositeText8: found %d clean bytes, bytes_to_clean are %d,"
++                        " this_chars %d.\n", bytes_to_write, bytes_to_clean, this_chars);
++                #endif
++
++                Data (dpy, chars, bytes_to_write);
++                chars += bytes_to_write;
++              }
++
++              bytes_to_write = this_chars % 4;
++              memcpy (tmpChar, chars, bytes_to_write);
++              chars += bytes_to_write;
++
++              #ifdef DEBUG
++              fprintf(stderr, "XRenderCompositeText8: last 32 bit, bytes_to_write are %d,"
++                      " bytes_to_clean are %d, this_chars are %d.\n", bytes_to_write, bytes_to_clean, this_chars);
++              #endif
++
++              #ifdef DUMP
++              fprintf(stderr, "XRenderCompositeText8: bytes_to_clean %d, ", bytes_to_clean);
++              #endif
++
++              while (bytes_to_clean > 0)
++              {
++                tmpChar[4 - bytes_to_clean] = 0;
++                bytes_to_clean--;
++
++                #ifdef DEBUG
++                fprintf(stderr, "XRenderCompositeText8: Cleaned %d byte.\n", 4 - bytes_to_clean);
++                #endif
++              }
++
++              Data (dpy, tmpChar, 4);
++              nchars -= this_chars;
++
++              #ifdef DUMP
++              fprintf(stderr, "Data: ");
++              for (i = 0; i < 4; i++)
++              {
++                fprintf(stderr, "[%d]", tmpChar[i]);
++              }
++              fprintf(stderr,"\n");
++              #endif
++
++              #ifdef DEBUG
++              fprintf(stderr, "XRenderCompositeText8: nchars now is %d.\n", nchars);
++              #endif
++
++              continue;
++            }
++
++            #endif /* NX_RENDER_CLEANUP */
++
+ 	    Data (dpy, chars, this_chars);
+ 	    nchars -= this_chars;
+ 	    chars += this_chars;
+@@ -517,6 +872,14 @@
+     _Xconst unsigned short    	*chars;
+     int				nchars;
+ 
++    #ifdef NX_RENDER_CLEANUP
++
++    int				bytes_to_write;
++    int				bytes_to_clean;
++    char			tmpChar[4];
++
++    #endif /* NX_RENDER_CLEANUP */
++
+     if (!nelt)
+ 	return;
+     
+@@ -574,6 +937,14 @@
+ 	{
+ 	    glyphset = elts[i].glyphset;
+ 	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
++
++	    #ifdef NX_RENDER_CLEANUP
++
++	    elt->pad1 = 0;
++	    elt->pad2 = 0;
++
++	    #endif /* NX_RENDER_CLEANUP */
++
+ 	    elt->len = 0xff;
+ 	    elt->deltax = 0;
+ 	    elt->deltay = 0;
+@@ -587,13 +958,77 @@
+ 	{
+ 	    int this_chars = nchars > MAX_16 ? MAX_16 : nchars;
+ 	    int this_bytes = this_chars * 2;
+-    
++
+ 	    BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
++
++	    #ifdef NX_RENDER_CLEANUP
++
++	    elt->pad1 = 0;
++	    elt->pad2 = 0;
++
++	    #endif /* NX_RENDER_CLEANUP */
++
+ 	    elt->len = this_chars;
+ 	    elt->deltax = xDst;
+ 	    elt->deltay = yDst;
+ 	    xDst = 0;
+ 	    yDst = 0;
++	    
++            #ifdef NX_RENDER_CLEANUP
++
++            bytes_to_write = this_bytes & ~3;
++            bytes_to_clean = ((this_bytes + 3) & ~3) - this_bytes;
++
++            #ifdef DEBUG
++            fprintf(stderr, "XRenderCompositeText16: this_chars %d, this_bytes %d.\n"
++                    "bytes_to_write %d, bytes_to_clean are %d.\n", this_chars, this_bytes,
++                    bytes_to_write, bytes_to_clean);
++            #endif
++
++            if (bytes_to_clean > 0)
++            {
++              if (bytes_to_write > 0)
++              {
++                Data16 (dpy, chars, bytes_to_write);
++
++                /*
++                 * Cast chars to avoid errors with pointer arithmetic.
++                 */
++
++                chars = (unsigned short *) ((char *) chars + bytes_to_write);
++              }
++
++              bytes_to_write = this_bytes % 4;
++              memcpy (tmpChar, (char *) chars, bytes_to_write);
++              chars = (unsigned short *) ((char *) chars + bytes_to_write);
++
++              #ifdef DEBUG
++              fprintf(stderr, "XRenderCompositeText16: last 32 bit, bytes_to_write are %d,"
++                      " bytes_to_clean are %d.\n", bytes_to_write, bytes_to_clean);
++              #endif
++
++              while (bytes_to_clean > 0)
++              {
++                tmpChar[4 - bytes_to_clean] = 0;
++                bytes_to_clean--;
++
++                #ifdef DEBUG
++                fprintf(stderr, "XRenderCompositeText16: Cleaned %d byte.\n", 4 - bytes_to_clean);
++                #endif
++              }
++
++              Data16 (dpy, tmpChar, 4);
++              nchars -= this_chars;
++
++              #ifdef DEBUG
++              fprintf(stderr, "XRenderCompositeText16: nchars now is %d.\n", nchars);
++              #endif
++
++              continue;
++            }
++
++            #endif /* NX_RENDER_CLEANUP */
++
+ 	    Data16 (dpy, chars, this_bytes);
+ 	    nchars -= this_chars;
+ 	    chars += this_chars;
+@@ -681,6 +1116,14 @@
+ 	{
+ 	    glyphset = elts[i].glyphset;
+ 	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
++
++	    #ifdef NX_RENDER_CLEANUP
++
++	    elt->pad1 = 0;
++	    elt->pad2 = 0;
++
++	    #endif /* NX_RENDER_CLEANUP */
++
+ 	    elt->len = 0xff;
+ 	    elt->deltax = 0;
+ 	    elt->deltay = 0;
+@@ -695,11 +1138,25 @@
+ 	    int this_chars = nchars > MAX_32 ? MAX_32 : nchars;
+ 	    int this_bytes = this_chars * 4;
+ 	    BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
++
++	    #ifdef NX_RENDER_CLEANUP
++
++	    elt->pad1 = 0;
++	    elt->pad2 = 0;
++
++	    #endif /* NX_RENDER_CLEANUP */
++
+ 	    elt->len = this_chars;
+ 	    elt->deltax = xDst;
+ 	    elt->deltay = yDst;
+ 	    xDst = 0;
+ 	    yDst = 0;
++
++            #ifdef TEST
++            fprintf(stderr, "XRenderCompositeText32: this_chars %d, this_bytes %d.\n",
++                    this_chars, this_bytes);
++            #endif
++
+ 	    DataInt32 (dpy, chars, this_bytes);
+ 	    nchars -= this_chars;
+ 	    chars += this_chars;
diff --git a/doc/nx-X11_vs_XOrg69_patches/IfEvent.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/IfEvent.c.NX.patch
new file mode 100644
index 0000000..fb5e164
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/IfEvent.c.NX.patch
@@ -0,0 +1,13 @@
+--- ./nx-X11/lib/X11/IfEvent.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/IfEvent.c	2015-02-10 19:13:12.796723642 +0100
+@@ -71,5 +71,10 @@
+ 	    if (prev && prev->qserial_num != qe_serial)
+ 		/* another thread has snatched this event */
+ 		prev = NULL;
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                return 0;
++            }
++#endif
+ 	}
+ }
diff --git a/doc/nx-X11_vs_XOrg69_patches/Imakefile.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Imakefile.NX.patch
new file mode 100644
index 0000000..7f3db6c
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Imakefile.NX.patch
@@ -0,0 +1,11 @@
+--- ./nx-X11/programs/Xserver/GL/mesa/X/Imakefile.X.original	2015-02-13 14:03:44.680442769 +0100
++++ ./nx-X11/programs/Xserver/GL/mesa/X/Imakefile	2015-02-10 19:13:14.340665851 +0100
+@@ -57,7 +57,7 @@
+ 		-I$(XF86OSSRC) \
+ 		-I$(DRMSRCDIR)/shared-core
+ 
+-      DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
++      DEFINES = $(GLX_DEFINES) $(GLXSRV_DEFINES) -DNXAGENT_SERVER /*-DUSE_X86_ASM*/ /*-DUSE_SPARC_ASM*/
+ 
+ #ifdef IHaveModules
+ ModuleObjectRule()
diff --git a/doc/nx-X11_vs_XOrg69_patches/MaskEvent.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/MaskEvent.c.NX.patch
new file mode 100644
index 0000000..6620d4b
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/MaskEvent.c.NX.patch
@@ -0,0 +1,13 @@
+--- ./nx-X11/lib/X11/MaskEvent.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/MaskEvent.c	2015-02-10 19:13:12.944718089 +0100
+@@ -75,5 +75,10 @@
+ 	    if (prev && prev->qserial_num != qe_serial)
+ 		/* another thread has snatched this event */
+ 		prev = NULL;
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                return 0;
++            }
++#endif
+ 	}
+ }
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXdamage.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXdamage.c.NX.patch
new file mode 100644
index 0000000..06d9121
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXdamage.c.NX.patch
@@ -0,0 +1,138 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original	2015-02-13 14:03:44.740441589 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c	2015-02-10 19:13:13.828684988 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+  *
+@@ -1358,17 +1375,24 @@
+     if (n != 0) {
+ 	damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+ 			   charinfo, imageblt, pGC->subWindowMode);
++
++#ifndef NXAGENT_SERVER
++
+ 	if (imageblt)
+ 	    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ 				       FONTGLYPHS(pGC->font));
+ 	else
+ 	    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+ 				      FONTGLYPHS(pGC->font));
++#endif
++
+     }
+     DEALLOCATE_LOCAL(charinfo);
+     return x + w;
+ }
+ 
++#ifndef NXAGENT_SERVER
++
+ static int
+ damagePolyText8(DrawablePtr pDrawable,
+ 		GCPtr	    pGC,
+@@ -1445,6 +1469,89 @@
+     DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+ }
+ 
++#else /* #ifndef NXAGENT_SERVER */
++
++static int
++damagePolyText8(DrawablePtr pDrawable,
++		GCPtr	    pGC,
++		int	    x,
++		int	    y,
++		int	    count,
++		char	    *chars)
++{
++    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
++
++    if (checkGCDamage (pDrawable, pGC))
++	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
++		    Linear8Bit, TT_POLY8);
++
++    x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
++
++    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
++    return x;
++}
++
++static int
++damagePolyText16(DrawablePtr	pDrawable,
++		 GCPtr		pGC,
++		 int		x,
++		 int		y,
++		 int		count,
++		 unsigned short	*chars)
++{
++    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
++
++    if (checkGCDamage (pDrawable, pGC))
++	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
++		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
++		    TT_POLY16);
++
++    x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
++
++    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
++    return x;
++}
++
++static void
++damageImageText8(DrawablePtr	pDrawable,
++		 GCPtr		pGC,
++		 int		x,
++		 int		y,
++		 int		count,
++		 char		*chars)
++{
++    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
++
++    if (checkGCDamage (pDrawable, pGC))
++	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
++		    Linear8Bit, TT_IMAGE8);
++
++    (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
++
++    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
++}
++
++static void
++damageImageText16(DrawablePtr	pDrawable,
++		  GCPtr		pGC,
++		  int		x,
++		  int		y,
++		  int		count,
++		  unsigned short *chars)
++{
++    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
++
++    if (checkGCDamage (pDrawable, pGC))
++	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
++		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
++		    TT_IMAGE16);
++
++    (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
++
++    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
++}
++
++#endif /* #ifndef NXAGENT_SERVER */
+ 
+ static void
+ damageImageGlyphBlt(DrawablePtr	    pDrawable,
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXdispatch.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXdispatch.c.NX.patch
new file mode 100644
index 0000000..d9e35f7
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXdispatch.c.NX.patch
@@ -0,0 +1,1036 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original	2015-02-13 14:03:44.740441589 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c	2015-02-13 14:03:44.740441589 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+ /* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+ /************************************************************
+@@ -87,6 +104,15 @@
+ int ProcInitialConnection();
+ #endif
+ 
++#ifdef __sun
++#define False 0
++#define True 1
++#endif
++
++#define GC XlibGC
++#include <X11/Xlib.h>
++#undef GC
++
+ #include "windowstr.h"
+ #include <X11/fonts/fontstruct.h>
+ #include "dixfontstr.h"
+@@ -100,7 +126,7 @@
+ #include "servermd.h"
+ #include "extnsionst.h"
+ #include "dixfont.h"
+-#include "dispatch.h"
++#include "../../dix/dispatch.h"
+ #include "swaprep.h"
+ #include "swapreq.h"
+ #ifdef PANORAMIX
+@@ -119,8 +145,69 @@
+ #include "inputstr.h"
+ #include <X11/extensions/XKBsrv.h>
+ #endif
++
++#include "Atoms.h"
++#include "Splash.h"
++#include "Client.h"
++#include "Clipboard.h"
++#include "Reconnect.h"
++#include "Millis.h"
++#include "Font.h"
++#include "Shadow.h"
++#include "Handlers.h"
++#include "Keyboard.h"
++
++const int nxagentMaxFontNames = 10000;
++
++char dispatchExceptionAtReset = DE_RESET;
++
++/*
++ * This allows the agent to exit if no
++ * client is connected within a timeout.
++ */
++
++int nxagentClients = 0;
++
++void nxagentWaitDisplay(void);
++
++void nxagentListRemoteFonts(const char *, int);
++
++unsigned int nxagentWMtimeout = 0;
++Bool         nxagentWMPassed  = 0;
++
++/*
++ * Timeouts based on screen saver time.
++ */
++
++int nxagentAutoDisconnectTimeout = 0;
++
+ #ifdef LBX
+-#include "lbxserve.h"
++#include "../../lbx/lbxserve.h"
++#endif
++
++#include "Xatom.h"
++
++/*
++ * Set here the required log level.
++ */
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  WATCH
++
++/*
++ * Log begin and end of the important handlers.
++ */
++
++#undef  BLOCKS
++
++#ifdef WATCH
++#include "unistd.h"
++#endif
++
++#ifdef TEST
++#include "Literals.h"
+ #endif
+ 
+ #define mskcnt ((MAXCLIENTS + 31) / 32)
+@@ -138,6 +225,28 @@
+ int NumCurrentSelections;
+ CallbackListPtr SelectionCallback = NULL;
+ 
++#ifdef VIEWPORT_FRAME
++
++extern WindowPtr nxagentViewportFrameLeft;
++extern WindowPtr nxagentViewportFrameRight;
++extern WindowPtr nxagentViewportFrameAbove;
++extern WindowPtr nxagentViewportFrameBelow;
++
++#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
++                                   (pWin) == nxagentViewportFrameRight || \
++                                       (pWin) == nxagentViewportFrameAbove || \
++                                           (pWin) == nxagentViewportFrameBelow)
++
++#else
++
++#define IsViewportFrame(pWin) (0)
++
++#endif /* #ifdef VIEWPORT_FRAME */
++
++extern int nxagentMaxAllowedResets;
++
++extern int nxagentFindClientResource(int, RESTYPE, pointer);
++
+ static ClientPtr grabClient;
+ #define GrabNone 0
+ #define GrabActive 1
+@@ -222,6 +331,30 @@
+ 	xfree(CurrentSelections);
+     CurrentSelections = (Selection *)NULL;
+     NumCurrentSelections = 0;
++
++#ifdef NXAGENT_CLIPBOARD
++    {
++      Selection *newsels;
++      newsels = (Selection *)xalloc(2 * sizeof(Selection));
++      if (!newsels)
++        return;
++      NumCurrentSelections += 2;
++      CurrentSelections = newsels;
++
++      CurrentSelections[0].selection = XA_PRIMARY;
++      CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
++      CurrentSelections[0].window = WindowTable[0]->drawable.id;
++      CurrentSelections[0].pWin = NULL;
++      CurrentSelections[0].client = NullClient;
++
++      CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
++      CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
++      CurrentSelections[1].window = WindowTable[0]->drawable.id;
++      CurrentSelections[1].pWin = NULL;
++      CurrentSelections[1].client = NullClient;
++    }
++#endif
++
+ }
+ 
+ void 
+@@ -369,14 +502,72 @@
+     long			start_tick;
+ #endif
+ 
++    unsigned long currentDispatch = 0;
++
+     nextFreeClientID = 1;
+     InitSelections();
+     nClients = 0;
+ 
++    /*
++     * The agent initialization was successfully
++     * completed. We can now handle our clients.
++     */
++
++    #ifdef XKB
++
++    nxagentInitXkbWrapper();
++
++    nxagentTuneXkbWrapper();
++
++    #endif
++
++    #ifdef NXAGENT_ONSTART
++
++    /*
++     * Set NX_WM property (used by NX client to identify
++     * the agent's window) three seconds since the first
++     * client connects.
++     */
++
++    nxagentWMtimeout = GetTimeInMillis() + 3000;
++
++    #endif
++
+     clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+     if (!clientReady)
+ 	return;
+ 
++  #ifdef WATCH
++
++  fprintf(stderr, "Dispatch: Watchpoint 12.\n");
++
++/*
++Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
++------- -----	------	-------			--------		----------	  -----
++#3      1		352 bits (0 KB) ->	236 bits (0 KB) ->	352/1 -> 236/1	= 1.492:1
++#14     1		256 bits (0 KB) ->	101 bits (0 KB) ->	256/1 -> 101/1	= 2.535:1
++#16     1		256 bits (0 KB) ->	26 bits (0 KB) ->	256/1 -> 26/1	= 9.846:1
++#20     2	2	12256 bits (1 KB) ->	56 bits (0 KB) ->	6128/1 -> 28/1	= 218.857:1
++#43     1		256 bits (0 KB) ->	45 bits (0 KB) ->	256/1 -> 45/1	= 5.689:1
++#47     2	2	42304 bits (5 KB) ->	49 bits (0 KB) ->	21152/1 -> 24/1	= 863.347:1
++#98     1		256 bits (0 KB) ->	34 bits (0 KB) ->	256/1 -> 34/1	= 7.529:1
++*/
++
++  sleep(30);
++
++  #endif
++
++  #ifdef TEST
++  fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
++              dispatchException);
++
++  fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
++              dispatchExceptionAtReset);
++  #endif
++
++  if (!(dispatchException & DE_TERMINATE))
++    dispatchException = 0;
++
+     while (!dispatchException)
+     {
+         if (*icheck[0] != *icheck[1])
+@@ -385,8 +576,75 @@
+ 	    FlushIfCriticalOutputPending();
+ 	}
+ 
++        /*
++         * Ensure we remove the splash after the timeout.
++         * Initializing clientReady[0] to -1 will tell
++         * WaitForSomething() to yield control after the
++         * timeout set in clientReady[1].
++         */
++
++        clientReady[0] = 0;
++
++        if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
++        {
++          #ifdef TEST
++          fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
++                      NXAGENT_WAKEUP);
++          #endif
++
++          clientReady[0] = -1;
++          clientReady[1] = NXAGENT_WAKEUP;
++        }
++
++        if (serverGeneration > nxagentMaxAllowedResets &&
++                nxagentSessionState == SESSION_STARTING &&
++                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
++        {
++          #ifdef NX_DEBUG_INPUT
++          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
++                      GetTimeAsString(), GetTimeInMillis());
++          #else
++          fprintf(stderr, "Session: Session started at '%s'.\n",
++                      GetTimeAsString());
++          #endif
++
++          nxagentSessionState = SESSION_UP;
++        }
++
++        #ifdef BLOCKS
++        fprintf(stderr, "[End dispatch]\n");
++        #endif
++
+ 	nready = WaitForSomething(clientReady);
+ 
++        #ifdef BLOCKS
++        fprintf(stderr, "[Begin dispatch]\n");
++        #endif
++
++        #ifdef TEST
++        fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
++                    nready);
++        #endif
++        
++        #ifdef NXAGENT_ONSTART
++
++        currentDispatch = GetTimeInMillis();
++
++        /*
++         * If the timeout is expired set the
++         * selection informing the NX client
++         * that the agent is ready.
++         */
++
++         if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
++         {
++           nxagentRemoveSplashWindow(NULL);
++         }
++
++         nxagentClients = nClients;
++
++         #endif
++
+ #ifdef SMART_SCHEDULE
+ 	if (nready && !SmartScheduleDisable)
+ 	{
+@@ -438,6 +696,11 @@
+ #endif
+ 		/* now, finally, deal with client requests */
+ 
++                #ifdef TEST
++                fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
++                            client->index);
++                #endif
++
+ 	        result = ReadRequestFromClient(client);
+ 	        if (result <= 0) 
+ 	        {
+@@ -445,6 +708,29 @@
+ 			CloseDownClient(client);
+ 		    break;
+ 	        }
++#ifdef NXAGENT_SERVER
++
++                #ifdef TEST
++
++                else
++                {
++
++                    if (MAJOROP > 127)
++                    {
++                      fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
++                                  "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
++                                      client->req_len << 2, client->index);
++                    }
++                    else
++                    {
++                      fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
++                                  nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
++                                      client->index);
++                    }
++                }
++
++                #endif
++#endif
+ 
+ 		client->sequence++;
+ #ifdef DEBUG
+@@ -456,8 +742,40 @@
+ 		if (result > (maxBigRequestSize << 2))
+ 		    result = BadLength;
+ 		else
++#ifdef NXAGENT_SERVER
++                {
++                    result = (* client->requestVector[MAJOROP])(client);
++
++                    #ifdef TEST
++
++                    if (MAJOROP > 127)
++                    {
++                      fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
++                                  "size [%d] client [%d] result [%d].\n", MAJOROP,
++                                      *((char *) client->requestBuffer + 1), client->req_len << 2,
++                                          client->index, result);
++                    }
++                    else
++                    {
++                      fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
++                                  "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
++                                      client->req_len << 2, client->index, result);
++                    }
++
++                    #endif
++
++                    /*
++                     * Can set isItTimeToYield to force
++                     * the dispatcher to pay attention
++                     * to another client.
++                     */
++
++                    nxagentDispatchHandler(client, client->req_len << 2, 0);
++                }
++#else
+ 		    result = (* client->requestVector[MAJOROP])(client);
+-	    
++#endif
++
+ 		if (result != Success) 
+ 		{
+ 		    if (client->noClientException != Success)
+@@ -485,6 +803,37 @@
+ #if defined(DDXBEFORERESET)
+     ddxBeforeReset ();
+ #endif
++    if ((dispatchException & DE_RESET) && 
++            (serverGeneration > nxagentMaxAllowedResets))
++    {
++        dispatchException &= ~DE_RESET;
++        dispatchException |= DE_TERMINATE;
++
++        fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
++    }
++
++    nxagentResetAtomMap();
++
++    if (serverGeneration > nxagentMaxAllowedResets)
++    {
++      /*
++       * The session is terminating. Force an I/O
++       * error on the display and wait until the
++       * NX transport is gone.
++       */
++  
++      fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
++
++      nxagentWaitDisplay();
++
++      fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
++    }
++
++    if (nxagentOption(Shadow) == 1)
++    {
++      NXShadowDestroy();
++    }
++
+     KillAllClients();
+     DEALLOCATE_LOCAL(clientReady);
+     dispatchException &= ~DE_RESET;
+@@ -656,6 +1005,12 @@
+ 					   SecurityWriteAccess);
+     if (!pWin)
+         return(BadWindow);
++
++    if (!nxagentWMPassed)
++    {
++      nxagentRemoveSplashWindow(pWin);
++    }
++
+     pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+ 					      SecurityWriteAccess);
+     if (!pParent)
+@@ -724,6 +1079,7 @@
+         return(BadWindow);
+     UnmapWindow(pWin, FALSE);
+            /* update cache to say it is mapped */
++
+     return(client->noClientException);
+ }
+ 
+@@ -760,6 +1116,7 @@
+         return BadLength;
+     result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+ 			      client);
++
+     if (client->noClientException != Success)
+         return(client->noClientException);
+     else
+@@ -865,7 +1222,12 @@
+         reply.parent = (Window)None;
+     pHead = RealChildHead(pWin);
+     for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
++    {
++      if (!IsViewportFrame(pChild))
++      {
+ 	numChildren++;
++      }
++    }
+     if (numChildren)
+     {
+ 	int curChild = 0;
+@@ -874,7 +1236,12 @@
+ 	if (!childIDs)
+ 	    return BadAlloc;
+ 	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
++        {
++          if (!IsViewportFrame(pChild))
++          {
+ 	    childIDs[curChild++] = pChild->drawable.id;
++          }
++        }
+     }
+     
+     reply.nChildren = numChildren;
+@@ -1038,6 +1405,16 @@
+ 	    info.kind= SelectionSetOwner;
+ 	    CallCallbacks(&SelectionCallback, &info);
+ 	}
++
++#ifdef NXAGENT_CLIPBOARD
++      if ((CurrentSelections[i].pWin != NULL) &&
++              (nxagentOption(Clipboard) != ClipboardNone) &&
++                  ((CurrentSelections[i].selection == XA_PRIMARY) ||
++                       (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
++      {
++        nxagentSetSelectionOwner(&CurrentSelections[i]);
++      }
++#endif
+ 	return (client->noClientException);
+     }
+     else 
+@@ -1092,6 +1469,27 @@
+     if (!pWin)
+         return(BadWindow);
+ 
++#ifdef NXAGENT_CLIPBOARD
++    if (((stuff->selection == XA_PRIMARY) ||
++           (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
++               nxagentOption(Clipboard) != ClipboardNone)
++    {
++      int i = 0;
++
++      while ((i < NumCurrentSelections) &&
++                CurrentSelections[i].selection != stuff->selection) i++;
++
++      if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
++      {
++        if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
++                                       stuff->property, stuff->target, stuff->time))
++        {
++          return (client->noClientException);
++        }
++      }
++    }
++#endif
++
+     paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+     if (stuff->property != None)
+ 	paramsOkay &= ValidAtom(stuff->property);
+@@ -1103,7 +1501,7 @@
+ 	while ((i < NumCurrentSelections) && 
+ 	       CurrentSelections[i].selection != stuff->selection) i++;
+ 	if ((i < NumCurrentSelections) && 
+-	    (CurrentSelections[i].window != None)
++	    (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+ #ifdef XCSECURITY
+ 	    && (!client->CheckAccess ||
+ 		(* client->CheckAccess)(client, CurrentSelections[i].window,
+@@ -1286,11 +1684,26 @@
+ ProcOpenFont(register ClientPtr client)
+ {
+     int	err;
++    char fontReq[256];
+     REQUEST(xOpenFontReq);
+ 
+     REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+     client->errorValue = stuff->fid;
+     LEGAL_NEW_RESOURCE(stuff->fid, client);
++
++    memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
++    fontReq[stuff->nbytes]=0;
++    if (strchr(fontReq,'*') || strchr(fontReq,'?'))
++    {
++       extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
++#ifdef NXAGENT_FONTMATCH_DEBUG
++       fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
++#endif
++       nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
++       err = nxOpenFont(client, stuff->fid, (Mask) 0,
++		stuff->nbytes, (char *)&stuff[1]);
++    }
++    else
+     err = OpenFont(client, stuff->fid, (Mask) 0,
+ 		stuff->nbytes, (char *)&stuff[1]);
+     if (err == Success)
+@@ -1310,8 +1723,43 @@
+     REQUEST_SIZE_MATCH(xResourceReq);
+     pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ 					    SecurityDestroyAccess);
+-    if ( pFont != (FontPtr)NULL)	/* id was valid */
++    if (pFont != (FontPtr)NULL)
+     {
++        #ifdef NXAGENT_SERVER
++
++        /*
++         * When a client closes a font the resource
++         * should not be lost if the reference counter
++         * is not 0, otherwise the server will not be
++         * able to find this font looping through the
++         * resources.
++         */
++
++        if (pFont -> refcnt > 0)
++        {
++          if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
++          {
++            #ifdef TEST
++            fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
++                        (void *) pFont);
++            #endif
++
++            nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
++
++            AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
++
++          }
++          #ifdef TEST
++          else
++          {
++            fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
++                        "resource switching skipped.\n", (void *) pFont);
++          }
++          #endif
++        }
++
++        #endif
++
+         FreeResource(stuff->id, RT_NONE);
+ 	return(client->noClientException);
+     }
+@@ -1332,6 +1780,8 @@
+ 
+     REQUEST_SIZE_MATCH(xResourceReq);
+     client->errorValue = stuff->id;		/* EITHER font or gc */
++
++    pFont = NULL;
+     pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+ 					    SecurityReadAccess);
+     if (!pFont)
+@@ -1347,6 +1797,33 @@
+ 	pFont = pGC->font;
+     }
+ 
++/* test
++{
++  Atom name_atom, value_atom;
++  int nprops;
++  FontPropPtr props;
++  int i;
++  char *name;
++
++  name_atom = MakeAtom("FONT", 4, True);
++  value_atom = 0L;
++
++  nprops = pFont->info.nprops;
++  props = pFont->info.props;
++
++  for (i = 0; i < nprops; i++)
++    if (props[i].name == name_atom) {
++      value_atom = props[i].value;
++      break;
++    }
++
++  if (!value_atom) return (BadFont);
++
++  name = (char *)NameForAtom(value_atom);
++  fprintf(stderr, "QueryFont: font name [%s]\n",name);
++}
++ end test */
++
+     {
+ 	xCharInfo	*pmax = FONTINKMAX(pFont);
+ 	xCharInfo	*pmin = FONTINKMIN(pFont);
+@@ -1364,6 +1841,7 @@
+ 	rlength = sizeof(xQueryFontReply) +
+ 	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+ 		     nprotoxcistructs * sizeof(xCharInfo);
++        reply = NULL;
+ 	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+ 	if(!reply)
+ 	{
+@@ -1434,10 +1912,18 @@
+ int
+ ProcListFonts(register ClientPtr client)
+ {
++    char tmp[256];
++
+     REQUEST(xListFontsReq);
+ 
+     REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
++    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
++    tmp[stuff->nbytes]=0;
+ 
++#ifdef NXAGENT_FONTMATCH_DEBUG
++    fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
++#endif
++    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+     return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+ 	stuff->maxNames);
+ }
+@@ -1445,10 +1931,18 @@
+ int
+ ProcListFontsWithInfo(register ClientPtr client)
+ {
++    char tmp[256];
+     REQUEST(xListFontsWithInfoReq);
+ 
+     REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+ 
++    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
++    tmp[stuff->nbytes]=0;
++#ifdef NXAGENT_FONTMATCH_DEBUG
++    fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
++#endif
++    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
++
+     return StartListFontsWithInfo(client, stuff->nbytes,
+ 				  (unsigned char *) &stuff[1], stuff->maxNames);
+ }
+@@ -1535,6 +2029,40 @@
+ 					     SecurityDestroyAccess);
+     if (pMap) 
+     {
++        #ifdef NXAGENT_SERVER
++
++        /*
++         * When a client releases a pixmap the resource
++         * should not be lost if the reference counter
++         * is not 0, otherwise the server will not be
++         * able to find this pixmap looping through the
++         * resources.
++         */
++
++        if (pMap -> refcnt > 0)
++        {
++          if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
++          {
++            #ifdef TEST
++            fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
++                       (void *) pMap);
++            #endif
++
++            nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
++
++            AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
++          }
++          #ifdef TEST
++          else
++          {
++            fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
++                        "resource switching skipped.\n", (void *) pMap);
++          }
++          #endif
++        }
++
++        #endif
++
+ 	FreeResource(stuff->id, RT_NONE);
+ 	return(client->noClientException);
+     }
+@@ -1819,8 +2347,10 @@
+     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+     npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+     if (npoint)
++    {
+         (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ 			  (xPoint *) &stuff[1]);
++    }
+     return (client->noClientException);
+ }
+ 
+@@ -1842,8 +2372,10 @@
+     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+     npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+     if (npoint > 1)
++    {
+ 	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+ 			      (DDXPointPtr) &stuff[1]);
++    }
+     return(client->noClientException);
+ }
+ 
+@@ -1862,7 +2394,9 @@
+ 	return(BadLength);
+     nsegs >>= 3;
+     if (nsegs)
++    {
+         (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
++    }
+     return (client->noClientException);
+ }
+ 
+@@ -1881,8 +2415,10 @@
+ 	return(BadLength);
+     nrects >>= 3;
+     if (nrects)
++    {
+         (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+ 		    nrects, (xRectangle *) &stuff[1]);
++    }
+     return(client->noClientException);
+ }
+ 
+@@ -1901,7 +2437,9 @@
+ 	return(BadLength);
+     narcs /= sizeof(xArc);
+     if (narcs)
++    {
+         (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
++    }
+     return (client->noClientException);
+ }
+ 
+@@ -1930,9 +2468,11 @@
+     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+     things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+     if (things)
++    {
+         (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ 			 stuff->coordMode, things,
+ 			 (DDXPointPtr) &stuff[1]);
++    }
+     return(client->noClientException);
+ }
+ 
+@@ -1952,8 +2492,10 @@
+     things >>= 3;
+ 
+     if (things)
++    {
+         (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ 		      (xRectangle *) &stuff[1]);
++    }
+     return (client->noClientException);
+ }
+ 
+@@ -1972,7 +2514,9 @@
+ 	return(BadLength);
+     narcs /= sizeof(xArc);
+     if (narcs)
++    {
+         (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
++    }
+     return (client->noClientException);
+ }
+ 
+@@ -3127,7 +3671,14 @@
+ 	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+ 
+     if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
++    {
++        #ifdef TEST
++        fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
++        #endif
++
+ 	    return (client->noClientException);
++    }
++
+     return BadAlloc;
+ }
+ 
+@@ -3243,25 +3794,68 @@
+         return BadValue;
+     }
+ 
+-    if (blankingOption == DefaultBlanking)
++    /*
++     * The NX agent uses the screen saver procedure
++     * to monitor the user activities and launch its
++     * handlers (like timeout feature), so we can't
++     * always allow the clients to change our values.
++     */
++
++    #ifdef TEST
++    fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
++                stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
++    #endif
++
++    if (nxagentOption(Timeout) == 0)
++    {
++      if (blankingOption == DefaultBlanking)
++      {
+ 	ScreenSaverBlanking = defaultScreenSaverBlanking;
+-    else
++      }
++      else
++      {
+ 	ScreenSaverBlanking = blankingOption; 
+-    if (exposureOption == DefaultExposures)
++      }
++
++      if (exposureOption == DefaultExposures)
++      {
+ 	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+-    else
+-	ScreenSaverAllowExposures = exposureOption;
++      }
++      else
++      {
++        ScreenSaverAllowExposures = exposureOption;
++      }
++
++      if (stuff->timeout >= 0)
++      {
++        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
++      }
++      else
++      {
++        ScreenSaverTime = defaultScreenSaverTime;
++      }
++
++      if (stuff->interval >= 0)
++      {
++        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
++      }
++      else
++      {
++        ScreenSaverInterval = defaultScreenSaverInterval;
++      }
++
++      SetScreenSaverTimer();
++    }
++    #ifdef TEST
+ 
+-    if (stuff->timeout >= 0)
+-	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+-    else 
+-	ScreenSaverTime = defaultScreenSaverTime;
+-    if (stuff->interval >= 0)
+-	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+     else
+-	ScreenSaverInterval = defaultScreenSaverInterval;
++    {
++      fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
++                  nxagentOption(Timeout));
++    }
++
++    #endif
+ 
+-    SetScreenSaverTimer();
+     return (client->noClientException);
+ }
+ 
+@@ -3481,7 +4075,30 @@
+ 	client->errorValue = stuff->mode;
+         return BadValue;
+     }
+-    SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
++
++    /*
++     * The NX agent uses the screen saver procedure
++     * to monitor the user activities and launch its
++     * handlers (like timeout feature), so we can't
++     * always allow the clients to force the screen
++     * saver handler execution.
++     */
++
++    if (nxagentOption(Timeout) == 0)
++    {
++      SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
++    }
++
++    #ifdef TEST
++
++    else
++    {
++      fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
++                  stuff -> mode);
++    }
++
++    #endif
++
+     return client->noClientException;
+ }
+ 
+@@ -3525,14 +4142,34 @@
+  *  then killed again, the client is really destroyed.
+  *********************/
+ 
+-char dispatchExceptionAtReset = DE_RESET;
+-
+ void
+ CloseDownClient(register ClientPtr client)
+ {
+     Bool really_close_down = client->clientGone ||
+ 			     client->closeDownMode == DestroyAll;
+ 
++    /*
++     * There must be a better way to hook a
++     * call-back function to be called any
++     * time a client is going to be closed.
++     */
++
++    nxagentClearClipboard(client, NULL);
++
++    /*
++     * Need to reset the karma counter and
++     * get rid of the pending sync replies.
++     */
++
++    nxagentWakeupByReset(client);
++
++    /*
++     * Check if the client
++     * is a shadow nxagent.
++     */
++
++    nxagentCheckIfShadowAgent(client);
++
+     if (!client->clientGone)
+     {
+ 	/* ungrab server if grabbing client dies */
+@@ -3673,7 +4310,7 @@
+     client->numSaved = 0;
+     client->saveSet = (SaveSetElt *)NULL;
+     client->noClientException = Success;
+-#ifdef DEBUG
++#ifdef LOG_DEBUG
+     client->requestLogIndex = 0;
+ #endif
+     client->requestVector = InitialVector;
+@@ -3746,6 +4383,13 @@
+ 	else
+ 	    ppriv->ptr = (pointer)NULL;
+     }
++
++    /*
++     * Initialize the private members.
++     */
++
++    nxagentInitClientPrivates(client);
++
+     return 1;
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch
new file mode 100644
index 0000000..f491948
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXdixfonts.c.NX.patch
@@ -0,0 +1,892 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c	2015-02-13 14:03:44.744441510 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+ /* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+ /************************************************************************
+@@ -68,12 +85,84 @@
+ #include "dixfontstr.h"
+ #include "closestr.h"
+ 
++/*
++#define NXAGENT_DEBUG
++*/
++
+ #ifdef DEBUG
+ #include	<stdio.h>
+ #endif
+ 
++#include "Agent.h"
++#include "Font.h"
++
++#ifndef NX_TRANS_SOCKET
++
++#define NX_TRANS_SOCKET
++
++#endif
++
++#ifdef NX_TRANS_SOCKET
++
++char _NXFontPath[1024];
++
++/*
++ * Override the default font path and make
++ * it configurable at run time, based on
++ * the NX_FONT environment.
++ */
++
++static const char *_NXGetFontPath(const char *path)
++{
++  const char *fontEnv;
++
++    /*
++     * Check the environment only once.
++     */
++
++    if (*_NXFontPath != '\0')
++    {
++        return _NXFontPath;
++    }
++
++    fontEnv = getenv("NX_FONT");
++
++    if (fontEnv != NULL && *fontEnv != '\0')
++    {
++        if (strlen(fontEnv) + 1 > 1024)
++        {
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
++#endif
++            goto _NXGetFontPathError;
++        }
++
++        strcpy(_NXFontPath, fontEnv);
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
++#endif
++
++        return _NXFontPath;
++    }
++
++_NXGetFontPathError:
++
++    strncpy(_NXFontPath, path, 1023);
++    _NXFontPath[1023] = '\0';
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
++#endif
++
++    return _NXFontPath;
++}
++
++#endif
++
+ #ifdef PANORAMIX
+-#include "panoramiX.h"
++#include "../../Xext/panoramiX.h"
++#include "../../Xext/panoramiXsrv.h"
+ #endif
+ 
+ #ifdef LBX
+@@ -245,6 +334,9 @@
+                *newname;
+     int         newlen;
+     int		aliascount = 20;
++    char nxagentOrigFontName[256];
++    int nxagentOrigFontNameLen;
++
+     /*
+      * Decide at runtime what FontFormat to use.
+      */
+@@ -276,6 +368,13 @@
+ 
+ 	BitmapFormatScanlineUnit8;
+ 
++
++    nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
++
++    memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
++
++    nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
++
+     if (client->clientGone)
+     {
+ 	if (c->current_fpe < c->num_fpes)
+@@ -324,6 +423,9 @@
+ 	    if (!c->slept) {
+ 		c->slept = TRUE;
+ 		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
++#ifdef NXAGENT_DEBUG
++                fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
++#endif
+ 	    }
+ 	    return TRUE;
+ 	}
+@@ -352,10 +454,15 @@
+ 	    pScr = screenInfo.screens[i];
+ 	    if (pScr->RealizeFont)
+ 	    {
+-		if (!(*pScr->RealizeFont) (pScr, pfont))
++
++                /* NXAGENT uses useless screen pointer to pass the original font name
++                *  to realizeFont, could be a source of problems in the future.
++                */
++
++		if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+ 		{
+ 		    CloseFont (pfont, (Font) 0);
+-		    err = AllocError;
++		    err=BadFontName;
+ 		    goto bail;
+ 		}
+ 	    }
+@@ -365,8 +472,19 @@
+ 	err = AllocError;
+ 	goto bail;
+     }
++    if( nxagentFontPriv(pfont) -> mirrorID == 0 )
++    {
++      extern RESTYPE RT_NX_FONT;
++
++      nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
++      if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
++        FreeResource(c->fontid, RT_NONE);
++        err = AllocError;
++        goto bail;
++      }
++    }
+     if (patternCache && pfont != c->non_cachable_font)
+-	CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
++	CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+ 			 pfont);
+ bail:
+     if (err != Successful && c->client != serverClient) {
+@@ -374,7 +492,12 @@
+ 			  c->fontid, FontToXError(err));
+     }
+     if (c->slept)
++    {
+ 	ClientWakeup(c->client);
++#ifdef NXAGENT_DEBUG
++        fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
++#endif
++    }
+     for (i = 0; i < c->num_fpes; i++) {
+ 	FreeFPE(c->fpe_list[i]);
+     }
+@@ -502,7 +625,10 @@
+ 	LbxFreeFontTag(pfont);
+ #endif
+ #ifdef XF86BIGFONT
+-	XF86BigfontFreeFontShm(pfont);
++        {
++           extern void XF86BigfontFreeFontShm(FontPtr);
++           XF86BigfontFreeFontShm(pfont);
++        }
+ #endif
+ 	fpe = pfont->fpe;
+ 	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+@@ -631,6 +757,9 @@
+ 		    ClientSleep(client,
+ 			(ClientSleepProcPtr)doListFontsAndAliases,
+ 			(pointer) c);
++#ifdef NXAGENT_DEBUG
++                    fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
++#endif
+ 		}
+ 		return TRUE;
+ 	    }
+@@ -677,6 +806,12 @@
+ 				    (ClientSleepProcPtr)doListFontsAndAliases,
+ 				    (pointer) c);
+ 			c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++                        fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
++#endif
++#ifdef NXAGENT_DEBUG
++                        fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
++#endif
+ 		    }
+ 		    return TRUE;
+ 		}
+@@ -813,6 +948,24 @@
+ 	    reply.nFonts--;
+ 	else
+ 	{
++	    {
++	      /* dirty hack: don't list to client fonts not existing on the remote side */
++	      char tmp[256];
++
++	      memcpy(tmp, names->names[i], names->length[i]);
++	      tmp[ names->length[i] ] = 0;
++
++	      if (nxagentFontLookUp(tmp) == 0)
++		{
++#ifdef NXAGENT_FONTMATCH_DEBUG
++		  fprintf(stderr, "doListFontsAndAliases:\n");
++		  fprintf(stderr, "      removing font: %s \n", tmp);
++#endif
++		  reply.nFonts--;
++		  stringLens -= names->length[i];
++		  continue;
++		}
++	    }
+ 	    *bufptr++ = names->length[i];
+ 	    memmove( bufptr, names->names[i], names->length[i]);
+ 	    bufptr += names->length[i];
+@@ -827,7 +980,12 @@
+ 
+ bail:
+     if (c->slept)
++    {
+ 	ClientWakeup(client);
++#ifdef NXAGENT_DEBUG
++        fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
++#endif
++    }
+     for (i = 0; i < c->num_fpes; i++)
+ 	FreeFPE(c->fpe_list[i]);
+     xfree(c->fpe_list);
+@@ -862,7 +1020,7 @@
+ 	xfree(c);
+ 	return BadAlloc;
+     }
+-    c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
++    c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+     if (!c->names)
+     {
+ 	xfree(c->fpe_list);
+@@ -933,6 +1091,9 @@
+  		{
+ 		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ 		    c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++                    fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
++#endif
+ 		}
+ 		return TRUE;
+ 	    }
+@@ -954,6 +1115,9 @@
+ 		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+ 			     c);
+ 		    c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++                    fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
++#endif
+ 		}
+ 		return TRUE;
+ 	    }
+@@ -1035,6 +1199,23 @@
+ 	}
+  	else if (err == Successful)
+  	{
++
++	    if (c->haveSaved)
++ 	    {
++		numFonts = c->savedNumFonts;
++		name = c->savedName;
++		namelen = strlen(name);
++	    }
++
++	   if (nxagentFontLookUp(name) == 0)
++	   {
++#ifdef NXAGENT_FONTMATCH_DEBUG
++	      fprintf(stderr, "doListFontsAndAliases (with info):\n");
++	      fprintf(stderr, "      removing font: %s \n", name);
++#endif
++	       continue;
++           }
++
+ 	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ 	    reply = c->reply;
+ 	    if (c->length < length)
+@@ -1048,12 +1229,6 @@
+ 		c->reply = reply;
+ 		c->length = length;
+ 	    }
+-	    if (c->haveSaved)
+- 	    {
+-		numFonts = c->savedNumFonts;
+-		name = c->savedName;
+-		namelen = strlen(name);
+-	    }
+ 	    reply->type = X_Reply;
+ 	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+ 			     pFontInfo->nprops * sizeof(xFontProp) +
+@@ -1100,7 +1275,12 @@
+     WriteSwappedDataToClient(client, length, &finalReply);
+ bail:
+     if (c->slept)
++    {
+ 	ClientWakeup(client);
++#ifdef NXAGENT_DEBUG
++        fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
++#endif
++    }
+     for (i = 0; i < c->num_fpes; i++)
+ 	FreeFPE(c->fpe_list[i]);
+     xfree(c->reply);
+@@ -1347,6 +1527,11 @@
+ 			err = BadAlloc;
+ 			goto bail;
+ 		    }
++
++                    pGC->tileIsPixel = TRUE;
++                    pGC->tile.pixel = 0;
++                    pGC->stipple = NullPixmap;
++
+ 		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ 				      GCPlaneMask | GCForeground |
+ 				      GCBackground | GCFillStyle |
+@@ -1371,6 +1556,9 @@
+ 		    ClientSleep(client,
+ 		    	     (ClientSleepProcPtr)doPolyText,
+ 			     (pointer) c);
++#ifdef NXAGENT_DEBUG
++                    fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
++#endif
+ 
+ 		    /* Set up to perform steps 3 and 4 */
+ 		    client_state = START_SLEEP;
+@@ -1419,6 +1607,9 @@
+     if (c->slept)
+     {
+ 	ClientWakeup(c->client);
++#ifdef NXAGENT_DEBUG
++        fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
++#endif
+ 	ChangeGC(c->pGC, clearGCmask, clearGC);
+ 
+ 	/* Unreference the font from the scratch GC */
+@@ -1535,6 +1726,11 @@
+ 		err = BadAlloc;
+ 		goto bail;
+ 	    }
++
++            pGC->tileIsPixel = TRUE;
++            pGC->tile.pixel = 0;
++            pGC->stipple = NullPixmap;
++
+ 	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ 			      GCForeground | GCBackground | GCFillStyle |
+ 			      GCTile | GCStipple | GCTileStipXOrigin |
+@@ -1553,6 +1749,10 @@
+ 
+ 	    c->slept = TRUE;
+             ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
++#ifdef NXAGENT_DEBUG
++            fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
++#endif
++
+         }
+         return TRUE;
+     }
+@@ -1575,6 +1775,9 @@
+     if (c->slept)
+     {
+ 	ClientWakeup(c->client);
++#ifdef NXAGENT_DEBUG
++        fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
++#endif
+ 	ChangeGC(c->pGC, clearGCmask, clearGC);
+ 
+ 	/* Unreference the font from the scratch GC */
+@@ -1751,11 +1954,13 @@
+ 		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ 		if (err != Successful)
+ 		{
++                    #ifndef NXAGENT_SERVER
+ 		    if (persist)
+ 		    {
+ 			ErrorF("Could not init font path element %s, removing from list!\n",
+ 			       fpe->name);
+ 		    }
++                    #endif
+ 		    xfree (fpe->name);
+ 		    xfree (fpe);
+ 		}
+@@ -1817,11 +2022,19 @@
+                 bad;
+ 
+     /* get enough for string, plus values -- use up commas */
++#ifdef NX_TRANS_SOCKET
++    len = strlen(_NXGetFontPath(path)) + 1;
++#else
+     len = strlen(path) + 1;
++#endif
+     nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+     if (!newpath)
+ 	return BadAlloc;
++#ifdef NX_TRANS_SOCKET
++    pp = (unsigned char *) _NXGetFontPath(path);
++#else
+     pp = (unsigned char *) path;
++#endif
+     cp++;
+     while (*pp) {
+ 	if (*pp == ',') {
+@@ -2148,3 +2361,445 @@
+ }
+ 
+ #endif
++
++
++typedef struct
++{
++   LFclosurePtr c;
++   OFclosurePtr oc;
++} nxFs,*nxFsPtr;
++
++static Bool
++#if NeedFunctionPrototypes
++nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
++#else
++nxdoListFontsAndAliases(client, fss)
++    ClientPtr   client;
++    nxFsPtr fss;
++#endif
++{
++    LFclosurePtr c=fss->c;
++    OFclosurePtr oc=fss->oc;
++    FontPathElementPtr fpe;
++    int         err = Successful;
++    char       *name, *resolved=NULL;
++    int         namelen, resolvedlen;
++    int         i;
++    int		aliascount = 0;
++    char        tmp[256];
++    tmp[0]=0;
++    if (client->clientGone)
++    {
++	if (c->current.current_fpe < c->num_fpes)
++	{
++	    fpe = c->fpe_list[c->current.current_fpe];
++	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
++	}
++	err = Successful;
++	goto bail;
++    }
++
++    if (!c->current.patlen)
++	goto finish;
++
++    while (c->current.current_fpe < c->num_fpes) {
++	fpe = c->fpe_list[c->current.current_fpe];
++	err = Successful;
++
++	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
++	{
++	    /* This FPE doesn't support/require list_fonts_and_aliases */
++
++	    err = (*fpe_functions[fpe->type].list_fonts)
++		((pointer) c->client, fpe, c->current.pattern,
++		 c->current.patlen, c->current.max_names - c->names->nnames,
++		 c->names);
++
++	    if (err == Suspended) {
++		if (!c->slept) {
++		    c->slept = TRUE;
++		    ClientSleep(client,
++			(ClientSleepProcPtr)nxdoListFontsAndAliases,
++			(pointer) fss);
++#ifdef NXAGENT_DEBUG
++                    fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
++#endif
++		}
++		return TRUE;
++	    }
++
++	    err = BadFontName;
++	}
++	else
++	{
++	    /* Start of list_fonts_and_aliases functionality.  Modeled
++	       after list_fonts_with_info in that it resolves aliases,
++	       except that the information collected from FPEs is just
++	       names, not font info.  Each list_next_font_or_alias()
++	       returns either a name into name/namelen or an alias into
++	       name/namelen and its target name into resolved/resolvedlen.
++	       The code at this level then resolves the alias by polling
++	       the FPEs.  */
++
++	    if (!c->current.list_started) {
++		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
++		    ((pointer) c->client, fpe, c->current.pattern,
++		     c->current.patlen, c->current.max_names - c->names->nnames,
++		     &c->current.private);
++		if (err == Suspended) {
++		    if (!c->slept) {
++			ClientSleep(client,
++				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
++				    (pointer) fss);
++			c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++                        fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
++#endif
++		    }
++		    return TRUE;
++		}
++		if (err == Successful)
++		    c->current.list_started = TRUE;
++	    }
++	    if (err == Successful) {
++		char    *tmpname;
++		name = 0;
++		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
++		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
++		     &resolvedlen, c->current.private);
++		if (err == Suspended) {
++		    if (!c->slept) {
++			ClientSleep(client,
++				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
++				    (pointer) fss);
++			c->slept = TRUE;
++#ifdef NXAGENT_DEBUG
++                        fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
++#endif
++		    }
++		    return TRUE;
++		}
++		if (err == FontNameAlias) {
++		    if (resolved) xfree(resolved);
++		    resolved = (char *) xalloc(resolvedlen + 1);
++		    if (resolved)
++                    {
++                        memmove(resolved, tmpname, resolvedlen);
++                        resolved[resolvedlen] = '\0';
++                    }
++		}
++	    }
++
++	    if (err == Successful)
++	    {
++		if (c->haveSaved)
++		{
++		    if (c->savedName)
++		    {
++		       memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
++		       tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
++		       if (nxagentFontLookUp(tmp))
++		          break;
++			else tmp[0]=0;
++		    }
++		}
++		else
++		{
++		   memcpy(tmp,name,namelen>255?255:namelen);
++		   tmp[namelen>255?256:namelen]=0;
++		   if (nxagentFontLookUp(tmp))
++		      break;
++		   else tmp[0]=0;
++		}
++	    }
++
++	    /*
++	     * When we get an alias back, save our state and reset back to
++	     * the start of the FPE looking for the specified name.  As
++	     * soon as a real font is found for the alias, pop back to the
++	     * old state
++	     */
++	    else if (err == FontNameAlias) {
++		char	tmp_pattern[XLFDMAXFONTNAMELEN];
++		/*
++		 * when an alias recurses, we need to give
++		 * the last FPE a chance to clean up; so we call
++		 * it again, and assume that the error returned
++		 * is BadFontName, indicating the alias resolution
++		 * is complete.
++		 */
++		memmove(tmp_pattern, resolved, resolvedlen);
++		if (c->haveSaved)
++		{
++		    char    *tmpname;
++		    int     tmpnamelen;
++
++		    tmpname = 0;
++		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
++			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
++			 &tmpname, &tmpnamelen, c->current.private);
++		    if (--aliascount <= 0)
++		    {
++			err = BadFontName;
++			goto ContBadFontName;
++		    }
++		}
++		else
++		{
++		    c->saved = c->current;
++		    c->haveSaved = TRUE;
++		    if (c->savedName)
++			xfree(c->savedName);
++		    c->savedName = (char *)xalloc(namelen + 1);
++		    if (c->savedName)
++                    {
++                        memmove(c->savedName, name, namelen);
++                        c->savedName[namelen] = '\0';
++                    }
++		    c->savedNameLen = namelen;
++		    aliascount = 20;
++		}
++		memmove(c->current.pattern, tmp_pattern, resolvedlen);
++		c->current.patlen = resolvedlen;
++		c->current.max_names = c->names->nnames + 1;
++		c->current.current_fpe = -1;
++		c->current.private = 0;
++		err = BadFontName;
++	    }
++	}
++	/*
++	 * At the end of this FPE, step to the next.  If we've finished
++	 * processing an alias, pop state back. If we've collected enough
++	 * font names, quit.
++	 */
++	if (err == BadFontName) {
++	  ContBadFontName: ;
++	    c->current.list_started = FALSE;
++	    c->current.current_fpe++;
++	    err = Successful;
++	    if (c->haveSaved)
++	    {
++		if (c->names->nnames == c->current.max_names ||
++			c->current.current_fpe == c->num_fpes) {
++		    c->haveSaved = FALSE;
++		    c->current = c->saved;
++		    /* Give the saved namelist a chance to clean itself up */
++		    continue;
++		}
++	    }
++	    if (c->names->nnames == c->current.max_names)
++		break;
++	}
++    }
++
++    /*
++     * send the reply
++     */
++bail:
++finish:
++    if (strlen(tmp))
++    {
++#ifdef NXAGENT_FONTMATCH_DEBUG
++      fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
++#endif
++      memcpy(oc->fontname, tmp, strlen(tmp));
++      oc->fnamelen = strlen(tmp);
++
++      oc->origFontName = oc->fontname;
++      oc->origFontNameLen = oc->fnamelen;
++
++    }
++    else
++    {
++        for (i = 0; i < c->names->nnames; i++)
++	{
++	  if (c->names->length[i] > 255)
++	     continue;
++	  else
++	  {
++	      memcpy(tmp, c->names->names[i], c->names->length[i]);
++	      tmp[ c->names->length[i] ] = 0;
++	      if (nxagentFontLookUp(tmp) == 0)
++		continue;
++	      memcpy(oc->fontname, tmp, strlen(tmp));
++	      oc->fnamelen = strlen(tmp);
++
++              oc->origFontName = oc->fontname;
++              oc->origFontNameLen = oc->fnamelen;
++
++#ifdef NXAGENT_FONTMATCH_DEBUG
++	      fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
++#endif
++	      break;
++	  }
++	}
++    }
++
++    if (c->slept)
++    {
++       ClientWakeup(client);
++#ifdef NXAGENT_DEBUG
++       fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
++#endif
++    }
++    for (i = 0; i < c->num_fpes; i++)
++	FreeFPE(c->fpe_list[i]);
++    xfree(c->fpe_list);
++    if (c->savedName) xfree(c->savedName);
++    FreeFontNames(c->names);
++    xfree(c);
++    xfree(fss);
++    if (resolved) xfree(resolved);
++
++    return doOpenFont(client, oc);
++}
++
++int
++nxOpenFont(client, fid, flags, lenfname, pfontname)
++    ClientPtr   client;
++    XID         fid;
++    Mask        flags;
++    unsigned    lenfname;
++    char       *pfontname;
++{
++    nxFsPtr      fss;
++    LFclosurePtr c;
++    OFclosurePtr oc;
++    int         i;
++    FontPtr     cached = (FontPtr)0;
++
++#ifdef FONTDEBUG
++    char *f;
++    f = (char *)xalloc(lenfname + 1);
++    memmove(f, pfontname, lenfname);
++    f[lenfname] = '\0';
++    ErrorF("OpenFont: fontname is \"%s\"\n", f);
++    xfree(f);
++#endif
++    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
++	return BadName;
++    if (patternCache)
++    {
++
++    /*
++    ** Check name cache.  If we find a cached version of this font that
++    ** is cachable, immediately satisfy the request with it.  If we find
++    ** a cached version of this font that is non-cachable, we do not
++    ** satisfy the request with it.  Instead, we pass the FontPtr to the
++    ** FPE's open_font code (the fontfile FPE in turn passes the
++    ** information to the rasterizer; the fserve FPE ignores it).
++    **
++    ** Presumably, the font is marked non-cachable because the FPE has
++    ** put some licensing restrictions on it.  If the FPE, using
++    ** whatever logic it relies on, determines that it is willing to
++    ** share this existing font with the client, then it has the option
++    ** to return the FontPtr we passed it as the newly-opened font.
++    ** This allows the FPE to exercise its licensing logic without
++    ** having to create another instance of a font that already exists.
++    */
++
++	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
++	if (cached && cached->info.cachable)
++	{
++	    if (!AddResource(fid, RT_FONT, (pointer) cached))
++		return BadAlloc;
++	    cached->refcnt++;
++	    return Success;
++	}
++    }
++    if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
++        return BadAlloc;
++
++    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
++    {
++	xfree(fss);
++	return BadAlloc;
++    }
++        c->fpe_list = (FontPathElementPtr *)
++	xalloc(sizeof(FontPathElementPtr) * num_fpes);
++    if (!c->fpe_list) {
++	xfree(c);
++	xfree(fss);
++	return BadAlloc;
++    }
++    c->names = MakeFontNamesRecord(100);
++    if (!c->names)
++    {
++	xfree(c->fpe_list);
++	xfree(c);
++	xfree(fss);
++	return BadAlloc;
++    }
++    memmove( c->current.pattern, pfontname, lenfname);
++    for (i = 0; i < num_fpes; i++) {
++	c->fpe_list[i] = font_path_elements[i];
++	UseFPE(c->fpe_list[i]);
++    }
++    c->client = client;
++    c->num_fpes = num_fpes;
++    c->current.patlen = lenfname;
++    c->current.current_fpe = 0;
++    c->current.max_names = nxagentMaxFontNames;
++    c->current.list_started = FALSE;
++    c->current.private = 0;
++    c->haveSaved = FALSE;
++    c->slept = FALSE;
++    c->savedName = 0;
++
++    oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
++    if (!oc)
++    {
++      for (i = 0; i < c->num_fpes; i++)
++        FreeFPE(c->fpe_list[i]);
++      xfree(c->fpe_list);
++      xfree(c);
++      xfree(fss);
++      return BadAlloc;
++    }
++    oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
++    oc->origFontName = pfontname;
++    oc->origFontNameLen = lenfname;
++    if (!oc->fontname) {
++      for (i = 0; i < c->num_fpes; i++)
++        FreeFPE(c->fpe_list[i]);
++      xfree(c->fpe_list);
++      xfree(c);
++      xfree(oc);
++      xfree(fss);
++      return BadAlloc;
++    }
++    /*
++     * copy the current FPE list, so that if it gets changed by another client
++     * while we're blocking, the request still appears atomic
++     */
++    oc->fpe_list = (FontPathElementPtr *)
++	xalloc(sizeof(FontPathElementPtr) * num_fpes);
++    if (!oc->fpe_list) {
++	xfree(oc->fontname);
++	xfree(oc);
++      for (i = 0; i < c->num_fpes; i++)
++         FreeFPE(c->fpe_list[i]);
++       xfree(c->fpe_list);
++       xfree(c);
++       xfree(fss);
++       return BadAlloc;
++    }
++    memmove(oc->fontname, pfontname, lenfname);
++    for (i = 0; i < num_fpes; i++) {
++	oc->fpe_list[i] = font_path_elements[i];
++	UseFPE(oc->fpe_list[i]);
++    }
++    oc->client = client;
++    oc->fontid = fid;
++    oc->current_fpe = 0;
++    oc->num_fpes = num_fpes;
++    oc->fnamelen = lenfname;
++    oc->slept = FALSE;
++    oc->flags = flags;
++    oc->non_cachable_font = cached;
++    fss->c=c;
++    fss->oc=oc;
++    nxdoListFontsAndAliases(client, fss);
++    return Success;
++}
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXevents.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXevents.c.NX.patch
new file mode 100644
index 0000000..f2f9e37
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXevents.c.NX.patch
@@ -0,0 +1,648 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c	2015-02-10 19:13:13.788686485 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+ /* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+ /************************************************************
+@@ -116,6 +133,7 @@
+ #endif
+ 
+ #include <X11/X.h>
++#include "Xlib.h"
+ #include "misc.h"
+ #include "resource.h"
+ #define NEED_EVENTS
+@@ -163,7 +181,22 @@
+ 
+ #include "dixevents.h"
+ #include "dixgrabs.h"
+-#include "dispatch.h"
++#include "../../dix/dispatch.h"
++
++#include "NXlib.h"
++
++#include "Events.h"
++#include "Windows.h"
++#include "Args.h"
++
++#ifdef NX_DEBUG_INPUT
++extern int nxagentDebugInput;
++extern int nxagentDebugInputDevices;
++#endif
++ 
++extern Display *nxagentDisplay;
++
++extern WindowPtr nxagentLastEnteredWindow;
+ 
+ #define EXTENSION_EVENT_BASE  64
+ 
+@@ -1322,6 +1355,51 @@
+     mouse->fromPassiveGrab = autoGrab;
+     PostNewCursor();
+     CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
++
++    #ifdef NXAGENT_SERVER
++
++    /*
++     * If grab is synchronous, events are delivered to clients only if they send
++     * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the 
++     * delivered event is saved in a queue and replayed later, when grab is released.
++     * We should  export sync grab to X as async in order to avoid events to be 
++     * queued twice, in the agent and in the X server. This solution have a drawback:
++     * replayed events are not delivered to that application that are not clients of
++     * the agent.
++     * A different solution could be to make the grab asynchronous in the agent and 
++     * to export it as synchronous. But this seems to be less safe.
++     *
++     * To make internal grab asynchronous, change previous line as follows.
++     *
++     * if (nxagentOption(Rootless))
++     * {
++     *   CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
++     * }
++     * else
++     * {
++     *   CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
++     * }
++     */
++
++    if (nxagentOption(Rootless) == 1)
++    {
++      /*
++       * FIXME: We should use the correct value
++       * for the cursor. Temporarily we set it
++       * to None.
++       */
++
++       int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
++                                                 nxagentCollectGrabPointerPredicate);
++
++       NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
++                                1, grab -> eventMask & PointerGrabMask,
++                                    GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
++                                        nxagentWindow(grab -> confineTo) : None,
++                                            None, CurrentTime);
++    }
++
++    #endif
+ }
+ 
+ void
+@@ -1346,6 +1424,22 @@
+     if (grab->cursor)
+ 	FreeCursor(grab->cursor, (Cursor)0);
+     ComputeFreezes();
++
++    #ifdef NXAGENT_SERVER
++
++    if (nxagentOption(Rootless) == 1)
++    {
++      XUngrabPointer(nxagentDisplay, CurrentTime);
++
++      if (sprite.win == ROOT)
++      {
++        mouse -> button -> state &=
++            ~(Button1Mask | Button2Mask | Button3Mask |
++                  Button4Mask | Button5Mask);
++      }
++    }
++
++    #endif
+ }
+ 
+ void
+@@ -1546,6 +1640,17 @@
+ 	    client->errorValue = stuff->mode;
+ 	    return BadValue;
+     }
++
++    /*
++     * This is not necessary if we export grab to X as asynchronous.
++     *
++     * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
++     *         stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
++     * {
++     *   XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
++     * }
++     */
++
+     return Success;
+ }
+ 
+@@ -1582,11 +1687,28 @@
+     int i;
+     int type;
+ 
+-#ifdef DEBUG
++#ifdef NX_DEBUG_INPUT
++    if (grab && nxagentDebugInput && grab->window)
++    {
++	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
++		(unsigned int)grab->window->drawable.id);
++	if (!SameClient(grab, client))
++		fprintf(stderr, "TryClientEvents: Events are going to be "
++			    "discarded.\n");
++    }
++#endif
++#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
++#ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInput == 1)
++	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
++	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
++	client->index);
++#else
+     if (debug_events) ErrorF(
+ 	"Event([%d, %d], mask=0x%x), client=%d",
+ 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+ #endif
++#endif
+     if ((client) && (client != serverClient) && (!client->clientGone) &&
+ 	((filter == CantBeFiltered) || (mask & filter)))
+     {
+@@ -1600,10 +1722,17 @@
+ 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+ 		    pEvents->u.keyButtonPointer.event)
+ 		{
+-#ifdef DEBUG
++#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
++#ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInput == 1)
++    {
++	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
++    }
++#else
+ 		    if (debug_events) ErrorF("\n");
+ 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+ #endif
++#endif
+ 		    return 1; /* don't send, but pretend we did */
+ 		}
+ 		pEvents->u.u.detail = NotifyHint;
+@@ -1640,16 +1769,26 @@
+ 	}
+ 
+ 	WriteEventsToClient(client, count, pEvents);
+-#ifdef DEBUG
++#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
++#ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInput == 1)
++	fprintf(stderr, " delivered\n");
++#else
+ 	if (debug_events) ErrorF(  " delivered\n");
+ #endif
++#endif
+ 	return 1;
+     }
+     else
+     {
+-#ifdef DEBUG
++#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
++#ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInput == 1)
++	fprintf(stderr, "\n");
++#else
+ 	if (debug_events) ErrorF("\n");
+ #endif
++#endif
+ 	return 0;
+     }
+ }
+@@ -1727,6 +1866,12 @@
+ 	tempGrab.pointerMode = GrabModeAsync;
+ 	tempGrab.confineTo = NullWindow;
+ 	tempGrab.cursor = NullCursor;
++        #ifdef NX_DEBUG_INPUT
++        if (nxagentDebugInputDevices == 1)
++        {
++          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
++        }
++        #endif
+ 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+ 					   currentTime, TRUE);
+     }
+@@ -1999,7 +2144,26 @@
+     BoxRec		box;
+ 
+     spriteTraceGood = 1;	/* root window still there */
+-    pWin = ROOT->firstChild;
++
++    if (nxagentOption(Rootless))
++    {
++      if (nxagentLastEnteredWindow == NULL)
++      {
++        return ROOT;
++      }
++
++      pWin = ROOT->lastChild;
++
++      while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
++      {
++        pWin = pWin->prevSib;
++      }
++    }
++    else
++    {
++      pWin = ROOT->firstChild;
++    }
++
+     while (pWin)
+     {
+ 	if ((pWin->mapped) &&
+@@ -2090,13 +2254,22 @@
+ 	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+ #endif
+ 	sprite.hotPhys = sprite.hot;
+-	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+-	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+-	{
+-	    (*sprite.hotPhys.pScreen->SetCursorPosition)(
+-		sprite.hotPhys.pScreen,
+-		sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+-	}
++
++        /*
++         * This code force cursor position to be inside the
++         * root window of the agent. We can't view a reason
++         * to do this and it interacts in an undesirable way
++         * with toggling fullscreen.
++         *
++         * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
++         *          (sprite.hotPhys.y != XE_KBPTR.rootY))
++         * {
++         *   (*sprite.hotPhys.pScreen->SetCursorPosition)(
++         *       sprite.hotPhys.pScreen,
++         *           sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
++         * }
++         */
++
+ 	XE_KBPTR.rootX = sprite.hot.x;
+ 	XE_KBPTR.rootY = sprite.hot.y;
+     }
+@@ -2176,6 +2349,10 @@
+ DefineInitialRootWindow(register WindowPtr win)
+ {
+     register ScreenPtr pScreen = win->drawable.pScreen;
++    #ifdef VIEWPORT_FRAME
++    extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
++    #endif
++    extern int  nxagentShadowInit(ScreenPtr, WindowPtr);
+ 
+     sprite.hotPhys.pScreen = pScreen;
+     sprite.hotPhys.x = pScreen->width / 2;
+@@ -2215,6 +2392,18 @@
+ 	REGION_NULL(pScreen, &sprite.Reg2);
+     }
+ #endif
++
++    #ifdef VIEWPORT_FRAME
++    nxagentInitViewportFrame(pScreen, win);
++    #endif
++
++    if (nxagentOption(Shadow))
++    {
++      if (nxagentShadowInit(pScreen, win) == -1)
++      {
++        FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName);
++      }
++    }
+ }
+ 
+ /*
+@@ -2553,6 +2742,13 @@
+ 				tempGrab.modifiersDetail.exact&(~0x1f00);
+ 	    }
+ #endif
++            #ifdef NX_DEBUG_INPUT
++            if (nxagentDebugInputDevices == 1)
++            {
++              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
++                          device == inputInfo.keyboard ? "keyboard" : "pointer");
++            }
++            #endif
+ 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+  
+ 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+@@ -2911,7 +3107,17 @@
+     else
+ 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+     if (deactivateGrab)
++    #ifdef NX_DEBUG_INPUT
++    {
++      if (nxagentDebugInputDevices == 1)
++      {
++        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
++      }
++    #endif
+         (*keybd->DeactivateGrab)(keybd);
++    #ifdef NX_DEBUG_INPUT
++    }
++    #endif
+ }
+ 
+ #ifdef XKB
+@@ -2961,7 +3167,9 @@
+     Bool                deactivateGrab = FALSE;
+     register ButtonClassPtr butc = mouse->button;
+ #ifdef XKB
+-    XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
++    XkbSrvInfoPtr xkbi;
++
++    xkbi = inputInfo.keyboard->key->xkbInfo;
+ #endif
+ #ifdef XEVIE
+     if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+@@ -2970,6 +3178,12 @@
+         xevieEventSent = 0;
+       else {
+         xeviemouse = mouse;
++        #ifdef NX_DEBUG_INPUT
++        if (nxagentDebugInput == 1)
++        {
++          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
++        }
++        #endif
+         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+         return;
+       }
+@@ -3024,14 +3238,38 @@
+ #if !defined(XFree86Server) || !defined(XINPUT)
+ 	    xE->u.u.detail = butc->map[key];
+ #endif
++	    #ifdef NX_DEBUG_INPUT
++	    if (xE->u.u.detail == 0)
++	    {
++		if (nxagentDebugInput == 1)
++		{
++		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
++			    " for ButtonPress.\n");
++		}
++		return;
++	    }
++	    #else
+ 	    if (xE->u.u.detail == 0)
+ 		return;
++	    #endif
+ 	    if (xE->u.u.detail <= 5)
+ 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+ 	    filters[MotionNotify] = Motion_Filter(butc);
+ 	    if (!grab)
++	    #ifdef NX_DEBUG_INPUT
++		if (CheckDeviceGrabs(mouse, xE, 0, count))
++		{
++		    if (nxagentDebugInput == 1)
++		    {
++			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
++				" returned True for ButtonPress.\n");
++		    }
++		    return;
++		}
++	    #else
+ 		if (CheckDeviceGrabs(mouse, xE, 0, count))
+ 		    return;
++	    #endif
+ 	    break;
+ 	case ButtonRelease: 
+ 	    mouse->valuator->motionHintWindow = NullWindow;
+@@ -3043,8 +3281,20 @@
+ #if !defined(XFree86Server) || !defined(XINPUT)
+ 	    xE->u.u.detail = butc->map[key];
+ #endif
++	    #ifdef NX_DEBUG_INPUT
+ 	    if (xE->u.u.detail == 0)
++	    {
++		if (nxagentDebugInput == 1)
++		{
++		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
++			    " for ButtonRelease.\n");
++		}
+ 		return;
++	    }
++	    #else
++	    if (xE->u.u.detail == 0)
++		return;
++	    #endif
+ 	    if (xE->u.u.detail <= 5)
+ 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+ 	    filters[MotionNotify] = Motion_Filter(butc);
+@@ -3055,6 +3305,36 @@
+ 	    FatalError("bogus pointer event from ddx");
+ 	}
+     }
++    #ifdef NX_DEBUG_INPUT
++    else if (!CheckMotion(xE))
++    {
++	if (nxagentDebugInput == 1)
++	{
++	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
++		    " for MotionNotify.\n");
++	}
++	return;
++    }
++    if (grab)
++    {
++	if (nxagentDebugInput == 1)
++	{
++	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
++		    "events (count = %d).\n", count);
++	}
++	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
++    }
++    else
++    {
++	if (nxagentDebugInput == 1)
++	{
++	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
++		    "events (count = %d).\n", count);
++	}
++	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
++			    mouse, count);
++    }
++    #else
+     else if (!CheckMotion(xE))
+ 	return;
+     if (grab)
+@@ -3062,8 +3342,19 @@
+     else
+ 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+ 			    mouse, count);
++    #endif
+     if (deactivateGrab)
++    #ifdef NX_DEBUG_INPUT
++    {
++      if (nxagentDebugInputDevices == 1)
++      {
++        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
++      }
++    #endif
+         (*mouse->DeactivateGrab)(mouse);
++    #ifdef NX_DEBUG_INPUT
++    }
++    #endif
+ }
+ 
+ #define AtMostOneClient \
+@@ -3784,6 +4075,12 @@
+     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+     if (!pWin)
+ 	return BadWindow;
++    #ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInputDevices == 1)
++    {
++      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
++    }
++    #endif
+     if (stuff->confineTo == None)
+ 	confineTo = NullWindow;
+     else 
+@@ -3843,6 +4140,12 @@
+ 	tempGrab.keyboardMode = stuff->keyboardMode;
+ 	tempGrab.pointerMode = stuff->pointerMode;
+ 	tempGrab.device = device;
++        #ifdef NX_DEBUG_INPUT
++        if (nxagentDebugInputDevices == 1)
++        {
++          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
++        }
++        #endif
+ 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+ 	if (oldCursor)
+ 	    FreeCursor (oldCursor, (Cursor)0);
+@@ -3906,6 +4209,12 @@
+     TimeStamp time;
+     REQUEST(xResourceReq);
+ 
++    #ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInputDevices == 1)
++    {
++      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
++    }
++    #endif
+     REQUEST_SIZE_MATCH(xResourceReq);
+     UpdateCurrentTime();
+     grab = device->grab;
+@@ -3913,7 +4222,25 @@
+     if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ 	    (grab) && SameClient(grab, client))
++    #ifdef NX_DEBUG_INPUT
++    {
++      if (nxagentDebugInputDevices == 1)
++      {
++        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
++      }
++    #endif
+ 	(*device->DeactivateGrab)(device);
++    #ifdef NX_DEBUG_INPUT
++    }
++    else
++    {
++      if (nxagentDebugInputDevices == 1)
++      {
++        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
++                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
++      }
++    }
++    #endif
+     return Success;
+ }
+ 
+@@ -3968,6 +4295,12 @@
+ 	tempGrab.pointerMode = other_mode;
+ 	tempGrab.eventMask = mask;
+ 	tempGrab.device = dev;
++        #ifdef NX_DEBUG_INPUT
++        if (nxagentDebugInputDevices == 1)
++        {
++          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
++        }
++        #endif
+ 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ 	*status = GrabSuccess;
+     }
+@@ -3981,6 +4314,12 @@
+     REQUEST(xGrabKeyboardReq);
+     int result;
+ 
++    #ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInputDevices == 1)
++    {
++      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
++    }
++    #endif
+     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+ #ifdef XCSECURITY
+     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+@@ -4011,6 +4350,12 @@
+     TimeStamp time;
+     REQUEST(xResourceReq);
+ 
++    #ifdef NX_DEBUG_INPUT
++    if (nxagentDebugInputDevices == 1)
++    {
++      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
++    }
++    #endif
+     REQUEST_SIZE_MATCH(xResourceReq);
+     UpdateCurrentTime();
+     grab = device->grab;
+@@ -4018,7 +4363,25 @@
+     if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+ 	(grab) && SameClient(grab, client))
++    #ifdef NX_DEBUG_INPUT
++    {
++      if (nxagentDebugInputDevices == 1)
++      {
++        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
++      }
++    #endif
+ 	(*device->DeactivateGrab)(device);
++    #ifdef NX_DEBUG_INPUT
++    }
++    else
++    {
++      if (nxagentDebugInputDevices == 1)
++      {
++        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
++                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
++      }
++    }
++    #endif
+     return Success;
+ }
+ 
+@@ -4152,6 +4515,17 @@
+     /* The client's event type must be a core event type or one defined by an
+ 	extension. */
+ 
++
++#ifdef NXAGENT_CLIPBOARD
++
++    if (stuff -> event.u.u.type == SelectionNotify)
++    {
++    	extern int nxagentSendNotify(xEvent*);
++	if (nxagentSendNotify(&stuff->event) == 1)
++	  return Success;
++    }
++#endif
++
+     if ( ! ((stuff->event.u.u.type > X_Reply &&
+ 	     stuff->event.u.u.type < LASTEvent) || 
+ 	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXextension.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXextension.c.NX.patch
new file mode 100644
index 0000000..84c5b13
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXextension.c.NX.patch
@@ -0,0 +1,70 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c	2015-02-10 19:13:13.804685886 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+ /***********************************************************
+ 
+@@ -60,7 +77,7 @@
+ #include "extnsionst.h"
+ #include "gcstruct.h"
+ #include "scrnintstr.h"
+-#include "dispatch.h"
++#include "../../dix/dispatch.h"
+ #ifdef XCSECURITY
+ #define _SECURITY_SERVER
+ #include <X11/extensions/security.h>
+@@ -69,6 +86,8 @@
+ #include "lbxserve.h"
+ #endif
+ 
++#include "Trap.h"
++
+ #define EXTENSION_BASE  128
+ #define EXTENSION_EVENT_BASE  64
+ #define LAST_EVENT  128
+@@ -324,6 +343,13 @@
+     {
+ 	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+         if (i < 0
++
++            /*
++             * Hide RENDER if our implementation
++             * is faulty.
++             */
++
++            || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+ #ifdef XCSECURITY
+ 	    /* don't show insecure extensions to untrusted clients */
+ 	    || (client->trustLevel == XSecurityClientUntrusted &&
+@@ -370,6 +396,14 @@
+ 		!extensions[i]->secure)
+ 		continue;
+ #endif
++            /*
++             * Hide RENDER if our implementation
++             * is faulty.
++             */
++
++            if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
++                continue;
++
+ 	    total_length += strlen(extensions[i]->name) + 1;
+ 	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+ 	    for (j = extensions[i]->num_aliases; --j >= 0;)
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXglxext.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXglxext.c.NX.patch
new file mode 100644
index 0000000..a8dbfe0
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXglxext.c.NX.patch
@@ -0,0 +1,118 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c	2015-02-10 19:13:13.808685737 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+ ** The contents of this file are subject to the GLX Public License Version 1.0
+ ** (the "License"). You may not use this file except in compliance with the
+@@ -33,6 +50,12 @@
+ #include "glxext.h"
+ #include "micmap.h"
+ 
++#include "Trap.h"
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
+ 
+ void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+ void GlxSetVisualConfigs(int nconfigs, 
+@@ -395,6 +418,8 @@
+ */
+ static int __glXDispatch(ClientPtr client)
+ {
++    int result;
++
+     REQUEST(xGLXSingleReq);
+     CARD8 opcode;
+     int (*proc)(__GLXclientState *cl, GLbyte *pc);
+@@ -444,11 +469,35 @@
+     ** Use the opcode to index into the procedure table.
+     */
+     proc = __glXSingleTable[opcode];
+-    return (*proc)(cl, (GLbyte *) stuff);
++
++    /*
++     * Report upstream that we are
++     * dispatching a GLX operation.
++     */
++
++    nxagentGlxTrap = 1;
++
++    #ifdef TEST
++    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
++                opcode, client -> index);
++    #endif
++    
++    result = (*proc)(cl, (GLbyte *) stuff);
++
++    nxagentGlxTrap = 0;
++
++    #ifdef TEST
++    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
++                opcode, client -> index);
++    #endif
++
++    return result;
+ }
+ 
+ static int __glXSwapDispatch(ClientPtr client)
+ {
++    int result;
++
+     REQUEST(xGLXSingleReq);
+     CARD8 opcode;
+     int (*proc)(__GLXclientState *cl, GLbyte *pc);
+@@ -490,7 +539,29 @@
+     ** Use the opcode to index into the procedure table.
+     */
+     proc = __glXSwapSingleTable[opcode];
+-    return (*proc)(cl, (GLbyte *) stuff);
++
++    /*
++     * Report upstream that we are
++     * dispatching a GLX operation.
++     */
++
++    nxagentGlxTrap = 1;
++
++    #ifdef TEST
++    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
++                opcode, client -> index);
++    #endif
++    
++    result = (*proc)(cl, (GLbyte *) stuff);
++
++    nxagentGlxTrap = 0;
++
++    #ifdef TEST
++    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
++                opcode, client -> index);
++    #endif
++
++    return result;
+ }
+ 
+ int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+@@ -502,4 +573,3 @@
+ {
+     return;
+ }
+-
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXglyph.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXglyph.c.NX.patch
new file mode 100644
index 0000000..8ac8e46
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXglyph.c.NX.patch
@@ -0,0 +1,160 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c	2015-02-10 19:13:13.824685138 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+  *
+@@ -40,9 +57,25 @@
+ #include "dixstruct.h"
+ #include "gcstruct.h"
+ #include "servermd.h"
++
++#ifdef NXAGENT_SERVER
++
++#include "NXpicturestr.h"
++#include "NXglyphstr.h"
++#include "Render.h"
++
++#define PANIC
++#define WARNING
++#undef  DEBUG
++#undef  TEST
++
++#else
++
+ #include "picturestr.h"
+ #include "glyphstr.h"
+ 
++#endif
++
+ #if HAVE_STDINT_H
+ #include <stdint.h>
+ #elif !defined(UINT32_MAX)
+@@ -293,7 +326,7 @@
+ 	gr->signature = hash;
+ 	globalGlyphs[glyphSet->fdepth].tableEntries++;
+     }
+-    
++ 
+     /* Insert/replace glyphset value */
+     gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+     ++glyph->refcnt;
+@@ -303,6 +336,13 @@
+ 	glyphSet->hash.tableEntries++;
+     gr->glyph = glyph;
+     gr->signature = id;
++
++    #ifdef NXAGENT_SERVER
++
++    gr -> corruptedGlyph = 1;
++
++    #endif
++
+     CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+ }
+ 
+@@ -324,6 +364,36 @@
+     return FALSE;
+ }
+ 
++#ifdef NXAGENT_SERVER
++
++GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
++{
++  GlyphRefPtr gr;
++  GlyphPtr    glyph;
++
++  gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
++  glyph = gr -> glyph;
++
++  if (glyph == DeletedGlyph)
++  {
++    glyph = 0;
++  }
++  else if (gr -> corruptedGlyph == 1)
++  {
++     #ifdef DEBUG
++     fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
++                 (void *) glyph, (void *) glyphSet);
++     #endif
++
++    nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
++                         (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
++  }
++
++  return glyph;
++}
++
++#else
++
+ GlyphPtr
+ FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+ {
+@@ -335,6 +405,8 @@
+     return glyph;
+ }
+ 
++#endif
++
+ GlyphPtr
+ AllocateGlyph (xGlyphInfo *gi, int fdepth)
+ {
+@@ -379,6 +451,12 @@
+     int		    oldSize;
+     CARD32	    s;
+ 
++    #ifdef NXAGENT_SERVER
++
++    CARD32          c;
++
++    #endif
++
+     tableEntries = hash->tableEntries + change;
+     hashSet = FindGlyphHashSet (tableEntries);
+     if (hashSet == hash->hashSet)
+@@ -396,9 +474,23 @@
+ 	    if (glyph && glyph != DeletedGlyph)
+ 	    {
+ 		s = hash->table[i].signature;
++
++                #ifdef NXAGENT_SERVER
++
++                c = hash->table[i].corruptedGlyph;
++
++                #endif
++
+ 		gr = FindGlyphRef (&newHash, s, global, glyph);
+ 		gr->signature = s;
+ 		gr->glyph = glyph;
++
++                #ifdef NXAGENT_SERVER
++
++                gr -> corruptedGlyph = c;
++
++                #endif
++
+ 		++newHash.tableEntries;
+ 	    }
+ 	}
+@@ -486,3 +578,4 @@
+     }
+     return Success;
+ }
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXglyphcurs.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXglyphcurs.c.NX.patch
new file mode 100644
index 0000000..c8d302c
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXglyphcurs.c.NX.patch
@@ -0,0 +1,121 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c	2015-02-10 19:13:13.808685737 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /************************************************************************
+ 
+ Copyright 1987, 1998  The Open Group
+@@ -62,6 +79,12 @@
+ #include "opaque.h"
+ #include "servermd.h"
+ 
++#include "../../fb/fb.h"
++#include "Pixmaps.h"
++
++#ifndef True
++#define True  1
++#endif
+ 
+ /*
+     get the bits out of the font in a portable way.  to avoid
+@@ -98,44 +121,68 @@
+     /* zeroing the (pad) bits seems to help some ddx cursor handling */
+     bzero(pbits, nby);
+ 
+-    ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width,
+-					       cm->height, 1);
++    ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+     pGC = GetScratchGC(1, pScreen);
+     if (!ppix || !pGC)
+     {
+ 	if (ppix)
+-	    (*pScreen->DestroyPixmap)(ppix);
++	    fbDestroyPixmap(ppix);
+ 	if (pGC)
+ 	    FreeScratchGC(pGC);
+ 	xfree(pbits);
+ 	return BadAlloc;
+     }
+ 
++    #ifdef TEST
++    fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
++                (void *) ppix, cm->width, cm->height, 1);
++    #endif
++
++    nxagentPixmapPriv(ppix) -> id = 0;
++    nxagentPixmapPriv(ppix) -> mid = 0;
++    nxagentPixmapPriv(ppix) -> isVirtual = True;
++    nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
++    nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
++
+     rect.x = 0;
+     rect.y = 0;
+     rect.width = cm->width;
+     rect.height = cm->height;
+ 
+-    /* fill the pixmap with 0 */
+-    gcval[0].val = GXcopy;
+-    gcval[1].val = 0;
+-    gcval[2].ptr = (pointer)pfont;
+-    dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
+-		NULL, gcval);
++    pGC->stateChanges |= GCFunction | GCForeground | GCFont;
++    pGC->alu = GXcopy;
++
++    pGC->fgPixel = 0;
++
++    pfont->refcnt++;
++
++    if (pGC->font)
++      CloseFont(pGC->font, (Font)0);
++
++    pGC->font = pfont;
++
+     ValidateGC((DrawablePtr)ppix, pGC);
+-    (*pGC->ops->PolyFillRect)((DrawablePtr)ppix, pGC, 1, &rect);
++    fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+ 
+     /* draw the glyph */
+     gcval[0].val = 1;
+-    dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
++    pGC->fgPixel = 1;
++
++    pGC->stateChanges |= GCForeground;
++
+     ValidateGC((DrawablePtr)ppix, pGC);
+-    (*pGC->ops->PolyText16)((DrawablePtr)ppix, pGC, cm->xhot, cm->yhot,
+-			    1, (unsigned short *)char2b);
+-    (*pScreen->GetImage)((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+-			 XYPixmap, 1, pbits);
++    miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
++    fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
++                         XYPixmap, 1, pbits);
+     *ppbits = (unsigned char *)pbits;
+     FreeScratchGC(pGC);
+-    (*pScreen->DestroyPixmap)(ppix);
++    fbDestroyPixmap(ppix);
++
++    #ifdef TEST
++    fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
++                (void *) ppix);
++    #endif
++
+     return Success;
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXglyphstr.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXglyphstr.h.NX.patch
new file mode 100644
index 0000000..76f0a16
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXglyphstr.h.NX.patch
@@ -0,0 +1,59 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h	2015-02-10 19:13:13.780686785 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+  *
+@@ -23,11 +40,18 @@
+  * Author:  Keith Packard, SuSE, Inc.
+  */
+ 
++/*
++ * This must keep the same symbol as the original glyphstr.h
++ * or symbols  will be redefined. The code here adds a field
++ * to _GlyphSet. This should be done by defining a new type
++ * and casting when appropriate.
++ */
++
+ #ifndef _GLYPHSTR_H_
+ #define _GLYPHSTR_H_
+ 
+ #include <X11/extensions/renderproto.h>
+-#include "picture.h"
++#include "../../render/picture.h"
+ #include "screenint.h"
+ 
+ #define GlyphFormat1	0
+@@ -47,6 +71,7 @@
+ typedef struct _GlyphRef {
+     CARD32	signature;
+     GlyphPtr	glyph;
++    CARD16      corruptedGlyph;
+ } GlyphRefRec, *GlyphRefPtr;
+ 
+ #define DeletedGlyph	((GlyphPtr) 1)
+@@ -70,6 +95,7 @@
+     GlyphHashRec    hash;
+     int             maxPrivate;
+     pointer         *devPrivates;
++    CARD32          remoteID;
+ } GlyphSetRec, *GlyphSetPtr;
+ 
+ #define GlyphSetGetPrivate(pGlyphSet,n)					\
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXmiexpose.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXmiexpose.c.NX.patch
new file mode 100644
index 0000000..829a95d
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXmiexpose.c.NX.patch
@@ -0,0 +1,116 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c	2015-02-10 19:13:13.768687235 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+ /* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+ /***********************************************************
+@@ -109,6 +126,12 @@
+ the region package can call this.
+ */
+ 
++#ifdef NXAGENT_SERVER
++
++#include "Windows.h"
++
++#endif
++
+ #ifndef RECTLIMIT
+ #define RECTLIMIT 25		/* pick a number, any number > 8 */
+ #endif
+@@ -158,6 +181,20 @@
+     BoxRec expBox;
+     Bool extents;
+ 
++#ifdef NXAGENT_SERVER
++
++    /*
++     * Set the elements reported by the compiler
++     * as uninitialized.
++     */
++
++    expBox.x1 = 0;
++    expBox.y1 = 0;
++    expBox.x2 = 0;
++    expBox.y2 = 0;
++
++#endif
++
+     /* This prevents warning about pscr not being used. */
+     pGC->pScreen = pscr = pGC->pScreen;
+ 
+@@ -498,6 +535,11 @@
+     WindowPtr pWin;
+     register RegionPtr prgn, other_exposed;
+ {
++#ifdef NXAGENT_SERVER
++
++    int total;
++
++#endif
+     RegionPtr   exposures = prgn;
+     if (pWin->backStorage && prgn)
+ 	/*
+@@ -533,7 +575,20 @@
+ 	    }
+ 	    exposures = other_exposed;
+ 	}
++#ifdef NXAGENT_SERVER
++
++        /*
++         * If the number of rectangles is greater
++         * than 4, let the function decide.
++         */
++
++        total = REGION_NUM_RECTS(exposures);
++
++        if (clientInterested && exposures && (total > RECTLIMIT ||
++                (total > 4 && nxagentExtentsPredicate(total) == 1)))
++#else
+ 	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
++#endif
+ 	{
+ 	    /*
+ 	     * If we have LOTS of rectangles, we decide to take the extents
+@@ -666,6 +721,25 @@
+     register xRectangle *prect;
+     int numRects;
+ 
++#ifdef NXAGENT_SERVER
++
++    /*
++     * Set the elements reported by the compiler
++     * as uninitialized.
++     */
++
++    prgnWin.extents.x1 = 0;
++    prgnWin.extents.y1 = 0;
++    prgnWin.extents.x2 = 0;
++    prgnWin.extents.y2 = 0;
++
++    prgnWin.data = NULL;
++
++    oldCorner.x = 0;
++    oldCorner.y = 0;
++
++#endif
++
+     gcmask = 0;
+ 
+     if (what == PW_BACKGROUND)
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXmiglyph.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXmiglyph.c.NX.patch
new file mode 100644
index 0000000..37b68d6
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXmiglyph.c.NX.patch
@@ -0,0 +1,156 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c	2015-02-10 19:13:13.804685886 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+  *
+@@ -35,6 +52,12 @@
+ #include "picturestr.h"
+ #include "mipict.h"
+ 
++#ifdef NXAGENT_SERVER
++
++#include "Render.h"
++
++#endif
++
+ void
+ miGlyphExtents (int		nlist,
+ 		GlyphListPtr	list,
+@@ -45,7 +68,7 @@
+     int		n;
+     GlyphPtr	glyph;
+     int		x, y;
+-    
++ 
+     x = 0;
+     y = 0;
+     extents->x1 = MAXSHORT;
+@@ -113,25 +136,58 @@
+     int		error;
+     BoxRec	extents;
+     CARD32	component_alpha;
+-    
++
++    #ifdef NXAGENT_SERVER
++
++    /*
++     * Get rid of the warning.
++     */
++
++    extents.x1 = 0;
++    extents.y1 = 0;
++
++    #endif
++
+     if (maskFormat)
+     {
+ 	GCPtr	    pGC;
+ 	xRectangle  rect;
+-	
+-	miGlyphExtents (nlist, list, glyphs, &extents);
+-	
++
++        #ifdef NXAGENT_SERVER
++
++        if (nxagentGlyphsExtents != NullBox)
++        {
++          memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
++        }
++        else
++        {
++          nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
++
++          miGlyphExtents (nlist, list, glyphs, &extents);
++
++          memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
++        }
++
++        #else
++
++        miGlyphExtents (nlist, list, glyphs, &extents);
++
++        #endif
++
+ 	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ 	    return;
+ 	width = extents.x2 - extents.x1;
+ 	height = extents.y2 - extents.y1;
+ 	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
++
+ 	if (!pMaskPixmap)
+ 	    return;
++
+ 	component_alpha = NeedsComponent(maskFormat->format);
+ 	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+ 			       maskFormat, CPComponentAlpha, &component_alpha,
+ 			       serverClient, &error);
++
+ 	if (!pMask)
+ 	{
+ 	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+@@ -160,6 +216,7 @@
+ 	x += list->xOff;
+ 	y += list->yOff;
+ 	n = list->len;
++
+ 	while (n--)
+ 	{
+ 	    glyph = *glyphs++;
+@@ -184,6 +241,21 @@
+ 	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+ 					    glyph->info.width, glyph->info.height,
+ 					    0, 0, -1, (pointer) (glyph + 1));
++
++            #ifdef NXAGENT_SERVER
++
++            /*
++             * The following line fixes a problem with glyphs that appeared
++             * as clipped. It was a side effect due the validate function
++             * "ValidatePicture" that makes a check on the Drawable serial
++             * number instead of the picture serial number, failing thus
++             * the clip mask update.
++             */
++
++            pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
++
++            #endif
++
+ 	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ 	    if (maskFormat)
+ 	    {
+@@ -215,6 +287,7 @@
+ 	    x += glyph->info.xOff;
+ 	    y += glyph->info.yOff;
+ 	}
++
+ 	list++;
+ 	if (pPicture)
+ 	{
+@@ -237,7 +310,9 @@
+ 			  0, 0,
+ 			  x, y,
+ 			  width, height);
++
+ 	FreePicture ((pointer) pMask, (XID) 0);
+ 	(*pScreen->DestroyPixmap) (pMaskPixmap);
+     }
++
+ }
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXmitrap.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXmitrap.c.NX.patch
new file mode 100644
index 0000000..220b26a
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXmitrap.c.NX.patch
@@ -0,0 +1,65 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c	2015-02-10 19:13:13.820685287 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+  *
+@@ -35,6 +52,12 @@
+ #include "picturestr.h"
+ #include "mipict.h"
+ 
++#ifdef NXAGENT_SERVER
++
++#include "Render.h"
++
++#endif
++
+ PicturePtr
+ miCreateAlphaPicture (ScreenPtr	    pScreen, 
+ 		      PicturePtr    pDst,
+@@ -159,7 +182,27 @@
+ 	xDst = traps[0].left.p1.x >> 16;
+ 	yDst = traps[0].left.p1.y >> 16;
+ 
+-	miTrapezoidBounds (ntrap, traps, &bounds);
++        #ifdef NXAGENT_SERVER
++
++        if (nxagentTrapezoidExtents != NullBox)
++        {
++          memcpy(&bounds, nxagentTrapezoidExtents, sizeof(BoxRec));
++        }
++        else
++        {
++          nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
++
++          miTrapezoidBounds (ntrap, traps, &bounds);
++
++          memcpy(nxagentTrapezoidExtents, &bounds, sizeof(BoxRec));
++        }
++
++        #else
++
++        miTrapezoidBounds (ntrap, traps, &bounds);
++
++        #endif
++
+ 	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ 	    return;
+ 	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXmiwindow.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXmiwindow.c.NX.patch
new file mode 100644
index 0000000..7d6be7b
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXmiwindow.c.NX.patch
@@ -0,0 +1,53 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c	2015-02-10 19:13:13.776686935 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+ /***********************************************************
+ 
+@@ -1048,8 +1065,29 @@
+ 	bsExposed = (*pScreen->TranslateBackingStore)
+ 			     (pWin, 0, 0, pOldClip,
+ 			      pWin->drawable.x, pWin->drawable.y);
++#ifdef NXAGENT_SERVER
++
++        /*
++         * We got a few, rare, segfaults here after having
++         * started using the backing store. It may be a
++         * different bug but miChangeSaveUnder() calls mi-
++         * CheckSubSaveUnder() that, in turn, can change
++         * the backing store attribute of the window. This
++         * means that we may try to destroy the region
++         * even if it was not created at the beginning of
++         * this function as, at the time, the backing store
++         * was off. miCheckSubSaveUnder() appear to get a
++         * pointer to the parent, so maybe doesn't change
++         * the attribute of the window itself. This is to
++         * be better investigated.
++         */
++
++        if (WasViewable && pOldClip)
++            REGION_DESTROY(pScreen, pOldClip);
++#else
+ 	if (WasViewable)
+ 	    REGION_DESTROY(pScreen, pOldClip);
++#endif
+ 	if (bsExposed)
+ 	{
+ 	    RegionPtr	valExposed = NullRegion;
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXpicture.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXpicture.c.NX.patch
new file mode 100644
index 0000000..9713e44
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXpicture.c.NX.patch
@@ -0,0 +1,615 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c	2015-02-13 14:03:44.744441510 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+  *
+@@ -40,7 +57,21 @@
+ #include "dixstruct.h"
+ #include "gcstruct.h"
+ #include "servermd.h"
+-#include "picturestr.h"
++#include "NXpicturestr.h"
++
++#include "Screen.h"
++#include "Pixmaps.h"
++#include "Drawable.h"
++#include "Render.h"
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
++void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
++
++void *nxagentMatchingFormats(PictFormatPtr pForm);
+ 
+ int		PictureScreenPrivateIndex = -1;
+ int		PictureWindowPrivateIndex;
+@@ -50,6 +81,13 @@
+ RESTYPE		GlyphSetType;
+ int		PictureCmapPolicy = PictureCmapPolicyDefault;
+ 
++typedef struct _formatInit {
++    CARD32  format;
++    CARD8   depth;
++} FormatInitRec, *FormatInitPtr;
++
++void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
++
+ /* Picture Private machinery */
+ 
+ static int picturePrivateCount;
+@@ -189,11 +227,6 @@
+     return 0;
+ }
+ 
+-typedef struct _formatInit {
+-    CARD32  format;
+-    CARD8   depth;
+-} FormatInitRec, *FormatInitPtr;
+-
+ static int
+ addFormat (FormatInitRec    formats[256],
+ 	   int		    nformat,
+@@ -207,6 +240,11 @@
+ 	    return nformat;
+     formats[nformat].format = format;
+     formats[nformat].depth = depth;
++
++    #ifdef DEBUG
++    fprintf(stderr, "addFormat: Added format [%lu] depth [%d].\n", format, depth);
++    #endif
++
+     return ++nformat;
+ }
+ 
+@@ -215,10 +253,13 @@
+ PictFormatPtr
+ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+ {
+-    int		    nformats, f;
++    int             nformats, f;
+     PictFormatPtr   pFormats;
+     FormatInitRec   formats[1024];
+     CARD32	    format;
++
++#ifndef NXAGENT_SERVER
++
+     CARD8	    depth;
+     VisualPtr	    pVisual;
+     int		    v;
+@@ -228,7 +269,16 @@
+     int		    d;
+     DepthPtr	    pDepth;
+ 
++#endif
++
+     nformats = 0;
++
++#ifdef NXAGENT_SERVER
++
++    nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
++
++#else
++
+     /* formats required by protocol */
+     formats[nformats].format = PICT_a1;
+     formats[nformats].depth = 1;
+@@ -254,6 +304,7 @@
+ 	if (!depth)
+ 	    continue;
+     	bpp = BitsPerPixel (depth);
++
+ 	switch (pVisual->class) {
+ 	case DirectColor:
+ 	case TrueColor:
+@@ -296,6 +347,7 @@
+ 	    break;
+ 	}
+     }
++
+     /*
+      * Walk supported depths and add useful Direct formats
+      */
+@@ -304,16 +356,18 @@
+ 	pDepth = &pScreen->allowedDepths[d];
+ 	bpp = BitsPerPixel (pDepth->depth);
+ 	format = 0;
++
+ 	switch (bpp) {
+ 	case 16:
+ 	    /* depth 12 formats */
+-	    if (pDepth->depth >= 12)
+-	    {
+-		nformats = addFormat (formats, nformats,
+-				      PICT_x4r4g4b4, pDepth->depth);
+-		nformats = addFormat (formats, nformats,
+-				      PICT_x4b4g4r4, pDepth->depth);
+-	    }
++	     if (pDepth->depth >= 12)
++	     {
++	        nformats = addFormat (formats, nformats,
++	      		      PICT_x4r4g4b4, pDepth->depth);
++	        nformats = addFormat (formats, nformats,
++	      		      PICT_x4b4g4r4, pDepth->depth);
++	     }
++
+ 	    /* depth 15 formats */
+ 	    if (pDepth->depth >= 15)
+ 	    {
+@@ -325,18 +379,18 @@
+ 	    /* depth 16 formats */
+ 	    if (pDepth->depth >= 16) 
+ 	    {
+-		nformats = addFormat (formats, nformats,
+-				      PICT_a1r5g5b5, pDepth->depth);
+-		nformats = addFormat (formats, nformats,
+-				      PICT_a1b5g5r5, pDepth->depth);
++	        nformats = addFormat (formats, nformats,
++	        		      PICT_a1r5g5b5, pDepth->depth);
++	        nformats = addFormat (formats, nformats,
++	       	        	      PICT_a1b5g5r5, pDepth->depth);
+ 		nformats = addFormat (formats, nformats,
+ 				      PICT_r5g6b5, pDepth->depth);
+ 		nformats = addFormat (formats, nformats,
+ 				      PICT_b5g6r5, pDepth->depth);
+ 		nformats = addFormat (formats, nformats,
+ 				      PICT_a4r4g4b4, pDepth->depth);
+-		nformats = addFormat (formats, nformats,
+-				      PICT_a4b4g4r4, pDepth->depth);
++	        nformats = addFormat (formats, nformats,
++	        		      PICT_a4b4g4r4, pDepth->depth);
+ 	    }
+ 	    break;
+ 	case 24:
+@@ -359,7 +413,8 @@
+ 	    break;
+ 	}
+     }
+-    
++
++#endif
+ 
+     pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+     if (!pFormats)
+@@ -368,9 +423,9 @@
+     for (f = 0; f < nformats; f++)
+     {
+         pFormats[f].id = FakeClientID (0);
+-	pFormats[f].depth = formats[f].depth;
+-	format = formats[f].format;
+-	pFormats[f].format = format;
++        pFormats[f].depth = formats[f].depth;
++        format = formats[f].format;
++        pFormats[f].format = format;
+ 	switch (PICT_FORMAT_TYPE(format)) {
+ 	case PICT_TYPE_ARGB:
+ 	    pFormats[f].type = PictTypeDirect;
+@@ -427,6 +482,29 @@
+ 	    pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+ 	    break;
+ 	}
++
++#ifdef NXAGENT_SERVER
++        if (nxagentMatchingFormats(&pFormats[f]) != NULL)
++        {
++          #ifdef DEBUG
++          fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
++                      "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
++                          pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
++                              pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
++                                  pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
++          #endif
++        }
++        else
++        {
++          #ifdef DEBUG
++          fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
++                      "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
++                          pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
++                              pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
++                                  pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
++          #endif
++        } 
++#endif
+     }
+     *nformatp = nformats;
+     return pFormats;
+@@ -795,9 +873,20 @@
+ 	else
+ 	    ppriv->ptr = (pointer)NULL;
+     }
++
++    nxagentPicturePriv(pPicture) -> picture = 0;
++
+     return pPicture;
+ }
+ 
++/*
++ * Let picture always point to the virtual pixmap.
++ * For sure this is not the best way to deal with
++ * the virtual frame-buffer.
++ */
++
++#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
++
+ PicturePtr
+ CreatePicture (Picture		pid,
+ 	       DrawablePtr	pDrawable,
+@@ -823,6 +912,12 @@
+     pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+     if (pDrawable->type == DRAWABLE_PIXMAP)
+     {
++        #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
++
++        pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
++
++        #endif
++
+ 	++((PixmapPtr)pDrawable)->refcnt;
+ 	pPicture->pNext = 0;
+     }
+@@ -972,7 +1067,49 @@
+ static PicturePtr createSourcePicture(void)
+ {
+     PicturePtr pPicture;
+-    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
++
++    extern int nxagentPicturePrivateIndex;
++
++    unsigned int totalPictureSize;
++
++    DevUnion *ppriv;
++
++    char *privPictureRecAddr;
++
++    int i;
++
++    /*
++     * Compute size of entire PictureRect, plus privates.
++     */
++
++    totalPictureSize = sizeof(PictureRec) +
++                           picturePrivateCount * sizeof(DevUnion) +
++                               sizeof(nxagentPrivPictureRec);
++
++    pPicture = (PicturePtr) xalloc(totalPictureSize);
++
++    if (pPicture != NULL)
++    {
++      ppriv = (DevUnion *) (pPicture + 1);
++
++      for (i = 0; i < picturePrivateCount; ++i)
++      {
++        /*
++         * Other privates are inaccessible.
++         */
++
++        ppriv[i].ptr = NULL;
++      }
++
++      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
++
++      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
++
++      pPicture -> devPrivates = ppriv;
++
++      nxagentPicturePriv(pPicture) -> picture = 0;
++    }
++
+     pPicture->pDrawable = 0;
+     pPicture->pFormat = 0;
+     pPicture->pNext = 0;
+@@ -1294,6 +1431,12 @@
+ 			pPixmap->refcnt++;
+ 		    }
+ 		}
++
++                #ifdef DEBUG
++                fprintf(stderr, "ChangePicture: Going to call ChangePictureClip with clipType [%d] pPixmap [%p].\n",
++                            clipType, (void *) pPixmap);
++                #endif
++
+ 		error = (*ps->ChangePictureClip)(pPicture, clipType,
+ 						 (pointer)pPixmap, 0);
+ 		break;
+@@ -1600,6 +1743,10 @@
+ 
+     if (--pPicture->refcnt == 0)
+     {
++#ifdef NXAGENT_SERVER
++        nxagentDestroyPicture(pPicture);
++#endif
++
+ 	if (pPicture->transform)
+ 	    xfree (pPicture->transform);
+         if (!pPicture->pDrawable) {
+@@ -1698,6 +1845,13 @@
+     
+     ValidatePicture (pSrc);
+     ValidatePicture (pDst);
++
++    #ifdef TEST
++    fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
++		"source at [%p] and destination at [%p].\n",
++		    (void *) pSrc, (void *) pDst);
++    #endif
++
+     (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+ }
+ 
+@@ -1862,3 +2016,255 @@
+     vector->vector[2] = xFixed1;
+     return TRUE;
+ }
++
++#ifndef True
++# define True 1
++#endif
++
++#ifndef False
++# define False 0
++#endif
++
++void nxagentReconnectPictFormat(void*, XID, void*);
++
++Bool nxagentReconnectAllPictFormat(void *p)
++{
++  PictFormatPtr formats_old, formats;
++  int nformats, nformats_old;
++  VisualPtr pVisual;
++  Bool success = True;
++  Bool matched;
++  int i, n;
++  CARD32 type, a, r, g, b;
++
++  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
++  fprintf(stderr, "nxagentReconnectAllPictFormat\n");
++  #endif
++
++  formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
++  nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
++
++  /*
++   * TODO: We could copy PictureCreateDefaultFormats,
++   *       in order not to waste ID with FakeClientID().
++   */
++  formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
++
++  if (!formats)
++    return False;
++
++  for (n = 0; n < nformats; n++)
++  {
++    if (formats[n].type == PictTypeIndexed)
++    {
++      pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
++
++      if ((pVisual->class | DynamicClass) == PseudoColor)
++        type = PICT_TYPE_COLOR;
++      else
++        type = PICT_TYPE_GRAY;
++      a = r = g = b = 0;
++    }
++    else
++    {
++      if ((formats[n].direct.redMask|
++           formats[n].direct.blueMask|
++           formats[n].direct.greenMask) == 0)
++        type = PICT_TYPE_A;
++      else if (formats[n].direct.red > formats[n].direct.blue)
++        type = PICT_TYPE_ARGB;
++      else
++        type = PICT_TYPE_ABGR;
++      a = Ones (formats[n].direct.alphaMask);
++      r = Ones (formats[n].direct.redMask);
++      g = Ones (formats[n].direct.greenMask);
++      b = Ones (formats[n].direct.blueMask);
++    }
++    formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
++  }
++
++  for (n = 0; n < nformats_old; n++)
++  {
++    for (i = 0, matched = False; (!matched) && (i < nformats); i++)
++    {
++      if (formats_old[n].format == formats[i].format &&
++          formats_old[n].type == formats[i].type &&
++          formats_old[n].direct.red == formats[i].direct.red &&
++          formats_old[n].direct.green == formats[i].direct.green &&
++          formats_old[n].direct.blue == formats[i].direct.blue &&
++          formats_old[n].direct.redMask == formats[i].direct.redMask &&
++          formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
++          formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
++          formats_old[n].direct.alpha == formats[i].direct.alpha &&
++          formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
++      {
++       /*
++        * Regard depth 16 and 15 as were the same, if all other values match.
++        */
++
++        if ((formats_old[n].depth == formats[i].depth) ||
++               ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
++                    (formats[i].depth == 15 || formats[i].depth == 16)))
++        {
++          matched = True;
++        }
++      }
++    }
++
++    if (!matched)
++    {
++      return False;
++    }
++  }
++
++  xfree(formats);
++
++  /* TODO: Perhaps do i have to do PictureFinishInit ?. */
++  /* TODO: We have to check for new Render protocol version. */
++
++  for (i = 0; (i < MAXCLIENTS) && (success); i++)
++  {
++    if (clients[i])
++    {
++      FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
++    }
++  }
++
++  return success;
++}
++
++/*
++ * It seem we don't have nothing
++ * to do for reconnect PictureFormat.
++ */
++
++void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
++{
++  PictFormatPtr pFormat;
++  Bool *pBool;
++
++  pFormat = (PictFormatPtr)p0;
++  pBool = (Bool*)p2;
++
++  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
++  fprintf(stderr, "nxagentReconnectPictFormat.\n");
++  #endif
++}
++
++/*
++ * The set of picture formats may change considerably
++ * between different X servers. This poses a problem
++ * while migrating NX sessions, because a requisite to
++ * successfully reconnect the session is that all pic-
++ * ture formats have to be available on the new X server.
++ * To reduce such problems, we use a limited set of
++ * pictures available on the most X servers.
++ */
++
++void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
++{
++  DepthPtr  pDepth;
++  VisualPtr pVisual;
++
++  CARD32 format;
++  CARD8 depth;
++
++  int r, g, b;
++  int bpp;
++  int d;
++  int v;
++
++
++  formats[*nformats].format = PICT_a1;
++  formats[*nformats].depth = 1;
++  *nformats += 1;
++  formats[*nformats].format = PICT_a4;
++  formats[*nformats].depth = 4;
++  *nformats += 1;
++  formats[*nformats].format = PICT_a8;
++  formats[*nformats].depth = 8;
++  *nformats += 1;
++  formats[*nformats].format = PICT_a8r8g8b8;
++  formats[*nformats].depth = 32;
++  *nformats += 1;
++
++  /*
++   * This format should be required by the
++   * protocol, but it's not used by Xgl.
++   *
++   * formats[*nformats].format = PICT_x8r8g8b8;
++   * formats[*nformats].depth = 32;
++   * *nformats += 1;
++   */
++
++  /* now look through the depths and visuals adding other formats */
++  for (v = 0; v < pScreen->numVisuals; v++)
++  {
++    pVisual = &pScreen->visuals[v];
++    depth = visualDepth (pScreen, pVisual);
++    if (!depth)
++      continue;
++
++    bpp = BitsPerPixel (depth);
++
++    switch (pVisual->class)
++    {
++      case DirectColor:
++      case TrueColor:
++        r = Ones (pVisual->redMask);
++        g = Ones (pVisual->greenMask);
++        b = Ones (pVisual->blueMask);
++
++        if (pVisual->offsetBlue == 0 &&
++            pVisual->offsetGreen == b &&
++            pVisual->offsetRed == b + g)
++        {
++    	  format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
++    	  *nformats = addFormat (formats, *nformats, format, depth);
++        }
++        break;
++      case StaticColor:
++      case PseudoColor:
++      case StaticGray:
++      case GrayScale:
++        break;
++    }
++  }
++
++  for (d = 0; d < pScreen -> numDepths; d++)
++  {
++    pDepth = &pScreen -> allowedDepths[d];
++    bpp = BitsPerPixel(pDepth -> depth);
++
++    switch (bpp) {
++    case 16:
++      if (pDepth->depth == 15)
++      {
++        *nformats = addFormat (formats, *nformats,
++    			      PICT_x1r5g5b5, pDepth->depth);
++      }
++
++      if (pDepth->depth == 16) 
++      {
++        *nformats = addFormat (formats, *nformats,
++    	                      PICT_r5g6b5, pDepth->depth);
++      }
++      break;
++    case 24:
++      if (pDepth->depth == 24)
++      {
++        *nformats = addFormat (formats, *nformats,
++    	                      PICT_r8g8b8, pDepth->depth);
++      }
++      break;
++    case 32:
++      if (pDepth->depth == 24)
++      {
++	*nformats = addFormat (formats, *nformats,
++			      PICT_x8r8g8b8, pDepth->depth);
++      }
++      break;
++    }
++  }
++}
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXpicturestr.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXpicturestr.h.NX.patch
new file mode 100644
index 0000000..9150cfa
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXpicturestr.h.NX.patch
@@ -0,0 +1,42 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h	2015-02-13 14:03:44.744441510 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+  *
+@@ -23,10 +40,17 @@
+  * Author:  Keith Packard, SuSE, Inc.
+  */
+ 
++/*
++ * This must keep the same symbol as the original
++ * picturestr.h or symbols  will be redefined. We
++ * should define a new types and cast when appro-
++ * priate.
++ */
++
+ #ifndef _PICTURESTR_H_
+ #define _PICTURESTR_H_
+ 
+-#include "glyphstr.h"
++#include "NXglyphstr.h"
+ #include "scrnintstr.h"
+ #include "resource.h"
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXproperty.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXproperty.c.NX.patch
new file mode 100644
index 0000000..7327501
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXproperty.c.NX.patch
@@ -0,0 +1,358 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original	2015-02-13 14:03:44.744441510 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c	2015-02-10 19:13:13.772687085 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+ /***********************************************************
+ 
+@@ -58,7 +75,7 @@
+ #include "windowstr.h"
+ #include "propertyst.h"
+ #include "dixstruct.h"
+-#include "dispatch.h"
++#include "../../dix/dispatch.h"
+ #include "swaprep.h"
+ #ifdef XCSECURITY
+ #define _SECURITY_SERVER
+@@ -69,6 +86,11 @@
+ #include "lbxtags.h"
+ #endif
+ 
++#include "Options.h"
++#include "Rootless.h"
++#include "Client.h"
++#include "Windows.h"
++
+ #if defined(LBX) || defined(LBX_COMPAT)
+ #if 0 /* no header in X11 environment, not used in X11 environment */
+ int fWriteToClient(ClientPtr client, int len, char *buf)
+@@ -78,6 +100,17 @@
+ #endif
+ #endif
+ 
++extern Atom clientCutProperty;
++
++#ifdef NXAGENT_SERVER
++typedef struct
++{
++  CARD32 state;
++  Window icon;
++}
++nxagentWMStateRec;
++#endif
++
+ /*****************************************************************
+  * Property Stuff
+  *
+@@ -234,6 +267,15 @@
+     totalSize = len * sizeInBytes;
+     REQUEST_FIXED_SIZE(xChangePropertyReq, totalSize);
+ 
++#ifdef NXAGENT_CLIPBOARD
++    {
++       extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
++
++       pWin = nxagentGetClipboardWindow(stuff->property, NULL);
++    }
++
++    if (pWin == NULL)
++#endif
+     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ 					   SecurityWriteAccess);
+     if (!pWin)
+@@ -261,6 +303,18 @@
+     }
+ #endif
+ 
++#ifdef NXAGENT_ARTSD
++    {
++    /* Do not process MCOPGLOBALS property changes,
++      they are already set reflecting the server side settings.
++      Just return success.
++    */
++      extern Atom mcop_local_atom;
++      if (stuff->property == mcop_local_atom)
++        return client->noClientException;
++    }
++#endif
++
+ #ifdef LBX
+     err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+ 	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+@@ -271,7 +325,23 @@
+     if (err != Success)
+ 	return err;
+     else
+-	return client->noClientException;
++    {
++      if (nxagentOption(Rootless) == 1)
++      {
++        nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
++                                  (int) mode, len, (pointer) &stuff[1]);
++      }
++
++      nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
++
++      nxagentGuessShadowHint(client, stuff->property);
++
++      #ifdef NX_DEBUG_INPUT
++      nxagentGuessDumpInputInfo(client, stuff->property, (char *) &stuff[1]);
++      #endif
++
++      return client->noClientException;
++    }
+ }
+ 
+ int
+@@ -289,10 +359,23 @@
+     int sizeInBytes;
+     int totalSize;
+     pointer data;
++    int copySize;
+ 
+     sizeInBytes = format>>3;
+     totalSize = len * sizeInBytes;
+ 
++    copySize = nxagentOption(CopyBufferSize);
++
++    if (copySize != COPY_UNLIMITED && property == clientCutProperty)
++    {
++      if (totalSize > copySize)
++      {
++        totalSize = copySize;
++        totalSize = totalSize - (totalSize % sizeInBytes);
++        len = totalSize / sizeInBytes;
++      }
++    }
++
+     /* first see if property already exists */
+ 
+     pProp = wUserProps (pWin);
+@@ -491,6 +574,11 @@
+ int
+ ProcGetProperty(ClientPtr client)
+ {
++    #ifdef NXAGENT_SERVER
++    nxagentWMStateRec wmState;
++    nxagentWMStateRec *wmsP = &wmState;
++    #endif
++
+     PropertyPtr pProp, prevProp;
+     unsigned long n, len, ind;
+     WindowPtr pWin;
+@@ -498,6 +586,7 @@
+     REQUEST(xGetPropertyReq);
+ 
+     REQUEST_SIZE_MATCH(xGetPropertyReq);
++
+     if (stuff->delete)
+ 	UpdateCurrentTime();
+     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+@@ -533,6 +622,59 @@
+ 
+     reply.type = X_Reply;
+     reply.sequenceNumber = client->sequence;
++
++    #ifdef NXAGENT_SERVER
++
++    /*
++     * Creating a reply for WM_STATE property if it doesn't exist.
++     * This is intended to allow drag & drop work in JAva 1.6 when
++     * the agent is connected to NXWin in multiwindow mode.
++     */
++
++    if (nxagentOption(Rootless) &&
++            nxagentWindowTopLevel(pWin) &&
++                (!pProp) &&
++                    strcmp(NameForAtom(stuff->property), "WM_STATE") == 0)
++    {
++      wmState.state = 1;
++      wmState.icon = None;
++
++      if (ChangeWindowProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState, 1) == Success)
++      {
++        nxagentExportProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState);
++      }
++
++      n = 8;
++      ind = stuff->longOffset << 2;        
++
++      if (n < ind)
++      {
++        client->errorValue = stuff->longOffset;
++        return BadValue;
++      }
++
++      len = min(n - ind, 4 * stuff->longLength);
++
++      reply.bytesAfter = n - (ind + len);
++      reply.length = (len + 3) >> 2;
++
++      reply.format = 32;
++      reply.nItems = len / 4;
++      reply.propertyType = stuff->property;
++
++      WriteReplyToClient(client, sizeof(xGenericReply), &reply);
++
++      if (len)
++      {
++        client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write;
++
++        WriteSwappedDataToClient(client, len, (char *)wmsP + ind);
++      }
++
++      return(client->noClientException);
++    }
++    #endif
++
+     if (!pProp) 
+ 	return NullPropertyReply(client, None, 0, &reply);
+ 
+@@ -643,6 +785,126 @@
+     return(client->noClientException);
+ }
+ 
++#ifdef NXAGENT_CLIPBOARD
++/* GetWindowProperty clipboard use only */
++int
++GetWindowProperty(pWin, property, longOffset, longLength, delete,
++            type, actualType, format, nItems, bytesAfter, propData )
++    WindowPtr	        pWin;
++    Atom		property;
++    long			longOffset;
++    long			longLength;
++    Bool			delete;
++    Atom		type;
++    Atom		*actualType;
++    int			*format;
++    unsigned long	*nItems;
++    unsigned long	*bytesAfter;
++    unsigned char	**propData;
++{
++    PropertyPtr pProp, prevProp;
++    unsigned long n, len, ind;
++
++    if (!pWin)
++	return BadWindow;
++
++
++    if (!ValidAtom(property))
++    {
++	return(BadAtom);
++    }
++    if ((type != AnyPropertyType) && !ValidAtom(type))
++    {
++	return(BadAtom);
++    }
++
++    pProp = wUserProps (pWin);
++    prevProp = (PropertyPtr)NULL;
++
++    while (pProp)
++    {
++	if (pProp->propertyName == property)
++	    break;
++	prevProp = pProp;
++	pProp = pProp->next;
++    }
++
++
++    if (!pProp)
++	return (BadAtom);
++
++    /* If the request type and actual type don't match. Return the
++    property information, but not the data. */
++
++    if (((type != pProp->type) &&
++	 (type != AnyPropertyType))
++       )
++    {
++	*bytesAfter = pProp->size;
++	*format = pProp->format;
++	*nItems = 0;
++	*actualType = pProp->type;
++	return(Success);
++    }
++
++/*
++ *  Return type, format, value to client
++ */
++    n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
++    ind = longOffset << 2;
++
++   /* If longOffset is invalid such that it causes "len" to
++	    be negative, it's a value error. */
++
++    if (n < ind)
++    {
++	return BadValue;
++    }
++
++    len = min(n - ind, 4 * longLength);
++
++    *bytesAfter = n - (ind + len);
++    *format = pProp->format;
++    *nItems = len / (pProp->format / 8 );
++    *actualType = pProp->type;
++
++    if (delete && (*bytesAfter == 0))
++    { /* send the event */
++	xEvent event;
++
++	event.u.u.type = PropertyNotify;
++	event.u.property.window = pWin->drawable.id;
++	event.u.property.state = PropertyDelete;
++	event.u.property.atom = pProp->propertyName;
++	event.u.property.time = currentTime.milliseconds;
++	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
++    }
++
++    if (len)
++    {
++	 *propData = (unsigned char *)(pProp->data) + ind;
++    }
++
++    if (delete && (*bytesAfter == 0))
++    { /* delete the Property */
++#ifdef LBX
++	if (pProp->tag_id)
++	    TagDeleteTag(pProp->tag_id);
++#endif
++	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
++	{
++	    if (!(pWin->optional->userProps = pProp->next))
++		CheckWindowOptionalNeed (pWin);
++	}
++	else
++	    prevProp->next = pProp->next;
++	xfree(pProp->data);
++	xfree(pProp);
++    }
++    return(Success);
++}
++#endif
++
+ int
+ ProcListProperties(ClientPtr client)
+ {
+@@ -727,3 +989,4 @@
+     else
+ 	return(result);
+ }
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXrender.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXrender.c.NX.patch
new file mode 100644
index 0000000..62c9e33
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXrender.c.NX.patch
@@ -0,0 +1,948 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original	2015-02-13 14:03:44.748441432 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c	2015-02-10 19:13:13.800686036 +0100
+@@ -24,6 +24,23 @@
+  * Author:  Keith Packard, SuSE, Inc.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #define NEED_REPLIES
+ #define NEED_EVENTS
+ #ifdef HAVE_DIX_CONFIG_H
+@@ -44,8 +61,6 @@
+ #include "servermd.h"
+ #include <X11/extensions/render.h>
+ #include <X11/extensions/renderproto.h>
+-#include "picturestr.h"
+-#include "glyphstr.h"
+ #include <X11/Xfuncproto.h>
+ #include "cursorstr.h"
+ #ifdef EXTMODULE
+@@ -56,6 +71,95 @@
+ #define UINT32_MAX 0xffffffffU
+ #endif
+ 
++#include "NXpicturestr.h"
++#include "NXglyphstr.h"
++
++#include "Trap.h"
++
++#include "Render.h"
++#include "Pixmaps.h"
++#include "Options.h"
++#include "Screen.h"
++#include "Cursor.h"
++
++/*
++ * Set here the required log level.
++ */
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
++#ifdef TEST
++#include "Literals.h"
++#endif
++
++/*
++ * From NXmiglyph.c.
++ */
++
++void miGlyphExtents(int nlist, GlyphListPtr list,
++                        GlyphPtr *glyphs, BoxPtr extents);
++
++/*
++ * From NXmitrap.c.
++ */
++
++void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
++
++/*
++ * Functions from Render.c.
++ */
++
++int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
++void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
++int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
++int  nxagentCreatePicture(PicturePtr, Mask);
++void nxagentChangePicture(PicturePtr, Mask);
++int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
++void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
++                          INT16, INT16, INT16, INT16, CARD16, CARD16);
++void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
++void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
++void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
++void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
++void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
++void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
++void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
++                                 pointer params, int nparams);
++void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
++                           INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
++
++void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
++
++void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
++                                           xPointFixed *p2, int nStops,
++                                               xFixed *stops,
++                                                   xRenderColor *colors);
++
++void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
++                                           xPointFixed *outer,
++                                               xFixed innerRadius,
++                                                   xFixed outerRadius,
++                                                       int nStops,
++                                                           xFixed *stops,
++                                                               xRenderColor *colors);
++
++void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
++                                            xPointFixed *center,
++                                                xFixed angle, int nStops, 
++                                                    xFixed *stops, 
++                                                        xRenderColor *colors);
++
++
++/*
++ * The void pointer is actually a XGlyphElt8.
++ */
++
++void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
++                       INT16, INT16, int, void *, int, GlyphPtr *);
++
+ static int ProcRenderQueryVersion (ClientPtr pClient);
+ static int ProcRenderQueryPictFormats (ClientPtr pClient);
+ static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+@@ -290,8 +394,8 @@
+     rep.type = X_Reply;
+     rep.length = 0;
+     rep.sequenceNumber = client->sequence;
+-    rep.majorVersion = RENDER_MAJOR;
+-    rep.minorVersion = RENDER_MINOR;
++    rep.majorVersion = nxagentRenderVersionMajor;
++    rep.minorVersion = nxagentRenderVersionMinor;
+     if (client->swapped) {
+     	swaps(&rep.sequenceNumber, n);
+     	swapl(&rep.length, n);
+@@ -363,6 +467,8 @@
+     int				    n;
+     int				    numScreens;
+     int				    numSubpixel;
++
++    extern int                      nxagentAlphaEnabled;
+ /*    REQUEST(xRenderQueryPictFormatsReq); */
+ 
+     REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+@@ -439,7 +545,7 @@
+ 		pictForm->direct.greenMask = pFormat->direct.greenMask;
+ 		pictForm->direct.blue = pFormat->direct.blue;
+ 		pictForm->direct.blueMask = pFormat->direct.blueMask;
+-		pictForm->direct.alpha = pFormat->direct.alpha;
++		pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+ 		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+ 		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+ 		    pictForm->colormap = pFormat->index.pColormap->mid;
+@@ -656,6 +762,8 @@
+ 			      &error);
+     if (!pPicture)
+ 	return error;
++    nxagentCreatePicture(pPicture, stuff -> mask);
++
+     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ 	return BadAlloc;
+     return Success;
+@@ -667,6 +775,7 @@
+     PicturePtr	    pPicture;
+     REQUEST(xRenderChangePictureReq);
+     int len;
++    int error;
+ 
+     REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+@@ -676,8 +785,12 @@
+     if (Ones(stuff->mask) != len)
+ 	return BadLength;
+     
+-    return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
++    error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+ 			  (DevUnion *) 0, client);
++    
++    nxagentChangePicture(pPicture, stuff->mask);
++
++    return error;
+ }
+ 
+ static int
+@@ -694,13 +807,26 @@
+     if (!pPicture->pDrawable)
+         return BadDrawable;
+ 
+-    nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
++    /*
++     * The original code used sizeof(xRenderChangePictureReq).
++     * This was harmless, as both structures have the same size.
++     *
++     * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
++     */
++    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+     if (nr & 4)
+ 	return BadLength;
+     nr >>= 3;
+     result = SetPictureClipRects (pPicture, 
+ 				  stuff->xOrigin, stuff->yOrigin,
+ 				  nr, (xRectangle *) &stuff[1]);
++    nxagentChangePictureClip (pPicture,
++                              CT_NONE,
++                              nr,
++                              (xRectangle *) &stuff[1],
++                              (int)stuff -> xOrigin,
++                              (int)stuff -> yOrigin);
++
+     if (client->noClientException != Success)
+         return(client->noClientException);
+     else
+@@ -717,6 +843,7 @@
+ 
+     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+ 		    RenderErrBase + BadPicture);
++
+     FreeResource (stuff->picture, RT_NONE);
+     return(client->noClientException);
+ }
+@@ -733,6 +860,71 @@
+     return FALSE;
+ }
+ 
++/*
++ * Check if both pictures have drawables which are
++ * virtual pixmaps. See the corresponding define
++ * in NXpicture.c
++ */
++
++#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
++
++#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
++
++#define nxagentCompositePredicate(pSrc, pDst)  TRUE
++
++#else
++
++/*
++ * This is still under development. The final
++ * goal is to let pictures point to the real
++ * pixmaps instead of pointing to virtuals.
++ */
++
++int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
++{
++  PixmapPtr pPixmap1;
++  PixmapPtr pPixmap2;
++
++  pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
++                 ((PixmapPtr) pSrc -> pDrawable) : NULL);
++
++  pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
++                 ((PixmapPtr) pDst -> pDrawable) : NULL);
++
++  if (pPixmap1 == NULL || pPixmap2 == NULL)
++  {
++    #ifdef TEST
++    fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
++    #endif
++
++    return FALSE;
++  }
++  else
++  {
++    #ifdef TEST
++    fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
++    #endif
++
++    if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
++            nxagentPixmapIsVirtual(pPixmap2) == 1)
++    {
++      #ifdef TEST
++      fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
++      #endif
++
++      return TRUE;
++    }
++  }
++
++  #ifdef TEST
++  fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
++  #endif
++
++  return FALSE;
++}
++
++#endif
++
+ static int
+ ProcRenderComposite (ClientPtr client)
+ {
+@@ -753,9 +945,32 @@
+ 		    RenderErrBase + BadPicture);
+     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+ 		  RenderErrBase + BadPicture);
++/*
++FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
++
+     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+ 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+ 	return BadMatch;
++*/
++    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
++	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
++	return BadMatch;
++
++    ValidatePicture (pSrc);
++    if (pMask)
++        ValidatePicture (pMask);
++    ValidatePicture (pDst);
++
++    #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
++
++    if (nxagentCompositePredicate(pSrc, pDst))
++    {
++      #ifdef TEST
++      fprintf(stderr, "ProcRenderComposite: Going to composite with "
++                  "source at [%p] mask at [%p] and destination at [%p].\n",
++                      (void *) pSrc, (void *) pMask, (void *) pDst);
++      #endif
++
+     CompositePicture (stuff->op,
+ 		      pSrc,
+ 		      pMask,
+@@ -768,6 +983,78 @@
+ 		      stuff->yDst,
+ 		      stuff->width,
+ 		      stuff->height);
++    }
++
++    #else
++
++    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
++            pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
++                (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
++    {
++      PixmapPtr pVirtualPixmapSrc;
++      PixmapPtr pVirtualPixmapDst;
++      PixmapPtr pVirtualPixmapMask;
++
++      PicturePtr pVirtualPictureSrc;
++      PicturePtr pVirtualPictureDst;
++      PicturePtr pVirtualPictureMask;
++
++      pVirtualPixmapSrc  = (PixmapPtr) pSrc  -> pDrawable;
++      pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
++
++      pVirtualPixmapDst  = (PixmapPtr) pDst  -> pDrawable;
++      pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
++
++      if (pMask)
++      {
++        pVirtualPixmapMask  = (PixmapPtr) pMask  -> pDrawable;
++        pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
++      }
++      else
++      {
++        pVirtualPixmapMask  = NULL;
++        pVirtualPictureMask = NULL;
++      }
++
++      if (pVirtualPictureSrc && pVirtualPictureDst)
++      {
++      #ifdef TEST
++      fprintf(stderr, "ProcRenderComposite: Going to composite with "
++                  "source at [%p] mask at [%p] and destination at [%p].\n",
++                      (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
++                          (void *) pVirtualPixmapDst);
++      #endif
++
++      CompositePicture (stuff->op,
++                        pVirtualPictureSrc,
++                        pVirtualPictureMask,
++                        pVirtualPictureDst,
++                        stuff->xSrc,
++                        stuff->ySrc,
++                        stuff->xMask,
++                        stuff->yMask,
++                        stuff->xDst,
++                        stuff->yDst,
++                        stuff->width,
++                        stuff->height);
++      }
++    }
++
++    #endif
++
++    nxagentComposite (stuff -> op,
++                      pSrc,
++                      pMask,
++                      pDst,
++                      stuff -> xSrc,
++                      stuff -> ySrc,
++                      stuff -> xMask,
++                      stuff -> yMask,
++                      stuff -> xDst,
++                      stuff -> yDst,
++                      stuff -> width,
++                      stuff -> height);
++
+     return Success;
+ }
+ 
+@@ -818,9 +1105,33 @@
+ 	return BadLength;
+     ntraps /= sizeof (xTrapezoid);
+     if (ntraps)
++    {
++      if (pFormat != NULL)
++      {
++        nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
++
++        miTrapezoidBounds (ntraps, (xTrapezoid *) &stuff[1], nxagentTrapezoidExtents);
++      }
++
++      if (nxagentCompositePredicate(pSrc, pDst) == 1)
++      {
+ 	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+ 			     stuff->xSrc, stuff->ySrc,
+ 			     ntraps, (xTrapezoid *) &stuff[1]);
++      }
++
++      nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
++                             stuff->xSrc, stuff->ySrc,
++                                 ntraps, (xTrapezoid *) &stuff[1]);
++
++      if (nxagentTrapezoidExtents != NullBox)
++      {
++        xfree(nxagentTrapezoidExtents);
++
++        nxagentTrapezoidExtents = NullBox;
++      }
++    }
++
+     return client->noClientException;
+ }
+ 
+@@ -1029,6 +1340,9 @@
+ 	return BadAlloc;
+     if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ 	return BadAlloc;
++
++    nxagentCreateGlyphSet(glyphSet);
++
+     return Success;
+ }
+ 
+@@ -1052,6 +1366,9 @@
+ 	return RenderErrBase + BadGlyphSet;
+     }
+     glyphSet->refcnt++;
++
++    nxagentReferenceGlyphSet(glyphSet);
++
+     if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+ 	return BadAlloc;
+     return client->noClientException;
+@@ -1076,6 +1393,9 @@
+ 	client->errorValue = stuff->glyphset;
+ 	return RenderErrBase + BadGlyphSet;
+     }
++
++    nxagentFreeGlyphSet(glyphSet);
++
+     FreeResource (stuff->glyphset, RT_NONE);
+     return client->noClientException;
+ }
+@@ -1092,7 +1412,7 @@
+     REQUEST(xRenderAddGlyphsReq);
+     GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+     GlyphNewPtr	    glyphsBase, glyphs;
+-    GlyphPtr	    glyph;
++    GlyphPtr	    glyph = NULL;
+     int		    remain, nglyphs;
+     CARD32	    *gids;
+     xGlyphInfo	    *gi;
+@@ -1100,6 +1420,8 @@
+     int		    size;
+     int		    err = BadAlloc;
+ 
++    int             totSizeImages;
++
+     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+     glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+ 						     stuff->glyphset,
+@@ -1128,10 +1450,12 @@
+ 
+     glyphs = glyphsBase;
+ 
++    totSizeImages = 0;
+     gids = (CARD32 *) (stuff + 1);
+     gi = (xGlyphInfo *) (gids + nglyphs);
+     bits = (CARD8 *) (gi + nglyphs);
+     remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
++
+     while (remain >= 0 && nglyphs)
+     {
+ 	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+@@ -1152,12 +1476,14 @@
+ 	if (size & 3)
+ 	    size += 4 - (size & 3);
+ 	bits += size;
++	totSizeImages += size;
+ 	remain -= size;
+ 	gi++;
+ 	gids++;
+ 	glyphs++;
+ 	nglyphs--;
+     }
++
+     if (nglyphs || remain)
+     {
+ 	err = BadLength;
+@@ -1216,6 +1542,9 @@
+     }
+     nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+     gids = (CARD32 *) (stuff + 1);
++
++    nxagentFreeGlyphs(glyphSet, gids, nglyph);
++
+     while (nglyph-- > 0)
+     {
+ 	glyph = *gids++;
+@@ -1228,6 +1557,14 @@
+     return client->noClientException;
+ }
+ 
++typedef struct XGlyphElt8{
++    GlyphSet                glyphset;
++    _Xconst char            *chars;
++    int                     nchars;
++    int                     xOff;
++    int                     yOff;
++} XGlyphElt8;
++
+ static int
+ ProcRenderCompositeGlyphs (ClientPtr client)
+ {
+@@ -1248,6 +1585,8 @@
+     int		    size;
+     int		    n;
+     
++    XGlyphElt8      *elements, *elementsBase;
++
+     REQUEST(xRenderCompositeGlyphsReq);
+ 
+     REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+@@ -1335,9 +1674,15 @@
+ 	if (!listsBase)
+ 	    return BadAlloc;
+     }
++
++    elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
++    if (!elementsBase)
++      return BadAlloc;
++
+     buffer = (CARD8 *) (stuff + 1);
+     glyphs = glyphsBase;
+     lists = listsBase;
++    elements = elementsBase;
+     while (buffer + sizeof (xGlyphElt) < end)
+     {
+ 	elt = (xGlyphElt *) buffer;
+@@ -1345,6 +1690,11 @@
+ 	
+ 	if (elt->len == 0xff)
+ 	{
++            #ifdef DEBUG
++            fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
++                        size);
++            #endif
++
+ 	    if (buffer + sizeof (GlyphSet) < end)
+ 	    {
+                 memcpy(&gs, buffer, sizeof(GlyphSet));
+@@ -1370,6 +1720,22 @@
+ 	    lists->yOff = elt->deltay;
+ 	    lists->format = glyphSet->format;
+ 	    lists->len = 0;
++
++            if (glyphSet -> remoteID == 0)
++            {
++              #ifdef TEST
++              fprintf(stderr, "ProcRenderCompositeGlyphs: Going to reconnect glyphset at [%p].\n",
++                          (void *) glyphSet);
++              #endif
++
++              nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
++            }
++
++            elements -> glyphset = glyphSet -> remoteID;
++            elements -> chars = (char *) buffer;
++            elements -> nchars = elt->len;
++            elements -> xOff = elt->deltax;
++            elements -> yOff = elt->deltay;
+ 	    n = elt->len;
+ 	    while (n--)
+ 	    {
+@@ -1396,26 +1762,65 @@
+ 	    if (space & 3)
+ 		buffer += 4 - (space & 3);
+ 	    lists++;
++            elements++;
+ 	}
+     }
+     if (buffer > end)
+ 	return BadLength;
+ 
+-    CompositeGlyphs (stuff->op,
+-		     pSrc,
+-		     pDst,
+-		     pFormat,
+-		     stuff->xSrc,
+-		     stuff->ySrc,
+-		     nlist,
+-		     listsBase,
+-		     glyphsBase);
++    /*
++     * We need to know the glyphs extents to synchronize
++     * the drawables involved in the composite text ope-
++     * ration. Also we need to synchronize only the back-
++     * ground of the text we are going to render, so the
++     * operations on the framebuffer must be executed
++     * after the X requests.
++     */
++
++    nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
++
++    miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
++
++    nxagentGlyphs(stuff -> op,
++                  pSrc,
++                  pDst,
++                  pFormat,
++                  stuff -> xSrc,
++                  stuff -> ySrc,
++                  nlist,
++                  elementsBase,
++                  size,
++                  glyphsBase);
++
++    if (nxagentCompositePredicate(pSrc, pDst) == 1)
++    {
++      #ifdef TEST
++      fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
++                  "source at [%p] and destination at [%p].\n",
++                      (void *) pSrc, (void *) pDst);
++      #endif
++
++      CompositeGlyphs(stuff -> op,
++                      pSrc,
++                      pDst,
++                      pFormat,
++                      stuff -> xSrc,
++                      stuff -> ySrc,
++                      nlist,
++                      listsBase,
++                      glyphsBase);
++    }
++
++    xfree(nxagentGlyphsExtents);
++    nxagentGlyphsExtents = NullBox;
+ 
+     if (glyphsBase != glyphsLocal)
+ 	DEALLOCATE_LOCAL (glyphsBase);
+     if (listsBase != listsLocal)
+ 	DEALLOCATE_LOCAL (listsBase);
+     
++    xfree(elementsBase);
++
+     return client->noClientException;
+ }
+ 
+@@ -1447,6 +1852,13 @@
+ 		    &stuff->color,
+ 		    things,
+ 		    (xRectangle *) &stuff[1]);
++
++    ValidatePicture (pDst);
++    nxagentCompositeRects(stuff -> op,
++                          pDst,
++                          &stuff -> color,
++                          things,
++                          (xRectangle *) &stuff[1]);
+     
+     return client->noClientException;
+ }
+@@ -1495,6 +1907,8 @@
+     CARD32	    twocolor[3];
+     int		    ncolor;
+ 
++    RealizeCursorProcPtr saveRealizeCursor;
++
+     REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+     LEGAL_NEW_RESOURCE(stuff->cid, client);
+     
+@@ -1662,6 +2076,20 @@
+     cm.height = height;
+     cm.xhot = stuff->x;
+     cm.yhot = stuff->y;
++
++    /*
++     * This cursor uses RENDER, so we make sure
++     * that it is allocated in a way that allows
++     * the mi and dix layers to handle it but we
++     * later create it on the server by mirror-
++     * ing the RENDER operation we got from the
++     * client.
++     */
++
++    saveRealizeCursor = pScreen -> RealizeCursor;
++
++    pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
++
+     pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+ 			       GetColor(twocolor[0], 16),
+ 			       GetColor(twocolor[0], 8),
+@@ -1669,7 +2097,27 @@
+ 			       GetColor(twocolor[1], 16),
+ 			       GetColor(twocolor[1], 8),
+ 			       GetColor(twocolor[1], 0));
+-    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
++
++    pScreen -> RealizeCursor = saveRealizeCursor;
++
++    /*
++     * Store into the private data members the
++     * information needed to recreate it at
++     * reconnection. This is done in two steps
++     * as in the first step we don't have the
++     * picture info.
++     */
++
++    if (pCursor == NULL)
++    {
++      return BadAlloc;
++    }
++
++    nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
++
++    nxagentRenderRealizeCursor(pScreen, pCursor);
++
++    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ 	return (client->noClientException);
+     return BadAlloc;
+ }
+@@ -1685,6 +2133,9 @@
+     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+ 		    RenderErrBase + BadPicture);
+     result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
++
++    nxagentSetPictureTransform(pPicture, &stuff->transform);
++    
+     if (client->noClientException != Success)
+         return(client->noClientException);
+     else
+@@ -1785,7 +2236,7 @@
+     {
+ 	register int n;
+ 
+-	for (i = 0; i < reply->numAliases; i++)
++	for (i = 0; i < (int)reply->numAliases; i++)
+ 	{
+ 	    swaps (&aliases[i], n);
+ 	}
+@@ -1817,6 +2268,9 @@
+     params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+     nparams = ((xFixed *) stuff + client->req_len) - params;
+     result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
++
++    nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
++
+     return result;
+ }
+ 
+@@ -1859,7 +2313,14 @@
+     xfree (cursors);
+     if (ret != Success)
+ 	return ret;
+-    
++
++    nxagentAnimCursorBits = pCursor -> bits;
++
++    for (i = 0; i < MAXSCREENS; i++)
++    {
++      pCursor -> devPriv[i] = NULL;
++    }
++
+     if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+ 	return client->noClientException;
+     return BadAlloc;
+@@ -1901,6 +2362,11 @@
+     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+     if (!pPicture)
+ 	return error;
++    /* AGENT SERVER */
++
++    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
++
++    /* AGENT SERVER */
+     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ 	return BadAlloc;
+     return Success;
+@@ -1932,6 +2398,12 @@
+                                             stuff->nStops, stops, colors, &error);
+     if (!pPicture)
+ 	return error;
++    /* AGENT SERVER */
++
++    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
++                                          stuff->nStops, stops, colors);
++
++    /* AGENT SERVER */
+     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ 	return BadAlloc;
+     return Success;
+@@ -1962,6 +2434,14 @@
+                                             stuff->nStops, stops, colors, &error);
+     if (!pPicture)
+ 	return error;
++    /* AGENT SERVER */
++
++    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
++                                          stuff->inner_radius,
++                                              stuff->outer_radius, 
++                                                  stuff->nStops, stops, colors);
++
++    /* AGENT SERVER */
+     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ 	return BadAlloc;
+     return Success;
+@@ -1991,6 +2471,13 @@
+                                              stuff->nStops, stops, colors, &error);
+     if (!pPicture)
+ 	return error;
++    /* AGENT SERVER */
++
++    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
++                                           stuff->angle, stuff->nStops, stops,
++                                               colors);
++
++    /* AGENT SERVER */
+     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+ 	return BadAlloc;
+     return Success;
+@@ -2000,10 +2487,41 @@
+ static int
+ ProcRenderDispatch (ClientPtr client)
+ {
++    int result;
++
+     REQUEST(xReq);
++
++    /*
++     * Let the client fail if we are
++     * hiding the RENDER extension.
++     */
+     
++    if (nxagentRenderTrap)
++    {
++        return BadRequest;
++    }
++
+     if (stuff->data < RenderNumberRequests)
+-	return (*ProcRenderVector[stuff->data]) (client);
++    {
++        #ifdef TEST
++        fprintf(stderr, "ProcRenderDispatch: Request [%s] OPCODE#%d.\n",
++                    nxagentRenderRequestLiteral[stuff->data], stuff->data);
++        #endif
++
++        /*
++         * Set the nxagentGCTrap flag while
++         * dispatching a render operation to
++         * avoid reentrancy in GCOps.c.
++         */
++
++        nxagentGCTrap = 1;
++
++        result = (*ProcRenderVector[stuff->data]) (client);
++
++        nxagentGCTrap = 0;
++
++        return result;
++    }
+     else
+ 	return BadRequest;
+ }
+@@ -2253,7 +2771,7 @@
+ SProcRenderAddGlyphs (ClientPtr client)
+ {
+     register int n;
+-    register int i;
++    register unsigned int i;
+     CARD32  *gids;
+     void    *end;
+     xGlyphInfo *gi;
+@@ -2595,10 +3113,36 @@
+ static int
+ SProcRenderDispatch (ClientPtr client)
+ {
++    int result;
++
+     REQUEST(xReq);
+     
++    /*
++     * Let the client fail if we are
++     * hiding the RENDER extension.
++     */
++    
++    if (nxagentRenderTrap)
++    {
++        return BadRequest;
++    }
++
+     if (stuff->data < RenderNumberRequests)
+-	return (*SProcRenderVector[stuff->data]) (client);
++    {
++        /*
++         * Set the nxagentGCTrap flag while
++         * dispatching a render operation to
++         * avoid reentrancy in GCOps.c.
++         */
++
++        nxagentGCTrap = 1;
++
++        result = (*SProcRenderVector[stuff->data]) (client);
++
++        nxagentGCTrap = 0;
++
++        return result;
++    }
+     else
+ 	return BadRequest;
+ }
+@@ -3314,3 +3858,4 @@
+ }
+ 
+ #endif	/* PANORAMIX */
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXresource.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXresource.c.NX.patch
new file mode 100644
index 0000000..3c7f45e
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXresource.c.NX.patch
@@ -0,0 +1,426 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original	2015-02-13 14:03:44.748441432 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c	2015-02-10 19:13:13.820685287 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /************************************************************
+ 
+ Copyright 1987, 1998  The Open Group
+@@ -125,6 +142,20 @@
+ #endif
+ #include <assert.h>
+ 
++#ifdef NXAGENT_SERVER
++
++#include "Agent.h"
++#include "Font.h"
++#include "Pixmaps.h"
++#include "GCs.h"
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
++#endif
++
+ static void RebuildTable(
+     int /*client*/
+ );
+@@ -170,6 +201,10 @@
+ 
+ #endif
+ 
++#ifdef NXAGENT_SERVER
++static int nxagentResChangedFlag = 0;
++#endif
++
+ RESTYPE
+ CreateNewResourceType(DeleteType deleteFunc)
+ {
+@@ -422,13 +457,107 @@
+     return id;
+ }
+ 
++#ifdef NXAGENT_SERVER
++
++int nxagentFindClientResource(int client, RESTYPE type, pointer value)
++{
++  ResourcePtr pResource;
++  ResourcePtr *resources;
++
++  int i;
++
++  for (i = 0; i < clientTable[client].buckets; i++)
++  {
++    resources = clientTable[client].resources;
++
++    for (pResource = resources[i]; pResource; pResource = pResource -> next)
++    {
++      if (pResource -> type == type && pResource -> value == value)
++      {
++        #ifdef TEST
++        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
++                    "for client [%d].\n", (void *) value,
++                        pResource -> type, client);
++        #endif
++
++        return 1;
++      }
++    }
++  }
++
++  return 0;
++}
++
++int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
++{
++  ResourcePtr pResource;
++  ResourcePtr *resources;
++
++  RESTYPE internalType = 0;
++
++  int i;
++
++  if (type == RT_PIXMAP)
++  {
++    internalType = RT_NX_PIXMAP;
++  }
++  else if (type == RT_GC)
++  {
++    internalType = RT_NX_GC;
++  }
++  else if (type == RT_FONT)
++  {
++    internalType = RT_NX_FONT;
++  }
++  else
++  {
++    return 0;
++  }
++
++  if (client == serverClient -> index)
++  {
++    #ifdef TEST
++    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
++                client);
++    #endif
++
++    return 0;
++  }
++
++  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
++  {
++    resources = clientTable[serverClient -> index].resources;
++
++    for (pResource = resources[i]; pResource; pResource = pResource -> next)
++    {
++      if (pResource -> type == internalType &&
++              pResource -> value == value)
++      {
++        #ifdef TEST
++        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
++                    "[%lu] for server client [%d].\n", (void *) value,
++                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
++        #endif
++
++        FreeResource(pResource -> id, RT_NONE);
++
++        return 1;
++      }
++    }
++  }
++
++  return 0;
++}
++
++#endif
++
+ Bool
+ AddResource(XID id, RESTYPE type, pointer value)
+ {
+     int client;
+     register ClientResourceRec *rrec;
+     register ResourcePtr res, *head;
+-    	
++
+     client = CLIENT_ID(id);
+     rrec = &clientTable[client];
+     if (!rrec->buckets)
+@@ -437,6 +566,18 @@
+ 		(unsigned long)id, type, (unsigned long)value, client);
+         FatalError("client not in use\n");
+     }
++
++#ifdef NXAGENT_SERVER
++
++    nxagentSwitchResourceType(client, type, value);
++
++    #ifdef TEST
++    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
++                client, (unsigned long) type, (void *) value, (unsigned long) id);
++    #endif
++
++#endif
++
+     if ((rrec->elements >= 4*rrec->buckets) &&
+ 	(rrec->hashsize < MAXHASHSIZE))
+ 	RebuildTable(client);
+@@ -453,6 +594,9 @@
+     res->value = value;
+     *head = res;
+     rrec->elements++;
++    #ifdef NXAGENT_SERVER
++    nxagentResChangedFlag = 1;
++    #endif
+     if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+ 	rrec->expectID = id + 1;
+     return TRUE;
+@@ -517,6 +661,14 @@
+     int		elements;
+     Bool	gotOne = FALSE;
+ 
++#ifdef NXAGENT_SERVER
++
++    #ifdef TEST
++    fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
++    #endif
++
++#endif
++
+     if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+     {
+ 	head = &clientTable[cid].resources[Hash(cid, id)];
+@@ -530,6 +682,9 @@
+ 		RESTYPE rtype = res->type;
+ 		*prev = res->next;
+ 		elements = --*eltptr;
++                #ifdef NXAGENT_SERVER
++                nxagentResChangedFlag = 1;
++                #endif
+ 		if (rtype & RC_CACHED)
+ 		    FlushClientCaches(res->id);
+ 		if (rtype != skipDeleteFuncType)
+@@ -570,6 +725,9 @@
+ 	    if (res->id == id && res->type == type)
+ 	    {
+ 		*prev = res->next;
++                #ifdef NXAGENT_SERVER
++                nxagentResChangedFlag = 1;
++                #endif
+ 		if (type & RC_CACHED)
+ 		    FlushClientCaches(res->id);
+ 		if (!skipFree)
+@@ -634,10 +792,28 @@
+     int i, elements;
+     register int *eltptr;
+ 
++    #ifdef NXAGENT_SERVER
++    register ResourcePtr **resptr;
++    #endif
++
+     if (!client)
+ 	client = serverClient;
+ 
++/*
++ * If func triggers a resource table
++ * rebuild then restart the loop.
++ */
++
++#ifdef NXAGENT_SERVER
++RestartLoop:
++#endif
++
+     resources = clientTable[client->index].resources;
++
++    #ifdef NXAGENT_SERVER
++    resptr = &clientTable[client->index].resources;
++    #endif
++
+     eltptr = &clientTable[client->index].elements;
+     for (i = 0; i < clientTable[client->index].buckets; i++) 
+     {
+@@ -646,8 +822,44 @@
+ 	    next = this->next;
+ 	    if (!type || this->type == type) {
+ 		elements = *eltptr;
++
++                /*
++                 * FIXME:
++                 * It is not safe to let a function change the resource
++                 * table we are reading!
++                 */
++
++                #ifdef NXAGENT_SERVER
++                nxagentResChangedFlag = 0;
++                #endif
+ 		(*func)(this->value, this->id, cdata);
++
++                /*
++                 * Avoid that a call to RebuildTable() could invalidate the
++                 * pointer. This is safe enough, because in RebuildTable()
++                 * the new pointer is allocated just before the old one is
++                 * freed, so it can't point to the same address.
++                 */
++
++                #ifdef NXAGENT_SERVER
++                if (*resptr != resources)
++                   goto RestartLoop;
++                #endif
++
++                /*
++                 * It's not enough to check if the number of elements has
++                 * changed, beacause it could happen that the number of
++                 * resources that have been added matches the number of
++                 * the freed ones.
++                 * 'nxagentResChangedFlag' is set if a resource has been
++                 * added or freed.
++                 */
++
++                #ifdef NXAGENT_SERVER
++                if (*eltptr != elements || nxagentResChangedFlag)
++                #else
+ 		if (*eltptr != elements)
++                #endif
+ 		    next = resources[i]; /* start over */
+ 	    }
+ 	}
+@@ -665,10 +877,28 @@
+     int i, elements;
+     register int *eltptr;
+ 
++    #ifdef NXAGENT_SERVER
++    register ResourcePtr **resptr;
++    #endif
++
+     if (!client)
+         client = serverClient;
+ 
++/*
++ * If func triggers a resource table
++ * rebuild then restart the loop.
++ */
++
++#ifdef NXAGENT_SERVER
++RestartLoop:
++#endif
++
+     resources = clientTable[client->index].resources;
++
++    #ifdef NXAGENT_SERVER
++    resptr = &clientTable[client->index].resources;
++    #endif
++
+     eltptr = &clientTable[client->index].elements;
+     for (i = 0; i < clientTable[client->index].buckets; i++)
+     {
+@@ -676,8 +906,44 @@
+         {
+             next = this->next;
+             elements = *eltptr;
++
++            /*
++             * FIXME:
++             * It is not safe to let a function change the resource
++             * table we are reading!
++             */
++
++            #ifdef NXAGENT_SERVER
++            nxagentResChangedFlag = 0;
++            #endif
+             (*func)(this->value, this->id, this->type, cdata);
++
++            /*
++             * Avoid that a call to RebuildTable() could invalidate the
++             * pointer. This is safe enough, because in RebuildTable()
++             * the new pointer is allocated just before the old one is
++             * freed, so it can't point to the same address.
++             */
++
++            #ifdef NXAGENT_SERVER
++            if (*resptr != resources)
++                goto RestartLoop;
++            #endif
++
++            /*
++             * It's not enough to check if the number of elements has
++             * changed, beacause it could happen that the number of
++             * resources that have been added matches the number of
++             * the freed ones.
++             * 'nxagentResChangedFlag' is set if a resource has been
++             * added or freed.
++             */
++
++            #ifdef NXAGENT_SERVER
++            if (*eltptr != elements || nxagentResChangedFlag)
++            #else
+             if (*eltptr != elements)
++            #endif
+                 next = resources[i]; /* start over */
+         }
+     }
+@@ -695,15 +961,44 @@
+     ResourcePtr this;
+     int i;
+ 
++    #ifdef NXAGENT_SERVER
++    ResourcePtr **resptr;
++    Bool res;
++    #endif
++
+     if (!client)
+ 	client = serverClient;
+ 
++/*
++ * If func triggers a resource table
++ * rebuild then restart the loop.
++ */
++
++#ifdef NXAGENT_SERVER
++RestartLoop:
++#endif
++
+     resources = clientTable[client->index].resources;
++
++    #ifdef NXAGENT_SERVER
++    resptr = &clientTable[client->index].resources;
++    #endif
++
+     for (i = 0; i < clientTable[client->index].buckets; i++) {
+         for (this = resources[i]; this; this = this->next) {
+ 	    if (!type || this->type == type) {
++                #ifdef NXAGENT_SERVER
++                res = (*func)(this->value, this->id, cdata);
++
++                if (*resptr != resources)
++                    goto RestartLoop;
++
++                if (res)
++                    return this->value;
++                #else
+ 		if((*func)(this->value, this->id, cdata))
+ 		    return this->value;
++                #endif
+ 	    }
+ 	}
+     }
+@@ -952,3 +1247,4 @@
+ }
+ 
+ #endif /* XCSECURITY */
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXshm.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXshm.c.NX.patch
new file mode 100644
index 0000000..ecc5d49
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXshm.c.NX.patch
@@ -0,0 +1,373 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original	2015-02-13 14:03:44.748441432 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c	2015-02-10 19:13:13.812685587 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+ /************************************************************
+ 
+@@ -73,6 +90,31 @@
+ 
+ #include "modinit.h"
+ 
++#include "Trap.h"
++#include "Agent.h"
++#include "Drawable.h"
++#include "Pixmaps.h"
++
++/*
++ * Set here the required log level.
++ */
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
++#ifdef TEST
++#include "Literals.h"
++#endif
++
++extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
++                           unsigned int format, unsigned long planeMask, char *d);
++
++extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
++                            int x, int y, int w, int h, int leftPad, int format,
++                                char *pImage);
++
+ typedef struct _ShmDesc {
+     struct _ShmDesc *next;
+     int shmid;
+@@ -216,15 +258,25 @@
+     }
+ #endif
+ 
++    if (nxagentOption(SharedMemory) == False)
++    {
++      return;
++    }
++
+     sharedPixmaps = xFalse;
+     pixmapFormat = 0;
+     {
+-      sharedPixmaps = xTrue;
++      sharedPixmaps = nxagentOption(SharedPixmaps);
+       pixmapFormat = shmPixFormat[0];
+       for (i = 0; i < screenInfo.numScreens; i++)
+       {
+ 	if (!shmFuncs[i])
++        {
++            #ifdef TEST
++            fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
++            #endif
+ 	    shmFuncs[i] = &miFuncs;
++        }
+ 	if (!shmFuncs[i]->CreatePixmap)
+ 	    sharedPixmaps = xFalse;
+ 	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+@@ -335,6 +387,9 @@
+ ShmRegisterFbFuncs(pScreen)
+     ScreenPtr pScreen;
+ {
++    #ifdef TEST
++    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
++    #endif
+     shmFuncs[pScreen->myNum] = &fbFuncs;
+ }
+ 
+@@ -512,12 +567,17 @@
+     PixmapPtr pmap;
+     GCPtr putGC;
+ 
++    nxagentShmTrap = 0;
+     putGC = GetScratchGC(depth, dst->pScreen);
+     if (!putGC)
++    {
++        nxagentShmTrap = 1;
+ 	return;
++    }
+     pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+     if (!pmap)
+     {
++        nxagentShmTrap = 1;
+ 	FreeScratchGC(putGC);
+ 	return;
+     }
+@@ -532,6 +592,7 @@
+ 	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ 				    dx, dy);
+     (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
++    nxagentShmTrap = 1;
+ }
+ 
+ static void
+@@ -542,6 +603,15 @@
+     unsigned int format;
+     char 	*data;
+ {
++    int length;
++    char *newdata;
++    extern int nxagentImageLength(int, int, int, int, int);
++
++    #ifdef TEST
++    fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
++                (void *) dst, (void *) pGC, (void *) data);
++    #endif
++
+     if ((format == ZPixmap) || (depth == 1))
+     {
+ 	PixmapPtr pPixmap;
+@@ -556,11 +626,45 @@
+ 	else
+ 	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ 					sx, sy, sw, sh, dx, dy);
++
++        /*
++         * We updated the internal framebuffer,
++         * now we want to go on the real X.
++         */
++
++        #ifdef TEST
++        fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
++                    " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
++                        " sh [%d] dx [%d].\n", depth, format, w, h,
++                            sx, sy, sw, sh, dx);
++        #endif
++
++        length = nxagentImageLength(sw, sh, format, 0, depth);
++
++        if ((newdata = xalloc(length)) != NULL)
++        {
++          fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
++          (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
++
++          xfree(newdata);
++        }
++        else
++        {
++          #ifdef WARNING
++          fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
++          #endif
++        }
++
+ 	FreeScratchPixmapHeader(pPixmap);
+     }
+     else
++    {
++        #ifdef TEST
++        fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
++        #endif
+ 	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ 		      data);
++    }
+ }
+ 
+ 
+@@ -895,26 +999,22 @@
+ 	return BadValue;
+     }
+ 
+-    if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
+-	 ((stuff->format != ZPixmap) &&
+-	  (stuff->srcX < screenInfo.bitmapScanlinePad) &&
+-	  ((stuff->format == XYBitmap) ||
+-	   ((stuff->srcY == 0) &&
+-	    (stuff->srcHeight == stuff->totalHeight))))) &&
+-	((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
+-	(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
+-			       stuff->dstX, stuff->dstY,
+-			       stuff->totalWidth, stuff->srcHeight, 
+-			       stuff->srcX, stuff->format, 
+-			       shmdesc->addr + stuff->offset +
+-			       (stuff->srcY * length));
+-    else
+-	(*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+-			       pDraw, pGC, stuff->depth, stuff->format,
+-			       stuff->totalWidth, stuff->totalHeight,
+-			       stuff->srcX, stuff->srcY,
+-			       stuff->srcWidth, stuff->srcHeight,
+-			       stuff->dstX, stuff->dstY,
++    #ifdef TEST
++    fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
++                "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
++                    stuff->srcY, stuff->totalWidth, stuff->totalHeight);
++    #endif
++
++    #ifdef TEST
++    fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
++    #endif
++
++    (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
++                               pDraw, pGC, stuff->depth, stuff->format,
++                               stuff->totalWidth, stuff->totalHeight,
++                               stuff->srcX, stuff->srcY,
++                               stuff->srcWidth, stuff->srcHeight,
++                               stuff->dstX, stuff->dstY,
+                                shmdesc->addr + stuff->offset);
+ 
+     if (stuff->sendEvent)
+@@ -1056,15 +1156,37 @@
+ {
+     register PixmapPtr pPixmap;
+ 
+-    pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
++    nxagentShmPixmapTrap = 1;
++
++    pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
++
+     if (!pPixmap)
+-	return NullPixmap;
++    {
++      nxagentShmPixmapTrap = 0;
++
++      return NullPixmap;
++    }
++
++    #ifdef TEST
++    fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
++    #endif
+ 
+     if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+-	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
+-	(*pScreen->DestroyPixmap)(pPixmap);
+-	return NullPixmap;
++	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) 
++    {
++      #ifdef WARNING
++      fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
++      #endif
++
++      (*pScreen->DestroyPixmap)(pPixmap);
++
++      nxagentShmPixmapTrap = 0;
++
++      return NullPixmap;
+     }
++
++    nxagentShmPixmapTrap = 0;
++
+     return pPixmap;
+ }
+ 
+@@ -1146,6 +1268,18 @@
+     register ClientPtr	client;
+ {
+     REQUEST(xReq);
++
++    #ifdef TEST
++    fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
++                stuff -> data, client -> index);
++
++    if (stuff->data <= X_ShmCreatePixmap)
++    {
++      fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n",
++                  nxagentShmRequestLiteral[stuff->data], stuff->data);
++    }
++    #endif
++
+     switch (stuff->data)
+     {
+     case X_ShmQueryVersion:
+@@ -1155,11 +1289,38 @@
+     case X_ShmDetach:
+ 	return ProcShmDetach(client);
+     case X_ShmPutImage:
++      {
++        int result;
++
++        #ifdef TEST
++        fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n", 
++                    client -> index);
++        #endif
++
++        nxagentShmTrap = 1;
++
+ #ifdef PANORAMIX
+         if ( !noPanoramiXExtension )
+-	   return ProcPanoramiXShmPutImage(client);
++        {
++           result = ProcPanoramiXShmPutImage(client);
++
++           nxagentShmTrap = 0;
++
++           return result;
++        }
+ #endif
+-	return ProcShmPutImage(client);
++
++        result = ProcShmPutImage(client);
++
++        nxagentShmTrap = 0;
++
++        #ifdef TEST
++        fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n", 
++                    client -> index);
++        #endif
++
++        return result;
++      }
+     case X_ShmGetImage:
+ #ifdef PANORAMIX
+         if ( !noPanoramiXExtension )
+@@ -1290,6 +1451,12 @@
+     register ClientPtr	client;
+ {
+     REQUEST(xReq);
++
++    #ifdef TEST
++    fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
++                stuff -> data, client -> index);
++    #endif
++
+     switch (stuff->data)
+     {
+     case X_ShmQueryVersion:
+@@ -1299,7 +1466,27 @@
+     case X_ShmDetach:
+ 	return SProcShmDetach(client);
+     case X_ShmPutImage:
+-	return SProcShmPutImage(client);
++      {
++        int result;
++
++        #ifdef TEST
++        fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n", 
++                    client -> index);
++        #endif
++
++        nxagentShmTrap = 1;
++
++        result = SProcShmPutImage(client);
++
++        nxagentShmTrap = 0;
++
++        #ifdef TEST
++        fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n", 
++                    client -> index);
++        #endif
++
++        return result;
++      }
+     case X_ShmGetImage:
+ 	return SProcShmGetImage(client);
+     case X_ShmCreatePixmap:
+@@ -1308,3 +1495,4 @@
+ 	return BadRequest;
+     }
+ }
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXwindow.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXwindow.c.NX.patch
new file mode 100644
index 0000000..667dadc
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXwindow.c.NX.patch
@@ -0,0 +1,561 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original	2015-02-13 14:03:44.748441432 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c	2015-02-10 19:13:13.780686785 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+ /* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+ /*
+@@ -97,9 +114,10 @@
+ #include "dixstruct.h"
+ #include "gcstruct.h"
+ #include "servermd.h"
++#include "selection.h"
+ #ifdef PANORAMIX
+-#include "panoramiX.h"
+-#include "panoramiXsrv.h"
++#include "../../Xext/panoramiX.h"
++#include "../../Xext/panoramiXsrv.h"
+ #endif
+ #include "dixevents.h"
+ #include "globals.h"
+@@ -112,6 +130,19 @@
+ #include <X11/extensions/security.h>
+ #endif
+ 
++#include "Screen.h"
++#include "Options.h"
++#include "Atoms.h"
++#include "Clipboard.h"
++#include "Splash.h"
++#include "Rootless.h"
++#include "Composite.h"
++#include "Drawable.h"
++#include "Colormap.h"
++
++extern Bool nxagentWMIsRunning;
++extern Bool nxagentScreenTrap;
++
+ /******
+  * Window stuff for server 
+  *
+@@ -160,10 +191,25 @@
+ #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+ 
+ 
++/*
++ * Set here the required log level.
++ */
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
+ int numSaveUndersViewable = 0;
+ int deltaSaveUndersViewable = 0;
+ 
+-#ifdef DEBUG
++WindowPtr nxagentRootTileWindow;
++
++/*
++ * This block used the DEBUG symbol.
++ */
++
++#ifdef WINDOW_TREE_DEBUG
+ /******
+  * PrintWindowTree
+  *    For debugging only
+@@ -289,6 +335,31 @@
+ #endif
+ }
+ 
++#ifdef NXAGENT_SERVER
++
++void nxagentClearSplash(WindowPtr pW)
++{
++    int w, h;
++    ScreenPtr pScreen;
++
++    w = pW->drawable.width;
++    h = pW->drawable.height;
++
++    pScreen = pW->drawable.pScreen;
++
++    if (pW->backgroundState == BackgroundPixmap)
++    {
++      (*pScreen->DestroyPixmap)(pW->background.pixmap);
++    }
++
++    pW->backgroundState = BackgroundPixel;
++    pW->background.pixel = nxagentLogoBlack;
++
++    (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
++}
++
++#endif /* NXAGENT_SERVER */
++
+ static void
+ MakeRootTile(WindowPtr pWin)
+ {
+@@ -333,6 +404,9 @@
+ 
+    FreeScratchGC(pGC);
+ 
++#ifdef NXAGENT_SERVER
++   nxagentRootTileWindow = pWin;
++#endif /* NXAGENT_SERVER */
+ }
+ 
+ WindowPtr
+@@ -458,9 +532,16 @@
+ 	return FALSE;
+ 
+     if (disableBackingStore)
+-	pScreen->backingStoreSupport = NotUseful;
++    {
++      pScreen -> backingStoreSupport = NotUseful;
++    }
++
+     if (enableBackingStore)
+-	pScreen->backingStoreSupport = Always;
++    {
++      pScreen -> backingStoreSupport = Always;
++    }
++
++    pScreen->saveUnderSupport = False;
+ 
+ #ifdef DO_SAVE_UNDERS
+     if ((pScreen->backingStoreSupport != NotUseful) &&
+@@ -480,6 +561,107 @@
+     return TRUE;
+ }
+ 
++#ifdef NXAGENT_SERVER
++
++void
++InitRootWindow(WindowPtr pWin)
++{
++    ScreenPtr pScreen;
++
++    #ifdef TEST
++    fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
++                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
++    #endif
++
++    if (nxagentOption(Rootless))
++    {
++      #ifdef TEST
++      fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
++                  (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
++      #endif
++
++      nxagentRootlessWindow = pWin;
++    }
++
++    pScreen = pWin->drawable.pScreen;
++
++    /*
++     * A root window is created for each screen by main
++     * and the pointer is saved in WindowTable as in the
++     * following snippet:
++     *
++     * for (i = 0; i < screenInfo.numScreens; i++)
++     *          InitRootWindow(WindowTable[i]);
++     *
++     * Our root window on the real display was already
++     * created at the time the screen was opened, so it
++     * is unclear how this window (or the other window,
++     * if you prefer) fits in the big picture.
++     */
++
++    #ifdef TEST
++    fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
++                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
++    #endif
++
++    if (!(*pScreen->CreateWindow)(pWin))
++	return; /* XXX */
++
++    #ifdef TEST
++    fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
++                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
++    #endif
++
++    (*pScreen->PositionWindow)(pWin, 0, 0);
++
++    pWin->cursorIsNone = FALSE;
++    pWin->optional->cursor = rootCursor;
++    rootCursor->refcnt++;
++    pWin->backingStore = defaultBackingStore;
++    pWin->forcedBS = (defaultBackingStore != NotUseful);
++
++    #ifdef NXAGENT_SPLASH
++    /* We SHOULD check for an error value here XXX */
++    pWin -> background.pixel = pScreen -> blackPixel;
++    (*pScreen->ChangeWindowAttributes)(pWin,
++		       CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
++    #else
++    (*pScreen->ChangeWindowAttributes)(pWin,
++		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
++    #endif
++
++    MakeRootTile(pWin);
++
++    /*
++     * Map both the root and the default agent window.
++     */
++
++    #ifdef TEST
++    fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
++    #endif
++
++    nxagentInitAtoms(pWin);
++
++    nxagentInitClipboard(pWin);
++
++    nxagentMapDefaultWindows();
++
++    nxagentRedirectDefaultWindows();
++
++    #ifdef NXAGENT_ARTSD
++    {
++      char artsd_port[10];
++      int nPort;
++      extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
++      nPort = atoi(display) + 7000;
++      sprintf(artsd_port,"%d", nPort);
++      nxagentPropagateArtsdProperties(pScreen, artsd_port);
++    }
++    #endif
++}
++
++#else /* NXAGENT_SERVER */
++
+ void
+ InitRootWindow(WindowPtr pWin)
+ {
+@@ -502,6 +684,8 @@
+     MapWindow(pWin, serverClient);
+ }
+ 
++#endif /* NXAGENT_SERVER */
++
+ /* Set the region to the intersection of the rectangle and the
+  * window's winSize.  The window is typically the parent of the
+  * window from which the region came.
+@@ -512,7 +696,9 @@
+                      register int x, register int y,
+                      register int w, register int h)
+ {
++#ifndef NXAGENT_SERVER
+     ScreenPtr pScreen = pWin->drawable.pScreen;
++#endif /* NXAGENT_SERVER */
+     BoxRec box;
+ 
+     box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+@@ -907,6 +1093,14 @@
+ 	if (pWin->prevSib)
+ 	    pWin->prevSib->nextSib = pWin->nextSib;
+     }
++
++    if (pWin -> optional &&
++            pWin -> optional -> colormap &&
++                pWin -> parent)
++    {
++      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
++    }
++
+     xfree(pWin);
+     return Success;
+ }
+@@ -1147,6 +1341,12 @@
+ 		goto PatchUp;
+ 	    }
+ 	    pWin->backingStore = val;
++
++            #ifdef TEST
++            fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
++                        val, (void*)pWin);
++            #endif
++
+ 	    pWin->forcedBS = FALSE;
+ 	    break;
+ 	  case CWBackingPlanes:
+@@ -1227,6 +1427,22 @@
+ #endif /* DO_SAVE_UNDERS */
+ 	    break;
+ 	  case CWEventMask:
++            /*
++             * TODO: Some applications like java bean shell
++             * don' t work if they cannot monitor the root
++             * window for Structure Redirect events. However
++             * this doesn't seem to be the best solution, since
++             * also an X server with a window manager running,
++             * doesn't allow to monitor for those events, but
++             * the java bean shell works flawlessy on this
++             * server.
++             *
++             * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
++             * {
++             *   return BadAccess;
++             * }
++             */
++
+ 	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+ 	    if (result)
+ 	    {
+@@ -1611,8 +1827,9 @@
+     pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+ #ifdef SHAPE
+     if (wBoundingShape (pWin) || wClipShape (pWin)) {
++#ifndef NXAGENT_SERVER
+ 	ScreenPtr pScreen = pWin->drawable.pScreen;
+-
++#endif /* NXAGENT_SERVER */
+ 	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+ 			 - pWin->drawable.y);
+ 	if (wBoundingShape (pWin))
+@@ -1647,8 +1864,9 @@
+ 			 (int)pWin->drawable.height);
+ #ifdef SHAPE
+     if (wBoundingShape (pWin) || wClipShape (pWin)) {
++#ifndef NXAGENT_SERVER
+ 	ScreenPtr pScreen = pWin->drawable.pScreen;
+-
++#endif /* NXAGENT_SERVER */
+ 	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+ 			 - pWin->drawable.y);
+ 	if (wBoundingShape (pWin))
+@@ -1689,8 +1907,9 @@
+ 		(int)(pWin->drawable.height + (bw<<1)));
+ #ifdef SHAPE
+ 	if (wBoundingShape (pWin)) {
++#ifndef NXAGENT_SERVER
+ 	    ScreenPtr pScreen = pWin->drawable.pScreen;
+-
++#endif /* NXAGENT_SERVER */
+ 	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+ 			     - pWin->drawable.y);
+ 	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+@@ -1800,7 +2019,19 @@
+ 	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+ 	SetWinSize (pSib);
+ 	SetBorderSize (pSib);
+-	(*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
++
++        /*
++         * Don't force X to move children. It will position them
++         * according with gravity.
++         *
++         * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
++         */
++
++        /*
++         * Update pSib privates, as this window is moved by X.
++         */
++
++        nxagentAddConfiguredWindow(pSib, CW_Update);
+ 
+ 	if ( (pChild = pSib->firstChild) )
+ 	{
+@@ -1812,8 +2043,10 @@
+ 				     pChild->origin.y;
+ 		SetWinSize (pChild);
+ 		SetBorderSize (pChild);
+-		(*pScreen->PositionWindow)(pChild,
+-				    pChild->drawable.x, pChild->drawable.y);
++
++                (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
++                                               pChild->drawable.y);
++
+ 		if (pChild->firstChild)
+ 		{
+ 		    pChild = pChild->firstChild;
+@@ -1900,8 +2133,9 @@
+     BoxPtr	pBox)
+ {
+     RegionPtr	pRgn;
++#ifndef NXAGENT_SERVER
+     ScreenPtr   pScreen = pWin->drawable.pScreen;
+-
++#endif /* NXAGENT_SERVER */
+     pRgn = REGION_CREATE(pScreen, pBox, 1);
+     if (wBoundingShape (pWin)) {
+ 	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+@@ -2286,6 +2520,28 @@
+ 	/* Figure out if the window should be moved.  Doesnt
+ 	   make the changes to the window if event sent */
+ 
++    #ifdef TEST
++    if (nxagentWindowTopLevel(pWin))
++    {
++
++      fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
++                  pWin, mask, client);
++
++      fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
++                  "smode [%d] pSib [%p]\n",
++                      x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
++    }
++    #endif
++
++    if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
++            pWin -> overrideRedirect == 0 &&
++                nxagentScreenTrap == 0)
++    {
++      nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
++
++      return Success;
++    }
++
+     if (mask & CWStackMode)
+ 	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+ 				    pParent->drawable.y + y,
+@@ -2443,6 +2699,9 @@
+ 
+     if (action != RESTACK_WIN)
+ 	CheckCursorConfinement(pWin);
++
++    nxagentFlushConfigureWindow();
++
+     return(Success);
+ #undef RESTACK_WIN
+ #undef MOVE_WIN
+@@ -2468,6 +2727,20 @@
+     xEvent event;
+     BoxRec box;
+ 
++    #ifdef TEST
++    fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
++                pParent, direction, client);
++    #endif
++
++    /*
++     * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
++     *         nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
++     * {
++     *   nxagentCirculateRootlessWindows(direction);
++     *   return Success;
++     * }
++     */
++
+     pHead = RealChildHead(pParent);
+     pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+     if (direction == RaiseLowest)
+@@ -2582,6 +2855,12 @@
+     /* insert at begining of pParent */
+     pWin->parent = pParent;
+     pPrev = RealChildHead(pParent);
++
++    if (pWin->parent == WindowTable[0])
++    {
++      nxagentSetTopLevelEventMask(pWin);
++    }
++ 
+     if (pPrev)
+     {
+ 	pWin->nextSib = pPrev->nextSib;
+@@ -2614,7 +2893,9 @@
+ 
+     if (pScreen->ReparentWindow)
+ 	(*pScreen->ReparentWindow)(pWin, pPriorParent);
++
+     (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
++
+     ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+ 
+     CheckWindowOptionalNeed(pWin);
+@@ -2677,6 +2958,13 @@
+ #endif
+     WindowPtr  pLayerWin;
+ 
++    #ifdef TEST
++    if (nxagentWindowTopLevel(pWin))
++    {
++      fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
++    }
++    #endif
++
+     if (pWin->mapped)
+ 	return(Success);
+ 
+@@ -2782,6 +3070,8 @@
+ 	REGION_UNINIT(pScreen, &temp);
+     }
+ 
++    nxagentFlushConfigureWindow();
++
+     return(Success);
+ }
+ 
+@@ -2981,6 +3271,14 @@
+     ScreenPtr pScreen = pWin->drawable.pScreen;
+     WindowPtr pLayerWin = pWin;
+ 
++    #ifdef TEST
++    if (nxagentWindowTopLevel(pWin))
++    {
++      fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
++                  fromConfigure);
++    }
++    #endif
++
+     if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+ 	return(Success);
+     if (SubStrSend(pWin, pParent))
+@@ -3324,9 +3622,19 @@
+ 	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+ 	if (savedScreenInfo[i].ExternalScreenSaver)
+ 	{
+-	    if ((*savedScreenInfo[i].ExternalScreenSaver)
+-		(screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+-		continue;
++          if (nxagentOption(Timeout) != 0)
++          {
++            #ifdef TEST
++            fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
++                        "Ignoring it to let the auto-disconnect feature work.\n");
++            #endif
++          }
++          else
++          {
++	      if ((*savedScreenInfo[i].ExternalScreenSaver)
++		  (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
++		  continue;
++          }
+ 	}
+ 	if (type == screenIsSaved)
+ 	    continue;
+@@ -3669,6 +3977,11 @@
+     }
+     else
+ 	pWin->cursorIsNone = TRUE;
++/* FIXME
++   There is an error when disposing ClientResources on Agent exit
++   this xfree is not valid in some window at exit
++*/
++
+     xfree (pWin->optional);
+     pWin->optional = NULL;
+ }
+@@ -3851,3 +4164,4 @@
+ }
+ 
+ #endif
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NXxvdisp.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NXxvdisp.c.NX.patch
new file mode 100644
index 0000000..d8c2066
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NXxvdisp.c.NX.patch
@@ -0,0 +1,266 @@
+--- ./nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original	2015-02-13 14:03:44.748441432 +0100
++++ ./nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c	2015-02-13 14:03:44.748441432 +0100
+@@ -1,3 +1,20 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NXAGENT, NX protocol compression and NX extensions to this software    */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+ /***********************************************************
+ Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+@@ -71,6 +88,11 @@
+ #include <X11/extensions/shmstr.h>
+ #endif
+ 
++#include "Trap.h"
++
++#undef  TEST
++#undef  DEBUG
++
+ #ifdef EXTMODULE
+ #include "xf86_ansic.h"
+ #endif
+@@ -227,129 +249,175 @@
+ int
+ ProcXvDispatch(ClientPtr client)
+ {
++  int result;
++
+   REQUEST(xReq);
+ 
+   UpdateCurrentTime();
+ 
++  /*
++   * Report upstream that we are
++   * dispatching a XVideo operation.
++   */
++
++  nxagentXvTrap = 1;
++
++  #ifdef TEST
++  fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
++              stuff->data, client -> index);
++  #endif
++
+   switch (stuff->data) 
+     {
+-    case xv_QueryExtension: return(ProcXvQueryExtension(client));
+-    case xv_QueryAdaptors: return(ProcXvQueryAdaptors(client));
+-    case xv_QueryEncodings: return(ProcXvQueryEncodings(client));
++    case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
++    case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
++    case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+     case xv_PutVideo:
+ #ifdef PANORAMIX
+         if(!noPanoramiXExtension)
+-            return(XineramaXvPutVideo(client));
++            result = (XineramaXvPutVideo(client)); break;
+         else
+ #endif
+-            return(ProcXvPutVideo(client));
++            result = (ProcXvPutVideo(client)); break;
+     case xv_PutStill:
+ #ifdef PANORAMIX
+         if(!noPanoramiXExtension)
+-            return(XineramaXvPutStill(client));
++            result = (XineramaXvPutStill(client)); break
+         else
+ #endif
+-    	    return(ProcXvPutStill(client));
+-    case xv_GetVideo: return(ProcXvGetVideo(client));
+-    case xv_GetStill: return(ProcXvGetStill(client));
+-    case xv_GrabPort: return(ProcXvGrabPort(client));
+-    case xv_UngrabPort: return(ProcXvUngrabPort(client));
+-    case xv_SelectVideoNotify: return(ProcXvSelectVideoNotify(client));
+-    case xv_SelectPortNotify: return(ProcXvSelectPortNotify(client));
++    	    result = (ProcXvPutStill(client)); break;
++    case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
++    case xv_GetStill: result = (ProcXvGetStill(client)); break;
++    case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
++    case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
++    case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
++    case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+     case xv_StopVideo: 
+ #ifdef PANORAMIX
+         if(!noPanoramiXExtension)
+-	    return(XineramaXvStopVideo(client));
++	    result = (XineramaXvStopVideo(client)); break;
+ 	else
+ #endif
+-	    return(ProcXvStopVideo(client));
++	    result = (ProcXvStopVideo(client)); break;
+     case xv_SetPortAttribute: 
+ #ifdef PANORAMIX
+         if(!noPanoramiXExtension)
+-	    return(XineramaXvSetPortAttribute(client));
++	    result = (XineramaXvSetPortAttribute(client)); break;
+ 	else
+ #endif
+-	    return(ProcXvSetPortAttribute(client));
+-    case xv_GetPortAttribute: return(ProcXvGetPortAttribute(client));
+-    case xv_QueryBestSize: return(ProcXvQueryBestSize(client));
+-    case xv_QueryPortAttributes: return(ProcXvQueryPortAttributes(client));
++	    result = (ProcXvSetPortAttribute(client)); break;
++    case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
++    case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
++    case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+     case xv_PutImage:
+ #ifdef PANORAMIX
+         if(!noPanoramiXExtension)
+-	    return(XineramaXvPutImage(client));
++	    result = (XineramaXvPutImage(client)); break;
+ 	else
+ #endif
+-	    return(ProcXvPutImage(client));
++	    result = (ProcXvPutImage(client)); break;
+ #ifdef MITSHM
+     case xv_ShmPutImage: 
+ #ifdef PANORAMIX
+         if(!noPanoramiXExtension)
+-	    return(XineramaXvShmPutImage(client));
++	    result = (XineramaXvShmPutImage(client)); break;
+ 	else
+ #endif
+-	    return(ProcXvShmPutImage(client));
++	    result = (ProcXvShmPutImage(client)); break;
+ #endif
+-    case xv_QueryImageAttributes: return(ProcXvQueryImageAttributes(client));
+-    case xv_ListImageFormats: return(ProcXvListImageFormats(client));
++    case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
++    case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+     default:
+       if (stuff->data < xvNumRequests)
+ 	{
+ 	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+ 			    BadImplementation);
+-	  return(BadImplementation);
++	  result = (BadImplementation); break;
+ 	}
+       else
+ 	{
+ 	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+-	  return(BadRequest);
++	  result = (BadRequest);  break;
+ 	}
+     }
++
++  nxagentXvTrap = 0;
++
++  #ifdef TEST
++  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
++              stuff->data, client -> index);
++  #endif
++
++  return result;
+ }
+ 
+ int
+ SProcXvDispatch(ClientPtr client)
+ {
++  int result;
++
+   REQUEST(xReq);
+ 
+   UpdateCurrentTime();
+ 
++  /*
++   * Report upstream that we are
++   * dispatching a XVideo operation.
++   */
++
++  nxagentXvTrap = 1;
++
++  #ifdef TEST
++  fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
++              stuff->data, client -> index);
++  #endif
++
+   switch (stuff->data) 
+     {
+-    case xv_QueryExtension: return(SProcXvQueryExtension(client));
+-    case xv_QueryAdaptors: return(SProcXvQueryAdaptors(client));
+-    case xv_QueryEncodings: return(SProcXvQueryEncodings(client));
+-    case xv_PutVideo: return(SProcXvPutVideo(client));
+-    case xv_PutStill: return(SProcXvPutStill(client));
+-    case xv_GetVideo: return(SProcXvGetVideo(client));
+-    case xv_GetStill: return(SProcXvGetStill(client));
+-    case xv_GrabPort: return(SProcXvGrabPort(client));
+-    case xv_UngrabPort: return(SProcXvUngrabPort(client));
+-    case xv_SelectVideoNotify: return(SProcXvSelectVideoNotify(client));
+-    case xv_SelectPortNotify: return(SProcXvSelectPortNotify(client));
+-    case xv_StopVideo: return(SProcXvStopVideo(client));
+-    case xv_SetPortAttribute: return(SProcXvSetPortAttribute(client));
+-    case xv_GetPortAttribute: return(SProcXvGetPortAttribute(client));
+-    case xv_QueryBestSize: return(SProcXvQueryBestSize(client));
+-    case xv_QueryPortAttributes: return(SProcXvQueryPortAttributes(client));
+-    case xv_PutImage: return(SProcXvPutImage(client));
++    case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
++    case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
++    case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
++    case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
++    case xv_PutStill: result = (SProcXvPutStill(client)); break;
++    case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
++    case xv_GetStill: result = (SProcXvGetStill(client)); break;
++    case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
++    case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
++    case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
++    case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
++    case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
++    case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
++    case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
++    case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
++    case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
++    case xv_PutImage: result = (SProcXvPutImage(client)); break;
+ #ifdef MITSHM
+-    case xv_ShmPutImage: return(SProcXvShmPutImage(client));
++    case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+ #endif
+-    case xv_QueryImageAttributes: return(SProcXvQueryImageAttributes(client));
+-    case xv_ListImageFormats: return(SProcXvListImageFormats(client));
++    case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
++    case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+     default:
+       if (stuff->data < xvNumRequests)
+ 	{
+ 	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+ 			    BadImplementation);
+-	  return(BadImplementation);
++	  result = (BadImplementation); break;
+ 	}
+       else
+ 	{
+ 	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+-	  return(BadRequest);
++	  result = (BadRequest); break;
+ 	}
+     }
++
++  nxagentXvTrap = 0;
++
++  #ifdef TEST
++  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
++              stuff->data, client -> index);
++  #endif
++
++  return result;
+ }
+ 
+ static int
+@@ -2215,3 +2283,4 @@
+ }
+ 
+ #endif
++
diff --git a/doc/nx-X11_vs_XOrg69_patches/NextEvent.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/NextEvent.c.NX.patch
new file mode 100644
index 0000000..6ddefa1
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/NextEvent.c.NX.patch
@@ -0,0 +1,42 @@
+--- ./nx-X11/lib/Xt/NextEvent.c.X.original	2015-02-13 14:03:44.656443242 +0100
++++ ./nx-X11/lib/Xt/NextEvent.c	2015-02-13 14:03:44.656443242 +0100
+@@ -58,6 +58,24 @@
+ in this Software without prior written authorization from The Open Group.
+ 
+ */
++
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/lib/Xt/NextEvent.c,v 3.26 2002/06/04 21:55:42 dawes Exp $ */
+ 
+ #ifdef HAVE_CONFIG_H
+@@ -345,6 +363,14 @@
+     wait_fds_ptr_t wf)
+ {
+ #ifndef USE_POLL
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++
++    fprintf(stderr, "Xt::IoWait: Select called with [%d][%p][%p][%p][%p].\n",
++                wf->nfds, (void *) &wf->rmask, (void *) &wf->wmask, (void *) &wf->emask,
++                    (void *) wt->wait_time_ptr);
++#endif
++
+     return Select (wf->nfds, &wf->rmask, &wf->wmask, &wf->emask,
+ 		   wt->wait_time_ptr);
+ #else
diff --git a/doc/nx-X11_vs_XOrg69_patches/OpenDis.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/OpenDis.c.NX.patch
new file mode 100644
index 0000000..897fe25
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/OpenDis.c.NX.patch
@@ -0,0 +1,96 @@
+--- ./nx-X11/lib/X11/OpenDis.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/OpenDis.c	2015-02-10 19:13:12.748725444 +0100
+@@ -24,6 +24,24 @@
+ in this Software without prior written authorization from The Open Group.
+ 
+ */
++
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/lib/X11/OpenDis.c,v 3.16 2003/07/04 16:24:23 eich Exp $ */
+ 
+ #define NEED_REPLIES
+@@ -43,6 +61,10 @@
+ #include "XKBlib.h"
+ #endif /* XKB */
+ 
++#ifdef NX_TRANS_SOCKET
++extern void *_X11TransSocketProxyConnInfo(XtransConnInfo);
++#endif
++
+ #ifdef X_NOT_POSIX
+ #define Size_t unsigned int
+ #else
+@@ -117,6 +139,9 @@
+ 	bzero((char *) &client, sizeof(client));
+ 	bzero((char *) &prefix, sizeof(prefix));
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        fprintf(stderr, "\nXOpenDisplay: Called with display [%s].\n", display);
++#endif
+ 	/*
+ 	 * If the display specifier string supplied as an argument to this 
+ 	 * routine is NULL or a pointer to NULL, read the DISPLAY variable.
+@@ -162,6 +187,9 @@
+ 
+ 	dpy->fd = _X11TransGetConnectionNumber (dpy->trans_conn);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) 
++        fprintf(stderr, "\nXOpenDisplay: Connected display with dpy->fd = [%d].\n", dpy->fd);
++#endif
+ 	/* Initialize as much of the display structure as we can.
+ 	 * Initialize pointers to NULL so that XFreeDisplayStructure will
+ 	 * work if we run out of memory before we finish initializing.
+@@ -258,6 +286,10 @@
+         conn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);
+     if (conn_buf_size < XLIBMINBUFSIZE)
+         conn_buf_size = XLIBMINBUFSIZE;
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) 
++    fprintf (stderr, "Xlib: Running with XLIBBUFFERSIZE [%d] XLIBMINBUFSIZE [%d] "
++                 "buffer size [%ld].\n", XLIBDEFAULTBUFSIZE, XLIBMINBUFSIZE, conn_buf_size);
++#endif
+ 
+     if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) {
+          OutOfMemory (dpy, setup);
+@@ -324,9 +356,16 @@
+ 
+ 	if (prefix.majorVersion != X_PROTOCOL) {
+ 	    /* XXX - printing messages marks a bad programming interface */
++#ifdef NX_TRANS_SOCKET
++            if (_X11TransSocketProxyConnInfo(dpy->trans_conn) == NULL) {
++                fprintf (stderr, "Xlib: client uses different protocol version (%d) "
++                             "than server (%d)!\r\n", X_PROTOCOL, prefix.majorVersion);
++            }
++#else
+ 	    fprintf (stderr,
+      "Xlib: client uses different protocol version (%d) than server (%d)!\r\n",
+ 		     X_PROTOCOL, prefix.majorVersion);
++#endif
+ 	    _XDisconnectDisplay (dpy->trans_conn);
+ 	    Xfree ((char *)dpy);
+ 	    return(NULL);
+@@ -698,6 +737,9 @@
+ /*
+  * and return successfully
+  */
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST) 
++        fprintf(stderr, "XOpenDisplay: Returning display at [%p].\n", dpy);
++#endif
+  	return(dpy);
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/PeekIfEv.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/PeekIfEv.c.NX.patch
new file mode 100644
index 0000000..7d87f13
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/PeekIfEv.c.NX.patch
@@ -0,0 +1,14 @@
+--- ./nx-X11/lib/X11/PeekIfEv.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/PeekIfEv.c	2015-02-10 19:13:12.952717788 +0100
+@@ -71,6 +71,11 @@
+ 	    if (prev && prev->qserial_num != qe_serial)
+ 		/* another thread has snatched this event */
+ 		prev = NULL;
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                return 0;
++            }
++#endif
+ 	}
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/Pending.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Pending.c.NX.patch
new file mode 100644
index 0000000..027ad79
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Pending.c.NX.patch
@@ -0,0 +1,30 @@
+--- ./nx-X11/lib/X11/Pending.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/Pending.c	2015-02-10 19:13:12.880720490 +0100
+@@ -25,6 +25,8 @@
+ 
+ */
+ 
++#include <stdio.h>
++
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+@@ -37,11 +39,18 @@
+     int mode;
+ {
+     int ret_val;
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "\nXEventsQueued: Called with a display at [%p].\n", dpy);
++#endif
++
+     LockDisplay(dpy);
+     if (dpy->qlen || (mode == QueuedAlready))
+ 	ret_val = dpy->qlen;
+     else
+ 	ret_val = _XEventsQueued (dpy, mode);
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "\nXEventsQueued: Going to unlock the display at [%p].\n", dpy);
++#endif
+     UnlockDisplay(dpy);
+     return ret_val;
+ }
diff --git a/doc/nx-X11_vs_XOrg69_patches/WSDrawBuffer.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/WSDrawBuffer.h.NX.patch
new file mode 100644
index 0000000..e69de29
diff --git a/doc/nx-X11_vs_XOrg69_patches/WaitFor.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/WaitFor.c.NX.patch
new file mode 100644
index 0000000..3850a2b
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/WaitFor.c.NX.patch
@@ -0,0 +1,271 @@
+--- ./nx-X11/programs/Xserver/os/WaitFor.c.X.original	2015-02-13 14:03:44.788440645 +0100
++++ ./nx-X11/programs/Xserver/os/WaitFor.c	2015-02-10 19:13:13.464698616 +0100
+@@ -48,6 +48,23 @@
+ 
+ /* $Xorg: WaitFor.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*****************************************************************
+  * OS Dependent input routines:
+  *
+@@ -80,6 +97,12 @@
+ #include "dpmsproc.h"
+ #endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP)
++
++static unsigned long startTimeInMillis;
++
++#endif
++
+ #ifdef WIN32
+ /* Error codes from windows sockets differ from fileio error codes  */
+ #undef EINTR
+@@ -169,8 +192,18 @@
+     Bool    someReady = FALSE;
+ #endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "WaitForSomething: Got called.\n");
++#endif
++
+     FD_ZERO(&clientsReadable);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP)
++
++    startTimeInMillis = GetTimeInMillis();
++
++#endif
++
+     /* We need a while loop here to handle 
+        crashed connections and the screen saver timeout */
+     while (1)
+@@ -231,18 +264,127 @@
+ 	    XTestComputeWaitTime (&waittime);
+ 	}
+ #endif /* XTESTEXT1 */
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP)
++
++        /*
++         * If caller has marked the first element of pClientsReady[],
++         * bail out of select after a short timeout. We need this to
++         * let the NX agent remove the splash screen when the timeout
++         * is expired. A better option would be to use the existing
++         * screen-saver timeout but it can be modified by clients, so
++         * we would need a special handling. This hack is trivial and
++         * keeps WaitForSomething() backward compatible with the exis-
++         * ting servers.
++         */
++
++        if (pClientsReady[0] == -1)
++        {
++            unsigned long timeoutInMillis;
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "WaitForSomething: pClientsReady[0] is [%d], pClientsReady[1] is [%d].\n",
++                        pClientsReady[0], pClientsReady[1]);
++#endif
++
++            timeoutInMillis = GetTimeInMillis();
++
++            if (timeoutInMillis - startTimeInMillis >= NX_TRANS_WAKEUP)
++            {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
++                fprintf(stderr, "WaitForSomething: Returning 0 because of wakeup timeout.\n");
++#endif
++                return 0;
++            }
++
++            timeoutInMillis = NX_TRANS_WAKEUP - (timeoutInMillis - startTimeInMillis);
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "WaitForSomething: Milliseconds to next wakeup are %ld.\n",
++                        timeoutInMillis);
++#endif
++            if (wt == NULL || (wt -> tv_sec * MILLI_PER_SECOND +
++                    wt -> tv_usec / MILLI_PER_SECOND) > timeoutInMillis)
++            {
++                if ((waittime.tv_sec * MILLI_PER_SECOND +
++                        waittime.tv_usec / MILLI_PER_SECOND) > timeoutInMillis)
++                {
++                    waittime.tv_sec = timeoutInMillis / MILLI_PER_SECOND;
++                    waittime.tv_usec = (timeoutInMillis * MILLI_PER_SECOND) %
++                                            (MILLI_PER_SECOND * 1000);
++                    wt = &waittime;
++                }
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
++                fprintf(stderr, "WaitForSomething: Next wakeup timeout set to %ld milliseconds.\n",
++                            (waittime.tv_sec * MILLI_PER_SECOND) +
++                                (waittime.tv_usec / MILLI_PER_SECOND));
++#endif
++            }
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_WAKEUP) && defined(NX_TRANS_DEBUG)
++            else
++            {
++                fprintf(stderr, "WaitForSomething: Using existing timeout of %ld milliseconds.\n",
++                            (waittime.tv_sec * MILLI_PER_SECOND) +
++                                (waittime.tv_usec / MILLI_PER_SECOND));
++            }
++#endif
++        }
++#endif
++
+ 	/* keep this check close to select() call to minimize race */
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
+ 	if (dispatchException)
++	{
+ 	    i = -1;
++
++            fprintf(stderr, "WaitForSomething: Value of dispatchException is true. Set i = -1.\n");
++	}
++#else
++        if (dispatchException)
++            i = -1;
++#endif
+ 	else if (AnyClientsWriteBlocked)
+ 	{
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            if (wt == NULL)
++            {
++                fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask and "
++                            "clientsWritable and null timeout.\n");
++            }
++            else
++            {
++                fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask, "
++                            "clientsWritable, %ld secs and %ld usecs.\n",
++                                wt -> tv_sec, wt -> tv_usec);
++            }
++#endif
+ 	    XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable);
+ 	    i = Select (MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
+ 	}
+ 	else 
+ 	{
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            if (wt == NULL)
++            {
++                fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask and null timeout.\n");
++            }
++            else
++            {
++                fprintf(stderr, "WaitForSomething: Executing select with LastSelectMask, %ld secs and %ld usecs.\n",
++                            wt -> tv_sec, wt -> tv_usec);
++            }
++#endif
+ 	    i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
+ 	}
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "WaitForSomething: Bailed out with i = [%d] and errno = [%d].\n", i, errno);
++
++        if (i < 0)
++        {
++            fprintf(stderr, "WaitForSomething: Error is [%s].\n", strerror(errno));
++        }
++#endif
+ 	selecterr = GetErrno();
+ 	WakeupHandler(i, (pointer)&LastSelectMask);
+ #ifdef XTESTEXT1
+@@ -261,15 +403,31 @@
+ #endif
+ 	if (i <= 0) /* An error or timeout occurred */
+ 	{
+-	    if (dispatchException)
+-		return 0;
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            if (dispatchException)
++            {
++                fprintf(stderr, "WaitForSomething: Returning 0 because of (dispatchException).\n");
++                return 0;
++            }
++#else
++            if (dispatchException)
++                return 0;
++#endif
+ 	    if (i < 0) 
+ 	    {
+ 		if (selecterr == EBADF)    /* Some client disconnected */
+ 		{
+ 		    CheckConnections ();
+-		    if (! XFD_ANYSET (&AllClients))
+-			return 0;
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++                    if (! XFD_ANYSET (&AllClients))
++                    {
++                        fprintf(stderr, "WaitForSomething: Returning 0 because of (! XFD_ANYSET (&AllClients)).\n");
++                        return 0;
++                    }
++#else
++                    if (! XFD_ANYSET (&AllClients))
++                        return 0;
++#endif
+ 		}
+ 		else if (selecterr == EINVAL)
+ 		{
+@@ -293,8 +451,18 @@
+ 		break;
+ 	    }
+ #endif
++#if defined(NX_TRANS_SOCKET)
++            if (*checkForInput[0] != *checkForInput[1])
++            {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++                fprintf(stderr, "WaitForSomething: Returning 0 because of (*checkForInput[0] != *checkForInput[1]).\n");
++#endif
++		return 0;
++            }
++#else
+ 	    if (*checkForInput[0] != *checkForInput[1])
+ 		return 0;
++#endif
+ 
+ 	    if (timers)
+ 	    {
+@@ -358,9 +526,19 @@
+ 	    /* Windows keyboard and mouse events are added to the input queue
+ 	       in Block- and WakupHandlers. There is no device to check if  
+ 	       data is ready. So check here if new input is available */
++#if defined(NX_TRANS_SOCKET)
++            if (*checkForInput[0] != *checkForInput[1])
++            {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++                fprintf(stderr, "WaitForSomething: Returning 0 because of (*checkForInput[0] != *checkForInput[1]).\n");
++#endif
++		return 0;
++            }
++#else
+ 	    if (*checkForInput[0] != *checkForInput[1])
+ 		return 0;
+ #endif
++#endif
+ 	}
+     }
+ 
+@@ -429,6 +607,9 @@
+ #endif
+ 	}
+     }
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "WaitForSomething: Returning nready.\n");
++#endif
+     return nready;
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/XKBMAlloc.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/XKBMAlloc.c.NX.patch
new file mode 100644
index 0000000..de5574c
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/XKBMAlloc.c.NX.patch
@@ -0,0 +1,84 @@
+--- ./nx-X11/lib/X11/XKBMAlloc.c.X.original	2015-02-13 14:03:44.620443950 +0100
++++ ./nx-X11/lib/X11/XKBMAlloc.c	2015-02-10 19:13:12.836722141 +0100
+@@ -738,8 +738,13 @@
+ 		    _XkbFree(prev_key_sym_map);
+ 		    return BadAlloc;
+ 		}
++#ifdef NXAGENT_SERVER
++                bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code+1],
++                                        tmp*sizeof(XkbSymMapRec));
++#else
+ 		bzero((char *)&xkb->map->key_sym_map[xkb->max_key_code],
+ 					tmp*sizeof(XkbSymMapRec));
++#endif
+ 		if (changes) {
+ 		    changes->map.changed= _ExtendRange(changes->map.changed,
+ 		    				XkbKeySymsMask,maxKC,
+@@ -756,7 +761,11 @@
+ 		    _XkbFree(prev_modmap);
+ 		    return BadAlloc;
+ 		}
++#ifdef NXAGENT_SERVER
++                bzero((char *)&xkb->map->modmap[xkb->max_key_code+1],tmp);
++#else
+ 		bzero((char *)&xkb->map->modmap[xkb->max_key_code],tmp);
++#endif
+ 		if (changes) {
+ 		    changes->map.changed= _ExtendRange(changes->map.changed,
+ 		    				XkbModifierMapMask,maxKC,
+@@ -775,8 +784,13 @@
+ 		    _XkbFree(prev_behaviors);
+ 		    return BadAlloc;
+ 		}
++#ifdef NXAGENT_SERVER
++                bzero((char *)&xkb->server->behaviors[xkb->max_key_code+1],
++                                                tmp*sizeof(XkbBehavior));
++#else
+ 		bzero((char *)&xkb->server->behaviors[xkb->max_key_code],
+ 						tmp*sizeof(XkbBehavior));
++#endif
+ 		if (changes) {
+ 		    changes->map.changed= _ExtendRange(changes->map.changed,
+ 		    			XkbKeyBehaviorsMask,maxKC,
+@@ -793,8 +807,13 @@
+ 		    _XkbFree(prev_key_acts);
+ 		    return BadAlloc;
+ 		}
++#ifdef NXAGENT_SERVER
++                bzero((char *)&xkb->server->key_acts[xkb->max_key_code+1],
++                                                tmp*sizeof(unsigned short));
++#else
+ 		bzero((char *)&xkb->server->key_acts[xkb->max_key_code],
+ 						tmp*sizeof(unsigned short));
++#endif
+ 		if (changes) {
+ 		    changes->map.changed= _ExtendRange(changes->map.changed,
+ 		    			XkbKeyActionsMask,maxKC,
+@@ -811,8 +830,13 @@
+ 		    _XkbFree(prev_vmodmap);
+ 		    return BadAlloc;
+ 		}
++#ifdef NXAGENT_SERVER
++                bzero((char *)&xkb->server->vmodmap[xkb->max_key_code+1],
++                                                tmp*sizeof(unsigned short));
++#else
+ 		bzero((char *)&xkb->server->vmodmap[xkb->max_key_code],
+ 						tmp*sizeof(unsigned short));
++#endif
+ 		if (changes) {
+ 		    changes->map.changed= _ExtendRange(changes->map.changed,
+ 		    			XkbVirtualModMapMask,maxKC,
+@@ -830,8 +854,13 @@
+ 		_XkbFree(prev_keys);
+ 		return BadAlloc;
+ 	    }
++#ifdef NXAGENT_SERVER
++            bzero((char *)&xkb->names->keys[xkb->max_key_code+1],
++                                                tmp*sizeof(XkbKeyNameRec));
++#else
+ 	    bzero((char *)&xkb->names->keys[xkb->max_key_code],
+ 	    					tmp*sizeof(XkbKeyNameRec));
++#endif
+ 	    if (changes) {
+ 		changes->names.changed= _ExtendRange(changes->names.changed,
+ 					XkbKeyNamesMask,maxKC,
diff --git a/doc/nx-X11_vs_XOrg69_patches/XKBsrv.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/XKBsrv.h.NX.patch
new file mode 100644
index 0000000..f85303b
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/XKBsrv.h.NX.patch
@@ -0,0 +1,14 @@
+--- ./nx-X11/include/extensions/XKBsrv.h.X.original	2015-02-13 14:03:44.612444107 +0100
++++ ./nx-X11/include/extensions/XKBsrv.h	2015-02-10 19:13:14.644654498 +0100
+@@ -73,6 +73,11 @@
+ #include <X11/extensions/XKBproto.h>
+ #include "inputstr.h"
+ 
++#ifdef NXAGENT_SERVER
++extern char *_NXGetXkbBasePath(const char *path);
++extern char *_NXGetXkbCompPath(const char *path);
++#endif
++
+ typedef struct _XkbInterest {
+ 	DeviceIntPtr		dev;
+ 	ClientPtr		client;
diff --git a/doc/nx-X11_vs_XOrg69_patches/Xlib.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Xlib.h.NX.patch
new file mode 100644
index 0000000..794ccf0
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Xlib.h.NX.patch
@@ -0,0 +1,30 @@
+--- ./nx-X11/lib/X11/Xlib.h.X.original	2015-02-13 14:03:44.624443872 +0100
++++ ./nx-X11/lib/X11/Xlib.h	2015-02-10 19:13:12.720726495 +0100
+@@ -2102,6 +2102,27 @@
+     XPointer		/* arg */
+ );
+ 
++#ifdef NX_TRANS_SOCKET
++
++/*
++ * This is just like XCheckIfEvent() but doesn't
++ * flush the output buffer if it can't read new
++ * events.
++ */
++
++extern Bool XCheckIfEventNoFlush(
++    Display*		/* display */,
++    XEvent*		/* event_return */,
++    Bool (*) (
++	       Display*			/* display */,
++               XEvent*			/* event */,
++               XPointer			/* arg */
++             )		/* predicate */,
++    XPointer		/* arg */
++);
++
++#endif
++
+ extern Bool XCheckMaskEvent(
+     Display*		/* display */,
+     long		/* event_mask */,
diff --git a/doc/nx-X11_vs_XOrg69_patches/XlibAsync.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/XlibAsync.c.NX.patch
new file mode 100644
index 0000000..82494f7
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/XlibAsync.c.NX.patch
@@ -0,0 +1,41 @@
+--- ./nx-X11/lib/X11/XlibAsync.c.X.original	2015-02-13 14:03:44.624443872 +0100
++++ ./nx-X11/lib/X11/XlibAsync.c	2015-02-10 19:13:13.064713591 +0100
+@@ -27,6 +27,23 @@
+ 
+ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #define NEED_REPLIES
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+@@ -122,6 +139,14 @@
+      */
+     if ((rep->generic.length << 2) > len)
+ 	_XEatData (dpy, (rep->generic.length << 2) - len);
++#ifdef NX_TRANS_SOCKET
++
++    /*
++     * The original code has provision
++     * for returning already.
++     */
++
++#endif
+     _XIOError (dpy);
+     return (char *)rep;
+ }
diff --git a/doc/nx-X11_vs_XOrg69_patches/XlibInt.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/XlibInt.c.NX.patch
new file mode 100644
index 0000000..b76e169
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/XlibInt.c.NX.patch
@@ -0,0 +1,1165 @@
+--- ./nx-X11/lib/X11/XlibInt.c.X.original	2015-02-13 14:03:44.624443872 +0100
++++ ./nx-X11/lib/X11/XlibInt.c	2015-02-10 19:13:12.800723493 +0100
+@@ -26,6 +26,24 @@
+ from The Open Group.
+ 
+ */
++
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/lib/X11/XlibInt.c,v 3.38 2003/10/30 21:55:05 alanh Exp $ */
+ 
+ /*
+@@ -100,6 +118,34 @@
+ 
+ #endif /* XTHREADS else */ 
+ 
++#include "NX.h"
++
++#ifdef NX_TRANS_SOCKET
++
++#include "NX.h"
++#include "NXvars.h"
++
++static struct timeval retry;
++
++/*
++ * From Xtranssock.c. Presently the congestion state
++ * is reported by the proxy to the application, by
++ * invoking the callback directly. The function will
++ * be possibly used in the future, to be able to track
++ * the bandwidth usage even when the NX transport is
++ * not running. Note that in this sample implementation
++ * the congestion state is checked very often and can
++ * be surely optimized.
++ */
++
++#ifdef NX_TRANS_CHANGE
++
++extern int _X11TransSocketCongestionChange(XtransConnInfo, int *);
++
++#endif
++
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ /* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+  * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+  */
+@@ -219,6 +265,100 @@
+ 	0, 0, 0
+ };
+ 
++#ifdef NX_TRANS_SOCKET
++
++/*
++ * Replace the standard Select with a version giving NX a
++ * chance to check its own descriptors. This doesn't cover
++ * the cases where the system is using poll or when system-
++ * specific defines override the Select definition (OS/2).
++ */
++
++int _XSelect(int maxfds, fd_set *readfds, fd_set *writefds,
++                 fd_set *exceptfds, struct timeval *timeout)
++{
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_XSelect: Called with [%d][%p][%p][%p][%p].\n",
++                maxfds, (void *) readfds, (void *) writefds, (void *) exceptfds,
++                    (void *) timeout);
++#endif
++
++    if (NXTransRunning(NX_FD_ANY))
++    {
++        fd_set t_readfds, t_writefds;
++        struct timeval t_timeout;
++
++        int n, r, e;
++
++#ifdef NX_TRANS_TEST
++
++        if (exceptfds != NULL)
++        {
++            fprintf(stderr, "_XSelect: WARNING! Can't handle exception fds in select.\n");
++        }
++
++#endif
++
++        if (readfds == NULL)
++        {
++            FD_ZERO(&t_readfds);
++
++            readfds = &t_readfds;
++        }
++
++        if (writefds == NULL)
++        {
++            FD_ZERO(&t_writefds);
++
++            writefds = &t_writefds;
++        }
++
++        if (timeout == NULL)
++        {
++            t_timeout.tv_sec  = 10;
++            t_timeout.tv_usec = 0;
++
++            timeout = &t_timeout;
++        }
++
++        n = maxfds;
++
++        /*
++         * If the transport is gone avoid
++         * sleeping until the timeout.
++         */
++
++        if (NXTransPrepare(&n, readfds, writefds, timeout) != 0)
++        {
++          NXTransSelect(&r, &e, &n, readfds, writefds, timeout);
++
++          NXTransExecute(&r, &e, &n, readfds, writefds, timeout);
++
++          errno = e;
++
++          return r;
++        }
++        else
++        {
++          return 0;
++        }
++    }
++    else
++    {
++        return select(maxfds, readfds, writefds, exceptfds, timeout);
++    }
++}
++
++#else /* #ifdef NX_TRANS_SOCKET */
++
++int _XSelect(int maxfds, fd_set *readfds, fd_set *writefds,
++                 fd_set *exceptfds, struct timeval *timeout)
++{
++    return select(maxfds, readfds, writefds, exceptfds, timeout);
++}
++
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ /*
+  * This is an OS dependent routine which:
+  * 1) returns as soon as the connection can be written on....
+@@ -242,6 +382,18 @@
+ #endif
+     int nfound;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++    int congestion;
++#endif
++
++#ifdef NX_TRANS_SOCKET
++
++    if (_XGetIOError(dpy)) {
++        return;
++    }
++
++#endif
++
+ #ifdef USE_POLL
+     filedes.fd = dpy->fd;
+     filedes.events = 0;
+@@ -276,6 +428,8 @@
+ 	     (!dpy->lock->reply_awaiters ||
+ 	      dpy->lock->reply_awaiters->cv == cv)))
+ #endif
++
++#ifndef NX_TRANS_SOCKET
+ #ifdef USE_POLL
+ 	    filedes.events = POLLIN;
+ 	filedes.events |= POLLOUT;
+@@ -283,17 +437,109 @@
+ 	FD_SET(dpy->fd, &r_mask);
+         FD_SET(dpy->fd, &w_mask);
+ #endif
++#endif /* #ifndef NX_TRANS_SOCKET */
+ 
+ 	do {
++#ifdef NX_TRANS_SOCKET
++            /*
++             * Give a chance to the registered client to perform
++             * any needed operation before entering the select.
++             */
++
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "_XWaitForWritable: WAIT! Waiting for the display to become writable.\n");
++#endif
++            NXTransFlush(dpy->fd);
++
++            if (_NXDisplayBlockFunction != NULL) {
++                    (*_NXDisplayBlockFunction)(dpy, NXBlockWrite);
++            }
++
++            /*
++             * Need to set again the descriptors as we could have
++             * run multiple selects before having the possibility
++             * to read or write to the X connection.
++             */
++
++#ifdef USE_POLL
++            filedes.events = POLLIN;
++            filedes.events |= POLLOUT;
++#else
++            FD_SET(dpy->fd, &r_mask);
++            FD_SET(dpy->fd, &w_mask);
++#endif
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ 	    UnlockDisplay(dpy);
+ #ifdef USE_POLL
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "_XWaitForWritable: Calling poll().\n");
++#endif
+ 	    nfound = poll (&filedes, 1, -1);
+ #else
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "_XWaitForWritable: Calling select() after [%ld] ms.\n",
++                        NXTransTime());
++#endif
++#ifdef NX_TRANS_SOCKET
++            /*
++             * Give a chance to the callback to detect
++             * the failure of the display even if we
++             * miss the interrupt inside the select.
++             */
++
++            if (_NXDisplayErrorFunction != NULL) {
++                retry.tv_sec  = 5;
++                retry.tv_usec = 0;
++                nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, &retry);
++            } else {
++                nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
++            }
++#else
+ 	    nfound = Select (dpy->fd + 1, &r_mask, &w_mask, NULL, NULL);
+ #endif
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "_XWaitForWritable: Out of select() with [%d] after [%ld] ms.\n",
++                        nfound, NXTransTime());
++
++            if (FD_ISSET(dpy->fd, &r_mask))
++            {
++                BytesReadable_t pend;
++
++                _X11TransBytesReadable(dpy->trans_conn, &pend);
++
++                fprintf(stderr, "_XWaitForWritable: Descriptor [%d] is ready with [%ld] bytes to read.\n",
++                            dpy->fd, pend);
++            }
++
++            if (FD_ISSET(dpy->fd, &w_mask))
++            {
++              fprintf(stderr, "_XWaitForWritable: Descriptor [%d] has become writable.\n\n",
++                          dpy->fd);
++            }
++#endif
++#endif
+ 	    InternalLockDisplay(dpy, cv != NULL);
+-	    if (nfound < 0 && !ECHECK(EINTR))
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++            if (_NXDisplayCongestionFunction != NULL &&
++                    _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++                (*_NXDisplayCongestionFunction)(dpy, congestion);
++            }
++#endif
++
++#ifdef NX_TRANS_SOCKET
++            if (nfound <= 0) {
++                if ((nfound == -1 && !ECHECK(EINTR)) ||
++                        (_NXDisplayErrorFunction != NULL &&
++                            (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                    _XIOError(dpy);
++                    return;
++                }
++              }
++#else
++          if (nfound < 0 && !ECHECK(EINTR))
+ 		_XIOError(dpy);
++#endif
+ 	} while (nfound <= 0);
+ 
+ 	if (
+@@ -311,7 +557,15 @@
+ 
+ 	    /* find out how much data can be read */
+ 	    if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
++#ifdef NX_TRANS_SOCKET
++            {
++                _XIOError(dpy);
++
++                return;
++            }
++#else
+ 		_XIOError(dpy);
++#endif
+ 	    len = pend;
+ 
+ 	    /* must read at least one xEvent; if none is pending, then
+@@ -464,6 +718,15 @@
+     int highest_fd = fd;
+ #endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++    int congestion;
++#endif
++#ifdef NX_TRANS_SOCKET
++    if (_XGetIOError(dpy)) {
++        return -1;
++    }
++#endif
++
+ #ifdef USE_POLL
+     if (dpy->im_fd_length + 1 > POLLFD_CACHE_SIZE
+ 	&& !(dpy->flags & XlibDisplayProcConni)) {
+@@ -495,16 +758,68 @@
+ #endif
+ 	UnlockDisplay(dpy);
+ #ifdef USE_POLL
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "_XWaitForReadable: Calling poll().\n");
++#endif
+ 	result = poll(filedes,
+ 		      (dpy->flags & XlibDisplayProcConni) ? 1 : 1+dpy->im_fd_length,
+ 		      -1);
+ #else
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "_XWaitForReadable: Calling select().\n");
++#endif
++#ifdef NX_TRANS_SOCKET
++        /*
++         * Give a chance to the registered application
++         * to perform any needed operation.
++         */
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_XWaitForReadable: WAIT! Waiting for the display to become readable.\n");
++#endif
++        NXTransFlush(dpy->fd);
++
++        if (_NXDisplayBlockFunction != NULL) {
++            (*_NXDisplayBlockFunction)(dpy, NXBlockRead);
++        }
++
++        if (_NXDisplayErrorFunction != NULL) {
++            retry.tv_sec  = 5;
++            retry.tv_usec = 0;
++            result = Select(highest_fd + 1, &r_mask, NULL, NULL, &retry);
++        } else {
++            result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
++        }
++#else
+ 	result = Select(highest_fd + 1, &r_mask, NULL, NULL, NULL);
+ #endif
++#endif
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "_XWaitForReadable: Out of select with result [%d] and errno [%d].\n",
++                    result, (result < 0 ? errno : 0));
++#endif
+ 	InternalLockDisplay(dpy, dpy->flags & XlibDisplayReply);
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        if (_NXDisplayCongestionFunction != NULL &&
++                _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++            (*_NXDisplayCongestionFunction)(dpy, congestion);
++        }
++#endif
++#ifdef NX_TRANS_SOCKET
++        if (result <= 0) {
++            if ((result == -1 && !ECHECK(EINTR)) ||
++                    (_NXDisplayErrorFunction != NULL &&
++                        (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                _XIOError(dpy);
++                return -1;
++            }
++            continue;
++        }
++#else
+ 	if (result == -1 && !ECHECK(EINTR)) _XIOError(dpy);
+ 	if (result <= 0)
+ 	    continue;
++#endif
+ #ifdef USE_POLL
+ 	if (filedes[0].revents & (POLLIN|POLLHUP|POLLERR))
+ #else
+@@ -562,6 +877,19 @@
+     xGetInputFocusReply rep;
+     register xReq *req;
+ 
++#ifdef NX_TRANS_SOCKET
++#ifdef NX_TRANS_DEBUG
++    fprintf(stderr, "_XSeqSyncFunction: Going to synchronize the display.\n");
++#endif
++    if (dpy->flags & XlibDisplayIOError)
++    {
++#ifdef NX_TRANS_DEBUG
++        fprintf(stderr, "_XSeqSyncFunction: Returning 0 with I/O error detected.\n");
++#endif
++        return 0;
++    }
++#endif
++
+     LockDisplay(dpy);
+     if ((dpy->request - dpy->last_request_read) >= (BUFSIZE / SIZEOF(xReq))) {
+ 	GetEmptyReq(GetInputFocus, req);
+@@ -611,7 +939,14 @@
+ 	register int write_stat;
+ 	register char *bufindex;
+ 	_XExtension *ext;
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        int congestion;
++#endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "_XFlushInt: Entering flush with [%d] bytes to write.\n",
++                    (dpy->bufptr - dpy->buffer));
++#endif
+ 	/* This fix resets the bufptr to the front of the buffer so
+ 	 * additional appends to the bufptr will not corrupt memory. Since
+ 	 * the server is down, these appends are no-op's anyway but 
+@@ -619,13 +954,23 @@
+ 	 */
+ 	if (dpy->flags & XlibDisplayIOError)
+ 	{
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "_XFlushInt: Returning with I/O error detected.\n");
++#endif
+ 	    dpy->bufptr = dpy->buffer;
+ 	    dpy->last_req = (char *)&_dummy_request;
+ 	    return;
+ 	}
+ 
+ #ifdef XTHREADS
++#ifdef NX_TRANS_SOCKET
++        while (dpy->flags & XlibDisplayWriting) {
++            if (_XGetIOError(dpy)) {
++                return;
++            }
++#else
+ 	while (dpy->flags & XlibDisplayWriting) {
++#endif
+ 	    if (dpy->lock) {
+ 		ConditionWait(dpy, dpy->lock->writers);
+ 	    } else {
+@@ -653,6 +998,17 @@
+ 	    write_stat = _X11TransWrite(dpy->trans_conn,
+ 					bufindex, (int) todo);
+ 	    if (write_stat >= 0) {
++#ifdef NX_TRANS_SOCKET
++                if (_NXDisplayWriteFunction != NULL) {
++                    (*_NXDisplayWriteFunction)(dpy, write_stat);
++                }
++#ifdef NX_TRANS_CHANGE
++                if (_NXDisplayCongestionFunction != NULL &&
++                        _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++                    (*_NXDisplayCongestionFunction)(dpy, congestion);
++                }
++#endif
++#endif
+ 		size -= write_stat;
+ 		todo = size;
+ 		bufindex += write_stat;
+@@ -682,11 +1038,25 @@
+ 				      );
+ 		}
+ #endif
++#ifdef NX_TRANS_SOCKET
++            } else if (!ECHECK(EINTR) ||
++                (_NXDisplayErrorFunction != NULL &&
++                    (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                _XIOError(dpy);
++                return;
++            }
++#else
+ 	    } else if (!ECHECK(EINTR)) {
+ 		/* Write failed! */
+ 		/* errno set by write system call. */
+ 		_XIOError(dpy);
+ 	    }
++#endif
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                return;
++            }
++#endif
+ 	}
+ 	dpy->last_req = (char *)&_dummy_request;
+ 	if ((dpy->request - dpy->last_request_read) >= SEQLIMIT &&
+@@ -727,6 +1097,12 @@
+ 	    if (dpy->qlen)
+ 		return(dpy->qlen);
+ 	}
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        if (dpy->flags & XlibDisplayIOError) {
++            fprintf(stderr, "_XEventsQueued: Returning [%d] after display failure.\n",
++                        dpy->qlen);
++        }
++#endif
+ 	if (dpy->flags & XlibDisplayIOError) return(dpy->qlen);
+ 
+ #ifdef XTHREADS
+@@ -767,8 +1143,19 @@
+ 	}
+ #endif /* XTHREADS*/
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++        fprintf(stderr, "_XEventsQueued: Checking bytes readable.\n");
++#endif
+ 	if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
++#ifdef NX_TRANS_SOCKET
++        {
++            _XIOError(dpy);
++
++            return (dpy->qlen);
++        }
++#else
+ 	    _XIOError(dpy);
++#endif
+ #ifdef XCONN_CHECK_FREQ
+ 	/* This is a crock, required because FIONREAD or equivalent is
+ 	 * not guaranteed to detect a broken connection.
+@@ -785,10 +1172,16 @@
+ 
+ 	    dpy->conn_checker = 0;
+ #ifdef USE_POLL
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "_XEventsQueued: Calling poll().\n");
++#endif
+ 	    filedes.fd = dpy->fd;
+ 	    filedes.events = POLLIN;
+ 	    if ((result = poll(&filedes, 1, 0)))
+ #else
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "_XEventsQueued: Calling select().\n");
++#endif
+ 	    FD_ZERO(&r_mask);
+ 	    FD_SET(dpy->fd, &r_mask);
+ 	    if ((result = Select(dpy->fd + 1, &r_mask, NULL, NULL, &zero_time)))
+@@ -797,13 +1190,32 @@
+ 		if (result > 0)
+ 		{
+ 		    if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
++#ifdef NX_TRANS_SOCKET
++                    {
++                        _XIOError(dpy);
++
++                        return (dpy->qlen);
++                    }
++#else
+ 			_XIOError(dpy);
++#endif
+ 		    /* we should not get zero, if we do, force a read */
+ 		    if (!pend)
+ 			pend = SIZEOF(xReply);
+ 		}
++#ifdef NX_TRANS_SOCKET
++                if (result <= 0) {
++                    if ((result == -1 && !ECHECK(EINTR)) ||
++                            (_NXDisplayErrorFunction != NULL &&
++                                (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                        _XIOError(dpy);
++                        return (dpy->qlen);
++                    }
++                }
++#else
+ 		else if (result < 0 && !ECHECK(EINTR))
+ 		    _XIOError(dpy);
++#endif
+ 	    }
+ 	}
+ #endif /* XCONN_CHECK_FREQ */
+@@ -815,6 +1227,10 @@
+ 	    {
+ 		UnlockNextEventReader(dpy);
+ 	    }
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++            fprintf(stderr, "_XEventsQueued: Returning [%d].\n", dpy->qlen);
++#endif
+ 	    return(dpy->qlen);
+ 	}
+       /* Force a read if there is not enough data.  Otherwise,
+@@ -847,6 +1263,11 @@
+ 
+ 	(void) _XRead (dpy, read_buf, (long) len);
+ 	
++#ifdef NX_TRANS_SOCKET
++        if (_XGetIOError(dpy)) {
++            return(dpy->qlen);
++        }
++#endif
+ #ifdef XTHREADS
+ 	/* what did we actually read: reply or event? */
+ 	if (dpy->lock && dpy->lock->reply_awaiters) {
+@@ -945,7 +1366,15 @@
+ #endif /* XTHREADS */
+ 	    /* find out how much data can be read */
+ 	    if (_X11TransBytesReadable(dpy->trans_conn, &pend) < 0)
++#ifdef NX_TRANS_SOCKET
++            {
++                _XIOError(dpy);
++
++                return;
++            }
++#else
+ 	    	_XIOError(dpy);
++#endif
+ 	    len = pend;
+ 
+ 	    /* must read at least one xEvent; if none is pending, then
+@@ -995,6 +1424,15 @@
+ 	    dpy->flags |= XlibDisplayReadEvents;
+ 	    i = _XRead (dpy, read_buf, (long) len);
+ 	    dpy->flags &= ~XlibDisplayReadEvents;
++#ifdef NX_TRANS_SOCKET
++            if (dpy->flags & XlibDisplayIOError)
++            {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++                fprintf(stderr, "_XReadEvents: Returning with I/O error detected.\n");
++#endif
++                return;
++            }
++#endif
+ 	    if (i == -2) {
+ 		/* special flag from _XRead to say that internal connection has
+ 		   done XPutBackEvent.  Which we can use so we're done. */
+@@ -1065,12 +1503,33 @@
+ #ifdef XTHREADS
+ 	int original_size = size;
+ #endif
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        int congestion;
++#endif
+ 
+ 	if ((dpy->flags & XlibDisplayIOError) || size == 0)
+ 	    return 0;
+ 	ESET(0);
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        while (1) {
++                /*
++                 * Need to check the congestion state
++                 * after the read so split the statement
++                 * in multiple blocks.
++                 */
++
++                bytes_read = _X11TransRead(dpy->trans_conn, data, (int)size);
++                if (_NXDisplayCongestionFunction != NULL &&
++                        _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++                    (*_NXDisplayCongestionFunction)(dpy, congestion);
++                }
++                if (bytes_read == size) {
++                    break;
++                }
++#else
+ 	while ((bytes_read = _X11TransRead(dpy->trans_conn, data, (int)size))
+ 		!= size) {
++#endif
+ 
+ 	    	if (bytes_read > 0) {
+ 		    size -= bytes_read;
+@@ -1090,14 +1549,34 @@
+ 		else if (bytes_read == 0) {
+ 		    /* Read failed because of end of file! */
+ 		    ESET(EPIPE);
++#ifdef NX_TRANS_SOCKET
++                    _XIOError(dpy);
++
++                    return -1;
++#else
+ 		    _XIOError(dpy);
++#endif
+ 		    }
+ 
+ 		else  /* bytes_read is less than 0; presumably -1 */ {
+ 		    /* If it's a system call interrupt, it's not an error. */
++#ifdef NX_TRANS_SOCKET
++                    if (!ECHECK(EINTR) ||
++                        (_NXDisplayErrorFunction != NULL &&
++                            (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                        _XIOError(dpy);
++                        return -1;
++                    }
++#else
+ 		    if (!ECHECK(EINTR))
+ 		    	_XIOError(dpy);
++#endif
+ 		    }
++#ifdef NX_TRANS_SOCKET
++                if (_XGetIOError(dpy)) {
++                    return -1;
++                }
++#endif
+ 	    	 }
+ #ifdef XTHREADS
+        if (dpy->lock && dpy->lock->reply_bytes_left > 0)
+@@ -1268,6 +1747,9 @@
+ #ifdef XTHREADS
+         int original_size;
+ #endif
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        int congestion;
++#endif
+ 
+ 	if ((dpy->flags & XlibDisplayIOError) || size == 0) return;
+ 	iov[0].iov_len = (int)size;
+@@ -1285,7 +1767,19 @@
+ 	original_size = size;
+ #endif
+ 	ESET(0);
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        while (1) {
++            bytes_read = _X11TransReadv (dpy->trans_conn, iov, 2);
++            if (_NXDisplayCongestionFunction != NULL &&
++                    _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++                (*_NXDisplayCongestionFunction)(dpy, congestion);
++            }
++            if (bytes_read == size) {
++                break;
++            }
++#else
+ 	while ((bytes_read = _X11TransReadv (dpy->trans_conn, iov, 2)) != size) {
++#endif
+ 
+ 	    if (bytes_read > 0) {
+ 		size -= bytes_read;
+@@ -1313,14 +1807,34 @@
+ 	    else if (bytes_read == 0) {
+ 		/* Read failed because of end of file! */
+ 		ESET(EPIPE);
++#ifdef NX_TRANS_SOCKET
++                _XIOError(dpy);
++
++                return;
++#else
+ 		_XIOError(dpy);
++#endif
+ 		}
+ 	    
+ 	    else  /* bytes_read is less than 0; presumably -1 */ {
+ 		/* If it's a system call interrupt, it's not an error. */
++#ifdef NX_TRANS_SOCKET
++		if (!ECHECK(EINTR) ||
++                        (_NXDisplayErrorFunction != NULL &&
++                            (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                    _XIOError(dpy);
++                    return;
++                }
++#else
+ 		if (!ECHECK(EINTR))
+ 		    _XIOError(dpy);
++#endif
+ 		}
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                return;
++            }
++#endif
+ 	    }
+ #ifdef XTHREADS
+        if (dpy->lock && dpy->lock->reply_bytes_left > 0)
+@@ -1351,8 +1865,31 @@
+ 
+ 	long skip, dbufsize, padsize, total, todo;
+ 	_XExtension *ext;
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_CHANGE)
++        int congestion;
++#endif
++
++#ifdef NX_TRANS_SOCKET
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "_XSend: Sending data with [%d] bytes to write.\n",
++                (dpy->bufptr - dpy->buffer));
++#endif
++        if (!size || (dpy->flags & XlibDisplayIOError))
++        {
++            if (dpy->flags & XlibDisplayIOError)
++            {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++                fprintf(stderr, "_XSend: Returning with I/O error detected.\n");
++#endif
++	        dpy->bufptr = dpy->buffer;
++	        dpy->last_req = (char *)&_dummy_request;
++            }
+ 
++	    return;
++	}
++#else
+ 	if (!size || (dpy->flags & XlibDisplayIOError)) return;
++#endif
+ 	dbufsize = dpy->bufptr - dpy->buffer;
+ #ifdef XTHREADS
+ 	dpy->flags |= XlibDisplayWriting;
+@@ -1418,6 +1955,17 @@
+     
+ 	    ESET(0);
+ 	    if ((len = _X11TransWritev(dpy->trans_conn, iov, i)) >= 0) {
++#ifdef NX_TRANS_SOCKET
++                if (_NXDisplayWriteFunction != NULL) {
++                    (*_NXDisplayWriteFunction)(dpy, len);
++                }
++#ifdef NX_TRANS_CHANGE
++                if (_NXDisplayCongestionFunction != NULL &&
++                        _X11TransSocketCongestionChange(dpy->trans_conn, &congestion) == 1) {
++                    (*_NXDisplayCongestionFunction)(dpy, congestion);
++                }
++#endif
++#endif
+ 		skip += len;
+ 		total -= len;
+ 		todo = total;
+@@ -1447,9 +1995,23 @@
+ 				      );
+ 		}
+ #endif
++#ifdef NX_TRANS_SOCKET
++            } else if (!ECHECK(EINTR) ||
++                (_NXDisplayErrorFunction != NULL &&
++                    (*_NXDisplayErrorFunction)(dpy, _XGetIOError(dpy)))) {
++                _XIOError(dpy);
++                return;
++            }
++#else
+ 	    } else if (!ECHECK(EINTR)) {
+ 		_XIOError(dpy);
+ 	    }
++#endif
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                return;
++            }
++#endif
+ 	}
+ 	dpy->last_req = (char *) & _dummy_request;
+ 	if ((dpy->request - dpy->last_request_read) >= SEQLIMIT &&
+@@ -1640,10 +2202,31 @@
+     if (newseq < lastseq) {
+ 	newseq += 0x10000;
+ 	if (newseq > dpy->request) {
++
++#ifdef NX_TRANS_SOCKET
++
++	    if (_NXLostSequenceFunction != NULL)
++            {
++                (*_NXLostSequenceFunction)(dpy, newseq, dpy->request,
++                                               (unsigned int) rep->type);
++            }
++            else
++            {
++                (void) fprintf (stderr, 
++                "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
++                                newseq, dpy->request, 
++                                (unsigned int) rep->type);
++            }
++
++#else /* #ifdef NX_TRANS_SOCKET */
++
+ 	    (void) fprintf (stderr, 
+ 	    "Xlib: sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
+ 			    newseq, dpy->request, 
+ 			    (unsigned int) rep->type);
++
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ 	    newseq -= 0x10000;
+ 	}
+     }
+@@ -1671,9 +2254,22 @@
+ #ifdef XTHREADS
+     struct _XCVList *cvl;
+ #endif
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "_XReply: Going to wait for an X reply.\n");
++#endif
+ 
++#ifdef NX_TRANS_SOCKET
++    if (dpy->flags & XlibDisplayIOError)
++    {
++#ifdef NX_TRANS_DEBUG
++        fprintf(stderr, "_XReply: Returning 0 with I/O error detected.\n");
++#endif
++        return 0;
++    }
++#else
+     if (dpy->flags & XlibDisplayIOError)
+ 	return 0;
++#endif
+ 
+ #ifdef XTHREADS
+     /* create our condition variable and append to list */
+@@ -1689,6 +2285,9 @@
+ 	   XThread_Self(), cvl);
+ #endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "_XReply: Going to flush the display buffer.\n");
++#endif
+     _XFlushInt(dpy, cvl ? cvl->cv : NULL);
+     /* if it is not our turn to read a reply off the wire,
+      * wait til we're at head of list.  if there is an event waiter,
+@@ -1704,6 +2303,20 @@
+     _XFlush(dpy);
+ #endif
+ 
++#ifdef NX_TRANS_SOCKET
++    /*
++     * We are going to block waiting for the remote
++     * X server. Be sure that the proxy has flushed
++     * all the data.
++     */
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_XReply: Requesting a flush of the NX transport.\n");
++#endif
++
++    NXTransFlush(dpy->fd);
++#endif
++
+     for (;;) {
+ #ifdef XTHREADS
+ 	/* Did another thread's _XReadEvents get our reply by accident? */
+@@ -1767,6 +2380,12 @@
+ 			((long) rep->generic.length) << 2);
+ 		dpy->flags &= ~XlibDisplayReply;
+ 		UnlockNextReplyReader(dpy);
++#ifdef NX_TRANS_SOCKET
++                /*
++                 * The original code has provision
++                 * for returning already.
++                 */
++#endif
+ 		_XIOError (dpy);
+ 		return (0);
+ 
+@@ -1830,6 +2449,12 @@
+ #endif
+ 		break;
+ 	    }
++#ifdef NX_TRANS_SOCKET
++            if (_XGetIOError(dpy)) {
++                UnlockNextReplyReader(dpy);
++                return 0;
++            }
++#endif
+ 	}
+ }   
+ 
+@@ -1849,6 +2474,14 @@
+     (void) _XSetLastRequestRead(dpy, &rep->generic);
+     len = SIZEOF(xReply) + (rep->generic.length << 2);
+     if (len < SIZEOF(xReply)) {
++#ifdef NX_TRANS_SOCKET
++
++        /*
++         * The original code has provision
++         * for returning already.
++         */
++
++#endif
+ 	_XIOError (dpy);
+ 	buf += *lenp;
+ 	*lenp = 0;
+@@ -1876,6 +2509,14 @@
+     }
+     if (len < SIZEOF(xReply))
+     {
++#ifdef NX_TRANS_SOCKET
++
++        /*
++         * The original code has provision
++         * for returning already.
++         */
++
++#endif
+ 	_XIOError (dpy);
+ 	buf += *lenp;
+ 	*lenp = 0;
+@@ -1944,6 +2585,10 @@
+     struct _XConnWatchInfo *watchers;
+     XPointer *wd;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "_XRegisterInternalConnection: Got called.\n");
++#endif
++
+     new_conni = (struct _XConnectionInfo*)Xmalloc(sizeof(struct _XConnectionInfo));
+     if (!new_conni)
+ 	return 0;
+@@ -1991,6 +2636,10 @@
+     struct _XConnWatchInfo *watch;
+     XPointer *wd;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "_XUnregisterInternalConnection: Got called.\n");
++#endif
++
+     for (prev = &dpy->im_fd_info; (info_list = *prev);
+ 	 prev = &info_list->next) {
+ 	if (info_list->fd == fd) {
+@@ -2030,6 +2679,10 @@
+     struct _XConnectionInfo *info_list;
+     int *fd_list;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "XInternalConnectionNumbers: Got called.\n");
++#endif
++
+     LockDisplay(dpy);
+     count = 0;
+     for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next)
+@@ -2088,6 +2741,10 @@
+ {
+     struct _XConnectionInfo *info_list;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "XProcessInternalConnection: Got called.\n");
++#endif
++
+     LockDisplay(dpy);
+     for (info_list=dpy->im_fd_info; info_list; info_list=info_list->next) {
+ 	if (info_list->fd == fd) {
+@@ -2116,6 +2773,10 @@
+     struct _XConnectionInfo *info_list;
+     XPointer *wd_array;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "XAddConnectionWatch: Got called.\n");
++#endif
++
+     LockDisplay(dpy);
+ 
+     /* allocate new watch data */
+@@ -2172,6 +2833,10 @@
+     struct _XConnectionInfo *conni;
+     int counter = 0;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "XRemoveConnectionWatch: Got called.\n");
++#endif
++
+     LockDisplay(dpy);
+     for (watch=dpy->conn_watchers; watch; watch=watch->next) {
+ 	if (watch->fn == callback  &&  watch->client_data == client_data) {
+@@ -2209,6 +2874,10 @@
+ #define SCRATCHSIZE 2048
+     char buf[SCRATCHSIZE];
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
++    fprintf(stderr, "_XEatData: Going to eat [%ld] bytes of data from descriptor [%d].\n",
++                n, dpy->fd);
++#endif
+     while (n > 0) {
+ 	register long bytes_read = (n > SCRATCHSIZE) ? SCRATCHSIZE : n;
+ 	(void) _XRead (dpy, buf, bytes_read);
+@@ -2237,7 +2906,13 @@
+ 	    (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
+ 		/* Malloc call failed! */
+ 		ESET(ENOMEM);
++#ifdef NX_TRANS_SOCKET
++                _XIOError(dpy);
++
++                return;
++#else
+ 		_XIOError(dpy);
++#endif
+ 	}
+ 	qelt->next = NULL;
+ 	/* go call through display to find proper event reformatter */
+@@ -2710,7 +3385,29 @@
+ 			QLength(dpy));
+ 
+ 	}
+-	exit(1);
++#ifdef NX_TRANS_SOCKET
++        if (_NXHandleDisplayError == 1)
++        {
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "_XDefaultIOError: Going to return from the error handler.\n");
++#endif
++            return 0;
++        }
++        else
++        {
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "_XDefaultIOError: Going to exit from the program.\n");
++#endif
++#ifdef NX_TRANS_EXIT
++            NXTransExit(1);
++#else
++            exit(1);
++#endif
++        }
++#else
++        exit(1);
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+         return(0); /* dummy - function should never return */
+ }
+ 
+@@ -2911,7 +3608,48 @@
+ 	(*_XIOErrorFunction)(dpy);
+     else
+ 	_XDefaultIOError(dpy);
++#ifdef NX_TRANS_SOCKET
++    /*
++     * Check if we are supposed to return in the case
++     * of a display failure. The client which originated
++     * the X operation will have to check the value of
++     * the XlibDisplayIOError flag and handle appropria-
++     * tely the display disconnection.
++     */
++
++    if (_NXHandleDisplayError == 0)
++    {
++#ifdef NX_TRANS_EXIT
++        NXTransExit(1);
++#else
++        exit(1);
++#endif
++    }
++
++    /*
++     * We are going to return. Reset the display
++     * buffers. Further writes will be discarded.
++     */
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_XIOError: Resetting the display buffer.\n");
++#endif
++
++    dpy->bufptr = dpy->buffer;
++    dpy->last_req = (char *) &_dummy_request;
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_XIOError: Resetting the display flags.\n");
++#endif
++
++    dpy->flags &= ~XlibDisplayProcConni;
++    dpy->flags &= ~XlibDisplayPrivSync;
++    dpy->flags &= ~XlibDisplayReadEvents;
++    dpy->flags &= ~XlibDisplayWriting;
++    dpy->flags &= ~XlibDisplayReply;
++#else
+     exit (1);
++#endif
+     return 0;
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/Xlibint.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Xlibint.h.NX.patch
new file mode 100644
index 0000000..a23172e
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Xlibint.h.NX.patch
@@ -0,0 +1,59 @@
+--- ./nx-X11/lib/X11/Xlibint.h.X.original	2015-02-13 14:03:44.624443872 +0100
++++ ./nx-X11/lib/X11/Xlibint.h	2015-02-10 19:13:12.888720189 +0100
+@@ -27,6 +27,24 @@
+ from The Open Group.
+ 
+ */
++
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/lib/X11/Xlibint.h,v 3.27 2003/05/27 22:26:26 tsi Exp $ */
+ 
+ #ifndef _XLIBINT_H_
+@@ -44,6 +62,15 @@
+ #include <X11/Xproto.h>		/* to declare xEvent */
+ #include <X11/XlibConf.h>	/* for configured options like XTHREADS */
+ 
++#ifdef NX_TRANS_SOCKET
++
++#include "NXvars.h"
++
++#define _XGetIOError(dpy) \
++    (dpy -> flags & XlibDisplayIOError)
++
++#endif
++
+ #ifdef WIN32
+ #define _XFlush _XFlushIt
+ #endif
+@@ -348,9 +375,15 @@
+ #define LOCKED 1
+ #define UNLOCKED 0
+ 
++#ifdef NX_TRANS_SOCKET
++#ifndef BUFSIZE                         /* Output buffer size is configurable  */
++#define BUFSIZE 8192                    /* but this is still used for reading. */
++#endif
++#else
+ #ifndef BUFSIZE
+ #define BUFSIZE 2048			/* X output buffer size. */
+ #endif
++#endif
+ #ifndef PTSPERBATCH
+ #define PTSPERBATCH 1024		/* point batching */
+ #endif
diff --git a/doc/nx-X11_vs_XOrg69_patches/Xpoll.h.in.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Xpoll.h.in.NX.patch
new file mode 100644
index 0000000..b869d58
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Xpoll.h.in.NX.patch
@@ -0,0 +1,67 @@
+--- ./nx-X11/include/Xpoll.h.in.X.original	2015-02-13 14:03:44.612444107 +0100
++++ ./nx-X11/include/Xpoll.h.in	2015-02-10 19:13:14.464661220 +0100
+@@ -51,6 +51,23 @@
+ 
+ /* $XFree86: xc/include/Xpoll.h,v 3.8 2001/01/17 17:53:11 dawes Exp $ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #ifndef _XPOLL_H_
+ #define _XPOLL_H_
+ 
+@@ -120,6 +137,31 @@
+ } fd_set;
+ #endif
+ 
++/*
++ * Replace the standard Select with a version giving NX a
++ * chance to check its own descriptors. This doesn't cover
++ * the cases where the system is using poll or when system-
++ * specific defines override the Select definition (OS/2).
++ * See XlibInt.c for _XSelect().
++ */
++
++#ifdef NX_TRANS_SOCKET
++
++extern int _XSelect(int maxfds, fd_set *readfds, fd_set *writefds,
++                        fd_set *exceptfds, struct timeval *timeout);
++
++#ifndef hpux /* and perhaps old BSD ??? */
++# define Select(n,r,w,e,t) _XSelect(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t)
++#else
++# ifndef _XPG4_EXTENDED /* HPUX 9.x and earlier */
++#  define Select(n,r,w,e,t) _XSelect(n,(int*)r,(int*)w,(int*)e,(struct timeval*)t)
++# else
++#  define Select(n,r,w,e,t) _XSelect(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t)
++# endif
++#endif
++
++#else /* #ifdef NX_TRANS_SOCKET */
++
+ #ifndef hpux /* and perhaps old BSD ??? */
+ # define Select(n,r,w,e,t) select(n,(fd_set*)r,(fd_set*)w,(fd_set*)e,(struct timeval*)t)
+ #else
+@@ -130,6 +172,8 @@
+ # endif
+ #endif
+ 
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ #define __X_FDS_BITS @USE_FDS_BITS@
+ 
+ #ifndef __FDS_BITS
diff --git a/doc/nx-X11_vs_XOrg69_patches/Xrender.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Xrender.h.NX.patch
new file mode 100644
index 0000000..8bda137
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Xrender.h.NX.patch
@@ -0,0 +1,39 @@
+--- ./nx-X11/lib/Xrender/Xrender.h.X.original	2015-02-13 14:03:44.652443320 +0100
++++ ./nx-X11/lib/Xrender/Xrender.h	2015-02-10 19:13:12.596731149 +0100
+@@ -25,6 +25,8 @@
+ #ifndef _XRENDER_H_
+ #define _XRENDER_H_
+ 
++#define NX_CLEANUP
++
+ #include <X11/extensions/render.h>
+ 
+ #include <X11/Xlib.h>
+@@ -32,6 +34,10 @@
+ #include <X11/Xosdefs.h>
+ #include <X11/Xutil.h>
+ 
++#ifdef NX_CLEANUP
++#include "renderproto.h"
++#endif
++
+ typedef struct {
+     short   red;
+     short   redMask;
+@@ -296,6 +302,16 @@
+ void
+ XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset);
+ 
++#ifdef NX_CLEANUP
++
++void XRenderCleanGlyphs (xGlyphInfo  *gi,
++                         int         nglyphs,
++                         CARD8       *images,
++                         int         depth,
++                         Display     *dpy);
++
++#endif /* #ifdef NX_CLEANUP */
++
+ void
+ XRenderAddGlyphs (Display		*dpy,
+ 		  GlyphSet		glyphset,
diff --git a/doc/nx-X11_vs_XOrg69_patches/Xtranssock.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/Xtranssock.c.NX.patch
new file mode 100644
index 0000000..fc81419
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/Xtranssock.c.NX.patch
@@ -0,0 +1,1133 @@
+--- ./nx-X11/lib/xtrans/Xtranssock.c.X.original	2015-02-13 14:03:44.672442927 +0100
++++ ./nx-X11/lib/xtrans/Xtranssock.c	2015-02-13 14:03:44.672442927 +0100
+@@ -53,6 +53,35 @@
+  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
++#ifdef NX_TRANS_SOCKET
++
++#ifdef NX_TRANS_DEBUG
++#define XTRANSDEBUG 5
++#endif
++
++#ifndef PF_LOCAL
++#define PF_LOCAL PF_UNIX
++#endif
++
++#endif
++
+ #include <ctype.h>
+ #ifdef XTHREADS
+ #include <X11/Xthreads.h>
+@@ -294,6 +323,560 @@
+ static int haveIPv6 = 1;
+ #endif
+ 
++#ifndef X11_t
++
++/*
++ * No NX changes if this is not
++ * compiled as a X11 transport.
++ */
++
++#undef NX_TRANS_SOCKET
++
++#endif
++
++#ifdef NX_TRANS_SOCKET
++
++#ifdef TRANS_CLIENT
++
++#include "NX.h"
++
++typedef struct
++{
++    XtransConnInfo info;
++    int            local;
++    int            remote;
++    int            congestion;
++
++} _NXProxyConnInfo;
++
++#define NX_PROXY_CONN_LIMIT     256
++
++static _NXProxyConnInfo *_NXProxyConnInfoTab[NX_PROXY_CONN_LIMIT];
++
++#endif /* #ifdef TRANS_CLIENT */
++
++/*
++ * Override the UNIX_DIR and UNIX_PATH settings and
++ * make them configurable, based on the NX_TEMP or
++ * the TEMP environment.
++ *
++ * We must be careful as the same defines are used
++ * for different directories, based on the subsystem
++ * that is compiling this, while we want to override
++ * only the '/tmp/.X11-unix' and '/tmp/.X11-unix/X'
++ * settings.
++ */
++
++static char _NXUnixDir[1024];
++static char _NXUnixPath[1024];
++
++static char *_NXGetUnixDir(char *dir)
++{
++    const char *tempDir;
++
++    PRMSG (3, "_NXGetUnixDir(%s)\n", dir, 0, 0);
++
++    if (strcmp(dir, UNIX_DIR) != 0)
++    {
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetUnixDir: Returning other Unix directory [%s].\n", dir);
++#endif
++        return dir;
++    }
++
++    /*
++     * Check the environment only once.
++     */
++
++    if (*_NXUnixDir != '\0')
++    {
++        return _NXUnixDir;
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetUnixDir: Trying with the NX_TEMP environment.\n");
++#endif
++
++    tempDir = getenv("NX_TEMP");
++
++    if (tempDir == NULL || *tempDir == '\0')
++    {
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetUnixDir: Trying with the TEMP environment.\n");
++#endif
++
++        tempDir = getenv("TEMP");
++    }
++
++    if (tempDir != NULL && *tempDir != '\0')
++    {
++        if (strlen(tempDir) + strlen("/.X11-unix") + 1 > 1024)
++        {
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "_NXGetUnixDir: WARNING! Maximum length of X11 Unix directory exceeded.\n");
++#endif
++            goto _NXGetUnixDirError;
++        }
++
++        strcpy(_NXUnixDir, tempDir);
++        strcat(_NXUnixDir, "/.X11-unix");
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetUnixDir: Using X11 Unix directory [%s].\n", _NXUnixDir);
++#endif
++
++        return _NXUnixDir;
++    }
++
++_NXGetUnixDirError:
++
++    strcpy(_NXUnixDir, dir);
++ 
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetUnixDir: Returning default X11 Unix directory [%s].\n", _NXUnixDir);
++#endif
++
++    return _NXUnixDir;
++}
++
++static char *_NXGetUnixPath(char *path)
++{
++    const char *unixDir;
++
++    PRMSG (3, "_NXGetUnixPath(%s)\n", path, 0, 0);
++
++    if (strcmp(path, UNIX_PATH) != 0)
++    {
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetUnixPath: Returning other X11 Unix path [%s].\n", path);
++#endif
++        return path;
++    }
++
++    /*
++     * Check the environment only once.
++     */
++
++    if (*_NXUnixPath != '\0')
++    {
++        return _NXUnixPath;
++    }
++
++    unixDir = _NXGetUnixDir(UNIX_DIR);
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetUnixPath: Got X11 Unix directory [%s].\n", unixDir);
++#endif
++
++    if (strlen(unixDir) + strlen("/X") + 1 > 1024)
++    {
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetUnixPath: WARNING! Maximum length of X11 Unix path exceeded.\n");
++#endif
++
++        goto _NXGetUnixPathError;
++    }
++
++    strcpy(_NXUnixPath, unixDir);
++    strcat(_NXUnixPath, "/X");
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetUnixPath: Returning X11 Unix path [%s].\n", _NXUnixPath);
++#endif
++
++    return _NXUnixPath;
++
++_NXGetUnixPathError:
++
++    strcpy(_NXUnixPath, path);
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetUnixPath: Returning default X11 Unix path [%s].\n", _NXUnixPath);
++#endif
++
++    return _NXUnixPath;
++}
++
++#ifdef hpux
++
++static char *_NXGetOldUnixPath(char *path)
++{
++    PRMSG (3, "_NXGetOldUnixPath(%s)\n", path, 0, 0);
++
++    if (strcmp(path, OLD_UNIX_PATH) == 0)
++    {
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetOldUnixPath: Returning X11 Unix path [%s].\n",
++                    _NXGetUnixPath(path));
++#endif
++
++        return _NXGetUnixPath(path);
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetOldUnixPath: Returning other old X11 Unix path [%s].\n", path);
++#endif
++
++    return path;
++}
++
++#endif /* #ifdef hpux */
++
++/*
++ * Forcibly close any connection attempt on the
++ * listening socket. Need this to avoid loopback
++ * connections to the agent server.
++ */
++
++#ifdef TRANS_SERVER
++
++void TRANS(SocketRejectConnection) (XtransConnInfo ciptr)
++{
++    size_t sa_l = sizeof(struct sockaddr);
++    struct sockaddr sa;
++    fd_set fs;
++    struct timeval t;
++    int f;
++
++    PRMSG (3, "SocketRejectConnection(%x)\n", ciptr, 0, 0);
++
++    FD_ZERO(&fs);
++    FD_SET(ciptr -> fd, &fs);
++
++    t.tv_sec  = 0;
++    t.tv_usec = 0;
++
++    /*
++     * Check if there is an awaiting connection.
++     */
++
++    if (select(ciptr -> fd + 1, &fs, NULL, NULL, &t) == 1)
++    {
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "SocketRejectConnection: Accepting connection attempt on fd [%d].\n",
++                    ciptr -> fd);
++#endif
++        /*
++         * If there is one, close it.
++         */
++ 
++        if ((f = accept(ciptr -> fd, &sa, &sa_l)) >= 0)
++        {
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "SocketRejectConnection: Closing connection attempt on fd [%d].\n",
++                        ciptr -> fd);
++#endif
++            close(f);
++        }
++    }
++}
++
++#endif /* #ifdef TRANS_SERVER */
++
++#ifdef TRANS_CLIENT
++
++void *TRANS(SocketProxyConnInfo) (XtransConnInfo ciptr)
++{
++    if (_NXProxyConnInfoTab[ciptr->fd] != NULL)
++    {
++      return ciptr->priv;
++    }
++
++    return NULL;
++}
++
++static XtransConnInfo TRANS(SocketCreateConnInfo) ()
++{
++    XtransConnInfo ciptr;
++
++    int fds[2];
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCreateConnInfo: Going to create the NX connection info.\n");
++#endif
++
++    if ((ciptr = (XtransConnInfo) xcalloc (1, sizeof(struct _XtransConnInfo))) == NULL)
++    {
++        PRMSG (1, "SocketCreateConnInfo: malloc failed\n", 0, 0, 0);
++        return NULL;
++    }
++
++    /*
++     * Create a pair of sockets. We'll communicate with
++     * the NX proxy by reading and writing to our end.
++     */
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCreateConnInfo: Going to create the NX socketpair.\n");
++#endif
++
++    if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) < 0)
++    {
++        PRMSG (1, "SocketCreateConnInfo: socketpair() failed.\n", 0, 0, 0);
++        xfree ((char *) ciptr);
++        return NULL;
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCreateConnInfo: X socket end is [%d] NX proxy end is [%d].\n",
++                fds[0], fds[1]);
++#endif
++
++    /*
++     * Save in _NXProxyConnInfoTab the local and remote end of
++     * the socketpair. The remote end will be used by the proxy.
++     * When the memory-to-memory transport is activated, the
++     * agent and the proxy don't read or write to the real des-
++     * criptors but the communication takes place by reading
++     * and writing to the proxy's buffers.
++     */
++
++    ciptr->fd = fds[0];
++
++    if (ciptr->fd >= NX_PROXY_CONN_LIMIT)
++    {
++        PRMSG (1, "SocketCreateConnInfo: No space for a new _NXProxyConnInfo for [%d].\n",
++                  ciptr->fd, 0, 0);
++        xfree ((char *) ciptr);
++        return NULL;
++    }
++    else if (_NXProxyConnInfoTab[ciptr->fd] != NULL)
++    {
++        PRMSG (1, "SocketCreateConnInfo: _NXProxyConnInfo for [%d] is not NULL. Exiting.\n",
++                   ciptr->fd, 0, 0);
++        exit(1);
++    }
++
++    _NXProxyConnInfoTab[ciptr->fd] = (_NXProxyConnInfo *) xcalloc(1, sizeof(_NXProxyConnInfo));
++
++    if (_NXProxyConnInfoTab[ciptr->fd] == NULL)
++    {
++        PRMSG (1, "SocketCreateConnInfo: Alloc of _NXProxyConnInfo failed.\n", 0, 0, 0);
++        xfree ((char *) ciptr);
++        return NULL;
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCreateConnInfo: Allocated new _NXProxyConnInfo for [%d].\n",
++                ciptr->fd);
++#endif
++
++    _NXProxyConnInfoTab[ciptr->fd]->info       = ciptr;
++    _NXProxyConnInfoTab[ciptr->fd]->local      = fds[0];
++    _NXProxyConnInfoTab[ciptr->fd]->remote     = fds[1];
++    _NXProxyConnInfoTab[ciptr->fd]->congestion = 0;
++
++    ciptr->priv = (char *) _NXProxyConnInfoTab[ciptr->fd];
++
++    return ciptr;
++}
++
++static int TRANS(SocketConnectConnInfo) (XtransConnInfo ciptr, char *host, char *port)
++{
++    int fds[2];
++    char display[1024];
++
++    _NXProxyConnInfo *proxy_conn;
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketConnectConnInfo: Going to connect NX fd [%d] to host [%s] port [%s].\n",
++                ciptr->fd, host, port);
++#endif
++
++    /*
++     * We should have already created the socket pair.
++     */
++
++    proxy_conn = (_NXProxyConnInfo *) ciptr->priv;
++
++    if (proxy_conn == NULL)
++    {
++        PRMSG (1, "SocketConnectConnInfo: Pointer to _NXProxyConnInfo is NULL. Exiting.\n", 0, 0, 0);
++
++        exit(1);
++    }
++    else if (_NXProxyConnInfoTab[ciptr->fd] != (_NXProxyConnInfo *) ciptr->priv)
++    {
++        PRMSG (1, "SocketConnectConnInfo: Can't find _NXProxyConnInfo in table. Exiting.\n",
++                   0, 0, 0);
++
++        exit(1);
++    }
++
++    if (strlen(host) + strlen(port) + 1 >= 1023)
++    {
++        PRMSG (1, "SocketConnectConnInfo: Length of NX display string '%s:%s' would exceed %d characters.\n",
++                   host, port, 1023);
++
++        return TRANS_CONNECT_FAILED;
++    }
++
++    sprintf(display, "%s:%s", host, port);
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketConnectConnInfo: Setting close-on-exec flag on local NX descriptor [%d].\n",
++                proxy_conn -> local);
++#endif
++
++#ifdef F_SETFD
++#ifdef FD_CLOEXEC
++    if (fcntl(proxy_conn -> local, F_SETFD, FD_CLOEXEC) != 0)
++#else
++    if (fcntl(proxy_conn -> local, F_SETFD, 1) != 0)
++#endif
++#endif
++    {
++        PRMSG (1, "SocketConnectConnInfo: Cannot set close-on-exec on local NX descriptor [%d].\n",
++                   proxy_conn -> local, 0, 0);
++
++        return TRANS_CONNECT_FAILED;
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketConnectConnInfo: Creating the NX transport with display [%s].\n",
++                display);
++#endif
++
++    if (NXTransCreate(NX_FD_ANY, NX_MODE_CLIENT, display) < 0)
++    {
++        PRMSG (1, "SocketConnectConnInfo: Cannot create the NX transport.\n",
++                   0, 0, 0);
++
++        return TRANS_CONNECT_FAILED;
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketConnectConnInfo: Starting the NX agent with descriptor [%d].\n",
++                proxy_conn -> remote);
++#endif
++
++    fds[0] = proxy_conn -> local;
++    fds[1] = proxy_conn -> remote;
++
++    NXTransAgent(fds);
++
++    return 0;
++}
++
++static void TRANS(SocketCloseConnInfo) (XtransConnInfo ciptr)
++{
++    _NXProxyConnInfo *proxy_conn;
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCloseConnInfo: Going to close the NX fd [%d].\n", ciptr->fd);
++#endif
++
++    proxy_conn = (_NXProxyConnInfo *) ciptr->priv;
++
++    if (proxy_conn == NULL)
++    {
++        PRMSG (1, "SocketCloseConnInfo: Pointer to _NXProxyConnInfo is NULL. Exiting.\n", 0, 0, 0);
++
++        exit(1);
++    }
++    else if (ciptr->fd >= NX_PROXY_CONN_LIMIT ||
++                 _NXProxyConnInfoTab[ciptr->fd] != (_NXProxyConnInfo *) ciptr->priv)
++    {
++        PRMSG (1, "SocketCloseConnInfo: Can't find _NXProxyConnInfo in table. Exiting.\n",
++                   0, 0, 0);
++        exit(1);
++    }
++    else if (_NXProxyConnInfoTab[ciptr->fd] -> info != ciptr ||
++                 _NXProxyConnInfoTab[ciptr->fd] -> local != ciptr->fd)
++    {
++        PRMSG (1, "SocketCloseConnInfo: Invalid _NXProxyConnInfo structure for [%d]. Exiting.\n",
++                   ciptr->fd, 0, 0);
++        exit(1);
++    }
++    else if (proxy_conn->local < 0 || proxy_conn->remote < 0)
++    {
++        PRMSG (1, "SocketCloseConnInfo: Invalid socket pair in NX connection for [%d]. Exiting.\n",
++                   ciptr->fd, 0, 0);
++        exit(1);
++    }
++
++    NXTransClose(ciptr->fd);
++
++    /*
++     *  Get rid of the _NXProxyConnInfo structure.
++     */
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCloseConnInfo: Freeing _NXProxyConnInfo structure for [%d].\n",
++                ciptr->fd);
++#endif
++
++    xfree((char *) _NXProxyConnInfoTab[ciptr->fd]);
++
++    _NXProxyConnInfoTab[ciptr->fd] = NULL;
++
++    ciptr->priv = NULL;
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCloseConnInfo: Should now close the local descriptor [%d].\n",
++                ciptr->fd);
++#endif
++}
++
++#endif /* #ifdef TRANS_CLIENT */
++
++#if defined(TRANS_CLIENT) && defined(NX_TRANS_CHANGE)
++
++/*
++ * Check the congestion state of the NX transport
++ * and return 1 if there has been a change. This
++ * can be extended by adding a few counters track-
++ * ing the bandwidth usage of the X11 connection.
++ */
++
++int TRANS(SocketCongestionChange) (XtransConnInfo ciptr, int *state)
++{
++    int congestion;
++
++    _NXProxyConnInfo *proxy_conn;
++
++    PRMSG (3, "SocketCongestionChange(%x)\n", ciptr, 0, 0);
++
++    proxy_conn = (_NXProxyConnInfo *) ciptr->priv;
++
++    if (proxy_conn == NULL)
++    {
++#ifdef NX_TRANS_DEBUG
++        fprintf(stderr, "SocketCongestionChange: Descriptor [%d] doesn't appear to be a NX connection.\n",
++                    ciptr->fd);
++#endif
++        return 0;
++    }
++
++#ifdef NX_TRANS_DEBUG
++    fprintf(stderr, "SocketCongestionChange: Checking congestion on fd [%d] with old state [%d].\n",
++                ciptr->fd, proxy_conn->congestion);
++#endif
++
++    congestion = NXTransCongestion(ciptr->fd);
++
++    if (congestion != proxy_conn->congestion)
++    {
++        proxy_conn->congestion = congestion;
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "SocketCongestionChange: Change detected on fd [%d] with new state [%d].\n",
++                    ciptr->fd, proxy_conn->congestion);
++#endif
++        return 1;
++    }
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketCongestionChange: No change on fd [%d] with current state [%d].\n",
++                ciptr->fd, congestion);
++#endif
++    return 0;
++}
++
++#endif /* #if defined(TRANS_CLIENT) && defined(NX_TRANS_CHANGE) */
++
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ /*
+  * These are some utility function used by the real interface function below.
+  */
+@@ -562,6 +1145,29 @@
+     SocketInitOnce();
+ 
+     while ((i = TRANS(SocketSelectFamily) (i, transname)) >= 0) {
++
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++        if ((!strcmp(protocol, "local") || !strcmp(protocol, "nx")) &&
++                (!strcasecmp(host, "nx") || !strncasecmp(host, "nx,", 3)))
++        {
++            ciptr = TRANS(SocketCreateConnInfo) ();
++
++            if (ciptr == NULL)
++            {
++                PRMSG (1, "SocketOpenCOTSClient: Unable to create the NX connection info for %s.\n",
++                           transname, 0, 0);
++
++                return NULL;
++            }
++
++            ciptr->index = i;
++
++            return ciptr;
++        }
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+ 	if ((ciptr = TRANS(SocketOpen) (
+ 		 i, Sockettrans2devtab[i].devcotsname)) != NULL)
+ 	    break;
+@@ -576,6 +1182,12 @@
+ 	return NULL;
+     }
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    ciptr->priv = NULL;
++
++#endif
++
+     /* Save the index for later use */
+ 
+     ciptr->index = i;
+@@ -677,6 +1289,29 @@
+     SocketInitOnce();
+ 
+     while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
++
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++        if ((!strcmp(protocol, "local") || !strcmp(protocol, "nx")) &&
++                (!strcasecmp(host, "nx") || !strncasecmp(host, "nx,", 3)))
++        {
++            ciptr = TRANS(SocketCreateConnInfo) ();
++
++            if (ciptr == NULL)
++            {
++                PRMSG (1, "SocketOpenCLTSClient: Unable to create the NX connection info for %s.\n",
++                           thistrans->TransName, 0, 0);
++
++                return NULL;
++            }
++
++            ciptr->index = i;
++
++            return ciptr;
++        }
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+ 	if ((ciptr = TRANS(SocketOpen) (
+ 		 i, Sockettrans2devtab[i].devcotsname)) != NULL)
+ 	    break;
+@@ -691,6 +1326,12 @@
+ 	return NULL;
+     }
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    ciptr->priv = NULL;
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+     /* Save the index for later use */
+ 
+     ciptr->index = i;
+@@ -826,6 +1467,11 @@
+ {
+     PRMSG (2,"SocketSetOption(%d,%d,%d)\n", ciptr->fd, option, arg);
+ 
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "SocketSetOption: WARNING! Not setting option [%d] with value [%d] on descriptor [%d].\n",
++                option, arg, ciptr -> fd);
++#endif
++
+     return -1;
+ }
+ 
+@@ -875,6 +1521,11 @@
+     else
+ 	retry = 0;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "SocketCreateListener: Creating listener for ciptr at [%p] on path [%s].\n",
++                (void *) ciptr, ((struct sockaddr_un *) sockname)->sun_family == AF_UNIX ?
++                    ((struct sockaddr_un *) sockname)->sun_path : "TCP");
++#endif
+     while (bind (fd, (struct sockaddr *) sockname, namelen) < 0)
+     {
+ 	if (errno == EADDRINUSE) {
+@@ -926,6 +1577,11 @@
+ 
+     ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "SocketCreateListener: Set flags to [%d] for ciptr [%p].\n",
++                ciptr->flags, (void *) ciptr);
++#endif
++
+     return 0;
+ }
+ 
+@@ -1084,9 +1740,15 @@
+ #else
+     mode = 0777;
+ #endif
++#ifdef NX_TRANS_SOCKET
++    if (trans_mkdir(_NXGetUnixDir(UNIX_DIR), mode) == -1) {
++        PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n",
++               _NXGetUnixDir(UNIX_DIR), errno, 0);
++#else
+     if (trans_mkdir(UNIX_DIR, mode) == -1) {
+ 	PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n",
+ 	       UNIX_DIR, errno, 0);
++#endif
+ 	(void) umask (oldUmask);
+ 	return TRANS_CREATE_LISTENER_FAILED;
+     }
+@@ -1095,12 +1757,20 @@
+     sockname.sun_family = AF_UNIX;
+ 
+     if (port && *port) {
++#ifdef NX_TRANS_SOCKET
++        if (set_sun_path(port, _NXGetUnixPath(UNIX_PATH), sockname.sun_path) != 0) {
++#else
+ 	if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) {
++#endif
+ 	    PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0);
+ 	    return TRANS_CREATE_LISTENER_FAILED;
+ 	}
+     } else {
++#ifdef NX_TRANS_SOCKET
++	sprintf (sockname.sun_path, "%s%ld", _NXGetUnixPath(UNIX_PATH), (long)getpid());
++#else
+ 	sprintf (sockname.sun_path, "%s%ld", UNIX_PATH, (long)getpid());
++#endif
+     }
+ 
+ #if (defined(BSD44SOCKETS) || defined(__UNIXWARE__)) && !defined(Lynx)
+@@ -1110,6 +1780,10 @@
+     namelen = strlen(sockname.sun_path) + sizeof(sockname.sun_family);
+ #endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "SocketUNIXCreateListener: Unlinking path [%s] for ciptr at [%p].\n",
++                sockname.sun_path, (void *) ciptr);
++#endif
+     unlink (sockname.sun_path);
+ 
+     if ((status = TRANS(SocketCreateListener) (ciptr,
+@@ -1181,9 +1855,15 @@
+ #else
+ 	mode = 0777;
+ #endif
++#ifdef NX_TRANS_SOCKET
++        if (trans_mkdir(_NXGetUnixDir(UNIX_DIR), mode) == -1) {
++            PRMSG (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n",
++            _NXGetUnixDir(UNIX_DIR), errno, 0);
++#else
+         if (trans_mkdir(UNIX_DIR, mode) == -1) {
+             PRMSG (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n",
+ 	    UNIX_DIR, errno, 0);
++#endif
+ 	    (void) umask (oldUmask);
+ 	    return TRANS_RESET_FAILURE;
+         }
+@@ -1962,7 +2642,12 @@
+      * we know for sure it will fail.
+      */
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++    if (strcmp(host, "unix") != 0 && strcasecmp(host, "nx") != 0 &&
++            strncasecmp(host, "nx,", 3) != 0 && !UnixHostReallyLocal (host))
++#else
+     if (strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
++#endif
+     {
+ 	PRMSG (1,
+ 	   "SocketUNIXConnect: Cannot connect to non-local host %s\n",
+@@ -1988,7 +2673,11 @@
+     
+     sockname.sun_family = AF_UNIX;
+ 
++#ifdef NX_TRANS_SOCKET
++    if (set_sun_path(port, _NXGetUnixPath(UNIX_PATH), sockname.sun_path) != 0) {
++#else
+     if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) {
++#endif
+ 	PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0);
+ 	return TRANS_CONNECT_FAILED;
+     }
+@@ -2006,7 +2695,11 @@
+      * This is gross, but it was in Xlib
+      */
+     old_sockname.sun_family = AF_UNIX;
++#ifdef NX_TRANS_SOCKET
++    if (set_sun_path(port, _NXGetOldUnixPath(OLD_UNIX_PATH), old_sockname.sun_path) != 0) {
++#else
+     if (set_sun_path(port, OLD_UNIX_PATH, old_sockname.sun_path) != 0) {
++#endif
+ 	PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0);
+ 	return TRANS_CONNECT_FAILED;
+     }
+@@ -2014,6 +2707,19 @@
+ 	sizeof (old_sockname.sun_family);
+ #endif
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    if (ciptr->priv != NULL)
++    {
++        if (TRANS(SocketConnectConnInfo) (ciptr, host, port) != 0)
++        {
++            return TRANS_CONNECT_FAILED;
++        }
++
++        goto SocketUNIXConnectPost;
++    }
++
++#endif
+ 
+     /*
+      * Do the connect()
+@@ -2065,6 +2771,12 @@
+ 	}
+     }
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++SocketUNIXConnectPost:
++
++#endif
++
+     /*
+      * Get the socket name and the peer name from the connect socket,
+      * since this is unix domain.
+@@ -2099,6 +2811,58 @@
+ {
+     PRMSG (2,"SocketBytesReadable(%p,%d,%p)\n",
+ 	ciptr, ciptr->fd, pend);
++
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    if (ciptr->priv)
++    {
++        if (NXTransRunning(ciptr->fd) == 0)
++        {
++            /*
++             * Force the application to shut down the
++             * socket if the NX transport is gone. We
++             * may probably save this additional call.
++             */
++
++#ifdef NX_TRANS_DEBUG
++            fprintf(stderr, "SocketBytesReadable: NX transport not running for descriptor [%d].\n",
++                        ciptr->fd);
++#endif
++            ESET(EPIPE);
++
++            return -1;
++        }
++        else
++        {
++            /*
++             * Emulate BytesReadable. Some X applications may use the system
++             * select() in their main loop, instead of the _XSelect() that is
++             * replaced by NX. Still these applications use _XEventsQueued to
++             * poll events from the X connection, and _XEventsQueued uses the
++             * NX _XSelect(), so it is generally possible to let the client
++             * yield the control to NX and let it handle the I/O on the proxy
++             * descriptors even if the application is not explicitly designed
++             * to work as a NX agent.         
++             */
++
++#ifdef NX_TRANS_DEBUG
++
++            int result;
++
++            result = NXTransReadable(ciptr->fd, (int *) pend);
++
++            fprintf(stderr, "SocketBytesReadable: Descriptor [%d] result [%d] readable [%ld].\n",
++                        ciptr->fd, result, *pend);
++
++            return result;
++#else
++            return NXTransReadable(ciptr->fd, (int *) pend);
++#endif
++        }
++    }
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+ #if defined(QNX4)
+     *pend = 0L; /* FIONREAD only returns a short. Zero out upper bits */
+ #endif
+@@ -2128,6 +2892,41 @@
+ {
+     PRMSG (2,"SocketRead(%d,%p,%d)\n", ciptr->fd, buf, size);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    /*
++     * If we have a valid priv pointer then this
++     * is an internal connection to the proxy.
++     * In this case we should emulate the read.
++     */
++
++    if (ciptr->priv)
++    {
++        int result;
++
++        result = NXTransRead(ciptr->fd, buf, size);
++
++#ifdef NX_TRANS_DEBUG
++        if (result < 0 && EGET() == EAGAIN)
++        {
++            fprintf(stderr, "SocketRead: Read from descriptor [%d] would block.\n",
++                     ciptr->fd);
++        }
++        else
++        {
++            fprintf(stderr, "SocketRead: Read [%d] bytes from descriptor [%d].\n",
++                     result, ciptr->fd);
++        }
++#endif
++        return result;
++    }
++    else
++    {
++        return read (ciptr->fd, buf, size);
++    }
++
++#else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+ #if defined(WIN32) || defined(__UNIXOS2__)
+     {
+ 	int ret = recv ((SOCKET)ciptr->fd, buf, size, 0);
+@@ -2139,6 +2938,8 @@
+ #else
+     return read (ciptr->fd, buf, size);
+ #endif /* WIN32 */
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
+ }
+ 
+ 
+@@ -2148,6 +2949,41 @@
+ {
+     PRMSG (2,"SocketWrite(%d,%p,%d)\n", ciptr->fd, buf, size);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    /*
++     * If we have a valid priv pointer then this
++     * is an internal connection to the proxy.
++     * In this case we should emulate the write.
++     */
++
++    if (ciptr->priv)
++    {
++        int result;
++
++        result = NXTransWrite(ciptr->fd, buf, size);
++
++#ifdef NX_TRANS_DEBUG
++        if (result < 0 && EGET() == EAGAIN)
++        {
++            fprintf(stderr, "SocketWrite: Write on descriptor [%d] would block.\n",
++                     ciptr->fd);
++        }
++        else
++        {
++            fprintf(stderr, "SocketWrite: Written [%d] bytes on descriptor [%d].\n",
++                     result, ciptr->fd);
++        }
++#endif
++        return result;
++    }
++    else
++    {
++        return write (ciptr->fd, buf, size);
++    }
++
++#else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+ #if defined(WIN32) || defined(__UNIXOS2__)
+     {
+ 	int ret = send ((SOCKET)ciptr->fd, buf, size, 0);
+@@ -2159,6 +2995,8 @@
+ #else
+     return write (ciptr->fd, buf, size);
+ #endif /* WIN32 */
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
+ }
+ 
+ 
+@@ -2168,7 +3006,28 @@
+ {
+     PRMSG (2,"SocketReadv(%d,%p,%d)\n", ciptr->fd, buf, size);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    /*
++     * If we have a valid priv pointer then this
++     * is an internal connection to the proxy.
++     * In this case we should emulate the readv.
++     */
++
++    if (ciptr->priv)
++    {
++        return NXTransReadVector(ciptr->fd, buf, size);
++    }
++    else
++    {
++        return READV (ciptr, buf, size);
++    }
++
++#else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+     return READV (ciptr, buf, size);
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
+ }
+ 
+ 
+@@ -2178,7 +3037,28 @@
+ {
+     PRMSG (2,"SocketWritev(%d,%p,%d)\n", ciptr->fd, buf, size);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    /*
++     * If we have a valid priv pointer then this
++     * is an internal connection to the proxy.
++     * In this case we should emulate the writev.
++     */
++
++    if (ciptr->priv)
++    {
++        return NXTransWriteVector(ciptr->fd, buf, size);
++    }
++    else
++    {
++        return WRITEV (ciptr, buf, size);
++    }
++
++#else /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
++
+     return WRITEV (ciptr, buf, size);
++
++#endif /* #if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT) */
+ }
+ 
+ 
+@@ -2234,17 +3114,41 @@
+     struct sockaddr_un	*sockname = (struct sockaddr_un *) ciptr->addr;
+     int ret;
+ 
+-    PRMSG (2,"SocketUNIXClose(%p,%d)\n", ciptr, ciptr->fd, 0);
++    PRMSG (2,"SocketUNIXClose(%x,%d)\n", ciptr, ciptr->fd, 0);
++
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    if (ciptr->priv)
++    {
++        TRANS(SocketCloseConnInfo) (ciptr);
++    }
++
++#endif
+ 
+     ret = close(ciptr->fd);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "SocketUNIXClose: Flags are [%d] for ciptr at [%p] check is [%d].\n",
++                ciptr->flags, (void *) ciptr, (ciptr->flags && sockname
++                    && sockname->sun_family == AF_UNIX && sockname->sun_path[0]));
++#endif
++
+     if (ciptr->flags
+        && sockname
+        && sockname->sun_family == AF_UNIX
+        && sockname->sun_path[0])
+     {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++        if (!(ciptr->flags & TRANS_NOUNLINK))
++        {
++                fprintf(stderr, "SocketUNIXClose: Unlinking path [%s] for ciptr at [%p].\n",
++                            sockname->sun_path, (void *) ciptr);
++                unlink (sockname->sun_path);
++        }
++#else
+ 	if (!(ciptr->flags & TRANS_NOUNLINK))
+ 		unlink (sockname->sun_path);
++#endif
+     }
+ 
+     return ret;
+@@ -2263,6 +3167,15 @@
+     PRMSG (2,"SocketUNIXCloseForCloning(%p,%d)\n",
+ 	ciptr, ciptr->fd, 0);
+ 
++#if defined(NX_TRANS_SOCKET) && defined(TRANS_CLIENT)
++
++    if (ciptr->priv)
++    {
++        TRANS(SocketCloseConnInfo) (ciptr);
++    }
++
++#endif
++
+     ret = close(ciptr->fd);
+ 
+     return ret;
diff --git a/doc/nx-X11_vs_XOrg69_patches/auth.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/auth.c.NX.patch
new file mode 100644
index 0000000..d7549c4
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/auth.c.NX.patch
@@ -0,0 +1,271 @@
+--- ./nx-X11/programs/Xserver/os/auth.c.X.original	2015-02-13 14:03:44.788440645 +0100
++++ ./nx-X11/programs/Xserver/os/auth.c	2015-02-10 19:13:13.452699065 +0100
+@@ -28,6 +28,23 @@
+ */
+ /* $XFree86: auth.c,v 1.13 2003/04/27 21:31:08 herrb Exp $ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /*
+  * authorization hooks for the server
+  * Author:  Keith Packard, MIT X Consortium
+@@ -129,7 +146,24 @@
+ void
+ InitAuthorization (char *file_name)
+ {
++#ifdef __sun 
++    char * envBuffer;
++#endif
+     authorization_file = file_name;
++#ifdef NX_TRANS_AUTH
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "InitAuthorization: Going to propagate auth file '%s' to the environment.\n",
++                authorization_file);
++#endif
++#ifdef __sun 
++    envBuffer = malloc(15+strlen(authorization_file));
++    sprintf(envBuffer,"NX_XAUTHORITY=%s",authorization_file);
++    putenv(envBuffer);
++#else
++    setenv("NX_XAUTHORITY", authorization_file, 1);
++#endif
++#endif
++
+ }
+ 
+ static int
+@@ -144,6 +178,68 @@
+     if (!authorization_file)
+ 	return 0;
+ 
++#ifdef NX_TRANS_AUTH
++
++    /*
++     * We think that the way LoadAuthorization() is working is wrong.
++     * It doesn't reset the list of stored authorizations before reading
++     * the new cookies. Our take is that if a new auth file is to be
++     * read, the only cookies that are to be accepted are those that are
++     * in the new file, not those in the file -plus- those that have
++     * been in the file in the past. Furthermore, if the list can't be
++     * read or it is empty, it should assume that it ignores which co-
++     * okies are valid and thus it should disable any access. Your mile-
++     * age can vary. A less draconian approach could be to leave the old
++     * cookies if the file can't be read and remove them only if the
++     * file is empty.
++     *
++     * Adding the cookies without removing the old values for the same
++     * protocol has an important implication. If an user shares the co-
++     * okie with somebody and later wants to revoke the access to the
++     * display, changing the cookie will not work. This is especially
++     * important with NX. For security reasons, after reconnecting the
++     * session to a different display, it is advisable to generate a
++     * new set of cookies, but doing that it is useless with the current
++     * code, as the old cookies are going to be still accepted. On the
++     * same topic, consider that once an user has got access to the X
++     * server, he/she can freely enable host authentication from any
++     * host, so the safe behaviour should be to reset the host based
++     * authenthication at least at reconnection, and keep as valid only
++     * the cookies that are actually in the file. This behaviour would
++     * surely break many applications, among them a SSH connection run
++     * inside a NX session, as ssh -X reads the cookie for the display
++     * only at session startup and does not read the cookies again
++     * when the auth file is changed.
++     *
++     * Another bug (or feature, depending on how you want to consider
++     * it) is that if the authority file contains entries for different
++     * displays (as it is the norm when the authority file is the default
++     * .Xauthority in the user's home), the server will match -any- of
++     * the cookies, even cookies that are not for its own display. This 
++     * means that you have be careful when passing an authority file to
++     * nxagent or Xnest and maybe keep separate files for letting nxagent
++     * find the cookie to be used to connect to the remote display and
++     * for letting it find what cookies to accept. If the file is the
++     * same, clients will be able to connect to nxagent with both the
++     * cookies.
++     */
++
++#ifdef NX_TRANS_AUTH_RESET
++
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "LoadAuthorization: Resetting authorization info.\n");
++    #endif
++
++    for (i = 0; i < NUM_AUTHORIZATION; i++) {
++        if (protocols[i].Reset) {
++            (*protocols[i].Reset) ();
++        }
++    }
++
++#endif
++
++#endif /* #ifdef NX_TRANS_AUTH */
++
+     f = Fopen (authorization_file, "r");
+     if (!f)
+ 	return -1;
+@@ -154,6 +250,14 @@
+ 		memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
+ 		protocols[i].Add)
+ 	    {
++#ifdef NX_TRANS_AUTH
++
++                #ifdef NX_TRANS_TEST
++                fprintf(stderr, "LoadAuthorization: Adding new record from file [%s].\n",
++                            authorization_file);
++                #endif
++
++#endif
+ 		++count;
+ 		(*protocols[i].Add) (auth->data_length, auth->data,
+ 					 FakeClientID(0));
+@@ -162,7 +266,46 @@
+ 	XauDisposeAuth (auth);
+     }
+ 
++#ifdef NX_TRANS_AUTH
++
++    if (count == 0)
++    {
++      fprintf(stderr, "Warning: No authorization record could be read from file '%s'.\n",
++                  authorization_file);
++
++      fprintf(stderr, "Warning: Please, create a valid authorization cookie using the command\n"
++                  "Warning: 'xauth -f %s add <display> MIT-MAGIC-COOKIE-1 <cookie>'.\n",
++                      authorization_file);
++    }
++
++#endif
++
++#ifdef NX_TRANS_AUTH
++    if (Fclose (f) != 0)
++    {
++        /*
++         * If the Fclose() fails, for example because of a signal,
++         * it's advisable to return the number of protocols read,
++         * if any, or otherwise the server would believe that no
++         * cookie is valid and eventually fall back to host based
++         * authentication. Note anyway that the new code in Check-
++         * Authorization() doesn't care the return value and gives
++         * a chance to the function to check the file at the next
++         * connection.
++         */
++
++        if (count > 0)
++        {
++            return count;
++        }
++        else
++        {
++            return -1;
++        }
++    }
++#else
+     Fclose (f);
++#endif
+     return count;
+ }
+ 
+@@ -194,7 +337,10 @@
+     int	i;
+     struct stat buf;
+     static time_t lastmod = 0;
++
++    #ifndef NX_TRANS_AUTH
+     static Bool loaded = FALSE;
++    #endif
+ 
+     if (!authorization_file || stat(authorization_file, &buf))
+     {
+@@ -225,7 +371,67 @@
+ 	 * entries for this server), and reloading it later fails, don't
+ 	 * change anything. (loadauth == -1 && loaded)
+ 	 */
+-	
++
++#ifdef NX_TRANS_AUTH
++
++        /*
++         * The implementation of CheckAuthorization() was changed. The way
++         * the auth file was handled previously was questionable and could
++         * open the way to a vast array of security problems. There might be
++         * ways for an attacker to prevent the server from reading the file
++         * and it was enough for the server to fail reading the file once
++         * (because of a not blocked signal, for example) to leave the dis-
++         * play open to all the users running a session on the same terminal
++         * server.
++         *
++         * In NX we want to have only two cases: either we have to check an
++         * authorization file or we don't. In the first case we need to do our
++         * best to read the file at any new client access and never fall back
++         * to host based authentication. Falling back to local host access has
++         * no way back, as it will always take precedence over the auth cookie
++         * (unless the user explicitly disables, one by one, all the rules
++         * allowing local access, if and only if he/she becomes aware of the
++         * problem). In the second case we assume that user doesn't care secu-
++         * rity and so allow unrestricted access from the local machine.
++         */
++
++        #ifdef NX_TRANS_TEST
++        fprintf(stderr, "CheckAuthorization: Going to set authorization with loadauth [%d].\n",
++                    loadauth);
++        #endif
++
++        if (authorization_file)
++        {
++            #ifdef NX_TRANS_TEST
++            fprintf(stderr, "CheckAuthorization: Disabling local host access.\n");
++            #endif
++
++            DisableLocalHost();
++        }
++        else
++        {
++            /*
++             * Enable host-based authentication only if
++             * the authorization file was not specified
++             * either on the command line or in the env-
++             * ironment.
++             */
++
++            #ifdef NX_TRANS_TEST
++            fprintf(stderr, "CheckAuthorization: Enabling local host access.\n");
++            #endif
++
++            EnableLocalHost();
++        }
++
++        /*
++         * Avoid the 'unused variable' warning.
++         */
++
++        loadauth = loadauth;
++
++#else /* #ifdef NX_TRANS_AUTH */
++
+ 	if (loadauth > 0)
+ 	{
+ 	    DisableLocalHost(); /* got at least one */
+@@ -233,6 +439,8 @@
+ 	}
+ 	else if (loadauth == 0 || !loaded)
+ 	    EnableLocalHost ();
++
++#endif /* #ifdef NX_TRANS_AUTH */
+     }
+     if (name_length) {
+ 	for (i = 0; i < NUM_AUTHORIZATION; i++) {
diff --git a/doc/nx-X11_vs_XOrg69_patches/charproc.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/charproc.c.NX.patch
new file mode 100644
index 0000000..ecd0f67
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/charproc.c.NX.patch
@@ -0,0 +1,40 @@
+--- ./nx-X11/programs/xterm/charproc.c.X.original	2015-02-13 14:03:44.800440409 +0100
++++ ./nx-X11/programs/xterm/charproc.c	2015-02-13 14:03:44.796440488 +0100
+@@ -82,6 +82,23 @@
+  * SOFTWARE.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* charproc.c */
+ 
+ #include <version.h>
+@@ -3177,6 +3194,13 @@
+ 	}
+ 	if (need_cleanup)
+ 	    Cleanup(0);
++
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "xterm::in_put: Select called with [%d][%p][%p][%p][%p].\n",
++                max_plus1, (void *) &select_mask, (void *) &write_mask, (void *) 0,
++                    (void *) (time_select ? &select_timeout : 0));
++#endif
++
+ 	i = Select(max_plus1, &select_mask, &write_mask, 0,
+ 		   (time_select ? &select_timeout : 0));
+ 	if (i < 0) {
diff --git a/doc/nx-X11_vs_XOrg69_patches/cmsProp.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/cmsProp.c.NX.patch
new file mode 100644
index 0000000..c929125
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/cmsProp.c.NX.patch
@@ -0,0 +1,14 @@
+--- ./nx-X11/lib/X11/cmsProp.c.X.original	2015-02-13 14:03:44.624443872 +0100
++++ ./nx-X11/lib/X11/cmsProp.c	2015-02-10 19:13:12.948717938 +0100
+@@ -121,7 +121,11 @@
+     char *prop_ret;
+     int format_ret;
+     long len = 6516;
++    #ifdef NXAGENT_SERVER
++    unsigned long nitems_ret, after_ret = 0;
++    #else
+     unsigned long nitems_ret, after_ret;
++    #endif
+     Atom atom_ret;
+     
+     while (XGetWindowProperty (pDpy, w, property, 0, len, False, 
diff --git a/doc/nx-X11_vs_XOrg69_patches/connection.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/connection.c.NX.patch
new file mode 100644
index 0000000..f25c016
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/connection.c.NX.patch
@@ -0,0 +1,48 @@
+--- ./nx-X11/programs/Xserver/os/connection.c.X.original	2015-02-13 14:03:44.788440645 +0100
++++ ./nx-X11/programs/Xserver/os/connection.c	2015-02-10 19:13:13.452699065 +0100
+@@ -486,6 +486,45 @@
+ #endif
+ }
+ 
++#ifdef NX_TRANS_SOCKET
++
++/*
++ * The following block is now defined also
++ * under Cygwin to support this environment.
++ */
++
++#ifndef __DARWIN__
++
++/*
++ * This is defined in Xtranssock.c and must
++ * be called explicitly as it doesn't share
++ * a pointer in the transport function table.
++ */
++
++extern void _XSERVTransSocketRejectConnection(XtransConnInfo);
++
++void
++RejectWellKnownSockets ()
++{
++    int i;
++
++    for (i = 0; i < ListenTransCount; i++)
++    {
++        _XSERVTransSocketRejectConnection(ListenTransConns[i]);
++    }
++}
++
++#endif /* #ifndef __DARWIN__ */
++
++#else /* #ifdef NX_TRANS_SOCKET */
++
++void
++RejectWellKnownSockets ()
++{
++}
++
++#endif /* #ifdef NX_TRANS_SOCKET */
++
+ void
+ ResetWellKnownSockets (void)
+ {
diff --git a/doc/nx-X11_vs_XOrg69_patches/context.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/context.c.NX.patch
new file mode 100644
index 0000000..92dedfc
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/context.c.NX.patch
@@ -0,0 +1,103 @@
+--- ./nx-X11/extras/Mesa/src/mesa/main/context.c.X.original	2015-02-13 14:03:44.464447019 +0100
++++ ./nx-X11/extras/Mesa/src/mesa/main/context.c	2015-02-10 19:13:14.800648672 +0100
+@@ -131,6 +131,10 @@
+ #endif
+ #include "shaderobjects.h"
+ 
++#ifdef NXAGENT_SERVER
++#include "WSDrawBuffer.h"
++#endif
++
+ #ifdef USE_SPARC_ASM
+ #include "sparc/sparc.h"
+ #endif
+@@ -143,6 +147,47 @@
+ int MESA_DEBUG_FLAGS = 0;
+ #endif
+ 
++#ifdef NXAGENT_SERVER
++extern WSDrawBufferPtr pWSDrawBuffer;
++
++int IsWSDrawBuffer(GLframebuffer *mesa_buffer)
++{
++  WSDrawBufferPtr p = pWSDrawBuffer;
++
++  while (p != NULL) {
++    if (p -> DrawBuffer == mesa_buffer) {
++      return 1;
++    }
++    p = p -> next;
++  }
++  return 0;
++}
++
++void FreeWSDrawBuffer(GLframebuffer *mesa_buffer)
++{
++  WSDrawBufferPtr p = pWSDrawBuffer;
++  WSDrawBufferPtr pOld = NULL;
++
++  if (p == NULL)
++    return;
++
++  if (p -> DrawBuffer == mesa_buffer) {
++    pWSDrawBuffer = p -> next;
++    free(p);
++    return;
++  }
++
++  while (p -> next != NULL) {
++    if (p -> next -> DrawBuffer == mesa_buffer) {
++      pOld = p -> next;
++      p -> next = p -> next -> next;
++      free(pOld);
++      return;
++    }
++    p = p -> next;
++  }
++}
++#endif
+ 
+ /* ubyte -> float conversion */
+ GLfloat _mesa_ubyte_to_float_color_tab[256];
+@@ -1520,6 +1565,10 @@
+ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
+                     GLframebuffer *readBuffer )
+ {
++   #ifdef NXAGENT_SERVER
++   int flag;
++   #endif
++
+    if (MESA_VERBOSE & VERBOSE_API)
+       _mesa_debug(newCtx, "_mesa_make_current()\n");
+ 
+@@ -1558,11 +1607,30 @@
+          ASSERT(readBuffer->Name == 0);
+          newCtx->WinSysDrawBuffer = drawBuffer;
+          newCtx->WinSysReadBuffer = readBuffer;
++
++#ifdef NXAGENT_SERVER
++         flag = 0;
++         if (newCtx->DrawBuffer) {
++           if (!IsWSDrawBuffer(newCtx->DrawBuffer)) {
++             if (newCtx->DrawBuffer->Name == 0) {
++               flag = 1;
++             }
++             FreeWSDrawBuffer(newCtx->DrawBuffer);
++           }
++           else flag = 1;
++         }
++
++         if (!newCtx->DrawBuffer || flag) {
++           newCtx->DrawBuffer = drawBuffer;
++           newCtx->ReadBuffer = readBuffer;
++         }
++#else
+          /* don't replace user-buffer bindings with window system buffer */
+          if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
+             newCtx->DrawBuffer = drawBuffer;
+             newCtx->ReadBuffer = readBuffer;
+          }
++#endif
+ 
+ 	 newCtx->NewState |= _NEW_BUFFERS;
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/cross.def.NX.patch b/doc/nx-X11_vs_XOrg69_patches/cross.def.NX.patch
new file mode 100644
index 0000000..907c5c8
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/cross.def.NX.patch
@@ -0,0 +1,33 @@
+--- ./nx-X11/config/cf/cross.def.X.original	2015-02-13 14:03:44.396448342 +0100
++++ ./nx-X11/config/cf/cross.def	2015-02-10 19:13:13.392701311 +0100
+@@ -16,16 +16,16 @@
+ #define StandardDefines 	-Dlinux -D__arm__ -D_POSIX_SOURCE \
+ 				-D_BSD_SOURCE -D_GNU_SOURCE -DX_LOCALE
+ #undef CcCmd
+-#define StdIncDir /skiff/local/arm-linux/include
++#define StdIncDir /opt/Embedix/tools/arm-linux/include
+ #define PreIncDir 
+ #undef PostIncDir
+-#define PostIncDir /skiff/local/lib/gcc-lib/arm-linux/2.95.2/include
+-#define CcCmd /skiff/local/bin/arm-linux-gcc
++#define PostIncDir /opt/Embedix/tools/lib/gcc-lib/arm-linux/2.95.2/include
++#define CcCmd /opt/Embedix/tools/bin/arm-linux-gcc
+ #undef CplusplusCmd
+ #define HasCplusplus YES
+-#define CplusplusCmd /skiff/local/bin/arm-linux-g++
++#define CplusplusCmd /opt/Embedix/tools/bin/arm-linux-g++
+ #define DoRanlibCmd YES
+-#define RanlibCmd /skiff/local/bin/arm-linux-ranlib
++#define RanlibCmd /opt/Embedix/tools/bin/arm-linux-ranlib
+ #undef ExtraLoadFlags
+ #define ExtraLoadFlags
+ #define FbNoPixelAddrCode
+@@ -33,7 +33,7 @@
+ #define TermcapLibrary -ltermcap
+ 
+ #undef LdPostLib
+-#define LdPostLib	-L/skiff/local/arm-linux/lib
++#define LdPostLib	-L/opt/Embedix/tools/arm-linux/lib
+ 
+ #undef ExtensionOSDefines
+ #define ExtensionOSDefines
diff --git a/doc/nx-X11_vs_XOrg69_patches/cursor.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/cursor.c.NX.patch
new file mode 100644
index 0000000..faf2421
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/cursor.c.NX.patch
@@ -0,0 +1,12 @@
+--- ./nx-X11/programs/Xserver/xfixes/cursor.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/xfixes/cursor.c	2015-02-10 19:13:13.508696968 +0100
+@@ -96,7 +96,8 @@
+ 	CursorCurrent = pCursor;
+ 	for (e = cursorEvents; e; e = e->next)
+ 	{
+-	    if (e->eventMask & XFixesDisplayCursorNotifyMask)
++	    if ((e->eventMask & XFixesDisplayCursorNotifyMask) &&
++		!e->pClient->clientGone)
+ 	    {
+ 		xXFixesCursorNotifyEvent	ev;
+ 		ev.type = XFixesEventBase + XFixesCursorNotify;
diff --git a/doc/nx-X11_vs_XOrg69_patches/ddxKillSrv.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/ddxKillSrv.c.NX.patch
new file mode 100644
index 0000000..a6acd7c
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/ddxKillSrv.c.NX.patch
@@ -0,0 +1,21 @@
+--- ./nx-X11/programs/Xserver/xkb/ddxKillSrv.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/xkb/ddxKillSrv.c	2015-02-10 19:13:13.736688433 +0100
+@@ -52,10 +52,18 @@
+ int
+ XkbDDXTerminateServer(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+ {
++#ifdef NXAGENT_SERVER
++
++    return 0;
++
++#else
++
+ #ifdef XF86DDXACTIONS
+     xf86ProcessActionEvent(ACTION_TERMINATE, NULL);
+ #else
+     GiveUp(1);
+ #endif
+     return 0;
++
++#endif /* NXAGENT_SERVER */
+ }
diff --git a/doc/nx-X11_vs_XOrg69_patches/ddxLoad.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/ddxLoad.c.NX.patch
new file mode 100644
index 0000000..3c2eda4
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/ddxLoad.c.NX.patch
@@ -0,0 +1,443 @@
+--- ./nx-X11/programs/Xserver/xkb/ddxLoad.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/xkb/ddxLoad.c	2015-02-13 14:03:44.792440567 +0100
+@@ -34,6 +34,7 @@
+ #include <xkb-config.h>
+ #endif
+ 
++#include <errno.h>
+ #include <stdio.h>
+ #include <ctype.h>
+ #define	NEED_EVENTS 1
+@@ -175,6 +176,310 @@
+ # endif
+ #endif
+ 
++#ifdef NXAGENT_SERVER
++
++#define NX_XKB_BASE_DIRECTORY            "/usr/lib/X11/xkb"
++#define NX_XKB_ALTERNATE_BASE_DIRECTORY  "/usr/share/X11/xkb"
++#define NX_KEYMAP_DIR_FILE               "keymap.dir"
++#define NX_ALT_XKBCOMP_PATH              "/usr/bin"
++
++static char _NXXkbBasePath[PATH_MAX];
++static char _NXXkbCompPath[PATH_MAX];
++
++static int NXVerifyXkbBaseDirectory(const char *dirPath)
++{
++  int size;
++  char *keymapDirFilePath;
++  struct stat keymapDirFileStat;
++
++  /*
++   * If keymap.dir file
++   * is not present into
++   * Xkb Base Directory,
++   * we suppose that the
++   * path is not valid.
++   */
++
++  size = strlen(dirPath) + strlen("/") +
++             strlen(NX_KEYMAP_DIR_FILE) + 1;
++
++  if ((keymapDirFilePath = malloc((size + 1) * sizeof(char))) == NULL)
++  {
++    FatalError("NXVerifyXkbBaseDirectory: malloc failed.\n");
++  }
++
++  strcpy(keymapDirFilePath, dirPath);
++  strcat(keymapDirFilePath, "/");
++  strcat(keymapDirFilePath, NX_KEYMAP_DIR_FILE);
++
++  #ifdef TEST
++  fprintf(stderr, "NXVerifyXkbBaseDirectory: Looking for [%s] file.\n",
++              keymapDirFilePath);
++  #endif
++
++  if (stat(keymapDirFilePath, &keymapDirFileStat) != 0)
++  {
++
++    #ifdef TEST
++    fprintf(stderr, "NXVerifyXkbBaseDirectory: Can't find the keymap.dir file [%s].\n",
++                keymapDirFilePath);
++    #endif
++
++    free(keymapDirFilePath);
++
++    return 0;
++  }
++
++  #ifdef TEST
++  fprintf(stderr, "NXVerifyXkbBaseDirectory: Xkb Base Directory [%s] is valid.\n",
++              dirPath);
++  #endif
++
++  free(keymapDirFilePath);
++
++  return 1;
++}
++
++/*
++ * This function returns the directory
++ * containing the configuration files.
++ * This directory is referred by Xkb-
++ * BaseDirectory variable (generally
++ * it contains the hardcoded path at
++ * compile time). If the directory
++ * does not exist, the function will
++ * try a set of well known directories.
++ */
++
++char *_NXGetXkbBasePath(const char *path)
++{
++  /*
++   * Check the xkb base directory only once.
++   */
++
++  if (*_NXXkbBasePath != '\0')
++  {
++    return _NXXkbBasePath;
++  }
++ 
++  if (NXVerifyXkbBaseDirectory(XkbBaseDirectory) == 1)
++  {
++    if (strlen(XkbBaseDirectory) + 1 > PATH_MAX)
++    {
++      #ifdef TEST
++      fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
++      #endif
++ 
++      goto _NXGetXkbBasePathError;
++    }
++
++    strcpy(_NXXkbBasePath, XkbBaseDirectory);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n",
++                _NXXkbBasePath);
++    #endif
++
++    return _NXXkbBasePath;
++  }
++ 
++  if (NXVerifyXkbBaseDirectory(NX_XKB_BASE_DIRECTORY) == 1)
++  {
++    if (strlen(NX_XKB_BASE_DIRECTORY) + 1 > PATH_MAX)
++    {
++      #ifdef TEST
++      fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
++      #endif
++
++      goto _NXGetXkbBasePathError;
++    }
++
++    strcpy(_NXXkbBasePath, NX_XKB_BASE_DIRECTORY);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n",
++                _NXXkbBasePath);
++    #endif
++
++    return _NXXkbBasePath;
++  }
++
++  if (NXVerifyXkbBaseDirectory(NX_XKB_ALTERNATE_BASE_DIRECTORY) == 1)
++  {
++    if (strlen(NX_XKB_ALTERNATE_BASE_DIRECTORY) + 1 > PATH_MAX)
++    {
++      #ifdef TEST
++      fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
++      #endif
++
++      goto _NXGetXkbBasePathError;
++    }
++
++    strcpy(_NXXkbBasePath, NX_XKB_ALTERNATE_BASE_DIRECTORY);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbBasePath: Using NX xkb base directory path [%s].\n",
++                _NXXkbBasePath);
++    #endif
++
++    return _NXXkbBasePath;
++  }
++
++_NXGetXkbBasePathError:
++
++  if (strlen(path) + 1 > PATH_MAX)
++  {
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbBasePath: WARNING! Maximum length of xkb base path exceeded.\n");
++    #endif
++  }
++
++  strcpy(_NXXkbBasePath, path);
++
++  #ifdef TEST
++  fprintf(stderr, "_NXGetXkbBasePath: Using default xkb base path [%s].\n",
++              _NXXkbBasePath);
++  #endif
++
++  return _NXXkbBasePath;
++}
++
++static int NXVerifyXkbCompPath(char *path)
++{
++  char *xkbCompPath;
++  int xkbCompPathSize;
++  struct stat xkbCompPathStat;
++
++  if (path == NULL)
++  {
++    return 0;
++  }
++
++  xkbCompPathSize = strlen(path) + strlen("/") +
++                        strlen("xkbcomp") + 1;
++
++  if ((xkbCompPath = malloc((xkbCompPathSize + 1) * sizeof(char))) == NULL)
++  {
++    FatalError("NXVerifyXkbCompPath: WARNING! malloc failed.\n");
++
++    return 0;
++  }
++
++  strcpy(xkbCompPath, path);
++  strcat(xkbCompPath, "/");
++  strcat(xkbCompPath, "xkbcomp");
++
++  if (stat(xkbCompPath, &xkbCompPathStat) != 0)
++  {
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "NXVerifyXkbCompPath: WARNING! Failed to stat xkbcomp path [%s].\n",
++                xkbCompPath);
++    #endif
++
++    free(xkbCompPath);
++
++    return 0;
++  }
++
++  free(xkbCompPath);
++
++  return 1;
++}
++
++/*
++ * This function returns the directory
++ * containing the xkbcomp executable.
++ * The function will first try to locate
++ * the executable in the hardcoded path
++ * (the same path as the "base" xkb one)
++ * and, if the xkbcomp file couldn't be
++ * found, the function will not include
++ * an explicit path and will rely on the
++ * PATH environment to list the directory.
++ */
++
++char *_NXGetXkbCompPath(const char *path)
++{
++
++  char * xkbCompPath;
++
++  /*
++   * Check the xkbcomp executable
++   * directory only once.
++   */
++
++  if (*_NXXkbCompPath != '\0')
++  {
++    return _NXXkbCompPath;
++  }
++
++  xkbCompPath = _NXGetXkbBasePath(path);
++
++  if (NXVerifyXkbCompPath(xkbCompPath) == 1)
++  {
++    if (strlen(xkbCompPath) + 1 > PATH_MAX)
++    {
++      #ifdef TEST
++      fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n");
++      #endif
++
++      goto _NXGetXkbCompPathError;
++    }
++
++    strcpy(_NXXkbCompPath, xkbCompPath);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbCompPath: Using xkbcomp path [%s].\n",
++                _NXXkbCompPath);
++    #endif
++
++    return _NXXkbCompPath;
++  }
++
++  xkbCompPath = NX_ALT_XKBCOMP_PATH;
++
++  if (NXVerifyXkbCompPath(xkbCompPath) == 1)
++  {
++    if (strlen(xkbCompPath) + 1 > PATH_MAX)
++    {
++      #ifdef TEST
++      fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n");
++      #endif
++
++      goto _NXGetXkbCompPathError;
++    }
++
++    strcpy(_NXXkbCompPath, xkbCompPath);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbCompPath: Using NX xkbcomp path [%s].\n",
++                _NXXkbCompPath);
++    #endif
++
++    return _NXXkbCompPath;
++  }
++
++_NXGetXkbCompPathError:
++
++  if (strlen(path) + 1 > PATH_MAX)
++  {
++    #ifdef TEST
++    fprintf(stderr, "_NXGetXkbCompPath: WARNING! Maximum length of xkbcomp path exceeded.\n");
++    #endif
++  }
++
++  strcpy(_NXXkbCompPath, path);
++
++  #ifdef TEST
++  fprintf(stderr, "_NXGetXkbCompPath: Using default xkbcomp path [%s].\n",
++              _NXXkbCompPath);
++  #endif
++
++  return _NXXkbCompPath;
++}
++
++#endif
++
+ static void
+ OutputDirectory(
+     char* outdir,
+@@ -240,14 +545,36 @@
+     XkbEnsureSafeMapName(outFile);
+     OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
+ 
++#ifdef NXAGENT_SERVER
++
++    if (_NXGetXkbCompPath(XkbBaseDirectory) != NULL)
++    {
++
++#else
++
+     if (XkbBaseDirectory!=NULL) {
++
++#endif
++
+ #ifndef __UNIXOS2__
++
++#ifdef NXAGENT_SERVER
++        char *xkbbasedir = _NXGetXkbBasePath(XkbBaseDirectory);
++        char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory);
++#else
+         char *xkbbasedir = XkbBaseDirectory;
+         char *xkbbindir = XkbBinDirectory;
++#endif
++
+ #else
+         /* relocate the basedir and replace the slashes with backslashes */
++#ifdef NXAGENT_SERVER
++        char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbBasePath(XkbBaseDirectory));
++        char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory));
++#else
+         char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory);
+         char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory);
++#endif
+         int i;
+ 
+ 	for (i=0; i<strlen(xkbbasedir); i++) 
+@@ -332,7 +659,13 @@
+     strcat(tmpname, "\\xkb_XXXXXX");
+     (void) mktemp(tmpname);
+ #endif
++
++#ifdef NXAGENT_SERVER
++    if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL) {
++#else
+     if (XkbBaseDirectory!=NULL) {
++#endif
++
+ #ifndef WIN32
+         char *xkmfile = "-";
+ #else
+@@ -341,12 +674,22 @@
+         char *xkmfile = tmpname;
+ #endif
+ #ifndef __UNIXOS2__
++#ifdef NXAGENT_SERVER
++        char *xkbbasedir = _NXGetXkbBasePath(XkbBaseDirectory);
++        char *xkbbindir = _NXGetXkbCompPath(XkbBinDirectory);
++#else
+         char *xkbbasedir = XkbBaseDirectory;
+         char *xkbbindir = XkbBinDirectory;
++#endif
+ #else
+         int i;
++#ifdef NXAGENT_SERVER
++        char *xkbbasedir = (char*)__XOS2RedirRoot(_NXGetXkbBasePath(XkbBaseDirectory));
++        char *xkbbindir = (char*)__XOS2RedirRoot(_NXGetXkbCompPath(XkbBinDirectory));
++#else
+         char *xkbbasedir = (char*)__XOS2RedirRoot(XkbBaseDirectory);
+         char *xkbbindir = (char*)__XOS2RedirRoot(XkbBinDirectory);
++#endif
+ 	for (i=0; i<strlen(xkbbasedir); i++) 
+             if (xkbbasedir[i]=='/') xkbbasedir[i]='\\';
+ 	for (i=0; i<strlen(xkbbindir); i++) 
+@@ -375,6 +718,15 @@
+ 		xkm_output_dir,keymap);
+     }
+     
++    #ifdef TEST
++    if (buf != NULL)
++        fprintf(stderr, "XkbDDXCompileKeymapByNames: "
++                    "Executing command [%s].\n", buf);
++    else
++        fprintf(stderr, "XkbDDXCompileKeymapByNames: "
++                    "Callin Popen() with null command.\n");
++    #endif
++
+ #ifndef WIN32
+     out= Popen(buf,"w");
+ #else
+@@ -390,7 +742,15 @@
+ #endif
+ 	XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need);
+ #ifndef WIN32
++#ifdef __sun
++        if (Pclose(out) != 0)
++        {
++            ErrorF("Warning: Spurious failure reported in Pclose() runnning 'xkbcomp'.\n");
++        }
++        if (1)
++#else
+ 	if (Pclose(out)==0)
++#endif
+ #else
+ 	if (fclose(out)==0 && System(buf) >= 0)
+ #endif
+@@ -415,9 +775,15 @@
+             {
+ 		int i;
+ 		char name[PATH_MAX];
++#ifdef NXAGENT_SERVER
++                if (_NXGetXkbCompPath(XkbBaseDirectory)!=NULL)
++		    sprintf(name,"%s/%s%s.xkm", _NXGetXkbCompPath(XkbBaseDirectory)
++			,xkm_output_dir, keymap);
++#else
+                 if (XkbBaseDirectory!=NULL)
+ 		    sprintf(name,"%s/%s%s.xkm", XkbBaseDirectory
+ 			,xkm_output_dir, keymap);
++#endif
+ 		else
+                     sprintf(name,"%s%s.xkm", xkm_output_dir, keymap);
+ 		for (i = 0; i < 10; i++) {
diff --git a/doc/nx-X11_vs_XOrg69_patches/dixfonts.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/dixfonts.c.NX.patch
new file mode 100644
index 0000000..1f0cbd4
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/dixfonts.c.NX.patch
@@ -0,0 +1,86 @@
+--- ./nx-X11/programs/Xserver/dix/dixfonts.c.X.original	2015-02-13 14:03:44.704442298 +0100
++++ ./nx-X11/programs/Xserver/dix/dixfonts.c	2015-02-13 14:03:44.704442298 +0100
+@@ -72,6 +72,63 @@
+ #include	<stdio.h>
+ #endif
+ 
++#ifdef NX_TRANS_SOCKET
++
++char _NXFontPath[1024];
++
++/*
++ * Override the default font path and make
++ * it configurable at run time, based on
++ * the NX_FONT environment.
++ */
++
++static const char *_NXGetFontPath(const char *path)
++{
++  const char *fontEnv;
++
++    /*
++     * Check the environment only once.
++     */
++
++    if (*_NXFontPath != '\0')
++    {
++        return _NXFontPath;
++    }
++
++    fontEnv = getenv("NX_FONT");
++
++    if (fontEnv != NULL && *fontEnv != '\0')
++    {
++        if (strlen(fontEnv) + 1 > 1024)
++        {
++#ifdef NX_TRANS_TEST
++            fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
++#endif
++            goto _NXGetFontPathError;
++        }
++
++        strcpy(_NXFontPath, fontEnv);
++
++#ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
++#endif
++
++        return _NXFontPath;
++    }
++
++_NXGetFontPathError:
++
++    strcpy(_NXFontPath, path);
++
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
++#endif
++
++    return _NXFontPath;
++}
++
++#endif
++
+ #ifdef PANORAMIX
+ #include "panoramiX.h"
+ #endif
+@@ -1817,11 +1874,19 @@
+                 bad;
+ 
+     /* get enough for string, plus values -- use up commas */
++#ifdef NX_TRANS_SOCKET
++    len = strlen(_NXGetFontPath(path)) + 1;
++#else
+     len = strlen(path) + 1;
++#endif
+     nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+     if (!newpath)
+ 	return BadAlloc;
++#ifdef NX_TRANS_SOCKET
++    pp = (unsigned char *) _NXGetFontPath(path);
++#else
+     pp = (unsigned char *) path;
++#endif
+     cp++;
+     while (*pp) {
+ 	if (*pp == ',') {
diff --git a/doc/nx-X11_vs_XOrg69_patches/dixstruct.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/dixstruct.h.NX.patch
new file mode 100644
index 0000000..f4bffa9
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/dixstruct.h.NX.patch
@@ -0,0 +1,12 @@
+--- ./nx-X11/programs/Xserver/include/dixstruct.h.X.original	2015-02-13 14:03:44.780440803 +0100
++++ ./nx-X11/programs/Xserver/include/dixstruct.h	2015-02-10 19:13:14.300667345 +0100
+@@ -170,6 +170,9 @@
+ extern Bool SmartScheduleIdle;
+ extern Bool SmartScheduleTimerStopped;
+ extern Bool SmartScheduleStartTimer(void);
++#ifdef NXAGENT_SERVER
++extern Bool SmartScheduleStopTimer(void);
++#endif
+ #define SMART_MAX_PRIORITY  (20)
+ #define SMART_MIN_PRIORITY  (-20)
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/encparse.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/encparse.c.NX.patch
new file mode 100644
index 0000000..116badc
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/encparse.c.NX.patch
@@ -0,0 +1,22 @@
+--- ./nx-X11/lib/font/fontfile/encparse.c.X.original	2015-02-13 14:03:44.668443005 +0100
++++ ./nx-X11/lib/font/fontfile/encparse.c	2015-02-10 19:13:12.336740907 +0100
+@@ -867,8 +867,10 @@
+         if(!strcasecmp(encoding_name, charset)) {
+             /* Found it */
+             if(file_name[0] != '/') {
+-                if(strlen(dir) + strlen(file_name) >= MAXFONTFILENAMELEN)
++                if(strlen(dir) + strlen(file_name) >= MAXFONTFILENAMELEN) {
++		    fclose(file);
+                     return NULL;
++		}
+                 strcpy(buf, dir);
+                 strcat(buf, file_name);
+             } else {
+@@ -877,6 +879,7 @@
+ 
+             f = FontFileOpen(buf);
+             if(f == NULL) {
++		fclose(file);		
+                 return NULL;
+             }
+             encoding = parseEncodingFile(f, 0);
diff --git a/doc/nx-X11_vs_XOrg69_patches/fbtrap.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/fbtrap.c.NX.patch
new file mode 100644
index 0000000..3435261
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/fbtrap.c.NX.patch
@@ -0,0 +1,12 @@
+--- ./nx-X11/programs/Xserver/fb/fbtrap.c.X.original	2015-02-13 14:03:44.704442298 +0100
++++ ./nx-X11/programs/Xserver/fb/fbtrap.c	2015-02-10 19:13:14.156672722 +0100
+@@ -115,6 +115,9 @@
+     RenderEdge	l, r;
+     xFixed	t, b;
+     
++    if (!xTrapezoidValid (trap))
++	return;
++
+     fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);
+ 
+     width = pPicture->pDrawable->width;
diff --git a/doc/nx-X11_vs_XOrg69_patches/glcontextmodes.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/glcontextmodes.c.NX.patch
new file mode 100644
index 0000000..47db91c
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/glcontextmodes.c.NX.patch
@@ -0,0 +1,10 @@
+--- ./nx-X11/extras/Mesa/src/mesa/drivers/dri/common/glcontextmodes.c.X.original	2015-02-13 14:03:44.416447966 +0100
++++ ./nx-X11/extras/Mesa/src/mesa/drivers/dri/common/glcontextmodes.c	2015-02-10 19:13:14.992641502 +0100
+@@ -44,6 +44,7 @@
+ # include "GL/glxint.h"
+ 
+ # ifdef XFree86Server
++void *memset( void * ptr, int val, size_t size);
+ #  include "GL/glx_ansic.h"
+ extern void * __glXMalloc( size_t size );
+ extern void __glXFree( void * ptr );
diff --git a/doc/nx-X11_vs_XOrg69_patches/host.def.NX.patch b/doc/nx-X11_vs_XOrg69_patches/host.def.NX.patch
new file mode 100644
index 0000000..f3454e7
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/host.def.NX.patch
@@ -0,0 +1,1023 @@
+--- ./nx-X11/config/cf/host.def.X.original	2015-02-13 14:03:44.400448260 +0100
++++ ./nx-X11/config/cf/host.def	2015-02-13 14:03:44.400448260 +0100
+@@ -0,0 +1,1020 @@
++XCOMM $XFree86: xc/config/cf/xf86site.def,v 3.186 2003/06/25 18:06:22 eich Exp $
++/******************************************************************************/
++/*
++ * This file is to provide a quick method for most people to change the
++ * behaviour of their Xorg installation without having to fully
++ * understand the workings of site.def and all the various '.cf' files.
++ *
++ * In the vast majority of cases, it should not be necessary to use this
++ * file at all or change it in any way.
++ *
++ * This file is divided into two sections.  The first contains settings
++ * that end-users might reasonably change.  The second contains settings
++ * that developers might want to change.
++ *
++ * IMPORTANT NOTE:  In all cases changing the defaults may cause problems
++ * and/or unexpected side-effects.  If you don't understand what a setting
++ * does, then it's best to not change it.  If you make changes and have
++ * problems, verify that those problems are also present when using an
++ * empty host.def file and unchanged version of this file before reporting
++ * them.
++ *
++ * A good way to use this file is to copy it to host.def, and make the
++ * changes there.  That way, future patches to this file won't fail.
++ * The host.def file will never be patched.
++ *
++ * The distributed version of this file MUST contain no uncommented
++ * definitions.  Default definitions belong in xorg.cf, or <vendor>.cf
++ * files.
++ */
++/******************************************************************************/
++
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
++#if !defined(NXZaurusXServer) && !defined(NXiPAQXServer) && !defined(DarwinArchitecture)
++
++#if defined(SunArchitecture)
++#define ProjectRoot /usr/openwin
++#endif
++
++/*
++ * Enable use the Cygwin IPC libraries to get MIT-SHM support.
++ */
++#if defined(cygwinArchitecture)
++#define UseCygIPC	YES
++#endif
++
++/*
++ * If you have build-specific modifications in your host.def file, but
++ * want an empty host.def file installed when doing 'make install',
++ * uncomment the following
++ *
++#define InstallEmptyHostDef
++ */
++
++/*
++ * Which servers to build.  There is only Xorg server.
++ * It can be disabled by the following.
++ *
++#define XorgServer		NO
++ */
++#define XorgServer		NO
++
++/*
++ * To disable building the Xnest server, uncomment this.
++ *
++#define XnestServer		NO
++ */
++#define XnestServer		NO
++
++/*
++ * To disable building Xvfb, uncomment this.
++ *
++#define XVirtualFramebufferServer	NO
++ */
++#define XVirtualFramebufferServer	NO
++
++/*
++ * To enable building Xdmx, uncomment this.
++ *
++#define XdmxServer YES
++ */
++#define XdmxServer NO
++
++/*
++ * To disable building Xprt, uncomment this.
++ *
++#define XprtServer NO
++ */
++#define XprtServer NO
++
++/*
++ * Xprint is needed by Xprt. You can disable it if
++ * you are not going to build Xprt.
++ *
++#define BuildXprint		NO
++ */
++#define BuildXprint		NO
++
++/*
++ * Building libraries with NX enhancements is disabled
++ * by default. You should enable this in your host.def.
++ *
++#define NXLibraries		YES
++ */
++#define NXLibraries		YES
++
++/*
++ * Building the NX agent nested server is disabled
++ * by default. Enable this in your host.def.
++ *
++#define NXAgentServer		YES
++ */
++#define NXAgentServer		YES
++
++/*
++ * Assume the new build tree.
++ *
++#define NXUpgradeAgentServer	NO
++ */
++#define NXUpgradeAgentServer	YES
++
++#ifdef NXAgentServer
++#define BuildRenderLibrary	YES
++#define SharedLibFreetype2	YES
++#define NormalLibFreetype2	YES
++#define FontLibSharedFreeType 	NO
++#endif
++
++/*
++ * Define this symbol to build the NX enhanced MS Windows
++ * X server for Cygnus environment.
++ *
++#define NXWinServer		YES
++ */
++#if defined(cygwinArchitecture)
++#define NXWinServer             NO
++#define XWinServer              NO
++#endif
++
++/*
++ * Set the default server (ie the one that gets the sym-link to "X")
++ *
++#define ServerToInstall		Xorg
++ */
++
++/*
++ * Force build of X libraries if any nested server is to be built.
++ *
++#define BuildLibraries			YES
++ *
++ * If you just want libraries for NXAgentServer, this should be
++ * enough (never tested, although).
++ *
++#define BuildLibrariesForXServers	YES
++ */
++#if XnestServer || NXAgentServer
++#define BuildLibraries			YES
++#endif
++
++#define BuildDamageLibrary              YES
++
++#define BuildXfixesLibrary              YES
++
++#define BuildCompositeLibrary           YES
++
++#define BuildRandRLibrary               YES
++
++#define BuildDocs                       NO
++
++#define BuildComposite			YES
++
++/*
++ * If you only run the X server under xdm the X servers don't need to be
++ * installed SetUID, and you may comment out the lines below.  If you run
++ * the servers by hand (with xinit or startx), then they do need to be
++ * installed SetUID on most platforms.
++ *
++ * Consult your system administrator before making the X server setuid.
++ *
++#define InstallXserverSetUID	NO
++ */
++
++
++/*
++ * Server configuration parameters.  The defaults are shown here:
++ */
++
++/*
++ * Which drivers to build.  When building a static server, each of these
++ * will be included in it.  When building the loadable server each of these
++ * modules will be built.
++ *
++#define XF86CardDrivers		mga glint nv tga s3virge sis rendition \
++				neomagic i740 tdfx savage \
++				cirrus vmware tseng trident chips apm \
++				GlideDriver fbdev i128 \
++				ati DevelDrivers ark cyrix \
++				siliconmotion \
++				vesa vga XF86OSCardDrivers XF86ExtraCardDrivers
++ */
++
++/*
++ * To add third party drivers to the standard driver list, set the
++ * following.
++ *
++#define XF86ExtraCardDrivers	extradriver1 extradriver2 ...
++ */
++
++/*
++ * Select the XInput devices you want by uncommenting this.
++ *
++#define XInputDrivers		mouse keyboard acecad calcomp citron \
++				digitaledge dmc dynapro elographics \
++				microtouch mutouch penmount spaceorb summa \
++				wacom void magictouch aiptek
++ */
++
++/* To enable building of development DRI drivers (insecure, or not
++ * useful on the chosen architecture, uncomment this define.
++#define BuildDevelDRIDrivers YES
++ */
++
++/*
++ * To use the deprecated, old keyboard driver, uncomment this.  But
++ * even better, make the new keyboard driver (hw/xfree86/input/keyboard)
++ * work for your architechture.  The old driver will be removed in the
++ * next release.
++ *
++#define UseDeprecatedKeyboardDriver YES
++ */
++
++/*
++ * There are three parameters that determine where and how the Matrox HAL
++ * library is used:
++ *
++ *   HaveMatroxHal  -- You have the HALlib.a binary library installed
++ *                     in xfree86/drivers/mga/HALlib, and you want it to
++ *                     be used.
++ *                     Default: NO
++ *
++ *   BuildMatroxHal -- You have the source for the HALlib library (installed
++ *                     in xfree86/drivers/mga/hallib), and want to build and
++ *                     use it.
++ *                     Default: NO
++ *
++ *   UseMatroxHal   -- You want to build support for loading/using the HAL
++ *                     library into the mga driver.  For module server builds
++ *                     you don't need to have the HALlib library to do this.
++ *                     but you want to build support for loading it and using
++ *                     it into the mga driver module.
++ *                     Default: YES for loadable server build
++ *                              (HaveMatroxHal || BuildMatroxHal) for static
++ */
++
++/*
++ * To disable use of the Matrox HAL library, uncomment this:
++ *
++#define UseMatroxHal		NO
++ */
++
++/*
++ * If you have the HALlib.a binary installed in xfree86/drivers/mga/HALlib,
++ * uncomment this:
++ *
++#define HaveMatroxHal		YES
++ */
++
++/*
++ * If you have the HALlib source code installed in xfree86/drivers/mga/hallib,
++ * uncomment this:
++#define BuildMatroxHal		YES
++ */
++
++/*
++ * To disable building the font server, uncomment this.
++ *
++#define BuildFontServer		NO
++ */
++#define BuildFontServer		NO
++
++/*
++ * Speedo fonts have been disabled by default in this release.
++ * To re-enable support for Speedo fonts, uncomment this.
++ *
++#define BuildSpeedo		YES
++ */
++
++/*
++ * To disable support for CID fonts, uncomment this.
++ *
++#define BuildCID		NO
++ */
++
++/*
++ * To disable support for TrueType fonts, uncomment these.
++ *
++#define BuildFreeType		NO
++ */
++
++/*
++ * To set non-default build options for the underlying FreeType libraries,
++ * add them here and uncomment.
++ *
++#define Freetype2BuildDefines	-DFREETYPE_BUILD_DEFINES
++ */
++
++/*
++ * To build the FreeType libraries with the TrueType byte code interpreter
++ * enabled, uncomment this.  Note that there are patent issues related to the
++ * TrueType byte code interpreter, and we only recommend you enabling this
++ * if you are sure that there are no legal impediments to you doing so.  See
++ * <http://www.freetype.org/patents.html> for further information.
++ *
++#define Freetype2BuildDefines -DTT_CONFIG_OPTION_BYTECODE_INTERPRETER
++ */
++
++/*
++ * Do you want to Build Fonts (Usually you only want to build and install
++ * fonts once, if this is a first time install you will want to build the
++ * fonts)
++ *
++#define BuildFonts		NO
++ */
++#define BuildFonts		NO
++
++/*
++ * To not build/install the 75dpi fonts, uncomment the following
++ *
++#define Build75DpiFonts		NO
++ */
++
++/*
++ * To not build/install the 100dpi fonts, uncomment the following
++ *
++#define Build100DpiFonts	NO
++ */
++
++/*
++ * To build/install the Speedo fonts, uncomment the following
++ * (see setting above about Speedo support as well)
++ *
++#define BuildSpeedoFonts	YES
++ */
++
++/*
++ * To not build/install the Type1 fonts, uncomment the following
++ *
++#define BuildType1Fonts		NO
++ */
++
++/*
++ * To not build/install the CID fonts, uncomment the following
++ *
++#define BuildCIDFonts		NO
++ */
++
++/*
++ * To not build/install the True Type fonts, uncomment the following
++ *
++#define BuildTrueTypeFonts	NO
++ */
++
++/*
++ * To not build/install the Cyrillic fonts, uncomment the following
++ *
++#define BuildCyrillicFonts	NO
++ */
++
++/*
++ * To not install the local font directory, uncomment the following
++ *
++#define MakeLocalFontDir	NO
++ */
++
++/*
++ * Include True Type Fonts to default font path. It is safe to do
++ * this by default as NX intaller carries only misc and TTF in the
++ * basic set of fonts installed under Windows.
++ *
++#define DefaultFontPath		$(FONTDIR)/misc/,$(FONTDIR)/Speedo/,$(FONTDIR)/Type1/,$(FONTDIR)/75dpi/,$(FONTDIR)/100dpi/
++ */
++
++#if defined(LinuxArchitecture) || defined(SunArchitecture) || defined(FreeBSDArchitecture)
++#define DefaultFontPath		$(FONTDIR)/misc/,$(FONTDIR)/Speedo/,$(FONTDIR)/Type1/,$(FONTDIR)/75dpi/,$(FONTDIR)/100dpi/,$(FONTDIR)/TTF/
++#endif /* #if defined(LinuxArchitecture) || defined(SunArchitecture) */
++
++#if defined(cygwinArchitecture)
++#define DefaultFontPath		/mnt/NX/fonts/base/,/mnt/NX/fonts/misc/,/mnt/NX/fonts/Speedo/,/mnt/NX/fonts/Type1/,/mnt/NX/fonts/75dpi/,/mnt/NX/fonts/100dpi/,/mnt/NX/fonts/TTF/
++#define DefaultRGBDatabase      /mnt/NX/fonts/rgb
++#endif /* #if defined(cygwinArchitecture) */
++
++/*
++ * To build only the servers with a cut-down source tree, uncomment
++ * this.
++ *
++#define BuildServersOnly	YES
++ */
++#define BuildServersOnly	YES
++
++/*
++ * By default, the sample config files for xinit, xdm and xfs are installed
++ * only when there is no pre-existing version installed.  Uncommenting the
++ * following lines will force the sample versions to be installed even if
++ * it means over-writing existing versions.
++ *
++#define InstallXinitConfig	YES
++#define InstallXdmConfig	YES
++#define InstallFSConfig		YES
++ */
++
++/*
++ * By default the application defaults files are always installed.
++ * Uncommenting the the following will prevent exising application
++ * defaults files from being over-written.
++ *
++#define InstallAppDefFiles	NO
++ */
++
++/*
++ * Undefine the following if you don't want to have config files and
++ * app-defaults installed in a separate directory (i.e. /etc/X11).
++ *
++#define UseSeparateConfDir NO
++ */
++
++/* 
++ * To enable building the glide driver, you need to define 
++ * HasGlide2 to YES and set the Glide2IncDir variable. 
++ * HasGlide2 is per default NO.
++ *
++#define HasGlide2 YES
++ */
++
++/*
++ * Set the path to your Glide include files.
++ *
++#define Glide2IncDir /usr/include/glide
++ */
++
++/* 
++ * Have glide 3?
++ *
++#define HasGlide3 YES
++ */
++
++/*
++ * Set the path to your Glide 3 include files.
++ *
++#define Glide3IncDir /usr/include/glide3
++ */
++
++
++
++/*
++ * Unless you're a developer you shouldn't need to change anything
++ * beyond this point.
++ */
++
++/*
++ * If you want to enable some developer settings, like more verbose
++ * compiler warnings, uncomment this.
++ *
++#define XFree86Devel	YES
++*/
++
++/*
++ * If using GCC 2.x on a system where it isn't the default, uncomment
++ * the following
++ *
++ */
++#if defined(SunArchitecture)
++#define HasGcc2		YES
++#define HasGcc		YES
++#endif
++
++/*
++ * The default optimisation flags for GCC 2.x.  -fno-strength-reduce is
++ * here to work around a bug in -O2 for GCC 2.x on i386 platforms.
++ * If you are using a version that doesn't have this bug, you can
++ * uncomment the following line, and remove '-fno-strength-reduce'
++ * If you are building binaries for a 486, it may be beneficial to add
++ * -m486
++ *
++#define DefaultGcc2i386Opt	-O2 -fno-strength-reduce
++ */
++
++#if defined (LinuxArchitecture)
++#define DefaultGcc2i386Opt      -g -O3
++#endif
++
++/*
++ * Enable all the optimizations on AMD64.
++ */
++
++#define DefaultGcc2AMD64Opt	-g -O3 GccAliasingArgs
++
++/*
++ * This allows the GCC warning flags to be set.  The default is shown here.
++ *
++#define GccWarningOptions -Wall -Wpointer-arith -Wstrict-prototypes \
++                          -Wmissing-prototypes -Wmissing-declarations \
++                          -Wredundant-decls -Wnested-externs
++ */
++
++/* 
++ * Sun Compiler stuff.. 
++ *
++#define HasSunC                         YES
++#define HasSunCplusplus                 YES
++#define CplusplusCompilerMajorVersion   5
++#define CplusplusCompilerMinorVersion   0
++#define CCompilerMajorVersion           5
++#define CCompilerMinorVersion           0
++ */
++
++/*
++ * Optimized Sun Compiler Build.
++ *
++#define DefaultCDebugFlags              -xO4 -xtarget=pentium_pro
++#define OptimizedCDebugFlags            -xO4 -xtarget=pentium_pro
++ */
++
++/* 
++ * Debuggable Sun Compiler Build. 
++ * Note: This builds _EVERYTHING_ as debuggable
++ *
++#define DefaultCDebugFlags              -g -xs
++#define OptimizedCDebugFlags            -g -xs
++ */
++
++/*
++ * For Linux, this should match the Binutils version you have.  This example
++ * is for 2.6.0.7.  See linux.cf for the default setting.
++ *
++ * This should automatically get set correctly by imake.
++ *
++#define LinuxBinUtilsMajorVersion	26
++ */
++
++/*
++ * For Linux, these should match the libc version you have.  This example
++ * is for libc.5.4.x.  See linux.cf for the default setting.
++ *
++ * This should automatically get set correctly by imake.
++ *
++#define LinuxCLibMajorVersion	5
++#define LinuxClibMinorVersion	4
++ */
++
++/*
++ * If you want to use the GNU malloc library, uncomment this
++ *
++#define UseGnuMalloc		YES
++ */
++
++/*
++ * Set this to whatever is required to access the GNU malloc library.
++ * The default is '-lgmalloc' unless is specified in the OS's .cf file.
++ *
++#define GnuMallocLibrary	-L/usr/local/lib -lgmalloc
++ */
++
++/*
++ * To enable the internal Xserver malloc, uncomment this
++ *
++#define UseInternalMalloc	YES
++ */
++
++/*
++ * Some Linux releases don't have a libtermcap.  In this case you may need
++ * to uncomment the following
++ *
++#define TermcapLibrary		-lncurses
++ */
++
++/*
++ * Build a server that dynamically loads the modules by setting
++ * this to YES.  This defaults to YES on most platforms.  A static server
++ * can be built by setting this to NO.
++ *
++#define DoLoadableServer	NO
++ */
++
++/*
++ * This release defaults to building dlopen() style modules instead of the 
++ * previously standard loader modules.
++ * 
++ * Uncomment the following to return to the XFree86 custom loader modules.
++ *
++#define MakeDllModules		NO
++ */
++
++/*
++ * Build XAA.  This can be disabled with:
++ *
++#define XF86XAA			NO
++ */
++
++/*
++ * Build vgahw.  This can be disabled with:
++ *
++#define XF86VgaHw		NO
++ */
++
++/*
++ * Build xf1bpp.  This can be disabled with:
++ *
++#define XF1Bpp			NO
++ */
++
++/*
++ * Build xf4bpp.  This can be disabled with:
++ *
++#define XF4Bpp			NO
++ */
++
++
++/*
++ * BSD Console driver support (for FreeBSD and NetBSD).
++ *
++ * By default, support is included for pccons and pcvt for NetBSD, and
++ * pccons, syscons and pcvt for FreeBSD.
++ *
++ * To change the list of supported drivers, set the following parameter.
++ * Possible values are -DPCCONS_SUPPORT, -DSYSCONS_SUPPORT, -DPCVT_SUPPORT.
++ * The following example includes support for syscons and pcvt only.
++ *
++#define XFree86ConsoleDefines	-DSYSCONS_SUPPORT -DPCVT_SUPPORT
++ */
++
++/*
++ * To link the X server with a dynamic version of the Xfont library,
++ * uncomment this.
++ *
++#define XserverStaticFontLib	NO
++ */
++
++/*
++ * To enable binary compatibility with previous versions of the font
++ * encoding support, uncomment this.
++ *
++#define FontencCompatibility    YES
++ */
++
++/*
++ * To disable building XInput support, uncomment this
++ *
++#define BuildXInputExt		NO
++ */
++#if defined(SunArchitecture)
++#define BuildXInputExt		YES
++#endif
++
++/*
++ * Uncomment this for joystick support.
++ *
++ * Note: Joystick support is broken, so don't enable this.
++ *
++#define JoystickSupport YES
++ */
++
++/*
++ * To disable the ScreenSaver Extension, uncomment this line.
++ *
++#define BuildScreenSaverExt	NO
++ */
++#define BuildScreenSaverExt	NO
++
++/* 
++ * If you don't want to build Xinerama support, uncomment this.
++ *
++#define BuildXinerama		NO
++ */
++#define BuildXinerama		NO
++
++/*
++ * If you don't want to build support for the GLX extension, uncomment this.
++ *
++#define BuildGlxExt             NO
++ */
++#define BuildGlxExt             YES
++
++/*
++ * Taken from xorg.cf.
++ */
++
++#if defined(SparcArchitecture)  \
++   || defined (Sparc64Architecture) \
++   || defined(ia64Architecture) \
++   || defined(s390xArchitecture) \
++   || defined(AMD64Architecture)
++#define GlxExtraDefines -D__GLX_ALIGN64
++#endif
++
++/*
++ * If you want to build the xf86rush extension, uncomment this line.
++ * This isn't recommended.
++ *
++#define BuildXF86RushExt	YES
++ */
++#define BuildXF86RushExt	NO
++
++/*
++ * If you want to build the client library for the xf86rush extension,
++ * uncomment this line.  This isn't recommended.
++ *
++#define BuildXF86RushLibrary	NO
++ */
++#define BuildXF86RushLibrary	NO
++
++/*
++ * We should never need LBX in a NX enabled environment...
++ *
++#define BuildLBX		NO
++ */
++#define BuildLBX		NO
++
++#define BuildXKB		YES
++#define BuildXKBlib		YES
++
++#define SharedLibXau		NO
++
++/*
++ * If you are running NetBSD 0.9C or later, and have the aperture driver
++ * installed, uncomment this.
++ *
++#define HasNetBSDApertureDriver	YES
++ */
++
++/*
++ * If you are running SVR3 and have the mmap driver installed (for linear
++ * framebuffer access) uncomment this.
++ *
++#define HasSVR3mmapDrv	YES
++ */
++
++/*
++ * If you are using an SVR3 (like ISC 4.x) which supports long file names,
++ * you can uncomment this to have manual pages installed under their
++ * full names
++ *
++#define ExpandManNames		YES
++ */
++
++/*
++ * For a POSIXized build on Interactive uncomment this
++ * Could be used with gcc 'till Version 2.6.3
++ * Should be used with gcc 2.7.2. 
++ *
++#define UsePosix		YES
++ */
++
++/*
++ * If you don't want XDMAUTH support (if you don't have Wraphelp.c), 
++ *  comment this out.
++ *
++ */
++#if defined(LinuxArchitecture)
++#define HasXdmAuth		YES
++#endif /* #if defined(LinuxArchitecture) */
++
++/*
++ * If you have Linux DECnet support, and want to build XFree86 with support
++ * for connections over DECnet, uncomment this.
++ *
++#define HasDECnet		YES
++ */
++
++/*
++ * To build static and shared libraries with debugging information, uncomment
++ * this. Assumes you have Gcc2.
++ * (If you don't have Gcc2, you can use the DebugLib{X11,Xt,Xaw,...} variables
++ * to build debugging versions of the libraries separately.)
++ *
++#define DebuggableLibraries	YES
++*/
++#if defined(LinuxArchitecture)
++#define DebuggableLibraries	YES
++#endif /* #if defined(LinuxArchitecture) */
++/*
++ * To forceably build static libraries in addition to shared libraries,
++ * uncomment this.
++ *
++#define ForceNormalLib		YES
++ */
++
++/*
++ * Uncomment this if your default tools (eg, gcc, ld, as, etc) are
++ * not the Linux ELF versions.
++ *
++#define LinuxElfDefault		NO
++ */
++
++/*
++ * To use ELF format shared libraries for supported OSs, uncomment this.
++ *
++ * For Linux the default setting of this is the same as the setting of
++ * LinuxElfDefault.
++ *
++ * For FreeBSD this should automatically be set correctly by imake.  Only
++ * change it here if you need to override the automatic setting.
++ *
++#define UseElfFormat		YES
++ */
++
++/*
++ * For FreeBSD/ELF (FreeBSD 3.0) it is possible to also build and install
++ * a.out compatibility libraries.  To enable that, uncomment this.
++ *
++#define BuildAoutLibraries	YES
++ */
++
++/*
++ * If you have trouble with make bombing out in Xlib, try uncommenting this.
++ * You will not get dependencies as a result, but better than nothing.
++ *
++#define MakeHashTableBug        YES
++ */
++
++/*
++ * If you do not want your man pages compress under SVR3 systems that
++ * support it, uncomment this.
++ *
++#define CompressManPages        NO
++ */
++
++/*
++ * If you have sgmlfmt (the XFree86 doctools package) and want to build
++ * formatted docs from the SGML source, uncomment this.
++ *
++#define HasSgmlFmt		YES
++ */
++
++/*
++ * To disable building some document formats, uncomment some of these.
++ *
++#define BuildLinuxDocText	NO
++#define BuildLinuxDocHtml	NO
++#define BuildLinuxDocPS		NO
++ */
++
++/*
++ * To install Japanese versions of the documentation uncomment this.
++ * Note: The Japanese documentation consists of a subset of the
++ * XFree86 3.1 docs.
++ *
++#define InstallJapaneseDocs	YES
++ */
++
++/*
++ * To build/install X specs docs, uncomment the following.
++ * The SpecsDocDirs setting here is recommended because it covers
++ * the docs that XFree86 has changed or added.
++ *
++#define BuildSpecsDocs		YES
++#define SpecsDocDirs		CTEXT GL ICCCM X11 Xext Xmu Xv XvMC i18n
++ */
++
++/*
++ * To build all specs docs, not just those listed in SpecsDocDirs, uncomment
++ * the following.
++ *
++#define BuildAllSpecsDocs	YES
++ */
++
++/*
++ * If your system doesn't support vm86() mode and you have
++ * libx86emu set library path here
++ *
++#define X86EMU_LIBPATH /usr/local/lib
++ */ 
++
++/*
++ * Most platforms default to using an already installed FreeType 2 library.
++ * To use the one included in this release instead, uncomment the following.
++ *
++#define HasFreetype2 NO
++ */
++#define HasFreetype2 NO
++
++/* 
++ * To use a FreeType library already installed outside the default search
++ * paths, uncomment the following and set the path as needed.
++ *
++#define HasFreetype2 YES
++#define Freetype2Dir /usr/local
++ */
++
++
++/*
++ * Most platforms default to using an already installed Fontconfig library.
++ * To use the one included in this release instead, uncomment the following.
++ *
++#define HasFontconfig NO
++ */
++#define HasFontconfig NO
++
++/* 
++ * To use a Fontconfig library already installed outside the default search
++ * paths, uncomment the following and set the path as needed.
++#define HasFontconfig YES
++#define FontconfigDir /usr/local
++ */
++
++
++/*
++ * Most platforms default to using an already installed Expat library.
++ * To use the one included in this release instead, uncomment the following.
++ *
++#define HasExpat NO
++ */
++#define HasExpat NO
++
++/* 
++ * To use a Expat library already installed outside the default search
++ * paths, uncomment the following and set the path as needed.
++#define HasExpat YES
++#define ExpatDir /usr/local
++ */
++
++
++/*
++ * Most platforms default to using an already installed PNG library.
++ * To use the one included in this release instead, uncomment the following.
++ *
++#define HasLibpng NO
++ */
++
++/* 
++ * To use a PNG library already installed outside the default search
++ * paths, uncomment the following and set the path as needed.
++#define HasLibpng YES
++#define LibpngDir /usr/local
++ */
++
++
++/*
++ * Most platforms default to using an already installed xterm program.
++ * To use the one included in this release instead, uncomment the following.
++ *
++#define BuildXterm YES
++ */
++
++#define SharedLibXau           NO
++
++#define SharedLibXdmcp         NO
++
++#define BuildXaw7              YES
++
++#else /* #if !defined(NXZaurusXServer) && !defined(NXiPAQXServer) && !defined(DarwinArchitecture) */
++
++#if defined(DarwinArchitecture) && !defined(NXZaurusXServer) && !defined(NXiPAQXServer)
++#define NXDarwinServer              NO
++#define BuildServersOnly            YES
++#define DefaultFontPath             /usr/NX/share/fonts/misc/,/usr/NX/share/fonts/TTF/
++#define DefaultRGBDatabase          /usr/NX/share/rgb
++#define XprtServer                  NO
++#define BuildXprint                 NO
++#define XnestServer                 NO
++#define XVirtualFramebufferServer   NO
++#define BuildFontServer             NO
++#define BuildFreeType               NO
++#define BuildXTrueType              NO
++#define FontLibSharedFreeType       NO
++#endif
++
++#if !defined(NXZaurusXServer) && defined(NXiPAQXServer)
++#define KDriveXServer               YES
++#define XiPAQH3500Server            YES
++#define BuildServersOnly            YES
++#define NXEmbeddedXServer           YES
++#define KdriveServerExtraDefines    -DITSY -DMAXSCREENS=1
++#define TinyXServer                 YES
++#define CrossCompiling              YES
++#define TouchScreen                 YES
++#define ItsyCompilerBug             YES
++#undef  BuildRandR
++#define BuildRandR                  YES
++#define BuildXInputLib              YES
++#define BuildXTrueType              YES
++#define ServerXdmcpDefines
++#define XipaqServer                 YES
++#endif
++
++#if !defined(NXiPAQXServer) && defined(NXZaurusXServer)
++#define KDriveXServer               YES
++#define XiPAQH3500Server            YES
++#define BuildServersOnly            YES
++#define ZaurusXServer               YES
++#define NXEmbeddedXServer           YES
++#define KdriveServerExtraDefines    -DITSY -DMAXSCREENS=1
++#define TinyXServer                 YES
++#define CrossCompiling              YES
++#define TouchScreen                 YES
++#define ItsyCompilerBug             YES
++#undef  BuildRandR
++#define BuildRandR                  YES
++#define BuildXInputLib              YES
++#define BuildXTrueType              YES
++#define ServerXdmcpDefines
++#define XipaqServer                 YES
++#define XfbdevServer                YES
++#endif
++
++#endif /* #if !defined(NXZaurusXServer) && !defined(NXiPAQXServer) && !defined(DarwinArchitecture) */
diff --git a/doc/nx-X11_vs_XOrg69_patches/iPAQH3600.cf.NX.patch b/doc/nx-X11_vs_XOrg69_patches/iPAQH3600.cf.NX.patch
new file mode 100644
index 0000000..ab93486
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/iPAQH3600.cf.NX.patch
@@ -0,0 +1,112 @@
+--- ./nx-X11/config/cf/iPAQH3600.cf.X.original	2015-02-13 14:03:44.400448260 +0100
++++ ./nx-X11/config/cf/iPAQH3600.cf	2015-02-13 14:03:44.400448260 +0100
+@@ -0,0 +1,109 @@
++/* $XFree86: xc/config/cf/iPAQH3600.cf,v 1.2 2000/10/10 14:05:48 tsi Exp $ */
++/*
++ * This configuration file contains additional configuration needed
++ * to cross compile X for the Compaq iPAQ H3600 PocketPC.
++ * To use this, add the following to host.def:
++   #define KDriveXServer YES
++   #define XiPAQH3500Server YES
++ */
++ 
++#define CrossCompiling YES
++
++#undef i386Architecture
++#define Arm32Architecture
++
++#undef OptimizedCDebugFlags
++#define OptimizedCDebugFlags 	-O2
++#define ServerCDebugFlags	-O2
++#undef StandardDefines
++#define StandardDefines 	-Dlinux -D__arm__ -D_POSIX_SOURCE \
++				-D_BSD_SOURCE -D_GNU_SOURCE -DX_LOCALE
++#undef CcCmd
++#define StdIncDir /opt/Embedix/tools/arm-linux/include
++#define PreIncDir 
++#undef PostIncDir
++#define PostIncDir /opt/Embedix/tools/lib/gcc-lib/arm-linux/2.95.2/include
++#define CcCmd /opt/Embedix/tools/bin/arm-linux-gcc
++#define DoRanlibCmd YES
++#define RanlibCmd /opt/Embedix/tools/bin/arm-linux-ranlib
++#undef ExtraLoadFlags
++#define ExtraLoadFlags
++#define FbNoPixelAddrCode
++#undef TermcapLibrary
++#define TermcapLibrary -ltermcap
++
++#undef LdPostLib
++#define LdPostLib	-L/opt/Embedix/tools/arm-linux/lib
++
++#undef XfbdevServer
++#define XfbdevServer		YES
++#undef BuildXprint
++#define BuildLBX 		NO
++#define BuildFonts 		NO
++#define BuildAppgroup 		NO
++#define BuildRECORD 		NO
++#define BuildDBE 		NO
++#define BuildXCSecurity 	NO
++#define ItsyCompilerBug 	YES
++#define FontServerAccess	NO
++#define ServerXdmcpDefines	/**/
++
++#undef ExtensionOSDefines
++#define ExtensionOSDefines
++
++#define ProjectRoot	/usr/X11R6
++
++#define GzipFontCompression	YES
++
++#define KdriveServerExtraDefines -DITSY -DMAXSCREENS=1
++
++#define HostLinkRule(target, flags, src, libs)  cc -I$(BUILDINCDIR) -o target src
++
++/* ComplexHostProgramTarget - Compile a program such that we can run
++ * it on this host, i.e., don't use the default cross compiler.
++ */
++#ifndef ComplexHostProgramTarget
++#define	ComplexHostProgramTarget(program)				@@\
++              CC=cc							@@\
++    STD_INCLUDES=							@@\
++          CFLAGS=$(TOP_INCLUDES) $(INCLUDES) $(BOOTSTRAPCFLAGS)		@@\
++EXTRA_LOAD_FLAGS=							@@\
++        PROGRAM = program						@@\
++									@@\
++AllTarget(program)							@@\
++									@@\
++program: $(OBJS) $(DEPLIBS)						@@\
++	RemoveTargetProgram($@)						@@\
++	HostLinkRule($@,$(_NOOP_),$(OBJS),$(DEPLIBS) $(LOCAL_LIBRARIES)) @@\
++									@@\
++DependTarget()								@@\
++									@@\
++LintTarget()								@@\
++									@@\
++clean::									@@\
++	RemoveFile(ProgramTargetName(program))
++#endif /* ComplexHostProgramTarget */
++
++#ifndef SimpleHostProgramTarget
++#define SimpleHostProgramTarget(program)				@@\
++           SRCS = program.c						@@\
++									@@\
++              CC=cc							@@\
++    STD_INCLUDES=							@@\
++          CFLAGS=$(TOP_INCLUDES) $(INCLUDES) $(BOOTSTRAPCFLAGS)		@@\
++EXTRA_LOAD_FLAGS=							@@\
++        PROGRAM = program						@@\
++									@@\
++AllTarget(program)							@@\
++									@@\
++program: program.o $(DEPLIBS)						@@\
++	RemoveTargetProgram($@)						@@\
++	HostLinkRule($@,$(_NOOP_),program.o,$(DEPLIBS) $(LOCAL_LIBRARIES)) @@\
++									@@\
++DependTarget()								@@\
++									@@\
++LintTarget()								@@\
++									@@\
++clean::									@@\
++	RemoveFile(ProgramTargetName(program))
++#endif /* SimpleHostProgramTarget */
diff --git a/doc/nx-X11_vs_XOrg69_patches/log.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/log.c.NX.patch
new file mode 100644
index 0000000..44407e0
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/log.c.NX.patch
@@ -0,0 +1,136 @@
+--- ./nx-X11/programs/Xserver/os/log.c.X.original	2015-02-13 14:03:44.788440645 +0100
++++ ./nx-X11/programs/Xserver/os/log.c	2015-02-13 14:03:44.788440645 +0100
+@@ -78,6 +78,23 @@
+ 
+ /* $XFree86: xc/programs/Xserver/os/log.c,v 1.6 2003/11/07 13:45:27 tsi Exp $ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #ifdef HAVE_DIX_CONFIG_H
+ #include <dix-config.h>
+ #endif
+@@ -98,9 +115,17 @@
+ #define getpid(x) _getpid(x)
+ #endif
+ 
++#ifdef NX_TRANS_SOCKET
++
++#include "NX.h"
++
++#endif
+ 
+ #ifdef DDXOSVERRORF
+ void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
++#ifdef NX_TRANS_EXIT
++int OsVendorVErrorFFatal = 0;
++#endif
+ #endif
+ 
+ static FILE *logFile = NULL;
+@@ -265,6 +290,32 @@
+      */
+     if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
+ 	vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
++#ifdef NX_TRANS_EXIT
++        /*
++         * Beautify the message. Make the
++         * first letter uppercase.
++         */
++
++        *tmpBuffer = toupper(*tmpBuffer);
++
++        /*
++         * Remove the trailing newline.
++         */
++
++        if (strlen(tmpBuffer) > 0 &&
++                *(tmpBuffer + strlen(tmpBuffer) - 1) == '\n') {
++            *(tmpBuffer + strlen(tmpBuffer) - 1) = '\0';
++        }
++
++        /*
++         * Remove the trailing full-stop.
++         */
++
++        if (strlen(tmpBuffer) > 0 &&
++                *(tmpBuffer + strlen(tmpBuffer) - 1) == '.') {
++            *(tmpBuffer + strlen(tmpBuffer) - 1) = '\0';
++        }
++#endif /* #ifdef NX_TRANS_EXIT */
+ 	len = strlen(tmpBuffer);
+     }
+     if ((verb < 0 || logVerbosity >= verb) && len > 0)
+@@ -404,12 +455,22 @@
+ void
+ AbortServer(void)
+ {
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "AbortServer: Going to abort the current server.\n");
++#endif
+     OsCleanup(TRUE);
+     AbortDDX();
+     fflush(stderr);
+     if (CoreDump)
+ 	abort();
++#ifdef NX_TRANS_EXIT
++#ifdef NX_TRANS_TEST
++    fprintf(stderr, "AbortServer: Going to clean up NX resources and exit.\n");
++#endif
++    NXTransExit(1);
++#else /* #ifdef NX_TRANS_EXIT */
+     exit (1);
++#endif
+ }
+ 
+ #ifndef AUDIT_PREFIX
+@@ -533,6 +594,27 @@
+     va_list args;
+     static Bool beenhere = FALSE;
+ 
++#ifdef NX_TRANS_EXIT
++    if (beenhere) {
++        fprintf(stderr, "Error: Aborting session with fatal error function reentered.\n");
++    }
++    else {
++        /*
++         * Tell to the log function that this
++         * is a fatal error.
++         */
++
++        OsVendorVErrorFFatal = 1;
++
++        fprintf(stderr, "Error: Aborting session with '");
++
++        va_start(args, f);
++        VErrorF(f, args);
++        va_end(args);
++
++        fprintf(stderr, "'.\n");
++    }
++#else /* #ifdef NX_TRANS_EXIT */
+     if (beenhere)
+ 	ErrorF("\nFatalError re-entered, aborting\n");
+     else
+@@ -542,6 +624,7 @@
+     VErrorF(f, args);
+     va_end(args);
+     ErrorF("\n");
++#endif /* #ifdef NX_TRANS_EXIT */
+ #ifdef DDXOSFATALERROR
+     if (!beenhere)
+ 	OsVendorFatalError();
diff --git a/doc/nx-X11_vs_XOrg69_patches/main.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/main.c.NX.patch
new file mode 100644
index 0000000..2ee2683
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/main.c.NX.patch
@@ -0,0 +1,42 @@
+--- ./nx-X11/programs/xterm/main.c.X.original	2015-02-13 14:03:44.804440330 +0100
++++ ./nx-X11/programs/xterm/main.c	2015-02-13 14:03:44.804440330 +0100
+@@ -91,8 +91,39 @@
+ 
+ ******************************************************************/
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ /* $XFree86: xc/programs/xterm/main.c,v 3.199 2005/11/13 23:10:36 dickey Exp $ */
+ 
++#ifdef NX_TRANS_EXIT
++
++/*
++ *  Redefine the libc exit() function to be
++ *  sure we get rid of proxy and detect any
++ *  abnormal termination.
++ */
++
++extern void NXTransExit(int code) __attribute__((noreturn));
++
++#define exit(code) NXTransExit(code)
++
++#endif /* #ifdef NX_TRANS_EXIT */
++
+ /* main.c */
+ 
+ #define RES_OFFSET(field)	XtOffsetOf(XTERM_RESOURCE, field)
diff --git a/doc/nx-X11_vs_XOrg69_patches/oscolor.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/oscolor.c.NX.patch
new file mode 100644
index 0000000..88acc87
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/oscolor.c.NX.patch
@@ -0,0 +1,214 @@
+--- ./nx-X11/programs/Xserver/os/oscolor.c.X.original	2015-02-13 14:03:44.788440645 +0100
++++ ./nx-X11/programs/Xserver/os/oscolor.c	2015-02-13 14:03:44.788440645 +0100
+@@ -47,6 +47,17 @@
+ ******************************************************************/
+ /* $Xorg: oscolor.c,v 1.4 2001/02/09 02:05:23 xorgcvs Exp $ */
+ 
++#ifdef NX_TRANS_SOCKET
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <unistd.h>
++
++static char* nxAltRgbPaths[] = {"/usr/NX/share/rgb", "/usr/share/X11/rgb", "/etc/X11/rgb"};
++static char _NXRgbPath[1024];
++
++#endif
++
+ #ifdef HAVE_DIX_CONFIG_H
+ #include <dix-config.h>
+ #endif
+@@ -174,6 +185,154 @@
+ 
+ static dbEntryPtr hashTab[HASHSIZE];
+ 
++#ifdef NX_TRANS_SOCKET
++
++static int NXVerifyRgbPath(char *path)
++{
++  int size;
++  char *rgbPath;
++  struct stat rgbFileStat;
++
++  /*
++   * Check if rgb file is present.
++   */
++
++  size = strlen(path) + strlen(".txt") + 1;
++
++  rgbPath = (char *) ALLOCATE_LOCAL(size + 1);
++
++  strcpy(rgbPath, path);
++
++  #ifdef NX_TRANS_TEST
++  fprintf(stderr, "NXVerifyRgbPath: Looking for [%s] file.\n",
++              rgbPath);
++  #endif
++
++  if (stat(rgbPath, &rgbFileStat) != 0)
++  {
++
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "NXVerifyRgbPath: Can't find the rgb file [%s].\n",
++                rgbPath);
++    #endif
++
++    strcat(rgbPath, ".txt");
++
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "NXVerifyRgbPath: Looking for [%s] file.\n",
++                rgbPath);
++    #endif
++
++    if (stat(rgbPath, &rgbFileStat) != 0)
++    {
++
++      #ifdef NX_TRANS_TEST
++      fprintf(stderr, "NXVerifyRgbPath: Can't find the rgb file [%s].\n",
++                  rgbPath);
++      #endif
++
++      DEALLOCATE_LOCAL(rgbPath);
++
++      return 0;
++    }
++  }
++
++  #ifdef NX_TRANS_TEST
++  fprintf(stderr, "NXVerifyRgbPath: rgb path [%s] is valid.\n",
++              path);
++  #endif
++
++  DEALLOCATE_LOCAL(rgbPath);
++
++  return 1;
++}
++
++static const char *_NXGetRgbPath(const char *path)
++{
++  const char *systemEnv;
++  char rgbPath[1024];
++  int numAltRgbPaths;
++  int i;
++
++  /*
++   * Check the environment only once.
++   */
++
++  if (*_NXRgbPath != '\0')
++  {
++    return _NXRgbPath;
++  }
++
++  systemEnv = getenv("NX_SYSTEM");
++
++  if (systemEnv != NULL && *systemEnv != '\0')
++  {
++    if (strlen(systemEnv) + strlen("/share/rgb") + 1 > 1024)
++    {
++
++      #ifdef NX_TRANS_TEST
++      fprintf(stderr, "_NXGetRgbPath: WARNING! Maximum length of rgb file path exceeded.\n");
++      #endif
++
++      goto _NXGetRgbPathError;
++    }
++
++    strcpy(rgbPath, systemEnv);
++    strcat(rgbPath, "/share/rgb");
++
++    if (NXVerifyRgbPath(rgbPath) == 1)
++    {
++      strcpy(_NXRgbPath, systemEnv);
++      strcat(_NXRgbPath, "/share/rgb");
++
++      #ifdef NX_TRANS_TEST
++      fprintf(stderr, "_NXGetRgbPath: Using rgb file path [%s].\n",
++                  _NXRgbPath);
++      #endif
++
++      return _NXRgbPath;
++    }
++  }
++
++  numAltRgbPaths = sizeof(nxAltRgbPaths) / sizeof(*nxAltRgbPaths);
++
++  for (i = 0; i < numAltRgbPaths; i++)
++  {
++    if (NXVerifyRgbPath(nxAltRgbPaths[i]) == 1)
++    {
++      if (strlen(nxAltRgbPaths[i]) + 1 > 1024)
++      {
++        #ifdef NX_TRANS_TEST
++        fprintf(stderr, "_NXGetRgbPath: WARNING! Maximum length of rgb file path exceeded.\n");
++        #endif
++
++        goto _NXGetRgbPathError;
++      }
++
++      strcpy(_NXRgbPath, nxAltRgbPaths[i]);
++
++      #ifdef NX_TRANS_TEST
++      fprintf(stderr, "_NXGetRgbPath: Using rgb file path [%s].\n",
++                  _NXRgbPath);
++      #endif
++
++      return _NXRgbPath;
++    }
++  }
++
++_NXGetRgbPathError:
++
++  strcpy(_NXRgbPath, path);
++
++  #ifdef NX_TRANS_TEST
++  fprintf(stderr, "_NXGetRgbPath: Using default rgb file path [%s].\n",
++              _NXRgbPath);
++  #endif
++
++  return _NXRgbPath;
++}
++
++#endif
+ 
+ static dbEntryPtr
+ lookup(char *name, int len, Bool create)
+@@ -229,9 +388,26 @@
+   if (!was_here)
+     {
+ #ifndef __UNIXOS2__
++#ifdef NX_TRANS_SOCKET
++      /*
++       * Add the trailing '.txt' if a
++       * 'rgb' file is not found.
++       */
++
++      struct stat statbuf;
++
++      path = (char*)ALLOCATE_LOCAL(strlen(_NXGetRgbPath(rgbPath)) + 5);
++      strcpy(path, _NXGetRgbPath(rgbPath));
++
++      if (stat(path, &statbuf) != 0)
++      {
++          strcat(path, ".txt");
++      }
++#else
+       path = (char*)ALLOCATE_LOCAL(strlen(rgbPath) +5);
+       strcpy(path, rgbPath);
+       strcat(path, ".txt");
++#endif
+ #else
+       char *tmp = (char*)__XOS2RedirRoot(rgbPath);
+       path = (char*)ALLOCATE_LOCAL(strlen(tmp) +5);
+@@ -240,7 +416,11 @@
+ #endif
+       if (!(rgb = fopen(path, "r")))
+         {
++#ifdef NX_TRANS_SOCKET
++           ErrorF( "Couldn't open RGB_DB '%s'\n", _NXGetRgbPath(rgbPath));
++#else
+ 	   ErrorF( "Couldn't open RGB_DB '%s'\n", rgbPath );
++#endif
+ 	   DEALLOCATE_LOCAL(path);
+ 	   return FALSE;
+ 	}
diff --git a/doc/nx-X11_vs_XOrg69_patches/panoramiXproto.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/panoramiXproto.h.NX.patch
new file mode 100644
index 0000000..3424f2e
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/panoramiXproto.h.NX.patch
@@ -0,0 +1,195 @@
+--- ./nx-X11/programs/Xserver/randr/panoramiXproto.h.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/panoramiXproto.h	2015-02-10 19:13:13.612693075 +0100
+@@ -0,0 +1,192 @@
++/* $Xorg: panoramiXproto.h,v 1.4 2000/08/18 04:05:45 coskrey Exp $ */
++/*****************************************************************
++Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
++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.
++
++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
++DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
++BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
++shall not be used in advertising or otherwise to promote the sale, use or other
++dealings in this Software without prior written authorization from Digital
++Equipment Corporation.
++******************************************************************/
++/* $XFree86: xc/include/extensions/panoramiXproto.h,v 3.5 2000/03/01 01:04:21 dawes Exp $ */
++
++/* THIS IS NOT AN X PROJECT TEAM SPECIFICATION */
++
++#ifndef _PANORAMIXPROTO_H_
++#define _PANORAMIXPROTO_H_
++
++#define PANORAMIX_PROTOCOL_NAME "XINERAMA"
++
++#define X_PanoramiXQueryVersion		0
++#define X_PanoramiXGetState		1
++#define X_PanoramiXGetScreenCount	2
++#define X_PanoramiXGetScreenSize	3
++
++#define X_XineramaIsActive		4
++#define X_XineramaQueryScreens		5
++
++typedef struct _PanoramiXQueryVersion {
++	CARD8	reqType;		/* always PanoramiXReqCode */
++	CARD8	panoramiXReqType;	/* always X_PanoramiXQueryVersion */
++	CARD16	length B16;
++	CARD8	clientMajor;
++	CARD8	clientMinor;
++	CARD16	unused B16;           
++} xPanoramiXQueryVersionReq;
++
++#define sz_xPanoramiXQueryVersionReq	8
++
++typedef struct {
++	CARD8	type;			/* must be X_Reply */
++	CARD8	pad1;			/* unused	*/
++	CARD16	sequenceNumber  B16;	/* last sequence number */
++	CARD32	length  B32;		/* 0 */
++	CARD16	majorVersion  B16;	
++	CARD16	minorVersion  B16;	
++	CARD32	pad2	B32;		/* unused */
++	CARD32	pad3	B32;		/* unused */
++	CARD32	pad4	B32;		/* unused */
++	CARD32	pad5	B32;		/* unused */
++	CARD32	pad6	B32;		/* unused */
++} xPanoramiXQueryVersionReply;
++
++#define sz_xPanoramiXQueryVersionReply	32
++
++
++typedef	struct	_PanoramiXGetState {
++        CARD8   reqType;	        /* always PanoramiXReqCode */
++        CARD8   panoramiXReqType;    	/* always X_PanoramiXGetState */
++        CARD16  length B16;
++	CARD32  window B32;
++} xPanoramiXGetStateReq;
++#define sz_xPanoramiXGetStateReq	8	
++
++typedef struct {
++	BYTE	type;
++	BYTE	state;
++	CARD16	sequenceNumber B16;
++	CARD32	length	B32;
++	CARD32  window  B32;
++	CARD32	pad1	B32;		/* unused */
++	CARD32	pad2	B32;		/* unused */
++	CARD32	pad3	B32;		/* unused */
++	CARD32	pad4	B32;		/* unused */
++	CARD32	pad5	B32;		/* unused */
++} xPanoramiXGetStateReply;
++
++#define sz_panoramiXGetStateReply	32
++
++typedef	struct	_PanoramiXGetScreenCount {
++        CARD8   reqType;             /* always PanoramiXReqCode */
++        CARD8   panoramiXReqType;    /* always X_PanoramiXGetScreenCount */
++        CARD16  length B16;
++	CARD32  window B32;
++} xPanoramiXGetScreenCountReq;
++#define sz_xPanoramiXGetScreenCountReq	8
++
++typedef struct {
++	BYTE	type;
++	BYTE	ScreenCount;
++	CARD16	sequenceNumber B16;
++	CARD32	length B32;
++	CARD32  window  B32;
++	CARD32	pad1	B32;		/* unused */
++	CARD32	pad2	B32;		/* unused */
++	CARD32	pad3	B32;		/* unused */
++	CARD32	pad4	B32;		/* unused */
++	CARD32	pad5	B32;		/* unused */
++} xPanoramiXGetScreenCountReply;
++#define sz_panoramiXGetScreenCountReply	32
++
++typedef	struct	_PanoramiXGetScreenSize {
++        CARD8   reqType;                /* always PanoramiXReqCode */
++        CARD8   panoramiXReqType;	/* always X_PanoramiXGetState */
++        CARD16  length B16;
++	CARD32  window B32;
++	CARD32	screen B32;
++} xPanoramiXGetScreenSizeReq;
++#define sz_xPanoramiXGetScreenSizeReq	12	
++
++typedef struct {
++	BYTE	type;
++	CARD8	pad1;			
++	CARD16	sequenceNumber B16;
++	CARD32	length	B32;
++	CARD32	width	B32;
++	CARD32	height	B32;
++	CARD32  window  B32;
++	CARD32  screen  B32;
++	CARD32	pad2	B32;		/* unused */
++	CARD32	pad3	B32;		/* unused */
++} xPanoramiXGetScreenSizeReply;
++#define sz_panoramiXGetScreenSizeReply 32	
++
++/************  Alternate protocol  ******************/
++
++typedef struct {
++        CARD8   reqType;
++        CARD8   panoramiXReqType;
++        CARD16  length B16;
++} xXineramaIsActiveReq;
++#define sz_xXineramaIsActiveReq 4
++
++typedef struct {
++	BYTE	type;
++	CARD8	pad1;			
++	CARD16	sequenceNumber B16;
++	CARD32	length	B32;
++	CARD32	state	B32;
++	CARD32	pad2	B32;
++	CARD32  pad3  	B32;
++	CARD32  pad4  	B32;
++	CARD32	pad5	B32;
++	CARD32	pad6	B32;
++} xXineramaIsActiveReply;
++#define sz_XineramaIsActiveReply 32	
++
++
++typedef struct {
++        CARD8   reqType;
++        CARD8   panoramiXReqType;
++        CARD16  length B16;
++} xXineramaQueryScreensReq;
++#define sz_xXineramaQueryScreensReq 4
++
++typedef struct {
++	BYTE	type;
++	CARD8	pad1;			
++	CARD16	sequenceNumber B16;
++	CARD32	length	B32;
++	CARD32	number	B32;
++	CARD32	pad2	B32;
++	CARD32  pad3  	B32;
++	CARD32  pad4  	B32;
++	CARD32	pad5	B32;
++	CARD32	pad6	B32;
++} xXineramaQueryScreensReply;
++#define sz_XineramaQueryScreensReply 32	
++
++typedef struct {
++	INT16   x_org   B16;
++	INT16   y_org   B16;
++	CARD16  width   B16;
++	CARD16  height  B16;
++} xXineramaScreenInfo;
++#define sz_XineramaScreenInfo 8
++
++#endif 
diff --git a/doc/nx-X11_vs_XOrg69_patches/pixmap.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/pixmap.c.NX.patch
new file mode 100644
index 0000000..77b32d2
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/pixmap.c.NX.patch
@@ -0,0 +1,18 @@
+--- ./nx-X11/programs/Xserver/dix/pixmap.c.X.original	2015-02-13 14:03:44.704442298 +0100
++++ ./nx-X11/programs/Xserver/dix/pixmap.c	2015-02-10 19:13:13.696689930 +0100
+@@ -121,7 +121,14 @@
+     if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
+ 	return NullPixmap;
+     
+-    pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize);
++    /*
++     * FIXME: Allocate 4 bytes at the end of each pixmap. This
++     * is a quick workaround intended to fix a problem reported
++     * by Valgrind due to fbBlt() writing just after the end of
++     * the pixmap buffer. This may be a RENDER bug.
++     */
++
++    pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize + 4);
+     if (!pPixmap)
+ 	return NullPixmap;
+     ppriv = (DevUnion *)(pPixmap + 1);
diff --git a/doc/nx-X11_vs_XOrg69_patches/randr.NX.patch b/doc/nx-X11_vs_XOrg69_patches/randr.NX.patch
new file mode 100644
index 0000000..6462b11
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/randr.NX.patch
@@ -0,0 +1,2704 @@
+diff -u ./nx-X11/programs/Xserver/randr.X.original/Imakefile ./nx-X11/programs/Xserver/randr/Imakefile
+--- ./nx-X11/programs/Xserver/randr.X.original/Imakefile	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/Imakefile	2015-02-10 19:13:13.636692176 +0100
+@@ -1,15 +1,33 @@
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
+ XCOMM $XFree86: xc/programs/Xserver/randr/Imakefile,v 1.1 2001/05/23 03:29:44 keithp Exp $
+ #include <Server.tmpl>
+ 
+-       SRCS =	randr.c mirandr.c
++       SRCS =	mirandr.c randr.c rrcrtc.c rrdispatch.c rrinfo.c rrmode.c rroutput.c rrpointer.c rrproperty.c rrscreen.c rrsdispatch.c rrxinerama.c
+ 
+-       OBJS =	randr.o mirandr.o
++       OBJS =	mirandr.o randr.o rrcrtc.o rrdispatch.o rrinfo.o rrmode.o rroutput.o rrpointer.o rrproperty.o rrscreen.o rrsdispatch.o rrxinerama.o
+ 
+    INCLUDES = -I../include -I../mi -I../../../include/fonts \
+ 		-I../fb -I../hw/kdrive -I$(EXTINCSRC) -I$(XINCLUDESRC) \
+ 		-I$(FONTINCSRC) -I../render
+    LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+ 
++    DEFINES = -DNXAGENT_SERVER
++
+ NormalLibraryTarget(randr,$(OBJS))
+ NormalLibraryObjectRule()
+ LintLibraryTarget(randr,$(SRCS))
+Only in ./nx-X11/programs/Xserver/randr: Imakefile.NX.original
+Only in ./nx-X11/programs/Xserver/randr: Imakefile.X.original
+Only in ./nx-X11/programs/Xserver/randr: Makefile.am
+Only in ./nx-X11/programs/Xserver/randr: Makefile.in
+diff -u ./nx-X11/programs/Xserver/randr.X.original/mirandr.c ./nx-X11/programs/Xserver/randr/mirandr.c
+--- ./nx-X11/programs/Xserver/randr.X.original/mirandr.c	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/mirandr.c	2015-02-10 19:13:13.616692925 +0100
+@@ -1,76 +1,42 @@
+ /*
+- * $XFree86: xc/programs/Xserver/randr/mirandr.c,v 1.5 2001/06/04 09:45:40 keithp Exp $
+- *
+- * Copyright © 2000, Compaq Computer Corporation, 
+- * Copyright © 2002, Hewlett Packard, Inc.
++ * Copyright © 2000 Compaq Computer Corporation
++ * Copyright © 2002 Hewlett-Packard Company
++ * Copyright © 2006 Intel Corporation
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of Compaq or HP not be used in advertising
+- * or publicity pertaining to distribution of the software without specific,
+- * written prior permission.  HP makes no representations about the
+- * suitability of this software for any purpose.  It is provided "as is"
+- * without express or implied warranty.
++ * the above copyright notice appear in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * that the name of the copyright holders not be used in advertising or
++ * publicity pertaining to distribution of the software without specific,
++ * written prior permission.  The copyright holders make no representations
++ * about the suitability of this software for any purpose.  It is provided "as
++ * is" without express or implied warranty.
+  *
+- * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
+- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++ * OF THIS SOFTWARE.
+  *
+- * Author:  Jim Gettys, HP Labs, Hewlett-Packard, Inc.
++ * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
++ *	    Keith Packard, Intel Corporation
+  */
+ 
+-
+ #ifdef HAVE_DIX_CONFIG_H
+ #include <dix-config.h>
+ #endif
+ 
+ #include "scrnintstr.h"
+ #include "mi.h"
+-#include <X11/extensions/randr.h>
+ #include "randrstr.h"
+ #include <stdio.h>
+ 
+-/*
+- * This function assumes that only a single depth can be
+- * displayed at a time, but that all visuals of that depth
+- * can be displayed simultaneously.  It further assumes that
+- * only a single size is available.  Hardware providing
+- * additional capabilties should use different code.
+- * XXX what to do here....
+- */
+-
+ Bool
+ miRRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+ {
+-    int	i;
+-    Bool setConfig = FALSE;
+-    
+-    *rotations = RR_Rotate_0;
+-    for (i = 0; i < pScreen->numDepths; i++)
+-    {
+-	if (pScreen->allowedDepths[i].numVids)
+-	{
+-		RRScreenSizePtr		pSize;
+-
+-		pSize = RRRegisterSize (pScreen,
+-					pScreen->width,
+-					pScreen->height,
+-					pScreen->mmWidth,
+-					pScreen->mmHeight);
+-		if (!pSize)
+-		    return FALSE;
+-		if (!setConfig)
+-		{
+-		    RRSetCurrentConfig (pScreen, RR_Rotate_0, 0, pSize);
+-		    setConfig = TRUE;
+-		}
+-	}
+-    }
+     return TRUE;
+ }
+ 
+@@ -79,24 +45,110 @@
+  * different here
+  */
+ Bool
+-miRRSetConfig (ScreenPtr	pScreen,
+-	       Rotation		rotation,
+-	       int		rate,
+-	       RRScreenSizePtr	pSize)
++miRRCrtcSet (ScreenPtr	pScreen,
++	     RRCrtcPtr	crtc,
++	     RRModePtr	mode,
++	     int	x,
++	     int	y,
++	     Rotation	rotation,
++	     int	numOutput,
++	     RROutputPtr *outputs)
+ {
+     return TRUE;
+ }
+ 
++static Bool
++miRRCrtcSetGamma (ScreenPtr	pScreen,
++		  RRCrtcPtr	crtc)
++{
++    return TRUE;
++}
++
++Bool
++miRROutputSetProperty (ScreenPtr	    pScreen,
++		       RROutputPtr	    output,
++		       Atom		    property,
++		       RRPropertyValuePtr   value)
++{
++    return TRUE;
++}
++
++Bool
++miRROutputValidateMode (ScreenPtr	    pScreen,
++			RROutputPtr	    output,
++			RRModePtr	    mode)
++{
++    return FALSE;
++}
++
++void
++miRRModeDestroy (ScreenPtr  pScreen,
++		 RRModePtr  mode)
++{
++}
++
++/*
++ * This function assumes that only a single depth can be
++ * displayed at a time, but that all visuals of that depth
++ * can be displayed simultaneously.  It further assumes that
++ * only a single size is available.  Hardware providing
++ * additional capabilties should use different code.
++ * XXX what to do here....
++ */
+ 
+ Bool
+ miRandRInit (ScreenPtr pScreen)
+ {
+-    rrScrPrivPtr    rp;
++    rrScrPrivPtr    pScrPriv;
++#if RANDR_12_INTERFACE
++    RRModePtr	mode;
++    RRCrtcPtr	crtc;
++    RROutputPtr	output;
++    xRRModeInfo modeInfo;
++    char	name[64];
++#endif
+     
+     if (!RRScreenInit (pScreen))
+ 	return FALSE;
+-    rp = rrGetScrPriv(pScreen);
+-    rp->rrGetInfo = miRRGetInfo;
+-    rp->rrSetConfig = miRRSetConfig;
++    pScrPriv = rrGetScrPriv(pScreen);
++    pScrPriv->rrGetInfo = miRRGetInfo;
++#if RANDR_12_INTERFACE
++    pScrPriv->rrCrtcSet = miRRCrtcSet;
++    pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma;
++    pScrPriv->rrOutputSetProperty = miRROutputSetProperty;
++    pScrPriv->rrOutputValidateMode = miRROutputValidateMode;
++    pScrPriv->rrModeDestroy = miRRModeDestroy;
++    
++    RRScreenSetSizeRange (pScreen,
++			  pScreen->width, pScreen->height,
++			  pScreen->width, pScreen->height);
++
++    sprintf (name, "%dx%d", pScreen->width, pScreen->height);
++    memset (&modeInfo, '\0', sizeof (modeInfo));
++    modeInfo.width = pScreen->width;
++    modeInfo.height = pScreen->height;
++    modeInfo.nameLength = strlen (name);
++    
++    mode = RRModeGet (&modeInfo, name);
++    if (!mode)
++	return FALSE;
++    
++    crtc = RRCrtcCreate (pScreen, NULL);
++    if (!crtc)
++	return FALSE;
++    
++    output = RROutputCreate (pScreen, "screen", 6, NULL);
++    if (!output)
++	return FALSE;
++    if (!RROutputSetClones (output, NULL, 0))
++	return FALSE;
++    if (!RROutputSetModes (output, &mode, 1, 0))
++	return FALSE;
++    if (!RROutputSetCrtcs (output, &crtc, 1))
++	return FALSE;
++    if (!RROutputSetConnection (output, RR_Connected))
++	return FALSE;
++    RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
++#endif
+     return TRUE;
+ }
+Only in ./nx-X11/programs/Xserver/randr: panoramiXproto.h
+Only in ./nx-X11/programs/Xserver/randr: panoramiXproto.h.NX.original
+Only in ./nx-X11/programs/Xserver/randr: panoramiXproto.h.X.original
+diff -u ./nx-X11/programs/Xserver/randr.X.original/randr.c ./nx-X11/programs/Xserver/randr/randr.c
+--- ./nx-X11/programs/Xserver/randr.X.original/randr.c	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/randr.c	2015-02-10 19:13:13.616692925 +0100
+@@ -1,29 +1,46 @@
+ /*
+- * $XFree86: xc/programs/Xserver/randr/randr.c,v 1.21tsi Exp $
+- *
+- * Copyright © 2000, Compaq Computer Corporation, 
+- * Copyright © 2002, Hewlett Packard, Inc.
++ * Copyright © 2000 Compaq Computer Corporation
++ * Copyright © 2002 Hewlett-Packard Company
++ * Copyright © 2006 Intel Corporation
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of Compaq or HP not be used in advertising
+- * or publicity pertaining to distribution of the software without specific,
+- * written prior permission.  HP makes no representations about the
+- * suitability of this software for any purpose.  It is provided "as is"
+- * without express or implied warranty.
++ * the above copyright notice appear in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * that the name of the copyright holders not be used in advertising or
++ * publicity pertaining to distribution of the software without specific,
++ * written prior permission.  The copyright holders make no representations
++ * about the suitability of this software for any purpose.  It is provided "as
++ * is" without express or implied warranty.
+  *
+- * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
+- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++ * OF THIS SOFTWARE.
+  *
+- * Author:  Jim Gettys, HP Labs, Hewlett-Packard, Inc.
++ * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
++ *	    Keith Packard, Intel Corporation
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
+ 
+ #define NEED_REPLIES
+ #define NEED_EVENTS
+@@ -31,28 +48,7 @@
+ #include <dix-config.h>
+ #endif
+ 
+-#include <X11/X.h>
+-#include <X11/Xproto.h>
+-#include "misc.h"
+-#include "os.h"
+-#include "dixstruct.h"
+-#include "resource.h"
+-#include "scrnintstr.h"
+-#include "windowstr.h"
+-#include "pixmapstr.h"
+-#include "extnsionst.h"
+-#include "servermd.h"
+-#include <X11/extensions/randr.h>
+-#include <X11/extensions/randrproto.h>
+ #include "randrstr.h"
+-#ifdef RENDER
+-#include <X11/extensions/render.h> 	/* we share subpixel order information */
+-#include "picturestr.h"
+-#endif
+-#include <X11/Xfuncproto.h>
+-#ifdef EXTMODULE
+-#include "xf86_ansic.h"
+-#endif
+ 
+ /* From render.h */
+ #ifndef SubPixelUnknown
+@@ -60,13 +56,7 @@
+ #endif
+ 
+ #define RR_VALIDATE
+-int	RRGeneration;
+-int	RRNScreens;
+-
+-static int ProcRRQueryVersion (ClientPtr pClient);
+-static int ProcRRDispatch (ClientPtr pClient);
+-static int SProcRRDispatch (ClientPtr pClient);
+-static int SProcRRQueryVersion (ClientPtr pClient);
++static int	RRNScreens;
+ 
+ #define wrap(priv,real,mem,func) {\
+     priv->mem = real->mem; \
+@@ -77,56 +67,20 @@
+     real->mem = priv->mem; \
+ }
+ 
+-#if 0
+-static CARD8	RRReqCode;
+-static int	RRErrBase;
+-#endif
+-static int	RREventBase;
+-static RESTYPE ClientType, EventType; /* resource types for event masks */
+-static int	RRClientPrivateIndex;
+-
+-typedef struct _RRTimes {
+-    TimeStamp	setTime;
+-    TimeStamp	configTime;
+-} RRTimesRec, *RRTimesPtr;
+-
+-typedef struct _RRClient {
+-    int		major_version;
+-    int		minor_version;
+-/*  RRTimesRec	times[0]; */
+-} RRClientRec, *RRClientPtr;
+-
+-/*
+- * each window has a list of clients requesting
+- * RRNotify events.  Each client has a resource
+- * for each window it selects RRNotify input for,
+- * this resource is used to delete the RRNotifyRec
+- * entry from the per-window queue.
+- */
+-
+-typedef struct _RREvent *RREventPtr;
+-
+-typedef struct _RREvent {
+-    RREventPtr  next;
+-    ClientPtr	client;
+-    WindowPtr	window;
+-    XID		clientResource;
+-    int		mask;
+-} RREventRec;
++static int ProcRRDispatch (ClientPtr pClient);
++static int SProcRRDispatch (ClientPtr pClient);
+ 
++int	RREventBase;
++int	RRErrorBase;
++RESTYPE RRClientType, RREventType; /* resource types for event masks */
++
++#ifndef NXAGENT_SERVER
++DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey;
++DevPrivateKey rrPrivKey = &rrPrivKey;
++#else
++int	RRClientPrivateIndex;
+ int	rrPrivIndex = -1;
+-
+-#define GetRRClient(pClient)    ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
+-#define rrClientPriv(pClient)	RRClientPtr pRRClient = GetRRClient(pClient)
+-
+-static Bool
+-RRClientKnowsRates (ClientPtr	pClient)
+-{
+-    rrClientPriv(pClient);
+-
+-    return (pRRClient->major_version > 1 ||
+-	    (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
+-}
++#endif
+ 
+ static void
+ RRClientCallback (CallbackListPtr	*list,
+@@ -163,10 +117,14 @@
+ RRCloseScreen (int i, ScreenPtr pScreen)
+ {
+     rrScrPriv(pScreen);
++    int		    j;
+ 
+     unwrap (pScrPriv, pScreen, CloseScreen);
+-    if (pScrPriv->pSizes)
+-	xfree (pScrPriv->pSizes);
++    for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
++	RRCrtcDestroy (pScrPriv->crtcs[j]);
++    for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
++	RROutputDestroy (pScrPriv->outputs[j]);
++    
+     xfree (pScrPriv);
+     RRNScreens -= 1;	/* ok, one fewer screen with RandR running */
+     return (*pScreen->CloseScreen) (i, pScreen);    
+@@ -191,18 +149,105 @@
+     cpswaps(from->subpixelOrder, to->subpixelOrder);
+ }
+ 
+-Bool RRScreenInit(ScreenPtr pScreen)
++static void
++SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
++			 xRRCrtcChangeNotifyEvent *to)
+ {
+-    rrScrPrivPtr   pScrPriv;
++    to->type = from->type;
++    to->subCode = from->subCode;
++    cpswaps(from->sequenceNumber, to->sequenceNumber);
++    cpswapl(from->timestamp, to->timestamp);
++    cpswapl(from->window, to->window);
++    cpswapl(from->crtc, to->crtc);
++    cpswapl(from->mode, to->mode);
++    cpswapl(from->window, to->window);
++    cpswaps(from->rotation, to->rotation);
++    cpswaps(from->x, to->x);
++    cpswaps(from->y, to->y);
++    cpswaps(from->width, to->width);
++    cpswaps(from->height, to->height);
++}
++
++static void
++SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from,
++			   xRROutputChangeNotifyEvent *to)
++{
++    to->type = from->type;
++    to->subCode = from->subCode;
++    cpswaps(from->sequenceNumber, to->sequenceNumber);
++    cpswapl(from->timestamp, to->timestamp);
++    cpswapl(from->configTimestamp, to->configTimestamp);
++    cpswapl(from->window, to->window);
++    cpswapl(from->output, to->output);
++    cpswapl(from->crtc, to->crtc);
++    cpswapl(from->mode, to->mode);
++    cpswaps(from->rotation, to->rotation);
++}
+ 
++static void
++SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from,
++			     xRROutputPropertyNotifyEvent *to)
++{
++    to->type = from->type;
++    to->subCode = from->subCode;
++    cpswaps(from->sequenceNumber, to->sequenceNumber);
++    cpswapl(from->window, to->window);
++    cpswapl(from->output, to->output);
++    cpswapl(from->atom, to->atom);
++    cpswapl(from->timestamp, to->timestamp);
++}
++
++static void
++SRRNotifyEvent (xEvent *from,
++		xEvent *to)
++{
++    switch (from->u.u.detail) {
++    case RRNotify_CrtcChange:
++	SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from,
++				  (xRRCrtcChangeNotifyEvent *) to);
++	break;
++    case RRNotify_OutputChange:
++	SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from,
++				    (xRROutputChangeNotifyEvent *) to);
++	break;
++    case RRNotify_OutputProperty:
++	SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from,
++				      (xRROutputPropertyNotifyEvent *) to);
++	break;
++    default:
++	break;
++    }
++}
++
++static int RRGeneration;
++
++Bool RRInit (void)
++{
+     if (RRGeneration != serverGeneration)
+     {
++        #ifdef NXAGENT_SERVER
+ 	if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
+ 	    return FALSE;
++        #endif
++	if (!RRModeInit ())
++	    return FALSE;
++	if (!RRCrtcInit ())
++	    return FALSE;
++	if (!RROutputInit ())
++	    return FALSE;
+ 	RRGeneration = serverGeneration;
+     }
++    return TRUE;
++}
++
++Bool RRScreenInit(ScreenPtr pScreen)
++{
++    rrScrPrivPtr   pScrPriv;
++
++    if (!RRInit ())
++	return FALSE;
+ 
+-    pScrPriv = (rrScrPrivPtr) xalloc (sizeof (rrScrPrivRec));
++    pScrPriv = (rrScrPrivPtr) xcalloc (1, sizeof (rrScrPrivRec));
+     if (!pScrPriv)
+ 	return FALSE;
+ 
+@@ -211,8 +256,31 @@
+     /*
+      * Calling function best set these function vectors
+      */
+-    pScrPriv->rrSetConfig = 0;
+     pScrPriv->rrGetInfo = 0;
++    pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width;
++    pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
++    
++    pScrPriv->width = pScreen->width;
++    pScrPriv->height = pScreen->height;
++    pScrPriv->mmWidth = pScreen->mmWidth;
++    pScrPriv->mmHeight = pScreen->mmHeight;
++#if RANDR_12_INTERFACE
++    pScrPriv->rrScreenSetSize = NULL;
++    pScrPriv->rrCrtcSet = NULL;
++    pScrPriv->rrCrtcSetGamma = NULL;
++#endif
++#if RANDR_10_INTERFACE    
++    pScrPriv->rrSetConfig = 0;
++    pScrPriv->rotations = RR_Rotate_0;
++    pScrPriv->reqWidth = pScreen->width;
++    pScrPriv->reqHeight = pScreen->height;
++    pScrPriv->nSizes = 0;
++    pScrPriv->pSizes = NULL;
++    pScrPriv->rotation = RR_Rotate_0;
++    pScrPriv->rate = 0;
++    pScrPriv->size = 0;
++#endif
++    
+     /*
+      * This value doesn't really matter -- any client must call
+      * GetScreenInfo before reading it which will automatically update
+@@ -223,14 +291,10 @@
+     
+     wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+ 
+-    pScrPriv->rotations = RR_Rotate_0;
+-    
+-    pScrPriv->nSizes = 0;
+-    pScrPriv->nSizesInUse = 0;
+-    pScrPriv->pSizes = 0;
+-    
+-    pScrPriv->rotation = RR_Rotate_0;
+-    pScrPriv->size = -1;
++    pScrPriv->numOutputs = 0;
++    pScrPriv->outputs = NULL;
++    pScrPriv->numCrtcs = 0;
++    pScrPriv->crtcs = NULL;
+     
+     RRNScreens += 1;	/* keep count of screens that implement randr */
+     return TRUE;
+@@ -246,7 +310,7 @@
+ 
+     pRREvent = (RREventPtr) data;
+     pWin = pRREvent->window;
+-    pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, EventType);
++    pHead = (RREventPtr *) LookupIDByType(pWin->drawable.id, RREventType);
+     if (pHead) {
+ 	pPrev = 0;
+ 	for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
+@@ -272,7 +336,7 @@
+     pHead = (RREventPtr *) data;
+     for (pCur = *pHead; pCur; pCur = pNext) {
+ 	pNext = pCur->next;
+-	FreeResource (pCur->clientResource, ClientType);
++	FreeResource (pCur->clientResource, RRClientType);
+ 	xfree ((pointer) pCur);
+     }
+     xfree ((pointer) pHead);
+@@ -286,1034 +350,172 @@
+ 
+     if (RRNScreens == 0) return;
+ 
++    #ifndef NXAGENT_SERVER
++    if (!dixRequestPrivate(RRClientPrivateKey,
++				sizeof (RRClientRec) +
++				screenInfo.numScreens * sizeof (RRTimesRec)))
++	return;
++    #else
+     RRClientPrivateIndex = AllocateClientPrivateIndex ();
+     if (!AllocateClientPrivate (RRClientPrivateIndex,
+ 				sizeof (RRClientRec) +
+ 				screenInfo.numScreens * sizeof (RRTimesRec)))
+ 	return;
++    #endif
+     if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
+ 	return;
+ 
+-    ClientType = CreateNewResourceType(RRFreeClient);
+-    if (!ClientType)
++    RRClientType = CreateNewResourceType(RRFreeClient);
++    if (!RRClientType)
+ 	return;
+-    EventType = CreateNewResourceType(RRFreeEvents);
+-    if (!EventType)
++    RREventType = CreateNewResourceType(RRFreeEvents);
++    if (!RREventType)
+ 	return;
+     extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
+ 			     ProcRRDispatch, SProcRRDispatch,
+ 			     RRResetProc, StandardMinorOpcode);
+     if (!extEntry)
+ 	return;
+-#if 0
+-    RRReqCode = (CARD8) extEntry->base;
+-    RRErrBase = extEntry->errorBase;
+-#endif
++    RRErrorBase = extEntry->errorBase;
+     RREventBase = extEntry->eventBase;
+     EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) 
+-      SRRScreenChangeNotifyEvent;
+-
+-    return;
++	SRRScreenChangeNotifyEvent;
++    EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
++	SRRNotifyEvent;
++#ifdef PANORAMIX
++    RRXineramaExtensionInit();
++#endif
+ }
+-		
++
+ static int
+ TellChanged (WindowPtr pWin, pointer value)
+ {
+     RREventPtr			*pHead, pRREvent;
+     ClientPtr			client;
+-    xRRScreenChangeNotifyEvent	se;
+     ScreenPtr			pScreen = pWin->drawable.pScreen;
+     rrScrPriv(pScreen);
+-    RRScreenSizePtr		pSize;
+-    WindowPtr			pRoot = WindowTable[pScreen->myNum];
++    int				i;
+ 
+-    pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, EventType);
++    pHead = (RREventPtr *) LookupIDByType (pWin->drawable.id, RREventType);
+     if (!pHead)
+ 	return WT_WALKCHILDREN;
+ 
+-    se.type = RRScreenChangeNotify + RREventBase;
+-    se.rotation = (CARD8) pScrPriv->rotation;
+-    se.timestamp = pScrPriv->lastSetTime.milliseconds;
+-    se.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+-    se.root =  pRoot->drawable.id;
+-    se.window = pWin->drawable.id;
+-#ifdef RENDER
+-    se.subpixelOrder = PictureGetSubpixelOrder (pScreen);
+-#else
+-    se.subpixelOrder = SubPixelUnknown;
+-#endif
+-    if (pScrPriv->size >= 0)
+-    {
+-	pSize = &pScrPriv->pSizes[pScrPriv->size];
+-	se.sizeID = pSize->id;
+-	se.widthInPixels = pSize->width;
+-	se.heightInPixels = pSize->height;
+-	se.widthInMillimeters = pSize->mmWidth;
+-	se.heightInMillimeters = pSize->mmHeight;
+-    }
+-    else
+-    {
+-	/*
+-	 * This "shouldn't happen", but a broken DDX can
+-	 * forget to set the current configuration on GetInfo
+-	 */
+-	se.sizeID = 0xffff;
+-	se.widthInPixels = 0;
+-	se.heightInPixels = 0;
+-	se.widthInMillimeters = 0;
+-	se.heightInMillimeters = 0;
+-    }    
+     for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) 
+     {
+ 	client = pRREvent->client;
+ 	if (client == serverClient || client->clientGone)
+ 	    continue;
+-	se.sequenceNumber = client->sequence;
+-	if(pRREvent->mask & RRScreenChangeNotifyMask)
+-	  WriteEventsToClient (client, 1, (xEvent *) &se);
+-    }
+-    return WT_WALKCHILDREN;
+-}
+ 
+-static Bool
+-RRGetInfo (ScreenPtr pScreen)
+-{
+-    rrScrPriv (pScreen);
+-    int		    i, j, k, l;
+-    Bool	    changed;
+-    Rotation	    rotations;
+-    RRScreenSizePtr pSize;
+-    RRScreenRatePtr pRate;
+-
+-    for (i = 0; i < pScrPriv->nSizes; i++)
+-    {
+-	pSize = &pScrPriv->pSizes[i];
+-	pSize->oldReferenced = pSize->referenced;
+-	pSize->referenced = FALSE;
+-	for (k = 0; k < pSize->nRates; k++)
++	if (pRREvent->mask & RRScreenChangeNotifyMask)
++	    RRDeliverScreenEvent (client, pWin, pScreen);
++	
++	if (pRREvent->mask & RRCrtcChangeNotifyMask)
+ 	{
+-	    pRate = &pSize->pRates[k];
+-	    pRate->oldReferenced = pRate->referenced;
+-	    pRate->referenced = FALSE;
+-	}
+-    }
+-    if (!(*pScrPriv->rrGetInfo) (pScreen, &rotations))
+-	return FALSE;
+-
+-    changed = FALSE;
+-
+-    /*
+-     * Check whether anything changed and simultaneously generate
+-     * the protocol id values for the objects
+-     */
+-    if (rotations != pScrPriv->rotations)
+-    {
+-	pScrPriv->rotations = rotations;
+-	changed = TRUE;
+-    }
+-
+-    j = 0;
+-    for (i = 0; i < pScrPriv->nSizes; i++)
+-    {
+-	pSize = &pScrPriv->pSizes[i];
+-	if (pSize->oldReferenced != pSize->referenced)
+-	    changed = TRUE;
+-	if (pSize->referenced)
+-	    pSize->id = j++;
+-	l = 0;
+-	for (k = 0; k < pSize->nRates; k++)
+-	{
+-	    pRate = &pSize->pRates[k];
+-	    if (pRate->oldReferenced != pRate->referenced)
+-		changed = TRUE;
+-	    if (pRate->referenced)
+-		l++;
+-	}
+-	pSize->nRatesInUse = l;
+-    }
+-    pScrPriv->nSizesInUse = j;
+-    if (changed)
+-    {
+-	UpdateCurrentTime ();
+-	pScrPriv->lastConfigTime = currentTime;
+-	WalkTree (pScreen, TellChanged, (pointer) pScreen);
+-    }
+-    return TRUE;
+-}
+-
+-static void
+-RRSendConfigNotify (ScreenPtr pScreen)
+-{
+-    WindowPtr	pWin = WindowTable[pScreen->myNum];
+-    xEvent	event;
+-
+-    event.u.u.type = ConfigureNotify;
+-    event.u.configureNotify.window = pWin->drawable.id;
+-    event.u.configureNotify.aboveSibling = None;
+-    event.u.configureNotify.x = 0;
+-    event.u.configureNotify.y = 0;
+-
+-    /* XXX xinerama stuff ? */
+-    
+-    event.u.configureNotify.width = pWin->drawable.width;
+-    event.u.configureNotify.height = pWin->drawable.height;
+-    event.u.configureNotify.borderWidth = wBorderWidth (pWin);
+-    event.u.configureNotify.override = pWin->overrideRedirect;
+-    DeliverEvents(pWin, &event, 1, NullWindow);
+-}
+-
+-static int
+-ProcRRQueryVersion (ClientPtr client)
+-{
+-    xRRQueryVersionReply rep;
+-    register int n;
+-    REQUEST(xRRQueryVersionReq);
+-    rrClientPriv(client);
+-
+-    REQUEST_SIZE_MATCH(xRRQueryVersionReq);
+-    pRRClient->major_version = stuff->majorVersion;
+-    pRRClient->minor_version = stuff->minorVersion;
+-    rep.type = X_Reply;
+-    rep.length = 0;
+-    rep.sequenceNumber = client->sequence;
+-    rep.majorVersion = RANDR_MAJOR;
+-    rep.minorVersion = RANDR_MINOR;
+-    if (client->swapped) {
+-    	swaps(&rep.sequenceNumber, n);
+-    	swapl(&rep.length, n);
+-	swapl(&rep.majorVersion, n);
+-	swapl(&rep.minorVersion, n);
+-    }
+-    WriteToClient(client, sizeof(xRRQueryVersionReply), (char *)&rep);
+-    return (client->noClientException);
+-}
+-
+-
+-extern char	*ConnectionInfo;
+-
+-static int padlength[4] = {0, 3, 2, 1};
+-
+-static void
+-RREditConnectionInfo (ScreenPtr pScreen)
+-{
+-    xConnSetup	    *connSetup;
+-    char	    *vendor;
+-    xPixmapFormat   *formats;
+-    xWindowRoot	    *root;
+-    xDepth	    *depth;
+-    xVisualType	    *visual;
+-    int		    screen = 0;
+-    int		    d;
+-
+-    connSetup = (xConnSetup *) ConnectionInfo;
+-    vendor = (char *) connSetup + sizeof (xConnSetup);
+-    formats = (xPixmapFormat *) ((char *) vendor +
+-				 connSetup->nbytesVendor +
+-				 padlength[connSetup->nbytesVendor & 3]);
+-    root = (xWindowRoot *) ((char *) formats +
+-			    sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
+-    while (screen != pScreen->myNum)
+-    {
+-	depth = (xDepth *) ((char *) root + 
+-			    sizeof (xWindowRoot));
+-	for (d = 0; d < root->nDepths; d++)
+-	{
+-	    visual = (xVisualType *) ((char *) depth +
+-				      sizeof (xDepth));
+-	    depth = (xDepth *) ((char *) visual +
+-				depth->nVisuals * sizeof (xVisualType));
+-	}
+-	root = (xWindowRoot *) ((char *) depth);
+-	screen++;
+-    }
+-    root->pixWidth = pScreen->width;
+-    root->pixHeight = pScreen->height;
+-    root->mmWidth = pScreen->mmWidth;
+-    root->mmHeight = pScreen->mmHeight;
+-}
+-
+-static int
+-ProcRRGetScreenInfo (ClientPtr client)
+-{
+-    REQUEST(xRRGetScreenInfoReq);
+-    xRRGetScreenInfoReply   rep;
+-    WindowPtr	    	    pWin;
+-    int			    n;
+-    ScreenPtr		    pScreen;
+-    rrScrPrivPtr	    pScrPriv;
+-    CARD8		    *extra;
+-    unsigned long	    extraLen;
+-
+-    REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
+-    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+-					   SecurityReadAccess);
+-
+-    if (!pWin)
+-	return BadWindow;
+-
+-    pScreen = pWin->drawable.pScreen;
+-    pScrPriv = rrGetScrPriv(pScreen);
+-    rep.pad = 0;
+-    if (!pScrPriv)
+-    {
+-	rep.type = X_Reply;
+-	rep.setOfRotations = RR_Rotate_0;;
+-	rep.sequenceNumber = client->sequence;
+-	rep.length = 0;
+-	rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+-	rep.timestamp = currentTime.milliseconds;
+-	rep.configTimestamp = currentTime.milliseconds;
+-	rep.nSizes = 0;
+-	rep.sizeID = 0;
+-	rep.rotation = RR_Rotate_0;
+-	rep.rate = 0;
+-	rep.nrateEnts = 0;
+-	extra = 0;
+-	extraLen = 0;
+-    }
+-    else
+-    {
+-	int			i, j;
+-	xScreenSizes		*size;
+-	CARD16			*rates;
+-	CARD8			*data8;
+-	Bool			has_rate = RRClientKnowsRates (client);
+-    
+-	RRGetInfo (pScreen);
+-
+-	rep.type = X_Reply;
+-	rep.setOfRotations = pScrPriv->rotations;
+-	rep.sequenceNumber = client->sequence;
+-	rep.length = 0;
+-	rep.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+-	rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+-	rep.configTimestamp = pScrPriv->lastConfigTime.milliseconds;
+-	rep.rotation = pScrPriv->rotation;
+-	rep.nSizes = pScrPriv->nSizesInUse;
+-	rep.rate = pScrPriv->rate;
+-        rep.nrateEnts = 0;
+-	if (has_rate)
+-	{
+-	    for (i = 0; i < pScrPriv->nSizes; i++)
++	    for (i = 0; i < pScrPriv->numCrtcs; i++)
+ 	    {
+-		RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+-		if (pSize->referenced)
+-		{
+-		    rep.nrateEnts += (1 + pSize->nRatesInUse);
+-		}
++		RRCrtcPtr   crtc = pScrPriv->crtcs[i];
++		if (crtc->changed)
++		    RRDeliverCrtcEvent (client, pWin, crtc);
+ 	    }
+ 	}
+-
+-	if (pScrPriv->size >= 0)
+-	    rep.sizeID = pScrPriv->pSizes[pScrPriv->size].id;
+-	else
+-	    return BadImplementation;
+-
+-	extraLen = (rep.nSizes * sizeof (xScreenSizes) +
+-		    rep.nrateEnts * sizeof (CARD16));
+-
+-	extra = (CARD8 *) xalloc (extraLen);
+-	if (!extra)
+-	    return BadAlloc;
+-	/*
+-	 * First comes the size information
+-	 */
+-	size = (xScreenSizes *) extra;
+-	rates = (CARD16 *) (size + rep.nSizes);
+-	for (i = 0; i < pScrPriv->nSizes; i++)
++	
++	if (pRREvent->mask & RROutputChangeNotifyMask)
+ 	{
+-	    RRScreenSizePtr pSize = &pScrPriv->pSizes[i];
+-	    if (pSize->referenced)
++	    for (i = 0; i < pScrPriv->numOutputs; i++)
+ 	    {
+-		size->widthInPixels = pSize->width;
+-		size->heightInPixels = pSize->height;
+-		size->widthInMillimeters = pSize->mmWidth;
+-		size->heightInMillimeters = pSize->mmHeight;
+-		if (client->swapped)
+-		{
+-		    swaps (&size->widthInPixels, n);
+-		    swaps (&size->heightInPixels, n);
+-		    swaps (&size->widthInMillimeters, n);
+-		    swaps (&size->heightInMillimeters, n);
+-		}
+-		size++;
+-		if (has_rate)
+-		{
+-		    *rates = pSize->nRatesInUse;
+-		    if (client->swapped)
+-		    {
+-			swaps (rates, n);
+-		    }
+-		    rates++;
+-		    for (j = 0; j < pSize->nRates; j++)
+-		    {
+-			RRScreenRatePtr	pRate = &pSize->pRates[j];
+-			if (pRate->referenced)
+-			{
+-			    *rates = pRate->rate;
+-			    if (client->swapped)
+-			    {
+-				swaps (rates, n);
+-			    }
+-			    rates++;
+-			}
+-		    }
+-		}
++		RROutputPtr   output = pScrPriv->outputs[i];
++		if (output->changed)
++		    RRDeliverOutputEvent (client, pWin, output);
+ 	    }
+ 	}
+-	data8 = (CARD8 *) rates;
+-
+-	if (data8 - (CARD8 *) extra != extraLen)
+-	    FatalError ("RRGetScreenInfo bad extra len %ld != %ld\n",
+-			(unsigned long)(data8 - (CARD8 *) extra), extraLen);
+-	rep.length =  (extraLen + 3) >> 2;
+-    }
+-    if (client->swapped) {
+-	swaps(&rep.sequenceNumber, n);
+-	swapl(&rep.length, n);
+-	swapl(&rep.timestamp, n);
+-	swaps(&rep.rotation, n);
+-	swaps(&rep.nSizes, n);
+-	swaps(&rep.sizeID, n);
+-	swaps(&rep.rate, n);
+-	swaps(&rep.nrateEnts, n);
+-    }
+-    WriteToClient(client, sizeof(xRRGetScreenInfoReply), (char *)&rep);
+-    if (extraLen)
+-    {
+-	WriteToClient (client, extraLen, (char *) extra);
+-	xfree (extra);
+     }
+-    return (client->noClientException);
++    return WT_WALKCHILDREN;
+ }
+ 
+-static int
+-ProcRRSetScreenConfig (ClientPtr client)
++/*
++ * Something changed; send events and adjust pointer position
++ */
++void
++RRTellChanged (ScreenPtr pScreen)
+ {
+-    REQUEST(xRRSetScreenConfigReq);
+-    xRRSetScreenConfigReply rep;
+-    DrawablePtr		    pDraw;
+-    int			    n;
+-    ScreenPtr		    pScreen;
+-    rrScrPrivPtr	    pScrPriv;
+-    TimeStamp		    configTime;
+-    TimeStamp		    time;
+-    RRScreenSizePtr	    pSize;
+-    int			    i;
+-    Rotation		    rotation;
+-    int			    rate;
+-    short		    oldWidth, oldHeight;
+-    Bool		    has_rate;
+-
+-    UpdateCurrentTime ();
+-
+-    if (RRClientKnowsRates (client))
+-    {
+-	REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+-	has_rate = TRUE;
+-    }
+-    else
+-    {
+-	REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+-	has_rate = FALSE;
+-    }
+-    
+-    SECURITY_VERIFY_DRAWABLE(pDraw, stuff->drawable, client,
+-			     SecurityWriteAccess);
+-
+-    pScreen = pDraw->pScreen;
+-
+-    pScrPriv = rrGetScrPriv(pScreen);
+-    
+-    time = ClientTimeToServerTime(stuff->timestamp);
+-    configTime = ClientTimeToServerTime(stuff->configTimestamp);
+-    
+-    oldWidth = pScreen->width;
+-    oldHeight = pScreen->height;
+-    
+-    if (!pScrPriv)
+-    {
+-	time = currentTime;
+-	rep.status = RRSetConfigFailed;
+-	goto sendReply;
+-    }
+-    if (!RRGetInfo (pScreen))
+-	return BadAlloc;
+-    
+-    /*
+-     * if the client's config timestamp is not the same as the last config
+-     * timestamp, then the config information isn't up-to-date and
+-     * can't even be validated
+-     */
+-    if (CompareTimeStamps (configTime, pScrPriv->lastConfigTime) != 0)
+-    {
+-	rep.status = RRSetConfigInvalidConfigTime;
+-	goto sendReply;
+-    }
+-    
+-    /*
+-     * Search for the requested size
+-     */
+-    pSize = 0;
+-    for (i = 0; i < pScrPriv->nSizes; i++)
+-    {
+-	pSize = &pScrPriv->pSizes[i];
+-	if (pSize->referenced && pSize->id == stuff->sizeID)
+-	{
+-	    break;
+-	}
+-    }
+-    if (i == pScrPriv->nSizes)
+-    {
+-	/*
+-	 * Invalid size ID
+-	 */
+-	client->errorValue = stuff->sizeID;
+-	return BadValue;
+-    }
++    rrScrPriv (pScreen);
++    int i;
+     
+-    /*
+-     * Validate requested rotation
+-     */
+-    rotation = (Rotation) stuff->rotation;
+-
+-    /* test the rotation bits only! */
+-    switch (rotation & 0xf) {
+-    case RR_Rotate_0:
+-    case RR_Rotate_90:
+-    case RR_Rotate_180:
+-    case RR_Rotate_270:
+-	break;
+-    default:
+-	/*
+-	 * Invalid rotation
+-	 */
+-	client->errorValue = stuff->rotation;
+-	return BadValue;
+-    }
+-
+-    if ((~pScrPriv->rotations) & rotation)
++    if (pScrPriv->changed)
+     {
+-	/*
+-	 * requested rotation or reflection not supported by screen
+-	 */
+-	client->errorValue = stuff->rotation;
+-	return BadMatch;
+-    }
+-
+-    /*
+-     * Validate requested refresh
+-     */
+-    if (has_rate)
+-	rate = (int) stuff->rate;
+-    else
+-	rate = 0;
+-
+-    if (rate)
+-    {
+-	for (i = 0; i < pSize->nRates; i++)
++	UpdateCurrentTime ();
++	if (pScrPriv->configChanged)
+ 	{
+-	    RRScreenRatePtr pRate = &pSize->pRates[i];
+-	    if (pRate->referenced && pRate->rate == rate)
+-		break;
++	    pScrPriv->lastConfigTime = currentTime;
++	    pScrPriv->configChanged = FALSE;
+ 	}
+-	if (i == pSize->nRates)
+-	{
+-	    /*
+-	     * Invalid rate
+-	     */
+-	    client->errorValue = rate;
+-	    return BadValue;
++	pScrPriv->changed = FALSE;
++	WalkTree (pScreen, TellChanged, (pointer) pScreen);
++	for (i = 0; i < pScrPriv->numOutputs; i++)
++	    pScrPriv->outputs[i]->changed = FALSE;
++	for (i = 0; i < pScrPriv->numCrtcs; i++)
++	    pScrPriv->crtcs[i]->changed = FALSE;
++	if (pScrPriv->layoutChanged)
++	{
++	    pScrPriv->layoutChanged = FALSE;
++	    RRPointerScreenConfigured (pScreen);
++	    RRSendConfigNotify (pScreen);
+ 	}
+     }
+-    
+-    /*
+-     * Make sure the requested set-time is not older than
+-     * the last set-time
+-     */
+-    if (CompareTimeStamps (time, pScrPriv->lastSetTime) < 0)
+-    {
+-	rep.status = RRSetConfigInvalidTime;
+-	goto sendReply;
+-    }
+-
+-    /*
+-     * call out to ddx routine to effect the change
+-     */
+-    if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+-				   pSize))
+-    {
+-	/*
+-	 * unknown DDX failure, report to client
+-	 */
+-	rep.status = RRSetConfigFailed;
+-	goto sendReply;
+-    }
+-    
+-    /*
+-     * set current extension configuration pointers
+-     */
+-    RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+-    
+-    /*
+-     * Deliver ScreenChangeNotify events whenever
+-     * the configuration is updated
+-     */
+-    WalkTree (pScreen, TellChanged, (pointer) pScreen);
+-    
+-    /*
+-     * Deliver ConfigureNotify events when root changes
+-     * pixel size
+-     */
+-    if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+-	RRSendConfigNotify (pScreen);
+-    RREditConnectionInfo (pScreen);
+-    
+-    /*
+-     * Fix pointer bounds and location
+-     */
+-    ScreenRestructured (pScreen);
+-    pScrPriv->lastSetTime = time;
+-    
+-    /*
+-     * Report Success
+-     */
+-    rep.status = RRSetConfigSuccess;
+-    
+-sendReply:
+-    
+-    rep.type = X_Reply;
+-    /* rep.status has already been filled in */
+-    rep.length = 0;
+-    rep.sequenceNumber = client->sequence;
+-
+-    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+-    rep.newConfigTimestamp = pScrPriv->lastConfigTime.milliseconds;
+-    rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+-
+-    if (client->swapped) 
+-    {
+-    	swaps(&rep.sequenceNumber, n);
+-    	swapl(&rep.length, n);
+-	swapl(&rep.newTimestamp, n);
+-	swapl(&rep.newConfigTimestamp, n);
+-	swapl(&rep.root, n);
+-    }
+-    WriteToClient(client, sizeof(xRRSetScreenConfigReply), (char *)&rep);
+-
+-    return (client->noClientException);
+ }
+ 
+-int
+-RRSetScreenConfig (ScreenPtr		pScreen,
+-		   Rotation		rotation,
+-		   int			rate,
+-		   RRScreenSizePtr	pSize)
++/*
++ * Return the first output which is connected to an active CRTC
++ * Used in emulating 1.0 behaviour
++ */
++RROutputPtr
++RRFirstOutput (ScreenPtr pScreen)
+ {
+-    rrScrPrivPtr	    pScrPriv;
+-    int			    i;
+-    short		    oldWidth, oldHeight;
+-
+-    pScrPriv = rrGetScrPriv(pScreen);
+-    
+-    oldWidth = pScreen->width;
+-    oldHeight = pScreen->height;
+-    
+-    if (!RRGetInfo (pScreen))
+-	return BadAlloc;
++    rrScrPriv(pScreen);
++    RROutputPtr		    output;
++    int	i, j;
+     
+-    /*
+-     * Validate requested rotation
+-     */
+-
+-    /* test the rotation bits only! */
+-    switch (rotation & 0xf) {
+-    case RR_Rotate_0:
+-    case RR_Rotate_90:
+-    case RR_Rotate_180:
+-    case RR_Rotate_270:
+-	break;
+-    default:
+-	/*
+-	 * Invalid rotation
+-	 */
+-	return BadValue;
+-    }
+-
+-    if ((~pScrPriv->rotations) & rotation)
+-    {
+-	/*
+-	 * requested rotation or reflection not supported by screen
+-	 */
+-	return BadMatch;
+-    }
+-
+-    /*
+-     * Validate requested refresh
+-     */
+-    if (rate)
++    for (i = 0; i < pScrPriv->numCrtcs; i++)
+     {
+-	for (i = 0; i < pSize->nRates; i++)
+-	{
+-	    RRScreenRatePtr pRate = &pSize->pRates[i];
+-	    if (pRate->referenced && pRate->rate == rate)
+-		break;
+-	}
+-	if (i == pSize->nRates)
++	RRCrtcPtr   crtc = pScrPriv->crtcs[i];
++	for (j = 0; j < pScrPriv->numOutputs; j++)
+ 	{
+-	    /*
+-	     * Invalid rate
+-	     */
+-	    return BadValue;
++	    output = pScrPriv->outputs[j];
++	    if (output->crtc == crtc)
++		return output;
+ 	}
+     }
+-
+-    /*
+-     * call out to ddx routine to effect the change
+-     */
+-    if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+-				   pSize))
+-    {
+-	/*
+-	 * unknown DDX failure, report to client
+-	 */
+-        return BadImplementation;
+-    }
+-    
+-    /*
+-     * set current extension configuration pointers
+-     */
+-    RRSetCurrentConfig (pScreen, rotation, rate, pSize);
+-    
+-    /*
+-     * Deliver ScreenChangeNotify events whenever
+-     * the configuration is updated
+-     */
+-    WalkTree (pScreen, TellChanged, (pointer) pScreen);
+-    
+-    /*
+-     * Deliver ConfigureNotify events when root changes
+-     * pixel size
+-     */
+-    if (oldWidth != pScreen->width || oldHeight != pScreen->height)
+-	RRSendConfigNotify (pScreen);
+-    RREditConnectionInfo (pScreen);
+-    
+-    /*
+-     * Fix pointer bounds and location
+-     */
+-    ScreenRestructured (pScreen);
+-    
+-    return Success;
++    return NULL;
+ }
+ 
+-static int
+-ProcRRSelectInput (ClientPtr client)
++CARD16
++RRVerticalRefresh (xRRModeInfo *mode)
+ {
+-    REQUEST(xRRSelectInputReq);
+-    rrClientPriv(client);
+-    RRTimesPtr	pTimes;
+-    WindowPtr	pWin;
+-    RREventPtr	pRREvent, pNewRREvent, *pHead;
+-    XID		clientResource;
+-
+-    REQUEST_SIZE_MATCH(xRRSelectInputReq);
+-    pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
+-    if (!pWin)
+-	return BadWindow;
+-    pHead = (RREventPtr *)SecurityLookupIDByType(client,
+-						 pWin->drawable.id, EventType,
+-						 SecurityWriteAccess);
+-
+-    if (stuff->enable & (RRScreenChangeNotifyMask)) 
+-    {
+-	ScreenPtr	pScreen = pWin->drawable.pScreen;
+-	rrScrPriv	(pScreen);
+-
+-	if (pHead) 
+-	{
+-	    /* check for existing entry. */
+-	    for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
+-		if (pRREvent->client == client)
+-		    return Success;
+-	}
+-
+-	/* build the entry */
+-	pNewRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
+-	if (!pNewRREvent)
+-	    return BadAlloc;
+-	pNewRREvent->next = 0;
+-	pNewRREvent->client = client;
+-	pNewRREvent->window = pWin;
+-	pNewRREvent->mask = stuff->enable;
+-	/*
+-	 * add a resource that will be deleted when
+-	 * the client goes away
+-	 */
+-	clientResource = FakeClientID (client->index);
+-	pNewRREvent->clientResource = clientResource;
+-	if (!AddResource (clientResource, ClientType, (pointer)pNewRREvent))
+-	    return BadAlloc;
+-	/*
+-	 * create a resource to contain a pointer to the list
+-	 * of clients selecting input.  This must be indirect as
+-	 * the list may be arbitrarily rearranged which cannot be
+-	 * done through the resource database.
+-	 */
+-	if (!pHead)
+-	{
+-	    pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
+-	    if (!pHead ||
+-		!AddResource (pWin->drawable.id, EventType, (pointer)pHead))
+-	    {
+-		FreeResource (clientResource, RT_NONE);
+-		return BadAlloc;
+-	    }
+-	    *pHead = 0;
+-	}
+-	pNewRREvent->next = *pHead;
+-	*pHead = pNewRREvent;
+-	/*
+-	 * Now see if the client needs an event
+-	 */
+-	if (pScrPriv)
+-	{
+-	    pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
+-	    if (CompareTimeStamps (pTimes->setTime, 
+-				   pScrPriv->lastSetTime) != 0 ||
+-		CompareTimeStamps (pTimes->configTime, 
+-				   pScrPriv->lastConfigTime) != 0)
+-	    {
+-		TellChanged (pWin, (pointer) pScreen);
+-	    }
+-	}
+-    }
+-    else if (stuff->enable == xFalse) 
+-    {
+-	/* delete the interest */
+-	if (pHead) {
+-	    pNewRREvent = 0;
+-	    for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
+-		if (pRREvent->client == client)
+-		    break;
+-		pNewRREvent = pRREvent;
+-	    }
+-	    if (pRREvent) {
+-		FreeResource (pRREvent->clientResource, ClientType);
+-		if (pNewRREvent)
+-		    pNewRREvent->next = pRREvent->next;
+-		else
+-		    *pHead = pRREvent->next;
+-		xfree (pRREvent);
+-	    }
+-	}
+-    }
+-    else 
+-    {
+-	client->errorValue = stuff->enable;
+-	return BadValue;
+-    }
+-    return Success;
++    CARD32  refresh;
++    CARD32  dots = mode->hTotal * mode->vTotal;
++    if (!dots)
++	return 0;
++    refresh = (mode->dotClock + dots/2) / dots;
++    if (refresh > 0xffff)
++	refresh = 0xffff;
++    return (CARD16) refresh;
+ }
+ 
+-
+ static int
+ ProcRRDispatch (ClientPtr client)
+ {
+     REQUEST(xReq);
+-    switch (stuff->data)
+-    {
+-    case X_RRQueryVersion:
+-	return ProcRRQueryVersion(client);
+-    case X_RRSetScreenConfig:
+-        return ProcRRSetScreenConfig(client);
+-    case X_RRSelectInput:
+-        return ProcRRSelectInput(client);
+-    case X_RRGetScreenInfo:
+-        return ProcRRGetScreenInfo(client);
+-    default:
++    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
+ 	return BadRequest;
+-    }
+-}
+-
+-static int
+-SProcRRQueryVersion (ClientPtr client)
+-{
+-    register int n;
+-    REQUEST(xRRQueryVersionReq);
+-
+-    swaps(&stuff->length, n);
+-    swapl(&stuff->majorVersion, n);
+-    swapl(&stuff->minorVersion, n);
+-    return ProcRRQueryVersion(client);
+-}
+-
+-static int
+-SProcRRGetScreenInfo (ClientPtr client)
+-{
+-    register int n;
+-    REQUEST(xRRGetScreenInfoReq);
+-
+-    swaps(&stuff->length, n);
+-    swapl(&stuff->window, n);
+-    return ProcRRGetScreenInfo(client);
+-}
+-
+-static int
+-SProcRRSetScreenConfig (ClientPtr client)
+-{
+-    register int n;
+-    REQUEST(xRRSetScreenConfigReq);
+-
+-    if (RRClientKnowsRates (client))
+-    {
+-	REQUEST_SIZE_MATCH (xRRSetScreenConfigReq);
+-	swaps (&stuff->rate, n);
+-    }
+-    else
+-    {
+-	REQUEST_SIZE_MATCH (xRR1_0SetScreenConfigReq);
+-    }
+-    
+-    swaps(&stuff->length, n);
+-    swapl(&stuff->drawable, n);
+-    swapl(&stuff->timestamp, n);
+-    swaps(&stuff->sizeID, n);
+-    swaps(&stuff->rotation, n);
+-    return ProcRRSetScreenConfig(client);
+-}
+-
+-static int
+-SProcRRSelectInput (ClientPtr client)
+-{
+-    register int n;
+-    REQUEST(xRRSelectInputReq);
+-
+-    swaps(&stuff->length, n);
+-    swapl(&stuff->window, n);
+-    return ProcRRSelectInput(client);
++    return (*ProcRandrVector[stuff->data]) (client);
+ }
+ 
+-
+ static int
+ SProcRRDispatch (ClientPtr client)
+ {
+     REQUEST(xReq);
+-    switch (stuff->data)
+-    {
+-    case X_RRQueryVersion:
+-	return SProcRRQueryVersion(client);
+-    case X_RRSetScreenConfig:
+-        return SProcRRSetScreenConfig(client);
+-    case X_RRSelectInput:
+-        return SProcRRSelectInput(client);
+-    case X_RRGetScreenInfo:
+-        return SProcRRGetScreenInfo(client);
+-    default:
++    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
+ 	return BadRequest;
+-    }
+-}
+-
+-
+-static Bool
+-RRScreenSizeMatches (RRScreenSizePtr  a,
+-		   RRScreenSizePtr  b)
+-{
+-    if (a->width != b->width)
+-	return FALSE;
+-    if (a->height != b->height)
+-	return FALSE;
+-    if (a->mmWidth != b->mmWidth)
+-	return FALSE;
+-    if (a->mmHeight != b->mmHeight)
+-	return FALSE;
+-    return TRUE;
+-}
+-
+-RRScreenSizePtr
+-RRRegisterSize (ScreenPtr	    pScreen,
+-		short		    width, 
+-		short		    height,
+-		short		    mmWidth,
+-		short		    mmHeight)
+-{
+-    rrScrPriv (pScreen);
+-    int		    i;
+-    RRScreenSize    tmp;
+-    RRScreenSizePtr pNew;
+-
+-    if (!pScrPriv)
+-	return 0;
+-    
+-    tmp.width = width;
+-    tmp.height= height;
+-    tmp.mmWidth = mmWidth;
+-    tmp.mmHeight = mmHeight;
+-    tmp.pRates = 0;
+-    tmp.nRates = 0;
+-    tmp.nRatesInUse = 0;
+-    tmp.referenced = TRUE;
+-    tmp.oldReferenced = FALSE;
+-    for (i = 0; i < pScrPriv->nSizes; i++)
+-	if (RRScreenSizeMatches (&tmp, &pScrPriv->pSizes[i]))
+-	{
+-	    pScrPriv->pSizes[i].referenced = TRUE;
+-	    return &pScrPriv->pSizes[i];
+-	}
+-    pNew = xrealloc (pScrPriv->pSizes,
+-		     (pScrPriv->nSizes + 1) * sizeof (RRScreenSize));
+-    if (!pNew)
+-	return 0;
+-    pNew[pScrPriv->nSizes++] = tmp;
+-    pScrPriv->pSizes = pNew;
+-    return &pNew[pScrPriv->nSizes-1];
+-}
+-
+-Bool RRRegisterRate (ScreenPtr		pScreen,
+-		     RRScreenSizePtr	pSize,
+-		     int		rate)
+-{
+-    rrScrPriv(pScreen);
+-    int		    i;
+-    RRScreenRatePtr pNew, pRate;
+-
+-    if (!pScrPriv)
+-	return FALSE;
+-    
+-    for (i = 0; i < pSize->nRates; i++)
+-    {
+-	pRate = &pSize->pRates[i];
+-	if (pRate->rate == rate)
+-	{
+-	    pRate->referenced = TRUE;
+-	    return TRUE;
+-	}
+-    }
+-
+-    pNew = xrealloc (pSize->pRates,
+-		     (pSize->nRates + 1) * sizeof (RRScreenRate));
+-    if (!pNew)
+-	return FALSE;
+-    pRate = &pNew[pSize->nRates++];
+-    pRate->rate = rate;
+-    pRate->referenced = TRUE;
+-    pRate->oldReferenced = FALSE;
+-    pSize->pRates = pNew;
+-    return TRUE;
++    return (*SProcRandrVector[stuff->data]) (client);
+ }
+ 
+-void
+-RRSetCurrentConfig (ScreenPtr		pScreen,
+-		    Rotation		rotation,
+-		    int			rate,
+-		    RRScreenSizePtr	pSize)
+-{
+-    rrScrPriv (pScreen);
+-
+-    if (!pScrPriv)
+-	return;
+-
+-    pScrPriv->rotation = rotation;
+-    pScrPriv->size = pSize - pScrPriv->pSizes;
+-    pScrPriv->rate = rate;
+-}
+Only in ./nx-X11/programs/Xserver/randr: randr.c.NX.original
+Only in ./nx-X11/programs/Xserver/randr: randr.c.X.original
+Only in ./nx-X11/programs/Xserver/randr: randr.h
+Only in ./nx-X11/programs/Xserver/randr: randr.h.NX.original
+Only in ./nx-X11/programs/Xserver/randr: randr.h.X.original
+Only in ./nx-X11/programs/Xserver/randr: randrproto.h
+Only in ./nx-X11/programs/Xserver/randr: randrproto.h.NX.original
+Only in ./nx-X11/programs/Xserver/randr: randrproto.h.X.original
+diff -u ./nx-X11/programs/Xserver/randr.X.original/randrstr.h ./nx-X11/programs/Xserver/randr/randrstr.h
+--- ./nx-X11/programs/Xserver/randr.X.original/randrstr.h	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/randrstr.h	2015-02-10 19:13:13.636692176 +0100
+@@ -1,25 +1,28 @@
+ /*
+- * $XFree86: xc/programs/Xserver/randr/randrstr.h,v 1.5 2002/09/29 23:39:45 keithp Exp $
+- *
+  * Copyright © 2000 Compaq Computer Corporation
++ * Copyright © 2002 Hewlett-Packard Company
++ * Copyright © 2006 Intel Corporation
+  *
+  * Permission to use, copy, modify, distribute, and sell this software and its
+  * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appear in all copies and that both that
+- * copyright notice and this permission notice appear in supporting
+- * documentation, and that the name of Compaq not be used in
+- * advertising or publicity pertaining to distribution of the software without
+- * specific, written prior permission.  Compaq makes no
+- * representations about the suitability of this software for any purpose.  It
+- * is provided "as is" without express or implied warranty.
++ * the above copyright notice appear in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * that the name of the copyright holders not be used in advertising or
++ * publicity pertaining to distribution of the software without specific,
++ * written prior permission.  The copyright holders make no representations
++ * about the suitability of this software for any purpose.  It is provided "as
++ * is" without express or implied warranty.
+  *
+- * COMPAQ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+- * EVENT SHALL COMPAQ BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+- * PERFORMANCE OF THIS SOFTWARE.
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++ * OF THIS SOFTWARE.
++ *
++ * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
++ *	    Keith Packard, Intel Corporation
+  */
+ 
+ #ifdef HAVE_DIX_CONFIG_H
+@@ -29,68 +32,456 @@
+ #ifndef _RANDRSTR_H_
+ #define _RANDRSTR_H_
+ 
++#include <X11/X.h>
++#include <X11/Xproto.h>
++#include "misc.h"
++#include "os.h"
++#include "dixstruct.h"
++#include "resource.h"
++#include "scrnintstr.h"
++#include "windowstr.h"
++#include "pixmapstr.h"
++#include "extnsionst.h"
++#include "servermd.h"
++#ifndef NXAGENT_SERVER
+ #include <X11/extensions/randr.h>
++#include <X11/extensions/randrproto.h>
++#else
++#include "randr.h"
++#include "randrproto.h"
++#endif
++#ifdef RENDER
++#include <X11/extensions/render.h> 	/* we share subpixel order information */
++#include "picturestr.h"
++#endif
++#include <X11/Xfuncproto.h>
++
++/* required for ABI compatibility for now */
++#define RANDR_10_INTERFACE 1
++#define RANDR_12_INTERFACE 1
++
++typedef XID	RRMode;
++typedef XID	RROutput;
++typedef XID	RRCrtc;
++
++extern int	RREventBase, RRErrorBase;
++
++extern int (*ProcRandrVector[RRNumberRequests])(ClientPtr);
++extern int (*SProcRandrVector[RRNumberRequests])(ClientPtr);
++    
++/*
++ * Modeline for a monitor. Name follows directly after this struct
++ */
++
++#define RRModeName(pMode) ((char *) (pMode + 1))
++typedef struct _rrMode		RRModeRec, *RRModePtr;
++typedef struct _rrPropertyValue	RRPropertyValueRec, *RRPropertyValuePtr;
++typedef struct _rrProperty	RRPropertyRec, *RRPropertyPtr;
++typedef struct _rrCrtc		RRCrtcRec, *RRCrtcPtr;
++typedef struct _rrOutput	RROutputRec, *RROutputPtr;
++
++struct _rrMode {
++    int		    refcnt;
++    xRRModeInfo	    mode;
++    char	    *name;
++    ScreenPtr	    userScreen;
++};
++
++struct _rrPropertyValue {
++    Atom	    type;       /* ignored by server */
++    short	    format;     /* format of data for swapping - 8,16,32 */
++    long	    size;	/* size of data in (format/8) bytes */
++    pointer         data;	/* private to client */
++};
++
++struct _rrProperty {
++    RRPropertyPtr   next;
++    ATOM 	    propertyName;
++    Bool	    is_pending;
++    Bool	    range;
++    Bool	    immutable;
++    int		    num_valid;
++    INT32	    *valid_values;
++    RRPropertyValueRec	current, pending;
++};
++
++struct _rrCrtc {
++    RRCrtc	    id;
++    ScreenPtr	    pScreen;
++    RRModePtr	    mode;
++    int		    x, y;
++    Rotation	    rotation;
++    Rotation	    rotations;
++    Bool	    changed;
++    int		    numOutputs;
++    RROutputPtr	    *outputs;
++    int		    gammaSize;
++    CARD16	    *gammaRed;
++    CARD16	    *gammaBlue;
++    CARD16	    *gammaGreen;
++    void	    *devPrivate;
++};
++
++struct _rrOutput {
++    RROutput	    id;
++    ScreenPtr	    pScreen;
++    char	    *name;
++    int		    nameLength;
++    CARD8	    connection;
++    CARD8	    subpixelOrder;
++    int		    mmWidth;
++    int		    mmHeight;
++    RRCrtcPtr	    crtc;
++    int		    numCrtcs;
++    RRCrtcPtr	    *crtcs;
++    int		    numClones;
++    RROutputPtr	    *clones;
++    int		    numModes;
++    int		    numPreferred;
++    RRModePtr	    *modes;
++    int		    numUserModes;
++    RRModePtr	    *userModes;
++    Bool	    changed;
++    RRPropertyPtr   properties;
++    Bool	    pendingProperties;
++    void	    *devPrivate;
++};
++
++#if RANDR_12_INTERFACE
++typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr	pScreen,
++					CARD16		width,
++					CARD16		height,
++					CARD32		mmWidth,
++					CARD32		mmHeight);
++					
++typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr		pScreen,
++				  RRCrtcPtr		crtc,
++				  RRModePtr		mode,
++				  int			x,
++				  int			y,
++				  Rotation		rotation,
++				  int			numOutputs,
++				  RROutputPtr		*outputs);
++
++typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr	pScreen,
++				       RRCrtcPtr	crtc);
++
++typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr		pScreen,
++					    RROutputPtr		output,
++					    Atom		property,
++					    RRPropertyValuePtr	value);
++
++typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr		pScreen,
++					     RROutputPtr	output,
++					     RRModePtr		mode);
++
++typedef void (*RRModeDestroyProcPtr) (ScreenPtr	    pScreen,
++				      RRModePtr	    mode);
++
++#endif
++
++typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
++typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
+ 
+-typedef struct _rrScreenRate {
+-    int		    rate;
+-    Bool	    referenced;
+-    Bool	    oldReferenced;
++/* These are for 1.0 compatibility */
++ 
++typedef struct _rrRefresh {
++    CARD16	    rate;
++    RRModePtr	    mode;
+ } RRScreenRate, *RRScreenRatePtr;
+ 
+ typedef struct _rrScreenSize {
+     int		    id;
+     short	    width, height;
+     short	    mmWidth, mmHeight;
+-    RRScreenRatePtr pRates;
+     int		    nRates;
+-    int		    nRatesInUse;
+-    Bool	    referenced;
+-    Bool	    oldReferenced;
++    RRScreenRatePtr pRates;
+ } RRScreenSize, *RRScreenSizePtr;
+ 
++#ifdef RANDR_10_INTERFACE
++
+ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr		pScreen,
+ 				    Rotation		rotation,
+ 				    int			rate,
+ 				    RRScreenSizePtr	pSize);
+ 
+-typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
+-typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
++#endif
+ 	
++
+ typedef struct _rrScrPriv {
++    /*
++     * 'public' part of the structure; DDXen fill this in
++     * as they initialize
++     */
++#if RANDR_10_INTERFACE
+     RRSetConfigProcPtr	    rrSetConfig;
++#endif
+     RRGetInfoProcPtr	    rrGetInfo;
++#if RANDR_12_INTERFACE
++    RRScreenSetSizeProcPtr  rrScreenSetSize;
++    RRCrtcSetProcPtr	    rrCrtcSet;
++    RRCrtcSetGammaProcPtr   rrCrtcSetGamma;
++    RROutputSetPropertyProcPtr	rrOutputSetProperty;
++    RROutputValidateModeProcPtr	rrOutputValidateMode;
++    RRModeDestroyProcPtr	rrModeDestroy;
++#endif
+     
++    /*
++     * Private part of the structure; not considered part of the ABI
++     */
+     TimeStamp		    lastSetTime;	/* last changed by client */
+     TimeStamp		    lastConfigTime;	/* possible configs changed */
+     RRCloseScreenProcPtr    CloseScreen;
+ 
++    Bool		    changed;		/* some config changed */
++    Bool		    configChanged;	/* configuration changed */
++    Bool		    layoutChanged;	/* screen layout changed */
++
++    CARD16		    minWidth, minHeight;
++    CARD16		    maxWidth, maxHeight;
++    CARD16		    width, height;	/* last known screen size */
++    CARD16		    mmWidth, mmHeight;	/* last known screen size */
++
++    int			    numOutputs;
++    RROutputPtr		    *outputs;
++
++    int			    numCrtcs;
++    RRCrtcPtr		    *crtcs;
++
++    /* Last known pointer position */
++    RRCrtcPtr		    pointerCrtc;
++
++#ifdef RANDR_10_INTERFACE
+     /*
+      * Configuration information
+      */
+     Rotation		    rotations;
++    CARD16		    reqWidth, reqHeight;
+     
+     int			    nSizes;
+-    int			    nSizesInUse;
+     RRScreenSizePtr	    pSizes;
+-
+-    /*
+-     * Current state
+-     */
++    
+     Rotation		    rotation;
+-    int			    size;
+     int			    rate;
++    int			    size;
++#endif
+ } rrScrPrivRec, *rrScrPrivPtr;
+ 
++#ifndef NXAGENT_SERVER
++extern DevPrivateKey rrPrivKey;
++#else
+ extern int rrPrivIndex;
++#endif
++
++#ifndef NXAGENT_SERVER
++
++#define rrGetScrPriv(pScr)  ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey))
++#define rrScrPriv(pScr)	rrScrPrivPtr    pScrPriv = rrGetScrPriv(pScr)
++#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p)
++
++#else
+ 
+ #define rrGetScrPriv(pScr)  ((rrScrPrivPtr) (pScr)->devPrivates[rrPrivIndex].ptr)
+ #define rrScrPriv(pScr)	rrScrPrivPtr    pScrPriv = rrGetScrPriv(pScr)
+ #define SetRRScreen(s,p) ((s)->devPrivates[rrPrivIndex].ptr = (pointer) (p))
+ 
++#endif
++
++/*
++ * each window has a list of clients requesting
++ * RRNotify events.  Each client has a resource
++ * for each window it selects RRNotify input for,
++ * this resource is used to delete the RRNotifyRec
++ * entry from the per-window queue.
++ */
++
++typedef struct _RREvent *RREventPtr;
++
++typedef struct _RREvent {
++    RREventPtr  next;
++    ClientPtr	client;
++    WindowPtr	window;
++    XID		clientResource;
++    int		mask;
++} RREventRec;
++
++typedef struct _RRTimes {
++    TimeStamp	setTime;
++    TimeStamp	configTime;
++} RRTimesRec, *RRTimesPtr;
++
++typedef struct _RRClient {
++    int		major_version;
++    int		minor_version;
++/*  RRTimesRec	times[0]; */
++} RRClientRec, *RRClientPtr;
++
++extern RESTYPE	RRClientType, RREventType; /* resource types for event masks */
++#ifndef NXAGENT_SERVER
++extern DevPrivateKey RRClientPrivateKey;
++#else
++extern int	RRClientPrivateIndex;
++#endif
++extern RESTYPE	RRCrtcType, RRModeType, RROutputType;
++
++#define LookupOutput(client,id,a) ((RROutputPtr) \
++				   (SecurityLookupIDByType (client, id, \
++							    RROutputType, a)))
++#define LookupCrtc(client,id,a) ((RRCrtcPtr) \
++				 (SecurityLookupIDByType (client, id, \
++							  RRCrtcType, a)))
++#define LookupMode(client,id,a) ((RRModePtr) \
++				 (SecurityLookupIDByType (client, id, \
++							  RRModeType, a)))
++#ifndef NXAGENT_SERVER
++
++#define GetRRClient(pClient)    ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
++#define rrClientPriv(pClient)	RRClientPtr pRRClient = GetRRClient(pClient)
++
++#else
++
++#define GetRRClient(pClient)    ((RRClientPtr) (pClient)->devPrivates[RRClientPrivateIndex].ptr)
++#define rrClientPriv(pClient)	RRClientPtr pRRClient = GetRRClient(pClient)
++
++#define DixUnknownAccess     SecurityUnknownAccess
++#define DixReadAccess        SecurityReadAccess   
++#define DixWriteAccess       SecurityWriteAccess  
++#define DixDestroyAccess     SecurityDestroyAccess
++
++#endif
++
+ /* Initialize the extension */
+ void
+ RRExtensionInit (void);
+ 
++#ifdef RANDR_12_INTERFACE
++/*
++ * Set the range of sizes for the screen
++ */
++void
++RRScreenSetSizeRange (ScreenPtr	pScreen,
++		      CARD16	minWidth,
++		      CARD16	minHeight,
++		      CARD16	maxWidth,
++		      CARD16	maxHeight);
++#endif
++
++/* rrscreen.c */
++/*
++ * Notify the extension that the screen size has been changed.
++ * The driver is responsible for calling this whenever it has changed
++ * the size of the screen
++ */
++void
++RRScreenSizeNotify (ScreenPtr	pScreen);
++
++/*
++ * Request that the screen be resized
++ */
++Bool
++RRScreenSizeSet (ScreenPtr  pScreen,
++		 CARD16	    width,
++		 CARD16	    height,
++		 CARD32	    mmWidth,
++		 CARD32	    mmHeight);
++
++/*
++ * Send ConfigureNotify event to root window when 'something' happens
++ */
++void
++RRSendConfigNotify (ScreenPtr pScreen);
++    
++/*
++ * screen dispatch
++ */
++int 
++ProcRRGetScreenSizeRange (ClientPtr client);
++
++int
++ProcRRSetScreenSize (ClientPtr client);
++
++int
++ProcRRGetScreenResources (ClientPtr client);
++
++int
++ProcRRSetScreenConfig (ClientPtr client);
++
++int
++ProcRRGetScreenInfo (ClientPtr client);
++
++/*
++ * Deliver a ScreenNotify event
++ */
++void
++RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
++    
++/* mirandr.c */
++Bool
++miRandRInit (ScreenPtr pScreen);
++
++Bool
++miRRGetInfo (ScreenPtr pScreen, Rotation *rotations);
++
++Bool
++miRRGetScreenInfo (ScreenPtr pScreen);
++
++Bool
++miRRCrtcSet (ScreenPtr	pScreen,
++	     RRCrtcPtr	crtc,
++	     RRModePtr	mode,
++	     int	x,
++	     int	y,
++	     Rotation	rotation,
++	     int	numOutput,
++	     RROutputPtr *outputs);
++
++Bool
++miRROutputSetProperty (ScreenPtr	    pScreen,
++		       RROutputPtr	    output,
++		       Atom		    property,
++		       RRPropertyValuePtr   value);
++
++Bool
++miRROutputValidateMode (ScreenPtr	    pScreen,
++			RROutputPtr	    output,
++			RRModePtr	    mode);
++
++void
++miRRModeDestroy (ScreenPtr  pScreen,
++		 RRModePtr  mode);
++
++/* randr.c */
++/*
++ * Send all pending events
++ */
++void
++RRTellChanged (ScreenPtr pScreen);
++
++/*
++ * Poll the driver for changed information
++ */
++Bool
++RRGetInfo (ScreenPtr pScreen);
++
++Bool RRInit (void);
++
++Bool RRScreenInit(ScreenPtr pScreen);
++
++RROutputPtr
++RRFirstOutput (ScreenPtr pScreen);
++
++Rotation
++RRGetRotation (ScreenPtr pScreen);
++
++CARD16
++RRVerticalRefresh (xRRModeInfo *mode);
++
++#ifdef RANDR_10_INTERFACE					
++/*
++ * This is the old interface, deprecated but left
++ * around for compatibility
++ */
++
+ /*
+  * Then, register the specific size with the screen
+  */
+@@ -116,7 +507,10 @@
+ 		    int			rate,
+ 		    RRScreenSizePtr	pSize);
+ 
+-Bool RRScreenInit(ScreenPtr pScreen);
++Bool RRScreenInit (ScreenPtr pScreen);
++
++Rotation
++RRGetRotation (ScreenPtr pScreen);
+ 
+ int
+ RRSetScreenConfig (ScreenPtr		pScreen,
+@@ -124,19 +518,371 @@
+ 		   int			rate,
+ 		   RRScreenSizePtr	pSize);
+ 
++#endif					
++
++/* rrcrtc.c */
++
++/*
++ * Notify the CRTC of some change; layoutChanged indicates that
++ * some position or size element changed
++ */
++void
++RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
++
++/*
++ * Create a CRTC
++ */
++RRCrtcPtr
++RRCrtcCreate (ScreenPtr pScreen, void	*devPrivate);
++
++/*
++ * Set the allowed rotations on a CRTC
++ */
++void
++RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
++
++/*
++ * Notify the extension that the Crtc has been reconfigured,
++ * the driver calls this whenever it has updated the mode
++ */
++Bool
++RRCrtcNotify (RRCrtcPtr	    crtc,
++	      RRModePtr	    mode,
++	      int	    x,
++	      int	    y,
++	      Rotation	    rotation,
++	      int	    numOutputs,
++	      RROutputPtr   *outputs);
++
++void
++RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
++    
++/*
++ * Request that the Crtc be reconfigured
++ */
+ Bool
+-miRandRInit (ScreenPtr pScreen);
++RRCrtcSet (RRCrtcPtr    crtc,
++	   RRModePtr	mode,
++	   int		x,
++	   int		y,
++	   Rotation	rotation,
++	   int		numOutput,
++	   RROutputPtr  *outputs);
++
++/*
++ * Request that the Crtc gamma be changed
++ */
+ 
+ Bool
+-miRRGetInfo (ScreenPtr pScreen, Rotation *rotations);
++RRCrtcGammaSet (RRCrtcPtr   crtc,
++		CARD16	    *red,
++		CARD16	    *green,
++		CARD16	    *blue);
++
++/*
++ * Notify the extension that the Crtc gamma has been changed
++ * The driver calls this whenever it has changed the gamma values
++ * in the RRCrtcRec
++ */
+ 
+ Bool
+-miRRSetConfig (ScreenPtr	pScreen,
+-	       Rotation		rotation,
+-	       int		rate,
+-	       RRScreenSizePtr	size);
++RRCrtcGammaNotify (RRCrtcPtr	crtc);
++
++/*
++ * Set the size of the gamma table at server startup time
++ */
+ 
+ Bool
+-miRRGetScreenInfo (ScreenPtr pScreen);
++RRCrtcGammaSetSize (RRCrtcPtr	crtc,
++		    int		size);
++
++/*
++ * Return the area of the frame buffer scanned out by the crtc,
++ * taking into account the current mode and rotation
++ */
++
++void
++RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
++
++/*
++ * Destroy a Crtc at shutdown
++ */
++void
++RRCrtcDestroy (RRCrtcPtr crtc);
++
++/*
++ * Initialize crtc type
++ */
++Bool
++RRCrtcInit (void);
++
++/*
++ * Crtc dispatch
++ */
++
++int
++ProcRRGetCrtcInfo (ClientPtr client);
++
++int
++ProcRRSetCrtcConfig (ClientPtr client);
++
++int
++ProcRRGetCrtcGammaSize (ClientPtr client);
++
++int
++ProcRRGetCrtcGamma (ClientPtr client);
++
++int
++ProcRRSetCrtcGamma (ClientPtr client);
++
++/* rrdispatch.c */
++Bool
++RRClientKnowsRates (ClientPtr	pClient);
++
++/* rrmode.c */
++/*
++ * Find, and if necessary, create a mode
++ */
++
++RRModePtr
++RRModeGet (xRRModeInfo	*modeInfo,
++	   const char	*name);
++
++void
++RRModePruneUnused (ScreenPtr pScreen);
++
++/*
++ * Destroy a mode.
++ */
++
++void
++RRModeDestroy (RRModePtr mode);
++
++/*
++ * Return a list of modes that are valid for some output in pScreen
++ */
++RRModePtr *
++RRModesForScreen (ScreenPtr pScreen, int *num_ret);
++    
++/*
++ * Initialize mode type
++ */
++Bool
++RRModeInit (void);
++    
++int
++ProcRRCreateMode (ClientPtr client);
++
++int
++ProcRRDestroyMode (ClientPtr client);
++
++int
++ProcRRAddOutputMode (ClientPtr client);
++
++int
++ProcRRDeleteOutputMode (ClientPtr client);
++
++/* rroutput.c */
++
++/*
++ * Notify the output of some change. configChanged indicates whether
++ * any external configuration (mode list, clones, connected status)
++ * has changed, or whether the change was strictly internal
++ * (which crtc is in use)
++ */
++void
++RROutputChanged (RROutputPtr output, Bool configChanged);
++
++/*
++ * Create an output
++ */
++
++RROutputPtr
++RROutputCreate (ScreenPtr   pScreen,
++		const char  *name,
++		int	    nameLength,
++		void	    *devPrivate);
++
++/*
++ * Notify extension that output parameters have been changed
++ */
++Bool
++RROutputSetClones (RROutputPtr  output,
++		   RROutputPtr  *clones,
++		   int		numClones);
++
++Bool
++RROutputSetModes (RROutputPtr	output,
++		  RRModePtr	*modes,
++		  int		numModes,
++		  int		numPreferred);
++
++int
++RROutputAddUserMode (RROutputPtr    output,
++		     RRModePtr	    mode);
++
++int
++RROutputDeleteUserMode (RROutputPtr output,
++			RRModePtr   mode);
++
++Bool
++RROutputSetCrtcs (RROutputPtr	output,
++		  RRCrtcPtr	*crtcs,
++		  int		numCrtcs);
++
++Bool
++RROutputSetConnection (RROutputPtr  output,
++		       CARD8	    connection);
++
++Bool
++RROutputSetSubpixelOrder (RROutputPtr output,
++			  int	      subpixelOrder);
++
++Bool
++RROutputSetPhysicalSize (RROutputPtr	output,
++			 int		mmWidth,
++			 int		mmHeight);
++
++void
++RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
++
++void
++RROutputDestroy (RROutputPtr	output);
++
++int
++ProcRRGetOutputInfo (ClientPtr client);
++
++/*
++ * Initialize output type
++ */
++Bool
++RROutputInit (void);
++    
++/* rrpointer.c */
++void
++RRPointerMoved (ScreenPtr pScreen, int x, int y);
++
++void
++RRPointerScreenConfigured (ScreenPtr pScreen);
++
++/* rrproperty.c */
++
++void
++RRDeleteAllOutputProperties (RROutputPtr output);
++
++RRPropertyValuePtr
++RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending);
++
++RRPropertyPtr
++RRQueryOutputProperty (RROutputPtr output, Atom property);
++		       
++void
++RRDeleteOutputProperty (RROutputPtr output, Atom property);
++
++Bool
++RRPostPendingProperties (RROutputPtr output);
++    
++int
++RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
++			int format, int mode, unsigned long len,
++			pointer value, Bool sendevent, Bool pending);
++
++int
++RRConfigureOutputProperty (RROutputPtr output, Atom property,
++			   Bool pending, Bool range, Bool immutable,
++			   int num_values, INT32 *values);
++int
++ProcRRChangeOutputProperty (ClientPtr client);
++
++int
++ProcRRGetOutputProperty (ClientPtr client);
++
++int
++ProcRRListOutputProperties (ClientPtr client);
++
++int
++ProcRRQueryOutputProperty (ClientPtr client);
++
++int
++ProcRRConfigureOutputProperty (ClientPtr client);
++
++int
++ProcRRDeleteOutputProperty (ClientPtr client);
++
++/* rrxinerama.c */
++void
++RRXineramaExtensionInit(void);
+ 
+ #endif /* _RANDRSTR_H_ */
++
++/*
++ 
++randr extension implementation structure
++
++Query state:
++    ProcRRGetScreenInfo/ProcRRGetScreenResources
++	RRGetInfo
++ 
++	    • Request configuration from driver, either 1.0 or 1.2 style
++	    • These functions only record state changes, all
++	      other actions are pended until RRTellChanged is called
++ 
++	    ->rrGetInfo
++	    1.0:
++		RRRegisterSize
++		RRRegisterRate
++		RRSetCurrentConfig
++	    1.2:
++		RRScreenSetSizeRange
++		RROutputSetCrtcs
++		RRModeGet
++		RROutputSetModes
++		RROutputSetConnection
++		RROutputSetSubpixelOrder
++		RROutputSetClones
++		RRCrtcNotify
++ 
++	• Must delay scanning configuration until after ->rrGetInfo returns
++	  because some drivers will call SetCurrentConfig in the middle
++	  of the ->rrGetInfo operation.
++ 
++	1.0:
++
++	    • Scan old configuration, mirror to new structures
++ 
++	    RRScanOldConfig
++		RRCrtcCreate
++		RROutputCreate
++		RROutputSetCrtcs
++		RROutputSetConnection
++		RROutputSetSubpixelOrder
++		RROldModeAdd	• This adds modes one-at-a-time
++		    RRModeGet
++		RRCrtcNotify
++ 
++	• send events, reset pointer if necessary
++ 
++	RRTellChanged
++	    WalkTree (sending events)
++ 
++	    • when layout has changed:
++		RRPointerScreenConfigured
++		RRSendConfigNotify
++ 
++Asynchronous state setting (1.2 only)
++    When setting state asynchronously, the driver invokes the
++    ->rrGetInfo function and then calls RRTellChanged to flush
++    the changes to the clients and reset pointer if necessary
++
++Set state
++
++    ProcRRSetScreenConfig
++	RRCrtcSet
++	    1.2:
++		->rrCrtcSet
++		    RRCrtcNotify
++	    1.0:
++		->rrSetConfig
++		RRCrtcNotify
++	    RRTellChanged
++ */
+Only in ./nx-X11/programs/Xserver/randr: registry.h
+Only in ./nx-X11/programs/Xserver/randr: registry.h.NX.original
+Only in ./nx-X11/programs/Xserver/randr: registry.h.X.original
+Only in ./nx-X11/programs/Xserver/randr: rrcrtc.c
+Only in ./nx-X11/programs/Xserver/randr: rrcrtc.c.NX.original
+Only in ./nx-X11/programs/Xserver/randr: rrcrtc.c.X.original
+Only in ./nx-X11/programs/Xserver/randr: rrdispatch.c
+Only in ./nx-X11/programs/Xserver/randr: rrdispatch.c.X.original
+Only in ./nx-X11/programs/Xserver/randr: rrinfo.c
+Only in ./nx-X11/programs/Xserver/randr: rrmode.c
+Only in ./nx-X11/programs/Xserver/randr: rrmode.c.NX.original
+Only in ./nx-X11/programs/Xserver/randr: rrmode.c.X.original
+Only in ./nx-X11/programs/Xserver/randr: rroutput.c
+Only in ./nx-X11/programs/Xserver/randr: rrpointer.c
+Only in ./nx-X11/programs/Xserver/randr: rrproperty.c
+Only in ./nx-X11/programs/Xserver/randr: rrscreen.c
+Only in ./nx-X11/programs/Xserver/randr: rrscreen.c.NX.original
+Only in ./nx-X11/programs/Xserver/randr: rrscreen.c.X.original
+Only in ./nx-X11/programs/Xserver/randr: rrsdispatch.c
+Only in ./nx-X11/programs/Xserver/randr: rrxinerama.c
+Only in ./nx-X11/programs/Xserver/randr: rrxinerama.c.NX.original
+Only in ./nx-X11/programs/Xserver/randr: rrxinerama.c.X.original
diff --git a/doc/nx-X11_vs_XOrg69_patches/randr.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/randr.c.NX.patch
new file mode 100644
index 0000000..d19f820
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/randr.c.NX.patch
@@ -0,0 +1,72 @@
+--- ./nx-X11/programs/Xserver/randr/randr.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/randr.c	2015-02-10 19:13:13.616692925 +0100
+@@ -25,6 +25,23 @@
+  *	    Keith Packard, Intel Corporation
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #define NEED_REPLIES
+ #define NEED_EVENTS
+ #ifdef HAVE_DIX_CONFIG_H
+@@ -56,9 +73,14 @@
+ int	RREventBase;
+ int	RRErrorBase;
+ RESTYPE RRClientType, RREventType; /* resource types for event masks */
+-DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey;
+ 
++#ifndef NXAGENT_SERVER
++DevPrivateKey RRClientPrivateKey = &RRClientPrivateKey;
+ DevPrivateKey rrPrivKey = &rrPrivKey;
++#else
++int	RRClientPrivateIndex;
++int	rrPrivIndex = -1;
++#endif
+ 
+ static void
+ RRClientCallback (CallbackListPtr	*list,
+@@ -203,6 +225,10 @@
+ {
+     if (RRGeneration != serverGeneration)
+     {
++        #ifdef NXAGENT_SERVER
++	if ((rrPrivIndex = AllocateScreenPrivateIndex()) < 0)
++	    return FALSE;
++        #endif
+ 	if (!RRModeInit ())
+ 	    return FALSE;
+ 	if (!RRCrtcInit ())
+@@ -324,10 +350,18 @@
+ 
+     if (RRNScreens == 0) return;
+ 
++    #ifndef NXAGENT_SERVER
+     if (!dixRequestPrivate(RRClientPrivateKey,
+ 				sizeof (RRClientRec) +
+ 				screenInfo.numScreens * sizeof (RRTimesRec)))
+ 	return;
++    #else
++    RRClientPrivateIndex = AllocateClientPrivateIndex ();
++    if (!AllocateClientPrivate (RRClientPrivateIndex,
++				sizeof (RRClientRec) +
++				screenInfo.numScreens * sizeof (RRTimesRec)))
++	return;
++    #endif
+     if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
+ 	return;
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/randr.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/randr.h.NX.patch
new file mode 100644
index 0000000..a6f2d9c
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/randr.h.NX.patch
@@ -0,0 +1,144 @@
+--- ./nx-X11/programs/Xserver/randr/randr.h.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/randr.h	2015-02-10 19:13:13.628692476 +0100
+@@ -0,0 +1,141 @@
++/*
++ * Copyright © 2000 Compaq Computer Corporation
++ * Copyright © 2002 Hewlett Packard Company
++ * Copyright © 2006 Intel Corporation
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * that the name of the copyright holders not be used in advertising or
++ * publicity pertaining to distribution of the software without specific,
++ * written prior permission.  The copyright holders make no representations
++ * about the suitability of this software for any purpose.  It is provided "as
++ * is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++ * OF THIS SOFTWARE.
++ *
++ * Author:  Jim Gettys, HP Labs, Hewlett-Packard, Inc.
++ *	    Keith Packard, Intel Corporation
++ */
++
++#ifndef _RANDR_H_
++#define _RANDR_H_
++
++typedef unsigned short	Rotation;
++typedef unsigned short	SizeID;
++typedef unsigned short	SubpixelOrder;
++typedef unsigned short	Connection;
++typedef unsigned short	XRandrRotation;
++typedef unsigned short	XRandrSizeID;
++typedef unsigned short	XRandrSubpixelOrder;
++typedef unsigned long	XRandrModeFlags;
++
++#define RANDR_NAME		"RANDR"
++#define RANDR_MAJOR		1
++#define RANDR_MINOR		2
++
++#define RRNumberErrors		3
++#define RRNumberEvents		2
++#define RRNumberRequests	25
++
++#define X_RRQueryVersion	0
++/* we skip 1 to make old clients fail pretty immediately */
++#define X_RROldGetScreenInfo	1
++#define X_RR1_0SetScreenConfig	2
++/* V1.0 apps share the same set screen config request id */
++#define X_RRSetScreenConfig	2
++#define X_RROldScreenChangeSelectInput	3
++/* 3 used to be ScreenChangeSelectInput; deprecated */
++#define X_RRSelectInput		4
++#define X_RRGetScreenInfo	5
++
++/* V1.2 additions */
++#define X_RRGetScreenSizeRange	    6
++#define X_RRSetScreenSize	    7
++#define X_RRGetScreenResources	    8
++#define X_RRGetOutputInfo	    9
++#define X_RRListOutputProperties    10
++#define X_RRQueryOutputProperty	    11
++#define X_RRConfigureOutputProperty 12
++#define X_RRChangeOutputProperty    13
++#define X_RRDeleteOutputProperty    14
++#define X_RRGetOutputProperty	    15
++#define X_RRCreateMode		    16
++#define X_RRDestroyMode		    17
++#define X_RRAddOutputMode	    18
++#define X_RRDeleteOutputMode	    19
++#define X_RRGetCrtcInfo		    20
++#define X_RRSetCrtcConfig	    21
++#define X_RRGetCrtcGammaSize	    22
++#define X_RRGetCrtcGamma	    23
++#define X_RRSetCrtcGamma	    24
++
++/* Event selection bits */
++#define RRScreenChangeNotifyMask  (1L << 0)
++/* V1.2 additions */
++#define RRCrtcChangeNotifyMask	    (1L << 1)
++#define RROutputChangeNotifyMask    (1L << 2)
++#define RROutputPropertyNotifyMask  (1L << 3)
++
++/* Event codes */
++#define RRScreenChangeNotify	0
++/* V1.2 additions */
++#define RRNotify		    1
++/* RRNotify Subcodes */
++#define  RRNotify_CrtcChange	    0
++#define  RRNotify_OutputChange	    1
++#define  RRNotify_OutputProperty    2
++
++/* used in the rotation field; rotation and reflection in 0.1 proto. */
++#define RR_Rotate_0		1
++#define RR_Rotate_90		2
++#define RR_Rotate_180		4
++#define RR_Rotate_270		8
++
++/* new in 1.0 protocol, to allow reflection of screen */
++
++#define RR_Reflect_X		16
++#define RR_Reflect_Y		32
++
++#define RRSetConfigSuccess		0
++#define RRSetConfigInvalidConfigTime	1
++#define RRSetConfigInvalidTime		2
++#define RRSetConfigFailed		3
++
++/* new in 1.2 protocol */
++
++#define RR_HSyncPositive	0x00000001
++#define RR_HSyncNegative	0x00000002
++#define RR_VSyncPositive	0x00000004
++#define RR_VSyncNegative	0x00000008
++#define RR_Interlace		0x00000010
++#define RR_DoubleScan		0x00000020
++#define RR_CSync		0x00000040
++#define RR_CSyncPositive	0x00000080
++#define RR_CSyncNegative	0x00000100
++#define RR_HSkewPresent		0x00000200
++#define RR_BCast		0x00000400
++#define RR_PixelMultiplex	0x00000800
++#define RR_DoubleClock		0x00001000
++#define RR_ClockDivideBy2	0x00002000
++
++#define RR_Connected		0
++#define RR_Disconnected		1
++#define RR_UnknownConnection	2
++
++#define BadRROutput		0
++#define BadRRCrtc		1
++#define BadRRMode		2
++
++/* Conventional RandR output properties */
++
++#define RR_PROPERTY_RANDR_EDID		"RANDR_EDID"
++
++#endif	/* _RANDR_H_ */
diff --git a/doc/nx-X11_vs_XOrg69_patches/randrproto.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/randrproto.h.NX.patch
new file mode 100644
index 0000000..5c4ed74
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/randrproto.h.NX.patch
@@ -0,0 +1,658 @@
+--- ./nx-X11/programs/Xserver/randr/randrproto.h.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/randrproto.h	2015-02-10 19:13:13.632692326 +0100
+@@ -0,0 +1,655 @@
++/*
++ * Copyright © 2000 Compaq Computer Corporation
++ * Copyright © 2002 Hewlett-Packard Company
++ * Copyright © 2006 Intel Corporation
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appear in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * that the name of the copyright holders not be used in advertising or
++ * publicity pertaining to distribution of the software without specific,
++ * written prior permission.  The copyright holders make no representations
++ * about the suitability of this software for any purpose.  It is provided "as
++ * is" without express or implied warranty.
++ *
++ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
++ * OF THIS SOFTWARE.
++ *
++ * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
++ *	    Keith Packard, Intel Corporation
++ */
++
++/* note that RANDR 1.0 is incompatible with version 0.0, or 0.1 */
++/* V1.0 removes depth switching from the protocol */
++#ifndef _XRANDRP_H_
++#define _XRANDRP_H_
++
++/*#include <X11/extensions/randr.h>*/
++#include "randr.h"
++
++#define Window CARD32
++#define Drawable CARD32
++#define Font CARD32
++#define Pixmap CARD32
++#define Cursor CARD32
++#define Colormap CARD32
++#define GContext CARD32
++#define Atom CARD32
++#define Time CARD32
++#define KeyCode CARD8
++#define KeySym CARD32
++#define RROutput CARD32
++#define RRMode CARD32
++#define RRCrtc CARD32
++#define RRModeFlags CARD32
++
++#define Rotation CARD16
++#define SizeID CARD16
++#define SubpixelOrder CARD16
++
++/*
++ * data structures
++ */
++
++typedef struct {
++    CARD16 widthInPixels B16;
++    CARD16 heightInPixels B16;
++    CARD16 widthInMillimeters B16;
++    CARD16 heightInMillimeters B16;
++} xScreenSizes;
++#define sz_xScreenSizes 8
++
++/* 
++ * requests and replies
++ */
++
++typedef struct {
++    CARD8   reqType;
++    CARD8   randrReqType;
++    CARD16  length B16;
++    CARD32  majorVersion B32;
++    CARD32  minorVersion B32;
++} xRRQueryVersionReq;
++#define sz_xRRQueryVersionReq   12
++
++typedef struct {
++    BYTE    type;   /* X_Reply */
++    BYTE    pad1;
++    CARD16  sequenceNumber B16;
++    CARD32  length B32;
++    CARD32  majorVersion B32;
++    CARD32  minorVersion B32;
++    CARD32  pad2 B32;
++    CARD32  pad3 B32;
++    CARD32  pad4 B32;
++    CARD32  pad5 B32;
++} xRRQueryVersionReply;
++#define sz_xRRQueryVersionReply	32
++
++typedef struct {
++    CARD8   reqType;
++    CARD8   randrReqType;
++    CARD16  length B16;
++    Window  window B32;
++} xRRGetScreenInfoReq;
++#define sz_xRRGetScreenInfoReq   8
++
++/* 
++ * the xRRScreenInfoReply structure is followed by:
++ *
++ * the size information
++ */
++
++
++typedef struct {
++    BYTE    type;   /* X_Reply */
++    BYTE    setOfRotations;
++    CARD16  sequenceNumber B16;
++    CARD32  length B32;
++    Window  root B32;
++    Time    timestamp B32;
++    Time    configTimestamp B32;
++    CARD16  nSizes B16;
++    SizeID  sizeID B16;
++    Rotation  rotation B16;
++    CARD16  rate B16;
++    CARD16  nrateEnts B16;
++    CARD16  pad B16;
++} xRRGetScreenInfoReply;
++#define sz_xRRGetScreenInfoReply	32
++
++typedef struct {
++    CARD8    reqType;
++    CARD8    randrReqType;
++    CARD16   length B16;
++    Drawable drawable B32;
++    Time     timestamp B32;
++    Time     configTimestamp B32;
++    SizeID   sizeID B16;
++    Rotation rotation B16;
++} xRR1_0SetScreenConfigReq;
++#define sz_xRR1_0SetScreenConfigReq   20
++
++typedef struct {
++    CARD8    reqType;
++    CARD8    randrReqType;
++    CARD16   length B16;
++    Drawable drawable B32;
++    Time     timestamp B32;
++    Time     configTimestamp B32;
++    SizeID   sizeID B16;
++    Rotation rotation B16;
++    CARD16   rate B16;
++    CARD16   pad B16;
++} xRRSetScreenConfigReq;
++#define sz_xRRSetScreenConfigReq   24
++
++typedef struct {
++    BYTE    type;   /* X_Reply */
++    CARD8   status;
++    CARD16  sequenceNumber B16;
++    CARD32  length B32;
++    Time    newTimestamp B32;  
++    Time    newConfigTimestamp B32;
++    Window  root;
++    CARD16  subpixelOrder B16;
++    CARD16  pad4 B16;
++    CARD32  pad5 B32;
++    CARD32  pad6 B32;
++} xRRSetScreenConfigReply;
++#define sz_xRRSetScreenConfigReply 32
++
++typedef struct {
++    CARD8   reqType;
++    CARD8   randrReqType;
++    CARD16  length B16;
++    Window  window B32;
++    CARD16  enable B16;
++    CARD16  pad2 B16;
++} xRRSelectInputReq;
++#define sz_xRRSelectInputReq   12
++
++/*
++ * Additions for version 1.2
++ */
++
++typedef struct _xRRModeInfo {
++    RRMode		id B32;
++    CARD16		width B16;
++    CARD16		height B16;
++    CARD32		dotClock B32;
++    CARD16		hSyncStart B16;
++    CARD16		hSyncEnd B16;
++    CARD16		hTotal B16;
++    CARD16		hSkew B16;
++    CARD16		vSyncStart B16;
++    CARD16		vSyncEnd B16;
++    CARD16		vTotal B16;
++    CARD16		nameLength B16;
++    RRModeFlags		modeFlags B32;
++} xRRModeInfo;
++#define sz_xRRModeInfo		    32
++
++typedef struct {
++    CARD8   reqType;
++    CARD8   randrReqType;
++    CARD16  length B16;
++    Window  window B32;
++} xRRGetScreenSizeRangeReq;
++#define sz_xRRGetScreenSizeRangeReq 8
++
++typedef struct {
++    BYTE    type;   /* X_Reply */
++    CARD8   pad;
++    CARD16  sequenceNumber B16;
++    CARD32  length B32;
++    CARD16  minWidth B16;
++    CARD16  minHeight B16;
++    CARD16  maxWidth B16;
++    CARD16  maxHeight B16;
++    CARD32  pad0 B32;
++    CARD32  pad1 B32;
++    CARD32  pad2 B32;
++    CARD32  pad3 B32;
++} xRRGetScreenSizeRangeReply;
++#define sz_xRRGetScreenSizeRangeReply 32
++
++typedef struct {
++    CARD8   reqType;
++    CARD8   randrReqType;
++    CARD16  length B16;
++    Window  window B32;
++    CARD16  width B16;
++    CARD16  height B16;
++    CARD32  widthInMillimeters B32;
++    CARD32  heightInMillimeters B32;
++} xRRSetScreenSizeReq;
++#define sz_xRRSetScreenSizeReq	    20
++
++typedef struct {
++    CARD8   reqType;
++    CARD8   randrReqType;
++    CARD16  length B16;
++    Window  window B32;
++} xRRGetScreenResourcesReq;
++#define sz_xRRGetScreenResourcesReq 8
++
++typedef struct {
++    BYTE	type;
++    CARD8	pad;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    Time	timestamp B32;
++    Time	configTimestamp B32;
++    CARD16	nCrtcs B16;
++    CARD16	nOutputs B16;
++    CARD16	nModes B16;
++    CARD16	nbytesNames B16;
++    CARD32	pad1 B32;
++    CARD32	pad2 B32;
++} xRRGetScreenResourcesReply;
++#define sz_xRRGetScreenResourcesReply	32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    Time	configTimestamp B32;
++} xRRGetOutputInfoReq;
++#define sz_xRRGetOutputInfoReq		12
++
++typedef struct {
++    BYTE	type;
++    CARD8	status;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    Time	timestamp B32;
++    RRCrtc	crtc B32;
++    CARD32	mmWidth B32;
++    CARD32	mmHeight B32;
++    CARD8	connection;
++    CARD8	subpixelOrder;
++    CARD16	nCrtcs B16;
++    CARD16	nModes B16;
++    CARD16	nPreferred B16;
++    CARD16	nClones B16;
++    CARD16	nameLength B16;
++} xRRGetOutputInfoReply;
++#define sz_xRRGetOutputInfoReply	36
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++} xRRListOutputPropertiesReq; 
++#define sz_xRRListOutputPropertiesReq	8
++
++typedef struct {
++    BYTE	type;
++    CARD8	pad0;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    CARD16	nAtoms B16;
++    CARD16	pad1 B16;
++    CARD32	pad2 B32;
++    CARD32	pad3 B32;
++    CARD32	pad4 B32;
++    CARD32	pad5 B32;
++    CARD32	pad6 B32;
++} xRRListOutputPropertiesReply;
++#define sz_xRRListOutputPropertiesReply	32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    Atom	property B32;
++} xRRQueryOutputPropertyReq; 
++#define sz_xRRQueryOutputPropertyReq	12
++
++typedef struct {
++    BYTE	type;
++    BYTE	pad0;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    BOOL	pending;
++    BOOL	range;
++    BOOL	immutable;
++    BYTE	pad1;
++    CARD32	pad2 B32;
++    CARD32	pad3 B32;
++    CARD32	pad4 B32;
++    CARD32	pad5 B32;
++    CARD32	pad6 B32;
++} xRRQueryOutputPropertyReply;
++#define sz_xRRQueryOutputPropertyReply	32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    Atom	property B32;
++    BOOL	pending;
++    BOOL	range;
++    CARD16	pad B16;
++} xRRConfigureOutputPropertyReq; 
++#define sz_xRRConfigureOutputPropertyReq	16
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    Atom	property B32;
++    Atom	type B32;
++    CARD8	format;
++    CARD8	mode;
++    CARD16	pad;
++    CARD32	nUnits B32;
++} xRRChangeOutputPropertyReq;
++#define sz_xRRChangeOutputPropertyReq	24
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    Atom	property B32;
++} xRRDeleteOutputPropertyReq;
++#define sz_xRRDeleteOutputPropertyReq	12
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    Atom	property B32;
++    Atom	type B32;
++    CARD32	longOffset B32;
++    CARD32	longLength B32;
++#ifdef __cplusplus
++    BOOL	_delete;
++#else
++    BOOL	delete;
++#endif
++    BOOL	pending;
++    CARD16	pad1 B16;
++} xRRGetOutputPropertyReq;
++#define sz_xRRGetOutputPropertyReq	28
++
++typedef struct {
++    BYTE	type;
++    CARD8	format;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    Atom	propertyType B32;
++    CARD32	bytesAfter B32;
++    CARD32	nItems B32;
++    CARD32	pad1 B32;
++    CARD32	pad2 B32;
++    CARD32	pad3 B32;
++} xRRGetOutputPropertyReply;
++#define sz_xRRGetOutputPropertyReply	32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    Window	window B32;
++    xRRModeInfo	modeInfo;
++} xRRCreateModeReq; 
++#define sz_xRRCreateModeReq		40
++
++typedef struct {
++    BYTE	type;
++    CARD8	pad0;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    RRMode	mode B32;
++    CARD32	pad1 B32;
++    CARD32	pad2 B32;
++    CARD32	pad3 B32;
++    CARD32	pad4 B32;
++    CARD32	pad5 B32;
++} xRRCreateModeReply;
++#define sz_xRRCreateModeReply		32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RRMode	mode B32;
++} xRRDestroyModeReq;
++#define sz_xRRDestroyModeReq		8
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    RRMode	mode B32;
++} xRRAddOutputModeReq;
++#define sz_xRRAddOutputModeReq		12
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RROutput	output B32;
++    RRMode	mode B32;
++} xRRDeleteOutputModeReq;
++#define sz_xRRDeleteOutputModeReq	12
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RRCrtc	crtc B32;
++    Time	configTimestamp B32;
++} xRRGetCrtcInfoReq; 
++#define sz_xRRGetCrtcInfoReq		12
++
++typedef struct {
++    BYTE	type;
++    CARD8	status;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    Time	timestamp B32;
++    INT16	x B16;
++    INT16	y B16;
++    CARD16	width B16;
++    CARD16	height B16;
++    RRMode	mode B32;
++    Rotation	rotation B16;
++    Rotation	rotations B16;
++    CARD16	nOutput B16;
++    CARD16	nPossibleOutput B16;
++} xRRGetCrtcInfoReply;
++#define sz_xRRGetCrtcInfoReply		32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RRCrtc	crtc B32;
++    Time	timestamp B32;
++    Time    	configTimestamp B32;
++    INT16	x B16;
++    INT16	y B16;
++    RRMode	mode B32;
++    Rotation	rotation B16;
++    CARD16	pad B16;
++} xRRSetCrtcConfigReq; 
++#define sz_xRRSetCrtcConfigReq		28
++
++typedef struct {
++    BYTE	type;
++    CARD8	status;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    Time	newTimestamp B32;
++    CARD32	pad1 B32;
++    CARD32	pad2 B16;
++    CARD32	pad3 B32;
++    CARD32	pad4 B32;
++    CARD32	pad5 B32;
++} xRRSetCrtcConfigReply;
++#define sz_xRRSetCrtcConfigReply	32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RRCrtc	crtc B32;
++} xRRGetCrtcGammaSizeReq; 
++#define sz_xRRGetCrtcGammaSizeReq	8
++
++typedef struct {
++    BYTE	type;
++    CARD8	status;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    CARD16	size B16;
++    CARD16	pad1 B16;
++    CARD32	pad2 B32;
++    CARD32	pad3 B32;
++    CARD32	pad4 B32;
++    CARD32	pad5 B32;
++    CARD32	pad6 B32;
++} xRRGetCrtcGammaSizeReply;
++#define sz_xRRGetCrtcGammaSizeReply	32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RRCrtc	crtc B32;
++} xRRGetCrtcGammaReq; 
++#define sz_xRRGetCrtcGammaReq		8
++
++typedef struct {
++    BYTE	type;
++    CARD8	status;
++    CARD16	sequenceNumber B16;
++    CARD32	length B32;
++    CARD16	size B16;
++    CARD16	pad1 B16;
++    CARD32	pad2 B32;
++    CARD32	pad3 B32;
++    CARD32	pad4 B32;
++    CARD32	pad5 B32;
++    CARD32	pad6 B32;
++} xRRGetCrtcGammaReply;
++#define sz_xRRGetCrtcGammaReply		32
++
++typedef struct {
++    CARD8	reqType;
++    CARD8	randrReqType;
++    CARD16	length B16;
++    RRCrtc	crtc B32;
++    CARD16	size B16;
++    CARD16	pad1 B16;
++} xRRSetCrtcGammaReq;
++#define sz_xRRSetCrtcGammaReq		12
++
++/*
++ * event
++ */
++typedef struct {
++    CARD8 type;				/* always evBase + ScreenChangeNotify */
++    CARD8 rotation;			/* new rotation */
++    CARD16 sequenceNumber B16;
++    Time timestamp B32;			/* time screen was changed */
++    Time configTimestamp B32;		/* time config data was changed */
++    Window root B32;			/* root window */
++    Window window B32;			/* window requesting notification */
++    SizeID sizeID B16;			/* new size ID */
++    CARD16 subpixelOrder B16;		/* subpixel order */
++    CARD16 widthInPixels B16;		/* new size */
++    CARD16 heightInPixels B16;
++    CARD16 widthInMillimeters B16;
++    CARD16 heightInMillimeters B16;
++} xRRScreenChangeNotifyEvent;
++#define sz_xRRScreenChangeNotifyEvent	32
++
++typedef struct {
++    CARD8 type;				/* always evBase + RRNotify */
++    CARD8 subCode;			/* RRNotify_CrtcChange */
++    CARD16 sequenceNumber B16;
++    Time timestamp B32;			/* time crtc was changed */
++    Window window B32;			/* window requesting notification */
++    RRCrtc crtc B32;			/* affected CRTC */
++    RRMode mode B32;			/* current mode */
++    CARD16 rotation B16;		/* rotation and reflection */
++    CARD16 pad1 B16;			/* unused */
++    INT16 x B16;			/* new location */
++    INT16 y B16;
++    CARD16 width B16;			/* new size */
++    CARD16 height B16;
++} xRRCrtcChangeNotifyEvent;
++#define sz_xRRCrtcChangeNotifyEvent	32
++
++typedef struct {
++    CARD8 type;				/* always evBase + RRNotify */
++    CARD8 subCode;			/* RRNotify_OutputChange */
++    CARD16 sequenceNumber B16;
++    Time timestamp B32;			/* time crtc was changed */
++    Time configTimestamp B32;		/* time crtc was changed */
++    Window window B32;			/* window requesting notification */
++    RROutput output B32;		/* affected output */
++    RRCrtc crtc B32;			/* current crtc */
++    RRMode mode B32;			/* current mode */
++    CARD16 rotation B16;		/* rotation and reflection */
++    CARD8 connection;			/* connection status */
++    CARD8 subpixelOrder;		/* subpixel order */
++} xRROutputChangeNotifyEvent;
++#define sz_xRROutputChangeNotifyEvent	32
++
++typedef struct {
++    CARD8 type;				/* always evBase + RRNotify */
++    CARD8 subCode;			/* RRNotify_OutputProperty */
++    CARD16 sequenceNumber B16;
++    Window window B32;			/* window requesting notification */
++    RROutput output B32;		/* affected output */
++    Atom atom B32;			/* property name */
++    Time timestamp B32;			/* time crtc was changed */
++    CARD8 state;			/* NewValue or Deleted */
++    CARD8 pad1;
++    CARD16 pad2 B16;
++    CARD32 pad3 B32;
++    CARD32 pad4 B32;
++} xRROutputPropertyNotifyEvent;
++#define sz_xRROutputPropertyNotifyEvent	32
++
++#undef RRModeFlags
++#undef RRCrtc
++#undef RRMode
++#undef RROutput
++#undef RRMode
++#undef RRCrtc
++#undef Drawable
++#undef Window
++#undef Font
++#undef Pixmap
++#undef Cursor
++#undef Colormap
++#undef GContext
++#undef Atom
++#undef Time
++#undef KeyCode
++#undef KeySym
++#undef Rotation
++#undef SizeID
++#undef SubpixelOrder
++
++#endif /* _XRANDRP_H_ */
diff --git a/doc/nx-X11_vs_XOrg69_patches/registry.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/registry.h.NX.patch
new file mode 100644
index 0000000..601bc0a
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/registry.h.NX.patch
@@ -0,0 +1,67 @@
+--- ./nx-X11/programs/Xserver/randr/registry.h.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/registry.h	2015-02-10 19:13:13.616692925 +0100
+@@ -0,0 +1,64 @@
++/***********************************************************
++
++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
++AUTHOR 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.
++
++******************************************************************/
++
++#ifndef DIX_REGISTRY_H
++#define DIX_REGISTRY_H
++
++/*
++ * Result returned from any unsuccessful lookup
++ */
++#define XREGISTRY_UNKNOWN "<unknown>"
++
++#ifdef XREGISTRY
++
++#include "resource.h"
++#include "extnsionst.h"
++
++/* Internal string registry - for auditing, debugging, security, etc. */
++
++/*
++ * Registration functions.  The name string is not copied, so it must
++ * not be a stack variable.
++ */
++void RegisterResourceName(RESTYPE type, char *name);
++void RegisterExtensionNames(ExtensionEntry *ext);
++
++/*
++ * Lookup functions.  The returned string must not be modified or freed.
++ */
++const char *LookupMajorName(int major);
++const char *LookupRequestName(int major, int minor);
++const char *LookupEventName(int event);
++const char *LookupErrorName(int error);
++const char *LookupResourceName(RESTYPE rtype);
++
++/*
++ * Setup and teardown
++ */
++void dixResetRegistry(void);
++
++#else /* XREGISTRY */
++
++/* Define calls away when the registry is not being built. */
++
++#define RegisterResourceName(a, b) { ; }
++#define RegisterExtensionNames(a) { ; }
++
++#define LookupMajorName(a) XREGISTRY_UNKNOWN
++#define LookupRequestName(a, b) XREGISTRY_UNKNOWN
++#define LookupEventName(a) XREGISTRY_UNKNOWN
++#define LookupErrorName(a) XREGISTRY_UNKNOWN
++#define LookupResourceName(a) XREGISTRY_UNKNOWN
++
++#define dixResetRegistry() { ; }
++
++#endif /* XREGISTRY */
++#endif /* DIX_REGISTRY_H */
diff --git a/doc/nx-X11_vs_XOrg69_patches/render2.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/render2.c.NX.patch
new file mode 100644
index 0000000..16fa7ad
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/render2.c.NX.patch
@@ -0,0 +1,11 @@
+--- ./nx-X11/programs/Xserver/GL/glx/render2.c.X.original	2015-02-13 14:03:44.680442769 +0100
++++ ./nx-X11/programs/Xserver/GL/glx/render2.c	2015-02-10 19:13:14.416663013 +0100
+@@ -43,7 +43,7 @@
+ #include "unpack.h"
+ #include "g_disptab.h"
+ #include "g_disptab_EXT.h"
+-
++#include "indirect_size.h"
+ 
+ void __glXDisp_Map1f(GLbyte *pc)
+ {
diff --git a/doc/nx-X11_vs_XOrg69_patches/render2swap.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/render2swap.c.NX.patch
new file mode 100644
index 0000000..1ae924d
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/render2swap.c.NX.patch
@@ -0,0 +1,11 @@
+--- ./nx-X11/programs/Xserver/GL/glx/render2swap.c.X.original	2015-02-13 14:03:44.680442769 +0100
++++ ./nx-X11/programs/Xserver/GL/glx/render2swap.c	2015-02-10 19:13:14.376664506 +0100
+@@ -43,7 +43,7 @@
+ #include "unpack.h"
+ #include "g_disptab.h"
+ #include "g_disptab_EXT.h"
+-
++#include "indirect_size.h"
+ 
+ void __glXDispSwap_Map1f(GLbyte *pc)
+ {
diff --git a/doc/nx-X11_vs_XOrg69_patches/renderedge.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/renderedge.c.NX.patch
new file mode 100644
index 0000000..3f15142
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/renderedge.c.NX.patch
@@ -0,0 +1,10 @@
+--- ./nx-X11/programs/Xserver/render/renderedge.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/render/renderedge.c	2015-02-10 19:13:13.592693823 +0100
+@@ -143,6 +143,7 @@
+     dx = x_bot - x_top;
+     dy = y_bot - y_top;
+     e->dy = dy;
++    e->dx = 0;
+     if (dy)
+     {
+ 	if (dx >= 0)
diff --git a/doc/nx-X11_vs_XOrg69_patches/rrcrtc.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/rrcrtc.c.NX.patch
new file mode 100644
index 0000000..6cb8359
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/rrcrtc.c.NX.patch
@@ -0,0 +1,48 @@
+--- ./nx-X11/programs/Xserver/randr/rrcrtc.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/rrcrtc.c	2015-02-10 19:13:13.624692625 +0100
+@@ -20,6 +20,23 @@
+  * OF THIS SOFTWARE.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #include "randrstr.h"
+ #include "swaprep.h"
+ #include "registry.h"
+@@ -836,6 +853,9 @@
+ 	rep.status = RRSetConfigFailed;
+ 	goto sendReply;
+     }
++    #ifdef NXAGENT_SERVER /* Bug 21987 */
++    pScrPriv->lastSetTime = time;
++    #endif
+     rep.status = RRSetConfigSuccess;
+     
+ sendReply:
+@@ -846,7 +866,11 @@
+     /* rep.status has already been filled in */
+     rep.length = 0;
+     rep.sequenceNumber = client->sequence;
++    #ifndef NXAGENT_SERVER /* Bug 21987 */
+     rep.newTimestamp = pScrPriv->lastConfigTime.milliseconds;
++    #else
++    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
++    #endif
+ 
+     if (client->swapped) 
+     {
diff --git a/doc/nx-X11_vs_XOrg69_patches/rrdispatch.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/rrdispatch.c.NX.patch
new file mode 100644
index 0000000..8a4cc13
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/rrdispatch.c.NX.patch
@@ -0,0 +1,15 @@
+--- ./nx-X11/programs/Xserver/randr/rrdispatch.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/rrdispatch.c	2015-02-10 19:13:13.632692326 +0100
+@@ -76,7 +76,12 @@
+     int		rc;
+ 
+     REQUEST_SIZE_MATCH(xRRSelectInputReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+     pHead = (RREventPtr *)SecurityLookupIDByType(client,
diff --git a/doc/nx-X11_vs_XOrg69_patches/rrmode.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/rrmode.c.NX.patch
new file mode 100644
index 0000000..ddbe739
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/rrmode.c.NX.patch
@@ -0,0 +1,39 @@
+--- ./nx-X11/programs/Xserver/randr/rrmode.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/rrmode.c	2015-02-10 19:13:13.612693075 +0100
+@@ -20,6 +20,23 @@
+  * OF THIS SOFTWARE.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #include "randrstr.h"
+ #include "registry.h"
+ 
+@@ -288,7 +305,12 @@
+     RRModePtr		mode;
+     
+     REQUEST_AT_LEAST_SIZE (xRRCreateModeReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/rrscreen.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/rrscreen.c.NX.patch
new file mode 100644
index 0000000..c5c3d47
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/rrscreen.c.NX.patch
@@ -0,0 +1,107 @@
+--- ./nx-X11/programs/Xserver/randr/rrscreen.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/rrscreen.c	2015-02-10 19:13:13.632692326 +0100
+@@ -20,6 +20,23 @@
+  * OF THIS SOFTWARE.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #include "randrstr.h"
+ 
+ extern char	*ConnectionInfo;
+@@ -212,7 +229,12 @@
+     int				rc;
+     
+     REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+ 
+@@ -263,7 +285,12 @@
+     int			i, rc;
+     
+     REQUEST_SIZE_MATCH(xRRSetScreenSizeReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+ 
+@@ -333,7 +360,12 @@
+     CARD8			*names;
+     
+     REQUEST_SIZE_MATCH(xRRGetScreenResourcesReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+     
+@@ -582,7 +614,12 @@
+     RROutputPtr		    output;
+ 
+     REQUEST_SIZE_MATCH(xRRGetScreenInfoReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+ 
+@@ -756,7 +793,12 @@
+ 	has_rate = FALSE;
+     }
+     
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
++    #else
++    pDraw = SecurityLookupDrawable(stuff->drawable, client, SecurityWriteAccess);
++    rc = pDraw ? Success : BadDrawable;
++    #endif
+     if (rc != Success)
+ 	return rc;
+ 
+@@ -921,8 +963,15 @@
+ 
+     if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output))
+ 	rep.status = RRSetConfigFailed;
++    #ifndef NXAGENT_SERVER /* Bug 21987 */
+     else
+ 	rep.status = RRSetConfigSuccess;
++    #else
++    else {
++	rep.status = RRSetConfigSuccess;
++	pScrPriv->lastSetTime = time;
++    }
++    #endif
+ 
+     /*
+      * XXX Configure other crtcs to mirror as much as possible
diff --git a/doc/nx-X11_vs_XOrg69_patches/rrxinerama.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/rrxinerama.c.NX.patch
new file mode 100644
index 0000000..f95d632
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/rrxinerama.c.NX.patch
@@ -0,0 +1,72 @@
+--- ./nx-X11/programs/Xserver/randr/rrxinerama.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/randr/rrxinerama.c	2015-02-10 19:13:13.620692775 +0100
+@@ -68,9 +68,30 @@
+  *           David Thomas <davtom at dream.org.uk>.
+  */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #include "randrstr.h"
+ #include "swaprep.h"
++#ifndef NXAGENT_SERVER
+ #include <X11/extensions/panoramiXproto.h>
++#else
++#include "panoramiXproto.h"
++#endif
+ 
+ #define RR_XINERAMA_MAJOR_VERSION   1
+ #define RR_XINERAMA_MINOR_VERSION   1
+@@ -122,7 +143,12 @@
+     Bool			active = FALSE;
+ 
+     REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if(rc != Success)
+ 	return rc;
+ 
+@@ -185,7 +211,12 @@
+     register int			n, rc;
+ 
+     REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+     
+@@ -213,7 +244,12 @@
+     register int			n, rc;
+ 
+     REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
++    #ifndef NXAGENT_SERVER
+     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
++    #else
++    pWin = SecurityLookupWindow(stuff->window, client, SecurityReadAccess);
++    rc = pWin ? Success : BadWindow;
++    #endif
+     if (rc != Success)
+ 	return rc;
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/security.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/security.c.NX.patch
new file mode 100644
index 0000000..bb461af
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/security.c.NX.patch
@@ -0,0 +1,315 @@
+--- ./nx-X11/programs/Xserver/Xext/security.c.X.original	2015-02-13 14:03:44.684442691 +0100
++++ ./nx-X11/programs/Xserver/Xext/security.c	2015-02-13 14:03:44.684442691 +0100
+@@ -27,6 +27,23 @@
+ */
+ /* $XFree86: xc/programs/Xserver/Xext/security.c,v 1.16tsi Exp $ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #ifdef HAVE_DIX_CONFIG_H
+ #include <dix-config.h>
+ #endif
+@@ -54,14 +71,49 @@
+ #include <stdio.h>  /* for file reading operations */
+ #include <X11/Xatom.h>  /* for XA_STRING */
+ 
++#ifdef NXAGENT_SERVER
++
++#include <unistd.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++
++#endif
++
+ #ifndef DEFAULTPOLICYFILE
+ # define DEFAULTPOLICYFILE NULL
+ #endif
++
++#ifdef NXAGENT_SERVER
++
++#define NX_ALTERNATIVEPOLICYFILE "/usr/lib/xserver/SecurityPolicy"
++
++#endif
++
+ #if defined(WIN32) || defined(__CYGWIN__)
+ #include <X11/Xos.h>
+ #undef index
+ #endif
+ 
++/*
++ * Set here the required NX log level.
++ */
++
++#ifdef NXAGENT_SERVER
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
++#endif
++
++#ifdef NXAGENT_SERVER
++
++static char _NXPolicyFilePath[1024];
++
++#endif
++
+ #include "modinit.h"
+ 
+ static int SecurityErrorBase;  /* first Security error number */
+@@ -87,6 +139,115 @@
+     ClientPtr /*client*/
+ );
+ 
++#ifdef NXAGENT_SERVER
++
++/*
++ * This function returns the SecurityPolicy
++ * file full path. This path is referred by
++ * SecurityPolicyFile variable (generally it
++ * contains the hardcoded path at compile time).
++ * If the path does not exist, the function will
++ * try a set of well known paths.
++ */
++
++const char *_NXGetPolicyFilePath(const char *path)
++{
++
++  struct stat SecurityPolicyStat;
++
++  /*
++   * Check the policy file path only once.
++   */
++
++  if (*_NXPolicyFilePath != '\0')
++  {
++    return _NXPolicyFilePath;
++  }
++
++  if (stat(path, &SecurityPolicyStat) == 0)
++  {
++    if (strlen(path) + 1 > 1024)
++    {
++      #ifdef WARNING
++      fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file path exceeded.\n");
++      #endif
++
++      goto _NXGetPolicyFilePathError;
++    }
++
++    strcpy(_NXPolicyFilePath, path);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetPolicyFilePath: Using SecurityPolicy file path [%s].\n",
++                _NXPolicyFilePath);
++    #endif
++
++    return _NXPolicyFilePath;
++  }
++
++  if (stat(DEFAULTPOLICYFILE, &SecurityPolicyStat) == 0)
++  {
++    if (strlen(DEFAULTPOLICYFILE) + 1 > 1024)
++    {
++      #ifdef WARNING
++      fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file path exceeded.\n");
++      #endif
++
++      goto _NXGetPolicyFilePathError;
++    }
++
++    strcpy(_NXPolicyFilePath, DEFAULTPOLICYFILE);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetPolicyFilePath: Using SecurityPolicy file path [%s].\n",
++                _NXPolicyFilePath);
++    #endif
++
++    return _NXPolicyFilePath;
++  }
++
++  if (stat(NX_ALTERNATIVEPOLICYFILE, &SecurityPolicyStat) == 0)
++  {
++    if (strlen(NX_ALTERNATIVEPOLICYFILE) + 1 > 1024)
++    {
++      #ifdef WARNING
++      fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file path exceeded.\n");
++      #endif
++
++      goto _NXGetPolicyFilePathError;
++    }
++
++    strcpy(_NXPolicyFilePath, NX_ALTERNATIVEPOLICYFILE);
++
++    #ifdef TEST
++    fprintf(stderr, "_NXGetPolicyFilePath: Using SecurityPolicy file path [%s].\n",
++                _NXPolicyFilePath);
++    #endif
++
++    return _NXPolicyFilePath;
++  }
++
++_NXGetPolicyFilePathError:
++
++  if (strlen(path) + 1 > 1024)
++  {
++    #ifdef WARNING
++    fprintf(stderr, "_NXGetPolicyFilePath: WARNING! Maximum length of SecurityPolicy file exceeded.\n");
++    #endif
++  }
++
++  strcpy(_NXPolicyFilePath, path);
++
++  #ifdef TEST
++  fprintf(stderr, "_NXGetPolicyFilePath: Using default SecurityPolicy file path [%s].\n",
++              _NXPolicyFilePath);
++  #endif
++
++  return _NXPolicyFilePath;
++}
++
++#endif
++
+ /* SecurityAudit
+  *
+  * Arguments:
+@@ -1647,18 +1808,60 @@
+ 
+     SecurityMaxPropertyName = 0;
+ 
++#ifdef NXAGENT_SERVER
++
++    if (!_NXGetPolicyFilePath(SecurityPolicyFile))
++    {
++      return;
++    }
++
++#else
++
+     if (!SecurityPolicyFile)
+ 	return;
+ 
++#endif
++
+ #ifndef __UNIXOS2__
++
++#ifdef NXAGENT_SERVER
++
++    f = Fopen(_NXGetPolicyFilePath(SecurityPolicyFile), "r");
++
++#else
++
+     f = Fopen(SecurityPolicyFile, "r");
++
++#endif
++
++#else
++
++#ifdef NXAGENT_SERVER
++
++    f = Fopen((char*)__XOS2RedirRoot( _NXGetPolicyFilePath(SecurityPolicyFile)), "r");
++
+ #else
++
+     f = Fopen((char*)__XOS2RedirRoot(SecurityPolicyFile), "r");
+-#endif    
++
++#endif
++
++#endif
++ 
+     if (!f)
+     {
++#ifdef NXAGENT_SERVER
++
++        ErrorF("error opening security policy file %s\n",
++                   _NXGetPolicyFilePath(SecurityPolicyFile));
++
++#else
++
+ 	ErrorF("error opening security policy file %s\n",
+ 	       SecurityPolicyFile);
++
++#endif
++
+ 	return;
+     }
+ 
+@@ -1678,8 +1881,19 @@
+ 	    char *v = SecurityParseString(&p);
+ 	    if (strcmp(v, SECURITY_POLICY_FILE_VERSION) != 0)
+ 	    {
++
++#ifdef NXAGENT_SERVER
++
++                ErrorF("%s: invalid security policy file version, ignoring file\n",
++                           _NXGetPolicyFilePath(SecurityPolicyFile));
++
++#else
++
+ 		ErrorF("%s: invalid security policy file version, ignoring file\n",
+ 		       SecurityPolicyFile);
++
++#endif
++
+ 		break;
+ 	    }
+ 	    validLine = TRUE;
+@@ -1706,9 +1920,22 @@
+ 	    }
+ 	}
+ 
++#ifdef NXAGENT_SERVER
++
++        if (!validLine)
++        {
++          ErrorF("Line %d of %s invalid, ignoring\n",
++                     lineNumber, _NXGetPolicyFilePath(SecurityPolicyFile));
++        }
++
++#else
++
+ 	if (!validLine)
+ 	    ErrorF("Line %d of %s invalid, ignoring\n",
+ 		   lineNumber, SecurityPolicyFile);
++
++#endif
++
+     } /* end while more input */
+ 
+ #ifdef PROPDEBUG
+@@ -1799,7 +2026,17 @@
+     {
+ 	struct stat buf;
+ 	static time_t lastmod = 0;
++
++#ifdef NXAGENT_SERVER
++
++        int ret = stat(_NXGetPolicyFilePath(SecurityPolicyFile), &buf);
++
++#else
++
+ 	int ret = stat(SecurityPolicyFile , &buf);
++
++#endif
++
+ 	if ( (ret == 0) && (buf.st_mtime > lastmod) )
+ 	{
+ 	    ErrorF("reloading property rules\n");
diff --git a/doc/nx-X11_vs_XOrg69_patches/select.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/select.c.NX.patch
new file mode 100644
index 0000000..9876bf4
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/select.c.NX.patch
@@ -0,0 +1,13 @@
+--- ./nx-X11/programs/Xserver/xfixes/select.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/xfixes/select.c	2015-02-10 19:13:13.504697118 +0100
+@@ -78,7 +78,9 @@
+     }
+     for (e = selectionEvents; e; e = e->next)
+     {
+-	if (e->selection == selection->selection && (e->eventMask & eventMask))
++	if (e->selection == selection->selection && 
++	    (e->eventMask & eventMask) &&
++	    !e->pClient->clientGone)
+ 	{
+ 	    xXFixesSelectionNotifyEvent	ev;
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/sun.cf.NX.patch b/doc/nx-X11_vs_XOrg69_patches/sun.cf.NX.patch
new file mode 100644
index 0000000..444c142
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/sun.cf.NX.patch
@@ -0,0 +1,50 @@
+--- ./nx-X11/config/cf/sun.cf.X.original	2015-02-13 14:03:44.400448260 +0100
++++ ./nx-X11/config/cf/sun.cf	2015-02-13 14:03:44.400448260 +0100
+@@ -299,7 +299,12 @@
+ 
+ #if OSMajorVersion == 4 
+ # if OSMinorVersion == 1
++/*
++ * Currently the NX transport only works with select().
++ *
+ #  define HasPoll		YES
++ */
++#  define HasPoll		NO
+ # endif
+ # if OSMinorVersion > 1 || (OSMinorVersion == 1 && OSTeenyVersion > 1)
+ /* You ALSO need this if you have Sun ld patch 100170-06 or later to 4.1.1 */
+@@ -359,10 +364,12 @@
+ # endif
+ #endif
+ 
+-#define ServerOSDefines		XFree86ServerOSDefines IncludeCG2HeaderDefine
++#define ServerOSDefines		XFree86ServerOSDefines IncludeCG2HeaderDefine \
++				-DPIXPRIV
+ #define ServerExtraDefines	AllocateLocalDefines XFree86ServerDefines \
+ 				CompilerServerExtraDefines \
+-				OSServerExtraDefines ArchServerExtraDefines
++				OSServerExtraDefines ArchServerExtraDefines \
++				-DPIXPRIV
+ 
+ #ifndef HasPerl
+ /* Solaris 8 comes with perl.  Earlier versions don't. */
+@@ -384,7 +391,8 @@
+ #endif
+ 
+ #if OSMajorVersion > 4
+-# define ConnectionFlags		-DTCPCONN -DUNIXCONN -DLOCALCONN
++/* #define ConnectionFlags             -DTCPCONN -DUNIXCONN -DLOCALCONN */
++#define ConnectionFlags                -DUNIXCONN -DTCPCONN
+ # if HasSunC
+ #  ifdef DefaultSunProCCompilerDir
+ #   ifndef  CcCmd
+@@ -452,7 +460,8 @@
+ #  endif
+ #  define ToolkitStringsABIOptions	-intelabi SolarisABIFlag
+ # else
+-#  define StandardDefines	  -Dsun -Dsparc -DSVR4 -D__EXTENSIONS__ LargefileDefines
++#  define StandardDefines	  -Dsun -Dsparc -DSVR4 -D__EXTENSIONS__ LargefileDefines \
++				  -DPIXPRIV
+ #  define ToolkitStringsABIOptions	-sparcabi SolarisABIFlag
+ # endif
+ # define ExtraLibraries    -lsocket -lnsl
diff --git a/doc/nx-X11_vs_XOrg69_patches/sunLib.tmpl.NX.patch b/doc/nx-X11_vs_XOrg69_patches/sunLib.tmpl.NX.patch
new file mode 100644
index 0000000..17f8584
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/sunLib.tmpl.NX.patch
@@ -0,0 +1,122 @@
+--- ./nx-X11/config/cf/sunLib.tmpl.X.original	2015-02-13 14:03:44.400448260 +0100
++++ ./nx-X11/config/cf/sunLib.tmpl	2015-02-13 14:03:44.400448260 +0100
+@@ -45,119 +45,6 @@
+ 
+ #else				/* else it's Solaris */
+ 
+-/* Solaris uses single digit library versions, and versions of libraries
+- * defined in SVID specs should match the versions specified there.
+- */
+-
+-#ifndef SharedX11Rev
+-# define SharedX11Rev 4
+-#endif
+-#ifndef SharedOldXRev
+-# define SharedOldXRev 6
+-#endif
+-#ifndef SharedXextRev
+-# define SharedXextRev 0
+-#endif
+-#ifndef SharedXauRev
+-# define SharedXauRev 6
+-#endif
+-#ifndef SharedXdmcpRev
+-# define SharedXdmcpRev 6
+-#endif
+-#ifndef SharedXmuRev
+-# define SharedXmuRev 4
+-#endif
+-#ifndef SharedXmuuRev
+-# define SharedXmuuRev 1
+-#endif
+-#ifndef SharedXpRev
+-# define SharedXpRev 1
+-#endif
+-#ifndef SharedXpmRev
+-# define SharedXpmRev 4
+-#endif
+-#ifndef SharedXtRev
+-# define SharedXtRev 4
+-#endif
+-#ifndef SharedXaw6Rev
+-# define SharedXaw6Rev 5
+-#endif
+-#ifndef SharedXiRev
+-# define SharedXiRev 5
+-#endif
+-#ifndef SharedXtstRev
+-# define SharedXtstRev 1
+-#endif
+-#ifndef SharedFSRev
+-# define SharedFSRev 5
+-#endif
+-#ifndef SharedICERev
+-# define SharedICERev 6
+-#endif
+-#ifndef SharedSMRev
+-# define SharedSMRev 6
+-#endif
+-#ifndef SharedXcursor
+-# define SharedXcursorRev 1
+-#endif
+-#ifndef SharedXdamageRev
+-# define SharedXdamageRev 1
+-#endif
+-#ifndef SharedXevieRev
+-# define SharedXevieRev 1
+-#endif
+-#ifndef SharedXfixesRev
+-# define SharedXfixesRev 1
+-#endif
+-#ifndef SharedXftRev
+-# define SharedXftRev 2
+-#endif
+-#ifndef SharedXineramaRev
+-# define SharedXineramaRev 1
+-#endif
+-#ifndef SharedXrenderRev
+-# define SharedXrenderRev 1
+-#endif
+-#ifndef SharedXResRev
+-# define SharedXResRev 1
+-#endif
+-#ifndef SharedXvRev
+-# define SharedXvRev 1
+-#endif
+-#ifndef SharedXvMCRev
+-# define SharedXvMCRev 1
+-#endif
+-#ifndef SharedXrandrRev
+-# define SharedXrandrRev 2
+-#endif
+-#ifndef SharedXssRev
+-# define SharedXssRev 1
+-#endif
+-#ifndef SharedFontconfigRev
+-# define SharedFontconfigRev 1
+-#endif
+-#ifndef SharedGlxRev
+-# define SharedGlxRev 1
+-#endif
+-#ifndef SharedGluRev
+-# define SharedGluRev 1
+-#endif
+-#ifndef SharedGLwRev
+-# define SharedGLwRev 1
+-#endif
+-#ifndef SharedOSMesaRev
+-# define SharedOSMesaRev 4
+-#endif
+-#ifndef SharedxkbfileRev
+-# define SharedxkbfileRev 5
+-#endif
+-#ifndef SharedXxf86miscRev
+-# define SharedXxf86miscRev 1
+-#endif
+-#ifndef SharedXxf86vmRev
+-# define SharedXxf86vmRev 1
+-#endif
+-
+ # if ThreadedX
+ #  if OSMinorVersion > 3
+ #   define SharedThreadReqs /**/
diff --git a/doc/nx-X11_vs_XOrg69_patches/svr4.cf.NX.patch b/doc/nx-X11_vs_XOrg69_patches/svr4.cf.NX.patch
new file mode 100644
index 0000000..487c295
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/svr4.cf.NX.patch
@@ -0,0 +1,24 @@
+--- ./nx-X11/config/cf/svr4.cf.X.original	2015-02-13 14:03:44.400448260 +0100
++++ ./nx-X11/config/cf/svr4.cf	2015-02-13 14:03:44.400448260 +0100
+@@ -51,7 +51,12 @@
+ #ifndef HasLdRunPath
+ #define HasLdRunPath		YES
+ #endif
++/*
++ * Currently the NX transport only works with select().
++ *
+ #define HasPoll			YES
++ */
++#define HasPoll			NO
+ #ifndef SVR4Architecture
+ #define SVR4Architecture
+ #endif
+@@ -278,7 +283,7 @@
+ # define XFree86ServerDefines	/* */
+ #endif
+ #ifndef XFree86ServerOSDefines
+-# define XFree86ServerOSDefines -DDDXOSINIT
++# define XFree86ServerOSDefines -DDDXOSINIT -DDDXOSFATALERROR -DDDXOSVERRORF
+ #endif
+ 
+ #if HasGcc2ForCplusplus
diff --git a/doc/nx-X11_vs_XOrg69_patches/utils.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/utils.c.NX.patch
new file mode 100644
index 0000000..5e18abf
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/utils.c.NX.patch
@@ -0,0 +1,250 @@
+--- ./nx-X11/programs/Xserver/os/utils.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/os/utils.c	2015-02-13 14:03:44.788440645 +0100
+@@ -52,6 +52,23 @@
+ */
+ /* $XFree86: xc/programs/Xserver/os/utils.c,v 3.96 2004/01/07 04:16:37 dawes Exp $ */
+ 
++/**************************************************************************/
++/*                                                                        */
++/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
++/*                                                                        */
++/* NX-X11, NX protocol compression and NX extensions to this software     */
++/* are copyright of NoMachine. Redistribution and use of the present      */
++/* software is allowed according to terms specified in the file LICENSE   */
++/* which comes in the source distribution.                                */
++/*                                                                        */
++/* Check http://www.nomachine.com/licensing.html for applicability.       */
++/*                                                                        */
++/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
++/*                                                                        */
++/* All rights reserved.                                                   */
++/*                                                                        */
++/**************************************************************************/
++
+ #ifdef HAVE_DIX_CONFIG_H
+ #include <dix-config.h>
+ #endif
+@@ -246,6 +263,20 @@
+ 
+ #include <errno.h>
+ 
++#ifdef NX_TRANS_SOCKET
++
++#include "NX.h"
++#include "NXvars.h"
++
++#endif
++
++#ifdef NX_TRANS_EXIT
++
++void (*OsVendorStartRedirectErrorFProc)() = NULL;
++void (*OsVendorEndRedirectErrorFProc)() = NULL;
++
++#endif
++
+ Bool CoreDump;
+ 
+ #ifdef PANORAMIX
+@@ -543,6 +574,10 @@
+ {
+     int olderrno = errno;
+ 
++#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_TEST)
++    fprintf(stderr, "GiveUp: Called with signal [%d].\n", sig);
++#endif
++
+     dispatchException |= DE_TERMINATE;
+     isItTimeToYield = TRUE;
+ #if defined(SYSV) && defined(X_NOT_POSIX)
+@@ -1548,12 +1583,21 @@
+ #define SMART_SCHEDULE_TIMER		ITIMER_REAL
+ #endif
+ 
++#ifdef NX_TRANS_SOCKET
++void
++SmartScheduleStopTimer (void)
++#else
+ static void
+ SmartScheduleStopTimer (void)
++#endif
+ {
+ #ifdef SMART_SCHEDULE_POSSIBLE
+     struct itimerval	timer;
+-    
++
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "SmartScheduleStopTimer: Stopping timer.\n");
++    #endif
++
+     timer.it_interval.tv_sec = 0;
+     timer.it_interval.tv_usec = 0;
+     timer.it_value.tv_sec = 0;
+@@ -1568,7 +1612,21 @@
+ {
+ #ifdef SMART_SCHEDULE_POSSIBLE
+     struct itimerval	timer;
+-    
++
++    #ifdef NX_TRANS_SOCKET
++
++    if (SmartScheduleDisable)
++    {
++      return FALSE;
++    }
++
++    #endif
++
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "SmartScheduleStartTimer: Starting timer with [%ld] ms.\n",
++                SmartScheduleInterval);
++    #endif
++
+     SmartScheduleTimerStopped = FALSE;
+     timer.it_interval.tv_sec = 0;
+     timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
+@@ -1586,6 +1644,12 @@
+     int olderrno = errno;
+ 
+     SmartScheduleTime += SmartScheduleInterval;
++
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "SmartScheduleTimer: Got timer with time [%ld] ms.\n",
++                SmartScheduleTime);
++    #endif
++
+     if (SmartScheduleIdle)
+     {
+ 	SmartScheduleStopTimer ();
+@@ -1603,6 +1667,10 @@
+     if (SmartScheduleDisable)
+ 	return TRUE;
+     
++    #ifdef NX_TRANS_TEST
++    fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n");
++    #endif
++
+     bzero ((char *) &act, sizeof(struct sigaction));
+ 
+     /* Set up the timer signal function */
+@@ -1714,6 +1782,11 @@
+     ErrorF("System: `%s'\n", command);
+ #endif
+ 
++#ifdef NX_TRANS_EXIT
++    if (OsVendorStartRedirectErrorFProc != NULL) {
++        OsVendorStartRedirectErrorFProc();
++    }
++#endif
+     switch (pid = fork()) {
+     case -1:	/* error */
+ 	p = -1;
+@@ -1730,6 +1803,11 @@
+ 	} while (p == -1 && errno == EINTR);
+ 	
+     }
++#ifdef NX_TRANS_EXIT
++    if (OsVendorEndRedirectErrorFProc != NULL) {
++        OsVendorEndRedirectErrorFProc();
++    }
++#endif
+ 
+ #ifdef SIGCHLD
+     signal(SIGCHLD, csig);
+@@ -1765,11 +1843,23 @@
+ 	return NULL;
+     }
+ 
++#ifdef NX_TRANS_EXIT
++    if (OsVendorStartRedirectErrorFProc != NULL) {
++        OsVendorStartRedirectErrorFProc();
++    }
++    OsBlockSignals ();
++#endif
+     switch (pid = fork()) {
+     case -1: 	/* error */
+ 	close(pdes[0]);
+ 	close(pdes[1]);
+ 	xfree(cur);
++#ifdef NX_TRANS_EXIT
++	if (OsVendorEndRedirectErrorFProc != NULL) {
++	    OsVendorEndRedirectErrorFProc();
++	}
++	OsReleaseSignals ();
++#endif
+ 	return NULL;
+     case 0:	/* child */
+ 	if (setgid(getgid()) == -1)
+@@ -1791,12 +1881,61 @@
+ 	    }
+ 	    close(pdes[1]);
+ 	}
++
++        #ifdef NX_TRANS_SOCKET
++
++        /*
++         * Check if the child process should not
++         * use the parent's libraries.
++         */
++
++        if (_NXUnsetLibraryPath)
++        {
++          #ifndef __sun
++
++          unsetenv ("LD_LIBRARY_PATH");
++
++          #else
++
++          extern char **environ;
++
++          char **ep = environ;
++
++          ep = environ;
++
++          while (*ep)
++          {
++            if (!strncmp("LD_LIBRARY_PATH=", *ep, strlen("LD_LIBRARY_PATH=")))
++            {
++              break;
++            }
++
++            *ep++;
++          }
++
++          while (*ep)
++          {
++            *ep = *(ep + 1);
++            ep++;
++          }
++
++          #endif
++        }
++
++        #endif
++
++        #ifdef NX_TRANS_EXIT
++	OsReleaseSignals ();
++        #endif
++
+ 	execl("/bin/sh", "sh", "-c", command, (char *)NULL);
+ 	_exit(127);
+     }
+ 
++#ifndef NX_TRANS_EXIT
+     /* Avoid EINTR during stdio calls */
+     OsBlockSignals ();
++#endif
+     
+     /* parent */
+     if (*type == 'r') {
+@@ -1945,6 +2084,11 @@
+     /* allow EINTR again */
+     OsReleaseSignals ();
+     
++#ifdef NX_TRANS_EXIT
++    if (OsVendorEndRedirectErrorFProc != NULL) {
++        OsVendorEndRedirectErrorFProc();
++    }
++#endif
+     return pid == -1 ? -1 : pstat;
+ }
+ 
diff --git a/doc/nx-X11_vs_XOrg69_patches/xdmcp.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/xdmcp.c.NX.patch
new file mode 100644
index 0000000..47e2314
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/xdmcp.c.NX.patch
@@ -0,0 +1,59 @@
+--- ./nx-X11/programs/Xserver/os/xdmcp.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/os/xdmcp.c	2015-02-10 19:13:13.472698316 +0100
+@@ -59,6 +59,13 @@
+ #include <netdir.h>
+ #endif
+ 
++#ifndef NX_TRANS_SOCKET
++
++#define NX_TRANS_SOCKET
++#define NX_TRANS_TEST
++
++#endif
++
+ #ifdef XDMCP
+ #undef REQUEST
+ 
+@@ -71,6 +78,15 @@
+ #define X_INCLUDE_NETDB_H
+ #include <X11/Xos_r.h>
+ 
++#ifdef NX_TRANS_SOCKET
++
++xdmcp_states XdmcpState;
++
++int XdmcpStartTime;
++int XdmcpTimeOutRtx;
++
++#endif
++
+ extern char *defaultDisplayClass;
+ 
+ static int		    xdmcpSocket, sessionSocket;
+@@ -590,6 +606,12 @@
+ void 
+ XdmcpInit(void)
+ {
++#ifdef NX_TRANS_SOCKET
++
++    XdmcpStartTime = GetTimeInMillis();	
++
++#endif
++
+     state = XDM_INIT_STATE;
+ #ifdef HASXDMAUTH
+     if (xdmAuthCookie)
+@@ -699,6 +721,13 @@
+     fd_set* LastSelectMask = (fd_set*)pReadmask;
+     fd_set   devicesReadable;
+ 
++#ifdef NX_TRANS_SOCKET
++
++    XdmcpState = state;
++    XdmcpTimeOutRtx = timeOutRtx;
++
++#endif
++
+     if (state == XDM_OFF)
+ 	return;
+     if (i > 0)
diff --git a/doc/nx-X11_vs_XOrg69_patches/xf86glx.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/xf86glx.c.NX.patch
new file mode 100644
index 0000000..eaa3a16
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/xf86glx.c.NX.patch
@@ -0,0 +1,70 @@
+--- ./nx-X11/programs/Xserver/GL/mesa/X/xf86glx.c.X.original	2015-02-13 14:03:44.680442769 +0100
++++ ./nx-X11/programs/Xserver/GL/mesa/X/xf86glx.c	2015-02-10 19:13:14.340665851 +0100
+@@ -71,6 +71,10 @@
+ 
+ #include "glcontextmodes.h"
+ 
++#ifdef NXAGENT_SERVER
++#include "../main/WSDrawBuffer.h"
++#endif
++
+ /*
+  * This structure is statically allocated in the __glXScreens[]
+  * structure.  This struct is not used anywhere other than in
+@@ -95,6 +99,36 @@
+     NULL                  /* WrappedPositionWindow is overwritten */
+ };
+ 
++#ifdef NXAGENT_SERVER
++WSDrawBufferPtr pWSDrawBuffer = NULL;
++
++void AddWSDrawBuffer(GLframebuffer *mesa_buffer)
++{
++  WSDrawBufferPtr prevWSDB;
++  WSDrawBufferPtr newWSDB;
++  WSDrawBufferPtr p;
++
++  prevWSDB = NULL;
++  newWSDB = NULL;
++  p = pWSDrawBuffer;
++  while (p != NULL) {
++    prevWSDB = p;
++    if (prevWSDB -> DrawBuffer == mesa_buffer) {
++      return;
++    }
++    p = p -> next;
++  }
++  newWSDB = malloc(sizeof(WSDrawBufferRec));
++  newWSDB -> DrawBuffer = mesa_buffer;
++  newWSDB -> next = NULL;
++
++  if (pWSDrawBuffer == NULL)
++    pWSDrawBuffer = newWSDB;
++  else
++    prevWSDB -> next = newWSDB;
++}
++#endif
++
+ void *__glXglDDXScreenInfo(void) {
+     return &__glDDXScreenInfo;
+ }
+@@ -748,6 +782,10 @@
+     __MESA_buffer buf = (__MESA_buffer)glPriv->private;
+     __GLXdrawablePrivate *glxPriv = (__GLXdrawablePrivate *)glPriv->other;
+ 
++#ifdef NXAGENT_SERVER
++    AddWSDrawBuffer(& (buf -> xm_buf -> mesa_buffer) );
++#endif
++
+     /* Destroy Mesa's buffers */
+     if (buf->xm_buf)
+ 	XMesaDestroyBuffer(buf->xm_buf);
+@@ -757,7 +795,7 @@
+     glPriv->frontBuffer.resize = buf->fbresize;
+ 
+     __glXFree(glPriv->private);
+-    glPriv->private = NULL;
++    glPriv->private = NULL; 
+ }
+ 
+ __GLinterface *__MESA_createContext(__GLimports *imports,
diff --git a/doc/nx-X11_vs_XOrg69_patches/xkbDflts.h.NX.patch b/doc/nx-X11_vs_XOrg69_patches/xkbDflts.h.NX.patch
new file mode 100644
index 0000000..41ef709
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/xkbDflts.h.NX.patch
@@ -0,0 +1,24 @@
+--- ./nx-X11/programs/Xserver/xkb/xkbDflts.h.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/xkb/xkbDflts.h	2015-02-10 19:13:13.736688433 +0100
+@@ -417,10 +417,21 @@
+          XkbSI_AnyOfOrNone, 0xff,
+          255,
+        {   XkbSA_LockControls, { 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } } },
++
++#ifndef NX_TRANS_SOCKET
++
++    /*
++     * Make sure that the server can't be killed
++     * by pressing this key-sequence.
++     */
++
+     {    XK_Terminate_Server, 0x0000,
+          XkbSI_AnyOfOrNone, 0xff,
+          255,
+        {      XkbSA_Terminate, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } },
++
++#endif
++
+     {    XK_ISO_Group_Latch, 0x0000,
+          XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+          3,
diff --git a/doc/nx-X11_vs_XOrg69_patches/xprintf.c.NX.patch b/doc/nx-X11_vs_XOrg69_patches/xprintf.c.NX.patch
new file mode 100644
index 0000000..fa0796d
--- /dev/null
+++ b/doc/nx-X11_vs_XOrg69_patches/xprintf.c.NX.patch
@@ -0,0 +1,75 @@
+--- ./nx-X11/programs/Xserver/os/xprintf.c.X.original	2015-02-13 14:03:44.792440567 +0100
++++ ./nx-X11/programs/Xserver/os/xprintf.c	2015-02-10 19:13:13.480698017 +0100
+@@ -43,6 +43,63 @@
+ # endif
+ #endif
+     
++#ifdef NX_TRANS_SOCKET
++
++#define PANIC
++#define WARNING
++#undef  TEST
++#undef  DEBUG
++
++#define START_SIZE  256
++#define END_SIZE   2048
++
++char *
++Xvprintf(const char *format, va_list va)
++{
++    char *ret;
++    char *newret;
++    int size;
++    int r;
++
++    size = 0;
++
++    for (;;)
++    {
++      if (size == 0)
++      {
++        ret = (char *)malloc(START_SIZE);
++        if (ret == NULL)
++          return NULL;
++        size = START_SIZE;
++      }
++      else if (size < END_SIZE &&
++                   (newret = (char *) realloc(ret, 2 * size)) != NULL)
++      {
++        ret = newret;
++        size = 2 * size;
++      }
++      else
++      {
++        free(ret);
++        return NULL;
++      }
++
++      r = vsnprintf(ret, size, format, va);
++
++      if (r == -1 || r == size || r > size || r == size - 1)
++      {
++        continue;
++      }
++      else
++      {
++        ret[r] = 0;
++        return ret;
++      }
++    }
++}
++
++#else
++
+ char *
+ Xvprintf(const char *format, va_list va)
+ {
+@@ -63,6 +120,8 @@
+     return ret;
+ }
+ 
++#endif
++
+ char *Xprintf(const char *format, ...)
+ {
+     char *ret;

--
Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/nx-libs.git


More information about the x2go-commits mailing list