XQuartz: pbproxy: Add a comment to pbproxy.h about how the DB()

macro causes a leak (according to the leaks program).

Attempt to fix several other leaks with release method calls.
For some reason the process still grows more than it should...

I will need to use some better methods than leaks, and malloc_history
I suspect.  Whatever is leaking, it's hard to find.  I need to isolate
the cases more.

Add a missing image/jpeg branch.

Remove read_prop_32 - it's not used.
(cherry picked from commit 63a680354dcb545fef935ac97596dd35ceaed960)
This commit is contained in:
George Peter Staplin 2008-09-22 17:36:21 -06:00 committed by Jeremy Huddleston
parent 106eb37e02
commit 238999cfc9
2 changed files with 129 additions and 94 deletions

View File

@ -12,7 +12,7 @@
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#undef Cursor #undef Cursor
#define DEBUG 1 #define DEBUG 0
/* from main.m */ /* from main.m */
extern void x_set_is_active (BOOL state); extern void x_set_is_active (BOOL state);
@ -30,6 +30,7 @@ extern void x_input_run (void);
#if DEBUG == 0 #if DEBUG == 0
# define DB(msg, args...) do {} while (0) # define DB(msg, args...) do {} while (0)
#else #else
/* BEWARE: this can cause a string memory leak, according to the leaks program. */
# define DB(msg, args...) debug_printf("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args) # define DB(msg, args...) debug_printf("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args)
#endif #endif

View File

