[Muine] dbus mmkeys + taglib-sharp



Hello,

Here are 2 patches I used when compiling muine from svn (revision
1137) for ubuntu feisty:

muine-mmkeys-dbus.patch: for this one, I borrowed the code from
rhythmbox to make use of dbus when handling multimedia-keys. The old
method doesn't work on my laptop.

muine-taglib-sharp.patch: a very old patch which I updated for the
latest revision. It skips metadata.c from libmuine and uses
tablib-sharp (http://www.taglib-sharp.com/) instead. Muine is even
able to play wma with this :o).

I hope they would help out some other people, even if they could have
some more polish (cleanup, fallback,...).

Keep up the good work and don't let this project die. It is by far the
best music player I've seen.

Vianney le Clément
Index: libmuine/mm-keys.c
===================================================================
--- libmuine/mm-keys.c	(revision 1137)
+++ libmuine/mm-keys.c	(working copy)
@@ -2,6 +2,8 @@
  * Copyright (C) 2004 Lee Willis <lee leewillis co uk>
  *    Borrowed heavily from code by Jan Arne Petersen <jpetersen uni-bonn de>
  *
+ * d-bus handling code taken from Rhythmbox
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of the
@@ -23,16 +25,13 @@
 #include "mm-keys.h"
 #include "macros.h"
 
+//#define log(...) printf(__VA_ARGS__)
+#define log(...)
+
 static void mmkeys_class_init (MmKeysClass *klass);
 static void mmkeys_init       (MmKeys      *object);
 static void mmkeys_finalize   (GObject     *object);
 
-static void grab_mmkey (int key_code, GdkWindow *root);
-
-static GdkFilterReturn filter_mmkeys (GdkXEvent *xevent,
-			              GdkEvent *event,
-			              gpointer data);
-
 enum {
 	MM_PLAYPAUSE,
 	MM_NEXT,
@@ -120,120 +119,120 @@
 	parent_class->finalize (G_OBJECT(object));
 }
 
-#define N_KEYCODES 5
-
 static void
-mmkeys_init (MmKeys *object)
+media_player_key_pressed (DBusGProxy *proxy,
+			  const gchar *application,
+			  const gchar *key,
+			  MmKeys *object)
 {
-	int keycodes[N_KEYCODES];
-	GdkDisplay *display;
-	GdkScreen *screen;
-	GdkWindow *root;
-	guint i, j;
+	log ("got media key '%s' for application '%s'\n",
+		  key, application);
 
-	display = gdk_display_get_default ();
+	if (strcmp (application, "Muine"))
+		return;
 
-	keycodes[0] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev);
-	keycodes[1] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioNext);
-	keycodes[2] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPlay);
-	keycodes[3] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPause);
-	keycodes[4] = XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioStop);
-
-	for (i = 0; i < gdk_display_get_n_screens (display); i++) {
-		screen = gdk_display_get_screen (display, i);
-
-		if (screen != NULL) {
-			root = gdk_screen_get_root_window (screen);
-
-			for (j = 0; j < N_KEYCODES; j++) {
-				if (keycodes[j] > 0)
-					grab_mmkey (keycodes[j], root);
-			}
-
-			gdk_window_add_filter (root, filter_mmkeys, object);
-		}
+	if (strcmp (key, "Play") == 0 || strcmp (key, "Pause") == 0) {
+		g_signal_emit (object, signals[MM_PLAYPAUSE], 0, 0);
+	} else if (strcmp (key, "Stop") == 0) {
+		g_signal_emit (object, signals[MM_STOP], 0, 0);
+	} else if (strcmp (key, "Previous") == 0) {
+		g_signal_emit (object, signals[MM_PREV], 0, 0);
+	} else if (strcmp (key, "Next") == 0) {
+		g_signal_emit (object, signals[MM_NEXT], 0, 0);
 	}
 }
 
