Original nxagent-3.5.0-9
authordimbor <i@dimbor.ru>
Thu, 20 Nov 2014 21:31:19 +0000 (00:31 +0300)
committerdimbor <i@dimbor.ru>
Thu, 20 Nov 2014 21:31:19 +0000 (00:31 +0300)
41 files changed:
nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
nx-X11/programs/Xserver/hw/nxagent/NXevents.c
nx-X11/programs/Xserver/hw/nxagent/NXextension.c
nx-X11/programs/Xserver/hw/nxagent/NXglxext.c
nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c
nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c
nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c
nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
nx-X11/programs/Xserver/hw/nxagent/NXrender.c
nx-X11/programs/Xserver/hw/nxagent/NXresource.c
nx-X11/programs/Xserver/hw/nxagent/NXshm.c
nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c
nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c

index a385a8b09ea155869bfbae1625855ef7bfec4a6c..4f59b8098f4e4099a54119d06a1d64c702f1acb7 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdispatch.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
 /* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
 /************************************************************
 
@@ -75,6 +98,15 @@ SOFTWARE.
 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 "fontstruct.h"
 #include "dixfontstr.h"
@@ -88,7 +120,7 @@ int ProcInitialConnection();
 #include "servermd.h"
 #include "extnsionst.h"
 #include "dixfont.h"
-#include "dispatch.h"
+#include "../../dix/dispatch.h"
 #include "swaprep.h"
 #include "swapreq.h"
 #ifdef PANORAMIX
@@ -107,8 +139,68 @@ int ProcInitialConnection();
 #include "inputstr.h"
 #include "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"
+
+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)
@@ -125,6 +217,20 @@ extern char *ConnectionInfo;
 Selection *CurrentSelections;
 int NumCurrentSelections;
 
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+                                   (pWin) == nxagentViewportFrameRight || \
+                                       (pWin) == nxagentViewportFrameAbove || \
+                                           (pWin) == nxagentViewportFrameBelow)
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
 static ClientPtr grabClient;
 #define GrabNone 0
 #define GrabActive 1
@@ -212,6 +318,30 @@ InitSelections()
        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 
@@ -249,7 +379,13 @@ FlushClientCaches(id)
 #define SMART_SCHEDULE_DEFAULT_INTERVAL        20          /* ms */
 #define SMART_SCHEDULE_MAX_SLICE       200         /* ms */
 
-Bool       SmartScheduleDisable;
+/*
+ * Disable the SmartScheduler as it doesn't
+ * seem to work for us.
+ */
+
+Bool       SmartScheduleDisable = True;
+
 long       SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
 long       SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
 long       SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
@@ -360,18 +496,71 @@ Dispatch(void)
     int                        start_tick;
 #endif
 
-    #ifdef __DARWIN__
-    extern char dispatchExceptionAtReset;
-    #endif    
+    unsigned long currentDispatch = 0;
 
     nextFreeClientID = 1;
     InitSelections();
     nClients = 0;
 
+    /*
+     * The agent initialization was successfully
+     * completed. We can now handle our clients.
+     */
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+      nxagentSessionState = SESSION_UP;
+    }
+
+#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])
@@ -380,8 +569,60 @@ Dispatch(void)
            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;
+        }
+
+        #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)
        {
@@ -433,6 +674,11 @@ Dispatch(void)
 #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) 
                {
@@ -440,6 +686,28 @@ Dispatch(void)
                        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
@@ -451,8 +719,40 @@ Dispatch(void)
                if (result > (MAX_BIG_REQUEST_SIZE << 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)
@@ -473,31 +773,39 @@ Dispatch(void)
            requestingClient = NULL;
        }
        dispatchException &= ~DE_PRIORITYCHANGE;
+    }
 
-        /* 
-         * On Darwin we found that the it is not possible
-         * to get the correct keyboard layout unless it is
-         * set on the local machine, before the NX session
-         * is started, by using xmodmap. As we set the key-
-         * board locally, we must prevent the X server to
-         * reset, otherwise we would loose any local confi-
-         * guration. The code below is aimed at this. Note
-         * also that a statically compiled version of xmod-
-         * map is included in the MacOS/X package.
-         */
+    if ((dispatchException & DE_RESET) && 
+            (serverGeneration > nxagentMaxAllowedResets))
+    {
+        dispatchException &= ~DE_RESET;
+        dispatchException |= DE_TERMINATE;
 
-        #ifdef __DARWIN__
+        fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+    }
 
-        if (dispatchException & DE_RESET )
-        {
-          dispatchException &= ~DE_RESET;
+    nxagentResetAtomMap();
 
-          dispatchExceptionAtReset = DE_TERMINATE;
-        }
+    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());
 
-        #endif /* __DARWIN__ */
+      nxagentWaitDisplay();
 
+      fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
     }
+
+    if (nxagentOption(Shadow))
+    {
+      NXShadowDestroy();
+    }
+
     KillAllClients();
     DEALLOCATE_LOCAL(clientReady);
     dispatchException &= ~DE_RESET;
@@ -678,6 +986,12 @@ ProcReparentWindow(client)
                                           SecurityWriteAccess);
     if (!pWin)
         return(BadWindow);
+
+    if (!nxagentWMPassed)
+    {
+      nxagentRemoveSplashWindow(pWin);
+    }
+
     pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
                                              SecurityWriteAccess);
     if (!pParent)
@@ -749,6 +1063,7 @@ ProcUnmapWindow(client)
         return(BadWindow);
     UnmapWindow(pWin, FALSE);
            /* update cache to say it is mapped */
+
     return(client->noClientException);
 }
 
@@ -787,6 +1102,7 @@ ProcConfigureWindow(client)
         return BadLength;
     result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
                              client);
+
     if (client->noClientException != Success)
         return(client->noClientException);
     else
@@ -897,7 +1213,12 @@ ProcQueryTree(client)
         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;
@@ -906,7 +1227,12 @@ ProcQueryTree(client)
        if (!childIDs)
            return BadAlloc;
        for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+        {
+          if (!IsViewportFrame(pChild))
+          {
            childIDs[curChild++] = pChild->drawable.id;
+          }
+        }
     }
     
     reply.nChildren = numChildren;
@@ -1065,6 +1391,16 @@ ProcSetSelectionOwner(client)
        CurrentSelections[i].window = stuff->window;
        CurrentSelections[i].pWin = pWin;
        CurrentSelections[i].client = (pWin ? client : NullClient);
+
+#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 
@@ -1121,6 +1457,27 @@ ProcConvertSelection(client)
     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);
@@ -1132,7 +1489,7 @@ ProcConvertSelection(client)
        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,
@@ -1318,11 +1675,26 @@ ProcOpenFont(client)
     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)
@@ -1343,8 +1715,43 @@ ProcCloseFont(client)
     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);
     }
@@ -1366,6 +1773,8 @@ ProcQueryFont(client)
 
     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)
@@ -1381,6 +1790,33 @@ ProcQueryFont(client)
        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);
@@ -1398,6 +1834,7 @@ ProcQueryFont(client)
        rlength = sizeof(xQueryFontReply) +
                     FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
                     nprotoxcistructs * sizeof(xCharInfo);
+        reply = NULL;
        reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
        if(!reply)
        {
@@ -1470,10 +1907,18 @@ int
 ProcListFonts(client)
     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);
 }
@@ -1482,10 +1927,18 @@ int
 ProcListFontsWithInfo(client)
     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);
 }
@@ -1556,6 +2009,40 @@ ProcFreePixmap(client)
                                             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);
     }
@@ -1850,8 +2337,10 @@ ProcPolyPoint(client)
     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);
 }
 
@@ -1874,8 +2363,10 @@ ProcPolyLine(client)
     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);
 }
 
@@ -1895,7 +2386,9 @@ ProcPolySegment(client)
        return(BadLength);
     nsegs >>= 3;
     if (nsegs)
+    {
         (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -1915,8 +2408,10 @@ ProcPolyRectangle (client)
        return(BadLength);
     nrects >>= 3;
     if (nrects)
+    {
         (*pGC->ops->PolyRectangle)(pDraw, pGC, 
                    nrects, (xRectangle *) &stuff[1]);
+    }
     return(client->noClientException);
 }
 
@@ -1936,7 +2431,9 @@ ProcPolyArc(client)
        return(BadLength);
     narcs /= sizeof(xArc);
     if (narcs)
+    {
         (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -1966,9 +2463,11 @@ ProcFillPoly(client)
     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);
 }
 
@@ -1989,8 +2488,10 @@ ProcPolyFillRectangle(client)
     things >>= 3;
 
     if (things)
+    {
         (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
                      (xRectangle *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -2010,7 +2511,9 @@ ProcPolyFillArc(client)
        return(BadLength);
     narcs /= sizeof(xArc);
     if (narcs)
+    {
         (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -3188,7 +3691,14 @@ ProcCreateCursor( client)
            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;
 }
 
@@ -3308,23 +3818,67 @@ ProcSetScreenSaver            (client)
         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;
+      }
+    }
+    #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
+
     return (client->noClientException);
 }
 
@@ -3553,7 +4107,30 @@ int ProcForceScreenSaver(client)
        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;
 }
 
@@ -3598,8 +4175,6 @@ InitProcVectors(void)
  *  then killed again, the client is really destroyed.
  *********************/
 
-char dispatchExceptionAtReset = DE_RESET;
-
 void
 CloseDownClient(client)
     register ClientPtr client;
@@ -3607,6 +4182,28 @@ CloseDownClient(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 */
@@ -3750,7 +4347,7 @@ void InitClient(client, i, ospriv)
     client->numSaved = 0;
     client->saveSet = (pointer *)NULL;
     client->noClientException = Success;
-#ifdef DEBUG
+#ifdef LOG_DEBUG
     client->requestLogIndex = 0;
 #endif
     client->requestVector = InitialVector;
@@ -3824,6 +4421,13 @@ InitClientPrivates(client)
        else
            ppriv->ptr = (pointer)NULL;
     }
+
+    /*
+     * Initialize the private members.
+     */
+
+    nxagentInitClientPrivates(client);
+
     return 1;
 }
 
