aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Sibiller <uli42@gmx.de>2020-09-23 15:48:43 +0200
committerUlrich Sibiller <uli42@gmx.de>2021-06-20 20:12:50 +0200
commita8d09f81501b76b507f080e6a812101f6cc2ada5 (patch)
treea8b209e2aec67b47f8749e7494f5f02b4ec5dfd3
parente526e1cd0fec37b35a746d600170e923e8e86041 (diff)
downloadnx-libs-a8d09f81501b76b507f080e6a812101f6cc2ada5.tar.gz
nx-libs-a8d09f81501b76b507f080e6a812101f6cc2ada5.tar.bz2
nx-libs-a8d09f81501b76b507f080e6a812101f6cc2ada5.zip
Clipboard.c: have lastServer* per selection
This will help in PRIMARY content appearing in CLIPBOARD and vice versa.
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c183
1 files 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)