[maemo-commits] [maemo-commits] r11446 - in projects/haf/trunk/hildon-desktop: . libhildondesktop src

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Fri May 4 15:24:32 EEST 2007
Author: lucasr
Date: 2007-05-04 15:24:30 +0300 (Fri, 04 May 2007)
New Revision: 11446

Modified:
   projects/haf/trunk/hildon-desktop/ChangeLog
   projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c
   projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h
   projects/haf/trunk/hildon-desktop/libhildondesktop/notification-manager.xml
   projects/haf/trunk/hildon-desktop/src/hd-desktop.c
Log:
2007-05-04  Lucas Rocha  <lucas.rocha at nokia.com>

	* libhildondesktop/hildon-desktop-notification-manager.[ch]: several
	code cleanups and crasher fixes. Added "notification-closed" signal.
	* src/hd-desktop: implemented system notifications support in the
	desktop. Notification manager is used as backend.


Modified: projects/haf/trunk/hildon-desktop/ChangeLog
===================================================================
--- projects/haf/trunk/hildon-desktop/ChangeLog	2007-05-04 12:05:33 UTC (rev 11445)
+++ projects/haf/trunk/hildon-desktop/ChangeLog	2007-05-04 12:24:30 UTC (rev 11446)
@@ -1,3 +1,10 @@
+2007-05-04  Lucas Rocha  <lucas.rocha at nokia.com>
+
+	* libhildondesktop/hildon-desktop-notification-manager.[ch]: several
+	code cleanups and crasher fixes. Added "notification-closed" signal.
+	* src/hd-desktop: implemented system notifications support in the
+	desktop. Notification manager is used as backend.
+
 2007-05-04  Moises Martinez  <moises.martinez at nokia.com>
 
 	* src/hd-switcher-menu.[ch]:

Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c	2007-05-04 12:05:33 UTC (rev 11445)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.c	2007-05-04 12:24:30 UTC (rev 11446)
@@ -31,6 +31,7 @@
 #include "hildon-desktop-notification-service.h"
 
 #include <string.h>
+#include <gtk/gtk.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
 #define HILDON_DESKTOP_NOTIFICATION_MANAGER_GET_PRIVATE(object) \
@@ -38,6 +39,13 @@
 
 G_DEFINE_TYPE (HildonDesktopNotificationManager, hildon_desktop_notification_manager, GTK_TYPE_LIST_STORE);
 
+enum {
+  SIGNAL_NOTIFICATION_CLOSED,
+  N_SIGNALS
+};
+
+static gint signals[N_SIGNALS];  
+
 #define HILDON_DESKTOP_NOTIFICATION_MANAGER_DBUS_NAME  "org.freedesktop.Notifications" 
 #define HILDON_DESKTOP_NOTIFICATION_MANAGER_DBUS_PATH  "/org/freedesktop/Notifications"
 
@@ -123,10 +131,21 @@
 static void
 hildon_desktop_notification_manager_class_init (HildonDesktopNotificationManagerClass *class)
 {
+  GObjectClass *g_object_class = (GObjectClass *) class;
+
+  signals[SIGNAL_NOTIFICATION_CLOSED] =
+        g_signal_new ("notification-closed",
+                      G_OBJECT_CLASS_TYPE (g_object_class),
+                      G_SIGNAL_RUN_FIRST,
+		      G_STRUCT_OFFSET (HildonDesktopNotificationManagerClass, notification_closed),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__INT,
+                      G_TYPE_NONE, 1, G_TYPE_INT);
+
   g_type_class_add_private (class, sizeof (HildonDesktopNotificationManagerPrivate));
 }
 
-static gboolean 
+gboolean 
 hildon_desktop_notification_manager_find_by_id (HildonDesktopNotificationManager *nm,
 						guint id, 
 					        GtkTreeIter *return_iter)
