diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 36 | ||||
-rw-r--r-- | src/Makefile.in | 692 | ||||
-rw-r--r-- | src/dbus-listener.c | 247 | ||||
-rw-r--r-- | src/dbus-listener.h | 82 | ||||
-rw-r--r-- | src/device.c | 666 | ||||
-rw-r--r-- | src/device.h | 107 | ||||
-rw-r--r-- | src/indicator-power.c | 844 | ||||
-rw-r--r-- | src/indicator-power.h | 58 |
8 files changed, 2067 insertions, 665 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..b2cf3df --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,36 @@ +CLEANFILES = +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + +################### +# Indicator Stuff +################### + +powerlibdir = $(INDICATORDIR) +powerlib_LTLIBRARIES = libpower.la + +libpower_la_SOURCES = \ + dbus-listener.c \ + dbus-listener.h \ + device.c \ + device.h \ + indicator-power.h \ + indicator-power.c + +CLEANFILES += .libs/*.gcda .libs/*.gcno *.gcda *.gcno + +libpower_la_CFLAGS = \ + $(UPOWER_CFLAGS) \ + $(INDICATOR_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + -Wall -Werror \ + -DG_LOG_DOMAIN=\"Indicator-Power\" + +libpower_la_LIBADD = \ + $(UPOWER_LIBS) \ + $(INDICATOR_LIBS) + +libpower_la_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -module \ + -avoid-version + diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..a454e5b --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,692 @@ +# Makefile.in generated by automake 1.11.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtest.m4 \ + $(top_srcdir)/m4/gcov.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(powerlibdir)" +LTLIBRARIES = $(powerlib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libpower_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libpower_la_OBJECTS = libpower_la-dbus-listener.lo \ + libpower_la-device.lo libpower_la-indicator-power.lo +libpower_la_OBJECTS = $(am_libpower_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libpower_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpower_la_CFLAGS) \ + $(CFLAGS) $(libpower_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libpower_la_SOURCES) +DIST_SOURCES = $(libpower_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASE_CXXFLAGS = @BASE_CXXFLAGS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_CXXFLAGS = @COVERAGE_CXXFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CWARNFLAGS = @CWARNFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EVEMU_CFLAGS = @EVEMU_CFLAGS@ +EVEMU_LIBS = @EVEMU_LIBS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCOVR = @GCOVR@ +GENHTML = @GENHTML@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +GSD_CFLAGS = @GSD_CFLAGS@ +GSD_LIBS = @GSD_LIBS@ +GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ +GTEST_CPPFLAGS = @GTEST_CPPFLAGS@ +GTEST_SOURCE = @GTEST_SOURCE@ +INDICATORDIR = @INDICATORDIR@ +INDICATORICONSDIR = @INDICATORICONSDIR@ +INDICATOR_CFLAGS = @INDICATOR_CFLAGS@ +INDICATOR_LIBS = @INDICATOR_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ +INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ +INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ +INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHTOOL = @SHTOOL@ +STRICT_CXXFLAGS = @STRICT_CXXFLAGS@ +STRIP = @STRIP@ +UPOWER_CFLAGS = @UPOWER_CFLAGS@ +UPOWER_LIBS = @UPOWER_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +X11_CFLAGS = @X11_CFLAGS@ +X11_LIBS = @X11_LIBS@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +XORG_GTEST_CPPFLAGS = @XORG_GTEST_CPPFLAGS@ +XORG_GTEST_SOURCE = @XORG_GTEST_SOURCE@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gsettingsschemadir = @gsettingsschemadir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +intltool__v_merge_options_ = @intltool__v_merge_options_@ +intltool__v_merge_options_0 = @intltool__v_merge_options_0@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +CLEANFILES = .libs/*.gcda .libs/*.gcno *.gcda *.gcno +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + +################### +# Indicator Stuff +################### +powerlibdir = $(INDICATORDIR) +powerlib_LTLIBRARIES = libpower.la +libpower_la_SOURCES = \ + dbus-listener.c \ + dbus-listener.h \ + device.c \ + device.h \ + indicator-power.h \ + indicator-power.c + +libpower_la_CFLAGS = \ + $(UPOWER_CFLAGS) \ + $(INDICATOR_CFLAGS) \ + $(COVERAGE_CFLAGS) \ + -Wall -Werror \ + -DG_LOG_DOMAIN=\"Indicator-Power\" + +libpower_la_LIBADD = \ + $(UPOWER_LIBS) \ + $(INDICATOR_LIBS) + +libpower_la_LDFLAGS = \ + $(COVERAGE_LDFLAGS) \ + -module \ + -avoid-version + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-powerlibLTLIBRARIES: $(powerlib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(powerlib_LTLIBRARIES)'; test -n "$(powerlibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(powerlibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(powerlibdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(powerlibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(powerlibdir)"; \ + } + +uninstall-powerlibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(powerlib_LTLIBRARIES)'; test -n "$(powerlibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(powerlibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(powerlibdir)/$$f"; \ + done + +clean-powerlibLTLIBRARIES: + -test -z "$(powerlib_LTLIBRARIES)" || rm -f $(powerlib_LTLIBRARIES) + @list='$(powerlib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libpower.la: $(libpower_la_OBJECTS) $(libpower_la_DEPENDENCIES) $(EXTRA_libpower_la_DEPENDENCIES) + $(AM_V_CCLD)$(libpower_la_LINK) -rpath $(powerlibdir) $(libpower_la_OBJECTS) $(libpower_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpower_la-dbus-listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpower_la-device.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpower_la-indicator-power.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libpower_la-dbus-listener.lo: dbus-listener.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpower_la_CFLAGS) $(CFLAGS) -MT libpower_la-dbus-listener.lo -MD -MP -MF $(DEPDIR)/libpower_la-dbus-listener.Tpo -c -o libpower_la-dbus-listener.lo `test -f 'dbus-listener.c' || echo '$(srcdir)/'`dbus-listener.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpower_la-dbus-listener.Tpo $(DEPDIR)/libpower_la-dbus-listener.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dbus-listener.c' object='libpower_la-dbus-listener.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpower_la_CFLAGS) $(CFLAGS) -c -o libpower_la-dbus-listener.lo `test -f 'dbus-listener.c' || echo '$(srcdir)/'`dbus-listener.c + +libpower_la-device.lo: device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpower_la_CFLAGS) $(CFLAGS) -MT libpower_la-device.lo -MD -MP -MF $(DEPDIR)/libpower_la-device.Tpo -c -o libpower_la-device.lo `test -f 'device.c' || echo '$(srcdir)/'`device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpower_la-device.Tpo $(DEPDIR)/libpower_la-device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='device.c' object='libpower_la-device.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpower_la_CFLAGS) $(CFLAGS) -c -o libpower_la-device.lo `test -f 'device.c' || echo '$(srcdir)/'`device.c + +libpower_la-indicator-power.lo: indicator-power.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpower_la_CFLAGS) $(CFLAGS) -MT libpower_la-indicator-power.lo -MD -MP -MF $(DEPDIR)/libpower_la-indicator-power.Tpo -c -o libpower_la-indicator-power.lo `test -f 'indicator-power.c' || echo '$(srcdir)/'`indicator-power.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpower_la-indicator-power.Tpo $(DEPDIR)/libpower_la-indicator-power.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='indicator-power.c' object='libpower_la-indicator-power.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpower_la_CFLAGS) $(CFLAGS) -c -o libpower_la-indicator-power.lo `test -f 'indicator-power.c' || echo '$(srcdir)/'`indicator-power.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(powerlibdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-powerlibLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-powerlibLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-powerlibLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-powerlibLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-powerlibLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-powerlibLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/dbus-listener.c b/src/dbus-listener.c new file mode 100644 index 0000000..b1f64a7 --- /dev/null +++ b/src/dbus-listener.c @@ -0,0 +1,247 @@ +/* + +Listens on DBus for Power changes and passes them to an IndicatorPower + +Copyright 2012 Canonical Ltd. + +Authors: + Charles Kerr <charles.kerr@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + +#include "dbus-listener.h" +#include "device.h" + +struct _IndicatorPowerDbusListenerPrivate +{ + GCancellable * cancellable; + GDBusProxy * proxy; + guint watcher_id; +}; + +#define INDICATOR_POWER_DBUS_LISTENER_GET_PRIVATE(o) (INDICATOR_POWER_DBUS_LISTENER(o)->priv) + +/* Signals */ +enum { + SIGNAL_DEVICES, + SIGNAL_LAST +}; +static guint signals[SIGNAL_LAST] = { 0 }; + + +/* GObject stuff */ +static void indicator_power_dbus_listener_class_init (IndicatorPowerDbusListenerClass *klass); +static void indicator_power_dbus_listener_init (IndicatorPowerDbusListener *self); +static void indicator_power_dbus_listener_dispose (GObject *object); +static void indicator_power_dbus_listener_finalize (GObject *object); + +static void gsd_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data); + +/* LCOV_EXCL_START */ +G_DEFINE_TYPE (IndicatorPowerDbusListener, indicator_power_dbus_listener, G_TYPE_OBJECT); +/* LCOV_EXCL_STOP */ + +static void +indicator_power_dbus_listener_class_init (IndicatorPowerDbusListenerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IndicatorPowerDbusListenerPrivate)); + + /* methods */ + object_class->dispose = indicator_power_dbus_listener_dispose; + object_class->finalize = indicator_power_dbus_listener_finalize; + + /** + * IndicatorPowerDbusListener::devices-enumerated: + * + * @listener: the IndicatorPowerDbusListener + * @devices: a GSList of #IndicatorPowerDevice objects. (transfer none) + * + * This is emitted each time a new set of devices is enumerated over the bus. + */ + signals[SIGNAL_DEVICES] = g_signal_new (INDICATOR_POWER_DBUS_LISTENER_DEVICES_ENUMERATED, + G_TYPE_FROM_CLASS(klass), 0, + G_STRUCT_OFFSET (IndicatorPowerDbusListenerClass, devices_enumerated), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} + +/* Initialize an instance */ +static void +indicator_power_dbus_listener_init (IndicatorPowerDbusListener *self) +{ + IndicatorPowerDbusListenerPrivate * priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_POWER_DBUS_LISTENER_TYPE, + IndicatorPowerDbusListenerPrivate); + + priv->cancellable = g_cancellable_new (); + + priv->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + GSD_SERVICE, + G_BUS_NAME_WATCHER_FLAGS_NONE, + gsd_appeared_callback, + NULL, + self, + NULL); + + self->priv = priv; +} + +static void +indicator_power_dbus_listener_dispose (GObject *object) +{ + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(object); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + g_clear_object (&priv->proxy); + + if (priv->cancellable != NULL) + { + g_cancellable_cancel (priv->cancellable); + g_clear_object (&priv->cancellable); + } + + if (priv->watcher_id) + { + g_bus_unwatch_name (priv->watcher_id); + priv->watcher_id = 0; + } + + G_OBJECT_CLASS (indicator_power_dbus_listener_parent_class)->dispose (object); +} + +static void +indicator_power_dbus_listener_finalize (GObject *object) +{ + G_OBJECT_CLASS (indicator_power_dbus_listener_parent_class)->finalize (object); +} + +/*** +**** +***/ + +static void +get_devices_cb (GObject * source_object, + GAsyncResult * res, + gpointer user_data) +{ + GError *error; + GSList * devices = NULL; + GVariant * devices_container; + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER (user_data); + + /* build an array of IndicatorPowerDevices from the DBus response */ + error = NULL; + devices_container = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + if (devices_container == NULL) + { + g_message ("Couldn't get devices: %s\n", error->message); + g_error_free (error); + } + else + { + gsize i; + GVariant * devices_variant = g_variant_get_child_value (devices_container, 0); + const int device_count = devices_variant ? g_variant_n_children (devices_variant) : 0; + + for (i=0; i<device_count; i++) + { + GVariant * v = g_variant_get_child_value (devices_variant, i); + devices = g_slist_prepend (devices, indicator_power_device_new_from_variant (v)); + g_variant_unref (v); + } + + devices = g_slist_reverse (devices); + + g_variant_unref (devices_variant); + g_variant_unref (devices_container); + } + + g_signal_emit (self, signals[SIGNAL_DEVICES], (GQuark)0, devices); + g_slist_free_full (devices, g_object_unref); +} + +static void +request_device_list (IndicatorPowerDbusListener * self) +{ + g_dbus_proxy_call (self->priv->proxy, + "GetDevices", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + self->priv->cancellable, + get_devices_cb, + self); +} + +static void +receive_properties_changed (GDBusProxy *proxy G_GNUC_UNUSED, + GVariant *changed_properties G_GNUC_UNUSED, + GStrv invalidated_properties G_GNUC_UNUSED, + gpointer user_data) +{ + request_device_list (INDICATOR_POWER_DBUS_LISTENER(user_data)); +} + + +static void +service_proxy_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GError * error = NULL; + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(user_data); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (error != NULL) + { + g_error ("Error creating proxy: %s", error->message); + g_error_free (error); + return; + } + + /* we want to change the primary device changes */ + g_signal_connect (priv->proxy, "g-properties-changed", + G_CALLBACK (receive_properties_changed), user_data); + + /* get the initial state */ + request_device_list (self); +} + +static void +gsd_appeared_callback (GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + IndicatorPowerDbusListener * self = INDICATOR_POWER_DBUS_LISTENER(user_data); + IndicatorPowerDbusListenerPrivate * priv = self->priv; + + g_dbus_proxy_new (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + name, + GSD_POWER_DBUS_PATH, + GSD_POWER_DBUS_INTERFACE, + priv->cancellable, + service_proxy_cb, + self); +} diff --git a/src/dbus-listener.h b/src/dbus-listener.h new file mode 100644 index 0000000..e4d006b --- /dev/null +++ b/src/dbus-listener.h @@ -0,0 +1,82 @@ +/* + +Listens for Power changes from org.gnome.SettingsDaemon.Power on Dbus + +Copyright 2012 Canonical Ltd. + +Authors: + Javier Jardon <javier.jardon@codethink.co.uk> + Charles Kerr <charles.kerr@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + +#ifndef __INDICATOR_POWER_DBUS_LISTENER_H__ +#define __INDICATOR_POWER_DBUS_LISTENER_H__ + +#include <glib-object.h> +#include <libupower-glib/upower.h> + +G_BEGIN_DECLS + +#define INDICATOR_POWER_DBUS_LISTENER_TYPE (indicator_power_dbus_listener_get_type ()) +#define INDICATOR_POWER_DBUS_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_POWER_DBUS_LISTENER_TYPE, IndicatorPowerDbusListener)) +#define INDICATOR_POWER_DBUS_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_POWER_DBUS_LISTENER_TYPE, IndicatorPowerDbusListenerClass)) +#define INDICATOR_IS_POWER_DBUS_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_POWER_DBUS_LISTENER_TYPE)) +#define INDICATOR_IS_POWER_DBUS_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_POWER_DBUS_LISTENER_TYPE)) +#define INDICATOR_POWER_DBUS_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_POWER_DBUS_LISTENER_TYPE, IndicatorPowerDbusListenerClass)) + +typedef struct _IndicatorPowerDbusListener IndicatorPowerDbusListener; +typedef struct _IndicatorPowerDbusListenerClass IndicatorPowerDbusListenerClass; +typedef struct _IndicatorPowerDbusListenerPrivate IndicatorPowerDbusListenerPrivate; + +#define GSD_SERVICE "org.gnome.SettingsDaemon" +#define GSD_PATH "/org/gnome/SettingsDaemon" +#define GSD_POWER_DBUS_INTERFACE GSD_SERVICE ".Power" +#define GSD_POWER_DBUS_PATH GSD_PATH "/Power" + +/* signals */ +#define INDICATOR_POWER_DBUS_LISTENER_DEVICES_ENUMERATED "devices-enumerated" + +/** + * IndicatorPowerDbusListenerClass: + * @parent_class: #GObjectClass + */ +struct _IndicatorPowerDbusListenerClass +{ + GObjectClass parent_class; + + void (* devices_enumerated) (IndicatorPowerDbusListener*, GSList * devices); +}; + +/** + * IndicatorPowerDbusListener: + * @parent: #GObject + * @priv: A cached reference to the private data for the instance. +*/ +struct _IndicatorPowerDbusListener +{ + GObject parent; + IndicatorPowerDbusListenerPrivate * priv; +}; + +/*** +**** +***/ + +GType indicator_power_dbus_listener_get_type (void); + +G_END_DECLS + +#endif diff --git a/src/device.c b/src/device.c new file mode 100644 index 0000000..c22aae8 --- /dev/null +++ b/src/device.c @@ -0,0 +1,666 @@ +/* + +A simple Device structure used internally by indicator-power + +Copyright 2012 Canonical Ltd. + +Authors: + Charles Kerr <charles.kerr@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include <glib/gi18n.h> + +#include "device.h" + +struct _IndicatorPowerDevicePrivate +{ + UpDeviceKind kind; + UpDeviceState state; + gchar * object_path; + gdouble percentage; + time_t time; +}; + +#define INDICATOR_POWER_DEVICE_GET_PRIVATE(o) (INDICATOR_POWER_DEVICE(o)->priv) + +/* Properties */ +/* Enum for the properties so that they can be quickly found and looked up. */ +enum { + PROP_0, + PROP_KIND, + PROP_STATE, + PROP_OBJECT_PATH, + PROP_PERCENTAGE, + PROP_TIME, + N_PROPERTIES +}; + +static GParamSpec * properties[N_PROPERTIES]; + +/* GObject stuff */ +static void indicator_power_device_class_init (IndicatorPowerDeviceClass *klass); +static void indicator_power_device_init (IndicatorPowerDevice *self); +static void indicator_power_device_dispose (GObject *object); +static void indicator_power_device_finalize (GObject *object); +static void set_property (GObject*, guint prop_id, const GValue*, GParamSpec* ); +static void get_property (GObject*, guint prop_id, GValue*, GParamSpec* ); + +/* LCOV_EXCL_START */ +G_DEFINE_TYPE (IndicatorPowerDevice, indicator_power_device, G_TYPE_OBJECT); +/* LCOV_EXCL_STOP */ + +static void +indicator_power_device_class_init (IndicatorPowerDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (IndicatorPowerDevicePrivate)); + + object_class->dispose = indicator_power_device_dispose; + object_class->finalize = indicator_power_device_finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; + + properties[PROP_KIND] = g_param_spec_int (INDICATOR_POWER_DEVICE_KIND, + "kind", + "The device's UpDeviceKind", + UP_DEVICE_KIND_UNKNOWN, UP_DEVICE_KIND_LAST, + UP_DEVICE_KIND_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_STATE] = g_param_spec_int (INDICATOR_POWER_DEVICE_STATE, + "state", + "The device's UpDeviceState", + UP_DEVICE_STATE_UNKNOWN, UP_DEVICE_STATE_LAST, + UP_DEVICE_STATE_UNKNOWN, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_OBJECT_PATH] = g_param_spec_string (INDICATOR_POWER_DEVICE_OBJECT_PATH, + "object path", + "The device's DBus object path", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_PERCENTAGE] = g_param_spec_double (INDICATOR_POWER_DEVICE_PERCENTAGE, + "percentage", + "percent charged", + 0.0, 100.0, + 0.0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + properties[PROP_TIME] = g_param_spec_uint64 (INDICATOR_POWER_DEVICE_TIME, + "time", + "time left", + 0, G_MAXUINT64, + 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); +} + +/* Initialize an instance */ +static void +indicator_power_device_init (IndicatorPowerDevice *self) +{ + IndicatorPowerDevicePrivate * priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_POWER_DEVICE_TYPE, + IndicatorPowerDevicePrivate); + priv->kind = UP_DEVICE_KIND_UNKNOWN; + priv->state = UP_DEVICE_STATE_UNKNOWN; + priv->object_path = NULL; + priv->percentage = 0.0; + priv->time = 0; + + self->priv = priv; +} + +static void +indicator_power_device_dispose (GObject *object) +{ + G_OBJECT_CLASS (indicator_power_device_parent_class)->dispose (object); +} + +static void +indicator_power_device_finalize (GObject *object) +{ + IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(object); + IndicatorPowerDevicePrivate * priv = self->priv; + + g_clear_pointer (&priv->object_path, g_free); + + G_OBJECT_CLASS (indicator_power_device_parent_class)->finalize (object); +} + +/*** +**** +***/ + +static void +get_property (GObject * o, guint prop_id, GValue * value, GParamSpec * pspec) +{ + IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o); + IndicatorPowerDevicePrivate * priv = self->priv; + + switch (prop_id) + { + case PROP_KIND: + g_value_set_int (value, priv->kind); + break; + + case PROP_STATE: + g_value_set_int (value, priv->state); + break; + + case PROP_OBJECT_PATH: + g_value_set_string (value, priv->object_path); + break; + + case PROP_PERCENTAGE: + g_value_set_double (value, priv->percentage); + break; + + case PROP_TIME: + g_value_set_uint64 (value, priv->time); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec); + break; + } +} + +static void +set_property (GObject * o, guint prop_id, const GValue * value, GParamSpec * pspec) +{ + IndicatorPowerDevice * self = INDICATOR_POWER_DEVICE(o); + IndicatorPowerDevicePrivate * priv = self->priv; + + switch (prop_id) + { + case PROP_KIND: + priv->kind = g_value_get_int (value); + break; + + case PROP_STATE: + priv->state = g_value_get_int (value); + break; + + case PROP_OBJECT_PATH: + g_free (priv->object_path); + priv->object_path = g_value_dup_string (value); + break; + + case PROP_PERCENTAGE: + priv->percentage = g_value_get_double (value); + break; + + case PROP_TIME: + priv->time = g_value_get_uint64(value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(o, prop_id, pspec); + break; + } +} + +/*** +**** Accessors +***/ + +UpDeviceKind +indicator_power_device_get_kind (const IndicatorPowerDevice * device) +{ + /* LCOV_EXCL_START */ + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), UP_DEVICE_KIND_UNKNOWN); + /* LCOV_EXCL_STOP */ + + return device->priv->kind; +} + +UpDeviceState +indicator_power_device_get_state (const IndicatorPowerDevice * device) +{ + /* LCOV_EXCL_START */ + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), UP_DEVICE_STATE_UNKNOWN); + /* LCOV_EXCL_STOP */ + + return device->priv->state; +} + +const gchar * +indicator_power_device_get_object_path (const IndicatorPowerDevice * device) +{ + /* LCOV_EXCL_START */ + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL); + /* LCOV_EXCL_STOP */ + + return device->priv->object_path; +} + +gdouble +indicator_power_device_get_percentage (const IndicatorPowerDevice * device) +{ + /* LCOV_EXCL_START */ + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), 0.0); + /* LCOV_EXCL_STOP */ + + return device->priv->percentage; +} + +time_t +indicator_power_device_get_time (const IndicatorPowerDevice * device) +{ + /* LCOV_EXCL_START */ + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), (time_t)0); + /* LCOV_EXCL_STOP */ + + return device->priv->time; +} + +/*** +**** +**** +***/ + +static const gchar * +get_device_icon_suffix (gdouble percentage) +{ + if (percentage >= 60) return "full"; + if (percentage >= 30) return "good"; + if (percentage >= 10) return "low"; + return "caution"; +} + +static const gchar * +get_device_icon_index (gdouble percentage) +{ + if (percentage >= 90) return "100"; + if (percentage >= 70) return "080"; + if (percentage >= 50) return "060"; + if (percentage >= 30) return "040"; + if (percentage >= 10) return "020"; + return "000"; +} + +/** + indicator_power_device_get_icon_names: + @device: #IndicatorPowerDevice from which to generate the icon names + + This function's logic differs from GSD's power plugin in some ways: + + 1. All charging batteries use the same icon regardless of progress. + <https://bugs.launchpad.net/indicator-power/+bug/824629/comments/7> + + 2. For discharging batteries, we decide whether or not to use the 'caution' + icon based on whether or not we have <= 30 minutes remaining, rather than + looking at the battery's percentage left. + <https://bugs.launchpad.net/indicator-power/+bug/743823> + + See also indicator_power_device_get_gicon(). + + Return value: (array zero-terminated=1) (transfer full): + A GStrv of icon names suitable for passing to g_themed_icon_new_from_names(). + Free with g_strfreev() when done. +*/ +GStrv +indicator_power_device_get_icon_names (const IndicatorPowerDevice * device) +{ + const gchar *suffix_str; + const gchar *index_str; + + /* LCOV_EXCL_START */ + g_return_val_if_fail (INDICATOR_IS_POWER_DEVICE(device), NULL); + /* LCOV_EXCL_STOP */ + + gdouble percentage = indicator_power_device_get_percentage (device); + const UpDeviceKind kind = indicator_power_device_get_kind (device); + const UpDeviceState state = indicator_power_device_get_state (device); + const gchar * kind_str = kind_str = up_device_kind_to_string (kind); + + GPtrArray * names = g_ptr_array_new (); + + if (kind == UP_DEVICE_KIND_LINE_POWER) + { + g_ptr_array_add (names, g_strdup("ac-adapter-symbolic")); + g_ptr_array_add (names, g_strdup("ac-adapter")); + } + else if (kind == UP_DEVICE_KIND_MONITOR) + { + g_ptr_array_add (names, g_strdup("gpm-monitor-symbolic")); + g_ptr_array_add (names, g_strdup("gpm-monitor")); + } + else switch (state) + { + case UP_DEVICE_STATE_EMPTY: + g_ptr_array_add (names, g_strdup("battery-empty-symbolic")); + g_ptr_array_add (names, g_strdup_printf("gpm-%s-empty", kind_str)); + g_ptr_array_add (names, g_strdup_printf("gpm-%s-000", kind_str)); + g_ptr_array_add (names, g_strdup("battery-empty")); + break; + + case UP_DEVICE_STATE_FULLY_CHARGED: + g_ptr_array_add (names, g_strdup("battery-full-charged-symbolic")); + g_ptr_array_add (names, g_strdup("battery-full-charging-symbolic")); + g_ptr_array_add (names, g_strdup_printf("gpm-%s-full", kind_str)); + g_ptr_array_add (names, g_strdup_printf("gpm-%s-100", kind_str)); + g_ptr_array_add (names, g_strdup("battery-full-charged")); + g_ptr_array_add (names, g_strdup("battery-full-charging")); + break; + + case UP_DEVICE_STATE_CHARGING: + case UP_DEVICE_STATE_PENDING_CHARGE: + /* When charging, always use the same icon regardless of percentage. + <http://bugs.launchpad.net/indicator-power/+bug/824629> */ + percentage = 0; + + suffix_str = get_device_icon_suffix (percentage); + index_str = get_device_icon_index (percentage); + g_ptr_array_add (names, g_strdup_printf ("battery-%s-charging-symbolic", suffix_str)); + g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s-charging", kind_str, index_str)); + g_ptr_array_add (names, g_strdup_printf ("battery-%s-charging", suffix_str)); + break; + + case UP_DEVICE_STATE_DISCHARGING: + case UP_DEVICE_STATE_PENDING_DISCHARGE: + /* Don't show the caution/red icons unless we have <=30 min left. + <https://bugs.launchpad.net/indicator-power/+bug/743823> + Themes use the caution color when the percentage is 0% or 20%, + so if we have >30 min left, use 30% as the icon's percentage floor */ + if (indicator_power_device_get_time (device) > (30*60)) + percentage = MAX(percentage, 30); + + suffix_str = get_device_icon_suffix (percentage); + index_str = get_device_icon_index (percentage); + g_ptr_array_add (names, g_strdup_printf ("battery-%s-symbolic", suffix_str)); + g_ptr_array_add (names, g_strdup_printf ("gpm-%s-%s", kind_str, index_str)); + g_ptr_array_add (names, g_strdup_printf ("battery-%s", suffix_str)); + break; + + default: + g_ptr_array_add (names, g_strdup("battery-missing-symbolic")); + g_ptr_array_add (names, g_strdup("gpm-battery-missing")); + g_ptr_array_add (names, g_strdup("battery-missing")); + } + + g_ptr_array_add (names, NULL); /* terminates the strv */ + return (GStrv) g_ptr_array_free (names, FALSE); +} + +/** + indicator_power_device_get_gicon: + @device: #IndicatorPowerDevice to generate the icon names from + + A convenience function to call g_themed_icon_new_from_names() + with the names returned by indicator_power_device_get_icon_names() + + Return value: (transfer full): A themed GIcon +*/ +GIcon * +indicator_power_device_get_gicon (const IndicatorPowerDevice * device) +{ + GStrv names = indicator_power_device_get_icon_names (device); + GIcon * icon = g_themed_icon_new_from_names (names, -1); + g_strfreev (names); + return icon; +} + +/*** +**** +***/ + +static void +get_timestring (guint64 time_secs, + gchar **short_timestring, + gchar **detailed_timestring) +{ + gint hours; + gint minutes; + + /* Add 0.5 to do rounding */ + minutes = (int) ( ( time_secs / 60.0 ) + 0.5 ); + + if (minutes == 0) + { + *short_timestring = g_strdup (_("Unknown time")); + *detailed_timestring = g_strdup (_("Unknown time")); + + return; + } + + if (minutes < 60) + { + *short_timestring = g_strdup_printf ("0:%.2i", minutes); + *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute", + "%i minutes", + minutes), minutes); + return; + } + + hours = minutes / 60; + minutes = minutes % 60; + + *short_timestring = g_strdup_printf ("%i:%.2i", hours, minutes); + + if (minutes == 0) + { + *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, + "%i hour", + "%i hours", + hours), hours); + } + else + { + /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" + * Swap order with "%2$s %2$i %1$s %1$i if needed */ + *detailed_timestring = g_strdup_printf (_("%i %s %i %s"), + hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours), + minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes)); + } +} + +static const gchar * +device_kind_to_localised_string (UpDeviceKind kind) +{ + const gchar *text = NULL; + + switch (kind) { + case UP_DEVICE_KIND_LINE_POWER: + /* TRANSLATORS: system power cord */ + text = _("AC Adapter"); + break; + case UP_DEVICE_KIND_BATTERY: + /* TRANSLATORS: laptop primary battery */ + text = _("Battery"); + break; + case UP_DEVICE_KIND_UPS: + /* TRANSLATORS: battery-backed AC power source */ + text = _("UPS"); + break; + case UP_DEVICE_KIND_MONITOR: + /* TRANSLATORS: a monitor is a device to measure voltage and current */ + text = _("Monitor"); + break; + case UP_DEVICE_KIND_MOUSE: + /* TRANSLATORS: wireless mice with internal batteries */ + text = _("Mouse"); + break; + case UP_DEVICE_KIND_KEYBOARD: + /* TRANSLATORS: wireless keyboard with internal battery */ + text = _("Keyboard"); + break; + case UP_DEVICE_KIND_PDA: + /* TRANSLATORS: portable device */ + text = _("PDA"); + break; + case UP_DEVICE_KIND_PHONE: + /* TRANSLATORS: cell phone (mobile...) */ + text = _("Cell phone"); + break; + case UP_DEVICE_KIND_MEDIA_PLAYER: + /* TRANSLATORS: media player, mp3 etc */ + text = _("Media player"); + break; + case UP_DEVICE_KIND_TABLET: + /* TRANSLATORS: tablet device */ + text = _("Tablet"); + break; + case UP_DEVICE_KIND_COMPUTER: + /* TRANSLATORS: tablet device */ + text = _("Computer"); + break; + default: + g_warning ("enum unrecognised: %i", kind); + text = up_device_kind_to_string (kind); + } + + return text; +} + +void +indicator_power_device_get_time_details (const IndicatorPowerDevice * device, + gchar ** short_details, + gchar ** details, + gchar ** accessible_name) +{ + if (!INDICATOR_IS_POWER_DEVICE(device)) + { + *short_details = NULL; + *details = NULL; + *accessible_name = NULL; + g_warning ("%s: %p is not an IndicatorPowerDevice", G_STRFUNC, device); + return; + } + + const time_t time = indicator_power_device_get_time (device); + const UpDeviceState state = indicator_power_device_get_state (device); + const gdouble percentage = indicator_power_device_get_percentage (device); + const UpDeviceKind kind = indicator_power_device_get_kind (device); + const gchar * device_name = device_kind_to_localised_string (kind); + + if (time > 0) + { + gchar *short_timestring = NULL; + gchar *detailed_timestring = NULL; + + get_timestring (time, + &short_timestring, + &detailed_timestring); + + if (state == UP_DEVICE_STATE_CHARGING) + { + /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */ + *accessible_name = g_strdup_printf (_("%s (%s to charge (%.0lf%%))"), device_name, detailed_timestring, percentage); + *details = g_strdup_printf (_("%s (%s to charge)"), device_name, short_timestring); + *short_details = g_strdup_printf ("(%s)", short_timestring); + } + else if ((state == UP_DEVICE_STATE_DISCHARGING) && (time > (60*60*12))) + { + *accessible_name = g_strdup_printf (_("%s"), device_name); + *details = g_strdup_printf (_("%s"), device_name); + *short_details = g_strdup (short_timestring); + } + else + { + /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */ + *accessible_name = g_strdup_printf (_("%s (%s left (%.0lf%%))"), device_name, detailed_timestring, percentage); + *details = g_strdup_printf (_("%s (%s left)"), device_name, short_timestring); + *short_details = g_strdup (short_timestring); + } + + g_free (short_timestring); + g_free (detailed_timestring); + } + else if (state == UP_DEVICE_STATE_FULLY_CHARGED) + { + *details = g_strdup_printf (_("%s (charged)"), device_name); + *accessible_name = g_strdup (*details); + *short_details = g_strdup (""); + } + else if (percentage > 0) + { + /* TRANSLATORS: %2 is a percentage value. Note: this string is only + * used when we don't have a time value */ + *details = g_strdup_printf (_("%s (%.0lf%%)"), device_name, percentage); + *accessible_name = g_strdup (*details); + *short_details = g_strdup_printf (_("(%.0lf%%)"), percentage); + } + else if (kind == UP_DEVICE_KIND_LINE_POWER) + { + *details = g_strdup (device_name); + *accessible_name = g_strdup (device_name); + *short_details = g_strdup (device_name); + } + else + { + *details = g_strdup_printf (_("%s (not present)"), device_name); + *accessible_name = g_strdup (*details); + *short_details = g_strdup (_("(not present)")); + } +} + +/*** +**** Instantiation +***/ + +IndicatorPowerDevice * +indicator_power_device_new (const gchar * object_path, + UpDeviceKind kind, + gdouble percentage, + UpDeviceState state, + time_t timestamp) +{ + GObject * o = g_object_new (INDICATOR_POWER_DEVICE_TYPE, + INDICATOR_POWER_DEVICE_KIND, kind, + INDICATOR_POWER_DEVICE_STATE, state, + INDICATOR_POWER_DEVICE_OBJECT_PATH, object_path, + INDICATOR_POWER_DEVICE_PERCENTAGE, percentage, + INDICATOR_POWER_DEVICE_TIME, (guint64)timestamp, + NULL); + return INDICATOR_POWER_DEVICE(o); +} + +IndicatorPowerDevice * +indicator_power_device_new_from_variant (GVariant * v) +{ + g_return_val_if_fail (g_variant_is_of_type (v, G_VARIANT_TYPE("(susdut)")), NULL); + + UpDeviceKind kind = UP_DEVICE_KIND_UNKNOWN; + UpDeviceState state = UP_DEVICE_STATE_UNKNOWN; + const gchar * icon = NULL; + const gchar * object_path = NULL; + gdouble percentage = 0; + guint64 time = 0; + + g_variant_get (v, "(&su&sdut)", + &object_path, + &kind, + &icon, + &percentage, + &state, + &time); + + return indicator_power_device_new (object_path, + kind, + percentage, + state, + time); +} diff --git a/src/device.h b/src/device.h new file mode 100644 index 0000000..3f7bbee --- /dev/null +++ b/src/device.h @@ -0,0 +1,107 @@ +/* + +A simple Device structure used internally by indicator-power + +Copyright 2012 Canonical Ltd. + +Authors: + Charles Kerr <charles.kerr@canonical.com> + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 3.0 as published by the Free Software Foundation. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License version 3.0 for more details. + +You should have received a copy of the GNU General Public +License along with this library. If not, see +<http://www.gnu.org/licenses/>. +*/ + +#ifndef __INDICATOR_POWER_DEVICE_H__ +#define __INDICATOR_POWER_DEVICE_H__ + +#include <glib-object.h> +#include <libupower-glib/upower.h> + +G_BEGIN_DECLS + +#define INDICATOR_POWER_DEVICE_TYPE (indicator_power_device_get_type ()) +#define INDICATOR_POWER_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_POWER_DEVICE_TYPE, IndicatorPowerDevice)) +#define INDICATOR_POWER_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_POWER_DEVICE_TYPE, IndicatorPowerDeviceClass)) +#define INDICATOR_IS_POWER_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_POWER_DEVICE_TYPE)) +#define INDICATOR_IS_POWER_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_POWER_DEVICE_TYPE)) +#define INDICATOR_POWER_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_POWER_DEVICE_TYPE, IndicatorPowerDeviceClass)) + +typedef struct _IndicatorPowerDevice IndicatorPowerDevice; +typedef struct _IndicatorPowerDeviceClass IndicatorPowerDeviceClass; +typedef struct _IndicatorPowerDevicePrivate IndicatorPowerDevicePrivate; + +#define INDICATOR_POWER_DEVICE_KIND "kind" +#define INDICATOR_POWER_DEVICE_STATE "state" +#define INDICATOR_POWER_DEVICE_OBJECT_PATH "object-path" +#define INDICATOR_POWER_DEVICE_PERCENTAGE "percentage" +#define INDICATOR_POWER_DEVICE_TIME "time" + +/** + * IndicatorPowerDeviceClass: + * @parent_class: #GObjectClass + */ +struct _IndicatorPowerDeviceClass +{ + GObjectClass parent_class; +}; + +/** + * IndicatorPowerDevice: + * @parent: #GObject + * @priv: A cached reference to the private data for the instance. +*/ +struct _IndicatorPowerDevice +{ + GObject parent; + IndicatorPowerDevicePrivate * priv; +}; + +/*** +**** +***/ + +GType indicator_power_device_get_type (void); + +IndicatorPowerDevice* indicator_power_device_new (const gchar * object_path, + UpDeviceKind kind, + gdouble percentage, + UpDeviceState state, + time_t time); + +/** + * Convenience wrapper around indicator_power_device_new() + * @variant holds the same args as indicator_power_device_new() in "(susdut)" + */ +IndicatorPowerDevice* indicator_power_device_new_from_variant (GVariant * variant); + + +UpDeviceKind indicator_power_device_get_kind (const IndicatorPowerDevice * device); +UpDeviceState indicator_power_device_get_state (const IndicatorPowerDevice * device); +const gchar * indicator_power_device_get_object_path (const IndicatorPowerDevice * device); +gdouble indicator_power_device_get_percentage (const IndicatorPowerDevice * device); +time_t indicator_power_device_get_time (const IndicatorPowerDevice * device); + +GStrv indicator_power_device_get_icon_names (const IndicatorPowerDevice * device); +GIcon * indicator_power_device_get_gicon (const IndicatorPowerDevice * device); + +void indicator_power_device_get_time_details (const IndicatorPowerDevice * device, + gchar ** short_details, + gchar ** details, + gchar ** accessible_name); + + + + +G_END_DECLS + +#endif diff --git a/src/indicator-power.c b/src/indicator-power.c index 5d37da3..f3a7235 100644 --- a/src/indicator-power.c +++ b/src/indicator-power.c @@ -20,7 +20,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif /* GStuff */ @@ -28,67 +28,41 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib/gi18n-lib.h> #include <gio/gio.h> -/* upower */ -#include <libupower-glib/upower.h> - -/* Indicator Stuff */ -#include <libindicator/indicator.h> -#include <libindicator/indicator-object.h> +#include "dbus-listener.h" +#include "device.h" +#include "indicator-power.h" #define ICON_POLICY_KEY "icon-policy" #define DEFAULT_ICON "gpm-battery-missing" -#define DBUS_SERVICE "org.gnome.SettingsDaemon" -#define DBUS_PATH "/org/gnome/SettingsDaemon" -#define POWER_DBUS_PATH DBUS_PATH "/Power" -#define POWER_DBUS_INTERFACE "org.gnome.SettingsDaemon.Power" - enum { POWER_INDICATOR_ICON_POLICY_PRESENT, POWER_INDICATOR_ICON_POLICY_CHARGE, POWER_INDICATOR_ICON_POLICY_NEVER }; -#define INDICATOR_POWER_TYPE (indicator_power_get_type ()) -#define INDICATOR_POWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_POWER_TYPE, IndicatorPower)) -#define INDICATOR_POWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_POWER_TYPE, IndicatorPowerClass)) -#define IS_INDICATOR_POWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_POWER_TYPE)) -#define IS_INDICATOR_POWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_POWER_TYPE)) -#define INDICATOR_POWER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_POWER_TYPE, IndicatorPowerClass)) - -typedef struct _IndicatorPowerClass IndicatorPowerClass; -typedef struct _IndicatorPower IndicatorPower; - -struct _IndicatorPowerClass -{ - IndicatorObjectClass parent_class; -}; - -struct _IndicatorPower +struct _IndicatorPowerPrivate { - IndicatorObject parent_instance; - GtkMenu *menu; GtkLabel *label; GtkImage *status_image; gchar *accessible_desc; - GCancellable *proxy_cancel; - GDBusProxy *proxy; - guint watcher_id; + IndicatorPowerDbusListener * dbus_listener; - GVariant *devices; - GVariant *device; + GSList * devices; + IndicatorPowerDevice * device; GSettings *settings; }; -GType indicator_power_get_type (void) G_GNUC_CONST; +/* LCOV_EXCL_START */ INDICATOR_SET_VERSION INDICATOR_SET_TYPE (INDICATOR_POWER_TYPE) +/* LCOV_EXCL_STOP */ /* Prototypes */ static void indicator_power_dispose (GObject *object); @@ -105,9 +79,13 @@ static gboolean should_be_visible (IndicatorPower * self); static void on_entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data); +/* static void gsd_appeared_callback (GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data); +*/ +/* LCOV_EXCL_START */ G_DEFINE_TYPE (IndicatorPower, indicator_power, INDICATOR_OBJECT_TYPE); +/* LCOV_EXCL_STOP */ static void indicator_power_class_init (IndicatorPowerClass *klass) @@ -115,6 +93,8 @@ indicator_power_class_init (IndicatorPowerClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS (klass); + g_type_class_add_private (klass, sizeof (IndicatorPowerPrivate)); + object_class->dispose = indicator_power_dispose; object_class->finalize = indicator_power_finalize; @@ -128,20 +108,20 @@ indicator_power_class_init (IndicatorPowerClass *klass) static void indicator_power_init (IndicatorPower *self) { - self->menu = GTK_MENU(gtk_menu_new()); + IndicatorPowerPrivate * priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE (self, INDICATOR_POWER_TYPE, IndicatorPowerPrivate); - self->accessible_desc = NULL; + priv->menu = GTK_MENU(gtk_menu_new()); - self->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, - DBUS_SERVICE, - G_BUS_NAME_WATCHER_FLAGS_NONE, - gsd_appeared_callback, - NULL, - self, - NULL); + priv->accessible_desc = NULL; - self->settings = g_settings_new ("com.canonical.indicator.power"); - g_signal_connect_swapped (self->settings, "changed::" ICON_POLICY_KEY, + priv->dbus_listener = g_object_new (INDICATOR_POWER_DBUS_LISTENER_TYPE, NULL); + g_signal_connect_swapped (priv->dbus_listener, INDICATOR_POWER_DBUS_LISTENER_DEVICES_ENUMERATED, + G_CALLBACK(indicator_power_set_devices), self); + + priv->settings = g_settings_new ("com.canonical.indicator.power"); + g_signal_connect_swapped (priv->settings, "changed::" ICON_POLICY_KEY, G_CALLBACK(update_visibility), self); g_object_set (G_OBJECT(self), INDICATOR_OBJECT_DEFAULT_VISIBILITY, FALSE, @@ -149,27 +129,29 @@ indicator_power_init (IndicatorPower *self) g_signal_connect (INDICATOR_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED, G_CALLBACK(on_entry_added), NULL); + + self->priv = priv; } static void +dispose_devices (IndicatorPower * self) +{ + IndicatorPowerPrivate * priv = self->priv; + + g_clear_object (&priv->device); + g_slist_free_full (priv->devices, g_object_unref); + priv->devices = NULL; +} +static void indicator_power_dispose (GObject *object) { IndicatorPower *self = INDICATOR_POWER(object); + IndicatorPowerPrivate * priv = self->priv; - if (self->devices != NULL) { - g_variant_unref (self->devices); - self->devices = NULL; - } - - if (self->device != NULL) { - g_variant_unref (self->device); - self->device = NULL; - } + dispose_devices (self); - g_clear_object (&self->proxy); - g_clear_object (&self->proxy_cancel); - - g_clear_object (&self->settings); + g_clear_object (&priv->dbus_listener); + g_clear_object (&priv->settings); G_OBJECT_CLASS (indicator_power_parent_class)->dispose (object); } @@ -178,8 +160,9 @@ static void indicator_power_finalize (GObject *object) { IndicatorPower *self = INDICATOR_POWER(object); + IndicatorPowerPrivate * priv = self->priv; - g_free (self->accessible_desc); + g_free (priv->accessible_desc); G_OBJECT_CLASS (indicator_power_parent_class)->finalize (object); } @@ -198,216 +181,17 @@ spawn_command_line_async (const char * command) } static void -show_info_cb (GtkMenuItem *item, - gpointer data) -{ - /*TODO: show the statistics of the specific device*/ - spawn_command_line_async ("gnome-power-statistics"); -} - -static void option_toggled_cb (GtkCheckMenuItem *item, IndicatorPower * self) { - gtk_widget_set_visible (GTK_WIDGET (self->label), + gtk_widget_set_visible (GTK_WIDGET (self->priv->label), gtk_check_menu_item_get_active(item)); } -static void -show_preferences_cb (GtkMenuItem *item, - gpointer data) -{ - spawn_command_line_async ("gnome-control-center power"); -} - -static void -get_timestring (guint64 time_secs, - gchar **short_timestring, - gchar **detailed_timestring) -{ - gint hours; - gint minutes; - - /* Add 0.5 to do rounding */ - minutes = (int) ( ( time_secs / 60.0 ) + 0.5 ); - - if (minutes == 0) - { - *short_timestring = g_strdup (_("Unknown time")); - *detailed_timestring = g_strdup (_("Unknown time")); - - return; - } - - if (minutes < 60) - { - *short_timestring = g_strdup_printf ("0:%.2i", minutes); - *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%i minute", - "%i minutes", - minutes), minutes); - return; - } - - hours = minutes / 60; - minutes = minutes % 60; - - *short_timestring = g_strdup_printf ("%i:%.2i", hours, minutes); - - if (minutes == 0) - { - *detailed_timestring = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, - "%i hour", - "%i hours", - hours), hours); - } - else - { - /* TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" - * Swap order with "%2$s %2$i %1$s %1$i if needed */ - *detailed_timestring = g_strdup_printf (_("%i %s %i %s"), - hours, g_dngettext (GETTEXT_PACKAGE, "hour", "hours", hours), - minutes, g_dngettext (GETTEXT_PACKAGE, "minute", "minutes", minutes)); - } -} - -static const gchar * -device_kind_to_localised_string (UpDeviceKind kind) -{ - const gchar *text = NULL; - - switch (kind) { - case UP_DEVICE_KIND_LINE_POWER: - /* TRANSLATORS: system power cord */ - text = _("AC adapter"); - break; - case UP_DEVICE_KIND_BATTERY: - /* TRANSLATORS: laptop primary battery */ - text = _("Battery"); - break; - case UP_DEVICE_KIND_UPS: - /* TRANSLATORS: battery-backed AC power source */ - text = _("UPS"); - break; - case UP_DEVICE_KIND_MONITOR: - /* TRANSLATORS: a monitor is a device to measure voltage and current */ - text = _("Monitor"); - break; - case UP_DEVICE_KIND_MOUSE: - /* TRANSLATORS: wireless mice with internal batteries */ - text = _("Mouse"); - break; - case UP_DEVICE_KIND_KEYBOARD: - /* TRANSLATORS: wireless keyboard with internal battery */ - text = _("Keyboard"); - break; - case UP_DEVICE_KIND_PDA: - /* TRANSLATORS: portable device */ - text = _("PDA"); - break; - case UP_DEVICE_KIND_PHONE: - /* TRANSLATORS: cell phone (mobile...) */ - text = _("Cell phone"); - break; - case UP_DEVICE_KIND_MEDIA_PLAYER: - /* TRANSLATORS: media player, mp3 etc */ - text = _("Media player"); - break; - case UP_DEVICE_KIND_TABLET: - /* TRANSLATORS: tablet device */ - text = _("Tablet"); - break; - case UP_DEVICE_KIND_COMPUTER: - /* TRANSLATORS: tablet device */ - text = _("Computer"); - break; - default: - g_warning ("enum unrecognised: %i", kind); - text = up_device_kind_to_string (kind); - } - - return text; -} - -static void -build_device_time_details (const gchar *device_name, - guint64 time, - UpDeviceState state, - gdouble percentage, - gchar **short_details, - gchar **details, - gchar **accessible_name) -{ - gchar *short_timestring = NULL; - gchar *detailed_timestring = NULL; - - if (time > 0) - { - get_timestring (time, - &short_timestring, - &detailed_timestring); - - if (state == UP_DEVICE_STATE_CHARGING) - { - /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */ - *accessible_name = g_strdup_printf (_("%s (%s to charge (%.0lf%%))"), - device_name, detailed_timestring, percentage); - *details = g_strdup_printf (_("%s (%s to charge)"), - device_name, short_timestring); - *short_details = g_strdup_printf ("(%s)", short_timestring); - } - else if (state == UP_DEVICE_STATE_DISCHARGING) - { - *short_details = g_strdup_printf ("%s", short_timestring); - - if (time > 43200) /* 12 hours */ - { - *accessible_name = g_strdup_printf (_("%s"), device_name); - *details = g_strdup_printf (_("%s"), device_name); - } - else - { - /* TRANSLATORS: %2 is a time string, e.g. "1 hour 5 minutes" */ - *accessible_name = g_strdup_printf (_("%s (%s left (%.0lf%%))"), - device_name, detailed_timestring, percentage); - *details = g_strdup_printf (_("%s (%s left)"), - device_name, short_timestring); - } - } - - g_free (short_timestring); - g_free (detailed_timestring); - } - else - { - if (state == UP_DEVICE_STATE_FULLY_CHARGED) - { - *details = g_strdup_printf (_("%s (charged)"), device_name); - *accessible_name = g_strdup (*details); - *short_details = g_strdup (""); - } - else if (percentage > 0) - { - /* TRANSLATORS: %2 is a percentage value. Note: this string is only - * used when we don't have a time value */ - *details = g_strdup_printf (_("%s (%.0lf%%)"), - device_name, percentage); - *accessible_name = g_strdup (*details); - *short_details = g_strdup_printf (_("(%.0lf%%)"), - percentage); - } - else - { - *details = g_strdup_printf (_("%s (not present)"), device_name); - *accessible_name = g_strdup (*details); - *short_details = g_strdup (_("(not present)")); - } - } -} - /* ensure that the entry is using self's accessible description */ static void refresh_entry_accessible_desc (IndicatorPower * self, IndicatorObjectEntry * entry) { - const char * newval = self->accessible_desc; + const char * newval = self->priv->accessible_desc; if (entry->accessible_desc != newval) { @@ -433,8 +217,8 @@ set_accessible_desc (IndicatorPower *self, const gchar *desc) if (desc && *desc) { /* update our copy of the string */ - char * oldval = self->accessible_desc; - self->accessible_desc = g_strdup (desc); + char * oldval = self->priv->accessible_desc; + self->priv->accessible_desc = g_strdup (desc); /* ensure that the entries are using self's accessible description */ GList * l; @@ -448,194 +232,70 @@ set_accessible_desc (IndicatorPower *self, const gchar *desc) } } -static const gchar * -get_icon_percentage_for_status (const gchar *status) -{ - - if (g_strcmp0 (status, "caution") == 0) - return "000"; - else if (g_strcmp0 (status, "low") == 0) - return "040"; - else if (g_strcmp0 (status, "good") == 0) - return "080"; - else - return "100"; -} - -static GIcon* -build_battery_icon (UpDeviceState state, - gchar *suffix_str) -{ - GIcon *gicon; - - GString *filename; - gchar **iconnames; - - filename = g_string_new (NULL); - - if (state == UP_DEVICE_STATE_FULLY_CHARGED) - { - g_string_append (filename, "battery-charged;"); - g_string_append (filename, "battery-full-charged-symbolic;"); - g_string_append (filename, "battery-full-charged;"); - g_string_append (filename, "gpm-battery-charged;"); - g_string_append (filename, "gpm-battery-100-charging;"); - } - else if (state == UP_DEVICE_STATE_CHARGING) - { - g_string_append (filename, "battery-000-charging;"); - g_string_append (filename, "battery-caution-charging-symbolic;"); - g_string_append (filename, "battery-caution-charging;"); - g_string_append (filename, "gpm-battery-000-charging;"); - } - else if (state == UP_DEVICE_STATE_DISCHARGING) - { - const gchar *percentage = get_icon_percentage_for_status (suffix_str); - g_string_append_printf (filename, "battery-%s;", suffix_str); - g_string_append_printf (filename, "battery-%s-symbolic;", suffix_str); - g_string_append_printf (filename, "battery-%s;", percentage); - g_string_append_printf (filename, "gpm-battery-%s;", percentage); - } - - iconnames = g_strsplit (filename->str, ";", -1); - gicon = g_themed_icon_new_from_names (iconnames, -1); - - g_strfreev (iconnames); - g_string_free (filename, TRUE); - - return gicon; -} - -static GIcon* -get_device_icon (UpDeviceKind kind, - UpDeviceState state, - guint64 time_sec, - const gchar *device_icon) +static gboolean +menu_add_device (GtkMenu * menu, const IndicatorPowerDevice * device) { - GIcon *gicon = NULL; + gboolean added = FALSE; + const UpDeviceKind kind = indicator_power_device_get_kind (device); - if (kind == UP_DEVICE_KIND_BATTERY && - (state == UP_DEVICE_STATE_FULLY_CHARGED || - state == UP_DEVICE_STATE_CHARGING || - state == UP_DEVICE_STATE_DISCHARGING)) - { - if (state == UP_DEVICE_STATE_FULLY_CHARGED || - state == UP_DEVICE_STATE_CHARGING) - { - gicon = build_battery_icon (state, NULL); - } - else if (state == UP_DEVICE_STATE_DISCHARGING) - { - if ((time_sec > 60 * 30) && /* more than 30 minutes left */ - (g_strrstr (device_icon, "000") || - g_strrstr (device_icon, "020") || - g_strrstr (device_icon, "caution"))) /* the icon is red */ - { - gicon = build_battery_icon (state, "low"); - } - } - } - - if (gicon == NULL) - gicon = g_icon_new_for_string (device_icon, NULL); - - return gicon; -} - - -static void -menu_add_device (GtkMenu *menu, - GVariant *device) -{ - UpDeviceKind kind; - UpDeviceState state; - GtkWidget *icon; - GtkWidget *item; - GtkWidget *details_label; - GtkWidget *grid; - GIcon *device_gicons; - const gchar *device_icon = NULL; - const gchar *object_path = NULL; - gdouble percentage; - guint64 time; - const gchar *device_name; - gchar *short_details = NULL; - gchar *details = NULL; - gchar *accessible_name = NULL; - AtkObject *atk_object; - - if (device == NULL) - return; - - g_variant_get (device, - "(&su&sdut)", - &object_path, - &kind, - &device_icon, - &percentage, - &state, - &time); - - g_debug ("%s: got data from object %s", G_STRFUNC, object_path); - - if (kind == UP_DEVICE_KIND_LINE_POWER) - return; - - /* Process the data */ - device_gicons = get_device_icon (kind, state, time, device_icon); - icon = gtk_image_new_from_gicon (device_gicons, - GTK_ICON_SIZE_SMALL_TOOLBAR); - g_clear_object (&device_gicons); - - device_name = device_kind_to_localised_string (kind); - - build_device_time_details (device_name, time, state, percentage, &short_details, &details, &accessible_name); - - /* Create menu item */ - item = gtk_image_menu_item_new (); - atk_object = gtk_widget_get_accessible(item); - if (atk_object != NULL) - atk_object_set_name (atk_object, accessible_name); - - grid = gtk_grid_new (); - gtk_grid_set_column_spacing (GTK_GRID (grid), 6); - gtk_grid_attach (GTK_GRID (grid), icon, 0, 0, 1, 1); - details_label = gtk_label_new (details); - gtk_grid_attach_next_to (GTK_GRID (grid), details_label, icon, GTK_POS_RIGHT, 1, 1); - gtk_container_add (GTK_CONTAINER (item), grid); - gtk_widget_show (grid); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (show_info_cb), NULL); + if (kind != UP_DEVICE_KIND_LINE_POWER) + { + GtkWidget *icon; + GtkWidget *item; + GtkWidget *details_label; + GtkWidget *grid; + GIcon *device_gicon; + gchar *short_details = NULL; + gchar *details = NULL; + gchar *accessible_name = NULL; + AtkObject *atk_object; + + /* Process the data */ + device_gicon = indicator_power_device_get_gicon (device); + icon = gtk_image_new_from_gicon (device_gicon, GTK_ICON_SIZE_SMALL_TOOLBAR); + g_clear_object (&device_gicon); + + indicator_power_device_get_time_details (device, &short_details, &details, &accessible_name); + + /* Create menu item */ + item = gtk_image_menu_item_new (); + atk_object = gtk_widget_get_accessible(item); + if (atk_object != NULL) + atk_object_set_name (atk_object, accessible_name); + + grid = gtk_grid_new (); + gtk_grid_set_column_spacing (GTK_GRID (grid), 6); + gtk_grid_attach (GTK_GRID (grid), icon, 0, 0, 1, 1); + details_label = gtk_label_new (details); + gtk_grid_attach_next_to (GTK_GRID (grid), details_label, icon, GTK_POS_RIGHT, 1, 1); + gtk_container_add (GTK_CONTAINER (item), grid); + gtk_widget_show (grid); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + added = TRUE; + + g_signal_connect_swapped (G_OBJECT (item), "activate", + G_CALLBACK (spawn_command_line_async), "gnome-power-statistics"); + + g_free (short_details); + g_free (details); + g_free (accessible_name); + } - g_free (short_details); - g_free (details); - g_free (accessible_name); + return added; } static gsize -menu_add_devices (GtkMenu *menu, - GVariant *devices) +menu_add_devices (GtkMenu * menu, GSList * devices) { - GVariant *device; - gsize n_devices; - guint i; - - if (devices == NULL) - return 0; + GSList * l; + gsize n_added = 0; - n_devices = g_variant_n_children (devices); - g_debug ("Num devices: '%" G_GSIZE_FORMAT "'\n", n_devices); + for (l=devices; l!=NULL; l=l->next) + if (menu_add_device (menu, l->data)) + ++n_added; - for (i = 0; i < n_devices; i++) - { - device = g_variant_get_child_value (devices, i); - menu_add_device (menu, device); - } - - return n_devices; + return n_added; } static gboolean @@ -653,79 +313,62 @@ build_menu (IndicatorPower *self) GtkWidget *image; GList *children; gsize n_devices = 0; + IndicatorPowerPrivate * priv = self->priv; /* remove the existing menuitems */ - children = gtk_container_get_children (GTK_CONTAINER (self->menu)); + children = gtk_container_get_children (GTK_CONTAINER (priv->menu)); g_list_foreach (children, (GFunc) gtk_widget_destroy, NULL); g_list_free (children); /* devices */ - n_devices = menu_add_devices (self->menu, self->devices); + n_devices = menu_add_devices (priv->menu, priv->devices); if (!get_greeter_mode ()) { /* only do the separator if we have at least one device */ if (n_devices != 0) { item = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item); } /* options */ item = gtk_check_menu_item_new_with_label (_("Show Time in Menu Bar")); g_signal_connect (item, "toggled", G_CALLBACK(option_toggled_cb), self); - g_settings_bind (self->settings, "show-time", item, "active", G_SETTINGS_BIND_DEFAULT); - gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item); + g_settings_bind (priv->settings, "show-time", item, "active", G_SETTINGS_BIND_DEFAULT); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item); /* preferences */ - item = gtk_image_menu_item_new_with_label (_("Power Settings...")); + item = gtk_image_menu_item_new_with_label (_("Power Settingsā¦")); image = gtk_image_new_from_icon_name (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (show_preferences_cb), NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (self->menu), item); + g_signal_connect_swapped (G_OBJECT (item), "activate", + G_CALLBACK (spawn_command_line_async), "gnome-control-center power"); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item); } /* show the menu */ - gtk_widget_show_all (GTK_WIDGET (self->menu)); + gtk_widget_show_all (GTK_WIDGET (priv->menu)); } -static GVariant * -get_primary_device (GVariant *devices) +static IndicatorPowerDevice* +get_primary_device (GSList * devices) { - UpDeviceKind kind; - UpDeviceState state; - GVariant *device; - GVariant *primary_device_charging = NULL; - GVariant *primary_device_discharging = NULL; - GVariant *primary_device = NULL; + IndicatorPowerDevice * primary_device = NULL; + IndicatorPowerDevice * primary_device_charging = NULL; + IndicatorPowerDevice * primary_device_discharging = NULL; gboolean charging = FALSE; gboolean discharging = FALSE; - gchar *object_path; - gchar *device_icon; - gdouble percentage; - guint64 time; guint64 min_discharging_time = G_MAXUINT64; guint64 max_charging_time = 0; - gsize n_devices; - guint i; - - n_devices = devices ? g_variant_n_children (devices) : 0; - g_debug ("Num devices: '%" G_GSIZE_FORMAT "'\n", n_devices); + GSList * l; - for (i = 0; i < n_devices; i++) + for (l=devices; l!=NULL; l=l->next) { - time = 0; - device = g_variant_get_child_value (devices, i); - g_variant_get (device, - "(susdut)", - &object_path, - &kind, - &device_icon, - &percentage, - &state, - &time); - - g_debug ("%s: got data from object %s", G_STRFUNC, object_path); + IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); + const UpDeviceKind kind = indicator_power_device_get_kind (device); + const UpDeviceState state = indicator_power_device_get_state (device); + const gdouble percentage = indicator_power_device_get_percentage (device); + const time_t time = indicator_power_device_get_time (device); /* Try to fix the case when we get a empty battery bay as a real battery */ if (state == UP_DEVICE_STATE_UNKNOWN && @@ -762,9 +405,6 @@ get_primary_device (GVariant *devices) { primary_device = device; } - - g_free (device_icon); - g_free (object_path); } if (discharging) @@ -776,102 +416,56 @@ get_primary_device (GVariant *devices) primary_device = primary_device_charging; } + if (primary_device != NULL) + g_object_ref (primary_device); + return primary_device; } static void -put_primary_device (IndicatorPower *self, - GVariant *device) +put_primary_device (IndicatorPower *self, IndicatorPowerDevice *device) { - UpDeviceKind kind; - UpDeviceState state; - GIcon *device_gicons; - gchar *short_details = NULL; - gchar *details = NULL; - gchar *accessible_name = NULL; - gchar *device_icon = NULL; - gchar *object_path = NULL; - gdouble percentage; - guint64 time; - const gchar *device_name; - - /* set the icon and text */ - g_variant_get (device, - "(susdut)", - &object_path, - &kind, - &device_icon, - &percentage, - &state, - &time); - - g_debug ("%s: got data from object %s", G_STRFUNC, object_path); + IndicatorPowerPrivate * priv = self->priv; /* set icon */ - device_gicons = get_device_icon (kind, state, time, device_icon); - gtk_image_set_from_gicon (self->status_image, - device_gicons, - GTK_ICON_SIZE_LARGE_TOOLBAR); - g_clear_object (&device_gicons); - gtk_widget_show (GTK_WIDGET (self->status_image)); - - - /* get the device name */ - device_name = device_kind_to_localised_string (kind); + GIcon * device_gicon = indicator_power_device_get_gicon (device); + gtk_image_set_from_gicon (priv->status_image, device_gicon, GTK_ICON_SIZE_LARGE_TOOLBAR); + g_clear_object (&device_gicon); + gtk_widget_show (GTK_WIDGET (priv->status_image)); /* get the description */ - build_device_time_details (device_name, time, state, percentage, &short_details, &details, &accessible_name); - - gtk_label_set_label (GTK_LABEL (self->label), - short_details); + gchar * short_details; + gchar * details; + gchar * accessible_name; + indicator_power_device_get_time_details (device, &short_details, &details, &accessible_name); + gtk_label_set_label (GTK_LABEL (priv->label), short_details); set_accessible_desc (self, accessible_name); - - g_free (short_details); - g_free (details); g_free (accessible_name); - g_free (device_icon); - g_free (object_path); + g_free (details); + g_free (short_details); } -static void -get_devices_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +void +indicator_power_set_devices (IndicatorPower * self, GSList * devices) { - IndicatorPower *self = INDICATOR_POWER (user_data); - GVariant *devices_container; - GError *error = NULL; + /* LCOV_EXCL_START */ + g_return_if_fail (IS_INDICATOR_POWER(self)); + /* LCOV_EXCL_STOP */ - devices_container = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); - if (devices_container == NULL) - { - g_message ("Couldn't get devices: %s\n", error->message); - g_error_free (error); - } - else /* update 'devices' */ - { - if (self->devices != NULL) - g_variant_unref (self->devices); - self->devices = g_variant_get_child_value (devices_container, 0); + IndicatorPowerPrivate * priv = self->priv; - g_variant_unref (devices_container); - - if (self->device != NULL) - g_variant_unref (self->device); - self->device = get_primary_device (self->devices); - - if (self->device == NULL) - { - g_message ("Couldn't find primary device"); - } - else - { - put_primary_device (self, self->device); - } - } + /* update our devices & primary device */ + g_slist_foreach (devices, (GFunc)g_object_ref, NULL); + dispose_devices (self); + priv->devices = g_slist_copy (devices); + priv->device = get_primary_device (priv->devices); + /* and our menus/visibility from the new device list */ + if (priv->device != NULL) + put_primary_device (self, priv->device); + else + g_message ("Couldn't find primary device"); build_menu (self); - update_visibility (self); } @@ -882,85 +476,6 @@ update_visibility (IndicatorPower * self) should_be_visible (self)); } -static void -receive_properties_changed (GDBusProxy *proxy G_GNUC_UNUSED, - GVariant *changed_properties G_GNUC_UNUSED, - GStrv invalidated_properties G_GNUC_UNUSED, - gpointer user_data) -{ - IndicatorPower *self = INDICATOR_POWER (user_data); - - /* it's time to refresh our device list */ - g_dbus_proxy_call (self->proxy, - "GetDevices", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - self->proxy_cancel, - get_devices_cb, - user_data); -} - -static void -service_proxy_cb (GObject *object, - GAsyncResult *res, - gpointer user_data) -{ - IndicatorPower *self = INDICATOR_POWER (user_data); - GError *error = NULL; - - self->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - - g_clear_object (&self->proxy_cancel); - - if (error != NULL) - { - g_error ("Error creating proxy: %s", error->message); - g_error_free (error); - - return; - } - - /* we want to change the primary device changes */ - g_signal_connect (self->proxy, - "g-properties-changed", - G_CALLBACK (receive_properties_changed), - user_data); - - /* get the initial state */ - g_dbus_proxy_call (self->proxy, - "GetDevices", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - self->proxy_cancel, - get_devices_cb, - user_data); -} - -static void -gsd_appeared_callback (GDBusConnection *connection, - const gchar *name, - const gchar *name_owner, - gpointer user_data) -{ - IndicatorPower *self = INDICATOR_POWER (user_data); - - self->proxy_cancel = g_cancellable_new (); - - g_dbus_proxy_new (connection, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - name, - POWER_DBUS_PATH, - POWER_DBUS_INTERFACE, - self->proxy_cancel, - service_proxy_cb, - self); -} - - - /* Grabs the label. Creates it if it doesn't exist already */ @@ -968,32 +483,34 @@ static GtkLabel * get_label (IndicatorObject *io) { IndicatorPower *self = INDICATOR_POWER (io); + IndicatorPowerPrivate * priv = self->priv; - if (self->label == NULL) + if (priv->label == NULL) { /* Create the label if it doesn't exist already */ - self->label = GTK_LABEL (gtk_label_new ("")); - gtk_widget_set_visible (GTK_WIDGET (self->label), FALSE); + priv->label = GTK_LABEL (gtk_label_new ("")); + gtk_widget_set_visible (GTK_WIDGET (priv->label), FALSE); } - return self->label; + return priv->label; } static GtkImage * get_image (IndicatorObject *io) { - IndicatorPower *self = INDICATOR_POWER (io); GIcon *gicon; + IndicatorPower *self = INDICATOR_POWER (io); + IndicatorPowerPrivate * priv = self->priv; - if (self->status_image == NULL) + if (priv->status_image == NULL) { /* Will create the status icon if it doesn't exist already */ gicon = g_themed_icon_new (DEFAULT_ICON); - self->status_image = GTK_IMAGE (gtk_image_new_from_gicon (gicon, + priv->status_image = GTK_IMAGE (gtk_image_new_from_gicon (gicon, GTK_ICON_SIZE_LARGE_TOOLBAR)); } - return self->status_image; + return priv->status_image; } static GtkMenu * @@ -1003,7 +520,7 @@ get_menu (IndicatorObject *io) build_menu (self); - return GTK_MENU (self->menu); + return GTK_MENU (self->priv->menu); } static const gchar * @@ -1011,7 +528,7 @@ get_accessible_desc (IndicatorObject *io) { IndicatorPower *self = INDICATOR_POWER (io); - return self->accessible_desc; + return self->priv->accessible_desc; } static const gchar * @@ -1025,23 +542,19 @@ get_name_hint (IndicatorObject *io) ***/ static void -count_batteries(GVariant *devices, int *total, int *inuse) +count_batteries (GSList * devices, int *total, int *inuse) { - const int n_devices = devices ? g_variant_n_children (devices) : 0; + GSList * l; - int i; - for (i=0; i<n_devices; i++) + for (l=devices; l!=NULL; l=l->next) { - GVariant * device = g_variant_get_child_value (devices, i); + const IndicatorPowerDevice * device = INDICATOR_POWER_DEVICE(l->data); - UpDeviceKind kind; - g_variant_get_child (device, 1, "u", &kind); - if (kind == UP_DEVICE_KIND_BATTERY) + if (indicator_power_device_get_kind(device) == UP_DEVICE_KIND_BATTERY) { ++*total; - UpDeviceState state; - g_variant_get_child (device, 4, "u", &state); + const UpDeviceState state = indicator_power_device_get_state (device); if ((state == UP_DEVICE_STATE_CHARGING) || (state == UP_DEVICE_STATE_DISCHARGING)) ++*inuse; } @@ -1054,8 +567,9 @@ static gboolean should_be_visible (IndicatorPower * self) { gboolean visible = TRUE; + IndicatorPowerPrivate * priv = self->priv; - const int icon_policy = g_settings_get_enum (self->settings, ICON_POLICY_KEY); + const int icon_policy = g_settings_get_enum (priv->settings, ICON_POLICY_KEY); g_debug ("icon_policy is: %d (present==0, charge==1, never==2)", icon_policy); @@ -1066,7 +580,7 @@ should_be_visible (IndicatorPower * self) else { int batteries=0, inuse=0; - count_batteries (self->devices, &batteries, &inuse); + count_batteries (priv->devices, &batteries, &inuse); if (icon_policy == POWER_INDICATOR_ICON_POLICY_PRESENT) { diff --git a/src/indicator-power.h b/src/indicator-power.h new file mode 100644 index 0000000..a696b40 --- /dev/null +++ b/src/indicator-power.h @@ -0,0 +1,58 @@ +/* +An indicator to power related information in the menubar. + +Copyright 2011 Canonical Ltd. + +Authors: + Javier Jardon <javier.jardon@codethink.co.uk> + +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/>. +*/ + +/* Gtk required */ +#include <gtk/gtk.h> + +/* parent class */ +#include <libindicator/indicator.h> +#include <libindicator/indicator-object.h> + +G_BEGIN_DECLS + +#define INDICATOR_POWER_TYPE (indicator_power_get_type ()) +#define INDICATOR_POWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_POWER_TYPE, IndicatorPower)) +#define INDICATOR_POWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_POWER_TYPE, IndicatorPowerClass)) +#define IS_INDICATOR_POWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_POWER_TYPE)) +#define IS_INDICATOR_POWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_POWER_TYPE)) +#define INDICATOR_POWER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_POWER_TYPE, IndicatorPowerClass)) + +typedef struct _IndicatorPower IndicatorPower; +typedef struct _IndicatorPowerClass IndicatorPowerClass; +typedef struct _IndicatorPowerPrivate IndicatorPowerPrivate; + +struct _IndicatorPowerClass +{ + IndicatorObjectClass parent_class; +}; + +struct _IndicatorPower +{ + IndicatorObject parent_instance; + IndicatorPowerPrivate * priv; +}; + +GType indicator_power_get_type (void) G_GNUC_CONST; + +void indicator_power_set_devices (IndicatorPower * power, + GSList * devices); + +G_END_DECLS |