aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2020-05-31 12:53:30 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2020-05-31 12:53:30 +0200
commit3f7bb584e1b56f787cc0b4bef684afc669359e83 (patch)
tree164b21be69dce127910dacfb27647da0b42681ea
parent4904bfe1f57d50134fd12a08424d299ef4094ef5 (diff)
parent49d63d92a81ff5157c18bbdc9a3b0cba1b70d425 (diff)
downloadnx-libs-3f7bb584e1b56f787cc0b4bef684afc669359e83.tar.gz
nx-libs-3f7bb584e1b56f787cc0b4bef684afc669359e83.tar.bz2
nx-libs-3f7bb584e1b56f787cc0b4bef684afc669359e83.zip
Merge branch 'uli42-pr/clipboard_dump' into 3.6.x
Attributes GH PR #918: https://github.com/ArcticaProject/nx-libs/pull/918
-rw-r--r--doc/nxagent/README.keystrokes4
-rw-r--r--etc/keystrokes.cfg1
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Client.h4
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.c335
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Clipboard.h2
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Events.c5
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Events.h1
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.c6
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Keystroke.h4
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c7
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXevents.c12
11 files changed, 204 insertions, 177 deletions
diff --git a/doc/nxagent/README.keystrokes b/doc/nxagent/README.keystrokes
index b76e9fd62..e916bddc0 100644
--- a/doc/nxagent/README.keystrokes
+++ b/doc/nxagent/README.keystrokes
@@ -129,6 +129,10 @@ reread_keystrokes
autograb
Toggles autograb mode
+dump_clipboard
+ print the current internal clipboard state (for debugging) to the
+ log.
+
force_synchronization
Forces immediate drawing of elements to be synchronized which can
fix some visual bugs.
diff --git a/etc/keystrokes.cfg b/etc/keystrokes.cfg
index 27acf8e84..ea9feeea6 100644
--- a/etc/keystrokes.cfg
+++ b/etc/keystrokes.cfg
@@ -25,4 +25,5 @@
<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="KP_Down" />
<keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" />
<keystroke action="autograb" Control="1" AltMeta="1" key="g" />
+<keystroke action="dump_clipboard" Control="1" Shift="1" AltMeta="1" key="c" />
</keystrokes>
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index a3e6e3cf3..ac2f34e8b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -75,8 +75,8 @@ extern void nxagentClientStateCallback(CallbackListPtr *callbacks, void *data, v
#define nxagentClientIsDialog(pClient) \
(nxagentClientHint(pClient) == NXCLIENT_DIALOG)
-#define nxagentClientInfoString(pClient) \
- (nxagentClientPriv(pClient) -> clientInfoString)
+#define nxagentClientInfoString(pClient) \
+ ((pClient) ? nxagentClientPriv(pClient) -> clientInfoString : NULL)
/*
* The actual reason why the client is sleeping.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index d51f066a9..ecc3f19be 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -38,6 +38,7 @@
#include "Rootless.h"
#include "Clipboard.h"
#include "Utils.h"
+#include "Client.h"
#include "gcstruct.h"
#include "xfixeswire.h"
@@ -68,9 +69,7 @@ extern Selection *CurrentSelections;
int nxagentLastClipboardClient = -1;
static int agentClipboardInitialized = False;
-#ifdef DEBUG
static int clientAccum;
-#endif
XlibAtom serverTransToAgentProperty;
Atom clientCutProperty;
@@ -156,19 +155,16 @@ static char szAgentCLIPBOARD[] = "CLIPBOARD";
/* number of milliseconds to wait for a conversion from the real X server. */
#define CONVERSION_TIMEOUT 5000
-#ifdef DEBUG
/*
* Time window (milliseconds) within to detect multiple conversion
* calls of the same client.
*/
#define ACCUM_TIME 5000
-#endif
/*
* some helpers for debugging output
*/
-#ifdef DEBUG
static const char * getClientSelectionStageString(int stage)
{
switch(stage)
@@ -181,15 +177,16 @@ static const char * getClientSelectionStageString(int stage)
default: return("UNKNOWN!"); break;;
}
}
-#define setClientSelectionStage(stage) do {fprintf(stderr, "%s: Changing selection stage from [%s] to [%s]\n", __func__, getClientSelectionStageString(lastClientStage), getClientSelectionStageString(SelectionStage##stage)); lastClientStage = SelectionStage##stage;} while (0)
+
+#ifdef DEBUG
#define printClientSelectionStage() do {fprintf(stderr, "%s: Current selection stage [%s]\n", __func__, getClientSelectionStageString(lastClientStage));} while (0)
-#define WINDOWID(ptr) (ptr) ? (ptr->drawable.id) : 0
-#define CLINDEX(clientptr) (clientptr) ? (clientptr->index) : -1
#else
-#define setClientSelectionStage(stage) do {lastClientStage = SelectionStage##stage;} while (0)
#define printClientSelectionStage()
#endif
+#define WINDOWID(ptr) (ptr) ? (ptr->drawable.id) : 0
+#define CLINDEX(clientptr) (clientptr) ? (clientptr->index) : -1
+
#ifdef DEBUG
/*
* see also nx-X11/lib/src/ErrDes.c
@@ -233,6 +230,7 @@ XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, 0 };
extern Display *nxagentDisplay;
static Bool validServerTargets(XlibAtom target);
+static void setClientSelectionStage(int stage);
static void endTransfer(Bool success);
#define SELECTION_SUCCESS True
#define SELECTION_FAULT False
@@ -244,17 +242,14 @@ static void initSelectionOwner(int index, Atom selection);
static void clearSelectionOwner(int index);
static void storeSelectionOwner(int index, Selection *sel);
static Bool matchSelectionOwner(int index, ClientPtr pClient, WindowPtr pWindow);
-
-static void notifyConvertFailure(ClientPtr client, Window requestor,
- Atom selection, Atom target, Time time);
static void setSelectionOwner(Selection *pSelection);
static int sendEventToClient(ClientPtr client, xEvent *pEvents);
-static int sendSelectionNotifyEventToClient(ClientPtr client,
- Time time,
- Window requestor,
- Atom selection,
- Atom target,
- Atom property);
+static void sendSelectionNotifyEventToClient(ClientPtr client,
+ Time time,
+ Window requestor,
+ Atom selection,
+ Atom target,
+ Atom property);
static Status sendSelectionNotifyEventToServer(XSelectionEvent *event_to_send);
#ifdef DEBUG
static void printSelectionStat(int sel);
@@ -267,7 +262,6 @@ void nxagentPrintClipboardStat(char *);
extern unsigned long startTime;
#endif
-#ifdef DEBUG
static void printSelectionStat(int sel)
{
SelectionOwner lOwner = lastSelectionOwner[sel];
@@ -275,17 +269,7 @@ static void printSelectionStat(int sel)
char *s = NULL;
fprintf(stderr, " owner is inside nxagent? %s\n", IS_INTERNAL_OWNER(sel) ? "yes" : "no");
-#ifdef CLIENTIDS
- fprintf(stderr, " lastSelectionOwner[].client [%p] index [%d] PID [%d] Cmd [%s]\n",
- (void *)lOwner.client,
- CLINDEX(lOwner.client),
- GetClientPid(lOwner.client),
- GetClientCmdName(lOwner.client));
-#else
- fprintf(stderr, " lastSelectionOwner[].client [%p] index [%d]\n",
- (void *)lOwner.client,
- CLINDEX(lOwner.client));
-#endif
+ fprintf(stderr, " lastSelectionOwner[].client %s\n", nxagentClientInfoString(lOwner.client));
fprintf(stderr, " lastSelectionOwner[].window [0x%x]\n", lOwner.window);
if (lOwner.windowPtr)
fprintf(stderr, " lastSelectionOwner[].windowPtr [%p] ([0x%x]\n", (void *)lOwner.windowPtr, WINDOWID(lOwner.windowPtr));
@@ -313,14 +297,12 @@ static void printSelectionStat(int sel)
fprintf(stderr, " CurrentSelections[].window [0x%x]\n", curSel.window);
return;
}
-#endif
-void nxagentPrintClipboardStat(char *header)
+void nxagentDumpClipboardStat(void)
{
- #ifdef DEBUG
char *s = NULL;
- fprintf(stderr, "/----- Clipboard internal status - %s -----\n", header);
+ fprintf(stderr, "/----- Clipboard internal status -----\n");
fprintf(stderr, " current time (Time) [%u]\n", GetTimeInMillis());
fprintf(stderr, " agentClipboardInitialized (Bool) [%s]\n", agentClipboardInitialized ? "True" : "False");
@@ -354,13 +336,19 @@ void nxagentPrintClipboardStat(char *header)
fprintf(stderr, " lastClientWindowPtr (WindowPtr) [%p] ([0x%x])\n", (void *)lastClientWindowPtr, WINDOWID(lastClientWindowPtr));
else
fprintf(stderr, " lastClientWindowPtr (WindowPtr) -\n");
- fprintf(stderr, " lastClientClientPtr (ClientPtr) [%p]\n", (void *)lastClientClientPtr);
+ fprintf(stderr, " lastClientClientPtr (ClientPtr) %s\n", nxagentClientInfoString(lastClientClientPtr));
fprintf(stderr, " lastClientRequestor (Window) [0x%x]\n", lastClientRequestor);
fprintf(stderr, " lastClientProperty (Atom) [% 4d][%s]\n", lastClientProperty, NameForAtom(lastClientProperty));
fprintf(stderr, " lastClientSelection (Atom) [% 4d][%s]\n", lastClientSelection, NameForAtom(lastClientSelection));
fprintf(stderr, " lastClientTarget (Atom) [% 4d][%s]\n", lastClientTarget, NameForAtom(lastClientTarget));
- fprintf(stderr, " lastClientTime (Time) [%u]\n", lastClientTime);
- fprintf(stderr, " lastClientReqTime (Time) [%u]\n", lastClientReqTime);
+ if (lastClientTime > 0)
+ fprintf(stderr, " lastClientTime (Time) [%u] ([%u]ms ago)\n", lastClientTime, GetTimeInMillis() - lastClientTime);
+ else
+ fprintf(stderr, " lastClientTime (Time) [%u]\n", lastClientTime);
+ if (lastClientReqTime > 0)
+ fprintf(stderr, " lastClientReqTime (Time) [%u] ([%u]ms ago)\n", lastClientReqTime, GetTimeInMillis() - lastClientReqTime);
+ else
+ fprintf(stderr, " lastClientReqTime (Time) [%u]\n", lastClientReqTime);
fprintf(stderr, " lastClientPropertySize (unsigned long) [%lu]\n", lastClientPropertySize);
fprintf(stderr, " lastClientStage (ClientSelectionStage) [%d][%s]\n", lastClientStage, getClientSelectionStageString(lastClientStage));
@@ -399,7 +387,31 @@ void nxagentPrintClipboardStat(char *header)
fprintf(stderr, "\\------------------------------------------------------------------------------\n");
SAFE_XFree(s);
-#endif
+}
+
+/*
+ * Helper to handle data transfer
+ */
+static void setClientSelectionStage(int stage)
+{
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Changing selection stage from [%s] to [%s]\n", __func__,
+ getClientSelectionStageString(lastClientStage), getClientSelectionStageString(stage));
+ #endif
+
+ lastClientStage = stage;
+ if (stage == SelectionStageNone)
+ {
+ lastClientWindowPtr = NULL;
+ lastClientClientPtr = NULL;
+ lastClientRequestor = 0;
+ lastClientProperty = 0;
+ lastClientSelection = 0;
+ lastClientTarget = 0;
+ lastClientTime = 0;
+ lastClientReqTime = 0;
+ lastClientPropertySize = 0;
+ }
}
/*
@@ -458,13 +470,25 @@ static int sendEventToClient(ClientPtr client, xEvent *pEvents)
return TryClientEvents(client, pEvents, 1, NoEventMask, NoEventMask, NullGrab);
}
-static int sendSelectionNotifyEventToClient(ClientPtr client,
+static void sendSelectionNotifyEventToClient(ClientPtr client,
Time time,
Window requestor,
Atom selection,
Atom target,
Atom property)
{
+ /*
+ * Check if the client is still valid.
+ */
+ if (clients[client -> index] != client)
+ {
+ #ifdef WARNING
+ fprintf(stderr, "%s: WARNING! Invalid client pointer.", __func__);
+ #endif
+
+ return;
+ }
+
xEvent x = {0};
x.u.u.type = SelectionNotify;
x.u.selectionNotify.time = time;
@@ -475,14 +499,14 @@ static int sendSelectionNotifyEventToClient(ClientPtr client,
#ifdef DEBUG
if (property == None)
- fprintf (stderr, "%s: Denying request to client [%d].\n", __func__,
- CLINDEX(client));
+ fprintf(stderr, "%s: Denying request to client %s.\n", __func__,
+ nxagentClientInfoString(client));
else
- fprintf (stderr, "%s: Sending event to client [%d].\n", __func__,
- CLINDEX(client));
+ fprintf(stderr, "%s: Sending event to client %s.\n", __func__,
+ nxagentClientInfoString(client));
#endif
- return sendEventToClient(client, &x);
+ sendEventToClient(client, &x);
}
/*
@@ -574,6 +598,12 @@ static Bool matchSelectionOwner(int index, ClientPtr pClient, WindowPtr pWindow)
(pWindow && lastSelectionOwner[index].windowPtr == pWindow));
}
+/*
+ * Clear relevant clipboard states if a client or window is closing.
+ * Attention: does not work properly when both client AND window
+ * are passed as setClientSelectionStage(None) will also clear
+ * the lastClientWindowPtr!
+ */
void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
{
#ifdef DEBUG
@@ -581,8 +611,6 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
(void *) pClient, CLINDEX(pClient), (void *) pWindow, WINDOWID(pWindow));
#endif
- nxagentPrintClipboardStat("before nxagentClearClipboard");
-
/*
* Only for PRIMARY and CLIPBOARD selections.
*/
@@ -598,8 +626,7 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
clearSelectionOwner(i);
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
lastServerRequestor = None;
}
@@ -607,11 +634,8 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
if (pWindow && pWindow == lastClientWindowPtr)
{
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
}
-
- nxagentPrintClipboardStat("after nxagentClearClipboard");
}
/*
@@ -655,8 +679,6 @@ void nxagentHandleSelectionClearFromXServer(XEvent *X)
fprintf(stderr, "%s: SelectionClear event for selection [%lu].\n", __func__, X->xselectionclear.selection);
#endif
- nxagentPrintClipboardStat("before nxagentHandleSelectionClearFromXServer");
-
if (!agentClipboardInitialized)
{
#ifdef DEBUG
@@ -699,9 +721,7 @@ void nxagentHandleSelectionClearFromXServer(XEvent *X)
clearSelectionOwner(i);
}
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
- nxagentPrintClipboardStat("after nxagentHandleSelectionClearFromXServer");
+ setClientSelectionStage(SelectionStageNone);
}
/*
@@ -760,8 +780,6 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
}
#endif
- nxagentPrintClipboardStat("before nxagentHandleSelectionRequestFromXServer");
-
if (!agentClipboardInitialized)
{
#ifdef DEBUG
@@ -969,9 +987,9 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
sendEventToClient(lastSelectionOwner[i].client, &x);
#ifdef DEBUG
- fprintf(stderr, "%s: sent SelectionRequest event to client [%d] property [%d][%s]" \
+ fprintf(stderr, "%s: sent SelectionRequest event to client %s property [%d][%s]" \
"target [%d][%s] requestor [0x%x].\n", __func__,
- CLINDEX(lastSelectionOwner[i].client),
+ nxagentClientInfoString(lastSelectionOwner[i].client),
x.u.selectionRequest.property, NameForAtom(x.u.selectionRequest.property),
x.u.selectionRequest.target, NameForAtom(x.u.selectionRequest.target),
x.u.selectionRequest.requestor);
@@ -984,7 +1002,6 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
}
}
}
- nxagentPrintClipboardStat("after nxagentHandleSelectionRequestFromXServer");
}
/*
@@ -1001,30 +1018,30 @@ static void endTransfer(Bool success)
#ifdef DEBUG
fprintf(stderr, "%s: lastClientClientPtr is NULL - doing nothing.\n", __func__);
#endif
- return;
}
-
- #ifdef DEBUG
- if (success == SELECTION_SUCCESS)
- fprintf(stderr, "%s: sending notification to client [%d], property [%d][%s]\n", __func__,
- CLINDEX(lastClientClientPtr), lastClientProperty, NameForAtom(lastClientProperty));
else
- fprintf(stderr, "%s: sending negative notification to client [%d]\n", __func__,
- CLINDEX(lastClientClientPtr));
- #endif
+ {
+ #ifdef DEBUG
+ if (success == SELECTION_SUCCESS)
+ fprintf(stderr, "%s: sending notification to client %s, property [%d][%s]\n", __func__,
+ nxagentClientInfoString(lastClientClientPtr), lastClientProperty, NameForAtom(lastClientProperty));
+ else
+ fprintf(stderr, "%s: sending negative notification to client %s\n", __func__,
+ nxagentClientInfoString(lastClientClientPtr));
+ #endif
- sendSelectionNotifyEventToClient(lastClientClientPtr,
- lastClientTime,
- lastClientRequestor,
- lastClientSelection,
- lastClientTarget,
- success == SELECTION_SUCCESS ? lastClientProperty : None);
+ sendSelectionNotifyEventToClient(lastClientClientPtr,
+ lastClientTime,
+ lastClientRequestor,
+ lastClientSelection,
+ lastClientTarget,
+ success == SELECTION_SUCCESS ? lastClientProperty : None);
+ }
/*
* Enable further requests from clients.
*/
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
}
static void transferSelection(int resource)
@@ -1032,8 +1049,8 @@ static void transferSelection(int resource)
if (lastClientClientPtr -> index != resource)
{
#ifdef DEBUG
- fprintf (stderr, "%s: WARNING! Inconsistent resource [%d] with current client [%d].\n", __func__,
- resource, CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: WARNING! Inconsistent resource [%d] with current client %s.\n", __func__,
+ resource, nxagentClientInfoString(lastClientClientPtr));
#endif
endTransfer(SELECTION_FAULT);
@@ -1079,8 +1096,8 @@ static void transferSelection(int resource)
if (result == -1)
{
#ifdef DEBUG
- fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__,
- CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: Aborting selection notify procedure for client %s.\n", __func__,
+ nxagentClientInfoString(lastClientClientPtr));
#endif
endTransfer(SELECTION_FAULT);
@@ -1088,7 +1105,7 @@ static void transferSelection(int resource)
return;
}
- setClientSelectionStage(WaitSize);
+ setClientSelectionStage(SelectionStageWaitSize);
NXFlushDisplay(nxagentDisplay, NXFlushLink);
@@ -1133,8 +1150,8 @@ static void transferSelection(int resource)
if (result == -1)
{
#ifdef DEBUG
- fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__,
- CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: Aborting selection notify procedure for client %s.\n", __func__,
+ nxagentClientInfoString(lastClientClientPtr));
#endif
endTransfer(SELECTION_FAULT);
@@ -1142,7 +1159,7 @@ static void transferSelection(int resource)
return;
}
- setClientSelectionStage(WaitData);
+ setClientSelectionStage(SelectionStageWaitData);
/* we've seen situations where you had to move the mouse or press a
key to let the transfer complete. Flushing here fixed it */
@@ -1153,8 +1170,8 @@ static void transferSelection(int resource)
default:
{
#ifdef DEBUG
- fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__,
- getClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client %s.\n", __func__,
+ getClientSelectionStageString(lastClientStage), nxagentClientInfoString(lastClientClientPtr));
#endif
break;
@@ -1176,20 +1193,19 @@ void nxagentCollectPropertyEvent(int resource)
unsigned long ulReturnItems;
unsigned long ulReturnBytesLeft;
unsigned char *pszReturnData = NULL;
- int result;
/*
* We have received the notification so we can safely retrieve data
* from the client structure.
*/
- result = NXGetCollectedProperty(nxagentDisplay,
- resource,
- &atomReturnType,
- &resultFormat,
- &ulReturnItems,
- &ulReturnBytesLeft,
- &pszReturnData);
+ int result = NXGetCollectedProperty(nxagentDisplay,
+ resource,
+ &atomReturnType,
+ &resultFormat,
+ &ulReturnItems,
+ &ulReturnBytesLeft,
+ &pszReturnData);
nxagentLastClipboardClient = -1;
@@ -1217,14 +1233,13 @@ void nxagentCollectPropertyEvent(int resource)
{
printClientSelectionStage();
#ifdef DEBUG
- fprintf (stderr, "%s: Got size notify event for client [%d].\n", __func__,
- CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: Got size notify event for client %s.\n", __func__, nxagentClientInfoString(lastClientClientPtr));
#endif
if (ulReturnBytesLeft == 0)
{
#ifdef DEBUG
- fprintf (stderr, "%s: Aborting selection notify procedure.\n", __func__);
+ fprintf (stderr, "%s: data size is [0] - aborting selection notify procedure.\n", __func__);
#endif
endTransfer(SELECTION_FAULT);
@@ -1232,14 +1247,14 @@ void nxagentCollectPropertyEvent(int resource)
else
{
#ifdef DEBUG
- fprintf(stderr, "%s: Got property size from remote server.\n", __func__);
+ fprintf(stderr, "%s: Got property size [%lu] from remote server.\n", __func__, ulReturnBytesLeft);
#endif
/*
* Request the selection data now.
*/
lastClientPropertySize = ulReturnBytesLeft;
- setClientSelectionStage(QueryData);
+ setClientSelectionStage(SelectionStageQueryData);
transferSelection(resource);
}
@@ -1249,14 +1264,13 @@ void nxagentCollectPropertyEvent(int resource)
{
printClientSelectionStage();
#ifdef DEBUG
- fprintf (stderr, "%s: Got data notify event for client [%d].\n", __func__,
- CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: Got data notify event for waiting client %s.\n", __func__, nxagentClientInfoString(lastClientClientPtr));
#endif
if (ulReturnBytesLeft != 0)
{
#ifdef DEBUG
- fprintf (stderr, "%s: Aborting selection notify procedure.\n", __func__);
+ fprintf (stderr, "%s: not all content could be retrieved - [%lu] bytes left - aborting selection notify procedure.\n", __func__, ulReturnBytesLeft);
#endif
endTransfer(SELECTION_FAULT);
@@ -1264,7 +1278,7 @@ void nxagentCollectPropertyEvent(int resource)
else
{
#ifdef DEBUG
- fprintf(stderr, "%s: Got property content from remote server.\n", __func__);
+ fprintf(stderr, "%s: Got property content from remote server. size [%lu] bytes.\n", __func__, (ulReturnItems * resultFormat / 8));
#endif
ChangeWindowProperty(lastClientWindowPtr,
@@ -1288,8 +1302,8 @@ void nxagentCollectPropertyEvent(int resource)
default:
{
#ifdef DEBUG
- fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__,
- getClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr));
+ fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client %s.\n", __func__,
+ getClientSelectionStageString(lastClientStage), nxagentClientInfoString(lastClientClientPtr));
#endif
break;
}
@@ -1343,8 +1357,8 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
X->xselection.property == serverTransToAgentProperty)
{
#ifdef DEBUG
- fprintf(stderr, "%s: Starting selection transferral for client [%d].\n", __func__,
- CLINDEX(lastClientClientPtr));
+ fprintf(stderr, "%s: Starting selection transferral for client %s.\n", __func__,
+ nxagentClientInfoString(lastClientClientPtr));
#endif
/*
@@ -1358,7 +1372,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
* tions.
*/
- setClientSelectionStage(QueryData);
+ setClientSelectionStage(SelectionStageQueryData);
lastClientPropertySize = 262144;
transferSelection(lastClientClientPtr -> index);
@@ -1529,8 +1543,7 @@ static void resetSelectionOwner(void)
clearSelectionOwner(i);
}
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
/* Hmm, this is already None when reaching this */
lastServerRequestor = None;
@@ -1649,9 +1662,9 @@ static void setSelectionOwner(Selection *pSelection)
if (i < NumCurrentSelections)
{
#ifdef DEBUG
- fprintf(stderr, "%s: lastSelectionOwner.client [%p] index [%d] -> [%p] index [%d]\n", __func__,
- (void *)lastSelectionOwner[i].client, CLINDEX(lastSelectionOwner[i].client),
- (void *)pSelection->client, CLINDEX(pSelection->client));
+ fprintf(stderr, "%s: lastSelectionOwner.client %s -> %s\n", __func__,
+ nxagentClientInfoString(lastSelectionOwner[i].client),
+ nxagentClientInfoString(pSelection->client));
fprintf(stderr, "%s: lastSelectionOwner.window [0x%x] -> [0x%x]\n", __func__,
lastSelectionOwner[i].window, pSelection->window);
fprintf(stderr, "%s: lastSelectionOwner.windowPtr [%p] -> [%p] [0x%x] (serverWindow: [0x%x])\n", __func__,
@@ -1676,8 +1689,7 @@ static void setSelectionOwner(Selection *pSelection)
storeSelectionOwner(i, pSelection);
}
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
lastServerRequestor = None;
@@ -1693,8 +1705,7 @@ FIXME
lastSelectionOwnerWindow = pSelection->window;
lastSelectionOwnerWindowPtr = pSelection->pWin;
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
lastServerRequestor = None;
}
@@ -1702,24 +1713,6 @@ FIXME
*/
}
-static void notifyConvertFailure(ClientPtr client, Window requestor,
- Atom selection, Atom target, Time time)
-{
- /*
- * Check if the client is still valid.
- */
- if (clients[client -> index] != client)
- {
- #ifdef WARNING
- fprintf(stderr, "%s: WARNING! Invalid client pointer.", __func__);
- #endif
-
- return;
- }
-
- sendSelectionNotifyEventToClient(client, time, requestor, selection, target, None);
-}
-
/*
* This is called from dix (ProcConvertSelection) if an nxagent client
* issues a ConvertSelection request. So all the Atoms are internal
@@ -1773,14 +1766,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
{
#ifdef DEBUG
fprintf(stderr, "%s: timeout expired on last request, "
- "notifying failure to client\n", __func__);
+ "notifying failure to client %s\n", __func__, nxagentClientInfoString(client));
#endif
- notifyConvertFailure(lastClientClientPtr, lastClientRequestor,
- lastClientSelection, lastClientTarget, lastClientTime);
-
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ endTransfer(SELECTION_FAULT);
}
else
{
@@ -1791,19 +1780,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
*/
#ifdef DEBUG
fprintf(stderr, "%s: got request "
- "before timeout expired on last request, notifying failure to client\n", __func__);
+ "before timeout expired on last request, notifying failure to client %s\n",
+ __func__, nxagentClientInfoString(client));
#endif
- notifyConvertFailure(client, requestor, selection, target, time);
+ sendSelectionNotifyEventToClient(client, time, requestor, selection, target, None);
return 1;
}
}
#ifdef DEBUG
- fprintf(stderr, "%s: client [%d] requests sel [%s] "
+ fprintf(stderr, "%s: client %s requests sel [%s] "
"on window [%x] prop [%d][%s] target [%d][%s].\n", __func__,
- CLINDEX(client), validateString(NameForAtom(selection)), requestor,
+ nxagentClientInfoString(client), validateString(NameForAtom(selection)), requestor,
property, validateString(NameForAtom(property)),
target, validateString(NameForAtom(target)));
#endif
@@ -1887,7 +1877,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
}
}
- #ifdef DEBUG
if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < ACCUM_TIME))
{
/*
@@ -1897,9 +1886,11 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
* client requesting PRIMARY and CLIPBOARD would match here, too
*/
- fprintf(stderr, "%s: Consecutives request from client [%p] selection [%u] "
- "elapsed time [%u] clientAccum [%d]\n", __func__, (void *) client, selection,
- GetTimeInMillis() - lastClientReqTime, clientAccum);
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Consecutives request from client %s selection [%u] "
+ "elapsed time [%u] clientAccum [%d]\n", __func__, nxagentClientInfoString(client),
+ selection, GetTimeInMillis() - lastClientReqTime, clientAccum);
+ #endif
clientAccum++;
}
@@ -1911,20 +1902,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
clientAccum = 0;
}
}
- #endif
if (target == clientTEXT ||
target == XA_STRING ||
target == clientCOMPOUND_TEXT ||
target == clientUTF8_STRING)
{
- lastClientWindowPtr = pWin;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
+
/*
* store the original requestor, we need that later after
* serverTransToAgentProperty contains the desired selection content
*/
lastClientRequestor = requestor;
+ lastClientWindowPtr = pWin;
lastClientClientPtr = client;
lastClientTime = time;
lastClientProperty = property;
@@ -1944,31 +1935,32 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
* we only convert to either UTF8 or XA_STRING, despite accepting
* TEXT and COMPOUND_TEXT.
*/
+ XlibAtom p = serverTransToAgentProperty;
+ XlibAtom t;
+ char * pstr = "NX_CUT_BUFFER_SERVER";
+ const char * tstr;
if (target == clientUTF8_STRING)
{
- #ifdef DEBUG
- fprintf(stderr, "%s: Sending XConvertSelection with target [%ld][%s], property [%ld][%s]\n", __func__,
- serverUTF8_STRING, szAgentUTF8_STRING, serverTransToAgentProperty, "NX_CUT_BUFFER_SERVER");
- #endif
- XConvertSelection(nxagentDisplay, selection, serverUTF8_STRING, serverTransToAgentProperty,
- serverWindow, CurrentTime);
+ t = serverUTF8_STRING;
+ tstr = szAgentUTF8_STRING;
}
else
{
- #ifdef DEBUG
- fprintf(stderr, "%s: Sending XConvertSelection with target [%d][%s], property [%ld][%s]\n", __func__,
- XA_STRING, validateString(NameForAtom(XA_STRING)), serverTransToAgentProperty, "NX_CUT_BUFFER_SERVER");
- #endif
-
- XConvertSelection(nxagentDisplay, selection, XA_STRING, serverTransToAgentProperty,
- serverWindow, CurrentTime);
+ t = XA_STRING;
+ tstr = validateString(NameForAtom(XA_STRING));
}
+ #ifdef DEBUG
+ fprintf(stderr, "%s: Sending XConvertSelection to real X server: requestor [0x%x] target [%ld][%s] property [%ld][%s] time [%ld]\n", __func__,
+ serverWindow, t, tstr, p, pstr, CurrentTime);
+ #endif
+
+ XConvertSelection(nxagentDisplay, selection, t, p, serverWindow, CurrentTime);
+
/* FIXME: check returncode of XConvertSelection */
#ifdef DEBUG
- fprintf(stderr, "%s: Sent XConvertSelection with target [%s], property [%s]\n", __func__,
- validateString(NameForAtom(target)), validateString(NameForAtom(property)));
+ fprintf(stderr, "%s: Sent XConvertSelection with target [%s], property [%s]\n", __func__, tstr, pstr);
#endif
return 1;
@@ -2289,8 +2281,7 @@ Bool nxagentInitClipboard(WindowPtr pWin)
lastServerRequestor = None;
- lastClientWindowPtr = NULL;
- setClientSelectionStage(None);
+ setClientSelectionStage(SelectionStageNone);
lastClientReqTime = GetTimeInMillis();
clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index b741ef286..4817a03e2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -78,4 +78,6 @@ extern WindowPtr nxagentGetClipboardWindow(Atom property);
extern int nxagentSendNotify(xEvent *event);
+extern void nxagentDumpClipboardStat(void);
+
#endif /* __Clipboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 83091eff4..346ee48d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1070,6 +1070,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
nxagentToggleAutoGrab();
break;
}
+ case doDumpClipboard:
+ {
+ nxagentDumpClipboardStat();
+ break;
+ }
default:
{
FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n");
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index a33a1abb1..fc00ba1d0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -52,6 +52,7 @@ enum HandleEventResult
doSwitchResizeMode,
doSwitchDeferMode,
doAutoGrab,
+ doDumpClipboard
};
extern CARD32 nxagentLastEventTime;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index 73a5901f8..d6c659fec 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -102,6 +102,8 @@ char * nxagentSpecialKeystrokeNames[] = {
"autograb",
+ "dump_clipboard",
+
NULL,
};
@@ -142,6 +144,7 @@ struct nxagentSpecialKeystrokeMap default_map[] = {
{KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down},
{KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
{KEYSTROKE_AUTOGRAB, ControlMask, True, XK_g},
+ {KEYSTROKE_DUMP_CLIPBOARD, ControlMask | ShiftMask, True, XK_c},
{KEYSTROKE_END_MARKER, 0, False, NoSymbol},
};
struct nxagentSpecialKeystrokeMap *map = default_map;
@@ -715,6 +718,9 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
case KEYSTROKE_AUTOGRAB:
*result = doAutoGrab;
break;
+ case KEYSTROKE_DUMP_CLIPBOARD:
+ *result = doDumpClipboard;
+ break;
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
case KEYSTROKE_MAX:
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index 463bda9b3..a5a6fbcf1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -78,10 +78,12 @@ enum nxagentSpecialKeystroke {
KEYSTROKE_AUTOGRAB,
- KEYSTROKE_NOTHING,
+ KEYSTROKE_DUMP_CLIPBOARD,
/* insert more here and in the string translation */
+ KEYSTROKE_NOTHING,
+
KEYSTROKE_MAX,
};
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index 8f806093e..f91dc248d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -127,6 +127,7 @@ Equipment Corporation.
#include "Handlers.h"
#include "Keyboard.h"
#include "Init.h"
+#include "Utils.h"
const int nxagentMaxFontNames = 10000;
@@ -584,6 +585,8 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio
nxagentFreeFontData();
#endif /* NXAGENT_SERVER */
+ nxagentFreeAtomMap();
+
KillAllClients();
free(clientReady);
dispatchException &= ~DE_RESET;
@@ -988,6 +991,10 @@ ProcFreePixmap(register ClientPtr client)
void
CloseDownClient(register ClientPtr client)
{
+ #ifdef DEBUG
+ fprintf(stderr, "%s: [%d]\n", __func__, client->clientState);
+ #endif
+
#ifdef NXAGENT_SERVER
/*
* Need to reset the karma counter and get rid of the pending sync
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index 4b4232c4b..ff50c9965 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -155,9 +155,13 @@ extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
extern int nxagentShadowInit(ScreenPtr, WindowPtr);
void
-ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
TimeStamp time, Bool autoGrab)
{
+ #ifdef DEBUG
+ fprintf(stderr, "%s: called\n", __func__);
+ #endif
+
xorg_ActivatePointerGrab(mouse, grab, time, autoGrab);
#ifdef NXAGENT_SERVER
@@ -166,7 +170,7 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
* If grab is synchronous, events are delivered to clients only if they send
* an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the
* delivered event is saved in a queue and replayed later, when grab is released.
- * We should export sync grab to X as async in order to avoid events to be
+ * We should export sync grab to X as async in order to avoid events to be
* queued twice, in the agent and in the X server. This solution have a drawback:
* replayed events are not delivered to that application that are not clients of
* the agent.
@@ -217,6 +221,10 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
void
DeactivatePointerGrab(register DeviceIntPtr mouse)
{
+ #ifdef DEBUG
+ fprintf(stderr, "%s: called\n", __func__);
+ #endif
+
xorg_DeactivatePointerGrab(mouse);
#ifdef NXAGENT_SERVER