-MmKeys *
-mmkeys_new (void)
-{
-	return MMKEYS (g_object_new (TYPE_MMKEYS, NULL));
-}
-
 static void
-grab_mmkey (int key_code, GdkWindow *root)
+marshal_VOID__STRING_STRING (GClosure     *closure,
+                             GValue       *return_value,
+                             guint         n_param_values,
+                             const GValue *param_values,
+                             gpointer      invocation_hint,
+                             gpointer      marshal_data)
 {
-	gdk_error_trap_push ();
+  typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer     data1,
+                                                    gpointer     arg_1,
+                                                    gpointer     arg_2,
+                                                    gpointer     data2);
+  register GMarshalFunc_VOID__STRING_STRING callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
 
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  0,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  Mod2Mask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  Mod5Mask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  LockMask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  Mod2Mask | Mod5Mask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  Mod2Mask | LockMask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  Mod5Mask | LockMask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
-	XGrabKey (GDK_DISPLAY (), key_code,
-		  Mod2Mask | Mod5Mask | LockMask,
-		  GDK_WINDOW_XID (root), True,
-		  GrabModeAsync, GrabModeAsync);
+  g_return_if_fail (n_param_values == 3);
 
-	gdk_flush ();
-	if (gdk_error_trap_pop ()) {
-		fprintf (stderr, "Error grabbing key %d, %p\n", key_code, root);
-	}
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback);
+
+  callback (data1,
+            (char*) g_value_get_string (param_values + 1),
+            (char*) g_value_get_string (param_values + 2),
+            data2);
 }
 
-static GdkFilterReturn
-filter_mmkeys (GdkXEvent *xevent, GdkEvent *UNUSED(event), gpointer data)
+static void
+mmkeys_init (MmKeys *object)
 {
-	XEvent *xev;
-	XKeyEvent *key;
+	DBusGConnection *bus;
+	
+	bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+	if (bus != NULL) {
+		GError *error = NULL;
 
-	xev = (XEvent *) xevent;
-	if (xev->type != KeyPress) {
-		return GDK_FILTER_CONTINUE;
-	}
+		object->proxy = dbus_g_proxy_new_for_name (bus,
+				"org.gnome.SettingsDaemon",
+				"/org/gnome/SettingsDaemon",
+				"org.gnome.SettingsDaemon");
+		if (object->proxy != NULL) {
+			dbus_g_proxy_call (object->proxy,
+					   "GrabMediaPlayerKeys", &error,
+					   G_TYPE_STRING, "Muine",
+					   G_TYPE_UINT, 0,
+					   G_TYPE_INVALID,
+					   G_TYPE_INVALID);
+			if (error == NULL) {
+				log ("created dbus proxy for org.gnome.SettingsDaemon; grabbing keys");
+				dbus_g_object_register_marshaller (marshal_VOID__STRING_STRING,
+						G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 
-	key = (XKeyEvent *) xevent;
+				dbus_g_proxy_add_signal (object->proxy,
+							 "MediaPlayerKeyPressed",
+							 G_TYPE_STRING,G_TYPE_STRING,G_TYPE_INVALID);
 
-	if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPlay) == key->keycode) {
-		g_signal_emit (data, signals[MM_PLAYPAUSE], 0, 0);
-		return GDK_FILTER_REMOVE;
-	} else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPause) == key->keycode) {
-		g_signal_emit (data, signals[MM_PLAYPAUSE], 0, 0);
-		return GDK_FILTER_REMOVE;
-	} else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev) == key->keycode) {
-		g_signal_emit (data, signals[MM_PREV], 0, 0);
-		return GDK_FILTER_REMOVE;
-	} else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioNext) == key->keycode) {
-		g_signal_emit (data, signals[MM_NEXT], 0, 0);
-		return GDK_FILTER_REMOVE;
-	} else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioStop) == key->keycode) {
-		g_signal_emit (data, signals[MM_STOP], 0, 0);
-		return GDK_FILTER_REMOVE;
+				dbus_g_proxy_connect_signal (object->proxy,
+							     "MediaPlayerKeyPressed",
+							     G_CALLBACK (media_player_key_pressed),
+							     object, NULL);
+
+			} else if (error->domain == DBUS_GERROR &&
+				   (error->code != DBUS_GERROR_NAME_HAS_NO_OWNER ||
+				   error->code != DBUS_GERROR_SERVICE_UNKNOWN)) {
+				/* settings daemon dbus service doesn't exist.
+				 * just silently fail.
+				 */
+				log ("org.gnome.SettingsDaemon dbus service not found\n");
+				g_error_free (error);
+			} else {
+				g_warning ("Unable to grab media player keys: %s", error->message);
+				g_error_free (error);
+			}
+		}
 	} else {
-		return GDK_FILTER_CONTINUE;
+		log ("couldn't get dbus session bus\n");
 	}
 }
