summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2009-12-15 22:21:15 -0500
committerWilliam Jon McCann <jmccann@redhat.com>2009-12-15 22:21:15 -0500
commitaf477956ddd06e3821bbcc3e9337a637fe91584a (patch)
treed39ae43b82876f286123ce5b0eff4c5c471c76f9
parent5a080e8f12ed6da1b1d1df545d15870742b99c2b (diff)
downloadgnome-desktop-af477956ddd06e3821bbcc3e9337a637fe91584a.tar.gz
Fix refcounting issues leading to leaks
Removes a FIXME by expecting all get_ functions to return refs.
-rw-r--r--libgnome-desktop/gnome-bg.c139
1 files changed, 94 insertions, 45 deletions
diff --git a/libgnome-desktop/gnome-bg.c b/libgnome-desktop/gnome-bg.c
index a539e060..2f382d1d 100644
--- a/libgnome-desktop/gnome-bg.c
+++ b/libgnome-desktop/gnome-bg.c
@@ -188,6 +188,11 @@ static Slide * get_current_slide (SlideShow *show,
double *alpha);
static gboolean slideshow_has_multiple_sizes (SlideShow *show);
+static SlideShow *read_slideshow_file (const char *filename,
+ GError **err);
+static SlideShow *slideshow_ref (SlideShow *show);
+static void slideshow_unref (SlideShow *show);
+
static FileSize *find_best_size (GSList *sizes,
gint width,
gint height);
@@ -811,16 +816,21 @@ draw_once (GnomeBG *bg,
GdkScreen *screen)
{
GdkRectangle rect;
+ GdkPixbuf *pixbuf;
rect.x = 0;
rect.y = 0;
rect.width = gdk_pixbuf_get_width (dest);
rect.height = gdk_pixbuf_get_height (dest);
- draw_image_area (bg->placement,
- get_pixbuf_for_size (bg, gdk_pixbuf_get_width (dest), gdk_pixbuf_get_height (dest)),
- dest,
- &rect);
+ pixbuf = get_pixbuf_for_size (bg, gdk_pixbuf_get_width (dest), gdk_pixbuf_get_height (dest));
+ if (pixbuf) {
+ draw_image_area (bg->placement,
+ pixbuf,
+ dest,
+ &rect);
+ g_object_unref (pixbuf);
+ }
}
static void
@@ -834,10 +844,15 @@ draw_each_monitor (GnomeBG *bg,
num_monitors = gdk_screen_get_n_monitors (screen);
for (monitor = 0; monitor < num_monitors; monitor++) {
+ GdkPixbuf *pixbuf;
gdk_screen_get_monitor_geometry (screen, monitor, &rect);
- draw_image_area (bg->placement,
- get_pixbuf_for_size (bg, rect.width, rect.height),
- dest, &rect);
+ pixbuf = get_pixbuf_for_size (bg, rect.width, rect.height);
+ if (pixbuf) {
+ draw_image_area (bg->placement,
+ pixbuf,
+ dest, &rect);
+ g_object_unref (pixbuf);
+ }
}
}
@@ -863,14 +878,19 @@ gboolean
gnome_bg_has_multiple_sizes (GnomeBG *bg)
{
SlideShow *show;
+ gboolean ret;
g_return_val_if_fail (bg != NULL, FALSE);
+ ret = FALSE;
+
show = get_as_slideshow (bg, bg->filename);
- if (show)
- return slideshow_has_multiple_sizes (show);
+ if (show) {
+ ret = slideshow_has_multiple_sizes (show);
+ slideshow_unref (show);
+ }
- return FALSE;
+ return ret;
}
static void
@@ -1011,6 +1031,7 @@ gnome_bg_is_dark (GnomeBG *bg,
color.red = (color.red * (0xFF - a) + r * 0x101 * a) / 0xFF;
color.green = (color.green * (0xFF - a) + g * 0x101 * a) / 0xFF;
color.blue = (color.blue * (0xFF - a) + b * 0x101 * a) / 0xFF;
+ g_object_unref (pixbuf);
}
intensity = (color.red * 77 +
@@ -1104,6 +1125,7 @@ get_filename_for_size (GnomeBG *bg, gint best_width, gint best_height)
}
slide = get_current_slide (show, NULL);
+ slideshow_unref (show);
size = find_best_size (slide->file1, best_width, best_height);
return size->file;
}
@@ -1419,10 +1441,6 @@ struct _SlideShow
GQueue *stack;
};
-static SlideShow *read_slideshow_file (const char *filename,
- GError **err);
-static void slideshow_ref (SlideShow *show);
-static void slideshow_unref (SlideShow *show);
static double
now (void)
@@ -1538,9 +1556,9 @@ bound_cache (GnomeBG *bg)
while (g_list_length (bg->file_cache) >= CACHE_SIZE) {
GList *last_link = g_list_last (bg->file_cache);
FileCacheEntry *ent = last_link->data;
-
+
file_cache_entry_delete (ent);
-
+
bg->file_cache = g_list_delete_link (bg->file_cache, last_link);
}
}
@@ -1587,7 +1605,7 @@ file_cache_add_pixbuf (GnomeBG *bg,
GdkPixbuf *pixbuf)
{
FileCacheEntry *ent = file_cache_entry_new (bg, PIXBUF, filename);
- ent->u.pixbuf = pixbuf;
+ ent->u.pixbuf = g_object_ref (pixbuf);
}
static void
@@ -1596,7 +1614,7 @@ file_cache_add_thumbnail (GnomeBG *bg,
GdkPixbuf *pixbuf)
{
FileCacheEntry *ent = file_cache_entry_new (bg, THUMBNAIL, filename);
- ent->u.thumbnail = pixbuf;
+ ent->u.thumbnail = g_object_ref (pixbuf);
}
static void
@@ -1605,7 +1623,7 @@ file_cache_add_slide_show (GnomeBG *bg,
SlideShow *show)
{
FileCacheEntry *ent = file_cache_entry_new (bg, SLIDESHOW, filename);
- ent->u.slideshow = show;
+ ent->u.slideshow = slideshow_ref (show);
}
static GdkPixbuf *
@@ -1616,7 +1634,7 @@ get_as_pixbuf_for_size (GnomeBG *bg,
{
const FileCacheEntry *ent;
if ((ent = file_cache_lookup (bg, PIXBUF, filename))) {
- return ent->u.pixbuf;
+ return g_object_ref (ent->u.pixbuf);
}
else {
GdkPixbufFormat *format;
@@ -1646,7 +1664,7 @@ get_as_slideshow (GnomeBG *bg, const char *filename)
{
const FileCacheEntry *ent;
if ((ent = file_cache_lookup (bg, SLIDESHOW, filename))) {
- return ent->u.slideshow;
+ return slideshow_ref (ent->u.slideshow);
}
else {
SlideShow *show = read_slideshow_file (filename, NULL);
@@ -1663,7 +1681,7 @@ get_as_thumbnail (GnomeBG *bg, GnomeDesktopThumbnailFactory *factory, const char
{
const FileCacheEntry *ent;
if ((ent = file_cache_lookup (bg, THUMBNAIL, filename))) {
- return ent->u.thumbnail;
+ return g_object_ref (ent->u.thumbnail);
}
else {
GdkPixbuf *thumb = create_thumbnail_for_filename (factory, filename);
@@ -1860,21 +1878,28 @@ create_img_thumbnail (GnomeBG *bg,
int frame_num)
{
if (bg->filename) {
- GdkPixbuf *thumb = get_as_thumbnail (bg, factory, bg->filename);
+ GdkPixbuf *thumb;
+
+ thumb = get_as_thumbnail (bg, factory, bg->filename);
if (thumb) {
- return scale_thumbnail (bg->placement, bg->filename,
- thumb, screen, dest_width, dest_height);
+ GdkPixbuf *result;
+ result = scale_thumbnail (bg->placement,
+ bg->filename,
+ thumb,
+ screen,
+ dest_width,
+ dest_height);
+ g_object_unref (thumb);
+ return result;
}
else {
SlideShow *show = get_as_slideshow (bg, bg->filename);
-
+
if (show) {
double alpha;
Slide *slide;
- slideshow_ref (show);
-
if (frame_num == -1)
slide = get_current_slide (show, &alpha);
else
@@ -1885,9 +1910,15 @@ create_img_thumbnail (GnomeBG *bg,
FileSize *fs;
fs = find_best_size (slide->file1, dest_width, dest_height);
tmp = get_as_thumbnail (bg, factory, fs->file);
- if (tmp)
- thumb = scale_thumbnail (bg->placement, fs->file,
- tmp, screen, dest_width, dest_height);
+ if (tmp) {
+ thumb = scale_thumbnail (bg->placement,
+ fs->file,
+ tmp,
+ screen,
+ dest_width,
+ dest_height);
+ g_object_unref (tmp);
+ }
}
else {
FileSize *fs1, *fs2;
@@ -1901,17 +1932,29 @@ create_img_thumbnail (GnomeBG *bg,
if (p1 && p2) {
GdkPixbuf *thumb1, *thumb2;
- thumb1 = scale_thumbnail (bg->placement, fs1->file,
- p1, screen, dest_width, dest_height);
+ thumb1 = scale_thumbnail (bg->placement,
+ fs1->file,
+ p1,
+ screen,
+ dest_width,
+ dest_height);
- thumb2 = scale_thumbnail (bg->placement, fs2->file,
- p2, screen, dest_width, dest_height);
+ thumb2 = scale_thumbnail (bg->placement,
+ fs2->file,
+ p2,
+ screen,
+ dest_width,
+ dest_height);
thumb = blend (thumb1, thumb2, alpha);
g_object_unref (thumb1);
g_object_unref (thumb2);
}
+ if (p1)
+ g_object_unref (p1);
+ if (p2)
+ g_object_unref (p2);
}
ensure_timeout (bg, slide);
@@ -1972,11 +2015,11 @@ find_best_size (GSList *sizes, gint width, gint height)
}
static GdkPixbuf *
-get_pixbuf_for_size (GnomeBG *bg, gint best_width, gint best_height)
+get_pixbuf_for_size (GnomeBG *bg,
+ gint best_width,
+ gint best_height)
{
- /* FIXME: this ref=TRUE/FALSE stuff is crazy */
guint time_until_next_change;
- gboolean ref = FALSE;
gboolean hit_cache = FALSE;
/* only hit the cache if the aspect ratio matches */
@@ -1985,12 +2028,15 @@ get_pixbuf_for_size (GnomeBG *bg, gint best_width, gint best_height)
width = gdk_pixbuf_get_width (bg->pixbuf_cache);
height = gdk_pixbuf_get_height (bg->pixbuf_cache);
hit_cache = 0.2 > fabs ((best_width / (double)best_height) - (width / (double)height));
+ if (!hit_cache) {
+ g_object_unref (bg->pixbuf_cache);
+ bg->pixbuf_cache = NULL;
+ }
}
if (!hit_cache && bg->filename) {
- ref = TRUE;
bg->file_mtime = get_mtime (bg->filename);
-
+
bg->pixbuf_cache = get_as_pixbuf_for_size (bg, bg->filename, best_width, best_height);
time_until_next_change = G_MAXUINT;
if (!bg->pixbuf_cache) {
@@ -2017,11 +2063,13 @@ get_pixbuf_for_size (GnomeBG *bg, gint best_width, gint best_height)
size = find_best_size (slide->file2, best_width, best_height);
p2 = get_as_pixbuf_for_size (bg, size->file, best_width, best_height);
-
if (p1 && p2) {
bg->pixbuf_cache = blend (p1, p2, alpha);
- ref = FALSE;
}
+ if (p1)
+ g_object_unref (p1);
+ if (p2)
+ g_object_unref (p2);
}
ensure_timeout (bg, slide);
@@ -2037,9 +2085,9 @@ get_pixbuf_for_size (GnomeBG *bg, gint best_width, gint best_height)
blow_expensive_caches_in_idle (bg);
}
- if (bg->pixbuf_cache && ref)
+ if (bg->pixbuf_cache)
g_object_ref (bg->pixbuf_cache);
-
+
return bg->pixbuf_cache;
}
@@ -2529,10 +2577,11 @@ handle_text (GMarkupParseContext *context,
}
}
-static void
+static SlideShow *
slideshow_ref (SlideShow *show)
{
show->ref_count++;
+ return show;
}
static void