--- notify/osd.c	2012-09-23 15:05:12.000000000 +0200
+++ notify2/osd.c	2012-11-10 00:34:12.053287913 +0100
@@ -1,4 +1,4 @@
-/*
+    /*
  * osd.c
  *
  * Copyright (C) 2010 Maximilian Bogner <max@mbogner.de>
@@ -19,21 +19,70 @@
 
 #include <glib.h>
 #include <audacious/debug.h>
+//#define AUDDBG(...) do {printf ("%s:%d %s(): ", __FILE__, __LINE__, __FUNCTION__); printf (__VA_ARGS__);} while (0)
 #include <libnotify/notify.h>
+#include <audacious/playlist.h>
+#include <audacious/drct.h>
+#include <libaudgui/libaudgui-gtk.h>
+#include <audacious/i18n.h>
+#include <audacious/misc.h>
 
 #include "osd.h"
 
 NotifyNotification *notification = NULL;
+gboolean notify_supports_actions = FALSE;
+gboolean notify_supports_icon_buttons = FALSE;
+gboolean notify_supports_persistence = FALSE;
 
 gboolean osd_init() {
     notification = NULL;
-    return notify_init ("Audacious");
+    if (notify_is_initted () == FALSE) {
+        GList *caps;
+
+        if (notify_init ("Audacious") == FALSE) {
+            g_warning ("libnotify initialization failed");
+            return FALSE;
+        }
+
+        /* ask the notification server if it supports actions */
+        caps = notify_get_server_caps ();
+        if (g_list_find_custom (caps, "actions", (GCompareFunc)g_strcmp0) != NULL) {
+            AUDDBG("notification server supports actions\n");
+            notify_supports_actions = TRUE;
+
+            if (g_list_find_custom (caps, "action-icons", (GCompareFunc)g_strcmp0) != NULL) {
+                AUDDBG("notifiction server supports icon buttons\n");
+                notify_supports_icon_buttons = TRUE;
+            }
+        } else {
+            AUDDBG("notification server does not support actions\n");
+        }
+        if (g_list_find_custom (caps, "persistence", (GCompareFunc)g_strcmp0) != NULL) {
+            AUDDBG("notification server supports persistence\n");
+            notify_supports_persistence = TRUE;
+        } else {
+            AUDDBG("notification server does not support persistence\n");
+        }
+        g_list_free_full(caps, g_free);
+        
+    }
+    AUDDBG("notification created\n");
+    notification = notify_notification_new ("Notification", NULL, "audacious");
+    return TRUE;
 }
 
 void osd_uninit (void)
 {
     if (notification)
     {
+        notify_notification_clear_hints(notification);
+        notify_notification_clear_actions(notification);
+        GError *error = NULL;
+        if (notify_notification_close(notification, &error) == FALSE)
+        {
+            AUDDBG("Failed to close notification : %s", error->message);
+            g_error_free (error);
+        }
         g_object_unref (notification);
         notification = NULL;
     }
@@ -41,37 +90,168 @@
     notify_uninit();
 }
 
