Merge remote-tracking branch 'jturney/master'

This commit is contained in:
Keith Packard 2014-12-08 18:04:08 -08:00
commit 6f4c398a0e
15 changed files with 349 additions and 213 deletions

View File

@ -793,6 +793,10 @@ winUseMsg(void)
#ifdef XWIN_CLIPBOARD
ErrorF("-nounicodeclipboard\n"
"\tDo not use Unicode clipboard even if on a NT-based platform.\n");
ErrorF("-[no]primary\n"
"\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
"\tto the Windows clipboard. Default is enabled.\n");
#endif
ErrorF("-refresh rate_in_Hz\n"

View File

@ -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

View File

@ -174,7 +174,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]"
@ -200,6 +200,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

View File

@ -39,10 +39,12 @@
#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)
#define WM_WM_QUIT (WM_USER + 2)
/*
* References to external symbols
@ -95,9 +97,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

View File

@ -123,6 +123,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
int iSelectError;
Bool fShutdown = FALSE;
static Bool fErrorHandlerSet = FALSE;
ClipboardConversionData data;
winDebug("winClipboardProc - Hello\n");
@ -254,21 +255,25 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
}
/* Pre-flush X events */
/*
* NOTE: Apparently you'll freeze if you don't do this,
* because there may be events in local data structures
* already.
*/
winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
data.fUseUnicode = fUseUnicode;
/* Pre-flush Windows messages */
if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
}
/* Loop for X events */
/* Loop for events */
while (1) {
/* Process X events */
winClipboardFlushXEvents(hwnd,
iWindow, pDisplay, &data, &atoms);
/* Process Windows messages */
if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue trapped "
"WM_QUIT message, exiting main loop.\n");
break;
}
/* We need to ensure that all pending requests are sent */
XFlush(pDisplay);
/* Setup the file descriptor set */
/*
* NOTE: You have to do this before every call to select
@ -315,10 +320,9 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
break;
}
/* Branch on which descriptor became active */
if (FD_ISSET(iConnectionNumber, &fdsRead)) {
/* Process X events */
winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, &atoms);
winDebug
("winClipboardProc - X connection ready, pumping X event queue\n");
}
#ifdef HAS_DEVWINDOWS
@ -328,14 +332,16 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
if (1)
#endif
{
/* Process Windows messages */
if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
ErrorF("winClipboardProc - "
"winClipboardFlushWindowsMessageQueue trapped "
"WM_QUIT message, exiting main loop.\n");
break;
}
winDebug
("winClipboardProc - /dev/windows ready, pumping Windows message queue\n");
}
#ifdef HAS_DEVWINDOWS
if (!(FD_ISSET(iConnectionNumber, &fdsRead)) &&
!(FD_ISSET(fdMessageQueue, &fdsRead))) {
winDebug("winClipboardProc - Spurious wake, select() returned %d\n", iReturn);
}
#endif
}
winClipboardProc_Exit:
@ -345,7 +351,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
winClipboardProc_Done:
/* Close our Windows window */
if (g_hwndClipboard) {
winClipboardWindowDestroy();
DestroyWindow(g_hwndClipboard);
}
/* Close our X window */
@ -485,7 +491,7 @@ void
winClipboardWindowDestroy(void)
{
if (g_hwndClipboard) {
SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
SendMessage(g_hwndClipboard, WM_WM_QUIT, 0, 0);
}
}

View File

@ -33,4 +33,6 @@ void winFixClipboardChain(void);
void winClipboardWindowDestroy(void);
extern Bool fPrimarySelection;
#endif

View File

