winclipboardxevents.c [plain text]
#include "winclipboard.h"
Bool
winClipboardFlushXEvents (HWND hwnd,
Atom atomClipboard,
Atom atomLocalProperty,
Atom atomUTF8String,
Atom atomCompoundText,
Atom atomTargets,
Atom atomDeleteWindow,
int iWindow,
Display *pDisplay,
Bool fUnicodeSupport)
{
Atom atomReturnType;
int iReturnFormat;
unsigned long ulReturnItems;
XTextProperty xtpText;
XEvent event;
XSelectionEvent eventSelection;
unsigned long ulReturnBytesLeft;
unsigned char *pszReturnData = NULL;
char *pszGlobalData = NULL;
int iReturn;
HGLOBAL hGlobal;
Bool fReturn = TRUE;
XICCEncodingStyle xiccesStyle;
int iUTF8;
char *pszUTF8 = NULL;
char *pszTextList[2];
int iCount;
char **ppszTextList = NULL;
wchar_t *pwszUnicodeStr = NULL;
int iUnicodeLen = 0;
while (XPending (pDisplay))
{
XNextEvent (pDisplay, &event);
switch (event.type)
{
case ClientMessage:
if (event.xclient.data.l[0] == atomDeleteWindow)
{
ErrorF ("\nwinClipboardFlushXEvents - Received "
"WM_DELETE_WINDOW\n\n");
fReturn = FALSE;
}
else
ErrorF ("\nwinClipboardFlushXEvents - Unknown ClientMessage\n\n");
break;
case SelectionClear:
iReturn = XConvertSelection (pDisplay,
event.xselectionclear.selection,
atomCompoundText,
atomLocalProperty,
iWindow,
CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionClear - "
"XConvertSelection () failed\n");
pthread_exit (NULL);
}
break;
case SelectionRequest:
#if 0
char *pszAtomName = NULL
ErrorF ("SelectionRequest - target %d\n",
event.xselectionrequest.target);
pszAtomName = XGetAtomName (pDisplay,
event.xselectionrequest.target);
ErrorF ("SelectionRequest - Target atom name %s\n", pszAtomName);
XFree (pszAtomName);
pszAtomName = NULL;
#endif
if (event.xselectionrequest.target != XA_STRING
&& event.xselectionrequest.target != atomUTF8String
&& event.xselectionrequest.target != atomCompoundText
&& event.xselectionrequest.target != atomTargets)
{
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
eventSelection.display = pDisplay;
eventSelection.requestor = event.xselectionrequest.requestor;
eventSelection.selection = event.xselectionrequest.selection;
eventSelection.target = event.xselectionrequest.target;
eventSelection.property = None;
eventSelection.time = event.xselectionrequest.time;
iReturn = XSendEvent (pDisplay,
eventSelection.requestor,
False,
0L,
(XEvent *) &eventSelection);
if (iReturn == BadValue || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"XSendEvent () failed\n");
pthread_exit (NULL);
}
break;
}
if (event.xselectionrequest.target == atomTargets)
{
Atom atomTargetArr[4] = {atomTargets,
atomCompoundText,
atomUTF8String,
XA_STRING};
iReturn = XChangeProperty (pDisplay,
event.xselectionrequest.requestor,
event.xselectionrequest.property,
event.xselectionrequest.target,
8,
PropModeReplace,
(char *) atomTargetArr,
sizeof (atomTargetArr));
if (iReturn == BadAlloc
|| iReturn == BadAtom
|| iReturn == BadMatch
|| iReturn == BadValue
|| iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"XChangeProperty failed: %d\n",
iReturn);
}
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
eventSelection.display = pDisplay;
eventSelection.requestor = event.xselectionrequest.requestor;
eventSelection.selection = event.xselectionrequest.selection;
eventSelection.target = event.xselectionrequest.target;
eventSelection.property = event.xselectionrequest.property;
eventSelection.time = event.xselectionrequest.time;
iReturn = XSendEvent (pDisplay,
eventSelection.requestor,
False,
0L,
(XEvent *) &eventSelection);
if (iReturn == BadValue || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"XSendEvent () failed\n");
}
break;
}
if (!OpenClipboard (hwnd))
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"OpenClipboard () failed: %08x\n",
GetLastError ());
pthread_exit (NULL);
}
if (event.xselectionrequest.target == XA_STRING)
xiccesStyle = XStringStyle;
else if (event.xselectionrequest.target == atomUTF8String)
xiccesStyle = XUTF8StringStyle;
else if (event.xselectionrequest.target == atomCompoundText)
xiccesStyle = XCompoundTextStyle;
else
xiccesStyle = XStringStyle;
if (fUnicodeSupport)
hGlobal = GetClipboardData (CF_UNICODETEXT);
else
hGlobal = GetClipboardData (CF_TEXT);
if (!hGlobal)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"GetClipboardData () failed: %08x\n",
GetLastError ());
pthread_exit (NULL);
}
pszGlobalData = (char *) GlobalLock (hGlobal);
if (fUnicodeSupport)
{
iUTF8 = WideCharToMultiByte (CP_UTF8,
0,
(LPCWSTR)pszGlobalData,
-1,
NULL,
0,
NULL,
NULL);
pszUTF8 = (char *) malloc (iUTF8);
WideCharToMultiByte (CP_UTF8,
0,
(LPCWSTR)pszGlobalData,
-1,
pszUTF8,
iUTF8,
NULL,
NULL);
}
if (fUnicodeSupport)
{
winClipboardDOStoUNIX (pszUTF8, strlen (pszUTF8));
pszTextList[0] = pszUTF8;
pszTextList[1] = NULL;
xtpText.value = NULL;
iReturn = Xutf8TextListToTextProperty (pDisplay,
pszTextList,
1,
xiccesStyle,
&xtpText);
if (iReturn == XNoMemory || iReturn == XLocaleNotSupported)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"Xutf8TextListToTextProperty failed: %d\n",
iReturn);
exit(1);
}
free (pszUTF8);
}
else
winClipboardDOStoUNIX (pszGlobalData, strlen (pszGlobalData));
if (fUnicodeSupport)
iReturn = XChangeProperty (pDisplay,
event.xselectionrequest.requestor,
event.xselectionrequest.property,
event.xselectionrequest.target,
8,
PropModeReplace,
xtpText.value,
xtpText.nitems);
else
iReturn = XChangeProperty (pDisplay,
event.xselectionrequest.requestor,
event.xselectionrequest.property,
event.xselectionrequest.target,
8,
PropModeReplace,
pszGlobalData,
strlen (pszGlobalData));
if (iReturn == BadAlloc || iReturn == BadAtom
|| iReturn == BadMatch || iReturn == BadValue
|| iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"XChangeProperty failed: %d\n",
iReturn);
pthread_exit (NULL);
}
GlobalUnlock (hGlobal);
pszGlobalData = NULL;
CloseClipboard ();
if (fUnicodeSupport)
{
XFree (xtpText.value);
xtpText.value = NULL;
}
eventSelection.type = SelectionNotify;
eventSelection.send_event = True;
eventSelection.display = pDisplay;
eventSelection.requestor = event.xselectionrequest.requestor;
eventSelection.selection = event.xselectionrequest.selection;
eventSelection.target = event.xselectionrequest.target;
eventSelection.property = event.xselectionrequest.property;
eventSelection.time = event.xselectionrequest.time;
iReturn = XSendEvent (pDisplay,
eventSelection.requestor,
False,
0L,
(XEvent *) &eventSelection);
if (iReturn == BadValue || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
"XSendEvent () failed\n");
pthread_exit (NULL);
}
break;
case SelectionNotify:
#if 0
ErrorF ("SelectionNotify\n");
#endif
{
char *pszAtomName;
pszAtomName = XGetAtomName (pDisplay,
event.xselection.selection);
ErrorF ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
pszAtomName);
XFree (pszAtomName);
}
#if 0
if (event.xselection.selection != atomClipboard)
break;
#endif
if (fUnicodeSupport)
{
if (event.xselection.property == None)
{
if(event.xselection.target == XA_STRING)
{
#if 0
ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
"XA_STRING\n");
#endif
return fReturn;
}
else if (event.xselection.target == atomUTF8String)
{
ErrorF ("winClipboardFlushXEvents - SelectionNotify "
"UTF8\n");
iReturn = XConvertSelection (pDisplay,
event.xselection.selection,
XA_STRING,
atomLocalProperty,
iWindow,
CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionNotify "
"- XConvertSelection () failed\n");
pthread_exit (NULL);
}
return fReturn;
}
else if (event.xselection.target == atomCompoundText)
{
ErrorF ("winClipboardFlushXEvents - SelectionNotify "
"CompoundText\n");
iReturn = XConvertSelection (pDisplay,
event.xselection.selection,
atomUTF8String,
atomLocalProperty,
iWindow,
CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - SelectionNotify "
"- XConvertSelection () failed\n");
pthread_exit (NULL);
}
return fReturn;
}
else
{
ErrorF ("winClipboardFlushXEvents - Unknown format\n");
return fReturn;
}
}
}
if (fUnicodeSupport)
iReturn = XGetWindowProperty (pDisplay,
iWindow,
atomLocalProperty,
0,
0,
False,
AnyPropertyType,
&xtpText.encoding,
&xtpText.format,
&xtpText.nitems,
&ulReturnBytesLeft,
&xtpText.value);
else
iReturn = XGetWindowProperty (pDisplay,
iWindow,
atomLocalProperty,
0,
0,
False,
AnyPropertyType,
&atomReturnType,
&iReturnFormat,
&ulReturnItems,
&ulReturnBytesLeft,
&pszReturnData);
if (iReturn != Success)
{
ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
"XGetWindowProperty () failed\n");
pthread_exit (NULL);
}
#if 0
if (fUnicodeSupport)
ErrorF ("SelectionNotify - returned data %d left %d\n",
xtpText.nitems, ulReturnBytesLeft);
else
ErrorF ("SelectionNotify - returned data %d left %d\n",
ulReturnItems, ulReturnBytesLeft);
#endif
if (fUnicodeSupport)
iReturn = XGetWindowProperty (pDisplay,
iWindow,
atomLocalProperty,
0,
ulReturnBytesLeft,
False,
AnyPropertyType,
&xtpText.encoding,
&xtpText.format,
&xtpText.nitems,
&ulReturnBytesLeft,
&xtpText.value);
else
iReturn = XGetWindowProperty (pDisplay,
iWindow,
atomLocalProperty,
0,
ulReturnBytesLeft,
False,
AnyPropertyType,
&atomReturnType,
&iReturnFormat,
&ulReturnItems,
&ulReturnBytesLeft,
&pszReturnData);
if (iReturn != Success)
{
ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
"XGetWindowProperty () failed\n");
pthread_exit (NULL);
}
if (fUnicodeSupport)
{
#if 0
char *pszAtomName = NULL;
ErrorF ("SelectionNotify - returned data %d left %d\n",
prop.nitems, ulReturnBytesLeft);
pszAtomName = XGetAtomName(pDisplay, prop.encoding);
ErrorF ("Notify atom name %s\n", pszAtomName);
XFree (pszAtomName);
pszAtomName = NULL;
#endif
Xutf8TextPropertyToTextList (pDisplay,
&xtpText,
&ppszTextList,
&iCount);
if (iCount > 0)
{
pszReturnData = malloc (strlen (ppszTextList[0]) + 1);
strcpy (pszReturnData, ppszTextList[0]);
}
else
{
pszReturnData = malloc (1);
pszReturnData[0] = 0;
}
XFreeStringList (ppszTextList);
XFree (xtpText.value);
}
winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData));
if (fUnicodeSupport)
{
iUnicodeLen = MultiByteToWideChar (CP_UTF8,
0,
pszReturnData,
-1,
NULL,
0);
pwszUnicodeStr
= (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1));
MultiByteToWideChar (CP_UTF8,
0,
pszReturnData,
-1,
pwszUnicodeStr,
iUnicodeLen);
}
if (!OpenClipboard (hwnd))
{
ErrorF ("winClipboardFlushXEvents - OpenClipboard () failed: "
"%08x\n", GetLastError ());
pthread_exit (NULL);
}
if (!EmptyClipboard ())
{
ErrorF ("winClipboardFlushXEvents - EmptyClipboard () failed: "
"%08x\n", GetLastError ());
pthread_exit (NULL);
}
if (fUnicodeSupport)
hGlobal = GlobalAlloc (GMEM_MOVEABLE,
sizeof (wchar_t) * (iUnicodeLen + 1));
else
hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen (pszReturnData) + 1);
pszGlobalData = GlobalLock (hGlobal);
if (pszGlobalData == NULL)
{
ErrorF ("winClipboardFlushXEvents - Could not lock global "
"memory for clipboard transfer\n");
pthread_exit (NULL);
}
if (fUnicodeSupport)
memcpy (pszGlobalData,
pwszUnicodeStr,
sizeof (wchar_t) * (iUnicodeLen + 1));
else
strcpy (pszGlobalData, pszReturnData);
if (fUnicodeSupport)
{
free (pwszUnicodeStr);
pwszUnicodeStr = NULL;
}
else
{
XFree (pszReturnData);
pszReturnData = NULL;
}
GlobalUnlock (hGlobal);
pszGlobalData = NULL;
if (fUnicodeSupport)
SetClipboardData (CF_UNICODETEXT, hGlobal);
else
SetClipboardData (CF_TEXT, hGlobal);
if (!CloseClipboard ())
{
ErrorF ("winClipboardFlushXEvents - CloseClipboard () failed: "
"%08x\n",
GetLastError ());
pthread_exit (NULL);
}
iReturn = XSetSelectionOwner (pDisplay,
event.xselection.selection,
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
char *pszAtomName = NULL;
pszAtomName = XGetAtomName (pDisplay,
event.xselection.selection);
ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
"Could not reassert ownership of selection ATOM: %s\n",
pszAtomName);
XFree (pszAtomName);
pszAtomName = NULL;
pthread_exit (NULL);
}
else
{
#if 0
char *pszAtomName = NULL;
pszAtomName = XGetAtomName (pDisplay,
event.xselection.selection);
ErrorF ("SelectionNotify - Reasserted ownership of ATOM: %s\n",
pszAtomName);
XFree (pszAtomName);
pszAtomName = NULL;
#endif
}
#if 0
iReturn = XSetSelectionOwner (pDisplay,
atomClipboard,
iWindow, CurrentTime);
if (iReturn == BadAtom || iReturn == BadWindow)
{
ErrorF ("winClipboardFlushXEvents - Could not reassert "
"ownership of selection\n");
pthread_exit (NULL);
}
#endif
break;
#if 0
case CreateNotify:
ErrorF ("FlushXEvents - CreateNotify parent: %ld\twindow: %ld\n",
event.xcreatewindow.parent, event.xcreatewindow.window);
break;
case DestroyNotify:
ErrorF ("FlushXEvents - DestroyNotify window: %ld\tevent: %ld\n",
event.xdestroywindow.window, event.xdestroywindow.event);
break;
#endif
default:
break;
}
}
return fReturn;
}