diff options
Diffstat (limited to 'xorg-server/hw/xwin/winclipboardxevents.c')
-rw-r--r-- | xorg-server/hw/xwin/winclipboardxevents.c | 1684 |
1 files changed, 859 insertions, 825 deletions
diff --git a/xorg-server/hw/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c index ec40814db..11fde16b9 100644 --- a/xorg-server/hw/xwin/winclipboardxevents.c +++ b/xorg-server/hw/xwin/winclipboardxevents.c @@ -1,825 +1,859 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the copyright holder(s) - *and author(s) shall not be used in advertising or otherwise to promote - *the sale, use or other dealings in this Software without prior written - *authorization from the copyright holder(s) and author(s). - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "winclipboard.h" -#include "misc.h" - - -/* - * References to external symbols - */ - -extern Bool g_fUnicodeSupport; - - -/* - * Process any pending X events - */ - -int -winClipboardFlushXEvents (HWND hwnd, - int iWindow, - Display *pDisplay, - Bool fUseUnicode) -{ - static Atom atomLocalProperty; - static Atom atomCompoundText; - static Atom atomUTF8String; - static Atom atomTargets; - static int generation; - - if (generation != serverGeneration) - { - generation = serverGeneration; - atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); - atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); - atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); - atomTargets = XInternAtom (pDisplay, "TARGETS", False); - } - - /* Process all pending events */ - while (XPending (pDisplay)) - { - XTextProperty xtpText = {0}; - XEvent event; - XSelectionEvent eventSelection; - unsigned long ulReturnBytesLeft; - unsigned char *pszReturnData = NULL; - char *pszGlobalData = NULL; - 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; - int i; - Bool fAbort = FALSE; - Bool fCloseClipboard = FALSE; - Bool fSetClipboardData = TRUE; - - /* Get the next event - will not block because one is ready */ - XNextEvent (pDisplay, &event); - - /* Branch on the event type */ - switch (event.type) - { - /* - * SelectionRequest - */ - - 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 - - /* Abort if invalid target type */ - if (event.xselectionrequest.target != XA_STRING - && event.xselectionrequest.target != atomUTF8String - && event.xselectionrequest.target != atomCompoundText - && event.xselectionrequest.target != atomTargets) - { - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Handle targets type of request */ - if (event.xselectionrequest.target == atomTargets) - { - Atom atomTargetArr[] = {atomTargets, - atomCompoundText, - atomUTF8String, - XA_STRING}; - - /* Try to change the property */ - iReturn = XChangeProperty (pDisplay, - event.xselectionrequest.requestor, - event.xselectionrequest.property, - XA_ATOM, - 32, - PropModeReplace, - (unsigned char *) atomTargetArr, - (sizeof (atomTargetArr) - / sizeof (atomTargetArr[0]))); - if (iReturn == BadAlloc - || iReturn == BadAtom - || iReturn == BadMatch - || iReturn == BadValue - || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XChangeProperty failed: %d\n", - iReturn); - } - - /* Setup selection notify xevent */ - 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; - - /* - * Notify the requesting window that - * the operation has completed - */ - iReturn = XSendEvent (pDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - } - break; - } - - /* Check that clipboard format is available */ - if (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? */ - if (hwnd != lasthwnd) count = 0; - count++; - if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " - "available from Win32 clipboard. Aborting %d.\n", count); - lasthwnd = hwnd; - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - else if (!fUseUnicode - && !IsClipboardFormatAvailable (CF_TEXT)) - { - ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " - "available from Win32 clipboard. Aborting.\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow () == hwnd) - { - CloseClipboard (); - } - - /* Access the clipboard */ - if (!OpenClipboard (hwnd)) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "OpenClipboard () failed: %08x\n", - GetLastError ()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Indicate that clipboard was opened */ - fCloseClipboard = TRUE; - - /* Setup the string style */ - if (event.xselectionrequest.target == XA_STRING) - xiccesStyle = XStringStyle; -#ifdef X_HAVE_UTF8_STRING - else if (event.xselectionrequest.target == atomUTF8String) - xiccesStyle = XUTF8StringStyle; -#endif - else if (event.xselectionrequest.target == atomCompoundText) - xiccesStyle = XCompoundTextStyle; - else - xiccesStyle = XStringStyle; - - /* - * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me - */ - - /* Get a pointer to the clipboard text, in desired format */ - if (fUseUnicode) - { - /* Retrieve clipboard data */ - hGlobal = GetClipboardData (CF_UNICODETEXT); - } - else - { - /* Retrieve clipboard data */ - hGlobal = GetClipboardData (CF_TEXT); - } - if (!hGlobal) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "GetClipboardData () failed: %08x\n", - GetLastError ()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - pszGlobalData = (char *) GlobalLock (hGlobal); - - /* Convert the Unicode string to UTF8 (MBCS) */ - if (fUseUnicode) - { - iConvertDataLen = WideCharToMultiByte (CP_UTF8, - 0, - (LPCWSTR)pszGlobalData, - -1, - NULL, - 0, - NULL, - NULL); - /* NOTE: iConvertDataLen includes space for null terminator */ - pszConvertData = (char *) malloc (iConvertDataLen); - WideCharToMultiByte (CP_UTF8, - 0, - (LPCWSTR)pszGlobalData, - -1, - pszConvertData, - iConvertDataLen, - NULL, - NULL); - } - else - { - pszConvertData = strdup (pszGlobalData); - iConvertDataLen = strlen (pszConvertData) + 1; - } - - /* Convert DOS string to UNIX string */ - winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); - - /* Setup our text list */ - pszTextList[0] = pszConvertData; - pszTextList[1] = NULL; - - /* Initialize the text property */ - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Create the text property from the text list */ - if (fUseUnicode) - { -#ifdef X_HAVE_UTF8_STRING - iReturn = Xutf8TextListToTextProperty (pDisplay, - pszTextList, - 1, - xiccesStyle, - &xtpText); -#endif - } - else - { - iReturn = XmbTextListToTextProperty (pDisplay, - pszTextList, - 1, - xiccesStyle, - &xtpText); - } - if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "X*TextListToTextProperty failed: %d\n", - iReturn); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Free the converted string */ - free (pszConvertData); - pszConvertData = NULL; - - /* Copy the clipboard text to the requesting window */ - iReturn = XChangeProperty (pDisplay, - event.xselectionrequest.requestor, - event.xselectionrequest.property, - event.xselectionrequest.target, - 8, - PropModeReplace, - xtpText.value, - xtpText.nitems); - if (iReturn == BadAlloc || iReturn == BadAtom - || iReturn == BadMatch || iReturn == BadValue - || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XChangeProperty failed: %d\n", - iReturn); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Release the clipboard data */ - GlobalUnlock (hGlobal); - pszGlobalData = NULL; - fCloseClipboard = FALSE; - CloseClipboard (); - - /* Clean up */ - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Setup selection notify event */ - 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; - - /* Notify the requesting window that the operation has completed */ - iReturn = XSendEvent (pDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - winClipboardFlushXEvents_SelectionRequest_Done: - /* Free allocated resources */ - if (xtpText.value) - { - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - } - if (pszConvertData) - free (pszConvertData); - if (hGlobal && pszGlobalData) - GlobalUnlock (hGlobal); - - /* - * Send a SelectionNotify event to the requesting - * client when we abort. - */ - if (fAbort) - { - /* Setup selection notify event */ - 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; - - /* Notify the requesting window that the operation is complete */ - iReturn = XSendEvent (pDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) - { - /* - * Should not be a problem if XSendEvent fails because - * the client may simply have exited. - */ - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed for abort event.\n"); - } - } - - /* Close clipboard if it was opened */ - if (fCloseClipboard) - { - fCloseClipboard = FALSE; - CloseClipboard (); - } - break; - - - /* - * SelectionNotify - */ - - case SelectionNotify: -#if 0 - ErrorF ("winClipboardFlushXEvents - SelectionNotify\n"); - { - char *pszAtomName; - - pszAtomName = XGetAtomName (pDisplay, - event.xselection.selection); - - ErrorF ("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", - pszAtomName); - - XFree (pszAtomName); - } -#endif - - - /* - * Request conversion of UTF8 and CompoundText targets. - */ - if (event.xselection.property == None) - { - if (event.xselection.target == XA_STRING) - { -#if 0 - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XA_STRING\n"); -#endif - return WIN_XEVENTS_CONVERT; - } - else if (event.xselection.target == atomUTF8String) - { -#if 0 - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "Requesting conversion of UTF8 target.\n"); -#endif - iReturn = XConvertSelection (pDisplay, - event.xselection.selection, - XA_STRING, - atomLocalProperty, - iWindow, - CurrentTime); - if (iReturn != Success) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XConvertSelection () failed for UTF8String, " - "aborting: %d\n", - iReturn); - break; - } - - /* Process the ConvertSelection event */ - XFlush (pDisplay); - return WIN_XEVENTS_CONVERT; - } -#ifdef X_HAVE_UTF8_STRING - else if (event.xselection.target == atomCompoundText) - { -#if 0 - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "Requesting conversion of CompoundText target.\n"); -#endif - iReturn = XConvertSelection (pDisplay, - event.xselection.selection, - atomUTF8String, - atomLocalProperty, - iWindow, - CurrentTime); - if (iReturn != Success) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XConvertSelection () failed for CompoundText, " - "aborting: %d\n", - iReturn); - break; - } - - /* Process the ConvertSelection event */ - XFlush (pDisplay); - return WIN_XEVENTS_CONVERT; - } -#endif - else - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "Unknown format. Cannot request conversion, " - "aborting.\n"); - 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 - SelectionNotify - " - "XGetWindowProperty () failed, aborting: %d\n", - iReturn); - break; - } - -#if 0 - ErrorF ("SelectionNotify - returned data %d left %d\n", - xtpText.nitems, ulReturnBytesLeft); -#endif - - /* Request the selection data */ - iReturn = XGetWindowProperty (pDisplay, - iWindow, - atomLocalProperty, - 0, - ulReturnBytesLeft, - False, - AnyPropertyType, - &xtpText.encoding, - &xtpText.format, - &xtpText.nitems, - &ulReturnBytesLeft, - &xtpText.value); - if (iReturn != Success) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XGetWindowProperty () failed, aborting: %d\n", - iReturn); - break; - } - -#if 0 - { - char *pszAtomName = NULL; - - ErrorF ("SelectionNotify - returned data %d left %d\n", - xtpText.nitems, ulReturnBytesLeft); - - pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); - ErrorF ("Notify atom name %s\n", pszAtomName); - XFree (pszAtomName); - pszAtomName = NULL; - } -#endif - - if (fUseUnicode) - { -#ifdef X_HAVE_UTF8_STRING - /* Convert the text property to a text list */ - iReturn = Xutf8TextPropertyToTextList (pDisplay, - &xtpText, - &ppszTextList, - &iCount); -#endif - } - else - { - iReturn = XmbTextPropertyToTextList (pDisplay, - &xtpText, - &ppszTextList, - &iCount); - } - if (iReturn == Success || iReturn > 0) - { - /* Conversion succeeded or some unconvertible characters */ - if (ppszTextList != NULL) - { - iReturnDataLen = 0; - for (i = 0; i < iCount; i++) - { - iReturnDataLen += strlen(ppszTextList[i]); - } - pszReturnData = malloc (iReturnDataLen + 1); - pszReturnData[0] = '\0'; - for (i = 0; i < iCount; i++) - { - strcat (pszReturnData, ppszTextList[i]); - } - } - else - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "X*TextPropertyToTextList list_return is NULL.\n"); - pszReturnData = malloc (1); - pszReturnData[0] = '\0'; - } - } - else - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "X*TextPropertyToTextList returned: "); - switch (iReturn) - { - case XNoMemory: - ErrorF ("XNoMemory\n"); - break; - case XConverterNotFound: - ErrorF ("XConverterNotFound\n"); - break; - default: - ErrorF ("%d", iReturn); - break; - } - pszReturnData = malloc (1); - pszReturnData[0] = '\0'; - } - - /* Free the data returned from XGetWindowProperty */ - if (ppszTextList) - XFreeStringList (ppszTextList); - ppszTextList = NULL; - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Convert the X clipboard string to DOS format */ - winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); - - if (fUseUnicode) - { - /* Find out how much space needed to convert MBCS to Unicode */ - iUnicodeLen = MultiByteToWideChar (CP_UTF8, - 0, - pszReturnData, - -1, - NULL, - 0); - - /* Allocate memory for the Unicode string */ - pwszUnicodeStr - = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); - if (!pwszUnicodeStr) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify " - "malloc failed for pwszUnicodeStr, aborting.\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionNotify_Done; - } - - /* Do the actual conversion */ - MultiByteToWideChar (CP_UTF8, - 0, - pszReturnData, - -1, - pwszUnicodeStr, - iUnicodeLen); - - /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc (GMEM_MOVEABLE, - sizeof (wchar_t) * (iUnicodeLen + 1)); - } - else - { - pszConvertData = strdup (pszReturnData); - iConvertDataLen = strlen (pszConvertData) + 1; - - /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); - } - - free (pszReturnData); - - /* Check that global memory was allocated */ - if (!hGlobal) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify " - "GlobalAlloc failed, aborting: %ld\n", - GetLastError ()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionNotify_Done; - } - - /* Obtain a pointer to the global memory */ - pszGlobalData = GlobalLock (hGlobal); - if (pszGlobalData == NULL) - { - ErrorF ("winClipboardFlushXEvents - Could not lock global " - "memory for clipboard transfer\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionNotify_Done; - } - - /* Copy the returned string into the global memory */ - if (fUseUnicode) - { - memcpy (pszGlobalData, - pwszUnicodeStr, - sizeof (wchar_t) * (iUnicodeLen + 1)); - free (pwszUnicodeStr); - pwszUnicodeStr = NULL; - } - else - { - strcpy (pszGlobalData, pszConvertData); - free (pszConvertData); - pszConvertData = NULL; - } - - /* Release the pointer to the global memory */ - GlobalUnlock (hGlobal); - pszGlobalData = NULL; - - /* Push the selection data to the Windows clipboard */ - if (fUseUnicode) - SetClipboardData (CF_UNICODETEXT, hGlobal); - else - SetClipboardData (CF_TEXT, hGlobal); - - /* Flag that SetClipboardData has been called */ - fSetClipboardData = FALSE; - - /* - * NOTE: Do not try to free pszGlobalData, it is owned by - * Windows after the call to SetClipboardData (). - */ - - winClipboardFlushXEvents_SelectionNotify_Done: - /* Free allocated resources */ - if (ppszTextList) - XFreeStringList (ppszTextList); - if (xtpText.value) - { - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - } - if (pszConvertData) - free (pszConvertData); - if (pwszUnicodeStr) - free (pwszUnicodeStr); - if (hGlobal && pszGlobalData) - GlobalUnlock (hGlobal); - if (fSetClipboardData && g_fUnicodeSupport) - SetClipboardData (CF_UNICODETEXT, NULL); - if (fSetClipboardData) - SetClipboardData (CF_TEXT, NULL); - return WIN_XEVENTS_NOTIFY; - - default: - break; - } - } - - return WIN_XEVENTS_SUCCESS; -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ *"Software"), to deal in the Software without restriction, including
+ *without limitation the rights to use, copy, modify, merge, publish,
+ *distribute, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
+ *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *Except as contained in this notice, the name of the copyright holder(s)
+ *and author(s) shall not be used in advertising or otherwise to promote
+ *the sale, use or other dealings in this Software without prior written
+ *authorization from the copyright holder(s) and author(s).
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "winclipboard.h"
+#include "misc.h"
+#include "winmsg.h"
+
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUnicodeSupport;
+
+
+/*
+ * Process any pending X events
+ */
+
+int
+winClipboardFlushXEvents (HWND hwnd,
+ int iWindow,
+ Display *pDisplay,
+ Bool fUseUnicode,
+ Bool ClipboardOpened)
+{
+ static Atom atomLocalProperty;
+ static Atom atomCompoundText;
+ static Atom atomUTF8String;
+ static Atom atomTargets;
+ static int generation;
+
+ if (generation != serverGeneration)
+ {
+ generation = serverGeneration;
+ atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
+ atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
+ atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
+ atomTargets = XInternAtom (pDisplay, "TARGETS", False);
+ }
+
+ /* Process all pending events */
+ while (XPending (pDisplay))
+ {
+ XTextProperty xtpText = {0};
+ XEvent event;
+ XSelectionEvent eventSelection;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+ char *pszGlobalData = NULL;
+ 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;
+ int i;
+ Bool fAbort = FALSE;
+ Bool fCloseClipboard = FALSE;
+ Bool fSetClipboardData = TRUE;
+
+ /* Get the next event - will not block because one is ready */
+ XNextEvent (pDisplay, &event);
+
+ winDebug ("Received event type %d\n",event.type);
+
+ /* Branch on the event type */
+ switch (event.type)
+ {
+ /*
+ * SelectionRequest
+ */
+
+ case SelectionRequest:
+#ifdef _DEBUG
+ {
+ char *pszAtomName = NULL;
+
+ winDebug ("SelectionRequest - target %d\n",
+ event.xselectionrequest.target);
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselectionrequest.target);
+ winDebug ("SelectionRequest - Target atom name %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+ winDebug ("SelectionRequest - owner %d\n", event.xselectionrequest.owner);
+ winDebug ("SelectionRequest - requestor %d\n", event.xselectionrequest.requestor);
+ }
+#endif
+
+ /* Abort if invalid target type */
+ if (event.xselectionrequest.target != XA_STRING
+ && event.xselectionrequest.target != atomUTF8String
+ && event.xselectionrequest.target != atomCompoundText
+ && event.xselectionrequest.target != atomTargets)
+ {
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Handle targets type of request */
+ if (event.xselectionrequest.target == atomTargets)
+ {
+ Atom atomTargetArr[] = {atomTargets,
+ atomCompoundText,
+ atomUTF8String,
+ XA_STRING};
+
+ /* Try to change the property */
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char *) atomTargetArr,
+ (sizeof (atomTargetArr)
+ / sizeof (atomTargetArr[0])));
+ if (iReturn == BadAlloc
+ || iReturn == BadAtom
+ || iReturn == BadMatch
+ || iReturn == BadValue
+ || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XChangeProperty failed: %d\n",
+ iReturn);
+ }
+
+ /* Setup selection notify xevent */
+ 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;
+
+ /*
+ * Notify the requesting window that
+ * the operation has completed
+ */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XSendEvent () failed\n");
+ }
+ break;
+ }
+
+ /* Check that clipboard format is available */
+ if (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? */
+ if (hwnd != lasthwnd) count = 0;
+ count++;
+ if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not "
+ "available from Win32 clipboard. Aborting %d.\n", count);
+ lasthwnd = hwnd;
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+ else if (!fUseUnicode
+ && !IsClipboardFormatAvailable (CF_TEXT))
+ {
+ ErrorF ("winClipboardFlushXEvents - CF_TEXT is not "
+ "available from Win32 clipboard. Aborting.\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Access the clipboard */
+ if (!ClipboardOpened)
+ {
+ if (!OpenClipboard (hwnd))
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "OpenClipboard () failed: %08x\n",
+ GetLastError ());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Indicate that clipboard was opened */
+ fCloseClipboard = TRUE;
+ }
+ /* Setup the string style */
+ if (event.xselectionrequest.target == XA_STRING)
+ xiccesStyle = XStringStyle;
+#ifdef X_HAVE_UTF8_STRING
+ else if (event.xselectionrequest.target == atomUTF8String)
+ xiccesStyle = XUTF8StringStyle;
+#endif
+ else if (event.xselectionrequest.target == atomCompoundText)
+ xiccesStyle = XCompoundTextStyle;
+ else
+ xiccesStyle = XStringStyle;
+
+ /*
+ * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me
+ */
+
+ /* Get a pointer to the clipboard text, in desired format */
+ if (fUseUnicode)
+ {
+ /* Retrieve clipboard data */
+ hGlobal = GetClipboardData (CF_UNICODETEXT);
+ }
+ else
+ {
+ /* Retrieve clipboard data */
+ hGlobal = GetClipboardData (CF_TEXT);
+ }
+ if (!hGlobal)
+ {
+ if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && ClipboardOpened)
+ {
+ ErrorF("We should not have received a SelectionRequest????\n"
+ "The owner is the clipboard, but in reality it was"
+ "an X window\n");
+ /* Set the owner to None */
+ XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
+ XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime);
+ }
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "GetClipboardData () failed: %08x\n",
+ GetLastError ());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+ pszGlobalData = (char *) GlobalLock (hGlobal);
+
+ /* Convert the Unicode string to UTF8 (MBCS) */
+ if (fUseUnicode)
+ {
+ iConvertDataLen = WideCharToMultiByte (CP_UTF8,
+ 0,
+ (LPCWSTR)pszGlobalData,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ /* NOTE: iConvertDataLen includes space for null terminator */
+ pszConvertData = (char *) malloc (iConvertDataLen);
+ WideCharToMultiByte (CP_UTF8,
+ 0,
+ (LPCWSTR)pszGlobalData,
+ -1,
+ pszConvertData,
+ iConvertDataLen,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ pszConvertData = strdup (pszGlobalData);
+ iConvertDataLen = strlen (pszConvertData) + 1;
+ }
+
+ /* Convert DOS string to UNIX string */
+ winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData));
+
+ /* Setup our text list */
+ pszTextList[0] = pszConvertData;
+ pszTextList[1] = NULL;
+
+ /* Initialize the text property */
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+
+ /* Create the text property from the text list */
+ if (fUseUnicode)
+ {
+#ifdef X_HAVE_UTF8_STRING
+ iReturn = Xutf8TextListToTextProperty (pDisplay,
+ pszTextList,
+ 1,
+ xiccesStyle,
+ &xtpText);
+#endif
+ }
+ else
+ {
+ iReturn = XmbTextListToTextProperty (pDisplay,
+ pszTextList,
+ 1,
+ xiccesStyle,
+ &xtpText);
+ }
+ if (iReturn == XNoMemory || iReturn == XLocaleNotSupported)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "X*TextListToTextProperty failed: %d\n",
+ iReturn);
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Free the converted string */
+ free (pszConvertData);
+ pszConvertData = NULL;
+
+ /* Copy the clipboard text to the requesting window */
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ event.xselectionrequest.target,
+ 8,
+ PropModeReplace,
+ xtpText.value,
+ xtpText.nitems);
+ if (iReturn == BadAlloc || iReturn == BadAtom
+ || iReturn == BadMatch || iReturn == BadValue
+ || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XChangeProperty failed: %d\n",
+ iReturn);
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Release the clipboard data */
+ GlobalUnlock (hGlobal);
+ pszGlobalData = NULL;
+ if (fCloseClipboard)
+ {
+ fCloseClipboard = FALSE;
+ CloseClipboard ();
+ }
+ /* Clean up */
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+
+ /* Setup selection notify event */
+ 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;
+
+ /* Notify the requesting window that the operation has completed */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XSendEvent () failed\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ winClipboardFlushXEvents_SelectionRequest_Done:
+ /* Free allocated resources */
+ if (xtpText.value)
+ {
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+ }
+ if (pszConvertData)
+ free (pszConvertData);
+ if (hGlobal && pszGlobalData)
+ GlobalUnlock (hGlobal);
+
+ /*
+ * Send a SelectionNotify event to the requesting
+ * client when we abort.
+ */
+ if (fAbort)
+ {
+ /* Setup selection notify event */
+ 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;
+
+ /* Notify the requesting window that the operation is complete */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ /*
+ * Should not be a problem if XSendEvent fails because
+ * the client may simply have exited.
+ */
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XSendEvent () failed for abort event.\n");
+ }
+ }
+
+ /* Close clipboard if it was opened */
+ if (fCloseClipboard)
+ {
+ fCloseClipboard = FALSE;
+ CloseClipboard ();
+ }
+ break;
+
+
+ /*
+ * SelectionClear
+ */
+ case SelectionClear:
+#ifdef _DEBUG
+ winDebug ("winClipboardFlushXEvents - SelectionClear\n");
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+
+ winDebug ("SelectionClear - ATOM: %s\n",
+ pszAtomName);
+ winDebug ("SelectionClear - owner %d\n", event.xselectionrequest.owner);
+
+ XFree (pszAtomName);
+ }
+#endif
+ break;
+
+ /*
+ * SelectionNotify
+ */
+ case SelectionNotify:
+#ifdef _DEBUG
+ winDebug ("winClipboardFlushXEvents - SelectionNotify\n");
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+
+ winDebug ("SelectionNotify - ATOM: %s\n",
+ pszAtomName);
+ winDebug ("SelectionNotify - requestor %d\n", event.xselectionrequest.requestor);
+
+ XFree (pszAtomName);
+ }
+#endif
+
+
+ /*
+ * Request conversion of UTF8 and CompoundText targets.
+ */
+ if (event.xselection.property == None)
+ {
+ if (event.xselection.target == XA_STRING)
+ {
+#if 0
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "XA_STRING\n");
+#endif
+ return WIN_XEVENTS_CONVERT;
+ }
+ else if (event.xselection.target == atomUTF8String)
+ {
+#if 0
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "Requesting conversion of UTF8 target.\n");
+#endif
+ iReturn = XConvertSelection (pDisplay,
+ event.xselection.selection,
+ XA_STRING,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+ if (iReturn != Success)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "XConvertSelection () failed for UTF8String, "
+ "aborting: %d\n",
+ iReturn);
+ break;
+ }
+
+ /* Process the ConvertSelection event */
+ XFlush (pDisplay);
+ return WIN_XEVENTS_CONVERT;
+ }
+#ifdef X_HAVE_UTF8_STRING
+ else if (event.xselection.target == atomCompoundText)
+ {
+#if 0
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "Requesting conversion of CompoundText target.\n");
+#endif
+ iReturn = XConvertSelection (pDisplay,
+ event.xselection.selection,
+ atomUTF8String,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+ if (iReturn != Success)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "XConvertSelection () failed for CompoundText, "
+ "aborting: %d\n",
+ iReturn);
+ break;
+ }
+
+ /* Process the ConvertSelection event */
+ XFlush (pDisplay);
+ return WIN_XEVENTS_CONVERT;
+ }
+#endif
+ else
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "Unknown format. Cannot request conversion, "
+ "aborting.\n");
+ 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 - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n",
+ iReturn);
+ break;
+ }
+
+#if 0
+ ErrorF ("SelectionNotify - returned data %d left %d\n",
+ xtpText.nitems, ulReturnBytesLeft);
+#endif
+
+ /* Request the selection data */
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ ulReturnBytesLeft,
+ False,
+ AnyPropertyType,
+ &xtpText.encoding,
+ &xtpText.format,
+ &xtpText.nitems,
+ &ulReturnBytesLeft,
+ &xtpText.value);
+ if (iReturn != Success)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n",
+ iReturn);
+ break;
+ }
+
+#if 0
+ {
+ char *pszAtomName = NULL;
+
+ ErrorF ("SelectionNotify - returned data %d left %d\n",
+ xtpText.nitems, ulReturnBytesLeft);
+
+ pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
+ ErrorF ("Notify atom name %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+ }
+#endif
+
+ if (fUseUnicode)
+ {
+#ifdef X_HAVE_UTF8_STRING
+ /* Convert the text property to a text list */
+ iReturn = Xutf8TextPropertyToTextList (pDisplay,
+ &xtpText,
+ &ppszTextList,
+ &iCount);
+#endif
+ }
+ else
+ {
+ iReturn = XmbTextPropertyToTextList (pDisplay,
+ &xtpText,
+ &ppszTextList,
+ &iCount);
+ }
+ if (iReturn == Success || iReturn > 0)
+ {
+ /* Conversion succeeded or some unconvertible characters */
+ if (ppszTextList != NULL)
+ {
+ iReturnDataLen = 0;
+ for (i = 0; i < iCount; i++)
+ {
+ iReturnDataLen += strlen(ppszTextList[i]);
+ }
+ pszReturnData = (char *) malloc (iReturnDataLen + 1);
+ pszReturnData[0] = '\0';
+ for (i = 0; i < iCount; i++)
+ {
+ strcat (pszReturnData, ppszTextList[i]);
+ }
+ }
+ else
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "X*TextPropertyToTextList list_return is NULL.\n");
+ pszReturnData = (char *) malloc (1);
+ pszReturnData[0] = '\0';
+ }
+ }
+ else
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "X*TextPropertyToTextList returned: ");
+ switch (iReturn)
+ {
+ case XNoMemory:
+ ErrorF ("XNoMemory\n");
+ break;
+ case XConverterNotFound:
+ ErrorF ("XConverterNotFound\n");
+ break;
+ default:
+ ErrorF ("%d", iReturn);
+ break;
+ }
+ pszReturnData = (char *) malloc (1);
+ pszReturnData[0] = '\0';
+ }
+
+ /* Free the data returned from XGetWindowProperty */
+ if (ppszTextList)
+ XFreeStringList (ppszTextList);
+ ppszTextList = NULL;
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+
+ /* Convert the X clipboard string to DOS format */
+ winClipboardUNIXtoDOS ((unsigned char **)&pszReturnData, strlen (pszReturnData));
+
+ if (fUseUnicode)
+ {
+ /* Find out how much space needed to convert MBCS to Unicode */
+ iUnicodeLen = MultiByteToWideChar (CP_UTF8,
+ 0,
+ pszReturnData,
+ -1,
+ NULL,
+ 0);
+
+ /* Allocate memory for the Unicode string */
+ pwszUnicodeStr
+ = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1));
+ if (!pwszUnicodeStr)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify "
+ "malloc failed for pwszUnicodeStr, aborting.\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
+ }
+
+ /* Do the actual conversion */
+ MultiByteToWideChar (CP_UTF8,
+ 0,
+ pszReturnData,
+ -1,
+ pwszUnicodeStr,
+ iUnicodeLen);
+
+ /* Allocate global memory for the X clipboard data */
+ hGlobal = GlobalAlloc (GMEM_MOVEABLE,
+ sizeof (wchar_t) * (iUnicodeLen + 1));
+ }
+ else
+ {
+ pszConvertData = strdup (pszReturnData);
+ iConvertDataLen = strlen (pszConvertData) + 1;
+
+ /* Allocate global memory for the X clipboard data */
+ hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen);
+ }
+
+ free (pszReturnData);
+
+ /* Check that global memory was allocated */
+ if (!hGlobal)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify "
+ "GlobalAlloc failed, aborting: %ld\n",
+ GetLastError ());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
+ }
+
+ /* Obtain a pointer to the global memory */
+ pszGlobalData = GlobalLock (hGlobal);
+ if (pszGlobalData == NULL)
+ {
+ ErrorF ("winClipboardFlushXEvents - Could not lock global "
+ "memory for clipboard transfer\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
+ }
+
+ /* Copy the returned string into the global memory */
+ if (fUseUnicode)
+ {
+ memcpy (pszGlobalData,
+ pwszUnicodeStr,
+ sizeof (wchar_t) * (iUnicodeLen + 1));
+ free (pwszUnicodeStr);
+ pwszUnicodeStr = NULL;
+ }
+ else
+ {
+ strcpy (pszGlobalData, pszConvertData);
+ free (pszConvertData);
+ pszConvertData = NULL;
+ }
+
+ /* Release the pointer to the global memory */
+ GlobalUnlock (hGlobal);
+ pszGlobalData = NULL;
+
+ /* Push the selection data to the Windows clipboard */
+ if (fUseUnicode)
+ SetClipboardData (CF_UNICODETEXT, hGlobal);
+ else
+ SetClipboardData (CF_TEXT, hGlobal);
+
+ /* Flag that SetClipboardData has been called */
+ fSetClipboardData = FALSE;
+
+ /*
+ * NOTE: Do not try to free pszGlobalData, it is owned by
+ * Windows after the call to SetClipboardData ().
+ */
+
+ winClipboardFlushXEvents_SelectionNotify_Done:
+ /* Free allocated resources */
+ if (ppszTextList)
+ XFreeStringList (ppszTextList);
+ if (xtpText.value)
+ {
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+ }
+ if (pszConvertData)
+ free (pszConvertData);
+ if (pwszUnicodeStr)
+ free (pwszUnicodeStr);
+ if (hGlobal && pszGlobalData)
+ GlobalUnlock (hGlobal);
+ if (fSetClipboardData && g_fUnicodeSupport)
+ SetClipboardData (CF_UNICODETEXT, NULL);
+ if (fSetClipboardData)
+ SetClipboardData (CF_TEXT, NULL);
+ return WIN_XEVENTS_NOTIFY;
+
+ default:
+ break;
+ }
+ }
+
+ return WIN_XEVENTS_SUCCESS;
+}
|