← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~cjcurran/indicator-session/device-menu-reorg into lp:indicator-session

 

Conor Curran has proposed merging lp:~cjcurran/indicator-session/device-menu-reorg into lp:indicator-session.

Requested reviews:
  Ted Gould (ted)

For more details, see:
https://code.launchpad.net/~cjcurran/indicator-session/device-menu-reorg/+merge/68737

sorts out the device menu, and backend of dealing with apt is largely built. More states still need to be handled. 
-- 
https://code.launchpad.net/~cjcurran/indicator-session/device-menu-reorg/+merge/68737
Your team ayatana-commits is subscribed to branch lp:indicator-session.
=== modified file 'src/Makefile.am'
--- src/Makefile.am	2011-07-18 11:19:38 +0000
+++ src/Makefile.am	2011-07-21 19:51:11 +0000
@@ -95,7 +95,13 @@
 	user-menu-mgr.h \
 	user-menu-mgr.c \	
 	device-menu-mgr.h \
-	device-menu-mgr.c 	
+	device-menu-mgr.c \
+	apt-watcher.h \
+	apt-watcher.c \
+	apt-transaction.h \
+	apt-transaction.c \
+	udev-mgr.h \
+	udev-mgr.c
 indicator_session_service_CFLAGS = \
 	$(SESSIONSERVICE_CFLAGS) \
 	$(GCONF_CFLAGS) \

=== added file 'src/apt-transaction.c'
--- src/apt-transaction.c	1970-01-01 00:00:00 +0000
+++ src/apt-transaction.c	2011-07-21 19:51:11 +0000
@@ -0,0 +1,197 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gio/gio.h>
+
+#include "apt-transaction.h"
+#include "dbus-shared-names.h"
+
+static void apt_transaction_investigate (AptTransaction* self);
+static void apt_transaction_simulate_transaction_cb (GObject * obj,
+                                                     GAsyncResult * res,
+                                                     gpointer user_data);
+static void apt_transaction_receive_signal (GDBusProxy * proxy,
+                                            gchar * sender_name,
+                                            gchar * signal_name,
+                                            GVariant * parameters,
+                                            gpointer user_data);
+
+struct _AptTransaction
+{
+	GObject       parent_instance;
+	GDBusProxy *  proxy;    
+  gchar*        id;
+  AptState      current_state;
+};
+
+enum {
+  UPDATE,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (AptTransaction, apt_transaction, G_TYPE_OBJECT);
+
+static void
+apt_transaction_init (AptTransaction *self)
+{
+  self->proxy = NULL;
+  self->id = NULL;
+  
+}
+
+static void
+apt_transaction_finalize (GObject *object)
+{
+	/* TODO: Add deinitalization code here */
+  AptTransaction* self = APT_TRANSACTION(object);
+  if (self->proxy != NULL){
+    g_object_unref (self->proxy);
+    self->proxy = NULL;
+  }    
+  g_free (self->id);
+	G_OBJECT_CLASS (apt_transaction_parent_class)->finalize (object);
+}
+
+static void
+apt_transaction_class_init (AptTransactionClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = apt_transaction_finalize;
+
+  signals[UPDATE] =  g_signal_new("state-update",
+                                   G_TYPE_FROM_CLASS (klass),
+                                   G_SIGNAL_RUN_LAST,
+                                   0,
+                                   NULL, NULL,
+                                   g_cclosure_marshal_VOID__INT,
+                                   G_TYPE_NONE, 1, G_TYPE_INT);  
+}
+
+static void
+apt_transaction_investigate(AptTransaction* self)
+{
+  GError * error = NULL;
+
+  self->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+                                               NULL, /* GDBusInterfaceInfo */
+                                               "org.debian.apt",
+                                               self->id,
+                                               "org.debian.apt.transaction",
+                                               NULL, /* GCancellable */
+                                               &error);        
+  if (error != NULL) {
+    g_warning ("unable to fetch proxy for transaction object path %s", self->id);
+    g_error_free (error);
+    return;
+  }
+
+  g_signal_connect (G_OBJECT(self->proxy),
+                    "g-signal",
+                    G_CALLBACK (apt_transaction_receive_signal),
+                    self);    
+
+  g_dbus_proxy_call (self->proxy,
+                     "Simulate",
+                     NULL,
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1,
+                     NULL,
+                     apt_transaction_simulate_transaction_cb,
+                     self);                                                                                        
+}
+
+static void
+apt_transaction_receive_signal (GDBusProxy * proxy,
+                                gchar * sender_name,
+                                gchar * signal_name,
+                                GVariant * parameters,
+                                gpointer user_data)
+{
+  g_return_if_fail (APT_IS_TRANSACTION (user_data));
+  AptTransaction* self = APT_TRANSACTION(user_data);      
+
+  if (g_strcmp0(signal_name, "PropertyChanged") == 0) 
+  {
+    gchar* prop_name= NULL;
+    GVariant* value = NULL;
+    g_variant_get (parameters, "(sv)", &prop_name, &value);
+    
+    if (g_strcmp0 (prop_name, "Dependencies") == 0){
+      
+      
+      gchar** install = NULL;
+      gchar** reinstall = NULL;
+      gchar** remove = NULL;
+      gchar** purge = NULL;
+      gchar** upgrade = NULL;
+      gchar** downgrade = NULL;
+      gchar** keep = NULL;
+      g_variant_get (value, "(asasasasasasas)", &install, 
+                     &reinstall, &remove, &purge, &upgrade, &downgrade,
+                     &keep);
+      
+      //g_debug ("Seemed to uppack dependencies without any warnings");
+      //g_debug ("Upgrade quantity : %u", g_strv_length(upgrade));
+      gboolean upgrade_needed = (g_strv_length(upgrade) > 0) ||
+                                (g_strv_length(install) > 0) ||
+                                (g_strv_length(reinstall) > 0) ||
+                                (g_strv_length(remove) > 0) ||
+                                (g_strv_length(purge) > 0);
+      if (upgrade_needed == TRUE){
+        g_signal_emit (self,
+                       signals[UPDATE],
+                       0,
+                       UPDATES_AVAILABLE);
+        
+      }
+      else{
+        g_signal_emit (self,
+                       signals[UPDATE],
+                       0,
+                       UP_TO_DATE);
+      }
+    }
+  }
+}
+
+static void
+apt_transaction_simulate_transaction_cb (GObject * obj,
+                                         GAsyncResult * res,
+                                         gpointer user_data)
+{
+	GError * error = NULL;
+
+	if (error != NULL) {
+    g_warning ("unable to complete the simulate call");
+    g_error_free (error);
+		return;
+	}
+}
+
+AptTransaction* apt_transaction_new (gchar* transaction_id)
+{
+  AptTransaction* tr = g_object_new (APT_TYPE_TRANSACTION, NULL);
+  tr->id = transaction_id;
+  g_debug ("Apt transaction new id = %s", tr->id);
+  apt_transaction_investigate (tr);
+  return tr;
+}