@@ -4108,3 +4712,5 @@ MarkClientException(client)
 {
     client->noClientException = -1;
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 5386c908bec2b7137811e611cd86b0ac2e5c620d..1cccfd972ed876ddfdca9127cbfd44639b794048 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdixfonts.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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/dixfonts.c,v 3.27 2003/02/15 03:47:05 dawes Exp $ */
 /************************************************************************
 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
@@ -37,12 +60,83 @@ SOFTWARE.
 #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:
+
+    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"
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
 #endif
 
 #ifdef LBX
@@ -237,6 +331,9 @@ doOpenFont(client, c)
                *newname;
     int         newlen;
     int                aliascount = 20;
+    char nxagentOrigFontName[256];
+    int nxagentOrigFontNameLen;
+
     /*
      * Decide at runtime what FontFormat to use.
      */
@@ -268,6 +365,13 @@ doOpenFont(client, c)
 
        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)
@@ -316,6 +420,9 @@ doOpenFont(client, c)
            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;
        }
@@ -337,10 +444,15 @@ doOpenFont(client, c)
            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;
                }
            }
@@ -350,8 +462,19 @@ doOpenFont(client, c)
        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) {
@@ -359,7 +482,12 @@ bail:
                          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]);
     }
@@ -493,7 +621,10 @@ CloseFont(value, fid)
        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);
@@ -630,6 +761,9 @@ doListFontsAndAliases(client, c)
                    ClientSleep(client,
                        (ClientSleepProcPtr)doListFontsAndAliases,
                        (pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
                }
                return TRUE;
            }
@@ -658,6 +792,9 @@ doListFontsAndAliases(client, c)
                                    (ClientSleepProcPtr)doListFontsAndAliases,
                                    (pointer) c);
                        c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
                    }
                    return TRUE;
                }
@@ -676,6 +813,9 @@ doListFontsAndAliases(client, c)
                                    (ClientSleepProcPtr)doListFontsAndAliases,
                                    (pointer) c);
                        c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
                    }
                    return TRUE;
                }
@@ -812,6 +952,24 @@ finish:
            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];
@@ -826,7 +984,12 @@ finish:
 
 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);
@@ -864,7 +1027,7 @@ ListFonts(client, pattern, length, max_names)
        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);
@@ -937,6 +1100,9 @@ doListFontsWithInfo(client, c)
                {
                    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
                    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
                }
                return TRUE;
            }
@@ -958,6 +1124,9 @@ doListFontsWithInfo(client, c)
                             (ClientSleepProcPtr)doListFontsWithInfo,
                             c);
                    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
                }
                return TRUE;
            }
@@ -1035,6 +1204,23 @@ doListFontsWithInfo(client, c)
        }
        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 +1234,6 @@ doListFontsWithInfo(client, c)
                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 +1280,12 @@ finish:
     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);
@@ -1350,6 +1535,11 @@ doPolyText(client, c)
                        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 |
@@ -1374,6 +1564,9 @@ doPolyText(client, c)
                    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;
@@ -1422,6 +1615,9 @@ bail:
     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 */
@@ -1548,6 +1744,11 @@ doImageText(client, c)
                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 |
@@ -1566,6 +1767,10 @@ doImageText(client, c)
 
            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;
     }
@@ -1588,6 +1793,9 @@ bail:
     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 */
@@ -1871,11 +2079,19 @@ SetDefaultFontPath(path)
                 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 == ',') {
@@ -2221,3 +2437,447 @@ dump_char_ascii(cip)
 }
 
 #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;
+}
+
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index ce8e53f92d675d38c5175f8d48a0b2e8d150c23d..f697cf3ca9858862d9347f899019a1e96253b61f 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXevents.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
 /************************************************************
 
@@ -71,6 +94,7 @@ SOFTWARE.
 /* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
 
 #include "X.h"
+#include "Xlib.h"
 #include "misc.h"
 #include "resource.h"
 #define NEED_EVENTS
@@ -108,7 +132,16 @@ extern Bool XkbFilterEvents();
 
 #include "dixevents.h"
 #include "dixgrabs.h"
-#include "dispatch.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
 
 #define EXTENSION_EVENT_BASE  64
 
@@ -1263,6 +1296,51 @@ ActivatePointerGrab(mouse, grab, time, autoGrab)
     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
@@ -1288,6 +1366,22 @@ DeactivatePointerGrab(mouse)
     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
@@ -1498,6 +1592,17 @@ ProcAllowEvents(client)
            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;
 }
 
@@ -1980,7 +2085,26 @@ XYToWindow(x, y)
     register WindowPtr  pWin;
 
     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) &&
@@ -2053,13 +2177,22 @@ CheckMotion(xE)
            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;
     }
@@ -2097,6 +2230,8 @@ DefineInitialRootWindow(win)
     register WindowPtr win;
 {
     register ScreenPtr pScreen = win->drawable.pScreen;
+    extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+    extern int nxagentShadowInit(ScreenPtr, WindowPtr);
 
     sprite.hotPhys.pScreen = pScreen;
     sprite.hotPhys.x = pScreen->width / 2;
@@ -2129,6 +2264,16 @@ DefineInitialRootWindow(win)
        REGION_INIT(pScreen, &sprite.Reg2, NullBox, 1);
     }
 #endif
+
+    nxagentInitViewportFrame(pScreen, win);
+
+    if (nxagentOption(Shadow))
+    {
+      if (nxagentShadowInit(pScreen, win) == -1)
+      {
+        GiveUp(0);
+      }
+    }
 }
 
 /*
@@ -2842,7 +2987,9 @@ ProcessPointerEvent (xE, mouse, count)
     Bool                deactivateGrab = FALSE;
     register ButtonClassPtr butc = mouse->button;
 #ifdef XKB
-    XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
+    XkbSrvInfoPtr xkbi;
+
+    xkbi = inputInfo.keyboard->key->xkbInfo;
 #endif
 
     if (!syncEvents.playingEvents)
@@ -4106,6 +4253,17 @@ ProcSendEvent(client)
     /* 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 &&
@@ -4635,3 +4793,5 @@ WriteEventsToClient(pClient, count, events)
        (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
     }
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 36f053f0283e77483184b23e18e2b24cad5dac46..1d86bf8708e9cfc10a093b2ca4bb61038144d4b8 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXextension.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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.12 2002/02/19 11:09:22 alanh Exp $ */
 /***********************************************************
 
@@ -56,7 +79,7 @@ SOFTWARE.
 #include "extnsionst.h"
 #include "gcstruct.h"
 #include "scrnintstr.h"
-#include "dispatch.h"
+#include "../../dix/dispatch.h"
 #ifdef XCSECURITY
 #define _SECURITY_SERVER
 #include "security.h"
@@ -65,6 +88,8 @@ SOFTWARE.
 #include "lbxserve.h"
 #endif
 
+#include "Trap.h"
+
 #define EXTENSION_BASE  128
 #define EXTENSION_EVENT_BASE  64
 #define LAST_EVENT  128
@@ -327,6 +352,13 @@ ProcQueryExtension(client)
     {
        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 &&
@@ -374,6 +406,14 @@ ProcListExtensions(client)
                !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;)
@@ -484,3 +524,5 @@ RegisterScreenProc(name, pScreen, proc)
     }
     return TRUE;
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 95a9c2e6ea6af6b468708fdbc5bdbf7c4a17b9b6..fe2f4aa6c7dfa7335b5616b0d2c6fff6dd67a586 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglxext.c"
+
+#else
+
 /* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.8 2001/08/23 18:25:40 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
 #include "glxext.h"
 #include "micmap.h"
 
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
 
 extern __GLXextensionInfo __glDDXExtensionInfo;
 
@@ -379,6 +391,8 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
 */
 static int __glXDispatch(ClientPtr client)
 {
+    int result;
+
     REQUEST(xGLXSingleReq);
     CARD8 opcode;
     int (*proc)(__GLXclientState *cl, GLbyte *pc);
@@ -428,11 +442,35 @@ static int __glXDispatch(ClientPtr client)
     ** 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);
@@ -474,7 +512,29 @@ static int __glXSwapDispatch(ClientPtr client)
     ** 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)
@@ -487,3 +547,4 @@ void __glXNoSuchRenderOpcode(GLbyte *pc)
     return;
 }
 
+#endif /* #ifdef NXAGENT_UPGRADE */
index b4f08c22328786246212c24e8ab6c2e9a61c41e2..22483b3fd3381cdc65b535f3ede7ba93e7f5e9a1 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyph.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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.6 2001/10/28 03:34:19 tsi Exp $
  *
 #include "dixstruct.h"
 #include "gcstruct.h"
 #include "servermd.h"
-#include "picturestr.h"
-#include "glyphstr.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef  DEBUG
+#undef  TEST
+
+#endif
 
 /*
  * From Knuth -- a good choice for hash/rehash values is p, p-2 where
@@ -239,7 +273,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
        gr->signature = hash;
        globalGlyphs[glyphSet->fdepth].tableEntries++;
     }
-    
     /* Insert/replace glyphset value */
     gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
     ++glyph->refcnt;
@@ -249,6 +283,13 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
        glyphSet->hash.tableEntries++;
     gr->glyph = glyph;
     gr->signature = id;
+
+    #ifdef NXAGENT_SERVER
+
+    gr -> corruptedGlyph = 1;
+
+    #endif
+
     CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
 }
 
