clipboard
Aric Stewart
aric at codeweavers.com
Wed Feb 21 18:55:30 CST 2001
This patch address three clipboard issues.
1st, We where not giving enough room for the null termination of the
text string when converting from one format to another (I do not know if
this was posted in a previous patch of mine or not, i have been busy
recently and not paying alot of attention to what I have already posted)
2nd, 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.
3nd, If an x selection it too large then x may give it to us in chunks.
we where not handling this well. Additionally in my reading i found that
sometimes X does not like being queried for large blocks all at once. So
i instead ask for smaller chunks in a loop to retreave the a selection.
There is one part of 3 that is still unaddressed, that is the INCR type.
Some X programs will give an INCR type to us if the selection is large.
We currently just bail in this case. We should handle the INCR and
actaully get the data.
-aric
-------------- next part --------------
Index: windows/clipboard.c
===================================================================
RCS file: /home/wine/wine/windows/clipboard.c,v
retrieving revision 1.36
diff -u -u -r1.36 clipboard.c
--- windows/clipboard.c 2001/02/20 01:54:08 1.36
+++ windows/clipboard.c 2001/02/22 00:43:32
@@ -617,6 +617,9 @@
else
src_chars = strlen(lpstrS)+1;
+ /* Make room for NULL termination */
+ src_chars++;
+
/* Calculate number of characters in the destination buffer */
dst_chars = CLIPBOARD_ConvertText(lpSource->wFormatID, lpstrS, src_chars,
lpTarget->wFormatID, NULL, 0);
Index: windows/x11drv/clipboard.c
===================================================================
RCS file: /home/wine/wine/windows/x11drv/clipboard.c,v
retrieving revision 1.28
diff -u -u -r1.28 clipboard.c
--- windows/x11drv/clipboard.c 2001/02/12 03:49:07 1.28
+++ windows/x11drv/clipboard.c 2001/02/22 00:43:33
@@ -460,9 +460,10 @@
{
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 @@
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 @@
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 @@
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 @@
TSXDeleteProperty(display,w,prop);
/* Free the retrieved property data */
- if (val)
- TSXFree(val);
-
+ HeapFree(GetProcessHeap(),0,val);
return bRet;
}
More information about the wine-patches
mailing list