=== added file 'src/apt-transaction.h'
--- src/apt-transaction.h	1970-01-01 00:00:00 +0000
+++ src/apt-transaction.h	2011-07-21 19:51:11 +0000
@@ -0,0 +1,48 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _APT_TRANSACTION_H_
+#define _APT_TRANSACTION_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define APT_TYPE_TRANSACTION             (apt_transaction_get_type ())
+#define APT_TRANSACTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), APT_TYPE_TRANSACTION, AptTransaction))
+#define APT_TRANSACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), APT_TYPE_TRANSACTION, AptTransactionClass))
+#define APT_IS_TRANSACTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APT_TYPE_TRANSACTION))
+#define APT_IS_TRANSACTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), APT_TYPE_TRANSACTION))
+#define APT_TRANSACTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), APT_TYPE_TRANSACTION, AptTransactionClass))
+
+typedef struct _AptTransactionClass AptTransactionClass;
+typedef struct _AptTransaction AptTransaction;
+
+struct _AptTransactionClass
+{
+	GObjectClass parent_class;
+};
+
+AptTransaction* apt_transaction_new (gchar* transaction_id);
+
+GType apt_transaction_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* _APT_TRANSACTION_H_ */

=== added file 'src/apt-watcher.c'
--- src/apt-watcher.c	1970-01-01 00:00:00 +0000
+++ src/apt-watcher.c	2011-07-21 19:51:11 +0000
@@ -0,0 +1,308 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include "apt-watcher.h"
+#include "dbus-shared-names.h"
+#include "apt-transaction.h"
+
+static guint watcher_id;
+
+struct _AptWatcher
+{
+	GObject parent_instance;
+	GCancellable * proxy_cancel;
+	GDBusProxy * proxy;  
+  SessionDbus* session_dbus_interface;
+  DbusmenuMenuitem* apt_item;
+  AptState current_state;
+  AptTransaction* current_transaction;
+};
+
+static void
+apt_watcher_on_name_appeared (GDBusConnection *connection,
+                              const gchar     *name,
+                              const gchar     *name_owner,
+                              gpointer         user_data);
+static void
+apt_watcher_on_name_vanished (GDBusConnection *connection,
+                              const gchar     *name,
+                              gpointer         user_data);
+static void fetch_proxy_cb (GObject * object,
+                            GAsyncResult * res,
+                            gpointer user_data);
+
+static void apt_watcher_upgrade_system_cb (GObject * obj,
+                                           GAsyncResult * res,
+                                           gpointer user_data);
+                                                 
+                
+static void apt_watcher_show_apt_dialog (DbusmenuMenuitem* mi,
+                                         guint timestamp,
+                                         gchar * type);
+
+static void apt_watcher_signal_cb (GDBusProxy* proxy,
+                                   gchar* sender_name,
+                                   gchar* signal_name,
+                                   GVariant* parameters,
+                                   gpointer user_data);
+static void  apt_watcher_manage_transactions (AptWatcher* self,
+                                              gchar* transaction_id);
+                                   
+
+
+G_DEFINE_TYPE (AptWatcher, apt_watcher, G_TYPE_OBJECT);
+
+static void
+apt_watcher_init (AptWatcher *self)
+{
+  self->current_state = UP_TO_DATE;
+  self->proxy_cancel = g_cancellable_new();
+  self->proxy = NULL;
+  self->current_transaction = NULL;
+  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+                            G_DBUS_PROXY_FLAGS_NONE,
+                            NULL,
+                            "org.debian.apt",
+                            "/org/debian/apt",
+                            "org.debian.apt",
+                            self->proxy_cancel,
+                            fetch_proxy_cb,
+                            self);
+}
+
+static void
+apt_watcher_finalize (GObject *object)
+{
+  g_bus_unwatch_name (watcher_id);  
+  AptWatcher* self = APT_WATCHER (object);
+           
+  if (self->proxy != NULL)
+    g_object_unref (self->proxy);
+
+	G_OBJECT_CLASS (apt_watcher_parent_class)->finalize (object);
+}
+
+static void
+apt_watcher_class_init (AptWatcherClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = apt_watcher_finalize;
+}
+
+static void
+fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+	GError * error = NULL;
+
+	AptWatcher* self = APT_WATCHER(user_data);
+	g_return_if_fail(self != NULL);
+
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+	if (self->proxy_cancel != NULL) {
+		g_object_unref(self->proxy_cancel);
+		self->proxy_cancel = NULL;
+	}
+
+	if (error != NULL) {
+		g_warning("Could not grab DBus proxy for %s: %s",
+               "org.debian.apt", error->message);
+		g_error_free(error);
+		return;
+	}
+
+	self->proxy = proxy;
+  // Set up the watch.
+  watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
+                                 "org.debian.apt",
+                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                 apt_watcher_on_name_appeared,
+                                 apt_watcher_on_name_vanished,
+                                 self,
+                                 NULL);
+  
+	g_signal_connect (self->proxy,
+                    "g-signal",
+                    G_CALLBACK(apt_watcher_signal_cb),
+                    self);  
+}
+
+
+static void
+apt_watcher_on_name_appeared (GDBusConnection *connection,
+                              const gchar     *name,
+                              const gchar     *name_owner,
+                              gpointer         user_data)
+{
+  g_return_if_fail (APT_IS_WATCHER (user_data));
+  AptWatcher* watcher = APT_WATCHER (user_data);
+  
+  g_print ("Name %s on %s is owned by %s\n",
+           name,
+           "the system bus",
+           name_owner);
+
+  g_dbus_proxy_call (watcher->proxy,
+                     "UpgradeSystem",
+                     g_variant_new("(b)", TRUE),
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1,
+                     NULL,
+                     apt_watcher_upgrade_system_cb,
+                     user_data);
+}
+
+static void
+apt_watcher_on_name_vanished (GDBusConnection *connection,
+                              const gchar     *name,
+                              gpointer         user_data)
+{
+  g_debug ("Name %s does not exist or has just vanished",
+           name);
+  g_return_if_fail (APT_IS_WATCHER (user_data));
+}
+
+static void
+apt_watcher_upgrade_system_cb (GObject * obj,
+                               GAsyncResult * res,
+                               gpointer user_data)
+{
+  g_return_if_fail (APT_IS_WATCHER (user_data));
+  AptWatcher* self = APT_WATCHER (user_data);
+
+	GError * error = NULL;
+	GVariant * result;
+
+	result = g_dbus_proxy_call_finish(self->proxy, res, &error);
+
+	if (error != NULL) {
+    g_warning ("unable to complete the UpgradeSystem apt call");
+    g_error_free (error);
+		return;
+	}
+  
+  gchar* transaction_id = NULL;
+  g_variant_get (result, "(s)", &transaction_id);
+
+  if (transaction_id == NULL){
+    g_warning ("apt_watcher_upgrade_system_cb - transaction id is null");
+    return;
+  }  
+  
+  apt_watcher_manage_transactions (self, transaction_id);
+  
+}
+
+static void
+apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi,
+                             guint timestamp,
+                             gchar * type)
+{
+  GError * error = NULL;
+  if (!g_spawn_command_line_async("update-manager", &error))
+  {
+    g_warning("Unable to show update-manager: %s", error->message);
+    g_error_free(error);
+  }  
+}
+
+static void
+apt_watcher_transaction_state_update_cb (AptTransaction* trans,
+                                         gint update,
+                                         gpointer user_data)
+{
+  g_debug ("apt-watcher -transaction update %i", update);
+  g_return_if_fail (APT_IS_WATCHER (user_data));
+  AptWatcher* self = APT_WATCHER (user_data);
+  
+  AptState state = (AptState)update;
+  
+  if ( state == UP_TO_DATE ){
+    dbusmenu_menuitem_property_set (self->apt_item,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Software Up to Date"));    
+  }
+  else if ( state == UPDATES_AVAILABLE ){
+    dbusmenu_menuitem_property_set (self->apt_item,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Updates Available…"));    
+  }  
+  self->current_state = state;
+  g_object_unref (self->current_transaction);
+  self->current_transaction = NULL;
+} 
+ 
+static void
+apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id)
+{
+    if (self->current_transaction == NULL){
+      self->current_transaction = apt_transaction_new (transaction_id);
+      g_object_ref (self->current_transaction);
+      g_signal_connect (G_OBJECT(self->current_transaction),
+                        "state-update",
+                        G_CALLBACK(apt_watcher_transaction_state_update_cb), self);
+    }  
+}
+
+// TODO - Ask MVO about this.
+// Signal is of type s not sas which is on d-feet !!!
+static void apt_watcher_signal_cb ( GDBusProxy* proxy,
+                                    gchar* sender_name,
+                                    gchar* signal_name,
+                                    GVariant* parameters,
+                                    gpointer user_data)
+{
+  g_return_if_fail (APT_IS_WATCHER (user_data));
+  AptWatcher* self = APT_WATCHER (user_data);
+
+  g_variant_ref (parameters);
+  GVariant *value = g_variant_get_child_value (parameters, 0);
+
+  if (g_strcmp0(signal_name, "ActiveTransactionsChanged") == 0){
+    gchar* input = NULL;
+    g_variant_get(value, "s", & input);
+
+    g_debug ("Active Transactions signal - input is null = %i", input == NULL);
+    // TODO don't call on null terminated input
+    g_dbus_proxy_call (self->proxy,
+                       "UpgradeSystem",
+                       g_variant_new("(b)", TRUE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       apt_watcher_upgrade_system_cb,
+                       user_data);    
+  }
+  g_variant_unref (parameters);
+}
+
+AptWatcher* apt_watcher_new (SessionDbus* session_dbus,
+                             DbusmenuMenuitem* item)
+{
+  AptWatcher* watcher = g_object_new (APT_TYPE_WATCHER, NULL);
+  watcher->session_dbus_interface = session_dbus;
+  watcher->apt_item = item;
+  g_signal_connect (G_OBJECT(watcher->apt_item),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(apt_watcher_show_apt_dialog), watcher);
+  return watcher;
+}
+                               

=== added file 'src/apt-watcher.h'
--- src/apt-watcher.h	1970-01-01 00:00:00 +0000
+++ src/apt-watcher.h	2011-07-21 19:51:11 +0000
@@ -0,0 +1,53 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _APT_WATCHER_H_
+#define _APT_WATCHER_H_
+
+#include <glib-object.h>
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-gtk3/menuitem.h>
+
+#include "session-dbus.h"
+
+G_BEGIN_DECLS
+
+#define APT_TYPE_WATCHER             (apt_watcher_get_type ())
+#define APT_WATCHER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), APT_TYPE_WATCHER, AptWatcher))
+#define APT_WATCHER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), APT_TYPE_WATCHER, AptWatcherClass))
+#define APT_IS_WATCHER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APT_TYPE_WATCHER))
+#define APT_IS_WATCHER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), APT_TYPE_WATCHER))
+#define APT_WATCHER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), APT_TYPE_WATCHER, AptWatcherClass))
+
+typedef struct _AptWatcherClass AptWatcherClass;
+typedef struct _AptWatcher AptWatcher;
+
+struct _AptWatcherClass
+{
+	GObjectClass parent_class;
+};
+
+GType apt_watcher_get_type (void) G_GNUC_CONST;
+
+AptWatcher* apt_watcher_new (SessionDbus* session_dbus,
+                             DbusmenuMenuitem* apt_item);
+
+G_END_DECLS
+
+#endif /* _APT_WATCHER_H_ */

=== modified file 'src/dbus-shared-names.h'
--- src/dbus-shared-names.h	2011-07-13 12:12:00 +0000
+++ src/dbus-shared-names.h	2011-07-21 19:51:11 +0000
@@ -20,6 +20,15 @@
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+typedef enum {
+  UP_TO_DATE,
+  CHECKING_FOR_UPDATES,
+  UPDATES_AVAILABLE,
+  FINISHED_CHECKING,
+  UPDATING,  
+  RESTART_NEEDED  
+}AptState;
+
 
 #ifndef __DBUS_SHARED_NAMES_H__
 #define __DBUS_SHARED_NAMES_H__ 1

=== modified file 'src/device-menu-mgr.c'
--- src/device-menu-mgr.c	2011-07-18 17:17:37 +0000
+++ src/device-menu-mgr.c	2011-07-21 19:51:11 +0000
@@ -17,12 +17,17 @@
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-gtk3/menuitem.h>
+
 #include "device-menu-mgr.h"
 #include "gconf-helper.h"
 #include "dbus-shared-names.h"
 #include "dbusmenu-shared.h"
 #include "lock-helper.h"
 #include "upower-client.h"
+#include "apt-watcher.h"
+
 
 #define UP_ADDRESS    "org.freedesktop.UPower"
 #define UP_OBJECT     "/org/freedesktop/UPower"
@@ -35,16 +40,25 @@
 	GObject parent_instance;
   DbusmenuMenuitem* root_item;
   SessionDbus* session_dbus_interface;  
+  AptWatcher* apt_watcher;                              
 };
 
 static GConfClient       *gconf_client  = NULL;
 static DbusmenuMenuitem  *lock_menuitem = NULL;
+static DbusmenuMenuitem  *system_settings_menuitem = NULL;
+static DbusmenuMenuitem  *display_settings_menuitem = NULL;
+static DbusmenuMenuitem  *bluetooth_settings_menuitem = NULL;
+static DbusmenuMenuitem  *login_settings_menuitem = NULL;
+static DbusmenuMenuitem  *software_updates_menuitem = NULL;
+static DbusmenuMenuitem  *printers_menuitem = NULL;
+static DbusmenuMenuitem  *scanners_menuitem = NULL;
+static DbusmenuMenuitem  *webcam_menuitem = NULL;
 
 static DBusGProxyCall * suspend_call = NULL;
 static DBusGProxyCall * hibernate_call = NULL;
 
 static DbusmenuMenuitem * hibernate_mi = NULL;
-static DbusmenuMenuitem * suspend_mi = NULL;
+//static DbusmenuMenuitem * suspend_mi = NULL;
 static DbusmenuMenuitem * logout_mi = NULL;
 static DbusmenuMenuitem * restart_mi = NULL;
 static DbusmenuMenuitem * shutdown_mi = NULL;
@@ -64,20 +78,25 @@
 static void lock_if_possible (DeviceMenuMgr* self);
 static void machine_sleep_with_context (DeviceMenuMgr* self,
                                         gchar* type);
+static void show_system_settings_with_context (DbusmenuMenuitem * mi,
+                                               guint timestamp,
+                                               gchar * type);                                               
+                                        
 static void
 machine_sleep_from_hibernate (DbusmenuMenuitem * mi,
                               guint timestamp,
                               gpointer userdata);
-static void
+/*static void
 machine_sleep_from_suspend (DbusmenuMenuitem * mi,
                             guint timestamp,
                             gpointer userdata);
-
+*/
 G_DEFINE_TYPE (DeviceMenuMgr, device_menu_mgr, G_TYPE_OBJECT);
 
 static void
 device_menu_mgr_init (DeviceMenuMgr *self)
 {
+  self->apt_watcher = NULL;
   self->root_item = dbusmenu_menuitem_new ();  
   setup_restart_watch(self);
 	setup_up(self);  
@@ -100,7 +119,8 @@
 	object_class->finalize = device_menu_mgr_finalize;
 }
 
-
+// TODO
+// Is this needed anymore
 static void
 lockdown_changed (GConfClient *client,
                   guint        cnxd_id,
@@ -167,14 +187,15 @@
 	return;
 }
 
-static void
+
+/*static void
 machine_sleep_from_suspend (DbusmenuMenuitem * mi,
                             guint timestamp,
                             gpointer userdata)
 {
   DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata);
   machine_sleep_with_context (self, "Suspend");
-}
+}*/
 
 static void
 machine_sleep_from_hibernate (DbusmenuMenuitem * mi,
@@ -208,6 +229,9 @@
 }
 
 /* A response to getting the suspend property */
+// TODO
+// Is this needed anymore
+
 static void
 suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
 {
@@ -227,13 +251,15 @@
 	gboolean local_can_suspend = g_value_get_boolean(&candoit);
 	if (local_can_suspend != can_suspend) {
 		can_suspend = local_can_suspend;
+    // TODO figure out what needs updating on the menu
 		device_menu_mgr_rebuild_items(self);
 	}
-
 	return;
 }
 
 /* Response to getting the hibernate property */
+// TODO
+// Is this needed anymore
 static void
 hibernate_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
 {
@@ -392,6 +418,7 @@
 static void
 show_dialog (DbusmenuMenuitem * mi, guint timestamp, gchar * type)
 {
+
 	gchar * helper = g_build_filename(LIBEXECDIR, "gtk-logout-helper", NULL);
 	gchar * dialog_line = g_strdup_printf("%s --%s", helper, type);
 	g_free(helper);
@@ -403,55 +430,194 @@
 		g_warning("Unable to show dialog: %s", error->message);
 		g_error_free(error);
 	}
-
-	g_free(dialog_line);
-
-	return;
-}
-
-
-static void
-device_menu_mgr_rebuild_items (DeviceMenuMgr* self)
-{
+	g_free(dialog_line);  
+}
+
+static void
+show_session_properties (DbusmenuMenuitem * mi,
+                         guint timestamp,
+                         gchar * type)
+{
+  GError * error = NULL;
+  if (!g_spawn_command_line_async("gnome-session-properties", &error))
+  {
+    g_warning("Unable to show dialog: %s", error->message);
+    g_error_free(error);
+  }  
+}                                   
+
+static void
+show_system_settings_with_context (DbusmenuMenuitem * mi,
+                                   guint timestamp,
+                                   gchar * type)
+{
+	gchar * control_centre_command = g_strdup_printf("%s %s",
+                                                   "gnome-control-center",
+                                                    type);
+
+	g_debug("Command centre exec call '%s'", control_centre_command);
+
+  GError * error = NULL;
+  if (!g_spawn_command_line_async(control_centre_command, &error))
+  {
+    g_warning("Unable to show dialog: %s", error->message);
+    g_error_free(error);
+  }
+	g_free(control_centre_command);
+}
+
+static void
+device_menu_mgr_build_static_items (DeviceMenuMgr* self)
+{
+  // Static Setting items
+  system_settings_menuitem  = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (system_settings_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("System Settings..."));
+  g_signal_connect (G_OBJECT(system_settings_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_system_settings_with_context), "");
+  dbusmenu_menuitem_child_add_position(self->root_item,
+                                       system_settings_menuitem,
+                                       0);
+  
+  display_settings_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (display_settings_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Displays..."));
+  g_signal_connect (G_OBJECT(display_settings_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_system_settings_with_context), "display");
+  dbusmenu_menuitem_child_add_position(self->root_item,
+                                       display_settings_menuitem,
+                                       1);
+  bluetooth_settings_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (bluetooth_settings_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Bluetooth..."));
+  g_signal_connect (G_OBJECT(bluetooth_settings_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_system_settings_with_context), "bluetooth");
+  dbusmenu_menuitem_child_add_position(self->root_item,
+                                       bluetooth_settings_menuitem,
+                                       2);
+
+  login_settings_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (login_settings_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Login Items..."));
+  g_signal_connect (G_OBJECT(login_settings_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_session_properties),
+                    "login");
+  dbusmenu_menuitem_child_add_position(self->root_item,
+                                       login_settings_menuitem,
+                                       3);
+  software_updates_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (software_updates_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Software Up to Date"));
+  dbusmenu_menuitem_child_add_position(self->root_item,
+                                       software_updates_menuitem,
+                                       4);
+
+  DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (separator1,
+                                  DBUSMENU_MENUITEM_PROP_TYPE,
+                                  DBUSMENU_CLIENT_TYPES_SEPARATOR);
+  dbusmenu_menuitem_child_add_position (self->root_item, separator1, 5);
+
+  // Devices control
+  DbusmenuMenuitem * device_heading = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (device_heading,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Attached Devices"));
+  dbusmenu_menuitem_property_set_bool (device_heading,
+                                       DBUSMENU_MENUITEM_PROP_ENABLED,
+                                       FALSE);
+  dbusmenu_menuitem_child_add_position (self->root_item,
+                                        device_heading,
+                                        6);
+
+  printers_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (printers_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Printers"));
+  g_signal_connect (G_OBJECT(printers_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_system_settings_with_context),
+                    "printers");
+  dbusmenu_menuitem_child_add_position(self->root_item,
+                                       printers_menuitem,
+                                       7);
+  scanners_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (scanners_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("HP Scanners"));
+  g_signal_connect (G_OBJECT(scanners_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_system_settings_with_context),
+                    "scanners");
+  dbusmenu_menuitem_child_add_position (self->root_item,
+                                        scanners_menuitem,
+                                        8);
+  webcam_menuitem = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (webcam_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("HP Webcam"));
+  g_signal_connect (G_OBJECT(webcam_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_system_settings_with_context),
+                    "HP Webcam");
+  dbusmenu_menuitem_child_add_position (self->root_item,
+                                        webcam_menuitem,
+                                        10);
+  DbusmenuMenuitem * separator3 = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (separator3,
+                                  DBUSMENU_MENUITEM_PROP_TYPE,
+                                  DBUSMENU_CLIENT_TYPES_SEPARATOR);
+  dbusmenu_menuitem_child_add_position (self->root_item, separator3, 11);
+                                        
+  // Session control  
   gboolean can_lockscreen;
 
   /* Make sure we have a valid GConf client, and build one
      if needed */
   device_menu_mgr_ensure_gconf_client (self);
-
   can_lockscreen = !gconf_client_get_bool ( gconf_client,
                                             LOCKDOWN_KEY_SCREENSAVER,
                                             NULL);
   /* Lock screen item */
   if (can_lockscreen) {
-	lock_menuitem = dbusmenu_menuitem_new();
-	dbusmenu_menuitem_property_set (lock_menuitem,
-                                  DBUSMENU_MENUITEM_PROP_LABEL,
-                                  _("Lock Screen"));
-
-	gchar * shortcut = gconf_client_get_string(gconf_client, KEY_LOCK_SCREEN, NULL);
-	if (shortcut != NULL) {
-		g_debug("Lock screen shortcut: %s", shortcut);
-		dbusmenu_menuitem_property_set_shortcut_string(lock_menuitem, shortcut);
-		g_free(shortcut);
-	} else {
-		g_debug("Unable to get lock screen shortcut.");
-	}
-
-	g_signal_connect (G_OBJECT(lock_menuitem),
-                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-                    G_CALLBACK(lock_screen), NULL);
-	dbusmenu_menuitem_child_append(self->root_item, lock_menuitem);
-  }
-
-	/* Start going through the session based items. */
-
+    lock_menuitem = dbusmenu_menuitem_new();
+    dbusmenu_menuitem_property_set (lock_menuitem,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Lock Screen"));
+
+    gchar * shortcut = gconf_client_get_string(gconf_client, KEY_LOCK_SCREEN, NULL);
+    if (shortcut != NULL) {
+      g_debug("Lock screen shortcut: %s", shortcut);
+      dbusmenu_menuitem_property_set_shortcut_string(lock_menuitem, shortcut);
+      g_free(shortcut);
+    }
+    else {
+      g_debug("Unable to get lock screen shortcut.");
+    }
+
+    g_signal_connect (G_OBJECT(lock_menuitem),
+                      DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                      G_CALLBACK(lock_screen), NULL);
+    dbusmenu_menuitem_child_append(self->root_item, lock_menuitem);
+  } 
+   
 	logout_mi = dbusmenu_menuitem_new();
+
 	if (supress_confirmations()) {
 		dbusmenu_menuitem_property_set (logout_mi,
                                     DBUSMENU_MENUITEM_PROP_LABEL,
                                     _("Log Out"));
-	} else {
+	}
+  else {
 		dbusmenu_menuitem_property_set (logout_mi,
                                     DBUSMENU_MENUITEM_PROP_LABEL,
                                     _("Log Out\342\200\246"));
@@ -464,18 +630,6 @@
                     DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
                     G_CALLBACK(show_dialog), "logout");
 
-	if (can_suspend && allow_suspend) {
-		suspend_mi = dbusmenu_menuitem_new();
-		dbusmenu_menuitem_property_set (suspend_mi,
-                                    DBUSMENU_MENUITEM_PROP_LABEL,
-                                    _("Suspend"));
-		dbusmenu_menuitem_child_append (self->root_item, suspend_mi);
-		g_signal_connect( G_OBJECT(suspend_mi),
-                      DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-                      G_CALLBACK(machine_sleep_from_suspend),
-                      self);
-	}
-
 	if (can_hibernate && allow_hibernate) {
 		hibernate_mi = dbusmenu_menuitem_new();
 		dbusmenu_menuitem_property_set (hibernate_mi,
@@ -486,34 +640,15 @@
                       DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
                       G_CALLBACK(machine_sleep_from_hibernate), self);
 	}
-
-	restart_mi = dbusmenu_menuitem_new();
-	dbusmenu_menuitem_property_set (restart_mi,
-                                  DBUSMENU_MENUITEM_PROP_TYPE,
-                                  RESTART_ITEM_TYPE);
-	if (supress_confirmations()) {
-		dbusmenu_menuitem_property_set (restart_mi,
-                                    RESTART_ITEM_LABEL,
-                                    _("Restart"));
-	} else {
-		dbusmenu_menuitem_property_set (restart_mi,
-                                    RESTART_ITEM_LABEL,
-                                    _("Restart\342\200\246"));
-	}
-	dbusmenu_menuitem_property_set_bool (restart_mi,
-                                       DBUSMENU_MENUITEM_PROP_VISIBLE,
-                                       show_restart());
-	dbusmenu_menuitem_child_append(self->root_item, restart_mi);
-	g_signal_connect (G_OBJECT(restart_mi),
-                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-                    G_CALLBACK(show_dialog), "restart");
-
+  
 	shutdown_mi = dbusmenu_menuitem_new();
+
 	if (supress_confirmations()) {
 		dbusmenu_menuitem_property_set (shutdown_mi,
                                     DBUSMENU_MENUITEM_PROP_LABEL,
                                     _("Shut Down"));
-	} else {
+	}
+  else {
 		dbusmenu_menuitem_property_set (shutdown_mi,
                                     DBUSMENU_MENUITEM_PROP_LABEL,
                                     _("Shut Down\342\200\246"));
@@ -528,12 +663,15 @@
 
 	RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1);
 	restart_shutdown_logout_mi->logout_mi = logout_mi;
-	restart_shutdown_logout_mi->restart_mi = restart_mi;
 	restart_shutdown_logout_mi->shutdown_mi = shutdown_mi;
 
-	update_menu_entries(restart_shutdown_logout_mi);
-
-	return;
+	update_menu_entries(restart_shutdown_logout_mi);                    
+}
+
+
+static void
+device_menu_mgr_rebuild_items (DeviceMenuMgr* self)
+{
 }
 
 /* When the directory changes we need to figure out how our menu
@@ -631,6 +769,8 @@
 {
   DeviceMenuMgr* device_mgr = g_object_new (DEVICE_TYPE_MENU_MGR, NULL);
   device_mgr->session_dbus_interface = session_dbus;
-  device_menu_mgr_rebuild_items (device_mgr);    
+  device_menu_mgr_build_static_items (device_mgr);   
+  device_mgr->apt_watcher = apt_watcher_new (session_dbus,
+                                             software_updates_menuitem);
   return device_mgr;
 }

=== modified file 'src/device-menu-mgr.h'
--- src/device-menu-mgr.h	2011-07-18 11:19:38 +0000
+++ src/device-menu-mgr.h	2011-07-21 19:51:11 +0000
@@ -22,7 +22,6 @@
 #define _DEVICE_MENU_MGR_H_
 
 #include <glib-object.h>
-#include <libdbusmenu-gtk3/menuitem.h>
 
 #include "session-dbus.h"
 

=== modified file 'src/indicator-session.c'
--- src/indicator-session.c	2011-07-14 16:20:38 +0000
+++ src/indicator-session.c	2011-07-21 19:51:11 +0000
@@ -6,7 +6,8 @@
 
 Authors:
     Ted Gould <ted@xxxxxxxxxxxxx>
-
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+    
 This program is free software: you can redistribute it and/or modify it 
 under the terms of the GNU General Public License version 3, as published 
 by the Free Software Foundation.
@@ -20,7 +21,6 @@
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-//TODO - remember to reinsert Ted's comments.
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -449,17 +449,17 @@
   //Otherwise
   self->show_users_entry = update;
 
-  IndicatorObjectEntry user_entry = self->users;
+  //IndicatorObjectEntry user_entry = self->users;
   
   if (self->show_users_entry == TRUE){
     g_signal_emit_by_name ((gpointer)self,
                            "entry-added",
-                           &user_entry);   
+                           &self->users);   
   }
   else{
     g_signal_emit_by_name ((gpointer)self,
                            "entry-removed",
-                           &user_entry);       
+                           &self->users);       
   }
 }
 

=== modified file 'src/session-dbus.xml'
--- src/session-dbus.xml	2011-07-14 12:06:38 +0000
+++ src/session-dbus.xml	2011-07-21 19:51:11 +0000
@@ -8,11 +8,17 @@
     <method name="GetUserMenuVisibility">
       <arg name="update" direction="out" type="b"/>
     </method>
+    <method name="IsUpdateNeeded">
+      <arg name="update" direction="out" type="b"/>
+    </method>
     <signal name="UserRealNameUpdated">
       <arg name="name" type="s"/>
     </signal>
     <signal name="UserMenuIsVisible">
       <arg name="update" type="b"/>
     </signal>
+    <signal name="RestartNeeded">
+      <arg name="name" type="s"/>
+    </signal>
   </interface>
 </node>

=== modified file 'src/session-service.c'
--- src/session-service.c	2011-07-19 10:15:38 +0000
+++ src/session-service.c	2011-07-21 19:51:11 +0000
@@ -52,12 +52,7 @@
 #include "users-service-dbus.h"
 #include "user-menu-mgr.h"
 #include "device-menu-mgr.h"
-
-//#include "gconf-helper.h"
-
 #include "session-dbus.h"
-//#include "lock-helper.h"
-
 
 typedef struct _ActivateData ActivateData;
 struct _ActivateData

=== added file 'src/udev-mgr.c'
--- src/udev-mgr.c	1970-01-01 00:00:00 +0000
+++ src/udev-mgr.c	2011-07-21 19:51:11 +0000
@@ -0,0 +1,46 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "udev-mgr.h"
+
+
+G_DEFINE_TYPE (UdevMgr, udev_mgr, G_TYPE_OBJECT);
+
+static void
+udev_mgr_init (UdevMgr *object)
+{
+	/* TODO: Add initialization code here */
+}
+
+static void
+udev_mgr_finalize (GObject *object)
+{
+	/* TODO: Add deinitalization code here */
+
+	G_OBJECT_CLASS (udev_mgr_parent_class)->finalize (object);
+}
+
+static void
+udev_mgr_class_init (UdevMgrClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = udev_mgr_finalize;
+}
+

=== added file 'src/udev-mgr.h'
--- src/udev-mgr.h	1970-01-01 00:00:00 +0000
+++ src/udev-mgr.h	2011-07-21 19:51:11 +0000
@@ -0,0 +1,51 @@
+/*
+Copyright 2011 Canonical Ltd.
+
+Authors:
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of the GNU General Public License version 3, as published 
+by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along 
+with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _UDEV_MGR_H_
+#define _UDEV_MGR_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define UDEV_TYPE_MGR             (udev_mgr_get_type ())
+#define UDEV_MGR(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), UDEV_TYPE_MGR, UdevMgr))
+#define UDEV_MGR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), UDEV_TYPE_MGR, UdevMgrClass))
+#define UDEV_IS_MGR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UDEV_TYPE_MGR))
+#define UDEV_IS_MGR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), UDEV_TYPE_MGR))
+#define UDEV_MGR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), UDEV_TYPE_MGR, UdevMgrClass))
+
+typedef struct _UdevMgrClass UdevMgrClass;
+typedef struct _UdevMgr UdevMgr;
+
+struct _UdevMgrClass
+{
+	GObjectClass parent_class;
+};
+
+struct _UdevMgr
+{
+	GObject parent_instance;
+};
+
+GType udev_mgr_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* _UDEV_MGR_H_ */


Follow ups