diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
commit | 9508a382f8a9f241dab097d921b6d290c1c3a776 (patch) | |
tree | fa456480bae7040c3f971a70b390f2d091c680b5 /hw/xwin/winclipboardxevents.c | |
parent | ded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff) |
Initial revision
Diffstat (limited to 'hw/xwin/winclipboardxevents.c')
-rw-r--r-- | hw/xwin/winclipboardxevents.c | 722 |
1 files changed, 722 insertions, 0 deletions
diff --git a/hw/xwin/winclipboardxevents.c b/hw/xwin/winclipboardxevents.c new file mode 100644 index 000000000..a09c7c185 --- /dev/null +++ b/hw/xwin/winclipboardxevents.c @@ -0,0 +1,722 @@ +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *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 THE XFREE86 PROJECT 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 + *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. + * + * Authors: Harold L Hunt II + */ +/* $XFree86: xc/programs/Xserver/hw/xwin/winclipboardxevents.c,v 1.1 2003/02/12 15:01:38 alanh Exp $ */ + +#include "winclipboard.h" + + +/* + * Process any pending X events + */ + +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; + + /* Process all pending events */ + while (XPending (pDisplay)) + { + /* 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 ("\nReceived WM_DELETE_WINDOW\n\n"); + fReturn = FALSE; + } + else + ErrorF ("\nUnknown 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 ("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; +#endif + + /* Abort if invalid target type */ + if (event.xselectionrequest.target != XA_STRING + && event.xselectionrequest.target != atomUTF8String + && 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 ("SelectionRequest - XSendEvent () failed\n"); + pthread_exit (NULL); + } + + break; + } + + /* Handle targets type of request */ + if (event.xselectionrequest.target == atomTargets) + { + Atom atomTargetArr[4] = {atomTargets, + atomCompoundText, + atomUTF8String, + XA_STRING}; + + /* Try to change the property */ + 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 ("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 ("SelectionRequest - XSendEvent () failed\n"); + } + break; + } + + /* Access the clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("SelectionRequest - OpenClipboard () failed: %08x\n", + GetLastError ()); + pthread_exit (NULL); + } + + /* Setup the string style */ + 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; + + /* + * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me + */ + + /* Get a pointer to the clipboard text */ + if (fUnicodeSupport) + hGlobal = GetClipboardData (CF_UNICODETEXT); + else + hGlobal = GetClipboardData (CF_TEXT); + if (!hGlobal) + { + ErrorF ("SelectionRequest - GetClipboardData () failed: %08x\n", + GetLastError ()); + pthread_exit (NULL); + } + 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 */ + WideCharToMultiByte (CP_UTF8, + 0, + (LPCWSTR)pszGlobalData, + -1, + pszUTF8, + iUTF8, + NULL, + NULL); + } + + /* Convert DOS string to UNIX string */ + 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 */ + iReturn = Xutf8TextListToTextProperty (pDisplay, + pszTextList, + 1, + xiccesStyle, + &xtpText); + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + ErrorF ("SelectionRequest - Xutf8TextListToTextProperty " + "failed: %d\n", + iReturn); + exit(1); + } + + /* Free the UTF8 string */ + free (pszUTF8); + } + else + winClipboardDOStoUNIX (pszGlobalData, strlen (pszGlobalData)); + + /* + * FIXME: Pass pszGlobalData and strlen (pszGlobalData( + * on 1 byte, pass xtpText.value and xtpText.nitems + * on 2 byte. + */ + + /* 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)); + if (iReturn == BadAlloc || iReturn == BadAtom + || iReturn == BadMatch || iReturn == BadValue + || iReturn == BadWindow) + { + ErrorF ("SelectionRequest - XChangeProperty failed: %d\n", + iReturn); + pthread_exit (NULL); + } + + /* 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; + } + + /* 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 ("SelectionRequest - XSendEvent () failed\n"); + pthread_exit (NULL); + } + break; + + + /* + * SelectionNotify + */ + + case SelectionNotify: +#if 0 + ErrorF ("SelectionNotify\n"); +#endif + { + char *pszAtomName; + + pszAtomName = XGetAtomName (pDisplay, + event.xselection.selection); + + ErrorF ("SelectionNotify - ATOM: %s\n", + pszAtomName); + + 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? + * + */ + if (fUnicodeSupport) + { + if (event.xselection.property == None) + { + if(event.xselection.target == XA_STRING) + { +#if 0 + ErrorF ("SelectionNotify XA_STRING\n"); +#endif + return fReturn; + } + else if (event.xselection.target == atomUTF8String) + { + ErrorF ("SelectionNotify UTF8\n"); + iReturn = XConvertSelection (pDisplay, + event.xselection.selection, + XA_STRING, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("SelectionNotify - XConvertSelection () " + "failed\n"); + pthread_exit (NULL); + } + return fReturn; + } + else if (event.xselection.target == atomCompoundText) + { + ErrorF ("SelectionNotify CompoundText\n"); + iReturn = XConvertSelection (pDisplay, + event.xselection.selection, + atomUTF8String, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + ErrorF ("SelectionNotify - XConvertSelection () " + "failed\n"); + pthread_exit (NULL); + } + return fReturn; + } + else + { + ErrorF("Unknown format\n"); + return fReturn; + } + } + } + + /* 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); + if (iReturn != Success) + { + ErrorF ("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 + + /* 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); + if (iReturn != Success) + { + ErrorF ("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 + + /* Convert the text property to a text list */ + 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; + } + + /* Free the data returned from XGetWindowProperty */ + XFreeStringList (ppszTextList); + XFree (xtpText.value); + } + + /* Convert the X clipboard string to DOS format */ + winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); + + if (fUnicodeSupport) + { + /* 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)); + + /* Do the actual conversion */ + MultiByteToWideChar (CP_UTF8, + 0, + pszReturnData, + -1, + pwszUnicodeStr, + iUnicodeLen); + } + + /* Access the Windows clipboard */ + if (!OpenClipboard (hwnd)) + { + ErrorF ("OpenClipboard () failed: %08x\n", GetLastError ()); + pthread_exit (NULL); + } + + /* Take ownership of the Window clipboard */ + if (!EmptyClipboard ()) + { + ErrorF ("EmptyClipboard () failed: %08x\n", GetLastError ()); + pthread_exit (NULL); + } + + /* 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); + + /* Obtain a pointer to the global memory */ + pszGlobalData = GlobalLock (hGlobal); + if (pszGlobalData == NULL) + { + ErrorF ("Could not lock global memory for clipboard transfer\n"); + pthread_exit (NULL); + } + + /* 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) + { + free (pwszUnicodeStr); + pwszUnicodeStr = NULL; + } + else + { + XFree (pszReturnData); + pszReturnData = NULL; + } + + /* Release the pointer to the global memory */ + GlobalUnlock (hGlobal); + pszGlobalData = NULL; + + /* Push the selection data to the Windows clipboard */ + if (fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, hGlobal); + else + SetClipboardData (CF_TEXT, hGlobal); + + /* + * NOTE: Do not try to free pszGlobalData, it is owned by + * Windows after the call to SetClipboardData (). + */ + + /* Release the clipboard */ + if (!CloseClipboard ()) + { + ErrorF ("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 ("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 ("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; +} |