aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKen VanDine <ken.vandine@canonical.com>2011-07-22 13:41:06 -0400
committerKen VanDine <ken.vandine@canonical.com>2011-07-22 13:41:06 -0400
commit108cec80746510d7f622ad0506a7f3d2a734c3ae (patch)
tree061bd5ba8a897fe82d74a941423192daa3b42a82 /src
parentbd7fb2850d02ae416b2fd2a80f668f25dc861872 (diff)
parenta1a7357b58d182e077ebfe8fb11c083e5eb18839 (diff)
downloadayatana-indicator-session-108cec80746510d7f622ad0506a7f3d2a734c3ae.tar.gz
ayatana-indicator-session-108cec80746510d7f622ad0506a7f3d2a734c3ae.tar.bz2
ayatana-indicator-session-108cec80746510d7f622ad0506a7f3d2a734c3ae.zip
Import upstream version 0.3.0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/Makefile.in104
-rw-r--r--src/apt-transaction.c260
-rw-r--r--src/apt-transaction.h49
-rw-r--r--src/apt-watcher.c337
-rw-r--r--src/apt-watcher.h60
-rw-r--r--src/dbus-shared-names.h18
-rw-r--r--src/device-menu-mgr.c798
-rw-r--r--src/device-menu-mgr.h53
-rw-r--r--src/dialog.c2
-rw-r--r--src/gconf-helper.h6
-rw-r--r--src/gen-session-dbus.xml.c6
-rw-r--r--src/indicator-session.c19
-rw-r--r--src/session-dbus.xml6
-rw-r--r--src/session-service.c777
-rw-r--r--src/udev-mgr.c46
-rw-r--r--src/udev-mgr.h51
-rw-r--r--src/user-menu-mgr.c357
-rw-r--r--src/user-menu-mgr.h53
19 files changed, 2240 insertions, 774 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 71537c5..83d12bb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -91,7 +91,17 @@ indicator_session_service_SOURCES = \
dbusmenu-shared.h \
gconf-helper.c \
users-service-dbus.h \
- users-service-dbus.c
+ users-service-dbus.c \
+ user-menu-mgr.h \
+ user-menu-mgr.c \
+ device-menu-mgr.h \
+ 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/Makefile.in b/src/Makefile.in
index 4b282fd..2ef9128 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -100,7 +100,12 @@ am_indicator_session_service_OBJECTS = \
indicator_session_service-session-dbus.$(OBJEXT) \
indicator_session_service-gen-session-dbus.xml.$(OBJEXT) \
indicator_session_service-gconf-helper.$(OBJEXT) \
- indicator_session_service-users-service-dbus.$(OBJEXT)
+ indicator_session_service-users-service-dbus.$(OBJEXT) \
+ indicator_session_service-user-menu-mgr.$(OBJEXT) \
+ indicator_session_service-device-menu-mgr.$(OBJEXT) \
+ indicator_session_service-apt-watcher.$(OBJEXT) \
+ indicator_session_service-apt-transaction.$(OBJEXT) \
+ indicator_session_service-udev-mgr.$(OBJEXT)
indicator_session_service_OBJECTS = \
$(am_indicator_session_service_OBJECTS)
indicator_session_service_DEPENDENCIES = $(am__DEPENDENCIES_1) \
@@ -337,7 +342,17 @@ indicator_session_service_SOURCES = \
dbusmenu-shared.h \
gconf-helper.c \
users-service-dbus.h \
- users-service-dbus.c
+ users-service-dbus.c \
+ user-menu-mgr.h \
+ user-menu-mgr.c \
+ device-menu-mgr.h \
+ 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) \
@@ -526,11 +541,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_logout_helper-dialog.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_logout_helper-gconf-helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_logout_helper-gtk-logout-helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-apt-transaction.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-apt-watcher.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-device-menu-mgr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-gconf-helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-gen-session-dbus.xml.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-lock-helper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-session-dbus.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-session-service.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-udev-mgr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-user-menu-mgr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-users-service-dbus.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsession_la-indicator-session.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsession_la-user-widget.Plo@am__quote@
@@ -719,6 +739,86 @@ indicator_session_service-users-service-dbus.obj: users-service-dbus.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-users-service-dbus.obj `if test -f 'users-service-dbus.c'; then $(CYGPATH_W) 'users-service-dbus.c'; else $(CYGPATH_W) '$(srcdir)/users-service-dbus.c'; fi`
+indicator_session_service-user-menu-mgr.o: user-menu-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-user-menu-mgr.o -MD -MP -MF $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo -c -o indicator_session_service-user-menu-mgr.o `test -f 'user-menu-mgr.c' || echo '$(srcdir)/'`user-menu-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-user-menu-mgr.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='user-menu-mgr.c' object='indicator_session_service-user-menu-mgr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-user-menu-mgr.o `test -f 'user-menu-mgr.c' || echo '$(srcdir)/'`user-menu-mgr.c
+
+indicator_session_service-user-menu-mgr.obj: user-menu-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-user-menu-mgr.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo -c -o indicator_session_service-user-menu-mgr.obj `if test -f 'user-menu-mgr.c'; then $(CYGPATH_W) 'user-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/user-menu-mgr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-user-menu-mgr.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='user-menu-mgr.c' object='indicator_session_service-user-menu-mgr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-user-menu-mgr.obj `if test -f 'user-menu-mgr.c'; then $(CYGPATH_W) 'user-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/user-menu-mgr.c'; fi`
+
+indicator_session_service-device-menu-mgr.o: device-menu-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-device-menu-mgr.o -MD -MP -MF $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo -c -o indicator_session_service-device-menu-mgr.o `test -f 'device-menu-mgr.c' || echo '$(srcdir)/'`device-menu-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-device-menu-mgr.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='device-menu-mgr.c' object='indicator_session_service-device-menu-mgr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-device-menu-mgr.o `test -f 'device-menu-mgr.c' || echo '$(srcdir)/'`device-menu-mgr.c
+
+indicator_session_service-device-menu-mgr.obj: device-menu-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-device-menu-mgr.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo -c -o indicator_session_service-device-menu-mgr.obj `if test -f 'device-menu-mgr.c'; then $(CYGPATH_W) 'device-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/device-menu-mgr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-device-menu-mgr.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='device-menu-mgr.c' object='indicator_session_service-device-menu-mgr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-device-menu-mgr.obj `if test -f 'device-menu-mgr.c'; then $(CYGPATH_W) 'device-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/device-menu-mgr.c'; fi`
+
+indicator_session_service-apt-watcher.o: apt-watcher.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-watcher.o -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-watcher.Tpo -c -o indicator_session_service-apt-watcher.o `test -f 'apt-watcher.c' || echo '$(srcdir)/'`apt-watcher.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-watcher.Tpo $(DEPDIR)/indicator_session_service-apt-watcher.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='apt-watcher.c' object='indicator_session_service-apt-watcher.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-watcher.o `test -f 'apt-watcher.c' || echo '$(srcdir)/'`apt-watcher.c
+
+indicator_session_service-apt-watcher.obj: apt-watcher.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-watcher.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-watcher.Tpo -c -o indicator_session_service-apt-watcher.obj `if test -f 'apt-watcher.c'; then $(CYGPATH_W) 'apt-watcher.c'; else $(CYGPATH_W) '$(srcdir)/apt-watcher.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-watcher.Tpo $(DEPDIR)/indicator_session_service-apt-watcher.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='apt-watcher.c' object='indicator_session_service-apt-watcher.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-watcher.obj `if test -f 'apt-watcher.c'; then $(CYGPATH_W) 'apt-watcher.c'; else $(CYGPATH_W) '$(srcdir)/apt-watcher.c'; fi`
+
+indicator_session_service-apt-transaction.o: apt-transaction.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-transaction.o -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-transaction.Tpo -c -o indicator_session_service-apt-transaction.o `test -f 'apt-transaction.c' || echo '$(srcdir)/'`apt-transaction.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-transaction.Tpo $(DEPDIR)/indicator_session_service-apt-transaction.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='apt-transaction.c' object='indicator_session_service-apt-transaction.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-transaction.o `test -f 'apt-transaction.c' || echo '$(srcdir)/'`apt-transaction.c
+
+indicator_session_service-apt-transaction.obj: apt-transaction.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-transaction.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-transaction.Tpo -c -o indicator_session_service-apt-transaction.obj `if test -f 'apt-transaction.c'; then $(CYGPATH_W) 'apt-transaction.c'; else $(CYGPATH_W) '$(srcdir)/apt-transaction.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-transaction.Tpo $(DEPDIR)/indicator_session_service-apt-transaction.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='apt-transaction.c' object='indicator_session_service-apt-transaction.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-transaction.obj `if test -f 'apt-transaction.c'; then $(CYGPATH_W) 'apt-transaction.c'; else $(CYGPATH_W) '$(srcdir)/apt-transaction.c'; fi`
+
+indicator_session_service-udev-mgr.o: udev-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-udev-mgr.o -MD -MP -MF $(DEPDIR)/indicator_session_service-udev-mgr.Tpo -c -o indicator_session_service-udev-mgr.o `test -f 'udev-mgr.c' || echo '$(srcdir)/'`udev-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-udev-mgr.Tpo $(DEPDIR)/indicator_session_service-udev-mgr.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='udev-mgr.c' object='indicator_session_service-udev-mgr.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-udev-mgr.o `test -f 'udev-mgr.c' || echo '$(srcdir)/'`udev-mgr.c
+
+indicator_session_service-udev-mgr.obj: udev-mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-udev-mgr.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-udev-mgr.Tpo -c -o indicator_session_service-udev-mgr.obj `if test -f 'udev-mgr.c'; then $(CYGPATH_W) 'udev-mgr.c'; else $(CYGPATH_W) '$(srcdir)/udev-mgr.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-udev-mgr.Tpo $(DEPDIR)/indicator_session_service-udev-mgr.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='udev-mgr.c' object='indicator_session_service-udev-mgr.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-udev-mgr.obj `if test -f 'udev-mgr.c'; then $(CYGPATH_W) 'udev-mgr.c'; else $(CYGPATH_W) '$(srcdir)/udev-mgr.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/src/apt-transaction.c b/src/apt-transaction.c
new file mode 100644
index 0000000..78a0ff2
--- /dev/null
+++ b/src/apt-transaction.c
@@ -0,0 +1,260 @@
+/*
+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;
+ TransactionType type;
+};
+
+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)
+{
+ AptTransaction* self = APT_TRANSACTION(object);
+ g_signal_handlers_disconnect_by_func (G_OBJECT (self->proxy),
+ G_CALLBACK (apt_transaction_receive_signal),
+ self);
+ 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);
+
+ if (self->type == SIMULATION){
+ 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);
+ AptState current_state = DONT_KNOW;
+
+ if (g_strcmp0(signal_name, "PropertyChanged") == 0 && self->type == SIMULATION)
+ {
+ gchar* prop_name= NULL;
+ GVariant* value = NULL;
+ g_variant_get (parameters, "(sv)", &prop_name, &value);
+ g_debug ("transaction prop update - prop = %s", prop_name);
+
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) == TRUE){
+ gchar* key = NULL;
+ g_variant_get (value, "s", &key);
+ g_debug ("transaction prop update - value = %s", key);
+ }
+
+ 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){
+ current_state = UPDATES_AVAILABLE;
+ }
+ else{
+ current_state = UP_TO_DATE;
+ }
+ }
+ }
+ else if (g_strcmp0(signal_name, "PropertyChanged") == 0 &&
+ self->type == REAL)
+ {
+ GVariant* role = g_dbus_proxy_get_cached_property (self->proxy,
+ "Role");
+ if (g_variant_is_of_type (role, G_VARIANT_TYPE_STRING) == TRUE){
+ gchar* current_role = NULL;
+ g_variant_get (role, "s", &current_role);
+ g_debug ("Current transaction role = %s", current_role);
+ if (g_strcmp0 (current_role, "role-commit-packages") == 0 ||
+ g_strcmp0 (current_role, "role-upgrade-system") == 0){
+ g_debug ("UPGRADE IN PROGRESS");
+ current_state = UPGRADE_IN_PROGRESS;
+ }
+ }
+ }
+ else if (g_strcmp0(signal_name, "Finished") == 0)
+ {
+ g_debug ("TRANSACTION Finished");
+ current_state = FINISHED;
+ }
+ // Finally send out the state update
+ if (current_state != DONT_KNOW){
+ g_signal_emit (self,
+ signals[UPDATE],
+ 0,
+ current_state);
+ }
+ 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;
+ }
+}
+TransactionType
+apt_transaction_get_transaction_type (AptTransaction* self)
+{
+ return self->type;
+}
+
+AptTransaction* apt_transaction_new (gchar* transaction_id, TransactionType t)
+{
+ AptTransaction* tr = g_object_new (APT_TYPE_TRANSACTION, NULL);
+ tr->id = transaction_id;
+ tr->type = t;
+ 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..9e4370d
--- /dev/null
+++ b/src/apt-transaction.h
@@ -0,0 +1,49 @@
+/*
+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>
+#include "dbus-shared-names.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, TransactionType t);
+TransactionType apt_transaction_get_transaction_type (AptTransaction* self);
+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..285eb81
--- /dev/null
+++ b/src/apt-watcher.c
@@ -0,0 +1,337 @@
+/*
+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 "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"));
+ // Simulations don't send a finished signal for some reason
+ // Anyway from a simulation we just need one state update
+ // (updates available or not)
+ if (apt_transaction_get_transaction_type (self->current_transaction)
+ == SIMULATION){
+ g_object_unref (G_OBJECT(self->current_transaction));
+ self->current_transaction = NULL;
+ }
+ }
+ else if (state == UPDATES_AVAILABLE){
+ dbusmenu_menuitem_property_set (self->apt_item,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Updates Available…"));
+ // Simulations don't send a finished signal for some reason
+ // Anyway from a simulation we just need one state update
+ // (updates available or not)
+ if (apt_transaction_get_transaction_type (self->current_transaction)
+ == SIMULATION){
+ g_object_unref (G_OBJECT(self->current_transaction));
+ self->current_transaction = NULL;
+ }
+ }
+ else if (state == UPGRADE_IN_PROGRESS){
+ dbusmenu_menuitem_property_set (self->apt_item,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Updates Installing…"));
+ }
+ else if (state == FINISHED){
+ dbusmenu_menuitem_property_set (self->apt_item,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Software Up to Date"));
+ g_object_unref (G_OBJECT(self->current_transaction));
+ self->current_transaction = NULL;
+ }
+ self->current_state = state;
+}
+
+static void
+apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id)
+{
+ if (self->current_transaction == NULL){
+ self->current_transaction = apt_transaction_new (transaction_id, SIMULATION);
+ 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);
+ if (g_str_has_prefix (input, "/org/debian/apt/transaction/") == TRUE){
+ g_debug ("Active Transactions signal - input is null = %i", input == NULL);
+
+ if (self->current_transaction != NULL)
+ {
+ g_object_unref (G_OBJECT(self->current_transaction));
+ self->current_transaction = NULL;
+ }
+
+ self->current_transaction = apt_transaction_new (input, REAL);
+ g_signal_connect (G_OBJECT(self->current_transaction),
+ "state-update",
+ G_CALLBACK(apt_watcher_transaction_state_update_cb), self);
+
+
+ }
+ }
+ 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..d9dfff1 100644
--- a/src/dbus-shared-names.h
+++ b/src/dbus-shared-names.h
@@ -20,9 +20,23 @@ 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 __DBUS_SHARED_NAMES_H__
-#define __DBUS_SHARED_NAMES_H__ 1
+#define __DBUS_SHARED_NAMES_H__
+
+typedef enum {
+ UP_TO_DATE,
+ CHECKING_FOR_UPDATES,
+ UPDATES_AVAILABLE,
+ UPGRADE_IN_PROGRESS,
+ FINISHED,
+ RESTART_NEEDED,
+ DONT_KNOW
+}AptState;
+
+typedef enum {
+ SIMULATION,
+ REAL
+}TransactionType;
#define INDICATOR_USERS_DBUS_NAME INDICATOR_SESSION_DBUS_NAME
#define INDICATOR_USERS_DBUS_OBJECT "/com/canonical/indicator/users/menu"
diff --git a/src/device-menu-mgr.c b/src/device-menu-mgr.c
new file mode 100644
index 0000000..324b3f1
--- /dev/null
+++ b/src/device-menu-mgr.c
@@ -0,0 +1,798 @@
+/*
+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 <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"
+#define UP_INTERFACE "org.freedesktop.UPower"
+
+#define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications"
+
+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 * logout_mi = NULL;
+static DbusmenuMenuitem * restart_mi = NULL;
+static DbusmenuMenuitem * shutdown_mi = NULL;
+
+static gboolean can_hibernate = TRUE;
+static gboolean can_suspend = TRUE;
+static gboolean allow_hibernate = TRUE;
+static gboolean allow_suspend = TRUE;
+
+static DBusGProxy * up_main_proxy = NULL;
+static DBusGProxy * up_prop_proxy = NULL;
+
+static void device_menu_mgr_ensure_gconf_client (DeviceMenuMgr* self);
+static void setup_restart_watch (DeviceMenuMgr* self);
+static void setup_up (DeviceMenuMgr* self);
+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
+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);
+ g_idle_add(lock_screen_setup, NULL);
+}
+
+static void
+device_menu_mgr_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (device_menu_mgr_parent_class)->finalize (object);
+}
+
+// TODO refactor into one helper method for both menu mgrs.
+static void
+device_menu_mgr_class_init (DeviceMenuMgrClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = device_menu_mgr_finalize;
+}
+
+// TODO
+// Is this needed anymore
+static void
+lockdown_changed (GConfClient *client,
+ guint cnxd_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ DeviceMenuMgr* self = DEVICE_MENU_MGR (user_data);
+ GConfValue *value = gconf_entry_get_value (entry);
+ const gchar *key = gconf_entry_get_key (entry);
+
+ if (value == NULL || key == NULL) {
+ return;
+ }
+
+ if (g_strcmp0 (key, LOCKDOWN_KEY_USER) == 0 ||
+ g_strcmp0 (key, LOCKDOWN_KEY_SCREENSAVER) == 0) {
+ device_menu_mgr_rebuild_items(self);
+ }
+
+ return;
+}
+
+static void
+keybinding_changed (GConfClient *client,
+ guint cnxd_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ GConfValue *value = gconf_entry_get_value (entry);
+ const gchar *key = gconf_entry_get_key (entry);
+
+ if (value == NULL || key == NULL) {
+ return;
+ }
+
+ if (g_strcmp0 (key, KEY_LOCK_SCREEN) == 0) {
+ g_debug("Keybinding changed to: %s", gconf_value_get_string(value));
+ if (lock_menuitem != NULL) {
+ dbusmenu_menuitem_property_set_shortcut_string (lock_menuitem,
+ gconf_value_get_string(value));
+ }
+ }
+ return;
+}
+
+/* Check to see if the lockdown key is protecting from
+ locking the screen. If not, lock it. */
+static void
+lock_if_possible (DeviceMenuMgr* self) {
+ device_menu_mgr_ensure_gconf_client (self);
+
+ if (!gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_SCREENSAVER, NULL)) {
+ lock_screen (NULL, 0, NULL);
+ }
+ return;
+}
+
+/* A return from the command to sleep the system. Make sure
+ that we unthrottle the screensaver. */
+static void
+sleep_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
+{
+ screensaver_unthrottle();
+ return;
+}
+
+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,
+ guint timestamp,
+ gpointer userdata)
+{
+ DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata);
+ machine_sleep_with_context (self, "Hibernate");
+}
+
+/* Let's put this machine to sleep, with some info on how
+ it should sleep. */
+static void
+machine_sleep_with_context (DeviceMenuMgr* self, gchar* type)
+{
+ if (up_main_proxy == NULL) {
+ g_warning("Can not %s as no upower proxy", type);
+ }
+
+ screensaver_throttle(type);
+ lock_if_possible (self);
+
+ dbus_g_proxy_begin_call(up_main_proxy,
+ type,
+ sleep_response,
+ NULL,
+ NULL,
+ G_TYPE_INVALID);
+
+ return;
+}
+
+/* A response to getting the suspend property */
+static void
+suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ suspend_call = NULL;
+ DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata);
+
+ GValue candoit = {0};
+ GError * error = NULL;
+ dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID);
+ if (error != NULL) {
+ g_warning("Unable to check suspend: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ g_debug("Got Suspend: %s", g_value_get_boolean(&candoit) ? "true" : "false");
+
+ 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
+ // And add or remove it but just don't rebuild the whole menu
+ // a waste
+ device_menu_mgr_rebuild_items(self);
+ }
+ return;
+}
+
+/* Response to getting the hibernate property */
+static void
+hibernate_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
+{
+ hibernate_call = NULL;
+ DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata);
+
+ GValue candoit = {0};
+ GError * error = NULL;
+ dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID);
+ if (error != NULL) {
+ g_warning("Unable to check hibernate: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ g_debug("Got Hibernate: %s", g_value_get_boolean(&candoit) ? "true" : "false");
+
+ gboolean local_can_hibernate = g_value_get_boolean(&candoit);
+ if (local_can_hibernate != can_hibernate) {
+ can_hibernate = local_can_hibernate;
+ device_menu_mgr_rebuild_items(self);
+ }
+}
+
+/* A signal that we need to recheck to ensure we can still
+ hibernate and/or suspend */
+static void
+up_changed_cb (DBusGProxy * proxy, gpointer user_data)
+{
+ /* Start Async call to see if we can hibernate */
+ if (suspend_call == NULL) {
+ suspend_call = dbus_g_proxy_begin_call(up_prop_proxy,
+ "Get",
+ suspend_prop_cb,
+ user_data,
+ NULL,
+ G_TYPE_STRING,
+ UP_INTERFACE,
+ G_TYPE_STRING,
+ "CanSuspend",
+ G_TYPE_INVALID,
+ G_TYPE_VALUE,
+ G_TYPE_INVALID);
+ }
+
+ /* Start Async call to see if we can suspend */
+ if (hibernate_call == NULL) {
+ hibernate_call = dbus_g_proxy_begin_call(up_prop_proxy,
+ "Get",
+ hibernate_prop_cb,
+ user_data,
+ NULL,
+ G_TYPE_STRING,
+ UP_INTERFACE,
+ G_TYPE_STRING,
+ "CanHibernate",
+ G_TYPE_INVALID,
+ G_TYPE_VALUE,
+ G_TYPE_INVALID);
+ }
+}
+/* Handle the callback from the allow functions to check and
+ see if we're changing the value, and if so, rebuilding the
+ menus based on that info. */
+static void
+allowed_suspend_cb (DBusGProxy *proxy,
+ gboolean OUT_allowed,
+ GError *error,
+ gpointer userdata)
+{
+ if (error != NULL) {
+ g_warning("Unable to get information on what is allowed from UPower: %s",
+ error->message);
+ return;
+ }
+
+ if (OUT_allowed != allow_suspend) {
+ allow_suspend = OUT_allowed;
+ device_menu_mgr_rebuild_items(DEVICE_MENU_MGR (userdata));
+ }
+}
+
+/* Handle the callback from the allow functions to check and
+ see if we're changing the value, and if so, rebuilding the
+ menus based on that info. */
+static void
+allowed_hibernate_cb (DBusGProxy *proxy,
+ gboolean OUT_allowed,
+ GError *error,
+ gpointer userdata)
+{
+ if (error != NULL) {
+ g_warning("Unable to get information on what is allowed from UPower: %s",
+ error->message);
+ return;
+ }
+
+ if (OUT_allowed != allow_hibernate) {
+ allow_hibernate = OUT_allowed;
+ device_menu_mgr_rebuild_items(DEVICE_MENU_MGR (userdata));
+ }
+}
+
+/* This function goes through and sets up what we need for
+ DKp checking. We're even setting up the calls for the props
+ we need */
+static void
+setup_up (DeviceMenuMgr* self) {
+ DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
+ g_return_if_fail(bus != NULL);
+
+ if (up_main_proxy == NULL) {
+ up_main_proxy = dbus_g_proxy_new_for_name(bus,
+ UP_ADDRESS,
+ UP_OBJECT,
+ UP_INTERFACE);
+ }
+ g_return_if_fail(up_main_proxy != NULL);
+
+ if (up_prop_proxy == NULL) {
+ up_prop_proxy = dbus_g_proxy_new_for_name(bus,
+ UP_ADDRESS,
+ UP_OBJECT,
+ DBUS_INTERFACE_PROPERTIES);
+ /* Connect to changed signal */
+ dbus_g_proxy_add_signal(up_main_proxy,
+ "Changed",
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal(up_main_proxy,
+ "Changed",
+ G_CALLBACK(up_changed_cb),
+ self,
+ NULL);
+ }
+ g_return_if_fail(up_prop_proxy != NULL);
+
+
+ /* Force an original "changed" event */
+ up_changed_cb(up_main_proxy, self);
+
+ /* Check to see if these are getting blocked by PolicyKit */
+ org_freedesktop_UPower_suspend_allowed_async(up_main_proxy,
+ allowed_suspend_cb,
+ self);
+ org_freedesktop_UPower_hibernate_allowed_async(up_main_proxy,
+ allowed_hibernate_cb,
+ self);
+
+ return;
+}
+
+/* This is the function to show a dialog on actions that
+ can destroy data. Currently it just calls the GTK version
+ but it seems that in the future it should figure out
+ what's going on and something better. */
+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);
+
+ g_debug("Showing dialog '%s'", dialog_line);
+
+ GError * error = NULL;
+ if (!g_spawn_command_line_async(dialog_line, &error)) {
+ 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);
+ }
+}
+
+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,
+ _("Startup Applications..."));
+ 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);
+ //tmp
+ dbusmenu_menuitem_property_set_bool (scanners_menuitem,
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ FALSE);
+
+ 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);
+ //tmp
+ dbusmenu_menuitem_property_set_bool (webcam_menuitem,
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ FALSE);
+
+ 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);
+ }
+
+ logout_mi = dbusmenu_menuitem_new();
+
+ if (supress_confirmations()) {
+ dbusmenu_menuitem_property_set (logout_mi,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Log Out"));
+ }
+ else {
+ dbusmenu_menuitem_property_set (logout_mi,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Log Out\342\200\246"));
+ }
+ dbusmenu_menuitem_property_set_bool (logout_mi,
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ show_logout());
+ dbusmenu_menuitem_child_append(self->root_item, logout_mi);
+ g_signal_connect( G_OBJECT(logout_mi),
+ 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,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Hibernate"));
+ dbusmenu_menuitem_child_append(self->root_item, hibernate_mi);
+ g_signal_connect (G_OBJECT(hibernate_mi),
+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK(machine_sleep_from_hibernate), self);
+ }
+
+ shutdown_mi = dbusmenu_menuitem_new();
+
+ if (supress_confirmations()) {
+ dbusmenu_menuitem_property_set (shutdown_mi,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Shut Down"));
+ }
+ else {
+ dbusmenu_menuitem_property_set (shutdown_mi,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Shut Down\342\200\246"));
+ }
+ dbusmenu_menuitem_property_set_bool (shutdown_mi,
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ show_shutdown());
+ dbusmenu_menuitem_child_append (self->root_item, shutdown_mi);
+ g_signal_connect (G_OBJECT(shutdown_mi),
+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK(show_dialog), "shutdown");
+
+ RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1);
+ restart_shutdown_logout_mi->logout_mi = logout_mi;
+ restart_shutdown_logout_mi->shutdown_mi = shutdown_mi;
+
+ update_menu_entries(restart_shutdown_logout_mi);
+}
+
+
+static void
+device_menu_mgr_rebuild_items (DeviceMenuMgr* self)
+{
+ dbusmenu_menuitem_property_set_bool (hibernate_mi,
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ can_hibernate && allow_hibernate);
+ dbusmenu_menuitem_property_set_bool (suspend_mi,
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ can_suspend && allow_suspend);
+}
+
+/* When the directory changes we need to figure out how our menu
+ item should look. */
+static void
+restart_dir_changed (gpointer userdata)
+{
+ DeviceMenuMgr* self = DEVICE_MENU_MGR (userdata);
+ gboolean restart_required = g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS);
+
+ if (restart_required) {
+ if (supress_confirmations()) {
+ dbusmenu_menuitem_property_set (restart_mi,
+ RESTART_ITEM_LABEL,
+ _("Restart to Complete Update"));
+ } else {
+ dbusmenu_menuitem_property_set (restart_mi,
+ RESTART_ITEM_LABEL,
+ _("Restart to Complete Update\342\200\246"));
+ }
+ dbusmenu_menuitem_property_set (restart_mi,
+ RESTART_ITEM_ICON,
+ "system-restart-panel");
+ if (self->session_dbus_interface != NULL) {
+ session_dbus_set_name (self->session_dbus_interface, ICON_RESTART);
+ }
+ } else {
+ 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_remove(restart_mi, RESTART_ITEM_ICON);
+ if (self->session_dbus_interface != NULL) {
+ session_dbus_set_name(self->session_dbus_interface, ICON_DEFAULT);
+ }
+ }
+ return;
+}
+
+/* Buids a file watcher for the directory so that when it
+ changes we can check to see if our reboot-required is
+ there. */
+static void
+setup_restart_watch (DeviceMenuMgr* self)
+{
+ GFile * filedir = g_file_new_for_path("/var/run");
+ GFileMonitor * filemon = g_file_monitor_directory(filedir, G_FILE_MONITOR_NONE, NULL, NULL);
+ if (filemon != NULL) {
+ g_signal_connect (G_OBJECT(filemon),
+ "changed",
+ G_CALLBACK(restart_dir_changed),
+ self);
+ }
+ restart_dir_changed(self);
+ return;
+}
+
+/* Ensures that we have a GConf client and if we build one
+ set up the signal handler. */
+static void
+device_menu_mgr_ensure_gconf_client (DeviceMenuMgr* self)
+{
+ if (!gconf_client) {
+ gconf_client = gconf_client_get_default ();
+
+ gconf_client_add_dir(gconf_client, LOCKDOWN_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+ gconf_client_notify_add (gconf_client,
+ LOCKDOWN_DIR,
+ lockdown_changed,
+ self,
+ NULL,
+ NULL);
+
+ gconf_client_add_dir(gconf_client, KEYBINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+ gconf_client_notify_add (gconf_client,
+ KEYBINDING_DIR,
+ keybinding_changed,
+ self,
+ NULL,
+ NULL);
+ }
+}
+
+DbusmenuMenuitem*
+device_mgr_get_root_item (DeviceMenuMgr* self)
+{
+ return self->root_item;
+}
+
+/*
+ * Clean Entry Point
+ */
+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_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
new file mode 100644
index 0000000..503b36a
--- /dev/null
+++ b/src/device-menu-mgr.h
@@ -0,0 +1,53 @@
+/*
+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 _DEVICE_MENU_MGR_H_
+#define _DEVICE_MENU_MGR_H_
+
+#include <glib-object.h>
+
+#include "session-dbus.h"
+
+G_BEGIN_DECLS
+
+#define DEVICE_TYPE_MENU_MGR (device_menu_mgr_get_type ())
+#define DEVICE_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEVICE_TYPE_MENU_MGR, DeviceMenuMgr))
+#define DEVICE_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEVICE_TYPE_MENU_MGR, DeviceMenuMgrClass))
+#define DEVICE_IS_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEVICE_TYPE_MENU_MGR))
+#define DEVICE_IS_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEVICE_TYPE_MENU_MGR))
+#define DEVICE_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEVICE_TYPE_MENU_MGR, DeviceMenuMgrClass))
+
+typedef struct _DeviceMenuMgrClass DeviceMenuMgrClass;
+typedef struct _DeviceMenuMgr DeviceMenuMgr;
+
+struct _DeviceMenuMgrClass
+{
+ GObjectClass parent_class;
+};
+
+GType device_menu_mgr_get_type (void) G_GNUC_CONST;
+
+DeviceMenuMgr* device_menu_mgr_new (SessionDbus* session_dbus);
+
+DbusmenuMenuitem* device_mgr_get_root_item (DeviceMenuMgr* self);
+
+G_END_DECLS
+
+#endif /* _DEVICE_MENU_MGR_H_ */
diff --git a/src/dialog.c b/src/dialog.c
index 9633224..d38f8bf 100644
--- a/src/dialog.c
+++ b/src/dialog.c
@@ -183,6 +183,8 @@ logout_dialog_new (LogoutDialogType type)
"text", _(body_strings[type]),
NULL));
+ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
+
gboolean allowed = FALSE;
if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) {
allowed = ck_check_allowed(LOGOUT_DIALOG_TYPE_RESTART);
diff --git a/src/gconf-helper.h b/src/gconf-helper.h
index 505c24f..039b309 100644
--- a/src/gconf-helper.h
+++ b/src/gconf-helper.h
@@ -39,6 +39,12 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define RESTART_KEY GLOBAL_DIR "/suppress_restart_menuitem"
#define SHUTDOWN_KEY GLOBAL_DIR "/suppress_shutdown_menuitem"
+#define LOCKDOWN_DIR "/desktop/gnome/lockdown"
+#define LOCKDOWN_KEY_USER LOCKDOWN_DIR "/disable_user_switching"
+#define LOCKDOWN_KEY_SCREENSAVER LOCKDOWN_DIR "/disable_lock_screen"
+#define KEYBINDING_DIR "/apps/gnome_settings_daemon/keybindings"
+#define KEY_LOCK_SCREEN KEYBINDING_DIR "/screensaver"
+
typedef struct _RestartShutdownLogoutMenuItems
{
DbusmenuMenuitem * logout_mi;
diff --git a/src/gen-session-dbus.xml.c b/src/gen-session-dbus.xml.c
index 9b20569..a945ca7 100644
--- a/src/gen-session-dbus.xml.c
+++ b/src/gen-session-dbus.xml.c
@@ -9,12 +9,18 @@ const char * _session_dbus =
" <method name=\"GetUserMenuVisibility\">\n"
" <arg name=\"update\" direction=\"out\" type=\"b\"/>\n"
" </method>\n"
+" <method name=\"IsUpdateNeeded\">\n"
+" <arg name=\"update\" direction=\"out\" type=\"b\"/>\n"
+" </method>\n"
" <signal name=\"UserRealNameUpdated\">\n"
" <arg name=\"name\" type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"UserMenuIsVisible\">\n"
" <arg name=\"update\" type=\"b\"/>\n"
" </signal>\n"
+" <signal name=\"RestartNeeded\">\n"
+" <arg name=\"name\" type=\"s\"/>\n"
+" </signal>\n"
" </interface>\n"
"</node>\n"
;
diff --git a/src/indicator-session.c b/src/indicator-session.c
index 068ffef..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,22 +444,19 @@ 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;
- 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);
}
}
@@ -489,18 +486,16 @@ receive_signal (GDBusProxy * proxy,
//Otherwise
self->show_users_entry = update;
-
- 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);
}
}
}
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 fb6ce37..bb473e9 100644
--- a/src/session-service.c
+++ b/src/session-service.c
@@ -37,32 +37,22 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/server.h>
#include <libdbusmenu-glib/menuitem.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 <libindicator/indicator-service.h>
#include "dbus-shared-names.h"
#include "dbusmenu-shared.h"
-
-#include "gconf-helper.h"
-
-#include "session-dbus.h"
#include "users-service-dbus.h"
-#include "lock-helper.h"
-#include "upower-client.h"
-
-#define UP_ADDRESS "org.freedesktop.UPower"
-#define UP_OBJECT "/org/freedesktop/UPower"
-#define UP_INTERFACE "org.freedesktop.UPower"
-
-#define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications"
-
-#define LOCKDOWN_DIR "/desktop/gnome/lockdown"
-#define LOCKDOWN_KEY_USER LOCKDOWN_DIR "/disable_user_switching"
-#define LOCKDOWN_KEY_SCREENSAVER LOCKDOWN_DIR "/disable_lock_screen"
-
-#define KEYBINDING_DIR "/apps/gnome_settings_daemon/keybindings"
-#define KEY_LOCK_SCREEN KEYBINDING_DIR "/screensaver"
+#include "user-menu-mgr.h"
+#include "device-menu-mgr.h"
+#include "session-dbus.h"
typedef struct _ActivateData ActivateData;
struct _ActivateData
@@ -71,672 +61,11 @@ struct _ActivateData
UserData *user;
};
-static UsersServiceDbus *dbus_interface = NULL;
+//static UsersServiceDbus *dbus_interface = NULL;
static SessionDbus *session_dbus = NULL;
-
-static DbusmenuMenuitem *lock_menuitem = NULL;
-static DbusmenuMenuitem *switch_menuitem = NULL;
-
-static DbusmenuMenuitem * session_root_menuitem = NULL;
-static DbusmenuMenuitem * users_root_menuitem = NULL;
-
static GMainLoop * mainloop = NULL;
-static DBusGProxy * up_main_proxy = NULL;
-static DBusGProxy * up_prop_proxy = NULL;
-
-static DBusGProxyCall * suspend_call = NULL;
-static DBusGProxyCall * hibernate_call = NULL;
-
-static DbusmenuMenuitem * hibernate_mi = NULL;
-static DbusmenuMenuitem * suspend_mi = NULL;
-static DbusmenuMenuitem * logout_mi = NULL;
-static DbusmenuMenuitem * restart_mi = NULL;
-static DbusmenuMenuitem * shutdown_mi = NULL;
-
-static gboolean can_hibernate = TRUE;
-static gboolean can_suspend = TRUE;
-static gboolean allow_hibernate = TRUE;
-static gboolean allow_suspend = TRUE;
-
-static GConfClient * gconf_client = NULL;
-
-static void rebuild_session_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
-static void rebuild_user_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
-static void activate_online_accounts (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data);
-
-static void
-lockdown_changed (GConfClient *client,
- guint cnxd_id,
- GConfEntry *entry,
- gpointer user_data)
-{
- GConfValue *value = gconf_entry_get_value (entry);
- const gchar *key = gconf_entry_get_key (entry);
-
- if (value == NULL || key == NULL) {
- return;
- }
-
- if (g_strcmp0 (key, LOCKDOWN_KEY_USER) == 0 || g_strcmp0 (key, LOCKDOWN_KEY_SCREENSAVER) == 0) {
- rebuild_session_items(session_root_menuitem, dbus_interface);
- }
-
- return;
-}
-
-static void
-keybinding_changed (GConfClient *client,
- guint cnxd_id,
- GConfEntry *entry,
- gpointer user_data)
-{
- GConfValue *value = gconf_entry_get_value (entry);
- const gchar *key = gconf_entry_get_key (entry);
-
- if (value == NULL || key == NULL) {
- return;
- }
-
- if (g_strcmp0 (key, KEY_LOCK_SCREEN) == 0) {
- g_debug("Keybinding changed to: %s", gconf_value_get_string(value));
- if (lock_menuitem != NULL) {
- dbusmenu_menuitem_property_set_shortcut_string(lock_menuitem, gconf_value_get_string(value));
- }
- }
- return;
-}
-
-/* Ensures that we have a GConf client and if we build one
- set up the signal handler. */
-static void
-ensure_gconf_client (void)
-{
- if (!gconf_client) {
- gconf_client = gconf_client_get_default ();
-
- gconf_client_add_dir(gconf_client, LOCKDOWN_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
- gconf_client_notify_add(gconf_client, LOCKDOWN_DIR, lockdown_changed, NULL, NULL, NULL);
-
- gconf_client_add_dir(gconf_client, KEYBINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
- gconf_client_notify_add(gconf_client, KEYBINDING_DIR, keybinding_changed, NULL, NULL, NULL);
- }
- return;
-}
-
-/* Check to see if the lockdown key is protecting from
- locking the screen. If not, lock it. */
-static void
-lock_if_possible (void) {
- ensure_gconf_client ();
-
- if (!gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_SCREENSAVER, NULL)) {
- lock_screen(NULL, 0, NULL);
- }
-
- return;
-}
-
-/* A return from the command to sleep the system. Make sure
- that we unthrottle the screensaver. */
-static void
-sleep_response (DBusGProxy * proxy, DBusGProxyCall * call, gpointer data)
-{
- screensaver_unthrottle();
- return;
-}
-
-/* Let's put this machine to sleep, with some info on how
- it should sleep. */
-static void
-machine_sleep (DbusmenuMenuitem * mi, guint timestamp, gpointer userdata)
-{
- gchar * type = (gchar *)userdata;
-
- if (up_main_proxy == NULL) {
- g_warning("Can not %s as no upower proxy", type);
- }
-
- screensaver_throttle(type);
- lock_if_possible();
-
- dbus_g_proxy_begin_call(up_main_proxy,
- type,
- sleep_response,
- NULL,
- NULL,
- G_TYPE_INVALID);
-
- return;
-}
-
-/* A response to getting the suspend property */
-static void
-suspend_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
-{
- suspend_call = NULL;
-
- GValue candoit = {0};
- GError * error = NULL;
- dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID);
- if (error != NULL) {
- g_warning("Unable to check suspend: %s", error->message);
- g_error_free(error);
- return;
- }
- g_debug("Got Suspend: %s", g_value_get_boolean(&candoit) ? "true" : "false");
-
- gboolean local_can_suspend = g_value_get_boolean(&candoit);
- if (local_can_suspend != can_suspend) {
- can_suspend = local_can_suspend;
- rebuild_session_items(session_root_menuitem, dbus_interface);
- }
-
- return;
-}
-
-/* Response to getting the hibernate property */
-static void
-hibernate_prop_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata)
-{
- hibernate_call = NULL;
-
- GValue candoit = {0};
- GError * error = NULL;
- dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &candoit, G_TYPE_INVALID);
- if (error != NULL) {
- g_warning("Unable to check hibernate: %s", error->message);
- g_error_free(error);
- return;
- }
- g_debug("Got Hibernate: %s", g_value_get_boolean(&candoit) ? "true" : "false");
-
- gboolean local_can_hibernate = g_value_get_boolean(&candoit);
- if (local_can_hibernate != can_hibernate) {
- can_hibernate = local_can_hibernate;
- rebuild_session_items(session_root_menuitem, dbus_interface);
- }
-
- return;
-}
-
-/* A signal that we need to recheck to ensure we can still
- hibernate and/or suspend */
-static void
-up_changed_cb (DBusGProxy * proxy, gpointer user_data)
-{
- /* Start Async call to see if we can hibernate */
- if (suspend_call == NULL) {
- suspend_call = dbus_g_proxy_begin_call(up_prop_proxy,
- "Get",
- suspend_prop_cb,
- NULL,
- NULL,
- G_TYPE_STRING,
- UP_INTERFACE,
- G_TYPE_STRING,
- "CanSuspend",
- G_TYPE_INVALID,
- G_TYPE_VALUE,
- G_TYPE_INVALID);
- }
-
- /* Start Async call to see if we can suspend */
- if (hibernate_call == NULL) {
- hibernate_call = dbus_g_proxy_begin_call(up_prop_proxy,
- "Get",
- hibernate_prop_cb,
- NULL,
- NULL,
- G_TYPE_STRING,
- UP_INTERFACE,
- G_TYPE_STRING,
- "CanHibernate",
- G_TYPE_INVALID,
- G_TYPE_VALUE,
- G_TYPE_INVALID);
- }
-
- return;
-}
-
-/* Handle the callback from the allow functions to check and
- see if we're changing the value, and if so, rebuilding the
- menus based on that info. */
-static void
-allowed_cb (DBusGProxy *proxy, gboolean OUT_allowed, GError *error, gpointer userdata)
-{
- if (error != NULL) {
- g_warning("Unable to get information on what is allowed from UPower: %s", error->message);
- return;
- }
-
- gboolean * can_do = (gboolean *)userdata;
-
- if (OUT_allowed != *can_do) {
- *can_do = OUT_allowed;
- rebuild_session_items (session_root_menuitem, dbus_interface);
- }
-}
-
-/* This function goes through and sets up what we need for
- DKp checking. We're even setting up the calls for the props
- we need */
-static void
-setup_up (void) {
- DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
- g_return_if_fail(bus != NULL);
-
- if (up_main_proxy == NULL) {
- up_main_proxy = dbus_g_proxy_new_for_name(bus,
- UP_ADDRESS,
- UP_OBJECT,
- UP_INTERFACE);
- }
- g_return_if_fail(up_main_proxy != NULL);
-
- if (up_prop_proxy == NULL) {
- up_prop_proxy = dbus_g_proxy_new_for_name(bus,
- UP_ADDRESS,
- UP_OBJECT,
- DBUS_INTERFACE_PROPERTIES);
- /* Connect to changed signal */
- dbus_g_proxy_add_signal(up_main_proxy,
- "Changed",
- G_TYPE_INVALID);
-
- dbus_g_proxy_connect_signal(up_main_proxy,
- "Changed",
- G_CALLBACK(up_changed_cb),
- NULL,
- NULL);
- }
- g_return_if_fail(up_prop_proxy != NULL);
- /* Force an original "changed" event */
- up_changed_cb(up_main_proxy, NULL);
-
- /* Check to see if these are getting blocked by PolicyKit */
- org_freedesktop_UPower_suspend_allowed_async(up_main_proxy,
- allowed_cb,
- &allow_suspend);
- org_freedesktop_UPower_hibernate_allowed_async(up_main_proxy,
- allowed_cb,
- &allow_hibernate);
-
- return;
-}
-
-/* This is the function to show a dialog on actions that
- can destroy data. Currently it just calls the GTK version
- but it seems that in the future it should figure out
- what's going on and something better. */
-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);
-
- g_debug("Showing dialog '%s'", dialog_line);
-
- GError * error = NULL;
- if (!g_spawn_command_line_async(dialog_line, &error)) {
- g_warning("Unable to show dialog: %s", error->message);
- g_error_free(error);
- }
-
- g_free(dialog_line);
-
- return;
-}
-
-/* Checks to see if we can create sessions */
-static gboolean
-check_new_session (void)
-{
- return TRUE;
-}
-
-/* Starts a new generic session */
-static void
-activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data)
-{
- lock_if_possible();
-
- users_service_dbus_show_greeter (USERS_SERVICE_DBUS(user_data));
-
- return;
-}
-
-/* Activates a session for a particular user. */
-static void
-activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data)
-{
- UserData *user = (UserData *)user_data;
- UsersServiceDbus *service = user->service;
-
- lock_if_possible();
-
- users_service_dbus_activate_user_session (service, user);
-}
-
-/* Comparison function to look into the UserData struct
- to compare by using the username value */
-static gint
-compare_users_by_username (const gchar *a,
- const gchar *b)
-{
- UserData *user1 = (UserData *)a;
- UserData *user2 = (UserData *)b;
-
- gint retval = g_strcmp0 (user1->real_name, user2->real_name);
-
- /* If they're the same, they're both in conflict. */
- if (retval == 0) {
- user1->real_name_conflict = TRUE;
- user2->real_name_conflict = TRUE;
- }
-
- return retval;
-}
-
-/* Builds up the menu for us */
-static void
-rebuild_user_items (DbusmenuMenuitem *root,
- UsersServiceDbus *service)
-{
- DbusmenuMenuitem *mi = NULL;
- DbusmenuMenuitem *guest_mi = NULL;
- GList *u;
- UserData *user;
- gboolean can_activate;
- GList *children;
-
- /* Make sure we have a valid GConf client, and build one
- if needed */
- ensure_gconf_client ();
-
- /* Check to see which menu items we're allowed to have */
- can_activate = users_service_dbus_can_activate_session (service) &&
- !gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_USER, NULL);
-
- /* Remove the old menu items if that makes sense */
- children = dbusmenu_menuitem_take_children (root);
- g_list_foreach (children, (GFunc)g_object_unref, NULL);
- g_list_free (children);
-
- /* Set to NULL just incase we don't end up building one */
- users_service_dbus_set_guest_item(service, NULL);
-
- /* Build all of the user switching items */
- if (can_activate == TRUE)
- {
- if (check_new_session ()){
- switch_menuitem = dbusmenu_menuitem_new ();
- dbusmenu_menuitem_property_set (switch_menuitem,
- DBUSMENU_MENUITEM_PROP_TYPE,
- MENU_SWITCH_TYPE);
- dbusmenu_menuitem_property_set (switch_menuitem,
- MENU_SWITCH_USER,
- g_get_user_name());
- dbusmenu_menuitem_child_append (root, switch_menuitem);
- g_signal_connect (G_OBJECT (switch_menuitem),
- DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK (activate_new_session),
- service);
- }
-
- GList * users = NULL;
- users = users_service_dbus_get_user_list (service);
- guint user_count = g_list_length(users);
- // g_debug ("USER COUNT = %i", user_count);
- // We only want to show this menu when we have more than one registered
- // user
- session_dbus_set_user_menu_visibility (session_dbus, user_count > 1);
-
- if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) {
- users = g_list_sort (users, (GCompareFunc)compare_users_by_username);
- }
-
- for (u = users; u != NULL; u = g_list_next (u)) {
- user = u->data;
- user->service = service;
-
- g_debug ("%i %s", (gint)user->uid, user->user_name);
-
- if (g_strcmp0(user->user_name, "guest") == 0) {
- /* Check to see if the guest has sessions and so therefore should
- get a check mark. */
- if (user->sessions != NULL) {
- dbusmenu_menuitem_property_set_bool (guest_mi,
- USER_ITEM_PROP_LOGGED_IN,
- TRUE);
- }
- /* If we're showing user accounts, keep going through the list */
- if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) {
- continue;
- }
- /* If not, we can stop here */
- break;
- }
-
- if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) {
- mi = dbusmenu_menuitem_new ();
- dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE);
- if (user->real_name_conflict) {
- gchar * conflictedname = g_strdup_printf("%s (%s)", user->real_name, user->user_name);
- dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, conflictedname);
- g_free(conflictedname);
- } else {
- dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, user->real_name);
- }
- dbusmenu_menuitem_property_set_bool (mi,
- USER_ITEM_PROP_LOGGED_IN,
- user->sessions != NULL);
- if (user->icon_file != NULL && user->icon_file[0] != '\0') {
- dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, user->icon_file);
- } else {
- dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, USER_ITEM_ICON_DEFAULT);
- }
-
- gboolean logged_in = g_strcmp0 (user->user_name, g_get_user_name()) == 0;
- dbusmenu_menuitem_property_set_bool (mi,
- USER_ITEM_PROP_IS_CURRENT_USER,
- logged_in);
- if (logged_in == TRUE){
- g_debug ("about to set the users real name to %s for user %s",
- user->real_name, user->user_name);
- session_dbus_set_users_real_name (session_dbus, user->real_name);
- }
-
- dbusmenu_menuitem_child_append (root, mi);
- g_signal_connect (G_OBJECT (mi),
- DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK (activate_user_session),
- user);
- user->menuitem = mi;
- }
- }
- g_list_free(users);
- }
- // Add the online accounts and separator
- DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (separator1,
- DBUSMENU_MENUITEM_PROP_TYPE,
- DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_child_append (root, separator1);
- DbusmenuMenuitem * online_accounts_item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (online_accounts_item,
- DBUSMENU_MENUITEM_PROP_TYPE,
- DBUSMENU_CLIENT_TYPES_DEFAULT);
- dbusmenu_menuitem_property_set (online_accounts_item,
- DBUSMENU_MENUITEM_PROP_LABEL,
- _("Online Accounts..."));
-
- g_signal_connect (G_OBJECT (online_accounts_item),
- DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK (activate_online_accounts),
- NULL);
-
- dbusmenu_menuitem_child_append (root, online_accounts_item);
-}
-
-// TODO
-// Wait until dialog is complete to find out name to pass
-// to the control centre.
-static void
-activate_online_accounts (DbusmenuMenuitem *mi,
- guint timestamp,
- gpointer user_data)
-{
- GError * error = NULL;
- if (!g_spawn_command_line_async("gnome-control-center online-accounts", &error))
- {
- g_warning("Unable to show control centre: %s", error->message);
- g_error_free(error);
- }
-}
-
-static void
-rebuild_session_items (DbusmenuMenuitem *root,
- UsersServiceDbus *service)
-{
- gboolean can_lockscreen;
-
- /* Make sure we have a valid GConf client, and build one
- if needed */
- ensure_gconf_client ();
-
- 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(root, lock_menuitem);
- }
-
- /* Start going through the session based items. */
-
- logout_mi = dbusmenu_menuitem_new();
- if (supress_confirmations()) {
- dbusmenu_menuitem_property_set (logout_mi,
- DBUSMENU_MENUITEM_PROP_LABEL,
- _("Log Out"));
- } else {
- dbusmenu_menuitem_property_set (logout_mi,
- DBUSMENU_MENUITEM_PROP_LABEL,
- _("Log Out\342\200\246"));
- }
- dbusmenu_menuitem_property_set_bool (logout_mi,
- DBUSMENU_MENUITEM_PROP_VISIBLE,
- show_logout());
- dbusmenu_menuitem_child_append(root, logout_mi);
- g_signal_connect( G_OBJECT(logout_mi),
- 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 (root, suspend_mi);
- g_signal_connect( G_OBJECT(suspend_mi),
- DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK(machine_sleep),
- "Suspend");
- }
-
- if (can_hibernate && allow_hibernate) {
- hibernate_mi = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set (hibernate_mi,
- DBUSMENU_MENUITEM_PROP_LABEL,
- _("Hibernate"));
- dbusmenu_menuitem_child_append(root, hibernate_mi);
- g_signal_connect (G_OBJECT(hibernate_mi),
- DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK(machine_sleep), "Hibernate");
- }
-
- 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(root, 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 {
- dbusmenu_menuitem_property_set (shutdown_mi,
- DBUSMENU_MENUITEM_PROP_LABEL,
- _("Shut Down\342\200\246"));
- }
- dbusmenu_menuitem_property_set_bool (shutdown_mi,
- DBUSMENU_MENUITEM_PROP_VISIBLE,
- show_shutdown());
- dbusmenu_menuitem_child_append (root, shutdown_mi);
- g_signal_connect (G_OBJECT(shutdown_mi),
- DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK(show_dialog), "shutdown");
-
- 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;
-}
-
-/* Signal called when a user is added. It updates the count and
- rebuilds the menu */
-static void
-user_change (UsersServiceDbus *service,
- const gchar *user_id,
- gpointer user_data)
-{
- DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
- rebuild_user_items (root, service);
- return;
-}
-
/* When the service interface starts to shutdown, we
should follow it. */
void
@@ -749,52 +78,6 @@ service_shutdown (IndicatorService * service, gpointer user_data)
return;
}
-/* When the directory changes we need to figure out how our menu
- item should look. */
-static void
-restart_dir_changed (void)
-{
- gboolean restart_required = g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS);
-
- if (restart_required) {
- if (supress_confirmations()) {
- dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_LABEL, _("Restart to Complete Update"));
- } else {
- dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_LABEL, _("Restart to Complete Update\342\200\246"));
- }
- dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_ICON, "system-restart-panel");
- if (session_dbus != NULL) {
- session_dbus_set_name(session_dbus, ICON_RESTART);
- }
- } else {
- 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_remove(restart_mi, RESTART_ITEM_ICON);
- if (session_dbus != NULL) {
- session_dbus_set_name(session_dbus, ICON_DEFAULT);
- }
- }
- return;
-}
-
-/* Buids a file watcher for the directory so that when it
- changes we can check to see if our reboot-required is
- there. */
-static void
-setup_restart_watch (void)
-{
- GFile * filedir = g_file_new_for_path("/var/run");
- GFileMonitor * filemon = g_file_monitor_directory(filedir, G_FILE_MONITOR_NONE, NULL, NULL);
- if (filemon != NULL) {
- g_signal_connect(G_OBJECT(filemon), "changed", G_CALLBACK(restart_dir_changed), NULL);
- }
- restart_dir_changed();
- return;
-}
-
/* Main, is well, main. It brings everything up and throws
us into the mainloop of no return. */
int
@@ -810,41 +93,21 @@ main (int argc, char ** argv)
IndicatorService * service = indicator_service_new_version (INDICATOR_SESSION_DBUS_NAME,
INDICATOR_SESSION_DBUS_VERSION);
- g_signal_connect(G_OBJECT(service),
- INDICATOR_SERVICE_SIGNAL_SHUTDOWN,
- G_CALLBACK(service_shutdown), NULL);
+ g_signal_connect (G_OBJECT(service),
+ INDICATOR_SERVICE_SIGNAL_SHUTDOWN,
+ G_CALLBACK(service_shutdown), NULL);
session_dbus = session_dbus_new();
- g_idle_add(lock_screen_setup, NULL);
-
- session_root_menuitem = dbusmenu_menuitem_new();
- g_debug("Session Root ID: %d", dbusmenu_menuitem_get_id(session_root_menuitem));
-
- dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL);
-
- rebuild_session_items (session_root_menuitem, dbus_interface);
-
+ // Devices
+ DeviceMenuMgr* device_mgr = device_menu_mgr_new (session_dbus);
DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT);
- dbusmenu_server_set_root(server, session_root_menuitem);
+ dbusmenu_server_set_root(server, device_mgr_get_root_item (device_mgr));
- users_root_menuitem = dbusmenu_menuitem_new();
- rebuild_user_items (users_root_menuitem, dbus_interface);
- g_signal_connect (G_OBJECT (dbus_interface),
- "user-added",
- G_CALLBACK (user_change),
- users_root_menuitem);
- g_signal_connect (G_OBJECT (dbus_interface),
- "user-removed",
- G_CALLBACK (user_change),
- users_root_menuitem);
-
- setup_restart_watch();
-
- setup_up();
-
- DbusmenuServer * users_server = dbusmenu_server_new (INDICATOR_USERS_DBUS_OBJECT);
- dbusmenu_server_set_root (users_server, users_root_menuitem);
+ // Users
+ UserMenuMgr* user_mgr = user_menu_mgr_new (session_dbus);
+ DbusmenuServer* users_server = dbusmenu_server_new (INDICATOR_USERS_DBUS_OBJECT);
+ dbusmenu_server_set_root (users_server, user_mgr_get_root_item (user_mgr));
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
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_ */
diff --git a/src/user-menu-mgr.c b/src/user-menu-mgr.c
new file mode 100644
index 0000000..611bcc7
--- /dev/null
+++ b/src/user-menu-mgr.c
@@ -0,0 +1,357 @@
+/*
+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 <libdbusmenu-glib/client.h>
+
+#include "user-menu-mgr.h"
+#include "gconf-helper.h"
+#include "dbus-shared-names.h"
+#include "dbusmenu-shared.h"
+#include "lock-helper.h"
+#include "users-service-dbus.h"
+
+static GConfClient * gconf_client = NULL;
+static DbusmenuMenuitem *switch_menuitem = NULL;
+
+struct _UserMenuMgr
+{
+ GObject parent_instance;
+ UsersServiceDbus* users_dbus_interface;
+ DbusmenuMenuitem* root_item;
+ gint user_count;
+ SessionDbus* session_dbus_interface;
+};
+
+static void activate_new_session (DbusmenuMenuitem * mi,
+ guint timestamp,
+ gpointer user_data);
+static void activate_user_session (DbusmenuMenuitem *mi,
+ guint timestamp,
+ gpointer user_data);
+static gint compare_users_by_username (const gchar *a,
+ const gchar *b);
+static void activate_online_accounts (DbusmenuMenuitem *mi,
+ guint timestamp,
+ gpointer user_data);
+static void user_menu_mgr_rebuild_items (UserMenuMgr *self);
+static gboolean check_new_session ();
+static void user_change (UsersServiceDbus *service,
+ const gchar *user_id,
+ gpointer user_data);
+
+static void ensure_gconf_client ();
+
+G_DEFINE_TYPE (UserMenuMgr, user_menu_mgr, G_TYPE_OBJECT);
+
+
+static void
+user_menu_mgr_init (UserMenuMgr *self)
+{
+ self->users_dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL);
+ self->root_item = dbusmenu_menuitem_new ();
+ g_signal_connect (G_OBJECT (self->users_dbus_interface),
+ "user-added",
+ G_CALLBACK (user_change),
+ self);
+ g_signal_connect (G_OBJECT (self->users_dbus_interface),
+ "user-removed",
+ G_CALLBACK (user_change),
+ self);
+}
+
+static void
+user_menu_mgr_finalize (GObject *object)
+{
+ /* TODO: Add deinitalization code here */
+ G_OBJECT_CLASS (user_menu_mgr_parent_class)->finalize (object);
+}
+
+static void
+user_menu_mgr_class_init (UserMenuMgrClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ //GObjectClass* parent_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = user_menu_mgr_finalize;
+}
+
+/* Builds up the menu for us */
+static void
+user_menu_mgr_rebuild_items (UserMenuMgr *self)
+{
+ DbusmenuMenuitem *mi = NULL;
+ DbusmenuMenuitem *guest_mi = NULL;
+ GList *u;
+ UserData *user;
+ gboolean can_activate;
+ GList *children;
+
+ /* Make sure we have a valid GConf client, and build one
+ if needed */
+ ensure_gconf_client ();
+
+ /* Check to see which menu items we're allowed to have */
+ can_activate = users_service_dbus_can_activate_session (self->users_dbus_interface) &&
+ !gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_USER, NULL);
+
+ /* Remove the old menu items if that makes sense */
+ children = dbusmenu_menuitem_take_children (self->root_item);
+ g_list_foreach (children, (GFunc)g_object_unref, NULL);
+ g_list_free (children);
+
+ /* Set to NULL just incase we don't end up building one */
+ users_service_dbus_set_guest_item(self->users_dbus_interface, NULL);
+
+ /* Build all of the user switching items */
+ if (can_activate == TRUE)
+ {
+ if (check_new_session ()){
+ switch_menuitem = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_property_set (switch_menuitem,
+ DBUSMENU_MENUITEM_PROP_TYPE,
+ MENU_SWITCH_TYPE);
+ dbusmenu_menuitem_property_set (switch_menuitem,
+ MENU_SWITCH_USER,
+ g_get_user_name());
+ dbusmenu_menuitem_child_append (self->root_item, switch_menuitem);
+ g_signal_connect (G_OBJECT (switch_menuitem),
+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK (activate_new_session),
+ self->users_dbus_interface);
+ }
+
+ GList * users = NULL;
+ users = users_service_dbus_get_user_list (self->users_dbus_interface);
+ self->user_count = g_list_length(users);
+
+ g_debug ("USER COUNT = %i", self->user_count);
+ session_dbus_set_user_menu_visibility (self->session_dbus_interface, self->user_count > 1);
+
+ if (self->user_count > MINIMUM_USERS && self->user_count < MAXIMUM_USERS) {
+ users = g_list_sort (users, (GCompareFunc)compare_users_by_username);
+ }
+
+ for (u = users; u != NULL; u = g_list_next (u)) {
+ user = u->data;
+ user->service = self->users_dbus_interface;
+
+ g_debug ("%i %s", (gint)user->uid, user->user_name);
+
+ if (g_strcmp0(user->user_name, "guest") == 0) {
+ /* Check to see if the guest has sessions and so therefore should
+ get a check mark. */
+ if (user->sessions != NULL) {
+ dbusmenu_menuitem_property_set_bool (guest_mi,
+ USER_ITEM_PROP_LOGGED_IN,
+ TRUE);
+ }
+ /* If we're showing user accounts, keep going through the list */
+ if (self->user_count > MINIMUM_USERS && self->user_count < MAXIMUM_USERS) {
+ continue;
+ }
+ /* If not, we can stop here */
+ break;
+ }
+
+ if (self->user_count > MINIMUM_USERS && self->user_count < MAXIMUM_USERS) {
+ mi = dbusmenu_menuitem_new ();
+ dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE);
+ if (user->real_name_conflict) {
+ gchar * conflictedname = g_strdup_printf("%s (%s)", user->real_name, user->user_name);
+ dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, conflictedname);
+ g_free(conflictedname);
+ } else {
+ dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, user->real_name);
+ }
+ dbusmenu_menuitem_property_set_bool (mi,
+ USER_ITEM_PROP_LOGGED_IN,
+ user->sessions != NULL);
+ if (user->icon_file != NULL && user->icon_file[0] != '\0') {
+ dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, user->icon_file);
+ } else {
+ dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, USER_ITEM_ICON_DEFAULT);
+ }
+
+ gboolean logged_in = g_strcmp0 (user->user_name, g_get_user_name()) == 0;
+ dbusmenu_menuitem_property_set_bool (mi,
+ USER_ITEM_PROP_IS_CURRENT_USER,
+ logged_in);
+ if (logged_in == TRUE){
+ g_debug ("about to set the users real name to %s for user %s",
+ user->real_name, user->user_name);
+ session_dbus_set_users_real_name (self->session_dbus_interface, user->real_name);
+ }
+
+ dbusmenu_menuitem_child_append (self->root_item, mi);
+ g_signal_connect (G_OBJECT (mi),
+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK (activate_user_session),
+ user);
+ user->menuitem = mi;
+ }
+ }
+ g_list_free(users);
+ }
+ // Add the online accounts and separator
+ DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (separator1,
+ DBUSMENU_MENUITEM_PROP_TYPE,
+ DBUSMENU_CLIENT_TYPES_SEPARATOR);
+ dbusmenu_menuitem_child_append (self->root_item, separator1);
+ DbusmenuMenuitem * online_accounts_item = dbusmenu_menuitem_new();
+ dbusmenu_menuitem_property_set (online_accounts_item,
+ DBUSMENU_MENUITEM_PROP_TYPE,
+ DBUSMENU_CLIENT_TYPES_DEFAULT);
+ dbusmenu_menuitem_property_set (online_accounts_item,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Online Accounts..."));
+
+ g_signal_connect (G_OBJECT (online_accounts_item),
+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+ G_CALLBACK (activate_online_accounts),
+ NULL);
+
+ dbusmenu_menuitem_child_append (self->root_item, online_accounts_item);
+}
+
+/* Checks to see if we can create sessions */
+// TODO what is this ?
+static gboolean
+check_new_session ()
+{
+ return TRUE;
+}
+
+/* Check to see if the lockdown key is protecting from
+ locking the screen. If not, lock it. */
+static void
+lock_if_possible (void) {
+ ensure_gconf_client ();
+
+ if (!gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_SCREENSAVER, NULL)) {
+ lock_screen(NULL, 0, NULL);
+ }
+
+ return;
+}
+
+
+/* Starts a new generic session */
+static void
+activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data)
+{
+ lock_if_possible();
+
+ users_service_dbus_show_greeter (USERS_SERVICE_DBUS(user_data));
+
+ return;
+}
+
+/* Activates a session for a particular user. */
+static void
+activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data)
+{
+ UserData *user = (UserData *)user_data;
+ UsersServiceDbus *service = user->service;
+
+ lock_if_possible();
+
+ users_service_dbus_activate_user_session (service, user);
+}
+
+/* Comparison function to look into the UserData struct
+ to compare by using the username value */
+static gint
+compare_users_by_username (const gchar *a,
+ const gchar *b)
+{
+ UserData *user1 = (UserData *)a;
+ UserData *user2 = (UserData *)b;
+
+ gint retval = g_strcmp0 (user1->real_name, user2->real_name);
+
+ /* If they're the same, they're both in conflict. */
+ if (retval == 0) {
+ user1->real_name_conflict = TRUE;
+ user2->real_name_conflict = TRUE;
+ }
+
+ return retval;
+}
+
+// TODO
+// Wait until dialog is complete to find out name to pass
+// to the control centre.
+static void
+activate_online_accounts (DbusmenuMenuitem *mi,
+ guint timestamp,
+ gpointer user_data)
+{
+ GError * error = NULL;
+ if (!g_spawn_command_line_async("gnome-control-center online-accounts", &error))
+ {
+ g_warning("Unable to show control centre: %s", error->message);
+ g_error_free(error);
+ }
+}
+
+/* Signal called when a user is added. It updates the count and
+ rebuilds the menu */
+static void
+user_change (UsersServiceDbus *service,
+ const gchar *user_id,
+ gpointer user_data)
+{
+ //DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
+ // TODO sort this out.
+ //rebuild_user_items (root, service);
+ return;
+}
+
+/* Ensures that we have a GConf client and if we build one
+ set up the signal handler. */
+static void
+ensure_gconf_client ()
+{
+ if (!gconf_client) {
+ gconf_client = gconf_client_get_default ();
+ gconf_client_add_dir (gconf_client, LOCKDOWN_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+ gconf_client_add_dir (gconf_client, KEYBINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+ }
+}
+
+DbusmenuMenuitem*
+user_mgr_get_root_item (UserMenuMgr* self)
+{
+ return self->root_item;
+}
+
+
+/*
+ * Clean Entry Point
+ */
+UserMenuMgr* user_menu_mgr_new (SessionDbus* session_dbus)
+{
+ UserMenuMgr* user_mgr = g_object_new (USER_TYPE_MENU_MGR, NULL);
+ user_mgr->session_dbus_interface = session_dbus;
+ user_menu_mgr_rebuild_items (user_mgr);
+ return user_mgr;
+}
+
+
diff --git a/src/user-menu-mgr.h b/src/user-menu-mgr.h
new file mode 100644
index 0000000..ff2cb77
--- /dev/null
+++ b/src/user-menu-mgr.h
@@ -0,0 +1,53 @@
+/*
+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 _USER_MENU_MGR_H_
+#define _USER_MENU_MGR_H_
+
+
+#include <glib-object.h>
+#include <libdbusmenu-gtk3/menuitem.h>
+
+#include "session-dbus.h"
+
+G_BEGIN_DECLS
+
+#define USER_TYPE_MENU_MGR (user_menu_mgr_get_type ())
+#define USER_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), USER_TYPE_MENU_MGR, UserMenuMgr))
+#define USER_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), USER_TYPE_MENU_MGR, UserMenuMgrClass))
+#define USER_IS_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), USER_TYPE_MENU_MGR))
+#define USER_IS_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), USER_TYPE_MENU_MGR))
+#define USER_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), USER_TYPE_MENU_MGR, UserMenuMgrClass))
+
+typedef struct _UserMenuMgrClass UserMenuMgrClass;
+typedef struct _UserMenuMgr UserMenuMgr;
+
+struct _UserMenuMgrClass
+{
+ GObjectClass parent_class;
+};
+
+GType user_menu_mgr_get_type (void) G_GNUC_CONST;
+UserMenuMgr* user_menu_mgr_new (SessionDbus* session_dbus);
+
+DbusmenuMenuitem* user_mgr_get_root_item (UserMenuMgr* self);
+G_END_DECLS
+
+#endif /* _USER_MENU_MGR_H_ */