aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS3
-rw-r--r--ChangeLog152
-rwxr-xr-xconfigure355
-rw-r--r--configure.ac48
-rw-r--r--debian/changelog6
-rw-r--r--po/POTFILES.in3
-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
25 files changed, 2735 insertions, 846 deletions
diff --git a/AUTHORS b/AUTHORS
index 27c2c48..2800da5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,15 +4,18 @@
Christoph Korn
Cody Russell
Conor Curran
+ Daniel van Vugt
David Barth
Gabor Kelemen
Ken VanDine
Kyle Nitzsche
Luke Yelavich
Marc Deslauriers
+ Marco Trevisan (Treviño)
Martin Pitt
Matthew Rasmus
Michael Terry
+ Neil Jagdish Patel
Robert Ancell
Ted Gould
vish
diff --git a/ChangeLog b/ChangeLog
index 6fd66a4..bec896c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,157 @@
# Generated by Makefile. Do not edit.
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ uncomment the disconnect method
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ moving to 0.3.0
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ added new files to the po index
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ bumped version in configure ac in prep for release
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ apt item partially working
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ apt progress now reflected dynamically in the menu
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ transaction object now properly disposed of
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ suspend plugged back in plus both it and hibernate menuitems should now be sensitive to changes coming from upower
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ Device menu torn apart and put back together, apt communication up and going
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ fixed issues
+
+2011-07-21 Conor Curran <conor.curran@canonical.com>
+
+ apt transactions working nicely
+
+2011-07-21 Conor Curran <conor.curran@canonical.com>
+
+ apt item now sensitive to updates available
+
+2011-07-21 Conor Curran <conor.curran@canonical.com>
+
+ properties changed signal is being triggered
+
+2011-07-21 Conor Curran <conor.curran@canonical.com>
+
+ transaction object in place
+
+2011-07-21 Conor Curran <conor.curran@canonical.com>
+
+ trying to figure out if upgrades are needed in progress
+
+2011-07-20 Conor Curran <conor.curran@canonical.com>
+
+ signals and methods from apt are working somewhat
+
+2011-07-20 Conor Curran <conor.curran@canonical.com>
+
+ apt watcher now controlling menuitem with signals and methods in place
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ apt watcher coming along nicely
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ all items in place, now for the gudev backend
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ settings dialog in place
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ system added to device menu, more tidying as we go
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ add the udev mgr files
+
+2011-07-22 Conor Curran <conor.curran@canonical.com>
+
+ merged Neil's pointer fix
+
+2011-07-21 Neil Jagdish Patel <neil.patel@canonical.com>
+
+ Always send the actual pointers to the entry not pointers to copies
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ merged in the device menu split out
+
+2011-07-18 Conor Curran <conor.curran@canonical.com>
+
+ device menu has been isolated
+
+2011-07-18 Conor Curran <conor.curran@canonical.com>
+
+ session menu mgr in progress
+
+2011-07-19 Conor Curran <conor.curran@canonical.com>
+
+ merged dialog behaviour fix
+
+2011-07-08 Daniel van Vugt <vanvugt@gmail.com>
+
+ Keep Log Out / Restart / Shut Down dialogs on top (LP: #807357)
+
+2011-07-18 Conor Curran <conor.curran@canonical.com>
+
+ user menu abstracted
+
+2011-07-15 Conor Curran <conor.curran@canonical.com>
+
+ user menu nicely separated for now, next the session menu
+
+2011-07-15 Conor Curran <conor.curran@canonical.com>
+
+ first step - it compiles
+
+2011-07-15 Conor Curran <conor.curran@canonical.com>
+
+ please tidy up that user manager
+
+2011-07-15 Conor Curran <conor.curran@canonical.com>
+
+ please tidy up that user manager
+
+2011-07-18 Conor Curran <conor.curran@canonical.com>
+
+ merged Trevino's gtk2 compilation fix
+
+2011-07-09 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ configure.ac: include the indicator dir in output
+
+2011-07-09 Marco Trevisan (Treviño) <mail@3v1n0.net>
+
+ Get support for gtk+2.0 back
+
+ indicator-session can still be compiled with gtk, using the
+ --with-gtk=2 configure flag (I've changed it to match the
+ other indicators).
+
2011-07-14 Conor Curran <conor.curran@canonical.com>
bumped release version
diff --git a/configure b/configure
index 1b88e0d..091054b 100755
--- a/configure
+++ b/configure
@@ -803,7 +803,7 @@ with_gnu_ld
with_sysroot
enable_libtool_lock
enable_silent_rules
-with_indicator_gtk
+with_gtk
with_gconf_source
with_gconf_schema_file_dir
enable_schemas_install
@@ -1472,7 +1472,7 @@ Optional Packages:
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-sysroot=DIR Search for dependent libraries within DIR
(or the compiler's sysroot if not specified).
- --with-indicator-gtk Which version of gtk to use for the indicator
+ --with-gtk Which version of gtk to use for the indicator
[default=3]
--with-gconf-source=sourceaddress
Config database for installing schema files.
@@ -2759,7 +2759,7 @@ fi
# Define the identity of the package.
PACKAGE=indicator-session
- VERSION=0.2.93
+ VERSION=0.3.0
cat >>confdefs.h <<_ACEOF
@@ -12780,11 +12780,11 @@ DBUSMENUGTK_REQUIRED_VERSION=0.3.91
POLKIT_REQUIRED_VERSION=0.92
-# Check whether --with-indicator-gtk was given.
-if test "${with_indicator_gtk+set}" = set; then :
- withval=$with_indicator_gtk;
+# Check whether --with-gtk was given.
+if test "${with_gtk+set}" = set; then :
+ withval=$with_gtk;
else
- with_indicator_gtk=3
+ with_gtk=3
fi
@@ -12908,7 +12908,7 @@ $as_echo "no" >&6; }
PKG_CONFIG=""
fi
fi
-if test "x$with_indicator_gtk" = x3; then :
+if test "x$with_gtk" = x3; then :
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for APPLET" >&5
@@ -13019,7 +13019,7 @@ $as_echo "yes" >&6; }
fi
-elif test "x$with_indicator_gtk" = x2; then :
+elif test "x$with_gtk" = x2; then :
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for APPLET" >&5
@@ -13142,6 +13142,7 @@ fi
DBUSMENUGLIB_REQUIRED_VERSION=0.1.1
+if test "x$with_gtk" = x3; then :
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SESSIONSERVICE" >&5
@@ -13152,23 +13153,23 @@ if test -n "$SESSIONSERVICE_CFLAGS"; then
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbusmenu-glib-0.4 >= \$DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= \$DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= \$INDICATOR_REQUIRED_VERSION\""; } >&5
+ dbusmenu-gtk3-0.4 >= \$DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= \$INDICATOR_REQUIRED_VERSION\""; } >&5
($PKG_CONFIG --exists --print-errors "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION") 2>&5
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_SESSIONSERVICE_CFLAGS=`$PKG_CONFIG --cflags "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>/dev/null`
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -13181,23 +13182,23 @@ if test -n "$SESSIONSERVICE_LIBS"; then
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbusmenu-glib-0.4 >= \$DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= \$DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= \$INDICATOR_REQUIRED_VERSION\""; } >&5
+ dbusmenu-gtk3-0.4 >= \$DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= \$INDICATOR_REQUIRED_VERSION\""; } >&5
($PKG_CONFIG --exists --print-errors "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION") 2>&5
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_SESSIONSERVICE_LIBS=`$PKG_CONFIG --libs "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>/dev/null`
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -13219,25 +13220,25 @@ else
fi
if test $_pkg_short_errors_supported = yes; then
SESSIONSERVICE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>&1`
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>&1`
else
SESSIONSERVICE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>&1`
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$SESSIONSERVICE_PKG_ERRORS" >&5
as_fn_error $? "Package requirements (dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION) were not met:
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION) were not met:
$SESSIONSERVICE_PKG_ERRORS
@@ -13270,10 +13271,143 @@ $as_echo "yes" >&6; }
fi
+elif test "x$with_gtk" = x2; then :
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SESSIONSERVICE" >&5
+$as_echo_n "checking for SESSIONSERVICE... " >&6; }
+
+if test -n "$SESSIONSERVICE_CFLAGS"; then
+ pkg_cv_SESSIONSERVICE_CFLAGS="$SESSIONSERVICE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbusmenu-glib-0.4 >= \$DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= \$DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= \$INDICATOR_REQUIRED_VERSION\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SESSIONSERVICE_CFLAGS=`$PKG_CONFIG --cflags "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SESSIONSERVICE_LIBS"; then
+ pkg_cv_SESSIONSERVICE_LIBS="$SESSIONSERVICE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbusmenu-glib-0.4 >= \$DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= \$DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= \$INDICATOR_REQUIRED_VERSION\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SESSIONSERVICE_LIBS=`$PKG_CONFIG --libs "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SESSIONSERVICE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>&1`
+ else
+ SESSIONSERVICE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SESSIONSERVICE_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION) were not met:
+
+$SESSIONSERVICE_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables SESSIONSERVICE_CFLAGS
+and SESSIONSERVICE_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables SESSIONSERVICE_CFLAGS
+and SESSIONSERVICE_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ SESSIONSERVICE_CFLAGS=$pkg_cv_SESSIONSERVICE_CFLAGS
+ SESSIONSERVICE_LIBS=$pkg_cv_SESSIONSERVICE_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+fi
+
+if test "x$with_gtk" = x3; then :
+
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTKLOGOUTHELPER" >&5
$as_echo_n "checking for GTKLOGOUTHELPER... " >&6; }
@@ -13283,14 +13417,14 @@ if test -n "$GTKLOGOUTHELPER_CFLAGS"; then
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= \$GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= \$POLKIT_REQUIRED_VERSION\""; } >&5
+ polkit-gobject-1 >= \$POLKIT_REQUIRED_VERSION\""; } >&5
($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION") 2>&5
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_GTKLOGOUTHELPER_CFLAGS=`$PKG_CONFIG --cflags "gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>/dev/null`
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -13303,14 +13437,14 @@ if test -n "$GTKLOGOUTHELPER_LIBS"; then
elif test -n "$PKG_CONFIG"; then
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= \$GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= \$POLKIT_REQUIRED_VERSION\""; } >&5
+ polkit-gobject-1 >= \$POLKIT_REQUIRED_VERSION\""; } >&5
($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION") 2>&5
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then
pkg_cv_GTKLOGOUTHELPER_LIBS=`$PKG_CONFIG --libs "gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>/dev/null`
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes
else
pkg_failed=yes
@@ -13332,16 +13466,16 @@ else
fi
if test $_pkg_short_errors_supported = yes; then
GTKLOGOUTHELPER_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>&1`
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>&1`
else
GTKLOGOUTHELPER_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>&1`
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$GTKLOGOUTHELPER_PKG_ERRORS" >&5
as_fn_error $? "Package requirements (gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION) were not met:
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION) were not met:
$GTKLOGOUTHELPER_PKG_ERRORS
@@ -13374,6 +13508,111 @@ $as_echo "yes" >&6; }
fi
+elif test "x$with_gtk" = x2; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTKLOGOUTHELPER" >&5
+$as_echo_n "checking for GTKLOGOUTHELPER... " >&6; }
+
+if test -n "$GTKLOGOUTHELPER_CFLAGS"; then
+ pkg_cv_GTKLOGOUTHELPER_CFLAGS="$GTKLOGOUTHELPER_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= \$GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= \$POLKIT_REQUIRED_VERSION\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTKLOGOUTHELPER_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GTKLOGOUTHELPER_LIBS"; then
+ pkg_cv_GTKLOGOUTHELPER_LIBS="$GTKLOGOUTHELPER_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= \$GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= \$POLKIT_REQUIRED_VERSION\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTKLOGOUTHELPER_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GTKLOGOUTHELPER_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>&1`
+ else
+ GTKLOGOUTHELPER_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GTKLOGOUTHELPER_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION) were not met:
+
+$GTKLOGOUTHELPER_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GTKLOGOUTHELPER_CFLAGS
+and GTKLOGOUTHELPER_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GTKLOGOUTHELPER_CFLAGS
+and GTKLOGOUTHELPER_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GTKLOGOUTHELPER_CFLAGS=$pkg_cv_GTKLOGOUTHELPER_CFLAGS
+ GTKLOGOUTHELPER_LIBS=$pkg_cv_GTKLOGOUTHELPER_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+fi
+
@@ -13584,7 +13823,7 @@ fi
if test "x$with_localinstall" = "xyes"; then
INDICATORDIR="${libdir}/indicators/2/"
INDICATORICONSDIR="${datadir}/indicator-applet/icons/"
-elif test "x$with_indicator_gtk" = x2; then
+elif test "x$with_gtk" = x2; then
INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator-0.4`
INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir indicator-0.4`
else
@@ -16788,12 +17027,14 @@ fi
SUS Indicator Configuration:
Prefix: $prefix
- Indicator GTK: $with_indicator_gtk
+ Indicator Dir: $INDICATORDIR
+ Indicator GTK: $with_gtk
" >&5
$as_echo "$as_me:
SUS Indicator Configuration:
Prefix: $prefix
- Indicator GTK: $with_indicator_gtk
+ Indicator Dir: $INDICATORDIR
+ Indicator GTK: $with_gtk
" >&6;}
diff --git a/configure.ac b/configure.ac
index 59227b8..369f12b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@ AC_INIT(src/indicator-session.c)
AC_PREREQ(2.53)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(indicator-session, 0.2.93)
+AM_INIT_AUTOMAKE(indicator-session, 0.3.0)
AM_MAINTAINER_MODE
@@ -31,18 +31,18 @@ INDICATOR_REQUIRED_VERSION=0.3.19
DBUSMENUGTK_REQUIRED_VERSION=0.3.91
POLKIT_REQUIRED_VERSION=0.92
-AC_ARG_WITH([indicator-gtk],
- [AS_HELP_STRING([--with-indicator-gtk],
+AC_ARG_WITH([gtk],
+ [AS_HELP_STRING([--with-gtk],
[Which version of gtk to use for the indicator @<:@default=3@:>@])],
[],
- [with_indicator_gtk=3])
+ [with_gtk=3])
-AS_IF([test "x$with_indicator_gtk" = x3],
+AS_IF([test "x$with_gtk" = x3],
[PKG_CHECK_MODULES(APPLET, gtk+-3.0 >= $GTK3_REQUIRED_VERSION
indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION
dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
],
- [test "x$with_indicator_gtk" = x2],
+ [test "x$with_gtk" = x2],
[PKG_CHECK_MODULES(APPLET, gtk+-2.0 >= $GTK_REQUIRED_VERSION
indicator-0.4 >= $INDICATOR_REQUIRED_VERSION
dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION)
@@ -54,17 +54,34 @@ AC_SUBST(APPLET_LIBS)
DBUSMENUGLIB_REQUIRED_VERSION=0.1.1
-PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
- dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
- dbus-glib-1
- gio-unix-2.0
- indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION)
+AS_IF([test "x$with_gtk" = x3],
+ [PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION)
+ ],
+ [test "x$with_gtk" = x2],
+ [PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
+ dbusmenu-gtk-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION
+ dbus-glib-1
+ gio-unix-2.0
+ indicator-0.4 >= $INDICATOR_REQUIRED_VERSION)
+ ]
+)
AC_SUBST(SESSIONERVICE_CFLAGS)
AC_SUBST(SESSIONERVICE_LIBS)
-PKG_CHECK_MODULES(GTKLOGOUTHELPER, gtk+-3.0 >= $GTK3_REQUIRED_VERSION
- polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
+AS_IF([test "x$with_gtk" = x3],
+ [PKG_CHECK_MODULES(GTKLOGOUTHELPER, gtk+-3.0 >= $GTK3_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
+ ],
+ [test "x$with_gtk" = x2],
+ [PKG_CHECK_MODULES(GTKLOGOUTHELPER, gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
+ ]
+)
AC_SUBST(GTKLOGOUTHELPER_CFLAGS)
@@ -94,7 +111,7 @@ AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all
if test "x$with_localinstall" = "xyes"; then
INDICATORDIR="${libdir}/indicators/2/"
INDICATORICONSDIR="${datadir}/indicator-applet/icons/"
-elif test "x$with_indicator_gtk" = x2; then
+elif test "x$with_gtk" = x2; then
INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator-0.4`
INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir indicator-0.4`
else
@@ -179,5 +196,6 @@ AC_MSG_NOTICE([
SUS Indicator Configuration:
Prefix: $prefix
- Indicator GTK: $with_indicator_gtk
+ Indicator Dir: $INDICATORDIR
+ Indicator GTK: $with_gtk
])
diff --git a/debian/changelog b/debian/changelog
index 61af3b0..9641785 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+indicator-session (0.3.0-0ubuntu1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Ken VanDine <ken.vandine@canonical.com> Fri, 22 Jul 2011 13:41:08 -0400
+
indicator-session (0.2.93-0ubuntu1) oneiric; urgency=low
* New upstream release.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c2256c1..08eff5f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,3 +7,6 @@ src/gtk-logout-helper.c
src/dialog.c
src/indicator-session.c
src/session-service.c
+src/apt-watcher.c
+src/device-menu-mgr.c
+src/user-menu-mgr.c
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_ */