[gnome-flashback] libstatus-notifier: fix icon pixmaps
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] libstatus-notifier: fix icon pixmaps
- Date: Sun, 13 Nov 2016 22:46:32 +0000 (UTC)
commit dd3499691cbdc3f55785b834d0206828b6420857
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Mon Nov 14 00:40:22 2016 +0200
libstatus-notifier: fix icon pixmaps
libstatus-notifier/sn-item.c | 144 +++++++++++++++++++++++++++++++++++-------
1 files changed, 120 insertions(+), 24 deletions(-)
---
diff --git a/libstatus-notifier/sn-item.c b/libstatus-notifier/sn-item.c
index 62bec4f..71c9fea 100644
--- a/libstatus-notifier/sn-item.c
+++ b/libstatus-notifier/sn-item.c
@@ -82,43 +82,143 @@ static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_PRIVATE (SnItem, sn_item, G_TYPE_OBJECT)
+static cairo_surface_t *
+surface_from_variant (GVariant *variant,
+ gint width,
+ gint height)
+{
+ cairo_format_t format;
+ gint stride;
+ guint32 *data;
+
+ format = CAIRO_FORMAT_ARGB32;
+ stride = cairo_format_stride_for_width (format, width);
+ data = (guint32 *) g_variant_get_data (variant);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ {
+ gint i;
+
+ for (i = 0; i < width * height; i++)
+ data[i] = GUINT32_FROM_BE (data[i]);
+ }
+#endif
+
+ return cairo_image_surface_create_for_data ((guchar *) data, format,
+ width, height, stride);
+}
+
+static cairo_surface_t *
+icon_surface_new (GVariant *variant,
+ gint width,
+ gint height)
+{
+ cairo_surface_t *surface;
+ cairo_surface_t *tmp;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+ return NULL;
+
+ tmp = surface_from_variant (variant, width, height);
+ if (cairo_surface_status (tmp) != CAIRO_STATUS_SUCCESS)
+ {
+ cairo_surface_destroy (surface);
+ return NULL;
+ }
+
+ cr = cairo_create (surface);
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+ {
+ cairo_surface_destroy (surface);
+ cairo_surface_destroy (tmp);
+ return NULL;
+ }
+
+ cairo_set_source_surface (cr, tmp, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (tmp);
+ cairo_destroy (cr);
+
+ return surface;
+}
+
static GdkPixbuf **
gvariant_to_gdk_pixbufs (GVariant *variant)
{
+ GPtrArray *array;
GVariantIter iter;
- gsize n_pixbufs;
- GdkPixbuf **pixbufs;
- guint i;
gint width;
gint height;
GVariant *value;
- n_pixbufs = g_variant_iter_init (&iter, variant);
- if (n_pixbufs == 0)
+ if (variant == NULL || g_variant_iter_init (&iter, variant) == 0)
return NULL;
- pixbufs = g_new0 (GdkPixbuf *, n_pixbufs + 1);
- i = 0;
-
+ array = g_ptr_array_new ();
while (g_variant_iter_next (&iter, "(ii@ay)", &width, &height, &value))
{
- GBytes *bytes;
- gint rowstride;
+ cairo_surface_t *surface;
- bytes = g_variant_get_data_as_bytes (value);
- rowstride = g_bytes_get_size (bytes) / height;
+ surface = icon_surface_new (value, width, height);
+ g_variant_unref (value);
- pixbufs[i++] = gdk_pixbuf_new_from_bytes (bytes, GDK_COLORSPACE_RGB,
- TRUE, 8, width, height,
- rowstride);
+ if (surface != NULL)
+ {
+ GdkPixbuf *pixbuf;
- g_bytes_unref (bytes);
- g_variant_unref (value);
+ pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height);
+ cairo_surface_destroy (surface);
+
+ if (pixbuf)
+ g_ptr_array_add (array, pixbuf);
+ }
}
- pixbufs[i] = NULL;
+ g_ptr_array_add (array, NULL);
+
+ return (GdkPixbuf **) g_ptr_array_free (array, FALSE);
+}
+
+static GVariant *
+get_variant_from_pixbuf (GdkPixbuf *pixbuf)
+{
+ gint width;
+ gint height;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ gint stride;
+ guint32 *data;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+
+ cairo_surface_flush (surface);
+ cairo_destroy (cr);
+
+ stride = cairo_image_surface_get_stride (surface);
+ data = (guint32 *) cairo_image_surface_get_data (surface);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ {
+ gint i;
+
+ for (i = 0; i < width * height; i++)
+ data[i] = GUINT32_TO_BE (data[i]);
+ }
+#endif
+
+ return g_variant_new_from_data (G_VARIANT_TYPE ("ay"), data, stride * height,
+ TRUE, (GDestroyNotify) cairo_surface_destroy,
+ surface);
- return pixbufs;
}
static GVariantBuilder *
@@ -136,15 +236,11 @@ gdk_pixbufs_to_gvariant_builder (GdkPixbuf **pixbufs)
{
gint width;
gint height;
- GBytes *bytes;
GVariant *variant;
width = gdk_pixbuf_get_width (pixbufs[i]);
height = gdk_pixbuf_get_height (pixbufs[i]);
- bytes = gdk_pixbuf_read_pixel_bytes (pixbufs[i]);
-
- variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"), bytes, TRUE);
- g_bytes_unref (bytes);
+ variant = get_variant_from_pixbuf (pixbufs[i]);
g_variant_builder_open (builder, G_VARIANT_TYPE ("(iiay)"));
g_variant_builder_add (builder, "i", width);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]