@@ -270,6 +311,36 @@ DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
     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)
 {
@@ -281,6 +352,8 @@ FindGlyph (GlyphSetPtr glyphSet, Glyph id)
     return glyph;
 }
 
+#endif
+
 GlyphPtr
 AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
@@ -321,6 +394,12 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
     int                    oldSize;
     CARD32         s;
 
+    #ifdef NXAGENT_SERVER
+
+    CARD32          c;
+
+    #endif
+
     tableEntries = hash->tableEntries + change;
     hashSet = FindGlyphHashSet (tableEntries);
     if (hashSet == hash->hashSet)
@@ -338,9 +417,23 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
            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;
            }
        }
@@ -414,3 +507,5 @@ FreeGlyphSet (pointer       value,
     }
     return Success;
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 630e98fa36c70e3870ba5aed5e3b1ad721d4df2b..9212bf438c959fab5e73e7ca1a9a86ebfbe41f89 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyphcurs.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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
@@ -58,6 +81,12 @@ SOFTWARE.
 #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 +127,68 @@ ServerBitsFromGlyph(pfont, ch, cm, ppbits)
     /* 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;
 }
 
@@ -195,3 +248,5 @@ CursorMetricsFromGlyph( pfont, ch, cm)
     }
     return TRUE;
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 99f55e3eb5ac1222530c7d390960209594beb77e..0f122be4a8068f6139f3f94cfd8197afafd5a833 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyphstr.h"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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.4 2001/01/21 21:19:39 tsi Exp $
  *
  * 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 "renderproto.h"
-#include "picture.h"
+#include "../../render/picture.h"
 #include "screenint.h"
 
 #define GlyphFormat1   0
@@ -47,6 +77,7 @@ typedef struct _Glyph {
 typedef struct _GlyphRef {
     CARD32     signature;
     GlyphPtr   glyph;
+    CARD16      corruptedGlyph;
 } GlyphRefRec, *GlyphRefPtr;
 
 #define DeletedGlyph   ((GlyphPtr) 1)
@@ -68,6 +99,7 @@ typedef struct _GlyphSet {
     PictFormatPtr   format;
     int                    fdepth;
     GlyphHashRec    hash;
+    CARD32          remoteID;
 } GlyphSetRec, *GlyphSetPtr;
 
 typedef struct _GlyphList {
@@ -125,3 +157,5 @@ FreeGlyphSet (pointer   value,
 
 
 #endif /* _GLYPHSTR_H_ */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index ca896b9e06284bdfbb065bed2c3d741a962b94a9..bd068170c5181f6d2c0d4600a546fc618a1f4c86 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiexpose.c"
+
+#else
+
 /* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9 2001/12/14 20:00:22 dawes Exp $ */
 /***********************************************************
 
@@ -77,6 +83,12 @@ SOFTWARE.
 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
@@ -126,6 +138,20 @@ miHandleExposures(pSrcDrawable, pDstDrawable,
     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;
 
@@ -466,6 +492,11 @@ miWindowExposures(pWin, prgn, other_exposed)
     WindowPtr pWin;
     register RegionPtr prgn, other_exposed;
 {
+#ifdef NXAGENT_SERVER
+
+    int total;
+
+#endif
     RegionPtr   exposures = prgn;
     if (pWin->backStorage && prgn)
        /*
@@ -501,7 +532,20 @@ miWindowExposures(pWin, prgn, other_exposed)
            }
            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
@@ -634,6 +678,25 @@ int what;
     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)
@@ -871,3 +934,5 @@ miClearDrawable(pDraw, pGC)
     DoChangeGC(pGC, GCForeground, &fg, 0);
     ValidateGC(pDraw, pGC);
 }
+
+#endif /* NXAGENT_UPGRADE */
index 00b6764d620ce7dffe91d190afdebe54432a39e9..09901ba9cc5b37969c4a0430dee94e9357c4f260 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiglyph.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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.6 2000/12/05 03:13:31 keithp Exp $
  *
 #include "picturestr.h"
 #include "mipict.h"
 
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
 void
 miGlyphExtents (int            nlist,
                GlyphListPtr    list,
@@ -41,7 +70,7 @@ miGlyphExtents (int           nlist,
     int                n;
     GlyphPtr   glyph;
     int                x, y;
-    
     x = 0;
     y = 0;
     extents->x1 = MAXSHORT;
@@ -109,25 +138,58 @@ miGlyphs (CARD8           op,
     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);
@@ -156,6 +218,7 @@ miGlyphs (CARD8             op,
        x += list->xOff;
        y += list->yOff;
        n = list->len;
+
        while (n--)
        {
            glyph = *glyphs++;
@@ -180,6 +243,21 @@ miGlyphs (CARD8            op,
            (*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)
            {
@@ -211,6 +289,7 @@ miGlyphs (CARD8             op,
            x += glyph->info.xOff;
            y += glyph->info.yOff;
        }
+
        list++;
        if (pPicture)
        {
@@ -233,7 +312,11 @@ miGlyphs (CARD8            op,
                          0, 0,
                          x, y,
                          width, height);
+
        FreePicture ((pointer) pMask, (XID) 0);
        (*pScreen->DestroyPixmap) (pMaskPixmap);
     }
+
 }
+
+#endif /* NXAGENT_UPGRADE */
index 7f592ccd480b94c81146ab63b1fd674b5613b730..7d0a99572de36b523695aee055f821bff0a53eb3 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmitrap.c"
+
+#else
+
 /*
  * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.9 2002/11/05 23:39:16 keithp Exp $
  *
@@ -194,3 +200,5 @@ miTrapezoids (CARD8     op,
        FreePicture (pPicture, 0);
     }
 }
+
+#endif /* NXAGENT_UPGRADE */
index fbced41c6b21f3ed9f72b08651ea77f1c9ccfd4d..ea2e7df28067ed2895bd3ff5c0f798e1ef87bce1 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiwindow.c"
+
+#else
+
 /* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.7 2001/12/14 20:00:28 dawes Exp $ */
 /***********************************************************
 
@@ -1038,8 +1044,29 @@ miSetShape(pWin)
        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;
@@ -1174,3 +1201,5 @@ miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
            miSegregateChildren(pChild, pReg, depth);
     }
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index b2ef69bdfb5124b8e8e2f8f3fe8a641666b863c0..d32cdb6c498a9620ba31e677c12418bb1673b85f 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXpicture.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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.30 2003/01/26 16:40:43 eich Exp $
  *
 #include "dixstruct.h"
 #include "gcstruct.h"
 #include "servermd.h"
-#include "picturestr.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
 
 int            PictureScreenPrivateIndex = -1;
 int            PictureWindowPrivateIndex;
@@ -158,7 +187,11 @@ addFormat (FormatInitRec    formats[256],
 PictFormatPtr
 PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
 {
-    int                    nformats, f;
+#ifdef NXAGENT_SERVER
+    int             nformats, f, n;
+#else
+    int             nformats, f;
+#endif
     PictFormatPtr   pFormats;
     FormatInitRec   formats[1024];
     CARD32         format;
@@ -308,12 +341,21 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
     if (!pFormats)
        return 0;
     memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+#ifdef NXAGENT_SERVER
+    for (f = 0, n = 0; n < nformats; n++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[n].depth;
+        format = formats[n].format;
+        pFormats[f].format = format;
+#else
     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;
+#endif
        switch (PICT_FORMAT_TYPE(format)) {
        case PICT_TYPE_ARGB:
            pFormats[f].type = PictTypeDirect;
@@ -370,8 +412,22 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
            pFormats[f].index.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
            break;
        }
+
+#ifdef NXAGENT_SERVER
+        if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+        {
+          f++;
+        }
+        else
+        {
+          memset(&pFormats[f], '\0', sizeof(PictFormatRec));
+        } 
+    }
+    *nformatp = f;
+#else
     }
     *nformatp = nformats;
+#endif
     return pFormats;
 }
 
@@ -720,6 +776,14 @@ AllocatePicture (ScreenPtr  pScreen)
     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,
@@ -745,6 +809,12 @@ CreatePicture (Picture             pid,
     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;
     }
@@ -1179,6 +1249,13 @@ CompositeGlyphs (CARD8           op,
     
     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);
 }
 
@@ -1303,3 +1380,133 @@ PictureTransformPoint (PictTransformPtr transform,
     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;
+  Bool success = True;
+  Bool matched;
+  int i, n;
+  CARD32 type, a, r, g, b;
+
+  #ifdef 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)
+    {
+      if ((formats[n].index.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;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectPictFormat.\n");
+  #endif
+}
+
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index cb5ea0ac95ecd67b1440b25cf9d25a59f4f51c4f..91eab01250f5e6ce9ae441e6d6c351af058541db 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXpicturestr.h"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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/picturestr.h,v 1.22 2002/11/23 02:38:15 keithp Exp $
  *
  * 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"
 
@@ -499,3 +529,5 @@ void PanoramiXRenderReset (void);
 #endif
 
 #endif /* _PICTURESTR_H_ */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index ba12faffec9f0e7a9438e6efb863d733d05389a2..20a6bd6dc916048a507d83c2736fa281a2604ddf 100644 (file)
@@ -1,3 +1,26 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXproperty.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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 $ */
 /***********************************************************
 
@@ -54,7 +77,7 @@ SOFTWARE.
 #include "windowstr.h"
 #include "propertyst.h"
 #include "dixstruct.h"
-#include "dispatch.h"
+#include "../../dix/dispatch.h"
 #include "swaprep.h"
 #ifdef XCSECURITY
 #define _SECURITY_SERVER
@@ -65,8 +88,15 @@ SOFTWARE.
 #include "lbxtags.h"
 #endif
 
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
 #if defined(LBX) || defined(LBX_COMPAT)
-int fWriteToClient(ClientPtr client, int len, char *buf)
+int fWriteToClient(client, len, buf)
+    ClientPtr   client;
+    int         len;
+    char        *buf;
 {
     return WriteToClient(client, len, buf);
 }
@@ -231,6 +261,15 @@ ProcChangeProperty(client)
     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)
@@ -258,6 +297,18 @@ ProcChangeProperty(client)
     }
 #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);
@@ -268,7 +319,19 @@ ProcChangeProperty(client)
     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);
+
+      return client->noClientException;
+    }
 }
 
 int
@@ -648,6 +711,126 @@ ProcGetProperty(client)
     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(client)
     ClientPtr client;
@@ -734,3 +917,5 @@ ProcDeleteProperty(client)
     else
        return(result);
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index a4f90ea77ef06f33fd8eda884f1328c657caa2aa..43607ac08e94c85498c48918ad67dc14b69afabd 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXrender.c"
+
+#else
+
 /*
  * $XFree86: xc/programs/Xserver/render/render.c,v 1.26 2003/02/14 18:15:21 dawes Exp $
  *
  * 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
 #include "X.h"
 #include "servermd.h"
 #include "render.h"
 #include "renderproto.h"
-#include "picturestr.h"
-#include "glyphstr.h"
 #include "Xfuncproto.h"
 #include "cursorstr.h"
 #ifdef EXTMODULE
 #include "xf86_ansic.h"
 #endif
 
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+                        GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * Functions from Render.c.
+ */
+
+int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+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);
+
+/*
+ * 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);
@@ -255,8 +333,8 @@ ProcRenderQueryVersion (ClientPtr client)
     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);
@@ -328,6 +406,8 @@ ProcRenderQueryPictFormats (ClientPtr client)
     int                                    n;
     int                                    numScreens;
     int                                    numSubpixel;
+
+    extern int                      nxagentAlphaEnabled;
 /*    REQUEST(xRenderQueryPictFormatsReq); */
 
     REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
@@ -404,7 +484,7 @@ ProcRenderQueryPictFormats (ClientPtr client)
                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;
@@ -621,6 +701,8 @@ ProcRenderCreatePicture (ClientPtr client)
                              &error);
     if (!pPicture)
        return error;
+    nxagentCreatePicture(pPicture, stuff -> mask);
+
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
        return BadAlloc;
     return Success;
@@ -632,6 +714,7 @@ ProcRenderChangePicture (ClientPtr client)
     PicturePtr     pPicture;
     REQUEST(xRenderChangePictureReq);
     int len;
+    int error;
 
     REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
@@ -640,8 +723,12 @@ ProcRenderChangePicture (ClientPtr client)
     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
@@ -655,13 +742,26 @@ ProcRenderSetPictureClipRectangles (ClientPtr client)
     REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
                    RenderErrBase + BadPicture);
-    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
@@ -678,6 +778,9 @@ ProcRenderFreePicture (ClientPtr client)
 
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
                    RenderErrBase + BadPicture);
+
+    nxagentDestroyPicture(pPicture);
+
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -694,6 +797,71 @@ PictOpValid (CARD8 op)
     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)
 {
@@ -715,6 +883,22 @@ ProcRenderComposite (ClientPtr client)
     if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
        (pMask && pSrc->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,
@@ -727,6 +911,78 @@ ProcRenderComposite (ClientPtr client)
                      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;
 }
 
@@ -775,9 +1031,19 @@ ProcRenderTrapezoids (ClientPtr client)
        return BadLength;
     ntraps /= sizeof (xTrapezoid);
     if (ntraps)
+    {
+        if (nxagentCompositePredicate(pSrc, pDst))
+        {
        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]);
+    }
+
     return client->noClientException;
 }
 