@@ -156,19 +175,12 @@
 
 static DBusMessage *
 hildon_desktop_notification_manager_create_signal (HildonDesktopNotificationManager *nm, 
-		                                   GtkTreeIter                      *iter, 
-						   const char                       *signal_name)
+		                                   guint id,
+						   const gchar *dest, 
+						   const gchar *signal_name)
 {
   DBusMessage *message;
-  gchar *dest;
-  gint id;
   
-  gtk_tree_model_get (GTK_TREE_MODEL (nm),
-                      iter,
-                      HD_NM_COL_SENDER, &dest,
-                      HD_NM_COL_ID, &id,
-                      -1);
-
   g_assert(dest != NULL);
 
   message = dbus_message_new_signal ("/org/freedesktop/Notifications",
@@ -181,25 +193,21 @@
                             DBUS_TYPE_UINT32, &id,
                             DBUS_TYPE_INVALID);
 
-  g_free (dest);
-  
   return message;
 }
 
 static void
 hildon_desktop_notification_manager_notification_closed (HildonDesktopNotificationManager *nm,
-		                                         GtkTreeIter *iter)
+		                                         guint id,
+							 const gchar *dest)
 {
   DBusMessage *message;
-  gint id;
   
-  gtk_tree_model_get (GTK_TREE_MODEL (nm), 
-                      iter,
-                      HD_NM_COL_ID, &id,
-                      -1);
+  message = hildon_desktop_notification_manager_create_signal (nm, 
+		  					       id, 
+							       dest, 
+							       "NotificationClosed");
 
-  message = hildon_desktop_notification_manager_create_signal (nm, iter, "NotificationClosed");
-
   if (message == NULL) return;
 
   dbus_connection_send (dbus_g_connection_get_connection (nm->priv->connection), 
@@ -207,6 +215,8 @@
 			NULL);
 
   dbus_message_unref (message);
+
+  g_signal_emit (nm, signals[SIGNAL_NOTIFICATION_CLOSED], 0, id);
 }
 
 static gboolean 
@@ -215,7 +225,8 @@
   GtkListStore *nm = 
      hildon_desktop_notification_manager_get_singleton ();
   GtkTreeIter iter;
-
+  gchar *dest;
+  
   if (!hildon_desktop_notification_manager_find_by_id (HILDON_DESKTOP_NOTIFICATION_MANAGER (nm), 
 			  			       id, 
 						       &iter))
@@ -223,12 +234,20 @@
     return FALSE;
   }
 
+  gtk_tree_model_get (GTK_TREE_MODEL (nm),
+      	        &iter,
+      		HD_NM_COL_SENDER, &dest,
+      		-1);
+  
   /* Notify the client */
   hildon_desktop_notification_manager_notification_closed (HILDON_DESKTOP_NOTIFICATION_MANAGER (nm), 
-		  					   &iter);
+		  					   id,
+							   dest);
  
   gtk_list_store_remove (nm, &iter);
 
+  g_free (dest);
+
   return FALSE;
 }
 
@@ -384,7 +403,38 @@
   return TRUE;
 }
 
+#if 0
 gboolean
+hildon_desktop_notification_manager_system_infoprint (HildonDesktopNotificationManager *nm,
+						      gchar *message,
+                                                      DBusGMethodInvocation *context)
+{
+  GHashTable *hints;
+
+  hints = 
+                                            const gchar           *app_name,
+                                            guint                  id,
+                                            const gchar           *icon,
+                                            const gchar           *summary,
+                                            const gchar           *body,
+                                            gchar                **actions,
+                                            GHashTable            *hints,
+                                            gint                   timeout, 
+
+  return TRUE;
+}
+
+gboolean
+hildon_desktop_notification_manager_system_dialog (HildonDesktopNotificationManager *nm,
+						   gchar *message,
+						   guint32 type
+                                                   DBusGMethodInvocation *context)
+{
+  return TRUE;
+}
+#endif
+
+gboolean
 hildon_desktop_notification_manager_get_capabilities  (HildonDesktopNotificationManager *nm, gchar ***caps)
 {
   *caps = g_new0 (gchar *, 4);
@@ -418,13 +468,15 @@
                                                     	GError               **error)
 {
   GtkTreeIter iter;
+  gchar *dest;
   gboolean removable = TRUE;
-
+  
   if (hildon_desktop_notification_manager_find_by_id (nm, id, &iter))
   {
     gtk_tree_model_get (GTK_TREE_MODEL (nm),
 		        &iter,
 			HD_NM_COL_REMOVABLE, &removable,
+			HD_NM_COL_SENDER, &dest,
 			-1);
 
     /* libnotify call close_notification_handler when updating a row 
@@ -439,11 +491,13 @@
     else
     {
       /* Notify the client */
-      hildon_desktop_notification_manager_notification_closed (nm, &iter);
+      hildon_desktop_notification_manager_notification_closed (nm, id, dest);
 
       gtk_list_store_remove (GTK_LIST_STORE (nm), &iter);
     }
-      
+
+    g_free (dest);
+    
     return TRUE;    
   }
   else
