[X2Go-Commits] [nx-libs] 377/429: Clipboard.c: extend target caching for the other direction
git-admin at x2go.org
git-admin at x2go.org
Mon Oct 18 09:37:11 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 51dae621fcfd6e6453657591205e673f16c2df04
Author: Ulrich Sibiller <uli42 at gmx.de>
Date: Wed Dec 2 23:43:53 2020 +0100
Clipboard.c: extend target caching for the other direction
This may seem unneccessary at first sight because we are only talking
to our own clients which generally is quick. But if you are using
nested nx sessions or clients from remote machines (e.g. via ssh X
forwarding) this still can save some lenghty communication.
Plus: it helps in debugging because there are fewer messages being
sent around.
---
nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 93 +++++++++++++++++++++-----
1 file changed, 76 insertions(+), 17 deletions(-)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 682dfbab0..f88d7588b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -108,15 +108,21 @@ static SelectionOwner *lastSelectionOwner = NULL;
/*
* cache for targets the current selection owner
- * on the real X server has to offer. We are storing the targets
- * after they have been converted from XlibAtom to Atom.
+ * has to offer. We are storing the targets
+ * after they have been converted
*/
typedef struct _Targets
{
- Atom *targets;
- int numTargets;
+ Bool type; /* EMPTY, FORINT, FORREM */
+ unsigned int numTargets;
+ Atom *forInt; /* Atoms converted for internal -> type Atom, not XlibAtom */
+ XlibAtom *forRem; /* Atoms converted for remote -> type XlibAtom, not Atom */
} Targets;
+#define EMPTY 0
+#define FORREM 1
+#define FORINT 2
+
static Targets *targetCache = NULL;
/* FIXME: can this also be stored per selection? */
@@ -394,7 +400,9 @@ static void printLastServerStat(int index)
static void printTargetCacheStat(int index)
{
- fprintf(stderr, " targetCache[].targets (Atom *) [%p]\n", (void *)targetCache[index].targets);
+ fprintf(stderr, " targetCache[].type (int) [%d]\n", targetCache[index].type);
+ fprintf(stderr, " targetCache[].forInt (Atom *) [%p]\n", (void *)targetCache[index].forInt);
+ fprintf(stderr, " targetCache[].forRem (XlibAtom *) [%p]\n", (void *)targetCache[index].forRem);
fprintf(stderr, " targetCache[].numTargets (int) [%d]\n", targetCache[index].numTargets);
}
@@ -768,14 +776,29 @@ int nxagentFindCurrentSelectionIndex(Atom sel)
return NumCurrentSelections;
}
-void cacheTargets(int index, Atom* targets, int numTargets)
+void cacheTargetsForInt(int index, Atom* targets, int numTargets)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "%s: caching [%d] targets for internal requests\n", __func__, numTargets);
+ #endif
+
+ SAFE_free(targetCache[index].forInt);
+ SAFE_free(targetCache[index].forRem);
+ targetCache[index].type = FORINT;
+ targetCache[index].forInt = targets;
+ targetCache[index].numTargets = numTargets;
+}
+
+void cacheTargetsForRem(int index, XlibAtom* targets, int numTargets)
{
#ifdef DEBUG
- fprintf(stderr, "%s: caching [%d] targets\n", __func__, numTargets);
+ fprintf(stderr, "%s: caching [%d] targets for remote requests\n", __func__, numTargets);
#endif
- SAFE_free(targetCache[index].targets);
- targetCache[index].targets = targets;
+ SAFE_free(targetCache[index].forInt);
+ SAFE_free(targetCache[index].forRem);
+ targetCache[index].type = FORREM;
+ targetCache[index].forRem = targets;
targetCache[index].numTargets = numTargets;
}
@@ -786,7 +809,9 @@ void invalidateTargetCache(int index)
fprintf(stderr, "%s: invalidating target cache [%d]\n", __func__, index);
#endif
- SAFE_free(targetCache[index].targets);
+ SAFE_free(targetCache[index].forInt);
+ SAFE_free(targetCache[index].forRem);
+ targetCache[index].type = EMPTY;
targetCache[index].numTargets = 0;
}
@@ -798,7 +823,9 @@ void invalidateTargetCaches(void)
for (int index = 0; index < nxagentMaxSelections; index++)
{
- SAFE_free(targetCache[index].targets);
+ SAFE_free(targetCache[index].forInt);
+ SAFE_free(targetCache[index].forRem);
+ targetCache[index].type = EMPTY;
targetCache[index].numTargets = 0;
}
}
@@ -1006,7 +1033,39 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
}
else
{
- /* do nothing, let TARGETS be passed on to the owner later */
+ /*
+ * Shortcut: Some applications tend to post multiple
+ * SelectionRequests. Further it can happen that multiple
+ * clients are interested in clipboard content. If we already
+ * know the answer and no intermediate SelectionOwner event
+ * occured we can answer with the cached list of targets.
+ */
+
+ if (targetCache[index].type == FORREM && targetCache[index].forRem)
+ {
+ XlibAtom *targets = targetCache[index].forRem;
+ unsigned int numTargets = targetCache[index].numTargets;
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Sending %d cached targets to remote requestor:\n", __func__, numTargets);
+ for (int i = 0; i < numTargets; i++)
+ {
+ fprintf(stderr, "%s: %ld %s\n", __func__, targets[i], NameForRemAtom(targets[i]));
+ }
+ #endif
+
+ XChangeProperty(nxagentDisplay,
+ X->xselectionrequest.requestor,
+ X->xselectionrequest.property,
+ XInternAtom(nxagentDisplay, "ATOM", 0),
+ 32,
+ PropModeReplace,
+ (unsigned char *)targets,
+ numTargets);
+
+ replyRequestSelectionToXServer(X, True);
+ return;
+ }
}
}
else if (X->xselectionrequest.target == serverTIMESTAMP)
@@ -1601,7 +1660,7 @@ Bool nxagentCollectPropertyEventFromXServer(int resource)
32, PropModeReplace,
ulReturnItems, (unsigned char*)targets, 1);
- cacheTargets(index, targets, numTargets);
+ cacheTargetsForInt(index, targets, numTargets);
endTransfer(SELECTION_SUCCESS, index);
}
@@ -1852,7 +1911,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
(unsigned char*)targets,
numTargets);
- SAFE_free(targets);
+ cacheTargetsForRem(index, targets, numTargets);
}
}
else
@@ -2358,13 +2417,13 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
* occured we can answer with the cached list of targets.
*/
- if (targetCache[index].targets)
+ if (targetCache[index].type == FORINT && targetCache[index].forInt)
{
- Atom *targets = targetCache[index].targets;
+ Atom *targets = targetCache[index].forInt;
int numTargets = targetCache[index].numTargets;
#ifdef DEBUG
- fprintf(stderr, "%s: Sending %d cached targets:\n", __func__, numTargets);
+ fprintf(stderr, "%s: Sending %d cached targets to internal client:\n", __func__, numTargets);
for (int i = 0; i < numTargets; i++)
{
fprintf(stderr, "%s: %d %s\n", __func__, targets[i], NameForIntAtom(targets[i]));
--
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