summaryrefslogtreecommitdiff
path: root/hw/xwin/winclipboardxevents.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
commit9508a382f8a9f241dab097d921b6d290c1c3a776 (patch)
treefa456480bae7040c3f971a70b390f2d091c680b5 /hw/xwin/winclipboardxevents.c
parentded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff)
Initial revision
Diffstat (limited to 'hw/xwin/winclipboardxevents.c')
-rw-r--r--hw/xwin/winclipboardxevents.c722
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;
+}