@@ -980,6 +1246,9 @@ ProcRenderCreateGlyphSet (ClientPtr client)
        return BadAlloc;
     if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
        return BadAlloc;
+
+    nxagentCreateGlyphSet(glyphSet);
+
     return Success;
 }
 
@@ -1003,6 +1272,9 @@ ProcRenderReferenceGlyphSet (ClientPtr client)
        return RenderErrBase + BadGlyphSet;
     }
     glyphSet->refcnt++;
+
+    nxagentReferenceGlyphSet(glyphSet);
+
     if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
        return BadAlloc;
     return client->noClientException;
@@ -1027,6 +1299,9 @@ ProcRenderFreeGlyphSet (ClientPtr client)
        client->errorValue = stuff->glyphset;
        return RenderErrBase + BadGlyphSet;
     }
+
+    nxagentFreeGlyphSet(glyphSet);
+
     FreeResource (stuff->glyphset, RT_NONE);
     return client->noClientException;
 }
@@ -1043,7 +1318,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     REQUEST(xRenderAddGlyphsReq);
     GlyphNewRec            glyphsLocal[NLOCALGLYPH];
     GlyphNewPtr            glyphsBase, glyphs;
-    GlyphPtr       glyph;
+    GlyphPtr       glyph = NULL;
     int                    remain, nglyphs;
     CARD32         *gids;
     xGlyphInfo     *gi;
@@ -1051,6 +1326,8 @@ ProcRenderAddGlyphs (ClientPtr client)
     int                    size;
     int                    err = BadAlloc;
 
+    int             totSizeImages;
+
     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
                                                     stuff->glyphset,
@@ -1076,10 +1353,12 @@ ProcRenderAddGlyphs (ClientPtr client)
 
     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);
@@ -1100,12 +1379,14 @@ ProcRenderAddGlyphs (ClientPtr client)
        if (size & 3)
            size += 4 - (size & 3);
        bits += size;
+       totSizeImages += size;
        remain -= size;
        gi++;
        gids++;
        glyphs++;
        nglyphs--;
     }
+
     if (nglyphs || remain)
     {
        err = BadLength;
@@ -1162,6 +1443,9 @@ ProcRenderFreeGlyphs (ClientPtr client)
     }
     nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
     gids = (CARD32 *) (stuff + 1);
+
+    nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
     while (nglyph-- > 0)
     {
        glyph = *gids++;
@@ -1174,6 +1458,14 @@ ProcRenderFreeGlyphs (ClientPtr client)
     return client->noClientException;
 }
 
+typedef struct XGlyphElt8{
+    GlyphSet                glyphset;
+    _Xconst char            *chars;
+    int                     nchars;
+    int                     xOff;
+    int                     yOff;
+} XGlyphElt8;
+
 static int
 ProcRenderCompositeGlyphs (ClientPtr client)
 {
@@ -1194,6 +1486,8 @@ ProcRenderCompositeGlyphs (ClientPtr client)
     int                    size;
     int                    n;
     
+    XGlyphElt8      *elements, *elementsBase;
+
     REQUEST(xRenderCompositeGlyphsReq);
 
     REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
@@ -1279,9 +1573,15 @@ ProcRenderCompositeGlyphs (ClientPtr client)
        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;
@@ -1289,6 +1589,11 @@ ProcRenderCompositeGlyphs (ClientPtr client)
        
        if (elt->len == 0xff)
        {
+            #ifdef DEBUG
+            fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+                        size);
+            #endif
+
            if (buffer + sizeof (GlyphSet) < end)
            {
                gs = *(GlyphSet *) buffer;
@@ -1314,6 +1619,11 @@ ProcRenderCompositeGlyphs (ClientPtr client)
            lists->yOff = elt->deltay;
            lists->format = glyphSet->format;
            lists->len = 0;
+            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--)
            {
@@ -1340,26 +1650,72 @@ ProcRenderCompositeGlyphs (ClientPtr client)
            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.
+     */
+
+    if (pFormat != NULL)
+    {
+      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);
+    }
+
+    if (nxagentGlyphsExtents != NullBox)
+    {
+      xfree(nxagentGlyphsExtents);
+
+      nxagentGlyphsExtents = NullBox;
+    }
 
     if (glyphsBase != glyphsLocal)
        DEALLOCATE_LOCAL (glyphsBase);
     if (listsBase != listsLocal)
        DEALLOCATE_LOCAL (listsBase);
     
+    xfree(elementsBase);
+
     return client->noClientException;
 }
 
@@ -1389,6 +1745,13 @@ ProcRenderFillRectangles (ClientPtr client)
                    &stuff->color,
                    things,
                    (xRectangle *) &stuff[1]);
+
+    ValidatePicture (pDst);
+    nxagentCompositeRects(stuff -> op,
+                          pDst,
+                          &stuff -> color,
+                          things,
+                          (xRectangle *) &stuff[1]);
     
     return client->noClientException;
 }
@@ -1437,6 +1800,8 @@ ProcRenderCreateCursor (ClientPtr client)
     CARD32         twocolor[3];
     int                    ncolor;
 
+    RealizeCursorProcPtr saveRealizeCursor;
+
     REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
     LEGAL_NEW_RESOURCE(stuff->cid, client);
     
@@ -1501,7 +1866,7 @@ ProcRenderCreateCursor (ClientPtr client)
        }
        pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
                                  client, &error);
-       if (!pPicture);
+       if (!pPicture)
        {
            xfree (argbbits);
            xfree (srcbits);
@@ -1600,6 +1965,20 @@ ProcRenderCreateCursor (ClientPtr client)
     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),
@@ -1607,7 +1986,27 @@ ProcRenderCreateCursor (ClientPtr client)
                               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;
 }
@@ -1623,6 +2022,9 @@ ProcRenderSetPictureTransform (ClientPtr client)
     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
@@ -1723,7 +2125,7 @@ ProcRenderQueryFilters (ClientPtr client)
     {
        register int n;
 
-       for (i = 0; i < reply->numAliases; i++)
+       for (i = 0; i < (int)reply->numAliases; i++)
        {
            swaps (&aliases[i], n);
        }
@@ -1755,6 +2157,9 @@ ProcRenderSetPictureFilter (ClientPtr client)
     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;
 }
 