@@ -583,19 +637,28 @@
 				                 const gchar                      *action_id)
 {
   DBusMessage *message = NULL;
-  GHashTable *hints; 
+  GHashTable *hints = NULL; 
   GtkTreeIter iter;
+  GValue *dbus_cb;
+  gchar *dest = NULL;
+  gchar *hint;
 
-  if (hildon_desktop_notification_manager_find_by_id (nm, id, &iter))
+  g_return_if_fail (nm != NULL);
+  g_return_if_fail (HILDON_DESKTOP_IS_NOTIFICATION_MANAGER (nm));
+  
+  if (!hildon_desktop_notification_manager_find_by_id (nm, id, &iter))
   {
-    GValue *dbus_cb;
-    gchar *hint;
-    
-    gtk_tree_model_get (GTK_TREE_MODEL (nm),
-                        &iter,
-                        HD_NM_COL_HINTS, &hints,
-                        -1);
+    return;
+  }
 
+  gtk_tree_model_get (GTK_TREE_MODEL (nm),
+                      &iter,
+                      HD_NM_COL_HINTS, &hints,
+                      HD_NM_COL_SENDER, &dest,
+                      -1);
+
+  if (hints != NULL)
+  {  
     hint = g_strconcat ("dbus-callback-", action_id, NULL);
     
     dbus_cb = (GValue *) g_hash_table_lookup (hints, hint);
@@ -612,21 +675,29 @@
       		            message, 
       		            NULL);
     }
-
+  
     g_free (hint);
   }
 
-  message = hildon_desktop_notification_manager_create_signal (nm, &iter, "ActionInvoked");
+  if (dest != NULL)
+  {
+    message = hildon_desktop_notification_manager_create_signal (nm, 
+		    						 id, 
+								 dest, 
+								 "ActionInvoked");
 
-  g_assert (message != NULL);
+    g_assert (message != NULL);
 
-  dbus_message_append_args (message,
-                            DBUS_TYPE_STRING, &action_id,
-                            DBUS_TYPE_INVALID);
+    dbus_message_append_args (message,
+                              DBUS_TYPE_STRING, &action_id,
+                              DBUS_TYPE_INVALID);
 
-  dbus_connection_send (dbus_g_connection_get_connection (nm->priv->connection), 
-		        message, 
-			NULL);
-  
-  dbus_message_unref (message);
+    dbus_connection_send (dbus_g_connection_get_connection (nm->priv->connection), 
+          	          message, 
+          		  NULL);
+    
+    dbus_message_unref (message);
+    
+    g_free (dest);
+  }
 }

Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h	2007-05-04 12:05:33 UTC (rev 11445)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/hildon-desktop-notification-manager.h	2007-05-04 12:24:30 UTC (rev 11446)
@@ -73,6 +73,9 @@
 struct _HildonDesktopNotificationManagerClass 
 {
   GtkListStoreClass parent_class;
+
+  void     *(*notification_closed)    (HildonDesktopNotificationManager *nm,
+		                       gint id);
 };
 
 GType      hildon_desktop_notification_manager_get_type           (void);
@@ -103,6 +106,10 @@
                                                                    guint id, 
 								   GError **error);
 
+gboolean   hildon_desktop_notification_manager_find_by_id         (HildonDesktopNotificationManager *nm,
+		 						   guint id,
+								   GtkTreeIter *return_iter);
+
 void       hildon_desktop_notification_manager_call_action        (HildonDesktopNotificationManager *nm,
                                                                    guint                  id,
 								   const gchar           *action_id);

Modified: projects/haf/trunk/hildon-desktop/libhildondesktop/notification-manager.xml
===================================================================
--- projects/haf/trunk/hildon-desktop/libhildondesktop/notification-manager.xml	2007-05-04 12:05:33 UTC (rev 11445)
+++ projects/haf/trunk/hildon-desktop/libhildondesktop/notification-manager.xml	2007-05-04 12:24:30 UTC (rev 11446)
@@ -28,6 +28,25 @@
       <arg type="u" name="id" direction="in" />
     </method>
 
