summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xwin/XWin.rc1
-rw-r--r--hw/xwin/man/XWin.man6
-rw-r--r--hw/xwin/winclipboard/internal.h16
-rw-r--r--hw/xwin/winclipboard/thread.c6
-rw-r--r--hw/xwin/winclipboard/winclipboard.h2
-rw-r--r--hw/xwin/winclipboard/wndproc.c137
-rw-r--r--hw/xwin/winclipboard/xevents.c222
-rw-r--r--hw/xwin/winclipboard/xwinclip.c7
-rw-r--r--hw/xwin/winclipboard/xwinclip.man3
-rw-r--r--hw/xwin/winprocarg.c21
-rw-r--r--hw/xwin/winresource.h1
-rw-r--r--hw/xwin/wintrayicon.c19
-rw-r--r--hw/xwin/winwndproc.c6
13 files changed, 303 insertions, 144 deletions
diff --git a/hw/xwin/XWin.rc b/hw/xwin/XWin.rc
index be17d8f19..e74a9a5ef 100644
--- a/hw/xwin/XWin.rc
+++ b/hw/xwin/XWin.rc
@@ -93,6 +93,7 @@ BEGIN
POPUP "TRAYICON_MENU"
BEGIN
MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT
+ MENUITEM "Clipboard may use &PRIMARY selection", ID_APP_MONITOR_PRIMARY
MENUITEM "&About...", ID_APP_ABOUT
MENUITEM SEPARATOR
MENUITEM "E&xit...", ID_APP_EXIT
diff --git a/hw/xwin/man/XWin.man b/hw/xwin/man/XWin.man
index cf5324131..9a046d930 100644
--- a/hw/xwin/man/XWin.man
+++ b/hw/xwin/man/XWin.man
@@ -177,7 +177,7 @@ on remote hosts, when that information is available and it's useful to do so.
.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
.TP 8
.B \-[no]clipboard
-Enables [disables] the integration between the Cygwin/X clipboard and
+Enables [disables] the integration between the X11 clipboard and
\fIWindows\fP clipboard. The default is enabled.
.TP 8
.B "\-emulate3buttons [\fItimeout\fP]"
@@ -203,6 +203,10 @@ prevents the \fIWindows\fP mouse cursor from being drawn on top of the X
cursor.
This parameter has no effect unless \fB-swcursor\fP is also specified.
.TP 8
+.B \-[no]primary
+Clipboard integration may [will not] use the PRIMARY selection.
+The default is enabled.
+.TP 8
.B \-swcursor
Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead.
.TP 8
diff --git a/hw/xwin/winclipboard/internal.h b/hw/xwin/winclipboard/internal.h
index 3f9746933..af8550a05 100644
--- a/hw/xwin/winclipboard/internal.h
+++ b/hw/xwin/winclipboard/internal.h
@@ -38,8 +38,9 @@
#include <X11/Xwindows.h>
#define WIN_XEVENTS_SUCCESS 0
-#define WIN_XEVENTS_CONVERT 2
-#define WIN_XEVENTS_NOTIFY 3
+#define WIN_XEVENTS_FAILED 1
+#define WIN_XEVENTS_NOTIFY_DATA 3
+#define WIN_XEVENTS_NOTIFY_TARGETS 4
#define WM_WM_REINIT (WM_USER + 1)
@@ -64,9 +65,6 @@ void
* winclipboardthread.c
*/
-void
-winClipboardWindowDestroy(void);
-
typedef struct
{
Atom atomClipboard;
@@ -96,9 +94,15 @@ typedef struct
* winclipboardxevents.c
*/
+typedef struct
+{
+ Bool fUseUnicode;
+ Atom *targetList;
+} ClipboardConversionData;
+
int
winClipboardFlushXEvents(HWND hwnd,
- Window iWindow, Display * pDisplay, Bool fUnicodeSupport, ClipboardAtoms *atom);
+ Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atom);
Atom
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 15a515649..2b9a6f34f 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -250,7 +250,9 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
* because there may be events in local data structures
* already.
*/
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
+ ClipboardConversionData data;
+ data.fUseUnicode = fUseUnicode;
+ winClipboardFlushXEvents(hwnd, iWindow, pDisplay, &data, &atoms);
/* Pre-flush Windows messages */
if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
@@ -317,7 +319,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
/* Process X events */
winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, fUseUnicode, &atoms);
+ iWindow, pDisplay, &data, &atoms);
}
#ifdef HAS_DEVWINDOWS
diff --git a/hw/xwin/winclipboard/winclipboard.h b/hw/xwin/winclipboard/winclipboard.h
index 52481301b..e7ccc3637 100644
--- a/hw/xwin/winclipboard/winclipboard.h
+++ b/hw/xwin/winclipboard/winclipboard.h
@@ -33,4 +33,6 @@ void winFixClipboardChain(void);
void winClipboardWindowDestroy(void);
+extern int fPrimarySelection;
+
#endif
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index a171ca595..83f11417d 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/time.h>
+#include <limits.h>
#include <X11/Xatom.h>
@@ -64,7 +65,7 @@
static int
winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
- Bool fUseUnicode, ClipboardAtoms *atoms, int iTimeoutSec)
+ ClipboardConversionData *data, ClipboardAtoms *atoms, int iTimeoutSec)
{
int iConnNumber;
struct timeval tv;
@@ -117,14 +118,14 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
/* Process X events */
/* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, fUseUnicode, atoms);
+ iWindow, pDisplay, data, atoms);
winDebug
("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
iReturn);
- if (WIN_XEVENTS_NOTIFY == iReturn) {
- /* Bail out if notify processed */
+ if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
+ /* Bail out */
return iReturn;
}
}
@@ -445,6 +446,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int iReturn;
Bool fConvertToUnicode;
+ Bool pasted = FALSE;
if (message == WM_RENDERALLFORMATS)
winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n");
@@ -458,18 +460,89 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
else
fConvertToUnicode = (CF_UNICODETEXT == wParam);
- /* Request the selection contents */
- iReturn = XConvertSelection(pDisplay,
- winClipboardGetLastOwnedSelectionAtom(atoms),
- atoms->atomCompoundText,
- atoms->atomLocalProperty,
- iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow) {
- ErrorF("winClipboardWindowProc - WM_RENDER*FORMAT - "
- "XConvertSelection () failed\n");
- break;
+ Atom selection = winClipboardGetLastOwnedSelectionAtom(atoms);
+
+ if (selection == None) {
+ ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
+ goto fake_paste;
+ }
+
+ winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
+
+ /* Request the selection's supported conversion targets */
+ XConvertSelection(pDisplay,
+ selection,
+ atoms->atomTargets,
+ atoms->atomLocalProperty,
+ iWindow, CurrentTime);
+
+ /* Process X events */
+ ClipboardConversionData data;
+ data.fUseUnicode = fConvertToUnicode;
+ iReturn = winProcessXEventsTimeout(hwnd,
+ iWindow,
+ pDisplay,
+ &data,
+ atoms,
+ WIN_POLL_TIMEOUT);
+
+ if (WIN_XEVENTS_NOTIFY_TARGETS != iReturn) {
+ ErrorF
+ ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_TARGETS\n");
+ goto fake_paste;
}
+ /* Choose the most preferred target */
+ struct target_priority
+ {
+ Atom target;
+ unsigned int priority;
+ };
+
+ struct target_priority target_priority_table[] =
+ {
+ { atoms->atomCompoundText, 0 },
+#ifdef X_HAVE_UTF8_STRING
+ { atoms->atomUTF8String, 1 },
+#endif
+ { XA_STRING, 2 },
+ };
+
+ int best_priority = INT_MAX;
+ int best_target = 0;
+
+ int i,j;
+ for (i = 0 ; data.targetList[i] != 0; i++)
+ {
+ for (j = 0; j < sizeof(target_priority_table)/sizeof(struct target_priority); j ++)
+ {
+ if ((data.targetList[i] == target_priority_table[j].target) &&
+ (target_priority_table[j].priority < best_priority))
+ {
+ best_target = target_priority_table[j].target;
+ best_priority = target_priority_table[j].priority;
+ }
+ }
+ }
+
+ free(data.targetList);
+ data.targetList = 0;
+
+ winDebug("winClipboardWindowProc - best target is %d\n", best_target);
+
+ /* No useful targets found */
+ if (best_target == 0)
+ goto fake_paste;
+
+ winDebug("winClipboardWindowProc - requesting selection from owner\n");
+
+ /* Request the selection contents */
+ XConvertSelection(pDisplay,
+ selection,
+ best_target,
+ atoms->atomLocalProperty,
+ iWindow, CurrentTime);
+
/* Special handling for WM_RENDERALLFORMATS */
if (message == WM_RENDERALLFORMATS) {
/* We must open and empty the clipboard */
@@ -483,40 +556,47 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
"OpenClipboard () failed: %08x\n",
GetLastError());
- break;
}
if (!EmptyClipboard()) {
ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - "
"EmptyClipboard () failed: %08x\n",
GetLastError());
- break;
}
}
- /* Process the SelectionNotify event */
+ /* Process X events */
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
pDisplay,
- fConvertToUnicode,
+ &data,
atoms,
WIN_POLL_TIMEOUT);
/*
- * The last call to winProcessXEventsTimeout
- * from above had better have seen a notify event, or else we
- * are dealing with a buggy or old X11 app. In these cases we
- * have to paste some fake data to the Win32 clipboard to
- * satisfy the requirement that we write something to it.
+ * winProcessXEventsTimeout had better have seen a notify event,
+ * or else we are dealing with a buggy or old X11 app.
*/
- if (WIN_XEVENTS_NOTIFY != iReturn) {
+ if (WIN_XEVENTS_NOTIFY_DATA != iReturn) {
+ ErrorF
+ ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_DATA\n");
+ }
+ else {
+ pasted = TRUE;
+ }
+
+ /*
+ * If we couldn't get the data from the X clipboard, we
+ * have to paste some fake data to the Win32 clipboard to
+ * satisfy the requirement that we write something to it.
+ */
+ fake_paste:
+ if (!pasted)
+ {
/* Paste no data, to satisfy required call to SetClipboardData */
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
-
- ErrorF
- ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n");
- }
+ }
/* Special handling for WM_RENDERALLFORMATS */
if (message == WM_RENDERALLFORMATS) {
@@ -526,7 +606,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
"CloseClipboard () failed: %08x\n",
GetLastError());
- break;
}
}
diff --git a/hw/xwin/winclipboard/xevents.c b/hw/xwin/winclipboard/xevents.c
index 1622d3223..1861b40cc 100644
--- a/hw/xwin/winclipboard/xevents.c
+++ b/hw/xwin/winclipboard/xevents.c
@@ -43,11 +43,14 @@
#undef _XSERVER64
#endif
-#include "internal.h"
+#include <limits.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xfixes.h>
+#include "winclipboard.h"
+#include "internal.h"
+
/*
* Constants
*/
@@ -62,6 +65,7 @@
*/
extern int xfixes_event_base;
+int fPrimarySelection = 1;
/*
* Local variables
@@ -112,6 +116,8 @@ winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms)
if (lastOwnedSelectionIndex == CLIP_OWN_NONE)
return None;
+ winDebug("GetLastOwnedSelectionAtom: selection %s owned by XID %x\n", szSelectionNames[lastOwnedSelectionIndex], s_iOwners[lastOwnedSelectionIndex]);
+
if (lastOwnedSelectionIndex == CLIP_OWN_PRIMARY)
return XA_PRIMARY;
@@ -132,13 +138,59 @@ winClipboardInitMonitoredSelections(void)
lastOwnedSelectionIndex = CLIP_OWN_NONE;
}
+static int
+winClipboardSelectionNotifyTargets(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+{
+ Atom type;
+ int format;
+ unsigned long nitems;
+ unsigned long after;
+ Atom *prop;
+
+ /* Retrieve the selection data and delete the property */
+ int iReturn = XGetWindowProperty(pDisplay,
+ iWindow,
+ atoms->atomLocalProperty,
+ 0,
+ INT_MAX,
+ True,
+ AnyPropertyType,
+ &type,
+ &format,
+ &nitems,
+ &after,
+ (unsigned char **)&prop);
+ if (iReturn != Success) {
+ ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+ } else {
+ int i;
+ data->targetList = malloc((nitems+1)*sizeof(Atom));
+
+ for (i = 0; i < nitems; i++)
+ {
+ Atom atom = prop[i];
+ data->targetList[i] = atom;
+ char *pszAtomName = XGetAtomName(pDisplay, atom);
+ winDebug("winClipboardFlushXEvents - SelectionNotify - target[%d] %d = %s\n", i, atom, pszAtomName);
+ XFree(pszAtomName);
+ }
+
+ data->targetList[nitems] = 0;
+
+ XFree(prop);
+ }
+
+ return WIN_XEVENTS_NOTIFY_TARGETS;
+}
+
/*
* Process any pending X events
*/
int
winClipboardFlushXEvents(HWND hwnd,
- Window iWindow, Display * pDisplay, Bool fUseUnicode, ClipboardAtoms *atoms)
+ Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
{
Atom atomClipboard = atoms->atomClipboard;
Atom atomLocalProperty = atoms->atomLocalProperty;
@@ -182,12 +234,14 @@ winClipboardFlushXEvents(HWND hwnd,
{
char *pszAtomName = NULL;
- winDebug("SelectionRequest - target %d\n",
- event.xselectionrequest.target);
+ pszAtomName = XGetAtomName(pDisplay,
+ event.xselectionrequest.selection);
+ winDebug("winClipboardFlushXEvents - SelectionRequest - Selection: %s\n", pszAtomName);
+ XFree(pszAtomName);
pszAtomName = XGetAtomName(pDisplay,
event.xselectionrequest.target);
- winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
+ winDebug("winClipboardFlushXEvents - SelectionRequest - Target %d = %s\n", event.xselectionrequest.target, pszAtomName);
XFree(pszAtomName);
pszAtomName = NULL;
}
@@ -209,7 +263,7 @@ winClipboardFlushXEvents(HWND hwnd,
atomUTF8String,
XA_STRING
};
- winDebug("SelectionRequest - populating targets\n");
+ winDebug("winClipboardFlushXEvents - SelectionRequest - populating targets\n");
/* Try to change the property */
iReturn = XChangeProperty(pDisplay,
@@ -272,7 +326,7 @@ winClipboardFlushXEvents(HWND hwnd,
fCloseClipboard = TRUE;
/* Check that clipboard format is available */
- if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ if (data->fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
static int count; /* Hack to stop acroread spamming the log */
static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */
@@ -289,7 +343,7 @@ winClipboardFlushXEvents(HWND hwnd,
fAbort = TRUE;
goto winClipboardFlushXEvents_SelectionRequest_Done;
}
- else if (!fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
+ else if (!data->fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
ErrorF("winClipboardFlushXEvents - CF_TEXT is not "
"available from Win32 clipboard. Aborting.\n");
@@ -311,7 +365,7 @@ winClipboardFlushXEvents(HWND hwnd,
xiccesStyle = XStringStyle;
/* Get a pointer to the clipboard text, in desired format */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
/* Retrieve clipboard data */
hGlobal = GetClipboardData(CF_UNICODETEXT);
}
@@ -330,7 +384,7 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = (char *) GlobalLock(hGlobal);
/* Convert the Unicode string to UTF8 (MBCS) */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
iConvertDataLen = WideCharToMultiByte(CP_UTF8,
0,
(LPCWSTR) pszGlobalData,
@@ -361,7 +415,7 @@ winClipboardFlushXEvents(HWND hwnd,
xtpText.nitems = 0;
/* Create the text property from the text list */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
iReturn = Xutf8TextListToTextProperty(pDisplay,
pszTextList,
@@ -455,7 +509,7 @@ winClipboardFlushXEvents(HWND hwnd,
* client when we abort.
*/
if (fAbort) {
- winDebug("SelectionRequest - aborting\n");
+ winDebug("winClipboardFlushXEvents - SelectionRequest - aborting\n");
/* Setup selection notify event */
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
@@ -507,116 +561,55 @@ winClipboardFlushXEvents(HWND hwnd,
}
/*
- * Request conversion of UTF8 and CompoundText targets.
- */
- if (event.xselection.property == None) {
- if (event.xselection.target == XA_STRING) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "XA_STRING\n");
+ SelectionNotify with property of None indicates either:
- return WIN_XEVENTS_CONVERT;
- }
- else if (event.xselection.target == atomUTF8String) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of UTF8 target.\n");
-
- XConvertSelection(pDisplay,
- event.xselection.selection,
- XA_STRING,
- atomLocalProperty, iWindow, CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush(pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselection.target == atomCompoundText) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of CompoundText target.\n");
-
- XConvertSelection(pDisplay,
- event.xselection.selection,
- atomUTF8String,
- atomLocalProperty, iWindow, CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush(pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#endif
- else {
+ (i) Generated by the X server if no owner for the specified selection exists
+ (perhaps it's disappeared on us mid-transaction), or
+ (ii) Sent by the selection owner when the requested selection conversion could
+ not be performed or server errors prevented the conversion data being returned
+ */
+ if (event.xselection.property == None) {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
- "Unknown format. Cannot request conversion, "
- "aborting.\n");
- break;
+ "Conversion to format %d refused.\n",
+ event.xselection.target);
+ return WIN_XEVENTS_FAILED;
}
- }
-
- case SelectionClear:
- winDebug("SelectionClear - doing nothing\n");
- break;
-
- case PropertyNotify:
- {
- char *pszAtomName;
-
- pszAtomName = XGetAtomName(pDisplay, event.xproperty.atom);
- winDebug("winClipboardFlushXEvents - PropertyNotify - ATOM: %s\n",
- pszAtomName);
- XFree(pszAtomName);
- }
-
- if (event.xproperty.atom != atomLocalProperty)
- break;
- /* Retrieve the size of the stored data */
- iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, 0, /* Don't get data, just size */
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft, &xtpText.value);
- if (iReturn != Success) {
- ErrorF("winClipboardFlushXEvents - PropertyNotify - "
- "XGetWindowProperty () failed, aborting: %d\n", iReturn);
- break;
+ if (event.xselection.target == atomTargets) {
+ return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
}
- winDebug("PropertyNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
-
- /* Request the selection data */
+ /* Retrieve the selection data and delete the property */
iReturn = XGetWindowProperty(pDisplay,
iWindow,
atomLocalProperty,
0,
- ulReturnBytesLeft,
- False,
+ INT_MAX,
+ True,
AnyPropertyType,
&xtpText.encoding,
&xtpText.format,
&xtpText.nitems,
&ulReturnBytesLeft, &xtpText.value);
if (iReturn != Success) {
- ErrorF("winClipboardFlushXEvents - PropertyNotify - "
+ ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
- break;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
}
{
char *pszAtomName = NULL;
- winDebug("PropertyNotify - returned data %d left %d\n",
+ winDebug("SelectionNotify - returned data %d left %d\n",
xtpText.nitems, ulReturnBytesLeft);
pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
- winDebug("PropertyNotify - encoding atom name %s\n",
+ winDebug("SelectionNotify - encoding atom name %s\n",
pszAtomName);
XFree(pszAtomName);
pszAtomName = NULL;
}
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
/* Convert the text property to a text list */
iReturn = Xutf8TextPropertyToTextList(pDisplay,
@@ -645,14 +638,14 @@ winClipboardFlushXEvents(HWND hwnd,
}
}
else {
- ErrorF("winClipboardFlushXEvents - PropertyNotify - "
+ ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"X*TextPropertyToTextList list_return is NULL.\n");
pszReturnData = malloc(1);
pszReturnData[0] = '\0';
}
}
else {
- ErrorF("winClipboardFlushXEvents - PropertyNotify - "
+ ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"X*TextPropertyToTextList returned: ");
switch (iReturn) {
case XNoMemory:
@@ -683,7 +676,7 @@ winClipboardFlushXEvents(HWND hwnd,
/* Convert the X clipboard string to DOS format */
winClipboardUNIXtoDOS(&pszReturnData, strlen(pszReturnData));
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
/* Find out how much space needed to convert MBCS to Unicode */
iUnicodeLen = MultiByteToWideChar(CP_UTF8,
0,
@@ -693,12 +686,12 @@ winClipboardFlushXEvents(HWND hwnd,
pwszUnicodeStr
= (wchar_t *) malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
if (!pwszUnicodeStr) {
- ErrorF("winClipboardFlushXEvents - PropertyNotify "
+ ErrorF("winClipboardFlushXEvents - SelectionNotify "
"malloc failed for pwszUnicodeStr, aborting.\n");
/* Abort */
fAbort = TRUE;
- goto winClipboardFlushXEvents_PropertyNotify_Done;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
}
/* Do the actual conversion */
@@ -723,11 +716,12 @@ winClipboardFlushXEvents(HWND hwnd,
/* Check that global memory was allocated */
if (!hGlobal) {
- ErrorF("winClipboardFlushXEvents - PropertyNotify "
+ ErrorF("winClipboardFlushXEvents - SelectionNotify "
"GlobalAlloc failed, aborting: %ld\n", GetLastError());
+
/* Abort */
fAbort = TRUE;
- goto winClipboardFlushXEvents_PropertyNotify_Done;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
}
/* Obtain a pointer to the global memory */
@@ -738,11 +732,11 @@ winClipboardFlushXEvents(HWND hwnd,
/* Abort */
fAbort = TRUE;
- goto winClipboardFlushXEvents_PropertyNotify_Done;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
}
/* Copy the returned string into the global memory */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
memcpy(pszGlobalData,
pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1));
free(pwszUnicodeStr);
@@ -759,7 +753,7 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = NULL;
/* Push the selection data to the Windows clipboard */
- if (fUseUnicode)
+ if (data->fUseUnicode)
SetClipboardData(CF_UNICODETEXT, hGlobal);
else
SetClipboardData(CF_TEXT, hGlobal);
@@ -772,7 +766,7 @@ winClipboardFlushXEvents(HWND hwnd,
* Windows after the call to SetClipboardData ().
*/
- winClipboardFlushXEvents_PropertyNotify_Done:
+ winClipboardFlushXEvents_SelectionNotify_Done:
/* Free allocated resources */
if (ppszTextList)
XFreeStringList(ppszTextList);
@@ -789,7 +783,23 @@ winClipboardFlushXEvents(HWND hwnd,
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
}
- return WIN_XEVENTS_NOTIFY;
+ return WIN_XEVENTS_NOTIFY_DATA;
+
+ case SelectionClear:
+ winDebug("winClipboardFlushXEvents - SelectionClear - doing nothing\n");
+ break;
+
+ case PropertyNotify:
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName(pDisplay, event.xproperty.atom);
+ winDebug("winClipboardFlushXEvents - PropertyNotify - ATOM: %s %s\n",
+ pszAtomName,
+ event.xproperty.state == PropertyNewValue ? "PropertyNewValue" : "PropertyDelete");
+ XFree(pszAtomName);
+ }
+ break;
case MappingNotify:
break;
@@ -802,7 +812,7 @@ winClipboardFlushXEvents(HWND hwnd,
winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n");
/* Save selection owners for monitored selections, ignore other selections */
- if (e->selection == XA_PRIMARY) {
+ if ((e->selection == XA_PRIMARY) && fPrimarySelection) {
MonitorSelection(e, CLIP_OWN_PRIMARY);
}
else if (e->selection == atomClipboard) {
diff --git a/hw/xwin/winclipboard/xwinclip.c b/hw/xwin/winclipboard/xwinclip.c
index 3677974c4..8dfd24bd9 100644
--- a/hw/xwin/winclipboard/xwinclip.c
+++ b/hw/xwin/winclipboard/xwinclip.c
@@ -92,6 +92,13 @@ main (int argc, char *argv[])
continue;
}
+ /* Look for -noprimary */
+ if (!strcmp (argv[i], "-noprimary"))
+ {
+ fPrimarySelection = 0;
+ continue;
+ }
+
/* Yack when we find a parameter that we don't know about */
printf ("Unknown parameter: %s\nExiting.\n", argv[i]);
exit (1);
diff --git a/hw/xwin/winclipboard/xwinclip.man b/hw/xwin/winclipboard/xwinclip.man
index 822db91d4..a53dc3029 100644
--- a/hw/xwin/winclipboard/xwinclip.man
+++ b/hw/xwin/winclipboard/xwinclip.man
@@ -29,6 +29,9 @@ Specifies the X server display to connect to.
.TP 8
.B \-nounicodeclipboard
Do not use unicode text on the clipboard.
+.TP 8
+.B \-noprimary
+Do not monitor the PRIMARY selection.
.SH "SEE ALSO"
XWin(1)
diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c
index 34d54f1c6..c91d8dc4d 100644
--- a/hw/xwin/winprocarg.c
+++ b/hw/xwin/winprocarg.c
@@ -48,6 +48,7 @@ from The Open Group.
#ifdef XWIN_CLIPBOARD
extern Bool g_fUnicodeClipboard;
extern Bool g_fClipboard;
+#include "winclipboard/winclipboard.h"
#endif
/*
@@ -720,6 +721,26 @@ ddxProcessArgument(int argc, char *argv[], int i)
/* Indicate that we have processed this argument */
return 1;
}
+
+ /*
+ * Look for the '-primary' argument
+ */
+ if (IS_OPTION("-primary")) {
+ fPrimarySelection = TRUE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-noprimary' argument
+ */
+ if (IS_OPTION("-noprimary")) {
+ fPrimarySelection = FALSE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
#endif
/*
diff --git a/hw/xwin/winresource.h b/hw/xwin/winresource.h
index afbf9f28d..37e92ce61 100644
--- a/hw/xwin/winresource.h
+++ b/hw/xwin/winresource.h
@@ -43,6 +43,7 @@
#define ID_APP_HIDE_ROOT 201
#define ID_APP_ALWAYS_ON_TOP 202
#define ID_APP_ABOUT 203
+#define ID_APP_MONITOR_PRIMARY 204
#define ID_ABOUT_WEBSITE 303
diff --git a/hw/xwin/wintrayicon.c b/hw/xwin/wintrayicon.c
index e0aa7e5ab..6acc0d712 100644
--- a/hw/xwin/wintrayicon.c
+++ b/hw/xwin/wintrayicon.c
@@ -32,9 +32,13 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
+
#include "win.h"
#include <shellapi.h>
#include "winprefs.h"
+#ifdef XWIN_CLIPBOARD
+#include "winclipboard/winclipboard.h"
+#endif
/*
* Initialize the tray icon
@@ -170,6 +174,21 @@ winHandleIconMessage(HWND hwnd, UINT message,
RemoveMenu(hmenuTray, ID_APP_HIDE_ROOT, MF_BYCOMMAND);
}
+#ifdef XWIN_CLIPBOARD
+ if (g_fClipboard) {
+ /* Set menu state to indicate if 'Monitor Primary' is enabled or not */
+ MENUITEMINFO mii = { 0 };
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_STATE;
+ mii.fState = fPrimarySelection ? MFS_CHECKED : MFS_UNCHECKED;
+ SetMenuItemInfo(hmenuTray, ID_APP_MONITOR_PRIMARY, FALSE, &mii);
+ }
+ else {
+ /* Remove 'Monitor Primary' menu item */
+ RemoveMenu(hmenuTray, ID_APP_MONITOR_PRIMARY, MF_BYCOMMAND);
+ }
+#endif
+
SetupRootMenu(hmenuTray);
/*
diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c
index 2829d5f8e..6b46d982a 100644
--- a/hw/xwin/winwndproc.c
+++ b/hw/xwin/winwndproc.c
@@ -1230,6 +1230,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
#endif
+#ifdef XWIN_CLIPBOARD
+ case ID_APP_MONITOR_PRIMARY:
+ fPrimarySelection = !fPrimarySelection;
+ return 0;
+#endif
+
case ID_APP_ABOUT:
/* Display the About box */
winDisplayAboutDialog(s_pScreenPriv);