From f14e80077c5640d2a3e2e9898dda37ef44ffeb38 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sat, 3 Aug 2019 23:20:42 +0200 Subject: Clipboard.c: do not send notify when pointer is NULL There was only one place where this was checked but we check it always. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index fe5c7d2c9..c3314d6dd 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -714,6 +714,14 @@ FIXME: Do we need this? void nxagentSendSelectionNotify(Atom property) { + if (lastClientClientPtr == NULL) + { + #ifdef DEBUG + fprintf(stderr, "%s: lastClientClientPtr is NULL - doing nothing.\n", __func__); + #endif + return; + } + xEvent x; #ifdef DEBUG @@ -920,10 +928,7 @@ void nxagentCollectPropertyEvent(int resource) fprintf (stderr, "%s: WARNING! Invalid property value.\n", __func__); #endif - if (lastClientClientPtr != NULL) - { - nxagentSendSelectionNotify(None); - } + nxagentSendSelectionNotify(None); lastClientWindowPtr = NULL; SetClientSelectionStage(None); -- cgit v1.2.3 From bc997cf645e480773d086ee72366f34605e12238 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sat, 3 Aug 2019 23:26:02 +0200 Subject: Clipboard.c: introduce central function to abort the transfer --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 76 ++++++++++++-------------- 1 file changed, 36 insertions(+), 40 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index c3314d6dd..a4990ec48 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -202,6 +202,9 @@ extern Display *nxagentDisplay; Bool nxagentValidServerTargets(Atom target); void nxagentSendSelectionNotify(Atom property); +static void endTransfer(Bool success); +#define SELECTION_SUCCESS True +#define SELECTION_FAULT False void nxagentTransferSelection(int resource); void nxagentCollectPropertyEvent(int resource); void nxagentResetSelectionOwner(void); @@ -745,6 +748,30 @@ void nxagentSendSelectionNotify(Atom property) return; } +/* + * client and resetting the corresponding variables and the state + * machine. If success is False send a None reply, meaning "request + * denied/failed" + * Use SELECTION_SUCCESS and SELECTION_FAULT macros for success. + */ +static void endTransfer(Bool success) +{ + if (success == SELECTION_SUCCESS) + { + nxagentSendSelectionNotify(lastClientProperty); + } + else + { + nxagentSendSelectionNotify(None); + } + + /* + * Enable further requests from clients. + */ + lastClientWindowPtr = NULL; + SetClientSelectionStage(None); +} + void nxagentTransferSelection(int resource) { int result; @@ -756,10 +783,7 @@ void nxagentTransferSelection(int resource) resource, lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); return; } @@ -804,10 +828,7 @@ void nxagentTransferSelection(int resource) lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); return; } @@ -857,10 +878,7 @@ void nxagentTransferSelection(int resource) lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); return; } @@ -913,10 +931,7 @@ void nxagentCollectPropertyEvent(int resource) lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); SAFE_XFree(pszReturnData); return; @@ -928,10 +943,7 @@ void nxagentCollectPropertyEvent(int resource) fprintf (stderr, "%s: WARNING! Invalid property value.\n", __func__); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); SAFE_XFree(pszReturnData); return; @@ -954,10 +966,7 @@ void nxagentCollectPropertyEvent(int resource) lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); SAFE_XFree(pszReturnData); return; @@ -993,10 +1002,7 @@ void nxagentCollectPropertyEvent(int resource) lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); SAFE_XFree(pszReturnData); return; @@ -1017,14 +1023,7 @@ void nxagentCollectPropertyEvent(int resource) validateString(NameForAtom(lastClientProperty)), pszReturnData); #endif - nxagentSendSelectionNotify(lastClientProperty); - - /* - * Enable further requests from clients. - */ - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_SUCCESS); break; } @@ -1093,10 +1092,7 @@ void nxagentNotifySelection(XEvent *X) lastClientClientPtr -> index); #endif - nxagentSendSelectionNotify(None); - - lastClientWindowPtr = NULL; - SetClientSelectionStage(None); + endTransfer(SELECTION_FAULT); } return; -- cgit v1.2.3 From 2ee7626a6efcf4ddf974485cbdc6212a6394ee36 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sat, 3 Aug 2019 23:43:27 +0200 Subject: Clipboard.c: introduce SendSelectionNotifyEventToServer fixup! Clipboard.c: introduce XSendNotificationEventHelper --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 132 ++++++++++--------------- 1 file changed, 50 insertions(+), 82 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index a4990ec48..91bacc48c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -355,6 +355,52 @@ int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset, long longL unsigned long *nItems, unsigned long *bytesAfter, unsigned char **propData); +/* + * Send a SelectionNotify event to the real X server and do some error + * handling (in DEBUG mode) + */ +Status SendSelectionNotifyEventToServer(XSelectionEvent *event_to_send) +{ + Window w = event_to_send->requestor; + + event_to_send->type = SelectionNotify; + event_to_send->send_event = True; + event_to_send->display = nxagentDisplay; + + #ifdef DEBUG + fprintf(stderr, "%s: Sending event to requestor [%p].\n", __func__, (void *)w); + #endif + + Status result = XSendEvent(nxagentDisplay, w, False, 0L, (XEvent *)event_to_send); + + #ifdef DEBUG + /* + * man XSendEvent: XSendEvent returns zero if the conversion to wire + * protocol format failed and returns nonzero otherwise. XSendEvent + * can generate BadValue and BadWindow errors. + */ + if (result == 0) + { + fprintf(stderr, "%s: XSendEvent to [0x%x] failed.\n", __func__, w); + } + else + { + if (result == BadValue || result == BadWindow) + { + fprintf(stderr, "%s: WARNING! XSendEvent to [0x%x] failed: %s\n", __func__, w, GetXErrorString(result)); + } + else + { + fprintf(stderr, "%s: XSendEvent() successfully sent to [0x%x]\n", __func__, w); + } + } + #endif + + //NXFlushDisplay(nxagentDisplay, NXFlushLink); + + return result; +} + Bool nxagentValidServerTargets(Atom target) { if (target == XA_STRING) @@ -560,35 +606,12 @@ FIXME: Do we need this? } } - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = nxagentDisplay; eventSelection.requestor = X->xselectionrequest.requestor; eventSelection.selection = X->xselectionrequest.selection; eventSelection.target = X->xselectionrequest.target; eventSelection.time = X->xselectionrequest.time; - #ifdef DEBUG - int result = - #endif - XSendEvent(nxagentDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - - #ifdef DEBUG - fprintf(stderr, "%s: XSendEvent() returned [%s]\n", __func__, GetXErrorString(result)); - if (result == BadValue || result == BadWindow) - { - fprintf(stderr, "%s: WARNING! XSendEvent failed.\n", __func__); - } - else - { - fprintf(stderr, "%s: XSendEvent sent to window [0x%lx].\n", __func__, - eventSelection.requestor); - } - #endif + SendSelectionNotifyEventToServer(&eventSelection); return; } @@ -679,36 +702,13 @@ FIXME: Do we need this? * to requestor with property None. */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = nxagentDisplay; eventSelection.requestor = X->xselectionrequest.requestor; eventSelection.selection = X->xselectionrequest.selection; eventSelection.target = X->xselectionrequest.target; eventSelection.property = None; eventSelection.time = X->xselectionrequest.time; - #ifdef DEBUG - int result = - #endif - XSendEvent(nxagentDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - - #ifdef DEBUG - fprintf(stderr, "%s: XSendEvent() returned [%s]\n", __func__, GetXErrorString(result)); - if (result == BadValue || result == BadWindow) - { - fprintf(stderr, "%s: WARNING! XSendEvent failed.\n", __func__); - } - else - { - fprintf(stderr, "%s: XSendEvent with property None sent to window [0x%lx].\n", __func__, - eventSelection.requestor); - } - #endif + SendSelectionNotifyEventToServer(&eventSelection); } } } @@ -1169,9 +1169,6 @@ void nxagentNotifySelection(XEvent *X) } memset(&eventSelection, 0, sizeof(XSelectionEvent)); - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = nxagentDisplay; eventSelection.requestor = lastServerRequestor; eventSelection.selection = X->xselection.selection; @@ -1189,23 +1186,7 @@ void nxagentNotifySelection(XEvent *X) * eventSelection.time = lastServerTime; */ - #ifdef DEBUG - fprintf(stderr, "%s: Sending event to requestor [%p].\n", __func__, (void *)eventSelection.requestor); - #endif - - result = XSendEvent(nxagentDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - - #ifdef DEBUG - fprintf(stderr, "%s: XSendEvent() returned [%s]\n", __func__, GetXErrorString(result)); - #endif - if (result == BadValue || result == BadWindow) - { - fprintf (stderr, "SelectionRequest - XSendEvent failed\n"); - } + SendSelectionNotifyEventToServer(&eventSelection); lastServerRequestor = None; /* allow further request */ } @@ -1688,16 +1669,12 @@ int nxagentSendNotify(xEvent *event) if (event->u.selectionNotify.property == clientCutProperty) { XSelectionEvent x; - int result; /* * Setup selection notify event to real server. */ memset(&x, 0, sizeof(XSelectionEvent)); - x.type = SelectionNotify; - x.send_event = True; - x.display = nxagentDisplay; x.requestor = serverWindow; /* @@ -1722,16 +1699,7 @@ int nxagentSendNotify(xEvent *event) fprintf(stderr, "%s: Propagating clientCutProperty to requestor [%p].\n", __func__, (void *)x.requestor); #endif - result = XSendEvent (nxagentDisplay, x.requestor, False, - 0L, (XEvent *) &x); - - #ifdef DEBUG - fprintf(stderr, "%s: XSendEvent() returned [%s]\n", __func__, GetXErrorString(result)); - #endif - if (result == BadValue || result == BadWindow) - { - fprintf (stderr, "%s: XSendEvent failed.\n", __func__); - } + SendSelectionNotifyEventToServer(&x); return 1; } -- cgit v1.2.3 From c233eec5fbc2c3dd253fe9e8a899530a3cd514c4 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sat, 3 Aug 2019 23:58:29 +0200 Subject: Clipboard.c: introduce SendEventToClient helper --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 91bacc48c..3d1db5809 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -401,6 +401,11 @@ Status SendSelectionNotifyEventToServer(XSelectionEvent *event_to_send) return result; } +int SendEventToClient(ClientPtr client, xEvent *pEvents) +{ + return TryClientEvents (client, pEvents, 1, NoEventMask, NoEventMask, NullGrab); +} + Bool nxagentValidServerTargets(Atom target) { if (target == XA_STRING) @@ -516,9 +521,7 @@ void nxagentClearSelection(XEvent *X) x.u.selectionClear.window = lastSelectionOwner[i].window; x.u.selectionClear.atom = CurrentSelections[i].selection; - (void) TryClientEvents(lastSelectionOwner[i].client, &x, 1, - NoEventMask, NoEventMask, - NullGrab); + SendEventToClient(lastSelectionOwner[i].client, &x); } CurrentSelections[i].window = screenInfo.screens[0]->root->drawable.id; @@ -687,9 +690,7 @@ FIXME: Do we need this? x.u.selectionRequest.property = clientCutProperty; - (void) TryClientEvents(lastSelectionOwner[i].client, &x, 1, - NoEventMask, NoEventMask /* CantBeFiltered */, - NullGrab); + SendEventToClient(lastSelectionOwner[i].client, &x); #ifdef DEBUG fprintf(stderr, "%s: Executed TryClientEvents with clientCutProperty.\n", __func__); @@ -742,8 +743,7 @@ void nxagentSendSelectionNotify(Atom property) x.u.selectionNotify.property = property; - TryClientEvents(lastClientClientPtr, &x, 1, NoEventMask, - NoEventMask , NullGrab); + SendEventToClient(lastClientClientPtr, &x); return; } @@ -1415,8 +1415,7 @@ FIXME: Why this pointer can be not a valid x.u.selectionNotify.target = target; x.u.selectionNotify.property = None; - (void) TryClientEvents(client, &x, 1, NoEventMask, - NoEventMask , NullGrab); + SendEventToClient(client, &x); } int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, @@ -1521,8 +1520,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, x.u.selectionNotify.target = target; x.u.selectionNotify.property = property; - (void) TryClientEvents(client, &x, 1, NoEventMask, - NoEventMask , NullGrab); + SendEventToClient(client, &x); return 1; } @@ -1554,8 +1552,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, x.u.selectionNotify.target = target; x.u.selectionNotify.property = property; - (void) TryClientEvents(client, &x, 1, NoEventMask, - NoEventMask , NullGrab); + SendEventToClient(client, &x); return 1; @@ -1642,7 +1639,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, x.u.selectionNotify.selection = selection; x.u.selectionNotify.target = target; x.u.selectionNotify.property = None; - (void) TryClientEvents(client, &x, 1, NoEventMask, NoEventMask , NullGrab); + SendEventToClient(client, &x); return 1; } return 0; -- cgit v1.2.3 From 7d06837013e7265d343adccb73dc22b76722a24f Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sun, 4 Aug 2019 00:17:01 +0200 Subject: Clipboard.c: introduce SendSelectionNotifyEventToClient helper --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 94 +++++++++----------------- 1 file changed, 32 insertions(+), 62 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 3d1db5809..9064598a6 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -406,6 +406,27 @@ int SendEventToClient(ClientPtr client, xEvent *pEvents) return TryClientEvents (client, pEvents, 1, NoEventMask, NoEventMask, NullGrab); } +int SendSelectionNotifyEventToClient(ClientPtr client, + Time time, + Window requestor, + Atom selection, + Atom target, + Atom property) +{ + #ifdef DEBUG + fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, client -> index); + #endif + + xEvent x = {0}; + x.u.u.type = SelectionNotify; + x.u.selectionNotify.time = time; + x.u.selectionNotify.requestor = requestor; + x.u.selectionNotify.selection = selection; + x.u.selectionNotify.target = target; + x.u.selectionNotify.property = property; + return SendEventToClient(client, &x); +} + Bool nxagentValidServerTargets(Atom target) { if (target == XA_STRING) @@ -726,26 +747,12 @@ void nxagentSendSelectionNotify(Atom property) return; } - xEvent x; - - #ifdef DEBUG - fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, - lastClientClientPtr -> index); - #endif - - memset(&x, 0, sizeof(xEvent)); - x.u.u.type = SelectionNotify; - - x.u.selectionNotify.time = lastClientTime; - x.u.selectionNotify.requestor = lastClientRequestor; - x.u.selectionNotify.selection = lastClientSelection; - x.u.selectionNotify.target = lastClientTarget; - - x.u.selectionNotify.property = property; - - SendEventToClient(lastClientClientPtr, &x); - - return; + SendSelectionNotifyEventToClient(lastClientClientPtr, + lastClientTime, + lastClientRequestor, + lastClientSelection, + lastClientTarget, + property); } /* @@ -1392,8 +1399,6 @@ FIXME void nxagentNotifyConvertFailure(ClientPtr client, Window requestor, Atom selection, Atom target, Time time) { - xEvent x; - /* FIXME: Why this pointer can be not a valid client pointer? @@ -1407,15 +1412,7 @@ FIXME: Why this pointer can be not a valid return; } - memset(&x, 0, sizeof(xEvent)); - x.u.u.type = SelectionNotify; - x.u.selectionNotify.time = time; - x.u.selectionNotify.requestor = requestor; - x.u.selectionNotify.selection = selection; - x.u.selectionNotify.target = target; - x.u.selectionNotify.property = None; - - SendEventToClient(client, &x); + SendSelectionNotifyEventToClient(client, time, requestor, selection, target, None); } int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, @@ -1496,7 +1493,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, if (target == clientTARGETS) { Atom xa_STRING[4]; - xEvent x; /* --- Order changed by dimbor (prevent sending COMPOUND_TEXT to client --- */ xa_STRING[0] = XA_STRING; @@ -1512,15 +1508,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, 4, &xa_STRING, 1); - memset(&x, 0, sizeof(xEvent)); - x.u.u.type = SelectionNotify; - x.u.selectionNotify.time = time; - x.u.selectionNotify.requestor = requestor; - x.u.selectionNotify.selection = selection; - x.u.selectionNotify.target = target; - x.u.selectionNotify.property = property; - - SendEventToClient(client, &x); + SendSelectionNotifyEventToClient(client, time, requestor, selection, target, property); return 1; } @@ -1534,7 +1522,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, if (i < NumCurrentSelections) { - xEvent x; ChangeWindowProperty(pWin, property, target, @@ -1544,18 +1531,9 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, (unsigned char *) &lastSelectionOwner[i].lastTimeChanged, 1); - memset(&x, 0, sizeof(xEvent)); - x.u.u.type = SelectionNotify; - x.u.selectionNotify.time = time; - x.u.selectionNotify.requestor = requestor; - x.u.selectionNotify.selection = selection; - x.u.selectionNotify.target = target; - x.u.selectionNotify.property = property; - - SendEventToClient(client, &x); + SendSelectionNotifyEventToClient(client, time, requestor, selection, target, property); return 1; - } } @@ -1625,21 +1603,13 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, } else { - xEvent x; - #ifdef DEBUG fprintf(stderr, "%s: Xserver generates a SelectionNotify event " "to the requestor with property None.\n", __func__); #endif - memset(&x, 0, sizeof(xEvent)); - x.u.u.type = SelectionNotify; - x.u.selectionNotify.time = time; - x.u.selectionNotify.requestor = requestor; - x.u.selectionNotify.selection = selection; - x.u.selectionNotify.target = target; - x.u.selectionNotify.property = None; - SendEventToClient(client, &x); + SendSelectionNotifyEventToClient(client, time, requestor, selection, target, None); + return 1; } return 0; -- cgit v1.2.3 From 25cbfd14f01bf2cdeb7504a5d8a3b03d924e243f Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sun, 4 Aug 2019 00:51:06 +0200 Subject: Clipboard.c: merge endTransfer and nxagentSendSelectionNotify endTransfer is the only caller --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 37 +++++++++----------------- 1 file changed, 12 insertions(+), 25 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 9064598a6..f5b163720 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -201,7 +201,6 @@ XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, 0 }; extern Display *nxagentDisplay; Bool nxagentValidServerTargets(Atom target); -void nxagentSendSelectionNotify(Atom property); static void endTransfer(Bool success); #define SELECTION_SUCCESS True #define SELECTION_FAULT False @@ -737,24 +736,6 @@ FIXME: Do we need this? nxagentPrintClipboardStat("after nxagentRequestSelection"); } -void nxagentSendSelectionNotify(Atom property) -{ - if (lastClientClientPtr == NULL) - { - #ifdef DEBUG - fprintf(stderr, "%s: lastClientClientPtr is NULL - doing nothing.\n", __func__); - #endif - return; - } - - SendSelectionNotifyEventToClient(lastClientClientPtr, - lastClientTime, - lastClientRequestor, - lastClientSelection, - lastClientTarget, - property); -} - /* * client and resetting the corresponding variables and the state * machine. If success is False send a None reply, meaning "request @@ -763,15 +744,21 @@ void nxagentSendSelectionNotify(Atom property) */ static void endTransfer(Bool success) { - if (success == SELECTION_SUCCESS) - { - nxagentSendSelectionNotify(lastClientProperty); - } - else + if (lastClientClientPtr == NULL) { - nxagentSendSelectionNotify(None); + #ifdef DEBUG + fprintf(stderr, "%s: lastClientClientPtr is NULL - doing nothing.\n", __func__); + #endif + return; } + SendSelectionNotifyEventToClient(lastClientClientPtr, + lastClientTime, + lastClientRequestor, + lastClientSelection, + lastClientTarget, + success == SELECTION_SUCCESS ? lastClientProperty : None); + /* * Enable further requests from clients. */ -- cgit v1.2.3 From 6d5cda4781afd18a49dacb588405bcd985364339 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sun, 4 Aug 2019 01:09:06 +0200 Subject: Clipboard.c: improve TARGETS request handling --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index f5b163720..07a82b16c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -599,15 +599,17 @@ FIXME: Do we need this? if (X->xselectionrequest.target == serverTARGETS) { - Atom xa_STRING = XA_STRING; + Atom targets[] = {XA_STRING}; + int numTargets = 1; + XChangeProperty (nxagentDisplay, X->xselectionrequest.requestor, X->xselectionrequest.property, XInternAtom(nxagentDisplay, "ATOM", 0), sizeof(Atom)*8, PropModeReplace, - (unsigned char*)&xa_STRING, - 1); + (unsigned char*)&targets, + numTargets); eventSelection.property = X->xselectionrequest.property; } else if (X->xselectionrequest.target == nxagentTimestampAtom) @@ -1479,21 +1481,18 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, if (target == clientTARGETS) { - Atom xa_STRING[4]; - /* --- Order changed by dimbor (prevent sending COMPOUND_TEXT to client --- */ - xa_STRING[0] = XA_STRING; - xa_STRING[1] = clientUTF8_STRING; - xa_STRING[2] = clientTEXT; - xa_STRING[3] = clientCOMPOUND_TEXT; + Atom targets[] = {XA_STRING, clientUTF8_STRING, clientTEXT, clientCOMPOUND_TEXT}; + int numTargets = 4; ChangeWindowProperty(pWin, property, MakeAtom("ATOM", 4, 1), sizeof(Atom)*8, PropModeReplace, - 4, - &xa_STRING, 1); + numTargets, + &targets, + 1); SendSelectionNotifyEventToClient(client, time, requestor, selection, target, property); -- cgit v1.2.3 From 6621c53c554b654f21c92ee09d1341c788d3a047 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sun, 4 Aug 2019 01:28:59 +0200 Subject: Clipboard.c: Fix: report timestamps as XA_INTEGER Just as everyone else does. ICCCM is not really clear about this. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 07a82b16c..5f948eeea 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -622,7 +622,7 @@ FIXME: Do we need this? XChangeProperty(nxagentDisplay, X->xselectionrequest.requestor, X->xselectionrequest.property, - X->xselectionrequest.target, + XA_INTEGER, 32, PropModeReplace, (unsigned char *) &lastSelectionOwner[i].lastTimeChanged, @@ -1510,7 +1510,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, { ChangeWindowProperty(pWin, property, - target, + XA_INTEGER, 32, PropModeReplace, 1, -- cgit v1.2.3 From 79867f4a0ee04c40a35402435902abe9849dcd93 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 15:51:42 +0200 Subject: Clipboard.c: introduce nxagent{Clear,Store}SelectionOwner --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 35 ++++++++++++++++---------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 5f948eeea..a5dade03e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -464,6 +464,23 @@ Bool nxagentValidServerTargets(Atom target) return False; } +void nxagentClearSelectionOwner(SelectionOwner *owner) +{ + /* there's no owner on nxagent side anymore */ + owner->client = NULL; + owner->window = None; + owner->lastTimeChanged = GetTimeInMillis(); + /* FIXME: why is windowPtr not cleared in the function? */ +} + +void nxagentStoreSelectionOwner(SelectionOwner *owner, Selection *sel) +{ + owner->client = sel->client; + owner->window = sel->window; + owner->windowPtr = sel->pWin; + owner->lastTimeChanged = GetTimeInMillis(); +} + void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) { #ifdef DEBUG @@ -487,10 +504,9 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) (void *) pClient, (void *) pWindow); #endif - lastSelectionOwner[i].client = NULL; - lastSelectionOwner[i].window = None; + /* FIXME: why is windowPtr not cleared in the function? */ + nxagentClearSelectionOwner(&lastSelectionOwner[i]); lastSelectionOwner[i].windowPtr = NULL; - lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis(); lastClientWindowPtr = NULL; SetClientSelectionStage(None); @@ -547,9 +563,7 @@ void nxagentClearSelection(XEvent *X) CurrentSelections[i].window = screenInfo.screens[0]->root->drawable.id; CurrentSelections[i].client = NullClient; - lastSelectionOwner[i].client = NULL; - lastSelectionOwner[i].window = None; - lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis(); + nxagentClearSelectionOwner(&lastSelectionOwner[i]); } lastClientWindowPtr = NULL; @@ -1221,10 +1235,8 @@ void nxagentResetSelectionOwner(void) fprintf(stderr, "%s: Reset clipboard state.\n", __func__); #endif - lastSelectionOwner[i].client = NULL; - lastSelectionOwner[i].window = None; + nxagentClearSelectionOwner(&lastSelectionOwner[i]); lastSelectionOwner[i].windowPtr = NULL; - lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis(); } lastClientWindowPtr = NULL; @@ -1352,10 +1364,7 @@ void nxagentSetSelectionOwner(Selection *pSelection) */ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime); - lastSelectionOwner[i].client = pSelection->client; - lastSelectionOwner[i].window = pSelection->window; - lastSelectionOwner[i].windowPtr = pSelection->pWin; - lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis(); + nxagentStoreSelectionOwner(&lastSelectionOwner[i], pSelection); } } -- cgit v1.2.3 From 5de8bac22e710ec6a17789fca88f5f0b49351773 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:08:40 +0200 Subject: Clipboard.c: introduce nxagentFind*Index functions At some places we were using NumCurrentSelections. We replace that by nxagentMaxSelections because they always have the identical value. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 69 +++++++++++-------------- nx-X11/programs/Xserver/hw/nxagent/Clipboard.h | 1 + nx-X11/programs/Xserver/hw/nxagent/Events.c | 7 +-- nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c | 6 +-- 4 files changed, 33 insertions(+), 50 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index a5dade03e..0452cd193 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -524,10 +524,30 @@ void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) nxagentPrintClipboardStat("after nxagentClearClipboard"); } -void nxagentClearSelection(XEvent *X) +int nxagentFindLastSelectionOwnerIndex(Atom sel) { int i = 0; + while ((i < nxagentMaxSelections) && + (lastSelectionOwner[i].selection != sel)) + { + i++; + } + return i; +} +int nxagentFindCurrentSelectionIndex(Atom sel) +{ + int i = 0; + while ((i < NumCurrentSelections) && + (CurrentSelections[i].selection != sel)) + { + i++; + } + return i; +} + +void nxagentClearSelection(XEvent *X) +{ #ifdef DEBUG fprintf(stderr, "%s: SelectionClear event for selection [%lu].\n", __func__, X->xselectionclear.selection); #endif @@ -540,11 +560,7 @@ void nxagentClearSelection(XEvent *X) return; } - while ((i < nxagentMaxSelections) && - (lastSelectionOwner[i].selection != X->xselectionclear.selection)) - { - i++; - } + int i = nxagentFindLastSelectionOwnerIndex(X->xselectionclear.selection); if (i < nxagentMaxSelections) { @@ -573,7 +589,6 @@ void nxagentClearSelection(XEvent *X) void nxagentRequestSelection(XEvent *X) { - int i = 0; XSelectionEvent eventSelection = {0}; #ifdef DEBUG @@ -628,10 +643,8 @@ FIXME: Do we need this? } else if (X->xselectionrequest.target == nxagentTimestampAtom) { - while ((i < NumCurrentSelections) && - lastSelectionOwner[i].selection != X->xselectionrequest.selection) i++; - - if (i < NumCurrentSelections) + int i = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection); + if (i < nxagentMaxSelections) { XChangeProperty(nxagentDisplay, X->xselectionrequest.requestor, @@ -661,13 +674,8 @@ FIXME: Do we need this? nxagentLastRequestedSelection = X->xselectionrequest.selection; - /* FIXME: shouldn't we reset i to 0 here first? */ - while ((i < nxagentMaxSelections) && - (lastSelectionOwner[i].selection != X->xselectionrequest.selection)) - { - i++; - } - + /* find the index of the requested selection */ + int i = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection); if (i < nxagentMaxSelections) { if ((lastClientWindowPtr != NULL) && (lastSelectionOwner[i].client != NULL)) @@ -1109,13 +1117,7 @@ void nxagentNotifySelection(XEvent *X) } else { - int i = 0; - - while ((i < nxagentMaxSelections) && (lastSelectionOwner[i].selection != X->xselection.selection)) - { - i++; - } - + int i = nxagentFindLastSelectionOwnerIndex(X->xselection.selection); if (i < nxagentMaxSelections) { if ((lastSelectionOwner[i].client != NULL) && @@ -1417,7 +1419,6 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, Window requestor, Atom property, Atom target, Time time) { const char *strTarget; - int i; if (agentClipboardStatus != 1 || nxagentOption(Clipboard) == ClipboardServer) @@ -1433,7 +1434,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, * Only for PRIMARY and CLIPBOARD selections. */ - for (i = 0; i < nxagentMaxSelections; i++) + for (int i = 0; i < nxagentMaxSelections; i++) { if ((selection == CurrentSelections[i].selection) && (lastSelectionOwner[i].client != NULL)) @@ -1510,11 +1511,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, if (target == MakeAtom("TIMESTAMP", 9, 1)) { - int i = 0; - - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != selection) i++; - + int i = nxagentFindCurrentSelectionIndex(selection); if (i < NumCurrentSelections) { ChangeWindowProperty(pWin, @@ -1673,17 +1670,11 @@ int nxagentSendNotify(xEvent *event) WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin) { - int i = 0; - #ifdef DEBUG fprintf(stderr, "%s: Got called, property [%d][%s] window [%p].\n", __func__, property, NameForAtom(property), (void *)pWin); #endif - while ((i < nxagentMaxSelections) && - (lastSelectionOwner[i].selection != nxagentLastRequestedSelection)) - { - i++; - } + int i = nxagentFindLastSelectionOwnerIndex(nxagentLastRequestedSelection); if ((i < nxagentMaxSelections) && (property == clientCutProperty) && (lastSelectionOwner[i].windowPtr != NULL)) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h index 62fc32fd9..2f43469ae 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h @@ -66,4 +66,5 @@ void nxagentClearSelection(); void nxagentRequestSelection(); void nxagentNotifySelection(); +int nxagentFindCurrentSelectionIndex(Atom sel); #endif /* __Clipboard_H__ */ diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c index e9de1450d..4a13f15ad 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Events.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c @@ -2933,12 +2933,7 @@ int nxagentHandleXFixesSelectionNotify(XEvent *X) if (SelectionCallback) { - int i = 0; - - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != local) - i++; - + int i = nxagentFindCurrentSelectionIndex(local); if (i < NumCurrentSelections) { SelectionInfoRec info; diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c index b7a054913..4a9ae73ae 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c @@ -691,11 +691,7 @@ ProcConvertSelection(register ClientPtr client) (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) && nxagentOption(Clipboard) != ClipboardNone) { - int i = 0; - - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != stuff->selection) i++; - + int i = nxagentFindCurrentSelectionIndex(stuff->selection); if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None)) { if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor, -- cgit v1.2.3 From 98a0810ffa77646bf4e206bdfabde1295d4ba861 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:13:47 +0200 Subject: Clipboard.c: rename some variables nxagentClipboardAtom -> serverCLIPBOARD nxagentTimestampAtom -> serverTIMESTAMP This is to match the names of the other server atom variables. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 0452cd193..ce4802e36 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -90,8 +90,6 @@ typedef struct _SelectionOwner static SelectionOwner *lastSelectionOwner; static Atom nxagentLastRequestedSelection; -static Atom nxagentClipboardAtom; -static Atom nxagentTimestampAtom; /* * Needed to handle the notify selection event to @@ -126,6 +124,8 @@ static Atom lastServerTarget; static Time lastServerTime; static Atom serverTARGETS; +static Atom serverCLIPBOARD; +static Atom serverTIMESTAMP; static Atom serverTEXT; static Atom serverUTF8_STRING; static Atom clientTARGETS; @@ -326,10 +326,10 @@ void nxagentPrintClipboardStat(char *header) SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverCutProperty); fprintf(stderr, " serverCutProperty [% 4d][%s]\n", serverCutProperty, s); - SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, nxagentClipboardAtom); - fprintf(stderr, " nxagentClipboardAtom [% 4d][%s]\n", nxagentClipboardAtom, s); - SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, nxagentTimestampAtom); - fprintf(stderr, " nxagentTimestampAtom [% 4d][%s]\n", nxagentTimestampAtom, s); + SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverCLIPBOARD); + fprintf(stderr, " serverCLIPBOARD [% 4d][%s]\n", serverCLIPBOARD, s); + SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverTIMESTAMP); + fprintf(stderr, " serverTIMESTAMP [% 4d][%s]\n", serverTIMESTAMP, s); fprintf(stderr, "Atoms (inside nxagent)\n"); fprintf(stderr, " clientTARGETS [% 4d][%s]\n", clientTARGETS, NameForAtom(clientTARGETS)); @@ -641,7 +641,7 @@ FIXME: Do we need this? numTargets); eventSelection.property = X->xselectionrequest.property; } - else if (X->xselectionrequest.target == nxagentTimestampAtom) + else if (X->xselectionrequest.target == serverTIMESTAMP) { int i = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection); if (i < nxagentMaxSelections) @@ -1714,8 +1714,8 @@ int nxagentInitClipboard(WindowPtr pWin) FatalError("nxagentInitClipboard: Failed to allocate memory for the clipboard selections.\n"); } - nxagentClipboardAtom = nxagentAtoms[10]; /* CLIPBOARD */ - nxagentTimestampAtom = nxagentAtoms[11]; /* TIMESTAMP */ + serverCLIPBOARD = nxagentAtoms[10]; /* CLIPBOARD */ + serverTIMESTAMP = nxagentAtoms[11]; /* TIMESTAMP */ lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY; lastSelectionOwner[nxagentPrimarySelection].client = NullClient; @@ -1723,7 +1723,7 @@ int nxagentInitClipboard(WindowPtr pWin) lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL; lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis(); - lastSelectionOwner[nxagentClipboardSelection].selection = nxagentClipboardAtom; + lastSelectionOwner[nxagentClipboardSelection].selection = serverCLIPBOARD; lastSelectionOwner[nxagentClipboardSelection].client = NullClient; lastSelectionOwner[nxagentClipboardSelection].window = screenInfo.screens[0]->root->drawable.id; lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL; -- cgit v1.2.3 From e34f152c928482cbe52e1ce8f73398a49291b70a Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:16:30 +0200 Subject: Clipboard.c: clientAccum is only used for debugging, add DEBUG ifdefs --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index ce4802e36..fd418cf8f 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -68,7 +68,9 @@ extern Selection *CurrentSelections; int nxagentLastClipboardClient = -1; static int agentClipboardStatus; +#ifdef DEBUG static int clientAccum; +#endif Atom serverCutProperty; Atom clientCutProperty; @@ -1529,29 +1531,29 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, } } + #ifdef DEBUG if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < 5000)) { /* - * The same client made consecutive requests - * of clipboard contents with less than 5 - * seconds time interval between them. + * The same client made consecutive requests of clipboard contents + * with less than 5 seconds time interval between them. */ - #ifdef DEBUG fprintf(stderr, "%s: Consecutives request from client [%p] selection [%u] " "elapsed time [%u] clientAccum [%d]\n", __func__, (void *) client, selection, GetTimeInMillis() - lastClientReqTime, clientAccum); - #endif clientAccum++; } else { + /* reset clientAccum as now another client requested the clipboard content */ if (lastClientClientPtr != client) { clientAccum = 0; } } + #endif if ((target == clientTEXT) || (target == XA_STRING) || -- cgit v1.2.3 From 1d05784b44c03fc136b5b446352fbe79184bb7d9 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:18:51 +0200 Subject: Clipboard.c: drop serverCLIPBOARD we reference lastSelectionOwner[nxagentClipboardSelection].selection everywhere. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index fd418cf8f..2f04d2960 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -126,7 +126,6 @@ static Atom lastServerTarget; static Time lastServerTime; static Atom serverTARGETS; -static Atom serverCLIPBOARD; static Atom serverTIMESTAMP; static Atom serverTEXT; static Atom serverUTF8_STRING; @@ -328,8 +327,6 @@ void nxagentPrintClipboardStat(char *header) SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverCutProperty); fprintf(stderr, " serverCutProperty [% 4d][%s]\n", serverCutProperty, s); - SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverCLIPBOARD); - fprintf(stderr, " serverCLIPBOARD [% 4d][%s]\n", serverCLIPBOARD, s); SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverTIMESTAMP); fprintf(stderr, " serverTIMESTAMP [% 4d][%s]\n", serverTIMESTAMP, s); @@ -1716,7 +1713,6 @@ int nxagentInitClipboard(WindowPtr pWin) FatalError("nxagentInitClipboard: Failed to allocate memory for the clipboard selections.\n"); } - serverCLIPBOARD = nxagentAtoms[10]; /* CLIPBOARD */ serverTIMESTAMP = nxagentAtoms[11]; /* TIMESTAMP */ lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY; @@ -1725,7 +1721,7 @@ int nxagentInitClipboard(WindowPtr pWin) lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL; lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis(); - lastSelectionOwner[nxagentClipboardSelection].selection = serverCLIPBOARD; + lastSelectionOwner[nxagentClipboardSelection].selection = nxagentAtoms[10]; /* CLIPBOARD */ lastSelectionOwner[nxagentClipboardSelection].client = NullClient; lastSelectionOwner[nxagentClipboardSelection].window = screenInfo.screens[0]->root->drawable.id; lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL; -- cgit v1.2.3 From 63320437ed4e95246ce62193560098f986ac265c Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:36:10 +0200 Subject: Clipboard.c: simplify nxagentGetClipboardWindow The second parameter was always NULL, so remove it. Also remove some debugging output which distracts while debugging as the function is called from ProcChangeProperty for _every_ property, also non-clipboard related ones. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 2f04d2960..c99c5f030 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -208,7 +208,7 @@ static void endTransfer(Bool success); void nxagentTransferSelection(int resource); void nxagentCollectPropertyEvent(int resource); void nxagentResetSelectionOwner(void); -WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin); +WindowPtr nxagentGetClipboardWindow(Atom property); void nxagentNotifyConvertFailure(ClientPtr client, Window requestor, Atom selection, Atom target, Time time); int nxagentSendNotify(xEvent *event); @@ -1667,12 +1667,8 @@ int nxagentSendNotify(xEvent *event) return 0; } -WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin) +WindowPtr nxagentGetClipboardWindow(Atom property) { - #ifdef DEBUG - fprintf(stderr, "%s: Got called, property [%d][%s] window [%p].\n", __func__, property, NameForAtom(property), (void *)pWin); - #endif - int i = nxagentFindLastSelectionOwnerIndex(nxagentLastRequestedSelection); if ((i < nxagentMaxSelections) && (property == clientCutProperty) && @@ -1686,13 +1682,8 @@ WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin) } else { - #ifdef DEBUG - fprintf(stderr, "%s: Returning original target window [%p].\n", __func__, (void *)pWin); - #endif - - return pWin; + return NULL; } - } int nxagentInitClipboard(WindowPtr pWin) -- cgit v1.2.3 From f99f52772241891779441318b953f6d2c987fe83 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:27:38 +0200 Subject: Clipboard.c: introduce macros CLINDEX and WINDOWID --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index c99c5f030..ea1e4192e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -159,6 +159,8 @@ const char * GetClientSelectionStageString(int stage) } #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) #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() @@ -225,13 +227,13 @@ void nxagentPrintSelectionStat(int sel) #ifdef CLIENTIDS fprintf(stderr, " lastSelectionOwner[].client [%p] index [%d] PID [%d] Cmd [%s]\n", (void *)lOwner.client, - lOwner.client ? lOwner.client->index : -1, + CLINDEX(lOwner.client), GetClientPid(lOwner.client), GetClientCmdName(lOwner.client)); #else fprintf(stderr, " lastSelectionOwner[].client [%p] index [%d]\n", (void *)lOwner.client, - lOwner.client ? lOwner.client->index : -1); + CLINDEX(lOwner.client)); #endif fprintf(stderr, " lastSelectionOwner[].window [0x%x]\n", lOwner.window); fprintf(stderr, " lastSelectionOwner[].windowPtr [%p]\n", (void *)lOwner.windowPtr); @@ -253,13 +255,13 @@ void nxagentPrintSelectionStat(int sel) #ifdef CLIENTIDS fprintf(stderr, " CurrentSelections[].client [%p] index [%d] PID [%d] Cmd [%s]\n", (void *)curSel.client, - curSel.client ? curSel.client->index : -1, + CLINDEX(curSel.client), GetClientPid(curSel.client), GetClientCmdName(curSel.client)); #else fprintf(stderr, " CurrentSelections[].client [%p] index [%d]\n", (void *)curSel.client, - curSel.client ? curSel.client->index : -1); + CLINDEX(curSel.client); #endif fprintf(stderr, " CurrentSelections[].window [0x%x]\n", curSel.window); return; @@ -412,7 +414,7 @@ int SendSelectionNotifyEventToClient(ClientPtr client, Atom property) { #ifdef DEBUG - fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, client -> index); + fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, CLINDEX(client)); #endif xEvent x = {0}; @@ -483,8 +485,8 @@ void nxagentStoreSelectionOwner(SelectionOwner *owner, Selection *sel) void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow) { #ifdef DEBUG - fprintf(stderr, "%s: Called with client [%p] window [%p].\n", __func__, - (void *) pClient, (void *) pWindow); + fprintf(stderr, "%s: Called with client [%p] index [%d] window [%p] ([0x%x]).\n", __func__, + (void *) pClient, CLINDEX(pClient), (void *) pWindow, WINDOWID(pWindow)); #endif nxagentPrintClipboardStat("before nxagentClearClipboard"); @@ -797,7 +799,7 @@ void nxagentTransferSelection(int resource) { #ifdef DEBUG fprintf (stderr, "%s: WARNING! Inconsistent resource [%d] with current client [%d].\n", __func__, - resource, lastClientClientPtr -> index); + resource, CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -842,7 +844,7 @@ void nxagentTransferSelection(int resource) { #ifdef DEBUG fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -892,7 +894,7 @@ void nxagentTransferSelection(int resource) { #ifdef DEBUG fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -908,7 +910,7 @@ void nxagentTransferSelection(int resource) { #ifdef DEBUG fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__, - GetClientSelectionStageString(lastClientStage), lastClientClientPtr -> index); + GetClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr)); #endif break; @@ -945,7 +947,7 @@ void nxagentCollectPropertyEvent(int resource) { #ifdef DEBUG fprintf (stderr, "%s: Failed to get reply data for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -973,14 +975,14 @@ void nxagentCollectPropertyEvent(int resource) PrintClientSelectionStage(); #ifdef DEBUG fprintf (stderr, "%s: Got size notify event for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif if (ulReturnBytesLeft == 0) { #ifdef DEBUG fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -1009,14 +1011,14 @@ void nxagentCollectPropertyEvent(int resource) PrintClientSelectionStage(); #ifdef DEBUG fprintf (stderr, "%s: Got data notify event for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif if (ulReturnBytesLeft != 0) { #ifdef DEBUG fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -1048,7 +1050,7 @@ void nxagentCollectPropertyEvent(int resource) { #ifdef DEBUG fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__, - GetClientSelectionStageString(lastClientStage), lastClientClientPtr -> index); + GetClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr)); #endif break; @@ -1083,7 +1085,7 @@ void nxagentNotifySelection(XEvent *X) { #ifdef DEBUG fprintf(stderr, "%s: Starting selection transferral for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif /* @@ -1106,7 +1108,7 @@ void nxagentNotifySelection(XEvent *X) { #ifdef DEBUG fprintf(stderr, "%s: WARNING! Resetting selection transferral for client [%d].\n", __func__, - lastClientClientPtr -> index); + CLINDEX(lastClientClientPtr)); #endif endTransfer(SELECTION_FAULT); @@ -1281,7 +1283,7 @@ void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data, { #ifdef DEBUG fprintf(stderr, "%s: called with SelectionCallbackKind SelectionSetOwner\n", __func__); - fprintf(stderr, "%s: pCurSel->pWin [0x%x]\n", __func__, pCurSel->pWin ? pCurSel->pWin->drawable.id : NULL); + fprintf(stderr, "%s: pCurSel->pWin [0x%x]\n", __func__, WINDOWID(pCurSel->pWin)); fprintf(stderr, "%s: pCurSel->selection [%s]\n", __func__, NameForAtom(pCurSel->selection)); #endif @@ -1477,7 +1479,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, #ifdef TEST fprintf(stderr, "%s: client [%d] ask for sel [%s] " "on window [%x] prop [%s] target [%s].\n", __func__, - client -> index, validateString(NameForAtom(selection)), requestor, + CLINDEX(client), validateString(NameForAtom(selection)), requestor, validateString(NameForAtom(property)), validateString(NameForAtom(target))); #endif @@ -1675,7 +1677,7 @@ WindowPtr nxagentGetClipboardWindow(Atom property) (lastSelectionOwner[i].windowPtr != NULL)) { #ifdef DEBUG - fprintf(stderr, "%s: Returning last clipboard owner window [%p].\n", __func__, (void *)lastSelectionOwner[i].windowPtr); + fprintf(stderr, "%s: Returning last clipboard owner window [%p] (0x%x).\n", __func__, (void *)lastSelectionOwner[i].windowPtr, WINDOWID(lastSelectionOwner[i].windowPtr)); #endif return lastSelectionOwner[i].windowPtr; -- cgit v1.2.3 From 5e2487108e8f663752c94023568c5354c0df721b Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:48:01 +0200 Subject: Clipboard.c: TIMESTAMP is a special server target This is not a functional change, it only helps in clearer debugging output. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index ea1e4192e..7f3dec05e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -458,6 +458,13 @@ Bool nxagentValidServerTargets(Atom target) #endif return False; } + else if (target == serverTIMESTAMP) + { + #ifdef DEBUG + fprintf(stderr, "%s: special target [TIMESTAMP].\n", __func__); + #endif + return False; + } #ifdef DEBUG fprintf(stderr, "%s: invalid target [%u].\n", __func__, target); -- cgit v1.2.3 From 1af01db33bd4e16ad344aaae86ca590e5688b822 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 16:56:57 +0200 Subject: Clipboard.c: factor out nxagentReplyRequestSelection --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 65 +++++++++++++++----------- 1 file changed, 38 insertions(+), 27 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 7f3dec05e..1ee60ec76 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -595,10 +595,37 @@ void nxagentClearSelection(XEvent *X) nxagentPrintClipboardStat("after nxagentClearSelection"); } -void nxagentRequestSelection(XEvent *X) +/* + * Send a SelectionNotify event as reply to the RequestSelection + * event X. If success is True take the property from the event, else + * take None (which reports "failed/denied" to the requestor. + */ + +void nxagentReplyRequestSelection(XEvent *X, Bool success) { - XSelectionEvent eventSelection = {0}; + XSelectionEvent eventSelection = { + .requestor = X->xselectionrequest.requestor, + .selection = X->xselectionrequest.selection, + .target = X->xselectionrequest.target, + .time = X->xselectionrequest.time, + .property = X->xselectionrequest.property + }; + + if (!success) + { + #ifdef DEBUG + fprintf(stderr, "%s: denying request\n", __func__); + #endif + eventSelection.property = None; + } + + SendSelectionNotifyEventToServer(&eventSelection); + NXFlushDisplay(nxagentDisplay, NXFlushLink); +} + +void nxagentRequestSelection(XEvent *X) +{ #ifdef DEBUG fprintf(stderr, "%s: Got called.\n", __func__); #endif @@ -631,9 +658,6 @@ FIXME: Do we need this? SAFE_XFree(strTarget); */ - memset(&eventSelection, 0, sizeof(XSelectionEvent)); - eventSelection.property = None; - if (X->xselectionrequest.target == serverTARGETS) { Atom targets[] = {XA_STRING}; @@ -647,7 +671,7 @@ FIXME: Do we need this? PropModeReplace, (unsigned char*)&targets, numTargets); - eventSelection.property = X->xselectionrequest.property; + nxagentReplyRequestSelection(X, True); } else if (X->xselectionrequest.target == serverTIMESTAMP) { @@ -662,17 +686,14 @@ FIXME: Do we need this? PropModeReplace, (unsigned char *) &lastSelectionOwner[i].lastTimeChanged, 1); - eventSelection.property = X->xselectionrequest.property; + nxagentReplyRequestSelection(X, True); } } - - eventSelection.requestor = X->xselectionrequest.requestor; - eventSelection.selection = X->xselectionrequest.selection; - eventSelection.target = X->xselectionrequest.target; - eventSelection.time = X->xselectionrequest.time; - - SendSelectionNotifyEventToServer(&eventSelection); - + else + { + /* deny the request */ + nxagentReplyRequestSelection(X, False); + } return; } @@ -750,18 +771,8 @@ FIXME: Do we need this? } else { - /* - * Probably we must send a Notify - * to requestor with property None. - */ - - eventSelection.requestor = X->xselectionrequest.requestor; - eventSelection.selection = X->xselectionrequest.selection; - eventSelection.target = X->xselectionrequest.target; - eventSelection.property = None; - eventSelection.time = X->xselectionrequest.time; - - SendSelectionNotifyEventToServer(&eventSelection); + /* deny the request */ + nxagentReplyRequestSelection(X, False); } } } -- cgit v1.2.3 From 6f071341b766fc6adf99f15146dbc81298f64e2a Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 17:07:25 +0200 Subject: Clipboard.c: use designated initializers where appropriate --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 65 ++++++++++---------------- 1 file changed, 24 insertions(+), 41 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 1ee60ec76..f27342931 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -574,8 +574,7 @@ void nxagentClearSelection(XEvent *X) { if (lastSelectionOwner[i].client != NULL) { - xEvent x; - memset(&x, 0, sizeof(xEvent)); + xEvent x = {0}; x.u.u.type = SelectionClear; x.u.selectionClear.time = GetTimeInMillis(); x.u.selectionClear.window = lastSelectionOwner[i].window; @@ -606,9 +605,9 @@ void nxagentReplyRequestSelection(XEvent *X, Bool success) XSelectionEvent eventSelection = { .requestor = X->xselectionrequest.requestor, .selection = X->xselectionrequest.selection, - .target = X->xselectionrequest.target, - .time = X->xselectionrequest.time, - .property = X->xselectionrequest.property + .target = X->xselectionrequest.target, + .time = X->xselectionrequest.time, + .property = X->xselectionrequest.property }; if (!success) @@ -722,8 +721,6 @@ FIXME: Do we need this? if (lastSelectionOwner[i].client != NULL && nxagentOption(Clipboard) != ClipboardClient) { - xEvent x; - lastServerProperty = X->xselectionrequest.property; lastServerRequestor = X->xselectionrequest.requestor; lastServerTarget = X->xselectionrequest.target; @@ -734,7 +731,7 @@ FIXME: Do we need this? lastServerTime = X->xselectionrequest.time; - memset(&x, 0, sizeof(xEvent)); + xEvent x = {0}; x.u.u.type = SelectionRequest; x.u.selectionRequest.time = GetTimeInMillis(); x.u.selectionRequest.owner = lastSelectionOwner[i].window; @@ -1080,8 +1077,6 @@ void nxagentCollectPropertyEvent(int resource) void nxagentNotifySelection(XEvent *X) { - XSelectionEvent eventSelection; - #ifdef DEBUG fprintf(stderr, "%s: Got called.\n", __func__); #endif @@ -1199,23 +1194,15 @@ void nxagentNotifySelection(XEvent *X) } - memset(&eventSelection, 0, sizeof(XSelectionEvent)); - eventSelection.requestor = lastServerRequestor; - - eventSelection.selection = X->xselection.selection; - - /* - * eventSelection.target = X->xselection.target; - */ - - eventSelection.target = lastServerTarget; - eventSelection.property = lastServerProperty; - eventSelection.time = lastServerTime; - - /* - * eventSelection.time = CurrentTime; - * eventSelection.time = lastServerTime; - */ + XSelectionEvent eventSelection = { + .requestor = lastServerRequestor, + .selection = X->xselection.selection, + /* .target = X->xselection.target, */ + .target = lastServerTarget, + .property = lastServerProperty, + .time = lastServerTime, + /* .time = CurrentTime */ + }; SendSelectionNotifyEventToServer(&eventSelection); @@ -1646,14 +1633,18 @@ int nxagentSendNotify(xEvent *event) if (event->u.selectionNotify.property == clientCutProperty) { - XSelectionEvent x; /* * Setup selection notify event to real server. */ - memset(&x, 0, sizeof(XSelectionEvent)); - x.requestor = serverWindow; + XSelectionEvent eventSelection = { + .requestor = serverWindow, + .selection = event->u.selectionNotify.selection, + .target = event->u.selectionNotify.target, + .property = event->u.selectionNotify.property, + .time = CurrentTime, + }; /* * On real server, the right CLIPBOARD atom is @@ -1662,22 +1653,14 @@ int nxagentSendNotify(xEvent *event) if (event->u.selectionNotify.selection == MakeAtom("CLIPBOARD", 9, 0)) { - x.selection = lastSelectionOwner[nxagentClipboardSelection].selection; + eventSelection.selection = lastSelectionOwner[nxagentClipboardSelection].selection; } - else - { - x.selection = event->u.selectionNotify.selection; - } - - x.target = event->u.selectionNotify.target; - x.property = event->u.selectionNotify.property; - x.time = CurrentTime; #ifdef DEBUG - fprintf(stderr, "%s: Propagating clientCutProperty to requestor [%p].\n", __func__, (void *)x.requestor); + fprintf(stderr, "%s: Propagating clientCutProperty to requestor [%p].\n", __func__, (void *)eventSelection.requestor); #endif - SendSelectionNotifyEventToServer(&x); + SendSelectionNotifyEventToServer(&eventSelection); return 1; } -- cgit v1.2.3 From 9006e19aa76dabf9eb97635a90091addfd2d22db Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 17:14:06 +0200 Subject: Clipboard.c: cleanup in nxagentRequestSelection --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 29 ++++++++++++-------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index f27342931..03430438e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -724,46 +724,43 @@ FIXME: Do we need this? lastServerProperty = X->xselectionrequest.property; lastServerRequestor = X->xselectionrequest.requestor; lastServerTarget = X->xselectionrequest.target; + lastServerTime = X->xselectionrequest.time; /* by dimbor */ if (lastServerTarget != XA_STRING) lastServerTarget = serverUTF8_STRING; - lastServerTime = X->xselectionrequest.time; - + /* prepare the request (like XConvertSelection, but internally) */ xEvent x = {0}; x.u.u.type = SelectionRequest; x.u.selectionRequest.time = GetTimeInMillis(); x.u.selectionRequest.owner = lastSelectionOwner[i].window; + x.u.selectionRequest.selection = CurrentSelections[i].selection; + x.u.selectionRequest.property = clientCutProperty; + x.u.selectionRequest.requestor = screenInfo.screens[0]->root->drawable.id; /* Fictitious window.*/ /* - * Fictitious window. - */ - - x.u.selectionRequest.requestor = screenInfo.screens[0]->root->drawable.id; - - /* - * Don't send the same window, some programs are - * clever and verify cut and paste operations - * inside the same window and don't Notify at all. + * Don't send the same window, some programs are clever and + * verify cut and paste operations inside the same window and + * don't Notify at all. * * x.u.selectionRequest.requestor = lastSelectionOwnerWindow; */ - x.u.selectionRequest.selection = CurrentSelections[i].selection; - /* by dimbor (idea from zahvatov) */ if (X->xselectionrequest.target != XA_STRING) x.u.selectionRequest.target = clientUTF8_STRING; else x.u.selectionRequest.target = XA_STRING; - x.u.selectionRequest.property = clientCutProperty; - SendEventToClient(lastSelectionOwner[i].client, &x); #ifdef DEBUG - fprintf(stderr, "%s: Executed TryClientEvents with clientCutProperty.\n", __func__); + fprintf(stderr, "%s: sent SelectionRequest event to client [%d] property [%d][%s] target [%d][%s] requestor [0x%x].\n", __func__, + CLINDEX(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); #endif } else -- cgit v1.2.3 From cb3e44a17e288fc68ce55e22e8e56a6a8f97258e Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 17:41:48 +0200 Subject: Clipboard.c: Refactor nxagentCollectPropertyEvent --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 160 ++++++++++++------------- 1 file changed, 77 insertions(+), 83 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 03430438e..319070d47 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -930,6 +930,13 @@ void nxagentTransferSelection(int resource) } } +/* + Called from Events.c/nxagentHandlePropertyNotify + + This event is generated after XChangeProperty(), XDeleteProperty() or + XGetWindowProperty(delete=True) +*/ + void nxagentCollectPropertyEvent(int resource) { Atom atomReturnType; @@ -940,9 +947,8 @@ void nxagentCollectPropertyEvent(int resource) int result; /* - * We have received the notification so - * we can safely retrieve data from the - * client structure. + * We have received the notification so we can safely retrieve data + * from the client structure. */ result = NXGetCollectedProperty(nxagentDisplay, @@ -958,117 +964,105 @@ void nxagentCollectPropertyEvent(int resource) if (result == 0) { #ifdef DEBUG - fprintf (stderr, "%s: Failed to get reply data for client [%d].\n", __func__, - CLINDEX(lastClientClientPtr)); + fprintf (stderr, "%s: Failed to get reply data.\n", __func__); #endif endTransfer(SELECTION_FAULT); - - SAFE_XFree(pszReturnData); - return; } - - if (resultFormat != 8 && resultFormat != 16 && resultFormat != 32) + else if (resultFormat != 8 && resultFormat != 16 && resultFormat != 32) { #ifdef DEBUG - fprintf (stderr, "%s: WARNING! Invalid property value.\n", __func__); + fprintf (stderr, "%s: WARNING! Invalid property format.\n", __func__); #endif endTransfer(SELECTION_FAULT); - - SAFE_XFree(pszReturnData); - return; } - - switch (lastClientStage) + else { - case SelectionStageWaitSize: + switch (lastClientStage) { - PrintClientSelectionStage(); - #ifdef DEBUG - fprintf (stderr, "%s: Got size notify event for client [%d].\n", __func__, - CLINDEX(lastClientClientPtr)); - #endif - - if (ulReturnBytesLeft == 0) + case SelectionStageWaitSize: { + PrintClientSelectionStage(); #ifdef DEBUG - fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, + fprintf (stderr, "%s: Got size notify event for client [%d].\n", __func__, CLINDEX(lastClientClientPtr)); #endif - endTransfer(SELECTION_FAULT); - - SAFE_XFree(pszReturnData); - return; - } - - #ifdef DEBUG - fprintf(stderr, "%s: Got property size from remote server.\n", __func__); - #endif - - /* - * Request the selection data now. - */ - - lastClientPropertySize = ulReturnBytesLeft; - SetClientSelectionStage(QueryData); + if (ulReturnBytesLeft == 0) + { + #ifdef DEBUG + fprintf (stderr, "%s: Aborting selection notify procedure.\n", __func__); + #endif - nxagentTransferSelection(resource); + endTransfer(SELECTION_FAULT); + } + else + { + #ifdef DEBUG + fprintf(stderr, "%s: Got property size from remote server.\n", __func__); + #endif - break; - } - case SelectionStageWaitData: - { - PrintClientSelectionStage(); - #ifdef DEBUG - fprintf (stderr, "%s: Got data notify event for client [%d].\n", __func__, - CLINDEX(lastClientClientPtr)); - #endif + /* + * Request the selection data now. + */ + lastClientPropertySize = ulReturnBytesLeft; + SetClientSelectionStage(QueryData); - if (ulReturnBytesLeft != 0) + nxagentTransferSelection(resource); + } + break; + } + case SelectionStageWaitData: { + PrintClientSelectionStage(); #ifdef DEBUG - fprintf (stderr, "%s: Aborting selection notify procedure for client [%d].\n", __func__, + fprintf (stderr, "%s: Got data notify event for client [%d].\n", __func__, CLINDEX(lastClientClientPtr)); #endif - endTransfer(SELECTION_FAULT); - - SAFE_XFree(pszReturnData); - return; - } - - #ifdef DEBUG - fprintf(stderr, "%s: Got property content from remote server.\n", __func__); - #endif - - ChangeWindowProperty(lastClientWindowPtr, - lastClientProperty, - lastClientTarget, - resultFormat, PropModeReplace, - ulReturnItems, pszReturnData, 1); + if (ulReturnBytesLeft != 0) + { + #ifdef DEBUG + fprintf (stderr, "%s: Aborting selection notify procedure.\n", __func__); + #endif - #ifdef DEBUG - fprintf(stderr, "%s: Selection property [%s] changed to [%s]\n", __func__, - validateString(NameForAtom(lastClientProperty)), pszReturnData); - #endif + endTransfer(SELECTION_FAULT); + } + else + { + #ifdef DEBUG + fprintf(stderr, "%s: Got property content from remote server.\n", __func__); + #endif - endTransfer(SELECTION_SUCCESS); + ChangeWindowProperty(lastClientWindowPtr, + lastClientProperty, + lastClientTarget, + resultFormat, PropModeReplace, + ulReturnItems, pszReturnData, 1); - break; - } - default: - { - #ifdef DEBUG - fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__, - GetClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr)); - #endif + #ifdef DEBUG + fprintf(stderr, "%s: Selection property [%d][%s] changed to [\"%*.*s\"...]\n", __func__, + lastClientProperty, validateString(NameForAtom(lastClientProperty)), + (int)(min(20, ulReturnItems * resultFormat / 8)), + (int)(min(20, ulReturnItems * resultFormat / 8)), + pszReturnData); + #endif - break; + endTransfer(SELECTION_SUCCESS); + } + break; + } + default: + { + #ifdef DEBUG + fprintf (stderr, "%s: WARNING! Inconsistent state [%s] for client [%d].\n", __func__, + GetClientSelectionStageString(lastClientStage), CLINDEX(lastClientClientPtr)); + #endif + break; + } } } - SAFE_XFree(pszReturnData); } -- cgit v1.2.3 From b393bca69640e27671e44a6c283b1499da9cacf9 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 17:52:34 +0200 Subject: Clipboard.c: scope improvements --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 319070d47..7d6b9ae2b 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -805,8 +805,6 @@ static void endTransfer(Bool success) void nxagentTransferSelection(int resource) { - int result; - if (lastClientClientPtr -> index != resource) { #ifdef DEBUG @@ -823,6 +821,8 @@ void nxagentTransferSelection(int resource) { case SelectionStageQuerySize: { + int result; + PrintClientSelectionStage(); /* * Don't get data yet, just get size. We skip @@ -870,6 +870,8 @@ void nxagentTransferSelection(int resource) } case SelectionStageQueryData: { + int result; + PrintClientSelectionStage(); /* @@ -1210,8 +1212,6 @@ void nxagentNotifySelection(XEvent *X) void nxagentResetSelectionOwner(void) { - int i; - if (lastServerRequestor != None) { #ifdef TEST @@ -1226,7 +1226,7 @@ void nxagentResetSelectionOwner(void) * Only for PRIMARY and CLIPBOARD selections. */ - for (i = 0; i < nxagentMaxSelections; i++) + for (int i = 0; i < nxagentMaxSelections; i++) { XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime); @@ -1415,8 +1415,6 @@ FIXME: Why this pointer can be not a valid int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, Window requestor, Atom property, Atom target, Time time) { - const char *strTarget; - if (agentClipboardStatus != 1 || nxagentOption(Clipboard) == ClipboardServer) { @@ -1479,7 +1477,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, validateString(NameForAtom(property)), validateString(NameForAtom(target))); #endif - strTarget = NameForAtom(target); + const char *strTarget = NameForAtom(target); if (strTarget == NULL) { @@ -1682,7 +1680,6 @@ WindowPtr nxagentGetClipboardWindow(Atom property) int nxagentInitClipboard(WindowPtr pWin) { - int i; Window iWindow = nxagentWindow(pWin); #ifdef DEBUG @@ -1763,7 +1760,7 @@ int nxagentInitClipboard(WindowPtr pWin) fprintf(stderr, "%s: Registering for XFixesSelectionNotify events.\n", __func__); #endif - for (i = 0; i < nxagentMaxSelections; i++) + for (int i = 0; i < nxagentMaxSelections; i++) { XFixesSelectSelectionInput(nxagentDisplay, iWindow, lastSelectionOwner[i].selection, @@ -1803,7 +1800,7 @@ int nxagentInitClipboard(WindowPtr pWin) * Only for PRIMARY and CLIPBOARD selections. */ - for (i = 0; i < nxagentMaxSelections; i++) + for (int i = 0; i < nxagentMaxSelections; i++) { if (lastSelectionOwner[i].client && lastSelectionOwner[i].window) { -- cgit v1.2.3 From 249e4321c67e9c3d9a4b6b0ee4ea80ef9ea7f63b Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 17:54:55 +0200 Subject: Clipboard.c: introduce nxagentInitSelectionOwner --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 7d6b9ae2b..9ec160650 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1678,6 +1678,15 @@ WindowPtr nxagentGetClipboardWindow(Atom property) } } +void nxagentInitSelectionOwner(SelectionOwner *owner, Atom selection) +{ + owner->selection = selection; + owner->client = NullClient; + owner->window = screenInfo.screens[0]->root->drawable.id; + owner->windowPtr = NULL; + owner->lastTimeChanged = GetTimeInMillis(); +} + int nxagentInitClipboard(WindowPtr pWin) { Window iWindow = nxagentWindow(pWin); @@ -1697,17 +1706,8 @@ int nxagentInitClipboard(WindowPtr pWin) serverTIMESTAMP = nxagentAtoms[11]; /* TIMESTAMP */ - lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY; - lastSelectionOwner[nxagentPrimarySelection].client = NullClient; - lastSelectionOwner[nxagentPrimarySelection].window = screenInfo.screens[0]->root->drawable.id; - lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL; - lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis(); - - lastSelectionOwner[nxagentClipboardSelection].selection = nxagentAtoms[10]; /* CLIPBOARD */ - lastSelectionOwner[nxagentClipboardSelection].client = NullClient; - lastSelectionOwner[nxagentClipboardSelection].window = screenInfo.screens[0]->root->drawable.id; - lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL; - lastSelectionOwner[nxagentClipboardSelection].lastTimeChanged = GetTimeInMillis(); + nxagentInitSelectionOwner(&lastSelectionOwner[nxagentPrimarySelection], XA_PRIMARY); + nxagentInitSelectionOwner(&lastSelectionOwner[nxagentClipboardSelection], nxagentAtoms[10]); /* CLIPBOARD */ #ifdef NXAGENT_TIMESTAMP { -- cgit v1.2.3 From a6c57d6ff5f6ce86074e3b499a0bf255741a76e7 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 17:57:37 +0200 Subject: Clipboard.c: improve readability by using an if clause --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 9ec160650..c11da0f96 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1562,8 +1562,9 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, lastClientSelection = selection; lastClientTarget = target; - lastClientReqTime = (GetTimeInMillis() - lastClientReqTime) > 5000 ? - GetTimeInMillis() : lastClientReqTime; + /* if the last client request time is more than 5s ago update it. Why? */ + if ((GetTimeInMillis() - lastClientReqTime) > 5000) + lastClientReqTime = GetTimeInMillis(); if (selection == MakeAtom("CLIPBOARD", 9, 0)) { -- cgit v1.2.3 From 1bf68e328bd8a1ef9248d9a037781e41b95c35ff Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 18:00:49 +0200 Subject: Clipboard.c: whitespace fixes --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index c11da0f96..7331e3886 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -663,13 +663,13 @@ FIXME: Do we need this? int numTargets = 1; XChangeProperty (nxagentDisplay, - X->xselectionrequest.requestor, - X->xselectionrequest.property, - XInternAtom(nxagentDisplay, "ATOM", 0), - sizeof(Atom)*8, - PropModeReplace, - (unsigned char*)&targets, - numTargets); + X->xselectionrequest.requestor, + X->xselectionrequest.property, + XInternAtom(nxagentDisplay, "ATOM", 0), + sizeof(Atom)*8, + PropModeReplace, + (unsigned char*)&targets, + numTargets); nxagentReplyRequestSelection(X, True); } else if (X->xselectionrequest.target == serverTIMESTAMP) @@ -678,13 +678,13 @@ FIXME: Do we need this? if (i < nxagentMaxSelections) { XChangeProperty(nxagentDisplay, - X->xselectionrequest.requestor, - X->xselectionrequest.property, - XA_INTEGER, - 32, - PropModeReplace, - (unsigned char *) &lastSelectionOwner[i].lastTimeChanged, - 1); + X->xselectionrequest.requestor, + X->xselectionrequest.property, + XA_INTEGER, + 32, + PropModeReplace, + (unsigned char *) &lastSelectionOwner[i].lastTimeChanged, + 1); nxagentReplyRequestSelection(X, True); } } -- cgit v1.2.3 From 9a144136d76589b2b7a7a55a38f2b8bd64ac7e5f Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Mon, 5 Aug 2019 18:22:00 +0200 Subject: Clipboard.c: remove unneccessary return --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 7331e3886..8255612ac 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1119,8 +1119,6 @@ void nxagentNotifySelection(XEvent *X) endTransfer(SELECTION_FAULT); } - - return; } else { -- cgit v1.2.3 From 92ad24a3b7069f009e2abe0f8b46cca717db110a Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Tue, 6 Aug 2019 22:54:55 +0200 Subject: Clipboard.c: translate internal to external atom serverClientCutProperty is the external equivalent of the internal clientCutProperty. We need it on the server side, too, because we use the property on the serverWindow on the real X server. We could (mis)use serverCutProperty here but this might introduce race conditions when both sides request selections simultaneously. --- nx-X11/programs/Xserver/hw/nxagent/Atoms.c | 1 + nx-X11/programs/Xserver/hw/nxagent/Atoms.h | 2 +- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 24 ++++++++++++++++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c index 1c48df61c..d9d203faa 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c @@ -90,6 +90,7 @@ static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] = "UTF8_STRING", /* 12 */ "_NET_WM_STATE", /* 13 */ "_NET_WM_STATE_FULLSCREEN", /* 14 */ + "NX_CUT_BUFFER_CLIENT", /* 15 */ NULL, NULL }; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h index 08eb1cfff..cbbb7bd1d 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h @@ -30,7 +30,7 @@ #include "../../include/window.h" #include "screenint.h" -#define NXAGENT_NUMBER_OF_ATOMS 16 +#define NXAGENT_NUMBER_OF_ATOMS 17 extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS]; diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 8255612ac..5d6c7cd7f 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -129,6 +129,7 @@ static Atom serverTARGETS; static Atom serverTIMESTAMP; static Atom serverTEXT; static Atom serverUTF8_STRING; +static Atom serverClientCutProperty; static Atom clientTARGETS; static Atom clientTEXT; static Atom clientCOMPOUND_TEXT; @@ -328,6 +329,8 @@ void nxagentPrintClipboardStat(char *header) fprintf(stderr, " serverUTF8_STRING [% 4d][%s]\n", serverUTF8_STRING, s); SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverCutProperty); fprintf(stderr, " serverCutProperty [% 4d][%s]\n", serverCutProperty, s); + SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverClientCutProperty); + fprintf(stderr, " serverClientCutProperty [% 4d][%s]\n", serverClientCutProperty, s); SAFE_XFree(s); s = XGetAtomName(nxagentDisplay, serverTIMESTAMP); fprintf(stderr, " serverTIMESTAMP [% 4d][%s]\n", serverTIMESTAMP, s); @@ -1127,7 +1130,7 @@ void nxagentNotifySelection(XEvent *X) { if ((lastSelectionOwner[i].client != NULL) && (lastSelectionOwner[i].windowPtr != NULL) && - (X->xselection.property == clientCutProperty)) + (X->xselection.property == serverClientCutProperty)) { Atom atomReturnType; int resultFormat; @@ -1624,19 +1627,30 @@ int nxagentSendNotify(xEvent *event) /* * Setup selection notify event to real server. + * + * .property must be a server-side Atom. As this property is only + * set on our serverWindow and normally there are no other + * properties except serverCutProperty, the only thing we need to + * ensure is that the internal Atom clientCutProperty must differ + * from the server-side serverCutProperty Atom. The actual name is + * not important. To be clean here we use a seperate + * serverClientCutProperty. */ XSelectionEvent eventSelection = { .requestor = serverWindow, .selection = event->u.selectionNotify.selection, .target = event->u.selectionNotify.target, - .property = event->u.selectionNotify.property, + .property = serverClientCutProperty, .time = CurrentTime, }; /* - * On real server, the right CLIPBOARD atom is - * XInternAtom(nxagentDisplay, "CLIPBOARD", 1). + * On the real server, the right CLIPBOARD atom is + * XInternAtom(nxagentDisplay, "CLIPBOARD", 1), which is stored in + * lastSelectionOwner[nxagentClipboardSelection].selection. For + * PRIMARY there's nothing to map because that is identical on all + * X servers (defined in Xatom.h). */ if (event->u.selectionNotify.selection == MakeAtom("CLIPBOARD", 9, 0)) @@ -1728,6 +1742,8 @@ int nxagentInitClipboard(WindowPtr pWin) serverTARGETS = nxagentAtoms[6]; /* TARGETS */ serverTEXT = nxagentAtoms[7]; /* TEXT */ serverUTF8_STRING = nxagentAtoms[12]; /* UTF8_STRING */ + /* see nxagentSendNotify for an explanation */ + serverClientCutProperty = nxagentAtoms[15]; /* NX_CUT_BUFFER_CLIENT */ if (serverCutProperty == None) { -- cgit v1.2.3 From e985f7111a46a2c9d7fb4985109a5c3b1bdc6a85 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 20:48:44 +0200 Subject: Clipboard.c: rework debug prints add new debug output, extend existing, drop meaningless --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 224 ++++++++++++++++++------- 1 file changed, 167 insertions(+), 57 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 5d6c7cd7f..6ba41a313 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -237,7 +237,10 @@ void nxagentPrintSelectionStat(int sel) CLINDEX(lOwner.client)); #endif fprintf(stderr, " lastSelectionOwner[].window [0x%x]\n", lOwner.window); - fprintf(stderr, " lastSelectionOwner[].windowPtr [%p]\n", (void *)lOwner.windowPtr); + if (lOwner.windowPtr) + fprintf(stderr, " lastSelectionOwner[].windowPtr [%p] ([0x%x]\n", (void *)lOwner.windowPtr, WINDOWID(lOwner.windowPtr)); + else + fprintf(stderr, " lastSelectionOwner[].windowPtr -\n"); fprintf(stderr, " lastSelectionOwner[].lastTimeChanged [%u]\n", lOwner.lastTimeChanged); /* @@ -304,7 +307,10 @@ void nxagentPrintClipboardStat(char *header) fprintf(stderr, " lastServerTime (Time) [%u]\n", lastServerTime); fprintf(stderr, "lastClient\n"); - fprintf(stderr, " lastClientWindowPtr (WindowPtr) [%p]\n", (void *)lastClientWindowPtr); + if (lastClientWindowPtr) + 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, " lastClientRequestor (Window) [0x%x]\n", lastClientRequestor); fprintf(stderr, " lastClientProperty (Atom) [% 4d][%s]\n", lastClientProperty, NameForAtom(lastClientProperty)); @@ -370,10 +376,6 @@ Status SendSelectionNotifyEventToServer(XSelectionEvent *event_to_send) event_to_send->send_event = True; event_to_send->display = nxagentDisplay; - #ifdef DEBUG - fprintf(stderr, "%s: Sending event to requestor [%p].\n", __func__, (void *)w); - #endif - Status result = XSendEvent(nxagentDisplay, w, False, 0L, (XEvent *)event_to_send); #ifdef DEBUG @@ -416,10 +418,6 @@ int SendSelectionNotifyEventToClient(ClientPtr client, Atom target, Atom property) { - #ifdef DEBUG - fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, CLINDEX(client)); - #endif - xEvent x = {0}; x.u.u.type = SelectionNotify; x.u.selectionNotify.time = time; @@ -427,6 +425,16 @@ int SendSelectionNotifyEventToClient(ClientPtr client, x.u.selectionNotify.selection = selection; x.u.selectionNotify.target = target; x.u.selectionNotify.property = property; + + #ifdef DEBUG + if (property == None) + fprintf (stderr, "%s: Denying request to client [%d].\n", __func__, + CLINDEX(client)); + else + fprintf (stderr, "%s: Sending event to client [%d].\n", __func__, + CLINDEX(client)); + #endif + return SendEventToClient(client, &x); } @@ -629,7 +637,24 @@ void nxagentReplyRequestSelection(XEvent *X, Bool success) void nxagentRequestSelection(XEvent *X) { #ifdef DEBUG - fprintf(stderr, "%s: Got called.\n", __func__); + { + char *strTarget = XGetAtomName(nxagentDisplay, X->xselectionrequest.target); + char *strSelection = XGetAtomName(nxagentDisplay, X->xselectionrequest.selection); + char *strProperty = XGetAtomName(nxagentDisplay, X->xselectionrequest.property); + + fprintf(stderr, "%s: Received SelectionRequest from real server: selection [%ld][%s] " \ + "target [%ld][%s] requestor [%s/0x%lx] destination [%ld][%s] lastServerRequestor [0x%x]\n", + __func__, + X->xselectionrequest.selection, validateString(strSelection), + X->xselectionrequest.target, validateString(strTarget), + DisplayString(nxagentDisplay), X->xselectionrequest.requestor, + X->xselectionrequest.property, validateString(strProperty), + lastServerRequestor); + + SAFE_XFree(strTarget); + SAFE_XFree(strSelection); + SAFE_XFree(strProperty); + } #endif nxagentPrintClipboardStat("before nxagentRequestSelection"); @@ -665,14 +690,26 @@ FIXME: Do we need this? Atom targets[] = {XA_STRING}; int numTargets = 1; - XChangeProperty (nxagentDisplay, - X->xselectionrequest.requestor, - X->xselectionrequest.property, - XInternAtom(nxagentDisplay, "ATOM", 0), - sizeof(Atom)*8, - PropModeReplace, - (unsigned char*)&targets, - numTargets); + #ifdef DEBUG + fprintf(stderr, "%s: available targets:\n", __func__); + for (int i = 0; i < numTargets; i++) + fprintf(stderr, "%s: %s\n", __func__, NameForAtom(targets[i])); + fprintf(stderr, "\n"); + #endif + + /* + * pass on the requested list by setting the property provided + * by the requestor accordingly. + */ + XChangeProperty(nxagentDisplay, + X->xselectionrequest.requestor, + X->xselectionrequest.property, + XInternAtom(nxagentDisplay, "ATOM", 0), + sizeof(Atom)*8, + PropModeReplace, + (unsigned char*)&targets, + numTargets); + nxagentReplyRequestSelection(X, True); } else if (X->xselectionrequest.target == serverTIMESTAMP) @@ -759,7 +796,8 @@ FIXME: Do we need this? SendEventToClient(lastSelectionOwner[i].client, &x); #ifdef DEBUG - fprintf(stderr, "%s: sent SelectionRequest event to client [%d] property [%d][%s] target [%d][%s] requestor [0x%x].\n", __func__, + fprintf(stderr, "%s: sent SelectionRequest event to client [%d] property [%d][%s]" \ + "target [%d][%s] requestor [0x%x].\n", __func__, CLINDEX(lastSelectionOwner[i].client), x.u.selectionRequest.property, NameForAtom(x.u.selectionRequest.property), x.u.selectionRequest.target, NameForAtom(x.u.selectionRequest.target), @@ -792,6 +830,15 @@ static void endTransfer(Bool success) 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 + SendSelectionNotifyEventToClient(lastClientClientPtr, lastClientTime, lastClientRequestor, @@ -1073,17 +1120,23 @@ void nxagentCollectPropertyEvent(int resource) void nxagentNotifySelection(XEvent *X) { - #ifdef DEBUG - fprintf(stderr, "%s: Got called.\n", __func__); - #endif - if (agentClipboardStatus != 1) { return; } #ifdef DEBUG - fprintf(stderr, "%s: SelectionNotify event.\n", __func__); + { + XSelectionEvent * e = (XSelectionEvent *)X; + char * s = XGetAtomName(nxagentDisplay, e->property); + char * t = XGetAtomName(nxagentDisplay, e->target); + fprintf(stderr, "%s: SelectionNotify event from real X server, property "\ + "[%ld][%s] requestor [0x%lx] target [%ld][%s] time [%ld] send_event [%d].\n", + __func__, e->property, validateString(s), e->requestor, e->target, + validateString(t), e->time, e->send_event); + SAFE_XFree(s); + SAFE_XFree(t); + } #endif PrintClientSelectionStage(); @@ -1143,12 +1196,12 @@ void nxagentNotifySelection(XEvent *X) &ulReturnItems, &ulReturnBytesLeft, &pszReturnData); #ifdef DEBUG - fprintf(stderr, "%s: GetWindowProperty() returned [%s]\n", __func__, GetXErrorString(result)); + fprintf(stderr, "%s: GetWindowProperty() window [0x%x] property [%d] returned [%s]\n", __func__, + lastSelectionOwner[i].window, clientCutProperty, GetXErrorString(result)); #endif if (result == BadAlloc || result == BadAtom || result == BadWindow || result == BadValue) { - fprintf (stderr, "Client GetProperty failed. Error = %s", GetXErrorString(result)); lastServerProperty = None; } else @@ -1158,13 +1211,13 @@ void nxagentNotifySelection(XEvent *X) &resultFormat, &ulReturnItems, &ulReturnBytesLeft, &pszReturnData); #ifdef DEBUG - fprintf(stderr, "%s: GetWindowProperty() returned [%s]\n", __func__, GetXErrorString(result)); + fprintf(stderr, "%s: GetWindowProperty() window [0x%x] property [%d] returned [%s]\n", __func__, + lastSelectionOwner[i].window, clientCutProperty, GetXErrorString(result)); #endif if (result == BadAlloc || result == BadAtom || result == BadWindow || result == BadValue) { - fprintf (stderr, "SelectionNotify - XChangeProperty failed. Error = %s\n", GetXErrorString(result)); lastServerProperty = None; } else @@ -1177,15 +1230,26 @@ void nxagentNotifySelection(XEvent *X) PropModeReplace, pszReturnData, ulReturnItems); + + #ifdef DEBUG + { + char *s = XGetAtomName(nxagentDisplay, lastServerProperty); + fprintf(stderr, "%s: XChangeProperty sent to window [0x%x] for property [%d][%s] value [\"%*.*s\"...]\n", + __func__, + lastServerRequestor, + lastServerProperty, + s, + (int)(min(20, ulReturnItems * 8 / 8)), + (int)(min(20, ulReturnItems * 8 / 8)), + pszReturnData); + SAFE_XFree(s); + } + #endif } - #ifdef DEBUG - fprintf(stderr, "%s: XChangeProperty() returned [%s]\n", __func__, GetXErrorString(result)); - #endif /* * SAFE_XFree(pszReturnData); */ - } XSelectionEvent eventSelection = { @@ -1197,6 +1261,10 @@ void nxagentNotifySelection(XEvent *X) .time = lastServerTime, /* .time = CurrentTime */ }; + #ifdef DEBUG + fprintf(stderr, "%s: Sending SelectionNotify event to requestor [%p].\n", __func__, + (void *)eventSelection.requestor); + #endif SendSelectionNotifyEventToServer(&eventSelection); @@ -1215,7 +1283,11 @@ void nxagentResetSelectionOwner(void) { if (lastServerRequestor != None) { - #ifdef TEST + /* + * we are in the process of communicating back and forth between + * real X server and nxagent's clients - let's not disturb. + */ + #if defined(TEST) || defined(DEBUG) fprintf(stderr, "%s: WARNING! Requestor window [0x%x] already found.\n", __func__, lastServerRequestor); #endif @@ -1232,7 +1304,7 @@ void nxagentResetSelectionOwner(void) XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime); #ifdef DEBUG - fprintf(stderr, "%s: Reset clipboard state.\n", __func__); + fprintf(stderr, "%s: Reset selection state for selection [%d].\n", __func__, i); #endif nxagentClearSelectionOwner(&lastSelectionOwner[i]); @@ -1318,10 +1390,6 @@ void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data, void nxagentSetSelectionOwner(Selection *pSelection) { - #ifdef DEBUG - fprintf(stderr, "%s: Got called.\n", __func__); - #endif - if (agentClipboardStatus != 1) { return; @@ -1332,10 +1400,14 @@ void nxagentSetSelectionOwner(Selection *pSelection) serverWindow); #endif - #ifdef TEST + #if defined(TEST) || defined(DEBUG) if (lastServerRequestor != None) { - fprintf (stderr, "%s: WARNING! Requestor window [0x%x] already found.\n", __func__, + /* + * we are in the process of communicating back and forth between + * real X server and nxagent's clients - let's not disturb + */ + fprintf (stderr, "%s: WARNING! Requestor window [0x%x] already set.\n", __func__, lastServerRequestor); } #endif @@ -1349,10 +1421,18 @@ void nxagentSetSelectionOwner(Selection *pSelection) if (pSelection->selection == CurrentSelections[i].selection) { #ifdef DEBUG - fprintf(stderr, "%s: lastSelectionOwner.client [0x%x] -> [0x%x]\n", __func__, lastSelectionOwner[i].client, pSelection->client); - fprintf(stderr, "%s: lastSelectionOwner.window [0x%x] -> [0x%x]\n", __func__, lastSelectionOwner[i].window, pSelection->window); - fprintf(stderr, "%s: lastSelectionOwner.windowPtr [0x%x] -> [0x%x] [0x%x] (serverWindow: [0x%x])\n", __func__, lastSelectionOwner[i].windowPtr, pSelection->pWin, nxagentWindow(pSelection->pWin), serverWindow); - fprintf(stderr, "%s: lastSelectionOwner.lastTimeChanged [%d]\n", __func__, lastSelectionOwner[i].lastTimeChanged); + 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.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__, + (void *)lastSelectionOwner[i].windowPtr, (void *)pSelection->pWin, + nxagentWindow(pSelection->pWin), serverWindow); + fprintf(stderr, "%s: lastSelectionOwner.lastTimeChanged [%d]\n", __func__, + lastSelectionOwner[i].lastTimeChanged); #endif /* @@ -1471,17 +1551,21 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, } } - #ifdef TEST - fprintf(stderr, "%s: client [%d] ask for sel [%s] " - "on window [%x] prop [%s] target [%s].\n", __func__, + #if defined(TEST) || defined(DEBUG) + fprintf(stderr, "%s: client [%d] requests sel [%s] " + "on window [%x] prop [%d][%s] target [%d][%s].\n", __func__, CLINDEX(client), validateString(NameForAtom(selection)), requestor, - validateString(NameForAtom(property)), validateString(NameForAtom(target))); + property, validateString(NameForAtom(property)), + target, validateString(NameForAtom(target))); #endif const char *strTarget = NameForAtom(target); if (strTarget == NULL) { + #ifdef DEBUG + fprintf(stderr, "%s: cannot find name for target Atom [%d] - returning\n", __func__, target); + #endif return 1; } @@ -1491,6 +1575,13 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, Atom targets[] = {XA_STRING, clientUTF8_STRING, clientTEXT, clientCOMPOUND_TEXT}; int numTargets = 4; + #ifdef DEBUG + fprintf(stderr, "%s: available targets:\n", __func__); + for (int i = 0; i < numTargets; i++) + fprintf(stderr, "%s: %s\n", __func__, NameForAtom(targets[i])); + fprintf(stderr, "\n"); + #endif + ChangeWindowProperty(pWin, property, MakeAtom("ATOM", 4, 1), @@ -1574,11 +1665,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, if (target == clientUTF8_STRING) { + #ifdef DEBUG + fprintf(stderr, "%s: Sending XConvertSelection with target [%d][UTF8_STRING], property [%d][NX_CUT_BUFFER_SERVER]\n", __func__, + serverUTF8_STRING, serverCutProperty); + #endif XConvertSelection(nxagentDisplay, selection, serverUTF8_STRING, serverCutProperty, serverWindow, CurrentTime); } else { + #ifdef DEBUG + fprintf(stderr, "%s: Sending XConvertSelection with target [%d][%s], property [%d][NX_CUT_BUFFER_SERVER]\n", __func__, + XA_STRING, validateString(NameForAtom(XA_STRING)), serverCutProperty); + #endif + XConvertSelection(nxagentDisplay, selection, XA_STRING, serverCutProperty, serverWindow, CurrentTime); } @@ -1592,11 +1692,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, } else { - #ifdef DEBUG - fprintf(stderr, "%s: Xserver generates a SelectionNotify event " - "to the requestor with property None.\n", __func__); - #endif - + /* deny request */ SendSelectionNotifyEventToClient(client, time, requestor, selection, target, None); return 1; @@ -1619,7 +1715,11 @@ int nxagentSendNotify(xEvent *event) } #ifdef DEBUG - fprintf(stderr, "%s: property is [%d][%s].\n", __func__, event->u.selectionNotify.property, NameForAtom(event->u.selectionNotify.property)); + fprintf(stderr, "%s: property is [%d][%s].\n", __func__, + event->u.selectionNotify.property, + NameForAtom(event->u.selectionNotify.property)); + fprintf(stderr, "%s: requestor is [0x%x].\n", __func__, event->u.selectionNotify.requestor); + fprintf(stderr, "%s: lastServerRequestor is [0x%x].\n", __func__, lastServerRequestor); #endif if (event->u.selectionNotify.property == clientCutProperty) @@ -1659,7 +1759,15 @@ int nxagentSendNotify(xEvent *event) } #ifdef DEBUG - fprintf(stderr, "%s: Propagating clientCutProperty to requestor [%p].\n", __func__, (void *)eventSelection.requestor); + fprintf(stderr, "%s: mapping local to remote Atom: [%d] -> [%ld] [%s]\n", __func__, + event->u.selectionNotify.selection, eventSelection.selection, + NameForAtom(event->u.selectionNotify.selection)); + fprintf(stderr, "%s: mapping local to remote Atom: [%d] -> [%ld] [%s]\n", __func__, + event->u.selectionNotify.target, eventSelection.target, + NameForAtom(event->u.selectionNotify.target)); + fprintf(stderr, "%s: mapping local to remote Atom: [%d] -> [%ld] [%s]\n", __func__, + event->u.selectionNotify.property, eventSelection.property, + NameForAtom(event->u.selectionNotify.property)); #endif SendSelectionNotifyEventToServer(&eventSelection); @@ -1680,7 +1788,9 @@ WindowPtr nxagentGetClipboardWindow(Atom property) (lastSelectionOwner[i].windowPtr != NULL)) { #ifdef DEBUG - fprintf(stderr, "%s: Returning last clipboard owner window [%p] (0x%x).\n", __func__, (void *)lastSelectionOwner[i].windowPtr, WINDOWID(lastSelectionOwner[i].windowPtr)); + fprintf(stderr, "%s: Returning last [%d] selection owner window [%p] (0x%x).\n", __func__, + lastSelectionOwner[i].selection, + (void *)lastSelectionOwner[i].windowPtr, WINDOWID(lastSelectionOwner[i].windowPtr)); #endif return lastSelectionOwner[i].windowPtr; -- cgit v1.2.3 From bf87f8bbe9ad711548d51d2512bcd3ecef275b4f Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 21:17:12 +0200 Subject: Clipboard.c: add loads of comments --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 227 +++++++++++++++++++++---- 1 file changed, 195 insertions(+), 32 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 6ba41a313..83175b22b 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -82,14 +82,19 @@ const int nxagentMaxSelections = 2; typedef struct _SelectionOwner { - Atom selection; - ClientPtr client; - Window window; - WindowPtr windowPtr; - Time lastTimeChanged; - + Atom selection; /* _external_ Atom */ + ClientPtr client; /* internal client */ + Window window; /* internal window id */ + WindowPtr windowPtr; /* internal window struct */ + Time lastTimeChanged; /* internal time */ } SelectionOwner; +/* + * this contains the last selection owner in nxagent. The + * lastTimeChanged is always an internal time. If .client is NULL the + * owner is outside nxagent. .selection will _always_ contain the + * external atom of the selection + */ static SelectionOwner *lastSelectionOwner; static Atom nxagentLastRequestedSelection; @@ -438,6 +443,11 @@ int SendSelectionNotifyEventToClient(ClientPtr client, return SendEventToClient(client, &x); } +/* + * Check if target is a valid content type target sent by the real X + * server, like .e.g XA_STRING or UTF8_STRING. Other, non content type + * targets like "TARGETS" or "TIMESTAMP" will return false. + */ Bool nxagentValidServerTargets(Atom target) { if (target == XA_STRING) @@ -565,6 +575,11 @@ int nxagentFindCurrentSelectionIndex(Atom sel) return i; } +/* + * This is called from Events.c dispatch loop on reception of a + * SelectionClear event. We receive this event if someone on the real + * X server claims the selection ownership. + */ void nxagentClearSelection(XEvent *X) { #ifdef DEBUG @@ -585,6 +600,7 @@ void nxagentClearSelection(XEvent *X) { if (lastSelectionOwner[i].client != NULL) { + /* send a SelectionClear event to (our) previous owner */ xEvent x = {0}; x.u.u.type = SelectionClear; x.u.selectionClear.time = GetTimeInMillis(); @@ -594,6 +610,11 @@ void nxagentClearSelection(XEvent *X) SendEventToClient(lastSelectionOwner[i].client, &x); } + /* + * set the root window with the NullClient as selection owner. Our + * clients asking for the owner via XGetSelectionOwner() will get + * these for an answer + */ CurrentSelections[i].window = screenInfo.screens[0]->root->drawable.id; CurrentSelections[i].client = NullClient; @@ -634,6 +655,13 @@ void nxagentReplyRequestSelection(XEvent *X, Bool success) NXFlushDisplay(nxagentDisplay, NXFlushLink); } +/* + * This is called from Events.c dispatch loop on reception of a + * SelectionRequest event, meaning a client of the real X server wants + * to have the selection content. The real X server knows the nxagent + * as selection owner. But in reality one of our windows is the owner, + * so we must pass the request on to the real owner. + */ void nxagentRequestSelection(XEvent *X) { #ifdef DEBUG @@ -664,6 +692,15 @@ void nxagentRequestSelection(XEvent *X) return; } + /* + * check if this request needs special treatment by checking + * if any of the following is true: + * - this is a special request like TARGETS or TIMESTAMP + * - lastServerRequestor in non-NULL (= we are currenty in the transfer phase) + * - the selection in this request is none we own. + * In all cases we'll send back a SelectionNotify event with an + * appropriate answer + */ if (!nxagentValidServerTargets(X->xselectionrequest.target) || (lastServerRequestor != None) || ((X->xselectionrequest.selection != lastSelectionOwner[nxagentPrimarySelection].selection) && @@ -687,6 +724,15 @@ FIXME: Do we need this? */ if (X->xselectionrequest.target == serverTARGETS) { + /* + * the selection request target is TARGETS. The requestor is + * asking for a list of supported data formats. Currently + * there's only one format we support: XA_STRING + * + * The selection does not matter here, we will return this for + * PRIMARY and CLIPBOARD. + */ + Atom targets[] = {XA_STRING}; int numTargets = 1; @@ -714,6 +760,17 @@ FIXME: Do we need this? } else if (X->xselectionrequest.target == serverTIMESTAMP) { + /* + * Section 2.6.2 of the ICCCM states: + * TIMESTAMP - To avoid some race conditions, it is important + * that requestors be able to discover the timestamp the owner + * used to acquire ownership. Until and unless the protocol is + * changed so that a GetSelectionOwner request returns the + * timestamp used to acquire ownership, selection owners must + * support conversion to TIMESTAMP, returning the timestamp they + * used to obtain the selection. + */ + int i = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection); if (i < nxagentMaxSelections) { @@ -737,9 +794,13 @@ FIXME: Do we need this? } /* - * This is necessary in nxagentGetClipboardWindow. + * reaching this means the request is neither a special request nor + * invalid. We can process it now. */ + /* + * This is required for nxagentGetClipboardWindow. + */ nxagentLastRequestedSelection = X->xselectionrequest.selection; /* find the index of the requested selection */ @@ -748,6 +809,10 @@ FIXME: Do we need this? { if ((lastClientWindowPtr != NULL) && (lastSelectionOwner[i].client != NULL)) { + /* + * Request the real X server to transfer the selection content + * to the NX_CUT_BUFFER_CLIENT property of the serverWindow. + */ XConvertSelection(nxagentDisplay, CurrentSelections[i].selection, X->xselectionrequest.target, serverCutProperty, serverWindow, lastClientTime); @@ -758,9 +823,18 @@ FIXME: Do we need this? } else { + /* + * if one of our clients owns the selection we ask it to copy + * the selection to the clientCutProperty on nxagent's root + * window + */ if (lastSelectionOwner[i].client != NULL && nxagentOption(Clipboard) != ClipboardClient) { + /* + * store who on the real X server requested the data and how + * and where it wants to have it + */ lastServerProperty = X->xselectionrequest.property; lastServerRequestor = X->xselectionrequest.requestor; lastServerTarget = X->xselectionrequest.target; @@ -815,6 +889,7 @@ FIXME: Do we need this? } /* + * end current selection transfer by sending a notification to the * client and resetting the corresponding variables and the state * machine. If success is False send a None reply, meaning "request * denied/failed" @@ -1118,6 +1193,11 @@ void nxagentCollectPropertyEvent(int resource) SAFE_XFree(pszReturnData); } +/* + * This is _only_ called from Events.c dispatch loop on reception of a + * SelectionNotify event from the real X server. These events are + * sent out by nxagent itself! + */ void nxagentNotifySelection(XEvent *X) { if (agentClipboardStatus != 1) @@ -1143,6 +1223,14 @@ void nxagentNotifySelection(XEvent *X) if (lastClientWindowPtr != NULL) { + /* + * We reach here after a paste inside the nxagent, triggered by + * the XConvertSelection call in nxagentConvertSelection(). This + * means that data we need has been transferred to the + * serverCutProperty of the serverWindow (our window on the real X + * server). We now need to transfer it to the original requestor, + * which is stored in the lastClient* variables. + */ if ((lastClientStage == SelectionStageNone) && (X->xselection.property == serverCutProperty)) { #ifdef DEBUG @@ -1181,6 +1269,7 @@ void nxagentNotifySelection(XEvent *X) int i = nxagentFindLastSelectionOwnerIndex(X->xselection.selection); if (i < nxagentMaxSelections) { + /* if the last owner was an internal one */ if ((lastSelectionOwner[i].client != NULL) && (lastSelectionOwner[i].windowPtr != NULL) && (X->xselection.property == serverClientCutProperty)) @@ -1191,6 +1280,7 @@ void nxagentNotifySelection(XEvent *X) unsigned long ulReturnBytesLeft; unsigned char *pszReturnData = NULL; + /* first get size values ... */ int result = GetWindowProperty(lastSelectionOwner[i].windowPtr, clientCutProperty, 0, 0, False, AnyPropertyType, &atomReturnType, &resultFormat, &ulReturnItems, &ulReturnBytesLeft, &pszReturnData); @@ -1206,6 +1296,7 @@ void nxagentNotifySelection(XEvent *X) } else { + /* ... then use the size values for the actual request */ result = GetWindowProperty(lastSelectionOwner[i].windowPtr, clientCutProperty, 0, ulReturnBytesLeft, False, AnyPropertyType, &atomReturnType, &resultFormat, &ulReturnItems, &ulReturnBytesLeft, @@ -1230,6 +1321,7 @@ void nxagentNotifySelection(XEvent *X) PropModeReplace, pszReturnData, ulReturnItems); + /* Fill the property on the initial requestor with the requested data */ #ifdef DEBUG { @@ -1252,6 +1344,14 @@ void nxagentNotifySelection(XEvent *X) */ } + /* + * inform the initial requestor that the requested data has + * arrived in the desired property. If we have been unable to + * get the data from the owner XChangeProperty will not have + * been called and lastServerProperty will be None which + * effectively will send a "Request denied" to the initial + * requestor. + */ XSelectionEvent eventSelection = { .requestor = lastServerRequestor, .selection = X->xselection.selection, @@ -1275,10 +1375,10 @@ void nxagentNotifySelection(XEvent *X) } /* - * Acquire selection so we don't get selection - * requests from real X clients. + * Let nxagent's serverWindow acquire the selection. All requests from + * the real X server (or its clients) will be sent to this window. The + * real X server never communicates with our windows directly. */ - void nxagentResetSelectionOwner(void) { if (lastServerRequestor != None) @@ -1314,22 +1414,31 @@ void nxagentResetSelectionOwner(void) lastClientWindowPtr = NULL; SetClientSelectionStage(None); + /* Hmm, this is already None when reaching this */ lastServerRequestor = None; return; } #ifdef NXAGENT_CLIPBOARD + +/* + * The callback is called from dix. This is the normal operation + * mode. The callback is also called when nxagent gets XFixes events + * from the real X server. In that case the Trap is set and the + * callback will do nothing. + */ + void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data, void *args) { /* - * Only act if the Trap is unset. The trap indicates that we are - * triggered by a clipboard event originating from the real X - * server. In that case we do not want to propagate back changes to - * the real X server, because it already knows about them and we + * Only act if the trap is unset. The trap indicates that we are + * triggered by an XFixes clipboard event originating from the real + * X server. In that case we do not want to propagate back changes + * to the real X server, because it already knows about them and we * would end up in an infinite loop of events. If there was a better - * way to identify that situation during Callback processing we + * way to identify that situation during callback processing we * could get rid of the Trap... */ if (nxagentExternalClipboardEventTrap != 0) @@ -1388,6 +1497,10 @@ void nxagentSetSelectionCallback(CallbackListPtr *callbacks, void *data, } #endif +/* + * This is called from the nxagentSetSelectionCallback, so it is using + * internal Atoms + */ void nxagentSetSelectionOwner(Selection *pSelection) { if (agentClipboardStatus != 1) @@ -1437,13 +1550,16 @@ void nxagentSetSelectionOwner(Selection *pSelection) /* * inform the real X server that our serverWindow is the - * clipboard owner. The real owner window (inside nxagent) is - * stored in lastSelectionOwner.window. - * lastSelectionOwner.windowPtr points to the struct that - * contains all information about the owner window + * clipboard owner. */ XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime); + /* + * The real owner window (inside nxagent) is stored in + * lastSelectionOwner.window. lastSelectionOwner.windowPtr + * points to the struct that contains all information about the + * owner window. + */ nxagentStoreSelectionOwner(&lastSelectionOwner[i], pSelection); } } @@ -1477,10 +1593,9 @@ FIXME void nxagentNotifyConvertFailure(ClientPtr client, Window requestor, Atom selection, Atom target, Time time) { -/* -FIXME: Why this pointer can be not a valid - client pointer? -*/ + /* + * Check if the client is still valid. + */ if (clients[client -> index] != client) { #ifdef WARNING @@ -1493,6 +1608,13 @@ FIXME: Why this pointer can be not a valid 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 + * return codes: + * 0: let dix process the request + * 1: don't let dix process the request + */ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, Window requestor, Atom property, Atom target, Time time) { @@ -1502,19 +1624,14 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, return 0; } - /* - * There is a client owner on the agent side, let normal stuff happen. - */ - - /* - * Only for PRIMARY and CLIPBOARD selections. - */ - for (int i = 0; i < nxagentMaxSelections; i++) { if ((selection == CurrentSelections[i].selection) && (lastSelectionOwner[i].client != NULL)) { + /* + * There is a client owner on the agent side, let normal dix stuff happen. + */ return 0; } } @@ -1569,6 +1686,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, return 1; } + /* + * The selection request target is TARGETS. The requestor is asking + * for a list of supported data formats. Currently there's 4 of them. + */ if (target == clientTARGETS) { /* --- Order changed by dimbor (prevent sending COMPOUND_TEXT to client --- */ @@ -1596,11 +1717,28 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, return 1; } + /* + * Section 2.6.2 of the ICCCM states: + * "TIMESTAMP - To avoid some race conditions, it is important + * that requestors be able to discover the timestamp the owner + * used to acquire ownership. Until and unless the protocol is + * changed so that a GetSelectionOwner request returns the + * timestamp used to acquire ownership, selection owners must + * support conversion to TIMESTAMP, returning the timestamp they + * used to obtain the selection." + */ if (target == MakeAtom("TIMESTAMP", 9, 1)) { int i = nxagentFindCurrentSelectionIndex(selection); if (i < NumCurrentSelections) { + /* + * "If the specified property is not None, the owner should place + * the data resulting from converting the selection into the + * specified property on the requestor window and should set the + * property's type to some appropriate value, which need not be + * the same as the specified target." + */ ChangeWindowProperty(pWin, property, XA_INTEGER, @@ -1620,7 +1758,7 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < 5000)) { /* - * The same client made consecutive requests of clipboard contents + * The same client made consecutive requests of clipboard content * with less than 5 seconds time interval between them. */ @@ -1647,6 +1785,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, { lastClientWindowPtr = pWin; SetClientSelectionStage(None); + /* + * store the original requestor, we need that later after + * serverCutProperty contains the desired selection content + */ lastClientRequestor = requestor; lastClientClientPtr = client; lastClientTime = time; @@ -1663,6 +1805,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, selection = lastSelectionOwner[nxagentClipboardSelection].selection; } + /* + * we only convert to either UTF8 or XA_STRING, despite accepting + * TEXT and COMPOUND_TEXT. + */ if (target == clientUTF8_STRING) { #ifdef DEBUG @@ -1700,6 +1846,23 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, return 0; } +/* + * This is _only_ called from ProcSendEvent in NXevents.c. It is used + * to send a SelectionNotify event to our server window which will + * trigger the dispatch loop in Events.c to run nxagentNotifySelection + * which in turn will take care of transferring the selection content + * from the owning client to to a property of the server window. + * + * Returning 1 here means the client request will not be further + * handled by dix. Returning 0 means a SelectionNotify event being + * pushed out to our clients. + * + * From https://tronche.com/gui/x/xlib/events/client-communication/selection.html: + * "This event is generated by the X server in response to a + * ConvertSelection protocol request when there is no owner for the + * selection. When there is an owner, it should be generated by the + * owner of the selection by using XSendEvent()." + */ int nxagentSendNotify(xEvent *event) { #ifdef DEBUG -- cgit v1.2.3 From 1c36e49ad0d90e47ae3e603f74119b6ba8c15f01 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 21:17:37 +0200 Subject: Clipboard.c: drop unneeded return code --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 83175b22b..95bbdd441 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1313,15 +1313,17 @@ void nxagentNotifySelection(XEvent *X) } else { - result = XChangeProperty(nxagentDisplay, - lastServerRequestor, - lastServerProperty, - lastServerTarget, - 8, - PropModeReplace, - pszReturnData, - ulReturnItems); /* Fill the property on the initial requestor with the requested data */ + /* The XChangeProperty source code reveals it will always + return 1, no matter what, so no need to check the result */ + XChangeProperty(nxagentDisplay, + lastServerRequestor, + lastServerProperty, + lastServerTarget, + 8, + PropModeReplace, + pszReturnData, + ulReturnItems); #ifdef DEBUG { -- cgit v1.2.3 From 4db1172ae35d7e153507ed91f20a58b22e3f6a2e Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 21:23:39 +0200 Subject: Clipboard.c: remove superflous return --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 95bbdd441..94219b6d1 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1418,8 +1418,6 @@ void nxagentResetSelectionOwner(void) /* Hmm, this is already None when reaching this */ lastServerRequestor = None; - - return; } #ifdef NXAGENT_CLIPBOARD -- cgit v1.2.3 From b5cac6722b0275d3ccdf0730e651232b0d621cb2 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 21:33:48 +0200 Subject: Clipboard.c: flush the display during transfer phase This avoids delays, timeouts and missing copy/paste actions. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 94219b6d1..3ecb8f161 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -991,6 +991,8 @@ void nxagentTransferSelection(int resource) SetClientSelectionStage(WaitSize); + NXFlushDisplay(nxagentDisplay, NXFlushLink); + break; } case SelectionStageQueryData: @@ -1043,6 +1045,10 @@ void nxagentTransferSelection(int resource) SetClientSelectionStage(WaitData); + /* we've seen situations where you had to move the mouse or press a + key to let the transfer complete. Flushing here fixed it */ + NXFlushDisplay(nxagentDisplay, NXFlushLink); + break; } default: -- cgit v1.2.3 From 21598c7e213d92d83417608a413f4ec34b4d5ef1 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 21:44:15 +0200 Subject: Clipboard.c: fix: translate target on transfer --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 3ecb8f161..639fc293d 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1927,6 +1927,29 @@ int nxagentSendNotify(xEvent *event) eventSelection.selection = lastSelectionOwner[nxagentClipboardSelection].selection; } + /* + * .target must be translated, too, as a client on the real + * server is requested to fill our property and it needs to know + * the format. + */ + + if (event->u.selectionNotify.target == clientUTF8_STRING) + { + eventSelection.target = serverUTF8_STRING; + } + else if (event->u.selectionNotify.target == clientTEXT) + { + eventSelection.target = serverTEXT; + } + /*else if (event->u.selectionNotify.target == clientCOMPOUND_TEXT) + { + eventSelection.target = serverCOMPOUND_TEXT; + }*/ + else + { + eventSelection.target = XA_STRING; + } + #ifdef DEBUG fprintf(stderr, "%s: mapping local to remote Atom: [%d] -> [%ld] [%s]\n", __func__, event->u.selectionNotify.selection, eventSelection.selection, -- cgit v1.2.3 From 899339f5affafccece7f71e527436b17910ca9f7 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 21:45:39 +0200 Subject: Clipboard.c: drop old commented code --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 639fc293d..298046352 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -706,22 +706,6 @@ void nxagentRequestSelection(XEvent *X) ((X->xselectionrequest.selection != lastSelectionOwner[nxagentPrimarySelection].selection) && (X->xselectionrequest.selection != lastSelectionOwner[nxagentClipboardSelection].selection))) { -/* -FIXME: Do we need this? - - char *strTarget; - - strTarget = XGetAtomName(nxagentDisplay, X->xselectionrequest.target); - - fprintf(stderr, "SelectionRequest event aborting sele=[%s] target=[%s]\n", - validateString(NameForAtom(X->xselectionrequest.selection)), - validateString(NameForAtom(X->xselectionrequest.target))); - - fprintf(stderr, "SelectionRequest event aborting sele=[%s] ext target=[%s] Atom size is [%d]\n", - validateString(NameForAtom(X->xselectionrequest.selection)), strTarget, sizeof(Atom)); - - SAFE_XFree(strTarget); -*/ if (X->xselectionrequest.target == serverTARGETS) { /* -- cgit v1.2.3 From ae44a8cd5c932f5a108dbc1cc92e3321f43b217d Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 22:48:38 +0200 Subject: Clipboard.c: add some more FIXMEs --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 298046352..400b966a6 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -715,6 +715,14 @@ void nxagentRequestSelection(XEvent *X) * * The selection does not matter here, we will return this for * PRIMARY and CLIPBOARD. + * + * FIXME: shouldn't we support UTF8_STRING, too? + * FIXME: I am wondering if we should align this with + * nxagentConvertSelection, where we report more formats. + * FIXME: the perfect solution should not just answer with + * XA_STRING but ask the real owner what format it supports. The + * should then be sent to the original requestor. + * FIXME: these must be external Atoms! */ Atom targets[] = {XA_STRING}; @@ -753,6 +761,8 @@ void nxagentRequestSelection(XEvent *X) * timestamp used to acquire ownership, selection owners must * support conversion to TIMESTAMP, returning the timestamp they * used to obtain the selection. + * + * FIXME: ensure we are reporting an _external_ timestamp */ int i = nxagentFindLastSelectionOwnerIndex(X->xselectionrequest.selection); @@ -796,6 +806,7 @@ void nxagentRequestSelection(XEvent *X) /* * Request the real X server to transfer the selection content * to the NX_CUT_BUFFER_CLIENT property of the serverWindow. + * FIXME: document how we can end up here */ XConvertSelection(nxagentDisplay, CurrentSelections[i].selection, X->xselectionrequest.target, serverCutProperty, @@ -1306,6 +1317,7 @@ void nxagentNotifySelection(XEvent *X) /* Fill the property on the initial requestor with the requested data */ /* The XChangeProperty source code reveals it will always return 1, no matter what, so no need to check the result */ + /* FIXME: better use the format returned by above request */ XChangeProperty(nxagentDisplay, lastServerRequestor, lastServerProperty, @@ -1331,6 +1343,7 @@ void nxagentNotifySelection(XEvent *X) #endif } + /* FIXME: free it or not? */ /* * SAFE_XFree(pszReturnData); */ @@ -1384,6 +1397,7 @@ void nxagentResetSelectionOwner(void) lastServerRequestor); #endif + /* FIXME: maybe we should put back the event that lead us here. */ return; } @@ -1521,6 +1535,7 @@ void nxagentSetSelectionOwner(Selection *pSelection) for (int i = 0; i < nxagentMaxSelections; i++) { + /* FIXME: using CurrentSelections with the index limited my MaxSelections looks wrong */ if (pSelection->selection == CurrentSelections[i].selection) { #ifdef DEBUG @@ -1679,6 +1694,9 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, /* * The selection request target is TARGETS. The requestor is asking * for a list of supported data formats. Currently there's 4 of them. + * + * FIXME: I am wondering if we should align this with + * nxagentRequestSelection, where we only report one format. */ if (target == clientTARGETS) { @@ -1819,6 +1837,8 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, 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))); -- cgit v1.2.3 From 6663cbe68e7211337488d534bac82592b996bec6 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Thu, 8 Aug 2019 22:55:52 +0200 Subject: Clipboard.c: fix nested clipboard handling Fixes ArcticaProject/nx-libs#632 --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index 400b966a6..e17ecef2c 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1895,7 +1895,14 @@ int nxagentSendNotify(xEvent *event) fprintf(stderr, "%s: lastServerRequestor is [0x%x].\n", __func__, lastServerRequestor); #endif - if (event->u.selectionNotify.property == clientCutProperty) + /* + * If we have nested sessions there are situations where we do not + * need to send out anything to the real X server because + * communication happens completely between our own clients (some of + * which can be nxagents themselves). In that case we return 0 (tell + * dix to go on) and do nothing! + */ + if (event->u.selectionNotify.property == clientCutProperty && lastServerRequestor != None) { /* -- cgit v1.2.3 From 72c022406f83d78425daae3037aebd2123f66293 Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Fri, 9 Aug 2019 11:03:16 +0200 Subject: Clipboard.c: rename nxagentNotifySelection to nxagentHandleSelectionNotifyFromXServer Use a more descriptive name. --- nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 9 +++++---- nx-X11/programs/Xserver/hw/nxagent/Clipboard.h | 2 +- nx-X11/programs/Xserver/hw/nxagent/Events.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'nx-X11/programs') diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c index e17ecef2c..5f7bdab4e 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c @@ -1199,7 +1199,7 @@ void nxagentCollectPropertyEvent(int resource) * SelectionNotify event from the real X server. These events are * sent out by nxagent itself! */ -void nxagentNotifySelection(XEvent *X) +void nxagentHandleSelectionNotifyFromXServer(XEvent *X) { if (agentClipboardStatus != 1) { @@ -1859,9 +1859,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection, /* * This is _only_ called from ProcSendEvent in NXevents.c. It is used * to send a SelectionNotify event to our server window which will - * trigger the dispatch loop in Events.c to run nxagentNotifySelection - * which in turn will take care of transferring the selection content - * from the owning client to to a property of the server window. + * trigger the dispatch loop in Events.c to run + * nxagentHandleSelectionNotifyFromXServer which in turn will take + * care of transferring the selection content from the owning client + * to to a property of the server window. * * Returning 1 here means the client request will not be further * handled by dix. Returning 0 means a SelectionNotify event being diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h index 2f43469ae..c2e783cb9 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h @@ -64,7 +64,7 @@ extern int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom select void nxagentClearSelection(); void nxagentRequestSelection(); -void nxagentNotifySelection(); +void nxagentHandleSelectionNotifyFromXServer(); int nxagentFindCurrentSelectionIndex(Atom sel); #endif /* __Clipboard_H__ */ diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c index 4a13f15ad..cbdf17a22 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Events.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c @@ -944,7 +944,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate) fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionNotify event.\n"); #endif - nxagentNotifySelection(&X); + nxagentHandleSelectionNotifyFromXServer(&X); break; } -- cgit v1.2.3