+    <!--
+    <method name="SystemNoteInfoprint">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="hildon_desktop_notification_manager_system_note_infoprint"/>
+
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+
+      <arg type="s" name="message" direction="in" />
+      <arg type="u" name="return_id" direction="out" />
+    </method>
+
+    <method name="SystemNoteDialog">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="hildon_desktop_notification_manager_system_note_dialog"/>
+
+      <arg type="s" name="message" direction="in" />
+      <arg type="u" name="type" direction="in" />
+      <arg type="u" name="return_id" direction="out" />
+    </method>
+    -->
+    
     <method name="GetCapabilities">
       <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="hildon_desktop_notification_manager_get_capabilities"/>
 

Modified: projects/haf/trunk/hildon-desktop/src/hd-desktop.c
===================================================================
--- projects/haf/trunk/hildon-desktop/src/hd-desktop.c	2007-05-04 12:05:33 UTC (rev 11445)
+++ projects/haf/trunk/hildon-desktop/src/hd-desktop.c	2007-05-04 12:24:30 UTC (rev 11446)
@@ -43,6 +43,7 @@
 #include <libhildondesktop/hildon-desktop-notification-manager.h>
 
 #include <hildon/hildon-banner.h>
+#include <hildon/hildon-note.h>
 
 #include "hd-desktop.h"
 #include "hd-select-plugins-dialog.h"
@@ -79,14 +80,22 @@
   GnomeVFSMonitorHandle  *plugin_dir_monitor;
 } HDDesktopContainerInfo;
 
