[X2Go-Commits] [nx-libs] 327/429: Clipboard.c: have lastServer* per selection

git-admin at x2go.org git-admin at x2go.org
Mon Oct 18 09:36:58 CEST 2021


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

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

commit a8d09f81501b76b507f080e6a812101f6cc2ada5
Author: Ulrich Sibiller <uli42 at gmx.de>
Date:   Wed Sep 23 15:48:43 2020 +0200

    Clipboard.c: have lastServer* per selection
    
    This will help in PRIMARY content appearing in CLIPBOARD and vice versa.
---
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 183 +++++++++++++++----------
 1 file changed, 110 insertions(+), 73 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index fe6d39281..fefb0286e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -93,6 +93,8 @@ typedef struct _SelectionOwner
  * owner is outside nxagent. .selection will _always_ contain the
  * external atom of the selection
  */
+
+/* FIXME: these should also be stored per selection */
 static SelectionOwner *lastSelectionOwner;
 static XlibAtom serverLastRequestedSelection;
 
@@ -130,10 +132,14 @@ typedef struct _lastClient
 
 static lastClient *lastClients;
 
-static Window   lastServerRequestor;
-static XlibAtom lastServerProperty;
-static XlibAtom lastServerTarget;
-static Time     lastServerTime;
+typedef struct _lastServer {
+  Window        requestor;
+  XlibAtom      property;
+  XlibAtom      target;
+  Time          time;
+} lastServer;
+
+static lastServer *lastServers;
 
 static XlibAtom serverTARGETS;
 static XlibAtom serverTIMESTAMP;
@@ -328,6 +334,19 @@ static void printLastClientStat(int index)
   fprintf(stderr, "  lastClients[].resource           (int) [%d]\n", lc.resource);
 }
 
+static void printLastServerStat(int index)
+{
+  lastServer ls = lastServers[index];
+  char *s = NULL;
+
+  fprintf(stderr, "  lastServer[].requestor        (Window) [0x%x]\n", ls.requestor);
+  SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, ls.property);
+  fprintf(stderr, "  lastServer[].property           (Atom) [% 4ld][%s]\n", ls.property, validateString(s));
+  SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, ls.target);
+  fprintf(stderr, "  lastServer[].target             (Atom) [% 4ld][%s]\n", ls.target, validateString(s));
+  fprintf(stderr, "  lastServer[].time               (Time) [%u]\n", ls.time);
+  SAFE_XFree(s);
+}
 
 void nxagentDumpClipboardStat(void)
 {
@@ -353,20 +372,14 @@ void nxagentDumpClipboardStat(void)
   }
   fprintf(stderr, "\n");
 
-  fprintf(stderr, "lastServer\n");
-  fprintf(stderr, "  lastServerRequestor           (Window) [0x%x]\n", lastServerRequestor);
-  SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, lastServerProperty);
-  fprintf(stderr, "  lastServerProperty              (Atom) [% 4ld][%s]\n", lastServerProperty, validateString(s));
-  SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, lastServerTarget);
-  fprintf(stderr, "  lastServerTarget                (Atom) [% 4ld][%s]\n", lastServerTarget, validateString(s));
-  fprintf(stderr, "  lastServerTime                  (Time) [%u]\n", lastServerTime);
-
   fprintf(stderr, "PRIMARY\n");
   printSelectionStat(nxagentPrimarySelection);
   printLastClientStat(nxagentPrimarySelection);
+  printLastServerStat(nxagentPrimarySelection);
   fprintf(stderr, "CLIPBOARD\n");
   printSelectionStat(nxagentClipboardSelection);
   printLastClientStat(nxagentClipboardSelection);
+  printLastServerStat(nxagentClipboardSelection);
 
   fprintf(stderr, "Atoms (remote X server)\n");
   SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverTARGETS);
@@ -665,7 +678,7 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
 
       setClientSelectionStage(SelectionStageNone, index);
 
-      lastServerRequestor = None;
+      lastServers[index].requestor = None;
     }
 
     if (pWindow && pWindow == lastClients[index].windowPtr)
@@ -803,13 +816,12 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
       char *strProperty = XGetAtomName(nxagentDisplay, X->xselectionrequest.property);
 
       fprintf(stderr, "%s: Received SelectionRequestEvent from real server: selection [%ld][%s] " \
-              "target [%ld][%s] requestor [display[%s]/0x%lx] destination [%ld][%s] lastServerRequestor [0x%x]\n",
+              "target [%ld][%s] requestor [display[%s]/0x%lx] destination [%ld][%s]\n",
               __func__,
               X->xselectionrequest.selection, validateString(strSelection),
               X->xselectionrequest.target,    validateString(strTarget),
               DisplayString(nxagentDisplay), X->xselectionrequest.requestor,
-              X->xselectionrequest.property,  validateString(strProperty),
-              lastServerRequestor);
+              X->xselectionrequest.property,  validateString(strProperty));
 
       SAFE_XFree(strTarget);
       SAFE_XFree(strSelection);
