aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c140
1 files changed, 88 insertions, 52 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index c0fe74c25..f35ab583a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -79,11 +79,12 @@ const int nxagentMaxSelections = 2;
typedef struct _SelectionOwner
{
- XlibAtom selection; /* _external_ Atom */
- ClientPtr client; /* internal client */
- Window window; /* internal window id */
- WindowPtr windowPtr; /* internal window struct */
- Time lastTimeChanged; /* internal time */
+ ClientPtr client; /* internal client */
+ Atom intSelection; /* internal Atom */
+ XlibAtom remSelection; /* _external_ Atom */
+ Window window; /* internal window id */
+ WindowPtr windowPtr; /* internal window struct */
+ Time lastTimeChanged; /* internal time */
} SelectionOwner;
/*
@@ -118,7 +119,7 @@ typedef struct _lastClient
ClientPtr clientPtr;
Window requestor;
Atom property;
- Atom selection;
+ Atom intSelection;
Atom target;
Time time;
Time reqTime;
@@ -241,7 +242,7 @@ static void transferSelectionFromXServer(int resource, int index);
#if 0
static void resetSelectionOwnerOnXServer(void);
#endif
-static void initSelectionOwnerData(int index, Atom selection);
+static void initSelectionOwnerData(int index, Atom intSelection, XlibAtom remSelection);
static void clearSelectionOwnerData(int index);
static void storeSelectionOwnerData(int index, Selection *sel);
static Bool matchSelectionOwner(int index, ClientPtr pClient, WindowPtr pWindow);
@@ -281,11 +282,9 @@ static void printSelectionStat(int sel)
fprintf(stderr, " lastSelectionOwner[].windowPtr -\n");
fprintf(stderr, " lastSelectionOwner[].lastTimeChanged [%u]\n", lOwner.lastTimeChanged);
- /*
- print the selection name. selection is _always_ a a remote Atom!
- */
- SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, lOwner.selection);
- fprintf(stderr, " lastSelectionOwner[].selection [% 4ld][%s] (%s)\n", lOwner.selection, validateString(s), lOwner.client ? "inside nxagent" : "remote X server");
+ fprintf(stderr, " lastSelectionOwner[].intSelection [% 4d][%s] (%s)\n", lOwner.intSelection, validateString(NameForAtom(lOwner.intSelection)), "inside nxagent");
+ SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, lOwner.remSelection);
+ fprintf(stderr, " lastSelectionOwner[].remSelection [% 4ld][%s] (%s)\n", lOwner.remSelection, validateString(s), "remote X server");
SAFE_XFree(s);
#ifdef CLIENTIDS
fprintf(stderr, " CurrentSelections[].client [%p] index [%d] PID [%d] Cmd [%s]\n",
@@ -312,7 +311,7 @@ static void printLastClientStat(int index)
fprintf(stderr, " lastClients[].clientPtr (ClientPtr) %s\n", nxagentClientInfoString(lc.clientPtr));
fprintf(stderr, " lastClients[].requestor (Window) [0x%x]\n", lc.requestor);
fprintf(stderr, " lastClients[].property (Atom) [% 4d][%s]\n", lc.property, NameForAtom(lc.property));
- fprintf(stderr, " lastClients[].selection (Atom) [% 4d][%s]\n", lc.selection, NameForAtom(lc.selection));
+ fprintf(stderr, " lastClients[].intSelection (Atom) [% 4d][%s]\n", lc.intSelection, NameForAtom(lc.intSelection));
fprintf(stderr, " lastClients[].target (Atom) [% 4d][%s]\n", lc.target, NameForAtom(lc.target));
if (lc.time > 0)
fprintf(stderr, " lastClients[].time (Time) [%u] ([%u]ms ago)\n", lc.time, GetTimeInMillis() - lc.time);
@@ -414,7 +413,8 @@ static void resetClientSelectionStage(int index)
lastClients[index].requestor = 0;
lastClients[index].property = 0;
/* NX_PRIMARY or clipboard atom */
- lastClients[index].selection = lastSelectionOwner[index].selection;
+ /* FIXME: we should only set the once on init and then never touch it again */
+ lastClients[index].intSelection = lastSelectionOwner[index].intSelection;
lastClients[index].target = 0;
lastClients[index].time = 0;
lastClients[index].reqTime = 0;
@@ -600,9 +600,10 @@ static Bool validServerTargets(XlibAtom target)
return False;
}
-static void initSelectionOwnerData(int index, Atom selection)
+static void initSelectionOwnerData(int index, Atom intSelection, XlibAtom remSelection)
{
- lastSelectionOwner[index].selection = selection;
+ lastSelectionOwner[index].intSelection = intSelection;
+ lastSelectionOwner[index].remSelection = remSelection;
lastSelectionOwner[index].client = NullClient;
lastSelectionOwner[index].window = screenInfo.screens[0]->root->drawable.id;
lastSelectionOwner[index].windowPtr = NULL;
@@ -680,7 +681,7 @@ int nxagentFindLastSelectionOwnerIndex(XlibAtom sel)
{
int i = 0;
while (i < nxagentMaxSelections &&
- lastSelectionOwner[i].selection != sel)
+ lastSelectionOwner[i].remSelection != sel)
{
i++;
}
@@ -1087,7 +1088,7 @@ static void endTransfer(Bool success, int index)
sendSelectionNotifyEventToClient(lastClients[index].clientPtr,
lastClients[index].time,
lastClients[index].requestor,
- lastClients[index].selection,
+ lastClients[index].intSelection,
lastClients[index].target,
success == SELECTION_SUCCESS ? lastClients[index].property : None);
}
@@ -1447,11 +1448,11 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
for (index = 0; index < nxagentMaxSelections; index++)
{
#ifdef DEBUG
- fprintf (stderr, "%s: lastClients[%d].selection [%d] selection [%d] .\n",
- __func__, index, lastClients[index].selection,
- nxagentRemoteToLocalAtom(e->selection));
+ fprintf (stderr, "%s: lastClients[%d].intSelection [%d] selection [%d] .\n",
+ __func__, index, lastClients[index].intSelection,
+ nxagentRemoteToLocalAtom(e->selection));
#endif
- if (lastClients[index].selection == nxagentRemoteToLocalAtom(e->selection))
+ if (lastClients[index].intSelection == nxagentRemoteToLocalAtom(e->selection))
{
break;
}
@@ -1682,7 +1683,7 @@ static void resetSelectionOwnerOnXServer(void)
for (int i = 0; i < nxagentMaxSelections; i++)
{
- XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].remSelection, serverWindow, CurrentTime);
#ifdef DEBUG
fprintf(stderr, "%s: Reset selection state for selection [%d].\n", __func__, i);
@@ -1827,7 +1828,7 @@ static void setSelectionOwnerOnXServer(Selection *pSelection)
* inform the real X server that our serverWindow is the
* clipboard owner.
*/
- XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].remSelection, serverWindow, CurrentTime);
/*
* The real owner window (inside nxagent) is stored in
@@ -1918,7 +1919,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
#endif
#ifdef DEBUG
- fprintf(stderr, "%s: lastClients[%d].selection [%d] - selection [%d]\n", __func__, index, lastClients[index].selection, selection);
+ fprintf(stderr, "%s: lastClients[%d].intSelection [%d] - selection [%d]\n", __func__, index, lastClients[index].intSelection, selection);
#endif
if ((GetTimeInMillis() - lastClients[index].reqTime) >= CONVERSION_TIMEOUT)
@@ -2072,50 +2073,75 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
lastClients[index].clientPtr = client;
lastClients[index].time = time;
lastClients[index].property = property;
- lastClients[index].selection = selection;
+ lastClients[index].intSelection = selection;
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();
- if (selection == clientCLIPBOARD)
+ XlibAtom remSelection = 0;
+
+ /* FIXME: we should use/have a function for stuff like that */
+ if (selection == XA_PRIMARY)
+ {
+ remSelection = XA_PRIMARY;
+ }
+ else if (selection == clientCLIPBOARD)
+ {
+ remSelection = lastSelectionOwner[nxagentClipboardSelection].remSelection;
+ }
+ else
{
- selection = lastSelectionOwner[nxagentClipboardSelection].selection;
+ remSelection = nxagentLocalToRemoteAtom(selection);
}
/*
* we only convert to either UTF8 or XA_STRING, despite accepting
* TEXT and COMPOUND_TEXT.
*/
- XlibAtom p = serverTransToAgentProperty;
- XlibAtom t;
+ XlibAtom remProperty = serverTransToAgentProperty;
+ XlibAtom remTarget;
#ifdef DEBUG
char * pstr = "NX_CUT_BUFFER_SERVER";
const char * tstr;
#endif
if (target == clientUTF8_STRING)
{
- t = serverUTF8_STRING;
+ remTarget = serverUTF8_STRING;
#ifdef DEBUG
tstr = szAgentUTF8_STRING;
#endif
}
else
{
- t = XA_STRING;
+ remTarget = XA_STRING;
#ifdef DEBUG
tstr = validateString(NameForAtom(XA_STRING));
#endif
}
#ifdef DEBUG
- fprintf(stderr, "%s: Sending XConvertSelection to real X server: requestor [0x%x] target [%ld][%s] property [%ld][%s] time [0][CurrentTime]\n", __func__,
- serverWindow, t, tstr, p, pstr);
+ /* FIXME: check Atoms.c for alternative to XGetAtomName */
+ fprintf(stderr, "%s: mapping local to remote Atom: [%d][%s] -> [%ld][%s]\n",
+ __func__, selection, NameForAtom(selection), remSelection,
+ XGetAtomName(nxagentDisplay, remSelection));
+ fprintf(stderr, "%s: mapping local to remote Atom: [%d][%s] -> [%ld][%s]\n",
+ __func__, target, NameForAtom(target), remTarget, tstr);
+ fprintf(stderr, "%s: mapping local to remote Atom: [%d][%s] -> [%ld][%s]\n",
+ __func__, property, NameForAtom(property), remProperty, pstr);
#endif
- XConvertSelection(nxagentDisplay, selection, t, p, serverWindow, CurrentTime);
+ /* 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%x] target [%ld][%s] property [%ld][%s] selection [%ld] time [0][CurrentTime]\n", __func__,
+ serverWindow, remTarget, tstr, remProperty, pstr, remSelection);
+ #endif
- /* FIXME: check result of XConvertSelection? */
+ XConvertSelection(nxagentDisplay, remSelection, remTarget, remProperty, serverWindow, CurrentTime);
+
+ /* XConvertSelection will always return (check the source!), so no need to check */
#ifdef DEBUG
fprintf(stderr, "%s: Sent XConvertSelection with target [%s], property [%s]\n", __func__, tstr, pstr);
@@ -2223,9 +2249,17 @@ int nxagentSendNotify(xEvent *event)
* X servers (defined in Xatom.h).
*/
- if (event->u.selectionNotify.selection == clientCLIPBOARD)
+ if (event->u.selectionNotify.selection == XA_PRIMARY)
+ {
+ eventSelection.selection = XA_PRIMARY;
+ }
+ else if (event->u.selectionNotify.selection == clientCLIPBOARD)
+ {
+ eventSelection.selection = lastSelectionOwner[nxagentClipboardSelection].remSelection;
+ }
+ else
{
- eventSelection.selection = lastSelectionOwner[nxagentClipboardSelection].selection;
+ eventSelection.selection = nxagentLocalToRemoteAtom(event->u.selectionNotify.selection);
}
/*
@@ -2282,8 +2316,8 @@ WindowPtr nxagentGetClipboardWindow(Atom property)
lastSelectionOwner[i].windowPtr != NULL)
{
#ifdef DEBUG
- fprintf(stderr, "%s: Returning last [%ld] selection owner window [%p] (0x%x).\n", __func__,
- lastSelectionOwner[i].selection,
+ fprintf(stderr, "%s: Returning last [%d] selection owner window [%p] (0x%x).\n", __func__,
+ lastSelectionOwner[i].intSelection,
(void *)lastSelectionOwner[i].windowPtr, WINDOWID(lastSelectionOwner[i].windowPtr));
#endif
@@ -2317,6 +2351,15 @@ Bool nxagentInitClipboard(WindowPtr pWin)
if (!nxagentReconnectTrap)
{
+ /* cannot move that down to others - we need it for
+ * initSelectionOwnerData ! */
+ clientCLIPBOARD = MakeAtom(szAgentCLIPBOARD, strlen(szAgentCLIPBOARD), True);
+ clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
+ clientTEXT = MakeAtom(szAgentTEXT, strlen(szAgentTEXT), True);
+ clientCOMPOUND_TEXT = MakeAtom(szAgentCOMPOUND_TEXT, strlen(szAgentCOMPOUND_TEXT), True);
+ clientUTF8_STRING = MakeAtom(szAgentUTF8_STRING, strlen(szAgentUTF8_STRING), True);
+ clientTIMESTAMP = MakeAtom(szAgentTIMESTAMP, strlen(szAgentTIMESTAMP), True);
+
SAFE_free(lastSelectionOwner);
lastSelectionOwner = (SelectionOwner *) malloc(nxagentMaxSelections * sizeof(SelectionOwner));
@@ -2325,8 +2368,8 @@ Bool nxagentInitClipboard(WindowPtr pWin)
{
FatalError("nxagentInitClipboard: Failed to allocate memory for the clipboard selections.\n");
}
- initSelectionOwnerData(nxagentPrimarySelection, XA_PRIMARY);
- initSelectionOwnerData(nxagentClipboardSelection, nxagentAtoms[10]); /* CLIPBOARD */
+ initSelectionOwnerData(nxagentPrimarySelection, XA_PRIMARY, XA_PRIMARY);
+ initSelectionOwnerData(nxagentClipboardSelection, clientCLIPBOARD, nxagentAtoms[10]); /* CLIPBOARD */
SAFE_free(lastClients);
@@ -2340,7 +2383,7 @@ Bool nxagentInitClipboard(WindowPtr pWin)
{
/* the clipboard selection atom might have changed on a new X
server. Primary is constant. */
- lastSelectionOwner[nxagentClipboardSelection].selection = nxagentAtoms[10]; /* CLIPBOARD */
+ lastSelectionOwner[nxagentClipboardSelection].remSelection = nxagentAtoms[10]; /* CLIPBOARD */
}
serverTARGETS = nxagentAtoms[6]; /* TARGETS */
@@ -2389,7 +2432,7 @@ Bool nxagentInitClipboard(WindowPtr pWin)
for (int i = 0; i < nxagentMaxSelections; i++)
{
XFixesSelectSelectionInput(nxagentDisplay, serverWindow,
- lastSelectionOwner[i].selection,
+ lastSelectionOwner[i].remSelection,
XFixesSetSelectionOwnerNotifyMask |
XFixesSelectionWindowDestroyNotifyMask |
XFixesSelectionClientCloseNotifyMask);
@@ -2437,7 +2480,7 @@ Bool nxagentInitClipboard(WindowPtr pWin)
*/
if (IS_INTERNAL_OWNER(i) && lastSelectionOwner[i].window)
{
- XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].remSelection, serverWindow, CurrentTime);
}
}
}
@@ -2455,13 +2498,6 @@ Bool nxagentInitClipboard(WindowPtr pWin)
lastServerRequestor = None;
- clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
- clientTEXT = MakeAtom(szAgentTEXT, strlen(szAgentTEXT), True);
- clientCOMPOUND_TEXT = MakeAtom(szAgentCOMPOUND_TEXT, strlen(szAgentCOMPOUND_TEXT), True);
- clientUTF8_STRING = MakeAtom(szAgentUTF8_STRING, strlen(szAgentUTF8_STRING), True);
- clientTIMESTAMP = MakeAtom(szAgentTIMESTAMP, strlen(szAgentTIMESTAMP), True);
- clientCLIPBOARD = MakeAtom(szAgentCLIPBOARD, strlen(szAgentCLIPBOARD), True);
-
clientCutProperty = MakeAtom(szAgentNX_CUT_BUFFER_CLIENT,
strlen(szAgentNX_CUT_BUFFER_CLIENT), True);
if (clientCutProperty == None)