-void osd_closed_handler(NotifyNotification *notification2, gpointer data) {
-    if(notification != NULL) {
-        g_object_unref(notification);
-        notification = NULL;
-        AUDDBG("notification unrefed!\n");
-    }
+static void
+goprevious (NotifyNotification *notification,
+            const char *action,
+            gpointer user_data)
+{
+    aud_drct_pl_prev();
+}
+
+static void
+gonext (NotifyNotification *notification,
+        const char *action,
+        gpointer user_data)
+{
+    aud_drct_pl_next();
 }
 
-void osd_show (const gchar * title, const gchar * _message, const gchar * icon,
- GdkPixbuf * pb)
+static void
+playpause (NotifyNotification *notification,
+           const char *action,
+           gpointer user_data)
+{
+    if(aud_drct_get_playing())
+    {aud_drct_pause();}
+    else
+    {aud_drct_play();}
+}
+
+static void
+show (NotifyNotification *notification,
+        const char *action,
+        gpointer user_data)
+{
+    aud_interface_show(TRUE);
+}
+
+static void
+do_notify (guint timeout,
+       const char *primary,
+       const char *secondary,
+       GdkPixbuf * pb)
 {
-    gchar * message = g_markup_escape_text (_message, -1);
     GError *error = NULL;
+    
+    if ( !(notify_is_initted() && (notification != NULL))) {return;}
+
+    if (primary == NULL)
+        primary = "";
+
+    if (secondary == NULL)
+        secondary = "";
+
+    notify_notification_clear_hints (notification);
+    notify_notification_update (notification, primary, secondary, "audacious");
+    notify_notification_set_timeout (notification, timeout);
+
+    if (pb != NULL) {
+        notify_notification_clear_hints (notification);
+/*        notify_notification_set_image_from_pixbuf(notification,pb);*/
+    }
+/*    notify_notification_set_hint (notification,*/
+/*                      "image_path",*/
+/*                      g_variant_new_string ("/home/oxayotl/.cache/rhythmbox/album-art/00000065"));*/
+
+    notify_notification_clear_actions (notification);
+    if (notify_supports_actions) {
+        if (notify_supports_icon_buttons) {
+            gboolean playing = FALSE;
+            if (aud_drct_get_playing()) {playing = !aud_drct_get_paused();}
+
+            notify_notification_add_action (notification,
+                            "media-skip-backward",
+                            N_("Previous"),
+                            (NotifyActionCallback) goprevious,
+                            NULL,
+                            NULL);
+            notify_notification_add_action (notification,
+                            playing ? "media-playback-pause" : "media-playback-start",
+                            playing ? N_("Pause") : N_("Play"),
+                            (NotifyActionCallback) playpause,
+                            NULL,
+                            NULL);
+            notify_notification_set_hint (notification, "action-icons", g_variant_new_boolean (TRUE));
+        }
+
+        notify_notification_add_action (notification,
+                        "media-skip-forward",
+                        N_("Next"),
+                        (NotifyActionCallback) gonext,
+                        NULL,
+                        NULL);
+        notify_notification_add_action (notification,
+                        "default",
+                        N_("Afficher Audacious"),
+                        (NotifyActionCallback) show,
+                        NULL,
+                        NULL);
+    }
 
-    if(notification == NULL) {
-        notification = notify_notification_new(title, message, pb == NULL ? icon : NULL);
-        g_signal_connect(notification, "closed", G_CALLBACK(osd_closed_handler), NULL);
-        AUDDBG("new osd created! (notification=%p)\n", (void *) notification);
-    } else {
-        if(notify_notification_update(notification, title, message, pb == NULL ? icon : NULL)) {
-            AUDDBG("old osd updated! (notification=%p)\n", (void *) notification);
+    if (notify_supports_persistence) {
+        const char *hint;
+
+        if (aud_drct_get_playing()) {
+            hint = "resident";
         } else {
-            AUDDBG("could not update old osd! (notification=%p)\n", (void *) notification);
+            hint = "transient";
         }
+        notify_notification_set_hint (notification, hint, g_variant_new_boolean (TRUE));
     }
+        if (notify_notification_show (notification, &error) == FALSE) {
+            AUDDBG("Failed to send notification (%s): %s", primary, error->message);
+            g_error_free (error);
+            return;
+        }
+}
+   
+void osd_show ()
+{
+    gchar * title;
+
+    if (aud_drct_get_playing())
+    {
+        gint list = aud_playlist_get_playing ();
+        gint entry = aud_playlist_get_position (list);
+
+        gchar * artist, * album, * message;
+        GdkPixbuf * pb;
 
-    if(pb != NULL)
-        notify_notification_set_icon_from_pixbuf(notification, pb);
+        aud_playlist_entry_describe (list, entry, & title, & artist, & album, FALSE);
 
-    if(!notify_notification_show(notification, &error))
-        AUDDBG("%s!\n", error->message);
+        if (!title){ title = g_strdup_printf (N_("Unknown track"));};
+        if (artist)
+        {
+            if (album)
+                message = g_strdup_printf ("%s\n%s", artist, album);
+            else
+                message = g_strdup (artist);
+        }
+        else if (album)
+            message = g_strdup (album);
+        else
+            message = g_strdup ("");
+
+        pb = audgui_pixbuf_for_current ();
+        if (pb)
+            audgui_pixbuf_scale_within (& pb, 128);
+
+        do_notify (NOTIFY_EXPIRES_DEFAULT, title, message, pb);
+
+        if (pb)
+            g_object_unref (pb);
+        if (message) 
+            g_free (message);
+        str_unref (title);
+        str_unref (artist);
+        str_unref (album);
+    }
+    
+    else
+    {
+        title = g_strdup (N_("Not playing"));
+        do_notify (NOTIFY_EXPIRES_DEFAULT, title, NULL, NULL);
+        g_free (title);
+    }
 
-    g_free (message);
 }