@@ -1798,6 +2203,11 @@ ProcRenderCreateAnimCursor (ClientPtr client)
     if (ret != Success)
        return ret;
     
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+      pCursor -> devPriv[i] = NULL;
+    }
+
     if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
        return client->noClientException;
     return BadAlloc;
@@ -1806,10 +2216,36 @@ ProcRenderCreateAnimCursor (ClientPtr client)
 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);
+    {
+        /*
+         * 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;
 }
@@ -2059,7 +2495,7 @@ static int
 SProcRenderAddGlyphs (ClientPtr client)
 {
     register int n;
-    register int i;
+    register unsigned int i;
     CARD32  *gids;
     void    *end;
     xGlyphInfo *gi;
@@ -2271,10 +2707,36 @@ SProcRenderCreateAnimCursor (ClientPtr client)
 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;
 }
@@ -2582,3 +3044,5 @@ PanoramiXRenderReset (void)
 }
 
 #endif /* PANORAMIX */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index d17586a77291ffb363cefc6e69df4ccafb7dca97..0c81c81ef45f674f94f2569740e09230303ec1b8 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXresource.c"
+
+#else
+
 /************************************************************
 
 Copyright 1987, 1998  The Open Group
@@ -94,6 +100,20 @@ SOFTWARE.
 #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(
 #if NeedFunctionPrototypes
     int /*client*/
@@ -413,6 +433,100 @@ FakeClientID(client)
     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(id, type, value)
     XID id;
@@ -431,6 +545,18 @@ AddResource(id, type, value)
                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);
@@ -973,3 +1099,5 @@ LookupIDByClass(id, classes)
 }
 
 #endif /* XCSECURITY */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 3ba9ad2c138a2e646fac90e646d157a9683291a2..e70415a7d7e960a526018428fe2c2eb2930efa1d 100644 (file)
@@ -1,3 +1,9 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXshm.c"
+
+#else
+
 /* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.36 2002/04/03 19:51:11 herrb Exp $ */
 /************************************************************
 
@@ -65,6 +71,27 @@ in this Software without prior written authorization from The Open Group.
 #include "panoramiXsrv.h"
 #endif
 
+#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
+
+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;
@@ -159,7 +186,7 @@ static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
 }
 
 
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
 #include <sys/signal.h>
 
 static Bool badSysCall = FALSE;
@@ -197,7 +224,7 @@ ShmExtensionInit()
     ExtensionEntry *extEntry;
     int i;
 
-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
     if (!CheckForShmSyscall())
     {
        ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
@@ -205,15 +232,25 @@ ShmExtensionInit()
     }
 #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))
@@ -324,6 +361,9 @@ void
 ShmRegisterFbFuncs(pScreen)
     ScreenPtr pScreen;
 {
+    #ifdef TEST
+    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+    #endif
     shmFuncs[pScreen->myNum] = &fbFuncs;
 }
 
@@ -501,12 +541,17 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
     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;
     }
@@ -521,6 +566,7 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
        (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
                                    dx, dy);
     (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+    nxagentShmTrap = 1;
 }
 
 static void
@@ -531,6 +577,15 @@ fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
     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;
@@ -545,11 +600,45 @@ fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
        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);
+    }
 }
 
 
@@ -860,26 +949,22 @@ ProcShmPutImage(client)
        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)
@@ -1021,15 +1106,37 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr)
 {
     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;
 }
 
@@ -1094,6 +1201,12 @@ ProcShmDispatch (client)
     register ClientPtr client;
 {
     REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
     switch (stuff->data)
     {
     case X_ShmQueryVersion:
@@ -1103,11 +1216,38 @@ ProcShmDispatch (client)
     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 )
@@ -1237,6 +1377,12 @@ SProcShmDispatch (client)
     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:
@@ -1246,7 +1392,27 @@ SProcShmDispatch (client)
     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:
@@ -1255,3 +1421,5 @@ SProcShmDispatch (client)
        return BadRequest;
     }
 }
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 30c0df03247b0d013648be97c45fe7457d34ecaf..95ecde951fbde9caf3d5d577136b6b99f7ac1242 100644 (file)
@@ -1,4 +1,26 @@
-/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXwindow.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* 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
@@ -48,7 +70,6 @@ SOFTWARE.
 
 */
 
-/* The panoramix components contained the following notice */
 /****************************************************************
 *                                                               *
 *    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
@@ -70,8 +91,6 @@ SOFTWARE.
 *                                                               *
 *****************************************************************/
 
-/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.32 2003/01/12 02:44:26 dawes Exp $ */
-
 #include "misc.h"
 #include "scrnintstr.h"
 #include "os.h"
@@ -85,9 +104,10 @@ SOFTWARE.
 #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"
@@ -100,6 +120,16 @@ SOFTWARE.
 #include "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"
+
 #if defined(NEED_SCREEN_REGIONS)
 #define REGION_PTR(pScreen,pWin) \
     register ScreenPtr pScreen = pWin->drawable.pScreen;
@@ -107,6 +137,9 @@ SOFTWARE.
 #define REGION_PTR(pScreen,pWin) /* nothing */
 #endif
 
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
 /******
  * Window stuff for server 
  *
@@ -117,9 +150,6 @@ SOFTWARE.
  *
  ******/
 
-static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
-static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
-
 int screenIsSaved = SCREEN_SAVER_OFF;
 
 ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
@@ -160,10 +190,25 @@ static Bool TileScreenSaver(
 #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
@@ -299,55 +344,36 @@ SetWindowToDefaults(pWin)
 #endif
 }
 
-static void
-#if NeedFunctionPrototypes
-MakeRootTile(WindowPtr pWin)
-#else
-MakeRootTile(pWin)
-    WindowPtr pWin;
-#endif
+void nxagentClearSplash(WindowPtr pW)
 {
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    GCPtr pGC;
-    unsigned char back[128];
-    int len = BitmapBytePad(sizeof(long));
-    register unsigned char *from, *to;
-    register int i, j;
+    int w, h;
+    ScreenPtr pScreen;
 
-    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
-                                                   pScreen->rootDepth);
+    w = pW->drawable.width;
+    h = pW->drawable.height;
 
-    pWin->backgroundState = BackgroundPixmap;
-    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
-    if (!pWin->background.pixmap || !pGC)
-       FatalError("could not create root tile");
+    pScreen = pW->drawable.pScreen;
 
+    if (pW->backgroundState == BackgroundPixmap)
     {
-       CARD32 attributes[2];
-
-       attributes[0] = pScreen->whitePixel;
-       attributes[1] = pScreen->blackPixel;
-
-       (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+      (*pScreen->DestroyPixmap)(pW->background.pixmap);
     }
 
-   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
-
-   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
-   to = back;
+    pW->backgroundState = BackgroundPixel;
+    pW->background.pixel = nxagentLogoBlack;
 
-   for (i = 4; i > 0; i--, from++)
-       for (j = len; j > 0; j--)
-           *to++ = *from;
-
-   if (blackRoot)
-       bzero(back, sizeof(back));
-
-   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
-                   0, 0, len, 4, 0, XYBitmap, (char *)back);
-
-   FreeScratchGC(pGC);
+    (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
 
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+    WindowPtr pWin;
+#endif
+{
+    nxagentRootTileWindow = pWin;
 }
 
 WindowPtr
@@ -474,9 +500,16 @@ CreateRootWindow(pScreen)
        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) &&
@@ -502,22 +535,96 @@ InitRootWindow(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++;
-    MakeRootTile(pWin);
     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
 
-    MapWindow(pWin, serverClient);
+    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
 }
 
 /* Set the region to the intersection of the rectangle and the
@@ -950,6 +1057,14 @@ DeleteWindow(value, wid)
            pWin->prevSib->nextSib = pWin->nextSib;
     }
     xfree(pWin);
+
+    if (pWin -> optional &&
+            pWin -> optional -> colormap &&
+                pWin -> parent)
+    {
+      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+    }
+
     return Success;
 }
 
@@ -1196,6 +1311,12 @@ ChangeWindowAttributes(pWin, vmask, vlist, client)
                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:
@@ -1276,6 +1397,22 @@ ChangeWindowAttributes(pWin, vmask, vlist, client)
 #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)
            {
@@ -1817,7 +1954,19 @@ ResizeChildrenWinSize(pWin, dx, dy, dw, dh)
        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) )
        {
@@ -1829,8 +1978,10 @@ ResizeChildrenWinSize(pWin, dx, dy, dw, dh)
                                     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;
@@ -2357,6 +2508,28 @@ ConfigureWindow(pWin, mask, vlist, client)
        /* 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,
@@ -2511,6 +2684,9 @@ ActuallyDoSomething:
 
     if (action != RESTACK_WIN)
        CheckCursorConfinement(pWin);
+
+    nxagentFlushConfigureWindow();
+
     return(Success);
 #undef RESTACK_WIN
 #undef MOVE_WIN
@@ -2539,6 +2715,20 @@ CirculateWindow(pParent, direction, client)
     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)
@@ -2661,6 +2851,12 @@ ReparentWindow(pWin, pParent, x, y, client)
     /* insert at begining of pParent */
     pWin->parent = pParent;
     pPrev = RealChildHead(pParent);
+
+    if (pWin->parent == WindowTable[0])
+    {
+      nxagentSetTopLevelEventMask(pWin);
+    }
     if (pPrev)
     {
        pWin->nextSib = pPrev->nextSib;
@@ -2693,7 +2889,9 @@ ReparentWindow(pWin, pParent, x, y, client)
 
     if (pScreen->ReparentWindow)
        (*pScreen->ReparentWindow)(pWin, pPriorParent);
+
     (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
     ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
 
     CheckWindowOptionalNeed(pWin);
@@ -2763,6 +2961,13 @@ MapWindow(pWin, client)
 #endif
     WindowPtr  pLayerWin;
 
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+    }
+    #endif
+
     if (pWin->mapped)
        return(Success);
 
@@ -2868,6 +3073,8 @@ MapWindow(pWin, client)
        REGION_UNINIT(pScreen, &temp);
     }
 
