Add CF_UNICODETEXT as primary text clipboard format.

Use [x11drv].TextCP for interchange with X.
This commit is contained in:
Dmitry Timoshkov 2000-12-11 01:09:56 +00:00 committed by Alexandre Julliard
parent 93dd2d694f
commit 1df0d36592
6 changed files with 271 additions and 131 deletions

View File

@ -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;

View File

@ -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 )
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 )
/* 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);
}
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 )
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 )
/* 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);
}
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;

View File

@ -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"

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
text = GlobalLock16(hText);
uni_text = GlobalLock(hUnicodeText);
if(!uni_text)
return None;
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;