Add CF_UNICODETEXT as primary text clipboard format.
Use [x11drv].TextCP for interchange with X.
This commit is contained in:
parent
93dd2d694f
commit
1df0d36592
|
@ -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;
|
||||
|
|
|
@ -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,8 +492,19 @@ 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 )
|
||||
{
|
||||
if(ClipFormats[CF_UNICODETEXT-1].wDataPresent)
|
||||
{
|
||||
/* Convert UNICODETEXT -> TEXT */
|
||||
lpSource = &ClipFormats[CF_UNICODETEXT-1];
|
||||
lpTarget = &ClipFormats[CF_TEXT-1];
|
||||
|
||||
TRACE("\tUNICODETEXT -> TEXT\n");
|
||||
}
|
||||
else if(ClipFormats[CF_OEMTEXT-1].wDataPresent)
|
||||
{
|
||||
/* Convert OEMTEXT -> TEXT */
|
||||
lpSource = &ClipFormats[CF_OEMTEXT-1];
|
||||
|
@ -447,9 +512,22 @@ static LPWINE_CLIPFORMAT CLIPBOARD_RenderText( UINT wFormat )
|
|||
|
||||
TRACE("\tOEMTEXT -> TEXT\n");
|
||||
}
|
||||
/* Asked for CF_OEM_TEXT, and CF_TEXT available */
|
||||
else if( wFormat == CF_OEMTEXT && !ClipFormats[CF_OEMTEXT-1].wDataPresent
|
||||
&& ClipFormats[CF_TEXT-1].wDataPresent )
|
||||
else
|
||||
lpSource = NULL; /* Conversion format is not available */
|
||||
}
|
||||
/* 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 )
|
||||
{
|
||||
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];
|
||||
|
@ -457,6 +535,32 @@ static LPWINE_CLIPFORMAT CLIPBOARD_RenderText( UINT wFormat )
|
|||
|
||||
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;
|
||||
TRACE("\tconverting from '%s' to '%s', %i chars\n",
|
||||
lpSource->Name, lpTarget->Name, size);
|
||||
|
||||
lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DDESHARE, size);
|
||||
/* 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, 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)
|
||||
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);
|
||||
bRet = EnumClipboardFormats(wFormat - 1) == wFormat;
|
||||
|
||||
TRACE("(%04X)- ret(%d)\n", wFormat, bRet);
|
||||
return bRet;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,38 +531,33 @@ 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)) )
|
||||
if( (lpstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nitems + inlcount + 1)) )
|
||||
{
|
||||
ZeroMemory(lpstr, 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 )
|
||||
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)
|
||||
{
|
||||
/* 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;
|
||||
|
||||
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 */
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -1055,6 +1054,8 @@ BOOL X11DRV_GetClipboardData(UINT wFormat)
|
|||
TRACE("\tpresent %s = %i\n", CLIPBOARD_GetFormatName(wFormat), bRet );
|
||||
}
|
||||
|
||||
TRACE("Returning %d\n", bRet);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue