diff options
Diffstat (limited to 'hw/xwin/winclipboardxevents.c')
-rw-r--r-- | hw/xwin/winclipboardxevents.c | 871 |
1 files changed, 457 insertions, 414 deletions
diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c index d2cfb2e55..598620c4c 100644 --- a/hw/xwin/winclipboardxevents.c +++ b/hw/xwin/winclipboardxevents.c @@ -1,5 +1,5 @@ /* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. * *Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -15,19 +15,18 @@ *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 THE XFREE86 PROJECT BE LIABLE FOR + *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 XFree86 Project + *Except as contained in this notice, the name of Harold L Hunt II *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 XFree86 Project. + *from Harold L Hunt II. * * Authors: Harold L Hunt II */ -/* $XFree86: xc/programs/Xserver/hw/xwin/winclip.c,v 1.2 2001/06/04 13:04:41 alanh Exp $ */ #include "winclipboard.h" @@ -36,92 +35,74 @@ * Process any pending X events */ -Bool +int 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; + Atom atomLocalProperty = XInternAtom (pDisplay, + WIN_LOCAL_PROPERTY, + False); + Atom atomUTF8String = XInternAtom (pDisplay, + "UTF8_STRING", + False); + Atom atomCompoundText = XInternAtom (pDisplay, + "COMPOUND_TEXT", + False); + Atom 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) { - 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: - /* Request the lost selection contents */ - 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; - - /* * 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; + { + 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 */ @@ -130,49 +111,29 @@ winClipboardFlushXEvents (HWND hwnd, && event.xselectionrequest.target != atomCompoundText && event.xselectionrequest.target != atomTargets) { - /* 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) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - pthread_exit (NULL); - } - - break; + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Handle targets type of request */ if (event.xselectionrequest.target == atomTargets) { - Atom atomTargetArr[4] = {atomTargets, - atomCompoundText, - atomUTF8String, - XA_STRING}; + Atom atomTargetArr[] = {atomTargets, + atomCompoundText, + atomUTF8String, + XA_STRING}; /* Try to change the property */ iReturn = XChangeProperty (pDisplay, event.xselectionrequest.requestor, event.xselectionrequest.property, event.xselectionrequest.target, - 8, + sizeof (atomTargetArr[0]), PropModeReplace, - (char *) atomTargetArr, - sizeof (atomTargetArr)); + (unsigned char *) atomTargetArr, + (sizeof (atomTargetArr) + / sizeof (atomTargetArr[0]))); if (iReturn == BadAlloc || iReturn == BadAtom || iReturn == BadMatch @@ -185,14 +146,14 @@ winClipboardFlushXEvents (HWND hwnd, } /* 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; + 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 @@ -211,20 +172,56 @@ winClipboardFlushXEvents (HWND hwnd, break; } + /* Check that clipboard format is available */ + if (fUnicodeSupport + && !IsClipboardFormatAvailable (CF_UNICODETEXT)) + { + ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " + "available from Win32 clipboard. Aborting.\n"); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + else if (!fUnicodeSupport + && !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 ()); - pthread_exit (NULL); + + /* 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 @@ -234,99 +231,110 @@ winClipboardFlushXEvents (HWND hwnd, * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me */ - /* Get a pointer to the clipboard text */ + /* Get a pointer to the clipboard text, in desired format */ if (fUnicodeSupport) - hGlobal = GetClipboardData (CF_UNICODETEXT); + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_UNICODETEXT); + } else - hGlobal = GetClipboardData (CF_TEXT); + { + /* Retrieve clipboard data */ + hGlobal = GetClipboardData (CF_TEXT); + } if (!hGlobal) { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "GetClipboardData () failed: %08x\n", GetLastError ()); - pthread_exit (NULL); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; } pszGlobalData = (char *) GlobalLock (hGlobal); /* Convert the Unicode string to UTF8 (MBCS) */ if (fUnicodeSupport) { - iUTF8 = WideCharToMultiByte (CP_UTF8, - 0, - (LPCWSTR)pszGlobalData, - -1, - NULL, - 0, - NULL, - NULL); - pszUTF8 = (char *) malloc (iUTF8); /* Don't need +1 */ + 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, - pszUTF8, - iUTF8, + 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; + + /* Create the text property from the text list */ if (fUnicodeSupport) { - winClipboardDOStoUNIX (pszUTF8, strlen (pszUTF8)); - - /* Setup our text list */ - pszTextList[0] = pszUTF8; - pszTextList[1] = NULL; - - /* Initialize the text property */ - xtpText.value = NULL; - - /* Create the text property from the text list */ +#ifdef X_HAVE_UTF8_STRING iReturn = Xutf8TextListToTextProperty (pDisplay, pszTextList, 1, xiccesStyle, &xtpText); - if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "Xutf8TextListToTextProperty failed: %d\n", - iReturn); - exit(1); - } - - /* Free the UTF8 string */ - free (pszUTF8); +#endif } else - winClipboardDOStoUNIX (pszGlobalData, strlen (pszGlobalData)); + { + iReturn = XmbTextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); + } + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + ErrorF ("winClipboardFlushXEvents - SelectionRequest - " + "X*TextListToTextProperty failed: %d\n", + iReturn); - /* - * FIXME: Pass pszGlobalData and strlen (pszGlobalData( - * on 1 byte, pass xtpText.value and xtpText.nitems - * on 2 byte. - */ + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; + } + + /* Free the converted string */ + free (pszConvertData); + pszConvertData = NULL; /* Copy the clipboard text to the requesting window */ - 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)); + 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) @@ -334,20 +342,19 @@ winClipboardFlushXEvents (HWND hwnd, ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XChangeProperty failed: %d\n", iReturn); - pthread_exit (NULL); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; } /* Release the clipboard data */ GlobalUnlock (hGlobal); pszGlobalData = NULL; - CloseClipboard (); - /* FIXME: Don't clean up on 1 byte. */ - if (fUnicodeSupport) - { - XFree (xtpText.value); - xtpText.value = NULL; - } + /* Clean up */ + XFree (xtpText.value); + xtpText.value = NULL; /* Setup selection notify event */ eventSelection.type = SelectionNotify; @@ -369,10 +376,59 @@ winClipboardFlushXEvents (HWND hwnd, { ErrorF ("winClipboardFlushXEvents - SelectionRequest - " "XSendEvent () failed\n"); - pthread_exit (NULL); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionRequest_Done; } - break; + + winClipboardFlushXEvents_SelectionRequest_Done: + /* Free allocated resources */ + if (xtpText.value) + XFree (xtpText.value); + 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) + CloseClipboard (); + break; + /* * SelectionNotify @@ -380,8 +436,7 @@ winClipboardFlushXEvents (HWND hwnd, case SelectionNotify: #if 0 - ErrorF ("SelectionNotify\n"); -#endif + ErrorF ("winClipboardFlushXEvents - SelectionNotify\n"); { char *pszAtomName; @@ -393,189 +448,212 @@ winClipboardFlushXEvents (HWND hwnd, XFree (pszAtomName); } - -#if 0 - /* - * TEMP: Bail if selection is anything other than CLIPBOARD - */ - - if (event.xselection.selection != atomClipboard) - break; #endif + /* - * - * What are we doing here? - * + * Request conversion of UTF8 and CompoundText targets. */ - if (fUnicodeSupport) + if (event.xselection.property == None) { - if (event.xselection.property == None) + if (event.xselection.target == XA_STRING) { - if(event.xselection.target == XA_STRING) - { #if 0 - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XA_STRING\n"); + 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) + 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 " - "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; + ErrorF ("winClipboardFlushXEvents - SelectionNotify - " + "XConvertSelection () failed for UTF8String, " + "aborting: %d\n", + iReturn); + break; } - else + + /* 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 - Unknown format\n"); - return fReturn; + 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 */ - if (fUnicodeSupport) - iReturn = XGetWindowProperty (pDisplay, - iWindow, - atomLocalProperty, - 0, - 0, /* Don't get data, just size */ - False, - AnyPropertyType, - &xtpText.encoding, - &xtpText.format, - &xtpText.nitems, - &ulReturnBytesLeft, - &xtpText.value); - else - iReturn = XGetWindowProperty (pDisplay, - iWindow, - atomLocalProperty, - 0, - 0, /* Don't get data, just size */ - False, - AnyPropertyType, - &atomReturnType, - &iReturnFormat, - &ulReturnItems, - &ulReturnBytesLeft, - &pszReturnData); + 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\n"); - pthread_exit (NULL); + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; } #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); + ErrorF ("SelectionNotify - returned data %d left %d\n", + xtpText.nitems, ulReturnBytesLeft); #endif /* Request the selection data */ - 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); + 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\n"); - pthread_exit (NULL); + "XGetWindowProperty () failed, aborting: %d\n", + iReturn); + break; } - if (fUnicodeSupport) - { #if 0 + { char *pszAtomName = NULL; ErrorF ("SelectionNotify - returned data %d left %d\n", - prop.nitems, ulReturnBytesLeft); + xtpText.nitems, ulReturnBytesLeft); - pszAtomName = XGetAtomName(pDisplay, prop.encoding); + pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); ErrorF ("Notify atom name %s\n", pszAtomName); XFree (pszAtomName); pszAtomName = NULL; + } #endif - + + if (fUnicodeSupport) + { +#ifdef X_HAVE_UTF8_STRING /* Convert the text property to a text list */ - Xutf8TextPropertyToTextList (pDisplay, - &xtpText, - &ppszTextList, - &iCount); - if (iCount > 0) + 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) { - pszReturnData = malloc (strlen (ppszTextList[0]) + 1); - strcpy (pszReturnData, ppszTextList[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; + pszReturnData[0] = '\0'; } - - /* Free the data returned from XGetWindowProperty */ - XFreeStringList (ppszTextList); - XFree (xtpText.value); } - + 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; + /* Convert the X clipboard string to DOS format */ winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); @@ -588,11 +666,20 @@ winClipboardFlushXEvents (HWND hwnd, -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, @@ -600,30 +687,31 @@ winClipboardFlushXEvents (HWND hwnd, -1, pwszUnicodeStr, iUnicodeLen); + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, + sizeof (wchar_t) * (iUnicodeLen + 1)); } - - /* Access the Windows clipboard */ - if (!OpenClipboard (hwnd)) + else { - ErrorF ("winClipboardFlushXEvents - OpenClipboard () failed: " - "%08x\n", GetLastError ()); - pthread_exit (NULL); + pszConvertData = strdup (pszReturnData); + iConvertDataLen = strlen (pszConvertData) + 1; + + /* Allocate global memory for the X clipboard data */ + hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); } - /* Take ownership of the Window clipboard */ - if (!EmptyClipboard ()) + /* Check that global memory was allocated */ + if (!hGlobal) { - ErrorF ("winClipboardFlushXEvents - EmptyClipboard () failed: " - "%08x\n", GetLastError ()); - pthread_exit (NULL); - } + ErrorF ("winClipboardFlushXEvents - SelectionNotify " + "GlobalAlloc failed, aborting: %ld\n", + GetLastError ()); - /* Allocate global memory for the X clipboard data */ - if (fUnicodeSupport) - hGlobal = GlobalAlloc (GMEM_MOVEABLE, - sizeof (wchar_t) * (iUnicodeLen + 1)); - else - hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen (pszReturnData) + 1); + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; + } /* Obtain a pointer to the global memory */ pszGlobalData = GlobalLock (hGlobal); @@ -631,27 +719,26 @@ winClipboardFlushXEvents (HWND hwnd, { ErrorF ("winClipboardFlushXEvents - Could not lock global " "memory for clipboard transfer\n"); - pthread_exit (NULL); + + /* Abort */ + fAbort = TRUE; + goto winClipboardFlushXEvents_SelectionNotify_Done; } /* Copy the returned string into the global memory */ if (fUnicodeSupport) - memcpy (pszGlobalData, - pwszUnicodeStr, - sizeof (wchar_t) * (iUnicodeLen + 1)); - else - strcpy (pszGlobalData, pszReturnData); - - /* Free the data returned from XGetWindowProperty */ - if (fUnicodeSupport) { + memcpy (pszGlobalData, + pwszUnicodeStr, + sizeof (wchar_t) * (iUnicodeLen + 1)); free (pwszUnicodeStr); pwszUnicodeStr = NULL; } else { - XFree (pszReturnData); - pszReturnData = NULL; + strcpy (pszGlobalData, pszConvertData); + free (pszConvertData); + pszConvertData = NULL; } /* Release the pointer to the global memory */ @@ -662,82 +749,38 @@ winClipboardFlushXEvents (HWND hwnd, if (fUnicodeSupport) SetClipboardData (CF_UNICODETEXT, hGlobal); else - SetClipboardData (CF_TEXT, hGlobal); + 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 (). */ - /* Release the clipboard */ - if (!CloseClipboard ()) - { - ErrorF ("winClipboardFlushXEvents - CloseClipboard () failed: " - "%08x\n", - GetLastError ()); - pthread_exit (NULL); - } - - /* Reassert ownership of the selection */ - 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 - /* Reassert ownership of the CLIPBOARD */ - 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 + winClipboardFlushXEvents_SelectionNotify_Done: + /* Free allocated resources */ + if (ppszTextList) + XFreeStringList (ppszTextList); + if (xtpText.value) + XFree (xtpText.value); + if (pszConvertData) + free (pszConvertData); + if (pwszUnicodeStr) + free (pwszUnicodeStr); + if (hGlobal && pszGlobalData) + GlobalUnlock (hGlobal); + if (fSetClipboardData && fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + if (fSetClipboardData && !fUnicodeSupport) + SetClipboardData (CF_TEXT, NULL); + return WIN_XEVENTS_NOTIFY; default: break; } } - return fReturn; + return WIN_XEVENTS_SUCCESS; } |