aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2019-06-11 12:24:44 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2019-06-11 12:24:44 +0200
commitc0754a35755cdd4e25386abc6378e07605845948 (patch)
tree556107b4e0267c6985f1dc8c7960502b88733983
parent58cd35745086567b5b1fa0fc7a295e849ac070ce (diff)
parent848dee5c42bffdf19c4b9f01c38334bf53fefa49 (diff)
downloadnx-libs-c0754a35755cdd4e25386abc6378e07605845948.tar.gz
nx-libs-c0754a35755cdd4e25386abc6378e07605845948.tar.bz2
nx-libs-c0754a35755cdd4e25386abc6378e07605845948.zip
Merge branch 'uli42-pr/use_selection_callback' into 3.6.x
Attributes GH PR #814: https://github.com/ArcticaProject/nx-libs/pull/814
-rw-r--r--nx-X11/programs/Xserver/dix/dispatch.c2
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c69
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Events.c12
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Init.c9
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c106
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Trap.c8
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Trap.h8
7 files changed, 106 insertions, 108 deletions
diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c
index 86a33ec65..6b6dbcad9 100644
--- a/nx-X11/programs/Xserver/dix/dispatch.c
+++ b/nx-X11/programs/Xserver/dix/dispatch.c
@@ -919,7 +919,6 @@ ProcGetAtomName(register ClientPtr client)
}
}
-#ifndef NXAGENT_SERVER
int
ProcSetSelectionOwner(register ClientPtr client)
{
@@ -1014,7 +1013,6 @@ ProcSetSelectionOwner(register ClientPtr client)
return (BadAtom);
}
}
-#endif /* NXAGENT_SERVER */
int
ProcGetSelectionOwner(register ClientPtr client)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 824c1dc47..9c518801b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1257,6 +1257,75 @@ void nxagentResetSelectionOwner(void)
return;
}
+#ifdef NXAGENT_CLIPBOARD
+void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data,
+ void *args)
+{
+ /*
+ * Only act if the Trap is unset. The trap indicates that we are
+ * triggered by a clipboard event originating from the real X
+ * server. In that case we do not want to propagate back changes to
+ * the real X server, because it already knows about them and we
+ * would end up in an infinite loop of events. If there was a better
+ * way to identify that situation during Callback processing we
+ * could get rid of the Trap...
+ */
+ if (nxagentExternalClipboardEventTrap != 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Trap is set, doing nothing\n", __func__);
+ #endif
+ return;
+ }
+
+ SelectionInfoRec *info = (SelectionInfoRec *)args;
+
+ Selection * pCurSel = (Selection *)info->selection;
+
+ #ifdef DEBUG
+ fprintf(stderr, "%s: pCurSel->lastTimeChanged [%d]\n", __func__, pCurSel->lastTimeChanged.milliseconds);
+ #endif
+
+ if (info->kind == SelectionSetOwner)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: called with SelectionCallbackKind SelectionSetOwner\n", __func__);
+ fprintf(stderr, "%s: pCurSel->pWin [0x%x]\n", __func__, pCurSel->pWin ? pCurSel->pWin->drawable.id : NULL);
+ fprintf(stderr, "%s: pCurSel->selection [%s]\n", __func__, NameForAtom(pCurSel->selection));
+ #endif
+
+ if ((pCurSel->pWin != NULL) &&
+ (nxagentOption(Clipboard) != ClipboardNone) &&
+ ((pCurSel->selection == XA_PRIMARY) ||
+ (pCurSel->selection == MakeAtom("CLIPBOARD", 9, 0))))
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: calling nxagentSetSelectionOwner\n", __func__);
+ #endif
+ nxagentSetSelectionOwner(pCurSel);
+ }
+ }
+ else if (info->kind == SelectionWindowDestroy)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: called with SelectionCallbackKind SelectionWindowDestroy\n", __func__);
+ #endif
+ }
+ else if (info->kind == SelectionClientClose)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: called with SelectionCallbackKind SelectionClientClose\n", __func__);
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "%s: called with unknown SelectionCallbackKind\n", __func__);
+ #endif
+ }
+}
+#endif
+
void nxagentSetSelectionOwner(Selection *pSelection)
{
#ifdef DEBUG
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 7ec97dada..4bddbba3a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -2968,7 +2968,19 @@ int nxagentHandleXFixesSelectionNotify(XEvent *X)
info.selection = &CurrentSelections[i];
info.kind = xfixesEvent->xfixesselection.subtype;
+
+ /*
+ * The trap indicates that we are triggered by a clipboard event
+ * originating from the real X server. In that case we do not
+ * want to propagate back changes to the real X server, because
+ * it already knows about them and we would end up in an
+ * infinite loop of events. If there was a better way to
+ * identify that situation during Callback processing we could
+ * get rid of the Trap...
+ */
+ nxagentExternalClipboardEventTrap = 1;
CallCallbacks(&SelectionCallback, &info);
+ nxagentExternalClipboardEventTrap = 0;
}
}
return 1;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 80ca5fac1..1e24a618e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -143,6 +143,11 @@ void OsVendorEndRedirectErrorFFunction();
static void nxagentGrabServerCallback(CallbackListPtr *callbacks, void *data,
void *args);
+#ifdef NXAGENT_CLIPBOARD
+extern void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data,
+ void *args);
+#endif
+
void ddxInitGlobals(void)
{
/*
@@ -411,6 +416,10 @@ FIXME: These variables, if not removed at all because have probably
blackRoot = TRUE;
nxagentInitKeystrokes(False);
+
+#ifdef NXAGENT_CLIPBOARD
+ AddCallback(&SelectionCallback, nxagentSetSelectionCallback, NULL);
+#endif
}
void
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index db055f0cd..339994e6c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -678,112 +678,6 @@ ProcQueryTree(register ClientPtr client)
int
-ProcSetSelectionOwner(register ClientPtr client)
-{
- WindowPtr pWin;
- TimeStamp time;
- REQUEST(xSetSelectionOwnerReq);
-
- REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
- UpdateCurrentTime();
- time = ClientTimeToServerTime(stuff->time);
-
- /* If the client's time stamp is in the future relative to the server's
- time stamp, do not set the selection, just return success. */
- if (CompareTimeStamps(time, currentTime) == LATER)
- return Success;
- if (stuff->window != None)
- {
- pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
- DixReadAccess);
- if (!pWin)
- return(BadWindow);
- }
- else
- pWin = (WindowPtr)None;
- if (ValidAtom(stuff->selection))
- {
- int i = 0;
-
- /*
- * First, see if the selection is already set...
- */
- while ((i < NumCurrentSelections) &&
- CurrentSelections[i].selection != stuff->selection)
- i++;
- if (i < NumCurrentSelections)
- {
- /* If the timestamp in client's request is in the past relative
- to the time stamp indicating the last time the owner of the
- selection was set, do not set the selection, just return
- success. */
- if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
- == EARLIER)
- return Success;
- if (CurrentSelections[i].client &&
- (!pWin || (CurrentSelections[i].client != client)))
- {
- xEvent event = {0};
- event.u.u.type = SelectionClear;
- event.u.selectionClear.time = time.milliseconds;
- event.u.selectionClear.window = CurrentSelections[i].window;
- event.u.selectionClear.atom = CurrentSelections[i].selection;
- (void) TryClientEvents (CurrentSelections[i].client, &event, 1,
- NoEventMask, NoEventMask /* CantBeFiltered */,
- NullGrab);
- }
- }
- else
- {
- /*
- * It doesn't exist, so add it...
- */
- Selection *newsels;
-
- if (i == 0)
- newsels = (Selection *)malloc(sizeof(Selection));
- else
- newsels = (Selection *)realloc(CurrentSelections,
- (NumCurrentSelections + 1) * sizeof(Selection));
- if (!newsels)
- return BadAlloc;
- NumCurrentSelections++;
- CurrentSelections = newsels;
- CurrentSelections[i].selection = stuff->selection;
- }
- CurrentSelections[i].lastTimeChanged = time;
- CurrentSelections[i].window = stuff->window;
- CurrentSelections[i].pWin = pWin;
- CurrentSelections[i].client = (pWin ? client : NullClient);
- if (SelectionCallback)
- {
- SelectionInfoRec info = {0};
-
- info.selection = &CurrentSelections[i];
- info.kind= SelectionSetOwner;
- CallCallbacks(&SelectionCallback, &info);
- }
-
-#ifdef NXAGENT_CLIPBOARD
- if ((CurrentSelections[i].pWin != NULL) &&
- (nxagentOption(Clipboard) != ClipboardNone) &&
- ((CurrentSelections[i].selection == XA_PRIMARY) ||
- (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
- {
- nxagentSetSelectionOwner(&CurrentSelections[i]);
- }
-#endif
- return (client->noClientException);
- }
- else
- {
- client->errorValue = stuff->selection;
- return (BadAtom);
- }
-}
-
-
-int
ProcConvertSelection(register ClientPtr client)
{
Bool paramsOkay;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index c582f6a16..f219bb43c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -120,3 +120,11 @@ int nxagentXkbCapsTrap = 0;
int nxagentXkbNumTrap = 0;
+
+/*
+ * Set to indicate we are processing a clipboard event triggered by
+ * the real X server. This is used to avoid endless loops if callbacks
+ * would trigger another event by the real X server
+ */
+
+int nxagentExternalClipboardEventTrap = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index f0884f657..9f0c055c8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -121,4 +121,12 @@ extern int nxagentXkbCapsTrap;
extern int nxagentXkbNumTrap;
+/*
+ * Set to indicate we are processing a clipboard event triggered by
+ * the real X server. This is used to avoid endless loops if callbacks
+ * would trigger another event by the real X server
+ */
+
+extern int nxagentExternalClipboardEventTrap;
+
#endif /* __Trap_H__ */