+    nxagentFlushConfigureWindow();
+
     return(Success);
 }
 
@@ -3077,6 +3284,14 @@ UnmapWindow(pWin, fromConfigure)
     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))
@@ -3408,9 +3623,19 @@ SaveScreens(on, mode)
           (* 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;
@@ -3758,6 +3983,11 @@ DisposeWindowOptional (pWin)
     }
     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;
 }
@@ -3945,3 +4175,5 @@ DrawLogo(pWin)
 }
 
 #endif
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 3d321e8ae6db20f9ef00b6db435cc57fc9f0c9b4..f3bfcf58ad8a89db13899457903836778ba3dfee 100644 (file)
@@ -1,3 +1,13 @@
+#ifdef NXAGENT_UPGRADE
+
+#if !defined(__sun) && !defined(__CYGWIN__)
+
+#include "X/NXxvdisp.c"
+
+#endif
+
+#else
+
 /***********************************************************
 Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
@@ -66,6 +76,11 @@ SOFTWARE.
 #include "shmstr.h"
 #endif
 
+#include "Trap.h"
+
+#undef  TEST
+#undef  DEBUG
+
 #ifdef EXTMODULE
 #include "xf86_ansic.h"
 #endif
@@ -220,129 +235,175 @@ static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
 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
@@ -2212,3 +2273,5 @@ void XineramifyXv(void)
 }
 
 #endif
+
+#endif /* #ifdef NXAGENT_UPGRADE */
index 286728cd16bdbb554e0b59da382f2694d41639e5..cf5d48ba219162252266c040f5003064814aaa44 100644 (file)
@@ -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 @@ damageText (DrawablePtr     pDrawable,
     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 @@ damageImageText16(DrawablePtr    pDrawable,
     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,
index 6941456deaaa108efbc0b595dd52cd07c1b99807..69ad30d2d47f1eb3025d0d5f808c40314f4f217b 100644 (file)
@@ -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 @@ Equipment Corporation.
 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 @@ int ProcInitialConnection();
 #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 @@ int ProcInitialConnection();
 #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 @@ Selection *CurrentSelections;
 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 @@ InitSelections()
        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 @@ Dispatch(void)
     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 @@ Dispatch(void)
            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 @@ Dispatch(void)
 #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 @@ Dispatch(void)
                        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 @@ Dispatch(void)
                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 @@ Dispatch(void)
 #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 @@ ProcReparentWindow(register ClientPtr client)
                                           SecurityWriteAccess);
     if (!pWin)
         return(BadWindow);
+
+    if (!nxagentWMPassed)
+    {
+      nxagentRemoveSplashWindow(pWin);
+    }
+
     pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
                                              SecurityWriteAccess);
     if (!pParent)
@@ -724,6 +1079,7 @@ ProcUnmapWindow(register ClientPtr client)
         return(BadWindow);
     UnmapWindow(pWin, FALSE);
            /* update cache to say it is mapped */
+
     return(client->noClientException);
 }
 
@@ -760,6 +1116,7 @@ ProcConfigureWindow(register ClientPtr client)
         return BadLength;
     result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
                              client);
+
     if (client->noClientException != Success)
         return(client->noClientException);
     else
@@ -865,7 +1222,12 @@ ProcQueryTree(register ClientPtr client)
         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 @@ ProcQueryTree(register ClientPtr client)
        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 @@ ProcSetSelectionOwner(register ClientPtr client)
            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 @@ ProcConvertSelection(register ClientPtr client)
     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 @@ ProcConvertSelection(register ClientPtr client)
        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 @@ int
 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 @@ ProcCloseFont(register ClientPtr client)
     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 @@ ProcQueryFont(register ClientPtr client)
 
     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 @@ ProcQueryFont(register ClientPtr client)
        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 @@ ProcQueryFont(register ClientPtr client)
        rlength = sizeof(xQueryFontReply) +
                     FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
                     nprotoxcistructs * sizeof(xCharInfo);
