aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Sibiller <uli42@gmx.de>2021-02-12 23:26:16 +0100
committerUlrich Sibiller <uli42@gmx.de>2021-06-20 20:12:51 +0200
commitd97e5022e8e04f5316908dc772a491e5fe422b4c (patch)
treee6fe32af510d6701c1dfe4fb7266debff5ec57c6
parent04ca25eb1af9b3ea3eb94ceb851e0eda2a08b535 (diff)
downloadnx-libs-d97e5022e8e04f5316908dc772a491e5fe422b4c.tar.gz
nx-libs-d97e5022e8e04f5316908dc772a491e5fe422b4c.tar.bz2
nx-libs-d97e5022e8e04f5316908dc772a491e5fe422b4c.zip
Clipboard.c: check target cache for valid targets
Instead of passing the target to the remote side and then receiving an "invalid target" reply we can do that check directly (if the target cache is filled). This way we can save some more roundtrips due to the target cache.
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 4c0c6d320..c85e61298 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1187,6 +1187,55 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
* can process it now.
*/
+ if (!nxagentOption(TextClipboard))
+ {
+ /* Optimization: if we have a current target cache check if the
+ * requested target is supported by the owner. If not we can take
+ * a shortcut and deny the request immediately without doing any
+ * further communication */
+ if (targetCache[index].type == FORREM && targetCache[index].forRem)
+ {
+ XlibAtom *targets = targetCache[index].forRem;
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Checking target validity\n", __func__);
+ #endif
+ Bool match = False;
+ for (int i = 0; i < targetCache[index].numTargets; i++)
+ {
+ if (targets[i] == X->xselectionrequest.target)
+ {
+ match = True;
+ break;
+ }
+ }
+ if (!match)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: target [%ld][%s] is not supported by the owner - denying request.\n",
+ __func__, X->xselectionrequest.target, NameForRemAtom(X->xselectionrequest.target));
+ #endif
+ replyRequestSelectionToXServer(X, False);
+ return;
+ }
+ }
+ else
+ {
+ /*
+ * at this stage we know a remote client has asked for a selection
+ * target without having retrieved the list of supported targets
+ * first.
+ */
+ #ifdef DEBUG
+ if (X->xselectionrequest.target != serverTARGETS)
+ {
+ fprintf(stderr, "%s: WARNING: remote client has not retrieved TARGETS before asking for selection!\n",
+ __func__);
+ }
+ #endif
+ }
+ }
+
/*
* This is required for nxagentGetClipboardWindow.
*/
@@ -2620,6 +2669,55 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
NameForIntAtom(target));
#endif
+ if (!nxagentOption(TextClipboard))
+ {
+ /* Optimization: if we have a current target cache check if the
+ * requested target is supported by the owner. If not we can take
+ * a shortcut and deny the request immediately without doing any
+ * further communication */
+ if (targetCache[index].type == FORINT && targetCache[index].forInt)
+ {
+ Atom *targets = targetCache[index].forInt;
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Checking target validity\n", __func__);
+ #endif
+ Bool match = False;
+ for (int i = 0; i < targetCache[index].numTargets; i++)
+ {
+ if (targets[i] == target)
+ {
+ match = True;
+ break;
+ }
+ }
+ if (!match)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: target [%d][%s] is not supported by the owner - denying request.\n",
+ __func__, target, NameForIntAtom(target));
+ #endif
+ sendSelectionNotifyEventToClient(client, time, requestor, selection, target, None);
+ return 1;
+ }
+ }
+ else
+ {
+ /*
+ * at this stage we know a client has asked for a selection
+ * target without having retrieved the list of supported targets
+ * first.
+ */
+ #ifdef DEBUG
+ if (target != clientTARGETS)
+ {
+ fprintf(stderr, "%s: WARNING: client has not retrieved TARGETS before asking for selection!\n",
+ __func__);
+ }
+ #endif
+ }
+ }
+
if (lastClients[index].clientPtr == client)
{
#ifdef DEBUG