Merge remote-tracking branch 'jturney/master'
This commit is contained in:
commit
6f4c398a0e
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,4 +33,6 @@ void winFixClipboardChain(void);
|
|||
|
||||
void winClipboardWindowDestroy(void);
|
||||
|
||||
extern Bool fPrimarySelection;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user