@ -1,7 +1,7 @@
/* x-selection.m -- proxies between NSPasteboard and X11 selections /* x-selection.m -- proxies between NSPasteboard and X11 selections
$Id: x-selection.m,v 1.9 2006-07-07 18:24:28 jharper Exp $ $Id: x-selection.m,v 1.9 2006-07-07 18:24:28 jharper Exp $
Copyright (c) 2002 Apple Computer, Inc. All rights reserved. Copyright (c) 2002, 2008 Apple Computer, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files obtaining a copy of this software and associated documentation files
@ -114,11 +114,16 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
unsigned long newbuflen; unsigned long newbuflen;
unsigned char *newbuf; unsigned char *newbuf;
#ifdef TEST
printf("bytesleft %lu\n", bytesleft);
#endif
if (Success != XGetWindowProperty (x_dpy, win, property, if (Success != XGetWindowProperty (x_dpy, win, property,
offset, length, delete, offset, length, delete,
AnyPropertyType, AnyPropertyType,
type, &format, &numitems, type, &format, &numitems,
&bytesleft, &chunk)) { &bytesleft, &chunk)) {
DB ("Error while getting window property.\n");
free (buf); free (buf);
return True; return True;
} }
@ -127,7 +132,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
printf("format %d numitems %lu bytesleft %lu\n", printf("format %d numitems %lu bytesleft %lu\n",
format, numitems, bytesleft); format, numitems, bytesleft);
printf("type %s\n", XGetAtomName(dis, *type)); printf("type %s\n", XGetAtomName (x_dpy, *type));
#endif #endif
/* Format is the number of bits. */ /* Format is the number of bits. */
@ -151,6 +156,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
buflen = newbuflen; buflen = newbuflen;
/* offset is a multiple of 32 bits*/ /* offset is a multiple of 32 bits*/
offset += chunkbytesize / 4; offset += chunkbytesize / 4;
#ifdef TEST
printf("bytesleft %lu\n", bytesleft);
#endif
} while (bytesleft > 0); } while (bytesleft > 0);
pdata->data = buf; pdata->data = buf;
@ -160,40 +169,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
} }
static unsigned long *
read_prop_32 (Window id, Atom prop, int *nitems_ret)
{
int r, format;
Atom type;
unsigned long nitems, bytes_after;
unsigned char *data;
r = XGetWindowProperty (x_dpy, id, prop, 0, 0,
False, AnyPropertyType, &type, &format,
&nitems, &bytes_after, &data);
if (r == Success && bytes_after != 0)
{
XFree (data);
r = XGetWindowProperty (x_dpy, id, prop, 0,
(bytes_after / 4) + 1, False,
AnyPropertyType, &type, &format,
&nitems, &bytes_after, &data);
}
if (r != Success)
return NULL;
if (format != 32)
{
XFree (data);
return NULL;
}
*nitems_ret = nitems;
return (unsigned long *) data;
}
/* Implementation methods */ /* Implementation methods */
/* This finds the preferred type from a TARGETS list.*/ /* This finds the preferred type from a TARGETS list.*/
@ -201,7 +176,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
{ {
Atom a = None; Atom a = None;
size_t i; size_t i;
Bool png = False, utf8 = False, string = False; Bool png = False, jpeg = False, utf8 = False, string = False;
TRACE (); TRACE ();
@ -219,6 +194,10 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
{ {
png = True; png = True;
} }
else if (a == atoms->image_jpeg)
{
jpeg = True;
}
else if (a == atoms->utf8_string) else if (a == atoms->utf8_string)
{ {
utf8 = True; utf8 = True;
@ -233,6 +212,9 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
if (png) if (png)
return atoms->image_png; return atoms->image_png;
if (jpeg)
return atoms->image_jpeg;
if (utf8) if (utf8)
return atoms->utf8_string; return atoms->utf8_string;
@ -309,7 +291,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
memcpy(newdata + pending.propdata.length, pdata->data, pdata->length); memcpy(newdata + pending.propdata.length, pdata->data, pdata->length);
pending.propdata.data = newdata; pending.propdata.data = newdata;
pending.propdata.length = newlength; pending.propdata.length = newlength;
return False; return False;
} }
@ -583,51 +565,63 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
{ {
XEvent reply; XEvent reply;
NSArray *pbtypes; NSArray *pbtypes;
NSString *data;
const char *bytes;
NSUInteger length;
TRACE (); TRACE ();
[self init_reply:&reply request:e]; [self init_reply:&reply request:e];
pbtypes = [_pasteboard types]; pbtypes = [_pasteboard types];
if ([pbtypes containsObject: NSStringPboardType]) if (![pbtypes containsObject:NSStringPboardType])
{ {
NSString *data = [_pasteboard stringForType:NSStringPboardType]; [self send_reply:&reply];
if (nil != data) return;
{
const char *bytes;
NSUInteger length;
if (utf8)
{
bytes = [data UTF8String];
/*
* We don't want the UTF-8 string length here.
* We want the length in bytes.
*/
length = strlen (bytes);
if (length < 50) {
DB ("UTF-8: %s\n", bytes);
DB ("UTF-8 length: %u\n", length);
}
}
else
{
DB ("Latin-1\n");
bytes = [data cStringUsingEncoding:NSISOLatin1StringEncoding];
length = strlen (bytes);
}
DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
XChangeProperty (x_dpy, e->requestor, e->property, e->target,
8, PropModeReplace, (unsigned char *) bytes, length);
reply.xselection.property = e->property;
}
} }
DB ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]);
data = [_pasteboard stringForType:NSStringPboardType];
if (nil == data)
{
[self send_reply:&reply];
return;
}
if (utf8)
{
bytes = [data UTF8String];
/*
* We don't want the UTF-8 string length here.
* We want the length in bytes.
*/
length = strlen (bytes);
if (length < 50) {
DB ("UTF-8: %s\n", bytes);
DB ("UTF-8 length: %u\n", length);
}
}
else
{
DB ("Latin-1\n");
bytes = [data cStringUsingEncoding:NSISOLatin1StringEncoding];
length = strlen (bytes);
}
DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
XChangeProperty (x_dpy, e->requestor, e->property, e->target,
8, PropModeReplace, (unsigned char *) bytes, length);
reply.xselection.property = e->property;
DB ("data retainCount before release %u\n", [data retainCount]);
[data release];
[self send_reply:&reply]; [self send_reply:&reply];
} }
@ -676,6 +670,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
if (textprop.value) if (textprop.value)
XFree (textprop.value); XFree (textprop.value);
[data release];
} }
} }
@ -730,8 +726,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
imagetype = NSPNGFileType; imagetype = NSPNGFileType;
else if (e->target == atoms->image_jpeg) else if (e->target == atoms->image_jpeg)
imagetype = NSJPEGFileType; imagetype = NSJPEGFileType;
if (nil == type) if (nil == type)
{ {
[self send_reply:&reply]; [self send_reply:&reply];
@ -748,18 +744,21 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
if (NSTIFFPboardType == type) if (NSTIFFPboardType == type)
{ {
NSBitmapImageRep *bmimage = [[NSBitmapImageRep alloc] initWithData:data]; NSBitmapImageRep *bmimage = [[NSBitmapImageRep alloc] initWithData:data];
NSDictionary *dict; NSDictionary *dict;
NSData *encdata; NSData *encdata;
if (nil == bmimage) if (nil == bmimage)
{ {
[data release];
[self send_reply:&reply]; [self send_reply:&reply];
return; return;
} }
/*FIXME Why is [bmimage retainCount] 2 here? */
DB ("bmimage retainCount after initWithData %u\n", [bmimage retainCount]);
DB ("have valid bmimage\n");
dict = [[NSDictionary alloc] init]; dict = [[NSDictionary alloc] init];
encdata = [bmimage representationUsingType:imagetype properties:dict]; encdata = [bmimage representationUsingType:imagetype properties:dict];
if (encdata) if (encdata)
@ -769,18 +768,27 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
length = [encdata length]; length = [encdata length];
bytes = [encdata bytes]; bytes = [encdata bytes];
XChangeProperty (x_dpy, e->requestor, e->property, e->target,
8, PropModeReplace, bytes, length);
XChangeProperty (x_dpy, e->requestor, e->property, e->target,
8, PropModeReplace, bytes, length);
reply.xselection.property = e->property; reply.xselection.property = e->property;
DB ("changed property for %s\n", XGetAtomName (x_dpy, e->target)); DB ("changed property for %s\n", XGetAtomName (x_dpy, e->target));
DB ("encdata retainCount %u\n", [encdata retainCount]);
[encdata release];
[bmimage release];
} }
DB ("dict retainCount before release %u\n", [dict retainCount]);
[dict release]; [dict release];
[bmimage release];
}
DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
/*FIXME Why on earth is retainCount 3? */
[bmimage release];
[bmimage release];
}
[data release];
[self send_reply:&reply]; [self send_reply:&reply];
} }
@ -812,8 +820,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
/*TODO we need a COMPOUND_TEXT test app*/ /*TODO we need a COMPOUND_TEXT test app*/
/*TODO we need a MULTIPLE test app*/ /*TODO we need a MULTIPLE test app*/
if (None != e->target)
DB ("e->target %s\n", XGetAtomName (x_dpy, e->target)); DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
if (e->target == atoms->targets) if (e->target == atoms->targets)
{ {
@ -890,7 +898,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
free_propdata (&pdata); free_propdata (&pdata);
pending.requestor = e->requestor; pending.requestor = e->requestor;
pending.selection = e->selection; pending.selection = e->selection;
DB ("set pending.requestor to 0x%lx\n", pending.requestor); DB ("set pending.requestor to 0x%lx\n", pending.requestor);
@ -993,14 +1001,21 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
return; return;
} }
DB ("data retainCount before NSBitmapImageRep initWithData: %u\n",
[data retainCount]);
bmimage = [[NSBitmapImageRep alloc] initWithData:data]; bmimage = [[NSBitmapImageRep alloc] initWithData:data];
if (nil == bmimage) if (nil == bmimage)
{ {
[data release];
DB ("unable to create NSBitmapImageRep!\n"); DB ("unable to create NSBitmapImageRep!\n");
return; return;
} }
DB ("data retainCount after NSBitmapImageRep initWithData: %u\n",
[data retainCount]);
@try @try
{ {
tiff = [bmimage TIFFRepresentation]; tiff = [bmimage TIFFRepresentation];
@ -1011,9 +1026,13 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
DB ("NSTIFFException!\n"); DB ("NSTIFFException!\n");
[data release]; [data release];
[bmimage release]; [bmimage release];
/*WHY 2?*/
[bmimage release];
return; return;
} }
DB ("bmimage retainCount after TIFFRepresentation %u\n", [bmimage retainCount]);
pbtypes = [NSArray arrayWithObjects:NSTIFFPboardType, nil]; pbtypes = [NSArray arrayWithObjects:NSTIFFPboardType, nil];
if (nil == pbtypes) if (nil == pbtypes)
@ -1021,17 +1040,28 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
[tiff release]; [tiff release];
[data release]; [data release];
[bmimage release]; [bmimage release];
/* WHY is the object with a retainCount of 2 after initWithData? */
[bmimage release];
return;
} }
[_pasteboard declareTypes:pbtypes owner:self]; [_pasteboard declareTypes:pbtypes owner:self];
if (YES != [_pasteboard setData:data forType:NSTIFFPboardType]) if (YES != [_pasteboard setData:tiff forType:NSTIFFPboardType])
{ {
DB ("writing pasteboard data failed!\n"); DB ("writing pasteboard data failed!\n");
} }
[pbtypes release]; [pbtypes release];
[data release]; [data release];
DB ("tiff retainCount before release %u\n", [tiff retainCount]);
[tiff release]; [tiff release];
DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
/*WHY 3?*/
[bmimage release];
[bmimage release];
[bmimage release]; [bmimage release];
} }
@ -1048,6 +1078,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
if (nil == string) if (nil == string)
return; return;
DB ("string retainCount is %u\n", [string retainCount]);
pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil]; pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
if (nil != pbtypes) if (nil != pbtypes)
@ -1083,9 +1115,10 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
{ {
[_pasteboard declareTypes:pbtypes owner:self]; [_pasteboard declareTypes:pbtypes owner:self];
[_pasteboard setString:string forType:NSStringPboardType]; [_pasteboard setString:string forType:NSStringPboardType];
DB ("pbtypes retainCount %u\n", [pbtypes retainCount]);
[pbtypes release]; [pbtypes release];
} }
[string release]; [string release];
} }
@ -1212,7 +1245,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
_pasteboard = [[NSPasteboard generalPasteboard] retain]; _pasteboard = [[NSPasteboard generalPasteboard] retain];
_known_types = [[NSArray arrayWithObject:NSStringPboardType] retain]; //_known_types = [[NSArray arrayWithObject:NSStringPboardType] retain];
_known_types = nil;
pixel = BlackPixel (x_dpy, DefaultScreen (x_dpy)); pixel = BlackPixel (x_dpy, DefaultScreen (x_dpy));
_selection_window = XCreateSimpleWindow (x_dpy, DefaultRootWindow (x_dpy), _selection_window = XCreateSimpleWindow (x_dpy, DefaultRootWindow (x_dpy),
@ -1240,7 +1274,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
[_pasteboard release]; [_pasteboard release];
_pasteboard = nil; _pasteboard = nil;
[_known_types release]; //[_known_types release];
_known_types = nil; _known_types = nil;
if (None != _selection_window) if (None != _selection_window)