diff options
author | Conor Curran <conor.curran@canonical.com> | 2011-07-22 17:44:04 +0100 |
---|---|---|
committer | Conor Curran <conor.curran@canonical.com> | 2011-07-22 17:44:04 +0100 |
commit | 15469febca3b4730bc4f3a403f114235b3c4a18b (patch) | |
tree | 8e62e72b96185a5f0c6715e133061d31c0f2f0e4 | |
parent | cf52e8764eb985e1b86b97962a9fd7b4400b8eb3 (diff) | |
parent | ae4e70778e02f44c68a5860d701f216cefe58cd3 (diff) | |
download | ayatana-indicator-session-15469febca3b4730bc4f3a403f114235b3c4a18b.tar.gz ayatana-indicator-session-15469febca3b4730bc4f3a403f114235b3c4a18b.tar.bz2 ayatana-indicator-session-15469febca3b4730bc4f3a403f114235b3c4a18b.zip |
Device menu torn apart and put back together, apt communication up and going
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/apt-transaction.c | 224 | ||||
-rw-r--r-- | src/apt-transaction.h | 48 | ||||
-rw-r--r-- | src/apt-watcher.c | 308 | ||||
-rw-r--r-- | src/apt-watcher.h | 60 | ||||
-rw-r--r-- | src/dbus-shared-names.h | 9 | ||||
-rw-r--r-- | src/device-menu-mgr.c | 288 | ||||
-rw-r--r-- | src/device-menu-mgr.h | 1 | ||||
-rw-r--r-- | src/indicator-session.c | 7 | ||||
-rw-r--r-- | src/session-dbus.xml | 6 | ||||
-rw-r--r-- | src/session-service.c | 5 | ||||
-rw-r--r-- | src/udev-mgr.c | 46 | ||||
-rw-r--r-- | src/udev-mgr.h | 51 |
13 files changed, 976 insertions, 85 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2230910..83d12bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,7 +95,13 @@ indicator_session_service_SOURCES = \ 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) \ diff --git a/src/apt-transaction.c b/src/apt-transaction.c new file mode 100644 index 0000000..51a5ce9 --- /dev/null +++ b/src/apt-transaction.c @@ -0,0 +1,224 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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); +static void apt_transaction_finish_proxy_setup (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + +struct _AptTransaction +{ + GObject parent_instance; + GDBusProxy * proxy; + GCancellable * proxy_cancel; + 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; + self->proxy_cancel = g_cancellable_new(); +} + +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); +} +// TODO: you don't need this additional helper +// Just GObject properties properly +static void +apt_transaction_investigate (AptTransaction* self) +{ + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.debian.apt", + self->id, + "org.debian.apt.transaction", + self->proxy_cancel, + apt_transaction_finish_proxy_setup, + self); +} + +static void +apt_transaction_finish_proxy_setup (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_return_if_fail (APT_IS_TRANSACTION (user_data)); + AptTransaction* self = APT_TRANSACTION(user_data); + GError * error = 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; + + 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); + } + } + } + g_variant_unref (parameters); +} + +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; +} diff --git a/src/apt-transaction.h b/src/apt-transaction.h new file mode 100644 index 0000000..dec62ef --- /dev/null +++ b/src/apt-transaction.h @@ -0,0 +1,48 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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_ */ diff --git a/src/apt-watcher.c b/src/apt-watcher.c new file mode 100644 index 0000000..546c733 --- /dev/null +++ b/src/apt-watcher.c @@ -0,0 +1,308 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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; +} + diff --git a/src/apt-watcher.h b/src/apt-watcher.h new file mode 100644 index 0000000..7b98a44 --- /dev/null +++ b/src/apt-watcher.h @@ -0,0 +1,60 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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 <gtk/gtk.h> +#if GTK_CHECK_VERSION(3, 0, 0) +#include <libdbusmenu-gtk3/menuitem.h> +#else +#include <libdbusmenu-gtk/menuitem.h> +#endif + +#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_ */ diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h index c4ccd05..13ad227 100644 --- a/src/dbus-shared-names.h +++ b/src/dbus-shared-names.h @@ -20,6 +20,15 @@ You should have received a copy of the GNU General Public License along 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 diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c index 0114b92..b13b2fa 100644 --- a/src/device-menu-mgr.c +++ b/src/device-menu-mgr.c @@ -17,12 +17,17 @@ 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 <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 @@ struct _DeviceMenuMgr 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 device_menu_mgr_rebuild_items (DeviceMenuMgr *self); 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 @@ device_menu_mgr_class_init (DeviceMenuMgrClass *klass) 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 @@ sleep_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data) 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 @@ machine_sleep_with_context (DeviceMenuMgr* self, gchar* type) } /* 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 @@ suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) 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 @@ setup_up (DeviceMenuMgr* self) { 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 @@ show_dialog (DbusmenuMenuitem * mi, guint timestamp, gchar * type) g_warning("Unable to show dialog: %s", error->message); g_error_free(error); } + 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); + } +} - g_free(dialog_line); +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); - return; -} + 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_rebuild_items (DeviceMenuMgr* self) +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 @@ device_menu_mgr_rebuild_items (DeviceMenuMgr* self) 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 @@ device_menu_mgr_rebuild_items (DeviceMenuMgr* self) 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 @@ device_menu_mgr_rebuild_items (DeviceMenuMgr* self) 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); + update_menu_entries(restart_shutdown_logout_mi); +} + - return; +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_menu_mgr_new (SessionDbus* session_dbus) { 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; } diff --git a/src/device-menu-mgr.h b/src/device-menu-mgr.h index caa9aee..503b36a 100644 --- a/src/device-menu-mgr.h +++ b/src/device-menu-mgr.h @@ -22,7 +22,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #define _DEVICE_MENU_MGR_H_ #include <glib-object.h> -#include <libdbusmenu-gtk3/menuitem.h> #include "session-dbus.h" diff --git a/src/indicator-session.c b/src/indicator-session.c index af4e2eb..d7155f6 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -6,7 +6,8 @@ Copyright 2009 Canonical Ltd. Authors: Ted Gould <ted@canonical.com> - + Conor Curran <conor.curran@canonical.com> + 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 @@ You should have received a copy of the GNU General Public License along 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 @@ -444,8 +444,7 @@ user_menu_visibility_get_cb (GObject* obj, GAsyncResult* res, gpointer user_data // If it is what we had before no need to do anything... if (self->show_users_entry == update){ return; - } - + } //Otherwise self->show_users_entry = update; diff --git a/src/session-dbus.xml b/src/session-dbus.xml index f496ff1..c42aca8 100644 --- a/src/session-dbus.xml +++ b/src/session-dbus.xml @@ -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> diff --git a/src/session-service.c b/src/session-service.c index 8bdd0c1..bb473e9 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -52,12 +52,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #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 diff --git a/src/udev-mgr.c b/src/udev-mgr.c new file mode 100644 index 0000000..6575ca5 --- /dev/null +++ b/src/udev-mgr.c @@ -0,0 +1,46 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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; +} + diff --git a/src/udev-mgr.h b/src/udev-mgr.h new file mode 100644 index 0000000..1c5ae73 --- /dev/null +++ b/src/udev-mgr.h @@ -0,0 +1,51 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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_ */ |