--- ./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;
     }
 }
+
