diff options
| author | Ken VanDine <ken.vandine@canonical.com> | 2011-07-22 13:41:06 -0400 | 
|---|---|---|
| committer | Ken VanDine <ken.vandine@canonical.com> | 2011-07-22 13:41:06 -0400 | 
| commit | 108cec80746510d7f622ad0506a7f3d2a734c3ae (patch) | |
| tree | 061bd5ba8a897fe82d74a941423192daa3b42a82 /src | |
| parent | bd7fb2850d02ae416b2fd2a80f668f25dc861872 (diff) | |
| parent | a1a7357b58d182e077ebfe8fb11c083e5eb18839 (diff) | |
| download | ayatana-indicator-session-108cec80746510d7f622ad0506a7f3d2a734c3ae.tar.gz ayatana-indicator-session-108cec80746510d7f622ad0506a7f3d2a734c3ae.tar.bz2 ayatana-indicator-session-108cec80746510d7f622ad0506a7f3d2a734c3ae.zip | |
Import upstream version 0.3.0
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 12 | ||||
| -rw-r--r-- | src/Makefile.in | 104 | ||||
| -rw-r--r-- | src/apt-transaction.c | 260 | ||||
| -rw-r--r-- | src/apt-transaction.h | 49 | ||||
| -rw-r--r-- | src/apt-watcher.c | 337 | ||||
| -rw-r--r-- | src/apt-watcher.h | 60 | ||||
| -rw-r--r-- | src/dbus-shared-names.h | 18 | ||||
| -rw-r--r-- | src/device-menu-mgr.c | 798 | ||||
| -rw-r--r-- | src/device-menu-mgr.h | 53 | ||||
| -rw-r--r-- | src/dialog.c | 2 | ||||
| -rw-r--r-- | src/gconf-helper.h | 6 | ||||
| -rw-r--r-- | src/gen-session-dbus.xml.c | 6 | ||||
| -rw-r--r-- | src/indicator-session.c | 19 | ||||
| -rw-r--r-- | src/session-dbus.xml | 6 | ||||
| -rw-r--r-- | src/session-service.c | 777 | ||||
| -rw-r--r-- | src/udev-mgr.c | 46 | ||||
| -rw-r--r-- | src/udev-mgr.h | 51 | ||||
| -rw-r--r-- | src/user-menu-mgr.c | 357 | ||||
| -rw-r--r-- | src/user-menu-mgr.h | 53 | 
19 files changed, 2240 insertions, 774 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am index 71537c5..83d12bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -91,7 +91,17 @@ indicator_session_service_SOURCES = \  	dbusmenu-shared.h \  	gconf-helper.c \  	users-service-dbus.h \ -	users-service-dbus.c +	users-service-dbus.c \ +	user-menu-mgr.h \ +	user-menu-mgr.c \	 +	device-menu-mgr.h \ +	device-menu-mgr.c \ +	apt-watcher.h \ +	apt-watcher.c \ +	apt-transaction.h \ +	apt-transaction.c \ +	udev-mgr.h \ +	udev-mgr.c  indicator_session_service_CFLAGS = \  	$(SESSIONSERVICE_CFLAGS) \  	$(GCONF_CFLAGS) \ diff --git a/src/Makefile.in b/src/Makefile.in index 4b282fd..2ef9128 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -100,7 +100,12 @@ am_indicator_session_service_OBJECTS =  \  	indicator_session_service-session-dbus.$(OBJEXT) \  	indicator_session_service-gen-session-dbus.xml.$(OBJEXT) \  	indicator_session_service-gconf-helper.$(OBJEXT) \ -	indicator_session_service-users-service-dbus.$(OBJEXT) +	indicator_session_service-users-service-dbus.$(OBJEXT) \ +	indicator_session_service-user-menu-mgr.$(OBJEXT) \ +	indicator_session_service-device-menu-mgr.$(OBJEXT) \ +	indicator_session_service-apt-watcher.$(OBJEXT) \ +	indicator_session_service-apt-transaction.$(OBJEXT) \ +	indicator_session_service-udev-mgr.$(OBJEXT)  indicator_session_service_OBJECTS =  \  	$(am_indicator_session_service_OBJECTS)  indicator_session_service_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @@ -337,7 +342,17 @@ indicator_session_service_SOURCES = \  	dbusmenu-shared.h \  	gconf-helper.c \  	users-service-dbus.h \ -	users-service-dbus.c +	users-service-dbus.c \ +	user-menu-mgr.h \ +	user-menu-mgr.c \ +	device-menu-mgr.h \ +	device-menu-mgr.c \ +	apt-watcher.h \ +	apt-watcher.c \ +	apt-transaction.h \ +	apt-transaction.c \ +	udev-mgr.h \ +	udev-mgr.c  indicator_session_service_CFLAGS = \  	$(SESSIONSERVICE_CFLAGS) \ @@ -526,11 +541,16 @@ distclean-compile:  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_logout_helper-dialog.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_logout_helper-gconf-helper.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk_logout_helper-gtk-logout-helper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-apt-transaction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-apt-watcher.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-device-menu-mgr.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-gconf-helper.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-gen-session-dbus.xml.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-lock-helper.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-session-dbus.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-session-service.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-udev-mgr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-user-menu-mgr.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_session_service-users-service-dbus.Po@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsession_la-indicator-session.Plo@am__quote@  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsession_la-user-widget.Plo@am__quote@ @@ -719,6 +739,86 @@ indicator_session_service-users-service-dbus.obj: users-service-dbus.c  @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@  @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-users-service-dbus.obj `if test -f 'users-service-dbus.c'; then $(CYGPATH_W) 'users-service-dbus.c'; else $(CYGPATH_W) '$(srcdir)/users-service-dbus.c'; fi` +indicator_session_service-user-menu-mgr.o: user-menu-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-user-menu-mgr.o -MD -MP -MF $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo -c -o indicator_session_service-user-menu-mgr.o `test -f 'user-menu-mgr.c' || echo '$(srcdir)/'`user-menu-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-user-menu-mgr.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='user-menu-mgr.c' object='indicator_session_service-user-menu-mgr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-user-menu-mgr.o `test -f 'user-menu-mgr.c' || echo '$(srcdir)/'`user-menu-mgr.c + +indicator_session_service-user-menu-mgr.obj: user-menu-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-user-menu-mgr.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo -c -o indicator_session_service-user-menu-mgr.obj `if test -f 'user-menu-mgr.c'; then $(CYGPATH_W) 'user-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/user-menu-mgr.c'; fi` +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-user-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-user-menu-mgr.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='user-menu-mgr.c' object='indicator_session_service-user-menu-mgr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-user-menu-mgr.obj `if test -f 'user-menu-mgr.c'; then $(CYGPATH_W) 'user-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/user-menu-mgr.c'; fi` + +indicator_session_service-device-menu-mgr.o: device-menu-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-device-menu-mgr.o -MD -MP -MF $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo -c -o indicator_session_service-device-menu-mgr.o `test -f 'device-menu-mgr.c' || echo '$(srcdir)/'`device-menu-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-device-menu-mgr.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='device-menu-mgr.c' object='indicator_session_service-device-menu-mgr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-device-menu-mgr.o `test -f 'device-menu-mgr.c' || echo '$(srcdir)/'`device-menu-mgr.c + +indicator_session_service-device-menu-mgr.obj: device-menu-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-device-menu-mgr.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo -c -o indicator_session_service-device-menu-mgr.obj `if test -f 'device-menu-mgr.c'; then $(CYGPATH_W) 'device-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/device-menu-mgr.c'; fi` +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-device-menu-mgr.Tpo $(DEPDIR)/indicator_session_service-device-menu-mgr.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='device-menu-mgr.c' object='indicator_session_service-device-menu-mgr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-device-menu-mgr.obj `if test -f 'device-menu-mgr.c'; then $(CYGPATH_W) 'device-menu-mgr.c'; else $(CYGPATH_W) '$(srcdir)/device-menu-mgr.c'; fi` + +indicator_session_service-apt-watcher.o: apt-watcher.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-watcher.o -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-watcher.Tpo -c -o indicator_session_service-apt-watcher.o `test -f 'apt-watcher.c' || echo '$(srcdir)/'`apt-watcher.c +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-watcher.Tpo $(DEPDIR)/indicator_session_service-apt-watcher.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='apt-watcher.c' object='indicator_session_service-apt-watcher.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-watcher.o `test -f 'apt-watcher.c' || echo '$(srcdir)/'`apt-watcher.c + +indicator_session_service-apt-watcher.obj: apt-watcher.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-watcher.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-watcher.Tpo -c -o indicator_session_service-apt-watcher.obj `if test -f 'apt-watcher.c'; then $(CYGPATH_W) 'apt-watcher.c'; else $(CYGPATH_W) '$(srcdir)/apt-watcher.c'; fi` +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-watcher.Tpo $(DEPDIR)/indicator_session_service-apt-watcher.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='apt-watcher.c' object='indicator_session_service-apt-watcher.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-watcher.obj `if test -f 'apt-watcher.c'; then $(CYGPATH_W) 'apt-watcher.c'; else $(CYGPATH_W) '$(srcdir)/apt-watcher.c'; fi` + +indicator_session_service-apt-transaction.o: apt-transaction.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-transaction.o -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-transaction.Tpo -c -o indicator_session_service-apt-transaction.o `test -f 'apt-transaction.c' || echo '$(srcdir)/'`apt-transaction.c +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-transaction.Tpo $(DEPDIR)/indicator_session_service-apt-transaction.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='apt-transaction.c' object='indicator_session_service-apt-transaction.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-transaction.o `test -f 'apt-transaction.c' || echo '$(srcdir)/'`apt-transaction.c + +indicator_session_service-apt-transaction.obj: apt-transaction.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-apt-transaction.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-apt-transaction.Tpo -c -o indicator_session_service-apt-transaction.obj `if test -f 'apt-transaction.c'; then $(CYGPATH_W) 'apt-transaction.c'; else $(CYGPATH_W) '$(srcdir)/apt-transaction.c'; fi` +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-apt-transaction.Tpo $(DEPDIR)/indicator_session_service-apt-transaction.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='apt-transaction.c' object='indicator_session_service-apt-transaction.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-apt-transaction.obj `if test -f 'apt-transaction.c'; then $(CYGPATH_W) 'apt-transaction.c'; else $(CYGPATH_W) '$(srcdir)/apt-transaction.c'; fi` + +indicator_session_service-udev-mgr.o: udev-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-udev-mgr.o -MD -MP -MF $(DEPDIR)/indicator_session_service-udev-mgr.Tpo -c -o indicator_session_service-udev-mgr.o `test -f 'udev-mgr.c' || echo '$(srcdir)/'`udev-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-udev-mgr.Tpo $(DEPDIR)/indicator_session_service-udev-mgr.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='udev-mgr.c' object='indicator_session_service-udev-mgr.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-udev-mgr.o `test -f 'udev-mgr.c' || echo '$(srcdir)/'`udev-mgr.c + +indicator_session_service-udev-mgr.obj: udev-mgr.c +@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -MT indicator_session_service-udev-mgr.obj -MD -MP -MF $(DEPDIR)/indicator_session_service-udev-mgr.Tpo -c -o indicator_session_service-udev-mgr.obj `if test -f 'udev-mgr.c'; then $(CYGPATH_W) 'udev-mgr.c'; else $(CYGPATH_W) '$(srcdir)/udev-mgr.c'; fi` +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/indicator_session_service-udev-mgr.Tpo $(DEPDIR)/indicator_session_service-udev-mgr.Po +@am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='udev-mgr.c' object='indicator_session_service-udev-mgr.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_session_service_CFLAGS) $(CFLAGS) -c -o indicator_session_service-udev-mgr.obj `if test -f 'udev-mgr.c'; then $(CYGPATH_W) 'udev-mgr.c'; else $(CYGPATH_W) '$(srcdir)/udev-mgr.c'; fi` +  mostlyclean-libtool:  	-rm -f *.lo diff --git a/src/apt-transaction.c b/src/apt-transaction.c new file mode 100644 index 0000000..78a0ff2 --- /dev/null +++ b/src/apt-transaction.c @@ -0,0 +1,260 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: +    Conor Curran <conor.curran@canonical.com> + +This program is free software: you can redistribute it and/or modify it  +under the terms of the GNU General Public License version 3, as published  +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but  +WITHOUT ANY WARRANTY; without even the implied warranties of  +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR  +PURPOSE.  See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along  +with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <gio/gio.h> + +#include "apt-transaction.h" +#include "dbus-shared-names.h" + +static void apt_transaction_investigate (AptTransaction* self); +static void apt_transaction_simulate_transaction_cb (GObject * obj, +                                                     GAsyncResult * res, +                                                     gpointer user_data); +static void apt_transaction_receive_signal (GDBusProxy * proxy, +                                            gchar * sender_name, +                                            gchar * signal_name, +                                            GVariant * parameters, +                                            gpointer user_data); +static void apt_transaction_finish_proxy_setup (GObject *source_object, +                                                GAsyncResult *res, +                                                gpointer user_data); + +struct _AptTransaction +{ +	GObject       parent_instance; +	GDBusProxy *  proxy;     +	GCancellable * proxy_cancel;   +  gchar*        id; +  TransactionType type; +}; + +enum { +  UPDATE, +  LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (AptTransaction, apt_transaction, G_TYPE_OBJECT); + +static void +apt_transaction_init (AptTransaction *self) +{ +  self->proxy = NULL; +  self->id = NULL; +  self->proxy_cancel = g_cancellable_new(); +} + +static void +apt_transaction_finalize (GObject *object) +{ +  AptTransaction* self = APT_TRANSACTION(object); +  g_signal_handlers_disconnect_by_func (G_OBJECT (self->proxy), +                                        G_CALLBACK (apt_transaction_receive_signal), +                                        self); +  if (self->proxy != NULL){ +    g_object_unref (self->proxy); +    self->proxy = NULL; +  } +  g_free (self->id); +	G_OBJECT_CLASS (apt_transaction_parent_class)->finalize (object); +} + +static void +apt_transaction_class_init (AptTransactionClass *klass) +{ +	GObjectClass* object_class = G_OBJECT_CLASS (klass); +	object_class->finalize = apt_transaction_finalize; + +  signals[UPDATE] =  g_signal_new("state-update", +                                   G_TYPE_FROM_CLASS (klass), +                                   G_SIGNAL_RUN_LAST, +                                   0, +                                   NULL, NULL, +                                   g_cclosure_marshal_VOID__INT, +                                   G_TYPE_NONE, 1, G_TYPE_INT);   +} + +// TODO: you don't need this additional helper +// Just GObject properties properly +static void +apt_transaction_investigate (AptTransaction* self) +{ +  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, +                            G_DBUS_PROXY_FLAGS_NONE, +                            NULL, +                            "org.debian.apt", +                            self->id, +                            "org.debian.apt.transaction", +                            self->proxy_cancel, +                            apt_transaction_finish_proxy_setup, +                            self); +} + +static void +apt_transaction_finish_proxy_setup (GObject *source_object, +                                    GAsyncResult *res, +                                    gpointer user_data) +{ +  g_return_if_fail (APT_IS_TRANSACTION (user_data)); +  AptTransaction* self = APT_TRANSACTION(user_data);       +	GError * error = NULL; + +	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + +	if (self->proxy_cancel != NULL) { +		g_object_unref(self->proxy_cancel); +		self->proxy_cancel = NULL; +	} + +	if (error != NULL) { +		g_warning("Could not grab DBus proxy for %s: %s", +               "org.debian.apt", error->message); +		g_error_free(error); +		return; +	} +   +  self->proxy = proxy; + +  g_signal_connect (G_OBJECT(self->proxy), +                    "g-signal", +                    G_CALLBACK (apt_transaction_receive_signal), +                    self);     + +  if (self->type == SIMULATION){ +    g_dbus_proxy_call (self->proxy, +                       "Simulate", +                       NULL, +                       G_DBUS_CALL_FLAGS_NONE, +                       -1, +                       NULL, +                       apt_transaction_simulate_transaction_cb, +                       self);                                                                                         +  }                        +} + +static void +apt_transaction_receive_signal (GDBusProxy * proxy, +                                gchar * sender_name, +                                gchar * signal_name, +                                GVariant * parameters, +                                gpointer user_data) +{ +  g_return_if_fail (APT_IS_TRANSACTION (user_data)); +  AptTransaction* self = APT_TRANSACTION(user_data); +  AptState current_state = DONT_KNOW; +   +  if (g_strcmp0(signal_name, "PropertyChanged") == 0 && self->type == SIMULATION)  +  { +    gchar* prop_name= NULL; +    GVariant* value = NULL; +    g_variant_get (parameters, "(sv)", &prop_name, &value);     +    g_debug ("transaction prop update - prop = %s", prop_name); +     +    if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) == TRUE){ +      gchar* key = NULL; +      g_variant_get (value, "s", &key); +      g_debug ("transaction prop update - value = %s", key); +    } +     +    if (g_strcmp0 (prop_name, "Dependencies") == 0){ +             +      gchar** install = NULL; +      gchar** reinstall = NULL; +      gchar** remove = NULL; +      gchar** purge = NULL; +      gchar** upgrade = NULL; +      gchar** downgrade = NULL; +      gchar** keep = NULL; +      g_variant_get (value, "(asasasasasasas)", &install,  +                     &reinstall, &remove, &purge, &upgrade, &downgrade, +                     &keep);       +      //g_debug ("Seemed to uppack dependencies without any warnings"); +      //g_debug ("Upgrade quantity : %u", g_strv_length(upgrade)); +      gboolean upgrade_needed = (g_strv_length(upgrade) > 0) || +                                (g_strv_length(install) > 0) || +                                (g_strv_length(reinstall) > 0) || +                                (g_strv_length(remove) > 0) || +                                (g_strv_length(purge) > 0); +      if (upgrade_needed == TRUE){ +        current_state = UPDATES_AVAILABLE;         +      } +      else{ +        current_state = UP_TO_DATE; +      } +    } +  } +  else if (g_strcmp0(signal_name, "PropertyChanged") == 0 && +           self->type == REAL) +  { +    GVariant* role = g_dbus_proxy_get_cached_property (self->proxy, +                                                       "Role"); +    if (g_variant_is_of_type (role, G_VARIANT_TYPE_STRING) == TRUE){ +      gchar* current_role = NULL; +      g_variant_get (role, "s", ¤t_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_ */ | 