+
+MmKeys *
+mmkeys_new (void)
+{
+	return MMKEYS (g_object_new (TYPE_MMKEYS, NULL));
+}
+
Index: libmuine/mm-keys.h
===================================================================
--- libmuine/mm-keys.h	(revision 1137)
+++ libmuine/mm-keys.h	(working copy)
@@ -18,10 +18,9 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include <X11/Xlib.h>
-#include <X11/XF86keysym.h>
+#include <string.h>
+#include <dbus/dbus-glib.h>
 #include <gdk/gdk.h>
-#include <gdk/gdkx.h>
 #include <stdio.h>
 #include <gtk/gtktogglebutton.h>
 
@@ -41,6 +40,7 @@
 struct _MmKeys
 {
 	GObject parent;
+	DBusGProxy *proxy;
 };
 
 struct _MmKeysClass
Index: configure.in
===================================================================
--- configure.in	(revision 1137)
+++ configure.in	(working copy)
@@ -26,6 +26,7 @@
 ICON_THEME_REQUIRED=2.10
 MONO_REQUIRED=1.1
 GTKSHARP_REQUIRED=2.6.0
+TAGLIBSHARP_REQUIRED=1.1.0
 MONODOC_REQUIRED=1.1.9
 
 dnl Audio backend stuff
@@ -66,6 +67,9 @@
 		  gconf-sharp-2.0 >= $GTKSHARP_REQUIRED \
 		  gnome-vfs-sharp-2.0 >= $GTKSHARP_REQUIRED)
 
