aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Sibiller <uli42@gmx.de>2020-09-23 23:54:36 +0200
committerUlrich Sibiller <uli42@gmx.de>2021-06-20 20:12:50 +0200
commita87ee1e8ff27e9592aa8ead83a443949f1c2fe46 (patch)
treea72addcde375947b47c174cb521926085f2aeff5
parenteba654ea77de62c4de288e5eb3eacaf0b2b938b4 (diff)
downloadnx-libs-a87ee1e8ff27e9592aa8ead83a443949f1c2fe46.tar.gz
nx-libs-a87ee1e8ff27e9592aa8ead83a443949f1c2fe46.tar.bz2
nx-libs-a87ee1e8ff27e9592aa8ead83a443949f1c2fe46.zip
Clipboard.c: target forwarding (Part 2/2)
Internal clients asking for the available targets for a selection will no longer get a predefined list but a the list of targets from the owning client on the real X server.
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c208
1 files changed, 98 insertions, 110 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 56cbf5eef..3721ace60 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -812,7 +812,7 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
else
{
fprintf(stderr, "%s: target [%ld][%s].\n", __func__, X->xselectionrequest.target,
- XGetAtomName(nxagentDisplay, X->xselectionrequest.target));
+ NameForRemAtom(X->xselectionrequest.target));
}
/*
@@ -1244,22 +1244,64 @@ Bool nxagentCollectPropertyEventFromXServer(int resource)
fprintf(stderr, "%s: Got property content from remote server. size [%lu] bytes.\n", __func__, (ulReturnItems * resultFormat / 8));
#endif
- ChangeWindowProperty(lastClients[index].windowPtr,
- lastClients[index].property,
- lastClients[index].target,
- resultFormat, PropModeReplace,
- ulReturnItems, pszReturnData, 1);
+ if (lastClients[index].target == clientTARGETS)
+ {
+ Atom * targets = calloc(sizeof(Atom), ulReturnItems);
+ if (targets == NULL)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "%s: WARNING! Could not alloc memory for clipboard targets transmission.\n", __func__);
+ #endif
- #ifdef DEBUG
- fprintf(stderr, "%s: Selection property [%d][%s] changed to [\"%*.*s\"...]\n", __func__,
- lastClients[index].property,
- NameForIntAtom(lastClients[index].property),
- (int)(min(20, ulReturnItems * resultFormat / 8)),
- (int)(min(20, ulReturnItems * resultFormat / 8)),
- pszReturnData);
- #endif
+ /* operation failed */
+ endTransfer(SELECTION_FAULT, index);
+ }
+ else
+ {
+ /* fprintf(stderr, "sizeof(Atom) [%lu], sizeof(XlibAtom) [%lu], sizeof(long) [%lu], sizeof(CARD32) [%lu] sizeof(INT32) [%lu]\n", sizeof(Atom), sizeof(XlibAtom), sizeof(long), sizeof(CARD32), sizeof(INT32)); */
+
+ Atom *addr = targets;
+ unsigned int numTargets = ulReturnItems;
+
+ for (int i = 0; i < numTargets; i++)
+ {
+ XlibAtom remote = *((XlibAtom*)(pszReturnData + i*resultFormat/8));
+ Atom local = nxagentRemoteToLocalAtom(remote);
+ *(addr++) = local;
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: converting atom: remote [%u][%s] -> local [%u][%s]\n", __func__,
+ (unsigned int)remote, NameForRemAtom(remote), local, NameForIntAtom(local));
+ #endif
+ }
+ ChangeWindowProperty(lastClients[index].windowPtr,
+ lastClients[index].property,
+ MakeAtom("ATOM", 4, 1),
+ 32, PropModeReplace,
+ ulReturnItems, (unsigned char*)targets, 1);
- endTransfer(SELECTION_SUCCESS, index);
+ endTransfer(SELECTION_SUCCESS, index);
+ }
+ }
+ else
+ {
+ ChangeWindowProperty(lastClients[index].windowPtr,
+ lastClients[index].property,
+ lastClients[index].target,
+ resultFormat, PropModeReplace,
+ ulReturnItems, pszReturnData, 1);
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Selection property [%d][%s] changed to [\"%*.*s\"...]\n", __func__,
+ lastClients[index].property,
+ validateString(NameForIntAtom(lastClients[index].property)),
+ (int)(min(20, ulReturnItems * resultFormat / 8)),
+ (int)(min(20, ulReturnItems * resultFormat / 8)),
+ pszReturnData);
+ #endif
+
+ endTransfer(SELECTION_SUCCESS, index);
+ }
}
break;
}
@@ -1475,9 +1517,8 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
*(addr++) = remote;
#ifdef DEBUG
- char *s = XGetAtomName(nxagentDisplay, remote);
- fprintf(stderr, "%s: converting atom: local [%d][%s] -> remote [%ld][%s]\n", __func__,local, NameForAtom(local), remote, s);
- SAFE_XFree(s);
+ fprintf(stderr, "%s: converting atom: local [%d][%s] -> remote [%ld][%s]\n", __func__,
+ local, NameForIntAtom(local), remote, NameForRemAtom(remote));
#endif
}
@@ -1510,16 +1551,14 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
ulReturnItems);
#ifdef DEBUG
{
- char *s = XGetAtomName(nxagentDisplay, lastServers[index].property);
fprintf(stderr, "%s: XChangeProperty sent to window [0x%x] for property [%ld][%s] value [\"%*.*s\"...]\n",
__func__,
lastServers[index].requestor,
lastServers[index].property,
- s,
+ NameForRemAtom(lastServers[index].property),
(int)(min(20, ulReturnItems * 8 / 8)),
(int)(min(20, ulReturnItems * 8 / 8)),
pszReturnData);
- SAFE_XFree(s);
}
#endif
}
@@ -1892,38 +1931,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
}
/*
- * The selection request target is TARGETS. The requestor is asking
- * for a list of supported data formats.
- *
- * The list is aligned with the one in nxagentHandleSelectionRequestFromXServer.
- */
- if (target == clientTARGETS)
- {
- Atom targets[] = {XA_STRING, clientUTF8_STRING, clientTEXT, clientCOMPOUND_TEXT, clientTARGETS, clientTIMESTAMP};
- int numTargets = sizeof(targets) / sizeof(targets[0]);
-
- #ifdef DEBUG
- fprintf(stderr, "%s: available targets [%d]:\n", __func__, numTargets);
- for (int j = 0; j < numTargets; j++)
- fprintf(stderr, "%s: %s\n", __func__, NameForIntAtom(targets[j]));
- fprintf(stderr, "\n");
- #endif
-
- ChangeWindowProperty(pWin,
- property,
- MakeAtom("ATOM", 4, 1),
- sizeof(Atom)*8,
- PropModeReplace,
- numTargets,
- &targets,
- 1);
-
- sendSelectionNotifyEventToClient(client, time, requestor, selection, target, property);
-
- return 1;
- }
-
- /*
* Section 2.6.2 of the ICCCM states:
* "TIMESTAMP - To avoid some race conditions, it is important
* that requestors be able to discover the timestamp the owner
@@ -1982,70 +1989,51 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
clientAccum = 0;
}
- if (target == clientTEXT ||
- target == XA_STRING ||
- target == clientCOMPOUND_TEXT ||
- target == clientUTF8_STRING)
- {
- setClientSelectionStage(SelectionStageNone, index);
-
- /*
- * store the original requestor, we need that later after
- * serverTransToAgentProperty contains the desired selection content
- */
- lastClients[index].requestor = requestor;
- lastClients[index].windowPtr = pWin;
- lastClients[index].clientPtr = client;
- lastClients[index].time = time;
- lastClients[index].property = property;
- lastClients[index].target = target;
- /* if the last client request time is more than 5s ago update it. Why? */
- if ((GetTimeInMillis() - lastClients[index].reqTime) >= CONVERSION_TIMEOUT)
- lastClients[index].reqTime = GetTimeInMillis();
-
- XlibAtom remSelection = translateLocalToRemoteSelection(selection);
- XlibAtom remTarget = translateLocalToRemoteTarget(target);
- XlibAtom remProperty = serverTransToAgentProperty;
-
- #ifdef DEBUG
- fprintf(stderr, "%s: replacing local by remote property: [%d][%s] -> [%ld][%s]\n",
- __func__, property, NameForIntAtom(property),
- remProperty, "NX_CUT_BUFFER_SERVER");
- #endif
+ setClientSelectionStage(SelectionStageNone, index);
- /* FIXME: check why using CurrentTime will not replace the value
- * by a real time. The reply also contains time "0" which is
- * unexpected (for me) */
- #ifdef DEBUG
- fprintf(stderr, "%s: Sending XConvertSelection to real X server: requestor [0x%lx] target [%ld][%s] property [%ld][%s] selection [%ld][%s] time [0][CurrentTime]\n", __func__,
- serverWindow, remTarget, NameForRemAtom(remTarget),
- remProperty, NameForRemAtom(remProperty),
- remSelection, NameForRemAtom(remSelection));
- #endif
+ /*
+ * store the original requestor, we need that later after
+ * serverTransToAgentProperty contains the desired selection content
+ */
+ lastClients[index].requestor = requestor;
+ lastClients[index].windowPtr = pWin;
+ lastClients[index].clientPtr = client;
+ lastClients[index].time = time;
+ lastClients[index].property = property;
+ lastClients[index].target = target;
+ /* if the last client request time is more than 5s ago update it. Why? */
+ if ((GetTimeInMillis() - lastClients[index].reqTime) >= CONVERSION_TIMEOUT)
+ lastClients[index].reqTime = GetTimeInMillis();
+
+ XlibAtom remSelection = translateLocalToRemoteSelection(selection);
+ XlibAtom remTarget = translateLocalToRemoteTarget(target);
+ XlibAtom remProperty = serverTransToAgentProperty;
- XConvertSelection(nxagentDisplay, remSelection, remTarget, remProperty, serverWindow, CurrentTime);
+ #ifdef DEBUG
+ fprintf(stderr, "%s: replacing local by remote property: [%d][%s] -> [%ld][%s]\n",
+ __func__, property, NameForIntAtom(property),
+ remProperty, "NX_CUT_BUFFER_SERVER");
+ #endif
- /* XConvertSelection will always return (check the source!), so no need to check */
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Sending XConvertSelection to real X server: requestor [0x%x] target [%ld][%s] property [%ld][%s] selection [%ld][%s] time [0][CurrentTime]\n", __func__,
+ serverWindow, remTarget, NameForRemAtom(remTarget),
+ remProperty, NameForRemAtom(remProperty),
+ remSelection, NameForRemAtom(remSelection));
+ #endif
- #ifdef DEBUG
- fprintf(stderr, "%s: Sent XConvertSelection\n", __func__);
- #endif
+ UpdateCurrentTime();
+ XConvertSelection(nxagentDisplay, remSelection, remTarget, remProperty,
+ serverWindow, CurrentTime);
- return 1;
- }
- else
- {
- /* deny request */
- #ifdef DEBUG
- fprintf(stderr, "%s: Unsupported target [%d][%s] - denying request\n", __func__, target,
- NameForIntAtom(target));
- #endif
- sendSelectionNotifyEventToClient(client, time, requestor, selection, target, None);
+ /* XConvertSelection will always return 1 (check the source!), so no
+ need to check */
- return 1;
- }
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Sent XConvertSelection\n", __func__);
+ #endif
- return 0;
+ return 1;
}
XlibAtom translateLocalToRemoteSelection(Atom local)