- 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:
Aric Stewart 2001-02-23 01:31:47 +00:00 committed by Alexandre Julliard
parent e2682cafd8
commit 278dd15eb2
1 changed files with 39 additions and 24 deletions

View File

@ -460,9 +460,10 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
{
Atom atype=AnyPropertyType;
int aformat;
unsigned long nitems,remain,itemSize;
long lRequestLength;
unsigned char* val=NULL;
unsigned long total,nitems,remain,itemSize,val_cnt;
long lRequestLength,bwc;
unsigned char* val;
unsigned char* buffer;
LPWINE_CLIPFORMAT lpFormat;
BOOL bRet = FALSE;
HWND hWndClipWindow = GetOpenClipboardWindow();
@ -495,26 +496,40 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
TRACE("\tretrieving %ld bytes...\n", itemSize * aformat/8);
lRequestLength = (itemSize * aformat/8)/4 + 1;
/*
* Retrieve the actual property in the required X format.
*/
if(TSXGetWindowProperty(display,w,prop,0,lRequestLength,False,AnyPropertyType/*reqType*/,
&atype, &aformat, &nitems, &remain, &val) != Success)
bwc = aformat/8;
/* 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,4096,False,
AnyPropertyType/*reqType*/,
&atype, &aformat, &nitems, &remain, &buffer)
!= Success)
{
WARN("\tcouldn't read property\n");
return bRet;
}
val = (char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
nitems*bwc);
memcpy(val,buffer,nitems*bwc);
TSXFree(buffer);
for (total = nitems*bwc,val_cnt=0; remain;)
{
val_cnt +=nitems*bwc;
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;
TRACE("\tType %s,Format %d,nitems %ld,remain %ld,value %s\n",
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);
goto END;
}
/*
* Translate the X property into the appropriate Windows clipboard
* format, if possible.
@ -526,8 +541,6 @@ static BOOL X11DRV_CLIPBOARD_ReadSelection(UINT wFormat, Window w, Atom prop, At
int i,inlcount = 0;
char* lpstr;
TRACE("\tselection is '%s'\n",val);
for(i=0; i <= nitems; i++)
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);
MultiByteToWideChar(text_cp, 0, lpstr, -1, textW, count);
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;
}
HeapFree(GetProcessHeap(), 0, lpstr);
@ -654,9 +671,7 @@ END:
TSXDeleteProperty(display,w,prop);
/* Free the retrieved property data */
if (val)
TSXFree(val);
HeapFree(GetProcessHeap(),0,val);
return bRet;
}