+        reply = NULL;
        reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
        if(!reply)
        {
@@ -1434,10 +1912,18 @@ ProcQueryTextExtents(register ClientPtr client)
 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 @@ ProcListFonts(register ClientPtr client)
 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 @@ ProcFreePixmap(register ClientPtr client)
                                             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 @@ ProcPolyPoint(register ClientPtr client)
     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 @@ ProcPolyLine(register ClientPtr client)
     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 @@ ProcPolySegment(register ClientPtr client)
        return(BadLength);
     nsegs >>= 3;
     if (nsegs)
+    {
         (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -1881,8 +2415,10 @@ ProcPolyRectangle (register ClientPtr client)
        return(BadLength);
     nrects >>= 3;
     if (nrects)
+    {
         (*pGC->ops->PolyRectangle)(pDraw, pGC, 
                    nrects, (xRectangle *) &stuff[1]);
+    }
     return(client->noClientException);
 }
 
@@ -1901,7 +2437,9 @@ ProcPolyArc(register ClientPtr client)
        return(BadLength);
     narcs /= sizeof(xArc);
     if (narcs)
+    {
         (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -1930,9 +2468,11 @@ ProcFillPoly(register ClientPtr client)
     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 @@ ProcPolyFillRectangle(register ClientPtr client)
     things >>= 3;
 
     if (things)
+    {
         (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
                      (xRectangle *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -1972,7 +2514,9 @@ ProcPolyFillArc(register ClientPtr client)
        return(BadLength);
     narcs /= sizeof(xArc);
     if (narcs)
+    {
         (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
     return (client->noClientException);
 }
 
@@ -3127,7 +3671,14 @@ ProcCreateCursor (register ClientPtr client)
            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 @@ ProcSetScreenSaver (register ClientPtr client)
         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 @@ int ProcForceScreenSaver(register ClientPtr client)
        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 @@ InitProcVectors(void)
  *  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 @@ void InitClient(ClientPtr client, int i, pointer ospriv)
     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 @@ InitClientPrivates(ClientPtr client)
        else
            ppriv->ptr = (pointer)NULL;
     }
+
+    /*
+     * Initialize the private members.
+     */
+
+    nxagentInitClientPrivates(client);
+
     return 1;
 }
 
index 2c5874e8dbe30a225533b49421eac2b86d673c0f..3234c9929ca184124ca1c3784741f1ecf1a39f8c 100644 (file)
@@ -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 @@ Equipment Corporation.
 #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 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
                *newname;
     int         newlen;
     int                aliascount = 20;
+    char nxagentOrigFontName[256];
+    int nxagentOrigFontNameLen;
+
     /*
      * Decide at runtime what FontFormat to use.
      */
@@ -276,6 +368,13 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 
        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 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
            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 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
            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 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
        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 @@ bail:
                          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 @@ CloseFont(pointer value, XID fid)
        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 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
                    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 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
                                    (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 @@ finish:
            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 @@ finish:
 
 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 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
        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 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
                {
                    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 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
                             (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 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
        }
        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 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
                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 @@ finish:
     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 @@ doPolyText(ClientPtr client, register PTclosurePtr c)
                        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 @@ doPolyText(ClientPtr client, register PTclosurePtr c)
                    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 @@ bail:
     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 @@ doImageText(ClientPtr client, register ITclosurePtr c)
                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 @@ doImageText(ClientPtr client, register ITclosurePtr c)
 
            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 @@ bail:
     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 @@ SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
                    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 @@ SetDefaultFontPath(char *path)
                 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 @@ dump_char_ascii(CharInfoPtr cip)
 }
 
 #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;
+}
+
index 4373673f93ee23dfea2b6ab94afb763ebcde7ced..c5593adbba46f888eef50a9bb8864593cdfb6f79 100644 (file)
@@ -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 @@ of the copyright holder.
 #endif
 
 #include <X11/X.h>
+#include "Xlib.h"
 #include "misc.h"
 #include "resource.h"
 #define NEED_EVENTS
@@ -163,7 +181,22 @@ xEvent *xeviexE;
 
 #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 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
     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 @@ DeactivatePointerGrab(register DeviceIntPtr mouse)
     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 @@ ProcAllowEvents(register ClientPtr client)
            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,10 +1687,27 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     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,9 +1722,16 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
                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 */
                }
@@ -1640,15 +1769,25 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
        }
 
        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 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
        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 @@ XYToWindow(int x, int y)
     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 @@ CheckMotion(xEvent *xE)
            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 @@ void
 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 @@ DefineInitialRootWindow(register WindowPtr win)
        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 @@ CheckPassiveGrabsOnWindow(
                                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 @@ drawable.id:0;
     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 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     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 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         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 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #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 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #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 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
            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 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     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 @@ ProcGrabPointer(ClientPtr client)
     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 @@ ProcGrabPointer(ClientPtr client)
        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 @@ ProcUngrabPointer(ClientPtr client)
     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 @@ ProcUngrabPointer(ClientPtr client)
     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 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
        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 @@ ProcGrabKeyboard(ClientPtr client)
     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 @@ ProcUngrabKeyboard(ClientPtr client)
     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 @@ ProcUngrabKeyboard(ClientPtr client)
     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 @@ ProcSendEvent(ClientPtr client)
     /* 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 &&
index 270d54f9b79eaba0755026fd15b4740cabd32d83..ead9b9d2852c329202b20487312549ea90df5ad0 100644 (file)
@@ -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 @@ SOFTWARE.
 #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 @@ SOFTWARE.
 #include "lbxserve.h"
 #endif
 
+#include "Trap.h"
+
 #define EXTENSION_BASE  128
 #define EXTENSION_EVENT_BASE  64
 #define LAST_EVENT  128
@@ -324,6 +343,13 @@ ProcQueryExtension(ClientPtr client)
     {
        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 @@ ProcListExtensions(ClientPtr client)
                !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;)
index fa13829835f98b5d1582a72d1f86f823fc967733..51c5479847b95e60b0f18f6be13643d362f791a3 100644 (file)
@@ -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
 #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 @@ __GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
 */
 static int __glXDispatch(ClientPtr client)
 {
+    int result;
+
     REQUEST(xGLXSingleReq);
     CARD8 opcode;
     int (*proc)(__GLXclientState *cl, GLbyte *pc);
@@ -444,11 +469,35 @@ static int __glXDispatch(ClientPtr client)
     ** 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 @@ static int __glXSwapDispatch(ClientPtr client)
     ** 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 @@ void __glXNoSuchRenderOpcode(GLbyte *pc)
 {
     return;
 }
-
index 9f4d1c87bd960a4aff49d83fb4ab91e08c24fe57..cd65fdc0e5fb8d50d53cd5d62fc1880d5d712d1d 100644 (file)
@@ -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 $
  *
 #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 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
        gr->signature = hash;
        globalGlyphs[glyphSet->fdepth].tableEntries++;
     }
-    
     /* Insert/replace glyphset value */
     gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
     ++glyph->refcnt;
@@ -303,6 +336,13 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
        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 @@ DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
     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 @@ FindGlyph (GlyphSetPtr glyphSet, Glyph id)
     return glyph;
 }
 
+#endif
+
 GlyphPtr
 AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
@@ -379,6 +451,12 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
     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 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
            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 @@ FreeGlyphSet (pointer       value,
     }
     return Success;
 }
+
index 8f8adf5ce294e3130f458bc8989beadd88fd2b5a..7a1d813b304d15316804a0744b74f9bc53f28032 100644 (file)
@@ -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 @@ SOFTWARE.
 #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 @@ ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, uns
     /* 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;
 }
 
index f4777a248a7ce28bb63298e744bb7c3fe1db2115..fa6b5fb02daa8454afcc3c4f70691f411375b315 100644 (file)
@@ -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 $
  *
  * 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 _Glyph {
 typedef struct _GlyphRef {
     CARD32     signature;
     GlyphPtr   glyph;
+    CARD16      corruptedGlyph;
 } GlyphRefRec, *GlyphRefPtr;
 
 #define DeletedGlyph   ((GlyphPtr) 1)
@@ -70,6 +95,7 @@ typedef struct _GlyphSet {
     GlyphHashRec    hash;
     int             maxPrivate;
     pointer         *devPrivates;
+    CARD32          remoteID;
 } GlyphSetRec, *GlyphSetPtr;
 
 #define GlyphSetGetPrivate(pGlyphSet,n)                                        \
index 9a0bd06b5356e9e2177a14d6496942f4354bcaf4..3fc73cf3b8e3ef7fe396e0dbcf75bcf4bdaf12c7 100644 (file)
@@ -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 @@ Equipment Corporation.
 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 @@ miHandleExposures(pSrcDrawable, pDstDrawable,
     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 @@ miWindowExposures(pWin, prgn, other_exposed)
     WindowPtr pWin;
     register RegionPtr prgn, other_exposed;
 {
+#ifdef NXAGENT_SERVER
+
+    int total;
+
+#endif
     RegionPtr   exposures = prgn;
     if (pWin->backStorage && prgn)
        /*
@@ -533,7 +575,20 @@ miWindowExposures(pWin, prgn, other_exposed)
            }
            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 @@ int what;
     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)
index 237ec13a415f3b9b85338db861f529ff246e4e55..5f32334ae992fe29931ed527319dd0cff823108d 100644 (file)
@@ -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 $
  *
 #include "picturestr.h"
 #include "mipict.h"
 
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
 void
 miGlyphExtents (int            nlist,
                GlyphListPtr    list,
@@ -45,7 +68,7 @@ miGlyphExtents (int           nlist,
     int                n;
     GlyphPtr   glyph;
     int                x, y;
-    
     x = 0;
     y = 0;
     extents->x1 = MAXSHORT;
@@ -113,25 +136,58 @@ miGlyphs (CARD8           op,
     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 @@ miGlyphs (CARD8             op,
        x += list->xOff;
        y += list->yOff;
        n = list->len;
+
        while (n--)
        {
            glyph = *glyphs++;
@@ -184,6 +241,21 @@ miGlyphs (CARD8            op,
            (*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 @@ miGlyphs (CARD8             op,
            x += glyph->info.xOff;
            y += glyph->info.yOff;
        }
+
        list++;
        if (pPicture)
        {
@@ -237,7 +310,9 @@ miGlyphs (CARD8             op,
                          0, 0,
                          x, y,
                          width, height);
+
        FreePicture ((pointer) pMask, (XID) 0);
        (*pScreen->DestroyPixmap) (pMaskPixmap);
     }
+
 }
index be17124200a013c628aac2709c9cd5eb94271b79..f418654b4e9acd268a0bce3487f617b9366f00ff 100644 (file)
@@ -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 $
  *
 #include "picturestr.h"
 #include "mipict.h"
 
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
 PicturePtr
 miCreateAlphaPicture (ScreenPtr            pScreen, 
                      PicturePtr    pDst,
@@ -159,7 +182,27 @@ miTrapezoids (CARD8            op,
        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,
index 280d0f8ebecd17a0a5282a9c8033fc77d29d771f..190294979dc02a03847d970781af0d37ff3fdd32 100644 (file)
@@ -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 @@ miSetShape(pWin)
        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;
index 3ed60310ece152e8f3b3a90227a78bf923e0bc2c..d9054b4b662c31467a7684b949e96f8b3d3e49d8 100644 (file)
@@ -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 $
  *
 #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              PictFormatType;
 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 @@ visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
     return 0;
 }
 
-typedef struct _formatInit {
-    CARD32  format;
-    CARD8   depth;
-} FormatInitRec, *FormatInitPtr;
-
 static int
 addFormat (FormatInitRec    formats[256],
           int              nformat,
@@ -207,6 +240,11 @@ addFormat (FormatInitRec    formats[256],
            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 @@ addFormat (FormatInitRec    formats[256],
 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 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
     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 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
        if (!depth)
            continue;
        bpp = BitsPerPixel (depth);
+
        switch (pVisual->class) {
        case DirectColor:
        case TrueColor:
@@ -296,6 +347,7 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
            break;
        }
     }
+
     /*
      * Walk supported depths and add useful Direct formats
      */
@@ -304,16 +356,18 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
        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 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
            /* 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 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
            break;
        }
     }
-    
+
+#endif
 
     pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
     if (!pFormats)
@@ -368,9 +423,9 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
     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 @@ PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
            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 @@ AllocatePicture (ScreenPtr  pScreen)
        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 @@ CreatePicture (Picture             pid,
     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 void initGradient(SourcePictPtr pGradient, int stopCount,
 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 @@ ChangePicture (PicturePtr        pPicture,
                        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 @@ FreePicture (pointer     value,
 
     if (--pPicture->refcnt == 0)
     {
+#ifdef NXAGENT_SERVER
+        nxagentDestroyPicture(pPicture);
+#endif
+
        if (pPicture->transform)
            xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
@@ -1698,6 +1845,13 @@ CompositeGlyphs (CARD8           op,
     
     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 @@ PictureTransformPoint (PictTransformPtr transform,
     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;
+    }
+  }
+}
+
index 4775793abb9ab42ad2f9dd49a5cc19f2239b1fd9..0d1a8e1d87b192611da15e2ab916d788779c8061 100644 (file)
@@ -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 $
  *
  * 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"
 
index cabe46eccd87a014ce4d90f8e82733aa8bd0fbe6..cd1ec6ddd8b655f839276ae410d2e8157fcd1acc 100644 (file)
@@ -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 @@ SOFTWARE.
 #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 @@ SOFTWARE.
 #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 @@ int fWriteToClient(ClientPtr client, int len, char *buf)
 #endif
 #endif
 
+extern Atom clientCutProperty;
+
+#ifdef NXAGENT_SERVER
+typedef struct
+{
+  CARD32 state;
+  Window icon;
+}
+nxagentWMStateRec;
+#endif
+
 /*****************************************************************
  * Property Stuff
  *
@@ -234,6 +267,15 @@ ProcChangeProperty(ClientPtr client)
     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 @@ ProcChangeProperty(ClientPtr client)
     }
 #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 @@ ProcChangeProperty(ClientPtr client)
     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 @@ ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
     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 @@ NullPropertyReply(
 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 @@ ProcGetProperty(ClientPtr client)
     REQUEST(xGetPropertyReq);
 
     REQUEST_SIZE_MATCH(xGetPropertyReq);
+
     if (stuff->delete)
        UpdateCurrentTime();
     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
@@ -533,6 +622,59 @@ ProcGetProperty(ClientPtr client)
 
     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 @@ ProcGetProperty(ClientPtr client)
     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 @@ ProcDeleteProperty(register ClientPtr client)
     else
        return(result);
 }
+
index d25d49756dc04688bb145ce277f2336e64983edc..89e790135b92d1460a98b1cc77c56d183536d594 100644 (file)
  * 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
 #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 @@ ProcRenderQueryVersion (ClientPtr client)
     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 @@ ProcRenderQueryPictFormats (ClientPtr client)
     int                                    n;
     int                                    numScreens;
     int                                    numSubpixel;
+
+    extern int                      nxagentAlphaEnabled;
 /*    REQUEST(xRenderQueryPictFormatsReq); */
 
     REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
@@ -439,7 +545,7 @@ ProcRenderQueryPictFormats (ClientPtr client)
                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 @@ ProcRenderCreatePicture (ClientPtr client)
                              &error);
     if (!pPicture)
        return error;
+    nxagentCreatePicture(pPicture, stuff -> mask);
+
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
        return BadAlloc;
     return Success;
@@ -667,6 +775,7 @@ ProcRenderChangePicture (ClientPtr client)
     PicturePtr     pPicture;
     REQUEST(xRenderChangePictureReq);
     int len;
+    int error;
 
     REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
@@ -676,8 +785,12 @@ ProcRenderChangePicture (ClientPtr client)
     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 @@ ProcRenderSetPictureClipRectangles (ClientPtr client)
     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 @@ ProcRenderFreePicture (ClientPtr client)
 
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
                    RenderErrBase + BadPicture);
+
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -733,6 +860,71 @@ PictOpValid (CARD8 op)
     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 @@ ProcRenderComposite (ClientPtr client)
                    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 @@ ProcRenderComposite (ClientPtr client)
                      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 @@ ProcRenderTrapezoids (ClientPtr client)
        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 @@ ProcRenderCreateGlyphSet (ClientPtr client)
        return BadAlloc;
     if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
        return BadAlloc;
+
+    nxagentCreateGlyphSet(glyphSet);
+
     return Success;
 }
 
