From 1df0d3659283915172336ca8c2c9db52e40d9959 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Mon, 11 Dec 2000 01:09:56 +0000 Subject: [PATCH] Add CF_UNICODETEXT as primary text clipboard format. Use [x11drv].TextCP for interchange with X. --- include/clipboard.h | 6 +- windows/clipboard.c | 285 ++++++++++++++++++++++++++++++++------------- windows/queue.c | 1 - windows/user.c | 1 - windows/x11drv/clipboard.c | 79 ++++++------- windows/x11drv/event.c | 26 +++-- 6 files changed, 269 insertions(+), 129 deletions(-) diff --git a/include/clipboard.h b/include/clipboard.h index 99b2a8fe592..dca0f1495f0 100644 --- a/include/clipboard.h +++ b/include/clipboard.h @@ -7,9 +7,9 @@ struct tagWND; typedef struct tagWINE_CLIPFORMAT { - WORD wFormatID; - WORD wRefCount; - WORD wDataPresent; + UINT wFormatID; + UINT wRefCount; + BOOL wDataPresent; LPSTR Name; HANDLE16 hData16; HANDLE hDataSrc32; diff --git a/windows/clipboard.c b/windows/clipboard.c index 3c3ddd881b8..2da3a59e3b8 100644 --- a/windows/clipboard.c +++ b/windows/clipboard.c @@ -58,7 +58,7 @@ static WORD LastRegFormat = CF_REGFORMATBASE; * WARNING: This data ordering is dependendent on the WINE_CLIPFORMAT structure * declared in clipboard.h */ -WINE_CLIPFORMAT ClipFormats[17] = { +WINE_CLIPFORMAT ClipFormats[] = { { CF_TEXT, 1, 0, "Text", 0, 0, 0, 0, NULL, &ClipFormats[1]}, { CF_BITMAP, 1, 0, "Bitmap", 0, 0, 0, 0, &ClipFormats[0], &ClipFormats[2]}, { CF_METAFILEPICT, 1, 0, "MetaFile Picture", 0, 0, 0, 0, &ClipFormats[1], &ClipFormats[3]}, @@ -71,11 +71,12 @@ WINE_CLIPFORMAT ClipFormats[17] = { { CF_PENDATA, 1, 0, "PenData", 0, 0, 0, 0, &ClipFormats[8], &ClipFormats[10]}, { CF_RIFF, 1, 0, "RIFF", 0, 0, 0, 0, &ClipFormats[9], &ClipFormats[11]}, { CF_WAVE, 1, 0, "Wave", 0, 0, 0, 0, &ClipFormats[10], &ClipFormats[12]}, - { CF_OWNERDISPLAY, 1, 0, "Owner Display", 0, 0, 0, 0, &ClipFormats[11], &ClipFormats[13]}, - { CF_DSPTEXT, 1, 0, "DSPText", 0, 0, 0, 0, &ClipFormats[12], &ClipFormats[14]}, - { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", 0, 0, 0, 0, &ClipFormats[13], &ClipFormats[15]}, - { CF_DSPBITMAP, 1, 0, "DSPBitmap", 0, 0, 0, 0, &ClipFormats[14], &ClipFormats[16]}, - { CF_HDROP, 1, 0, "HDROP", 0, 0, 0, 0, &ClipFormats[15], NULL} + { CF_UNICODETEXT, 1, 0, "Unicode Text", 0, 0, 0, 0, &ClipFormats[11], &ClipFormats[13]}, + { CF_OWNERDISPLAY, 1, 0, "Owner Display", 0, 0, 0, 0, &ClipFormats[12], &ClipFormats[14]}, + { CF_DSPTEXT, 1, 0, "DSPText", 0, 0, 0, 0, &ClipFormats[13], &ClipFormats[15]}, + { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", 0, 0, 0, 0, &ClipFormats[14], &ClipFormats[16]}, + { CF_DSPBITMAP, 1, 0, "DSPBitmap", 0, 0, 0, 0, &ClipFormats[15], &ClipFormats[17]}, + { CF_HDROP, 1, 0, "HDROP", 0, 0, 0, 0, &ClipFormats[16], NULL} }; @@ -276,9 +277,10 @@ BOOL CLIPBOARD_IsPresent(WORD wFormat) { /* special case */ - if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT ) + if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT || wFormat == CF_UNICODETEXT ) return ClipFormats[CF_TEXT-1].wDataPresent || - ClipFormats[CF_OEMTEXT-1].wDataPresent; + ClipFormats[CF_OEMTEXT-1].wDataPresent || + ClipFormats[CF_UNICODETEXT-1].wDataPresent; else { LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat ); @@ -422,6 +424,58 @@ static BOOL CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat) return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE; } +/************************************************************************** + * CLIPBOARD_ConvertText + * Returns number of required/converted characters - not bytes! + */ +static INT CLIPBOARD_ConvertText(WORD src_fmt, void const *src, INT src_size, + WORD dst_fmt, void *dst, INT dst_size) +{ + UINT cp; + + if(src_fmt == CF_UNICODETEXT) + { + switch(dst_fmt) + { + case CF_TEXT: + cp = CP_ACP; + break; + case CF_OEMTEXT: + cp = CP_OEMCP; + break; + default: + return 0; + } + return WideCharToMultiByte(cp, 0, src, src_size, dst, dst_size, NULL, NULL); + } + + if(dst_fmt == CF_UNICODETEXT) + { + switch(src_fmt) + { + case CF_TEXT: + cp = CP_ACP; + break; + case CF_OEMTEXT: + cp = CP_OEMCP; + break; + default: + return 0; + } + return MultiByteToWideChar(cp, 0, src, src_size, dst, dst_size); + } + + if(!dst_size) return src_size; + + if(dst_size > src_size) dst_size = src_size; + + if(src_fmt == CF_TEXT ) + CharToOemBuffA(src, dst, dst_size); + else + OemToCharBuffA(src, dst, dst_size); + + return dst_size; +} /************************************************************************** * CLIPBOARD_RenderText @@ -438,24 +492,74 @@ static LPWINE_CLIPFORMAT CLIPBOARD_RenderText( UINT wFormat ) LPWINE_CLIPFORMAT lpSource = ClipFormats; LPWINE_CLIPFORMAT lpTarget; - /* Asked for CF_TEXT and not available - always attempt to convert from CF_OEM_TEXT */ + /* Asked for CF_TEXT but not available - always attempt to convert + from CF_UNICODETEXT or CF_OEMTEXT */ if( wFormat == CF_TEXT && !ClipFormats[CF_TEXT-1].wDataPresent ) { - /* Convert OEMTEXT -> TEXT */ - lpSource = &ClipFormats[CF_OEMTEXT-1]; - lpTarget = &ClipFormats[CF_TEXT-1]; + if(ClipFormats[CF_UNICODETEXT-1].wDataPresent) + { + /* Convert UNICODETEXT -> TEXT */ + lpSource = &ClipFormats[CF_UNICODETEXT-1]; + lpTarget = &ClipFormats[CF_TEXT-1]; - TRACE("\tOEMTEXT -> TEXT\n"); + TRACE("\tUNICODETEXT -> TEXT\n"); + } + else if(ClipFormats[CF_OEMTEXT-1].wDataPresent) + { + /* Convert OEMTEXT -> TEXT */ + lpSource = &ClipFormats[CF_OEMTEXT-1]; + lpTarget = &ClipFormats[CF_TEXT-1]; + + TRACE("\tOEMTEXT -> TEXT\n"); + } + else + lpSource = NULL; /* Conversion format is not available */ } - /* Asked for CF_OEM_TEXT, and CF_TEXT available */ - else if( wFormat == CF_OEMTEXT && !ClipFormats[CF_OEMTEXT-1].wDataPresent - && ClipFormats[CF_TEXT-1].wDataPresent ) + /* Asked for CF_OEMTEXT but not available - always attempt to convert + from CF_UNICODETEXT or CF_TEXT */ + else if( wFormat == CF_OEMTEXT && !ClipFormats[CF_OEMTEXT-1].wDataPresent ) { - /* Convert TEXT -> OEMTEXT */ - lpSource = &ClipFormats[CF_TEXT-1]; - lpTarget = &ClipFormats[CF_OEMTEXT-1]; - - TRACE("\tTEXT -> OEMTEXT\n"); + if(ClipFormats[CF_UNICODETEXT-1].wDataPresent) + { + /* Convert UNICODETEXT -> OEMTEXT */ + lpSource = &ClipFormats[CF_UNICODETEXT-1]; + lpTarget = &ClipFormats[CF_OEMTEXT-1]; + + TRACE("\tUNICODETEXT -> OEMTEXT\n"); + } + else if(ClipFormats[CF_TEXT-1].wDataPresent) + { + /* Convert TEXT -> OEMTEXT */ + lpSource = &ClipFormats[CF_TEXT-1]; + lpTarget = &ClipFormats[CF_OEMTEXT-1]; + + TRACE("\tTEXT -> OEMTEXT\n"); + } + else + lpSource = NULL; /* Conversion format is not available */ + } + /* Asked for CF_UNICODETEXT but not available - always attempt to convert + from CF_TEXT or CF_OEMTEXT */ + else if( wFormat == CF_UNICODETEXT && !ClipFormats[CF_UNICODETEXT-1].wDataPresent ) + { + if(ClipFormats[CF_TEXT-1].wDataPresent) + { + /* Convert TEXT -> UNICODETEXT */ + lpSource = &ClipFormats[CF_TEXT-1]; + lpTarget = &ClipFormats[CF_UNICODETEXT-1]; + + TRACE("\tTEXT -> UNICODETEXT\n"); + } + else if(ClipFormats[CF_OEMTEXT-1].wDataPresent) + { + /* Convert OEMTEXT -> UNICODETEXT */ + lpSource = &ClipFormats[CF_OEMTEXT-1]; + lpTarget = &ClipFormats[CF_UNICODETEXT-1]; + + TRACE("\tOEMTEXT -> UNICODETEXT\n"); + } + else + lpSource = NULL; /* Conversion format is not available */ } /* Text format requested is available - no conversion necessary */ else @@ -470,35 +574,48 @@ static LPWINE_CLIPFORMAT CLIPBOARD_RenderText( UINT wFormat ) /* Convert to the desired target text format, if necessary */ if( lpTarget != lpSource && !lpTarget->hData16 && !lpTarget->hData32 ) { - UINT16 size; + INT src_chars, dst_chars, alloc_size; LPCSTR lpstrS; LPSTR lpstrT; if (lpSource->hData32) { - size = GlobalSize( lpSource->hData32 ); lpstrS = (LPSTR)GlobalLock(lpSource->hData32); } else { - size = GlobalSize16( lpSource->hData16 ); lpstrS = (LPSTR)GlobalLock16(lpSource->hData16); } if( !lpstrS ) return NULL; + + /* Text always NULL terminated */ + if(lpSource->wFormatID == CF_UNICODETEXT) + src_chars = strlenW((LPCWSTR)lpstrS); + else + src_chars = strlen(lpstrS); + + /* Calculate number of characters in the destination buffer */ + dst_chars = CLIPBOARD_ConvertText(lpSource->wFormatID, lpstrS, src_chars, + lpTarget->wFormatID, NULL, 0); + if(!dst_chars) return NULL; + TRACE("\tconverting from '%s' to '%s', %i chars\n", - lpSource->Name, lpTarget->Name, size); - - lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, size); + lpSource->Name, lpTarget->Name, src_chars); + + /* Convert characters to bytes */ + if(lpTarget->wFormatID == CF_UNICODETEXT) + alloc_size = dst_chars * sizeof(WCHAR); + else + alloc_size = dst_chars; + + lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, alloc_size); lpstrT = (LPSTR)GlobalLock(lpTarget->hData32); - + if( lpstrT ) { - if( lpSource->wFormatID == CF_TEXT ) - CharToOemBuffA(lpstrS, lpstrT, size); - else - OemToCharBuffA(lpstrS, lpstrT, size); - TRACE("\tgot %s\n", lpstrT); + CLIPBOARD_ConvertText(lpSource->wFormatID, lpstrS, src_chars, + lpTarget->wFormatID, lpstrT, dst_chars); GlobalUnlock(lpTarget->hData32); } else @@ -678,18 +795,22 @@ HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData ) { CLIPBOARD_DeleteRecord(lpFormat, TRUE); - /* delete existing CF_TEXT/CF_OEMTEXT aliases */ - - if( wFormat == CF_TEXT - && ( ClipFormats[CF_OEMTEXT-1].hData16 - || ClipFormats[CF_OEMTEXT-1].hData32 ) - && !ClipFormats[CF_OEMTEXT-1].wDataPresent ) + /* delete existing CF_UNICODETEXT/CF_TEXT/CF_OEMTEXT aliases */ + if(wFormat == CF_UNICODETEXT) + { + CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE); CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE); - if( wFormat == CF_OEMTEXT - && ( ClipFormats[CF_OEMTEXT-1].hData16 - || ClipFormats[CF_OEMTEXT-1].hData32 ) - && !ClipFormats[CF_TEXT-1].wDataPresent ) + } + else if(wFormat == CF_TEXT) + { + CLIPBOARD_DeleteRecord(&ClipFormats[CF_UNICODETEXT-1], TRUE); + CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE); + } + else if(wFormat == CF_OEMTEXT) + { + CLIPBOARD_DeleteRecord(&ClipFormats[CF_UNICODETEXT-1], TRUE); CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE); + } } bCBHasChanged = TRUE; @@ -732,18 +853,22 @@ HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData ) { CLIPBOARD_DeleteRecord(lpFormat, TRUE); - /* delete existing CF_TEXT/CF_OEMTEXT aliases */ - - if( wFormat == CF_TEXT - && ( ClipFormats[CF_OEMTEXT-1].hData16 - || ClipFormats[CF_OEMTEXT-1].hData32 ) - && !ClipFormats[CF_OEMTEXT-1].wDataPresent ) + /* delete existing CF_UNICODETEXT/CF_TEXT/CF_OEMTEXT aliases */ + if(wFormat == CF_UNICODETEXT) + { + CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE); CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE); - if( wFormat == CF_OEMTEXT - && ( ClipFormats[CF_OEMTEXT-1].hData16 - || ClipFormats[CF_OEMTEXT-1].hData32 ) - && !ClipFormats[CF_TEXT-1].wDataPresent ) + } + else if(wFormat == CF_TEXT) + { + CLIPBOARD_DeleteRecord(&ClipFormats[CF_UNICODETEXT-1], TRUE); + CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE); + } + else if(wFormat == CF_OEMTEXT) + { + CLIPBOARD_DeleteRecord(&ClipFormats[CF_UNICODETEXT-1], TRUE); CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE); + } } bCBHasChanged = TRUE; @@ -780,7 +905,7 @@ HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat ) return 0; } - if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT ) + if( wFormat == CF_UNICODETEXT || wFormat == CF_TEXT || wFormat == CF_OEMTEXT ) { lpRender = CLIPBOARD_RenderText(wFormat); if ( !lpRender ) return 0; @@ -847,7 +972,7 @@ HANDLE WINAPI GetClipboardData( UINT wFormat ) return 0; } - if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT ) + if( wFormat == CF_UNICODETEXT || wFormat == CF_TEXT || wFormat == CF_OEMTEXT ) { lpRender = CLIPBOARD_RenderText(wFormat); if ( !lpRender ) return 0; @@ -938,10 +1063,10 @@ INT WINAPI CountClipboardFormats(void) lpFormat = lpFormat->NextFormat; } - /* these two are equivalent, adjust the total */ - - FormatCount += abs(ClipFormats[CF_TEXT-1].wDataPresent - - ClipFormats[CF_OEMTEXT-1].wDataPresent); + /* these are equivalent, adjust the total */ + FormatCount += (ClipFormats[CF_UNICODETEXT-1].wDataPresent || + ClipFormats[CF_TEXT-1].wDataPresent || + ClipFormats[CF_OEMTEXT-1].wDataPresent) ? 1 : 0; TRACE("\ttotal %d\n", FormatCount); return FormatCount; @@ -988,25 +1113,35 @@ UINT WINAPI EnumClipboardFormats( UINT wFormat ) { if (lpFormat == NULL) return 0; - /* Synthesize CF_TEXT from CF_OEMTEXT and vice versa */ - bFormatPresent = (lpFormat->wDataPresent || - (lpFormat->wFormatID == CF_OEMTEXT && ClipFormats[CF_TEXT-1].wDataPresent) || - (lpFormat->wFormatID == CF_TEXT && ClipFormats[CF_OEMTEXT-1].wDataPresent) ); + if(CLIPBOARD_IsPresent(lpFormat->wFormatID)) + break; /* Query the driver if not yet in the cache */ - if (!bFormatPresent && !USER_Driver.pIsSelectionOwner()) + if (!USER_Driver.pIsSelectionOwner()) { - bFormatPresent = - USER_Driver.pIsClipboardFormatAvailable( (lpFormat->wFormatID == CF_TEXT) ? - CF_OEMTEXT : lpFormat->wFormatID ); + if(lpFormat->wFormatID == CF_UNICODETEXT || + lpFormat->wFormatID == CF_TEXT || + lpFormat->wFormatID == CF_OEMTEXT) + { + if(USER_Driver.pIsClipboardFormatAvailable(CF_UNICODETEXT) || + USER_Driver.pIsClipboardFormatAvailable(CF_TEXT) || + USER_Driver.pIsClipboardFormatAvailable(CF_OEMTEXT)) + bFormatPresent = TRUE; + else + bFormatPresent = FALSE; + } + else + bFormatPresent = USER_Driver.pIsClipboardFormatAvailable(lpFormat->wFormatID); + + if(bFormatPresent) + break; } - if (bFormatPresent) - break; - lpFormat = lpFormat->NextFormat; } + TRACE("Next available format %d\n", lpFormat->wFormatID); + return lpFormat->wFormatID; } @@ -1230,14 +1365,8 @@ BOOL WINAPI IsClipboardFormatAvailable( UINT wFormat ) if (wFormat == 0) /* Reject this case quickly */ bRet = FALSE; - - /* If WINE is not the clipboard selection owner ask the clipboard driver */ - else if ( !USER_Driver.pIsSelectionOwner() ) - bRet = USER_Driver.pIsClipboardFormatAvailable( (wFormat == CF_TEXT) ? - CF_OEMTEXT : wFormat ); - /* Check if the format is in the local cache */ - else - bRet = CLIPBOARD_IsPresent(wFormat); + else + bRet = EnumClipboardFormats(wFormat - 1) == wFormat; TRACE("(%04X)- ret(%d)\n", wFormat, bRet); return bRet; diff --git a/windows/queue.c b/windows/queue.c index 9f90f58408b..4e9ca17526d 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -14,7 +14,6 @@ #include "queue.h" #include "task.h" #include "win.h" -#include "clipboard.h" #include "hook.h" #include "heap.h" #include "thread.h" diff --git a/windows/user.c b/windows/user.c index 137d65f6f94..422929938f7 100644 --- a/windows/user.c +++ b/windows/user.c @@ -15,7 +15,6 @@ #include "task.h" #include "queue.h" #include "win.h" -#include "clipboard.h" #include "controls.h" #include "cursoricon.h" #include "hook.h" diff --git a/windows/x11drv/clipboard.c b/windows/x11drv/clipboard.c index 8434793dcff..2ce203f6648 100644 --- a/windows/x11drv/clipboard.c +++ b/windows/x11drv/clipboard.c @@ -107,7 +107,7 @@ UINT X11DRV_CLIPBOARD_MapPropertyToFormat(char *itemFmtName) else if ( 0 == strncmp(itemFmtName, FMT_PREFIX, strlen(FMT_PREFIX)) ) return RegisterClipboardFormatA(itemFmtName + strlen(FMT_PREFIX)); else if ( 0 == strcmp(itemFmtName, "STRING") ) - return CF_OEMTEXT; + return CF_UNICODETEXT; else if ( 0 == strcmp(itemFmtName, "PIXMAP") || 0 == strcmp(itemFmtName, "BITMAP") ) { @@ -139,8 +139,12 @@ Atom X11DRV_CLIPBOARD_MapFormatToProperty(UINT wFormat) switch (wFormat) { + /* We support only CF_UNICODETEXT, other formats are synthesized */ case CF_OEMTEXT: case CF_TEXT: + return None; + + case CF_UNICODETEXT: prop = XA_STRING; break; @@ -516,9 +520,9 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At * format, if possible. */ if ( (reqType == XA_STRING) - && (atype == XA_STRING) && (aformat == 8) ) /* treat Unix text as CF_OEMTEXT */ + && (atype == XA_STRING) && (aformat == 8) ) + /* convert Unix text to CF_UNICODETEXT */ { - HANDLE16 hText = 0; int i,inlcount = 0; char* lpstr; @@ -527,37 +531,32 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At for(i=0; i <= nitems; i++) if( val[i] == '\n' ) inlcount++; - hText=GlobalAlloc16(GMEM_MOVEABLE, nitems + inlcount + 1); - if( (lpstr = (char*)GlobalLock16(hText)) ) - { - ZeroMemory(lpstr, nitems + inlcount + 1); + if( (lpstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nitems + inlcount + 1)) ) + { + static UINT text_cp = (UINT)-1; + UINT count; + HANDLE hUnicodeText; + for(i=0,inlcount=0; i <= nitems; i++) { if( val[i] == '\n' ) lpstr[inlcount++]='\r'; lpstr[inlcount++]=val[i]; } - GlobalUnlock16(hText); - } - else - hText = 0; - - if( hText ) - { - /* delete previous CF_TEXT and CF_OEMTEXT data */ - lpFormat = CLIPBOARD_LookupFormat(CF_TEXT); - if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32) - CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow)); - - lpFormat = CLIPBOARD_LookupFormat(CF_OEMTEXT); - if (lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32) - CLIPBOARD_DeleteRecord(lpFormat, !(hWndClipWindow)); - - /* Update the CF_OEMTEXT record */ - lpFormat->wDataPresent = 1; - lpFormat->hData32 = 0; - lpFormat->hData16 = hText; - - bRet = TRUE; + + if(text_cp == (UINT)-1) + text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP); + + count = MultiByteToWideChar(text_cp, 0, lpstr, -1, NULL, 0); + hUnicodeText = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, count * sizeof(WCHAR)); + if(hUnicodeText) + { + WCHAR *textW = GlobalLock(hUnicodeText); + MultiByteToWideChar(text_cp, 0, lpstr, -1, textW, count); + GlobalUnlock(hUnicodeText); + SetClipboardData(CF_UNICODETEXT, hUnicodeText); + bRet = TRUE; + } + HeapFree(GetProcessHeap(), 0, lpstr); } } else if ( reqType == XA_PIXMAP || reqType == XA_BITMAP ) /* treat PIXMAP as CF_DIB or CF_BITMAP */ @@ -594,7 +593,7 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At WARN("PIXMAP conversion failed!\n" ); goto END; } - + /* Delete previous clipboard data */ lpFormat = CLIPBOARD_LookupFormat(wFormat); if (lpFormat->wDataPresent && (lpFormat->hData16 || lpFormat->hData32)) @@ -891,6 +890,8 @@ BOOL X11DRV_IsClipboardFormatAvailable(UINT wFormat) Window ownerPrimary = TSXGetSelectionOwner(display,XA_PRIMARY); Window ownerClipboard = TSXGetSelectionOwner(display,xaClipboard); + TRACE("%d\n", wFormat); + /* * If the selection has not been previously cached, or the selection has changed, * try and cache the list of available selection targets from the current selection. @@ -913,14 +914,10 @@ BOOL X11DRV_IsClipboardFormatAvailable(UINT wFormat) /* Exit if there is no selection */ if ( !ownerClipboard && !ownerPrimary ) + { + TRACE("There is no selection\n"); return FALSE; - - if ( wFormat == CF_TEXT ) - wFormat = CF_OEMTEXT; - - /* Check if the format is available in the clipboard cache */ - if ( CLIPBOARD_IsPresent(wFormat) ) - return TRUE; + } /* * Many X client apps (such as XTerminal) don't support being queried @@ -930,6 +927,7 @@ BOOL X11DRV_IsClipboardFormatAvailable(UINT wFormat) if ( !cSelectionTargets ) return X11DRV_GetClipboardData( wFormat ); + TRACE("There is no selection\n"); return FALSE; } @@ -987,8 +985,7 @@ void X11DRV_SetClipboardData(UINT wFormat) * * This method is invoked only when we DO NOT own the X selection * - * NOTE: Clipboard driver doesn't get requests for CF_TEXT data, only - * for CF_OEMTEXT. + * NOTE: Clipboard driver get requests only for CF_UNICODETEXT data. * We always get the data from the selection client each time, * since we have no way of determining if the data in our cache is stale. */ @@ -1000,6 +997,8 @@ BOOL X11DRV_GetClipboardData(UINT wFormat) WND* wnd = NULL; LPWINE_CLIPFORMAT lpFormat; + TRACE("%d\n", wFormat); + if( !selectionAcquired && (wnd = WIN_FindWndPtr(hWnd)) ) { XEvent xe; @@ -1054,6 +1053,8 @@ BOOL X11DRV_GetClipboardData(UINT wFormat) TRACE("\tpresent %s = %i\n", CLIPBOARD_GetFormatName(wFormat), bRet ); } + + TRACE("Returning %d\n", bRet); return bRet; } diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index 519ab377a0c..99364a6d76e 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -1071,29 +1071,40 @@ static Atom EVENT_SelectionRequest_TARGETS( Window requestor, Atom target, Atom */ static Atom EVENT_SelectionRequest_STRING( Window requestor, Atom target, Atom rprop ) { - HANDLE16 hText; + static UINT text_cp = (UINT)-1; + HANDLE hUnicodeText; + LPWSTR uni_text; LPSTR text; int size,i,j; char* lpstr = 0; char *itemFmtName; int xRc; + if(text_cp == (UINT)-1) + text_cp = PROFILE_GetWineIniInt("x11drv", "TextCP", CP_ACP); + /* * Map the requested X selection property type atom name to a * windows clipboard format ID. */ itemFmtName = TSXGetAtomName(display, target); TRACE("Request for %s (wFormat=%x %s)\n", - itemFmtName, CF_TEXT, CLIPBOARD_GetFormatName(CF_TEXT)); + itemFmtName, CF_UNICODETEXT, CLIPBOARD_GetFormatName(CF_UNICODETEXT)); TSXFree(itemFmtName); - hText = GetClipboardData16(CF_TEXT); - if ( !hText ) + hUnicodeText = GetClipboardData(CF_UNICODETEXT); + if(!hUnicodeText) + return None; + uni_text = GlobalLock(hUnicodeText); + if(!uni_text) return None; - text = GlobalLock16(hText); + + size = WideCharToMultiByte(text_cp, 0, uni_text, -1, NULL, 0, NULL, NULL); + text = HeapAlloc(GetProcessHeap(), 0, size); if (!text) return None; - size = GlobalSize16(hText); + WideCharToMultiByte(text_cp, 0, uni_text, -1, text, size, NULL, NULL); + /* remove carriage returns */ lpstr = (char*)HeapAlloc( GetProcessHeap(), 0, size-- ); @@ -1113,7 +1124,8 @@ static Atom EVENT_SelectionRequest_STRING( Window requestor, Atom target, Atom r lpstr, j); TRACE("(Rc=%d)\n", xRc); - GlobalUnlock16(hText); + GlobalUnlock(hUnicodeText); + HeapFree(GetProcessHeap(), 0, text); HeapFree( GetProcessHeap(), 0, lpstr ); return rprop; -- 2.11.4.GIT