diff -u -r 20020612/xevents.c i18n/xevents.c --- 20020612/xevents.c 2002-06-13 02:05:42.000000000 +0900 +++ i18n/xevents.c 2002-06-18 02:40:20.000000000 +0900 @@ -76,7 +76,8 @@ Bool FlushXEvents (HWND hwnd, Atom atomLocalProperty, Atom atomUTF8String, - int iWindow, Display *pDisplay, Atom atomDeleteWindow) + Atom atomCompoundText, Atom atomTargets, int iWindow, + Display *pDisplay, Atom atomDeleteWindow) { XEvent event; XSelectionEvent eventSelection; @@ -88,6 +89,16 @@ int iReturn; HGLOBAL hGlobal; Bool fReturn = TRUE; + XTextProperty prop; + char **cl; + int count; + unsigned long left; + char *textList[2]; + char *lpUTF8str; + int iUTF8len; + XICCEncodingStyle style; + wchar_t *lpUnicodeStr; + int iUnicodeLen; /* Process all pending events */ while (XPending (pDisplay)) @@ -112,7 +123,7 @@ /* Request the lost selection contents */ iReturn = XConvertSelection (pDisplay, event.xselectionclear.selection, - XA_STRING, + atomCompoundText, atomLocalProperty, iWindow, CurrentTime); @@ -132,11 +143,14 @@ #if 0 printf ("SelectionRequest - target %d\n", event.xselectionrequest.target); + printf ("Target atom name %s\n", + XGetAtomName(pDisplay, event.xselectionrequest.target)); #endif - /* Abort if invalid target type */ if (event.xselectionrequest.target != XA_STRING - && event.xselectionrequest.target != atomUTF8String) + && event.xselectionrequest.target != atomUTF8String + && event.xselectionrequest.target != atomCompoundText + && event.xselectionrequest.target != atomTargets) { /* Setup selection notify event */ eventSelection.type = SelectionNotify; @@ -163,6 +177,50 @@ break; } + if (event.xselectionrequest.target == atomTargets) + { + Atom atTargetArr[4] = {atomTargets, atomCompoundText, atomUTF8String, XA_STRING}; + + iReturn = XChangeProperty (pDisplay, + event.xselectionrequest.requestor, + event.xselectionrequest.property, + event.xselectionrequest.target, + 8, + PropModeReplace, + (char *)(atTargetArr), + sizeof(atTargetArr)); + + if (iReturn == BadAlloc || iReturn == BadAtom + || iReturn == BadMatch || iReturn == BadValue + || iReturn == BadWindow) + { + printf ("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) + { + printf ("XSendEvent () failed\n"); + } + break; + } + /* Access the clipboard */ if (!OpenClipboard (hwnd)) { @@ -170,17 +228,43 @@ exit (1); } + if (event.xselectionrequest.target == XA_STRING) + style = XStringStyle; + else if (event.xselectionrequest.target == atomUTF8String) + style = XUTF8StringStyle; + else if (event.xselectionrequest.target == atomCompoundText) + style = XCompoundTextStyle; + else + style = XStringStyle; + /* Get a pointer to the clipboard text */ - hGlobal = GetClipboardData (CF_TEXT); + hGlobal = GetClipboardData (CF_UNICODETEXT); if (!hGlobal) { printf ("GetClipboardData () failed\n"); exit (1); } pszGlobalData = (char *) GlobalLock (hGlobal); + iUTF8len = WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)pszGlobalData, -1, NULL, 0, NULL, NULL); + lpUTF8str = (char*)malloc(iUTF8len+1); + WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)pszGlobalData, -1, lpUTF8str, iUTF8len, NULL, NULL); /* Convert DOS string to UNIX string */ - DOStoUNIX (pszGlobalData, strlen (pszGlobalData)); + DOStoUNIX (lpUTF8str, strlen (lpUTF8str)); + textList[0] = lpUTF8str; + textList[1] = NULL; + prop.value = NULL; + + iReturn = Xutf8TextListToTextProperty (pDisplay, textList, 1, + style, + &prop); + if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) + { + printf ("SelectionRequest - Xutf8TextListToTextProperty failed: %d\n", + iReturn); + exit(1); + } + free (lpUTF8str); /* Copy the clipboard text to the requesting window */ iReturn = XChangeProperty (pDisplay, @@ -189,8 +273,8 @@ event.xselectionrequest.target, 8, PropModeReplace, - pszGlobalData, - strlen (pszGlobalData)); + prop.value, + prop.nitems); if (iReturn == BadAlloc || iReturn == BadAtom || iReturn == BadMatch || iReturn == BadValue || iReturn == BadWindow) @@ -203,6 +287,7 @@ /* Release the clipboard data */ GlobalUnlock (hGlobal); pszGlobalData = NULL; + XFree(prop.value); CloseClipboard (); /* Setup selection notify event */ @@ -237,6 +322,53 @@ #if 0 printf ("SelectionNotify\n"); #endif + if (event.xselection.property == None) + { + if(event.xselection.target == XA_STRING) + { +#if 0 + printf ("SelectionNotify XA_STRING\n"); +#endif + return fReturn; + } + else if (event.xselection.target == atomUTF8String) + { + printf ("SelectionNotify UTF8\n"); + iReturn = XConvertSelection (pDisplay, + XA_PRIMARY, + XA_STRING, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + printf ("SelectionNotify - XConvertSelection () failed\n"); + exit (1); + } + return fReturn; + } + else if (event.xselection.target == atomCompoundText) + { + printf ("SelectionNotify CompoundText\n"); + iReturn = XConvertSelection (pDisplay, + XA_PRIMARY, + atomUTF8String, + atomLocalProperty, + iWindow, + CurrentTime); + if (iReturn == BadAtom || iReturn == BadWindow) + { + printf ("SelectionNotify - XConvertSelection () failed\n"); + exit (1); + } + return fReturn; + } + else + { + printf("Unknown format\n"); + return fReturn; + } + } /* Retrieve the size of the stored data */ iReturn = XGetWindowProperty (pDisplay, @@ -246,11 +378,11 @@ 0, /* Don't get data, just get size */ False, AnyPropertyType, - &atomReturnType, - &iReturnFormat, - &ulReturnItems, - &ulReturnBytesLeft, - &pszReturnData); + &prop.encoding, + &prop.format, + &prop.nitems, + &left, + &prop.value); if (iReturn != Success) { printf ("SelectionNotify - XGetWindowProperty () failed\n"); @@ -259,7 +391,7 @@ #if 0 printf ("SelectionNotify - returned data %d left %d\n", - ulReturnItems, ulReturnBytesLeft); + prop.nitems, left); #endif /* Request the selection data */ @@ -267,23 +399,48 @@ iWindow, atomLocalProperty, 0, - ulReturnBytesLeft, + left, False, AnyPropertyType, - &atomReturnType, - &iReturnFormat, - &ulReturnItems, + &prop.encoding, + &prop.format, + &prop.nitems, &ulReturnBytesLeft, - &pszReturnData); + &prop.value); if (iReturn != Success) { printf ("SelectionNotify - XGetWindowProperty () failed\n"); exit (1); } +#if 0 + printf ("SelectionNotify - returned data %d left %d\n", + prop.nitems, ulReturnBytesLeft); + printf ("Notify atom name %s\n", + XGetAtomName(pDisplay, prop.encoding)); +#endif + Xutf8TextPropertyToTextList (pDisplay, &prop, &cl, &count); + if (count > 0) + { + pszReturnData = malloc (strlen(cl[0])+1); + strcpy (pszReturnData, cl[0]); + } + else + { + pszReturnData = malloc (1); + pszReturnData[0] = 0; + } + /* Free the data returned from XGetWindowProperty */ + XFreeStringList (cl); + XFree (prop.value); + /* Convert the X clipboard string to DOS format */ UNIXtoDOS (&pszReturnData, strlen (pszReturnData)); + iUnicodeLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0); + lpUnicodeStr = (wchar_t*)malloc(sizeof(wchar_t)*(iUnicodeLen+1)); + MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, lpUnicodeStr, iUnicodeLen); + /* Access the Windows clipboard */ if (!OpenClipboard (hwnd)) { @@ -299,7 +456,7 @@ } /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc (GMEM_MOVEABLE, strlen (pszReturnData) + 1); + hGlobal = GlobalAlloc (GMEM_MOVEABLE, sizeof(wchar_t)*(iUnicodeLen+1)); /* Obtain a pointer to the global memory */ pszGlobalData = GlobalLock (hGlobal); @@ -310,18 +467,17 @@ } /* Copy the returned string into the global memory */ - strcpy (pszGlobalData, pszReturnData); + memcpy (pszGlobalData, lpUnicodeStr, sizeof(wchar_t)*(iUnicodeLen+1)); - /* Free the data returned from XGetWindowProperty */ - XFree (pszReturnData); - pszReturnData = NULL; + free (lpUnicodeStr); + lpUnicodeStr = NULL; /* Release the pointer to the global memory */ GlobalUnlock (hGlobal); pszGlobalData = NULL; /* Push the selection data to the Windows clipboard */ - SetClipboardData (CF_TEXT, hGlobal); + SetClipboardData (CF_UNICODETEXT, hGlobal); /* * NOTE: Do not try to free pszGlobalData, it is owned by diff -u -r 20020612/xevents.h i18n/xevents.h --- 20020612/xevents.h 2002-06-13 02:05:52.000000000 +0900 +++ i18n/xevents.h 2002-06-17 16:42:20.000000000 +0900 @@ -37,6 +37,7 @@ Bool FlushXEvents (HWND hwnd, Atom atomLocalProperty, Atom atomUTF8String, - int iWindow, Display *pDisplay, Atom atomDeleteWindow); + Atom atomCompoundText, Atom atomTargets, int iWindow, + Display *pDisplay, Atom atomDeleteWindow); #endif diff -u -r 20020612/xwinclip.c i18n/xwinclip.c --- 20020612/xwinclip.c 2002-06-13 02:37:44.000000000 +0900 +++ i18n/xwinclip.c 2002-06-17 16:42:20.000000000 +0900 @@ -42,7 +42,11 @@ #include #include #include - +#ifdef X_LOCALE +#include +#else +#include +#endif /* Fixups to prevent collisions between Windows and X headers */ #undef MINSHORT @@ -119,6 +123,8 @@ Atom atomClipboard, atomClipboardManager; Atom atomLocalProperty; Atom atomUTF8String; + Atom atomCompoundText; + Atom atomTargets; #if 0 char *pszAtom = NULL; char *pszProperty = NULL; @@ -141,6 +147,22 @@ signal (SIGQUIT, handle_kill); #endif + +#ifdef X_LOCALE + if (!Xsetlocale(LC_ALL, "")) +#else + if (!setlocale(LC_ALL, "")) +#endif + { + printf ("setlocale() error\n"); + exit (1); + } + if (XSupportsLocale() == False) + { + printf ("Locale not supported by X\n"); + exit (1); + } + /* Open the X display */ do { pDisplay = XOpenDisplay (NULL); @@ -308,14 +330,30 @@ exit (1); } + /* Create an atom for COMPOUND_TEXT */ + atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); + if (atomCompoundText == None) + { + printf ("Could not create COMPOUND_TEXT atom\n"); + exit (1); + } + + /* Create an atom for TARGETS */ + atomTargets = XInternAtom (pDisplay, "TARGETS", False); + if (atomTargets == None) + { + printf ("Could not create TARGETS atom\n"); + exit (1); + } + /* Pre-flush X events */ /* * NOTE: Apparently you'll freeze if you don't do this, * because there may be events in local data structures * already. */ - FlushXEvents (hwnd, atomLocalProperty, atomUTF8String, - iWindow, pDisplay, atomDeleteWindow); + FlushXEvents (hwnd, atomLocalProperty, atomUTF8String, atomCompoundText, + atomTargets, iWindow, pDisplay, atomDeleteWindow); /* Pre-flush Windows messages */ FlushWindowsMessageQueue (hwnd); @@ -365,8 +403,8 @@ /* Process X events */ /* Exit when we see that server is shutting down */ - fReturn = FlushXEvents (hwnd, atomLocalProperty, atomUTF8String, - iWindow, pDisplay, atomDeleteWindow); + fReturn = FlushXEvents (hwnd, atomLocalProperty, atomUTF8String, atomCompoundText, + atomTargets, iWindow, pDisplay, atomDeleteWindow); if (!fReturn) { printf ("Caught WM_DELETE_WINDOW - shutting down\n");