@ -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;
@ -82,8 +83,18 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
fd_set fdsRead;
long remainingTime;
/* We need to ensure that all pending events are processed */
XSync(pDisplay, FALSE);
/* Process X events */
iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
/* Bail out */
return iReturn;
}
/* We need to ensure that all pending requests are sent */
XFlush(pDisplay);
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
@ -112,24 +123,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
break;
}
/* Branch on which descriptor became active */
if (FD_ISSET(iConnNumber, &fdsRead)) {
/* Process X events */
/* Exit when we see that server is shutting down */
iReturn = winClipboardFlushXEvents(hwnd,
iWindow, pDisplay, fUseUnicode, atoms);
winDebug
("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
iReturn);
if (WIN_XEVENTS_NOTIFY == iReturn) {
/* Bail out if notify processed */
return iReturn;
}
}
else {
winDebug("winProcessXEventsTimeout - Spurious wake\n");
if (!FD_ISSET(iConnNumber, &fdsRead)) {
winDebug("winProcessXEventsTimeout - Spurious wake, select() returned %d\n", iReturn);
}
}
@ -148,6 +143,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static Display *pDisplay;
static Window iWindow;
static ClipboardAtoms *atoms;
static Bool fRunning;
/* Branch on message type */
switch (message) {
@ -159,7 +155,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ChangeClipboardChain(hwnd, s_hwndNextViewer);
s_hwndNextViewer = NULL;
}
return 0;
case WM_WM_QUIT:
{
winDebug("winClipboardWindowProc - WM_WM_QUIT\n");
fRunning = FALSE;
PostQuitMessage(0);
}
return 0;
@ -175,6 +177,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
pDisplay = cwcp->pClipboardDisplay;
iWindow = cwcp->iClipboardWindow;
atoms = cwcp->atoms;
fRunning = TRUE;
first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
if (first == hwnd)
@ -307,6 +310,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
}
/* Bail when shutting down */
if (!fRunning)
return 0;
/*
* Do not take ownership of the X11 selections when something
* other than CF_TEXT or CF_UNICODETEXT has been copied
@ -410,93 +417,151 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n");
return 0;
case WM_RENDERFORMAT:
case WM_RENDERALLFORMATS:
winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n");
/*
WM_RENDERALLFORMATS is sent as we are shutting down, to render the
clipboard so it's contents remains available to other applications.
Unfortunately, this can't work without major changes. The server is
already waiting for us to stop, so we can't ask for the rendering of
clipboard text now.
*/
return 0;
case WM_RENDERFORMAT:
{
int iReturn;
Bool fConvertToUnicode;
Bool pasted = FALSE;
Atom selection;
ClipboardConversionData data;
int best_target = 0;
winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
wParam);
/* Flag whether to convert to Unicode or not */
if (message == WM_RENDERALLFORMATS)
fConvertToUnicode = FALSE;
else
fConvertToUnicode = (CF_UNICODETEXT == wParam);
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;
selection = winClipboardGetLastOwnedSelectionAtom(atoms);
if (selection == None) {
ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
goto fake_paste;
}
/* Special handling for WM_RENDERALLFORMATS */
if (message == WM_RENDERALLFORMATS) {
/* We must open and empty the clipboard */
winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
/* Close clipboard if we have it open already */
if (GetOpenClipboardWindow() == hwnd) {
CloseClipboard();
}
/* Request the selection's supported conversion targets */
XConvertSelection(pDisplay,
selection,
atoms->atomTargets,
atoms->atomLocalProperty,
iWindow, CurrentTime);
if (!OpenClipboard(hwnd)) {
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 */
data.fUseUnicode = fConvertToUnicode;
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
pDisplay,
fConvertToUnicode,
&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 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);
/* Process X events */
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
pDisplay,
&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) {
/* We must close the clipboard */
if (!CloseClipboard()) {
ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - "
"CloseClipboard () failed: %08x\n",
GetLastError());
break;
}
}
winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n");
winDebug("winClipboardWindowProc - WM_RENDERFORMAT - Returning.\n");
return 0;
}
}

View File

