Unverified Commit 3f7bb584 authored by Mike Gabriel's avatar Mike Gabriel

Merge branch 'uli42-pr/clipboard_dump' into 3.6.x

parents 4904bfe1 49d63d92
...@@ -129,6 +129,10 @@ reread_keystrokes ...@@ -129,6 +129,10 @@ reread_keystrokes
autograb autograb
Toggles autograb mode Toggles autograb mode
dump_clipboard
print the current internal clipboard state (for debugging) to the
log.
force_synchronization force_synchronization
Forces immediate drawing of elements to be synchronized which can Forces immediate drawing of elements to be synchronized which can
fix some visual bugs. fix some visual bugs.
...@@ -25,4 +25,5 @@ ...@@ -25,4 +25,5 @@
<keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="KP_Down" /> <keystroke action="viewport_scroll_down" Control="1" AltMeta="1" key="KP_Down" />
<keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" /> <keystroke action="reread_keystrokes" Control="1" AltMeta="1" key="k" />
<keystroke action="autograb" Control="1" AltMeta="1" key="g" /> <keystroke action="autograb" Control="1" AltMeta="1" key="g" />
<keystroke action="dump_clipboard" Control="1" Shift="1" AltMeta="1" key="c" />
</keystrokes> </keystrokes>
...@@ -75,8 +75,8 @@ extern void nxagentClientStateCallback(CallbackListPtr *callbacks, void *data, v ...@@ -75,8 +75,8 @@ extern void nxagentClientStateCallback(CallbackListPtr *callbacks, void *data, v
#define nxagentClientIsDialog(pClient) \ #define nxagentClientIsDialog(pClient) \
(nxagentClientHint(pClient) == NXCLIENT_DIALOG) (nxagentClientHint(pClient) == NXCLIENT_DIALOG)
#define nxagentClientInfoString(pClient) \ #define nxagentClientInfoString(pClient) \
(nxagentClientPriv(pClient) -> clientInfoString) ((pClient) ? nxagentClientPriv(pClient) -> clientInfoString : NULL)
/* /*
* The actual reason why the client is sleeping. * The actual reason why the client is sleeping.
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "Rootless.h" #include "Rootless.h"
#include "Clipboard.h" #include "Clipboard.h"
#include "Utils.h" #include "Utils.h"
#include "Client.h"
#include "gcstruct.h" #include "gcstruct.h"
#include "xfixeswire.h" #include "xfixeswire.h"
...@@ -68,9 +69,7 @@ extern Selection *CurrentSelections; ...@@ -68,9 +69,7 @@ extern Selection *CurrentSelections;
int nxagentLastClipboardClient = -1; int nxagentLastClipboardClient = -1;
static int agentClipboardInitialized = False; static int agentClipboardInitialized = False;
#ifdef DEBUG
static int clientAccum; static int clientAccum;
#endif
XlibAtom serverTransToAgentProperty; XlibAtom serverTransToAgentProperty;
Atom clientCutProperty; Atom clientCutProperty;
...@@ -156,19 +155,16 @@ static char szAgentCLIPBOARD[] = "CLIPBOARD"; ...@@ -156,19 +155,16 @@ static char szAgentCLIPBOARD[] = "CLIPBOARD";
/* number of milliseconds to wait for a conversion from the real X server. */ /* number of milliseconds to wait for a conversion from the real X server. */
#define CONVERSION_TIMEOUT 5000 #define CONVERSION_TIMEOUT 5000
#ifdef DEBUG
/* /*
* Time window (milliseconds) within to detect multiple conversion * Time window (milliseconds) within to detect multiple conversion
* calls of the same client. * calls of the same client.
*/ */
#define ACCUM_TIME 5000 #define ACCUM_TIME 5000
#endif
/* /*
* some helpers for debugging output * some helpers for debugging output
*/ */
#ifdef DEBUG
static const char * getClientSelectionStageString(int stage) static const char * getClientSelectionStageString(int stage)
{ {
switch(stage) switch(stage)
...@@ -181,15 +177,16 @@ static const char * getClientSelectionStageString(int stage) ...@@ -181,15 +177,16 @@ static const char * getClientSelectionStageString(int stage)
default: return("UNKNOWN!"); break;; 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 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 #else
#define setClientSelectionStage(stage) do {lastClientStage = SelectionStage##stage;} while (0)
#define printClientSelectionStage() #define printClientSelectionStage()
#endif #endif
#define WINDOWID(ptr) (ptr) ? (ptr->drawable.id) : 0
#define CLINDEX(clientptr) (clientptr) ? (clientptr->index) : -1
#ifdef DEBUG #ifdef DEBUG
/* /*
* see also nx-X11/lib/src/ErrDes.c * see also nx-X11/lib/src/ErrDes.c
...@@ -233,6 +230,7 @@ XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, 0 }; ...@@ -233,6 +230,7 @@ XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, 0 };
extern Display *nxagentDisplay; extern Display *nxagentDisplay;
static Bool validServerTargets(XlibAtom target); static Bool validServerTargets(XlibAtom target);
static void setClientSelectionStage(int stage);
static void endTransfer(Bool success); static void endTransfer(Bool success);
#define SELECTION_SUCCESS True #define SELECTION_SUCCESS True
#define SELECTION_FAULT False #define SELECTION_FAULT False
...@@ -244,17 +242,14 @@ static void initSelectionOwner(int index, Atom selection); ...@@ -244,17 +242,14 @@ static void initSelectionOwner(int index, Atom selection);
static void clearSelectionOwner(int index); static void clearSelectionOwner(int index);
static void storeSelectionOwner(int index, Selection *sel); static void storeSelectionOwner(int index, Selection *sel);
static Bool matchSelectionOwner(int index, ClientPtr pClient, WindowPtr pWindow); 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 void setSelectionOwner(Selection *pSelection);
static int sendEventToClient(ClientPtr client, xEvent *pEvents); static int sendEventToClient(ClientPtr client, xEvent *pEvents);
static int sendSelectionNotifyEventToClient(ClientPtr client, static void sendSelectionNotifyEventToClient(ClientPtr client,
Time time, Time time,
Window requestor, Window requestor,
Atom selection, Atom selection,
Atom target, Atom target,
Atom property); Atom property);
static Status sendSelectionNotifyEventToServer(XSelectionEvent *event_to_send); static Status sendSelectionNotifyEventToServer(XSelectionEvent *event_to_send);
#ifdef DEBUG #ifdef DEBUG
static void printSelectionStat(int sel); static void printSelectionStat(int sel);
...@@ -267,7 +262,6 @@ void nxagentPrintClipboardStat(char *); ...@@ -267,7 +262,6 @@ void nxagentPrintClipboardStat(char *);
extern unsigned long startTime; extern unsigned long startTime;
#endif #endif
#ifdef DEBUG
static void printSelectionStat(int sel) static void printSelectionStat(int sel)
{ {
SelectionOwner lOwner = lastSelectionOwner[sel]; SelectionOwner lOwner = lastSelectionOwner[sel];
...@@ -275,17 +269,7 @@ static void printSelectionStat(int sel) ...@@ -275,17 +269,7 @@ static void printSelectionStat(int sel)
char *s = NULL; char *s = NULL;
fprintf(stderr, " owner is inside nxagent? %s\n", IS_INTERNAL_OWNER(sel) ? "yes" : "no"); fprintf(stderr, " owner is inside nxagent? %s\n", IS_INTERNAL_OWNER(sel) ? "yes" : "no");
#ifdef CLIENTIDS fprintf(stderr, " lastSelectionOwner[].client %s\n", nxagentClientInfoString(lOwner.client));
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[].window [0x%x]\n", lOwner.window); fprintf(stderr, " lastSelectionOwner[].window [0x%x]\n", lOwner.window);
if (lOwner.windowPtr) if (lOwner.windowPtr)
fprintf(stderr, " lastSelectionOwner[].windowPtr [%p] ([0x%x]\n", (void *)lOwner.windowPtr, WINDOWID(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) ...@@ -313,14 +297,12 @@ static void printSelectionStat(int sel)
fprintf(stderr, " CurrentSelections[].window [0x%x]\n", curSel.window); fprintf(stderr, " CurrentSelections[].window [0x%x]\n", curSel.window);
return; return;
} }
#endif
void nxagentPrintClipboardStat(char *header) void nxagentDumpClipboardStat(void)
{ {
#ifdef DEBUG
char *s = NULL; 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, " current time (Time) [%u]\n", GetTimeInMillis());
fprintf(stderr, " agentClipboardInitialized (Bool) [%s]\n", agentClipboardInitialized ? "True" : "False"); fprintf(stderr, " agentClipboardInitialized (Bool) [%s]\n", agentClipboardInitialized ? "True" : "False");
...@@ -354,13 +336,19 @@ void nxagentPrintClipboardStat(char *header) ...@@ -354,13 +336,19 @@ void nxagentPrintClipboardStat(char *header)
fprintf(stderr, " lastClientWindowPtr (WindowPtr) [%p] ([0x%x])\n", (void *)lastClientWindowPtr, WINDOWID(lastClientWindowPtr)); fprintf(stderr, " lastClientWindowPtr (WindowPtr) [%p] ([0x%x])\n", (void *)lastClientWindowPtr, WINDOWID(lastClientWindowPtr));
else else
fprintf(stderr, " lastClientWindowPtr (WindowPtr) -\n"); 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, " lastClientRequestor (Window) [0x%x]\n", lastClientRequestor);
fprintf(stderr, " lastClientProperty (Atom) [% 4d][%s]\n", lastClientProperty, NameForAtom(lastClientProperty)); fprintf(stderr, " lastClientProperty (Atom) [% 4d][%s]\n", lastClientProperty, NameForAtom(lastClientProperty));
fprintf(stderr, " lastClientSelection (Atom) [% 4d][%s]\n", lastClientSelection, NameForAtom(lastClientSelection)); fprintf(stderr, " lastClientSelection (Atom) [% 4d][%s]\n", lastClientSelection, NameForAtom(lastClientSelection));
fprintf(stderr, " lastClientTarget (Atom) [% 4d][%s]\n", lastClientTarget, NameForAtom(lastClientTarget)); fprintf(stderr, " lastClientTarget (Atom) [% 4d][%s]\n", lastClientTarget, NameForAtom(lastClientTarget));
fprintf(stderr, " lastClientTime (Time) [%u]\n", lastClientTime); if (lastClientTime > 0)
fprintf(stderr, " lastClientReqTime (Time) [%u]\n", lastClientReqTime); 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, " lastClientPropertySize (unsigned long) [%lu]\n", lastClientPropertySize);
fprintf(stderr, " lastClientStage (ClientSelectionStage) [%d][%s]\n", lastClientStage, getClientSelectionStageString(lastClientStage)); fprintf(stderr, " lastClientStage (ClientSelectionStage) [%d][%s]\n", lastClientStage, getClientSelectionStageString(lastClientStage));
...@@ -399,7 +387,31 @@ void nxagentPrintClipboardStat(char *header) ...@@ -399,7 +387,31 @@ void nxagentPrintClipboardStat(char *header)
fprintf(stderr, "\\------------------------------------------------------------------------------\n"); fprintf(stderr, "\\------------------------------------------------------------------------------\n");
SAFE_XFree(s); 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) ...@@ -458,13 +470,25 @@ static int sendEventToClient(ClientPtr client, xEvent *pEvents)
return TryClientEvents(client, pEvents, 1, NoEventMask, NoEventMask, NullGrab); return TryClientEvents(client, pEvents, 1, NoEventMask, NoEventMask, NullGrab);
} }
static int sendSelectionNotifyEventToClient(ClientPtr client, static void sendSelectionNotifyEventToClient(ClientPtr client,
Time time, Time time,
Window requestor, Window requestor,
Atom selection, Atom selection,
Atom target, Atom target,
Atom property) 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}; xEvent x = {0};
x.u.u.type = SelectionNotify; x.u.u.type = SelectionNotify;
x.u.selectionNotify.time = time; x.u.selectionNotify.time = time;
...@@ -475,14 +499,14 @@ static int sendSelectionNotifyEventToClient(ClientPtr client, ...@@ -475,14 +499,14 @@ static int sendSelectionNotifyEventToClient(ClientPtr client,
#ifdef DEBUG #ifdef DEBUG
if (property == None) if (property == None)
fprintf (stderr, "%s: Denying request to client [%d].\n", __func__, fprintf(stderr, "%s: Denying request to client %s.\n", __func__,
CLINDEX(client)); nxagentClientInfoString(client));
else else
fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, fprintf(stderr, "%s: Sending event to client %s.\n", __func__,
CLINDEX(client)); nxagentClientInfoString(client));
#endif #endif
return sendEventToClient(client, &x); sendEventToClient(client, &x);
} }
/* /*
...@@ -574,6 +598,12 @@ static Bool matchSelectionOwner(int index, ClientPtr pClient, WindowPtr pWindow) ...@@ -574,6 +598,12 @@ static Bool matchSelectionOwner(int index, ClientPtr pClient, WindowPtr pWindow)
(pWindow && lastSelectionOwner[index].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) void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
{ {
#ifdef DEBUG #ifdef DEBUG
...@@ -581,8 +611,6 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) ...@@ -581,8 +611,6 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
(void *) pClient, CLINDEX(pClient), (void *) pWindow, WINDOWID(pWindow)); (void *) pClient, CLINDEX(pClient), (void *) pWindow, WINDOWID(pWindow));
#endif #endif
nxagentPrintClipboardStat("before nxagentClearClipboard");
/* /*
* Only for PRIMARY and CLIPBOARD selections. * Only for PRIMARY and CLIPBOARD selections.
*/ */
...@@ -598,8 +626,7 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) ...@@ -598,8 +626,7 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
clearSelectionOwner(i); clearSelectionOwner(i);
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
lastServerRequestor = None; lastServerRequestor = None;
} }
...@@ -607,11 +634,8 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) ...@@ -607,11 +634,8 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
if (pWindow && pWindow == lastClientWindowPtr) if (pWindow && pWindow == lastClientWindowPtr)
{ {
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
} }
nxagentPrintClipboardStat("after nxagentClearClipboard");
} }
/* /*
...@@ -655,8 +679,6 @@ void nxagentHandleSelectionClearFromXServer(XEvent *X) ...@@ -655,8 +679,6 @@ void nxagentHandleSelectionClearFromXServer(XEvent *X)
fprintf(stderr, "%s: SelectionClear event for selection [%lu].\n", __func__, X->xselectionclear.selection); fprintf(stderr, "%s: SelectionClear event for selection [%lu].\n", __func__, X->xselectionclear.selection);
#endif #endif
nxagentPrintClipboardStat("before nxagentHandleSelectionClearFromXServer");
if (!agentClipboardInitialized) if (!agentClipboardInitialized)
{ {
#ifdef DEBUG #ifdef DEBUG
...@@ -699,9 +721,7 @@ void nxagentHandleSelectionClearFromXServer(XEvent *X) ...@@ -699,9 +721,7 @@ void nxagentHandleSelectionClearFromXServer(XEvent *X)
clearSelectionOwner(i); clearSelectionOwner(i);
} }
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
nxagentPrintClipboardStat("after nxagentHandleSelectionClearFromXServer");
} }
/* /*
...@@ -760,8 +780,6 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X) ...@@ -760,8 +780,6 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
} }
#endif #endif
nxagentPrintClipboardStat("before nxagentHandleSelectionRequestFromXServer");
if (!agentClipboardInitialized) if (!agentClipboardInitialized)
{ {
#ifdef DEBUG #ifdef DEBUG
...@@ -969,9 +987,9 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X) ...@@ -969,9 +987,9 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
sendEventToClient(lastSelectionOwner[i].client, &x); sendEventToClient(lastSelectionOwner[i].client, &x);
#ifdef DEBUG #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__, "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.property, NameForAtom(x.u.selectionRequest.property),
x.u.selectionRequest.target, NameForAtom(x.u.selectionRequest.target), x.u.selectionRequest.target, NameForAtom(x.u.selectionRequest.target),
x.u.selectionRequest.requestor); x.u.selectionRequest.requestor);
...@@ -984,7 +1002,6 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X) ...@@ -984,7 +1002,6 @@ void nxagentHandleSelectionRequestFromXServer(XEvent *X)
} }
} }
} }
nxagentPrintClipboardStat("after nxagentHandleSelectionRequestFromXServer");
} }
/* /*
...@@ -1001,30 +1018,30 @@ static void endTransfer(Bool success) ...@@ -1001,30 +1018,30 @@ static void endTransfer(Bool success)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: lastClientClientPtr is NULL - doing nothing.\n", __func__); fprintf(stderr, "%s: lastClientClientPtr is NULL - doing nothing.\n", __func__);
#endif #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 else
fprintf(stderr, "%s: sending negative notification to client [%d]\n", __func__, {
CLINDEX(lastClientClientPtr)); #ifdef DEBUG
#endif 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, sendSelectionNotifyEventToClient(lastClientClientPtr,
lastClientTime, lastClientTime,
lastClientRequestor, lastClientRequestor,
lastClientSelection, lastClientSelection,
lastClientTarget, lastClientTarget,
success == SELECTION_SUCCESS ? lastClientProperty : None); success == SELECTION_SUCCESS ? lastClientProperty : None);
}
/* /*
* Enable further requests from clients. * Enable further requests from clients.
*/ */
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
} }
static void transferSelection(int resource) static void transferSelection(int resource)
...@@ -1032,8 +1049,8 @@ static void transferSelection(int resource) ...@@ -1032,8 +1049,8 @@ static void transferSelection(int resource)
if (lastClientClientPtr -> index != resource) if (lastClientClientPtr -> index != resource)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: WARNING! Inconsistent resource [%d] with current client [%d].\n", __func__, fprintf (stderr, "%s: WARNING! Inconsistent resource [%d] with current client %s.\n", __func__,
resource, CLINDEX(lastClientClientPtr)); resource, nxagentClientInfoString(lastClientClientPtr));
#endif #endif
endTransfer(SELECTION_FAULT); endTransfer(SELECTION_FAULT);
...@@ -1079,8 +1096,8 @@ static void transferSelection(int resource) ...@@ -1079,8 +1096,8 @@ static void transferSelection(int resource)
if (result == -1) if (result == -1)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, fprintf (stderr, "%s: Aborting selection notify procedure for client %s.\n", __func__,
CLINDEX(lastClientClientPtr)); nxagentClientInfoString(lastClientClientPtr));
#endif #endif
endTransfer(SELECTION_FAULT); endTransfer(SELECTION_FAULT);
...@@ -1088,7 +1105,7 @@ static void transferSelection(int resource) ...@@ -1088,7 +1105,7 @@ static void transferSelection(int resource)
return; return;
} }
setClientSelectionStage(WaitSize); setClientSelectionStage(SelectionStageWaitSize);
NXFlushDisplay(nxagentDisplay, NXFlushLink); NXFlushDisplay(nxagentDisplay, NXFlushLink);
...@@ -1133,8 +1150,8 @@ static void transferSelection(int resource) ...@@ -1133,8 +1150,8 @@ static void transferSelection(int resource)
if (result == -1) if (result == -1)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, fprintf (stderr, "%s: Aborting selection notify procedure for client %s.\n", __func__,
CLINDEX(lastClientClientPtr)); nxagentClientInfoString(lastClientClientPtr));
#endif #endif
endTransfer(SELECTION_FAULT); endTransfer(SELECTION_FAULT);
...@@ -1142,7 +1159,7 @@ static void transferSelection(int resource) ...@@ -1142,7 +1159,7 @@ static void transferSelection(int resource)
return; return;
} }
setClientSelectionStage(WaitData); setClientSelectionStage(SelectionStageWaitData);
/* we've seen situations where you had to move the mouse or press a /* we've seen situations where you had to move the mouse or press a
key to let the transfer complete. Flushing here fixed it */ key to let the transfer complete. Flushing here fixed it */
...@@ -1153,8 +1170,8 @@ static void transferSelection(int resource) ...@@ -1153,8 +1170,8 @@ static void transferSelection(int resource)
default: default:
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__, fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client %s.\n", __func__,
getClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr)); getClientSelectionStageString(lastClientStage), nxagentClientInfoString(lastClientClientPtr));
#endif #endif
break; break;
...@@ -1176,20 +1193,19 @@ void nxagentCollectPropertyEvent(int resource) ...@@ -1176,20 +1193,19 @@ void nxagentCollectPropertyEvent(int resource)
unsigned long ulReturnItems; unsigned long ulReturnItems;
unsigned long ulReturnBytesLeft; unsigned long ulReturnBytesLeft;
unsigned char *pszReturnData = NULL; unsigned char *pszReturnData = NULL;
int result;
/* /*
* We have received the notification so we can safely retrieve data * We have received the notification so we can safely retrieve data
* from the client structure. * from the client structure.
*/ */
result = NXGetCollectedProperty(nxagentDisplay, int result = NXGetCollectedProperty(nxagentDisplay,
resource, resource,
&atomReturnType, &atomReturnType,
&resultFormat, &resultFormat,
&ulReturnItems, &ulReturnItems,
&ulReturnBytesLeft, &ulReturnBytesLeft,
&pszReturnData); &pszReturnData);
nxagentLastClipboardClient = -1; nxagentLastClipboardClient = -1;
...@@ -1217,14 +1233,13 @@ void nxagentCollectPropertyEvent(int resource) ...@@ -1217,14 +1233,13 @@ void nxagentCollectPropertyEvent(int resource)
{ {
printClientSelectionStage(); printClientSelectionStage();
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: Got size notify event for client [%d].\n", __func__, fprintf (stderr, "%s: Got size notify event for client %s.\n", __func__, nxagentClientInfoString(lastClientClientPtr));
CLINDEX(lastClientClientPtr));
#endif #endif
if (ulReturnBytesLeft == 0) if (ulReturnBytesLeft == 0)
{ {
#ifdef DEBUG #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 #endif
endTransfer(SELECTION_FAULT); endTransfer(SELECTION_FAULT);
...@@ -1232,14 +1247,14 @@ void nxagentCollectPropertyEvent(int resource) ...@@ -1232,14 +1247,14 @@ void nxagentCollectPropertyEvent(int resource)
else else
{ {
#ifdef DEBUG #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 #endif
/* /*
* Request the selection data now. * Request the selection data now.
*/ */
lastClientPropertySize = ulReturnBytesLeft; lastClientPropertySize = ulReturnBytesLeft;
setClientSelectionStage(QueryData); setClientSelectionStage(SelectionStageQueryData);
transferSelection(resource); transferSelection(resource);
} }
...@@ -1249,14 +1264,13 @@ void nxagentCollectPropertyEvent(int resource) ...@@ -1249,14 +1264,13 @@ void nxagentCollectPropertyEvent(int resource)
{ {
printClientSelectionStage(); printClientSelectionStage();
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: Got data notify event for client [%d].\n", __func__, fprintf (stderr, "%s: Got data notify event for waiting client %s.\n", __func__, nxagentClientInfoString(lastClientClientPtr));
CLINDEX(lastClientClientPtr));
#endif #endif
if (ulReturnBytesLeft != 0) if (ulReturnBytesLeft != 0)
{ {
#ifdef DEBUG #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 #endif
endTransfer(SELECTION_FAULT); endTransfer(SELECTION_FAULT);
...@@ -1264,7 +1278,7 @@ void nxagentCollectPropertyEvent(int resource) ...@@ -1264,7 +1278,7 @@ void nxagentCollectPropertyEvent(int resource)
else else
{ {
#ifdef DEBUG #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 #endif
ChangeWindowProperty(lastClientWindowPtr, ChangeWindowProperty(lastClientWindowPtr,
...@@ -1288,8 +1302,8 @@ void nxagentCollectPropertyEvent(int resource) ...@@ -1288,8 +1302,8 @@ void nxagentCollectPropertyEvent(int resource)
default: default:
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__, fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client %s.\n", __func__,
getClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr)); getClientSelectionStageString(lastClientStage), nxagentClientInfoString(lastClientClientPtr));
#endif #endif
break; break;
} }
...@@ -1343,8 +1357,8 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X) ...@@ -1343,8 +1357,8 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
X->xselection.property == serverTransToAgentProperty) X->xselection.property == serverTransToAgentProperty)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: Starting selection transferral for client [%d].\n", __func__, fprintf(stderr, "%s: Starting selection transferral for client %s.\n", __func__,
CLINDEX(lastClientClientPtr)); nxagentClientInfoString(lastClientClientPtr));
#endif #endif
/* /*
...@@ -1358,7 +1372,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X) ...@@ -1358,7 +1372,7 @@ void nxagentHandleSelectionNotifyFromXServer(XEvent *X)
* tions. * tions.
*/ */
setClientSelectionStage(QueryData); setClientSelectionStage(SelectionStageQueryData);
lastClientPropertySize = 262144; lastClientPropertySize = 262144;
transferSelection(lastClientClientPtr -> index); transferSelection(lastClientClientPtr -> index);
...@@ -1529,8 +1543,7 @@ static void resetSelectionOwner(void) ...@@ -1529,8 +1543,7 @@ static void resetSelectionOwner(void)
clearSelectionOwner(i); clearSelectionOwner(i);
} }
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
/* Hmm, this is already None when reaching this */ /* Hmm, this is already None when reaching this */
lastServerRequestor = None; lastServerRequestor = None;
...@@ -1649,9 +1662,9 @@ static void setSelectionOwner(Selection *pSelection) ...@@ -1649,9 +1662,9 @@ static void setSelectionOwner(Selection *pSelection)
if (i < NumCurrentSelections) if (i < NumCurrentSelections)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: lastSelectionOwner.client [%p] index [%d] -> [%p] index [%d]\n", __func__, fprintf(stderr, "%s: lastSelectionOwner.client %s -> %s\n", __func__,
(void *)lastSelectionOwner[i].client, CLINDEX(lastSelectionOwner[i].client), nxagentClientInfoString(lastSelectionOwner[i].client),
(void *)pSelection->client, CLINDEX(pSelection->client)); nxagentClientInfoString(pSelection->client));
fprintf(stderr, "%s: lastSelectionOwner.window [0x%x] -> [0x%x]\n", __func__, fprintf(stderr, "%s: lastSelectionOwner.window [0x%x] -> [0x%x]\n", __func__,
lastSelectionOwner[i].window, pSelection->window); lastSelectionOwner[i].window, pSelection->window);
fprintf(stderr, "%s: lastSelectionOwner.windowPtr [%p] -> [%p] [0x%x] (serverWindow: [0x%x])\n", __func__, fprintf(stderr, "%s: lastSelectionOwner.windowPtr [%p] -> [%p] [0x%x] (serverWindow: [0x%x])\n", __func__,
...@@ -1676,8 +1689,7 @@ static void setSelectionOwner(Selection *pSelection) ...@@ -1676,8 +1689,7 @@ static void setSelectionOwner(Selection *pSelection)
storeSelectionOwner(i, pSelection); storeSelectionOwner(i, pSelection);
} }
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
lastServerRequestor = None; lastServerRequestor = None;
...@@ -1693,8 +1705,7 @@ FIXME ...@@ -1693,8 +1705,7 @@ FIXME
lastSelectionOwnerWindow = pSelection->window; lastSelectionOwnerWindow = pSelection->window;
lastSelectionOwnerWindowPtr = pSelection->pWin; lastSelectionOwnerWindowPtr = pSelection->pWin;
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
lastServerRequestor = None; lastServerRequestor = None;
} }
...@@ -1702,24 +1713,6 @@ FIXME ...@@ -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 * This is called from dix (ProcConvertSelection) if an nxagent client
* issues a ConvertSelection request. So all the Atoms are internal * issues a ConvertSelection request. So all the Atoms are internal
...@@ -1773,14 +1766,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, ...@@ -1773,14 +1766,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: timeout expired on last request, " fprintf(stderr, "%s: timeout expired on last request, "
"notifying failure to client\n", __func__); "notifying failure to client %s\n", __func__, nxagentClientInfoString(client));
#endif #endif
notifyConvertFailure(lastClientClientPtr, lastClientRequestor, endTransfer(SELECTION_FAULT);
lastClientSelection, lastClientTarget, lastClientTime);
lastClientWindowPtr = NULL;
setClientSelectionStage(None);
} }
else else
{ {
...@@ -1791,19 +1780,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, ...@@ -1791,19 +1780,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
*/ */
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: got request " 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 #endif
notifyConvertFailure(client, requestor, selection, target, time); sendSelectionNotifyEventToClient(client, time, requestor, selection, target, None);
return 1; return 1;
} }
} }
#ifdef DEBUG #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__, "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)), property, validateString(NameForAtom(property)),
target, validateString(NameForAtom(target))); target, validateString(NameForAtom(target)));
#endif #endif
...@@ -1887,7 +1877,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, ...@@ -1887,7 +1877,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
} }
} }
#ifdef DEBUG
if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < ACCUM_TIME)) if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < ACCUM_TIME))
{ {
/* /*
...@@ -1897,9 +1886,11 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, ...@@ -1897,9 +1886,11 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
* client requesting PRIMARY and CLIPBOARD would match here, too * client requesting PRIMARY and CLIPBOARD would match here, too
*/ */
fprintf(stderr, "%s: Consecutives request from client [%p] selection [%u] " #ifdef DEBUG
"elapsed time [%u] clientAccum [%d]\n", __func__, (void *) client, selection, fprintf(stderr, "%s: Consecutives request from client %s selection [%u] "
GetTimeInMillis() - lastClientReqTime, clientAccum); "elapsed time [%u] clientAccum [%d]\n", __func__, nxagentClientInfoString(client),
selection, GetTimeInMillis() - lastClientReqTime, clientAccum);
#endif
clientAccum++; clientAccum++;
} }
...@@ -1911,20 +1902,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, ...@@ -1911,20 +1902,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
clientAccum = 0; clientAccum = 0;
} }
} }
#endif
if (target == clientTEXT || if (target == clientTEXT ||
target == XA_STRING || target == XA_STRING ||
target == clientCOMPOUND_TEXT || target == clientCOMPOUND_TEXT ||
target == clientUTF8_STRING) target == clientUTF8_STRING)
{ {
lastClientWindowPtr = pWin; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
/* /*
* store the original requestor, we need that later after * store the original requestor, we need that later after
* serverTransToAgentProperty contains the desired selection content * serverTransToAgentProperty contains the desired selection content
*/ */
lastClientRequestor = requestor; lastClientRequestor = requestor;
lastClientWindowPtr = pWin;
lastClientClientPtr = client; lastClientClientPtr = client;
lastClientTime = time; lastClientTime = time;
lastClientProperty = property; lastClientProperty = property;
...@@ -1944,31 +1935,32 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, ...@@ -1944,31 +1935,32 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
* we only convert to either UTF8 or XA_STRING, despite accepting * we only convert to either UTF8 or XA_STRING, despite accepting
* TEXT and COMPOUND_TEXT. * TEXT and COMPOUND_TEXT.
*/ */
XlibAtom p = serverTransToAgentProperty;
XlibAtom t;
char * pstr = "NX_CUT_BUFFER_SERVER";
const char * tstr;
if (target == clientUTF8_STRING) if (target == clientUTF8_STRING)
{ {
#ifdef DEBUG t = serverUTF8_STRING;
fprintf(stderr, "%s: Sending XConvertSelection with target [%ld][%s], property [%ld][%s]\n", __func__, tstr = szAgentUTF8_STRING;
serverUTF8_STRING, szAgentUTF8_STRING, serverTransToAgentProperty, "NX_CUT_BUFFER_SERVER");
#endif
XConvertSelection(nxagentDisplay, selection, serverUTF8_STRING, serverTransToAgentProperty,
serverWindow, CurrentTime);
} }
else else
{ {
#ifdef DEBUG t = XA_STRING;
fprintf(stderr, "%s: Sending XConvertSelection with target [%d][%s], property [%ld][%s]\n", __func__, tstr = validateString(NameForAtom(XA_STRING));
XA_STRING, validateString(NameForAtom(XA_STRING)), serverTransToAgentProperty, "NX_CUT_BUFFER_SERVER");
#endif
XConvertSelection(nxagentDisplay, selection, XA_STRING, serverTransToAgentProperty,
serverWindow, CurrentTime);
} }
#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 */ /* FIXME: check returncode of XConvertSelection */
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "%s: Sent XConvertSelection with target [%s], property [%s]\n", __func__, fprintf(stderr, "%s: Sent XConvertSelection with target [%s], property [%s]\n", __func__, tstr, pstr);
validateString(NameForAtom(target)), validateString(NameForAtom(property)));
#endif #endif
return 1; return 1;
...@@ -2289,8 +2281,7 @@ Bool nxagentInitClipboard(WindowPtr pWin) ...@@ -2289,8 +2281,7 @@ Bool nxagentInitClipboard(WindowPtr pWin)
lastServerRequestor = None; lastServerRequestor = None;
lastClientWindowPtr = NULL; setClientSelectionStage(SelectionStageNone);
setClientSelectionStage(None);
lastClientReqTime = GetTimeInMillis(); lastClientReqTime = GetTimeInMillis();
clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True); clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
......
...@@ -78,4 +78,6 @@ extern WindowPtr nxagentGetClipboardWindow(Atom property); ...@@ -78,4 +78,6 @@ extern WindowPtr nxagentGetClipboardWindow(Atom property);
extern int nxagentSendNotify(xEvent *event); extern int nxagentSendNotify(xEvent *event);
extern void nxagentDumpClipboardStat(void);
#endif /* __Clipboard_H__ */ #endif /* __Clipboard_H__ */
...@@ -1070,6 +1070,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate) ...@@ -1070,6 +1070,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
nxagentToggleAutoGrab(); nxagentToggleAutoGrab();
break; break;
} }
case doDumpClipboard:
{
nxagentDumpClipboardStat();
break;
}
default: default:
{ {
FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n"); FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n");
......
...@@ -52,6 +52,7 @@ enum HandleEventResult ...@@ -52,6 +52,7 @@ enum HandleEventResult
doSwitchResizeMode, doSwitchResizeMode,
doSwitchDeferMode, doSwitchDeferMode,
doAutoGrab, doAutoGrab,
doDumpClipboard
}; };
extern CARD32 nxagentLastEventTime; extern CARD32 nxagentLastEventTime;
......
...@@ -102,6 +102,8 @@ char * nxagentSpecialKeystrokeNames[] = { ...@@ -102,6 +102,8 @@ char * nxagentSpecialKeystrokeNames[] = {
"autograb", "autograb",
"dump_clipboard",
NULL, NULL,
}; };
...@@ -142,6 +144,7 @@ struct nxagentSpecialKeystrokeMap default_map[] = { ...@@ -142,6 +144,7 @@ struct nxagentSpecialKeystrokeMap default_map[] = {
{KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down}, {KEYSTROKE_VIEWPORT_SCROLL_DOWN, ControlMask, True, XK_KP_Down},
{KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k}, {KEYSTROKE_REREAD_KEYSTROKES, ControlMask, True, XK_k},
{KEYSTROKE_AUTOGRAB, ControlMask, True, XK_g}, {KEYSTROKE_AUTOGRAB, ControlMask, True, XK_g},
{KEYSTROKE_DUMP_CLIPBOARD, ControlMask | ShiftMask, True, XK_c},
{KEYSTROKE_END_MARKER, 0, False, NoSymbol}, {KEYSTROKE_END_MARKER, 0, False, NoSymbol},
}; };
struct nxagentSpecialKeystrokeMap *map = default_map; struct nxagentSpecialKeystrokeMap *map = default_map;
...@@ -715,6 +718,9 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result) ...@@ -715,6 +718,9 @@ Bool nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
case KEYSTROKE_AUTOGRAB: case KEYSTROKE_AUTOGRAB:
*result = doAutoGrab; *result = doAutoGrab;
break; break;
case KEYSTROKE_DUMP_CLIPBOARD:
*result = doDumpClipboard;
break;
case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */ case KEYSTROKE_NOTHING: /* do nothing. difference to KEYSTROKE_IGNORE is the return value */
case KEYSTROKE_END_MARKER: /* just to make gcc STFU */ case KEYSTROKE_END_MARKER: /* just to make gcc STFU */
case KEYSTROKE_MAX: case KEYSTROKE_MAX:
......
...@@ -78,10 +78,12 @@ enum nxagentSpecialKeystroke { ...@@ -78,10 +78,12 @@ enum nxagentSpecialKeystroke {
KEYSTROKE_AUTOGRAB, KEYSTROKE_AUTOGRAB,
KEYSTROKE_NOTHING, KEYSTROKE_DUMP_CLIPBOARD,
/* insert more here and in the string translation */ /* insert more here and in the string translation */
KEYSTROKE_NOTHING,
KEYSTROKE_MAX, KEYSTROKE_MAX,
}; };
......
...@@ -127,6 +127,7 @@ Equipment Corporation. ...@@ -127,6 +127,7 @@ Equipment Corporation.
#include "Handlers.h" #include "Handlers.h"
#include "Keyboard.h" #include "Keyboard.h"
#include "Init.h" #include "Init.h"
#include "Utils.h"
const int nxagentMaxFontNames = 10000; const int nxagentMaxFontNames = 10000;
...@@ -584,6 +585,8 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio ...@@ -584,6 +585,8 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio
nxagentFreeFontData(); nxagentFreeFontData();
#endif /* NXAGENT_SERVER */ #endif /* NXAGENT_SERVER */
nxagentFreeAtomMap();
KillAllClients(); KillAllClients();
free(clientReady); free(clientReady);
dispatchException &= ~DE_RESET; dispatchException &= ~DE_RESET;
...@@ -988,6 +991,10 @@ ProcFreePixmap(register ClientPtr client) ...@@ -988,6 +991,10 @@ ProcFreePixmap(register ClientPtr client)
void void
CloseDownClient(register ClientPtr client) CloseDownClient(register ClientPtr client)
{ {
#ifdef DEBUG
fprintf(stderr, "%s: [%d]\n", __func__, client->clientState);
#endif
#ifdef NXAGENT_SERVER #ifdef NXAGENT_SERVER
/* /*
* Need to reset the karma counter and get rid of the pending sync * Need to reset the karma counter and get rid of the pending sync
......
...@@ -155,9 +155,13 @@ extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr); ...@@ -155,9 +155,13 @@ extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
extern int nxagentShadowInit(ScreenPtr, WindowPtr); extern int nxagentShadowInit(ScreenPtr, WindowPtr);
void void
ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
TimeStamp time, Bool autoGrab) TimeStamp time, Bool autoGrab)
{ {
#ifdef DEBUG
fprintf(stderr, "%s: called\n", __func__);
#endif
xorg_ActivatePointerGrab(mouse, grab, time, autoGrab); xorg_ActivatePointerGrab(mouse, grab, time, autoGrab);
#ifdef NXAGENT_SERVER #ifdef NXAGENT_SERVER
...@@ -166,7 +170,7 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, ...@@ -166,7 +170,7 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
* If grab is synchronous, events are delivered to clients only if they send * 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 * 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. * 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: * 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 * replayed events are not delivered to that application that are not clients of
* the agent. * the agent.
...@@ -217,6 +221,10 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, ...@@ -217,6 +221,10 @@ ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab,
void void
DeactivatePointerGrab(register DeviceIntPtr mouse) DeactivatePointerGrab(register DeviceIntPtr mouse)
{ {
#ifdef DEBUG
fprintf(stderr, "%s: called\n", __func__);
#endif
xorg_DeactivatePointerGrab(mouse); xorg_DeactivatePointerGrab(mouse);
#ifdef NXAGENT_SERVER #ifdef NXAGENT_SERVER
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment