diff options
-rw-r--r-- | hw/xwin/XWin.rc | 1 | ||||
-rw-r--r-- | hw/xwin/man/XWin.man | 6 | ||||
-rw-r--r-- | hw/xwin/winclipboard/internal.h | 16 | ||||
-rw-r--r-- | hw/xwin/winclipboard/thread.c | 6 | ||||
-rw-r--r-- | hw/xwin/winclipboard/winclipboard.h | 2 | ||||
-rw-r--r-- | hw/xwin/winclipboard/wndproc.c | 137 | ||||
-rw-r--r-- | hw/xwin/winclipboard/xevents.c | 222 | ||||
-rw-r--r-- | hw/xwin/winclipboard/xwinclip.c | 7 | ||||
-rw-r--r-- | hw/xwin/winclipboard/xwinclip.man | 3 | ||||
-rw-r--r-- | hw/xwin/winprocarg.c | 21 | ||||
-rw-r--r-- | hw/xwin/winresource.h | 1 | ||||
-rw-r--r-- | hw/xwin/wintrayicon.c | 19 | ||||
-rw-r--r-- | hw/xwin/winwndproc.c | 6 |
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); |