+PKG_CHECK_MODULES(TAGLIBSHARP,
+		  taglib-sharp >= $TAGLIBSHARP_REQUIRED)
+
 dnl external ndesk-dbus
 
 PKG_CHECK_MODULES(DBUS, ndesk-dbus-1.0 >= 0.4 \
Index: src/Metadata.cs
===================================================================
--- src/Metadata.cs	(revision 1137)
+++ src/Metadata.cs	(working copy)
@@ -17,13 +17,10 @@
  * Boston, MA 02111-1307, USA.
  */
 
-using System;
-using System.Runtime.InteropServices;
-using System.Collections;
-
-using Gdk;
-
 using Mono.Unix;
+using TagLib;
+using TagLib.Id3v2;
+using TagLib.Mpeg4;
 
 namespace Muine
 {
@@ -32,234 +29,214 @@
 		// Strings
 		private static readonly string string_error_load =
 			Catalog.GetString ("Failed to load metadata: {0}");
-
-		// Objects
-		private IntPtr raw = IntPtr.Zero;
-		private Pixbuf album_art = null;
-
-		// Constructor
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_load (string filename,
-					                    out IntPtr error_message_return);
-		
+			
+		private TagLib.File file = null;
+		private Gdk.Pixbuf album_art = null;
+		private double peak = 0.0, gain = 0.0;
+		private bool peak_set = false, gain_set = false;
+ 		
+		// Constructor		
 		public Metadata (string filename)
 		{
-			IntPtr error_ptr;
-			
-			raw = metadata_load (filename, out error_ptr);
-
-			if (error_ptr != IntPtr.Zero) {
-				string error = GLib.Marshaller.PtrToStringGFree (error_ptr);
-				throw new Exception (String.Format (string_error_load, error));
-			}
+			file = TagLib.File.Create (filename);
+			if (file == null || file.Tag == null || file.AudioProperties == null)
+				throw new System.Exception (System.String.Format (string_error_load, filename));
 		}
 
 		// Properties
 		// Properties :: Title (get;)
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_title (IntPtr metadata);
-
 		public string Title {
-			get {
-				IntPtr title_ptr = metadata_get_title (raw);
-				
-				string title = "";
-				
-				if (title_ptr != IntPtr.Zero) {
-					string title_tmp = Marshal.PtrToStringAnsi (title_ptr);
-					title = title_tmp.Trim ();
-				}
-				
-				return title;
-			}
+			get { return file.Tag.Title != null ? file.Tag.Title : ""; }
 		}
 
 		// Properties :: Artists (get;)
 		//	FIXME: Refactor Artists and Performers properties
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_artist_count (IntPtr metadata);
-
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_artist
-		  (IntPtr metadata, int index);
-
 		public string [] Artists {
-			get {
-				ArrayList strings = new ArrayList ();
-
-				int count = metadata_get_artist_count (raw);
-
-				for (int i = 0; i < count; i++) {
-					IntPtr artist_ptr = metadata_get_artist (raw, i);
-					string artist = Marshal.PtrToStringAnsi (artist_ptr);
-
-					if (artist == null || artist.Length <= 0)
-						continue;
-
-					strings.Add (artist.Trim());
-				}
-
-				Type string_type = typeof (string);
-				return (string []) strings.ToArray (string_type);
-			}
+			get { return file.Tag.AlbumArtists; }
 		}
 
 		// Properties :: Performers (get;)
 		//	FIXME: Refactor Artists and Performers properties
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_performer
-		  (IntPtr metadata, int index);
-
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_performer_count
-		  (IntPtr metadata);
-
 		public string [] Performers {
-			get {
-				ArrayList strings = new ArrayList ();
-
-				int count = metadata_get_performer_count (raw);
-
-				for (int i = 0; i < count; i++) {
-					IntPtr performer_ptr = metadata_get_performer (raw, i);
-					string performer = Marshal.PtrToStringAnsi (performer_ptr);
-
-					if (performer == null || performer.Length <= 0)
-						continue;
-
-					strings.Add (performer.Trim());
-				}
-
-				Type string_type = typeof (string);
-				return (string []) strings.ToArray (string_type);
-			}			
+			get { return file.Tag.Performers; }
 		}
 
 		// Properties :: Album (get;)
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_album (IntPtr metadata);
-
 		public string Album {
-			get { 
-				IntPtr album_ptr = metadata_get_album (raw);
-				
-				string album;
-				if (album_ptr == IntPtr.Zero) {
-					album = "";
-				} else {
-					string album_tmp = Marshal.PtrToStringAnsi (album_ptr);
-					album = album_tmp.Trim ();
-				}
-				
-				return album;
-			}
+			get { return file.Tag.Album != null ? file.Tag.Album : ""; }
 		}
 
 		// Properties :: AlbumArt (get;)
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_album_art (IntPtr metadata);
+		public Gdk.Pixbuf AlbumArt {
+			get {
+				if (album_art == null) {
+					TagLib.Mpeg4.AppleTag apple_tag = (TagLib.Mpeg4.AppleTag) file.GetTag (TagTypes.Apple);
+					TagLib.Id3v2.Tag id3v2_tag = (TagLib.Id3v2.Tag) file.GetTag (TagTypes.Id3v2);
 
-		public Pixbuf AlbumArt {
-			get { 
-				if (album_art != null)
-					return album_art;
-					
-				IntPtr album_art_ptr = metadata_get_album_art (raw);
+					if (id3v2_tag != null) {
+						// Try to get a cover image first.
+						foreach (AttachedPictureFrame f in id3v2_tag.GetFrames ("APIC")) {
+							if (f.Type == PictureType.FrontCover) {
+								album_art = GetPixbuf (f.Data);
 
-				if (album_art_ptr != IntPtr.Zero)
-					album_art = new Pixbuf (album_art_ptr);
+								if (album_art != null)
+									return album_art;
+							}
+						}
+						
+						// Take any image we can get.
+						foreach (AttachedPictureFrame f in id3v2_tag.GetFrames ("APIC")) {
+							album_art = GetPixbuf (f.Data);
 
+							if (album_art != null)
+								return album_art;
+						}
+					}
+
+					if (apple_tag != null) {
+						foreach (AppleDataBox b in apple_tag.DataBoxes ("covr")) {
+							if (b.Flags == (uint) AppleDataBox.FlagTypes.ContainsJpegData ||
+							    b.Flags == (uint) AppleDataBox.FlagTypes.ContainsPngData) {
+								album_art = GetPixbuf (b.Data);
+
+								if (album_art != null)
+									return album_art;
+							}
+						}
+					}
+				}
 				return album_art;
 			}
 		}
 
 		// Properties :: TrackNumber (get;)
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_track_number (IntPtr metadata);
-		
 		public int TrackNumber {
-			get { return metadata_get_track_number (raw); }
+			get { return (int) file.Tag.Track; }
 		}
 
 		// Properties :: TotalTracks (get;)
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_total_tracks (IntPtr metadata);
-		
 		public int TotalTracks {
-			get { return metadata_get_total_tracks (raw); }
+			get { return (int) file.Tag.TrackCount; }
 		}
 
 		// Properties :: DiscNumber (get;)
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_disc_number (IntPtr metadata);
-
 		public int DiscNumber {
-			get { return metadata_get_disc_number (raw); }
+			get { return (int) file.Tag.Disc; }
 		}
 
 		// Properties :: Year (get;)
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_year (IntPtr metadata);
-
 		public string Year {
-			get {
-				IntPtr year_ptr = metadata_get_year (raw);
-				
-				string year = "";
-				
-				if (year_ptr != IntPtr.Zero)
-					year = Marshal.PtrToStringAnsi (year_ptr);
-				
-				return year;
-			}
+			get { return file.Tag.Year.ToString ();}
 		}
 
 		// Properties :: Duration (get;)
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_duration (IntPtr metadata);
-
 		public int Duration {
-			get { return metadata_get_duration (raw); }
+			get { return file.AudioProperties.Length; }
 		}
 
 		// Properties :: MimeType (get;)
-		[DllImport ("libmuine")]
-		private static extern IntPtr metadata_get_mime_type (IntPtr metadata);
-
 		public string MimeType {
-			get {
-				IntPtr type_ptr = metadata_get_mime_type (raw);
-				
-				string type = "";
-				if (type_ptr != IntPtr.Zero)
-					Marshal.PtrToStringAnsi (type_ptr);
-				
-				return type;
-			}
+			get { return file.MimeType != null ? file.MimeType : ""; }
 		}
 
 		// Properties :: MTime (get;)
-		[DllImport ("libmuine")]
-		private static extern int metadata_get_mtime (IntPtr metadata);
-
 		public int MTime {
-			get { return metadata_get_mtime (raw); }
+			get {
+				Mono.Unix.Native.Stat buf;
+				Mono.Unix.Native.Syscall.stat (file.Name, out buf);
+				return (int) buf.st_mtime;
+			}
 		}
 
 		// Properties :: Gain (get;)
-		[DllImport ("libmuine")]
-		private static extern double metadata_get_gain (IntPtr metadata);
-
 		public double Gain {
-			get { return metadata_get_gain (raw); }
+			get {
+				if (!gain_set)
+				{
+					gain_set = true;
+					
+					TagLib.Ogg.XiphComment xiph_comment = (TagLib.Ogg.XiphComment) file.GetTag (TagTypes.Xiph);
+					TagLib.Id3v2.Tag id3v2_tag = (TagLib.Id3v2.Tag) file.GetTag (TagTypes.Id3v2);
+
+					if (id3v2_tag != null) {
+						foreach (RelativeVolumeFrame f in id3v2_tag.GetFrames ("RVA2")) {
+							gain = f.VolumeAdjustment (ChannelType.MasterVolume);
+							return gain;
+						}
+					}
+
+					if (xiph_comment != null) {
+						string [] names = {"replaygain_track_gain", "replaygain_album_gain", "rg_audiophile", "rg_radio"};
+						foreach (string name in names) {
+							StringList l = xiph_comment.GetField (name);
+							if (l != null && l.Count != 0)
+								foreach (string s in l)
+									try {
+										gain = System.Double.Parse (s);
+										return gain;
+									} catch {}
+						}
+					}
+				}
+				
+				return gain;
+			}
 		}
 
 		// Properties :: Peak (get;)
-		[DllImport ("libmuine")]
-		private static extern double metadata_get_peak (IntPtr metadata);
-		
 		public double Peak {
-			get { return metadata_get_peak (raw); }
+			get {
+				if (!peak_set)
+				{
+					peak_set = true;
+					
+					TagLib.Ogg.XiphComment xiph_comment = (TagLib.Ogg.XiphComment) file.GetTag (TagTypes.Xiph);
+					TagLib.Id3v2.Tag id3v2_tag = (TagLib.Id3v2.Tag) file.GetTag (TagTypes.Id3v2);
+
+					if (id3v2_tag != null) {
+						foreach (RelativeVolumeFrame f in id3v2_tag.GetFrames ("RVA2")) {
+							peak = f.PeakVolume (ChannelType.MasterVolume);
+							return peak;
+						}
+					}
+
+					if (xiph_comment != null) {
+						string [] names = {"replaygain_track_peak", "replaygain_album_peak", "rg_peak"};
+						foreach (string name in names) {
+							StringList l = xiph_comment.GetField (name);
+							if (l != null && l.Count != 0)
+								foreach (string s in l)
+									try {
+										peak = System.Double.Parse (s);
+										return peak;
+									} catch {}
+						}
+					}
+				}
+				
+				return peak;
+			}
 		}
+		
+		private Gdk.Pixbuf GetPixbuf (ByteVector data)
+		{
+			bool bail = false;
+			Gdk.Pixbuf output;
+			Gdk.PixbufLoader loader = new Gdk.PixbufLoader ();
+			
+			try {
+				if (!loader.Write (data.Data))
+					bail = true;
+			} catch {bail = true;}
+
+			try {
+				if (!loader.Close ())
+					bail = true;
+			} catch {bail = true;}
+
+			output = (!bail) ? loader.Pixbuf : null;
+
+			return output;
+		}
 	}
 }
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 1137)
+++ src/Makefile.am	(working copy)
@@ -107,7 +107,7 @@
 	    < $^ > $@
 
 $(TARGET): $(MUINE_CSFILES) $(MUINE_GENERATED_CSFILES) $(top_builddir)/PluginLib/muine-plugin.dll $(top_builddir)/DBusLib/muine-dbus.dll
-	$(CSC) -out:$@ $(MUINE_CSFILES) $(MUINE_GENERATED_CSFILES) $(MUINE_ASSEMBLIES) $(MUINE_RESOURCES) $(GTKSHARP_LIBS)
+	$(CSC) -out:$@ $(MUINE_CSFILES) $(MUINE_GENERATED_CSFILES) $(MUINE_ASSEMBLIES) $(MUINE_RESOURCES) $(GTKSHARP_LIBS) $(TAGLIBSHARP_LIBS)
 
 all: $(TARGET)
 


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