@ -43,11 +43,15 @@
#undef _XSERVER64
#endif
#include "internal.h"
#include <limits.h>
#include <wchar.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xfixes.h>
#include "winclipboard.h"
#include "internal.h"
/*
* Constants
*/
@ -62,6 +66,7 @@
*/
extern int xfixes_event_base;
Bool fPrimarySelection = TRUE;
/*
* Local variables
@ -133,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];
char *pszAtomName = XGetAtomName(pDisplay, atom);
data->targetList[i] = 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;
@ -158,14 +209,11 @@ winClipboardFlushXEvents(HWND hwnd,
int iReturn;
HGLOBAL hGlobal = NULL;
XICCEncodingStyle xiccesStyle;
int iConvertDataLen = 0;
char *pszConvertData = NULL;
char *pszTextList[2] = { NULL };
int iCount;
char **ppszTextList = NULL;
wchar_t *pwszUnicodeStr = NULL;
int iUnicodeLen = 0;
int iReturnDataLen = 0;
Bool fAbort = FALSE;
Bool fCloseClipboard = FALSE;
Bool fSetClipboardData = TRUE;
@ -272,7 +320,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 +337,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 +359,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,8 +378,8 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = (char *) GlobalLock(hGlobal);
/* Convert the Unicode string to UTF8 (MBCS) */
if (fUseUnicode) {
iConvertDataLen = WideCharToMultiByte(CP_UTF8,
if (data->fUseUnicode) {
int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
0,
(LPCWSTR) pszGlobalData,
-1, NULL, 0, NULL, NULL);
@ -346,7 +394,6 @@ winClipboardFlushXEvents(HWND hwnd,
}
else {
pszConvertData = strdup(pszGlobalData);
iConvertDataLen = strlen(pszConvertData) + 1;
}
/* Convert DOS string to UNIX string */
@ -361,7 +408,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,
@ -491,7 +538,6 @@ winClipboardFlushXEvents(HWND hwnd,
*/
case SelectionNotify:
winDebug("winClipboardFlushXEvents - SelectionNotify\n");
{
char *pszAtomName;
@ -506,75 +552,31 @@ winClipboardFlushXEvents(HWND hwnd,
}
/*
* Request conversion of UTF8 and CompoundText targets.
*/
SelectionNotify with property of None indicates either:
(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) {
if (event.xselection.target == XA_STRING) {
winDebug("winClipboardFlushXEvents - SelectionNotify - "
"XA_STRING\n");
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 {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"Unknown format. Cannot request conversion, "
"aborting.\n");
break;
"Conversion to format %d refused.\n",
event.xselection.target);
return WIN_XEVENTS_FAILED;
}
if (event.xselection.target == atomTargets) {
return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
}
/* 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 - SelectionNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
break;
}
winDebug("SelectionNotify - 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,
@ -583,7 +585,7 @@ winClipboardFlushXEvents(HWND hwnd,
if (iReturn != Success) {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
break;
goto winClipboardFlushXEvents_SelectionNotify_Done;
}
{
@ -597,7 +599,7 @@ winClipboardFlushXEvents(HWND hwnd,
pszAtomName = NULL;
}
if (fUseUnicode) {
if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
/* Convert the text property to a text list */
iReturn = Xutf8TextPropertyToTextList(pDisplay,
@ -614,8 +616,7 @@ winClipboardFlushXEvents(HWND hwnd,
/* Conversion succeeded or some unconvertible characters */
if (ppszTextList != NULL) {
int i;
iReturnDataLen = 0;
int iReturnDataLen = 0;
for (i = 0; i < iCount; i++) {
iReturnDataLen += strlen(ppszTextList[i]);
}
@ -664,14 +665,14 @@ 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,
int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
0,
pszReturnData, -1, NULL, 0);
/* Allocate memory for the Unicode string */
pwszUnicodeStr = malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
/* NOTE: iUnicodeLen includes space for null terminator */
pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
if (!pwszUnicodeStr) {
ErrorF("winClipboardFlushXEvents - SelectionNotify "
"malloc failed for pwszUnicodeStr, aborting.\n");
@ -689,9 +690,10 @@ winClipboardFlushXEvents(HWND hwnd,
/* Allocate global memory for the X clipboard data */
hGlobal = GlobalAlloc(GMEM_MOVEABLE,
sizeof(wchar_t) * (iUnicodeLen + 1));
sizeof(wchar_t) * iUnicodeLen);
}
else {
int iConvertDataLen = 0;
pszConvertData = strdup(pszReturnData);
iConvertDataLen = strlen(pszConvertData) + 1;
@ -723,9 +725,8 @@ winClipboardFlushXEvents(HWND hwnd,
}
/* Copy the returned string into the global memory */
if (fUseUnicode) {
memcpy(pszGlobalData,
pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1));
if (data->fUseUnicode) {
wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
free(pwszUnicodeStr);
pwszUnicodeStr = NULL;
}
@ -740,7 +741,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);
@ -770,7 +771,7 @@ winClipboardFlushXEvents(HWND hwnd,
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
}
return WIN_XEVENTS_NOTIFY;
return WIN_XEVENTS_NOTIFY_DATA;
case SelectionClear:
winDebug("SelectionClear - doing nothing\n");
@ -790,7 +791,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) {

View File

@ -92,6 +92,13 @@ main (int argc, char *argv[])
continue;
}
/* Look for -noprimary */
if (!strcmp (argv[i], "-noprimary"))
{
fPrimarySelection = False;
continue;
}
/* Yack when we find a parameter that we don't know about */
printf ("Unknown parameter: %s\nExiting.\n", argv[i]);
exit (1);

View File

@ -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)

View File

@ -43,12 +43,6 @@
DISPATCH_PROC(winProcEstablishConnection);
/*
* References to external symbols
*/
extern Bool g_fClipboard;
/*
* Wrapper for internal EstablishConnection function.
* Initializes internal clients that must not be started until

View File

@ -37,13 +37,8 @@ from The Open Group.
#include "winmsg.h"
#include "winmonitors.h"
/*
* References to external symbols
*/
#ifdef XWIN_CLIPBOARD
extern Bool g_fUnicodeClipboard;
extern Bool g_fClipboard;
#include "winclipboard/winclipboard.h"
#endif
/*
@ -716,6 +711,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
/*

View File

@ -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

View File

@ -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);
/*

View File

@ -1218,6 +1218,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);