@@ -1052,6 +1366,9 @@ ProcRenderReferenceGlyphSet (ClientPtr client)
        return RenderErrBase + BadGlyphSet;
     }
     glyphSet->refcnt++;
+
+    nxagentReferenceGlyphSet(glyphSet);
+
     if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
        return BadAlloc;
     return client->noClientException;
@@ -1076,6 +1393,9 @@ ProcRenderFreeGlyphSet (ClientPtr client)
        client->errorValue = stuff->glyphset;
        return RenderErrBase + BadGlyphSet;
     }
+
+    nxagentFreeGlyphSet(glyphSet);
+
     FreeResource (stuff->glyphset, RT_NONE);
     return client->noClientException;
 }
@@ -1092,7 +1412,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     REQUEST(xRenderAddGlyphsReq);
     GlyphNewRec            glyphsLocal[NLOCALGLYPH];
     GlyphNewPtr            glyphsBase, glyphs;
-    GlyphPtr       glyph;
+    GlyphPtr       glyph = NULL;
     int                    remain, nglyphs;
     CARD32         *gids;
     xGlyphInfo     *gi;
@@ -1100,6 +1420,8 @@ ProcRenderAddGlyphs (ClientPtr client)
     int                    size;
     int                    err = BadAlloc;
 
+    int             totSizeImages;
+
     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
                                                     stuff->glyphset,
@@ -1128,10 +1450,12 @@ ProcRenderAddGlyphs (ClientPtr client)
 
     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 @@ ProcRenderAddGlyphs (ClientPtr client)
        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 @@ ProcRenderFreeGlyphs (ClientPtr client)
     }
     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 @@ ProcRenderFreeGlyphs (ClientPtr client)
     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 @@ ProcRenderCompositeGlyphs (ClientPtr client)
     int                    size;
     int                    n;
     
+    XGlyphElt8      *elements, *elementsBase;
+
     REQUEST(xRenderCompositeGlyphsReq);
 
     REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
@@ -1335,9 +1674,15 @@ ProcRenderCompositeGlyphs (ClientPtr client)
        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 @@ ProcRenderCompositeGlyphs (ClientPtr client)
        
        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 @@ ProcRenderCompositeGlyphs (ClientPtr client)
            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 @@ ProcRenderCompositeGlyphs (ClientPtr client)
            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 @@ ProcRenderFillRectangles (ClientPtr client)
                    &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 @@ ProcRenderCreateCursor (ClientPtr client)
     CARD32         twocolor[3];
     int                    ncolor;
 
+    RealizeCursorProcPtr saveRealizeCursor;
+
     REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
     LEGAL_NEW_RESOURCE(stuff->cid, client);
     
@@ -1662,6 +2076,20 @@ ProcRenderCreateCursor (ClientPtr client)
     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 @@ ProcRenderCreateCursor (ClientPtr client)
                               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 @@ ProcRenderSetPictureTransform (ClientPtr client)
     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 @@ ProcRenderQueryFilters (ClientPtr client)
     {
        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 @@ ProcRenderSetPictureFilter (ClientPtr client)
     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 @@ ProcRenderCreateAnimCursor (ClientPtr client)
     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 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     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 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             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 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             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 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              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 ProcRenderCreateConicalGradient (ClientPtr client)
 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 @@ static int
 SProcRenderAddGlyphs (ClientPtr client)
 {
     register int n;
-    register int i;
+    register unsigned int i;
     CARD32  *gids;
     void    *end;
     xGlyphInfo *gi;
@@ -2595,10 +3113,36 @@ SProcRenderCreateConicalGradient (ClientPtr client)
 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 @@ PanoramiXRenderReset (void)
 }
 
 #endif /* PANORAMIX */
+
index e12bc7b672074abff0b505e030279ed544d25eed..d1c8325f2bf105b950ed5ba44bd034b22264f552 100644 (file)
@@ -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 @@ Equipment Corporation.
 #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 @@ void RegisterResourceName (RESTYPE type, char *name)
 
 #endif
 
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
 RESTYPE
 CreateNewResourceType(DeleteType deleteFunc)
 {
@@ -422,13 +457,107 @@ FakeClientID(register int client)
     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 @@ AddResource(XID id, RESTYPE type, pointer value)
                (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 @@ AddResource(XID id, RESTYPE type, pointer value)
     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 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
     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 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
                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 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
            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 @@ FindClientResourcesByType(
     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 @@ FindClientResourcesByType(
            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 @@ FindAllClientResources(
     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 @@ FindAllClientResources(
         {
             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 @@ LookupClientResourceComplex(
     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 @@ LookupIDByClass(XID id, RESTYPE classes)
 }
 
 #endif /* XCSECURITY */
+
index f25bb9b5d152bbc4a74e2c05d7e1d6195d145024..eaaa9204130b2ecf7f945ec86c26eea346149f56 100644 (file)
@@ -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 @@ in this Software without prior written authorization from The Open Group.
 
 #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 @@ ShmExtensionInit(INITARGS)
     }
 #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 @@ void
 ShmRegisterFbFuncs(pScreen)
     ScreenPtr pScreen;
 {
+    #ifdef TEST
+    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+    #endif
     shmFuncs[pScreen->myNum] = &fbFuncs;
 }
 
@@ -512,12 +567,17 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
     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 @@ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
        (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 @@ fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
     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 @@ fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
        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 @@ ProcShmPutImage(client)
        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 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr)
 {
     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 @@ ProcShmDispatch (client)
     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 @@ ProcShmDispatch (client)
     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 @@ SProcShmDispatch (client)
     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 @@ SProcShmDispatch (client)
     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 @@ SProcShmDispatch (client)
        return BadRequest;
     }
 }
+
index c060f4a2349aca9e80241b9bd9a5343cc003ce50..76e86fd2a17a4d7975cea328674510caebfd4495 100644 (file)
@@ -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 @@ Equipment Corporation.
 #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 @@ Equipment Corporation.
 #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 @@ static Bool TileScreenSaver(int i, int kind);
 #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 @@ SetWindowToDefaults(register WindowPtr pWin)
 #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 @@ MakeRootTile(WindowPtr pWin)
 
    FreeScratchGC(pGC);
 
+#ifdef NXAGENT_SERVER
+   nxagentRootTileWindow = pWin;
+#endif /* NXAGENT_SERVER */
 }
 
 WindowPtr
@@ -458,9 +532,16 @@ CreateRootWindow(ScreenPtr pScreen)
        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 @@ CreateRootWindow(ScreenPtr pScreen)
     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 @@ InitRootWindow(WindowPtr pWin)
     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 @@ ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
                      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 @@ DeleteWindow(pointer value, XID wid)
        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 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt
                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 @@ ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPt
 #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 @@ CreateUnclippedWinSize (register WindowPtr pWin)
     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 @@ SetWinSize (register WindowPtr pWin)
                         (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 @@ SetBorderSize (register WindowPtr pWin)
                (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 @@ ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
        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 @@ ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
                                     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 @@ MakeBoundingRegion (
     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 @@ ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientP
        /* 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 @@ ActuallyDoSomething:
 
     if (action != RESTACK_WIN)
        CheckCursorConfinement(pWin);
+
+    nxagentFlushConfigureWindow();
+
     return(Success);
 #undef RESTACK_WIN
 #undef MOVE_WIN
@@ -2468,6 +2727,20 @@ CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
     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 @@ ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
     /* 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 @@ ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
 
     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 @@ MapWindow(register WindowPtr pWin, ClientPtr client)
 #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 @@ MapWindow(register WindowPtr pWin, ClientPtr client)
        REGION_UNINIT(pScreen, &temp);
     }
 
+    nxagentFlushConfigureWindow();
+
     return(Success);
 }
 
@@ -2981,6 +3271,14 @@ UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
     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 @@ SaveScreens(int on, int mode)
           (* 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 @@ DisposeWindowOptional (register WindowPtr pWin)
     }
     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 @@ DrawLogo(WindowPtr pWin)
 }
 
 #endif
+
index 21ab0b6a0df0532e04a5923cd70102af12e4aeb7..f6dad312a047692a8306faca06ade207b4bc98ad 100644 (file)
@@ -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 @@ SOFTWARE.
 #include <X11/extensions/shmstr.h>
 #endif
 
+#include "Trap.h"
+
+#undef  TEST
+#undef  DEBUG
+
 #ifdef EXTMODULE
 #include "xf86_ansic.h"
 #endif
@@ -227,129 +249,175 @@ static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
 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 @@ void XineramifyXv(void)
 }
 
 #endif
+