+typedef struct
+{
+  guint      id;
+  HDDesktop *desktop;
+} HDDesktopNotificationInfo;
+
 struct _HDDesktopPrivate 
 {
   gchar                 *config_file;
   GnomeVFSMonitorHandle *system_conf_monitor;
   GnomeVFSMonitorHandle *user_conf_monitor;
   GHashTable            *containers;
+  GHashTable            *notifications;
+  GQueue                *dialog_queue;
   GObject               *pm;
-  GtkListStore          *nm;
+  GtkTreeModel          *nm;
 #ifdef HAVE_LIBOSSO
   osso_context_t  *osso_context;
 #endif
@@ -121,7 +130,7 @@
   lapp_name = hd_wm_watchable_app_get_localized_name (app);
 
   info->msg = 
-    g_strdup_printf (_(hd_wm_watchable_app_is_hibernating(app) ?
+    g_strdup_printf (_(hd_wm_watchable_app_is_hibernating (app) ?
                      APP_LAUNCH_BANNER_MSG_RESUMING :
                      APP_LAUNCH_BANNER_MSG_LOADING),
                      lapp_name ? _(lapp_name) : "" );
@@ -152,7 +161,7 @@
   t2 = (long unsigned int) current_time.tv_sec;
   time_left = (guint) (t2 - t1);
 
-  if (time_left >= current_banner_timeout+4)/* ||
+  if (time_left >= current_banner_timeout + 4)/* ||
       hd_wm_watchable_app_has_windows (info->app))*/
   {
     hd_desktop_launch_banner_close (NULL, info);
@@ -648,6 +657,297 @@
                           user_data);
 }
 
+#if 0
+#ifdef HAVE_LIBOSSO
+static gint 
+hildon_desktop_rpc_cb (const gchar *interface,
+                       const gchar *method,
+                       GArray *arguments,
+                       gpointer data,
+                       osso_rpc_t *retval)
+{
+  HDDesktop *desktop;
+  osso_rpc_t *val[5];
+  gint i;
+
+  if (!interface || !method || !arguments || !data) 
+  {
+    return OSSO_ERROR;
+  }
+
+  desktop = (HDDesktop *) data;
+
+  for (i = 0; i < arguments->len; ++i) 
+  {
+    val[i] = &g_array_index (arguments, osso_rpc_t, i);
+  }
+
+  if (g_str_equal("system_note_infoprint", method))
+  {
+    if (arguments->len < 1 || val[0]->type != DBUS_TYPE_STRING ) 
+    {
+      if (arguments->len < 1) 
+      {
+        retval->value.s = g_strdup ("Not enough args to infoprint");
+      } 
+      else 
+      {
+        g_sprintf (retval->value.s,
+                   "Wrong type param to infoprint (%d)", val[0]->type);
+      }
+
+      g_warning (retval->value.s);
+
+      return OSSO_ERROR;
+    }
+
+    hildon_banner_show_information( NULL, NULL, val[0]->value.s);
+  }
+  else if (g_str_equal ("system_note_dialog", method))
+  {
+    if (arguments->len < 2 ||
+        val[0]->type != DBUS_TYPE_STRING ||
+        val[1]->type != DBUS_TYPE_INT32 ) 
+    {
+      if (arguments->len < 2) 
+      {
+        retval->value.s = "Not enough args to dialog";
+      } 
+      else 
+      {
+        retval->value.s = "Wrong type of arguments to dialog";
+      }
+
+      g_warning (retval->value.s);
+
+      return OSSO_ERROR;
+    }
+
+    hildon_status_bar_lib_prepare_dialog (val[1]->value.i, 
+                                          NULL,
+                                          val[0]->value.s,  
+                                          0, 
+                                          NULL, 
+                                          NULL);
+  }
+  else if (g_str_equal ("open_closeable_system_dialog", method))
+  {
+    gint id;
+    const gchar *btext = NULL;
+
+    if (arguments->len < 4 ||
+        val[0]->type != DBUS_TYPE_STRING ||
+        val[1]->type != DBUS_TYPE_INT32 ||
+        val[2]->type != DBUS_TYPE_STRING ||
+        val[3]->type != DBUS_TYPE_BOOLEAN)
+    {
+      retval->type = DBUS_TYPE_STRING;
+
+      if (arguments->len < 4) 
+      {
+        retval->value.s = g_strdup ("Not enough args to dialog");
+      } 
+      else 
+      {
+        retval->value.s = g_strdup ("Wrong type of arguments to dialog");
+      }
+
+      g_warning (retval->value.s);
+
+      return OSSO_ERROR;
+    }
+
+    if ((val[2]->value.s)[0] != '\0')
+    {
+      btext = val[2]->value.s;
+    }
+
+    id = hildon_status_bar_lib_open_closeable_dialog (val[1]->value.i,
+                                                      val[0]->value.s, 
+                                                      btext, 
+                                                      val[0]->value.b);
+
+    retval->type = DBUS_TYPE_INT32;
+    retval->value.i = id;
+  }
+  else if (g_str_equal ("close_closeable_system_dialog", method))
+  {
+    /* The id of the dialog is given as argument */
+    if (arguments->len < 1 || val[0]->type != DBUS_TYPE_INT32)
+    {
+      retval->type = DBUS_TYPE_STRING;
+
+      if (arguments->len < 1) 
+      {
+        retval->value.s = g_strdup ("Not enough args to dialog");
+      } 
+      else 
+      {
+        retval->value.s = g_strdup ("Argument has invalid type");
+      }
+
+      g_warning (retval->value.s);
+
+      return OSSO_ERROR;
+    }
+
+    hildon_status_bar_lib_close_closeable_dialog (val[0]->value.i);
+  }
+  else if (g_str_equal( "get_system_dialog_response", method))
+  {
+    gint response = -1;
+
+    /* The id of the dialog is given as argument */
+    if (arguments->len < 1 || val[0]->type != DBUS_TYPE_INT32)
+    {
+      retval->type = DBUS_TYPE_STRING;
+
+      if (arguments->len < 1) 
+      {
+        retval->value.s = g_strdup ("Not enough args to dialog");
+      } 
+      else 
+      {
+        retval->value.s = g_strdup ("Argument has invalid type");
+      }
+
+      g_warning (retval->value.s);
+
+      return OSSO_ERROR;
+    }
+
+    response = hildon_status_bar_lib_get_dialog_response (val[0]->value.i);
+
+    retval->type = DBUS_TYPE_INT32;
+    retval->value.i = response;
+  }
+  else if (g_str_equal ("delayed_infobanner", method))
+  {
+      gint parent_window_id = 0;
+
+      if (arguments->len < 4 ||
+          arguments->len > 5 ||
+          val[0]->type != DBUS_TYPE_INT32 ||
+          val[1]->type != DBUS_TYPE_INT32 ||
+          val[2]->type != DBUS_TYPE_INT32 ||
+          val[3]->type != DBUS_TYPE_STRING ||
+          (arguments->len == 5 && val[4]->type != DBUS_TYPE_INT32))
+      {
+        if (arguments->len < 4) 
+        {
+          retval->value.s = "Not enough arguments.";
+        } 
+        else 
+        {
+          g_sprintf (retval->value.s, "Wrong type of arguments: "
+                     "(%d,%d,%d,%d); was expecting (%d, %d, %d and %d)",
+                     val[0]->type, val[1]->type,
+                     val[2]->type, val[3]->type,
+                     DBUS_TYPE_INT32, DBUS_TYPE_INT32,
+                     DBUS_TYPE_INT32, DBUS_TYPE_STRING);
+        }
+
+        g_warning (retval->value.s);
+
+        return OSSO_ERROR;
+      }
+
+      if (arguments->len == 5)
+        parent_window_id = val[4]->value.i;
+
+      return _delayed_infobanner_add (val[0]->value.i,
+                                      val[1]->value.i,
+                                      val[2]->value.i,
+                                      val[3]->value.s,
+                                      parent_window_id);
+  }
+  else if (g_str_equal( "cancel_delayed_infobanner", method))
+  {
+    if (arguments->len > 1 ||
+        val[0]->type != DBUS_TYPE_INT32 ) 
+    {
+      retval->type = DBUS_TYPE_STRING;
+
+      if (arguments->len > 1) 
+      {
+        retval->value.s = "Too many args.";
+      } 
+      else 
+      {
+        g_sprintf(retval->value.s, "Wrong type of arguments: "
+                  "(%d), was expecting int (%d)",
+                  val[0]->type, DBUS_TYPE_INT32);
+      }
+
+      g_warning (retval->value.s);
+
+      return OSSO_ERROR;
+    }
+
+    _delayed_infobanner_remove (GINT_TO_POINTER (val[0]->value.i));
+
+    /* This function returns boolean for the timeout functions, *
+     * we don't care about that here. It's false always, anyway */
+    return OSSO_OK;
+
+  }
+  else if( g_str_equal( "statusbar_insensitive", method ))
+  {
+    sb_is_sensitive = FALSE;
+
+    gtk_container_foreach (GTK_CONTAINER (panel->fixed),
+                           (GtkCallback) (statusbar_insensitive_cb),
+                           NULL);
+
+    gtk_container_foreach (GTK_CONTAINER (panel->arrow_button),
+                           (GtkCallback) (statusbar_insensitive_cb),
+                           NULL);
+
+    return OSSO_OK;
+  }
+  else if (g_str_equal("statusbar_sensitive", method))
+  {
+    sb_is_sensitive = TRUE;
+
+    gtk_container_foreach (GTK_CONTAINER (panel->fixed),
+                           (GtkCallback) (statusbar_sensitive_cb),
+                           NULL);
+
+    gtk_container_foreach (GTK_CONTAINER (panel->arrow_button),
+                           (GtkCallback) (statusbar_sensitive_cb),
+                           NULL);
+
+    return OSSO_OK;
+  }
+  else if (g_str_equal("statusbar_get_conditional", method))
+  {
+    int i;
+
+    for (i = 0; i < HSB_MAX_NO_OF_ITEMS; i++) /* Can we break earlier? */
+    {
+       if (panel->items[i])
+       {
+         statusbar_send_signal (osso_get_dbus_connection (panel->osso),
+                                HILDON_STATUS_BAR_ITEM (panel->items[i]),
+                                hildon_status_bar_item_get_conditional
+                                (HILDON_STATUS_BAR_ITEM (panel->items[i])));
+       }
+    }
+
+    return OSSO_OK;
+  }
+  else
+  {
+    g_warning ("Unknown SB RPC method");
+
+    return OSSO_ERROR;
+  }
+
+  return OSSO_OK;
+}
+#endif
+#endif
+
 static void 
 hd_desktop_load_containers (HDDesktop *desktop)
 {
@@ -1029,14 +1329,216 @@
   g_key_file_free (keyfile);
 }
 
+static GtkWidget *
+hd_desktop_create_note_infoprint (const gchar *summary, 
+				  const gchar *body, 
+				  const gchar *icon_name)
+{
+  GtkWidget *banner;
+
+  banner = GTK_WIDGET (g_object_new (HILDON_TYPE_BANNER, 
+		                     "is-timed", FALSE,
+			             NULL));
+
+  hildon_banner_set_markup (HILDON_BANNER (banner), body);
+  hildon_banner_set_icon (HILDON_BANNER (banner), icon_name);
+
+  return banner;
+}
+	
 static void
+hd_desktop_system_notification_dialog_response (GtkWidget *widget,
+	       					gint response,	
+		                                HDDesktopNotificationInfo *ninfo)
+{
+  HildonDesktopNotificationManager *nm;
+  HDDesktop *desktop;
+  GtkWidget *next_dialog = NULL;
+
+  desktop = ninfo->desktop;
+
+  nm = (HildonDesktopNotificationManager *) 
+	  gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (desktop->priv->nm));
+
+  hildon_desktop_notification_manager_close_notification (nm, ninfo->id, NULL);
+  
+  g_free (ninfo);
+
+  g_queue_pop_head (desktop->priv->dialog_queue);
+  gtk_widget_destroy (widget);
+
+  g_debug ("DIALOG QUEUE: %d", g_queue_get_length (desktop->priv->dialog_queue));
+    
+  /* Show next system notification dialog if present */
+  while (!g_queue_is_empty (desktop->priv->dialog_queue))
+  {
+    next_dialog = (GtkWidget *) g_queue_peek_head (desktop->priv->dialog_queue);
+
+    if (GTK_IS_WIDGET (next_dialog))
+    {
+      gtk_widget_show_all (next_dialog);
+      break;
+    }
+    else
+    {
+      g_queue_pop_head (desktop->priv->dialog_queue);
+    }
+  }
+}
+
+static GtkWidget *
+hd_desktop_create_note_dialog (const gchar *summary, 
+			       const gchar *body, 
+			       const gchar *icon_name)
+{
+  GtkWidget *note;
+
+  note = hildon_note_new_information_with_icon_name (NULL, 
+		  				     body, 
+						     icon_name);
+
+  return note;
+}
+
+static void
+hd_desktop_system_notification_closed (HildonDesktopNotificationManager *nm,
+				       gint id,
+				       HDDesktop *desktop)
+{
+  gpointer widget;
+
+  widget = g_hash_table_lookup (desktop->priv->notifications, GINT_TO_POINTER (id));
+
+  g_hash_table_remove (desktop->priv->notifications, GINT_TO_POINTER (id));
+
+  if (GTK_IS_WIDGET (widget))
+  {
+    gtk_widget_destroy (GTK_WIDGET (widget));
+  }
+}
+
+static void
+hd_desktop_system_notification_received (GtkTreeModel *model,
+                                         GtkTreePath *path,
+                                         GtkTreeIter *iter,
+                                         gpointer user_data)  
+
+{
+  HDDesktop *desktop;
+  GtkWidget *notification = NULL;
+  GHashTable *hints;
+  GValue *hint;
+  const gchar *hint_s;
+  gchar *summary;
+  gchar *body;
+  gchar *icon_name;
+  gint id;
+
+  g_return_if_fail (HD_IS_DESKTOP (user_data));
+  
+  desktop = HD_DESKTOP (user_data);
+
+  gtk_tree_model_get (model,
+		      iter,
+		      HD_NM_COL_ID, &id,
+		      HD_NM_COL_SUMMARY, &summary,
+		      HD_NM_COL_BODY, &body,
+		      HD_NM_COL_ICON_NAME, &icon_name,
+		      HD_NM_COL_HINTS, &hints,
+		      -1);
+
+  hint = g_hash_table_lookup (hints, "category");
+  hint_s = g_value_get_string (hint);
+
+  if (g_str_equal (hint_s, "system.note_infoprint")) 
+  {
+    notification = hd_desktop_create_note_infoprint (summary, 
+		    				     body, 
+						     icon_name);
+
+    gtk_widget_show_all (notification);
+  }
+  else if (g_str_equal (hint_s, "system.note_dialog")) 
+  {
+    HDDesktopNotificationInfo *ninfo;
+
+    notification = hd_desktop_create_note_dialog (summary, 
+		    				  body, 
+						  icon_name);
+
+    ninfo = g_new0 (HDDesktopNotificationInfo, 1); 
+
+    ninfo->id = id;
+    ninfo->desktop = desktop;
+  
+    g_signal_connect (G_OBJECT (notification),
+  		      "response",
+  		      G_CALLBACK (hd_desktop_system_notification_dialog_response),
+  		      ninfo);
+
+    if (g_queue_is_empty (desktop->priv->dialog_queue))
+    {
+      gtk_widget_show_all (notification);
+    }
+
+    g_queue_push_tail (desktop->priv->dialog_queue, notification);
+  } 
+  else
+  {
+    goto clean;
+  }
+
+  g_hash_table_insert (desktop->priv->notifications, 
+		       GINT_TO_POINTER (id), 
+		       notification);
+
+clean:
+  g_free (summary);
+  g_free (body);
+  g_free (icon_name);
+}
+
+static gboolean
+hd_desktop_system_notifications_filter (GtkTreeModel *model,
+				        GtkTreeIter *iter,
+				        gpointer user_data)
+{
+  GHashTable *hints;
+  GValue *category;
+
+  gtk_tree_model_get (model,
+		      iter,
+		      HD_NM_COL_HINTS, &hints,
+		      -1);
+
+  if (hints == NULL) 
+    return FALSE;
+  
+  category = g_hash_table_lookup (hints, "category");
+
+  if (category == NULL)
+  {
+    return FALSE;
+  }
+  else if (g_str_has_prefix (g_value_get_string (category), "system."))
+  {
+    return TRUE;
+  } 
+  else
+  {
+    return FALSE;
+  }
+}
+
+static void
 hd_desktop_init (HDDesktop *desktop)
 {
   HDDesktopPrivate *priv;
   gchar *user_conf_dir;
   const gchar *env_config_file;
   HDWM *hdwm;
-
+  GtkListStore *nm;
+  
   desktop->priv = HD_DESKTOP_GET_PRIVATE (desktop);
 
   priv = desktop->priv;
@@ -1081,17 +1583,42 @@
 
   desktop->priv->pm = hd_plugin_manager_new (); 
 
-  desktop->priv->nm = hildon_desktop_notification_manager_get_singleton (); 
+  nm = hildon_desktop_notification_manager_get_singleton (); 
 
+  priv->nm = gtk_tree_model_filter_new (GTK_TREE_MODEL (nm), NULL);
+
+  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->nm),
+		                          hd_desktop_system_notifications_filter,
+					  NULL,
+					  NULL);
+  
+  g_signal_connect (nm,
+		    "notification-closed",
+		    G_CALLBACK (hd_desktop_system_notification_closed),
+		    desktop);
+
+  g_signal_connect (priv->nm,
+		    "row-inserted",
+		    G_CALLBACK (hd_desktop_system_notification_received),
+		    desktop);
+
   hdwm = hd_wm_get_singleton ();
 
   g_signal_connect (hdwm,
 		    "application-starting",
 		    G_CALLBACK (hd_desktop_launch_banner_show),
 		    NULL);
-		    
+
   desktop->priv->system_conf_monitor = NULL;
   desktop->priv->user_conf_monitor = NULL;
+
+  desktop->priv->notifications = 
+          g_hash_table_new_full (g_direct_hash, 
+	  		         g_direct_equal,
+			         NULL,
+			         NULL);
+
+  desktop->priv->dialog_queue = g_queue_new ();
 }
 
 static void
@@ -1140,6 +1667,18 @@
     priv->user_conf_monitor = NULL;
   }
 
+  if (priv->notifications != NULL)
+  {
+    g_hash_table_destroy (priv->notifications);
+    priv->notifications = NULL;
+  }
+
+  if (priv->dialog_queue != NULL)
+  {
+    g_queue_free (priv->dialog_queue);
+    priv->dialog_queue = NULL;
+  }
+
   G_OBJECT_CLASS (hd_desktop_parent_class)->finalize (object);
 }
 


More information about the maemo-commits mailing list