@@ -825,23 +837,27 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
     return;
   }
 
-  /* lastServerRequestor in non-NULL (= we are currently in the transfer phase) */
-  if (lastServerRequestor != None)
+  /* the selection in this request is none we own. */
+  int index = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection);
+  if (index == nxagentMaxSelections)
   {
     #ifdef DEBUG
-    fprintf(stderr, "%s: denying additional request during transfer phase.\n", __func__);
+    fprintf(stderr, "%s: not owning selection [%ld] - denying request.\n", __func__, X->xselectionrequest.selection);
     #endif
 
     replyRequestSelectionToXServer(X, False);
     return;
   }
 
-  /* the selection in this request is none we own. */
-  int index = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection);
-  if (index == nxagentMaxSelections)
+  #ifdef DEBUG
+  fprintf(stderr, "%s: lastServers[%d].requestor [0x%x].\n", __func__, index, lastServers[index].requestor);
+  #endif
+
+  /* lastServers[index].requestor in non-NULL (= we are currently in the transfer phase) */
+  if (lastServers[index].requestor != None)
   {
     #ifdef DEBUG
-    fprintf(stderr, "%s: not owning selection [%ld] - denying request.\n", __func__, X->xselectionrequest.selection);
+    fprintf(stderr, "%s: denying additional request during transfer phase.\n", __func__);
     #endif
 
     replyRequestSelectionToXServer(X, False);
@@ -997,14 +1013,14 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
        * store who on the real X server requested the data and how
        * and where it wants to have it
        */
-      lastServerProperty = X->xselectionrequest.property;
-      lastServerRequestor = X->xselectionrequest.requestor;
-      lastServerTarget = X->xselectionrequest.target;
-      lastServerTime = X->xselectionrequest.time;
+      lastServers[index].property = X->xselectionrequest.property;
+      lastServers[index].requestor = X->xselectionrequest.requestor;
+      lastServers[index].target = X->xselectionrequest.target;
+      lastServers[index].time = X->xselectionrequest.time;
 
       /* by dimbor */
-      if (lastServerTarget != XA_STRING)
-          lastServerTarget = serverUTF8_STRING;
+      if (lastServers[index].target != XA_STRING)
+          lastServers[index].target = serverUTF8_STRING;
 
       /* prepare the request (like XConvertSelection, but internally) */
       xEvent x = {0};
@@ -1029,6 +1045,7 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
       else
         x.u.selectionRequest.target = XA_STRING;
 
+      x.u.selectionRequest.target = nxagentRemoteToLocalAtom(X->xselectionrequest.target);
       sendEventToClient(lastSelectionOwner[index].client, &x);
 
       #ifdef DEBUG
@@ -1533,7 +1550,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
     {
       /* if the last owner was an internal one, read the
        * clientCutProperty and push the contents to the
-       * lastServerRequestor on the real X server.
+       * lastServers[index].requestor on the real X server.
        */
       if (IS_INTERNAL_OWNER(index) &&
              lastSelectionOwner[index].windowPtr != NULL &&
@@ -1557,7 +1574,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
         if (result == BadAlloc || result == BadAtom ||
                 result == BadWindow || result == BadValue)
         {
-          lastServerProperty = None;
+          lastServers[index].property = None;
         }
         else
         {
@@ -1574,7 +1591,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
           if (result == BadAlloc || result == BadAtom ||
                   result == BadWindow || result == BadValue)
           {
-            lastServerProperty = None;
+            lastServers[index].property = None;
           }
           else
           {
@@ -1583,9 +1600,9 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
                return 1, no matter what, so no need to check the result */
             /* FIXME: better use the format returned by above request */
             XChangeProperty(nxagentDisplay,
-                            lastServerRequestor,
-                            lastServerProperty,
-                            lastServerTarget,
+                            lastServers[index].requestor,
+                            lastServers[index].property,
+                            lastServers[index].target,
                             8,
                             PropModeReplace,
                             pszReturnData,
@@ -1593,11 +1610,11 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
 
             #ifdef DEBUG
             {
-              char *s = XGetAtomName(nxagentDisplay, lastServerProperty);
+              char *s = XGetAtomName(nxagentDisplay, lastServers[index].property);
               fprintf(stderr, "%s: XChangeProperty sent to window [0x%x] for property [%ld][%s] value [\"%*.*s\"...]\n",
                       __func__,
-                      lastServerRequestor,
-                      lastServerProperty,
+                      lastServers[index].requestor,
+                      lastServers[index].property,
                       s,
                       (int)(min(20, ulReturnItems * 8 / 8)),
                       (int)(min(20, ulReturnItems * 8 / 8)),
@@ -1617,17 +1634,17 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
          * inform the initial requestor that the requested data has
          * arrived in the desired property. If we have been unable to
          * get the data from the owner XChangeProperty will not have
-         * been called and lastServerProperty will be None which
+         * been called and lastServers[index].property will be None which
          * effectively will send a "Request denied" to the initial
          * requestor.
          */
         XSelectionEvent eventSelection = {
-          .requestor = lastServerRequestor,
+          .requestor = lastServers[index].requestor,
           .selection = X->xselection.selection,
           /* .target = X->xselection.target, */
-          .target    = lastServerTarget,
-          .property  = lastServerProperty,
-          .time      = lastServerTime,
+          .target    = lastServers[index].target,
+          .property  = lastServers[index].property,
+          .time      = lastServers[index].time,
           /* .time   = CurrentTime */
         };
         #ifdef DEBUG
@@ -1637,7 +1654,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
 
         sendSelectionNotifyEventToXServer(&eventSelection);
 
-        lastServerRequestor = None; /* allow further request */
+        lastServers[index].requestor = None; /* allow further request */
       }
     }
   }
@@ -1652,15 +1669,15 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
  */
 static void resetSelectionOwnerOnXServer(void)
 {
-  if (lastServerRequestor != None)
+  if (lastServers[index].requestor != None)
   {
     /*
      * we are in the process of communicating back and forth between
      * real X server and nxagent's clients - let's not disturb.
      */
     #if defined(TEST) || defined(DEBUG)
-    fprintf(stderr, "%s: WARNING! Requestor window [0x%x] already found.\n", __func__,
-                lastServerRequestor);
+    fprintf(stderr, "%s: WARNING! Requestor window [0x%x] already set.\n", __func__,
+                lastServers[index].requestor);
     #endif
 
     /* FIXME: maybe we should put back the event that lead us here. */
@@ -1685,7 +1702,7 @@ static void resetSelectionOwnerOnXServer(void)
   }
 
   /* Hmm, this is already None when reaching this */
-  lastServerRequestor = None;
+  lastServers[index].requestor = None;
 }
 #endif
 
@@ -1785,19 +1802,6 @@ static void setSelectionOwnerOnXServer(Selection *pSelection)
               serverWindow);
   #endif
 
-  #if defined(TEST) || defined(DEBUG)
-  if (lastServerRequestor != None)
-  {
-    /*
-     * we are in the process of communicating back and forth between
-     * real X server and nxagent's clients - let's not disturb
-     * FIXME: by continuing after the warning were ARE disturbing!
-     */
-    fprintf (stderr, "%s: WARNING! Requestor window [0x%x] already set.\n", __func__,
-                 lastServerRequestor);
-  }
-  #endif
-
   int index = nxagentFindCurrentSelectionIndex(pSelection->selection);
   if (index < NumCurrentSelections)
   {
@@ -1814,6 +1818,19 @@ static void setSelectionOwnerOnXServer(Selection *pSelection)
             lastSelectionOwner[index].lastTimeChanged);
     #endif
 
+    #if defined(TEST) || defined(DEBUG)
+    if (lastServers[index].requestor != None)
+    {
+      /*
+       * we are in the process of communicating back and forth between
+       * real X server and nxagent's clients - let's not disturb
+       * FIXME: by continuing after the warning were ARE disturbing!
+       */
+      fprintf (stderr, "%s: WARNING! lastServers[%d].requestor window [0x%x] already set.\n",
+                   __func__, index, lastServers[index].requestor);
+    }
+    #endif
+
     /*
      * inform the real X server that our serverWindow is the
      * clipboard owner.
@@ -1831,7 +1848,7 @@ static void setSelectionOwnerOnXServer(Selection *pSelection)
     setClientSelectionStage(SelectionStageNone, index);
   }
 
-  lastServerRequestor = None;
+  lastServers[index].requestor = None;
 
 /*
 FIXME
@@ -1847,7 +1864,7 @@ FIXME
 
       setClientSelectionStage(SelectionStageNone);
 
-      lastServerRequestor = None;
+      lastServers[index].requestor = None;
    }
    else fprintf (stderr, "%s: SetSelectionOwner failed\n", __func__);
 */
@@ -2227,8 +2244,24 @@ int nxagentSendNotify(xEvent *event)
   fprintf(stderr, "%s: property is [%d][%s].\n", __func__,
           event->u.selectionNotify.property,
           NameForAtom(event->u.selectionNotify.property));
+  fprintf(stderr, "%s: selection is [%d][%s].\n", __func__,
+          event->u.selectionNotify.selection,
+          NameForAtom(event->u.selectionNotify.selection));
   fprintf(stderr, "%s: requestor is [0x%x].\n", __func__, event->u.selectionNotify.requestor);
-  fprintf(stderr, "%s: lastServerRequestor is [0x%x].\n", __func__, lastServerRequestor);
+  #endif
+
+  int index = nxagentFindCurrentSelectionIndex(event->u.selectionNotify.selection);
+  if (index == nxagentMaxSelections)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "%s: unknown selection [%d]\n", __func__,
+                event->u.selectionNotify.selection);
+    #endif
+    return 0;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "%s: lastServers[index].requestor is [0x%x].\n", __func__, lastServers[index].requestor);
   #endif
 
   /*
@@ -2239,7 +2272,7 @@ int nxagentSendNotify(xEvent *event)
    * dix to go on) and do nothing!
    * Be sure to not let this trigger for the failure answer (property 0)
    */
-  if (!(event->u.selectionNotify.property == clientCutProperty || event->u.selectionNotify.property == 0) || lastServerRequestor == None)
+  if (!(event->u.selectionNotify.property == clientCutProperty || event->u.selectionNotify.property == 0) || lastServers[index].requestor == None)
   {
     #ifdef DEBUG
     fprintf(stderr, "%s: sent nothing - message to real X server is not required.\n", __func__);
@@ -2332,7 +2365,6 @@ Bool nxagentInitClipboard(WindowPtr pWin)
     clientTIMESTAMP = MakeAtom(szAgentTIMESTAMP, strlen(szAgentTIMESTAMP), True);
 
     SAFE_free(lastSelectionOwner);
-
     lastSelectionOwner = (SelectionOwner *) malloc(nxagentMaxSelections * sizeof(SelectionOwner));
 
     if (lastSelectionOwner == NULL)
@@ -2343,11 +2375,17 @@ Bool nxagentInitClipboard(WindowPtr pWin)
     initSelectionOwnerData(nxagentClipboardSelection, clientCLIPBOARD, nxagentAtoms[10]);   /* CLIPBOARD */
 
     SAFE_free(lastClients);
-
-    lastClients = (lastClient *) malloc(nxagentMaxSelections * sizeof(lastClient));
+    lastClients = (lastClient *) calloc(nxagentMaxSelections, sizeof(lastClient));
     if (lastClients == NULL)
     {
-      FatalError("nxagentInitClipboard: Failed to allocate memory for the last client array.\n");
+      FatalError("nxagentInitClipboard: Failed to allocate memory for the last clients array.\n");
+    }
+
+    SAFE_free(lastServers);
+    lastServers = (lastServer *) calloc(nxagentMaxSelections, sizeof(lastServer));
+    if (lastServers == NULL)
+    {
+      FatalError("nxagentInitClipboard: Failed to allocate memory for the last servers array.\n");
     }
   }
   else
@@ -2455,7 +2493,7 @@ Bool nxagentInitClipboard(WindowPtr pWin)
          }
       }
     }
-    /* FIXME: Shouldn't we reset lastServer* and lastClients[index].* here? */
+    /* FIXME: Shouldn't we reset lastServers[index].* and lastClients[index].* here? */
   }
   else
   {
@@ -2463,12 +2501,11 @@ Bool nxagentInitClipboard(WindowPtr pWin)
     {
       clearSelectionOwnerData(index);
       resetClientSelectionStage(index);
-      /* FIXME: required? move to setSelctionStage? */
+      /* FIXME: required? move to setSelectionStage? */
       lastClients[index].reqTime = GetTimeInMillis();
+      lastServers[index].requestor = None;
     }
 
-    lastServerRequestor = None;
-
     clientCutProperty = MakeAtom(szAgentNX_CUT_BUFFER_CLIENT,
                                     strlen(szAgentNX_CUT_BUFFER_CLIENT), True);
     if (clientCutProperty == None)

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/nx-libs.git


More information about the x2go-commits mailing list