[gnome-shell/message-tray] Implement additional notification daemon icon types



commit af1a3b11f5e569a9e8bc2892f6567d5e1421442c
Author: Dan Winship <danw gnome org>
Date:   Tue Dec 8 17:36:34 2009 -0500

    Implement additional notification daemon icon types
    
    https://bugzilla.gnome.org/show_bug.cgi?id=603546

 js/ui/notificationDaemon.js |   48 ++++++++++++++++++++++++------
 src/shell-texture-cache.c   |   67 +++++++++++++++++++++++++++++++++++++++---
 src/shell-texture-cache.h   |    9 ++++++
 3 files changed, 109 insertions(+), 15 deletions(-)
---
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index 51044f1..fef31f3 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -1,6 +1,7 @@
 /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 
 const DBus = imports.dbus;
+const GLib = imports.gi.GLib;
 const Lang = imports.lang;
 const Shell = imports.gi.Shell;
 const Mainloop = imports.mainloop;
@@ -81,16 +82,7 @@ NotificationDaemon.prototype = {
         if (source == null) {
             id = nextNotificationId++;
 
-            source = new MessageTray.Source(this._sourceId(id), Lang.bind(this,
-                function (size) {
-                    if (icon != '')
-                        return Shell.TextureCache.get_default().load_icon_name(icon, size);
-                    else {
-                        // FIXME: load icon data from hints
-                        // FIXME: better fallback icon
-                        return Shell.TextureCache.get_default().load_icon_name('gtk-dialog-info', size);
-                    }
-                }));
+            source = new Source(this._sourceId(id), icon, hints);
             Main.messageTray.add(source);
 
             source.connect('clicked', Lang.bind(this,
@@ -143,3 +135,39 @@ NotificationDaemon.prototype = {
 
 DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
 
+function Source(sourceId, icon, hints) {
+    this._init(sourceId, icon, hints);
+}
+
+Source.prototype = {
+    __proto__:  MessageTray.Source.prototype,
+
+    _init: function(sourceId, icon, hints) {
+        MessageTray.Source.prototype._init.call(this, sourceId);
+
+        this._icon = icon;
+        this._iconData = hints.icon_data;
+    },
+
+    createIcon: function(size) {
+        let textureCache = Shell.TextureCache.get_default();
+
+        if (this._icon) {
+            if (this._icon.substr(0, 7) == 'file://')
+                return textureCache.load_uri_async(this._icon, size, size);
+            else if (this._icon[0] == '/') {
+                let uri = GLib.filename_to_uri(this._icon, null);
+                return textureCache.load_uri_async(uri, size, size);
+            } else
+                return textureCache.load_icon_name(this._icon, size);
+        } else if (this._iconData) {
+            let [width, height, rowStride, hasAlpha,
+                 bitsPerSample, nChannels, data] = this._iconData;
+            return textureCache.load_from_raw(data, data.length, hasAlpha,
+                                              width, height, rowStride, size);
+        } else {
+            // FIXME: fallback icon?
+            return textureCache.load_icon_name('gtk-dialog-info', size);
+        }
+    }
+};
diff --git a/src/shell-texture-cache.c b/src/shell-texture-cache.c
index d85ca84..9b022ba 100644
--- a/src/shell-texture-cache.c
+++ b/src/shell-texture-cache.c
@@ -1154,7 +1154,7 @@ shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
 /**
  * shell_texture_cache_load_from_data:
  * @cache: The texture cache instance
- * @data: Raw image data
+ * @data: Image data in PNG, GIF, etc format
  * @len: length of @data
  * @size: Size in pixels to use for the resulting texture
  * @error: Return location for error
@@ -1192,7 +1192,6 @@ shell_texture_cache_load_from_data (ShellTextureCache *cache,
   texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
   if (texdata == NULL)
     {
-      g_debug ("creating new pixbuf");
       pixbuf = impl_load_pixbuf_data (data, len, size, size, error);
       if (!pixbuf)
         {
@@ -1207,12 +1206,70 @@ shell_texture_cache_load_from_data (ShellTextureCache *cache,
 
       g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key), texdata);
     }
-  else
+
+  g_free (key.checksum);
+
+  set_texture_cogl_texture (texture, texdata);
+  return CLUTTER_ACTOR (texture);
+}
+
+/**
+ * shell_texture_cache_load_from_raw:
+ * @cache: a #ShellTextureCache
+ * @data: raw pixel data
+ * @len: the length of @data
+ * @has_alpha: whether @data includes an alpha channel
+ * @width: width in pixels of @data
+ * @height: width in pixels of @data
+ * @rowstride: rowstride of @data
+ * @size: size of icon to return
+ *
+ * Creates (or retrieves from cache) an icon based on raw pixel data.
+ *
+ * Return value: (transfer none): a new #ClutterActor displaying a
+ * pixbuf created from @data and the other parameters.
+ **/
+ClutterActor *
+shell_texture_cache_load_from_raw (ShellTextureCache *cache,
+                                   const guchar      *data,
+                                   gsize              len,
+                                   gboolean           has_alpha,
+                                   int                width,
+                                   int                height,
+                                   int                rowstride,
+                                   int                size,
+                                   GError           **error)
+{
+  ClutterTexture *texture;
+  CoglHandle texdata;
+  CacheKey key;
+  gchar *checksum;
+
+  texture = create_default_texture (cache);
+  clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
+
+  /* In theory, two images of different size could have the same
+   * pixel data. We ignore that theory.
+   */
+  checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len);
+
+  memset (&key, 0, sizeof(key));
+  key.size = size;
+  key.checksum = checksum;
+
+  texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
+  if (texdata == NULL)
     {
-      g_debug ("using texture from cache");
-      set_texture_cogl_texture (texture, texdata);
+      texdata = cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE,
+                                            has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
+                                            COGL_PIXEL_FORMAT_ANY,
+                                            rowstride, data);
+      g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key), texdata);
     }
 
+  g_free (key.checksum);
+
+  set_texture_cogl_texture (texture, texdata);
   return CLUTTER_ACTOR (texture);
 }
 
diff --git a/src/shell-texture-cache.h b/src/shell-texture-cache.h
index 14d132e..d7280c4 100644
--- a/src/shell-texture-cache.h
+++ b/src/shell-texture-cache.h
@@ -85,6 +85,15 @@ ClutterActor *shell_texture_cache_load_from_data (ShellTextureCache *cache,
                                                   gsize              len,
                                                   int                size,
                                                   GError           **error);
+ClutterActor *shell_texture_cache_load_from_raw  (ShellTextureCache *cache,
+                                                  const guchar      *data,
+                                                  gsize              len,
+                                                  gboolean           has_alpha,
+                                                  int                width,
+                                                  int                height,
+                                                  int                rowstride,
+                                                  int                size,
+                                                  GError           **error);
 
 gboolean shell_texture_cache_pixbuf_equal (ShellTextureCache *cache, GdkPixbuf *a, GdkPixbuf *b);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]