[Pkg-mozext-commits] [firetray] 43/399: finish text icon implementation for displaying unread messages count in mail applications

David Prévot taffit at alioth.debian.org
Tue Oct 29 18:23:11 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch dfsg-clean
in repository firetray.

commit 0ccfb11cfc72c4e031c1422d5243ace0861b085f
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Mon Sep 19 18:29:18 2011 +0200

    finish text icon implementation for displaying unread messages count in mail
    applications
---
 src/chrome/content/overlay.js        |    4 +-
 src/chrome/skin/message-mail-new.png |  Bin 770 -> 0 bytes
 src/install.rdf                      |    2 +-
 src/modules/MoztHandler.jsm          |    2 +-
 src/modules/MoztIconLinux.jsm        |  215 ++++++++++++++++++----------------
 src/modules/MoztMessaging.jsm        |    8 +-
 src/modules/cairo.jsm                |   28 +++++
 src/modules/commons.js               |   12 ++
 src/modules/ctypes-utils.jsm         |    4 +-
 src/modules/gdk.jsm                  |   18 ++-
 src/modules/gobject.jsm              |    1 +
 src/modules/gtk.jsm                  |    9 ++
 src/modules/pango.jsm                |   60 ++++++++++
 testing/gtk_icon_example.c           |   38 +++---
 14 files changed, 266 insertions(+), 135 deletions(-)

diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js
index 4f8b22d..c91453e 100644
--- a/src/chrome/content/overlay.js
+++ b/src/chrome/content/overlay.js
@@ -91,8 +91,8 @@ window.addEventListener(
 
 // // TEST - can we catch minimize event ?
 // window.addEventListener(
-//   'DOMAttrModified', function (e) { // focus
-//     removeEventListener('deactivate', arguments.callee, true);
+//   'command', function (e) {
+//     removeEventListener('command', arguments.callee, true);
 //     WARN("Got deactivated: "+e.originalTarget.windowState); // Ci.nsIDOMChromeWindow.STATE_MINIMIZED|STATE_NORMAL
 //     WARN("attrName: "+e.attrName);
 //   },
diff --git a/src/chrome/skin/message-mail-new.png b/src/chrome/skin/message-mail-new.png
deleted file mode 100644
index 3691cb7..0000000
Binary files a/src/chrome/skin/message-mail-new.png and /dev/null differ
diff --git a/src/install.rdf b/src/install.rdf
index d688e21..1a0a6e6 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -44,7 +44,7 @@
       <Description>
         <em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
         <em:minVersion>2.0a1</em:minVersion>
-        <em:maxVersion>2.4.*   </em:maxVersion>
+        <em:maxVersion>2.4.*</em:maxVersion>
       </Description>
     </em:targetApplication>
 
diff --git a/src/modules/MoztHandler.jsm b/src/modules/MoztHandler.jsm
index 4a0d14b..e57afaf 100644
--- a/src/modules/MoztHandler.jsm
+++ b/src/modules/MoztHandler.jsm
@@ -50,7 +50,7 @@ mozt.Handler = {
     if (winType == "BaseWindow")
       winOut = winInterface.getInterface(Ci.nsIBaseWindow);
     else if (winType == "XUL")
-    winOut = winInterface.getInterface(Ci.nsIXULWindow);
+      winOut = winInterface.getInterface(Ci.nsIXULWindow);
     else {
       ERROR("MOZTRAY: unknown winType '" + winType + "'");
       return null;
diff --git a/src/modules/MoztIconLinux.jsm b/src/modules/MoztIconLinux.jsm
index 7d08b25..035e961 100644
--- a/src/modules/MoztIconLinux.jsm
+++ b/src/modules/MoztIconLinux.jsm
@@ -8,9 +8,11 @@ const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://moztray/cairo.jsm");
 Cu.import("resource://moztray/gobject.jsm");
 Cu.import("resource://moztray/gdk.jsm");
 Cu.import("resource://moztray/gtk.jsm");
+Cu.import("resource://moztray/pango.jsm");
 Cu.import("resource://moztray/commons.js");
 
 if ("undefined" == typeof(mozt.Handler))
@@ -26,8 +28,10 @@ mozt.IconLinux = {
   tryIcon: null,
   menu: null,
   appName: null,
-  ICON_FILENAME_DEFAULT: null,
-  ICON_SUFFIX: "32.png",
+  FILENAME_DEFAULT: null,
+  FILENAME_SUFFIX: "32.png",
+  FILENAME_NEWMAIL: "newmail.png",
+  MIN_FONT_SIZE: 4,
 
   init: function() {
 
@@ -36,10 +40,12 @@ mozt.IconLinux = {
       // init tray icon, some variables
       this.trayIcon  = gtk.gtk_status_icon_new();
       this.appName = Services.appinfo.name.toLowerCase();
-      this.ICON_FILENAME_DEFAULT = mozt.Utils.chromeToPath(
-        "chrome://moztray/skin/" +  this.appName + this.ICON_SUFFIX);
+      this.FILENAME_DEFAULT = mozt.Utils.chromeToPath(
+        "chrome://moztray/skin/" +  this.appName + this.FILENAME_SUFFIX);
+      this.FILENAME_NEWMAIL = mozt.Utils.chromeToPath(
+        "chrome://moztray/skin/newmail.png");
 
-      this.setDefaultImage();
+      this.setImageDefault();
 
       // build icon popup menu
       this.menu = gtk.gtk_menu_new();
@@ -68,7 +74,7 @@ mozt.IconLinux = {
       gobject.g_signal_connect(this.trayIcon, "popup-menu",
                                   mozt_popupMenuCb, this.menu);
 
-      this.setDefaultTooltip();
+      this.setTooltipDefault();
 
       // watch out for binding problems ! here we prefer to keep 'this' in
       // showHideToTray() and abandon the args.
@@ -77,7 +83,6 @@ mozt.IconLinux = {
       gobject.g_signal_connect(this.trayIcon, "activate",
                                   mozt_iconActivateCb, null);
 
-
     } catch (x) {
       ERROR(x);
       return false;
@@ -108,10 +113,10 @@ mozt.IconLinux = {
     return true;
   },
 
-  setDefaultImage: function() {
-    if (!this.ICON_FILENAME_DEFAULT)
+  setImageDefault: function() {
+    if (!this.FILENAME_DEFAULT)
       throw "Default application icon filename not set";
-    this.setImage(this.ICON_FILENAME_DEFAULT);
+    this.setImage(this.FILENAME_DEFAULT);
   },
 
   // GTK bug: Gdk-CRITICAL **: IA__gdk_window_get_root_coords: assertion `GDK_IS_WINDOW (window)' failed
@@ -123,104 +128,110 @@ mozt.IconLinux = {
     return true;
   },
 
-  setDefaultTooltip: function() {
+  setTooltipDefault: function() {
     if (!this.appName)
       throw "application name not initialized";
     this.setTooltip(this.appName);
   },
 
-  // SetIconText(GtkStatusIcon *tray_icon, const char *text, const char *color) {
-  setText: function() {
-
-  // // build background from image
-  // GdkPixbuf* special_icon = gdk_pixbuf_new_from_file("newmail.png", NULL); // GError **error);
-  // GdkPixbuf *dest = gdk_pixbuf_copy(special_icon);
-  // int w=gdk_pixbuf_get_width(special_icon);
-  // int h=gdk_pixbuf_get_height(special_icon);
-
-  // // prepare colors/alpha
-  // GdkColormap* cmap=gdk_screen_get_system_colormap(gdk_screen_get_default());
-  // int screen_depth=24;
-  // GdkVisual* visual = gdk_colormap_get_visual(cmap);
-  // screen_depth = visual->depth;
-  // GdkColor fore = { 0, 0, 0, 0 };
-  // GdkColor alpha  = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-  // gdk_color_parse  (color, &fore) )
-  // if(fore.red==alpha.red && fore.green==alpha.green && fore.blue==alpha.blue) {
-  //   alpha.red=0; //make sure alpha is different from fore
-  // }
-  // gdk_colormap_alloc_color (cmap, &fore, TRUE, TRUE);
-  // gdk_colormap_alloc_color (cmap, &alpha, TRUE, TRUE);
-
-  // // build pixmap with rectangle
-  // GdkPixmap *pm = gdk_pixmap_new (NULL, w, h, screen_depth);
-  // GdkGC *gc = gdk_gc_new (pm); // graphic context. DEPRECATED ?
-  // gdk_gc_set_foreground(gc,&alpha);
-  // /* gdk_draw_rectangle(pm,gc,TRUE, 0, 0, w ,h ); */
-  // cairo_t *cr;
-  // cr = gdk_cairo_create(pm);
-  // cairo_rectangle(cr, 0, 0, w, h);
-  // /* void                cairo_rectangle                     (cairo_t *cr, */
-  // /*                                                          double x, */
-  // /*                                                          double y, */
-  // /*                                                          double width, */
-  // /*                                                          double height); */
-  // cairo_set_source_rgb(cr, 1, 1, 1); /* TODO: consider cairo_set_source_rgba (notice the ending "a" for alpha) */
-  // cairo_fill(cr);
-  // cairo_destroy(cr);
-
-  // // build text
-  // GtkWidget *scratch = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-  // PangoLayout *layout = gtk_widget_create_pango_layout(scratch, NULL);
-  // gtk_widget_destroy(scratch);
-  // PangoFontDescription *fnt = pango_font_description_from_string("Sans 18");
-  // pango_font_description_set_weight (fnt,PANGO_WEIGHT_SEMIBOLD);
-  // pango_layout_set_spacing            (layout,0);
-  // pango_layout_set_font_description   (layout, fnt);
-  // pango_layout_set_text (layout, (gchar *)text,-1);
-  // int tw=0;
-  // int th=0;
-  // int sz;
-  // int border=4;
-  // pango_layout_get_pixel_size(layout, &tw, &th);
-  // while( (tw>w - border || th > h - border)) //fit text to the icon by decreasing font size
-  // {
-  //   sz=pango_font_description_get_size (fnt);
-  //   if(sz<MIN_FONT_SIZE) {
-  //     sz=MIN_FONT_SIZE;
-  //     break;
-  //   }
-  //   sz-=PANGO_SCALE;
-  //   pango_font_description_set_size (fnt,sz);
-  //   pango_layout_set_font_description   (layout, fnt);
-  //   pango_layout_get_pixel_size(layout, &tw, &th);
-  // }
-  // // center text
-  // int px, py;
-  // px=(w-tw)/2;
-  // py=(h-th)/2;
-
-  // // draw text on pixmap
-  // gdk_draw_layout_with_colors (pm, gc, px, py, layout, &fore, NULL);
-
-  // GdkPixbuf *buf = gdk_pixbuf_get_from_drawable (NULL, pm, NULL, 0, 0, 0, 0, w, h);
-  // g_object_unref (pm);
-  // GdkPixbuf *alpha_buf = gdk_pixbuf_add_alpha  (buf, TRUE, (guchar)alpha.red, (guchar)alpha.green, (guchar)alpha.blue);
-
-  // // cleaning
-  // g_object_unref (buf);
-  // g_object_unref (layout);
-  // pango_font_description_free (fnt);
-  // g_object_unref (gc);
-
-
-  // //merge the rendered text on top
-  // gdk_pixbuf_composite (alpha_buf,dest,0,0,w,h,0,0,1,1,GDK_INTERP_NEAREST,255);
-  // g_object_unref(alpha_buf);
-
-
-  // gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(tray_icon), GDK_PIXBUF(dest));
+  setText: function(text, color) { // TODO: split into smaller functions;
+    LOG("setText");
+    if (typeof(text) != "string" ) {
+      ERROR("'text' arguement must be toString()'d: ");
+      return false;
+    }
 
+    // build background from image
+    let specialIcon = gdk.gdk_pixbuf_new_from_file(this.FILENAME_NEWMAIL, null); // GError **error);
+    let dest = gdk.gdk_pixbuf_copy(specialIcon);
+    let w = gdk.gdk_pixbuf_get_width(specialIcon);
+    let h = gdk.gdk_pixbuf_get_height(specialIcon);
+
+    // prepare colors/alpha
+    let colorMap = gdk.gdk_screen_get_system_colormap(gdk.gdk_screen_get_default());
+    let visual = gdk.gdk_colormap_get_visual(colorMap);
+    let screenDepth = 24; // = visual.depth; // FIXME: was visual->depth
+    let fore = new gdk.GdkColor;
+    fore.pixel = fore.red = fore.green = fore.blue = 0;
+    let alpha  = new gdk.GdkColor;
+    alpha.pixel = alpha.red = alpha.green = alpha.blue = 0xFFFF;
+    if (!fore || !alpha)
+      WARN("Undefined GdkColor fore or alpha");
+    gdk.gdk_color_parse(color, fore.address());
+    if(fore.red == alpha.red && fore.green == alpha.green && fore.blue == alpha.blue) {
+      alpha.red=0; // make sure alpha is different from fore
+    }
+    gdk.gdk_colormap_alloc_color(colorMap, fore.address(), true, true);
+    gdk.gdk_colormap_alloc_color(colorMap, alpha.address(), true, true);
+
+    // build pixmap with rectangle
+    let pm = gdk.gdk_pixmap_new(null, w, h, screenDepth);
+    let pmDrawable = ctypes.cast(pm, gdk.GdkDrawable.ptr);
+    let cr = gdk.gdk_cairo_create(pmDrawable);
+    gdk.gdk_cairo_set_source_color(cr, alpha.address());
+    cairo.cairo_rectangle(cr, 0, 0, w, h);
+    cairo.cairo_set_source_rgb(cr, 1, 1, 1);
+    cairo.cairo_fill(cr);
+
+    // build text
+    let scratch = gtk.gtk_window_new(gtk.GTK_WINDOW_TOPLEVEL);
+    let layout = gtk.gtk_widget_create_pango_layout(scratch, null);
+    gtk.gtk_widget_destroy(scratch);
+    let fnt = pango.pango_font_description_from_string("Sans 18");
+    pango.pango_font_description_set_weight(fnt,pango.PANGO_WEIGHT_SEMIBOLD);
+    pango.pango_layout_set_spacing(layout,0);
+    pango.pango_layout_set_font_description(layout, fnt);
+    LOG("layout="+layout);
+    LOG("text="+text);
+    pango.pango_layout_set_text(layout, text,-1);
+    let tw = new ctypes.int;
+    let th = new ctypes.int;
+    let sz;
+    let border = 4;
+    pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
+    LOG("tw="+tw.value+" th="+th.value);
+    // fit text to the icon by decreasing font size
+    while ( tw.value > (w - border) || th.value > (h - border) ) {
+      sz = pango.pango_font_description_get_size(fnt);
+      if(sz < this.MIN_FONT_SIZE) {
+        sz = this.MIN_FONT_SIZE;
+        break;
+      }
+      sz -= pango.PANGO_SCALE;
+      pango.pango_font_description_set_size(fnt,sz);
+      pango.pango_layout_set_font_description(layout, fnt);
+      pango.pango_layout_get_pixel_size(layout, tw.address(), th.address());
+    }
+    LOG("tw="+tw.value+" th="+th.value);
+    pango.pango_font_description_free(fnt);
+    // center text
+    let px = (w-tw.value)/2;
+    let py = (h-th.value)/2;
+
+    // draw text on pixmap
+    gdk.gdk_cairo_set_source_color(cr, fore.address());
+    cairo.cairo_move_to(cr, px, py);
+    pangocairo.pango_cairo_show_layout(cr, layout);
+    cairo.cairo_destroy(cr);
+    gobject.g_object_unref(layout);
+
+    let buf = gdk.gdk_pixbuf_get_from_drawable(null, pmDrawable, null, 0, 0, 0, 0, w, h);
+    gobject.g_object_unref(pm);
+    LOG("alpha="+alpha);
+    let alphaRed = gobject.guint16(alpha.red);
+    let alphaRed_guchar = ctypes.cast(alphaRed, gobject.guchar);
+    let alphaGreen = gobject.guint16(alpha.green);
+    let alphaGreen_guchar = ctypes.cast(alphaGreen, gobject.guchar);
+    let alphaBlue = gobject.guint16(alpha.blue);
+    let alphaBlue_guchar = ctypes.cast(alphaBlue, gobject.guchar);
+    let bufAlpha = gdk.gdk_pixbuf_add_alpha(buf, true, alphaRed_guchar, alphaGreen_guchar, alphaBlue_guchar);
+    gobject.g_object_unref(buf);
+
+    // merge the rendered text on top
+    gdk.gdk_pixbuf_composite(bufAlpha,dest,0,0,w,h,0,0,1,1,gdk.GDK_INTERP_NEAREST,255);
+    gobject.g_object_unref(bufAlpha);
+
+    gtk.gtk_status_icon_set_from_pixbuf(this.trayIcon, dest);
   }
 
 }; // mozt.IconLinux
diff --git a/src/modules/MoztMessaging.jsm b/src/modules/MoztMessaging.jsm
index e59864c..e7dfadf 100644
--- a/src/modules/MoztMessaging.jsm
+++ b/src/modules/MoztMessaging.jsm
@@ -19,6 +19,7 @@ const FLDR_UNINTERESTING =
   Ci.nsMsgFolderFlags.SentMail |
   Ci.nsMsgFolderFlags.Templates |
   Ci.nsMsgFolderFlags.Trash;
+const ICON_TEXT_COLOR = "#00000";
 
 /**
  * mozt namespace.
@@ -107,11 +108,10 @@ mozt.Messaging = {
 
     // update icon
     if (this._unreadMsgCount == 0) {
-      mozt.IconLinux.setDefaultImage();
-      mozt.IconLinux.setDefaultTooltip();
+      mozt.IconLinux.setImageDefault();
+      mozt.IconLinux.setTooltipDefault();
     } else if (this._unreadMsgCount > 0) {
-      mozt.IconLinux.setImage(
-        mozt.Utils.chromeToPath("chrome://moztray/skin/message-mail-new.png"));
+      mozt.IconLinux.setText(this._unreadMsgCount.toString(), ICON_TEXT_COLOR);
       let localizedMessage = PluralForm.get(
         this._unreadMsgCount,
         mozt.Utils.strings.GetStringFromName("tooltip.unread_messages"))
diff --git a/src/modules/cairo.jsm b/src/modules/cairo.jsm
new file mode 100644
index 0000000..a5085f6
--- /dev/null
+++ b/src/modules/cairo.jsm
@@ -0,0 +1,28 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+var EXPORTED_SYMBOLS = [ "cairo" ];
+
+const CAIRO_LIBNAME = "cairo";
+const CAIRO_ABIS    = [ 2 ];
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://moztray/ctypes-utils.jsm");
+
+function cairo_defines(lib) {
+  this.cairo_t = ctypes.StructType("cairo_t");
+
+  lib.lazy_bind("cairo_rectangle", ctypes.void_t, this.cairo_t.ptr, ctypes.double, ctypes.double, ctypes.double, ctypes.double);
+  lib.lazy_bind("cairo_set_source_rgb", ctypes.void_t, this.cairo_t.ptr, ctypes.double, ctypes.double, ctypes.double);
+  lib.lazy_bind("cairo_fill", ctypes.void_t, this.cairo_t.ptr);
+  lib.lazy_bind("cairo_move_to", ctypes.void_t, this.cairo_t.ptr, ctypes.double, ctypes.double);
+  lib.lazy_bind("cairo_destroy", ctypes.void_t, this.cairo_t.ptr);
+
+}
+
+if (!cairo) {
+  var cairo = new ctypes_library(CAIRO_LIBNAME, CAIRO_ABIS, cairo_defines);
+}
diff --git a/src/modules/commons.js b/src/modules/commons.js
index 9ccdc6b..de22b7f 100644
--- a/src/modules/commons.js
+++ b/src/modules/commons.js
@@ -38,6 +38,18 @@ mozt.Utils = {
   prefService: Services.prefs.getBranch("extensions.moztray."),
   strings: Services.strings.createBundle("chrome://moztray/locale/overlay.properties"),
 
+  dumpObj: function(obj) {
+    let str = "";
+    for(i in obj) {
+      try {
+        str += "obj["+i+"]: " + obj[i] + "\n";
+      } catch(e) {
+        str += "obj["+i+"]: Unavailable\n";
+      }
+    }
+    LOG(str);
+  },
+
   // adapted from http://forums.mozillazine.org/viewtopic.php?p=921150#921150
   chromeToPath: function(aPath) {
     if (!aPath || !(/^chrome:/.test(aPath)))
diff --git a/src/modules/ctypes-utils.jsm b/src/modules/ctypes-utils.jsm
index 2f12f45..6946d0e 100644
--- a/src/modules/ctypes-utils.jsm
+++ b/src/modules/ctypes-utils.jsm
@@ -63,7 +63,9 @@ function ctypes_library(name, abis, defines) {
         this.ABI = abi;
         LOG("Successfully loaded " + soname);
         break;
-      } catch(e) {}
+      } catch(e) {
+          ERROR(soname+" unfound.");
+      }
     }
 
     this.close = function() {
diff --git a/src/modules/gdk.jsm b/src/modules/gdk.jsm
index 7a45c3b..a859a91 100644
--- a/src/modules/gdk.jsm
+++ b/src/modules/gdk.jsm
@@ -48,11 +48,12 @@ const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://moztray/ctypes-utils.jsm");
+Cu.import("resource://moztray/cairo.jsm");
 Cu.import("resource://moztray/glib.jsm");
 Cu.import("resource://moztray/gobject.jsm");
 
 function gdk_defines(lib) {
-  this.GDK_INTERP_NEAREST = 1, // GdkInterpType
+  this.GDK_INTERP_NEAREST = 1, // enum GdkInterpType
 
   this.GdkWindow = ctypes.StructType("GdkWindow");
   this.GdkByteOrder = ctypes.int; // enum
@@ -110,6 +111,7 @@ function gdk_defines(lib) {
   this.GdkPixmap = ctypes.StructType("GdkPixmap");
   this.GdkDrawable = ctypes.StructType("GdkDrawable");
   this.GdkGC = ctypes.StructType("GdkGC");
+  this.GdkInterpType = ctypes.int;
 
   lib.lazy_bind("gdk_window_new", this.GdkWindow.ptr, this.GdkWindow.ptr, this.GdkWindowAttributes.ptr, gobject.gint);
   lib.lazy_bind("gdk_window_destroy", ctypes.void_t, this.GdkWindow.ptr);
@@ -127,9 +129,17 @@ function gdk_defines(lib) {
   lib.lazy_bind("gdk_color_parse", gobject.gboolean, gobject.gchar.ptr, this.GdkColor.ptr);
   lib.lazy_bind("gdk_colormap_alloc_color", gobject.gboolean, this.GdkColormap.ptr, this.GdkColor.ptr, gobject.gboolean, gobject.gboolean);
   lib.lazy_bind("gdk_pixmap_new", this.GdkPixmap.ptr, this.GdkDrawable.ptr, gobject.gint, gobject.gint, gobject.gint);
-  lib.lazy_bind("gdk_gc_new", this.GdkGC.ptr, this.GdkDrawable.ptr);
-  lib.lazy_bind("gdk_gc_set_foreground", ctypes.void_t, this.GdkGC.ptr, this.GdkColor.ptr);
-  lib.lazy_bind("gdk_draw_rectangle", ctypes.void_t, this.GdkDrawable.ptr, this.GdkGC.ptr, gobject.gboolean, gobject.gint, gobject.gint, gobject.gint, gobject.gint);
+
+  // DEPRECATED
+  // lib.lazy_bind("gdk_gc_new", this.GdkGC.ptr, this.GdkDrawable.ptr);
+  // lib.lazy_bind("gdk_gc_set_foreground", ctypes.void_t, this.GdkGC.ptr, this.GdkColor.ptr);
+  // lib.lazy_bind("gdk_draw_rectangle", ctypes.void_t, this.GdkDrawable.ptr, this.GdkGC.ptr, gobject.gboolean, gobject.gint, gobject.gint, gobject.gint, gobject.gint);
+
+  lib.lazy_bind("gdk_cairo_create", cairo.cairo_t.ptr, this.GdkDrawable.ptr);
+  lib.lazy_bind("gdk_cairo_set_source_color", ctypes.void_t, cairo.cairo_t.ptr, this.GdkColor.ptr);
+  lib.lazy_bind("gdk_pixbuf_get_from_drawable", this.GdkPixbuf.ptr, this.GdkPixbuf.ptr, this.GdkDrawable.ptr, this.GdkColormap.ptr, ctypes.int, ctypes.int, ctypes.int, ctypes.int, ctypes.int, ctypes.int);
+  lib.lazy_bind("gdk_pixbuf_add_alpha", this.GdkPixbuf.ptr, this.GdkPixbuf.ptr, gobject.gboolean, gobject.guchar, gobject.guchar, gobject.guchar);
+  lib.lazy_bind("gdk_pixbuf_composite", ctypes.void_t, this.GdkPixbuf.ptr, this.GdkPixbuf.ptr, ctypes.int, ctypes.int, ctypes.int, ctypes.int, ctypes.double, ctypes.double, ctypes.double, ctypes.double, this.GdkInterpType, ctypes.int);
 
 }
 
diff --git a/src/modules/gobject.jsm b/src/modules/gobject.jsm
index 05e1864..518d840 100644
--- a/src/modules/gobject.jsm
+++ b/src/modules/gobject.jsm
@@ -58,6 +58,7 @@ function gobject_defines(lib) {
   this.guint16 = ctypes.uint16_t;
   this.gint = ctypes.int;
   this.gchar = ctypes.unsigned_char;
+  this.guchar = ctypes.unsigned_char;
   this.gboolean = this.gint;
   this.gfloat = ctypes.float;
   this.GCallback = ctypes.voidptr_t;
diff --git a/src/modules/gtk.jsm b/src/modules/gtk.jsm
index 57403e8..a71503f 100644
--- a/src/modules/gtk.jsm
+++ b/src/modules/gtk.jsm
@@ -13,9 +13,11 @@ Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://moztray/ctypes-utils.jsm");
 Cu.import("resource://moztray/gdk.jsm");
 Cu.import("resource://moztray/gobject.jsm");
+Cu.import("resource://moztray/pango.jsm");
 
 function gtk_defines(lib) {
   this.GTK_ICON_SIZE_MENU = 1;
+  this.GTK_WINDOW_TOPLEVEL = 1;
 
   this.GtkStatusIcon = ctypes.StructType("GtkStatusIcon");
   this.GtkStyle = ctypes.StructType("GtkStyle");
@@ -44,6 +46,8 @@ function gtk_defines(lib) {
   // use ctypes.cast(menu, LibGtkStatusIcon.GtkMenuShell.ptr);
   this.GtkMenuShell = ctypes.StructType("GtkMenuShell");
   this.GtkImageMenuItem = ctypes.StructType("GtkImageMenuItem");
+  this.GtkWindow = ctypes.StructType("GtkWindow");
+  this.GtkWindowType = ctypes.int; // enum
 
   this.GtkMenuPositionFunc_t = ctypes.FunctionType(
     ctypes.default_abi, ctypes.void_t,
@@ -77,6 +81,11 @@ function gtk_defines(lib) {
                 this.GtkMenu.ptr, gobject.gint.ptr, gobject.gint.ptr,
                 gobject.gboolean.ptr, gobject.gpointer);
 
+  lib.lazy_bind("gtk_window_new", this.GtkWidget.ptr, this.GtkWindowType);
+  lib.lazy_bind("gtk_widget_create_pango_layout", pango.PangoLayout.ptr, this.GtkWidget.ptr, gobject.gchar.ptr);
+  lib.lazy_bind("gtk_widget_destroy", ctypes.void_t, this.GtkWidget.ptr);
+  lib.lazy_bind("gtk_status_icon_set_from_pixbuf", ctypes.void_t, this.GtkStatusIcon.ptr, gdk.GdkPixbuf.ptr);
+
 }
 
 if (!gtk) {
diff --git a/src/modules/pango.jsm b/src/modules/pango.jsm
new file mode 100644
index 0000000..66a514e
--- /dev/null
+++ b/src/modules/pango.jsm
@@ -0,0 +1,60 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+var EXPORTED_SYMBOLS = [ "pango", "pangocairo" ];
+
+const PANGO_LIBNAME = "pango-1.0";
+const PANGO_ABIS    = [ 0 ];
+const PANGOCAIRO_LIBNAME = "pangocairo-1.0";
+const PANGOCAIRO_ABIS    = [ 0 ];
+
+const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://moztray/ctypes-utils.jsm");
+Cu.import("resource://moztray/cairo.jsm");
+Cu.import("resource://moztray/gobject.jsm");
+
+function pango_defines(lib) {
+  this.PANGO_WEIGHT_THIN = 100,
+  this.PANGO_WEIGHT_ULTRALIGHT = 200,
+  this.PANGO_WEIGHT_LIGHT = 300,
+  this.PANGO_WEIGHT_BOOK = 380,
+  this.PANGO_WEIGHT_NORMAL = 400,
+  this.PANGO_WEIGHT_MEDIUM = 500,
+  this.PANGO_WEIGHT_SEMIBOLD = 600,
+  this.PANGO_WEIGHT_BOLD = 700,
+  this.PANGO_WEIGHT_ULTRABOLD = 800,
+  this.PANGO_WEIGHT_HEAVY = 900,
+  this.PANGO_WEIGHT_ULTRAHEAVY = 1000,
+  this.PANGO_SCALE = 1024,
+
+  this.PangoFontDescription = ctypes.StructType("PangoFontDescription");
+  this.PangoLayout = ctypes.StructType("PangoLayout");
+  this.PangoWeight = ctypes.int; // enum
+
+  lib.lazy_bind("pango_font_description_from_string", this.PangoFontDescription.ptr, ctypes.char.ptr);
+  lib.lazy_bind("pango_font_description_set_weight", ctypes.void_t, this.PangoFontDescription.ptr, this.PangoWeight);
+  lib.lazy_bind("pango_layout_set_spacing", ctypes.void_t, this.PangoLayout.ptr, ctypes.int);
+  lib.lazy_bind("pango_layout_set_font_description", ctypes.void_t, this.PangoLayout.ptr, this.PangoFontDescription.ptr);
+  lib.lazy_bind("pango_layout_set_text", ctypes.void_t, this.PangoLayout.ptr, ctypes.char.ptr, ctypes.int);
+  lib.lazy_bind("pango_layout_get_pixel_size", ctypes.void_t, this.PangoLayout.ptr, ctypes.int.ptr, ctypes.int.ptr);
+  lib.lazy_bind("pango_font_description_get_size", gobject.gint, this.PangoFontDescription.ptr);
+  lib.lazy_bind("pango_font_description_set_size", ctypes.void_t, this.PangoFontDescription.ptr, gobject.gint);
+  lib.lazy_bind("pango_font_description_free", ctypes.void_t, this.PangoFontDescription.ptr);
+
+}
+
+if (!pango) {
+  var pango = new ctypes_library(PANGO_LIBNAME, PANGO_ABIS, pango_defines);
+}
+
+
+function pangocairo_defines(lib) {
+  lib.lazy_bind("pango_cairo_show_layout", ctypes.void_t, cairo.cairo_t.ptr, pango.PangoLayout.ptr);
+}
+
+if (!pangocairo) {
+  var pangocairo = new ctypes_library(PANGOCAIRO_LIBNAME, PANGOCAIRO_ABIS, pangocairo_defines);
+}
diff --git a/testing/gtk_icon_example.c b/testing/gtk_icon_example.c
index 478c6ab..46c453b 100644
--- a/testing/gtk_icon_example.c
+++ b/testing/gtk_icon_example.c
@@ -83,29 +83,27 @@ SetIconText(GtkStatusIcon *tray_icon, const char *text, const char *color) {
   screen_depth = visual->depth;
   GdkColor fore = { 0, 0, 0, 0 };
   GdkColor alpha  = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-  gdk_color_parse  (color, &fore) )
+  gdk_color_parse(color, &fore);
   if(fore.red==alpha.red && fore.green==alpha.green && fore.blue==alpha.blue) {
-    alpha.red=0; //make sure alpha is different from fore
+    alpha.red=0; // make sure alpha is different from fore
   }
   gdk_colormap_alloc_color (cmap, &fore, TRUE, TRUE);
   gdk_colormap_alloc_color (cmap, &alpha, TRUE, TRUE);
 
   // build pixmap with rectangle
   GdkPixmap *pm = gdk_pixmap_new (NULL, w, h, screen_depth);
-  GdkGC *gc = gdk_gc_new (pm); // graphic context. DEPRECATED ?
-  gdk_gc_set_foreground(gc,&alpha);
-  /* gdk_draw_rectangle(pm,gc,TRUE, 0, 0, w ,h ); */
-  cairo_t *cr;
-  cr = gdk_cairo_create(pm);
+  cairo_t *cr = gdk_cairo_create(pm);
+  gdk_cairo_set_source_color(cr, &alpha);
+/* void                gdk_cairo_set_source_color          (cairo_t *cr, */
+/*                                                          const GdkColor *color); */
   cairo_rectangle(cr, 0, 0, w, h);
   /* void                cairo_rectangle                     (cairo_t *cr, */
   /*                                                          double x, */
   /*                                                          double y, */
   /*                                                          double width, */
   /*                                                          double height); */
-  cairo_set_source_rgb(cr, 1, 1, 1); /* TODO: consider cairo_set_source_rgba (notice the ending "a" for alpha) */
+  cairo_set_source_rgb(cr, 1, 1, 1);
   cairo_fill(cr);
-  cairo_destroy(cr);
 
   // build text
   GtkWidget *scratch = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@@ -133,29 +131,29 @@ SetIconText(GtkStatusIcon *tray_icon, const char *text, const char *color) {
     pango_layout_set_font_description   (layout, fnt);
     pango_layout_get_pixel_size(layout, &tw, &th);
   }
+  pango_font_description_free (fnt);
   // center text
   int px, py;
   px=(w-tw)/2;
   py=(h-th)/2;
 
   // draw text on pixmap
-  gdk_draw_layout_with_colors (pm, gc, px, py, layout, &fore,NULL);
+  gdk_cairo_set_source_color(cr, &fore);
+  cairo_move_to (cr, px, py);
+  pango_cairo_show_layout (cr, layout);
+  cairo_destroy(cr);
+  g_object_unref (layout);
 
   GdkPixbuf *buf = gdk_pixbuf_get_from_drawable (NULL, pm, NULL, 0, 0, 0, 0, w, h);
   g_object_unref (pm);
-  GdkPixbuf *alpha_buf = gdk_pixbuf_add_alpha  (buf, TRUE, (guchar)alpha.red, (guchar)alpha.green, (guchar)alpha.blue);
-
-  // cleaning
+  GdkPixbuf *alpha_buf = gdk_pixbuf_add_alpha(buf, TRUE, (guchar)alpha.red, (guchar)alpha.green, (guchar)alpha.blue);
   g_object_unref (buf);
-  g_object_unref (layout);
-  pango_font_description_free (fnt);
-  g_object_unref (gc);
-
 
   //merge the rendered text on top
-  gdk_pixbuf_composite (alpha_buf,dest,0,0,w,h,0,0,1,1,GDK_INTERP_NEAREST,255);
+  gdk_pixbuf_composite(alpha_buf,dest,0,0,w,h,0,0,1,1,GDK_INTERP_NEAREST,255);
   g_object_unref(alpha_buf);
-
+  /* gdk_pixbuf_composite(buf,dest,0,0,w,h,0,0,1,1,GDK_INTERP_NEAREST,255); */
+  /* g_object_unref(buf); */
 
   gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(tray_icon), GDK_PIXBUF(dest));
 }
@@ -180,7 +178,7 @@ int main(int argc, char **argv) {
     gtk_widget_show_all (window);
 
     /* TESTING */
-    SetIconText(tray_icon,"F", "#000000");
+    SetIconText(tray_icon,"1", "#000000");
 
         gtk_main();
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firetray.git



More information about the Pkg-mozext-commits mailing list