diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-13 14:14:26 +0100 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-13 14:18:50 +0100 |
commit | 1e5ee575d4912665dd2356681f0827d5229fa1f5 (patch) | |
tree | 31db7768b2686507a5f9ea2ffa03d9c62ccf78c9 /doc/nx-X11_vs_XOrg69_patches | |
parent | 1fd8551f1632efbc2655c9293087bba08cf2f0c9 (diff) | |
download | nx-libs-1e5ee575d4912665dd2356681f0827d5229fa1f5.tar.gz nx-libs-1e5ee575d4912665dd2356681f0827d5229fa1f5.tar.bz2 nx-libs-1e5ee575d4912665dd2356681f0827d5229fa1f5.zip |
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.
Diffstat (limited to 'doc/nx-X11_vs_XOrg69_patches')
88 files changed, 20245 insertions, 0 deletions
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 000000000..940a3fee4 --- /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 000000000..085401dd9 --- /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 000000000..333838d51 --- /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 000000000..17f054970 --- /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 000000000..6dd036e2c --- /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 000000000..fb5e164a3 --- /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 000000000..7f3db6c8b --- /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 000000000..6620d4baa --- /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 000000000..06d91218f --- /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 000000000..d9e35f7ae --- /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 000000000..f491948f0 --- /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 000000000..f2f9e37ee --- /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 000000000..84c5b130a --- /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 000000000..a8dbfe0fd --- /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 000000000..8ac8e4662 --- /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 000000000..c8d302c97 --- /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 000000000..76f0a1625 --- /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 000000000..829a95df4 --- /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 000000000..37b68d613 --- /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 000000000..220b26a49 --- /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 000000000..7d6be7b0c --- /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 000000000..9713e4495 --- /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 000000000..9150cfae8 --- /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 000000000..7327501ac --- /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 000000000..62c9e339f --- /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 000000000..3c7f45e46 --- /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 000000000..ecc5d490c --- /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 000000000..667dadc42 --- /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 000000000..d8c20669d --- /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 000000000..6ddefa10c --- /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 000000000..897fe2598 --- /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 000000000..7d87f13b1 --- /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 000000000..027ad7951 --- /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 000000000..e69de29bb --- /dev/null +++ b/doc/nx-X11_vs_XOrg69_patches/WSDrawBuffer.h.NX.patch 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 000000000..3850a2b26 --- /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 000000000..de5574c32 --- /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 000000000..f85303bb2 --- /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 000000000..794ccf09a --- /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 000000000..82494f70a --- /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 000000000..b76e169ee --- /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 000000000..a23172ed9 --- /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 000000000..b869d589d --- /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 000000000..8bda13795 --- /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 000000000..fc81419d7 --- /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 000000000..d7549c487 --- /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 000000000..ecd0f67bb --- /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 000000000..c929125f7 --- /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 000000000..f25c0160e --- /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 000000000..92dedfc0a --- /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 000000000..907c5c850 --- /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 000000000..faf242160 --- /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 000000000..a6acd7c04 --- /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 000000000..3c2eda498 --- /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 000000000..1f0cbd4fd --- /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 000000000..f4bffa980 --- /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 000000000..116badc07 --- /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 000000000..343526131 --- /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 000000000..47db91cca --- /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 000000000..f3454e760 --- /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 000000000..ab93486c4 --- /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 000000000..44407e05a --- /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 000000000..2ee26838e --- /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 000000000..88acc878a --- /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 000000000..3424f2e4a --- /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 000000000..77b32d21c --- /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 000000000..6462b1176 --- /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 000000000..d19f82022 --- /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 000000000..a6f2d9c95 --- /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 000000000..5c4ed74eb --- /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 000000000..601bc0a98 --- /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 000000000..16fa7adcc --- /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 000000000..1ae924df0 --- /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 000000000..3f1514250 --- /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 000000000..6cb8359b7 --- /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 000000000..8a4cc1387 --- /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 000000000..ddbe739b6 --- /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 000000000..c5c3d4757 --- /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 000000000..f95d6325a --- /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@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 000000000..bb461afcd --- /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 000000000..9876bf465 --- /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 000000000..444c142be --- /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 000000000..17f858440 --- /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 000000000..487c295fc --- /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 000000000..5e18abfdb --- /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 000000000..47e231453 --- /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 000000000..eaa3a1624 --- /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 000000000..41ef7091e --- /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 000000000..fa0796dc9 --- /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; |