- We need to make sure we pay attention to if our call to
SetClipboardData from the X11DRV version of the function works. If not we need to delete the global block we allocated. This is a sever memory leak with large clipboard items. - If an X selection it too large then X may give it to us in chunks, we were not handling this well.
This commit is contained in:
parent
e2682cafd8
commit
278dd15eb2
@ -460,9 +460,10 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
|
|||||||
{
|
{
|
||||||
Atom atype=AnyPropertyType;
|
Atom atype=AnyPropertyType;
|
||||||
int aformat;
|
int aformat;
|
||||||
unsigned long nitems,remain,itemSize;
|
unsigned long total,nitems,remain,itemSize,val_cnt;
|
||||||
long lRequestLength;
|
long lRequestLength,bwc;
|
||||||
unsigned char* val=NULL;
|
unsigned char* val;
|
||||||
|
unsigned char* buffer;
|
||||||
LPWINE_CLIPFORMAT lpFormat;
|
LPWINE_CLIPFORMAT lpFormat;
|
||||||
BOOL bRet = FALSE;
|
BOOL bRet = FALSE;
|
||||||
HWND hWndClipWindow = GetOpenClipboardWindow();
|
HWND hWndClipWindow = GetOpenClipboardWindow();
|
||||||
@ -496,24 +497,38 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
|
|||||||
TRACE("\tretrieving %ld bytes...\n", itemSize * aformat/8);
|
TRACE("\tretrieving %ld bytes...\n", itemSize * aformat/8);
|
||||||
lRequestLength = (itemSize * aformat/8)/4 + 1;
|
lRequestLength = (itemSize * aformat/8)/4 + 1;
|
||||||
|
|
||||||
/*
|
bwc = aformat/8;
|
||||||
* Retrieve the actual property in the required X format.
|
/* we want to read the property, but not it too large of chunks or
|
||||||
*/
|
we could hang the cause problems. Lets go for 4k blocks */
|
||||||
if(TSXGetWindowProperty(display,w,prop,0,lRequestLength,False,AnyPropertyType/*reqType*/,
|
|
||||||
&atype, &aformat, &nitems, &remain, &val) != Success)
|
if(TSXGetWindowProperty(display,w,prop,0,4096,False,
|
||||||
|
AnyPropertyType/*reqType*/,
|
||||||
|
&atype, &aformat, &nitems, &remain, &buffer)
|
||||||
|
!= Success)
|
||||||
{
|
{
|
||||||
WARN("\tcouldn't read property\n");
|
WARN("\tcouldn't read property\n");
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
val = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
|
||||||
|
nitems*bwc);
|
||||||
|
memcpy(val,buffer,nitems*bwc);
|
||||||
|
TSXFree(buffer);
|
||||||
|
|
||||||
TRACE("\tType %s,Format %d,nitems %ld,remain %ld,value %s\n",
|
for (total = nitems*bwc,val_cnt=0; remain;)
|
||||||
atype ? TSXGetAtomName(display,atype) : NULL, aformat,nitems,remain,val);
|
|
||||||
|
|
||||||
if (remain)
|
|
||||||
{
|
{
|
||||||
WARN("\tCouldn't read entire property- selection may be too large! Remain=%ld\n", remain);
|
val_cnt +=nitems*bwc;
|
||||||
goto END;
|
TSXGetWindowProperty(display, w, prop,
|
||||||
|
(total / 4), 4096, False,
|
||||||
|
AnyPropertyType, &atype,
|
||||||
|
&aformat, &nitems, &remain,
|
||||||
|
&buffer);
|
||||||
|
|
||||||
|
total += nitems*bwc;
|
||||||
|
HeapReAlloc(GetProcessHeap(),0,val, total);
|
||||||
|
memcpy(&val[val_cnt], buffer, nitems*(aformat/8));
|
||||||
|
TSXFree(buffer);
|
||||||
}
|
}
|
||||||
|
nitems = total;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translate the X property into the appropriate Windows clipboard
|
* Translate the X property into the appropriate Windows clipboard
|
||||||
@ -526,8 +541,6 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
|
|||||||
int i,inlcount = 0;
|
int i,inlcount = 0;
|
||||||
char* lpstr;
|
char* lpstr;
|
||||||
|
|
||||||
TRACE("\tselection is '%s'\n",val);
|
|
||||||
|
|
||||||
for(i=0; i <= nitems; i++)
|
for(i=0; i <= nitems; i++)
|
||||||
if( val[i] == '\n' ) inlcount++;
|
if( val[i] == '\n' ) inlcount++;
|
||||||
|
|
||||||
@ -553,7 +566,11 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
|
|||||||
WCHAR *textW = GlobalLock(hUnicodeText);
|
WCHAR *textW = GlobalLock(hUnicodeText);
|
||||||
MultiByteToWideChar(text_cp, 0, lpstr, -1, textW, count);
|
MultiByteToWideChar(text_cp, 0, lpstr, -1, textW, count);
|
||||||
GlobalUnlock(hUnicodeText);
|
GlobalUnlock(hUnicodeText);
|
||||||
SetClipboardData(CF_UNICODETEXT, hUnicodeText);
|
if (!SetClipboardData(CF_UNICODETEXT, hUnicodeText))
|
||||||
|
{
|
||||||
|
ERR("Not SET! Need to free our own block\n");
|
||||||
|
GlobalFree(hUnicodeText);
|
||||||
|
}
|
||||||
bRet = TRUE;
|
bRet = TRUE;
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, lpstr);
|
HeapFree(GetProcessHeap(), 0, lpstr);
|
||||||
@ -654,9 +671,7 @@ END:
|
|||||||
TSXDeleteProperty(display,w,prop);
|
TSXDeleteProperty(display,w,prop);
|
||||||
|
|
||||||
/* Free the retrieved property data */
|
/* Free the retrieved property data */
|
||||||
if (val)
|
HeapFree(GetProcessHeap(),0,val);
|
||||||
TSXFree(val);
|
|
||||||
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user