From d34d7a02e6510cb0fdcab4ba58b2aceac4f0e65b Mon Sep 17 00:00:00 2001 From: Jens Granseuer Date: Tue, 11 Mar 2008 17:43:43 +0000 Subject: [PATCH] Encountering a theme that could not be thumbnailed (e.g. because the 2008-03-11 Jens Granseuer Encountering a theme that could not be thumbnailed (e.g. because the metacity theme for a metatheme isn't installed) would make the thumbnailer crash. Since it's not restarted by the appearance capplet this would result in all themes encountered after the broken one not to be thumbnailed either. This change fixes up error handling in the thumbnailer so that the broken theme is simply skipped and processing can continue with the next one. (bug #521009) * theme-thumbnail.c: (create_meta_theme_pixbuf), (create_metacity_theme_pixbuf), (message_from_capplet), (message_from_child), (read_pixbuf), (generate_theme_thumbnail_async), (theme_thumbnail_factory_init): properly handle failed thumbnailing attempts svn path=/trunk/; revision=8576 --- capplets/common/ChangeLog | 16 ++++++ capplets/common/theme-thumbnail.c | 83 +++++++++++++++++++------------ 2 files changed, 67 insertions(+), 32 deletions(-) diff --git a/capplets/common/ChangeLog b/capplets/common/ChangeLog index ac618abd2..01113ec65 100644 --- a/capplets/common/ChangeLog +++ b/capplets/common/ChangeLog @@ -1,3 +1,19 @@ +2008-03-11 Jens Granseuer + + Encountering a theme that could not be thumbnailed (e.g. because the + metacity theme for a metatheme isn't installed) would make the + thumbnailer crash. Since it's not restarted by the appearance capplet + this would result in all themes encountered after the broken one not + to be thumbnailed either. This change fixes up error handling in the + thumbnailer so that the broken theme is simply skipped and processing + can continue with the next one. (bug #521009) + + * theme-thumbnail.c: (create_meta_theme_pixbuf), + (create_metacity_theme_pixbuf), (message_from_capplet), + (message_from_child), (read_pixbuf), + (generate_theme_thumbnail_async), (theme_thumbnail_factory_init): + properly handle failed thumbnailing attempts + 2008-03-11 Jens Granseuer * gconf-property-editor.c: (peditor_numeric_range_widget_changed): don't diff --git a/capplets/common/theme-thumbnail.c b/capplets/common/theme-thumbnail.c index 008d4bf4a..a7e09e4b3 100644 --- a/capplets/common/theme-thumbnail.c +++ b/capplets/common/theme-thumbnail.c @@ -268,7 +268,10 @@ create_meta_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data) "gtk-icon-theme-name", (char *) theme_thumbnail_data->icon_theme_name->data, "gtk-color-scheme", (char *) theme_thumbnail_data->gtk_color_scheme->data, NULL); + theme = meta_theme_load ((char *) theme_thumbnail_data->wm_theme_name->data, NULL); + if (theme == NULL) + return NULL; /* Represent the icon theme */ icon = create_folder_icon ((char *) theme_thumbnail_data->icon_theme_name->data); @@ -473,6 +476,8 @@ create_metacity_theme_pixbuf (ThemeThumbnailData *theme_thumbnail_data) GdkRegion *region; theme = meta_theme_load ((char *) theme_thumbnail_data->wm_theme_name->data, NULL); + if (theme == NULL) + return NULL; flags = META_FRAME_ALLOWS_DELETE | META_FRAME_ALLOWS_MENU | @@ -712,10 +717,14 @@ message_from_capplet (GIOChannel *source, else g_assert_not_reached (); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - pixels = gdk_pixbuf_get_pixels (pixbuf); + if (pixbuf == NULL) { + width = height = 0; + } else { + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + } /* Write the pixbuf's size */ write (pipe_from_factory_fd[1], &width, sizeof (width)); @@ -723,16 +732,18 @@ message_from_capplet (GIOChannel *source, for (i = 0; i < height; i++) { - write (pipe_from_factory_fd[1], pixels + (rowstride)*i, width * gdk_pixbuf_get_n_channels (pixbuf)); + write (pipe_from_factory_fd[1], pixels + rowstride * i, width * gdk_pixbuf_get_n_channels (pixbuf)); } - g_object_unref (pixbuf); - theme_thumbnail_data->status = READY_FOR_THEME; + + if (pixbuf) + g_object_unref (pixbuf); g_byte_array_set_size (theme_thumbnail_data->type, 0); g_byte_array_set_size (theme_thumbnail_data->control_theme_name, 0); g_byte_array_set_size (theme_thumbnail_data->gtk_color_scheme, 0); g_byte_array_set_size (theme_thumbnail_data->wm_theme_name, 0); g_byte_array_set_size (theme_thumbnail_data->icon_theme_name, 0); g_byte_array_set_size (theme_thumbnail_data->application_font, 0); + theme_thumbnail_data->status = READY_FOR_THEME; } return TRUE; @@ -798,9 +809,7 @@ message_from_child (GIOChannel *source, return TRUE; if (condition == G_IO_HUP) - { return FALSE; - } status = g_io_channel_read_chars (source, buffer, @@ -812,24 +821,28 @@ message_from_child (GIOChannel *source, case G_IO_STATUS_NORMAL: g_byte_array_append (async_data.data, (guchar *) buffer, bytes_read); - if (async_data.thumbnail_width == 0 && async_data.data->len >= 2 * sizeof (gint)) + if (async_data.thumbnail_width == -1 && async_data.data->len >= 2 * sizeof (gint)) { async_data.thumbnail_width = *((gint *) async_data.data->data); async_data.thumbnail_height = *(((gint *) async_data.data->data) + 1); g_byte_array_remove_range (async_data.data, 0, 2 * sizeof (gint)); } - else if (async_data.thumbnail_width > 0 && async_data.data->len == async_data.thumbnail_width * async_data.thumbnail_height * 4) + + if (async_data.thumbnail_width >= 0 && async_data.data->len == async_data.thumbnail_width * async_data.thumbnail_height * 4) { - GdkPixbuf *pixbuf; - gchar *pixels; - gint i, rowstride; + GdkPixbuf *pixbuf = NULL; - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, async_data.thumbnail_width, async_data.thumbnail_height); - pixels = (gchar *) gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); + if (async_data.thumbnail_width > 0) { + gchar *pixels; + gint i, rowstride; - for (i = 0; i < async_data.thumbnail_height; i++) - memcpy (pixels + rowstride * i, async_data.data->data + 4 * async_data.thumbnail_width * i, async_data.thumbnail_width * 4); + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, async_data.thumbnail_width, async_data.thumbnail_height); + pixels = (gchar *) gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + + for (i = 0; i < async_data.thumbnail_height; ++i) + memcpy (pixels + rowstride * i, async_data.data->data + 4 * async_data.thumbnail_width * i, async_data.thumbnail_width * 4); + } /* callback function needs to unref the pixbuf */ (* async_data.func) (pixbuf, async_data.theme_name, async_data.user_data); @@ -843,8 +856,8 @@ message_from_child (GIOChannel *source, g_io_channel_unref (async_data.channel); /* reset async_data */ - async_data.thumbnail_width = 0; - async_data.thumbnail_height = 0; + async_data.thumbnail_width = -1; + async_data.thumbnail_height = -1; async_data.theme_name = NULL; async_data.channel = NULL; async_data.func = NULL; @@ -920,10 +933,15 @@ read_pixbuf (void) do { bytes_read = read (pipe_from_factory_fd[0], ((guint8*) size) + j, 2 * sizeof (gint)); + if (bytes_read == 0) + goto eof; j += bytes_read; } while (j < 2 * sizeof (gint)); + if (size[0] <= 0 || size[1] <= 0) + return NULL; + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size[0], size[1]); rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixels = gdk_pixbuf_get_pixels (pixbuf); @@ -934,25 +952,28 @@ read_pixbuf (void) do { - bytes_read = read (pipe_from_factory_fd[0], pixels + (rowstride)*i + j, size[0] * gdk_pixbuf_get_n_channels (pixbuf) - j); + bytes_read = read (pipe_from_factory_fd[0], pixels + rowstride * i + j, size[0] * gdk_pixbuf_get_n_channels (pixbuf) - j); if (bytes_read > 0) j += bytes_read; else if (bytes_read == 0) { - g_warning ("Received EOF while reading thumbnail"); g_object_unref (pixbuf); - close (pipe_to_factory_fd[1]); - pipe_to_factory_fd[1] = 0; - close (pipe_from_factory_fd[0]); - pipe_from_factory_fd[0] = 0; - return NULL; + goto eof; } } while (j < size[0] * gdk_pixbuf_get_n_channels (pixbuf)); } return pixbuf; + +eof: + g_warning ("Received EOF while reading thumbnail"); + close (pipe_to_factory_fd[1]); + pipe_to_factory_fd[1] = 0; + close (pipe_from_factory_fd[0]); + pipe_from_factory_fd[0] = 0; + return NULL; } static GdkPixbuf * @@ -1072,8 +1093,8 @@ generate_theme_thumbnail_async (gpointer theme_info, } async_data.set = TRUE; - async_data.thumbnail_width = 0; - async_data.thumbnail_height = 0; + async_data.thumbnail_width = -1; + async_data.thumbnail_height = -1; async_data.theme_name = g_strdup (theme_name); async_data.func = func; async_data.user_data = user_data; @@ -1205,8 +1226,6 @@ theme_thumbnail_factory_init (int argc, char *argv[]) close (pipe_to_factory_fd[0]); close (pipe_from_factory_fd[1]); async_data.set = FALSE; - async_data.thumbnail_width = 0; - async_data.thumbnail_height = 0; async_data.theme_name = NULL; async_data.data = g_byte_array_new (); }