summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2011-12-11 12:55:19 +0100
committerStefano Karapetsas <[email protected]>2011-12-11 12:55:19 +0100
commit51175189c6d7313a3b84019e39496f957c4e6164 (patch)
treee4c2c130fa3140bca28685ef900f04a012e53dcd /src
downloadmate-power-manager-51175189c6d7313a3b84019e39496f957c4e6164.tar.bz2
mate-power-manager-51175189c6d7313a3b84019e39496f957c4e6164.tar.xz
moved from Mate-Extra
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am305
-rw-r--r--src/Makefile.in2033
-rw-r--r--src/egg-array-float.c770
-rw-r--r--src/egg-array-float.h56
-rw-r--r--src/egg-color.c157
-rw-r--r--src/egg-color.h59
-rw-r--r--src/egg-console-kit.c363
-rw-r--r--src/egg-console-kit.h71
-rw-r--r--src/egg-dbus-monitor.c251
-rw-r--r--src/egg-dbus-monitor.h65
-rw-r--r--src/egg-dbus-proxy.c301
-rw-r--r--src/egg-dbus-proxy.h66
-rw-r--r--src/egg-debug.c308
-rw-r--r--src/egg-debug.h83
-rw-r--r--src/egg-discrete.c162
-rw-r--r--src/egg-discrete.h41
-rw-r--r--src/egg-idletime.c690
-rw-r--r--src/egg-idletime.h68
-rw-r--r--src/egg-precision.c193
-rw-r--r--src/egg-precision.h39
-rw-r--r--src/egg-string.c453
-rw-r--r--src/egg-string.h47
-rw-r--r--src/egg-test.c343
-rw-r--r--src/egg-test.h48
-rw-r--r--src/egg-unique.c151
-rw-r--r--src/egg-unique.h59
-rw-r--r--src/gpm-backlight-helper.c280
-rw-r--r--src/gpm-backlight.c821
-rw-r--r--src/gpm-backlight.h73
-rw-r--r--src/gpm-brightness.c997
-rw-r--r--src/gpm-brightness.h69
-rw-r--r--src/gpm-button.c387
-rw-r--r--src/gpm-button.h73
-rw-r--r--src/gpm-common.c210
-rw-r--r--src/gpm-common.h183
-rw-r--r--src/gpm-control.c347
-rw-r--r--src/gpm-control.h88
-rw-r--r--src/gpm-disks.c209
-rw-r--r--src/gpm-disks.h57
-rw-r--r--src/gpm-dpms.c474
-rw-r--r--src/gpm-dpms.h80
-rw-r--r--src/gpm-engine.c1267
-rw-r--r--src/gpm-engine.h79
-rw-r--r--src/gpm-graph-widget.c1170
-rw-r--r--src/gpm-graph-widget.h89
-rw-r--r--src/gpm-idle.c729
-rw-r--r--src/gpm-idle.h74
-rw-r--r--src/gpm-load.c282
-rw-r--r--src/gpm-load.h56
-rw-r--r--src/gpm-main.c286
-rw-r--r--src/gpm-manager.c2110
-rw-r--r--src/gpm-manager.h82
-rw-r--r--src/gpm-marshal.list16
-rw-r--r--src/gpm-networkmanager.c102
-rw-r--r--src/gpm-networkmanager.h32
-rw-r--r--src/gpm-phone.c508
-rw-r--r--src/gpm-phone.h76
-rw-r--r--src/gpm-point-obj.c64
-rw-r--r--src/gpm-point-obj.h42
-rw-r--r--src/gpm-prefs-core.c1024
-rw-r--r--src/gpm-prefs-core.h57
-rw-r--r--src/gpm-prefs-server.c138
-rw-r--r--src/gpm-prefs-server.h67
-rw-r--r--src/gpm-prefs.c133
-rw-r--r--src/gpm-screensaver.c453
-rw-r--r--src/gpm-screensaver.h68
-rw-r--r--src/gpm-self-test.c84
-rw-r--r--src/gpm-session.c551
-rw-r--r--src/gpm-session.h79
-rw-r--r--src/gpm-statistics.c1829
-rw-r--r--src/gpm-stock-icons.h41
-rw-r--r--src/gpm-tray-icon.c430
-rw-r--r--src/gpm-tray-icon.h63
-rw-r--r--src/gpm-upower.c661
-rw-r--r--src/gpm-upower.h41
-rw-r--r--src/gsd-media-keys-window.c1079
-rw-r--r--src/gsd-media-keys-window.h71
-rw-r--r--src/org.mate.PowerManager.Backlight.xml15
-rw-r--r--src/org.mate.PowerManager.xml9
79 files changed, 25487 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..9aa8cdc
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,305 @@
+## We require new-style dependency handling.
+AUTOMAKE_OPTIONS = 1.7
+
+NULL =
+
+EXTRA_DIST = \
+ org.mate.PowerManager.xml \
+ org.mate.PowerManager.Backlight.xml \
+ gpm-marshal.list \
+ $(NULL)
+
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(MATE_CFLAGS) \
+ $(UNIQUE_CFLAGS) \
+ $(X11_CFLAGS) \
+ $(LIBMATENOTIFY_CFLAGS) \
+ $(CANBERRA_CFLAGS) \
+ $(GSTREAMER_CFLAGS) \
+ -DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE \
+ $(UPOWER_CFLAGS) \
+ -DBINDIR=\"$(bindir)\" \
+ -DSBINDIR=\"$(sbindir)\" \
+ -DMATELOCALEDIR=\""$(datadir)/locale"\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DPREFIX=\""$(prefix)"\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DLIBDIR=\""$(libdir)"\" \
+ -DVERSION="\"$(VERSION)\"" \
+ -DGPM_DATA=\"$(pkgdatadir)\" \
+ -DGTKBUILDERDIR=\"$(pkgdatadir)\" \
+ -DUP_DISABLE_DEPRECATED \
+ -DEGG_LOG_FILE=\""/tmp/gpm.log"\" \
+ -DEGG_VERBOSE="\"GPM_VERBOSE\"" \
+ -DEGG_LOGGING="\"GPM_LOGGING\"" \
+ -DEGG_CONSOLE="\"GPM_CONSOLE\"" \
+ -I$(top_srcdir) \
+ $(NULL)
+
+bin_PROGRAMS = \
+ mate-power-manager \
+ mate-power-preferences \
+ mate-power-statistics \
+ $(NULL)
+
+sbin_PROGRAMS = \
+ mate-power-backlight-helper \
+ $(NULL)
+
+check_PROGRAMS = \
+ mate-power-self-test
+
+noinst_LIBRARIES = libgpmshared.a
+libgpmshared_a_SOURCES = \
+ egg-color.c \
+ egg-color.h \
+ egg-debug.h \
+ egg-debug.c \
+ egg-unique.h \
+ egg-unique.c \
+ egg-precision.h \
+ egg-precision.c \
+ egg-array-float.c \
+ egg-array-float.h \
+ egg-idletime.h \
+ egg-idletime.c \
+ egg-dbus-proxy.h \
+ egg-dbus-proxy.c \
+ egg-dbus-monitor.h \
+ egg-dbus-monitor.c \
+ egg-discrete.h \
+ egg-discrete.c \
+ egg-string.h \
+ egg-string.c \
+ egg-console-kit.h \
+ egg-console-kit.c \
+ gpm-common.h \
+ gpm-common.c \
+ gpm-marshal.h \
+ gpm-marshal.c \
+ gpm-upower.c \
+ gpm-upower.h \
+ $(NULL)
+
+mate_power_backlight_helper_SOURCES = \
+ gpm-backlight-helper.c \
+ $(NULL)
+
+mate_power_backlight_helper_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ -lm
+
+mate_power_backlight_helper_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_statistics_SOURCES = \
+ gpm-statistics.c \
+ gpm-point-obj.c \
+ gpm-point-obj.h \
+ gpm-graph-widget.h \
+ gpm-graph-widget.c \
+ $(NULL)
+
+mate_power_statistics_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(UPOWER_LIBS) \
+ $(MATE_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(DBUS_LIBS) \
+ -lm
+
+mate_power_statistics_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_preferences_SOURCES = \
+ gpm-prefs.c \
+ gpm-prefs-core.h \
+ gpm-prefs-core.c \
+ $(NULL)
+
+mate_power_preferences_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(MATE_LIBS) \
+ $(DBUS_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(GPM_EXTRA_LIBS) \
+ $(UPOWER_LIBS) \
+ -lm
+
+mate_power_preferences_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_manager_SOURCES = \
+ gpm-dpms.h \
+ gpm-dpms.c \
+ gpm-phone.h \
+ gpm-phone.c \
+ gpm-backlight.h \
+ gpm-backlight.c \
+ gpm-prefs-server.h \
+ gpm-prefs-server.c \
+ gpm-idle.h \
+ gpm-idle.c \
+ gpm-load.h \
+ gpm-load.c \
+ gpm-disks.h \
+ gpm-disks.c \
+ gpm-control.h \
+ gpm-control.c \
+ gpm-button.h \
+ gpm-button.c \
+ gpm-brightness.h \
+ gpm-brightness.c \
+ gpm-main.c \
+ gpm-manager.h \
+ gpm-manager.c \
+ gpm-tray-icon.h \
+ gpm-tray-icon.c \
+ gpm-screensaver.h \
+ gpm-screensaver.c \
+ gpm-session.h \
+ gpm-session.c \
+ gpm-networkmanager.h \
+ gpm-networkmanager.c \
+ gpm-stock-icons.h \
+ gsd-media-keys-window.h \
+ gsd-media-keys-window.c \
+ gpm-engine.h \
+ gpm-engine.c \
+ $(NULL)
+
+mate_power_manager_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(GSTREAMER_LIBS) \
+ $(MATE_LIBS) \
+ $(DBUS_LIBS) \
+ $(X11_LIBS) \
+ $(CANBERRA_LIBS) \
+ $(LIBMATENOTIFY_LIBS) \
+ $(GPM_EXTRA_LIBS) \
+ $(UPOWER_LIBS) \
+ -lm
+
+mate_power_manager_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_self_test_SOURCES = \
+ gpm-self-test.c \
+ egg-color.h \
+ egg-color.c \
+ egg-test.h \
+ egg-test.c \
+ egg-debug.h \
+ egg-debug.c \
+ egg-dbus-monitor.h \
+ egg-dbus-monitor.c \
+ egg-dbus-proxy.h \
+ egg-dbus-proxy.c \
+ egg-precision.h \
+ egg-precision.c \
+ egg-idletime.h \
+ egg-idletime.c \
+ egg-discrete.h \
+ egg-discrete.c \
+ egg-array-float.h \
+ egg-array-float.c \
+ egg-console-kit.h \
+ egg-console-kit.c \
+ gpm-prefs-server.h \
+ gpm-prefs-server.c \
+ gpm-control.h \
+ gpm-control.c \
+ gpm-networkmanager.h \
+ gpm-networkmanager.c \
+ gpm-dpms.h \
+ gpm-dpms.c \
+ gpm-button.h \
+ gpm-button.c \
+ gpm-screensaver.h \
+ gpm-screensaver.c \
+ gpm-engine.h \
+ gpm-engine.c \
+ gpm-phone.h \
+ gpm-phone.c \
+ gpm-idle.h \
+ gpm-idle.c \
+ gpm-session.h \
+ gpm-session.c \
+ gpm-load.h \
+ gpm-load.c \
+ gpm-marshal.h \
+ gpm-marshal.c \
+ gpm-common.h \
+ gpm-common.c \
+ gpm-upower.h \
+ gpm-upower.c \
+ $(NULL)
+
+mate_power_self_test_LDADD = \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(MATE_LIBS) \
+ $(GSTREAMER_LIBS) \
+ $(UPOWER_LIBS) \
+ $(DBUS_LIBS) \
+ $(X11_LIBS) \
+ $(LIBMATENOTIFY_LIBS) \
+ $(GPM_EXTRA_LIBS) \
+ -lm
+
+mate_power_self_test_CFLAGS = -DEGG_TEST $(AM_CFLAGS) $(WARNINGFLAGS)
+
+BUILT_SOURCES = \
+ org.mate.PowerManager.h \
+ org.mate.PowerManager.Backlight.h \
+ gpm-marshal.c \
+ gpm-marshal.h \
+ $(NULL)
+
+gpm-marshal.c: gpm-marshal.list
+ echo "#include \"gpm-marshal.h\"" > $@ && \
+ @GLIB_GENMARSHAL@ $< --prefix=gpm_marshal --body >> $@
+
+gpm-marshal.h: gpm-marshal.list
+ @GLIB_GENMARSHAL@ $< --prefix=gpm_marshal --header > $@
+
+org.mate.PowerManager.h: org.mate.PowerManager.xml
+ libtool --mode=execute dbus-binding-tool \
+ --prefix=gpm_manager \
+ --mode=glib-server \
+ --output=org.mate.PowerManager.h \
+ $(srcdir)/org.mate.PowerManager.xml
+
+org.mate.PowerManager.Backlight.h: org.mate.PowerManager.Backlight.xml
+ libtool --mode=execute dbus-binding-tool \
+ --prefix=gpm_backlight \
+ --mode=glib-server \
+ --output=org.mate.PowerManager.Backlight.h \
+ $(srcdir)/org.mate.PowerManager.Backlight.xml
+
+clean-local:
+ rm -f *~
+ rm -f gpm-marshal.c gpm-marshal.h
+
+CLEANFILES = $(BUILT_SOURCES)
+
+TESTS = mate-power-self-test
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in \
+ $(NULL)
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..8ba1f19
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,2033 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@
+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@
+bin_PROGRAMS = mate-power-manager$(EXEEXT) \
+ mate-power-preferences$(EXEEXT) mate-power-statistics$(EXEEXT) \
+ $(am__EXEEXT_1)
+sbin_PROGRAMS = mate-power-backlight-helper$(EXEEXT) $(am__EXEEXT_1)
+check_PROGRAMS = mate-power-self-test$(EXEEXT)
+TESTS = mate-power-self-test$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/mate-doc-utils.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_$(V))
+am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
+am__v_AR_0 = @echo " AR " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+libgpmshared_a_AR = $(AR) $(ARFLAGS)
+libgpmshared_a_LIBADD =
+am__objects_1 =
+am_libgpmshared_a_OBJECTS = egg-color.$(OBJEXT) egg-debug.$(OBJEXT) \
+ egg-unique.$(OBJEXT) egg-precision.$(OBJEXT) \
+ egg-array-float.$(OBJEXT) egg-idletime.$(OBJEXT) \
+ egg-dbus-proxy.$(OBJEXT) egg-dbus-monitor.$(OBJEXT) \
+ egg-discrete.$(OBJEXT) egg-string.$(OBJEXT) \
+ egg-console-kit.$(OBJEXT) gpm-common.$(OBJEXT) \
+ gpm-marshal.$(OBJEXT) gpm-upower.$(OBJEXT) $(am__objects_1)
+libgpmshared_a_OBJECTS = $(am_libgpmshared_a_OBJECTS)
+am__EXEEXT_1 =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
+PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
+am_mate_power_backlight_helper_OBJECTS = \
+ mate_power_backlight_helper-gpm-backlight-helper.$(OBJEXT) \
+ $(am__objects_1)
+mate_power_backlight_helper_OBJECTS = \
+ $(am_mate_power_backlight_helper_OBJECTS)
+am__DEPENDENCIES_1 =
+mate_power_backlight_helper_DEPENDENCIES = libgpmshared.a \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+mate_power_backlight_helper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(mate_power_backlight_helper_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_mate_power_manager_OBJECTS = mate_power_manager-gpm-dpms.$(OBJEXT) \
+ mate_power_manager-gpm-phone.$(OBJEXT) \
+ mate_power_manager-gpm-backlight.$(OBJEXT) \
+ mate_power_manager-gpm-prefs-server.$(OBJEXT) \
+ mate_power_manager-gpm-idle.$(OBJEXT) \
+ mate_power_manager-gpm-load.$(OBJEXT) \
+ mate_power_manager-gpm-disks.$(OBJEXT) \
+ mate_power_manager-gpm-control.$(OBJEXT) \
+ mate_power_manager-gpm-button.$(OBJEXT) \
+ mate_power_manager-gpm-brightness.$(OBJEXT) \
+ mate_power_manager-gpm-main.$(OBJEXT) \
+ mate_power_manager-gpm-manager.$(OBJEXT) \
+ mate_power_manager-gpm-tray-icon.$(OBJEXT) \
+ mate_power_manager-gpm-screensaver.$(OBJEXT) \
+ mate_power_manager-gpm-session.$(OBJEXT) \
+ mate_power_manager-gpm-networkmanager.$(OBJEXT) \
+ mate_power_manager-gsd-media-keys-window.$(OBJEXT) \
+ mate_power_manager-gpm-engine.$(OBJEXT) $(am__objects_1)
+mate_power_manager_OBJECTS = $(am_mate_power_manager_OBJECTS)
+mate_power_manager_DEPENDENCIES = libgpmshared.a $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+mate_power_manager_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(mate_power_manager_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_mate_power_preferences_OBJECTS = \
+ mate_power_preferences-gpm-prefs.$(OBJEXT) \
+ mate_power_preferences-gpm-prefs-core.$(OBJEXT) \
+ $(am__objects_1)
+mate_power_preferences_OBJECTS = $(am_mate_power_preferences_OBJECTS)
+mate_power_preferences_DEPENDENCIES = libgpmshared.a \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+mate_power_preferences_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(mate_power_preferences_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_mate_power_self_test_OBJECTS = \
+ mate_power_self_test-gpm-self-test.$(OBJEXT) \
+ mate_power_self_test-egg-color.$(OBJEXT) \
+ mate_power_self_test-egg-test.$(OBJEXT) \
+ mate_power_self_test-egg-debug.$(OBJEXT) \
+ mate_power_self_test-egg-dbus-monitor.$(OBJEXT) \
+ mate_power_self_test-egg-dbus-proxy.$(OBJEXT) \
+ mate_power_self_test-egg-precision.$(OBJEXT) \
+ mate_power_self_test-egg-idletime.$(OBJEXT) \
+ mate_power_self_test-egg-discrete.$(OBJEXT) \
+ mate_power_self_test-egg-array-float.$(OBJEXT) \
+ mate_power_self_test-egg-console-kit.$(OBJEXT) \
+ mate_power_self_test-gpm-prefs-server.$(OBJEXT) \
+ mate_power_self_test-gpm-control.$(OBJEXT) \
+ mate_power_self_test-gpm-networkmanager.$(OBJEXT) \
+ mate_power_self_test-gpm-dpms.$(OBJEXT) \
+ mate_power_self_test-gpm-button.$(OBJEXT) \
+ mate_power_self_test-gpm-screensaver.$(OBJEXT) \
+ mate_power_self_test-gpm-engine.$(OBJEXT) \
+ mate_power_self_test-gpm-phone.$(OBJEXT) \
+ mate_power_self_test-gpm-idle.$(OBJEXT) \
+ mate_power_self_test-gpm-session.$(OBJEXT) \
+ mate_power_self_test-gpm-load.$(OBJEXT) \
+ mate_power_self_test-gpm-marshal.$(OBJEXT) \
+ mate_power_self_test-gpm-common.$(OBJEXT) \
+ mate_power_self_test-gpm-upower.$(OBJEXT) $(am__objects_1)
+mate_power_self_test_OBJECTS = $(am_mate_power_self_test_OBJECTS)
+mate_power_self_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+mate_power_self_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(mate_power_self_test_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_mate_power_statistics_OBJECTS = \
+ mate_power_statistics-gpm-statistics.$(OBJEXT) \
+ mate_power_statistics-gpm-point-obj.$(OBJEXT) \
+ mate_power_statistics-gpm-graph-widget.$(OBJEXT) \
+ $(am__objects_1)
+mate_power_statistics_OBJECTS = $(am_mate_power_statistics_OBJECTS)
+mate_power_statistics_DEPENDENCIES = libgpmshared.a \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+mate_power_statistics_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(mate_power_statistics_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/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_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+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_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libgpmshared_a_SOURCES) \
+ $(mate_power_backlight_helper_SOURCES) \
+ $(mate_power_manager_SOURCES) \
+ $(mate_power_preferences_SOURCES) \
+ $(mate_power_self_test_SOURCES) \
+ $(mate_power_statistics_SOURCES)
+DIST_SOURCES = $(libgpmshared_a_SOURCES) \
+ $(mate_power_backlight_helper_SOURCES) \
+ $(mate_power_manager_SOURCES) \
+ $(mate_power_preferences_SOURCES) \
+ $(mate_power_self_test_SOURCES) \
+ $(mate_power_statistics_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+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@
+BINDIR = @BINDIR@
+CANBERRA_CFLAGS = @CANBERRA_CFLAGS@
+CANBERRA_LIBS = @CANBERRA_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIR = @DATADIR@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SERVICES_DIR = @DBUS_SERVICES_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
+DOCBOOK2MAN = @DOCBOOK2MAN@
+DOCDIR = @DOCDIR@
+DOC_USER_FORMATS = @DOC_USER_FORMATS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GDK_CFLAGS = @GDK_CFLAGS@
+GDK_LIBS = @GDK_LIBS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GPM_EXTRA_LIBS = @GPM_EXTRA_LIBS@
+GREP = @GREP@
+HELP_DIR = @HELP_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBMATENOTIFY_CFLAGS = @LIBMATENOTIFY_CFLAGS@
+LIBMATENOTIFY_LIBS = @LIBMATENOTIFY_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MATECONFTOOL = @MATECONFTOOL@
+MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@
+MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@
+MATE_CFLAGS = @MATE_CFLAGS@
+MATE_LIBS = @MATE_LIBS@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMF_DIR = @OMF_DIR@
+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@
+PANEL_CFLAGS = @PANEL_CFLAGS@
+PANEL_LIBS = @PANEL_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+RANLIB = @RANLIB@
+SBINDIR = @SBINDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSCONFDIR = @SYSCONFDIR@
+UNIQUE_CFLAGS = @UNIQUE_CFLAGS@
+UNIQUE_LIBS = @UNIQUE_LIBS@
+UPOWER_CFLAGS = @UPOWER_CFLAGS@
+UPOWER_LIBS = @UPOWER_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARNINGFLAGS = @WARNINGFLAGS@
+WARN_CFLAGS = @WARN_CFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+XMLTO = @XMLTO@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+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@
+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@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+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@
+AUTOMAKE_OPTIONS = 1.7
+NULL =
+EXTRA_DIST = \
+ org.mate.PowerManager.xml \
+ org.mate.PowerManager.Backlight.xml \
+ gpm-marshal.list \
+ $(NULL)
+
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(MATE_CFLAGS) \
+ $(UNIQUE_CFLAGS) \
+ $(X11_CFLAGS) \
+ $(LIBMATENOTIFY_CFLAGS) \
+ $(CANBERRA_CFLAGS) \
+ $(GSTREAMER_CFLAGS) \
+ -DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE \
+ $(UPOWER_CFLAGS) \
+ -DBINDIR=\"$(bindir)\" \
+ -DSBINDIR=\"$(sbindir)\" \
+ -DMATELOCALEDIR=\""$(datadir)/locale"\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DPREFIX=\""$(prefix)"\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DLIBDIR=\""$(libdir)"\" \
+ -DVERSION="\"$(VERSION)\"" \
+ -DGPM_DATA=\"$(pkgdatadir)\" \
+ -DGTKBUILDERDIR=\"$(pkgdatadir)\" \
+ -DUP_DISABLE_DEPRECATED \
+ -DEGG_LOG_FILE=\""/tmp/gpm.log"\" \
+ -DEGG_VERBOSE="\"GPM_VERBOSE\"" \
+ -DEGG_LOGGING="\"GPM_LOGGING\"" \
+ -DEGG_CONSOLE="\"GPM_CONSOLE\"" \
+ -I$(top_srcdir) \
+ $(NULL)
+
+noinst_LIBRARIES = libgpmshared.a
+libgpmshared_a_SOURCES = \
+ egg-color.c \
+ egg-color.h \
+ egg-debug.h \
+ egg-debug.c \
+ egg-unique.h \
+ egg-unique.c \
+ egg-precision.h \
+ egg-precision.c \
+ egg-array-float.c \
+ egg-array-float.h \
+ egg-idletime.h \
+ egg-idletime.c \
+ egg-dbus-proxy.h \
+ egg-dbus-proxy.c \
+ egg-dbus-monitor.h \
+ egg-dbus-monitor.c \
+ egg-discrete.h \
+ egg-discrete.c \
+ egg-string.h \
+ egg-string.c \
+ egg-console-kit.h \
+ egg-console-kit.c \
+ gpm-common.h \
+ gpm-common.c \
+ gpm-marshal.h \
+ gpm-marshal.c \
+ gpm-upower.c \
+ gpm-upower.h \
+ $(NULL)
+
+mate_power_backlight_helper_SOURCES = \
+ gpm-backlight-helper.c \
+ $(NULL)
+
+mate_power_backlight_helper_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ -lm
+
+mate_power_backlight_helper_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_statistics_SOURCES = \
+ gpm-statistics.c \
+ gpm-point-obj.c \
+ gpm-point-obj.h \
+ gpm-graph-widget.h \
+ gpm-graph-widget.c \
+ $(NULL)
+
+mate_power_statistics_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(UPOWER_LIBS) \
+ $(MATE_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(DBUS_LIBS) \
+ -lm
+
+mate_power_statistics_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_preferences_SOURCES = \
+ gpm-prefs.c \
+ gpm-prefs-core.h \
+ gpm-prefs-core.c \
+ $(NULL)
+
+mate_power_preferences_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(MATE_LIBS) \
+ $(DBUS_LIBS) \
+ $(UNIQUE_LIBS) \
+ $(GPM_EXTRA_LIBS) \
+ $(UPOWER_LIBS) \
+ -lm
+
+mate_power_preferences_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_manager_SOURCES = \
+ gpm-dpms.h \
+ gpm-dpms.c \
+ gpm-phone.h \
+ gpm-phone.c \
+ gpm-backlight.h \
+ gpm-backlight.c \
+ gpm-prefs-server.h \
+ gpm-prefs-server.c \
+ gpm-idle.h \
+ gpm-idle.c \
+ gpm-load.h \
+ gpm-load.c \
+ gpm-disks.h \
+ gpm-disks.c \
+ gpm-control.h \
+ gpm-control.c \
+ gpm-button.h \
+ gpm-button.c \
+ gpm-brightness.h \
+ gpm-brightness.c \
+ gpm-main.c \
+ gpm-manager.h \
+ gpm-manager.c \
+ gpm-tray-icon.h \
+ gpm-tray-icon.c \
+ gpm-screensaver.h \
+ gpm-screensaver.c \
+ gpm-session.h \
+ gpm-session.c \
+ gpm-networkmanager.h \
+ gpm-networkmanager.c \
+ gpm-stock-icons.h \
+ gsd-media-keys-window.h \
+ gsd-media-keys-window.c \
+ gpm-engine.h \
+ gpm-engine.c \
+ $(NULL)
+
+mate_power_manager_LDADD = \
+ libgpmshared.a \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(GSTREAMER_LIBS) \
+ $(MATE_LIBS) \
+ $(DBUS_LIBS) \
+ $(X11_LIBS) \
+ $(CANBERRA_LIBS) \
+ $(LIBMATENOTIFY_LIBS) \
+ $(GPM_EXTRA_LIBS) \
+ $(UPOWER_LIBS) \
+ -lm
+
+mate_power_manager_CFLAGS = \
+ $(WARNINGFLAGS) \
+ $(NULL)
+
+mate_power_self_test_SOURCES = \
+ gpm-self-test.c \
+ egg-color.h \
+ egg-color.c \
+ egg-test.h \
+ egg-test.c \
+ egg-debug.h \
+ egg-debug.c \
+ egg-dbus-monitor.h \
+ egg-dbus-monitor.c \
+ egg-dbus-proxy.h \
+ egg-dbus-proxy.c \
+ egg-precision.h \
+ egg-precision.c \
+ egg-idletime.h \
+ egg-idletime.c \
+ egg-discrete.h \
+ egg-discrete.c \
+ egg-array-float.h \
+ egg-array-float.c \
+ egg-console-kit.h \
+ egg-console-kit.c \
+ gpm-prefs-server.h \
+ gpm-prefs-server.c \
+ gpm-control.h \
+ gpm-control.c \
+ gpm-networkmanager.h \
+ gpm-networkmanager.c \
+ gpm-dpms.h \
+ gpm-dpms.c \
+ gpm-button.h \
+ gpm-button.c \
+ gpm-screensaver.h \
+ gpm-screensaver.c \
+ gpm-engine.h \
+ gpm-engine.c \
+ gpm-phone.h \
+ gpm-phone.c \
+ gpm-idle.h \
+ gpm-idle.c \
+ gpm-session.h \
+ gpm-session.c \
+ gpm-load.h \
+ gpm-load.c \
+ gpm-marshal.h \
+ gpm-marshal.c \
+ gpm-common.h \
+ gpm-common.c \
+ gpm-upower.h \
+ gpm-upower.c \
+ $(NULL)
+
+mate_power_self_test_LDADD = \
+ $(GLIB_LIBS) \
+ $(X11_LIBS) \
+ $(MATE_LIBS) \
+ $(GSTREAMER_LIBS) \
+ $(UPOWER_LIBS) \
+ $(DBUS_LIBS) \
+ $(X11_LIBS) \
+ $(LIBMATENOTIFY_LIBS) \
+ $(GPM_EXTRA_LIBS) \
+ -lm
+
+mate_power_self_test_CFLAGS = -DEGG_TEST $(AM_CFLAGS) $(WARNINGFLAGS)
+BUILT_SOURCES = \
+ org.mate.PowerManager.h \
+ org.mate.PowerManager.Backlight.h \
+ gpm-marshal.c \
+ gpm-marshal.h \
+ $(NULL)
+
+CLEANFILES = $(BUILT_SOURCES)
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in \
+ $(NULL)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(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: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libgpmshared.a: $(libgpmshared_a_OBJECTS) $(libgpmshared_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f libgpmshared.a
+ $(AM_V_AR)$(libgpmshared_a_AR) libgpmshared.a $(libgpmshared_a_OBJECTS) $(libgpmshared_a_LIBADD)
+ $(AM_V_at)$(RANLIB) libgpmshared.a
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+mate-power-backlight-helper$(EXEEXT): $(mate_power_backlight_helper_OBJECTS) $(mate_power_backlight_helper_DEPENDENCIES)
+ @rm -f mate-power-backlight-helper$(EXEEXT)
+ $(AM_V_CCLD)$(mate_power_backlight_helper_LINK) $(mate_power_backlight_helper_OBJECTS) $(mate_power_backlight_helper_LDADD) $(LIBS)
+mate-power-manager$(EXEEXT): $(mate_power_manager_OBJECTS) $(mate_power_manager_DEPENDENCIES)
+ @rm -f mate-power-manager$(EXEEXT)
+ $(AM_V_CCLD)$(mate_power_manager_LINK) $(mate_power_manager_OBJECTS) $(mate_power_manager_LDADD) $(LIBS)
+mate-power-preferences$(EXEEXT): $(mate_power_preferences_OBJECTS) $(mate_power_preferences_DEPENDENCIES)
+ @rm -f mate-power-preferences$(EXEEXT)
+ $(AM_V_CCLD)$(mate_power_preferences_LINK) $(mate_power_preferences_OBJECTS) $(mate_power_preferences_LDADD) $(LIBS)
+mate-power-self-test$(EXEEXT): $(mate_power_self_test_OBJECTS) $(mate_power_self_test_DEPENDENCIES)
+ @rm -f mate-power-self-test$(EXEEXT)
+ $(AM_V_CCLD)$(mate_power_self_test_LINK) $(mate_power_self_test_OBJECTS) $(mate_power_self_test_LDADD) $(LIBS)
+mate-power-statistics$(EXEEXT): $(mate_power_statistics_OBJECTS) $(mate_power_statistics_DEPENDENCIES)
+ @rm -f mate-power-statistics$(EXEEXT)
+ $(AM_V_CCLD)$(mate_power_statistics_LINK) $(mate_power_statistics_OBJECTS) $(mate_power_statistics_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-array-float.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-color.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-console-kit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-dbus-monitor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-dbus-proxy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-debug.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-discrete.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-idletime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-precision.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-string.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/egg-unique.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpm-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpm-marshal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpm-upower.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-backlight.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-brightness.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-button.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-control.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-disks.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-dpms.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-engine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-idle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-load.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-networkmanager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-phone.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-prefs-server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-screensaver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gpm-tray-icon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_manager-gsd-media-keys-window.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_preferences-gpm-prefs-core.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_preferences-gpm-prefs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-array-float.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-color.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-console-kit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-debug.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-discrete.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-idletime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-precision.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-egg-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-button.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-control.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-dpms.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-engine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-idle.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-load.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-marshal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-networkmanager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-phone.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-prefs-server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-screensaver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-self-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_self_test-gpm-upower.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_statistics-gpm-graph-widget.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_statistics-gpm-point-obj.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mate_power_statistics-gpm-statistics.Po@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
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(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
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mate_power_backlight_helper-gpm-backlight-helper.o: gpm-backlight-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_backlight_helper_CFLAGS) $(CFLAGS) -MT mate_power_backlight_helper-gpm-backlight-helper.o -MD -MP -MF $(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Tpo -c -o mate_power_backlight_helper-gpm-backlight-helper.o `test -f 'gpm-backlight-helper.c' || echo '$(srcdir)/'`gpm-backlight-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Tpo $(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-backlight-helper.c' object='mate_power_backlight_helper-gpm-backlight-helper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_backlight_helper_CFLAGS) $(CFLAGS) -c -o mate_power_backlight_helper-gpm-backlight-helper.o `test -f 'gpm-backlight-helper.c' || echo '$(srcdir)/'`gpm-backlight-helper.c
+
+mate_power_backlight_helper-gpm-backlight-helper.obj: gpm-backlight-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_backlight_helper_CFLAGS) $(CFLAGS) -MT mate_power_backlight_helper-gpm-backlight-helper.obj -MD -MP -MF $(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Tpo -c -o mate_power_backlight_helper-gpm-backlight-helper.obj `if test -f 'gpm-backlight-helper.c'; then $(CYGPATH_W) 'gpm-backlight-helper.c'; else $(CYGPATH_W) '$(srcdir)/gpm-backlight-helper.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Tpo $(DEPDIR)/mate_power_backlight_helper-gpm-backlight-helper.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-backlight-helper.c' object='mate_power_backlight_helper-gpm-backlight-helper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_backlight_helper_CFLAGS) $(CFLAGS) -c -o mate_power_backlight_helper-gpm-backlight-helper.obj `if test -f 'gpm-backlight-helper.c'; then $(CYGPATH_W) 'gpm-backlight-helper.c'; else $(CYGPATH_W) '$(srcdir)/gpm-backlight-helper.c'; fi`
+
+mate_power_manager-gpm-dpms.o: gpm-dpms.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-dpms.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-dpms.Tpo -c -o mate_power_manager-gpm-dpms.o `test -f 'gpm-dpms.c' || echo '$(srcdir)/'`gpm-dpms.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-dpms.Tpo $(DEPDIR)/mate_power_manager-gpm-dpms.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-dpms.c' object='mate_power_manager-gpm-dpms.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-dpms.o `test -f 'gpm-dpms.c' || echo '$(srcdir)/'`gpm-dpms.c
+
+mate_power_manager-gpm-dpms.obj: gpm-dpms.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-dpms.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-dpms.Tpo -c -o mate_power_manager-gpm-dpms.obj `if test -f 'gpm-dpms.c'; then $(CYGPATH_W) 'gpm-dpms.c'; else $(CYGPATH_W) '$(srcdir)/gpm-dpms.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-dpms.Tpo $(DEPDIR)/mate_power_manager-gpm-dpms.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-dpms.c' object='mate_power_manager-gpm-dpms.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-dpms.obj `if test -f 'gpm-dpms.c'; then $(CYGPATH_W) 'gpm-dpms.c'; else $(CYGPATH_W) '$(srcdir)/gpm-dpms.c'; fi`
+
+mate_power_manager-gpm-phone.o: gpm-phone.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-phone.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-phone.Tpo -c -o mate_power_manager-gpm-phone.o `test -f 'gpm-phone.c' || echo '$(srcdir)/'`gpm-phone.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-phone.Tpo $(DEPDIR)/mate_power_manager-gpm-phone.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-phone.c' object='mate_power_manager-gpm-phone.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-phone.o `test -f 'gpm-phone.c' || echo '$(srcdir)/'`gpm-phone.c
+
+mate_power_manager-gpm-phone.obj: gpm-phone.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-phone.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-phone.Tpo -c -o mate_power_manager-gpm-phone.obj `if test -f 'gpm-phone.c'; then $(CYGPATH_W) 'gpm-phone.c'; else $(CYGPATH_W) '$(srcdir)/gpm-phone.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-phone.Tpo $(DEPDIR)/mate_power_manager-gpm-phone.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-phone.c' object='mate_power_manager-gpm-phone.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-phone.obj `if test -f 'gpm-phone.c'; then $(CYGPATH_W) 'gpm-phone.c'; else $(CYGPATH_W) '$(srcdir)/gpm-phone.c'; fi`
+
+mate_power_manager-gpm-backlight.o: gpm-backlight.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-backlight.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-backlight.Tpo -c -o mate_power_manager-gpm-backlight.o `test -f 'gpm-backlight.c' || echo '$(srcdir)/'`gpm-backlight.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-backlight.Tpo $(DEPDIR)/mate_power_manager-gpm-backlight.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-backlight.c' object='mate_power_manager-gpm-backlight.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-backlight.o `test -f 'gpm-backlight.c' || echo '$(srcdir)/'`gpm-backlight.c
+
+mate_power_manager-gpm-backlight.obj: gpm-backlight.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-backlight.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-backlight.Tpo -c -o mate_power_manager-gpm-backlight.obj `if test -f 'gpm-backlight.c'; then $(CYGPATH_W) 'gpm-backlight.c'; else $(CYGPATH_W) '$(srcdir)/gpm-backlight.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-backlight.Tpo $(DEPDIR)/mate_power_manager-gpm-backlight.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-backlight.c' object='mate_power_manager-gpm-backlight.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-backlight.obj `if test -f 'gpm-backlight.c'; then $(CYGPATH_W) 'gpm-backlight.c'; else $(CYGPATH_W) '$(srcdir)/gpm-backlight.c'; fi`
+
+mate_power_manager-gpm-prefs-server.o: gpm-prefs-server.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-prefs-server.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-prefs-server.Tpo -c -o mate_power_manager-gpm-prefs-server.o `test -f 'gpm-prefs-server.c' || echo '$(srcdir)/'`gpm-prefs-server.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-prefs-server.Tpo $(DEPDIR)/mate_power_manager-gpm-prefs-server.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs-server.c' object='mate_power_manager-gpm-prefs-server.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-prefs-server.o `test -f 'gpm-prefs-server.c' || echo '$(srcdir)/'`gpm-prefs-server.c
+
+mate_power_manager-gpm-prefs-server.obj: gpm-prefs-server.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-prefs-server.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-prefs-server.Tpo -c -o mate_power_manager-gpm-prefs-server.obj `if test -f 'gpm-prefs-server.c'; then $(CYGPATH_W) 'gpm-prefs-server.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs-server.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-prefs-server.Tpo $(DEPDIR)/mate_power_manager-gpm-prefs-server.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs-server.c' object='mate_power_manager-gpm-prefs-server.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-prefs-server.obj `if test -f 'gpm-prefs-server.c'; then $(CYGPATH_W) 'gpm-prefs-server.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs-server.c'; fi`
+
+mate_power_manager-gpm-idle.o: gpm-idle.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-idle.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-idle.Tpo -c -o mate_power_manager-gpm-idle.o `test -f 'gpm-idle.c' || echo '$(srcdir)/'`gpm-idle.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-idle.Tpo $(DEPDIR)/mate_power_manager-gpm-idle.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-idle.c' object='mate_power_manager-gpm-idle.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-idle.o `test -f 'gpm-idle.c' || echo '$(srcdir)/'`gpm-idle.c
+
+mate_power_manager-gpm-idle.obj: gpm-idle.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-idle.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-idle.Tpo -c -o mate_power_manager-gpm-idle.obj `if test -f 'gpm-idle.c'; then $(CYGPATH_W) 'gpm-idle.c'; else $(CYGPATH_W) '$(srcdir)/gpm-idle.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-idle.Tpo $(DEPDIR)/mate_power_manager-gpm-idle.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-idle.c' object='mate_power_manager-gpm-idle.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-idle.obj `if test -f 'gpm-idle.c'; then $(CYGPATH_W) 'gpm-idle.c'; else $(CYGPATH_W) '$(srcdir)/gpm-idle.c'; fi`
+
+mate_power_manager-gpm-load.o: gpm-load.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-load.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-load.Tpo -c -o mate_power_manager-gpm-load.o `test -f 'gpm-load.c' || echo '$(srcdir)/'`gpm-load.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-load.Tpo $(DEPDIR)/mate_power_manager-gpm-load.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-load.c' object='mate_power_manager-gpm-load.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-load.o `test -f 'gpm-load.c' || echo '$(srcdir)/'`gpm-load.c
+
+mate_power_manager-gpm-load.obj: gpm-load.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-load.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-load.Tpo -c -o mate_power_manager-gpm-load.obj `if test -f 'gpm-load.c'; then $(CYGPATH_W) 'gpm-load.c'; else $(CYGPATH_W) '$(srcdir)/gpm-load.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-load.Tpo $(DEPDIR)/mate_power_manager-gpm-load.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-load.c' object='mate_power_manager-gpm-load.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-load.obj `if test -f 'gpm-load.c'; then $(CYGPATH_W) 'gpm-load.c'; else $(CYGPATH_W) '$(srcdir)/gpm-load.c'; fi`
+
+mate_power_manager-gpm-disks.o: gpm-disks.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-disks.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-disks.Tpo -c -o mate_power_manager-gpm-disks.o `test -f 'gpm-disks.c' || echo '$(srcdir)/'`gpm-disks.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-disks.Tpo $(DEPDIR)/mate_power_manager-gpm-disks.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-disks.c' object='mate_power_manager-gpm-disks.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-disks.o `test -f 'gpm-disks.c' || echo '$(srcdir)/'`gpm-disks.c
+
+mate_power_manager-gpm-disks.obj: gpm-disks.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-disks.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-disks.Tpo -c -o mate_power_manager-gpm-disks.obj `if test -f 'gpm-disks.c'; then $(CYGPATH_W) 'gpm-disks.c'; else $(CYGPATH_W) '$(srcdir)/gpm-disks.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-disks.Tpo $(DEPDIR)/mate_power_manager-gpm-disks.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-disks.c' object='mate_power_manager-gpm-disks.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-disks.obj `if test -f 'gpm-disks.c'; then $(CYGPATH_W) 'gpm-disks.c'; else $(CYGPATH_W) '$(srcdir)/gpm-disks.c'; fi`
+
+mate_power_manager-gpm-control.o: gpm-control.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-control.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-control.Tpo -c -o mate_power_manager-gpm-control.o `test -f 'gpm-control.c' || echo '$(srcdir)/'`gpm-control.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-control.Tpo $(DEPDIR)/mate_power_manager-gpm-control.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-control.c' object='mate_power_manager-gpm-control.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-control.o `test -f 'gpm-control.c' || echo '$(srcdir)/'`gpm-control.c
+
+mate_power_manager-gpm-control.obj: gpm-control.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-control.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-control.Tpo -c -o mate_power_manager-gpm-control.obj `if test -f 'gpm-control.c'; then $(CYGPATH_W) 'gpm-control.c'; else $(CYGPATH_W) '$(srcdir)/gpm-control.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-control.Tpo $(DEPDIR)/mate_power_manager-gpm-control.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-control.c' object='mate_power_manager-gpm-control.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-control.obj `if test -f 'gpm-control.c'; then $(CYGPATH_W) 'gpm-control.c'; else $(CYGPATH_W) '$(srcdir)/gpm-control.c'; fi`
+
+mate_power_manager-gpm-button.o: gpm-button.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-button.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-button.Tpo -c -o mate_power_manager-gpm-button.o `test -f 'gpm-button.c' || echo '$(srcdir)/'`gpm-button.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-button.Tpo $(DEPDIR)/mate_power_manager-gpm-button.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-button.c' object='mate_power_manager-gpm-button.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-button.o `test -f 'gpm-button.c' || echo '$(srcdir)/'`gpm-button.c
+
+mate_power_manager-gpm-button.obj: gpm-button.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-button.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-button.Tpo -c -o mate_power_manager-gpm-button.obj `if test -f 'gpm-button.c'; then $(CYGPATH_W) 'gpm-button.c'; else $(CYGPATH_W) '$(srcdir)/gpm-button.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-button.Tpo $(DEPDIR)/mate_power_manager-gpm-button.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-button.c' object='mate_power_manager-gpm-button.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-button.obj `if test -f 'gpm-button.c'; then $(CYGPATH_W) 'gpm-button.c'; else $(CYGPATH_W) '$(srcdir)/gpm-button.c'; fi`
+
+mate_power_manager-gpm-brightness.o: gpm-brightness.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-brightness.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-brightness.Tpo -c -o mate_power_manager-gpm-brightness.o `test -f 'gpm-brightness.c' || echo '$(srcdir)/'`gpm-brightness.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-brightness.Tpo $(DEPDIR)/mate_power_manager-gpm-brightness.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-brightness.c' object='mate_power_manager-gpm-brightness.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-brightness.o `test -f 'gpm-brightness.c' || echo '$(srcdir)/'`gpm-brightness.c
+
+mate_power_manager-gpm-brightness.obj: gpm-brightness.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-brightness.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-brightness.Tpo -c -o mate_power_manager-gpm-brightness.obj `if test -f 'gpm-brightness.c'; then $(CYGPATH_W) 'gpm-brightness.c'; else $(CYGPATH_W) '$(srcdir)/gpm-brightness.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-brightness.Tpo $(DEPDIR)/mate_power_manager-gpm-brightness.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-brightness.c' object='mate_power_manager-gpm-brightness.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-brightness.obj `if test -f 'gpm-brightness.c'; then $(CYGPATH_W) 'gpm-brightness.c'; else $(CYGPATH_W) '$(srcdir)/gpm-brightness.c'; fi`
+
+mate_power_manager-gpm-main.o: gpm-main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-main.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-main.Tpo -c -o mate_power_manager-gpm-main.o `test -f 'gpm-main.c' || echo '$(srcdir)/'`gpm-main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-main.Tpo $(DEPDIR)/mate_power_manager-gpm-main.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-main.c' object='mate_power_manager-gpm-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-main.o `test -f 'gpm-main.c' || echo '$(srcdir)/'`gpm-main.c
+
+mate_power_manager-gpm-main.obj: gpm-main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-main.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-main.Tpo -c -o mate_power_manager-gpm-main.obj `if test -f 'gpm-main.c'; then $(CYGPATH_W) 'gpm-main.c'; else $(CYGPATH_W) '$(srcdir)/gpm-main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-main.Tpo $(DEPDIR)/mate_power_manager-gpm-main.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-main.c' object='mate_power_manager-gpm-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-main.obj `if test -f 'gpm-main.c'; then $(CYGPATH_W) 'gpm-main.c'; else $(CYGPATH_W) '$(srcdir)/gpm-main.c'; fi`
+
+mate_power_manager-gpm-manager.o: gpm-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-manager.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-manager.Tpo -c -o mate_power_manager-gpm-manager.o `test -f 'gpm-manager.c' || echo '$(srcdir)/'`gpm-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-manager.Tpo $(DEPDIR)/mate_power_manager-gpm-manager.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-manager.c' object='mate_power_manager-gpm-manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-manager.o `test -f 'gpm-manager.c' || echo '$(srcdir)/'`gpm-manager.c
+
+mate_power_manager-gpm-manager.obj: gpm-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-manager.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-manager.Tpo -c -o mate_power_manager-gpm-manager.obj `if test -f 'gpm-manager.c'; then $(CYGPATH_W) 'gpm-manager.c'; else $(CYGPATH_W) '$(srcdir)/gpm-manager.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-manager.Tpo $(DEPDIR)/mate_power_manager-gpm-manager.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-manager.c' object='mate_power_manager-gpm-manager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-manager.obj `if test -f 'gpm-manager.c'; then $(CYGPATH_W) 'gpm-manager.c'; else $(CYGPATH_W) '$(srcdir)/gpm-manager.c'; fi`
+
+mate_power_manager-gpm-tray-icon.o: gpm-tray-icon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-tray-icon.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-tray-icon.Tpo -c -o mate_power_manager-gpm-tray-icon.o `test -f 'gpm-tray-icon.c' || echo '$(srcdir)/'`gpm-tray-icon.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-tray-icon.Tpo $(DEPDIR)/mate_power_manager-gpm-tray-icon.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-tray-icon.c' object='mate_power_manager-gpm-tray-icon.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-tray-icon.o `test -f 'gpm-tray-icon.c' || echo '$(srcdir)/'`gpm-tray-icon.c
+
+mate_power_manager-gpm-tray-icon.obj: gpm-tray-icon.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-tray-icon.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-tray-icon.Tpo -c -o mate_power_manager-gpm-tray-icon.obj `if test -f 'gpm-tray-icon.c'; then $(CYGPATH_W) 'gpm-tray-icon.c'; else $(CYGPATH_W) '$(srcdir)/gpm-tray-icon.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-tray-icon.Tpo $(DEPDIR)/mate_power_manager-gpm-tray-icon.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-tray-icon.c' object='mate_power_manager-gpm-tray-icon.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-tray-icon.obj `if test -f 'gpm-tray-icon.c'; then $(CYGPATH_W) 'gpm-tray-icon.c'; else $(CYGPATH_W) '$(srcdir)/gpm-tray-icon.c'; fi`
+
+mate_power_manager-gpm-screensaver.o: gpm-screensaver.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-screensaver.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-screensaver.Tpo -c -o mate_power_manager-gpm-screensaver.o `test -f 'gpm-screensaver.c' || echo '$(srcdir)/'`gpm-screensaver.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-screensaver.Tpo $(DEPDIR)/mate_power_manager-gpm-screensaver.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-screensaver.c' object='mate_power_manager-gpm-screensaver.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-screensaver.o `test -f 'gpm-screensaver.c' || echo '$(srcdir)/'`gpm-screensaver.c
+
+mate_power_manager-gpm-screensaver.obj: gpm-screensaver.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-screensaver.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-screensaver.Tpo -c -o mate_power_manager-gpm-screensaver.obj `if test -f 'gpm-screensaver.c'; then $(CYGPATH_W) 'gpm-screensaver.c'; else $(CYGPATH_W) '$(srcdir)/gpm-screensaver.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-screensaver.Tpo $(DEPDIR)/mate_power_manager-gpm-screensaver.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-screensaver.c' object='mate_power_manager-gpm-screensaver.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-screensaver.obj `if test -f 'gpm-screensaver.c'; then $(CYGPATH_W) 'gpm-screensaver.c'; else $(CYGPATH_W) '$(srcdir)/gpm-screensaver.c'; fi`
+
+mate_power_manager-gpm-session.o: gpm-session.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-session.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-session.Tpo -c -o mate_power_manager-gpm-session.o `test -f 'gpm-session.c' || echo '$(srcdir)/'`gpm-session.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-session.Tpo $(DEPDIR)/mate_power_manager-gpm-session.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-session.c' object='mate_power_manager-gpm-session.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-session.o `test -f 'gpm-session.c' || echo '$(srcdir)/'`gpm-session.c
+
+mate_power_manager-gpm-session.obj: gpm-session.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-session.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-session.Tpo -c -o mate_power_manager-gpm-session.obj `if test -f 'gpm-session.c'; then $(CYGPATH_W) 'gpm-session.c'; else $(CYGPATH_W) '$(srcdir)/gpm-session.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-session.Tpo $(DEPDIR)/mate_power_manager-gpm-session.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-session.c' object='mate_power_manager-gpm-session.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-session.obj `if test -f 'gpm-session.c'; then $(CYGPATH_W) 'gpm-session.c'; else $(CYGPATH_W) '$(srcdir)/gpm-session.c'; fi`
+
+mate_power_manager-gpm-networkmanager.o: gpm-networkmanager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-networkmanager.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-networkmanager.Tpo -c -o mate_power_manager-gpm-networkmanager.o `test -f 'gpm-networkmanager.c' || echo '$(srcdir)/'`gpm-networkmanager.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-networkmanager.Tpo $(DEPDIR)/mate_power_manager-gpm-networkmanager.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-networkmanager.c' object='mate_power_manager-gpm-networkmanager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-networkmanager.o `test -f 'gpm-networkmanager.c' || echo '$(srcdir)/'`gpm-networkmanager.c
+
+mate_power_manager-gpm-networkmanager.obj: gpm-networkmanager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-networkmanager.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-networkmanager.Tpo -c -o mate_power_manager-gpm-networkmanager.obj `if test -f 'gpm-networkmanager.c'; then $(CYGPATH_W) 'gpm-networkmanager.c'; else $(CYGPATH_W) '$(srcdir)/gpm-networkmanager.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-networkmanager.Tpo $(DEPDIR)/mate_power_manager-gpm-networkmanager.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-networkmanager.c' object='mate_power_manager-gpm-networkmanager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-networkmanager.obj `if test -f 'gpm-networkmanager.c'; then $(CYGPATH_W) 'gpm-networkmanager.c'; else $(CYGPATH_W) '$(srcdir)/gpm-networkmanager.c'; fi`
+
+mate_power_manager-gsd-media-keys-window.o: gsd-media-keys-window.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gsd-media-keys-window.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gsd-media-keys-window.Tpo -c -o mate_power_manager-gsd-media-keys-window.o `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gsd-media-keys-window.Tpo $(DEPDIR)/mate_power_manager-gsd-media-keys-window.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='mate_power_manager-gsd-media-keys-window.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gsd-media-keys-window.o `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c
+
+mate_power_manager-gsd-media-keys-window.obj: gsd-media-keys-window.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gsd-media-keys-window.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gsd-media-keys-window.Tpo -c -o mate_power_manager-gsd-media-keys-window.obj `if test -f 'gsd-media-keys-window.c'; then $(CYGPATH_W) 'gsd-media-keys-window.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-window.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gsd-media-keys-window.Tpo $(DEPDIR)/mate_power_manager-gsd-media-keys-window.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='mate_power_manager-gsd-media-keys-window.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gsd-media-keys-window.obj `if test -f 'gsd-media-keys-window.c'; then $(CYGPATH_W) 'gsd-media-keys-window.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-window.c'; fi`
+
+mate_power_manager-gpm-engine.o: gpm-engine.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-engine.o -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-engine.Tpo -c -o mate_power_manager-gpm-engine.o `test -f 'gpm-engine.c' || echo '$(srcdir)/'`gpm-engine.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-engine.Tpo $(DEPDIR)/mate_power_manager-gpm-engine.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-engine.c' object='mate_power_manager-gpm-engine.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-engine.o `test -f 'gpm-engine.c' || echo '$(srcdir)/'`gpm-engine.c
+
+mate_power_manager-gpm-engine.obj: gpm-engine.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -MT mate_power_manager-gpm-engine.obj -MD -MP -MF $(DEPDIR)/mate_power_manager-gpm-engine.Tpo -c -o mate_power_manager-gpm-engine.obj `if test -f 'gpm-engine.c'; then $(CYGPATH_W) 'gpm-engine.c'; else $(CYGPATH_W) '$(srcdir)/gpm-engine.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_manager-gpm-engine.Tpo $(DEPDIR)/mate_power_manager-gpm-engine.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-engine.c' object='mate_power_manager-gpm-engine.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_manager_CFLAGS) $(CFLAGS) -c -o mate_power_manager-gpm-engine.obj `if test -f 'gpm-engine.c'; then $(CYGPATH_W) 'gpm-engine.c'; else $(CYGPATH_W) '$(srcdir)/gpm-engine.c'; fi`
+
+mate_power_preferences-gpm-prefs.o: gpm-prefs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -MT mate_power_preferences-gpm-prefs.o -MD -MP -MF $(DEPDIR)/mate_power_preferences-gpm-prefs.Tpo -c -o mate_power_preferences-gpm-prefs.o `test -f 'gpm-prefs.c' || echo '$(srcdir)/'`gpm-prefs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_preferences-gpm-prefs.Tpo $(DEPDIR)/mate_power_preferences-gpm-prefs.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs.c' object='mate_power_preferences-gpm-prefs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -c -o mate_power_preferences-gpm-prefs.o `test -f 'gpm-prefs.c' || echo '$(srcdir)/'`gpm-prefs.c
+
+mate_power_preferences-gpm-prefs.obj: gpm-prefs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -MT mate_power_preferences-gpm-prefs.obj -MD -MP -MF $(DEPDIR)/mate_power_preferences-gpm-prefs.Tpo -c -o mate_power_preferences-gpm-prefs.obj `if test -f 'gpm-prefs.c'; then $(CYGPATH_W) 'gpm-prefs.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_preferences-gpm-prefs.Tpo $(DEPDIR)/mate_power_preferences-gpm-prefs.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs.c' object='mate_power_preferences-gpm-prefs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -c -o mate_power_preferences-gpm-prefs.obj `if test -f 'gpm-prefs.c'; then $(CYGPATH_W) 'gpm-prefs.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs.c'; fi`
+
+mate_power_preferences-gpm-prefs-core.o: gpm-prefs-core.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -MT mate_power_preferences-gpm-prefs-core.o -MD -MP -MF $(DEPDIR)/mate_power_preferences-gpm-prefs-core.Tpo -c -o mate_power_preferences-gpm-prefs-core.o `test -f 'gpm-prefs-core.c' || echo '$(srcdir)/'`gpm-prefs-core.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_preferences-gpm-prefs-core.Tpo $(DEPDIR)/mate_power_preferences-gpm-prefs-core.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs-core.c' object='mate_power_preferences-gpm-prefs-core.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -c -o mate_power_preferences-gpm-prefs-core.o `test -f 'gpm-prefs-core.c' || echo '$(srcdir)/'`gpm-prefs-core.c
+
+mate_power_preferences-gpm-prefs-core.obj: gpm-prefs-core.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -MT mate_power_preferences-gpm-prefs-core.obj -MD -MP -MF $(DEPDIR)/mate_power_preferences-gpm-prefs-core.Tpo -c -o mate_power_preferences-gpm-prefs-core.obj `if test -f 'gpm-prefs-core.c'; then $(CYGPATH_W) 'gpm-prefs-core.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs-core.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_preferences-gpm-prefs-core.Tpo $(DEPDIR)/mate_power_preferences-gpm-prefs-core.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs-core.c' object='mate_power_preferences-gpm-prefs-core.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_preferences_CFLAGS) $(CFLAGS) -c -o mate_power_preferences-gpm-prefs-core.obj `if test -f 'gpm-prefs-core.c'; then $(CYGPATH_W) 'gpm-prefs-core.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs-core.c'; fi`
+
+mate_power_self_test-gpm-self-test.o: gpm-self-test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-self-test.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-self-test.Tpo -c -o mate_power_self_test-gpm-self-test.o `test -f 'gpm-self-test.c' || echo '$(srcdir)/'`gpm-self-test.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-self-test.Tpo $(DEPDIR)/mate_power_self_test-gpm-self-test.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-self-test.c' object='mate_power_self_test-gpm-self-test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-self-test.o `test -f 'gpm-self-test.c' || echo '$(srcdir)/'`gpm-self-test.c
+
+mate_power_self_test-gpm-self-test.obj: gpm-self-test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-self-test.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-self-test.Tpo -c -o mate_power_self_test-gpm-self-test.obj `if test -f 'gpm-self-test.c'; then $(CYGPATH_W) 'gpm-self-test.c'; else $(CYGPATH_W) '$(srcdir)/gpm-self-test.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-self-test.Tpo $(DEPDIR)/mate_power_self_test-gpm-self-test.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-self-test.c' object='mate_power_self_test-gpm-self-test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-self-test.obj `if test -f 'gpm-self-test.c'; then $(CYGPATH_W) 'gpm-self-test.c'; else $(CYGPATH_W) '$(srcdir)/gpm-self-test.c'; fi`
+
+mate_power_self_test-egg-color.o: egg-color.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-color.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-color.Tpo -c -o mate_power_self_test-egg-color.o `test -f 'egg-color.c' || echo '$(srcdir)/'`egg-color.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-color.Tpo $(DEPDIR)/mate_power_self_test-egg-color.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-color.c' object='mate_power_self_test-egg-color.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-color.o `test -f 'egg-color.c' || echo '$(srcdir)/'`egg-color.c
+
+mate_power_self_test-egg-color.obj: egg-color.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-color.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-color.Tpo -c -o mate_power_self_test-egg-color.obj `if test -f 'egg-color.c'; then $(CYGPATH_W) 'egg-color.c'; else $(CYGPATH_W) '$(srcdir)/egg-color.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-color.Tpo $(DEPDIR)/mate_power_self_test-egg-color.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-color.c' object='mate_power_self_test-egg-color.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-color.obj `if test -f 'egg-color.c'; then $(CYGPATH_W) 'egg-color.c'; else $(CYGPATH_W) '$(srcdir)/egg-color.c'; fi`
+
+mate_power_self_test-egg-test.o: egg-test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-test.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-test.Tpo -c -o mate_power_self_test-egg-test.o `test -f 'egg-test.c' || echo '$(srcdir)/'`egg-test.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-test.Tpo $(DEPDIR)/mate_power_self_test-egg-test.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-test.c' object='mate_power_self_test-egg-test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-test.o `test -f 'egg-test.c' || echo '$(srcdir)/'`egg-test.c
+
+mate_power_self_test-egg-test.obj: egg-test.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-test.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-test.Tpo -c -o mate_power_self_test-egg-test.obj `if test -f 'egg-test.c'; then $(CYGPATH_W) 'egg-test.c'; else $(CYGPATH_W) '$(srcdir)/egg-test.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-test.Tpo $(DEPDIR)/mate_power_self_test-egg-test.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-test.c' object='mate_power_self_test-egg-test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-test.obj `if test -f 'egg-test.c'; then $(CYGPATH_W) 'egg-test.c'; else $(CYGPATH_W) '$(srcdir)/egg-test.c'; fi`
+
+mate_power_self_test-egg-debug.o: egg-debug.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-debug.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-debug.Tpo -c -o mate_power_self_test-egg-debug.o `test -f 'egg-debug.c' || echo '$(srcdir)/'`egg-debug.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-debug.Tpo $(DEPDIR)/mate_power_self_test-egg-debug.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-debug.c' object='mate_power_self_test-egg-debug.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-debug.o `test -f 'egg-debug.c' || echo '$(srcdir)/'`egg-debug.c
+
+mate_power_self_test-egg-debug.obj: egg-debug.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-debug.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-debug.Tpo -c -o mate_power_self_test-egg-debug.obj `if test -f 'egg-debug.c'; then $(CYGPATH_W) 'egg-debug.c'; else $(CYGPATH_W) '$(srcdir)/egg-debug.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-debug.Tpo $(DEPDIR)/mate_power_self_test-egg-debug.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-debug.c' object='mate_power_self_test-egg-debug.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-debug.obj `if test -f 'egg-debug.c'; then $(CYGPATH_W) 'egg-debug.c'; else $(CYGPATH_W) '$(srcdir)/egg-debug.c'; fi`
+
+mate_power_self_test-egg-dbus-monitor.o: egg-dbus-monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-dbus-monitor.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Tpo -c -o mate_power_self_test-egg-dbus-monitor.o `test -f 'egg-dbus-monitor.c' || echo '$(srcdir)/'`egg-dbus-monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Tpo $(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-dbus-monitor.c' object='mate_power_self_test-egg-dbus-monitor.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-dbus-monitor.o `test -f 'egg-dbus-monitor.c' || echo '$(srcdir)/'`egg-dbus-monitor.c
+
+mate_power_self_test-egg-dbus-monitor.obj: egg-dbus-monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-dbus-monitor.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Tpo -c -o mate_power_self_test-egg-dbus-monitor.obj `if test -f 'egg-dbus-monitor.c'; then $(CYGPATH_W) 'egg-dbus-monitor.c'; else $(CYGPATH_W) '$(srcdir)/egg-dbus-monitor.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Tpo $(DEPDIR)/mate_power_self_test-egg-dbus-monitor.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-dbus-monitor.c' object='mate_power_self_test-egg-dbus-monitor.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-dbus-monitor.obj `if test -f 'egg-dbus-monitor.c'; then $(CYGPATH_W) 'egg-dbus-monitor.c'; else $(CYGPATH_W) '$(srcdir)/egg-dbus-monitor.c'; fi`
+
+mate_power_self_test-egg-dbus-proxy.o: egg-dbus-proxy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-dbus-proxy.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Tpo -c -o mate_power_self_test-egg-dbus-proxy.o `test -f 'egg-dbus-proxy.c' || echo '$(srcdir)/'`egg-dbus-proxy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Tpo $(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-dbus-proxy.c' object='mate_power_self_test-egg-dbus-proxy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-dbus-proxy.o `test -f 'egg-dbus-proxy.c' || echo '$(srcdir)/'`egg-dbus-proxy.c
+
+mate_power_self_test-egg-dbus-proxy.obj: egg-dbus-proxy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-dbus-proxy.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Tpo -c -o mate_power_self_test-egg-dbus-proxy.obj `if test -f 'egg-dbus-proxy.c'; then $(CYGPATH_W) 'egg-dbus-proxy.c'; else $(CYGPATH_W) '$(srcdir)/egg-dbus-proxy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Tpo $(DEPDIR)/mate_power_self_test-egg-dbus-proxy.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-dbus-proxy.c' object='mate_power_self_test-egg-dbus-proxy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-dbus-proxy.obj `if test -f 'egg-dbus-proxy.c'; then $(CYGPATH_W) 'egg-dbus-proxy.c'; else $(CYGPATH_W) '$(srcdir)/egg-dbus-proxy.c'; fi`
+
+mate_power_self_test-egg-precision.o: egg-precision.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-precision.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-precision.Tpo -c -o mate_power_self_test-egg-precision.o `test -f 'egg-precision.c' || echo '$(srcdir)/'`egg-precision.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-precision.Tpo $(DEPDIR)/mate_power_self_test-egg-precision.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-precision.c' object='mate_power_self_test-egg-precision.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-precision.o `test -f 'egg-precision.c' || echo '$(srcdir)/'`egg-precision.c
+
+mate_power_self_test-egg-precision.obj: egg-precision.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-precision.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-precision.Tpo -c -o mate_power_self_test-egg-precision.obj `if test -f 'egg-precision.c'; then $(CYGPATH_W) 'egg-precision.c'; else $(CYGPATH_W) '$(srcdir)/egg-precision.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-precision.Tpo $(DEPDIR)/mate_power_self_test-egg-precision.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-precision.c' object='mate_power_self_test-egg-precision.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-precision.obj `if test -f 'egg-precision.c'; then $(CYGPATH_W) 'egg-precision.c'; else $(CYGPATH_W) '$(srcdir)/egg-precision.c'; fi`
+
+mate_power_self_test-egg-idletime.o: egg-idletime.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-idletime.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-idletime.Tpo -c -o mate_power_self_test-egg-idletime.o `test -f 'egg-idletime.c' || echo '$(srcdir)/'`egg-idletime.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-idletime.Tpo $(DEPDIR)/mate_power_self_test-egg-idletime.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-idletime.c' object='mate_power_self_test-egg-idletime.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-idletime.o `test -f 'egg-idletime.c' || echo '$(srcdir)/'`egg-idletime.c
+
+mate_power_self_test-egg-idletime.obj: egg-idletime.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-idletime.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-idletime.Tpo -c -o mate_power_self_test-egg-idletime.obj `if test -f 'egg-idletime.c'; then $(CYGPATH_W) 'egg-idletime.c'; else $(CYGPATH_W) '$(srcdir)/egg-idletime.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-idletime.Tpo $(DEPDIR)/mate_power_self_test-egg-idletime.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-idletime.c' object='mate_power_self_test-egg-idletime.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-idletime.obj `if test -f 'egg-idletime.c'; then $(CYGPATH_W) 'egg-idletime.c'; else $(CYGPATH_W) '$(srcdir)/egg-idletime.c'; fi`
+
+mate_power_self_test-egg-discrete.o: egg-discrete.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-discrete.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-discrete.Tpo -c -o mate_power_self_test-egg-discrete.o `test -f 'egg-discrete.c' || echo '$(srcdir)/'`egg-discrete.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-discrete.Tpo $(DEPDIR)/mate_power_self_test-egg-discrete.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-discrete.c' object='mate_power_self_test-egg-discrete.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-discrete.o `test -f 'egg-discrete.c' || echo '$(srcdir)/'`egg-discrete.c
+
+mate_power_self_test-egg-discrete.obj: egg-discrete.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-discrete.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-discrete.Tpo -c -o mate_power_self_test-egg-discrete.obj `if test -f 'egg-discrete.c'; then $(CYGPATH_W) 'egg-discrete.c'; else $(CYGPATH_W) '$(srcdir)/egg-discrete.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-discrete.Tpo $(DEPDIR)/mate_power_self_test-egg-discrete.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-discrete.c' object='mate_power_self_test-egg-discrete.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-discrete.obj `if test -f 'egg-discrete.c'; then $(CYGPATH_W) 'egg-discrete.c'; else $(CYGPATH_W) '$(srcdir)/egg-discrete.c'; fi`
+
+mate_power_self_test-egg-array-float.o: egg-array-float.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-array-float.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-array-float.Tpo -c -o mate_power_self_test-egg-array-float.o `test -f 'egg-array-float.c' || echo '$(srcdir)/'`egg-array-float.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-array-float.Tpo $(DEPDIR)/mate_power_self_test-egg-array-float.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-array-float.c' object='mate_power_self_test-egg-array-float.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-array-float.o `test -f 'egg-array-float.c' || echo '$(srcdir)/'`egg-array-float.c
+
+mate_power_self_test-egg-array-float.obj: egg-array-float.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-array-float.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-array-float.Tpo -c -o mate_power_self_test-egg-array-float.obj `if test -f 'egg-array-float.c'; then $(CYGPATH_W) 'egg-array-float.c'; else $(CYGPATH_W) '$(srcdir)/egg-array-float.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-array-float.Tpo $(DEPDIR)/mate_power_self_test-egg-array-float.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-array-float.c' object='mate_power_self_test-egg-array-float.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-array-float.obj `if test -f 'egg-array-float.c'; then $(CYGPATH_W) 'egg-array-float.c'; else $(CYGPATH_W) '$(srcdir)/egg-array-float.c'; fi`
+
+mate_power_self_test-egg-console-kit.o: egg-console-kit.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-console-kit.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-console-kit.Tpo -c -o mate_power_self_test-egg-console-kit.o `test -f 'egg-console-kit.c' || echo '$(srcdir)/'`egg-console-kit.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-console-kit.Tpo $(DEPDIR)/mate_power_self_test-egg-console-kit.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-console-kit.c' object='mate_power_self_test-egg-console-kit.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-console-kit.o `test -f 'egg-console-kit.c' || echo '$(srcdir)/'`egg-console-kit.c
+
+mate_power_self_test-egg-console-kit.obj: egg-console-kit.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-egg-console-kit.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-egg-console-kit.Tpo -c -o mate_power_self_test-egg-console-kit.obj `if test -f 'egg-console-kit.c'; then $(CYGPATH_W) 'egg-console-kit.c'; else $(CYGPATH_W) '$(srcdir)/egg-console-kit.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-egg-console-kit.Tpo $(DEPDIR)/mate_power_self_test-egg-console-kit.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='egg-console-kit.c' object='mate_power_self_test-egg-console-kit.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-egg-console-kit.obj `if test -f 'egg-console-kit.c'; then $(CYGPATH_W) 'egg-console-kit.c'; else $(CYGPATH_W) '$(srcdir)/egg-console-kit.c'; fi`
+
+mate_power_self_test-gpm-prefs-server.o: gpm-prefs-server.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-prefs-server.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-prefs-server.Tpo -c -o mate_power_self_test-gpm-prefs-server.o `test -f 'gpm-prefs-server.c' || echo '$(srcdir)/'`gpm-prefs-server.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-prefs-server.Tpo $(DEPDIR)/mate_power_self_test-gpm-prefs-server.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs-server.c' object='mate_power_self_test-gpm-prefs-server.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-prefs-server.o `test -f 'gpm-prefs-server.c' || echo '$(srcdir)/'`gpm-prefs-server.c
+
+mate_power_self_test-gpm-prefs-server.obj: gpm-prefs-server.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-prefs-server.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-prefs-server.Tpo -c -o mate_power_self_test-gpm-prefs-server.obj `if test -f 'gpm-prefs-server.c'; then $(CYGPATH_W) 'gpm-prefs-server.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs-server.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-prefs-server.Tpo $(DEPDIR)/mate_power_self_test-gpm-prefs-server.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-prefs-server.c' object='mate_power_self_test-gpm-prefs-server.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-prefs-server.obj `if test -f 'gpm-prefs-server.c'; then $(CYGPATH_W) 'gpm-prefs-server.c'; else $(CYGPATH_W) '$(srcdir)/gpm-prefs-server.c'; fi`
+
+mate_power_self_test-gpm-control.o: gpm-control.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-control.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-control.Tpo -c -o mate_power_self_test-gpm-control.o `test -f 'gpm-control.c' || echo '$(srcdir)/'`gpm-control.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-control.Tpo $(DEPDIR)/mate_power_self_test-gpm-control.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-control.c' object='mate_power_self_test-gpm-control.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-control.o `test -f 'gpm-control.c' || echo '$(srcdir)/'`gpm-control.c
+
+mate_power_self_test-gpm-control.obj: gpm-control.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-control.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-control.Tpo -c -o mate_power_self_test-gpm-control.obj `if test -f 'gpm-control.c'; then $(CYGPATH_W) 'gpm-control.c'; else $(CYGPATH_W) '$(srcdir)/gpm-control.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-control.Tpo $(DEPDIR)/mate_power_self_test-gpm-control.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-control.c' object='mate_power_self_test-gpm-control.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-control.obj `if test -f 'gpm-control.c'; then $(CYGPATH_W) 'gpm-control.c'; else $(CYGPATH_W) '$(srcdir)/gpm-control.c'; fi`
+
+mate_power_self_test-gpm-networkmanager.o: gpm-networkmanager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-networkmanager.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-networkmanager.Tpo -c -o mate_power_self_test-gpm-networkmanager.o `test -f 'gpm-networkmanager.c' || echo '$(srcdir)/'`gpm-networkmanager.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-networkmanager.Tpo $(DEPDIR)/mate_power_self_test-gpm-networkmanager.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-networkmanager.c' object='mate_power_self_test-gpm-networkmanager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-networkmanager.o `test -f 'gpm-networkmanager.c' || echo '$(srcdir)/'`gpm-networkmanager.c
+
+mate_power_self_test-gpm-networkmanager.obj: gpm-networkmanager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-networkmanager.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-networkmanager.Tpo -c -o mate_power_self_test-gpm-networkmanager.obj `if test -f 'gpm-networkmanager.c'; then $(CYGPATH_W) 'gpm-networkmanager.c'; else $(CYGPATH_W) '$(srcdir)/gpm-networkmanager.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-networkmanager.Tpo $(DEPDIR)/mate_power_self_test-gpm-networkmanager.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-networkmanager.c' object='mate_power_self_test-gpm-networkmanager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-networkmanager.obj `if test -f 'gpm-networkmanager.c'; then $(CYGPATH_W) 'gpm-networkmanager.c'; else $(CYGPATH_W) '$(srcdir)/gpm-networkmanager.c'; fi`
+
+mate_power_self_test-gpm-dpms.o: gpm-dpms.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-dpms.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-dpms.Tpo -c -o mate_power_self_test-gpm-dpms.o `test -f 'gpm-dpms.c' || echo '$(srcdir)/'`gpm-dpms.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-dpms.Tpo $(DEPDIR)/mate_power_self_test-gpm-dpms.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-dpms.c' object='mate_power_self_test-gpm-dpms.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-dpms.o `test -f 'gpm-dpms.c' || echo '$(srcdir)/'`gpm-dpms.c
+
+mate_power_self_test-gpm-dpms.obj: gpm-dpms.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-dpms.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-dpms.Tpo -c -o mate_power_self_test-gpm-dpms.obj `if test -f 'gpm-dpms.c'; then $(CYGPATH_W) 'gpm-dpms.c'; else $(CYGPATH_W) '$(srcdir)/gpm-dpms.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-dpms.Tpo $(DEPDIR)/mate_power_self_test-gpm-dpms.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-dpms.c' object='mate_power_self_test-gpm-dpms.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-dpms.obj `if test -f 'gpm-dpms.c'; then $(CYGPATH_W) 'gpm-dpms.c'; else $(CYGPATH_W) '$(srcdir)/gpm-dpms.c'; fi`
+
+mate_power_self_test-gpm-button.o: gpm-button.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-button.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-button.Tpo -c -o mate_power_self_test-gpm-button.o `test -f 'gpm-button.c' || echo '$(srcdir)/'`gpm-button.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-button.Tpo $(DEPDIR)/mate_power_self_test-gpm-button.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-button.c' object='mate_power_self_test-gpm-button.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-button.o `test -f 'gpm-button.c' || echo '$(srcdir)/'`gpm-button.c
+
+mate_power_self_test-gpm-button.obj: gpm-button.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-button.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-button.Tpo -c -o mate_power_self_test-gpm-button.obj `if test -f 'gpm-button.c'; then $(CYGPATH_W) 'gpm-button.c'; else $(CYGPATH_W) '$(srcdir)/gpm-button.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-button.Tpo $(DEPDIR)/mate_power_self_test-gpm-button.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-button.c' object='mate_power_self_test-gpm-button.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-button.obj `if test -f 'gpm-button.c'; then $(CYGPATH_W) 'gpm-button.c'; else $(CYGPATH_W) '$(srcdir)/gpm-button.c'; fi`
+
+mate_power_self_test-gpm-screensaver.o: gpm-screensaver.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-screensaver.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-screensaver.Tpo -c -o mate_power_self_test-gpm-screensaver.o `test -f 'gpm-screensaver.c' || echo '$(srcdir)/'`gpm-screensaver.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-screensaver.Tpo $(DEPDIR)/mate_power_self_test-gpm-screensaver.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-screensaver.c' object='mate_power_self_test-gpm-screensaver.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-screensaver.o `test -f 'gpm-screensaver.c' || echo '$(srcdir)/'`gpm-screensaver.c
+
+mate_power_self_test-gpm-screensaver.obj: gpm-screensaver.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-screensaver.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-screensaver.Tpo -c -o mate_power_self_test-gpm-screensaver.obj `if test -f 'gpm-screensaver.c'; then $(CYGPATH_W) 'gpm-screensaver.c'; else $(CYGPATH_W) '$(srcdir)/gpm-screensaver.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-screensaver.Tpo $(DEPDIR)/mate_power_self_test-gpm-screensaver.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-screensaver.c' object='mate_power_self_test-gpm-screensaver.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-screensaver.obj `if test -f 'gpm-screensaver.c'; then $(CYGPATH_W) 'gpm-screensaver.c'; else $(CYGPATH_W) '$(srcdir)/gpm-screensaver.c'; fi`
+
+mate_power_self_test-gpm-engine.o: gpm-engine.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-engine.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-engine.Tpo -c -o mate_power_self_test-gpm-engine.o `test -f 'gpm-engine.c' || echo '$(srcdir)/'`gpm-engine.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-engine.Tpo $(DEPDIR)/mate_power_self_test-gpm-engine.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-engine.c' object='mate_power_self_test-gpm-engine.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-engine.o `test -f 'gpm-engine.c' || echo '$(srcdir)/'`gpm-engine.c
+
+mate_power_self_test-gpm-engine.obj: gpm-engine.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-engine.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-engine.Tpo -c -o mate_power_self_test-gpm-engine.obj `if test -f 'gpm-engine.c'; then $(CYGPATH_W) 'gpm-engine.c'; else $(CYGPATH_W) '$(srcdir)/gpm-engine.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-engine.Tpo $(DEPDIR)/mate_power_self_test-gpm-engine.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-engine.c' object='mate_power_self_test-gpm-engine.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-engine.obj `if test -f 'gpm-engine.c'; then $(CYGPATH_W) 'gpm-engine.c'; else $(CYGPATH_W) '$(srcdir)/gpm-engine.c'; fi`
+
+mate_power_self_test-gpm-phone.o: gpm-phone.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-phone.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-phone.Tpo -c -o mate_power_self_test-gpm-phone.o `test -f 'gpm-phone.c' || echo '$(srcdir)/'`gpm-phone.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-phone.Tpo $(DEPDIR)/mate_power_self_test-gpm-phone.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-phone.c' object='mate_power_self_test-gpm-phone.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-phone.o `test -f 'gpm-phone.c' || echo '$(srcdir)/'`gpm-phone.c
+
+mate_power_self_test-gpm-phone.obj: gpm-phone.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-phone.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-phone.Tpo -c -o mate_power_self_test-gpm-phone.obj `if test -f 'gpm-phone.c'; then $(CYGPATH_W) 'gpm-phone.c'; else $(CYGPATH_W) '$(srcdir)/gpm-phone.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-phone.Tpo $(DEPDIR)/mate_power_self_test-gpm-phone.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-phone.c' object='mate_power_self_test-gpm-phone.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-phone.obj `if test -f 'gpm-phone.c'; then $(CYGPATH_W) 'gpm-phone.c'; else $(CYGPATH_W) '$(srcdir)/gpm-phone.c'; fi`
+
+mate_power_self_test-gpm-idle.o: gpm-idle.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-idle.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-idle.Tpo -c -o mate_power_self_test-gpm-idle.o `test -f 'gpm-idle.c' || echo '$(srcdir)/'`gpm-idle.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-idle.Tpo $(DEPDIR)/mate_power_self_test-gpm-idle.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-idle.c' object='mate_power_self_test-gpm-idle.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-idle.o `test -f 'gpm-idle.c' || echo '$(srcdir)/'`gpm-idle.c
+
+mate_power_self_test-gpm-idle.obj: gpm-idle.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-idle.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-idle.Tpo -c -o mate_power_self_test-gpm-idle.obj `if test -f 'gpm-idle.c'; then $(CYGPATH_W) 'gpm-idle.c'; else $(CYGPATH_W) '$(srcdir)/gpm-idle.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-idle.Tpo $(DEPDIR)/mate_power_self_test-gpm-idle.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-idle.c' object='mate_power_self_test-gpm-idle.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-idle.obj `if test -f 'gpm-idle.c'; then $(CYGPATH_W) 'gpm-idle.c'; else $(CYGPATH_W) '$(srcdir)/gpm-idle.c'; fi`
+
+mate_power_self_test-gpm-session.o: gpm-session.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-session.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-session.Tpo -c -o mate_power_self_test-gpm-session.o `test -f 'gpm-session.c' || echo '$(srcdir)/'`gpm-session.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-session.Tpo $(DEPDIR)/mate_power_self_test-gpm-session.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-session.c' object='mate_power_self_test-gpm-session.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-session.o `test -f 'gpm-session.c' || echo '$(srcdir)/'`gpm-session.c
+
+mate_power_self_test-gpm-session.obj: gpm-session.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-session.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-session.Tpo -c -o mate_power_self_test-gpm-session.obj `if test -f 'gpm-session.c'; then $(CYGPATH_W) 'gpm-session.c'; else $(CYGPATH_W) '$(srcdir)/gpm-session.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-session.Tpo $(DEPDIR)/mate_power_self_test-gpm-session.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-session.c' object='mate_power_self_test-gpm-session.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-session.obj `if test -f 'gpm-session.c'; then $(CYGPATH_W) 'gpm-session.c'; else $(CYGPATH_W) '$(srcdir)/gpm-session.c'; fi`
+
+mate_power_self_test-gpm-load.o: gpm-load.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-load.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-load.Tpo -c -o mate_power_self_test-gpm-load.o `test -f 'gpm-load.c' || echo '$(srcdir)/'`gpm-load.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-load.Tpo $(DEPDIR)/mate_power_self_test-gpm-load.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-load.c' object='mate_power_self_test-gpm-load.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-load.o `test -f 'gpm-load.c' || echo '$(srcdir)/'`gpm-load.c
+
+mate_power_self_test-gpm-load.obj: gpm-load.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-load.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-load.Tpo -c -o mate_power_self_test-gpm-load.obj `if test -f 'gpm-load.c'; then $(CYGPATH_W) 'gpm-load.c'; else $(CYGPATH_W) '$(srcdir)/gpm-load.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-load.Tpo $(DEPDIR)/mate_power_self_test-gpm-load.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-load.c' object='mate_power_self_test-gpm-load.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-load.obj `if test -f 'gpm-load.c'; then $(CYGPATH_W) 'gpm-load.c'; else $(CYGPATH_W) '$(srcdir)/gpm-load.c'; fi`
+
+mate_power_self_test-gpm-marshal.o: gpm-marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-marshal.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-marshal.Tpo -c -o mate_power_self_test-gpm-marshal.o `test -f 'gpm-marshal.c' || echo '$(srcdir)/'`gpm-marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-marshal.Tpo $(DEPDIR)/mate_power_self_test-gpm-marshal.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-marshal.c' object='mate_power_self_test-gpm-marshal.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-marshal.o `test -f 'gpm-marshal.c' || echo '$(srcdir)/'`gpm-marshal.c
+
+mate_power_self_test-gpm-marshal.obj: gpm-marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-marshal.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-marshal.Tpo -c -o mate_power_self_test-gpm-marshal.obj `if test -f 'gpm-marshal.c'; then $(CYGPATH_W) 'gpm-marshal.c'; else $(CYGPATH_W) '$(srcdir)/gpm-marshal.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-marshal.Tpo $(DEPDIR)/mate_power_self_test-gpm-marshal.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-marshal.c' object='mate_power_self_test-gpm-marshal.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-marshal.obj `if test -f 'gpm-marshal.c'; then $(CYGPATH_W) 'gpm-marshal.c'; else $(CYGPATH_W) '$(srcdir)/gpm-marshal.c'; fi`
+
+mate_power_self_test-gpm-common.o: gpm-common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-common.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-common.Tpo -c -o mate_power_self_test-gpm-common.o `test -f 'gpm-common.c' || echo '$(srcdir)/'`gpm-common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-common.Tpo $(DEPDIR)/mate_power_self_test-gpm-common.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-common.c' object='mate_power_self_test-gpm-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-common.o `test -f 'gpm-common.c' || echo '$(srcdir)/'`gpm-common.c
+
+mate_power_self_test-gpm-common.obj: gpm-common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-common.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-common.Tpo -c -o mate_power_self_test-gpm-common.obj `if test -f 'gpm-common.c'; then $(CYGPATH_W) 'gpm-common.c'; else $(CYGPATH_W) '$(srcdir)/gpm-common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-common.Tpo $(DEPDIR)/mate_power_self_test-gpm-common.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-common.c' object='mate_power_self_test-gpm-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-common.obj `if test -f 'gpm-common.c'; then $(CYGPATH_W) 'gpm-common.c'; else $(CYGPATH_W) '$(srcdir)/gpm-common.c'; fi`
+
+mate_power_self_test-gpm-upower.o: gpm-upower.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-upower.o -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-upower.Tpo -c -o mate_power_self_test-gpm-upower.o `test -f 'gpm-upower.c' || echo '$(srcdir)/'`gpm-upower.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-upower.Tpo $(DEPDIR)/mate_power_self_test-gpm-upower.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-upower.c' object='mate_power_self_test-gpm-upower.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-upower.o `test -f 'gpm-upower.c' || echo '$(srcdir)/'`gpm-upower.c
+
+mate_power_self_test-gpm-upower.obj: gpm-upower.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -MT mate_power_self_test-gpm-upower.obj -MD -MP -MF $(DEPDIR)/mate_power_self_test-gpm-upower.Tpo -c -o mate_power_self_test-gpm-upower.obj `if test -f 'gpm-upower.c'; then $(CYGPATH_W) 'gpm-upower.c'; else $(CYGPATH_W) '$(srcdir)/gpm-upower.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_self_test-gpm-upower.Tpo $(DEPDIR)/mate_power_self_test-gpm-upower.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-upower.c' object='mate_power_self_test-gpm-upower.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_self_test_CFLAGS) $(CFLAGS) -c -o mate_power_self_test-gpm-upower.obj `if test -f 'gpm-upower.c'; then $(CYGPATH_W) 'gpm-upower.c'; else $(CYGPATH_W) '$(srcdir)/gpm-upower.c'; fi`
+
+mate_power_statistics-gpm-statistics.o: gpm-statistics.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -MT mate_power_statistics-gpm-statistics.o -MD -MP -MF $(DEPDIR)/mate_power_statistics-gpm-statistics.Tpo -c -o mate_power_statistics-gpm-statistics.o `test -f 'gpm-statistics.c' || echo '$(srcdir)/'`gpm-statistics.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_statistics-gpm-statistics.Tpo $(DEPDIR)/mate_power_statistics-gpm-statistics.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-statistics.c' object='mate_power_statistics-gpm-statistics.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -c -o mate_power_statistics-gpm-statistics.o `test -f 'gpm-statistics.c' || echo '$(srcdir)/'`gpm-statistics.c
+
+mate_power_statistics-gpm-statistics.obj: gpm-statistics.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -MT mate_power_statistics-gpm-statistics.obj -MD -MP -MF $(DEPDIR)/mate_power_statistics-gpm-statistics.Tpo -c -o mate_power_statistics-gpm-statistics.obj `if test -f 'gpm-statistics.c'; then $(CYGPATH_W) 'gpm-statistics.c'; else $(CYGPATH_W) '$(srcdir)/gpm-statistics.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_statistics-gpm-statistics.Tpo $(DEPDIR)/mate_power_statistics-gpm-statistics.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-statistics.c' object='mate_power_statistics-gpm-statistics.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -c -o mate_power_statistics-gpm-statistics.obj `if test -f 'gpm-statistics.c'; then $(CYGPATH_W) 'gpm-statistics.c'; else $(CYGPATH_W) '$(srcdir)/gpm-statistics.c'; fi`
+
+mate_power_statistics-gpm-point-obj.o: gpm-point-obj.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -MT mate_power_statistics-gpm-point-obj.o -MD -MP -MF $(DEPDIR)/mate_power_statistics-gpm-point-obj.Tpo -c -o mate_power_statistics-gpm-point-obj.o `test -f 'gpm-point-obj.c' || echo '$(srcdir)/'`gpm-point-obj.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_statistics-gpm-point-obj.Tpo $(DEPDIR)/mate_power_statistics-gpm-point-obj.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-point-obj.c' object='mate_power_statistics-gpm-point-obj.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -c -o mate_power_statistics-gpm-point-obj.o `test -f 'gpm-point-obj.c' || echo '$(srcdir)/'`gpm-point-obj.c
+
+mate_power_statistics-gpm-point-obj.obj: gpm-point-obj.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -MT mate_power_statistics-gpm-point-obj.obj -MD -MP -MF $(DEPDIR)/mate_power_statistics-gpm-point-obj.Tpo -c -o mate_power_statistics-gpm-point-obj.obj `if test -f 'gpm-point-obj.c'; then $(CYGPATH_W) 'gpm-point-obj.c'; else $(CYGPATH_W) '$(srcdir)/gpm-point-obj.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_statistics-gpm-point-obj.Tpo $(DEPDIR)/mate_power_statistics-gpm-point-obj.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-point-obj.c' object='mate_power_statistics-gpm-point-obj.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -c -o mate_power_statistics-gpm-point-obj.obj `if test -f 'gpm-point-obj.c'; then $(CYGPATH_W) 'gpm-point-obj.c'; else $(CYGPATH_W) '$(srcdir)/gpm-point-obj.c'; fi`
+
+mate_power_statistics-gpm-graph-widget.o: gpm-graph-widget.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -MT mate_power_statistics-gpm-graph-widget.o -MD -MP -MF $(DEPDIR)/mate_power_statistics-gpm-graph-widget.Tpo -c -o mate_power_statistics-gpm-graph-widget.o `test -f 'gpm-graph-widget.c' || echo '$(srcdir)/'`gpm-graph-widget.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_statistics-gpm-graph-widget.Tpo $(DEPDIR)/mate_power_statistics-gpm-graph-widget.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-graph-widget.c' object='mate_power_statistics-gpm-graph-widget.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -c -o mate_power_statistics-gpm-graph-widget.o `test -f 'gpm-graph-widget.c' || echo '$(srcdir)/'`gpm-graph-widget.c
+
+mate_power_statistics-gpm-graph-widget.obj: gpm-graph-widget.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -MT mate_power_statistics-gpm-graph-widget.obj -MD -MP -MF $(DEPDIR)/mate_power_statistics-gpm-graph-widget.Tpo -c -o mate_power_statistics-gpm-graph-widget.obj `if test -f 'gpm-graph-widget.c'; then $(CYGPATH_W) 'gpm-graph-widget.c'; else $(CYGPATH_W) '$(srcdir)/gpm-graph-widget.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mate_power_statistics-gpm-graph-widget.Tpo $(DEPDIR)/mate_power_statistics-gpm-graph-widget.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gpm-graph-widget.c' object='mate_power_statistics-gpm-graph-widget.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mate_power_statistics_CFLAGS) $(CFLAGS) -c -o mate_power_statistics-gpm-graph-widget.obj `if test -f 'gpm-graph-widget.c'; then $(CYGPATH_W) 'gpm-graph-widget.c'; else $(CYGPATH_W) '$(srcdir)/gpm-graph-widget.c'; fi`
+
+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
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+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
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) 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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+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."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libtool clean-local clean-noinstLIBRARIES \
+ clean-sbinPROGRAMS 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-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-sbinPROGRAMS
+
+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-binPROGRAMS uninstall-sbinPROGRAMS
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libtool clean-local clean-noinstLIBRARIES \
+ clean-sbinPROGRAMS ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS 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-ps install-ps-am \
+ install-sbinPROGRAMS 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-binPROGRAMS \
+ uninstall-sbinPROGRAMS
+
+
+gpm-marshal.c: gpm-marshal.list
+ echo "#include \"gpm-marshal.h\"" > $@ && \
+ @GLIB_GENMARSHAL@ $< --prefix=gpm_marshal --body >> $@
+
+gpm-marshal.h: gpm-marshal.list
+ @GLIB_GENMARSHAL@ $< --prefix=gpm_marshal --header > $@
+
+org.mate.PowerManager.h: org.mate.PowerManager.xml
+ libtool --mode=execute dbus-binding-tool \
+ --prefix=gpm_manager \
+ --mode=glib-server \
+ --output=org.mate.PowerManager.h \
+ $(srcdir)/org.mate.PowerManager.xml
+
+org.mate.PowerManager.Backlight.h: org.mate.PowerManager.Backlight.xml
+ libtool --mode=execute dbus-binding-tool \
+ --prefix=gpm_backlight \
+ --mode=glib-server \
+ --output=org.mate.PowerManager.Backlight.h \
+ $(srcdir)/org.mate.PowerManager.Backlight.xml
+
+clean-local:
+ rm -f *~
+ rm -f gpm-marshal.c gpm-marshal.h
+
+# 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/egg-array-float.c b/src/egg-array-float.c
new file mode 100644
index 0000000..3213330
--- /dev/null
+++ b/src/egg-array-float.c
@@ -0,0 +1,770 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+
+#include "egg-debug.h"
+#include "egg-array-float.h"
+
+/**
+ * egg_array_float_guassian_value:
+ *
+ * @x: input value
+ * @sigma: sigma value
+ * Return value: the gaussian, in floating point precision
+ **/
+static gfloat
+egg_array_float_guassian_value (gfloat x, gfloat sigma)
+{
+ return (1.0 / (sqrtf(2.0*3.1415927) * sigma)) * (expf((-(powf(x,2.0)))/(2.0 * powf(sigma, 2.0))));
+}
+
+/**
+ * egg_array_float_new:
+ *
+ * @length: length of array
+ * Return value: Allocate array
+ *
+ * Creates a new size array which is zeroed. Free with g_array_free();
+ **/
+EggArrayFloat *
+egg_array_float_new (guint length)
+{
+ guint i;
+ EggArrayFloat *array;
+ array = g_array_sized_new (TRUE, FALSE, sizeof(gfloat), length);
+ array->len = length;
+
+ /* clear to 0.0 */
+ for (i=0; i<length; i++)
+ g_array_index (array, gfloat, i) = 0.0;
+ return array;
+}
+
+/**
+ * egg_array_float_get:
+ *
+ * @array: input array
+ **/
+gfloat
+egg_array_float_get (EggArrayFloat *array, guint i)
+{
+ if (i >= array->len)
+ g_error ("above index! (%i)", i);
+ return g_array_index (array, gfloat, i);
+}
+
+/**
+ * egg_array_float_set:
+ *
+ * @array: input array
+ **/
+void
+egg_array_float_set (EggArrayFloat *array, guint i, gfloat value)
+{
+ g_array_index (array, gfloat, i) = value;
+}
+
+/**
+ * egg_array_float_free:
+ *
+ * @array: input array
+ *
+ * Frees the array, deallocating data
+ **/
+void
+egg_array_float_free (EggArrayFloat *array)
+{
+ if (array != NULL)
+ g_array_free (array, TRUE);
+}
+
+/**
+ * egg_array_float_get_average:
+ * @array: This class instance
+ *
+ * Gets the average value.
+ **/
+gfloat
+egg_array_float_get_average (EggArrayFloat *array)
+{
+ guint i;
+ guint length;
+ gfloat average = 0;
+
+ length = array->len;
+ for (i=0; i<length; i++)
+ average += g_array_index (array, gfloat, i);
+ return average / (gfloat) length;
+}
+
+/**
+ * egg_array_float_compute_gaussian:
+ *
+ * @length: length of output array
+ * @sigma: sigma value
+ * Return value: Gaussian array
+ *
+ * Create a set of Gaussian array of a specified size
+ **/
+EggArrayFloat *
+egg_array_float_compute_gaussian (guint length, gfloat sigma)
+{
+ EggArrayFloat *array;
+ guint half_length;
+ guint i;
+ gfloat division;
+ gfloat value;
+
+ g_return_val_if_fail (length % 2 == 1, NULL);
+
+ array = egg_array_float_new (length);
+
+ /* array positions 0..length, has to be an odd number */
+ half_length = (length / 2) + 1;
+ for (i=0; i<half_length; i++) {
+ division = half_length - (i + 1);
+ egg_debug ("half_length=%i, div=%f, sigma=%f", half_length, division, sigma);
+ g_array_index (array, gfloat, i) = egg_array_float_guassian_value (division, sigma);
+ }
+
+ /* no point working these out, we can just reflect the gaussian */
+ for (i=half_length; i<length; i++) {
+ division = g_array_index (array, gfloat, length-(i+1));
+ g_array_index (array, gfloat, i) = division;
+ }
+
+ /* make sure we get an accurate gaussian */
+ value = egg_array_float_sum (array);
+ if (fabs (value - 1.0f) > 0.01f) {
+ egg_warning ("got wrong sum (%f), perhaps sigma too high for size?", value);
+ egg_array_float_free (array);
+ array = NULL;
+ }
+
+ return array;
+}
+
+/**
+ * egg_array_float_sum:
+ *
+ * @array: input array
+ *
+ * Sum the elements of the array
+ **/
+gfloat
+egg_array_float_sum (EggArrayFloat *array)
+{
+ guint length;
+ guint i;
+ gfloat total = 0;
+
+ length = array->len;
+ for (i=0; i<length; i++)
+ total += g_array_index (array, gfloat, i);
+ return total;
+}
+
+/**
+ * egg_array_float_print:
+ *
+ * @array: input array
+ *
+ * Print the array
+ **/
+gboolean
+egg_array_float_print (EggArrayFloat *array)
+{
+ guint length;
+ guint i;
+
+ length = array->len;
+ /* debug out */
+ for (i=0; i<length; i++)
+ egg_debug ("[%i]\tval=%f", i, g_array_index (array, gfloat, i));
+ return TRUE;
+}
+
+/**
+ * egg_array_float_convolve:
+ *
+ * @data: input array
+ * @kernel: kernel array
+ * Return value: Colvolved array, same length as data
+ *
+ * Convolves an array with a kernel, and returns an array the same size.
+ * THIS FUNCTION IS REALLY SLOW...
+ **/
+EggArrayFloat *
+egg_array_float_convolve (EggArrayFloat *data, EggArrayFloat *kernel)
+{
+ gint length_data;
+ gint length_kernel;
+ EggArrayFloat *result;
+ gfloat value;
+ gint i;
+ gint j;
+ gint idx;
+
+ length_data = data->len;
+ length_kernel = kernel->len;
+
+ result = egg_array_float_new (length_data);
+
+ /* convolve */
+ for (i=0;i<length_data;i++) {
+ value = 0;
+ for (j=0;j<length_kernel;j++) {
+ idx = i+j-(length_kernel/2);
+ if (idx < 0)
+ idx = 0;
+ else if (idx >= length_data)
+ idx = length_data - 1;
+ value += g_array_index (data, gfloat, idx) * g_array_index (kernel, gfloat, j);
+ }
+ g_array_index (result, gfloat, i) = value;
+ }
+ return result;
+}
+
+/**
+ * egg_array_float_compute_integral:
+ * @array: This class instance
+ *
+ * Computes complete discrete integral of dataset.
+ * Will only work with a step size of one.
+ **/
+gfloat
+egg_array_float_compute_integral (EggArrayFloat *array, guint x1, guint x2)
+{
+ gfloat value;
+ guint i;
+
+ g_return_val_if_fail (x2 >= x1, 0.0);
+
+ /* if the same point, then we have no area */
+ if (x1 == x2)
+ return 0.0;
+
+ value = 0.0;
+ for (i=x1; i <= x2; i++)
+ value += g_array_index (array, gfloat, i);
+ return value;
+}
+
+/**
+ * powfi:
+ **/
+static gfloat
+powfi (gfloat base, guint n)
+{
+ guint i;
+ gfloat retval = 1;
+ for (i=1; i <= n; i++)
+ retval *= base;
+ return retval;
+}
+
+/**
+ * egg_array_float_remove_outliers:
+ *
+ * @data: input array
+ * @size: size to analyse
+ * @sigma: sigma for standard deviation
+ * Return value: Data with outliers removed
+ *
+ * Compares local sections of the data, removing outliers if they fall
+ * ouside of sigma, and using the average of the other points in it's place.
+ **/
+EggArrayFloat *
+egg_array_float_remove_outliers (EggArrayFloat *data, guint length, gfloat sigma)
+{
+ guint i;
+ guint j;
+ guint half_length;
+ gfloat value;
+ gfloat average;
+ gfloat average_not_inc;
+ gfloat average_square;
+ gfloat biggest_difference;
+ gfloat outlier_value;
+ EggArrayFloat *result;
+
+ g_return_val_if_fail (length % 2 == 1, NULL);
+ result = egg_array_float_new (data->len);
+
+ /* check for no data */
+ if (data->len == 0)
+ goto out;
+
+ half_length = (length - 1) / 2;
+
+ /* copy start and end of array */
+ for (i=0; i < half_length; i++)
+ g_array_index (result, gfloat, i) = g_array_index (data, gfloat, i);
+ for (i=data->len-half_length; i < data->len; i++)
+ g_array_index (result, gfloat, i) = g_array_index (data, gfloat, i);
+
+ /* find the standard deviation of a block off data */
+ for (i=half_length; i < data->len-half_length; i++) {
+ average = 0;
+ average_square = 0;
+
+ /* find the average and the squared average */
+ for (j=i-half_length; j<i+half_length+1; j++) {
+ value = g_array_index (data, gfloat, j);
+ average += value;
+ average_square += powfi (value, 2);
+ }
+
+ /* divide by length to get average */
+ average /= length;
+ average_square /= length;
+
+ /* find the standard deviation */
+ value = sqrtf (average_square - powfi (average, 2));
+
+ /* stddev is okay */
+ if (value < sigma) {
+ g_array_index (result, gfloat, i) = g_array_index (data, gfloat, i);
+ } else {
+ /* ignore the biggest difference from the average */
+ biggest_difference = 0;
+ outlier_value = 0;
+ for (j=i-half_length; j<i+half_length+1; j++) {
+ value = fabs (g_array_index (data, gfloat, j) - average);
+ if (value > biggest_difference) {
+ biggest_difference = value;
+ outlier_value = g_array_index (data, gfloat, j);
+ }
+ }
+ average_not_inc = (average * length) - outlier_value;
+ average_not_inc /= length - 1;
+ g_array_index (result, gfloat, i) = average_not_inc;
+ }
+ }
+out:
+ return result;
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+egg_array_float_test (gpointer data)
+{
+ EggArrayFloat *array;
+ EggArrayFloat *kernel;
+ EggArrayFloat *result;
+ gfloat value;
+ gfloat sigma;
+ guint size;
+ EggTest *test = (EggTest *) data;
+
+ if (egg_test_start (test, "EggArrayFloat") == FALSE)
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get a non null array");
+ array = egg_array_float_new (10);
+ if (array != NULL)
+ egg_test_success (test, "got EggArrayFloat");
+ else
+ egg_test_failed (test, "could not get EggArrayFloat");
+ egg_array_float_print (array);
+ egg_array_float_free (array);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct length array");
+ array = egg_array_float_new (10);
+ if (array->len == 10)
+ egg_test_success (test, "got correct size");
+ else
+ egg_test_failed (test, "got wrong size");
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum");
+ value = egg_array_float_sum (array);
+ if (value == 0.0)
+ egg_test_success (test, "got correct sum");
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "remove outliers");
+ egg_array_float_set (array, 0, 30.0);
+ egg_array_float_set (array, 1, 29.0);
+ egg_array_float_set (array, 2, 31.0);
+ egg_array_float_set (array, 3, 33.0);
+ egg_array_float_set (array, 4, 100.0);
+ egg_array_float_set (array, 5, 27.0);
+ egg_array_float_set (array, 6, 30.0);
+ egg_array_float_set (array, 7, 29.0);
+ egg_array_float_set (array, 8, 31.0);
+ egg_array_float_set (array, 9, 30.0);
+ kernel = egg_array_float_remove_outliers (array, 3, 10.0);
+ if (kernel != NULL && kernel->len == 10)
+ egg_test_success (test, "got correct length outlier array");
+ else
+ egg_test_failed (test, "got gaussian array length (%i)", array->len);
+ egg_array_float_print (array);
+ egg_array_float_print (kernel);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we removed the outliers");
+ value = egg_array_float_sum (kernel);
+ if (fabs(value - 30*10) < 1)
+ egg_test_success (test, "got sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+ egg_array_float_free (kernel);
+
+ /************************************************************/
+ egg_test_title (test, "remove outliers step");
+ egg_array_float_set (array, 0, 0.0);
+ egg_array_float_set (array, 1, 0.0);
+ egg_array_float_set (array, 2, 0.0);
+ egg_array_float_set (array, 3, 0.0);
+ egg_array_float_set (array, 4, 0.0);
+ egg_array_float_set (array, 5, 0.0);
+ egg_array_float_set (array, 6, 0.0);
+ egg_array_float_set (array, 7, 10.0);
+ egg_array_float_set (array, 8, 20.0);
+ egg_array_float_set (array, 9, 50.0);
+ kernel = egg_array_float_remove_outliers (array, 3, 20.0);
+ if (kernel != NULL && kernel->len == 10)
+ egg_test_success (test, "got correct length outlier array");
+ else
+ egg_test_failed (test, "got gaussian array length (%i)", array->len);
+ egg_array_float_print (array);
+ egg_array_float_print (kernel);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we removed the outliers");
+ value = egg_array_float_sum (kernel);
+ if (fabs(value - 80) < 1)
+ egg_test_success (test, "got sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+ egg_array_float_free (kernel);
+
+ /************************************************************/
+ egg_test_title (test, "get gaussian 0.0, sigma 1.1");
+ value = egg_array_float_guassian_value (0.0, 1.1);
+ if (fabs (value - 0.36267) < 0.0001)
+ egg_test_success (test, "got correct gaussian");
+ else
+ egg_test_failed (test, "got wrong gaussian (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "get gaussian 0.5, sigma 1.1");
+ value = egg_array_float_guassian_value (0.5, 1.1);
+ if (fabs (value - 0.32708) < 0.0001)
+ egg_test_success (test, "got correct gaussian");
+ else
+ egg_test_failed (test, "got wrong gaussian (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "get gaussian 1.0, sigma 1.1");
+ value = egg_array_float_guassian_value (1.0, 1.1);
+ if (fabs (value - 0.23991) < 0.0001)
+ egg_test_success (test, "got correct gaussian");
+ else
+ egg_test_failed (test, "got wrong gaussian (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "get gaussian 0.5, sigma 4.5");
+ value = egg_array_float_guassian_value (0.5, 4.5);
+ if (fabs (value - 0.088108) < 0.0001)
+ egg_test_success (test, "got correct gaussian");
+ else
+ egg_test_failed (test, "got wrong gaussian (%f)", value);
+
+ /************************************************************/
+ size = 5;
+ sigma = 1.1;
+ egg_test_title (test, "get inprecise gaussian array (%i), sigma %f", size, sigma);
+ kernel = egg_array_float_compute_gaussian (size, sigma);
+ if (kernel == NULL)
+ egg_test_success (test, NULL);
+ else {
+ egg_test_failed (test, "got gaussian array length (%i)", array->len);
+ egg_array_float_print (kernel);
+ }
+
+ /************************************************************/
+ size = 9;
+ sigma = 1.1;
+ egg_test_title (test, "get gaussian-9 array (%i), sigma %f", size, sigma);
+ kernel = egg_array_float_compute_gaussian (size, sigma);
+ if (kernel != NULL && kernel->len == size)
+ egg_test_success (test, "got correct length gaussian array");
+ else
+ egg_test_failed (test, "got gaussian array length (%i)", array->len);
+ egg_array_float_print (kernel);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get an accurate gaussian");
+ value = egg_array_float_sum (kernel);
+ if (fabs(value - 1.0) < 0.01)
+ egg_test_success (test, "got sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get get and set");
+ egg_array_float_set (array, 4, 100.0);
+ value = egg_array_float_get (array, 4);
+ if (value == 100.0)
+ egg_test_success (test, "got value okay", value);
+ else
+ egg_test_failed (test, "got wrong value (%f)", value);
+ egg_array_float_print (array);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum (2)");
+ egg_array_float_set (array, 0, 20.0);
+ egg_array_float_set (array, 1, 44.0);
+ egg_array_float_set (array, 2, 45.0);
+ egg_array_float_set (array, 3, 89.0);
+ egg_array_float_set (array, 4, 100.0);
+ egg_array_float_set (array, 5, 12.0);
+ egg_array_float_set (array, 6, 76.0);
+ egg_array_float_set (array, 7, 78.0);
+ egg_array_float_set (array, 8, 1.20);
+ egg_array_float_set (array, 9, 3.0);
+ value = egg_array_float_sum (array);
+ if (fabs (value - 468.2) < 0.0001f)
+ egg_test_success (test, "got correct sum");
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "test convolving with kernel #1");
+ egg_array_float_set (array, 0, 0.0);
+ egg_array_float_set (array, 1, 0.0);
+ egg_array_float_set (array, 2, 0.0);
+ egg_array_float_set (array, 3, 0.0);
+ egg_array_float_set (array, 4, 100.0);
+ egg_array_float_set (array, 5, 0.0);
+ egg_array_float_set (array, 6, 0.0);
+ egg_array_float_set (array, 7, 0.0);
+ egg_array_float_set (array, 8, 0.0);
+ egg_array_float_set (array, 9, 0.0);
+ result = egg_array_float_convolve (array, kernel);
+ if (result->len == 10)
+ egg_test_success (test, "got correct size convolve product");
+ else
+ egg_test_failed (test, "got correct size convolve product (%f)", result->len);
+ egg_array_float_print (result);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum of convolve #1");
+ value = egg_array_float_sum (result);
+ if (fabs(value - 100.0) < 5.0)
+ egg_test_success (test, "got correct (enough) sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+ egg_array_float_free (result);
+
+ /************************************************************/
+ egg_test_title (test, "test convolving with kernel #2");
+ egg_array_float_set (array, 0, 100.0);
+ egg_array_float_set (array, 1, 0.0);
+ egg_array_float_set (array, 2, 0.0);
+ egg_array_float_set (array, 3, 0.0);
+ egg_array_float_set (array, 4, 0.0);
+ egg_array_float_set (array, 5, 0.0);
+ egg_array_float_set (array, 6, 0.0);
+ egg_array_float_set (array, 7, 0.0);
+ egg_array_float_set (array, 8, 0.0);
+ egg_array_float_set (array, 9, 0.0);
+ result = egg_array_float_convolve (array, kernel);
+ if (result->len == 10)
+ egg_test_success (test, "got correct size convolve product");
+ else
+ egg_test_failed (test, "got correct size convolve product (%f)", result->len);
+ egg_array_float_print (array);
+ egg_array_float_print (result);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum of convolve #2");
+ value = egg_array_float_sum (result);
+ if (fabs(value - 100.0) < 10.0)
+ egg_test_success (test, "got correct (enough) sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+
+ egg_array_float_free (result);
+
+ /************************************************************/
+ egg_test_title (test, "test convolving with kernel #3");
+ egg_array_float_set (array, 0, 0.0);
+ egg_array_float_set (array, 1, 0.0);
+ egg_array_float_set (array, 2, 0.0);
+ egg_array_float_set (array, 3, 0.0);
+ egg_array_float_set (array, 4, 0.0);
+ egg_array_float_set (array, 5, 0.0);
+ egg_array_float_set (array, 6, 0.0);
+ egg_array_float_set (array, 7, 0.0);
+ egg_array_float_set (array, 8, 0.0);
+ egg_array_float_set (array, 9, 100.0);
+ result = egg_array_float_convolve (array, kernel);
+ if (result->len == 10)
+ egg_test_success (test, "got correct size convolve product");
+ else
+ egg_test_failed (test, "got correct size convolve product (%f)", result->len);
+ egg_array_float_print (array);
+ egg_array_float_print (result);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum of convolve #3");
+ value = egg_array_float_sum (result);
+ if (fabs(value - 100.0) < 10.0)
+ egg_test_success (test, "got correct (enough) sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+ egg_array_float_free (result);
+
+ /************************************************************/
+ egg_test_title (test, "test convolving with kernel #4");
+ egg_array_float_set (array, 0, 10.0);
+ egg_array_float_set (array, 1, 10.0);
+ egg_array_float_set (array, 2, 10.0);
+ egg_array_float_set (array, 3, 10.0);
+ egg_array_float_set (array, 4, 10.0);
+ egg_array_float_set (array, 5, 10.0);
+ egg_array_float_set (array, 6, 10.0);
+ egg_array_float_set (array, 7, 10.0);
+ egg_array_float_set (array, 8, 10.0);
+ egg_array_float_set (array, 9, 10.0);
+ result = egg_array_float_convolve (array, kernel);
+ if (result->len == 10)
+ egg_test_success (test, "got correct size convolve product");
+ else
+ egg_test_failed (test, "got incorrect size convolve product (%f)", result->len);
+ egg_array_float_print (array);
+ egg_array_float_print (result);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum of convolve #4");
+ value = egg_array_float_sum (result);
+ if (fabs(value - 100.0) < 1.0)
+ egg_test_success (test, "got correct (enough) sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+
+ /************************************************************/
+ egg_test_title (test, "test convolving with kernel #5");
+ egg_array_float_set (array, 0, 10.0);
+ egg_array_float_set (array, 1, 10.0);
+ egg_array_float_set (array, 2, 10.0);
+ egg_array_float_set (array, 3, 10.0);
+ egg_array_float_set (array, 4, 0.0);
+ egg_array_float_set (array, 5, 10.0);
+ egg_array_float_set (array, 6, 10.0);
+ egg_array_float_set (array, 7, 10.0);
+ egg_array_float_set (array, 8, 10.0);
+ egg_array_float_set (array, 9, 10.0);
+ result = egg_array_float_convolve (array, kernel);
+ if (result->len == 10)
+ egg_test_success (test, "got correct size convolve product");
+ else
+ egg_test_failed (test, "got incorrect size convolve product (%f)", result->len);
+ egg_array_float_print (array);
+ egg_array_float_print (result);
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get the correct array sum of convolve #5");
+ value = egg_array_float_sum (result);
+ if (fabs(value - 90.0) < 1.0)
+ egg_test_success (test, "got correct (enough) sum (%f)", value);
+ else
+ egg_test_failed (test, "got wrong sum (%f)", value);
+
+ /*************** INTEGRATION TEST ************************/
+ egg_test_title (test, "integration down");
+ egg_array_float_set (array, 0, 0.0);
+ egg_array_float_set (array, 1, 1.0);
+ egg_array_float_set (array, 2, 2.0);
+ egg_array_float_set (array, 3, 3.0);
+ egg_array_float_set (array, 4, 4.0);
+ egg_array_float_set (array, 5, 5.0);
+ egg_array_float_set (array, 6, 6.0);
+ egg_array_float_set (array, 7, 7.0);
+ egg_array_float_set (array, 8, 8.0);
+ egg_array_float_set (array, 9, 9.0);
+ size = egg_array_float_compute_integral (array, 0, 4);
+ if (size == 0+1+2+3+4)
+ egg_test_success (test, "intergrated okay");
+ else
+ egg_test_failed (test, "did not intergrated okay (%i)", size);
+ egg_test_title (test, "integration up");
+ size = egg_array_float_compute_integral (array, 5, 9);
+ if (size == 5+6+7+8+9)
+ egg_test_success (test, "intergrated okay");
+ else
+ egg_test_failed (test, "did not intergrated okay (%i)", size);
+ egg_test_title (test, "integration all");
+ size = egg_array_float_compute_integral (array, 0, 9);
+ if (size == 0+1+2+3+4+5+6+7+8+9)
+ egg_test_success (test, "intergrated okay");
+ else
+ egg_test_failed (test, "did not intergrated okay (%i)", size);
+
+ /*************** AVERAGE TEST ************************/
+ egg_test_title (test, "average");
+ egg_array_float_set (array, 0, 0.0);
+ egg_array_float_set (array, 1, 1.0);
+ egg_array_float_set (array, 2, 2.0);
+ egg_array_float_set (array, 3, 3.0);
+ egg_array_float_set (array, 4, 4.0);
+ egg_array_float_set (array, 5, 5.0);
+ egg_array_float_set (array, 6, 6.0);
+ egg_array_float_set (array, 7, 7.0);
+ egg_array_float_set (array, 8, 8.0);
+ egg_array_float_set (array, 9, 9.0);
+ value = egg_array_float_get_average (array);
+ if (value == 4.5)
+ egg_test_success (test, "averaged okay");
+ else
+ egg_test_failed (test, "did not average okay (%i)", value);
+
+ egg_array_float_free (result);
+ egg_array_float_free (array);
+ egg_array_float_free (kernel);
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/egg-array-float.h b/src/egg-array-float.h
new file mode 100644
index 0000000..e37e1d0
--- /dev/null
+++ b/src/egg-array-float.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_ARRAY_FLOAT_H
+#define __EGG_ARRAY_FLOAT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/* at the moment just use a GArray as it's quick */
+typedef GArray EggArrayFloat;
+
+EggArrayFloat *egg_array_float_new (guint length);
+void egg_array_float_free (EggArrayFloat *array);
+gfloat egg_array_float_sum (EggArrayFloat *array);
+EggArrayFloat *egg_array_float_compute_gaussian (guint length,
+ gfloat sigma);
+gfloat egg_array_float_compute_integral (EggArrayFloat *array,
+ guint x1,
+ guint x2);
+gfloat egg_array_float_get_average (EggArrayFloat *array);
+gboolean egg_array_float_print (EggArrayFloat *array);
+EggArrayFloat *egg_array_float_convolve (EggArrayFloat *data,
+ EggArrayFloat *kernel);
+gfloat egg_array_float_get (EggArrayFloat *array,
+ guint i);
+void egg_array_float_set (EggArrayFloat *array,
+ guint i,
+ gfloat value);
+EggArrayFloat *egg_array_float_remove_outliers (EggArrayFloat *data, guint length, gfloat sigma);
+#ifdef EGG_TEST
+void egg_array_float_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __EGG_ARRAY_FLOAT_H */
diff --git a/src/egg-color.c b/src/egg-color.c
new file mode 100644
index 0000000..2dcbca8
--- /dev/null
+++ b/src/egg-color.c
@@ -0,0 +1,157 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <glib.h>
+#include "egg-color.h"
+
+/**
+ * egg_color_from_rgb:
+ * @red: The red value
+ * @green: The green value
+ * @blue: The blue value
+ **/
+guint32
+egg_color_from_rgb (guint8 red, guint8 green, guint8 blue)
+{
+ guint32 color = 0;
+ color += (guint32) red * 0x10000;
+ color += (guint32) green * 0x100;
+ color += (guint32) blue;
+ return color;
+}
+
+/**
+ * egg_color_to_rgb:
+ * @red: The red value
+ * @green: The green value
+ * @blue: The blue value
+ **/
+void
+egg_color_to_rgb (guint32 color, guint8 *red, guint8 *green, guint8 *blue)
+{
+ *red = (color & 0xff0000) / 0x10000;
+ *green = (color & 0x00ff00) / 0x100;
+ *blue = color & 0x0000ff;
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+egg_color_test (gpointer data)
+{
+ guint8 r, g, b;
+ guint32 color;
+ EggTest *test = (EggTest *) data;
+
+ if (egg_test_start (test, "EggColor") == FALSE) {
+ return;
+ }
+
+ /************************************************************/
+ egg_test_title (test, "get red");
+ egg_color_to_rgb (0xff0000, &r, &g, &b);
+ if (r == 255 && g == 0 && b == 0) {
+ egg_test_success (test, "got red");
+ } else {
+ egg_test_failed (test, "could not get red (%i, %i, %i)", r, g, b);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "get green");
+ egg_color_to_rgb (0x00ff00, &r, &g, &b);
+ if (r == 0 && g == 255 && b == 0) {
+ egg_test_success (test, "got green");
+ } else {
+ egg_test_failed (test, "could not get green (%i, %i, %i)", r, g, b);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "get blue");
+ egg_color_to_rgb (0x0000ff, &r, &g, &b);
+ if (r == 0 && g == 0 && b == 255) {
+ egg_test_success (test, "got blue");
+ } else {
+ egg_test_failed (test, "could not get blue (%i, %i, %i)", r, g, b);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "get black");
+ egg_color_to_rgb (0x000000, &r, &g, &b);
+ if (r == 0 && g == 0 && b == 0) {
+ egg_test_success (test, "got black");
+ } else {
+ egg_test_failed (test, "could not get black (%i, %i, %i)", r, g, b);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "get white");
+ egg_color_to_rgb (0xffffff, &r, &g, &b);
+ if (r == 255 && g == 255 && b == 255) {
+ egg_test_success (test, "got white");
+ } else {
+ egg_test_failed (test, "could not get white (%i, %i, %i)", r, g, b);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "set red");
+ color = egg_color_from_rgb (0xff, 0x00, 0x00);
+ if (color == 0xff0000) {
+ egg_test_success (test, "set red");
+ } else {
+ egg_test_failed (test, "could not set red (%i)", color);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "set green");
+ color = egg_color_from_rgb (0x00, 0xff, 0x00);
+ if (color == 0x00ff00) {
+ egg_test_success (test, "set green");
+ } else {
+ egg_test_failed (test, "could not set green (%i)", color);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "set blue");
+ color = egg_color_from_rgb (0x00, 0x00, 0xff);
+ if (color == 0x0000ff) {
+ egg_test_success (test, "set blue");
+ } else {
+ egg_test_failed (test, "could not set blue (%i)", color);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "set white");
+ color = egg_color_from_rgb (0xff, 0xff, 0xff);
+ if (color == 0xffffff) {
+ egg_test_success (test, "set white");
+ } else {
+ egg_test_failed (test, "could not set white (%i)", color);
+ }
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/egg-color.h b/src/egg-color.h
new file mode 100644
index 0000000..71d0752
--- /dev/null
+++ b/src/egg-color.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_COLOR_H
+#define __EGG_COLOR_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define EGG_COLOR_WHITE 0xffffff
+#define EGG_COLOR_BLACK 0x000000
+#define EGG_COLOR_RED 0xff0000
+#define EGG_COLOR_GREEN 0x00ff00
+#define EGG_COLOR_BLUE 0x0000ff
+#define EGG_COLOR_CYAN 0x00ffff
+#define EGG_COLOR_MAGENTA 0xff00ff
+#define EGG_COLOR_YELLOW 0xffff00
+#define EGG_COLOR_GREY 0xcccccc
+#define EGG_COLOR_DARK_RED 0x600000
+#define EGG_COLOR_DARK_GREEN 0x006000
+#define EGG_COLOR_DARK_BLUE 0x000060
+#define EGG_COLOR_DARK_CYAN 0x006060
+#define EGG_COLOR_DARK_MAGENTA 0x600060
+#define EGG_COLOR_DARK_YELLOW 0x606000
+#define EGG_COLOR_DARK_GREY 0x606060
+
+guint32 egg_color_from_rgb (guint8 red,
+ guint8 green,
+ guint8 blue);
+void egg_color_to_rgb (guint32 color,
+ guint8 *red,
+ guint8 *green,
+ guint8 *blue);
+#ifdef EGG_TEST
+void egg_color_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __EGG_COLOR_H */
diff --git a/src/egg-console-kit.c b/src/egg-console-kit.c
new file mode 100644
index 0000000..0602d7c
--- /dev/null
+++ b/src/egg-console-kit.c
@@ -0,0 +1,363 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+
+#include "egg-debug.h"
+#include "egg-console-kit.h"
+
+static void egg_console_kit_finalize (GObject *object);
+
+#define EGG_CONSOLE_KIT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_CONSOLE_KIT, EggConsoleKitPrivate))
+
+#define CONSOLEKIT_NAME "org.freedesktop.ConsoleKit"
+#define CONSOLEKIT_PATH "/org/freedesktop/ConsoleKit"
+#define CONSOLEKIT_INTERFACE "org.freedesktop.ConsoleKit"
+
+#define CONSOLEKIT_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CONSOLEKIT_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
+#define CONSOLEKIT_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat"
+#define CONSOLEKIT_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session"
+
+struct EggConsoleKitPrivate
+{
+ DBusGConnection *connection;
+ DBusGProxy *proxy_manager;
+ DBusGProxy *proxy_session;
+ gchar *session_id;
+};
+
+enum {
+ EGG_CONSOLE_KIT_ACTIVE_CHANGED,
+ EGG_CONSOLE_KIT_LAST_SIGNAL
+};
+
+static gpointer egg_console_kit_object = NULL;
+static guint signals [EGG_CONSOLE_KIT_LAST_SIGNAL] = { 0 };
+G_DEFINE_TYPE (EggConsoleKit, egg_console_kit, G_TYPE_OBJECT)
+
+/**
+ * egg_console_kit_restart:
+ **/
+gboolean
+egg_console_kit_restart (EggConsoleKit *console, GError **error)
+{
+ gboolean ret;
+ GError *error_local = NULL;
+
+ g_return_val_if_fail (EGG_IS_CONSOLE_KIT (console), FALSE);
+ g_return_val_if_fail (console->priv->proxy_manager != NULL, FALSE);
+
+ ret = dbus_g_proxy_call (console->priv->proxy_manager, "Restart", &error_local,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("Couldn't restart: %s", error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, "%s", error_local->message);
+ g_error_free (error_local);
+ }
+ return ret;
+}
+
+/**
+ * egg_console_kit_stop:
+ **/
+gboolean
+egg_console_kit_stop (EggConsoleKit *console, GError **error)
+{
+ gboolean ret;
+ GError *error_local = NULL;
+
+ g_return_val_if_fail (EGG_IS_CONSOLE_KIT (console), FALSE);
+ g_return_val_if_fail (console->priv->proxy_manager != NULL, FALSE);
+
+ ret = dbus_g_proxy_call (console->priv->proxy_manager, "Stop", &error_local,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("Couldn't stop: %s", error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, "%s", error_local->message);
+ g_error_free (error_local);
+ }
+ return ret;
+}
+
+/**
+ * egg_console_kit_can_stop:
+ **/
+gboolean
+egg_console_kit_can_stop (EggConsoleKit *console, gboolean *can_stop, GError **error)
+{
+ gboolean ret;
+ GError *error_local = NULL;
+
+ g_return_val_if_fail (EGG_IS_CONSOLE_KIT (console), FALSE);
+ g_return_val_if_fail (console->priv->proxy_manager != NULL, FALSE);
+
+ ret = dbus_g_proxy_call (console->priv->proxy_manager, "CanStop", &error_local,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, can_stop, G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("Couldn't do CanStop: %s", error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, "%s", error_local->message);
+ g_error_free (error_local);
+ /* CanStop was only added in new versions of ConsoleKit,
+ * so assume true if this failed */
+ *can_stop = TRUE;
+ }
+ return ret;
+}
+
+/**
+ * egg_console_kit_can_restart:
+ **/
+gboolean
+egg_console_kit_can_restart (EggConsoleKit *console, gboolean *can_restart, GError **error)
+{
+ gboolean ret;
+ GError *error_local = NULL;
+
+ g_return_val_if_fail (EGG_IS_CONSOLE_KIT (console), FALSE);
+ g_return_val_if_fail (console->priv->proxy_manager != NULL, FALSE);
+
+ ret = dbus_g_proxy_call (console->priv->proxy_manager, "CanRestart", &error_local,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, can_restart, G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("Couldn't do CanRestart: %s", error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, "%s", error_local->message);
+ g_error_free (error_local);
+ /* CanRestart was only added in new versions of ConsoleKit,
+ * so assume true if this failed */
+ *can_restart = TRUE;
+ }
+ return ret;
+}
+
+/**
+ * egg_console_kit_is_local:
+ *
+ * Return value: Returns whether the session is local
+ **/
+gboolean
+egg_console_kit_is_local (EggConsoleKit *console)
+{
+ gboolean ret = FALSE;
+ gboolean value = FALSE;
+ GError *error = NULL;
+
+ g_return_val_if_fail (EGG_IS_CONSOLE_KIT (console), FALSE);
+
+ /* maybe console kit does not know about our session */
+ if (console->priv->proxy_session == NULL) {
+ egg_warning ("no ConsoleKit session");
+ goto out;
+ }
+
+ /* is our session local */
+ ret = dbus_g_proxy_call (console->priv->proxy_session, "IsLocal", &error, G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &value, G_TYPE_INVALID);
+ if (!ret) {
+ g_warning ("IsLocal failed: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* return value only if we successed */
+ ret = value;
+out:
+ return ret;
+}
+
+/**
+ * egg_console_kit_is_active:
+ *
+ * Return value: Returns whether the session is active on the Seat that it is attached to.
+ **/
+gboolean
+egg_console_kit_is_active (EggConsoleKit *console)
+{
+ gboolean ret = FALSE;
+ gboolean value = FALSE;
+ GError *error = NULL;
+
+ g_return_val_if_fail (EGG_IS_CONSOLE_KIT (console), FALSE);
+
+ /* maybe console kit does not know about our session */
+ if (console->priv->proxy_session == NULL) {
+ egg_warning ("no ConsoleKit session");
+ goto out;
+ }
+
+ /* is our session active */
+ ret = dbus_g_proxy_call (console->priv->proxy_session, "IsActive", &error, G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &value, G_TYPE_INVALID);
+ if (!ret) {
+ g_warning ("IsActive failed: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* return value only if we successed */
+ ret = value;
+out:
+ return ret;
+}
+
+/**
+ * egg_console_kit_active_changed_cb:
+ **/
+static void
+egg_console_kit_active_changed_cb (DBusGProxy *proxy, gboolean active, EggConsoleKit *console)
+{
+ egg_debug ("emitting active: %i", active);
+ g_signal_emit (console, signals [EGG_CONSOLE_KIT_ACTIVE_CHANGED], 0, active);
+}
+
+/**
+ * egg_console_kit_class_init:
+ * @klass: The EggConsoleKitClass
+ **/
+static void
+egg_console_kit_class_init (EggConsoleKitClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = egg_console_kit_finalize;
+ g_type_class_add_private (klass, sizeof (EggConsoleKitPrivate));
+ signals [EGG_CONSOLE_KIT_ACTIVE_CHANGED] =
+ g_signal_new ("active-changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggConsoleKitClass, active_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+/**
+ * egg_console_kit_init:
+ **/
+static void
+egg_console_kit_init (EggConsoleKit *console)
+{
+ gboolean ret;
+ GError *error = NULL;
+ guint32 pid;
+
+ console->priv = EGG_CONSOLE_KIT_GET_PRIVATE (console);
+ console->priv->proxy_manager = NULL;
+ console->priv->session_id = NULL;
+
+ /* connect to D-Bus */
+ console->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (console->priv->connection == NULL) {
+ egg_warning ("Failed to connect to the D-Bus daemon: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* connect to ConsoleKit */
+ console->priv->proxy_manager =
+ dbus_g_proxy_new_for_name (console->priv->connection, CONSOLEKIT_NAME,
+ CONSOLEKIT_MANAGER_PATH, CONSOLEKIT_MANAGER_INTERFACE);
+ if (console->priv->proxy_manager == NULL) {
+ egg_warning ("cannot connect to ConsoleKit");
+ goto out;
+ }
+
+ /* get the session we are running in */
+ pid = getpid ();
+ ret = dbus_g_proxy_call (console->priv->proxy_manager, "GetSessionForUnixProcess", &error,
+ G_TYPE_UINT, pid,
+ G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &console->priv->session_id,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("Failed to get session for pid %i: %s", pid, error->message);
+ g_error_free (error);
+ goto out;
+ }
+ egg_debug ("ConsoleKit session ID: %s", console->priv->session_id);
+
+ /* connect to session */
+ console->priv->proxy_session =
+ dbus_g_proxy_new_for_name (console->priv->connection, CONSOLEKIT_NAME,
+ console->priv->session_id, CONSOLEKIT_SESSION_INTERFACE);
+ if (console->priv->proxy_session == NULL) {
+ egg_warning ("cannot connect to: %s", console->priv->session_id);
+ goto out;
+ }
+ dbus_g_proxy_add_signal (console->priv->proxy_session, "ActiveChanged", G_TYPE_BOOLEAN, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (console->priv->proxy_session, "ActiveChanged",
+ G_CALLBACK (egg_console_kit_active_changed_cb), console, NULL);
+
+out:
+ return;
+}
+
+/**
+ * egg_console_kit_finalize:
+ * @object: The object to finalize
+ **/
+static void
+egg_console_kit_finalize (GObject *object)
+{
+ EggConsoleKit *console;
+
+ g_return_if_fail (EGG_IS_CONSOLE_KIT (object));
+
+ console = EGG_CONSOLE_KIT (object);
+
+ g_return_if_fail (console->priv != NULL);
+ if (console->priv->proxy_manager != NULL)
+ g_object_unref (console->priv->proxy_manager);
+ if (console->priv->proxy_session != NULL)
+ g_object_unref (console->priv->proxy_session);
+ g_free (console->priv->session_id);
+
+ G_OBJECT_CLASS (egg_console_kit_parent_class)->finalize (object);
+}
+
+/**
+ * egg_console_kit_new:
+ *
+ * Return value: a new EggConsoleKit object.
+ **/
+EggConsoleKit *
+egg_console_kit_new (void)
+{
+ if (egg_console_kit_object != NULL) {
+ g_object_ref (egg_console_kit_object);
+ } else {
+ egg_console_kit_object = g_object_new (EGG_TYPE_CONSOLE_KIT, NULL);
+ g_object_add_weak_pointer (egg_console_kit_object, &egg_console_kit_object);
+ }
+
+ return EGG_CONSOLE_KIT (egg_console_kit_object);
+}
+
diff --git a/src/egg-console-kit.h b/src/egg-console-kit.h
new file mode 100644
index 0000000..c93ddce
--- /dev/null
+++ b/src/egg-console-kit.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_CONSOLE_KIT_H
+#define __EGG_CONSOLE_KIT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_CONSOLE_KIT (egg_console_kit_get_type ())
+#define EGG_CONSOLE_KIT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_CONSOLE_KIT, EggConsoleKit))
+#define EGG_CONSOLE_KIT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_CONSOLE_KIT, EggConsoleKitClass))
+#define EGG_IS_CONSOLE_KIT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_CONSOLE_KIT))
+#define EGG_IS_CONSOLE_KIT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_CONSOLE_KIT))
+#define EGG_CONSOLE_KIT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_CONSOLE_KIT, EggConsoleKitClass))
+#define EGG_CONSOLE_KIT_ERROR (egg_console_kit_error_quark ())
+#define EGG_CONSOLE_KIT_TYPE_ERROR (egg_console_kit_error_get_type ())
+
+typedef struct EggConsoleKitPrivate EggConsoleKitPrivate;
+
+typedef struct
+{
+ GObject parent;
+ EggConsoleKitPrivate *priv;
+} EggConsoleKit;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* active_changed) (EggConsoleKit *console,
+ gboolean active);
+} EggConsoleKitClass;
+
+GType egg_console_kit_get_type (void);
+EggConsoleKit *egg_console_kit_new (void);
+gboolean egg_console_kit_is_local (EggConsoleKit *console);
+gboolean egg_console_kit_is_active (EggConsoleKit *console);
+gboolean egg_console_kit_stop (EggConsoleKit *console,
+ GError **error);
+gboolean egg_console_kit_restart (EggConsoleKit *console,
+ GError **error);
+gboolean egg_console_kit_can_stop (EggConsoleKit *console,
+ gboolean *can_stop,
+ GError **error);
+gboolean egg_console_kit_can_restart (EggConsoleKit *console,
+ gboolean *can_restart,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __EGG_CONSOLE_KIT_H */
+
diff --git a/src/egg-dbus-monitor.c b/src/egg-dbus-monitor.c
new file mode 100644
index 0000000..b8238d1
--- /dev/null
+++ b/src/egg-dbus-monitor.c
@@ -0,0 +1,251 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-monitor.h"
+
+static void egg_dbus_monitor_finalize (GObject *object);
+
+#define EGG_DBUS_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_DBUS_MONITOR, EggDbusMonitorPrivate))
+
+struct EggDbusMonitorPrivate
+{
+ gchar *service;
+ DBusGProxy *proxy;
+ DBusGConnection *connection;
+ const gchar *unique_name;
+};
+
+enum {
+ EGG_DBUS_MONITOR_CONNECTION_CHANGED,
+ EGG_DBUS_MONITOR_CONNECTION_REPLACED,
+ EGG_DBUS_MONITOR_LAST_SIGNAL
+};
+
+static guint signals [EGG_DBUS_MONITOR_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (EggDbusMonitor, egg_dbus_monitor, G_TYPE_OBJECT)
+
+/**
+ * egg_dbus_monitor_name_owner_changed_cb:
+ **/
+static void
+egg_dbus_monitor_name_owner_changed_cb (DBusGProxy *proxy, const gchar *name,
+ const gchar *prev, const gchar *new,
+ EggDbusMonitor *monitor)
+{
+ guint new_len;
+ guint prev_len;
+
+ g_return_if_fail (EGG_IS_DBUS_MONITOR (monitor));
+ if (monitor->priv->proxy == NULL)
+ return;
+
+ /* not us */
+ if (strcmp (name, monitor->priv->service) != 0)
+ return;
+
+ /* ITS4: ignore, not used for allocation */
+ new_len = strlen (new);
+ /* ITS4: ignore, not used for allocation */
+ prev_len = strlen (prev);
+
+ /* something --> nothing */
+ if (prev_len != 0 && new_len == 0) {
+ g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED], 0, FALSE);
+ return;
+ }
+
+ /* nothing --> something */
+ if (prev_len == 0 && new_len != 0) {
+ g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED], 0, TRUE);
+ return;
+ }
+
+ /* something --> something (we've replaced the old process) */
+ if (prev_len != 0 && new_len != 0) {
+ /* only send this to the prev client */
+ if (strcmp (monitor->priv->unique_name, prev) == 0)
+ g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_REPLACED], 0);
+ return;
+ }
+}
+
+/**
+ * egg_dbus_monitor_assign:
+ * @monitor: This class instance
+ * @connection: The bus connection
+ * @service: The EGG_DBUS_MONITOR service name
+ * Return value: success
+ *
+ * Emits connection-changed(TRUE) if connection is alive - this means you
+ * have to connect up the callback before this function is called.
+ **/
+gboolean
+egg_dbus_monitor_assign (EggDbusMonitor *monitor, DBusGConnection *connection, const gchar *service)
+{
+ GError *error = NULL;
+ gboolean connected;
+ DBusConnection *conn;
+
+ g_return_val_if_fail (EGG_IS_DBUS_MONITOR (monitor), FALSE);
+ g_return_val_if_fail (service != NULL, FALSE);
+ g_return_val_if_fail (connection != NULL, FALSE);
+
+ if (monitor->priv->proxy != NULL) {
+ egg_warning ("already assigned!");
+ return FALSE;
+ }
+
+ monitor->priv->service = g_strdup (service);
+ monitor->priv->connection = connection;
+ monitor->priv->proxy = dbus_g_proxy_new_for_name_owner (monitor->priv->connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &error);
+ if (error != NULL) {
+ egg_warning ("Cannot connect to DBUS: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ dbus_g_proxy_add_signal (monitor->priv->proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (monitor->priv->proxy, "NameOwnerChanged",
+ G_CALLBACK (egg_dbus_monitor_name_owner_changed_cb),
+ monitor, NULL);
+
+ /* coldplug */
+ connected = egg_dbus_monitor_is_connected (monitor);
+ if (connected)
+ g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED], 0, TRUE);
+
+ /* save this for the replaced check */
+ conn = dbus_g_connection_get_connection (monitor->priv->connection);
+ monitor->priv->unique_name = dbus_bus_get_unique_name (conn);
+ return TRUE;
+}
+
+/**
+ * egg_dbus_monitor_is_connected:
+ * @monitor: This class instance
+ * Return value: if we are connected to a valid watch
+ **/
+gboolean
+egg_dbus_monitor_is_connected (EggDbusMonitor *monitor)
+{
+ DBusError error;
+ DBusConnection *conn;
+ gboolean ret;
+ g_return_val_if_fail (EGG_IS_DBUS_MONITOR (monitor), FALSE);
+
+ /* get raw connection */
+ conn = dbus_g_connection_get_connection (monitor->priv->connection);
+ dbus_error_init (&error);
+ ret = dbus_bus_name_has_owner (conn, monitor->priv->service, &error);
+ if (dbus_error_is_set (&error)) {
+ egg_debug ("error: %s", error.message);
+ dbus_error_free (&error);
+ }
+
+ return ret;
+}
+
+/**
+ * egg_dbus_monitor_class_init:
+ * @klass: The EggDbusMonitorClass
+ **/
+static void
+egg_dbus_monitor_class_init (EggDbusMonitorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = egg_dbus_monitor_finalize;
+ g_type_class_add_private (klass, sizeof (EggDbusMonitorPrivate));
+ signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED] =
+ g_signal_new ("connection-changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggDbusMonitorClass, connection_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals [EGG_DBUS_MONITOR_CONNECTION_REPLACED] =
+ g_signal_new ("connection-replaced",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggDbusMonitorClass, connection_replaced),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * egg_dbus_monitor_init:
+ * @monitor: This class instance
+ **/
+static void
+egg_dbus_monitor_init (EggDbusMonitor *monitor)
+{
+ monitor->priv = EGG_DBUS_MONITOR_GET_PRIVATE (monitor);
+ monitor->priv->service = NULL;
+ monitor->priv->connection = NULL;
+ monitor->priv->proxy = NULL;
+}
+
+/**
+ * egg_dbus_monitor_finalize:
+ * @object: The object to finalize
+ **/
+static void
+egg_dbus_monitor_finalize (GObject *object)
+{
+ EggDbusMonitor *monitor;
+
+ g_return_if_fail (EGG_IS_DBUS_MONITOR (object));
+
+ monitor = EGG_DBUS_MONITOR (object);
+
+ g_return_if_fail (monitor->priv != NULL);
+ if (monitor->priv->proxy != NULL)
+ g_object_unref (monitor->priv->proxy);
+
+ G_OBJECT_CLASS (egg_dbus_monitor_parent_class)->finalize (object);
+}
+
+/**
+ * egg_dbus_monitor_new:
+ *
+ * Return value: a new EggDbusMonitor object.
+ **/
+EggDbusMonitor *
+egg_dbus_monitor_new (void)
+{
+ EggDbusMonitor *monitor;
+ monitor = g_object_new (EGG_TYPE_DBUS_MONITOR, NULL);
+ return EGG_DBUS_MONITOR (monitor);
+}
+
diff --git a/src/egg-dbus-monitor.h b/src/egg-dbus-monitor.h
new file mode 100644
index 0000000..9efa8b9
--- /dev/null
+++ b/src/egg-dbus-monitor.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_DBUS_MONITOR_H
+#define __EGG_DBUS_MONITOR_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_DBUS_MONITOR (egg_dbus_monitor_get_type ())
+#define EGG_DBUS_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_DBUS_MONITOR, EggDbusMonitor))
+#define EGG_DBUS_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_DBUS_MONITOR, EggDbusMonitorClass))
+#define EGG_IS_DBUS_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_DBUS_MONITOR))
+#define EGG_IS_DBUS_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_DBUS_MONITOR))
+#define EGG_DBUS_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_DBUS_MONITOR, EggDbusMonitorClass))
+#define EGG_DBUS_MONITOR_ERROR (egg_dbus_monitor_error_quark ())
+#define EGG_DBUS_MONITOR_TYPE_ERROR (egg_dbus_monitor_error_get_type ())
+
+typedef struct EggDbusMonitorPrivate EggDbusMonitorPrivate;
+
+typedef struct
+{
+ GObject parent;
+ EggDbusMonitorPrivate *priv;
+} EggDbusMonitor;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* connection_changed) (EggDbusMonitor *watch,
+ gboolean connected);
+ void (* connection_replaced) (EggDbusMonitor *watch);
+} EggDbusMonitorClass;
+
+GType egg_dbus_monitor_get_type (void);
+EggDbusMonitor *egg_dbus_monitor_new (void);
+gboolean egg_dbus_monitor_assign (EggDbusMonitor *monitor,
+ DBusGConnection *connection,
+ const gchar *service);
+gboolean egg_dbus_monitor_is_connected (EggDbusMonitor *monitor);
+
+G_END_DECLS
+
+#endif /* __EGG_DBUS_MONITOR_H */
+
diff --git a/src/egg-dbus-proxy.c b/src/egg-dbus-proxy.c
new file mode 100644
index 0000000..8490682
--- /dev/null
+++ b/src/egg-dbus-proxy.c
@@ -0,0 +1,301 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include "egg-debug.h"
+#include "egg-dbus-monitor.h"
+#include "egg-dbus-proxy.h"
+
+static void egg_dbus_proxy_finalize (GObject *object);
+
+#define EGG_DBUS_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_DBUS_PROXY, EggDbusProxyPrivate))
+
+/* this is a managed proxy, i.e. a proxy that handles messagebus and DBUS service restarts. */
+struct EggDbusProxyPrivate
+{
+ gchar *service;
+ gchar *interface;
+ gchar *path;
+ DBusGProxy *proxy;
+ EggDbusMonitor *monitor;
+ gboolean assigned;
+ DBusGConnection *connection;
+ gulong monitor_callback_id;
+};
+
+enum {
+ PROXY_STATUS,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (EggDbusProxy, egg_dbus_proxy, G_TYPE_OBJECT)
+
+/**
+ * egg_dbus_proxy_connect:
+ * @proxy: This class instance
+ * Return value: success
+ **/
+static gboolean
+egg_dbus_proxy_connect (EggDbusProxy *proxy)
+{
+ GError *error = NULL;
+
+ g_return_val_if_fail (EGG_IS_DBUS_PROXY (proxy), FALSE);
+
+ /* are already connected? */
+ if (proxy->priv->proxy != NULL) {
+ egg_debug ("already connected to %s", proxy->priv->service);
+ return FALSE;
+ }
+
+ proxy->priv->proxy = dbus_g_proxy_new_for_name_owner (proxy->priv->connection,
+ proxy->priv->service,
+ proxy->priv->path,
+ proxy->priv->interface,
+ &error);
+ /* check for any possible error */
+ if (error) {
+ egg_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ proxy->priv->proxy = NULL;
+ }
+
+ /* shouldn't be, but make sure proxy valid */
+ if (proxy->priv->proxy == NULL) {
+ egg_debug ("proxy is NULL, maybe the daemon responsible "
+ "for %s is not running?", proxy->priv->service);
+ return FALSE;
+ }
+
+ g_signal_emit (proxy, signals [PROXY_STATUS], 0, TRUE);
+
+ return TRUE;
+}
+
+/**
+ * egg_dbus_proxy_disconnect:
+ * @proxy: This class instance
+ * Return value: success
+ **/
+static gboolean
+egg_dbus_proxy_disconnect (EggDbusProxy *proxy)
+{
+ g_return_val_if_fail (EGG_IS_DBUS_PROXY (proxy), FALSE);
+
+ /* are already disconnected? */
+ if (proxy->priv->proxy == NULL) {
+ if (proxy->priv->service)
+ egg_debug ("already disconnected from %s", proxy->priv->service);
+ else
+ egg_debug ("already disconnected.");
+ return FALSE;
+ }
+
+ g_signal_emit (proxy, signals [PROXY_STATUS], 0, FALSE);
+
+ g_object_unref (proxy->priv->proxy);
+ proxy->priv->proxy = NULL;
+
+ return TRUE;
+}
+
+/**
+ * dbus_monitor_connection_cb:
+ * @proxy: The dbus raw proxy
+ * @status: The status of the service, where TRUE is connected
+ * @screensaver: This class instance
+ **/
+static void
+dbus_monitor_connection_cb (EggDbusMonitor *monitor, gboolean status, EggDbusProxy *proxy)
+{
+ g_return_if_fail (EGG_IS_DBUS_PROXY (proxy));
+ if (proxy->priv->assigned == FALSE)
+ return;
+ if (status)
+ egg_dbus_proxy_connect (proxy);
+ else
+ egg_dbus_proxy_disconnect (proxy);
+}
+
+/**
+ * egg_dbus_proxy_assign:
+ * @proxy: This class instance
+ * @connections: The bus connection
+ * @service: The DBUS service name
+ * @interface: The DBUS interface
+ * @path: The DBUS path
+ * Return value: The DBUS proxy, or NULL if we haven't connected yet.
+ **/
+DBusGProxy *
+egg_dbus_proxy_assign (EggDbusProxy *proxy, DBusGConnection *connection,
+ const gchar *service, const gchar *path, const gchar *interface)
+{
+ g_return_val_if_fail (EGG_IS_DBUS_PROXY (proxy), NULL);
+ g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (service != NULL, NULL);
+ g_return_val_if_fail (interface != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ if (proxy->priv->assigned) {
+ egg_warning ("already assigned proxy!");
+ return NULL;
+ }
+
+ proxy->priv->service = g_strdup (service);
+ proxy->priv->interface = g_strdup (interface);
+ proxy->priv->path = g_strdup (path);
+ proxy->priv->connection = connection;
+ proxy->priv->assigned = TRUE;
+
+ /* We have to save the connection and remove the signal id later as
+ instances of this object are likely to be registering with a
+ singleton object many times */
+ egg_dbus_monitor_assign (proxy->priv->monitor, connection, service);
+
+ /* try to connect and return proxy (or NULL if invalid) */
+ egg_dbus_proxy_connect (proxy);
+
+ return proxy->priv->proxy;
+}
+
+/**
+ * egg_dbus_proxy_get_proxy:
+ * @proxy: This class instance
+ * Return value: The DBUS proxy, or NULL if we are not connected
+ **/
+DBusGProxy *
+egg_dbus_proxy_get_proxy (EggDbusProxy *proxy)
+{
+ g_return_val_if_fail (EGG_IS_DBUS_PROXY (proxy), NULL);
+ if (proxy->priv->assigned == FALSE)
+ return NULL;
+ return proxy->priv->proxy;
+}
+
+/**
+ * egg_dbus_proxy_is_connected:
+ * @proxy: This class instance
+ * Return value: if we are connected to a valid proxy
+ **/
+gboolean
+egg_dbus_proxy_is_connected (EggDbusProxy *proxy)
+{
+ g_return_val_if_fail (EGG_IS_DBUS_PROXY (proxy), FALSE);
+ if (proxy->priv->assigned == FALSE)
+ return FALSE;
+ if (proxy->priv->proxy == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+/**
+ * egg_dbus_proxy_class_init:
+ * @proxy: This class instance
+ **/
+static void
+egg_dbus_proxy_class_init (EggDbusProxyClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = egg_dbus_proxy_finalize;
+ g_type_class_add_private (klass, sizeof (EggDbusProxyPrivate));
+
+ signals [PROXY_STATUS] =
+ g_signal_new ("proxy-status",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggDbusProxyClass, proxy_status),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+/**
+ * egg_dbus_proxy_init:
+ * @egg_dbus_proxy: This class instance
+ **/
+static void
+egg_dbus_proxy_init (EggDbusProxy *proxy)
+{
+ proxy->priv = EGG_DBUS_PROXY_GET_PRIVATE (proxy);
+
+ proxy->priv->connection = NULL;
+ proxy->priv->proxy = NULL;
+ proxy->priv->service = NULL;
+ proxy->priv->interface = NULL;
+ proxy->priv->path = NULL;
+ proxy->priv->assigned = FALSE;
+ proxy->priv->monitor = egg_dbus_monitor_new ();
+ proxy->priv->monitor_callback_id =
+ g_signal_connect (proxy->priv->monitor, "connection-changed",
+ G_CALLBACK (dbus_monitor_connection_cb), proxy);
+ proxy->priv->monitor_callback_id = 0;
+}
+
+/**
+ * egg_dbus_proxy_finalize:
+ * @object: This class instance
+ **/
+static void
+egg_dbus_proxy_finalize (GObject *object)
+{
+ EggDbusProxy *proxy;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (EGG_IS_DBUS_PROXY (object));
+
+ proxy = EGG_DBUS_PROXY (object);
+ proxy->priv = EGG_DBUS_PROXY_GET_PRIVATE (proxy);
+
+ if (proxy->priv->monitor_callback_id != 0)
+ g_signal_handler_disconnect (proxy->priv->monitor,
+ proxy->priv->monitor_callback_id);
+
+ egg_dbus_proxy_disconnect (proxy);
+
+ if (proxy->priv->proxy != NULL)
+ g_object_unref (proxy->priv->proxy);
+ g_object_unref (proxy->priv->monitor);
+ g_free (proxy->priv->service);
+ g_free (proxy->priv->interface);
+ g_free (proxy->priv->path);
+
+ G_OBJECT_CLASS (egg_dbus_proxy_parent_class)->finalize (object);
+}
+
+/**
+ * egg_dbus_proxy_new:
+ * Return value: new class instance.
+ **/
+EggDbusProxy *
+egg_dbus_proxy_new (void)
+{
+ EggDbusProxy *proxy;
+ proxy = g_object_new (EGG_TYPE_DBUS_PROXY, NULL);
+ return EGG_DBUS_PROXY (proxy);
+}
+
diff --git a/src/egg-dbus-proxy.h b/src/egg-dbus-proxy.h
new file mode 100644
index 0000000..30a00cf
--- /dev/null
+++ b/src/egg-dbus-proxy.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __DBUSPROXY_H
+#define __DBUSPROXY_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_DBUS_PROXY (egg_dbus_proxy_get_type ())
+#define EGG_DBUS_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_DBUS_PROXY, EggDbusProxy))
+#define EGG_DBUS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_DBUS_PROXY, EggDbusProxyClass))
+#define EGG_IS_DBUS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_DBUS_PROXY))
+#define EGG_IS_DBUS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_DBUS_PROXY))
+#define EGG_DBUS_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_DBUS_PROXY, EggDbusProxyClass))
+
+typedef struct EggDbusProxyPrivate EggDbusProxyPrivate;
+
+typedef struct
+{
+ GObject parent;
+ EggDbusProxyPrivate *priv;
+} EggDbusProxy;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* proxy_status) (EggDbusProxy *proxy,
+ gboolean status);
+} EggDbusProxyClass;
+
+GType egg_dbus_proxy_get_type (void);
+EggDbusProxy *egg_dbus_proxy_new (void);
+
+DBusGProxy *egg_dbus_proxy_assign (EggDbusProxy *dbus_proxy,
+ DBusGConnection *connection,
+ const gchar *service,
+ const gchar *path,
+ const gchar *interface);
+DBusGProxy *egg_dbus_proxy_get_proxy (EggDbusProxy *egg_dbus_proxy);
+gboolean egg_dbus_proxy_is_connected (EggDbusProxy *egg_dbus_proxy);
+
+G_END_DECLS
+
+#endif /* __DBUSPROXY_H */
+
diff --git a/src/egg-debug.c b/src/egg-debug.c
new file mode 100644
index 0000000..2f140f2
--- /dev/null
+++ b/src/egg-debug.c
@@ -0,0 +1,308 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * SECTION:egg-debug
+ * @short_description: Debugging functions
+ *
+ * This file contains functions that can be used for debugging.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <execinfo.h>
+
+#include "egg-debug.h"
+
+#define CONSOLE_RESET 0
+#define CONSOLE_BLACK 30
+#define CONSOLE_RED 31
+#define CONSOLE_GREEN 32
+#define CONSOLE_YELLOW 33
+#define CONSOLE_BLUE 34
+#define CONSOLE_MAGENTA 35
+#define CONSOLE_CYAN 36
+#define CONSOLE_WHITE 37
+
+static gint fd = -1;
+
+/**
+ * pk_set_console_mode:
+ **/
+static void
+pk_set_console_mode (guint console_code)
+{
+ gchar command[13];
+
+ /* don't put extra commands into logs */
+ if (!egg_debug_is_console ())
+ return;
+
+ /* Command is the control command to the terminal */
+ g_snprintf (command, 13, "%c[%dm", 0x1B, console_code);
+ printf ("%s", command);
+}
+
+/**
+ * egg_debug_backtrace:
+ **/
+void
+egg_debug_backtrace (void)
+{
+ void *call_stack[512];
+ int call_stack_size;
+ char **symbols;
+ int i = 1;
+
+ call_stack_size = backtrace (call_stack, G_N_ELEMENTS (call_stack));
+ symbols = backtrace_symbols (call_stack, call_stack_size);
+ if (symbols != NULL) {
+ pk_set_console_mode (CONSOLE_RED);
+ g_print ("Traceback:\n");
+ while (i < call_stack_size) {
+ g_print ("\t%s\n", symbols[i]);
+ i++;
+ }
+ pk_set_console_mode (CONSOLE_RESET);
+ free (symbols);
+ }
+}
+
+/**
+ * pk_log_line:
+ **/
+static void
+pk_log_line (const gchar *buffer)
+{
+ ssize_t count;
+ /* open a file */
+ if (fd == -1) {
+ /* ITS4: ignore, /var/log/foo is owned by root, and this is just debug text */
+ fd = open (EGG_LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0777);
+ if (fd == -1)
+ g_error ("could not open log: '%s'", EGG_LOG_FILE);
+ }
+
+ /* ITS4: ignore, debug text always NULL terminated */
+ count = write (fd, buffer, strlen (buffer));
+ if (count == -1)
+ g_warning ("could not write %s", buffer);
+ /* newline */
+ count = write (fd, "\n", 1);
+ if (count == -1)
+ g_warning ("could not write newline");
+}
+
+/**
+ * pk_print_line:
+ **/
+static void
+pk_print_line (const gchar *func, const gchar *file, const int line, const gchar *buffer, guint color)
+{
+ gchar *str_time;
+ gchar *header;
+ time_t the_time;
+ GThread *thread;
+
+ time (&the_time);
+ str_time = g_new0 (gchar, 255);
+ strftime (str_time, 254, "%H:%M:%S", localtime (&the_time));
+ thread = g_thread_self ();
+
+ /* generate header text */
+ header = g_strdup_printf ("TI:%s\tTH:%p\tFI:%s\tFN:%s,%d", str_time, thread, file, func, line);
+ g_free (str_time);
+
+ /* always in light green */
+ pk_set_console_mode (CONSOLE_GREEN);
+ printf ("%s\n", header);
+
+ /* different colors according to the severity */
+ pk_set_console_mode (color);
+ printf (" - %s\n", buffer);
+ pk_set_console_mode (CONSOLE_RESET);
+
+ /* log to a file */
+ if (egg_debug_is_logging ()) {
+ pk_log_line (header);
+ pk_log_line (buffer);
+ }
+
+ /* flush this output, as we need to debug */
+ fflush (stdout);
+
+ g_free (header);
+}
+
+/**
+ * egg_debug_real:
+ **/
+void
+egg_debug_real (const gchar *func, const gchar *file, const int line, const gchar *format, ...)
+{
+ va_list args;
+ gchar *buffer = NULL;
+
+ if (!egg_debug_enabled ())
+ return;
+
+ va_start (args, format);
+ g_vasprintf (&buffer, format, args);
+ va_end (args);
+
+ pk_print_line (func, file, line, buffer, CONSOLE_BLUE);
+
+ g_free(buffer);
+}
+
+/**
+ * egg_warning_real:
+ **/
+void
+egg_warning_real (const gchar *func, const gchar *file, const int line, const gchar *format, ...)
+{
+ va_list args;
+ gchar *buffer = NULL;
+
+ if (!egg_debug_enabled ())
+ return;
+
+ va_start (args, format);
+ g_vasprintf (&buffer, format, args);
+ va_end (args);
+
+ /* do extra stuff for a warning */
+ if (!egg_debug_is_console ())
+ printf ("*** WARNING ***\n");
+ pk_print_line (func, file, line, buffer, CONSOLE_RED);
+
+ g_free(buffer);
+}
+
+/**
+ * egg_error_real:
+ **/
+void
+egg_error_real (const gchar *func, const gchar *file, const int line, const gchar *format, ...)
+{
+ va_list args;
+ gchar *buffer = NULL;
+
+ va_start (args, format);
+ g_vasprintf (&buffer, format, args);
+ va_end (args);
+
+ /* do extra stuff for a warning */
+ if (!egg_debug_is_console ())
+ printf ("*** ERROR ***\n");
+ pk_print_line (func, file, line, buffer, CONSOLE_RED);
+ g_free(buffer);
+
+ /* we want to fix this! */
+ egg_debug_backtrace ();
+
+ exit (1);
+}
+
+/**
+ * egg_debug_enabled:
+ *
+ * Returns: TRUE if we have debugging enabled
+ **/
+gboolean
+egg_debug_enabled (void)
+{
+ const gchar *env;
+ env = g_getenv (EGG_VERBOSE);
+ return (g_strcmp0 (env, "1") == 0);
+}
+
+/**
+ * egg_debug_is_logging:
+ *
+ * Returns: TRUE if we have logging enabled
+ **/
+gboolean
+egg_debug_is_logging (void)
+{
+ const gchar *env;
+ env = g_getenv (EGG_LOGGING);
+ return (g_strcmp0 (env, "1") == 0);
+}
+
+/**
+ * egg_debug_is_console:
+ *
+ * Returns: TRUE if we have debugging enabled
+ **/
+gboolean
+egg_debug_is_console (void)
+{
+ const gchar *env;
+ env = g_getenv (EGG_CONSOLE);
+ return (g_strcmp0 (env, "1") == 0);
+}
+
+/**
+ * egg_debug_set_logging:
+ **/
+void
+egg_debug_set_logging (gboolean enabled)
+{
+ if (enabled)
+ g_setenv (EGG_LOGGING, "1", TRUE);
+ else
+ g_setenv (EGG_LOGGING, "0", TRUE);
+
+ if (egg_debug_is_logging ())
+ egg_debug ("logging to %s", EGG_LOG_FILE);
+}
+
+/**
+ * egg_debug_init:
+ * @debug: If we should print out verbose logging
+ **/
+void
+egg_debug_init (gboolean debug)
+{
+ /* check if we are on console */
+ if (isatty (fileno (stdout)) == 1)
+ g_setenv (EGG_CONSOLE, "1", FALSE);
+ else
+ g_setenv (EGG_CONSOLE, "0", FALSE);
+ if (debug)
+ g_setenv (EGG_VERBOSE, "1", FALSE);
+ else
+ g_setenv (EGG_VERBOSE, "0", FALSE);
+ egg_debug ("Verbose debugging %i (on console %i)%s", egg_debug_enabled (), egg_debug_is_console (), EGG_VERBOSE);
+}
+
diff --git a/src/egg-debug.h b/src/egg-debug.h
new file mode 100644
index 0000000..fdfb02b
--- /dev/null
+++ b/src/egg-debug.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_DEBUG_H
+#define __EGG_DEBUG_H
+
+#include <stdarg.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+/**
+ * egg_debug:
+ *
+ * Non critical debugging
+ */
+#define egg_debug(...) egg_debug_real (__func__, __FILE__, __LINE__, __VA_ARGS__)
+
+/**
+ * egg_warning:
+ *
+ * Important debugging
+ */
+#define egg_warning(...) egg_warning_real (__func__, __FILE__, __LINE__, __VA_ARGS__)
+
+/**
+ * egg_error:
+ *
+ * Critical debugging, with exit
+ */
+#define egg_error(...) egg_error_real (__func__, __FILE__, __LINE__, __VA_ARGS__)
+
+#elif defined(__GNUC__) && __GNUC__ >= 3
+#define egg_debug(...) egg_debug_real (__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
+#define egg_warning(...) egg_warning_real (__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
+#define egg_error(...) egg_error_real (__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define egg_debug(...)
+#define egg_warning(...)
+#define egg_error(...)
+#endif
+
+void egg_debug_init (gboolean debug);
+void egg_debug_set_logging (gboolean enabled);
+gboolean egg_debug_enabled (void);
+gboolean egg_debug_is_logging (void);
+gboolean egg_debug_is_console (void);
+void egg_debug_backtrace (void);
+void egg_debug_real (const gchar *func,
+ const gchar *file,
+ int line,
+ const gchar *format, ...) __attribute__((format (printf,4,5)));
+void egg_warning_real (const gchar *func,
+ const gchar *file,
+ int line,
+ const gchar *format, ...) __attribute__((format (printf,4,5)));
+void egg_error_real (const gchar *func,
+ const gchar *file,
+ int line,
+ const gchar *format, ...) G_GNUC_NORETURN __attribute__((format (printf,4,5)));
+
+G_END_DECLS
+
+#endif /* __EGG_DEBUG_H */
diff --git a/src/egg-discrete.c b/src/egg-discrete.c
new file mode 100644
index 0000000..a051282
--- /dev/null
+++ b/src/egg-discrete.c
@@ -0,0 +1,162 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+
+#include "egg-debug.h"
+#include "egg-discrete.h"
+
+/**
+ * egg_discrete_from_percent:
+ * @percentage: The percentage to convert
+ * @levels: The number of discrete levels
+ *
+ * We have to be carefull when converting from %->discrete as precision is very
+ * important if we want the highest value.
+ *
+ * Return value: The discrete value for this percentage.
+ **/
+guint
+egg_discrete_from_percent (guint percentage, guint levels)
+{
+ /* check we are in range */
+ if (percentage > 100)
+ return levels;
+ if (levels == 0) {
+ egg_warning ("levels is 0!");
+ return 0;
+ }
+ return ((gfloat) percentage * (gfloat) (levels - 1)) / 100.0f;
+}
+
+/**
+ * egg_discrete_to_percent:
+ * @hw: The discrete level
+ * @levels: The number of discrete levels
+ *
+ * We have to be carefull when converting from discrete->%.
+ *
+ * Return value: The percentage for this discrete value.
+ **/
+guint
+egg_discrete_to_percent (guint discrete, guint levels)
+{
+ /* check we are in range */
+ if (discrete > levels)
+ return 100;
+ if (levels == 0) {
+ egg_warning ("levels is 0!");
+ return 0;
+ }
+ return (guint) ((gfloat) discrete * (100.0f / (gfloat) (levels - 1)));
+}
+
+/**
+ * egg_discrete_to_fraction:
+ * @hw: The discrete level
+ * @levels: The number of discrete levels
+ *
+ * We have to be careful when converting from discrete->fractions.
+ *
+ * Return value: The floating point fraction (0..1) for this discrete value.
+ **/
+gfloat
+egg_discrete_to_fraction (guint discrete, guint levels)
+{
+ /* check we are in range */
+ if (discrete > levels)
+ return 1.0;
+ if (levels == 0) {
+ egg_warning ("levels is 0!");
+ return 0.0;
+ }
+ return (guint) ((gfloat) discrete / ((gfloat) (levels - 1)));
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+egg_discrete_test (gpointer data)
+{
+ guint value;
+ gfloat fvalue;
+ EggTest *test = (EggTest *) data;
+
+ if (!egg_test_start (test, "EggDiscrete"))
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "convert discrete 0/10 levels");
+ value = egg_discrete_to_percent (0, 10);
+ if (value == 0) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "conversion incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "convert discrete 9/10 levels");
+ value = egg_discrete_to_percent (9, 10);
+ if (value == 100) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "conversion incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "convert discrete 20/10 levels");
+ value = egg_discrete_to_percent (20, 10);
+ if (value == 100) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "conversion incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "convert discrete 0/10 levels");
+ fvalue = egg_discrete_to_fraction (0, 10);
+ if (fvalue > -0.01 && fvalue < 0.01) {
+ egg_test_success (test, "got %f", fvalue);
+ } else {
+ egg_test_failed (test, "conversion incorrect (%f)", fvalue);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "convert discrete 9/10 levels");
+ fvalue = egg_discrete_to_fraction (9, 10);
+ if (fvalue > -1.01 && fvalue < 1.01) {
+ egg_test_success (test, "got %f", fvalue);
+ } else {
+ egg_test_failed (test, "conversion incorrect (%f)", fvalue);
+ }
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/egg-discrete.h b/src/egg-discrete.h
new file mode 100644
index 0000000..9192a59
--- /dev/null
+++ b/src/egg-discrete.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_DISCRETE_H
+#define __EGG_DISCRETE_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+guint egg_discrete_from_percent (guint percentage,
+ guint levels);
+guint egg_discrete_to_percent (guint discrete,
+ guint levels);
+gfloat egg_discrete_to_fraction (guint discrete,
+ guint levels);
+#ifdef EGG_TEST
+void egg_discrete_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __EGG_DISCRETE_H */
diff --git a/src/egg-idletime.c b/src/egg-idletime.c
new file mode 100644
index 0000000..28b7390
--- /dev/null
+++ b/src/egg-idletime.c
@@ -0,0 +1,690 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <glib.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/sync.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "egg-idletime.h"
+
+static void egg_idletime_finalize (GObject *object);
+
+#define EGG_IDLETIME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_IDLETIME_TYPE, EggIdletimePrivate))
+
+struct EggIdletimePrivate
+{
+ gint sync_event;
+ gboolean reset_set;
+ XSyncCounter idle_counter;
+ GPtrArray *array;
+ Display *dpy;
+};
+
+typedef struct
+{
+ guint id;
+ XSyncValue timeout;
+ XSyncAlarm xalarm;
+ EggIdletime *idletime;
+} EggIdletimeAlarm;
+
+enum {
+ SIGNAL_ALARM_EXPIRED,
+ SIGNAL_RESET,
+ LAST_SIGNAL
+};
+
+typedef enum {
+ EGG_IDLETIME_ALARM_TYPE_POSITIVE,
+ EGG_IDLETIME_ALARM_TYPE_NEGATIVE,
+ EGG_IDLETIME_ALARM_TYPE_DISABLED
+} EggIdletimeAlarmType;
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer egg_idletime_object = NULL;
+
+G_DEFINE_TYPE (EggIdletime, egg_idletime, G_TYPE_OBJECT)
+
+/**
+ * egg_idletime_xsyncvalue_to_int64:
+ */
+static gint64
+egg_idletime_xsyncvalue_to_int64 (XSyncValue value)
+{
+ return ((guint64) XSyncValueHigh32 (value)) << 32 | (guint64) XSyncValueLow32 (value);
+}
+
+/**
+ * egg_idletime_get_time:
+ */
+gint64
+egg_idletime_get_time (EggIdletime *idletime)
+{
+ XSyncValue value;
+ XSyncQueryCounter (idletime->priv->dpy, idletime->priv->idle_counter, &value);
+ return egg_idletime_xsyncvalue_to_int64 (value);
+}
+
+/**
+ * egg_idletime_xsync_alarm_set:
+ */
+static void
+egg_idletime_xsync_alarm_set (EggIdletime *idletime, EggIdletimeAlarm *alarm, EggIdletimeAlarmType alarm_type)
+{
+ XSyncAlarmAttributes attr;
+ XSyncValue delta;
+ unsigned int flags;
+ XSyncTestType test;
+
+ /* just remove it */
+ if (alarm_type == EGG_IDLETIME_ALARM_TYPE_DISABLED) {
+ if (alarm->xalarm) {
+ XSyncDestroyAlarm (idletime->priv->dpy, alarm->xalarm);
+ alarm->xalarm = None;
+ }
+ return;
+ }
+
+ /* which way do we do the test? */
+ if (alarm_type == EGG_IDLETIME_ALARM_TYPE_POSITIVE)
+ test = XSyncPositiveTransition;
+ else
+ test = XSyncNegativeTransition;
+
+ XSyncIntToValue (&delta, 0);
+
+ attr.trigger.counter = idletime->priv->idle_counter;
+ attr.trigger.value_type = XSyncAbsolute;
+ attr.trigger.test_type = test;
+ attr.trigger.wait_value = alarm->timeout;
+ attr.delta = delta;
+
+ flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType | XSyncCAValue | XSyncCADelta;
+
+ if (alarm->xalarm)
+ XSyncChangeAlarm (idletime->priv->dpy, alarm->xalarm, flags, &attr);
+ else
+ alarm->xalarm = XSyncCreateAlarm (idletime->priv->dpy, flags, &attr);
+}
+
+/**
+ * egg_idletime_alarm_reset_all:
+ */
+void
+egg_idletime_alarm_reset_all (EggIdletime *idletime)
+{
+ guint i;
+ EggIdletimeAlarm *alarm;
+
+ g_return_if_fail (EGG_IS_IDLETIME (idletime));
+
+ if (!idletime->priv->reset_set)
+ return;
+
+ /* reset all the alarms (except the reset alarm) to their timeouts */
+ for (i=1; i<idletime->priv->array->len; i++) {
+ alarm = g_ptr_array_index (idletime->priv->array, i);
+ egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_POSITIVE);
+ }
+
+ /* set the reset alarm to be disabled */
+ alarm = g_ptr_array_index (idletime->priv->array, 0);
+ egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_DISABLED);
+
+ /* emit signal so say we've reset all timers */
+ g_signal_emit (idletime, signals [SIGNAL_RESET], 0);
+
+ /* we need to be reset again on the next event */
+ idletime->priv->reset_set = FALSE;
+}
+
+/**
+ * egg_idletime_alarm_find_id:
+ */
+static EggIdletimeAlarm *
+egg_idletime_alarm_find_id (EggIdletime *idletime, guint id)
+{
+ guint i;
+ EggIdletimeAlarm *alarm;
+ for (i=0; i<idletime->priv->array->len; i++) {
+ alarm = g_ptr_array_index (idletime->priv->array, i);
+ if (alarm->id == id)
+ return alarm;
+ }
+ return NULL;
+}
+
+/**
+ * egg_idletime_set_reset_alarm:
+ */
+static void
+egg_idletime_set_reset_alarm (EggIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event)
+{
+ EggIdletimeAlarm *alarm;
+ int overflow;
+ XSyncValue add;
+ gint64 current, reset_threshold;
+
+ alarm = egg_idletime_alarm_find_id (idletime, 0);
+
+ if (!idletime->priv->reset_set) {
+ /* don't match on the current value because
+ * XSyncNegativeComparison means less or equal. */
+ XSyncIntToValue (&add, -1);
+ XSyncValueAdd (&alarm->timeout, alarm_event->counter_value, add, &overflow);
+
+ /* set the reset alarm to fire the next time
+ * idletime->priv->idle_counter < the current counter value */
+ egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_NEGATIVE);
+
+ /* don't try to set this again if multiple timers are going off in sequence */
+ idletime->priv->reset_set = TRUE;
+
+ current = egg_idletime_get_time (idletime);
+ reset_threshold = egg_idletime_xsyncvalue_to_int64 (alarm->timeout);
+ if (current < reset_threshold) {
+ /* We've missed the alarm already */
+ egg_idletime_alarm_reset_all (idletime);
+ }
+ }
+}
+
+/**
+ * egg_idletime_alarm_find_event:
+ */
+static EggIdletimeAlarm *
+egg_idletime_alarm_find_event (EggIdletime *idletime, XSyncAlarmNotifyEvent *alarm_event)
+{
+ guint i;
+ EggIdletimeAlarm *alarm;
+ for (i=0; i<idletime->priv->array->len; i++) {
+ alarm = g_ptr_array_index (idletime->priv->array, i);
+ if (alarm_event->alarm == alarm->xalarm)
+ return alarm;
+ }
+ return NULL;
+}
+
+/**
+ * egg_idletime_event_filter_cb:
+ */
+static GdkFilterReturn
+egg_idletime_event_filter_cb (GdkXEvent *gdkxevent, GdkEvent *event, gpointer data)
+{
+ EggIdletimeAlarm *alarm;
+ XEvent *xevent = (XEvent *) gdkxevent;
+ EggIdletime *idletime = (EggIdletime *) data;
+ XSyncAlarmNotifyEvent *alarm_event;
+
+ /* no point continuing */
+ if (xevent->type != idletime->priv->sync_event + XSyncAlarmNotify)
+ return GDK_FILTER_CONTINUE;
+
+ alarm_event = (XSyncAlarmNotifyEvent *) xevent;
+
+ /* did we match one of our alarms? */
+ alarm = egg_idletime_alarm_find_event (idletime, alarm_event);
+ if (alarm == NULL)
+ return GDK_FILTER_CONTINUE;
+
+ /* are we the reset alarm? */
+ if (alarm->id == 0) {
+ egg_idletime_alarm_reset_all (idletime);
+ goto out;
+ }
+
+ /* emit */
+ g_signal_emit (alarm->idletime, signals [SIGNAL_ALARM_EXPIRED], 0, alarm->id);
+
+ /* we need the first alarm to go off to set the reset alarm */
+ egg_idletime_set_reset_alarm (idletime, alarm_event);
+out:
+ /* don't propagate */
+ return GDK_FILTER_REMOVE;
+}
+
+/**
+ * egg_idletime_alarm_new:
+ */
+static EggIdletimeAlarm *
+egg_idletime_alarm_new (EggIdletime *idletime, guint id)
+{
+ EggIdletimeAlarm *alarm;
+
+ /* create a new alarm */
+ alarm = g_new0 (EggIdletimeAlarm, 1);
+
+ /* set the default values */
+ alarm->id = id;
+ alarm->xalarm = None;
+ alarm->idletime = g_object_ref (idletime);
+
+ return alarm;
+}
+
+/**
+ * egg_idletime_alarm_set:
+ */
+gboolean
+egg_idletime_alarm_set (EggIdletime *idletime, guint id, guint timeout)
+{
+ EggIdletimeAlarm *alarm;
+
+ g_return_val_if_fail (EGG_IS_IDLETIME (idletime), FALSE);
+ g_return_val_if_fail (id != 0, FALSE);
+ g_return_val_if_fail (timeout != 0, FALSE);
+
+ /* see if we already created an alarm with this ID */
+ alarm = egg_idletime_alarm_find_id (idletime, id);
+ if (alarm == NULL) {
+ /* create a new alarm */
+ alarm = egg_idletime_alarm_new (idletime, id);
+
+ /* add to array */
+ g_ptr_array_add (idletime->priv->array, alarm);
+ }
+
+ /* set the timeout */
+ XSyncIntToValue (&alarm->timeout, (gint)timeout);
+
+ /* set, and start the timer */
+ egg_idletime_xsync_alarm_set (idletime, alarm, EGG_IDLETIME_ALARM_TYPE_POSITIVE);
+ return TRUE;
+}
+
+/**
+ * egg_idletime_alarm_free:
+ */
+static gboolean
+egg_idletime_alarm_free (EggIdletime *idletime, EggIdletimeAlarm *alarm)
+{
+ g_return_val_if_fail (EGG_IS_IDLETIME (idletime), FALSE);
+ g_return_val_if_fail (alarm != NULL, FALSE);
+
+ if (alarm->xalarm)
+ XSyncDestroyAlarm (idletime->priv->dpy, alarm->xalarm);
+ g_object_unref (alarm->idletime);
+ g_free (alarm);
+ g_ptr_array_remove (idletime->priv->array, alarm);
+ return TRUE;
+}
+
+/**
+ * egg_idletime_alarm_free:
+ */
+gboolean
+egg_idletime_alarm_remove (EggIdletime *idletime, guint id)
+{
+ EggIdletimeAlarm *alarm;
+
+ g_return_val_if_fail (EGG_IS_IDLETIME (idletime), FALSE);
+
+ alarm = egg_idletime_alarm_find_id (idletime, id);
+ if (alarm == NULL)
+ return FALSE;
+ egg_idletime_alarm_free (idletime, alarm);
+ return TRUE;
+}
+
+/**
+ * egg_idletime_class_init:
+ **/
+static void
+egg_idletime_class_init (EggIdletimeClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = egg_idletime_finalize;
+ g_type_class_add_private (klass, sizeof (EggIdletimePrivate));
+
+ signals [SIGNAL_ALARM_EXPIRED] =
+ g_signal_new ("alarm-expired",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggIdletimeClass, alarm_expired),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+ signals [SIGNAL_RESET] =
+ g_signal_new ("reset",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggIdletimeClass, reset),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * egg_idletime_init:
+ **/
+static void
+egg_idletime_init (EggIdletime *idletime)
+{
+ int sync_error;
+ int ncounters;
+ XSyncSystemCounter *counters;
+ EggIdletimeAlarm *alarm;
+ guint i;
+
+ idletime->priv = EGG_IDLETIME_GET_PRIVATE (idletime);
+
+ idletime->priv->array = g_ptr_array_new ();
+
+ idletime->priv->reset_set = FALSE;
+ idletime->priv->idle_counter = None;
+ idletime->priv->sync_event = 0;
+ idletime->priv->dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default());
+
+ /* get the sync event */
+ if (!XSyncQueryExtension (idletime->priv->dpy, &idletime->priv->sync_event, &sync_error)) {
+ g_warning ("No Sync extension.");
+ return;
+ }
+
+ /* gtk_init should do XSyncInitialize for us */
+ counters = XSyncListSystemCounters (idletime->priv->dpy, &ncounters);
+ for (i=0; i < ncounters && !idletime->priv->idle_counter; i++) {
+ if (strcmp(counters[i].name, "IDLETIME") == 0)
+ idletime->priv->idle_counter = counters[i].counter;
+ }
+ XSyncFreeSystemCounterList (counters);
+
+ /* arh. we don't have IDLETIME support */
+ if (!idletime->priv->idle_counter) {
+ g_warning ("No idle counter.");
+ return;
+ }
+
+ /* catch the timer alarm */
+ gdk_window_add_filter (NULL, egg_idletime_event_filter_cb, idletime);
+
+ /* create a reset alarm */
+ alarm = egg_idletime_alarm_new (idletime, 0);
+ g_ptr_array_add (idletime->priv->array, alarm);
+}
+
+/**
+ * egg_idletime_finalize:
+ **/
+static void
+egg_idletime_finalize (GObject *object)
+{
+ guint i;
+ EggIdletime *idletime;
+ EggIdletimeAlarm *alarm;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (EGG_IS_IDLETIME (object));
+
+ idletime = EGG_IDLETIME (object);
+ idletime->priv = EGG_IDLETIME_GET_PRIVATE (idletime);
+
+ /* free all counters, including reset counter */
+ for (i=0; i<idletime->priv->array->len; i++) {
+ alarm = g_ptr_array_index (idletime->priv->array, i);
+ egg_idletime_alarm_free (idletime, alarm);
+ }
+ g_ptr_array_free (idletime->priv->array, TRUE);
+
+ G_OBJECT_CLASS (egg_idletime_parent_class)->finalize (object);
+}
+
+/**
+ * egg_idletime_new:
+ **/
+EggIdletime *
+egg_idletime_new (void)
+{
+ if (egg_idletime_object != NULL) {
+ g_object_ref (egg_idletime_object);
+ } else {
+ egg_idletime_object = g_object_new (EGG_IDLETIME_TYPE, NULL);
+ g_object_add_weak_pointer (egg_idletime_object, &egg_idletime_object);
+ }
+ return EGG_IDLETIME (egg_idletime_object);
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+static void
+egg_test_egg_idletime_wait (guint time_ms)
+{
+ GTimer *ltimer = g_timer_new ();
+ gfloat goal = time_ms / (gfloat) 1000.0f;
+ do {
+ g_main_context_iteration (NULL, FALSE);
+ } while (g_timer_elapsed (ltimer, NULL) < goal);
+ g_timer_destroy (ltimer);
+}
+
+static guint last_alarm = 0;
+static guint event_time;
+GTimer *timer;
+
+static void
+gpm_alarm_expired_cb (EggIdletime *idletime, guint alarm, gpointer data)
+{
+ last_alarm = alarm;
+ event_time = g_timer_elapsed (timer, NULL) * (gfloat) 1000.0f;
+// g_print ("[evt %i in %ims]\n", alarm, event_time);
+}
+
+static void
+wait_until_alarm (void)
+{
+ g_print ("*****************************\n");
+ g_print ("*** DO NOT MOVE THE MOUSE ***\n");
+ g_print ("*****************************\n");
+ while (last_alarm == 0)
+ g_main_context_iteration (NULL, FALSE);
+}
+
+static void
+wait_until_reset (void)
+{
+ if (last_alarm == 0)
+ return;
+ g_print ("*****************************\n");
+ g_print ("*** MOVE THE MOUSE ***\n");
+ g_print ("*****************************\n");
+ while (last_alarm != 0)
+ g_main_context_iteration (NULL, FALSE);
+ egg_test_egg_idletime_wait (1000);
+}
+
+void
+egg_idletime_test (gpointer data)
+{
+ EggIdletime *idletime;
+ gboolean ret;
+ guint i;
+ EggTest *test = (EggTest *) data;
+
+ if (egg_test_start (test, "EggIdletime") == FALSE)
+ return;
+
+ timer = g_timer_new ();
+ gdk_init (NULL, NULL);
+
+ /* warn */
+
+ g_timer_start (timer);
+ /************************************************************/
+ egg_test_title (test, "check to see if delay works as expected");
+ egg_test_egg_idletime_wait (2000);
+ event_time = g_timer_elapsed (timer, NULL) * (gfloat) 1000.0f;
+ if (event_time > 1800 && event_time < 2200) {
+ egg_test_success (test, "time %i~=%i", 2000, event_time);
+ } else {
+ egg_test_failed (test, "time not the same! %i != %i", event_time, 2000);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get a non null device");
+ idletime = egg_idletime_new ();
+ if (idletime != NULL) {
+ egg_test_success (test, "got EggIdletime");
+ } else {
+ egg_test_failed (test, "could not get EggIdletime");
+ }
+ g_signal_connect (idletime, "alarm-expired",
+ G_CALLBACK (gpm_alarm_expired_cb), NULL);
+
+ /************************************************************/
+ egg_test_title (test, "check if we are alarm zero with no alarms");
+ if (last_alarm == 0) {
+ egg_test_success (test, NULL);
+ } else {
+ egg_test_failed (test, "alarm %i set!", last_alarm);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check if we can set an reset alarm");
+ ret = egg_idletime_alarm_set (idletime, 0, 100);
+ if (!ret) {
+ egg_test_success (test, "ignored reset alarm");
+ } else {
+ egg_test_failed (test, "did not ignore reset alarm");
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check if we can set an alarm timeout of zero");
+ ret = egg_idletime_alarm_set (idletime, 999, 0);
+ if (!ret) {
+ egg_test_success (test, "ignored invalid alarm");
+ } else {
+ egg_test_failed (test, "did not ignore invalid alarm");
+ }
+
+ /************************************************************/
+ g_timer_start (timer);
+ egg_test_title (test, "check if we can set an alarm");
+ ret = egg_idletime_alarm_set (idletime, 101, 5000);
+ if (ret) {
+ egg_test_success (test, "set alarm okay");
+ } else {
+ egg_test_failed (test, "could not set alarm");
+ }
+
+ egg_idletime_alarm_set (idletime, 101, 5000);
+ wait_until_alarm ();
+
+ /* loop this two times */
+ for (i=0; i<2; i++) {
+ /* just let it time out, and wait for human input */
+ wait_until_reset ();
+ g_timer_start (timer);
+
+ /************************************************************/
+ g_timer_start (timer);
+ egg_test_title (test, "check if we can set an alarm");
+ ret = egg_idletime_alarm_set (idletime, 101, 5000);
+ if (ret) {
+ egg_test_success (test, "set alarm 5000ms okay");
+ } else {
+ egg_test_failed (test, "could not set alarm 5000ms");
+ }
+
+ /* wait for alarm to go off */
+ wait_until_alarm ();
+ g_timer_start (timer);
+
+ /************************************************************/
+ egg_test_title (test, "check if correct alarm has gone off");
+ if (last_alarm == 101) {
+ egg_test_success (test, "correct alarm");
+ } else {
+ egg_test_failed (test, "alarm %i set!", last_alarm);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check if alarm has gone off in correct time");
+ if (event_time > 3000 && event_time < 6000) {
+ egg_test_success (test, "correct, timeout ideally %ims (we did after %ims)", 5000, event_time);
+ } else {
+ egg_test_failed (test, "alarm %i did not timeout correctly !", last_alarm);
+ }
+ }
+
+ /* just let it time out, and wait for human input */
+ wait_until_reset ();
+ g_timer_start (timer);
+
+ /************************************************************/
+ g_timer_start (timer);
+ egg_test_title (test, "check if we can set an existing alarm");
+ ret = egg_idletime_alarm_set (idletime, 101, 10000);
+ if (ret) {
+ egg_test_success (test, "set alarm 10000ms okay");
+ } else {
+ egg_test_failed (test, "could not set alarm 10000ms");
+ }
+
+ /* wait for alarm to go off */
+ wait_until_alarm ();
+ g_timer_start (timer);
+
+ /************************************************************/
+ egg_test_title (test, "check if alarm has gone off in the old time");
+ if (event_time > 5000) {
+ egg_test_success (test, "last timeout value used");
+ } else {
+ egg_test_failed (test, "incorrect timeout used %ims", event_time);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check if we can remove an invalid alarm");
+ ret = egg_idletime_alarm_remove (idletime, 202);
+ if (!ret) {
+ egg_test_success (test, "ignored invalid alarm");
+ } else {
+ egg_test_failed (test, "removed invalid alarm");
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check if we can remove an valid alarm");
+ ret = egg_idletime_alarm_remove (idletime, 101);
+ if (ret) {
+ egg_test_success (test, "removed valid alarm");
+ } else {
+ egg_test_failed (test, "failed to remove valid alarm");
+ }
+
+ g_timer_destroy (timer);
+ g_object_unref (idletime);
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/egg-idletime.h b/src/egg-idletime.h
new file mode 100644
index 0000000..19b8ece
--- /dev/null
+++ b/src/egg-idletime.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_IDLETIME_H
+#define __EGG_IDLETIME_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EGG_IDLETIME_TYPE (egg_idletime_get_type ())
+#define EGG_IDLETIME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_IDLETIME_TYPE, EggIdletime))
+#define EGG_IDLETIME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_IDLETIME_TYPE, EggIdletimeClass))
+#define EGG_IS_IDLETIME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_IDLETIME_TYPE))
+#define EGG_IS_IDLETIME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_IDLETIME_TYPE))
+#define EGG_IDLETIME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_IDLETIME_TYPE, EggIdletimeClass))
+
+typedef struct EggIdletimePrivate EggIdletimePrivate;
+
+typedef struct
+{
+ GObject parent;
+ EggIdletimePrivate *priv;
+} EggIdletime;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* alarm_expired) (EggIdletime *idletime,
+ guint timer_id);
+ void (* reset) (EggIdletime *idletime);
+} EggIdletimeClass;
+
+GType egg_idletime_get_type (void);
+EggIdletime *egg_idletime_new (void);
+
+void egg_idletime_alarm_reset_all (EggIdletime *idletime);
+gboolean egg_idletime_alarm_set (EggIdletime *idletime,
+ guint alarm_id,
+ guint timeout);
+gboolean egg_idletime_alarm_remove (EggIdletime *idletime,
+ guint alarm_id);
+gint64 egg_idletime_get_time (EggIdletime *idletime);
+#ifdef EGG_TEST
+void egg_idletime_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __EGG_IDLETIME_H */
diff --git a/src/egg-precision.c b/src/egg-precision.c
new file mode 100644
index 0000000..02f0cce
--- /dev/null
+++ b/src/egg-precision.c
@@ -0,0 +1,193 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+
+#include "egg-debug.h"
+#include "egg-precision.h"
+
+/**
+ * egg_precision_round_up:
+ * @value: The input value
+ * @smallest: The smallest increment allowed
+ *
+ * 101, 10 110
+ * 95, 10 100
+ * 0, 10 0
+ * 112, 10 120
+ * 100, 10 100
+ **/
+gint
+egg_precision_round_up (gfloat value, gint smallest)
+{
+ gfloat division;
+ if (fabs (value) < 0.01)
+ return 0;
+ if (smallest == 0) {
+ egg_warning ("divisor zero");
+ return 0;
+ }
+ division = (gfloat) value / (gfloat) smallest;
+ division = ceilf (division);
+ division *= smallest;
+ return (gint) division;
+}
+
+/**
+ * egg_precision_round_down:
+ * @value: The input value
+ * @smallest: The smallest increment allowed
+ *
+ * 101, 10 100
+ * 95, 10 90
+ * 0, 10 0
+ * 112, 10 110
+ * 100, 10 100
+ **/
+gint
+egg_precision_round_down (gfloat value, gint smallest)
+{
+ gfloat division;
+ if (fabs (value) < 0.01)
+ return 0;
+ if (smallest == 0) {
+ egg_warning ("divisor zero");
+ return 0;
+ }
+ division = (gfloat) value / (gfloat) smallest;
+ division = floorf (division);
+ division *= smallest;
+ return (gint) division;
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+egg_precision_test (gpointer data)
+{
+ guint value;
+ EggTest *test = (EggTest *) data;
+
+ if (!egg_test_start (test, "EggPrecision"))
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "limit precision down 0,10");
+ value = egg_precision_round_down (0, 10);
+ if (value == 0) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision down 4,10");
+ value = egg_precision_round_down (4, 10);
+ if (value == 0) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision down 11,10");
+ value = egg_precision_round_down (11, 10);
+ if (value == 10) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision down 201,2");
+ value = egg_precision_round_down (201, 2);
+ if (value == 200) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision down 100,10");
+ value = egg_precision_round_down (100, 10);
+ if (value == 100) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision up 0,10");
+ value = egg_precision_round_up (0, 10);
+ if (value == 0) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision up 4,10");
+ value = egg_precision_round_up (4, 10);
+ if (value == 10) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision up 11,10");
+ value = egg_precision_round_up (11, 10);
+ if (value == 20) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision up 201,2");
+ value = egg_precision_round_up (201, 2);
+ if (value == 202) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "limit precision up 100,10");
+ value = egg_precision_round_up (100, 10);
+ if (value == 100) {
+ egg_test_success (test, "got %i", value);
+ } else {
+ egg_test_failed (test, "precision incorrect (%i)", value);
+ }
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/egg-precision.h b/src/egg-precision.h
new file mode 100644
index 0000000..aae8291
--- /dev/null
+++ b/src/egg-precision.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_PRECISION_H
+#define __EGG_PRECISION_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gint egg_precision_round_up (gfloat value,
+ gint smallest);
+gint egg_precision_round_down (gfloat value,
+ gint smallest);
+#ifdef EGG_TEST
+void egg_precision_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __EGG_PRECISION_H */
diff --git a/src/egg-string.c b/src/egg-string.c
new file mode 100644
index 0000000..204e6d9
--- /dev/null
+++ b/src/egg-string.c
@@ -0,0 +1,453 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * SECTION:pk-common
+ * @short_description: Common utility functions for PackageKit
+ *
+ * This file contains functions that may be useful.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib.h>
+
+#include "egg-debug.h"
+#include "egg-string.h"
+
+/**
+ * egg_strtoint:
+ * @text: The text the convert
+ * @value: The return numeric return value
+ *
+ * Converts a string into a signed integer value in a safe way.
+ *
+ * Return value: %TRUE if the string was converted correctly
+ **/
+gboolean
+egg_strtoint (const gchar *text, gint *value)
+{
+ gchar *endptr = NULL;
+ gint64 value_raw;
+
+ /* invalid */
+ if (text == NULL)
+ return FALSE;
+
+ /* parse */
+ value_raw = g_ascii_strtoll (text, &endptr, 10);
+
+ /* parsing error */
+ if (endptr == text)
+ return FALSE;
+
+ /* out of range */
+ if (value_raw > G_MAXINT || value_raw < G_MININT)
+ return FALSE;
+
+ /* cast back down to value */
+ *value = (gint) value_raw;
+ return TRUE;
+}
+
+/**
+ * egg_strtouint:
+ * @text: The text the convert
+ * @value: The return numeric return value
+ *
+ * Converts a string into a unsigned integer value in a safe way.
+ *
+ * Return value: %TRUE if the string was converted correctly
+ **/
+gboolean
+egg_strtouint (const gchar *text, guint *value)
+{
+ gchar *endptr = NULL;
+ guint64 value_raw;
+
+ /* invalid */
+ if (text == NULL)
+ return FALSE;
+
+ /* parse */
+ value_raw = g_ascii_strtoull (text, &endptr, 10);
+
+ /* parsing error */
+ if (endptr == text)
+ return FALSE;
+
+ /* out of range */
+ if (value_raw > G_MAXINT)
+ return FALSE;
+
+ /* cast back down to value */
+ *value = (guint) value_raw;
+ return TRUE;
+}
+
+/**
+ * egg_strzero:
+ * @text: The text to check
+ *
+ * This function is a much safer way of doing "if (strlen (text) == 0))"
+ * as it does not rely on text being NULL terminated. It's also much
+ * quicker as it only checks the first byte rather than scanning the whole
+ * string just to verify it's not zero length.
+ *
+ * Return value: %TRUE if the string was converted correctly
+ **/
+gboolean
+egg_strzero (const gchar *text)
+{
+ if (text == NULL)
+ return TRUE;
+ if (text[0] == '\0')
+ return TRUE;
+ return FALSE;
+}
+
+/**
+ * egg_strlen:
+ * @text: The text to check
+ * @len: The maximum length of the string
+ *
+ * This function is a much safer way of doing strlen as it checks for NULL and
+ * a stupidly long string.
+ *
+ * Return value: the length of the string, or len if the string is too long.
+ **/
+guint
+egg_strlen (const gchar *text, guint len)
+{
+ guint i;
+
+ /* common case */
+ if (text == NULL || text[0] == '\0')
+ return 0;
+
+ /* only count up to len */
+ for (i=1; i<len; i++) {
+ if (text[i] == '\0')
+ break;
+ }
+ return i;
+}
+
+/**
+ * egg_strvequal:
+ * @id1: the first item of text to test
+ * @id2: the second item of text to test
+ *
+ * This function will check to see if the GStrv arrays are string equal
+ *
+ * Return value: %TRUE if the arrays are the same, or are both %NULL
+ **/
+gboolean
+egg_strvequal (gchar **id1, gchar **id2)
+{
+ guint i;
+ guint length1;
+ guint length2;
+
+ if (id1 == NULL && id2 == NULL)
+ return TRUE;
+
+ if (id1 == NULL || id2 == NULL) {
+ egg_debug ("GStrv compare invalid '%p' and '%p'", id1, id2);
+ return FALSE;
+ }
+
+ /* check different sizes */
+ length1 = g_strv_length (id1);
+ length2 = g_strv_length (id2);
+ if (length1 != length2)
+ return FALSE;
+
+ /* text equal each one */
+ for (i=0; i<length1; i++) {
+ if (g_strcmp0 (id1[i], id2[i]) != 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * egg_strreplace:
+ * @text: The input text to make safe
+ * @find: What to search for
+ * @replace: What to replace with
+ *
+ * Replaces chars in the text with a replacement.
+ * The %find and %replace variables to not have to be of the same length
+ *
+ * Return value: the new string (copied)
+ **/
+gchar *
+egg_strreplace (const gchar *text, const gchar *find, const gchar *replace)
+{
+ gchar **array;
+ gchar *retval;
+
+ /* common case, not found */
+ if (strstr (text, find) == NULL) {
+ return g_strdup (text);
+ }
+
+ /* split apart and rejoin with new delimiter */
+ array = g_strsplit (text, find, 0);
+ retval = g_strjoinv (replace, array);
+ g_strfreev (array);
+ return retval;
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+egg_string_test (EggTest *test)
+{
+ gboolean ret;
+ gchar *text_safe;
+ const gchar *temp;
+ guint length;
+ gint value;
+ guint uvalue;
+ gchar **id1;
+ gchar **id2;
+
+ if (!egg_test_start (test, "EggString"))
+ return;
+
+ /************************************************************
+ **************** String array equal ******************
+ ************************************************************/
+ egg_test_title (test, "egg_strvequal same argument");
+ id1 = g_strsplit ("the quick brown fox", " ", 0);
+ if (egg_strvequal (id1, id1))
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "incorrect ret when both same");
+ g_strfreev (id1);
+
+ /************************************************************/
+ egg_test_title (test, "egg_strvequal same");
+ id1 = g_strsplit ("the quick brown fox", " ", 0);
+ id2 = g_strsplit ("the quick brown fox", " ", 0);
+ if (egg_strvequal (id1, id2))
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "incorrect ret when both same");
+ g_strfreev (id1);
+ g_strfreev (id2);
+
+ /************************************************************/
+ egg_test_title (test, "egg_strvequal different lengths");
+ id1 = g_strsplit ("the quick brown", " ", 0);
+ id2 = g_strsplit ("the quick brown fox", " ", 0);
+ if (!egg_strvequal (id1, id2))
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "incorrect ret when both same");
+ g_strfreev (id1);
+ g_strfreev (id2);
+
+ /************************************************************/
+ egg_test_title (test, "egg_strvequal different");
+ id1 = g_strsplit ("the quick brown fox", " ", 0);
+ id2 = g_strsplit ("richard hughes maintainer dude", " ", 0);
+ if (!egg_strvequal (id1, id2))
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "same when different");
+ g_strfreev (id1);
+ g_strfreev (id2);
+
+ /************************************************************
+ **************** Zero ******************
+ ************************************************************/
+ temp = NULL;
+ egg_test_title (test, "test strzero (null)");
+ ret = egg_strzero (NULL);
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed null");
+
+ /************************************************************/
+ egg_test_title (test, "test strzero (null first char)");
+ ret = egg_strzero ("");
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed null");
+
+ /************************************************************/
+ egg_test_title (test, "test strzero (long string)");
+ ret = egg_strzero ("Richard");
+ if (!ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "zero length word!");
+
+ /************************************************************/
+ egg_test_title (test, "id strcmp pass");
+ ret = (g_strcmp0 ("moo;0.0.1;i386;fedora", "moo;0.0.1;i386;fedora") == 0);
+ egg_test_assert (test, ret);
+
+ /************************************************************/
+ egg_test_title (test, "id strcmp fail");
+ ret = (g_strcmp0 ("moo;0.0.1;i386;fedora", "moo;0.0.2;i386;fedora") == 0);
+ egg_test_assert (test, !ret);
+
+ /************************************************************
+ **************** strlen ******************
+ ************************************************************/
+ egg_test_title (test, "strlen bigger");
+ length = egg_strlen ("123456789", 20);
+ if (length == 9)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the strlen %i", length);
+
+ /************************************************************/
+ egg_test_title (test, "strlen smaller");
+ length = egg_strlen ("123456789", 5);
+ if (length == 5)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the strlen %i", length);
+
+ /************************************************************/
+ egg_test_title (test, "strlen correct");
+ length = egg_strlen ("123456789", 9);
+ if (length == 9)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the strlen %i", length);
+
+ /************************************************************
+ **************** Replace ******************
+ ************************************************************/
+ egg_test_title (test, "replace start");
+ text_safe = egg_strreplace ("richard\nhughes", "r", "e");
+ if (g_strcmp0 (text_safe, "eichaed\nhughes") == 0)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the replace '%s'", text_safe);
+ g_free (text_safe);
+
+ /************************************************************/
+ egg_test_title (test, "replace none");
+ text_safe = egg_strreplace ("richard\nhughes", "dave", "e");
+ if (g_strcmp0 (text_safe, "richard\nhughes") == 0)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the replace '%s'", text_safe);
+ g_free (text_safe);
+
+ /************************************************************/
+ egg_test_title (test, "replace end");
+ text_safe = egg_strreplace ("richard\nhughes", "s", "e");
+ if (g_strcmp0 (text_safe, "richard\nhughee") == 0)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the replace '%s'", text_safe);
+ g_free (text_safe);
+
+ /************************************************************/
+ egg_test_title (test, "replace unicode");
+ text_safe = egg_strreplace ("richard\n- hughes", "\n- ", "\n• ");
+ if (g_strcmp0 (text_safe, "richard\n• hughes") == 0)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed the replace '%s'", text_safe);
+ g_free (text_safe);
+
+ /************************************************************
+ ************** Convert numbers ****************
+ ************************************************************/
+ egg_test_title (test, "convert valid number");
+ ret = egg_strtoint ("234", &value);
+ if (ret && value == 234)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "value is %i", value);
+
+ /************************************************************/
+ egg_test_title (test, "convert negative valid number");
+ ret = egg_strtoint ("-234", &value);
+ if (ret && value == -234)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "value is %i", value);
+
+ /************************************************************/
+ egg_test_title (test, "don't convert invalid number");
+ ret = egg_strtoint ("dave", &value);
+ if (!ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "value is %i", value);
+
+ /************************************************************/
+ egg_test_title (test, "convert NULL to a number");
+ ret = egg_strtouint (NULL, &uvalue);
+ if (!ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "value is %i", uvalue);
+
+ /************************************************************/
+ egg_test_title (test, "convert valid uint number");
+ ret = egg_strtouint ("234", &uvalue);
+ if (ret && uvalue == 234)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "value is %i", uvalue);
+
+ /************************************************************/
+ egg_test_title (test, "convert invalid uint number");
+ ret = egg_strtouint ("-234", &uvalue);
+ if (ret == FALSE)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "value is %i", uvalue);
+
+ egg_test_end (test);
+}
+#endif
+
diff --git a/src/egg-string.h b/src/egg-string.h
new file mode 100644
index 0000000..6b8e097
--- /dev/null
+++ b/src/egg-string.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_STRING_H
+#define __EGG_STRING_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+guint egg_strlen (const gchar *text,
+ guint len)
+ G_GNUC_WARN_UNUSED_RESULT;
+gboolean egg_strzero (const gchar *text)
+ G_GNUC_WARN_UNUSED_RESULT;
+gboolean egg_strvequal (gchar **id1,
+ gchar **id2)
+ G_GNUC_WARN_UNUSED_RESULT;
+gboolean egg_strtoint (const gchar *text,
+ gint *value);
+gboolean egg_strtouint (const gchar *text,
+ guint *value);
+gchar *egg_strreplace (const gchar *text,
+ const gchar *find,
+ const gchar *replace);
+
+G_END_DECLS
+
+#endif /* __EGG_STRING_H */
diff --git a/src/egg-test.c b/src/egg-test.c
new file mode 100644
index 0000000..996d017
--- /dev/null
+++ b/src/egg-test.c
@@ -0,0 +1,343 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+#include <string.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+
+#include "egg-test.h"
+
+struct EggTest {
+ guint total;
+ guint succeeded;
+ gboolean started;
+ gboolean titled;
+ gchar *type;
+ GTimer *timer;
+ GMainLoop *loop;
+ guint hang_loop_id;
+ gpointer user_data;
+};
+
+/**
+ * egg_test_init:
+ **/
+EggTest *
+egg_test_init ()
+{
+ EggTest *test;
+ test = g_new (EggTest, 1);
+ test->total = 0;
+ test->succeeded = 0;
+ test->type = NULL;
+ test->started = FALSE;
+ test->titled = FALSE;
+ test->timer = g_timer_new ();
+ test->loop = g_main_loop_new (NULL, FALSE);
+ test->hang_loop_id = 0;
+ return test;
+}
+
+/**
+ * egg_test_loop_quit:
+ **/
+void
+egg_test_loop_quit (EggTest *test)
+{
+ /* disable the loop watch */
+ if (test->hang_loop_id != 0) {
+ g_source_remove (test->hang_loop_id);
+ test->hang_loop_id = 0;
+ }
+ g_main_loop_quit (test->loop);
+}
+
+/**
+ * egg_test_hang_check:
+ **/
+static gboolean
+egg_test_hang_check (gpointer data)
+{
+ EggTest *test = (EggTest *) data;
+ g_main_loop_quit (test->loop);
+ return FALSE;
+}
+
+/**
+ * egg_test_loop_wait:
+ **/
+void
+egg_test_loop_wait (EggTest *test, guint timeout)
+{
+ test->hang_loop_id = g_timeout_add (timeout, egg_test_hang_check, test);
+ g_main_loop_run (test->loop);
+}
+
+/**
+ * egg_test_loop_check:
+ **/
+void
+egg_test_loop_check (EggTest *test)
+{
+ guint elapsed = egg_test_elapsed (test);
+ egg_test_title (test, "did we timeout out of the loop");
+ if (test->hang_loop_id == 0) {
+ egg_test_success (test, "loop blocked for %ims", elapsed);
+ } else {
+ egg_test_failed (test, "hangcheck saved us after %ims", elapsed);
+ }
+}
+
+/**
+ * egg_test_set_user_data:
+ **/
+void
+egg_test_set_user_data (EggTest *test, gpointer user_data)
+{
+ test->user_data = user_data;
+}
+
+/**
+ * egg_test_get_user_data:
+ **/
+gpointer
+egg_test_get_user_data (EggTest *test)
+{
+ return test->user_data;
+}
+
+/**
+ * egg_test_finish:
+ **/
+gint
+egg_test_finish (EggTest *test)
+{
+ gint retval;
+ g_print ("test passes (%u/%u) : ", test->succeeded, test->total);
+ if (test->succeeded == test->total) {
+ g_print ("ALL OKAY\n");
+ retval = 0;
+ } else {
+ g_print ("%u FAILURE(S)\n", test->total - test->succeeded);
+ retval = 1;
+ }
+
+ g_timer_destroy (test->timer);
+ g_main_loop_unref (test->loop);
+ g_free (test);
+
+ return retval;
+}
+
+/**
+ * egg_test_elapsed:
+ *
+ * Returns: time in ms
+ **/
+guint
+egg_test_elapsed (EggTest *test)
+{
+ gdouble time_s;
+ time_s = g_timer_elapsed (test->timer, NULL);
+ return (guint) (time_s * 1000.0f);
+}
+
+/**
+ * egg_test_start:
+ **/
+gboolean
+egg_test_start (EggTest *test, const gchar *name)
+{
+ if (test->started) {
+ g_print ("Not ended test! Cannot start!\n");
+ exit (1);
+ }
+ test->type = g_strdup (name);
+ test->started = TRUE;
+ return TRUE;
+}
+
+/**
+ * egg_test_end:
+ **/
+void
+egg_test_end (EggTest *test)
+{
+ if (test->started == FALSE) {
+ g_print ("Not started test! Cannot finish!\n");
+ exit (1);
+ }
+ g_print ("OK\n");
+
+ /* disable hang check */
+ if (test->hang_loop_id != 0) {
+ g_source_remove (test->hang_loop_id);
+ test->hang_loop_id = 0;
+ }
+
+ test->started = FALSE;
+ g_free (test->type);
+}
+
+/**
+ * egg_test_title:
+ **/
+void
+egg_test_title (EggTest *test, const gchar *format, ...)
+{
+ va_list args;
+ gchar *va_args_buffer = NULL;
+
+ /* already titled? */
+ if (test->titled) {
+ g_print ("Already titled!\n");
+ exit (1);
+ }
+
+ /* reset the value egg_test_elapsed replies with */
+ g_timer_reset (test->timer);
+
+ va_start (args, format);
+ g_vasprintf (&va_args_buffer, format, args);
+ va_end (args);
+ g_print ("> check #%u\t%s: \t%s...", test->total+1, test->type, va_args_buffer);
+ g_free (va_args_buffer);
+
+ test->titled = TRUE;
+ test->total++;
+}
+
+/**
+ * egg_test_success:
+ **/
+void
+egg_test_success (EggTest *test, const gchar *format, ...)
+{
+ va_list args;
+ gchar *va_args_buffer = NULL;
+
+ /* not titled? */
+ if (!test->titled) {
+ g_print ("Not titled!\n");
+ exit (1);
+ }
+ if (format == NULL) {
+ g_print ("...OK\n");
+ goto finish;
+ }
+ va_start (args, format);
+ g_vasprintf (&va_args_buffer, format, args);
+ va_end (args);
+ g_print ("...OK [%s]\n", va_args_buffer);
+ g_free (va_args_buffer);
+finish:
+ test->titled = FALSE;
+ test->succeeded++;
+}
+
+/**
+ * egg_test_failed:
+ **/
+void
+egg_test_failed (EggTest *test, const gchar *format, ...)
+{
+ va_list args;
+ gchar *va_args_buffer = NULL;
+
+ /* not titled? */
+ if (!test->titled) {
+ g_print ("Not titled!\n");
+ exit (1);
+ }
+ if (format == NULL) {
+ g_print ("FAILED\n");
+ goto failed;
+ }
+ va_start (args, format);
+ g_vasprintf (&va_args_buffer, format, args);
+ va_end (args);
+ g_print ("FAILED [%s]\n", va_args_buffer);
+ g_free (va_args_buffer);
+failed:
+ exit (1);
+}
+
+/**
+ * egg_test_assert:
+ **/
+void
+egg_test_assert (EggTest *test, gboolean value)
+{
+ if (value)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, NULL);
+}
+
+/**
+ * egg_test_title_assert:
+ **/
+void
+egg_test_title_assert (EggTest *test, const gchar *text, gboolean value)
+{
+ egg_test_title (test, "%s", text);
+ if (value)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, NULL);
+}
+
+/**
+ * egg_test_get_data_file:
+ **/
+gchar *
+egg_test_get_data_file (const gchar *filename)
+{
+ gboolean ret;
+ gchar *full;
+
+ /* check to see if we are being run in the build root */
+ full = g_build_filename ("..", "data", "tests", filename, NULL);
+ ret = g_file_test (full, G_FILE_TEST_EXISTS);
+ if (ret)
+ return full;
+ g_free (full);
+
+ /* check to see if we are being run in the build root */
+ full = g_build_filename ("..", "..", "data", "tests", filename, NULL);
+ ret = g_file_test (full, G_FILE_TEST_EXISTS);
+ if (ret)
+ return full;
+ g_free (full);
+
+ /* check to see if we are being run in make check */
+ full = g_build_filename ("..", "..", "..", "data", "tests", filename, NULL);
+ ret = g_file_test (full, G_FILE_TEST_EXISTS);
+ if (ret)
+ return full;
+ g_print ("[WARN] failed to find '%s'\n", full);
+ g_free (full);
+ return NULL;
+}
+
diff --git a/src/egg-test.h b/src/egg-test.h
new file mode 100644
index 0000000..1b05092
--- /dev/null
+++ b/src/egg-test.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_TEST_H
+#define __EGG_TEST_H
+
+#include <glib.h>
+#include <string.h>
+
+typedef struct EggTest EggTest;
+
+gboolean egg_test_start (EggTest *test, const gchar *name);
+void egg_test_end (EggTest *test);
+void egg_test_title (EggTest *test, const gchar *format, ...);
+void egg_test_title_assert (EggTest *test, const gchar *text, gboolean value);
+void egg_test_assert (EggTest *test, gboolean value);
+void egg_test_success (EggTest *test, const gchar *format, ...);
+void egg_test_failed (EggTest *test, const gchar *format, ...) G_GNUC_NORETURN;
+EggTest *egg_test_init (void);
+gint egg_test_finish (EggTest *test);
+guint egg_test_elapsed (EggTest *test);
+void egg_test_loop_quit (EggTest *test);
+void egg_test_loop_wait (EggTest *test, guint timeout);
+void egg_test_loop_check (EggTest *test);
+void egg_test_set_user_data (EggTest *test, gpointer user_data);
+gpointer egg_test_get_user_data (EggTest *test);
+gchar *egg_test_get_data_file (const gchar *filename);
+
+#endif /* __EGG_TEST_H */
+
diff --git a/src/egg-unique.c b/src/egg-unique.c
new file mode 100644
index 0000000..41a5182
--- /dev/null
+++ b/src/egg-unique.c
@@ -0,0 +1,151 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <unique/unique.h>
+
+#include "egg-unique.h"
+#include "egg-debug.h"
+
+static void egg_unique_finalize (GObject *object);
+
+#define EGG_UNIQUE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_UNIQUE_TYPE, EggUniquePrivate))
+
+struct EggUniquePrivate
+{
+ UniqueApp *uniqueapp;
+};
+
+enum {
+ ACTIVATED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (EggUnique, egg_unique, G_TYPE_OBJECT)
+
+/**
+ * egg_unique_message_cb:
+ **/
+static void
+egg_unique_message_cb (UniqueApp *app, UniqueCommand command, UniqueMessageData *message_data, guint time_s, EggUnique *egg_unique)
+{
+ g_return_if_fail (EGG_IS_UNIQUE (egg_unique));
+ if (command == UNIQUE_ACTIVATE)
+ g_signal_emit (egg_unique, signals [ACTIVATED], 0);
+}
+
+/**
+ * egg_unique_assign:
+ * @egg_unique: This class instance
+ * @service: The service name
+ * Return value: %FALSE if we should exit as another instance is running
+ **/
+gboolean
+egg_unique_assign (EggUnique *egg_unique, const gchar *service)
+{
+ g_return_val_if_fail (EGG_IS_UNIQUE (egg_unique), FALSE);
+ g_return_val_if_fail (service != NULL, FALSE);
+
+ if (egg_unique->priv->uniqueapp != NULL) {
+ g_warning ("already assigned!");
+ return FALSE;
+ }
+
+ /* check to see if the user has another instance open */
+ egg_unique->priv->uniqueapp = unique_app_new (service, NULL);
+ if (unique_app_is_running (egg_unique->priv->uniqueapp)) {
+ egg_debug ("You have another instance running. This program will now close");
+ unique_app_send_message (egg_unique->priv->uniqueapp, UNIQUE_ACTIVATE, NULL);
+ return FALSE;
+ }
+
+ /* Listen for messages from another instances */
+ g_signal_connect (G_OBJECT (egg_unique->priv->uniqueapp), "message-received",
+ G_CALLBACK (egg_unique_message_cb), egg_unique);
+ return TRUE;
+}
+
+/**
+ * egg_unique_class_init:
+ * @egg_unique: This class instance
+ **/
+static void
+egg_unique_class_init (EggUniqueClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = egg_unique_finalize;
+ g_type_class_add_private (klass, sizeof (EggUniquePrivate));
+
+ signals [ACTIVATED] =
+ g_signal_new ("activated",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EggUniqueClass, activated),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * egg_unique_init:
+ * @egg_unique: This class instance
+ **/
+static void
+egg_unique_init (EggUnique *egg_unique)
+{
+ egg_unique->priv = EGG_UNIQUE_GET_PRIVATE (egg_unique);
+ egg_unique->priv->uniqueapp = NULL;
+}
+
+/**
+ * egg_unique_finalize:
+ * @object: This class instance
+ **/
+static void
+egg_unique_finalize (GObject *object)
+{
+ EggUnique *egg_unique;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (EGG_IS_UNIQUE (object));
+
+ egg_unique = EGG_UNIQUE_OBJECT (object);
+ egg_unique->priv = EGG_UNIQUE_GET_PRIVATE (egg_unique);
+
+ if (egg_unique->priv->uniqueapp != NULL)
+ g_object_unref (egg_unique->priv->uniqueapp);
+ G_OBJECT_CLASS (egg_unique_parent_class)->finalize (object);
+}
+
+/**
+ * egg_unique_new:
+ * Return value: new class instance.
+ **/
+EggUnique *
+egg_unique_new (void)
+{
+ EggUnique *egg_unique;
+ egg_unique = g_object_new (EGG_UNIQUE_TYPE, NULL);
+ return EGG_UNIQUE_OBJECT (egg_unique);
+}
+
diff --git a/src/egg-unique.h b/src/egg-unique.h
new file mode 100644
index 0000000..7259135
--- /dev/null
+++ b/src/egg-unique.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __EGG_UNIQUE_H
+#define __EGG_UNIQUE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EGG_UNIQUE_TYPE (egg_unique_get_type ())
+#define EGG_UNIQUE_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_UNIQUE_TYPE, EggUnique))
+#define EGG_UNIQUE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EGG_UNIQUE_TYPE, EggUniqueClass))
+#define EGG_IS_UNIQUE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_UNIQUE_TYPE))
+#define EGG_IS_UNIQUE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EGG_UNIQUE_TYPE))
+#define EGG_UNIQUE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EGG_UNIQUE_TYPE, EggUniqueClass))
+
+typedef struct EggUniquePrivate EggUniquePrivate;
+
+typedef struct
+{
+ GObject parent;
+ EggUniquePrivate *priv;
+} EggUnique;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* activated) (EggUnique *unique);
+} EggUniqueClass;
+
+GType egg_unique_get_type (void);
+EggUnique *egg_unique_new (void);
+
+gboolean egg_unique_assign (EggUnique *unique,
+ const gchar *service);
+
+G_END_DECLS
+
+#endif /* __EGG_UNIQUE_H */
+
diff --git a/src/gpm-backlight-helper.c b/src/gpm-backlight-helper.c
new file mode 100644
index 0000000..4868446
--- /dev/null
+++ b/src/gpm-backlight-helper.c
@@ -0,0 +1,280 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS 0
+#define GCM_BACKLIGHT_HELPER_EXIT_CODE_FAILED 1
+#define GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID 3
+#define GCM_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER 4
+
+#define GCM_BACKLIGHT_HELPER_SYSFS_LOCATION "/sys/class/backlight"
+
+/**
+ * gcm_backlight_helper_get_best_backlight:
+ **/
+static gchar *
+gcm_backlight_helper_get_best_backlight ()
+{
+ gchar *filename;
+ guint i;
+ gboolean ret;
+ GDir *dir = NULL;
+ GError *error = NULL;
+ const gchar *first_device;
+
+ /* available kernel interfaces in priority order */
+ static const gchar *backlight_interfaces[] = {
+ "nv_backlight",
+ "asus_laptop",
+ "toshiba",
+ "eeepc",
+ "thinkpad_screen",
+ "acpi_video1",
+ "mbp_backlight",
+ "acpi_video0",
+ "fujitsu-laptop",
+ "sony",
+ "samsung",
+ NULL,
+ };
+
+ /* search each one */
+ for (i=0; backlight_interfaces[i] != NULL; i++) {
+ filename = g_build_filename (GCM_BACKLIGHT_HELPER_SYSFS_LOCATION,
+ backlight_interfaces[i], NULL);
+ ret = g_file_test (filename, G_FILE_TEST_EXISTS);
+ if (ret)
+ goto out;
+ g_free (filename);
+ }
+
+ /* nothing found in the ordered list */
+ filename = NULL;
+
+ /* find any random ones */
+ dir = g_dir_open (GCM_BACKLIGHT_HELPER_SYSFS_LOCATION, 0, &error);
+ if (dir == NULL) {
+ g_warning ("failed to find any devices: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get first device if any */
+ first_device = g_dir_read_name (dir);
+ if (first_device != NULL) {
+ filename = g_build_filename (GCM_BACKLIGHT_HELPER_SYSFS_LOCATION,
+ first_device, NULL);
+ }
+out:
+ if (dir != NULL)
+ g_dir_close (dir);
+ return filename;
+}
+
+/**
+ * gcm_backlight_helper_write:
+ **/
+static gboolean
+gcm_backlight_helper_write (const gchar *filename, gint value, GError **error)
+{
+ gchar *text = NULL;
+ gint retval;
+ gint length;
+ gint fd = -1;
+ gboolean ret = TRUE;
+
+ fd = open (filename, O_WRONLY);
+ if (fd < 0) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "failed to open filename: %s", filename);
+ goto out;
+ }
+
+ /* convert to text */
+ text = g_strdup_printf ("%i", value);
+ length = strlen (text);
+
+ /* write to device file */
+ retval = write (fd, text, length);
+ if (retval != length) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "writing '%s' to %s failed", text, filename);
+ goto out;
+ }
+out:
+ if (fd >= 0)
+ close (fd);
+ g_free (text);
+ return ret;
+}
+
+/**
+ * main:
+ **/
+gint
+main (gint argc, gchar *argv[])
+{
+ GOptionContext *context;
+ gint uid;
+ gint euid;
+ guint retval = 0;
+ const gchar *pkexec_uid_str;
+ GError *error = NULL;
+ gboolean ret = FALSE;
+ gint set_brightness = -1;
+ gboolean get_brightness = FALSE;
+ gboolean get_max_brightness = FALSE;
+ gchar *filename = NULL;
+ gchar *filename_file = NULL;
+ gchar *contents = NULL;
+
+ const GOptionEntry options[] = {
+ { "set-brightness", '\0', 0, G_OPTION_ARG_INT, &set_brightness,
+ /* command line argument */
+ _("Set the current brightness"), NULL },
+ { "get-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_brightness,
+ /* command line argument */
+ _("Get the current brightness"), NULL },
+ { "get-max-brightness", '\0', 0, G_OPTION_ARG_NONE, &get_max_brightness,
+ /* command line argument */
+ _("Get the number of brightness levels supported"), NULL },
+ { NULL}
+ };
+
+ /* setup translations */
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ /* setup type system */
+ g_type_init ();
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: tool that is used when copying profiles system-wide */
+ g_option_context_set_summary (context, _("MATE Power Manager Backlight Helper"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ /* no input */
+ if (set_brightness == -1 && !get_brightness && !get_max_brightness) {
+ /* TRANSLATORS: user did not specify valid options */
+ g_print ("%s\n", _("No valid option was specified"));
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* find device */
+ filename = gcm_backlight_helper_get_best_backlight ();
+ if (filename == NULL) {
+ /* TRANSLATORS: no backlights found */
+ g_print ("%s\n", _("No backlights were found on your system"));
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER;
+ goto out;
+ }
+
+ /* GetBrightness */
+ if (get_brightness) {
+ filename_file = g_build_filename (filename, "brightness", NULL);
+ ret = g_file_get_contents (filename_file, &contents, NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: failed to access backlight file */
+ g_print ("%s: %s\n", _("Could not get the value of the backlight"), error->message);
+ g_error_free (error);
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* just print the contents to stdout */
+ g_print ("%s", contents);
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS;
+ goto out;
+ }
+
+ /* GetSteps */
+ if (get_max_brightness) {
+ filename_file = g_build_filename (filename, "max_brightness", NULL);
+ ret = g_file_get_contents (filename_file, &contents, NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: failed to access backlight file */
+ g_print ("%s: %s\n", _("Could not get the maximum value of the backlight"), error->message);
+ g_error_free (error);
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* just print the contents to stdout */
+ g_print ("%s", contents);
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS;
+ goto out;
+ }
+
+ /* get calling process */
+ uid = getuid ();
+ euid = geteuid ();
+ if (uid != 0 || euid != 0) {
+ /* TRANSLATORS: only able to install profiles as root */
+ g_print ("%s\n", _("This program can only be used by the root user"));
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+
+ /* check we're not being spoofed */
+ pkexec_uid_str = g_getenv ("PKEXEC_UID");
+ if (pkexec_uid_str == NULL) {
+ /* TRANSLATORS: the program must never be directly run */
+ g_print ("%s\n", _("This program must only be run through pkexec"));
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_INVALID_USER;
+ goto out;
+ }
+
+ /* SetBrightness */
+ if (set_brightness != -1) {
+ filename_file = g_build_filename (filename, "brightness", NULL);
+ ret = gcm_backlight_helper_write (filename_file, set_brightness, &error);
+ if (!ret) {
+ /* TRANSLATORS: failed to access backlight file */
+ g_print ("%s: %s\n", _("Could not set the value of the backlight"), error->message);
+ g_error_free (error);
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_ARGUMENTS_INVALID;
+ goto out;
+ }
+ }
+
+ /* success */
+ retval = GCM_BACKLIGHT_HELPER_EXIT_CODE_SUCCESS;
+out:
+ g_free (filename);
+ g_free (filename_file);
+ g_free (contents);
+ return retval;
+}
+
diff --git a/src/gpm-backlight.c b/src/gpm-backlight.c
new file mode 100644
index 0000000..c0479fd
--- /dev/null
+++ b/src/gpm-backlight.c
@@ -0,0 +1,821 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2009 Richard Hughes <[email protected]>
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <math.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <mateconf/mateconf-client.h>
+#include <libupower-glib/upower.h>
+
+#include "gpm-button.h"
+#include "gpm-backlight.h"
+#include "gpm-brightness.h"
+#include "gpm-control.h"
+#include "gpm-common.h"
+#include "egg-debug.h"
+#include "gsd-media-keys-window.h"
+#include "gpm-dpms.h"
+#include "gpm-idle.h"
+#include "gpm-marshal.h"
+#include "gpm-stock-icons.h"
+#include "gpm-prefs-server.h"
+#include "egg-console-kit.h"
+
+#define GPM_BACKLIGHT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_BACKLIGHT, GpmBacklightPrivate))
+
+struct GpmBacklightPrivate
+{
+ UpClient *client;
+ GpmBrightness *brightness;
+ GpmButton *button;
+ MateConfClient *conf;
+ GtkWidget *popup;
+ GpmControl *control;
+ GpmDpms *dpms;
+ GpmIdle *idle;
+ EggConsoleKit *consolekit;
+ gboolean can_dim;
+ gboolean system_is_idle;
+ GTimer *idle_timer;
+ guint idle_dim_timeout;
+ guint master_percentage;
+};
+
+enum {
+ BRIGHTNESS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GpmBacklight, gpm_backlight, G_TYPE_OBJECT)
+
+/**
+ * gpm_backlight_error_quark:
+ * Return value: Our personal error quark.
+ **/
+GQuark
+gpm_backlight_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("gpm_backlight_error");
+ return quark;
+}
+
+/**
+ * gpm_backlight_get_brightness:
+ **/
+gboolean
+gpm_backlight_get_brightness (GpmBacklight *backlight, guint *brightness, GError **error)
+{
+ guint level;
+ gboolean ret;
+ g_return_val_if_fail (backlight != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_BACKLIGHT (backlight), FALSE);
+ g_return_val_if_fail (brightness != NULL, FALSE);
+
+ /* check if we have the hw */
+ if (backlight->priv->can_dim == FALSE) {
+ g_set_error_literal (error, gpm_backlight_error_quark (),
+ GPM_BACKLIGHT_ERROR_HARDWARE_NOT_PRESENT,
+ "Dim capable hardware not present");
+ return FALSE;
+ }
+
+ /* gets the current brightness */
+ ret = gpm_brightness_get (backlight->priv->brightness, &level);
+ if (ret) {
+ *brightness = level;
+ } else {
+ g_set_error_literal (error, gpm_backlight_error_quark (),
+ GPM_BACKLIGHT_ERROR_DATA_NOT_AVAILABLE,
+ "Data not available");
+ }
+ return ret;
+}
+
+/**
+ * gpm_backlight_set_brightness:
+ **/
+gboolean
+gpm_backlight_set_brightness (GpmBacklight *backlight, guint percentage, GError **error)
+{
+ gboolean ret;
+ gboolean hw_changed;
+
+ g_return_val_if_fail (backlight != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_BACKLIGHT (backlight), FALSE);
+
+ /* check if we have the hw */
+ if (backlight->priv->can_dim == FALSE) {
+ g_set_error_literal (error, gpm_backlight_error_quark (),
+ GPM_BACKLIGHT_ERROR_HARDWARE_NOT_PRESENT,
+ "Dim capable hardware not present");
+ return FALSE;
+ }
+
+ /* just set the master percentage for now, don't try to be clever */
+ backlight->priv->master_percentage = percentage;
+
+ /* sets the current policy brightness */
+ ret = gpm_brightness_set (backlight->priv->brightness, percentage, &hw_changed);
+ if (!ret) {
+ g_set_error_literal (error, gpm_backlight_error_quark (),
+ GPM_BACKLIGHT_ERROR_GENERAL,
+ "Cannot set policy brightness");
+ }
+ /* we emit a signal for the brightness applet */
+ if (ret && hw_changed) {
+ egg_debug ("emitting brightness-changed : %i", percentage);
+ g_signal_emit (backlight, signals [BRIGHTNESS_CHANGED], 0, percentage);
+ }
+ return ret;
+}
+
+/**
+ * gpm_backlight_dialog_init:
+ *
+ * Initialises the popup, and makes sure that it matches the compositing of the screen.
+ **/
+static void
+gpm_backlight_dialog_init (GpmBacklight *backlight)
+{
+ if (backlight->priv->popup != NULL
+ && !gsd_media_keys_window_is_valid (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup))) {
+ gtk_widget_destroy (backlight->priv->popup);
+ backlight->priv->popup = NULL;
+ }
+
+ if (backlight->priv->popup == NULL) {
+ backlight->priv->popup= gsd_media_keys_window_new ();
+ gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup),
+ "gpm-brightness-lcd",
+ TRUE);
+ gtk_window_set_position (GTK_WINDOW (backlight->priv->popup), GTK_WIN_POS_NONE);
+ }
+}
+
+/**
+ * gpm_backlight_dialog_show:
+ *
+ * Show the brightness popup, and place it nicely on the screen.
+ **/
+static void
+gpm_backlight_dialog_show (GpmBacklight *backlight)
+{
+ int orig_w;
+ int orig_h;
+ int screen_w;
+ int screen_h;
+ int x;
+ int y;
+ int pointer_x;
+ int pointer_y;
+ GtkRequisition win_req;
+ GdkScreen *pointer_screen;
+ GdkRectangle geometry;
+ int monitor;
+
+ /*
+ * get the window size
+ * if the window hasn't been mapped, it doesn't necessarily
+ * know its true size, yet, so we need to jump through hoops
+ */
+ gtk_window_get_default_size (GTK_WINDOW (backlight->priv->popup), &orig_w, &orig_h);
+ gtk_widget_size_request (backlight->priv->popup, &win_req);
+
+ if (win_req.width > orig_w) {
+ orig_w = win_req.width;
+ }
+ if (win_req.height > orig_h) {
+ orig_h = win_req.height;
+ }
+
+ pointer_screen = NULL;
+ gdk_display_get_pointer (gtk_widget_get_display (backlight->priv->popup),
+ &pointer_screen,
+ &pointer_x,
+ &pointer_y,
+ NULL);
+ monitor = gdk_screen_get_monitor_at_point (pointer_screen,
+ pointer_x,
+ pointer_y);
+
+ gdk_screen_get_monitor_geometry (pointer_screen,
+ monitor,
+ &geometry);
+
+ screen_w = geometry.width;
+ screen_h = geometry.height;
+
+ x = ((screen_w - orig_w) / 2) + geometry.x;
+ y = geometry.y + (screen_h / 2) + (screen_h / 2 - orig_h) / 2;
+
+ gtk_window_move (GTK_WINDOW (backlight->priv->popup), x, y);
+
+ gtk_widget_show (backlight->priv->popup);
+
+ gdk_display_sync (gtk_widget_get_display (backlight->priv->popup));
+}
+
+/**
+ * gpm_common_sum_scale:
+ *
+ * Finds the average between value1 and value2 set on a scale factor
+ **/
+inline static gfloat
+gpm_common_sum_scale (gfloat value1, gfloat value2, gfloat factor)
+{
+ gfloat diff;
+ diff = value1 - value2;
+ return value2 + (diff * factor);
+}
+
+/**
+ * gpm_backlight_brightness_evaluate_and_set:
+ **/
+static gboolean
+gpm_backlight_brightness_evaluate_and_set (GpmBacklight *backlight, gboolean interactive)
+{
+ gfloat brightness;
+ gfloat scale;
+ gboolean ret;
+ gboolean on_battery;
+ gboolean do_laptop_lcd;
+ gboolean enable_action;
+ gboolean battery_reduce;
+ gboolean hw_changed;
+ guint value;
+ guint old_value;
+
+ if (backlight->priv->can_dim == FALSE) {
+ egg_warning ("no dimming hardware");
+ return FALSE;
+ }
+
+ do_laptop_lcd = mateconf_client_get_bool (backlight->priv->conf, GPM_CONF_BACKLIGHT_ENABLE, NULL);
+ if (do_laptop_lcd == FALSE) {
+ egg_warning ("policy is no dimming");
+ return FALSE;
+ }
+
+ /* get the last set brightness */
+ brightness = backlight->priv->master_percentage / 100.0f;
+ egg_debug ("1. main brightness %f", brightness);
+
+ /* get battery status */
+ g_object_get (backlight->priv->client,
+ "on-battery", &on_battery,
+ NULL);
+
+ /* reduce if on battery power if we should */
+ battery_reduce = mateconf_client_get_bool (backlight->priv->conf, GPM_CONF_BACKLIGHT_BATTERY_REDUCE, NULL);
+ if (on_battery && battery_reduce) {
+ value = mateconf_client_get_int (backlight->priv->conf, GPM_CONF_BACKLIGHT_BRIGHTNESS_DIM_BATT, NULL);
+ if (value > 100) {
+ egg_warning ("cannot use battery brightness value %i, correcting to 50", value);
+ value = 50;
+ }
+ scale = (100 - value) / 100.0f;
+ brightness *= scale;
+ } else {
+ scale = 1.0f;
+ }
+ egg_debug ("2. battery scale %f, brightness %f", scale, brightness);
+
+ /* reduce if system is momentarily idle */
+ if (!on_battery)
+ enable_action = mateconf_client_get_bool (backlight->priv->conf, GPM_CONF_BACKLIGHT_IDLE_DIM_AC, NULL);
+ else
+ enable_action = mateconf_client_get_bool (backlight->priv->conf, GPM_CONF_BACKLIGHT_IDLE_DIM_BATT, NULL);
+ if (enable_action && backlight->priv->system_is_idle) {
+ value = mateconf_client_get_int (backlight->priv->conf, GPM_CONF_BACKLIGHT_IDLE_BRIGHTNESS, NULL);
+ if (value > 100) {
+ egg_warning ("cannot use idle brightness value %i, correcting to 50", value);
+ value = 50;
+ }
+ scale = value / 100.0f;
+ brightness *= scale;
+ } else {
+ scale = 1.0f;
+ }
+ egg_debug ("3. idle scale %f, brightness %f", scale, brightness);
+
+ /* convert to percentage */
+ value = (guint) ((brightness * 100.0f) + 0.5);
+
+ /* only do stuff if the brightness is different */
+ gpm_brightness_get (backlight->priv->brightness, &old_value);
+ if (old_value == value) {
+ egg_debug ("values are the same, no action");
+ return FALSE;
+ }
+
+ /* only show dialog if interactive */
+ if (interactive) {
+ gpm_backlight_dialog_init (backlight);
+ gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup),
+ round (brightness));
+ gpm_backlight_dialog_show (backlight);
+ }
+
+ ret = gpm_brightness_set (backlight->priv->brightness, value, &hw_changed);
+ /* we emit a signal for the brightness applet */
+ if (ret && hw_changed) {
+ egg_debug ("emitting brightness-changed : %i", value);
+ g_signal_emit (backlight, signals [BRIGHTNESS_CHANGED], 0, value);
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_conf_mateconf_key_changed_cb:
+ *
+ * We might have to do things when the mateconf keys change; do them here.
+ **/
+static void
+gpm_conf_mateconf_key_changed_cb (MateConfClient *client, guint cnxn_id, MateConfEntry *entry, GpmBacklight *backlight)
+{
+ MateConfValue *value;
+ gboolean on_battery;
+
+ value = mateconf_entry_get_value (entry);
+ if (value == NULL)
+ return;
+
+ /* get battery status */
+ g_object_get (backlight->priv->client,
+ "on-battery", &on_battery,
+ NULL);
+
+ if (!on_battery && strcmp (entry->key, GPM_CONF_BACKLIGHT_BRIGHTNESS_AC) == 0) {
+ backlight->priv->master_percentage = mateconf_value_get_int (value);
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ } else if (on_battery && strcmp (entry->key, GPM_CONF_BACKLIGHT_BRIGHTNESS_DIM_BATT) == 0) {
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ } else if (strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_DIM_AC) == 0 ||
+ strcmp (entry->key, GPM_CONF_BACKLIGHT_ENABLE) == 0 ||
+ strcmp (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT) == 0 ||
+ strcmp (entry->key, GPM_CONF_BACKLIGHT_BATTERY_REDUCE) == 0 ||
+ strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_BRIGHTNESS) == 0) {
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ } else if (strcmp (entry->key, GPM_CONF_BACKLIGHT_IDLE_DIM_TIME) == 0) {
+ backlight->priv->idle_dim_timeout = mateconf_value_get_int (value);
+ gpm_idle_set_timeout_dim (backlight->priv->idle, backlight->priv->idle_dim_timeout);
+ } else {
+ egg_debug ("unknown key %s", entry->key);
+ }
+}
+
+/**
+ * gpm_backlight_client_changed_cb:
+ * @client: The up_client class instance
+ * @backlight: This class instance
+ *
+ * Does the actions when the ac power source is inserted/removed.
+ **/
+static void
+gpm_backlight_client_changed_cb (UpClient *client, GpmBacklight *backlight)
+{
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+}
+
+/**
+ * gpm_backlight_button_pressed_cb:
+ * @power: The power class instance
+ * @type: The button type, e.g. "power"
+ * @state: The state, where TRUE is depressed or closed
+ * @brightness: This class instance
+ **/
+static void
+gpm_backlight_button_pressed_cb (GpmButton *button, const gchar *type, GpmBacklight *backlight)
+{
+ gboolean ret;
+ GError *error = NULL;
+ guint percentage;
+ gboolean hw_changed;
+ egg_debug ("Button press event type=%s", type);
+
+ if (strcmp (type, GPM_BUTTON_BRIGHT_UP) == 0) {
+ /* go up one step */
+ ret = gpm_brightness_up (backlight->priv->brightness, &hw_changed);
+
+ /* show the new value */
+ if (ret) {
+ gpm_brightness_get (backlight->priv->brightness, &percentage);
+ gpm_backlight_dialog_init (backlight);
+ gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup),
+ percentage);
+ gpm_backlight_dialog_show (backlight);
+ /* save the new percentage */
+ backlight->priv->master_percentage = percentage;
+ }
+ /* we emit a signal for the brightness applet */
+ if (ret && hw_changed) {
+ egg_debug ("emitting brightness-changed : %i", percentage);
+ g_signal_emit (backlight, signals [BRIGHTNESS_CHANGED], 0, percentage);
+ }
+ } else if (strcmp (type, GPM_BUTTON_BRIGHT_DOWN) == 0) {
+ /* go up down step */
+ ret = gpm_brightness_down (backlight->priv->brightness, &hw_changed);
+
+ /* show the new value */
+ if (ret) {
+ gpm_brightness_get (backlight->priv->brightness, &percentage);
+ gpm_backlight_dialog_init (backlight);
+ gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup),
+ percentage);
+ gpm_backlight_dialog_show (backlight);
+ /* save the new percentage */
+ backlight->priv->master_percentage = percentage;
+ }
+ /* we emit a signal for the brightness applet */
+ if (ret && hw_changed) {
+ egg_debug ("emitting brightness-changed : %i", percentage);
+ g_signal_emit (backlight, signals [BRIGHTNESS_CHANGED], 0, percentage);
+ }
+ } else if (strcmp (type, GPM_BUTTON_LID_OPEN) == 0) {
+ /* make sure we undim when we lift the lid */
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ /* ensure backlight is on */
+ ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+ if (!ret) {
+ egg_warning ("failed to turn on DPMS: %s", error->message);
+ g_error_free (error);
+ }
+ }
+}
+
+/**
+ * gpm_backlight_notify_system_idle_changed:
+ **/
+static gboolean
+gpm_backlight_notify_system_idle_changed (GpmBacklight *backlight, gboolean is_idle)
+{
+ gdouble elapsed;
+
+ /* no point continuing */
+ if (backlight->priv->system_is_idle == is_idle) {
+ egg_debug ("state not changed");
+ return FALSE;
+ }
+
+ /* get elapsed time and reset timer */
+ elapsed = g_timer_elapsed (backlight->priv->idle_timer, NULL);
+ g_timer_reset (backlight->priv->idle_timer);
+
+ if (is_idle == FALSE) {
+ egg_debug ("we have just been idle for %lfs", elapsed);
+
+ /* The user immediatly undimmed the screen!
+ * We should double the timeout to avoid this happening again */
+ if (elapsed < 10) {
+ /* double the event time */
+ backlight->priv->idle_dim_timeout *= 2.0;
+ egg_debug ("increasing idle dim time to %is", backlight->priv->idle_dim_timeout);
+ gpm_idle_set_timeout_dim (backlight->priv->idle, backlight->priv->idle_dim_timeout);
+ }
+
+ /* We reset the dimming after 2 minutes of idle,
+ * as the user will have changed tasks */
+ if (elapsed > 2*60) {
+ /* reset back to our default dimming */
+ backlight->priv->idle_dim_timeout =
+ mateconf_client_get_int (backlight->priv->conf,
+ GPM_CONF_BACKLIGHT_IDLE_DIM_TIME, NULL);
+ egg_debug ("resetting idle dim time to %is", backlight->priv->idle_dim_timeout);
+ gpm_idle_set_timeout_dim (backlight->priv->idle, backlight->priv->idle_dim_timeout);
+ }
+ } else {
+ egg_debug ("we were active for %lfs", elapsed);
+ }
+
+ egg_debug ("changing powersave idle status to %i", is_idle);
+ backlight->priv->system_is_idle = is_idle;
+ return TRUE;
+}
+
+/**
+ * idle_changed_cb:
+ * @idle: The idle class instance
+ * @mode: The idle mode, e.g. GPM_IDLE_MODE_BLANK
+ * @manager: This class instance
+ *
+ * This callback is called when mate-screensaver detects that the idle state
+ * has changed. GPM_IDLE_MODE_BLANK is when the session has become inactive,
+ * and GPM_IDLE_MODE_SLEEP is where the session has become inactive, AND the
+ * session timeout has elapsed for the idle action.
+ **/
+static void
+idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmBacklight *backlight)
+{
+ gboolean ret;
+ GError *error = NULL;
+ gboolean on_battery;
+ gchar *dpms_method;
+ GpmDpmsMode dpms_mode;
+
+ /* don't dim or undim the screen when the lid is closed */
+ if (gpm_button_is_lid_closed (backlight->priv->button))
+ return;
+
+ /* don't dim or undim the screen unless we are on the active console */
+ if (!egg_console_kit_is_active (backlight->priv->consolekit)) {
+ egg_debug ("ignoring as not on active console");
+ return;
+ }
+
+ if (mode == GPM_IDLE_MODE_NORMAL) {
+ /* sync lcd brightness */
+ gpm_backlight_notify_system_idle_changed (backlight, FALSE);
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ /* ensure backlight is on */
+ ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+ if (!ret) {
+ egg_warning ("failed to turn on DPMS: %s", error->message);
+ g_error_free (error);
+ }
+
+ } else if (mode == GPM_IDLE_MODE_DIM) {
+
+ /* sync lcd brightness */
+ gpm_backlight_notify_system_idle_changed (backlight, TRUE);
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ /* ensure backlight is on */
+ ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+ if (!ret) {
+ egg_warning ("failed to turn on DPMS: %s", error->message);
+ g_error_free (error);
+ }
+
+ } else if (mode == GPM_IDLE_MODE_BLANK) {
+
+ /* sync lcd brightness */
+ gpm_backlight_notify_system_idle_changed (backlight, TRUE);
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+
+ /* get the DPMS state we're supposed to use on the power state */
+ g_object_get (backlight->priv->client,
+ "on-battery", &on_battery,
+ NULL);
+ if (!on_battery)
+ dpms_method = mateconf_client_get_string (backlight->priv->conf, GPM_CONF_BACKLIGHT_DPMS_METHOD_AC, NULL);
+ else
+ dpms_method = mateconf_client_get_string (backlight->priv->conf, GPM_CONF_BACKLIGHT_DPMS_METHOD_BATT, NULL);
+
+ /* convert the string types to standard types */
+ dpms_mode = gpm_dpms_mode_from_string (dpms_method);
+
+ /* check if method is valid */
+ if (dpms_mode == GPM_DPMS_MODE_UNKNOWN || dpms_mode == GPM_DPMS_MODE_ON) {
+ egg_warning ("BACKLIGHT method %s unknown. Using OFF.", dpms_method);
+ dpms_mode = GPM_DPMS_MODE_OFF;
+ }
+
+ /* turn backlight off */
+ ret = gpm_dpms_set_mode (backlight->priv->dpms, dpms_mode, &error);
+ if (!ret) {
+ egg_warning ("failed to change DPMS: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (dpms_method);
+ }
+}
+
+/**
+ * brightness_changed_cb:
+ * @brightness: The GpmBrightness class instance
+ * @percentage: The new percentage brightness
+ * @brightness: This class instance
+ *
+ * This callback is called when the brightness value changes.
+ **/
+static void
+brightness_changed_cb (GpmBrightness *brightness, guint percentage, GpmBacklight *backlight)
+{
+ /* save the new percentage */
+ backlight->priv->master_percentage = percentage;
+
+ /* we emit a signal for the brightness applet */
+ egg_debug ("emitting brightness-changed : %i", percentage);
+ g_signal_emit (backlight, signals [BRIGHTNESS_CHANGED], 0, percentage);
+}
+
+/**
+ * control_resume_cb:
+ * @control: The control class instance
+ * @power: This power class instance
+ *
+ * We have to update the caches on resume
+ **/
+static void
+control_resume_cb (GpmControl *control, GpmControlAction action, GpmBacklight *backlight)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ /* ensure backlight is on */
+ ret = gpm_dpms_set_mode (backlight->priv->dpms, GPM_DPMS_MODE_ON, &error);
+ if (!ret) {
+ egg_warning ("failed to turn on DPMS: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+/**
+ * gpm_backlight_finalize:
+ **/
+static void
+gpm_backlight_finalize (GObject *object)
+{
+ GpmBacklight *backlight;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_BACKLIGHT (object));
+ backlight = GPM_BACKLIGHT (object);
+
+ g_timer_destroy (backlight->priv->idle_timer);
+ gtk_widget_destroy (backlight->priv->popup);
+
+ g_object_unref (backlight->priv->dpms);
+ g_object_unref (backlight->priv->control);
+ g_object_unref (backlight->priv->conf);
+ g_object_unref (backlight->priv->client);
+ g_object_unref (backlight->priv->button);
+ g_object_unref (backlight->priv->idle);
+ g_object_unref (backlight->priv->brightness);
+ g_object_unref (backlight->priv->consolekit);
+
+ g_return_if_fail (backlight->priv != NULL);
+ G_OBJECT_CLASS (gpm_backlight_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_backlight_class_init:
+ **/
+static void
+gpm_backlight_class_init (GpmBacklightClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_backlight_finalize;
+
+ signals [BRIGHTNESS_CHANGED] =
+ g_signal_new ("brightness-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmBacklightClass, brightness_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ g_type_class_add_private (klass, sizeof (GpmBacklightPrivate));
+}
+
+/**
+ * gpm_backlight_init:
+ * @brightness: This brightness class instance
+ *
+ * initialises the brightness class. NOTE: We expect laptop_panel objects
+ * to *NOT* be removed or added during the session.
+ * We only control the first laptop_panel object if there are more than one.
+ **/
+static void
+gpm_backlight_init (GpmBacklight *backlight)
+{
+ gboolean lid_is_present = TRUE;
+ GpmPrefsServer *prefs_server;
+
+ backlight->priv = GPM_BACKLIGHT_GET_PRIVATE (backlight);
+
+ /* record our idle time */
+ backlight->priv->idle_timer = g_timer_new ();
+
+ /* watch for manual brightness changes (for the popup widget) */
+ backlight->priv->brightness = gpm_brightness_new ();
+ g_signal_connect (backlight->priv->brightness, "brightness-changed",
+ G_CALLBACK (brightness_changed_cb), backlight);
+
+ /* we use up_client for the ac-adapter-changed signal */
+ backlight->priv->client = up_client_new ();
+ g_signal_connect (backlight->priv->client, "changed",
+ G_CALLBACK (gpm_backlight_client_changed_cb), backlight);
+
+ /* gets caps */
+ backlight->priv->can_dim = gpm_brightness_has_hw (backlight->priv->brightness);
+
+ /* we use UPower to see if we should show the lid UI */
+ g_object_get (backlight->priv->client,
+ "lid-is-present", &lid_is_present,
+ NULL);
+
+ /* expose ui in prefs program */
+ prefs_server = gpm_prefs_server_new ();
+ if (lid_is_present)
+ gpm_prefs_server_set_capability (prefs_server, GPM_PREFS_SERVER_LID);
+ if (backlight->priv->can_dim)
+ gpm_prefs_server_set_capability (prefs_server, GPM_PREFS_SERVER_BACKLIGHT);
+ g_object_unref (prefs_server);
+
+ /* watch for dim value changes */
+ backlight->priv->conf = mateconf_client_get_default ();
+
+ /* watch mate-power-manager keys */
+ mateconf_client_add_dir (backlight->priv->conf, GPM_CONF_DIR, MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+ mateconf_client_notify_add (backlight->priv->conf, GPM_CONF_DIR,
+ (MateConfClientNotifyFunc) gpm_conf_mateconf_key_changed_cb,
+ backlight, NULL, NULL);
+
+ /* set the main brightness, this is designed to be updated if the user changes the
+ * brightness so we can undim to the 'correct' value */
+ backlight->priv->master_percentage = mateconf_client_get_int (backlight->priv->conf, GPM_CONF_BACKLIGHT_BRIGHTNESS_AC, NULL);
+
+ /* watch for brightness up and down buttons and also check lid state */
+ backlight->priv->button = gpm_button_new ();
+ g_signal_connect (backlight->priv->button, "button-pressed",
+ G_CALLBACK (gpm_backlight_button_pressed_cb), backlight);
+
+ /* watch for idle mode changes */
+ backlight->priv->idle = gpm_idle_new ();
+ g_signal_connect (backlight->priv->idle, "idle-changed",
+ G_CALLBACK (idle_changed_cb), backlight);
+
+ /* assumption */
+ backlight->priv->system_is_idle = FALSE;
+ backlight->priv->idle_dim_timeout = mateconf_client_get_int (backlight->priv->conf, GPM_CONF_BACKLIGHT_IDLE_DIM_TIME, NULL);
+ gpm_idle_set_timeout_dim (backlight->priv->idle, backlight->priv->idle_dim_timeout);
+
+ /* use a visual widget */
+ backlight->priv->popup = gsd_media_keys_window_new ();
+ gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (backlight->priv->popup),
+ "gpm-brightness-lcd",
+ TRUE);
+ gtk_window_set_position (GTK_WINDOW (backlight->priv->popup), GTK_WIN_POS_NONE);
+
+ /* DPMS mode poll class */
+ backlight->priv->dpms = gpm_dpms_new ();
+
+ /* we refresh DPMS on resume */
+ backlight->priv->control = gpm_control_new ();
+ g_signal_connect (backlight->priv->control, "resume",
+ G_CALLBACK (control_resume_cb), backlight);
+
+ /* Don't do dimming on inactive console */
+ backlight->priv->consolekit = egg_console_kit_new ();
+
+ /* sync at startup */
+ gpm_backlight_brightness_evaluate_and_set (backlight, FALSE);
+}
+
+/**
+ * gpm_backlight_new:
+ * Return value: A new brightness class instance.
+ **/
+GpmBacklight *
+gpm_backlight_new (void)
+{
+ GpmBacklight *backlight = g_object_new (GPM_TYPE_BACKLIGHT, NULL);
+ return backlight;
+}
+
diff --git a/src/gpm-backlight.h b/src/gpm-backlight.h
new file mode 100644
index 0000000..1060587
--- /dev/null
+++ b/src/gpm-backlight.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ * Copyright (C) 2004-2005 William Jon McCann <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_BACKLIGHT_H
+#define __GPM_BACKLIGHT_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_BACKLIGHT (gpm_backlight_get_type ())
+#define GPM_BACKLIGHT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_BACKLIGHT, GpmBacklight))
+#define GPM_BACKLIGHT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_BACKLIGHT, GpmBacklightClass))
+#define GPM_IS_BACKLIGHT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_BACKLIGHT))
+#define GPM_IS_BACKLIGHT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_BACKLIGHT))
+#define GPM_BACKLIGHT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_BACKLIGHT, GpmBacklightClass))
+
+typedef struct GpmBacklightPrivate GpmBacklightPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmBacklightPrivate *priv;
+} GpmBacklight;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* brightness_changed) (GpmBacklight *backlight,
+ gint brightness);
+} GpmBacklightClass;
+
+typedef enum
+{
+ GPM_BACKLIGHT_ERROR_GENERAL,
+ GPM_BACKLIGHT_ERROR_DATA_NOT_AVAILABLE,
+ GPM_BACKLIGHT_ERROR_HARDWARE_NOT_PRESENT
+} GpmBacklightError;
+
+GType gpm_backlight_get_type (void);
+GQuark gpm_backlight_error_quark (void);
+GpmBacklight *gpm_backlight_new (void);
+
+gboolean gpm_backlight_get_brightness (GpmBacklight *backlight,
+ guint *brightness,
+ GError **error);
+gboolean gpm_backlight_set_brightness (GpmBacklight *backlight,
+ guint brightness,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GPM_BACKLIGHT_H */
+
diff --git a/src/gpm-brightness.c b/src/gpm-brightness.c
new file mode 100644
index 0000000..e92b6e4
--- /dev/null
+++ b/src/gpm-brightness.c
@@ -0,0 +1,997 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008-2010 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "egg-discrete.h"
+#include "egg-debug.h"
+#include "egg-string.h"
+
+#include "gpm-brightness.h"
+#include "gpm-common.h"
+#include "gpm-marshal.h"
+
+#define GPM_BRIGHTNESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_BRIGHTNESS, GpmBrightnessPrivate))
+#define GPM_SOLE_SETTER_USE_CACHE TRUE /* this may be insanity */
+
+struct GpmBrightnessPrivate
+{
+ gboolean has_changed_events;
+ gboolean cache_trusted;
+ guint cache_percentage;
+ guint last_set_hw;
+ Atom backlight;
+ Display *dpy;
+ GdkWindow *root_window;
+ guint shared_value;
+ gboolean has_extension;
+#ifdef HAVE_XRANDR_13
+ gboolean has_randr13;
+#endif
+ gboolean hw_changed;
+ /* A cache of XRRScreenResources is used as XRRGetScreenResources is expensive */
+ GPtrArray *resources;
+ gint extension_levels;
+ gint extension_current;
+};
+
+enum {
+ BRIGHTNESS_CHANGED,
+ LAST_SIGNAL
+};
+
+typedef enum {
+ ACTION_BACKLIGHT_GET,
+ ACTION_BACKLIGHT_SET,
+ ACTION_BACKLIGHT_INC,
+ ACTION_BACKLIGHT_DEC
+} GpmXRandROp;
+
+G_DEFINE_TYPE (GpmBrightness, gpm_brightness, G_TYPE_OBJECT)
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_brightness_object = NULL;
+
+/**
+ * gpm_brightness_helper_get_value:
+ **/
+static gint
+gpm_brightness_helper_get_value (const gchar *argument)
+{
+ gboolean ret;
+ GError *error = NULL;
+ gchar *stdout_data = NULL;
+ gint exit_status = 0;
+ gint value = -1;
+ gchar *command = NULL;
+
+ /* get the data */
+ command = g_strdup_printf (SBINDIR "/mate-power-backlight-helper --%s", argument);
+ ret = g_spawn_command_line_sync (command,
+ &stdout_data, NULL, &exit_status, &error);
+ if (!ret) {
+ egg_error ("failed to get value: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ egg_debug ("executing %s retval: %i", command, exit_status);
+
+ /* parse for a number */
+ ret = egg_strtoint (stdout_data, &value);
+ if (!ret)
+ goto out;
+out:
+ g_free (command);
+ g_free (stdout_data);
+ return value;
+}
+
+/**
+ * gpm_brightness_helper_set_value:
+ **/
+static gboolean
+gpm_brightness_helper_set_value (const gchar *argument, gint value)
+{
+ gboolean ret;
+ GError *error = NULL;
+ gint exit_status = 0;
+ gchar *command = NULL;
+
+ /* get the data */
+ command = g_strdup_printf ("pkexec " SBINDIR "/mate-power-backlight-helper --%s %i", argument, value);
+ ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error);
+ if (!ret) {
+ egg_error ("failed to get value: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ egg_debug ("executing %s retval: %i", command, exit_status);
+out:
+ g_free (command);
+ return ret;
+}
+
+/**
+ * gpm_brightness_get_step:
+ * @levels: The number of levels supported
+ * Return value: the amount of hardware steps to do on each increment or decrement
+ **/
+static guint
+gpm_brightness_get_step (guint levels)
+{
+ /* macbook pro has a bazzillion brightness levels, do in 5% steps */
+ if (levels > 20)
+ return levels / 20;
+ return 1;
+}
+
+/**
+ * gpm_brightness_output_get_internal:
+ **/
+static gboolean
+gpm_brightness_output_get_internal (GpmBrightness *brightness, RROutput output, guint *cur)
+{
+ unsigned long nitems;
+ unsigned long bytes_after;
+ guint *prop;
+ Atom actual_type;
+ int actual_format;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ if (brightness->priv->backlight == None)
+ return FALSE;
+
+ if (XRRGetOutputProperty (brightness->priv->dpy, output, brightness->priv->backlight,
+ 0, 4, False, False, None,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, ((unsigned char **)&prop)) != Success) {
+ egg_debug ("failed to get property");
+ return FALSE;
+ }
+ if (actual_type == XA_INTEGER && nitems == 1 && actual_format == 32) {
+ memcpy (cur, prop, sizeof (guint));
+ ret = TRUE;
+ }
+ XFree (prop);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_set_internal:
+ **/
+static gboolean
+gpm_brightness_output_set_internal (GpmBrightness *brightness, RROutput output, guint value)
+{
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* don't abort on error */
+ gdk_error_trap_push ();
+ XRRChangeOutputProperty (brightness->priv->dpy, output, brightness->priv->backlight, XA_INTEGER, 32,
+ PropModeReplace, (unsigned char *) &value, 1);
+ XFlush (brightness->priv->dpy);
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ egg_warning ("failed to XRRChangeOutputProperty for brightness %i", value);
+ ret = FALSE;
+ }
+ /* we changed the hardware */
+ if (ret)
+ brightness->priv->hw_changed = TRUE;
+ return ret;
+}
+
+/**
+ * gpm_brightness_setup_display:
+ **/
+static gboolean
+gpm_brightness_setup_display (GpmBrightness *brightness)
+{
+ gint major, minor;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* get the display */
+ brightness->priv->dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default());
+ if (!brightness->priv->dpy) {
+ egg_error ("Cannot open display");
+ return FALSE;
+ }
+ /* is XRandR new enough? */
+ if (!XRRQueryVersion (brightness->priv->dpy, &major, &minor)) {
+ egg_debug ("RandR extension missing");
+ return FALSE;
+ }
+ if (major < 1 || (major == 1 && minor < 2)) {
+ egg_debug ("RandR version %d.%d too old", major, minor);
+ return FALSE;
+ }
+ /* can we support BACKLIGHT */
+ brightness->priv->backlight = XInternAtom (brightness->priv->dpy, "BACKLIGHT", True);
+ if (brightness->priv->backlight == None) {
+ egg_debug ("No outputs have backlight property");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#ifdef HAVE_XRANDR_13
+/**
+ * gpm_brightness_setup_version: Check whether xserver really supports xrandr-1.3 features.
+ **/
+static gboolean
+gpm_brightness_setup_version (GpmBrightness *brightness)
+{
+ gint major, minor;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* get the display */
+ brightness->priv->dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default());
+ if (!brightness->priv->dpy) {
+ egg_error ("Cannot open display");
+ return FALSE;
+ }
+ if (!XRRQueryVersion (brightness->priv->dpy, &major, &minor)) {
+ return FALSE;
+ }
+ if (major == 1 && minor < 3) {
+ egg_debug ("RandR version %d.%d does not support XRRGetScreenResourcesCurrent", major, minor);
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+/**
+ * gpm_brightness_output_get_limits:
+ **/
+static gboolean
+gpm_brightness_output_get_limits (GpmBrightness *brightness, RROutput output,
+ guint *min, guint *max)
+{
+ XRRPropertyInfo *info;
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ info = XRRQueryOutputProperty (brightness->priv->dpy, output, brightness->priv->backlight);
+ if (info == NULL) {
+ egg_debug ("could not get output property");
+ return FALSE;
+ }
+ if (!info->range || info->num_values != 2) {
+ egg_debug ("was not range");
+ ret = FALSE;
+ goto out;
+ }
+ *min = info->values[0];
+ *max = info->values[1];
+out:
+ XFree (info);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_get_percentage:
+ **/
+static gboolean
+gpm_brightness_output_get_percentage (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ gboolean ret;
+ guint min, max;
+ guint percentage;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ percentage = egg_discrete_to_percent (cur, (max-min)+1);
+ egg_debug ("percentage %i", percentage);
+ brightness->priv->shared_value = percentage;
+ return TRUE;
+}
+
+/**
+ * gpm_brightness_output_down:
+ **/
+static gboolean
+gpm_brightness_output_down (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ guint step;
+ gboolean ret;
+ guint min, max;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ if (cur == min) {
+ egg_debug ("already min");
+ return TRUE;
+ }
+ step = gpm_brightness_get_step ((max-min)+1);
+ if (cur < step) {
+ egg_debug ("truncating to %i", min);
+ cur = min;
+ } else {
+ cur -= step;
+ }
+ ret = gpm_brightness_output_set_internal (brightness, output, cur);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_up:
+ **/
+static gboolean
+gpm_brightness_output_up (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ gboolean ret;
+ guint min, max;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ if (cur == max) {
+ egg_debug ("already max");
+ return TRUE;
+ }
+ cur += gpm_brightness_get_step ((max-min)+1);
+ if (cur > max) {
+ egg_debug ("truncating to %i", max);
+ cur = max;
+ }
+ ret = gpm_brightness_output_set_internal (brightness, output, cur);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_set:
+ **/
+static gboolean
+gpm_brightness_output_set (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ gboolean ret;
+ guint min, max;
+ gint i;
+ gint shared_value_abs;
+ guint step;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+
+ shared_value_abs = egg_discrete_from_percent (brightness->priv->shared_value, (max-min)+1);
+ egg_debug ("percent=%i, absolute=%i", brightness->priv->shared_value, shared_value_abs);
+
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ if (shared_value_abs > (gint) max)
+ shared_value_abs = max;
+ if (shared_value_abs < (gint) min)
+ shared_value_abs = min;
+ if ((gint) cur == shared_value_abs) {
+ egg_debug ("already set %i", cur);
+ return TRUE;
+ }
+
+ /* step the correct way */
+ if ((gint) cur < shared_value_abs) {
+
+ /* some adaptors have a large number of steps */
+ step = gpm_brightness_get_step (shared_value_abs - cur);
+ egg_debug ("using step of %i", step);
+
+ /* going up */
+ for (i=cur; i<=shared_value_abs; i+=step) {
+ ret = gpm_brightness_output_set_internal (brightness, output, i);
+ if (!ret)
+ break;
+ if ((gint) cur != shared_value_abs)
+ g_usleep (1000 * GPM_BRIGHTNESS_DIM_INTERVAL);
+ }
+ } else {
+
+ /* some adaptors have a large number of steps */
+ step = gpm_brightness_get_step (cur - shared_value_abs);
+ egg_debug ("using step of %i", step);
+
+ /* going down */
+ for (i=cur; i>=shared_value_abs; i-=step) {
+ ret = gpm_brightness_output_set_internal (brightness, output, i);
+ if (!ret)
+ break;
+ if ((gint) cur != shared_value_abs)
+ g_usleep (1000 * GPM_BRIGHTNESS_DIM_INTERVAL);
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_brightness_foreach_resource:
+ **/
+static gboolean
+gpm_brightness_foreach_resource (GpmBrightness *brightness, GpmXRandROp op, XRRScreenResources *resources)
+{
+ gint i;
+ gboolean ret;
+ gboolean success_any = FALSE;
+ RROutput output;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* do for each output */
+ for (i=0; i<resources->noutput; i++) {
+ output = resources->outputs[i];
+ egg_debug ("resource %i of %i", i+1, resources->noutput);
+ if (op==ACTION_BACKLIGHT_GET) {
+ ret = gpm_brightness_output_get_percentage (brightness, output);
+ } else if (op==ACTION_BACKLIGHT_INC) {
+ ret = gpm_brightness_output_up (brightness, output);
+ } else if (op==ACTION_BACKLIGHT_DEC) {
+ ret = gpm_brightness_output_down (brightness, output);
+ } else if (op==ACTION_BACKLIGHT_SET) {
+ ret = gpm_brightness_output_set (brightness, output);
+ } else {
+ ret = FALSE;
+ egg_warning ("op not known");
+ }
+ if (ret) {
+ success_any = TRUE;
+ }
+ }
+ return success_any;
+}
+
+/**
+ * gpm_brightness_foreach_screen:
+ **/
+static gboolean
+gpm_brightness_foreach_screen (GpmBrightness *brightness, GpmXRandROp op)
+{
+ guint i;
+ guint length;
+ XRRScreenResources *resource;
+ gboolean ret;
+ gboolean success_any = FALSE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* Return immediately if we can't use XRandR */
+ if (!brightness->priv->has_extension)
+ return FALSE;
+
+ /* do for each screen */
+ length = brightness->priv->resources->len;
+ for (i=0; i<length; i++) {
+ resource = (XRRScreenResources *) g_ptr_array_index (brightness->priv->resources, i);
+ egg_debug ("using resource %p", resource);
+ ret = gpm_brightness_foreach_resource (brightness, op, resource);
+ if (ret)
+ success_any = TRUE;
+ }
+ XSync (brightness->priv->dpy, False);
+ return success_any;
+}
+
+/**
+ * gpm_brightness_trust_cache:
+ * @brightness: This brightness class instance
+ * Return value: if we can trust the cache
+ **/
+static gboolean
+gpm_brightness_trust_cache (GpmBrightness *brightness)
+{
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+ /* only return the cached value if the cache is trusted and we have change events */
+ if (brightness->priv->cache_trusted && brightness->priv->has_changed_events) {
+ egg_debug ("using cache for value %u (okay)", brightness->priv->cache_percentage);
+ return TRUE;
+ }
+
+ /* can we trust that if we set a value 5 minutes ago, will it still be valid now?
+ * if we have multiple things setting policy on the workstation, e.g. fast user switching
+ * or kpowersave, then this will be invalid -- this logic may be insane */
+ if (GPM_SOLE_SETTER_USE_CACHE && brightness->priv->cache_trusted) {
+ egg_warning ("using cache for value %u (probably okay)", brightness->priv->cache_percentage);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * gpm_brightness_set:
+ * @brightness: This brightness class instance
+ * @percentage: The percentage brightness
+ * @hw_changed: If the hardware was changed, i.e. the brightness changed
+ * Return value: %TRUE if success, %FALSE if there was an error
+ **/
+gboolean
+gpm_brightness_set (GpmBrightness *brightness, guint percentage, gboolean *hw_changed)
+{
+ gboolean ret = FALSE;
+ gboolean trust_cache;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* can we check the new value with the cache? */
+ trust_cache = gpm_brightness_trust_cache (brightness);
+ if (trust_cache && percentage == brightness->priv->cache_percentage) {
+ egg_debug ("not setting the same value %i", percentage);
+ return TRUE;
+ }
+
+ /* set the value we want */
+ brightness->priv->shared_value = percentage;
+
+ /* reset to not-changed */
+ brightness->priv->hw_changed = FALSE;
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_SET);
+
+ /* legacy fallback */
+ if (!ret) {
+ if (brightness->priv->extension_levels < 0)
+ brightness->priv->extension_levels = gpm_brightness_helper_get_value ("get-max-brightness");
+ brightness->priv->extension_current = egg_discrete_from_percent (percentage, brightness->priv->extension_levels+1);
+ ret = gpm_brightness_helper_set_value ("set-brightness", brightness->priv->extension_current);
+ }
+
+ /* did the hardware have to be modified? */
+ if (ret && hw_changed != NULL)
+ *hw_changed = brightness->priv->hw_changed;
+
+ /* we did something to the hardware, so untrusted */
+ if (ret)
+ brightness->priv->cache_trusted = FALSE;
+
+ return ret;
+}
+
+/**
+ * gpm_brightness_get:
+ * @brightness: This brightness class instance
+ * Return value: The percentage brightness, or -1 for no hardware or error
+ *
+ * Gets the current (or at least what this class thinks is current) percentage
+ * brightness. This is quick as no HAL inquiry is done.
+ **/
+gboolean
+gpm_brightness_get (GpmBrightness *brightness, guint *percentage)
+{
+ gboolean ret = FALSE;
+ gboolean trust_cache;
+ guint percentage_local;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+ g_return_val_if_fail (percentage != NULL, FALSE);
+
+ /* can we use the cache? */
+ trust_cache = gpm_brightness_trust_cache (brightness);
+ if (trust_cache) {
+ *percentage = brightness->priv->cache_percentage;
+ return TRUE;
+ }
+
+ /* get the brightness from hardware -- slow */
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_GET);
+ percentage_local = brightness->priv->shared_value;
+
+ /* legacy fallback */
+ if (!ret) {
+ if (brightness->priv->extension_levels < 0)
+ brightness->priv->extension_levels = gpm_brightness_helper_get_value ("get-max-brightness");
+ brightness->priv->extension_current = gpm_brightness_helper_get_value ("get-brightness");
+ percentage_local = egg_discrete_to_percent (brightness->priv->extension_current, brightness->priv->extension_levels+1);
+ ret = TRUE;
+ }
+
+ /* valid? */
+ if (percentage_local > 100) {
+ egg_warning ("percentage value of %i will be truncated", percentage_local);
+ percentage_local = 100;
+ }
+
+ /* a new value is always trusted if the method and checks succeed */
+ if (ret) {
+ brightness->priv->cache_percentage = percentage_local;
+ brightness->priv->cache_trusted = TRUE;
+ *percentage = percentage_local;
+ } else {
+ brightness->priv->cache_trusted = FALSE;
+ }
+ return ret;
+}
+
+/**
+ * gpm_brightness_up:
+ * @brightness: This brightness class instance
+ * @hw_changed: If the hardware was changed, i.e. the brightness changed
+ * Return value: %TRUE if success, %FALSE if there was an error
+ *
+ * If possible, put the brightness of the LCD up one unit.
+ **/
+gboolean
+gpm_brightness_up (GpmBrightness *brightness, gboolean *hw_changed)
+{
+ gboolean ret = FALSE;
+ guint step;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* reset to not-changed */
+ brightness->priv->hw_changed = FALSE;
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_INC);
+
+ /* did the hardware have to be modified? */
+ if (ret && hw_changed != NULL)
+ *hw_changed = brightness->priv->hw_changed;
+
+ /* we did something to the hardware, so untrusted */
+ if (ret)
+ brightness->priv->cache_trusted = FALSE;
+
+ /* legacy fallback */
+ if (!ret) {
+ if (brightness->priv->extension_levels < 0)
+ brightness->priv->extension_levels = gpm_brightness_helper_get_value ("get-max-brightness");
+ brightness->priv->extension_current = gpm_brightness_helper_get_value ("get-brightness");
+
+ /* increase by the step, limiting to the maximum possible levels */
+ if (brightness->priv->extension_current < brightness->priv->extension_levels) {
+ step = gpm_brightness_get_step (brightness->priv->extension_levels);
+ brightness->priv->extension_current += step;
+ if (brightness->priv->extension_current > brightness->priv->extension_levels)
+ brightness->priv->extension_current = brightness->priv->extension_levels;
+ ret = gpm_brightness_helper_set_value ("set-brightness", brightness->priv->extension_current);
+ }
+ if (hw_changed != NULL)
+ *hw_changed = ret;
+ brightness->priv->cache_trusted = FALSE;
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gpm_brightness_down:
+ * @brightness: This brightness class instance
+ * @hw_changed: If the hardware was changed, i.e. the brightness changed
+ * Return value: %TRUE if success, %FALSE if there was an error
+ *
+ * If possible, put the brightness of the LCD down one unit.
+ **/
+gboolean
+gpm_brightness_down (GpmBrightness *brightness, gboolean *hw_changed)
+{
+ gboolean ret = FALSE;
+ guint step;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* reset to not-changed */
+ brightness->priv->hw_changed = FALSE;
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_DEC);
+
+ /* did the hardware have to be modified? */
+ if (ret && hw_changed != NULL)
+ *hw_changed = brightness->priv->hw_changed;
+
+ /* we did something to the hardware, so untrusted */
+ if (ret)
+ brightness->priv->cache_trusted = FALSE;
+
+ /* legacy fallback */
+ if (!ret) {
+ if (brightness->priv->extension_levels < 0)
+ brightness->priv->extension_levels = gpm_brightness_helper_get_value ("get-max-brightness");
+ brightness->priv->extension_current = gpm_brightness_helper_get_value ("get-brightness");
+
+ /* decrease by the step, limiting to zero */
+ if (brightness->priv->extension_current > 0) {
+ step = gpm_brightness_get_step (brightness->priv->extension_levels);
+ brightness->priv->extension_current -= step;
+ if (brightness->priv->extension_current < 0)
+ brightness->priv->extension_current = 0;
+ ret = gpm_brightness_helper_set_value ("set-brightness", brightness->priv->extension_current);
+ }
+ if (hw_changed != NULL)
+ *hw_changed = ret;
+ brightness->priv->cache_trusted = FALSE;
+ goto out;
+ }
+out:
+ return ret;
+}
+
+
+/**
+ * gpm_brightness_may_have_changed:
+ **/
+static void
+gpm_brightness_may_have_changed (GpmBrightness *brightness)
+{
+ gboolean ret;
+ guint percentage;
+ ret = gpm_brightness_get (brightness, &percentage);
+ if (!ret) {
+ egg_warning ("failed to get output");
+ return;
+ }
+ egg_debug ("emitting brightness-changed (%i)", percentage);
+ g_signal_emit (brightness, signals [BRIGHTNESS_CHANGED], 0, percentage);
+}
+
+/**
+ * gpm_brightness_filter_xevents:
+ **/
+static GdkFilterReturn
+gpm_brightness_filter_xevents (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ GpmBrightness *brightness = GPM_BRIGHTNESS (data);
+ if (event->type == GDK_NOTHING)
+ return GDK_FILTER_CONTINUE;
+ gpm_brightness_may_have_changed (brightness);
+ return GDK_FILTER_CONTINUE;
+}
+
+
+static void gpm_brightness_update_cache (GpmBrightness *brightness);
+
+/**
+ * gpm_brightness_monitors_changed:
+ **/
+static void
+gpm_brightness_monitors_changed (GdkScreen *screen, GpmBrightness *brightness)
+{
+ g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
+ gpm_brightness_update_cache (brightness);
+}
+
+/**
+ * gpm_brightness_update_cache:
+ **/
+static void
+gpm_brightness_update_cache (GpmBrightness *brightness)
+{
+ guint length;
+ gint screen;
+ Window root;
+ GdkScreen *gscreen;
+ GdkDisplay *display;
+ XRRScreenResources *resource;
+
+ g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
+
+ /* invalidate and remove all the previous entries */
+ length = brightness->priv->resources->len;
+ if (length > 0)
+ g_ptr_array_set_size (brightness->priv->resources, 0);
+
+ /* do for each screen */
+ display = gdk_display_get_default ();
+ length = ScreenCount (brightness->priv->dpy);
+ for (screen = 0; screen < (gint) length; screen++) {
+ egg_debug ("screen %i of %i", screen+1, length);
+ gscreen = gdk_display_get_screen (display, screen);
+
+ /* if we have not setup the changed on the monitor, set it here */
+ if (g_object_get_data (G_OBJECT (gscreen), "gpk-set-monitors-changed") == NULL) {
+ egg_debug ("watching ::monitors_changed on %p", gscreen);
+ g_object_set_data (G_OBJECT (gscreen), "gpk-set-monitors-changed", (gpointer) "true");
+ g_signal_connect (G_OBJECT (gscreen), "monitors_changed",
+ G_CALLBACK (gpm_brightness_monitors_changed), brightness);
+ }
+
+ root = RootWindow (brightness->priv->dpy, screen);
+ /* XRRGetScreenResourcesCurrent is less expensive than
+ XRRGetScreenResources, however it is available only
+ in RandR 1.3 or higher and of course xserver needs
+ to support it.
+ */
+#ifdef HAVE_XRANDR_13
+ if (brightness->priv->has_randr13)
+ resource = XRRGetScreenResourcesCurrent (brightness->priv->dpy, root);
+ else
+#endif
+ resource = XRRGetScreenResources (brightness->priv->dpy, root);
+
+ if (resource != NULL) {
+ egg_debug ("adding resource %p", resource);
+ g_ptr_array_add (brightness->priv->resources, resource);
+ }
+ }
+}
+
+/**
+ * gpm_brightness_has_hw:
+ **/
+gboolean
+gpm_brightness_has_hw (GpmBrightness *brightness)
+{
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* use XRandR first */
+ if (brightness->priv->has_extension)
+ return TRUE;
+
+ /* fallback to legacy access */
+ if (brightness->priv->extension_levels < 0)
+ brightness->priv->extension_levels = gpm_brightness_helper_get_value ("get-max-brightness");
+ if (brightness->priv->extension_levels > 0)
+ return TRUE;
+ return FALSE;
+}
+
+/**
+ * gpm_brightness_finalize:
+ **/
+static void
+gpm_brightness_finalize (GObject *object)
+{
+ GpmBrightness *brightness;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_BRIGHTNESS (object));
+ brightness = GPM_BRIGHTNESS (object);
+ g_ptr_array_unref (brightness->priv->resources);
+ gdk_window_remove_filter (brightness->priv->root_window,
+ gpm_brightness_filter_xevents, brightness);
+ G_OBJECT_CLASS (gpm_brightness_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_brightness_class_init:
+ **/
+static void
+gpm_brightness_class_init (GpmBrightnessClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_brightness_finalize;
+
+ signals [BRIGHTNESS_CHANGED] =
+ g_signal_new ("brightness-changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmBrightnessClass, brightness_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ g_type_class_add_private (klass, sizeof (GpmBrightnessPrivate));
+}
+
+/**
+ * gpm_brightness_init:
+ * @brightness: This brightness class instance
+ **/
+static void
+gpm_brightness_init (GpmBrightness *brightness)
+{
+ GdkScreen *screen;
+ GdkDisplay *display;
+ int event_base;
+ int ignore;
+
+ brightness->priv = GPM_BRIGHTNESS_GET_PRIVATE (brightness);
+
+ brightness->priv->cache_trusted = FALSE;
+ brightness->priv->has_changed_events = FALSE;
+ brightness->priv->cache_percentage = 0;
+ brightness->priv->hw_changed = FALSE;
+ brightness->priv->extension_levels = -1;
+ brightness->priv->resources = g_ptr_array_new_with_free_func ((GDestroyNotify) XRRFreeScreenResources);
+
+ /* can we do this */
+ brightness->priv->has_extension = gpm_brightness_setup_display (brightness);
+#ifdef HAVE_XRANDR_13
+ brightness->priv->has_randr13 = gpm_brightness_setup_version (brightness);
+#endif
+ if (brightness->priv->has_extension == FALSE)
+ egg_debug ("no XRANDR extension");
+
+ screen = gdk_screen_get_default ();
+ brightness->priv->root_window = gdk_screen_get_root_window (screen);
+ display = gdk_display_get_default ();
+
+ /* as we a filtering by a window, we have to add an event type */
+ if (!XRRQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default()), &event_base, &ignore)) {
+ egg_warning ("can't get event_base for XRR");
+ }
+ gdk_x11_register_standard_event_type (display, event_base, RRNotify + 1);
+ gdk_window_add_filter (brightness->priv->root_window,
+ gpm_brightness_filter_xevents, brightness);
+
+ /* don't abort on error */
+ gdk_error_trap_push ();
+ XRRSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default()),
+ GDK_WINDOW_XID (brightness->priv->root_window),
+ RRScreenChangeNotifyMask |
+ RROutputPropertyNotifyMask); /* <--- the only one we need, but see rh:345551 */
+ gdk_flush ();
+ if (gdk_error_trap_pop ())
+ egg_warning ("failed to select XRRSelectInput");
+
+ /* create cache of XRRScreenResources as XRRGetScreenResources() is slow */
+ gpm_brightness_update_cache (brightness);
+}
+
+/**
+ * gpm_brightness_new:
+ * Return value: A new brightness class instance.
+ * Can return NULL if no suitable hardware is found.
+ **/
+GpmBrightness *
+gpm_brightness_new (void)
+{
+ if (gpm_brightness_object != NULL) {
+ g_object_ref (gpm_brightness_object);
+ } else {
+ gpm_brightness_object = g_object_new (GPM_TYPE_BRIGHTNESS, NULL);
+ g_object_add_weak_pointer (gpm_brightness_object, &gpm_brightness_object);
+ }
+ return GPM_BRIGHTNESS (gpm_brightness_object);
+}
+
diff --git a/src/gpm-brightness.h b/src/gpm-brightness.h
new file mode 100644
index 0000000..918793d
--- /dev/null
+++ b/src/gpm-brightness.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_BRIGHTNESS_H
+#define __GPM_BRIGHTNESS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_BRIGHTNESS (gpm_brightness_get_type ())
+#define GPM_BRIGHTNESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_BRIGHTNESS, GpmBrightness))
+#define GPM_BRIGHTNESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_BRIGHTNESS, GpmBrightnessClass))
+#define GPM_IS_BRIGHTNESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_BRIGHTNESS))
+#define GPM_IS_BRIGHTNESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_BRIGHTNESS))
+#define GPM_BRIGHTNESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_BRIGHTNESS, GpmBrightnessClass))
+
+#define GPM_BRIGHTNESS_DIM_INTERVAL 5 /* ms */
+
+typedef struct GpmBrightnessPrivate GpmBrightnessPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmBrightnessPrivate *priv;
+} GpmBrightness;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* brightness_changed) (GpmBrightness *brightness,
+ guint percentage);
+} GpmBrightnessClass;
+
+GType gpm_brightness_get_type (void);
+GpmBrightness *gpm_brightness_new (void);
+
+gboolean gpm_brightness_has_hw (GpmBrightness *brightness);
+gboolean gpm_brightness_up (GpmBrightness *brightness,
+ gboolean *hw_changed);
+gboolean gpm_brightness_down (GpmBrightness *brightness,
+ gboolean *hw_changed);
+gboolean gpm_brightness_get (GpmBrightness *brightness,
+ guint *percentage);
+gboolean gpm_brightness_set (GpmBrightness *brightness,
+ guint percentage,
+ gboolean *hw_changed);
+
+G_END_DECLS
+
+#endif /* __GPM_BRIGHTNESS_H */
diff --git a/src/gpm-button.c b/src/gpm-button.c
new file mode 100644
index 0000000..cb5cd50
--- /dev/null
+++ b/src/gpm-button.c
@@ -0,0 +1,387 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <X11/X.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#include <X11/XF86keysym.h>
+#include <libupower-glib/upower.h>
+
+#include "gpm-common.h"
+#include "gpm-button.h"
+
+#include "egg-debug.h"
+
+static void gpm_button_finalize (GObject *object);
+
+#define GPM_BUTTON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_BUTTON, GpmButtonPrivate))
+
+struct GpmButtonPrivate
+{
+ GdkScreen *screen;
+ GdkWindow *window;
+ GHashTable *keysym_to_name_hash;
+ gchar *last_button;
+ GTimer *timer;
+ gboolean lid_is_closed;
+ UpClient *client;
+};
+
+enum {
+ BUTTON_PRESSED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_button_object = NULL;
+
+G_DEFINE_TYPE (GpmButton, gpm_button, G_TYPE_OBJECT)
+
+#define GPM_BUTTON_DUPLICATE_TIMEOUT 0.125f
+
+/**
+ * gpm_button_emit_type:
+ **/
+static gboolean
+gpm_button_emit_type (GpmButton *button, const gchar *type)
+{
+ g_return_val_if_fail (GPM_IS_BUTTON (button), FALSE);
+
+ /* did we just have this button before the timeout? */
+ if (g_strcmp0 (type, button->priv->last_button) == 0 &&
+ g_timer_elapsed (button->priv->timer, NULL) < GPM_BUTTON_DUPLICATE_TIMEOUT) {
+ egg_debug ("ignoring duplicate button %s", type);
+ return FALSE;
+ }
+
+ egg_debug ("emitting button-pressed : %s", type);
+ g_signal_emit (button, signals [BUTTON_PRESSED], 0, type);
+
+ /* save type and last size */
+ g_free (button->priv->last_button);
+ button->priv->last_button = g_strdup (type);
+ g_timer_reset (button->priv->timer);
+
+ return TRUE;
+}
+
+/**
+ * gpm_button_filter_x_events:
+ **/
+static GdkFilterReturn
+gpm_button_filter_x_events (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ GpmButton *button = (GpmButton *) data;
+ XEvent *xev = (XEvent *) xevent;
+ guint keycode;
+ const gchar *key;
+ gchar *keycode_str;
+
+ if (xev->type != KeyPress)
+ return GDK_FILTER_CONTINUE;
+
+ keycode = xev->xkey.keycode;
+
+ /* is the key string already in our DB? */
+ keycode_str = g_strdup_printf ("0x%x", keycode);
+ key = g_hash_table_lookup (button->priv->keysym_to_name_hash, (gpointer) keycode_str);
+ g_free (keycode_str);
+
+ /* found anything? */
+ if (key == NULL) {
+ egg_debug ("Key %i not found in hash", keycode);
+ /* pass normal keypresses on, which might help with accessibility access */
+ return GDK_FILTER_CONTINUE;
+ }
+
+ egg_debug ("Key %i mapped to key %s", keycode, key);
+ gpm_button_emit_type (button, key);
+
+ return GDK_FILTER_REMOVE;
+}
+
+/**
+ * gpm_button_grab_keystring:
+ * @button: This button class instance
+ * @keystr: The key string, e.g. "<Control><Alt>F11"
+ * @hashkey: A unique key made up from the modmask and keycode suitable for
+ * referencing in a hashtable.
+ * You must free this string, or specify NULL to ignore.
+ *
+ * Grab the key specified in the key string.
+ *
+ * Return value: TRUE if we parsed and grabbed okay
+ **/
+static gboolean
+gpm_button_grab_keystring (GpmButton *button, guint64 keycode)
+{
+ guint modmask = AnyModifier;
+ Display *display;
+ gint ret;
+
+ /* get the current X Display */
+ display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default());
+
+ /* don't abort on error */
+ gdk_error_trap_push ();
+
+ /* grab the key if possible */
+ ret = XGrabKey (display, keycode, modmask,
+ GDK_WINDOW_XID (button->priv->window), True,
+ GrabModeAsync, GrabModeAsync);
+ if (ret == BadAccess) {
+ egg_warning ("Failed to grab modmask=%u, keycode=%li",
+ modmask, (long int) keycode);
+ return FALSE;
+ }
+
+ /* grab the lock key if possible */
+ ret = XGrabKey (display, keycode, LockMask | modmask,
+ GDK_WINDOW_XID (button->priv->window), True,
+ GrabModeAsync, GrabModeAsync);
+ if (ret == BadAccess) {
+ egg_warning ("Failed to grab modmask=%u, keycode=%li",
+ LockMask | modmask, (long int) keycode);
+ return FALSE;
+ }
+
+ /* we are not processing the error */
+ gdk_flush ();
+ gdk_error_trap_pop ();
+
+ egg_debug ("Grabbed modmask=%x, keycode=%li", modmask, (long int) keycode);
+ return TRUE;
+}
+
+/**
+ * gpm_button_grab_keystring:
+ * @button: This button class instance
+ * @keystr: The key string, e.g. "<Control><Alt>F11"
+ * @hashkey: A unique key made up from the modmask and keycode suitable for
+ * referencing in a hashtable.
+ * You must free this string, or specify NULL to ignore.
+ *
+ * Grab the key specified in the key string.
+ *
+ * Return value: TRUE if we parsed and grabbed okay
+ **/
+static gboolean
+gpm_button_xevent_key (GpmButton *button, guint keysym, const gchar *key_name)
+{
+ gchar *key = NULL;
+ gboolean ret;
+ gchar *keycode_str;
+ guint keycode;
+
+ /* convert from keysym to keycode */
+ keycode = XKeysymToKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default()), keysym);
+ if (keycode == 0) {
+ egg_warning ("could not map keysym %x to keycode", keysym);
+ return FALSE;
+ }
+
+ /* is the key string already in our DB? */
+ keycode_str = g_strdup_printf ("0x%x", keycode);
+ key = g_hash_table_lookup (button->priv->keysym_to_name_hash, (gpointer) keycode_str);
+ if (key != NULL) {
+ egg_warning ("found in hash %i", keycode);
+ g_free (keycode_str);
+ return FALSE;
+ }
+
+ /* try to register X event */
+ ret = gpm_button_grab_keystring (button, keycode);
+ if (!ret) {
+ egg_warning ("Failed to grab %i", keycode);
+ g_free (keycode_str);
+ return FALSE;
+ }
+
+ /* add to hash table */
+ g_hash_table_insert (button->priv->keysym_to_name_hash, (gpointer) keycode_str, (gpointer) g_strdup (key_name));
+
+ /* the key is freed in the hash function unref */
+ return TRUE;
+}
+
+/**
+ * gpm_button_class_init:
+ * @button: This class instance
+ **/
+static void
+gpm_button_class_init (GpmButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_button_finalize;
+ g_type_class_add_private (klass, sizeof (GpmButtonPrivate));
+
+ signals [BUTTON_PRESSED] =
+ g_signal_new ("button-pressed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmButtonClass, button_pressed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+/**
+ * gpm_button_is_lid_closed:
+ **/
+gboolean
+gpm_button_is_lid_closed (GpmButton *button)
+{
+ g_return_val_if_fail (GPM_IS_BUTTON (button), FALSE);
+ return up_client_get_lid_is_closed (button->priv->client);
+}
+
+/**
+ * gpm_button_reset_time:
+ *
+ * We have to refresh the event time on resume to handle duplicate buttons
+ * properly when the time is significant when we suspend.
+ **/
+gboolean
+gpm_button_reset_time (GpmButton *button)
+{
+ g_return_val_if_fail (GPM_IS_BUTTON (button), FALSE);
+ g_timer_reset (button->priv->timer);
+ return TRUE;
+}
+
+/**
+ * gpm_button_client_changed_cb
+ **/
+static void
+gpm_button_client_changed_cb (UpClient *client, GpmButton *button)
+{
+ gboolean lid_is_closed;
+
+ /* get new state */
+ lid_is_closed = up_client_get_lid_is_closed (button->priv->client);
+
+ /* same state */
+ if (button->priv->lid_is_closed == lid_is_closed)
+ return;
+
+ /* save state */
+ button->priv->lid_is_closed = lid_is_closed;
+
+ /* sent correct event */
+ if (lid_is_closed)
+ gpm_button_emit_type (button, GPM_BUTTON_LID_CLOSED);
+ else
+ gpm_button_emit_type (button, GPM_BUTTON_LID_OPEN);
+}
+
+/**
+ * gpm_button_init:
+ * @button: This class instance
+ **/
+static void
+gpm_button_init (GpmButton *button)
+{
+ button->priv = GPM_BUTTON_GET_PRIVATE (button);
+
+ button->priv->screen = gdk_screen_get_default ();
+ button->priv->window = gdk_screen_get_root_window (button->priv->screen);
+
+ button->priv->keysym_to_name_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ button->priv->last_button = NULL;
+ button->priv->timer = g_timer_new ();
+
+ button->priv->client = up_client_new ();
+ button->priv->lid_is_closed = up_client_get_lid_is_closed (button->priv->client);
+ g_signal_connect (button->priv->client, "changed",
+ G_CALLBACK (gpm_button_client_changed_cb), button);
+
+ /* register the brightness keys */
+ gpm_button_xevent_key (button, XF86XK_PowerOff, GPM_BUTTON_POWER);
+#ifdef HAVE_XF86XK_SUSPEND
+ /* The kernel messes up suspend/hibernate in some places. One of
+ * them is the key names. Unfortunately, they refuse to see the
+ * errors of their way in the name of 'compatibility'. Meh
+ */
+ gpm_button_xevent_key (button, XF86XK_Suspend, GPM_BUTTON_HIBERNATE);
+#endif
+ gpm_button_xevent_key (button, XF86XK_Sleep, GPM_BUTTON_SUSPEND); /* should be configurable */
+#ifdef HAVE_XF86XK_HIBERNATE
+ gpm_button_xevent_key (button, XF86XK_Hibernate, GPM_BUTTON_HIBERNATE);
+#endif
+ gpm_button_xevent_key (button, XF86XK_MonBrightnessUp, GPM_BUTTON_BRIGHT_UP);
+ gpm_button_xevent_key (button, XF86XK_MonBrightnessDown, GPM_BUTTON_BRIGHT_DOWN);
+ gpm_button_xevent_key (button, XF86XK_ScreenSaver, GPM_BUTTON_LOCK);
+#ifdef HAVE_XF86XK_BATTERY
+ gpm_button_xevent_key (button, XF86XK_Battery, GPM_BUTTON_BATTERY);
+#endif
+ gpm_button_xevent_key (button, XF86XK_KbdBrightnessUp, GPM_BUTTON_KBD_BRIGHT_UP);
+ gpm_button_xevent_key (button, XF86XK_KbdBrightnessDown, GPM_BUTTON_KBD_BRIGHT_DOWN);
+ gpm_button_xevent_key (button, XF86XK_KbdLightOnOff, GPM_BUTTON_KBD_BRIGHT_TOGGLE);
+
+ /* use global filter */
+ gdk_window_add_filter (button->priv->window,
+ gpm_button_filter_x_events, (gpointer) button);
+}
+
+/**
+ * gpm_button_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_button_finalize (GObject *object)
+{
+ GpmButton *button;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_BUTTON (object));
+
+ button = GPM_BUTTON (object);
+ button->priv = GPM_BUTTON_GET_PRIVATE (button);
+
+ g_object_unref (button->priv->client);
+ g_free (button->priv->last_button);
+ g_timer_destroy (button->priv->timer);
+
+ g_hash_table_unref (button->priv->keysym_to_name_hash);
+
+ G_OBJECT_CLASS (gpm_button_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_button_new:
+ * Return value: new class instance.
+ **/
+GpmButton *
+gpm_button_new (void)
+{
+ if (gpm_button_object != NULL) {
+ g_object_ref (gpm_button_object);
+ } else {
+ gpm_button_object = g_object_new (GPM_TYPE_BUTTON, NULL);
+ g_object_add_weak_pointer (gpm_button_object, &gpm_button_object);
+ }
+ return GPM_BUTTON (gpm_button_object);
+}
diff --git a/src/gpm-button.h b/src/gpm-button.h
new file mode 100644
index 0000000..8992007
--- /dev/null
+++ b/src/gpm-button.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPMBUTTON_H
+#define __GPMBUTTON_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_BUTTON (gpm_button_get_type ())
+#define GPM_BUTTON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_BUTTON, GpmButton))
+#define GPM_BUTTON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_BUTTON, GpmButtonClass))
+#define GPM_IS_BUTTON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_BUTTON))
+#define GPM_IS_BUTTON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_BUTTON))
+#define GPM_BUTTON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_BUTTON, GpmButtonClass))
+
+typedef struct GpmButtonPrivate GpmButtonPrivate;
+
+#define GPM_BUTTON_POWER "power"
+#define GPM_BUTTON_SLEEP "sleep"
+#define GPM_BUTTON_SUSPEND "suspend"
+#define GPM_BUTTON_HIBERNATE "hibernate"
+#define GPM_BUTTON_LID_DEP "lid" /* Remove when HAL drops input support */
+#define GPM_BUTTON_LID_OPEN "lid-up"
+#define GPM_BUTTON_LID_CLOSED "lid-down"
+#define GPM_BUTTON_BRIGHT_UP "brightness-up"
+#define GPM_BUTTON_BRIGHT_DOWN "brightness-down"
+#define GPM_BUTTON_KBD_BRIGHT_UP "kbd-illum-up"
+#define GPM_BUTTON_KBD_BRIGHT_DOWN "kbd-illum-down"
+#define GPM_BUTTON_KBD_BRIGHT_TOGGLE "kbd-illum-toggle"
+#define GPM_BUTTON_LOCK "lock"
+#define GPM_BUTTON_BATTERY "battery"
+
+typedef struct
+{
+ GObject parent;
+ GpmButtonPrivate *priv;
+} GpmButton;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* button_pressed) (GpmButton *button,
+ const gchar *type);
+} GpmButtonClass;
+
+GType gpm_button_get_type (void);
+GpmButton *gpm_button_new (void);
+gboolean gpm_button_is_lid_closed (GpmButton *button);
+gboolean gpm_button_reset_time (GpmButton *button);
+
+G_END_DECLS
+
+#endif /* __GPMBUTTON_H */
diff --git a/src/gpm-common.c b/src/gpm-common.c
new file mode 100644
index 0000000..0d0e536
--- /dev/null
+++ b/src/gpm-common.c
@@ -0,0 +1,210 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include "egg-debug.h"
+#include "gpm-common.h"
+
+/**
+ * gpm_get_timestring:
+ * @time_secs: The time value to convert in seconds
+ * @cookie: The cookie we are looking for
+ *
+ * Returns a localised timestring
+ *
+ * Return value: The time string, e.g. "2 hours 3 minutes"
+ **/
+gchar *
+gpm_get_timestring (guint time_secs)
+{
+ char* timestring = NULL;
+ gint hours;
+ gint minutes;
+
+ /* Add 0.5 to do rounding */
+ minutes = (int) ( ( time_secs / 60.0 ) + 0.5 );
+
+ if (minutes == 0) {
+ timestring = g_strdup (_("Unknown time"));
+ return timestring;
+ }
+
+ if (minutes < 60) {
+ timestring = g_strdup_printf (ngettext ("%i minute",
+ "%i minutes",
+ minutes), minutes);
+ return timestring;
+ }
+
+ hours = minutes / 60;
+ minutes = minutes % 60;
+
+ if (minutes == 0)
+ timestring = g_strdup_printf (ngettext (
+ "%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 */
+ timestring = g_strdup_printf (_("%i %s %i %s"),
+ hours, ngettext ("hour", "hours", hours),
+ minutes, ngettext ("minute", "minutes", minutes));
+ return timestring;
+}
+
+/**
+ * gpm_icon_policy_from_string:
+ **/
+GpmIconPolicy
+gpm_icon_policy_from_string (const gchar *policy)
+{
+ if (policy == NULL)
+ return GPM_ICON_POLICY_NEVER;
+ if (g_strcmp0 (policy, "always") == 0)
+ return GPM_ICON_POLICY_ALWAYS;
+ if (g_strcmp0 (policy, "present") == 0)
+ return GPM_ICON_POLICY_PRESENT;
+ if (g_strcmp0 (policy, "charge") == 0)
+ return GPM_ICON_POLICY_CHARGE;
+ if (g_strcmp0 (policy, "low") == 0)
+ return GPM_ICON_POLICY_LOW;
+ if (g_strcmp0 (policy, "critical") == 0)
+ return GPM_ICON_POLICY_CRITICAL;
+ if (g_strcmp0 (policy, "never") == 0)
+ return GPM_ICON_POLICY_NEVER;
+ return GPM_ICON_POLICY_NEVER;
+}
+
+/**
+ * gpm_icon_policy_to_string:
+ **/
+const gchar *
+gpm_icon_policy_to_string (GpmIconPolicy policy)
+{
+ if (policy == GPM_ICON_POLICY_ALWAYS)
+ return "always";
+ if (policy == GPM_ICON_POLICY_PRESENT)
+ return "present";
+ if (policy == GPM_ICON_POLICY_CHARGE)
+ return "charge";
+ if (policy == GPM_ICON_POLICY_LOW)
+ return "low";
+ if (policy == GPM_ICON_POLICY_CRITICAL)
+ return "critical";
+ if (policy == GPM_ICON_POLICY_NEVER)
+ return "never";
+ return "never";
+}
+
+/**
+ * gpm_action_policy_from_string:
+ **/
+GpmActionPolicy
+gpm_action_policy_from_string (const gchar *policy)
+{
+ if (policy == NULL)
+ return GPM_ACTION_POLICY_NOTHING;
+ if (g_strcmp0 (policy, "blank") == 0)
+ return GPM_ACTION_POLICY_BLANK;
+ if (g_strcmp0 (policy, "shutdown") == 0)
+ return GPM_ACTION_POLICY_SHUTDOWN;
+ if (g_strcmp0 (policy, "suspend") == 0)
+ return GPM_ACTION_POLICY_SUSPEND;
+ if (g_strcmp0 (policy, "hibernate") == 0)
+ return GPM_ACTION_POLICY_HIBERNATE;
+ if (g_strcmp0 (policy, "interactive") == 0)
+ return GPM_ACTION_POLICY_INTERACTIVE;
+ return GPM_ACTION_POLICY_NOTHING;
+}
+
+/**
+ * gpm_action_policy_to_string:
+ **/
+const gchar *
+gpm_action_policy_to_string (GpmActionPolicy policy)
+{
+ if (policy == GPM_ACTION_POLICY_BLANK)
+ return "blank";
+ if (policy == GPM_ACTION_POLICY_SHUTDOWN)
+ return "shutdown";
+ if (policy == GPM_ACTION_POLICY_SUSPEND)
+ return "suspend";
+ if (policy == GPM_ACTION_POLICY_HIBERNATE)
+ return "hibernate";
+ if (policy == GPM_ACTION_POLICY_INTERACTIVE)
+ return "interactive";
+ return "nothing";
+}
+
+/**
+ * gpm_help_display:
+ * @link_id: Subsection of mate-power-manager help section
+ **/
+void
+gpm_help_display (const gchar *link_id)
+{
+ GError *error = NULL;
+ gchar *uri;
+
+ if (link_id != NULL)
+ uri = g_strconcat ("ghelp:mate-power-manager?", link_id, NULL);
+ else
+ uri = g_strdup ("ghelp:mate-power-manager");
+
+ gtk_show_uri (NULL, uri, GDK_CURRENT_TIME, &error);
+
+ if (error != NULL) {
+ GtkWidget *d;
+ d = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", error->message);
+ gtk_dialog_run (GTK_DIALOG(d));
+ gtk_widget_destroy (d);
+ g_error_free (error);
+ }
+ g_free (uri);
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+gpm_common_test (gpointer data)
+{
+ EggTest *test = (EggTest *) data;
+ if (egg_test_start (test, "GpmCommon") == FALSE)
+ return;
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/gpm-common.h b/src/gpm-common.h
new file mode 100644
index 0000000..e2733a8
--- /dev/null
+++ b/src/gpm-common.h
@@ -0,0 +1,183 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPMCOMMON_H
+#define __GPMCOMMON_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define GPM_DBUS_SERVICE "org.mate.PowerManager"
+#define GPM_DBUS_INTERFACE "org.mate.PowerManager"
+#define GPM_DBUS_INTERFACE_BACKLIGHT "org.mate.PowerManager.Backlight"
+#define GPM_DBUS_PATH "/org/mate/PowerManager"
+#define GPM_DBUS_PATH_BACKLIGHT "/org/mate/PowerManager/Backlight"
+
+/* common descriptions of this program */
+#define GPM_NAME _("Power Manager")
+#define GPM_DESCRIPTION _("Power Manager for the MATE desktop")
+
+/* help location */
+#define GPM_HOMEPAGE_URL "http://www.mate.org/projects/mate-power-manager/"
+#define GPM_BUGZILLA_URL "http://bugzilla.mate.org/buglist.cgi?product=mate-power-manager"
+#define GPM_FAQ_URL "http://live.mate.org/MatePowerManager/Faq"
+
+/* change general/installed_schema whenever adding or moving keys */
+#define GPM_CONF_SCHEMA_ID 3
+
+#define GPM_CONF_DIR "/apps/mate-power-manager"
+
+/* actions */
+#define GPM_CONF_ACTIONS_CRITICAL_UPS GPM_CONF_DIR "/actions/critical_ups"
+#define GPM_CONF_ACTIONS_CRITICAL_BATT GPM_CONF_DIR "/actions/critical_battery"
+#define GPM_CONF_ACTIONS_LOW_UPS GPM_CONF_DIR "/actions/low_ups"
+#define GPM_CONF_ACTIONS_SLEEP_TYPE_AC GPM_CONF_DIR "/actions/sleep_type_ac"
+#define GPM_CONF_ACTIONS_SLEEP_TYPE_BATT GPM_CONF_DIR "/actions/sleep_type_battery"
+#define GPM_CONF_ACTIONS_SLEEP_WHEN_CLOSED GPM_CONF_DIR "/actions/event_when_closed_battery"
+
+/* backlight stuff */
+#define GPM_CONF_BACKLIGHT_ENABLE GPM_CONF_DIR "/backlight/enable"
+#define GPM_CONF_BACKLIGHT_BATTERY_REDUCE GPM_CONF_DIR "/backlight/battery_reduce"
+#define GPM_CONF_BACKLIGHT_DPMS_METHOD_AC GPM_CONF_DIR "/backlight/dpms_method_ac"
+#define GPM_CONF_BACKLIGHT_DPMS_METHOD_BATT GPM_CONF_DIR "/backlight/dpms_method_battery"
+#define GPM_CONF_BACKLIGHT_IDLE_BRIGHTNESS GPM_CONF_DIR "/backlight/idle_brightness"
+#define GPM_CONF_BACKLIGHT_IDLE_DIM_AC GPM_CONF_DIR "/backlight/idle_dim_ac"
+#define GPM_CONF_BACKLIGHT_IDLE_DIM_BATT GPM_CONF_DIR "/backlight/idle_dim_battery"
+#define GPM_CONF_BACKLIGHT_IDLE_DIM_TIME GPM_CONF_DIR "/backlight/idle_dim_time"
+#define GPM_CONF_BACKLIGHT_BRIGHTNESS_AC GPM_CONF_DIR "/backlight/brightness_ac"
+#define GPM_CONF_BACKLIGHT_BRIGHTNESS_DIM_BATT GPM_CONF_DIR "/backlight/brightness_dim_battery"
+
+/* buttons */
+#define GPM_CONF_BUTTON_LID_AC GPM_CONF_DIR "/buttons/lid_ac"
+#define GPM_CONF_BUTTON_LID_BATT GPM_CONF_DIR "/buttons/lid_battery"
+#define GPM_CONF_BUTTON_SUSPEND GPM_CONF_DIR "/buttons/suspend"
+#define GPM_CONF_BUTTON_HIBERNATE GPM_CONF_DIR "/buttons/hibernate"
+#define GPM_CONF_BUTTON_POWER GPM_CONF_DIR "/buttons/power"
+
+/* general */
+#define GPM_CONF_SCHEMA_VERSION GPM_CONF_DIR "/general/installed_schema"
+#define GPM_CONF_USE_TIME_POLICY GPM_CONF_DIR "/general/use_time_for_policy"
+#define GPM_CONF_USE_PROFILE_TIME GPM_CONF_DIR "/general/use_profile_time"
+#define GPM_CONF_NETWORKMANAGER_SLEEP GPM_CONF_DIR "/general/network_sleep"
+#define GPM_CONF_IDLE_CHECK_CPU GPM_CONF_DIR "/general/check_type_cpu"
+#define GPM_CONF_LAPTOP_USES_EXT_MON GPM_CONF_DIR "/general/using_external_monitor"
+
+/* lock */
+#define GPM_CONF_LOCK_USE_SCREENSAVER GPM_CONF_DIR "/lock/use_screensaver_settings"
+#define GPM_CONF_LOCK_ON_BLANK_SCREEN GPM_CONF_DIR "/lock/blank_screen"
+#define GPM_CONF_LOCK_ON_SUSPEND GPM_CONF_DIR "/lock/suspend"
+#define GPM_CONF_LOCK_ON_HIBERNATE GPM_CONF_DIR "/lock/hibernate"
+#define GPM_CONF_LOCK_MATE_KEYRING_SUSPEND GPM_CONF_DIR "/lock/mate_keyring_suspend"
+#define GPM_CONF_LOCK_MATE_KEYRING_HIBERNATE GPM_CONF_DIR "/lock/mate_keyring_hibernate"
+
+/* disks */
+#define GPM_CONF_DISKS_SPINDOWN_ENABLE_AC GPM_CONF_DIR "/disks/spindown_enable_ac"
+#define GPM_CONF_DISKS_SPINDOWN_ENABLE_BATT GPM_CONF_DIR "/disks/spindown_enable_battery"
+#define GPM_CONF_DISKS_SPINDOWN_TIMEOUT_AC GPM_CONF_DIR "/disks/spindown_timeout_ac"
+#define GPM_CONF_DISKS_SPINDOWN_TIMEOUT_BATT GPM_CONF_DIR "/disks/spindown_timeout_battery"
+
+/* notify */
+#define GPM_CONF_NOTIFY_PERHAPS_RECALL GPM_CONF_DIR "/notify/perhaps_recall"
+#define GPM_CONF_NOTIFY_LOW_CAPACITY GPM_CONF_DIR "/notify/low_capacity"
+#define GPM_CONF_NOTIFY_DISCHARGING GPM_CONF_DIR "/notify/discharging"
+#define GPM_CONF_NOTIFY_FULLY_CHARGED GPM_CONF_DIR "/notify/fully_charged"
+#define GPM_CONF_NOTIFY_SLEEP_FAILED GPM_CONF_DIR "/notify/sleep_failed"
+#define GPM_CONF_NOTIFY_SLEEP_FAILED_URI GPM_CONF_DIR "/notify/sleep_failed_uri"
+#define GPM_CONF_NOTIFY_LOW_POWER GPM_CONF_DIR "/notify/low_power"
+
+/* statistics */
+#define GPM_CONF_STATS_SHOW_AXIS_LABELS GPM_CONF_DIR "/statistics/show_axis_labels"
+#define GPM_CONF_STATS_SHOW_EVENTS GPM_CONF_DIR "/statistics/show_events"
+#define GPM_CONF_STATS_SMOOTH_DATA GPM_CONF_DIR "/statistics/smooth_data"
+#define GPM_CONF_STATS_GRAPH_TYPE GPM_CONF_DIR "/statistics/graph_type"
+#define GPM_CONF_STATS_MAX_TIME GPM_CONF_DIR "/statistics/data_max_time"
+
+/* thresholds */
+#define GPM_CONF_THRESH_PERCENTAGE_LOW GPM_CONF_DIR "/thresholds/percentage_low"
+#define GPM_CONF_THRESH_PERCENTAGE_CRITICAL GPM_CONF_DIR "/thresholds/percentage_critical"
+#define GPM_CONF_THRESH_PERCENTAGE_ACTION GPM_CONF_DIR "/thresholds/percentage_action"
+#define GPM_CONF_THRESH_TIME_LOW GPM_CONF_DIR "/thresholds/time_low"
+#define GPM_CONF_THRESH_TIME_CRITICAL GPM_CONF_DIR "/thresholds/time_critical"
+#define GPM_CONF_THRESH_TIME_ACTION GPM_CONF_DIR "/thresholds/time_action"
+
+/* timeout */
+#define GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC GPM_CONF_DIR "/timeout/sleep_computer_ac"
+#define GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT GPM_CONF_DIR "/timeout/sleep_computer_battery"
+#define GPM_CONF_TIMEOUT_SLEEP_COMPUTER_UPS GPM_CONF_DIR "/timeout/sleep_computer_ups"
+#define GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC GPM_CONF_DIR "/timeout/sleep_display_ac"
+#define GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT GPM_CONF_DIR "/timeout/sleep_display_battery"
+#define GPM_CONF_TIMEOUT_SLEEP_DISPLAY_UPS GPM_CONF_DIR "/timeout/sleep_display_ups"
+
+/* ui */
+#define GPM_CONF_UI_ICON_POLICY GPM_CONF_DIR "/ui/icon_policy"
+#define GPM_CONF_UI_ENABLE_SOUND GPM_CONF_DIR "/ui/enable_sound"
+#define GPM_CONF_UI_SHOW_ACTIONS GPM_CONF_DIR "/ui/show_actions"
+
+/* new info binary */
+#define GPM_CONF_INFO_HISTORY_TIME "/apps/mate-power-manager/info/history_time"
+#define GPM_CONF_INFO_HISTORY_TYPE "/apps/mate-power-manager/info/history_type"
+#define GPM_CONF_INFO_HISTORY_GRAPH_SMOOTH "/apps/mate-power-manager/info/history_graph_smooth"
+#define GPM_CONF_INFO_HISTORY_GRAPH_POINTS "/apps/mate-power-manager/info/history_graph_points"
+#define GPM_CONF_INFO_STATS_TYPE "/apps/mate-power-manager/info/stats_type"
+#define GPM_CONF_INFO_STATS_GRAPH_SMOOTH "/apps/mate-power-manager/info/stats_graph_smooth"
+#define GPM_CONF_INFO_STATS_GRAPH_POINTS "/apps/mate-power-manager/info/stats_graph_points"
+#define GPM_CONF_INFO_PAGE_NUMBER "/apps/mate-power-manager/info/page_number"
+#define GPM_CONF_INFO_LAST_DEVICE "/apps/mate-power-manager/info/last_device"
+
+/* mate-screensaver */
+#define GS_CONF_DIR "/apps/mate-screensaver"
+#define GS_PREF_LOCK_ENABLED GS_CONF_DIR "/lock_enabled"
+
+/* mate-session */
+#define GPM_CONF_IDLE_DELAY "/desktop/mate/session/idle_delay"
+
+typedef enum {
+ GPM_ICON_POLICY_ALWAYS,
+ GPM_ICON_POLICY_PRESENT,
+ GPM_ICON_POLICY_CHARGE,
+ GPM_ICON_POLICY_LOW,
+ GPM_ICON_POLICY_CRITICAL,
+ GPM_ICON_POLICY_NEVER
+} GpmIconPolicy;
+
+typedef enum {
+ GPM_ACTION_POLICY_BLANK,
+ GPM_ACTION_POLICY_SUSPEND,
+ GPM_ACTION_POLICY_SHUTDOWN,
+ GPM_ACTION_POLICY_HIBERNATE,
+ GPM_ACTION_POLICY_INTERACTIVE,
+ GPM_ACTION_POLICY_NOTHING
+} GpmActionPolicy;
+
+gchar *gpm_get_timestring (guint time);
+GpmIconPolicy gpm_icon_policy_from_string (const gchar *policy);
+const gchar *gpm_icon_policy_to_string (GpmIconPolicy policy);
+GpmActionPolicy gpm_action_policy_from_string (const gchar *policy);
+const gchar *gpm_action_policy_to_string (GpmActionPolicy policy);
+void gpm_help_display (const gchar *link_id);
+#ifdef EGG_TEST
+void gpm_common_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __GPMCOMMON_H */
diff --git a/src/gpm-control.c b/src/gpm-control.c
new file mode 100644
index 0000000..50212b8
--- /dev/null
+++ b/src/gpm-control.c
@@ -0,0 +1,347 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <mate-keyring.h>
+#include <mateconf/mateconf-client.h>
+#include <libupower-glib/upower.h>
+
+#include "egg-debug.h"
+#include "egg-console-kit.h"
+
+#include "gpm-screensaver.h"
+#include "gpm-common.h"
+#include "gpm-control.h"
+#include "gpm-networkmanager.h"
+
+#define GPM_CONTROL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_CONTROL, GpmControlPrivate))
+
+struct GpmControlPrivate
+{
+ MateConfClient *conf;
+ UpClient *client;
+};
+
+enum {
+ RESUME,
+ SLEEP,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_control_object = NULL;
+
+G_DEFINE_TYPE (GpmControl, gpm_control, G_TYPE_OBJECT)
+
+/**
+ * gpm_control_error_quark:
+ * Return value: Our personal error quark.
+ **/
+GQuark
+gpm_control_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("gpm_control_error");
+ return quark;
+}
+
+/**
+ * gpm_control_shutdown:
+ * @control: This class instance
+ *
+ * Shuts down the computer
+ **/
+gboolean
+gpm_control_shutdown (GpmControl *control, GError **error)
+{
+ gboolean ret;
+ EggConsoleKit *console;
+ console = egg_console_kit_new ();
+ ret = egg_console_kit_stop (console, error);
+ g_object_unref (console);
+ return ret;
+}
+
+/**
+ * gpm_control_get_lock_policy:
+ * @control: This class instance
+ * @policy: The policy mateconf string.
+ *
+ * This function finds out if we should lock the screen when we do an
+ * action. It is required as we can either use the mate-screensaver policy
+ * or the custom policy. See the yelp file for more information.
+ *
+ * Return value: TRUE if we should lock.
+ **/
+gboolean
+gpm_control_get_lock_policy (GpmControl *control, const gchar *policy)
+{
+ gboolean do_lock;
+ gboolean use_ss_setting;
+ /* This allows us to over-ride the custom lock settings set in mateconf
+ with a system default set in mate-screensaver.
+ See bug #331164 for all the juicy details. :-) */
+ use_ss_setting = mateconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_USE_SCREENSAVER, NULL);
+ if (use_ss_setting) {
+ do_lock = mateconf_client_get_bool (control->priv->conf, GS_PREF_LOCK_ENABLED, NULL);
+ egg_debug ("Using ScreenSaver settings (%i)", do_lock);
+ } else {
+ do_lock = mateconf_client_get_bool (control->priv->conf, policy, NULL);
+ egg_debug ("Using custom locking settings (%i)", do_lock);
+ }
+ return do_lock;
+}
+
+/**
+ * gpm_control_suspend:
+ **/
+gboolean
+gpm_control_suspend (GpmControl *control, GError **error)
+{
+ gboolean allowed;
+ gboolean ret = FALSE;
+ gboolean do_lock;
+ gboolean nm_sleep;
+ gboolean lock_mate_keyring;
+ MateKeyringResult keyres;
+ GpmScreensaver *screensaver;
+ guint32 throttle_cookie = 0;
+
+ screensaver = gpm_screensaver_new ();
+
+ g_object_get (control->priv->client,
+ "can-suspend", &allowed,
+ NULL);
+ if (!allowed) {
+ egg_debug ("cannot suspend as not allowed from policy");
+ g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot suspend");
+ goto out;
+ }
+
+ /* we should perhaps lock keyrings when sleeping #375681 */
+ lock_mate_keyring = mateconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_MATE_KEYRING_SUSPEND, NULL);
+ if (lock_mate_keyring) {
+ keyres = mate_keyring_lock_all_sync ();
+ if (keyres != MATE_KEYRING_RESULT_OK)
+ egg_warning ("could not lock keyring");
+ }
+
+ do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_SUSPEND);
+ if (do_lock) {
+ throttle_cookie = gpm_screensaver_add_throttle (screensaver, "suspend");
+ gpm_screensaver_lock (screensaver);
+ }
+
+ nm_sleep = mateconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
+ if (nm_sleep)
+ gpm_networkmanager_sleep ();
+
+ /* Do the suspend */
+ egg_debug ("emitting sleep");
+ g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_SUSPEND);
+
+ ret = up_client_suspend_sync (control->priv->client, NULL, error);
+
+ egg_debug ("emitting resume");
+ g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_SUSPEND);
+
+ if (do_lock) {
+ gpm_screensaver_poke (screensaver);
+ if (throttle_cookie)
+ gpm_screensaver_remove_throttle (screensaver, throttle_cookie);
+ }
+
+ nm_sleep = mateconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
+ if (nm_sleep)
+ gpm_networkmanager_wake ();
+
+out:
+ g_object_unref (screensaver);
+ return ret;
+}
+
+/**
+ * gpm_control_hibernate:
+ **/
+gboolean
+gpm_control_hibernate (GpmControl *control, GError **error)
+{
+ gboolean allowed;
+ gboolean ret = FALSE;
+ gboolean do_lock;
+ gboolean nm_sleep;
+ gboolean lock_mate_keyring;
+ MateKeyringResult keyres;
+ GpmScreensaver *screensaver;
+ guint32 throttle_cookie = 0;
+
+ screensaver = gpm_screensaver_new ();
+
+ g_object_get (control->priv->client,
+ "can-hibernate", &allowed,
+ NULL);
+ if (!allowed) {
+ egg_debug ("cannot hibernate as not allowed from policy");
+ g_set_error_literal (error, GPM_CONTROL_ERROR, GPM_CONTROL_ERROR_GENERAL, "Cannot hibernate");
+ goto out;
+ }
+
+ /* we should perhaps lock keyrings when sleeping #375681 */
+ lock_mate_keyring = mateconf_client_get_bool (control->priv->conf, GPM_CONF_LOCK_MATE_KEYRING_HIBERNATE, NULL);
+ if (lock_mate_keyring) {
+ keyres = mate_keyring_lock_all_sync ();
+ if (keyres != MATE_KEYRING_RESULT_OK) {
+ egg_warning ("could not lock keyring");
+ }
+ }
+
+ do_lock = gpm_control_get_lock_policy (control, GPM_CONF_LOCK_ON_HIBERNATE);
+ if (do_lock) {
+ throttle_cookie = gpm_screensaver_add_throttle (screensaver, "hibernate");
+ gpm_screensaver_lock (screensaver);
+ }
+
+ nm_sleep = mateconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
+ if (nm_sleep)
+ gpm_networkmanager_sleep ();
+
+ egg_debug ("emitting sleep");
+ g_signal_emit (control, signals [SLEEP], 0, GPM_CONTROL_ACTION_HIBERNATE);
+
+ ret = up_client_hibernate_sync (control->priv->client, NULL, error);
+
+ egg_debug ("emitting resume");
+ g_signal_emit (control, signals [RESUME], 0, GPM_CONTROL_ACTION_HIBERNATE);
+
+ if (do_lock) {
+ gpm_screensaver_poke (screensaver);
+ if (throttle_cookie)
+ gpm_screensaver_remove_throttle (screensaver, throttle_cookie);
+ }
+
+ nm_sleep = mateconf_client_get_bool (control->priv->conf, GPM_CONF_NETWORKMANAGER_SLEEP, NULL);
+ if (nm_sleep)
+ gpm_networkmanager_wake ();
+
+out:
+ g_object_unref (screensaver);
+ return ret;
+}
+
+/**
+ * gpm_control_finalize:
+ **/
+static void
+gpm_control_finalize (GObject *object)
+{
+ GpmControl *control;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_CONTROL (object));
+ control = GPM_CONTROL (object);
+
+ g_object_unref (control->priv->conf);
+ g_object_unref (control->priv->client);
+
+ g_return_if_fail (control->priv != NULL);
+ G_OBJECT_CLASS (gpm_control_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_control_class_init:
+ **/
+static void
+gpm_control_class_init (GpmControlClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_control_finalize;
+
+ signals [RESUME] =
+ g_signal_new ("resume",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmControlClass, resume),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals [SLEEP] =
+ g_signal_new ("sleep",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmControlClass, sleep),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+
+ g_type_class_add_private (klass, sizeof (GpmControlPrivate));
+}
+
+/**
+ * gpm_control_init:
+ * @control: This control class instance
+ **/
+static void
+gpm_control_init (GpmControl *control)
+{
+ control->priv = GPM_CONTROL_GET_PRIVATE (control);
+
+ control->priv->client = up_client_new ();
+ control->priv->conf = mateconf_client_get_default ();
+}
+
+/**
+ * gpm_control_new:
+ * Return value: A new control class instance.
+ **/
+GpmControl *
+gpm_control_new (void)
+{
+ if (gpm_control_object != NULL) {
+ g_object_ref (gpm_control_object);
+ } else {
+ gpm_control_object = g_object_new (GPM_TYPE_CONTROL, NULL);
+ g_object_add_weak_pointer (gpm_control_object, &gpm_control_object);
+ }
+ return GPM_CONTROL (gpm_control_object);
+}
+
diff --git a/src/gpm-control.h b/src/gpm-control.h
new file mode 100644
index 0000000..f4b36d7
--- /dev/null
+++ b/src/gpm-control.h
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_CONTROL_H
+#define __GPM_CONTROL_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_CONTROL (gpm_control_get_type ())
+#define GPM_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_CONTROL, GpmControl))
+#define GPM_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_CONTROL, GpmControlClass))
+#define GPM_IS_CONTROL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_CONTROL))
+#define GPM_IS_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_CONTROL))
+#define GPM_CONTROL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_CONTROL, GpmControlClass))
+
+typedef struct GpmControlPrivate GpmControlPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmControlPrivate *priv;
+} GpmControl;
+
+typedef enum
+{
+ GPM_CONTROL_ACTION_SUSPEND,
+ GPM_CONTROL_ACTION_HIBERNATE,
+ GPM_CONTROL_ACTION_LAST
+} GpmControlAction;
+
+typedef enum
+{
+ GPM_CONTROL_ERROR_GENERAL,
+ GPM_CONTROL_ERROR_LAST
+} GpmControlError;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* resume) (GpmControl *control,
+ GpmControlAction action);
+ void (* sleep) (GpmControl *control,
+ GpmControlAction action);
+ void (* sleep_failure) (GpmControl *control,
+ GpmControlAction action);
+ void (* request) (GpmControl *control,
+ const gchar **type);
+} GpmControlClass;
+
+#define GPM_CONTROL_ERROR gpm_control_error_quark ()
+
+GQuark gpm_control_error_quark (void);
+GType gpm_control_get_type (void);
+GpmControl *gpm_control_new (void);
+gboolean gpm_control_suspend (GpmControl *control,
+ GError **error);
+gboolean gpm_control_hibernate (GpmControl *control,
+ GError **error);
+gboolean gpm_control_shutdown (GpmControl *control,
+ GError **error);
+gboolean gpm_control_get_lock_policy (GpmControl *control,
+ const gchar *policy);
+
+G_END_DECLS
+
+#endif /* __GPM_CONTROL_H */
diff --git a/src/gpm-disks.c b/src/gpm-disks.c
new file mode 100644
index 0000000..eec3358
--- /dev/null
+++ b/src/gpm-disks.c
@@ -0,0 +1,209 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include "egg-debug.h"
+#include "gpm-disks.h"
+
+static void gpm_disks_finalize (GObject *object);
+
+#define GPM_DISKS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_DISKS, GpmDisksPrivate))
+
+struct GpmDisksPrivate
+{
+ DBusGProxy *proxy;
+ gchar *cookie;
+};
+
+static gpointer gpm_disks_object = NULL;
+
+G_DEFINE_TYPE (GpmDisks, gpm_disks, G_TYPE_OBJECT)
+
+/**
+ * gpm_disks_unregister:
+ **/
+static gboolean
+gpm_disks_unregister (GpmDisks *disks)
+{
+ gboolean ret = FALSE;
+ GError *error = NULL;
+
+ /* no UDisks */
+ if (disks->priv->proxy == NULL) {
+ egg_warning ("no UDisks");
+ goto out;
+ }
+
+ /* clear spindown timeouts */
+ ret = dbus_g_proxy_call (disks->priv->proxy, "DriveUnsetAllSpindownTimeouts", &error,
+ G_TYPE_STRING, disks->priv->cookie,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to clear spindown timeout: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ /* reset */
+ g_free (disks->priv->cookie);
+ disks->priv->cookie = NULL;
+
+ return ret;
+}
+
+/**
+ * gpm_disks_register:
+ **/
+static gboolean
+gpm_disks_register (GpmDisks *disks, gint timeout)
+{
+ gboolean ret = FALSE;
+ GError *error = NULL;
+ const gchar **options = {NULL};
+
+ /* no UDisks */
+ if (disks->priv->proxy == NULL) {
+ egg_warning ("no UDisks");
+ goto out;
+ }
+
+ /* set spindown timeouts */
+ ret = dbus_g_proxy_call (disks->priv->proxy, "DriveSetAllSpindownTimeouts", &error,
+ G_TYPE_INT, timeout,
+ G_TYPE_STRV, options,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &disks->priv->cookie,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to set spindown timeout: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gpm_disks_set_spindown_timeout:
+ **/
+gboolean
+gpm_disks_set_spindown_timeout (GpmDisks *disks, gint timeout)
+{
+ gboolean ret = TRUE;
+
+ /* get rid of last request */
+ if (disks->priv->cookie != NULL) {
+ egg_debug ("unregistering %s", disks->priv->cookie);
+ gpm_disks_unregister (disks);
+ }
+
+ /* is not enabled? */
+ if (timeout == 0) {
+ egg_debug ("disk spindown disabled");
+ goto out;
+ }
+
+ /* register */
+ ret = gpm_disks_register (disks, timeout);
+ if (ret)
+ egg_debug ("registered %s (%i)", disks->priv->cookie, timeout);
+out:
+ return ret;
+}
+
+/**
+ * gpm_disks_init:
+ */
+static void
+gpm_disks_init (GpmDisks *disks)
+{
+ GError *error = NULL;
+ DBusGConnection *connection;
+
+ disks->priv = GPM_DISKS_GET_PRIVATE (disks);
+
+ disks->priv->cookie = NULL;
+
+ /* get proxy to interface */
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ disks->priv->proxy = dbus_g_proxy_new_for_name_owner (connection,
+ "org.freedesktop.UDisks",
+ "/org/freedesktop/UDisks",
+ "org.freedesktop.UDisks", &error);
+ if (disks->priv->proxy == NULL) {
+ egg_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+/**
+ * gpm_disks_coldplug:
+ *
+ * @object: This disks instance
+ */
+static void
+gpm_disks_finalize (GObject *object)
+{
+ GpmDisks *disks;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_DISKS (object));
+ disks = GPM_DISKS (object);
+ g_return_if_fail (disks->priv != NULL);
+
+ g_free (disks->priv->cookie);
+ g_object_unref (disks->priv->proxy);
+
+ G_OBJECT_CLASS (gpm_disks_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_disks_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_disks_class_init (GpmDisksClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_disks_finalize;
+ g_type_class_add_private (klass, sizeof (GpmDisksPrivate));
+}
+
+/**
+ * gpm_disks_new:
+ * Return value: new #GpmDisks instance.
+ **/
+GpmDisks *
+gpm_disks_new (void)
+{
+ if (gpm_disks_object != NULL) {
+ g_object_ref (gpm_disks_object);
+ } else {
+ gpm_disks_object = g_object_new (GPM_TYPE_DISKS, NULL);
+ g_object_add_weak_pointer (gpm_disks_object, &gpm_disks_object);
+ }
+ return GPM_DISKS (gpm_disks_object);
+}
+
diff --git a/src/gpm-disks.h b/src/gpm-disks.h
new file mode 100644
index 0000000..df5bbb4
--- /dev/null
+++ b/src/gpm-disks.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_DISKS_H
+#define __GPM_DISKS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_DISKS (gpm_disks_get_type ())
+#define GPM_DISKS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_DISKS, GpmDisks))
+#define GPM_DISKS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_DISKS, GpmDisksClass))
+#define GPM_IS_DISKS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_DISKS))
+#define GPM_IS_DISKS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_DISKS))
+#define GPM_DISKS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_DISKS, GpmDisksClass))
+
+typedef struct GpmDisksPrivate GpmDisksPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmDisksPrivate *priv;
+} GpmDisks;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpmDisksClass;
+
+GType gpm_disks_get_type (void);
+GpmDisks *gpm_disks_new (void);
+
+gboolean gpm_disks_set_spindown_timeout (GpmDisks *disks,
+ gint timeout);
+
+G_END_DECLS
+
+#endif /* __GPM_DISKS_H */
diff --git a/src/gpm-dpms.c b/src/gpm-dpms.c
new file mode 100644
index 0000000..13928f9
--- /dev/null
+++ b/src/gpm-dpms.c
@@ -0,0 +1,474 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2006-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include <X11/Xproto.h>
+#include <X11/extensions/dpms.h>
+
+#include "egg-debug.h"
+#include "gpm-dpms.h"
+
+static void gpm_dpms_finalize (GObject *object);
+
+#define GPM_DPMS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_DPMS, GpmDpmsPrivate))
+
+/* until we get a nice event-emitting DPMS extension, we have to poll... */
+#define GPM_DPMS_POLL_TIME 10
+
+struct GpmDpmsPrivate
+{
+ gboolean dpms_capable;
+ GpmDpmsMode mode;
+ guint timer_id;
+ Display *display;
+};
+
+enum {
+ MODE_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_dpms_object = NULL;
+
+G_DEFINE_TYPE (GpmDpms, gpm_dpms, G_TYPE_OBJECT)
+
+/**
+ * gpm_dpms_error_quark:
+ **/
+GQuark
+gpm_dpms_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("gpm_dpms_error");
+ return quark;
+}
+
+/**
+ * gpm_dpms_x11_get_mode:
+ **/
+static gboolean
+gpm_dpms_x11_get_mode (GpmDpms *dpms, GpmDpmsMode *mode, GError **error)
+{
+ GpmDpmsMode result;
+ BOOL enabled = FALSE;
+ CARD16 state;
+
+ if (dpms->priv->dpms_capable == FALSE) {
+ /* Server or monitor can't DPMS -- assume the monitor is on. */
+ result = GPM_DPMS_MODE_ON;
+ goto out;
+ }
+
+ DPMSInfo (dpms->priv->display, &state, &enabled);
+ if (!enabled) {
+ /* Server says DPMS is disabled -- so the monitor is on. */
+ result = GPM_DPMS_MODE_ON;
+ goto out;
+ }
+
+ switch (state) {
+ case DPMSModeOn:
+ result = GPM_DPMS_MODE_ON;
+ break;
+ case DPMSModeStandby:
+ result = GPM_DPMS_MODE_STANDBY;
+ break;
+ case DPMSModeSuspend:
+ result = GPM_DPMS_MODE_SUSPEND;
+ break;
+ case DPMSModeOff:
+ result = GPM_DPMS_MODE_OFF;
+ break;
+ default:
+ result = GPM_DPMS_MODE_ON;
+ break;
+ }
+out:
+ if (mode)
+ *mode = result;
+ return TRUE;
+}
+
+/**
+ * gpm_dpms_x11_set_mode:
+ **/
+static gboolean
+gpm_dpms_x11_set_mode (GpmDpms *dpms, GpmDpmsMode mode, GError **error)
+{
+ GpmDpmsMode current_mode;
+ CARD16 state;
+ CARD16 current_state;
+ BOOL current_enabled;
+
+ if (!dpms->priv->dpms_capable) {
+ egg_debug ("not DPMS capable");
+ g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
+ "Display is not DPMS capable");
+ return FALSE;
+ }
+
+ if (!DPMSInfo (dpms->priv->display, &current_state, &current_enabled)) {
+ egg_debug ("couldn't get DPMS info");
+ g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
+ "Unable to get DPMS state");
+ return FALSE;
+ }
+
+ if (!current_enabled) {
+ egg_debug ("DPMS not enabled");
+ g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
+ "DPMS is not enabled");
+ return FALSE;
+ }
+
+ switch (mode) {
+ case GPM_DPMS_MODE_ON:
+ state = DPMSModeOn;
+ break;
+ case GPM_DPMS_MODE_STANDBY:
+ state = DPMSModeStandby;
+ break;
+ case GPM_DPMS_MODE_SUSPEND:
+ state = DPMSModeSuspend;
+ break;
+ case GPM_DPMS_MODE_OFF:
+ state = DPMSModeOff;
+ break;
+ default:
+ state = DPMSModeOn;
+ break;
+ }
+
+ gpm_dpms_x11_get_mode (dpms, &current_mode, NULL);
+ if (current_mode != mode) {
+ if (! DPMSForceLevel (dpms->priv->display, state)) {
+ g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
+ "Could not change DPMS mode");
+ return FALSE;
+ }
+ XSync (dpms->priv->display, FALSE);
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpm_dpms_mode_from_string:
+ **/
+GpmDpmsMode
+gpm_dpms_mode_from_string (const gchar *str)
+{
+ if (str == NULL)
+ return GPM_DPMS_MODE_UNKNOWN;
+ if (strcmp (str, "on") == 0)
+ return GPM_DPMS_MODE_ON;
+ if (strcmp (str, "standby") == 0)
+ return GPM_DPMS_MODE_STANDBY;
+ if (strcmp (str, "suspend") == 0)
+ return GPM_DPMS_MODE_SUSPEND;
+ if (strcmp (str, "off") == 0)
+ return GPM_DPMS_MODE_OFF;
+ return GPM_DPMS_MODE_UNKNOWN;
+}
+
+/**
+ * gpm_dpms_mode_to_string:
+ **/
+const gchar *
+gpm_dpms_mode_to_string (GpmDpmsMode mode)
+{
+ const gchar *str = NULL;
+
+ switch (mode) {
+ case GPM_DPMS_MODE_ON:
+ str = "on";
+ break;
+ case GPM_DPMS_MODE_STANDBY:
+ str = "standby";
+ break;
+ case GPM_DPMS_MODE_SUSPEND:
+ str = "suspend";
+ break;
+ case GPM_DPMS_MODE_OFF:
+ str = "off";
+ break;
+ default:
+ str = NULL;
+ break;
+ }
+ return str;
+}
+
+/**
+ * gpm_dpms_set_mode:
+ **/
+gboolean
+gpm_dpms_set_mode (GpmDpms *dpms, GpmDpmsMode mode, GError **error)
+{
+ gboolean ret;
+
+ g_return_val_if_fail (GPM_IS_DPMS (dpms), FALSE);
+
+ if (mode == GPM_DPMS_MODE_UNKNOWN) {
+ egg_debug ("mode unknown");
+ g_set_error (error, GPM_DPMS_ERROR, GPM_DPMS_ERROR_GENERAL,
+ "Unknown DPMS mode");
+ return FALSE;
+ }
+
+ ret = gpm_dpms_x11_set_mode (dpms, mode, error);
+ return ret;
+}
+
+/**
+ * gpm_dpms_get_mode:
+ **/
+gboolean
+gpm_dpms_get_mode (GpmDpms *dpms, GpmDpmsMode *mode, GError **error)
+{
+ gboolean ret;
+ if (mode)
+ *mode = GPM_DPMS_MODE_UNKNOWN;
+ ret = gpm_dpms_x11_get_mode (dpms, mode, error);
+ return ret;
+}
+
+/**
+ * gpm_dpms_poll_mode_cb:
+ **/
+static gboolean
+gpm_dpms_poll_mode_cb (GpmDpms *dpms)
+{
+ gboolean ret;
+ GpmDpmsMode mode;
+ GError *error = NULL;
+
+ /* Try again */
+ ret = gpm_dpms_x11_get_mode (dpms, &mode, &error);
+ if (!ret) {
+ g_clear_error (&error);
+ return TRUE;
+ }
+
+ if (mode != dpms->priv->mode) {
+ dpms->priv->mode = mode;
+ g_signal_emit (dpms, signals [MODE_CHANGED], 0, mode);
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpm_dpms_clear_timeouts:
+ **/
+static gboolean
+gpm_dpms_clear_timeouts (GpmDpms *dpms)
+{
+ gboolean ret = FALSE;
+
+ /* never going to work */
+ if (!dpms->priv->dpms_capable) {
+ egg_debug ("not DPMS capable");
+ goto out;
+ }
+
+ egg_debug ("set timeouts to zero");
+ ret = DPMSSetTimeouts (dpms->priv->display, 0, 0, 0);
+
+out:
+ return ret;
+}
+
+/**
+ * gpm_dpms_class_init:
+ **/
+static void
+gpm_dpms_class_init (GpmDpmsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gpm_dpms_finalize;
+
+ signals [MODE_CHANGED] =
+ g_signal_new ("mode-changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmDpmsClass, mode_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ g_type_class_add_private (klass, sizeof (GpmDpmsPrivate));
+}
+
+/**
+ * gpm_dpms_init:
+ **/
+static void
+gpm_dpms_init (GpmDpms *dpms)
+{
+ dpms->priv = GPM_DPMS_GET_PRIVATE (dpms);
+
+ /* DPMSCapable() can never change for a given display */
+ dpms->priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default());
+ dpms->priv->dpms_capable = DPMSCapable (dpms->priv->display);
+ dpms->priv->timer_id = g_timeout_add_seconds (GPM_DPMS_POLL_TIME, (GSourceFunc)gpm_dpms_poll_mode_cb, dpms);
+
+ /* ensure we clear the default timeouts (Standby: 1200s, Suspend: 1800s, Off: 2400s) */
+ gpm_dpms_clear_timeouts (dpms);
+}
+
+/**
+ * gpm_dpms_finalize:
+ **/
+static void
+gpm_dpms_finalize (GObject *object)
+{
+ GpmDpms *dpms;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_DPMS (object));
+
+ dpms = GPM_DPMS (object);
+
+ g_return_if_fail (dpms->priv != NULL);
+
+ if (dpms->priv->timer_id != 0)
+ g_source_remove (dpms->priv->timer_id);
+
+ G_OBJECT_CLASS (gpm_dpms_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_dpms_new:
+ **/
+GpmDpms *
+gpm_dpms_new (void)
+{
+ if (gpm_dpms_object != NULL) {
+ g_object_ref (gpm_dpms_object);
+ } else {
+ gpm_dpms_object = g_object_new (GPM_TYPE_DPMS, NULL);
+ g_object_add_weak_pointer (gpm_dpms_object, &gpm_dpms_object);
+ }
+ return GPM_DPMS (gpm_dpms_object);
+}
+
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+gpm_dpms_test (gpointer data)
+{
+ GpmDpms *dpms;
+ gboolean ret;
+ GError *error = NULL;
+ EggTest *test = (EggTest *) data;
+
+ if (!egg_test_start (test, "GpmDpms"))
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "get object");
+ dpms = gpm_dpms_new ();
+ if (dpms != NULL)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "got no object");
+
+ /************************************************************/
+ egg_test_title (test, "set on");
+ ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_ON, &error);
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed: %s", error->message);
+
+ g_usleep (2*1000*1000);
+
+ /************************************************************/
+ egg_test_title (test, "set STANDBY");
+ ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_STANDBY, &error);
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed: %s", error->message);
+
+ g_usleep (2*1000*1000);
+
+ /************************************************************/
+ egg_test_title (test, "set SUSPEND");
+ ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_SUSPEND, &error);
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed: %s", error->message);
+
+ g_usleep (2*1000*1000);
+
+ /************************************************************/
+ egg_test_title (test, "set OFF");
+ ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_OFF, &error);
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed: %s", error->message);
+
+ g_usleep (2*1000*1000);
+
+ /************************************************************/
+ egg_test_title (test, "set on");
+ ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_ON, &error);
+ if (ret)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "failed: %s", error->message);
+
+ g_usleep (2*1000*1000);
+
+ g_object_unref (dpms);
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/gpm-dpms.h b/src/gpm-dpms.h
new file mode 100644
index 0000000..95cd226
--- /dev/null
+++ b/src/gpm-dpms.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2004-2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2006-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_DPMS_H
+#define __GPM_DPMS_H
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_DPMS (gpm_dpms_get_type ())
+#define GPM_DPMS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_DPMS, GpmDpms))
+#define GPM_DPMS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_DPMS, GpmDpmsClass))
+#define GPM_IS_DPMS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_DPMS))
+#define GPM_IS_DPMS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_DPMS))
+#define GPM_DPMS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_DPMS, GpmDpmsClass))
+
+typedef enum {
+ GPM_DPMS_MODE_ON,
+ GPM_DPMS_MODE_STANDBY,
+ GPM_DPMS_MODE_SUSPEND,
+ GPM_DPMS_MODE_OFF,
+ GPM_DPMS_MODE_UNKNOWN
+} GpmDpmsMode;
+
+typedef struct GpmDpmsPrivate GpmDpmsPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmDpmsPrivate *priv;
+} GpmDpms;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* mode_changed) (GpmDpms *dpms,
+ GpmDpmsMode mode);
+} GpmDpmsClass;
+
+typedef enum
+{
+ GPM_DPMS_ERROR_GENERAL
+} GpmDpmsError;
+
+#define GPM_DPMS_ERROR gpm_dpms_error_quark ()
+
+GQuark gpm_dpms_error_quark (void);
+GType gpm_dpms_get_type (void);
+GpmDpms *gpm_dpms_new (void);
+gboolean gpm_dpms_get_mode (GpmDpms *dpms,
+ GpmDpmsMode *mode,
+ GError **error);
+gboolean gpm_dpms_set_mode (GpmDpms *dpms,
+ GpmDpmsMode mode,
+ GError **error);
+const gchar *gpm_dpms_mode_to_string (GpmDpmsMode mode);
+GpmDpmsMode gpm_dpms_mode_from_string (const gchar *mode);
+void gpm_dpms_test (gpointer data);
+
+G_END_DECLS
+
+#endif /* __GPM_DPMS_H */
diff --git a/src/gpm-engine.c b/src/gpm-engine.c
new file mode 100644
index 0000000..1ca78b8
--- /dev/null
+++ b/src/gpm-engine.c
@@ -0,0 +1,1267 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <mateconf/mateconf-client.h>
+#include <libupower-glib/upower.h>
+
+#include "egg-debug.h"
+
+#include "gpm-common.h"
+#include "gpm-upower.h"
+#include "gpm-marshal.h"
+#include "gpm-engine.h"
+#include "gpm-stock-icons.h"
+#include "gpm-prefs-server.h"
+#include "gpm-phone.h"
+
+static void gpm_engine_finalize (GObject *object);
+
+#define GPM_ENGINE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_ENGINE, GpmEnginePrivate))
+#define GPM_ENGINE_RESUME_DELAY 2*1000
+#define GPM_ENGINE_WARN_ACCURACY 20
+
+struct GpmEnginePrivate
+{
+ MateConfClient *conf;
+ UpClient *client;
+ UpDevice *battery_composite;
+ GPtrArray *array;
+ GpmPhone *phone;
+ GpmIconPolicy icon_policy;
+ gchar *previous_icon;
+ gchar *previous_summary;
+
+ gboolean use_time_primary;
+ gboolean time_is_accurate;
+
+ guint low_percentage;
+ guint critical_percentage;
+ guint action_percentage;
+ guint low_time;
+ guint critical_time;
+ guint action_time;
+};
+
+enum {
+ ICON_CHANGED,
+ SUMMARY_CHANGED,
+ FULLY_CHARGED,
+ CHARGE_LOW,
+ CHARGE_CRITICAL,
+ CHARGE_ACTION,
+ DISCHARGING,
+ LOW_CAPACITY,
+ PERHAPS_RECALL,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_engine_object = NULL;
+
+G_DEFINE_TYPE (GpmEngine, gpm_engine, G_TYPE_OBJECT)
+
+static UpDevice *gpm_engine_get_composite_device (GpmEngine *engine, UpDevice *original_device);
+static UpDevice *gpm_engine_update_composite_device (GpmEngine *engine, UpDevice *original_device);
+
+typedef enum {
+ GPM_ENGINE_WARNING_NONE = 0,
+ GPM_ENGINE_WARNING_DISCHARGING = 1,
+ GPM_ENGINE_WARNING_LOW = 2,
+ GPM_ENGINE_WARNING_CRITICAL = 3,
+ GPM_ENGINE_WARNING_ACTION = 4
+} GpmEngineWarning;
+
+/**
+ * gpm_engine_get_warning_csr:
+ **/
+static GpmEngineWarning
+gpm_engine_get_warning_csr (GpmEngine *engine, UpDevice *device)
+{
+ gdouble percentage;
+
+ /* get device properties */
+ g_object_get (device, "percentage", &percentage, NULL);
+
+ if (percentage < 26.0f)
+ return GPM_ENGINE_WARNING_LOW;
+ else if (percentage < 13.0f)
+ return GPM_ENGINE_WARNING_CRITICAL;
+ return GPM_ENGINE_WARNING_NONE;
+}
+
+/**
+ * gpm_engine_get_warning_percentage:
+ **/
+static GpmEngineWarning
+gpm_engine_get_warning_percentage (GpmEngine *engine, UpDevice *device)
+{
+ gdouble percentage;
+
+ /* get device properties */
+ g_object_get (device, "percentage", &percentage, NULL);
+
+ if (percentage <= engine->priv->action_percentage)
+ return GPM_ENGINE_WARNING_ACTION;
+ if (percentage <= engine->priv->critical_percentage)
+ return GPM_ENGINE_WARNING_CRITICAL;
+ if (percentage <= engine->priv->low_percentage)
+ return GPM_ENGINE_WARNING_LOW;
+ return GPM_ENGINE_WARNING_NONE;
+}
+
+/**
+ * gpm_engine_get_warning_time:
+ **/
+static GpmEngineWarning
+gpm_engine_get_warning_time (GpmEngine *engine, UpDevice *device)
+{
+ UpDeviceKind kind;
+ gint64 time_to_empty;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "time-to-empty", &time_to_empty,
+ NULL);
+
+ /* this is probably an error condition */
+ if (time_to_empty == 0) {
+ egg_debug ("time zero, falling back to percentage for %s", up_device_kind_to_string (kind));
+ return gpm_engine_get_warning_percentage (engine, device);
+ }
+
+ if (time_to_empty <= engine->priv->action_time)
+ return GPM_ENGINE_WARNING_ACTION;
+ if (time_to_empty <= engine->priv->critical_time)
+ return GPM_ENGINE_WARNING_CRITICAL;
+ if (time_to_empty <= engine->priv->low_time)
+ return GPM_ENGINE_WARNING_LOW;
+ return GPM_ENGINE_WARNING_NONE;
+}
+
+/**
+ * gpm_engine_get_warning:
+ *
+ * This gets the possible engine state for the device according to the
+ * policy, which could be per-percent, or per-time.
+ *
+ * Return value: A GpmEngine state, e.g. GPM_ENGINE_WARNING_DISCHARGING
+ **/
+static GpmEngineWarning
+gpm_engine_get_warning (GpmEngine *engine, UpDevice *device)
+{
+ UpDeviceKind kind;
+ UpDeviceState state;
+ GpmEngineWarning warning_type;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ NULL);
+
+ /* default to no engine */
+ warning_type = GPM_ENGINE_WARNING_NONE;
+
+ /* if the device in question is on ac, don't give a warning */
+ if (state == UP_DEVICE_STATE_CHARGING)
+ goto out;
+
+ if (kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD) {
+
+ warning_type = gpm_engine_get_warning_csr (engine, device);
+
+ } else if (kind == UP_DEVICE_KIND_UPS ||
+#if UP_CHECK_VERSION(0,9,5)
+ kind == UP_DEVICE_KIND_MEDIA_PLAYER ||
+ kind == UP_DEVICE_KIND_TABLET ||
+ kind == UP_DEVICE_KIND_COMPUTER ||
+#endif
+ kind == UP_DEVICE_KIND_PDA) {
+
+ warning_type = gpm_engine_get_warning_percentage (engine, device);
+
+ } else if (kind == UP_DEVICE_KIND_PHONE) {
+
+ warning_type = gpm_engine_get_warning_percentage (engine, device);
+
+ } else if (kind == UP_DEVICE_KIND_BATTERY) {
+ /* only use the time when it is accurate, and MateConf is not disabled */
+ if (engine->priv->use_time_primary)
+ warning_type = gpm_engine_get_warning_time (engine, device);
+ else
+ warning_type = gpm_engine_get_warning_percentage (engine, device);
+ }
+
+ /* If we have no important engines, we should test for discharging */
+ if (warning_type == GPM_ENGINE_WARNING_NONE) {
+ if (state == UP_DEVICE_STATE_DISCHARGING)
+ warning_type = GPM_ENGINE_WARNING_DISCHARGING;
+ }
+
+ out:
+ return warning_type;
+}
+
+/**
+ * gpm_engine_get_summary:
+ * @engine: This engine class instance
+ * @string: The returned string
+ *
+ * Returns the complete tooltip ready for display
+ **/
+gchar *
+gpm_engine_get_summary (GpmEngine *engine)
+{
+ guint i;
+ GPtrArray *array;
+ UpDevice *device;
+ UpDeviceState state;
+ GString *tooltip = NULL;
+ gchar *part;
+ gboolean is_present;
+
+ g_return_val_if_fail (GPM_IS_ENGINE (engine), NULL);
+
+ /* need to get AC state */
+ tooltip = g_string_new ("");
+
+ /* do we have specific device types? */
+ array = engine->priv->array;
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+ g_object_get (device,
+ "is-present", &is_present,
+ "state", &state,
+ NULL);
+ if (!is_present)
+ continue;
+ if (state == UP_DEVICE_STATE_EMPTY)
+ continue;
+ part = gpm_upower_get_device_summary (device);
+ if (part != NULL)
+ g_string_append_printf (tooltip, "%s\n", part);
+ g_free (part);
+ }
+
+ /* remove the last \n */
+ g_string_truncate (tooltip, tooltip->len-1);
+
+ egg_debug ("tooltip: %s", tooltip->str);
+
+ return g_string_free (tooltip, FALSE);
+}
+
+/**
+ * gpm_engine_get_icon_priv:
+ *
+ * Returns the icon
+ **/
+static gchar *
+gpm_engine_get_icon_priv (GpmEngine *engine, UpDeviceKind device_kind, GpmEngineWarning warning, gboolean use_state)
+{
+ guint i;
+ GPtrArray *array;
+ UpDevice *device;
+ GpmEngineWarning warning_temp;
+ UpDeviceKind kind;
+ UpDeviceState state;
+ gboolean is_present;
+
+ /* do we have specific device types? */
+ array = engine->priv->array;
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "is-present", &is_present,
+ NULL);
+
+ /* if battery then use composite device to cope with multiple batteries */
+ if (kind == UP_DEVICE_KIND_BATTERY)
+ device = gpm_engine_get_composite_device (engine, device);
+
+ warning_temp = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-warning-old"));
+ if (kind == device_kind && is_present) {
+ if (warning != GPM_ENGINE_WARNING_NONE) {
+ if (warning_temp == warning)
+ return gpm_upower_get_device_icon (device);
+ continue;
+ }
+ if (use_state) {
+ if (state == UP_DEVICE_STATE_CHARGING || state == UP_DEVICE_STATE_DISCHARGING)
+ return gpm_upower_get_device_icon (device);
+ continue;
+ }
+ return gpm_upower_get_device_icon (device);
+ }
+ }
+ return NULL;
+}
+
+/**
+ * gpm_engine_get_icon:
+ *
+ * Returns the icon
+ **/
+gchar *
+gpm_engine_get_icon (GpmEngine *engine)
+{
+ gchar *icon = NULL;
+
+ g_return_val_if_fail (GPM_IS_ENGINE (engine), NULL);
+
+ /* policy */
+ if (engine->priv->icon_policy == GPM_ICON_POLICY_NEVER) {
+ egg_debug ("no icon allowed, so no icon will be displayed.");
+ return NULL;
+ }
+
+ /* we try CRITICAL: BATTERY, UPS, MOUSE, KEYBOARD */
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_CRITICAL, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_CRITICAL, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_MOUSE, GPM_ENGINE_WARNING_CRITICAL, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_KEYBOARD, GPM_ENGINE_WARNING_CRITICAL, FALSE);
+ if (icon != NULL)
+ return icon;
+
+ /* policy */
+ if (engine->priv->icon_policy == GPM_ICON_POLICY_CRITICAL) {
+ egg_debug ("no devices critical, so no icon will be displayed.");
+ return NULL;
+ }
+
+ /* we try CRITICAL: BATTERY, UPS, MOUSE, KEYBOARD */
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_LOW, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_LOW, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_MOUSE, GPM_ENGINE_WARNING_LOW, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_KEYBOARD, GPM_ENGINE_WARNING_LOW, FALSE);
+ if (icon != NULL)
+ return icon;
+
+ /* policy */
+ if (engine->priv->icon_policy == GPM_ICON_POLICY_LOW) {
+ egg_debug ("no devices low, so no icon will be displayed.");
+ return NULL;
+ }
+
+ /* we try (DIS)CHARGING: BATTERY, UPS */
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_NONE, TRUE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_NONE, TRUE);
+ if (icon != NULL)
+ return icon;
+
+ /* policy */
+ if (engine->priv->icon_policy == GPM_ICON_POLICY_CHARGE) {
+ egg_debug ("no devices (dis)charging, so no icon will be displayed.");
+ return NULL;
+ }
+
+ /* we try PRESENT: BATTERY, UPS */
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_BATTERY, GPM_ENGINE_WARNING_NONE, FALSE);
+ if (icon != NULL)
+ return icon;
+ icon = gpm_engine_get_icon_priv (engine, UP_DEVICE_KIND_UPS, GPM_ENGINE_WARNING_NONE, FALSE);
+ if (icon != NULL)
+ return icon;
+
+ /* policy */
+ if (engine->priv->icon_policy == GPM_ICON_POLICY_PRESENT) {
+ egg_debug ("no devices present, so no icon will be displayed.");
+ return NULL;
+ }
+
+ /* we fallback to the ac_adapter icon */
+ egg_debug ("Using fallback");
+ return g_strdup (GPM_STOCK_AC_ADAPTER);
+}
+
+/**
+ * gpm_engine_recalculate_state_icon:
+ */
+static gboolean
+gpm_engine_recalculate_state_icon (GpmEngine *engine)
+{
+ gchar *icon;
+
+ g_return_val_if_fail (engine != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_ENGINE (engine), FALSE);
+
+ /* show a different icon if we are disconnected */
+ icon = gpm_engine_get_icon (engine);
+ if (icon == NULL) {
+ /* none before, now none */
+ if (engine->priv->previous_icon == NULL)
+ return FALSE;
+ /* icon before, now none */
+ egg_debug ("** EMIT: icon-changed: none");
+ g_signal_emit (engine, signals [ICON_CHANGED], 0, NULL);
+
+ g_free (engine->priv->previous_icon);
+ engine->priv->previous_icon = NULL;
+ return TRUE;
+ }
+
+ /* no icon before, now icon */
+ if (engine->priv->previous_icon == NULL) {
+ egg_debug ("** EMIT: icon-changed: %s", icon);
+ g_signal_emit (engine, signals [ICON_CHANGED], 0, icon);
+ engine->priv->previous_icon = icon;
+ return TRUE;
+ }
+
+ /* icon before, now different */
+ if (strcmp (engine->priv->previous_icon, icon) != 0) {
+ g_free (engine->priv->previous_icon);
+ engine->priv->previous_icon = icon;
+ egg_debug ("** EMIT: icon-changed: %s", icon);
+ g_signal_emit (engine, signals [ICON_CHANGED], 0, icon);
+ return TRUE;
+ }
+
+ egg_debug ("no change");
+ /* nothing to do */
+ g_free (icon);
+ return FALSE;
+}
+
+/**
+ * gpm_engine_recalculate_state_summary:
+ */
+static gboolean
+gpm_engine_recalculate_state_summary (GpmEngine *engine)
+{
+ gchar *summary;
+
+ summary = gpm_engine_get_summary (engine);
+ if (engine->priv->previous_summary == NULL) {
+ engine->priv->previous_summary = summary;
+ egg_debug ("** EMIT: summary-changed(1): %s", summary);
+ g_signal_emit (engine, signals [SUMMARY_CHANGED], 0, summary);
+ return TRUE;
+ }
+
+ if (strcmp (engine->priv->previous_summary, summary) != 0) {
+ g_free (engine->priv->previous_summary);
+ engine->priv->previous_summary = summary;
+ egg_debug ("** EMIT: summary-changed(2): %s", summary);
+ g_signal_emit (engine, signals [SUMMARY_CHANGED], 0, summary);
+ return TRUE;
+ }
+ egg_debug ("no change");
+ /* nothing to do */
+ g_free (summary);
+ return FALSE;
+}
+
+/**
+ * gpm_engine_recalculate_state:
+ */
+static void
+gpm_engine_recalculate_state (GpmEngine *engine)
+{
+
+ g_return_if_fail (engine != NULL);
+ g_return_if_fail (GPM_IS_ENGINE (engine));
+
+ gpm_engine_recalculate_state_icon (engine);
+ gpm_engine_recalculate_state_summary (engine);
+}
+
+/**
+ * gpm_engine_conf_key_changed_cb:
+ **/
+static void
+gpm_engine_conf_key_changed_cb (MateConfClient *conf, guint cnxn_id, MateConfEntry *entry, GpmEngine *engine)
+{
+ MateConfValue *value;
+ gchar *icon_policy;
+
+ if (entry == NULL)
+ return;
+ value = mateconf_entry_get_value (entry);
+ if (value == NULL)
+ return;
+
+ if (strcmp (entry->key, GPM_CONF_USE_TIME_POLICY) == 0) {
+
+ engine->priv->use_time_primary = mateconf_value_get_bool (value);
+
+ } else if (strcmp (entry->key, GPM_CONF_UI_ICON_POLICY) == 0) {
+
+ /* do we want to display the icon in the tray */
+ icon_policy = mateconf_client_get_string (conf, GPM_CONF_UI_ICON_POLICY, NULL);
+ engine->priv->icon_policy = gpm_icon_policy_from_string (icon_policy);
+ g_free (icon_policy);
+
+ /* perhaps change icon */
+ gpm_engine_recalculate_state_icon (engine);
+ }
+}
+
+/**
+ * gpm_engine_device_check_capacity:
+ **/
+static gboolean
+gpm_engine_device_check_capacity (GpmEngine *engine, UpDevice *device)
+{
+ gboolean ret;
+ UpDeviceKind kind;
+ gdouble capacity;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "capacity", &capacity,
+ NULL);
+
+ /* not laptop battery */
+ if (kind != UP_DEVICE_KIND_BATTERY)
+ return FALSE;
+
+ /* capacity okay */
+ if (capacity > 50.0f)
+ return FALSE;
+
+ /* capacity invalid */
+ if (capacity < 1.0f)
+ return FALSE;
+
+ /* only emit this if specified in mateconf */
+ ret = mateconf_client_get_bool (engine->priv->conf, GPM_CONF_NOTIFY_LOW_CAPACITY, NULL);
+ if (ret) {
+ egg_debug ("** EMIT: low-capacity");
+ g_signal_emit (engine, signals [LOW_CAPACITY], 0, device);
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_engine_get_composite_device:
+ **/
+static UpDevice *
+gpm_engine_get_composite_device (GpmEngine *engine, UpDevice *original_device)
+{
+ guint battery_devices = 0;
+ GPtrArray *array;
+ UpDevice *device;
+ UpDeviceKind kind;
+ guint i;
+
+ /* find out how many batteries in the system */
+ array = engine->priv->array;
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+ g_object_get (device,
+ "kind", &kind,
+ NULL);
+ if (kind == UP_DEVICE_KIND_BATTERY)
+ battery_devices++;
+ }
+
+ /* just use the original device if only one primary battery */
+ if (battery_devices <= 1) {
+ egg_debug ("using original device as only one primary battery");
+ device = original_device;
+ goto out;
+ }
+
+ /* use the composite device */
+ device = engine->priv->battery_composite;
+out:
+ /* return composite device or original device */
+ return device;
+}
+
+/**
+ * gpm_engine_update_composite_device:
+ **/
+static UpDevice *
+gpm_engine_update_composite_device (GpmEngine *engine, UpDevice *original_device)
+{
+ guint i;
+ gdouble percentage = 0.0;
+ gdouble energy = 0.0;
+ gdouble energy_full = 0.0;
+ gdouble energy_rate = 0.0;
+ gdouble energy_total = 0.0;
+ gdouble energy_full_total = 0.0;
+ gdouble energy_rate_total = 0.0;
+ gint64 time_to_empty = 0;
+ gint64 time_to_full = 0;
+ guint battery_devices = 0;
+ gboolean is_charging = FALSE;
+ gboolean is_discharging = FALSE;
+ gboolean is_fully_charged = TRUE;
+ GPtrArray *array;
+ UpDevice *device;
+ UpDeviceState state;
+ UpDeviceKind kind;
+ gboolean debug;
+ gchar *text;
+
+ /* are we printing to console? */
+ debug = egg_debug_enabled ();
+
+ /* update the composite device */
+ array = engine->priv->array;
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "energy", &energy,
+ "energy-full", &energy_full,
+ "energy-rate", &energy_rate,
+ NULL);
+ if (kind != UP_DEVICE_KIND_BATTERY)
+ continue;
+
+ if (debug) {
+ text = up_device_to_text (device);
+ egg_debug ("printing device %i:\n%s", i, text);
+ g_free (text);
+ }
+
+ /* one of these will be charging or discharging */
+ if (state == UP_DEVICE_STATE_CHARGING)
+ is_charging = TRUE;
+ if (state == UP_DEVICE_STATE_DISCHARGING)
+ is_discharging = TRUE;
+ if (state != UP_DEVICE_STATE_FULLY_CHARGED)
+ is_fully_charged = FALSE;
+
+ /* sum up composite */
+ energy_total += energy;
+ energy_full_total += energy_full;
+ energy_rate_total += energy_rate;
+ battery_devices++;
+ }
+
+ /* just use the original device if only one primary battery */
+ if (battery_devices == 1) {
+ egg_debug ("using original device as only one primary battery");
+ device = original_device;
+ goto out;
+ }
+
+ /* use percentage weighted for each battery capacity */
+ percentage = 100.0 * energy_total / energy_full_total;
+
+ /* set composite state */
+ if (is_charging)
+ state = UP_DEVICE_STATE_CHARGING;
+ else if (is_discharging)
+ state = UP_DEVICE_STATE_DISCHARGING;
+ else if (is_fully_charged)
+ state = UP_DEVICE_STATE_FULLY_CHARGED;
+ else
+ state = UP_DEVICE_STATE_UNKNOWN;
+
+ /* calculate a quick and dirty time remaining value */
+ if (energy_rate_total > 0) {
+ if (state == UP_DEVICE_STATE_DISCHARGING)
+ time_to_empty = 3600 * (energy_total / energy_rate_total);
+ else if (state == UP_DEVICE_STATE_CHARGING)
+ time_to_full = 3600 * ((energy_full_total - energy_total) / energy_rate_total);
+ }
+
+ /* okay, we can use the composite device */
+ device = engine->priv->battery_composite;
+
+ egg_debug ("printing composite device");
+ g_object_set (device,
+ "energy", energy,
+ "energy-full", energy_full,
+ "energy-rate", energy_rate,
+ "time-to-empty", time_to_empty,
+ "time-to-full", time_to_full,
+ "percentage", percentage,
+ "state", state,
+ NULL);
+ if (debug) {
+ text = up_device_to_text (device);
+ egg_debug ("composite:\n%s", text);
+ g_free (text);
+ }
+
+ /* force update of icon */
+ gpm_engine_recalculate_state_icon (engine);
+out:
+ /* return composite device or original device */
+ return device;
+}
+
+/**
+ * gpm_engine_device_add:
+ **/
+static void
+gpm_engine_device_add (GpmEngine *engine, UpDevice *device)
+{
+ GpmEngineWarning warning;
+ UpDeviceState state;
+ UpDeviceKind kind;
+ UpDevice *composite;
+
+ /* assign warning */
+ warning = gpm_engine_get_warning (engine, device);
+ g_object_set_data (G_OBJECT(device), "engine-warning-old", GUINT_TO_POINTER(warning));
+
+ /* check capacity */
+ gpm_engine_device_check_capacity (engine, device);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ NULL);
+
+ /* add old state for transitions */
+ egg_debug ("adding %s with state %s", up_device_get_object_path (device), up_device_state_to_string (state));
+ g_object_set_data (G_OBJECT(device), "engine-state-old", GUINT_TO_POINTER(state));
+
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ egg_debug ("updating because we added a device");
+ composite = gpm_engine_update_composite_device (engine, device);
+
+ /* get the same values for the composite device */
+ warning = gpm_engine_get_warning (engine, composite);
+ g_object_set_data (G_OBJECT(composite), "engine-warning-old", GUINT_TO_POINTER(warning));
+ g_object_get (composite, "state", &state, NULL);
+ g_object_set_data (G_OBJECT(composite), "engine-state-old", GUINT_TO_POINTER(state));
+ }
+}
+
+/**
+ * gpm_engine_check_recall:
+ **/
+static gboolean
+gpm_engine_check_recall (GpmEngine *engine, UpDevice *device)
+{
+ UpDeviceKind kind;
+ gboolean recall_notice = FALSE;
+ gchar *recall_vendor = NULL;
+ gchar *recall_url = NULL;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "recall-notice", &recall_notice,
+ "recall-vendor", &recall_vendor,
+ "recall-url", &recall_url,
+ NULL);
+
+ /* not battery */
+ if (kind != UP_DEVICE_KIND_BATTERY)
+ goto out;
+
+ /* no recall data */
+ if (!recall_notice)
+ goto out;
+
+ /* emit signal for manager */
+ egg_debug ("** EMIT: perhaps-recall");
+ g_signal_emit (engine, signals [PERHAPS_RECALL], 0, device, recall_vendor, recall_url);
+out:
+ g_free (recall_vendor);
+ g_free (recall_url);
+ return recall_notice;
+}
+
+/**
+ * gpm_engine_coldplug_idle_cb:
+ **/
+static gboolean
+gpm_engine_coldplug_idle_cb (GpmEngine *engine)
+{
+ guint i;
+ GPtrArray *array;
+ gboolean has_battery = FALSE;
+ gboolean has_ups = FALSE;
+ GpmPrefsServer *prefs_server;
+ UpDevice *device;
+ UpDeviceKind kind;
+ gboolean ret;
+ GError *error = NULL;
+
+ g_return_val_if_fail (engine != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_ENGINE (engine), FALSE);
+
+ /* get devices from UPower */
+ ret = up_client_enumerate_devices_sync (engine->priv->client, NULL, &error);
+ if (!ret) {
+ egg_error ("failed to get device list: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ engine->priv->array = up_client_get_devices (engine->priv->client);
+
+ /* do we have specific device types? */
+ array = engine->priv->array;
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ NULL);
+
+ if (kind == UP_DEVICE_KIND_BATTERY)
+ has_battery = TRUE;
+ else if (kind == UP_DEVICE_KIND_UPS)
+ has_ups = TRUE;
+ }
+
+ /* only show the battery prefs section if we have batteries */
+ prefs_server = gpm_prefs_server_new ();
+ if (has_battery)
+ gpm_prefs_server_set_capability (prefs_server, GPM_PREFS_SERVER_BATTERY);
+ if (has_ups)
+ gpm_prefs_server_set_capability (prefs_server, GPM_PREFS_SERVER_UPS);
+ g_object_unref (prefs_server);
+
+ /* connected mobile phones */
+ gpm_phone_coldplug (engine->priv->phone);
+
+ gpm_engine_recalculate_state (engine);
+
+ /* add to database */
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+ gpm_engine_device_add (engine, device);
+ gpm_engine_check_recall (engine, device);
+ }
+out:
+ /* never repeat */
+ return FALSE;
+}
+
+/**
+ * gpm_engine_device_added_cb:
+ **/
+static void
+gpm_engine_device_added_cb (UpClient *client, UpDevice *device, GpmEngine *engine)
+{
+ /* add to list */
+ g_ptr_array_add (engine->priv->array, g_object_ref (device));
+ gpm_engine_check_recall (engine, device);
+
+ gpm_engine_recalculate_state (engine);
+}
+
+/**
+ * gpm_engine_device_removed_cb:
+ **/
+static void
+gpm_engine_device_removed_cb (UpClient *client, UpDevice *device, GpmEngine *engine)
+{
+ gboolean ret;
+ ret = g_ptr_array_remove (engine->priv->array, device);
+ if (!ret)
+ return;
+ gpm_engine_recalculate_state (engine);
+}
+
+
+/**
+ * gpm_engine_device_changed_cb:
+ **/
+static void
+gpm_engine_device_changed_cb (UpClient *client, UpDevice *device, GpmEngine *engine)
+{
+ UpDeviceKind kind;
+ UpDeviceState state;
+ UpDeviceState state_old;
+ GpmEngineWarning warning_old;
+ GpmEngineWarning warning;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ NULL);
+
+ /* if battery then use composite device to cope with multiple batteries */
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ egg_debug ("updating because %s changed", up_device_get_object_path (device));
+ device = gpm_engine_update_composite_device (engine, device);
+ }
+
+ /* get device properties (may be composite) */
+ g_object_get (device,
+ "state", &state,
+ NULL);
+
+ egg_debug ("%s state is now %s", up_device_get_object_path (device), up_device_state_to_string (state));
+
+ /* see if any interesting state changes have happened */
+ state_old = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-state-old"));
+ if (state_old != state) {
+ if (state == UP_DEVICE_STATE_DISCHARGING) {
+ egg_debug ("** EMIT: discharging");
+ g_signal_emit (engine, signals [DISCHARGING], 0, device);
+ } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) {
+ egg_debug ("** EMIT: fully charged");
+ g_signal_emit (engine, signals [FULLY_CHARGED], 0, device);
+ }
+
+ /* save new state */
+ g_object_set_data (G_OBJECT(device), "engine-state-old", GUINT_TO_POINTER(state));
+ }
+
+ /* check the warning state has not changed */
+ warning_old = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(device), "engine-warning-old"));
+ warning = gpm_engine_get_warning (engine, device);
+ if (warning != warning_old) {
+ if (warning == GPM_ENGINE_WARNING_LOW) {
+ egg_debug ("** EMIT: charge-low");
+ g_signal_emit (engine, signals [CHARGE_LOW], 0, device);
+ } else if (warning == GPM_ENGINE_WARNING_CRITICAL) {
+ egg_debug ("** EMIT: charge-critical");
+ g_signal_emit (engine, signals [CHARGE_CRITICAL], 0, device);
+ } else if (warning == GPM_ENGINE_WARNING_ACTION) {
+ egg_debug ("** EMIT: charge-action");
+ g_signal_emit (engine, signals [CHARGE_ACTION], 0, device);
+ }
+ /* save new state */
+ g_object_set_data (G_OBJECT(device), "engine-warning-old", GUINT_TO_POINTER(warning));
+ }
+
+ gpm_engine_recalculate_state (engine);
+}
+
+/**
+ * gpm_engine_get_devices:
+ *
+ * Return value: the UpDevice array, free with g_ptr_array_unref()
+ **/
+GPtrArray *
+gpm_engine_get_devices (GpmEngine *engine)
+{
+ return g_ptr_array_ref (engine->priv->array);
+}
+
+/**
+ * phone_device_added_cb:
+ **/
+static void
+phone_device_added_cb (GpmPhone *phone, guint idx, GpmEngine *engine)
+{
+ UpDevice *device;
+ device = up_device_new ();
+
+ egg_debug ("phone added %i", idx);
+
+ /* get device properties */
+ g_object_set (device,
+ "kind", UP_DEVICE_KIND_PHONE,
+ "is-rechargeable", TRUE,
+ "native-path", g_strdup_printf ("dummy:phone_%i", idx),
+ "is-present", TRUE,
+ NULL);
+
+ /* state changed */
+ gpm_engine_device_add (engine, device);
+ g_ptr_array_add (engine->priv->array, g_object_ref (device));
+ gpm_engine_recalculate_state (engine);
+}
+
+/**
+ * phone_device_removed_cb:
+ **/
+static void
+phone_device_removed_cb (GpmPhone *phone, guint idx, GpmEngine *engine)
+{
+ guint i;
+ UpDevice *device;
+ UpDeviceKind kind;
+
+ egg_debug ("phone removed %i", idx);
+
+ for (i=0; i<engine->priv->array->len; i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ NULL);
+
+ if (kind == UP_DEVICE_KIND_PHONE) {
+ g_ptr_array_remove_index (engine->priv->array, i);
+ break;
+ }
+ }
+
+ /* state changed */
+ gpm_engine_recalculate_state (engine);
+}
+
+/**
+ * phone_device_refresh_cb:
+ **/
+static void
+phone_device_refresh_cb (GpmPhone *phone, guint idx, GpmEngine *engine)
+{
+ guint i;
+ UpDevice *device;
+ UpDeviceKind kind;
+ UpDeviceState state;
+ gboolean is_present;
+ gdouble percentage;
+
+ egg_debug ("phone refresh %i", idx);
+
+ for (i=0; i<engine->priv->array->len; i++) {
+ device = g_ptr_array_index (engine->priv->array, i);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "percentage", &percentage,
+ "is-present", &is_present,
+ NULL);
+
+ if (kind == UP_DEVICE_KIND_PHONE) {
+ is_present = gpm_phone_get_present (phone, idx);
+ state = gpm_phone_get_on_ac (phone, idx) ? UP_DEVICE_STATE_CHARGING : UP_DEVICE_STATE_DISCHARGING;
+ percentage = gpm_phone_get_percentage (phone, idx);
+ break;
+ }
+ }
+
+ /* state changed */
+ gpm_engine_recalculate_state (engine);
+}
+
+/**
+ * gpm_engine_init:
+ * @engine: This class instance
+ **/
+static void
+gpm_engine_init (GpmEngine *engine)
+{
+ gchar *icon_policy;
+
+ engine->priv = GPM_ENGINE_GET_PRIVATE (engine);
+
+ engine->priv->array = g_ptr_array_new_with_free_func (g_object_unref);
+ engine->priv->client = up_client_new ();
+ g_signal_connect (engine->priv->client, "device-added",
+ G_CALLBACK (gpm_engine_device_added_cb), engine);
+ g_signal_connect (engine->priv->client, "device-removed",
+ G_CALLBACK (gpm_engine_device_removed_cb), engine);
+ g_signal_connect (engine->priv->client, "device-changed",
+ G_CALLBACK (gpm_engine_device_changed_cb), engine);
+
+ engine->priv->conf = mateconf_client_get_default ();
+ mateconf_client_notify_add (engine->priv->conf, GPM_CONF_DIR,
+ (MateConfClientNotifyFunc) gpm_engine_conf_key_changed_cb,
+ engine, NULL, NULL);
+
+ engine->priv->phone = gpm_phone_new ();
+ g_signal_connect (engine->priv->phone, "device-added",
+ G_CALLBACK (phone_device_added_cb), engine);
+ g_signal_connect (engine->priv->phone, "device-removed",
+ G_CALLBACK (phone_device_removed_cb), engine);
+ g_signal_connect (engine->priv->phone, "device-refresh",
+ G_CALLBACK (phone_device_refresh_cb), engine);
+
+ /* create a fake virtual composite battery */
+ engine->priv->battery_composite = up_device_new ();
+ g_object_set (engine->priv->battery_composite,
+ "kind", UP_DEVICE_KIND_BATTERY,
+ "is-rechargeable", TRUE,
+ "native-path", "dummy:composite_battery",
+ "power-supply", TRUE,
+ "is-present", TRUE,
+ NULL);
+
+ engine->priv->previous_icon = NULL;
+ engine->priv->previous_summary = NULL;
+
+ /* do we want to display the icon in the tray */
+ icon_policy = mateconf_client_get_string (engine->priv->conf, GPM_CONF_UI_ICON_POLICY, NULL);
+ engine->priv->icon_policy = gpm_icon_policy_from_string (icon_policy);
+ g_free (icon_policy);
+
+ /* get percentage policy */
+ engine->priv->low_percentage = mateconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_PERCENTAGE_LOW, NULL);
+ engine->priv->critical_percentage = mateconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_PERCENTAGE_CRITICAL, NULL);
+ engine->priv->action_percentage = mateconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_PERCENTAGE_ACTION, NULL);
+
+ /* get time policy */
+ engine->priv->low_time = mateconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_TIME_LOW, NULL);
+ engine->priv->critical_time = mateconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_TIME_CRITICAL, NULL);
+ engine->priv->action_time = mateconf_client_get_int (engine->priv->conf, GPM_CONF_THRESH_TIME_ACTION, NULL);
+
+ /* we can disable this if the time remaining is inaccurate or just plain wrong */
+ engine->priv->use_time_primary = mateconf_client_get_bool (engine->priv->conf, GPM_CONF_USE_TIME_POLICY, NULL);
+ if (engine->priv->use_time_primary)
+ egg_debug ("Using per-time notification policy");
+ else
+ egg_debug ("Using percentage notification policy");
+
+ g_idle_add ((GSourceFunc) gpm_engine_coldplug_idle_cb, engine);
+}
+
+/**
+ * gpm_engine_class_init:
+ * @engine: This class instance
+ **/
+static void
+gpm_engine_class_init (GpmEngineClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_engine_finalize;
+ g_type_class_add_private (klass, sizeof (GpmEnginePrivate));
+
+ signals [ICON_CHANGED] =
+ g_signal_new ("icon-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, icon_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+ signals [SUMMARY_CHANGED] =
+ g_signal_new ("summary-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, summary_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+ signals [LOW_CAPACITY] =
+ g_signal_new ("low-capacity",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, low_capacity),
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals [PERHAPS_RECALL] =
+ g_signal_new ("perhaps-recall",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, perhaps_recall),
+ NULL, NULL, gpm_marshal_VOID__POINTER_STRING_STRING,
+ G_TYPE_NONE,
+ 3, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING);
+ signals [FULLY_CHARGED] =
+ g_signal_new ("fully-charged",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, fully_charged),
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals [DISCHARGING] =
+ g_signal_new ("discharging",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, discharging),
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals [CHARGE_ACTION] =
+ g_signal_new ("charge-action",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, charge_action),
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals [CHARGE_LOW] =
+ g_signal_new ("charge-low",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, charge_low),
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals [CHARGE_CRITICAL] =
+ g_signal_new ("charge-critical",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmEngineClass, charge_critical),
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+}
+
+/**
+ * gpm_engine_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_engine_finalize (GObject *object)
+{
+ GpmEngine *engine;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_ENGINE (object));
+
+ engine = GPM_ENGINE (object);
+ engine->priv = GPM_ENGINE_GET_PRIVATE (engine);
+
+ g_ptr_array_unref (engine->priv->array);
+ g_object_unref (engine->priv->client);
+ g_object_unref (engine->priv->phone);
+ g_object_unref (engine->priv->battery_composite);
+
+ g_free (engine->priv->previous_icon);
+ g_free (engine->priv->previous_summary);
+
+ G_OBJECT_CLASS (gpm_engine_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_engine_new:
+ * Return value: new class instance.
+ **/
+GpmEngine *
+gpm_engine_new (void)
+{
+ if (gpm_engine_object != NULL) {
+ g_object_ref (gpm_engine_object);
+ } else {
+ gpm_engine_object = g_object_new (GPM_TYPE_ENGINE, NULL);
+ g_object_add_weak_pointer (gpm_engine_object, &gpm_engine_object);
+ }
+ return GPM_ENGINE (gpm_engine_object);
+
+}
+
diff --git a/src/gpm-engine.h b/src/gpm-engine.h
new file mode 100644
index 0000000..be1ccd6
--- /dev/null
+++ b/src/gpm-engine.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_ENGINE_H
+#define __GPM_ENGINE_H
+
+#include <glib-object.h>
+#include <libupower-glib/upower.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_ENGINE (gpm_engine_get_type ())
+#define GPM_ENGINE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_ENGINE, GpmEngine))
+#define GPM_ENGINE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_ENGINE, GpmEngineClass))
+#define GPM_IS_ENGINE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_ENGINE))
+#define GPM_IS_ENGINE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_ENGINE))
+#define GPM_ENGINE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_ENGINE, GpmEngineClass))
+
+typedef struct GpmEnginePrivate GpmEnginePrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmEnginePrivate *priv;
+} GpmEngine;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* icon_changed) (GpmEngine *engine,
+ gchar *icon);
+ void (* summary_changed) (GpmEngine *engine,
+ gchar *status);
+ void (* perhaps_recall) (GpmEngine *engine,
+ UpDevice *device,
+ const gchar *oem_vendor,
+ const gchar *website);
+ void (* low_capacity) (GpmEngine *engine,
+ UpDevice *device);
+ void (* charge_low) (GpmEngine *engine,
+ UpDevice *device);
+ void (* charge_critical) (GpmEngine *engine,
+ UpDevice *device);
+ void (* charge_action) (GpmEngine *engine,
+ UpDevice *device);
+ void (* fully_charged) (GpmEngine *engine,
+ UpDevice *device);
+ void (* discharging) (GpmEngine *engine,
+ UpDevice *device);
+} GpmEngineClass;
+
+GType gpm_engine_get_type (void);
+GpmEngine *gpm_engine_new (void);
+gchar *gpm_engine_get_icon (GpmEngine *engine);
+gchar *gpm_engine_get_summary (GpmEngine *engine);
+GPtrArray *gpm_engine_get_devices (GpmEngine *engine);
+
+G_END_DECLS
+
+#endif /* __GPM_ENGINE_H */
+
diff --git a/src/gpm-graph-widget.c b/src/gpm-graph-widget.c
new file mode 100644
index 0000000..a9ba689
--- /dev/null
+++ b/src/gpm-graph-widget.c
@@ -0,0 +1,1170 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include <gtk/gtk.h>
+#include <pango/pangocairo.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+
+#include "gpm-common.h"
+#include "gpm-point-obj.h"
+#include "gpm-graph-widget.h"
+
+#include "egg-debug.h"
+#include "egg-color.h"
+#include "egg-precision.h"
+
+G_DEFINE_TYPE (GpmGraphWidget, gpm_graph_widget, GTK_TYPE_DRAWING_AREA);
+#define GPM_GRAPH_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_GRAPH_WIDGET, GpmGraphWidgetPrivate))
+#define GPM_GRAPH_WIDGET_FONT "Sans 8"
+
+struct GpmGraphWidgetPrivate
+{
+ gboolean use_grid;
+ gboolean use_legend;
+ gboolean autorange_x;
+ gboolean autorange_y;
+
+ GSList *key_data; /* lines */
+
+ gint stop_x;
+ gint stop_y;
+ gint start_x;
+ gint start_y;
+ gint box_x; /* size of the white box, not the widget */
+ gint box_y;
+ gint box_width;
+ gint box_height;
+
+ gfloat unit_x; /* 10th width of graph */
+ gfloat unit_y; /* 10th width of graph */
+
+ GpmGraphWidgetType type_x;
+ GpmGraphWidgetType type_y;
+ gchar *title;
+
+ cairo_t *cr;
+ PangoLayout *layout;
+
+ GPtrArray *data_list;
+ GPtrArray *plot_list;
+};
+
+static gboolean gpm_graph_widget_expose (GtkWidget *graph, GdkEventExpose *event);
+static void gpm_graph_widget_finalize (GObject *object);
+
+enum
+{
+ PROP_0,
+ PROP_USE_LEGEND,
+ PROP_USE_GRID,
+ PROP_TYPE_X,
+ PROP_TYPE_Y,
+ PROP_AUTORANGE_X,
+ PROP_AUTORANGE_Y,
+ PROP_START_X,
+ PROP_START_Y,
+ PROP_STOP_X,
+ PROP_STOP_Y,
+};
+
+/**
+ * gpm_graph_widget_key_data_clear:
+ **/
+static gboolean
+gpm_graph_widget_key_data_clear (GpmGraphWidget *graph)
+{
+ GpmGraphWidgetKeyData *keyitem;
+ guint i;
+
+ g_return_val_if_fail (GPM_IS_GRAPH_WIDGET (graph), FALSE);
+
+ /* remove items in list and free */
+ for (i=0; i<g_slist_length (graph->priv->key_data); i++) {
+ keyitem = (GpmGraphWidgetKeyData *) g_slist_nth_data (graph->priv->key_data, i);
+ g_free (keyitem->desc);
+ g_free (keyitem);
+ }
+ g_slist_free (graph->priv->key_data);
+ graph->priv->key_data = NULL;
+
+ return TRUE;
+}
+
+/**
+ * gpm_graph_widget_key_data_add:
+ **/
+gboolean
+gpm_graph_widget_key_data_add (GpmGraphWidget *graph, guint32 color, const gchar *desc)
+{
+ GpmGraphWidgetKeyData *keyitem;
+
+ g_return_val_if_fail (GPM_IS_GRAPH_WIDGET (graph), FALSE);
+
+ egg_debug ("add to list %s", desc);
+ keyitem = g_new0 (GpmGraphWidgetKeyData, 1);
+
+ keyitem->color = color;
+ keyitem->desc = g_strdup (desc);
+
+ graph->priv->key_data = g_slist_append (graph->priv->key_data, (gpointer) keyitem);
+ return TRUE;
+}
+
+/**
+ * up_graph_get_property:
+ **/
+static void
+up_graph_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GpmGraphWidget *graph = GPM_GRAPH_WIDGET (object);
+ switch (prop_id) {
+ case PROP_USE_LEGEND:
+ g_value_set_boolean (value, graph->priv->use_legend);
+ break;
+ case PROP_USE_GRID:
+ g_value_set_boolean (value, graph->priv->use_grid);
+ break;
+ case PROP_TYPE_X:
+ g_value_set_uint (value, graph->priv->type_x);
+ break;
+ case PROP_TYPE_Y:
+ g_value_set_uint (value, graph->priv->type_y);
+ break;
+ case PROP_AUTORANGE_X:
+ g_value_set_boolean (value, graph->priv->autorange_x);
+ break;
+ case PROP_AUTORANGE_Y:
+ g_value_set_boolean (value, graph->priv->autorange_y);
+ break;
+ case PROP_START_X:
+ g_value_set_int (value, graph->priv->start_x);
+ break;
+ case PROP_START_Y:
+ g_value_set_int (value, graph->priv->start_y);
+ break;
+ case PROP_STOP_X:
+ g_value_set_int (value, graph->priv->stop_x);
+ break;
+ case PROP_STOP_Y:
+ g_value_set_int (value, graph->priv->stop_y);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * up_graph_set_property:
+ **/
+static void
+up_graph_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GpmGraphWidget *graph = GPM_GRAPH_WIDGET (object);
+
+ switch (prop_id) {
+ case PROP_USE_LEGEND:
+ graph->priv->use_legend = g_value_get_boolean (value);
+ break;
+ case PROP_USE_GRID:
+ graph->priv->use_grid = g_value_get_boolean (value);
+ break;
+ case PROP_TYPE_X:
+ graph->priv->type_x = g_value_get_uint (value);
+ break;
+ case PROP_TYPE_Y:
+ graph->priv->type_y = g_value_get_uint (value);
+ break;
+ case PROP_AUTORANGE_X:
+ graph->priv->autorange_x = g_value_get_boolean (value);
+ break;
+ case PROP_AUTORANGE_Y:
+ graph->priv->autorange_y = g_value_get_boolean (value);
+ break;
+ case PROP_START_X:
+ graph->priv->start_x = g_value_get_int (value);
+ break;
+ case PROP_START_Y:
+ graph->priv->start_y = g_value_get_int (value);
+ break;
+ case PROP_STOP_X:
+ graph->priv->stop_x = g_value_get_int (value);
+ break;
+ case PROP_STOP_Y:
+ graph->priv->stop_y = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+
+ /* refresh widget */
+ gtk_widget_hide (GTK_WIDGET (graph));
+ gtk_widget_show (GTK_WIDGET (graph));
+}
+
+/**
+ * gpm_graph_widget_class_init:
+ * @class: This graph class instance
+ **/
+static void
+gpm_graph_widget_class_init (GpmGraphWidgetClass *class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ widget_class->expose_event = gpm_graph_widget_expose;
+ object_class->get_property = up_graph_get_property;
+ object_class->set_property = up_graph_set_property;
+ object_class->finalize = gpm_graph_widget_finalize;
+
+ g_type_class_add_private (class, sizeof (GpmGraphWidgetPrivate));
+
+ /* properties */
+ g_object_class_install_property (object_class,
+ PROP_USE_LEGEND,
+ g_param_spec_boolean ("use-legend", NULL, NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_USE_GRID,
+ g_param_spec_boolean ("use-grid", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_TYPE_X,
+ g_param_spec_uint ("type-x", NULL, NULL,
+ GPM_GRAPH_WIDGET_TYPE_INVALID,
+ GPM_GRAPH_WIDGET_TYPE_UNKNOWN,
+ GPM_GRAPH_WIDGET_TYPE_TIME,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_TYPE_Y,
+ g_param_spec_uint ("type-y", NULL, NULL,
+ GPM_GRAPH_WIDGET_TYPE_INVALID,
+ GPM_GRAPH_WIDGET_TYPE_UNKNOWN,
+ GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_AUTORANGE_X,
+ g_param_spec_boolean ("autorange-x", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_AUTORANGE_Y,
+ g_param_spec_boolean ("autorange-y", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_START_X,
+ g_param_spec_int ("start-x", NULL, NULL,
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_START_Y,
+ g_param_spec_int ("start-y", NULL, NULL,
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_STOP_X,
+ g_param_spec_int ("stop-x", NULL, NULL,
+ G_MININT, G_MAXINT, 60,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_STOP_Y,
+ g_param_spec_int ("stop-y", NULL, NULL,
+ G_MININT, G_MAXINT, 100,
+ G_PARAM_READWRITE));
+}
+
+/**
+ * gpm_graph_widget_init:
+ * @graph: This class instance
+ **/
+static void
+gpm_graph_widget_init (GpmGraphWidget *graph)
+{
+ PangoFontMap *fontmap;
+ PangoContext *context;
+ PangoFontDescription *desc;
+
+ graph->priv = GPM_GRAPH_WIDGET_GET_PRIVATE (graph);
+ graph->priv->start_x = 0;
+ graph->priv->start_y = 0;
+ graph->priv->stop_x = 60;
+ graph->priv->stop_y = 100;
+ graph->priv->use_grid = TRUE;
+ graph->priv->use_legend = FALSE;
+ graph->priv->data_list = g_ptr_array_new_with_free_func ((GDestroyNotify) g_ptr_array_unref);
+ graph->priv->plot_list = g_ptr_array_new ();
+ graph->priv->key_data = NULL;
+ graph->priv->type_x = GPM_GRAPH_WIDGET_TYPE_TIME;
+ graph->priv->type_y = GPM_GRAPH_WIDGET_TYPE_PERCENTAGE;
+
+ /* do pango stuff */
+ fontmap = pango_cairo_font_map_get_default ();
+ context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+ pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
+
+ graph->priv->layout = pango_layout_new (context);
+ desc = pango_font_description_from_string (GPM_GRAPH_WIDGET_FONT);
+ pango_layout_set_font_description (graph->priv->layout, desc);
+ pango_font_description_free (desc);
+}
+
+/**
+ * gpm_graph_widget_data_clear:
+ **/
+gboolean
+gpm_graph_widget_data_clear (GpmGraphWidget *graph)
+{
+ g_return_val_if_fail (GPM_IS_GRAPH_WIDGET (graph), FALSE);
+
+ g_ptr_array_set_size (graph->priv->data_list, 0);
+ g_ptr_array_set_size (graph->priv->plot_list, 0);
+
+ return TRUE;
+}
+
+/**
+ * gpm_graph_widget_finalize:
+ * @object: This graph class instance
+ **/
+static void
+gpm_graph_widget_finalize (GObject *object)
+{
+ PangoContext *context;
+ GpmGraphWidget *graph = (GpmGraphWidget*) object;
+
+ /* clear key and data */
+ gpm_graph_widget_key_data_clear (graph);
+ gpm_graph_widget_data_clear (graph);
+
+ /* free data */
+ g_ptr_array_unref (graph->priv->data_list);
+ g_ptr_array_unref (graph->priv->plot_list);
+
+ context = pango_layout_get_context (graph->priv->layout);
+ g_object_unref (graph->priv->layout);
+ g_object_unref (context);
+ G_OBJECT_CLASS (gpm_graph_widget_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_graph_widget_data_assign:
+ * @graph: This class instance
+ * @data: an array of GpmPointObj's
+ *
+ * Sets the data for the graph
+ **/
+gboolean
+gpm_graph_widget_data_assign (GpmGraphWidget *graph, GpmGraphWidgetPlot plot, GPtrArray *data)
+{
+ GPtrArray *copy;
+ GpmPointObj *obj;
+ guint i;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_GRAPH_WIDGET (graph), FALSE);
+
+ /* make a deep copy */
+ copy = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
+ for (i=0; i<data->len; i++) {
+ obj = gpm_point_obj_copy (g_ptr_array_index (data, i));
+ g_ptr_array_add (copy, obj);
+ }
+
+ /* get the new data */
+ g_ptr_array_add (graph->priv->data_list, copy);
+ g_ptr_array_add (graph->priv->plot_list, GUINT_TO_POINTER(plot));
+
+ /* refresh */
+ gtk_widget_queue_draw (GTK_WIDGET (graph));
+
+ return TRUE;
+}
+
+/**
+ * gpm_get_axis_label:
+ * @axis: The axis type, e.g. GPM_GRAPH_WIDGET_TYPE_TIME
+ * @value: The data value, e.g. 120
+ *
+ * Unit is:
+ * GPM_GRAPH_WIDGET_TYPE_TIME: seconds
+ * GPM_GRAPH_WIDGET_TYPE_POWER: Wh (not Ah)
+ * GPM_GRAPH_WIDGET_TYPE_PERCENTAGE: %
+ *
+ * Return value: a string value depending on the axis type and the value.
+ **/
+static gchar *
+gpm_get_axis_label (GpmGraphWidgetType axis, gfloat value)
+{
+ gchar *text = NULL;
+ if (axis == GPM_GRAPH_WIDGET_TYPE_TIME) {
+ gint time_s = abs((gint) value);
+ gint minutes = time_s / 60;
+ gint seconds = time_s - (minutes * 60);
+ gint hours = minutes / 60;
+ gint days = hours / 24;
+ minutes = minutes - (hours * 60);
+ hours = hours - (days * 24);
+ if (days > 0) {
+ if (hours == 0) {
+ /*Translators: This is %i days*/
+ text = g_strdup_printf (_("%id"), days);
+ } else {
+ /*Translators: This is %i days %02i hours*/
+ text = g_strdup_printf (_("%id%02ih"), days, hours);
+ }
+ } else if (hours > 0) {
+ if (minutes == 0) {
+ /*Translators: This is %i hours*/
+ text = g_strdup_printf (_("%ih"), hours);
+ } else {
+ /*Translators: This is %i hours %02i minutes*/
+ text = g_strdup_printf (_("%ih%02im"), hours, minutes);
+ }
+ } else if (minutes > 0) {
+ if (seconds == 0) {
+ /*Translators: This is %2i minutes*/
+ text = g_strdup_printf (_("%2im"), minutes);
+ } else {
+ /*Translators: This is %2i minutes %02i seconds*/
+ text = g_strdup_printf (_("%2im%02i"), minutes, seconds);
+ }
+ } else {
+ /*Translators: This is %2i seconds*/
+ text = g_strdup_printf (_("%2is"), seconds);
+ }
+ } else if (axis == GPM_GRAPH_WIDGET_TYPE_PERCENTAGE) {
+ /*Translators: This is %i Percentage*/
+ text = g_strdup_printf (_("%i%%"), (gint) value);
+ } else if (axis == GPM_GRAPH_WIDGET_TYPE_POWER) {
+ /*Translators: This is %.1f Watts*/
+ text = g_strdup_printf (_("%.1fW"), value);
+ } else if (axis == GPM_GRAPH_WIDGET_TYPE_FACTOR) {
+ text = g_strdup_printf ("%.1f", value);
+ } else if (axis == GPM_GRAPH_WIDGET_TYPE_VOLTAGE) {
+ /*Translators: This is %.1f Volts*/
+ text = g_strdup_printf (_("%.1fV"), value);
+ } else {
+ text = g_strdup_printf ("%i", (gint) value);
+ }
+ return text;
+}
+
+/**
+ * gpm_graph_widget_draw_grid:
+ * @graph: This class instance
+ * @cr: Cairo drawing context
+ *
+ * Draw the 10x10 dotted grid onto the graph.
+ **/
+static void
+gpm_graph_widget_draw_grid (GpmGraphWidget *graph, cairo_t *cr)
+{
+ guint i;
+ gfloat b;
+ gdouble dotted[] = {1., 2.};
+ gfloat divwidth = (gfloat)graph->priv->box_width / 10.0f;
+ gfloat divheight = (gfloat)graph->priv->box_height / 10.0f;
+
+ cairo_save (cr);
+
+ cairo_set_line_width (cr, 1);
+ cairo_set_dash (cr, dotted, 2, 0.0);
+
+ /* do vertical lines */
+ cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+ for (i=1; i<10; i++) {
+ b = graph->priv->box_x + ((gfloat) i * divwidth);
+ cairo_move_to (cr, (gint)b + 0.5f, graph->priv->box_y);
+ cairo_line_to (cr, (gint)b + 0.5f, graph->priv->box_y + graph->priv->box_height);
+ cairo_stroke (cr);
+ }
+
+ /* do horizontal lines */
+ for (i=1; i<10; i++) {
+ b = graph->priv->box_y + ((gfloat) i * divheight);
+ cairo_move_to (cr, graph->priv->box_x, (gint)b + 0.5f);
+ cairo_line_to (cr, graph->priv->box_x + graph->priv->box_width, (int)b + 0.5f);
+ cairo_stroke (cr);
+ }
+
+ cairo_restore (cr);
+}
+
+/**
+ * gpm_graph_widget_draw_labels:
+ * @graph: This class instance
+ * @cr: Cairo drawing context
+ *
+ * Draw the X and the Y labels onto the graph.
+ **/
+static void
+gpm_graph_widget_draw_labels (GpmGraphWidget *graph, cairo_t *cr)
+{
+ guint i;
+ gfloat b;
+ gchar *text;
+ gfloat value;
+ gfloat divwidth = (gfloat)graph->priv->box_width / 10.0f;
+ gfloat divheight = (gfloat)graph->priv->box_height / 10.0f;
+ gint length_x = graph->priv->stop_x - graph->priv->start_x;
+ gint length_y = graph->priv->stop_y - graph->priv->start_y;
+ PangoRectangle ink_rect, logical_rect;
+ gfloat offsetx = 0;
+ gfloat offsety = 0;
+
+ cairo_save (cr);
+
+ /* do x text */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ for (i=0; i<11; i++) {
+ b = graph->priv->box_x + ((gfloat) i * divwidth);
+ value = ((length_x / 10.0f) * (gfloat) i) + (gfloat) graph->priv->start_x;
+ text = gpm_get_axis_label (graph->priv->type_x, value);
+
+ pango_layout_set_text (graph->priv->layout, text, -1);
+ pango_layout_get_pixel_extents (graph->priv->layout, &ink_rect, &logical_rect);
+ /* have data points 0 and 10 bounded, but 1..9 centered */
+ if (i == 0)
+ offsetx = 2.0;
+ else if (i == 10)
+ offsetx = ink_rect.width;
+ else
+ offsetx = (ink_rect.width / 2.0f);
+
+ cairo_move_to (cr, b - offsetx,
+ graph->priv->box_y + graph->priv->box_height + 2.0);
+
+ pango_cairo_show_layout (cr, graph->priv->layout);
+ g_free (text);
+ }
+
+ /* do y text */
+ for (i=0; i<11; i++) {
+ b = graph->priv->box_y + ((gfloat) i * divheight);
+ value = ((gfloat) length_y / 10.0f) * (10 - (gfloat) i) + graph->priv->start_y;
+ text = gpm_get_axis_label (graph->priv->type_y, value);
+
+ pango_layout_set_text (graph->priv->layout, text, -1);
+ pango_layout_get_pixel_extents (graph->priv->layout, &ink_rect, &logical_rect);
+
+ /* have data points 0 and 10 bounded, but 1..9 centered */
+ if (i == 10)
+ offsety = 0;
+ else if (i == 0)
+ offsety = ink_rect.height;
+ else
+ offsety = (ink_rect.height / 2.0f);
+ offsetx = ink_rect.width + 7;
+ offsety -= 10;
+ cairo_move_to (cr, graph->priv->box_x - offsetx - 2, b + offsety);
+ pango_cairo_show_layout (cr, graph->priv->layout);
+ g_free (text);
+ }
+
+ cairo_restore (cr);
+}
+
+/**
+ * gpm_graph_widget_get_y_label_max_width:
+ * @graph: This class instance
+ * @cr: Cairo drawing context
+ *
+ * Draw the X and the Y labels onto the graph.
+ **/
+static guint
+gpm_graph_widget_get_y_label_max_width (GpmGraphWidget *graph, cairo_t *cr)
+{
+ guint i;
+ gchar *text;
+ gint value;
+ gint length_y = graph->priv->stop_y - graph->priv->start_y;
+ PangoRectangle ink_rect, logical_rect;
+ guint biggest = 0;
+
+ /* do y text */
+ for (i=0; i<11; i++) {
+ value = (length_y / 10) * (10 - (gfloat) i) + graph->priv->start_y;
+ text = gpm_get_axis_label (graph->priv->type_y, value);
+ pango_layout_set_text (graph->priv->layout, text, -1);
+ pango_layout_get_pixel_extents (graph->priv->layout, &ink_rect, &logical_rect);
+ if (ink_rect.width > (gint) biggest)
+ biggest = ink_rect.width;
+ g_free (text);
+ }
+ return biggest;
+}
+
+/**
+ * gpm_graph_widget_autorange_x:
+ * @graph: This class instance
+ *
+ * Autoranges the graph axis depending on the axis type, and the maximum
+ * value of the data. We have to be careful to choose a number that gives good
+ * resolution but also a number that scales "well" to a 10x10 grid.
+ **/
+static void
+gpm_graph_widget_autorange_x (GpmGraphWidget *graph)
+{
+ gfloat biggest_x = G_MINFLOAT;
+ gfloat smallest_x = G_MAXFLOAT;
+ guint rounding_x = 1;
+ GPtrArray *data;
+ GpmPointObj *point;
+ guint i, j;
+ guint len = 0;
+ GPtrArray *array;
+
+ array = graph->priv->data_list;
+
+ /* find out if we have no data */
+ for (j=0; j<array->len; j++) {
+ data = g_ptr_array_index (array, j);
+ len = data->len;
+ if (len > 0)
+ break;
+ }
+
+ /* no data in any array */
+ if (len == 0) {
+ egg_debug ("no data");
+ graph->priv->start_x = 0;
+ graph->priv->stop_x = 10;
+ return;
+ }
+
+ /* get the range for the graph */
+ for (j=0; j<array->len; j++) {
+ data = g_ptr_array_index (array, j);
+ for (i=0; i < data->len; i++) {
+ point = (GpmPointObj *) g_ptr_array_index (data, i);
+ if (point->x > biggest_x)
+ biggest_x = point->x;
+ if (point->x < smallest_x)
+ smallest_x = point->x;
+ }
+ }
+ egg_debug ("Data range is %f<x<%f", smallest_x, biggest_x);
+ /* don't allow no difference */
+ if (biggest_x - smallest_x < 0.0001) {
+ biggest_x++;
+ smallest_x--;
+ }
+
+ if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_PERCENTAGE) {
+ rounding_x = 10;
+ } else if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_FACTOR) {
+ rounding_x = 1;
+ } else if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_POWER) {
+ rounding_x = 10;
+ } else if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_VOLTAGE) {
+ rounding_x = 1000;
+ } else if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_TIME) {
+ if (biggest_x-smallest_x < 150)
+ rounding_x = 150;
+ else if (biggest_x-smallest_x < 5*60)
+ rounding_x = 5 * 60;
+ else
+ rounding_x = 10 * 60;
+ }
+
+ graph->priv->start_x = egg_precision_round_down (smallest_x, rounding_x);
+ graph->priv->stop_x = egg_precision_round_up (biggest_x, rounding_x);
+
+ egg_debug ("Processed(1) range is %i<x<%i",
+ graph->priv->start_x, graph->priv->stop_x);
+
+ /* if percentage, and close to the end points, then extend */
+ if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_PERCENTAGE) {
+ if (graph->priv->stop_x >= 90)
+ graph->priv->stop_x = 100;
+ if (graph->priv->start_x > 0 && graph->priv->start_x <= 10)
+ graph->priv->start_x = 0;
+ } else if (graph->priv->type_x == GPM_GRAPH_WIDGET_TYPE_TIME) {
+ if (graph->priv->start_x > 0 && graph->priv->start_x <= 60*10)
+ graph->priv->start_x = 0;
+ }
+
+ egg_debug ("Processed range is %i<x<%i",
+ graph->priv->start_x, graph->priv->stop_x);
+}
+
+/**
+ * gpm_graph_widget_autorange_y:
+ * @graph: This class instance
+ *
+ * Autoranges the graph axis depending on the axis type, and the maximum
+ * value of the data. We have to be careful to choose a number that gives good
+ * resolution but also a number that scales "well" to a 10x10 grid.
+ **/
+static void
+gpm_graph_widget_autorange_y (GpmGraphWidget *graph)
+{
+ gfloat biggest_y = G_MINFLOAT;
+ gfloat smallest_y = G_MAXFLOAT;
+ guint rounding_y = 1;
+ GPtrArray *data;
+ GpmPointObj *point;
+ guint i, j;
+ guint len = 0;
+ GPtrArray *array;
+
+ array = graph->priv->data_list;
+
+ /* find out if we have no data */
+ for (j=0; j<array->len; j++) {
+ data = g_ptr_array_index (array, j);
+ len = data->len;
+ if (len > 0)
+ break;
+ }
+
+ /* no data in any array */
+ if (len == 0) {
+ egg_debug ("no data");
+ graph->priv->start_y = 0;
+ graph->priv->stop_y = 10;
+ return;
+ }
+
+ /* get the range for the graph */
+ for (j=0; j<array->len; j++) {
+ data = g_ptr_array_index (array, j);
+ for (i=0; i < data->len; i++) {
+ point = (GpmPointObj *) g_ptr_array_index (data, i);
+ if (point->y > biggest_y)
+ biggest_y = point->y;
+ if (point->y < smallest_y)
+ smallest_y = point->y;
+ }
+ }
+ egg_debug ("Data range is %f<y<%f", smallest_y, biggest_y);
+ /* don't allow no difference */
+ if (biggest_y - smallest_y < 0.0001) {
+ biggest_y++;
+ smallest_y--;
+ }
+
+ if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_PERCENTAGE) {
+ rounding_y = 10;
+ } else if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_FACTOR) {
+ rounding_y = 1;
+ } else if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_POWER) {
+ rounding_y = 10;
+ } else if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_VOLTAGE) {
+ rounding_y = 1000;
+ } else if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_TIME) {
+ if (biggest_y-smallest_y < 150)
+ rounding_y = 150;
+ else if (biggest_y < 5*60)
+ rounding_y = 5 * 60;
+ else
+ rounding_y = 10 * 60;
+ }
+
+ graph->priv->start_y = egg_precision_round_down (smallest_y, rounding_y);
+ graph->priv->stop_y = egg_precision_round_up (biggest_y, rounding_y);
+
+ /* a factor graph always is centered around zero */
+ if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_FACTOR) {
+ if (abs (graph->priv->stop_y) > abs (graph->priv->start_y))
+ graph->priv->start_y = -graph->priv->stop_y;
+ else
+ graph->priv->stop_y = -graph->priv->start_y;
+ }
+
+ egg_debug ("Processed(1) range is %i<y<%i",
+ graph->priv->start_y, graph->priv->stop_y);
+
+ if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_PERCENTAGE) {
+ if (graph->priv->stop_y >= 90)
+ graph->priv->stop_y = 100;
+ if (graph->priv->start_y > 0 && graph->priv->start_y <= 10)
+ graph->priv->start_y = 0;
+ } else if (graph->priv->type_y == GPM_GRAPH_WIDGET_TYPE_TIME) {
+ if (graph->priv->start_y <= 60*10)
+ graph->priv->start_y = 0;
+ }
+
+ egg_debug ("Processed range is %i<y<%i",
+ graph->priv->start_y, graph->priv->stop_y);
+}
+
+/**
+ * gpm_graph_widget_set_color:
+ * @cr: Cairo drawing context
+ * @color: The color enum
+ **/
+static void
+gpm_graph_widget_set_color (cairo_t *cr, guint32 color)
+{
+ guint8 r, g, b;
+ egg_color_to_rgb (color, &r, &g, &b);
+ cairo_set_source_rgb (cr, ((gdouble) r)/256.0f, ((gdouble) g)/256.0f, ((gdouble) b)/256.0f);
+}
+
+/**
+ * gpm_graph_widget_draw_legend_line:
+ * @cr: Cairo drawing context
+ * @x: The X-coordinate for the center
+ * @y: The Y-coordinate for the center
+ * @color: The color enum
+ *
+ * Draw the legend line on the graph of a specified color
+ **/
+static void
+gpm_graph_widget_draw_legend_line (cairo_t *cr, gfloat x, gfloat y, guint32 color)
+{
+ gfloat width = 10;
+ gfloat height = 2;
+ /* background */
+ cairo_rectangle (cr, (int) (x - (width/2)) + 0.5, (int) (y - (height/2)) + 0.5, width, height);
+ gpm_graph_widget_set_color (cr, color);
+ cairo_fill (cr);
+ /* solid outline box */
+ cairo_rectangle (cr, (int) (x - (width/2)) + 0.5, (int) (y - (height/2)) + 0.5, width, height);
+ cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+}
+
+/**
+ * gpm_graph_widget_get_pos_on_graph:
+ * @graph: This class instance
+ * @data_x: The data X-coordinate
+ * @data_y: The data Y-coordinate
+ * @x: The returned X position on the cairo surface
+ * @y: The returned Y position on the cairo surface
+ **/
+static void
+gpm_graph_widget_get_pos_on_graph (GpmGraphWidget *graph, gfloat data_x, gfloat data_y, float *x, float *y)
+{
+ *x = graph->priv->box_x + (graph->priv->unit_x * (data_x - graph->priv->start_x)) + 1;
+ *y = graph->priv->box_y + (graph->priv->unit_y * (gfloat)(graph->priv->stop_y - data_y)) + 1.5;
+}
+
+/**
+ * gpm_graph_widget_draw_dot:
+ **/
+static void
+gpm_graph_widget_draw_dot (cairo_t *cr, gfloat x, gfloat y, guint32 color)
+{
+ gfloat width;
+ /* box */
+ width = 2.0;
+ cairo_rectangle (cr, (gint)x + 0.5f - (width/2), (gint)y + 0.5f - (width/2), width, width);
+ gpm_graph_widget_set_color (cr, color);
+ cairo_fill (cr);
+ cairo_rectangle (cr, (gint)x + 0.5f - (width/2), (gint)y + 0.5f - (width/2), width, width);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+}
+
+/**
+ * gpm_graph_widget_draw_line:
+ * @graph: This class instance
+ * @cr: Cairo drawing context
+ *
+ * Draw the data line onto the graph with a big green line. We should already
+ * limit the data to < ~100 values, so this shouldn't take too long.
+ **/
+static void
+gpm_graph_widget_draw_line (GpmGraphWidget *graph, cairo_t *cr)
+{
+ gfloat oldx, oldy;
+ gfloat newx, newy;
+ GPtrArray *data;
+ GPtrArray *array;
+ GpmGraphWidgetPlot plot;
+ GpmPointObj *point;
+ guint i, j;
+
+ if (graph->priv->data_list->len == 0) {
+ egg_debug ("no data");
+ return;
+ }
+ cairo_save (cr);
+
+ array = graph->priv->data_list;
+
+ /* do each line */
+ for (j=0; j<array->len; j++) {
+ data = g_ptr_array_index (array, j);
+ if (data->len == 0)
+ continue;
+ plot = GPOINTER_TO_UINT (g_ptr_array_index (graph->priv->plot_list, j));
+
+ /* get the very first point so we can work out the old */
+ point = (GpmPointObj *) g_ptr_array_index (data, 0);
+ oldx = 0;
+ oldy = 0;
+ gpm_graph_widget_get_pos_on_graph (graph, point->x, point->y, &oldx, &oldy);
+ if (plot == GPM_GRAPH_WIDGET_PLOT_POINTS || plot == GPM_GRAPH_WIDGET_PLOT_BOTH)
+ gpm_graph_widget_draw_dot (cr, oldx, oldy, point->color);
+
+ for (i=1; i < data->len; i++) {
+ point = (GpmPointObj *) g_ptr_array_index (data, i);
+
+ gpm_graph_widget_get_pos_on_graph (graph, point->x, point->y, &newx, &newy);
+
+ /* ignore white lines */
+ if (point->color == 0xffffff) {
+ oldx = newx;
+ oldy = newy;
+ continue;
+ }
+
+ /* draw line */
+ if (plot == GPM_GRAPH_WIDGET_PLOT_LINE || plot == GPM_GRAPH_WIDGET_PLOT_BOTH) {
+ cairo_move_to (cr, oldx, oldy);
+ cairo_line_to (cr, newx, newy);
+ cairo_set_line_width (cr, 1.5);
+ gpm_graph_widget_set_color (cr, point->color);
+ cairo_stroke (cr);
+ }
+
+ /* draw data dot */
+ if (plot == GPM_GRAPH_WIDGET_PLOT_POINTS || plot == GPM_GRAPH_WIDGET_PLOT_BOTH)
+ gpm_graph_widget_draw_dot (cr, newx, newy, point->color);
+
+ /* save old */
+ oldx = newx;
+ oldy = newy;
+ }
+ }
+
+ cairo_restore (cr);
+}
+
+/**
+ * gpm_graph_widget_draw_bounding_box:
+ * @cr: Cairo drawing context
+ * @x: The X-coordinate for the top-left
+ * @y: The Y-coordinate for the top-left
+ * @width: The item width
+ * @height: The item height
+ **/
+static void
+gpm_graph_widget_draw_bounding_box (cairo_t *cr, gint x, gint y, gint width, gint height)
+{
+ /* background */
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_fill (cr);
+ /* solid outline box */
+ cairo_rectangle (cr, x + 0.5f, y + 0.5f, width - 1, height - 1);
+ cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+}
+
+/**
+ * gpm_graph_widget_draw_legend:
+ * @cr: Cairo drawing context
+ * @x: The X-coordinate for the top-left
+ * @y: The Y-coordinate for the top-left
+ * @width: The item width
+ * @height: The item height
+ **/
+static void
+gpm_graph_widget_draw_legend (GpmGraphWidget *graph, gint x, gint y, gint width, gint height)
+{
+ cairo_t *cr = graph->priv->cr;
+ gint y_count;
+ guint i;
+ GpmGraphWidgetKeyData *keydataitem;
+
+ gpm_graph_widget_draw_bounding_box (cr, x, y, width, height);
+ y_count = y + 10;
+
+ /* add the line colors to the legend */
+ for (i=0; i<g_slist_length (graph->priv->key_data); i++) {
+ keydataitem = (GpmGraphWidgetKeyData *) g_slist_nth_data (graph->priv->key_data, i);
+ if (keydataitem == NULL) {
+ /* this shouldn't ever happen */
+ egg_warning ("keydataitem NULL!");
+ break;
+ }
+ gpm_graph_widget_draw_legend_line (cr, x + 8, y_count, keydataitem->color);
+ cairo_move_to (cr, x + 8 + 10, y_count - 6);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ pango_layout_set_text (graph->priv->layout, keydataitem->desc, -1);
+ pango_cairo_show_layout (cr, graph->priv->layout);
+ y_count = y_count + GPM_GRAPH_WIDGET_LEGEND_SPACING;
+ }
+}
+
+/**
+ * gpm_graph_widget_legend_calculate_width:
+ * @graph: This class instance
+ * @cr: Cairo drawing context
+ * Return value: The width of the legend, including borders.
+ *
+ * We have to find the maximum size of the text so we know the width of the
+ * legend box. We can't hardcode this as the dpi or font size might differ
+ * from machine to machine.
+ **/
+static gboolean
+gpm_graph_widget_legend_calculate_size (GpmGraphWidget *graph, cairo_t *cr,
+ guint *width, guint *height)
+{
+ guint i;
+ PangoRectangle ink_rect, logical_rect;
+ GpmGraphWidgetKeyData *keydataitem;
+
+ g_return_val_if_fail (GPM_IS_GRAPH_WIDGET (graph), FALSE);
+
+ /* set defaults */
+ *width = 0;
+ *height = 0;
+
+ /* add the line colors to the legend */
+ for (i=0; i<g_slist_length (graph->priv->key_data); i++) {
+ keydataitem = (GpmGraphWidgetKeyData *) g_slist_nth_data (graph->priv->key_data, i);
+ *height = *height + GPM_GRAPH_WIDGET_LEGEND_SPACING;
+ pango_layout_set_text (graph->priv->layout, keydataitem->desc, -1);
+ pango_layout_get_pixel_extents (graph->priv->layout, &ink_rect, &logical_rect);
+ if ((gint) *width < ink_rect.width)
+ *width = ink_rect.width;
+ }
+
+ /* have we got no entries? */
+ if (*width == 0 && *height == 0)
+ return TRUE;
+
+ /* add for borders */
+ *width += 25;
+ *height += 3;
+
+ return TRUE;
+}
+
+/**
+ * gpm_graph_widget_draw_graph:
+ * @graph: This class instance
+ * @cr: Cairo drawing context
+ *
+ * Draw the complete graph, with the box, the grid, the labels and the line.
+ **/
+static void
+gpm_graph_widget_draw_graph (GtkWidget *graph_widget, cairo_t *cr)
+{
+ GtkAllocation allocation;
+ gint legend_x = 0;
+ gint legend_y = 0;
+ guint legend_height = 0;
+ guint legend_width = 0;
+ gfloat data_x;
+ gfloat data_y;
+
+ GpmGraphWidget *graph = (GpmGraphWidget*) graph_widget;
+ g_return_if_fail (graph != NULL);
+ g_return_if_fail (GPM_IS_GRAPH_WIDGET (graph));
+
+ gpm_graph_widget_legend_calculate_size (graph, cr, &legend_width, &legend_height);
+ cairo_save (cr);
+
+ /* we need this so we know the y text */
+ if (graph->priv->autorange_x)
+ gpm_graph_widget_autorange_x (graph);
+ if (graph->priv->autorange_y)
+ gpm_graph_widget_autorange_y (graph);
+
+ graph->priv->box_x = gpm_graph_widget_get_y_label_max_width (graph, cr) + 10;
+ graph->priv->box_y = 5;
+
+ gtk_widget_get_allocation (graph_widget, &allocation);
+ graph->priv->box_height = allocation.height - (20 + graph->priv->box_y);
+
+ /* make size adjustment for legend */
+ if (graph->priv->use_legend && legend_height > 0) {
+ graph->priv->box_width = allocation.width -
+ (3 + legend_width + 5 + graph->priv->box_x);
+ legend_x = graph->priv->box_x + graph->priv->box_width + 6;
+ legend_y = graph->priv->box_y;
+ } else {
+ graph->priv->box_width = allocation.width -
+ (3 + graph->priv->box_x);
+ }
+
+ /* graph background */
+ gpm_graph_widget_draw_bounding_box (cr, graph->priv->box_x, graph->priv->box_y,
+ graph->priv->box_width, graph->priv->box_height);
+ if (graph->priv->use_grid)
+ gpm_graph_widget_draw_grid (graph, cr);
+
+ /* -3 is so we can keep the lines inside the box at both extremes */
+ data_x = graph->priv->stop_x - graph->priv->start_x;
+ data_y = graph->priv->stop_y - graph->priv->start_y;
+ graph->priv->unit_x = (float)(graph->priv->box_width - 3) / (float) data_x;
+ graph->priv->unit_y = (float)(graph->priv->box_height - 3) / (float) data_y;
+
+ gpm_graph_widget_draw_labels (graph, cr);
+ gpm_graph_widget_draw_line (graph, cr);
+
+ if (graph->priv->use_legend && legend_height > 0)
+ gpm_graph_widget_draw_legend (graph, legend_x, legend_y, legend_width, legend_height);
+
+ cairo_restore (cr);
+}
+
+/**
+ * gpm_graph_widget_expose:
+ * @graph: This class instance
+ * @event: The expose event
+ *
+ * Just repaint the entire graph widget on expose.
+ **/
+static gboolean
+gpm_graph_widget_expose (GtkWidget *graph, GdkEventExpose *event)
+{
+ cairo_t *cr;
+
+ /* get a cairo_t */
+ cr = gdk_cairo_create (gtk_widget_get_window (graph));
+ cairo_rectangle (cr,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cairo_clip (cr);
+ ((GpmGraphWidget *)graph)->priv->cr = cr;
+
+ gpm_graph_widget_draw_graph (graph, cr);
+
+ cairo_destroy (cr);
+ return FALSE;
+}
+
+/**
+ * gpm_graph_widget_new:
+ * Return value: A new GpmGraphWidget object.
+ **/
+GtkWidget *
+gpm_graph_widget_new (void)
+{
+ return g_object_new (GPM_TYPE_GRAPH_WIDGET, NULL);
+}
+
diff --git a/src/gpm-graph-widget.h b/src/gpm-graph-widget.h
new file mode 100644
index 0000000..d9c127f
--- /dev/null
+++ b/src/gpm-graph-widget.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_GRAPH_WIDGET_H__
+#define __GPM_GRAPH_WIDGET_H__
+
+#include <gtk/gtk.h>
+#include "gpm-point-obj.h"
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_GRAPH_WIDGET (gpm_graph_widget_get_type ())
+#define GPM_GRAPH_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GPM_TYPE_GRAPH_WIDGET, GpmGraphWidget))
+#define GPM_GRAPH_WIDGET_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GPM_GRAPH_WIDGET, GpmGraphWidgetClass))
+#define GPM_IS_GRAPH_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GPM_TYPE_GRAPH_WIDGET))
+#define GPM_IS_GRAPH_WIDGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), EFF_TYPE_GRAPH_WIDGET))
+#define GPM_GRAPH_WIDGET_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), GPM_TYPE_GRAPH_WIDGET, GpmGraphWidgetClass))
+
+#define GPM_GRAPH_WIDGET_LEGEND_SPACING 17
+
+typedef struct GpmGraphWidget GpmGraphWidget;
+typedef struct GpmGraphWidgetClass GpmGraphWidgetClass;
+typedef struct GpmGraphWidgetPrivate GpmGraphWidgetPrivate;
+
+typedef enum {
+ GPM_GRAPH_WIDGET_TYPE_INVALID,
+ GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
+ GPM_GRAPH_WIDGET_TYPE_FACTOR,
+ GPM_GRAPH_WIDGET_TYPE_TIME,
+ GPM_GRAPH_WIDGET_TYPE_POWER,
+ GPM_GRAPH_WIDGET_TYPE_VOLTAGE,
+ GPM_GRAPH_WIDGET_TYPE_UNKNOWN
+} GpmGraphWidgetType;
+
+typedef enum {
+ GPM_GRAPH_WIDGET_PLOT_LINE,
+ GPM_GRAPH_WIDGET_PLOT_POINTS,
+ GPM_GRAPH_WIDGET_PLOT_BOTH
+} GpmGraphWidgetPlot;
+
+/* the different kinds of lines in the key */
+typedef struct {
+ guint32 color;
+ gchar *desc;
+} GpmGraphWidgetKeyData;
+
+struct GpmGraphWidget
+{
+ GtkDrawingArea parent;
+ GpmGraphWidgetPrivate *priv;
+};
+
+struct GpmGraphWidgetClass
+{
+ GtkDrawingAreaClass parent_class;
+};
+
+GType gpm_graph_widget_get_type (void);
+GtkWidget *gpm_graph_widget_new (void);
+
+gboolean gpm_graph_widget_data_clear (GpmGraphWidget *graph);
+gboolean gpm_graph_widget_data_assign (GpmGraphWidget *graph,
+ GpmGraphWidgetPlot plot,
+ GPtrArray *array);
+gboolean gpm_graph_widget_key_data_add (GpmGraphWidget *graph,
+ guint32 color,
+ const gchar *desc);
+
+G_END_DECLS
+
+#endif
diff --git a/src/gpm-idle.c b/src/gpm-idle.c
new file mode 100644
index 0000000..0a7c33c
--- /dev/null
+++ b/src/gpm-idle.c
@@ -0,0 +1,729 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "egg-debug.h"
+#include "egg-idletime.h"
+
+#include "gpm-idle.h"
+#include "gpm-load.h"
+#include "gpm-session.h"
+
+#define GPM_IDLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_IDLE, GpmIdlePrivate))
+
+/* Sets the idle percent limit, i.e. how hard the computer can work
+ while considered "at idle" */
+#define GPM_IDLE_CPU_LIMIT 5
+#define GPM_IDLE_IDLETIME_ID 1
+
+struct GpmIdlePrivate
+{
+ EggIdletime *idletime;
+ GpmLoad *load;
+ GpmSession *session;
+ GpmIdleMode mode;
+ guint timeout_dim; /* in seconds */
+ guint timeout_blank; /* in seconds */
+ guint timeout_sleep; /* in seconds */
+ guint timeout_blank_id;
+ guint timeout_sleep_id;
+ gboolean x_idle;
+ gboolean check_type_cpu;
+};
+
+enum {
+ IDLE_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_idle_object = NULL;
+
+G_DEFINE_TYPE (GpmIdle, gpm_idle, G_TYPE_OBJECT)
+
+/**
+ * gpm_idle_mode_to_string:
+ **/
+static const gchar *
+gpm_idle_mode_to_string (GpmIdleMode mode)
+{
+ if (mode == GPM_IDLE_MODE_NORMAL)
+ return "normal";
+ if (mode == GPM_IDLE_MODE_DIM)
+ return "dim";
+ if (mode == GPM_IDLE_MODE_BLANK)
+ return "blank";
+ if (mode == GPM_IDLE_MODE_SLEEP)
+ return "sleep";
+ return "unknown";
+}
+
+/**
+ * gpm_idle_set_mode:
+ * @mode: The new mode, e.g. GPM_IDLE_MODE_SLEEP
+ **/
+static void
+gpm_idle_set_mode (GpmIdle *idle, GpmIdleMode mode)
+{
+ g_return_if_fail (GPM_IS_IDLE (idle));
+
+ if (mode != idle->priv->mode) {
+ idle->priv->mode = mode;
+ egg_debug ("Doing a state transition: %s", gpm_idle_mode_to_string (mode));
+ g_signal_emit (idle, signals [IDLE_CHANGED], 0, mode);
+ }
+}
+
+/**
+ * gpm_idle_set_check_cpu:
+ * @check_type_cpu: If we should check the CPU before mode becomes
+ * GPM_IDLE_MODE_SLEEP and the event is done.
+ **/
+void
+gpm_idle_set_check_cpu (GpmIdle *idle, gboolean check_type_cpu)
+{
+ g_return_if_fail (GPM_IS_IDLE (idle));
+ egg_debug ("Setting the CPU load check to %i", check_type_cpu);
+ idle->priv->check_type_cpu = check_type_cpu;
+}
+
+/**
+ * gpm_idle_get_mode:
+ * Return value: The current mode, e.g. GPM_IDLE_MODE_SLEEP
+ **/
+GpmIdleMode
+gpm_idle_get_mode (GpmIdle *idle)
+{
+ return idle->priv->mode;
+}
+
+/**
+ * gpm_idle_blank_cb:
+ **/
+static gboolean
+gpm_idle_blank_cb (GpmIdle *idle)
+{
+ if (idle->priv->mode > GPM_IDLE_MODE_BLANK) {
+ egg_debug ("ignoring current mode %s", gpm_idle_mode_to_string (idle->priv->mode));
+ return FALSE;
+ }
+ gpm_idle_set_mode (idle, GPM_IDLE_MODE_BLANK);
+ return FALSE;
+}
+
+/**
+ * gpm_idle_sleep_cb:
+ **/
+static gboolean
+gpm_idle_sleep_cb (GpmIdle *idle)
+{
+ gdouble load;
+ gboolean ret = FALSE;
+
+ /* get our computed load value */
+ if (idle->priv->check_type_cpu) {
+ load = gpm_load_get_current (idle->priv->load);
+ if (load > GPM_IDLE_CPU_LIMIT) {
+ /* check if system is "idle" enough */
+ egg_debug ("Detected that the CPU is busy");
+ ret = TRUE;
+ goto out;
+ }
+ }
+ gpm_idle_set_mode (idle, GPM_IDLE_MODE_SLEEP);
+out:
+ return ret;
+}
+
+/**
+ * gpm_idle_evaluate:
+ **/
+static void
+gpm_idle_evaluate (GpmIdle *idle)
+{
+ gboolean is_idle;
+ gboolean is_idle_inhibited;
+ gboolean is_suspend_inhibited;
+
+ is_idle = gpm_session_get_idle (idle->priv->session);
+ is_idle_inhibited = gpm_session_get_idle_inhibited (idle->priv->session);
+ is_suspend_inhibited = gpm_session_get_suspend_inhibited (idle->priv->session);
+ egg_debug ("session_idle=%i, idle_inhibited=%i, suspend_inhibited=%i, x_idle=%i", is_idle, is_idle_inhibited, is_suspend_inhibited, idle->priv->x_idle);
+
+ /* check we are really idle */
+ if (!idle->priv->x_idle) {
+ gpm_idle_set_mode (idle, GPM_IDLE_MODE_NORMAL);
+ egg_debug ("X not idle");
+ if (idle->priv->timeout_blank_id != 0) {
+ g_source_remove (idle->priv->timeout_blank_id);
+ idle->priv->timeout_blank_id = 0;
+ }
+ if (idle->priv->timeout_sleep_id != 0) {
+ g_source_remove (idle->priv->timeout_sleep_id);
+ idle->priv->timeout_sleep_id = 0;
+ }
+ goto out;
+ }
+
+ /* are we inhibited from going idle */
+ if (is_idle_inhibited) {
+ egg_debug ("inhibited, so using normal state");
+ gpm_idle_set_mode (idle, GPM_IDLE_MODE_NORMAL);
+ if (idle->priv->timeout_blank_id != 0) {
+ g_source_remove (idle->priv->timeout_blank_id);
+ idle->priv->timeout_blank_id = 0;
+ }
+ if (idle->priv->timeout_sleep_id != 0) {
+ g_source_remove (idle->priv->timeout_sleep_id);
+ idle->priv->timeout_sleep_id = 0;
+ }
+ goto out;
+ }
+
+ /* normal to dim */
+ if (idle->priv->mode == GPM_IDLE_MODE_NORMAL) {
+ egg_debug ("normal to dim");
+ gpm_idle_set_mode (idle, GPM_IDLE_MODE_DIM);
+ }
+
+ /* set up blank callback even when session is not idle,
+ * but only if we actually want to blank. */
+ if (idle->priv->timeout_blank_id == 0 &&
+ idle->priv->timeout_blank != 0) {
+ egg_debug ("setting up blank callback for %is", idle->priv->timeout_blank);
+ idle->priv->timeout_blank_id = g_timeout_add_seconds (idle->priv->timeout_blank, (GSourceFunc) gpm_idle_blank_cb, idle);
+ }
+
+ /* are we inhibited from sleeping */
+ if (is_suspend_inhibited) {
+ egg_debug ("suspend inhibited");
+ if (idle->priv->timeout_sleep_id != 0) {
+ g_source_remove (idle->priv->timeout_sleep_id);
+ idle->priv->timeout_sleep_id = 0;
+ }
+ } else if (is_idle) {
+ /* only do the sleep timeout when the session is idle and we aren't inhibited from sleeping */
+ if (idle->priv->timeout_sleep_id == 0 &&
+ idle->priv->timeout_sleep != 0) {
+ egg_debug ("setting up sleep callback %is", idle->priv->timeout_sleep);
+ idle->priv->timeout_sleep_id = g_timeout_add_seconds (idle->priv->timeout_sleep, (GSourceFunc) gpm_idle_sleep_cb, idle);
+ }
+ }
+out:
+ return;
+}
+
+/**
+ * gpm_idle_adjust_timeout_dim:
+ * @idle_time: The new timeout we want to set, in seconds.
+ * @timeout: Current idle time, in seconds.
+ *
+ * On slow machines, or machines that have lots to load duing login,
+ * the current idle time could be bigger than the requested timeout.
+ * In this case the scheduled idle timeout will never fire, unless
+ * some user activity (keyboard, mouse) resets the current idle time.
+ * Instead of relying on user activity to correct this issue, we need
+ * to adjust timeout, as related to current idle time, so the idle
+ * timeout will fire as designed.
+ *
+ * Return value: timeout to set, adjusted acccording to current idle time.
+ **/
+static guint
+gpm_idle_adjust_timeout_dim (guint idle_time, guint timeout)
+{
+ /* allow 2 sec margin for messaging delay. */
+ idle_time += 2;
+
+ /* Double timeout until it's larger than current idle time.
+ * Give up for ultra slow machines. (86400 sec = 24 hours) */
+ while (timeout < idle_time && timeout < 86400 && timeout > 0) {
+ timeout *= 2;
+ }
+ return timeout;
+}
+
+/**
+ * gpm_idle_set_timeout_dim:
+ * @timeout: The new timeout we want to set, in seconds
+ **/
+gboolean
+gpm_idle_set_timeout_dim (GpmIdle *idle, guint timeout)
+{
+ gint64 idle_time_in_msec;
+ guint timeout_adjusted;
+
+ g_return_val_if_fail (GPM_IS_IDLE (idle), FALSE);
+
+ idle_time_in_msec = egg_idletime_get_time (idle->priv->idletime);
+ timeout_adjusted = gpm_idle_adjust_timeout_dim (idle_time_in_msec / 1000, timeout);
+ egg_debug ("Current idle time=%lldms, timeout was %us, becomes %us after adjustment",
+ (long long int)idle_time_in_msec, timeout, timeout_adjusted);
+ timeout = timeout_adjusted;
+
+ egg_debug ("Setting dim idle timeout: %ds", timeout);
+ if (idle->priv->timeout_dim != timeout) {
+ idle->priv->timeout_dim = timeout;
+
+ if (timeout > 0)
+ egg_idletime_alarm_set (idle->priv->idletime, GPM_IDLE_IDLETIME_ID, timeout * 1000);
+ else
+ egg_idletime_alarm_remove (idle->priv->idletime, GPM_IDLE_IDLETIME_ID);
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_idle_set_timeout_blank:
+ * @timeout: The new timeout we want to set, in seconds
+ **/
+gboolean
+gpm_idle_set_timeout_blank (GpmIdle *idle, guint timeout)
+{
+ g_return_val_if_fail (GPM_IS_IDLE (idle), FALSE);
+
+ egg_debug ("Setting blank idle timeout: %ds", timeout);
+ if (idle->priv->timeout_blank != timeout) {
+ idle->priv->timeout_blank = timeout;
+ gpm_idle_evaluate (idle);
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_idle_set_timeout_sleep:
+ * @timeout: The new timeout we want to set, in seconds
+ **/
+gboolean
+gpm_idle_set_timeout_sleep (GpmIdle *idle, guint timeout)
+{
+ g_return_val_if_fail (GPM_IS_IDLE (idle), FALSE);
+
+ egg_debug ("Setting sleep idle timeout: %ds", timeout);
+ if (idle->priv->timeout_sleep != timeout) {
+ idle->priv->timeout_sleep = timeout;
+ gpm_idle_evaluate (idle);
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_idle_session_idle_changed_cb:
+ * @is_idle: If the session is idle
+ *
+ * The SessionIdleChanged callback from mate-session.
+ **/
+static void
+gpm_idle_session_idle_changed_cb (GpmSession *session, gboolean is_idle, GpmIdle *idle)
+{
+ egg_debug ("Received mate session idle changed: %i", is_idle);
+ gpm_idle_evaluate (idle);
+}
+
+/**
+ * gpm_idle_session_inhibited_changed_cb:
+ **/
+static void
+gpm_idle_session_inhibited_changed_cb (GpmSession *session, gboolean is_idle_inhibited, gboolean is_suspend_inhibited, GpmIdle *idle)
+{
+ egg_debug ("Received mate session inhibited changed: idle=(%i), suspend=(%i)", is_idle_inhibited, is_suspend_inhibited);
+ gpm_idle_evaluate (idle);
+}
+
+/**
+ * gpm_idle_idletime_alarm_expired_cb:
+ *
+ * We're idle, something timed out
+ **/
+static void
+gpm_idle_idletime_alarm_expired_cb (EggIdletime *idletime, guint alarm_id, GpmIdle *idle)
+{
+ egg_debug ("idletime alarm: %i", alarm_id);
+
+ /* set again */
+ idle->priv->x_idle = TRUE;
+ gpm_idle_evaluate (idle);
+}
+
+/**
+ * gpm_idle_idletime_reset_cb:
+ *
+ * We're no longer idle, the user moved
+ **/
+static void
+gpm_idle_idletime_reset_cb (EggIdletime *idletime, GpmIdle *idle)
+{
+ egg_debug ("idletime reset");
+
+ idle->priv->x_idle = FALSE;
+ gpm_idle_evaluate (idle);
+}
+
+/**
+ * gpm_idle_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_idle_finalize (GObject *object)
+{
+ GpmIdle *idle;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_IDLE (object));
+
+ idle = GPM_IDLE (object);
+
+ g_return_if_fail (idle->priv != NULL);
+
+ if (idle->priv->timeout_blank_id != 0)
+ g_source_remove (idle->priv->timeout_blank_id);
+ if (idle->priv->timeout_sleep_id != 0)
+ g_source_remove (idle->priv->timeout_sleep_id);
+
+ g_object_unref (idle->priv->load);
+ g_object_unref (idle->priv->session);
+
+ egg_idletime_alarm_remove (idle->priv->idletime, GPM_IDLE_IDLETIME_ID);
+ g_object_unref (idle->priv->idletime);
+
+ G_OBJECT_CLASS (gpm_idle_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_idle_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_idle_class_init (GpmIdleClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gpm_idle_finalize;
+
+ signals [IDLE_CHANGED] =
+ g_signal_new ("idle-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmIdleClass, idle_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+
+ g_type_class_add_private (klass, sizeof (GpmIdlePrivate));
+}
+
+/**
+ * gpm_idle_init:
+ *
+ * Gets a DBUS connection, and aquires the session connection so we can
+ * get session changed events.
+ *
+ **/
+static void
+gpm_idle_init (GpmIdle *idle)
+{
+ idle->priv = GPM_IDLE_GET_PRIVATE (idle);
+
+ idle->priv->timeout_dim = G_MAXUINT;
+ idle->priv->timeout_blank = G_MAXUINT;
+ idle->priv->timeout_sleep = G_MAXUINT;
+ idle->priv->timeout_blank_id = 0;
+ idle->priv->timeout_sleep_id = 0;
+ idle->priv->x_idle = FALSE;
+ idle->priv->load = gpm_load_new ();
+ idle->priv->session = gpm_session_new ();
+ g_signal_connect (idle->priv->session, "idle-changed", G_CALLBACK (gpm_idle_session_idle_changed_cb), idle);
+ g_signal_connect (idle->priv->session, "inhibited-changed", G_CALLBACK (gpm_idle_session_inhibited_changed_cb), idle);
+
+ idle->priv->idletime = egg_idletime_new ();
+ g_signal_connect (idle->priv->idletime, "reset", G_CALLBACK (gpm_idle_idletime_reset_cb), idle);
+ g_signal_connect (idle->priv->idletime, "alarm-expired", G_CALLBACK (gpm_idle_idletime_alarm_expired_cb), idle);
+
+ gpm_idle_evaluate (idle);
+}
+
+/**
+ * gpm_idle_new:
+ * Return value: A new GpmIdle instance.
+ **/
+GpmIdle *
+gpm_idle_new (void)
+{
+ if (gpm_idle_object != NULL) {
+ g_object_ref (gpm_idle_object);
+ } else {
+ gpm_idle_object = g_object_new (GPM_TYPE_IDLE, NULL);
+ g_object_add_weak_pointer (gpm_idle_object, &gpm_idle_object);
+ }
+ return GPM_IDLE (gpm_idle_object);
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+#include "gpm-dpms.h"
+
+static GpmIdleMode _mode = 0;
+
+static void
+gpm_idle_test_idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, EggTest *test)
+{
+ _mode = mode;
+ egg_debug ("idle-changed %s", gpm_idle_mode_to_string (mode));
+ egg_test_loop_quit (test);
+}
+
+static gboolean
+gpm_idle_test_delay_cb (EggTest *test)
+{
+ egg_warning ("timing out");
+ egg_test_loop_quit (test);
+ return FALSE;
+}
+
+void
+gpm_idle_test (gpointer data)
+{
+ GpmIdle *idle;
+ gboolean ret;
+ EggTest *test = (EggTest *) data;
+ GpmIdleMode mode;
+ GpmDpms *dpms;
+
+ if (!egg_test_start (test, "GpmIdle"))
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "get object");
+ idle = gpm_idle_new ();
+ if (idle != NULL)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "got no object");
+
+ /* set up defaults */
+ gpm_idle_set_check_cpu (idle, FALSE);
+ gpm_idle_set_timeout_dim (idle, 4);
+ gpm_idle_set_timeout_blank (idle, 5);
+ gpm_idle_set_timeout_sleep (idle, 15);
+ g_signal_connect (idle, "idle-changed",
+ G_CALLBACK (gpm_idle_test_idle_changed_cb), test);
+
+ /************************************************************/
+ egg_test_title (test, "check cpu type");
+ egg_test_assert (test, (idle->priv->check_type_cpu == FALSE));
+
+ /************************************************************/
+ egg_test_title (test, "check timeout dim");
+ egg_test_assert (test, (idle->priv->timeout_dim == 4));
+
+ /************************************************************/
+ egg_test_title (test, "check timeout blank");
+ egg_test_assert (test, (idle->priv->timeout_blank == 5));
+
+ /************************************************************/
+ egg_test_title (test, "check timeout sleep");
+ egg_test_assert (test, (idle->priv->timeout_sleep == 15));
+
+ /************************************************************/
+ egg_test_title (test, "check x_idle");
+ egg_test_assert (test, (idle->priv->x_idle == FALSE));
+
+ /************************************************************/
+ egg_test_title (test, "check blank id");
+ egg_test_assert (test, (idle->priv->timeout_blank_id == 0));
+
+ /************************************************************/
+ egg_test_title (test, "check sleep id");
+ egg_test_assert (test, (idle->priv->timeout_sleep_id == 0));
+
+ /************************************************************/
+ egg_test_title (test, "check normal at startup");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_NORMAL)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ g_print ("*****************************\n");
+ g_print ("*** DO NOT MOVE THE MOUSE ***\n");
+ g_print ("*****************************\n");
+ egg_test_loop_wait (test, 2000 + 10000);
+ egg_test_loop_check (test);
+
+ /************************************************************/
+ egg_test_title (test, "check callback mode");
+ if (_mode == GPM_IDLE_MODE_DIM)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check current mode");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_DIM)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check x_idle");
+ egg_test_assert (test, (idle->priv->x_idle == TRUE));
+
+ /************************************************************/
+ egg_test_title (test, "check blank id");
+ egg_test_assert (test, (idle->priv->timeout_blank_id != 0));
+
+ /************************************************************/
+ egg_test_title (test, "check sleep id");
+ egg_test_assert (test, (idle->priv->timeout_sleep_id == 0));
+
+ /************************************************************/
+ egg_test_loop_wait (test, 5000 + 1000);
+ egg_test_loop_check (test);
+
+ /************************************************************/
+ egg_test_title (test, "check callback mode");
+ if (_mode == GPM_IDLE_MODE_BLANK)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check current mode");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_BLANK)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ g_print ("**********************\n");
+ g_print ("*** MOVE THE MOUSE ***\n");
+ g_print ("**********************\n");
+ egg_test_loop_wait (test, G_MAXUINT);
+ egg_test_loop_check (test);
+
+ /************************************************************/
+ egg_test_title (test, "check callback mode");
+ if (_mode == GPM_IDLE_MODE_NORMAL)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check current mode");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_NORMAL)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check x_idle");
+ egg_test_assert (test, (idle->priv->x_idle == FALSE));
+
+ /************************************************************/
+ egg_test_title (test, "check blank id");
+ egg_test_assert (test, (idle->priv->timeout_blank_id == 0));
+
+ /************************************************************/
+ g_print ("*****************************\n");
+ g_print ("*** DO NOT MOVE THE MOUSE ***\n");
+ g_print ("*****************************\n");
+ egg_test_loop_wait (test, 4000 + 1500);
+ egg_test_loop_check (test);
+
+ /************************************************************/
+ egg_test_title (test, "check current mode");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_DIM)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check x_idle");
+ egg_test_assert (test, (idle->priv->x_idle == TRUE));
+
+ egg_test_loop_wait (test, 15000);
+ egg_test_loop_check (test);
+
+ /************************************************************/
+ egg_test_title (test, "check current mode");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_BLANK)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "set dpms off");
+ dpms = gpm_dpms_new ();
+ ret = gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_OFF, NULL);
+ egg_test_assert (test, ret);
+
+ /* wait for normal event to be suppressed */
+ g_timeout_add (2000, (GSourceFunc) gpm_idle_test_delay_cb, test);
+ egg_test_loop_wait (test, G_MAXUINT);
+ egg_test_loop_check (test);
+
+ /************************************************************/
+ egg_test_title (test, "check current mode");
+ mode = gpm_idle_get_mode (idle);
+ if (mode == GPM_IDLE_MODE_BLANK)
+ egg_test_success (test, NULL);
+ else
+ egg_test_failed (test, "mode: %s", gpm_idle_mode_to_string (mode));
+
+ /************************************************************/
+ egg_test_title (test, "check x_idle");
+ egg_test_assert (test, (idle->priv->x_idle == TRUE));
+
+ gpm_dpms_set_mode (dpms, GPM_DPMS_MODE_ON, NULL);
+
+ g_object_unref (idle);
+ g_object_unref (dpms);
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/gpm-idle.h b/src/gpm-idle.h
new file mode 100644
index 0000000..e186838
--- /dev/null
+++ b/src/gpm-idle.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_IDLE_H
+#define __GPM_IDLE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_IDLE (gpm_idle_get_type ())
+#define GPM_IDLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_IDLE, GpmIdle))
+#define GPM_IDLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_IDLE, GpmIdleClass))
+#define GPM_IS_IDLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_IDLE))
+#define GPM_IS_IDLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_IDLE))
+#define GPM_IDLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_IDLE, GpmIdleClass))
+
+typedef enum {
+ GPM_IDLE_MODE_NORMAL,
+ GPM_IDLE_MODE_DIM,
+ GPM_IDLE_MODE_BLANK,
+ GPM_IDLE_MODE_SLEEP
+} GpmIdleMode;
+
+typedef struct GpmIdlePrivate GpmIdlePrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmIdlePrivate *priv;
+} GpmIdle;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* idle_changed) (GpmIdle *idle,
+ GpmIdleMode mode);
+} GpmIdleClass;
+
+GType gpm_idle_get_type (void);
+GpmIdle *gpm_idle_new (void);
+GpmIdleMode gpm_idle_get_mode (GpmIdle *idle);
+void gpm_idle_set_check_cpu (GpmIdle *idle,
+ gboolean check_type_cpu);
+gboolean gpm_idle_set_timeout_dim (GpmIdle *idle,
+ guint timeout);
+gboolean gpm_idle_set_timeout_blank (GpmIdle *idle,
+ guint timeout);
+gboolean gpm_idle_set_timeout_sleep (GpmIdle *idle,
+ guint timeout);
+void gpm_idle_test (gpointer data);
+
+G_END_DECLS
+
+#endif /* __GPM_IDLE_H */
diff --git a/src/gpm-load.c b/src/gpm-load.c
new file mode 100644
index 0000000..eab0129
--- /dev/null
+++ b/src/gpm-load.c
@@ -0,0 +1,282 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#if defined(sun) && defined(__SVR4)
+#include <kstat.h>
+#include <sys/sysinfo.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+
+#include "gpm-common.h"
+#include "gpm-marshal.h"
+#include "egg-debug.h"
+
+#include "gpm-load.h"
+
+static void gpm_load_finalize (GObject *object);
+
+#define GPM_LOAD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_LOAD, GpmLoadPrivate))
+
+struct GpmLoadPrivate
+{
+ long unsigned old_idle;
+ long unsigned old_total;
+};
+
+static gpointer gpm_load_object = NULL;
+
+G_DEFINE_TYPE (GpmLoad, gpm_load, G_TYPE_OBJECT)
+
+/**
+ * gpm_load_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_load_class_init (GpmLoadClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_load_finalize;
+ g_type_class_add_private (klass, sizeof (GpmLoadPrivate));
+}
+
+#if defined(sun) && defined(__SVR4)
+
+/**
+ * gpm_load_get_cpu_values:
+ * @cpu_idle: The idle time reported by the CPU
+ * @cpu_total: The total time reported by the CPU
+ * Return value: Success of reading /proc/stat.
+ **/
+static gboolean
+gpm_load_get_cpu_values (long unsigned *cpu_idle, long unsigned *cpu_total)
+{
+ long unsigned cpu_user = 0;
+ long unsigned cpu_kernel = 0;
+ long unsigned cpu_wait = 0;
+ kstat_ctl_t *kc = NULL;
+ kstat_named_t *kn = NULL;
+ kstat_t *ks = NULL;
+ cpu_stat_t data;
+ int ncpus;
+ int count;
+
+ kc = kstat_open();
+ if (!kc) {
+ egg_warning ("Cannot open kstat!\n");
+ return FALSE;
+ }
+
+ ks = kstat_lookup(kc, "unix", 0, "system_misc");
+ if (kstat_read(kc, ks, NULL) == -1) {
+ egg_warning ("Cannot read kstat on module unix!\n");
+ goto out;
+ }
+ kn = kstat_data_lookup (ks, "ncpus");
+ if (!kn) {
+ egg_warning ("Cannot get number of cpus in current system!\n");
+ goto out;
+ }
+ ncpus = kn->value.ui32;
+
+ /*
+ * To aggresive ticks used of all cpus,
+ * traverse kstat chain to access very cpu_stat instane.
+ */
+ for(count = 0, *cpu_idle =0, *cpu_total = 0; count < ncpus; count++){
+
+ ks = kstat_lookup(kc, "cpu_stat", count, NULL);
+ if (ks == NULL) {
+ egg_warning ("Null output for kstat on cpu%d\n", count);
+ goto out;
+ }
+
+ if (kstat_read(kc, ks, &data) == -1) {
+ egg_warning ("Cannot read kstat entry on cpu%d\n", count);
+ goto out;
+ }
+
+ egg_debug ("cpu%d:\t%lu\t%lu\t%lu\t%lu\n", count,
+ data.cpu_sysinfo.cpu[CPU_IDLE],
+ data.cpu_sysinfo.cpu[CPU_USER],
+ data.cpu_sysinfo.cpu[CPU_KERNEL],
+ data.cpu_sysinfo.cpu[CPU_WAIT]);
+
+ *cpu_idle += data.cpu_sysinfo.cpu[CPU_IDLE];
+ cpu_user += data.cpu_sysinfo.cpu[CPU_USER];
+ cpu_kernel += data.cpu_sysinfo.cpu[CPU_KERNEL];
+ cpu_wait += data.cpu_sysinfo.cpu[CPU_WAIT];
+ }
+ kstat_close(kc);
+ /*
+ * Summing up all these times gives you the system uptime.
+ * This is what the uptime command does.
+ */
+ *cpu_total = cpu_user + cpu_kernel + cpu_wait + *cpu_idle;
+ return TRUE;
+
+out:
+ kstat_close(kc);
+ return FALSE;
+}
+
+#else
+
+/**
+ * gpm_load_get_cpu_values:
+ * @cpu_idle: The idle time reported by the CPU
+ * @cpu_total: The total time reported by the CPU
+ * Return value: Success of reading /proc/stat.
+ **/
+static gboolean
+gpm_load_get_cpu_values (long unsigned *cpu_idle, long unsigned *cpu_total)
+{
+ long unsigned cpu_user;
+ long unsigned cpu_nice;
+ long unsigned cpu_system;
+ int len;
+ char tmp[5];
+ char str[80];
+ FILE *fd;
+ char *suc;
+ gboolean ret = FALSE;
+
+ /* open file */
+ fd = fopen("/proc/stat", "r");
+ if (!fd)
+ goto out;
+
+ /* get data */
+ suc = fgets (str, 80, fd);
+ if (suc == NULL)
+ goto out;
+
+ /* parse */
+ len = sscanf (str, "%s %lu %lu %lu %lu", tmp,
+ &cpu_user, &cpu_nice, &cpu_system, cpu_idle);
+ if (len != 5)
+ goto out;
+
+ /* summing up all these times gives you the system uptime in jiffies */
+ *cpu_total = cpu_user + cpu_nice + cpu_system + *cpu_idle;
+ ret = TRUE;
+out:
+ if (!fd)
+ fclose (fd);
+ return ret;
+}
+#endif /* sun & __SVR4 */
+
+/**
+ * gpm_load_get_current:
+ * @load: This class instance
+ * Return value: The CPU idle load
+ **/
+gdouble
+gpm_load_get_current (GpmLoad *load)
+{
+ double percentage_load;
+ long unsigned cpu_idle;
+ long unsigned cpu_total;
+ long unsigned diff_idle;
+ long unsigned diff_total;
+ gboolean ret;
+
+ /* work out the differences */
+ ret = gpm_load_get_cpu_values (&cpu_idle, &cpu_total);
+ if (!ret)
+ return 0.0;
+
+ diff_idle = cpu_idle - load->priv->old_idle;
+ diff_total = cpu_total - load->priv->old_total;
+
+ /* If we divide the total time by idle time we get the load. */
+ if (diff_idle > 0)
+ percentage_load = (double) diff_total / (double) diff_idle;
+ else
+ percentage_load = 100;
+
+ load->priv->old_idle = cpu_idle;
+ load->priv->old_total = cpu_total;
+
+ return percentage_load;
+}
+
+/**
+ * gpm_load_init:
+ */
+static void
+gpm_load_init (GpmLoad *load)
+{
+ load->priv = GPM_LOAD_GET_PRIVATE (load);
+
+ load->priv->old_idle = 0;
+ load->priv->old_total = 0;
+
+ /* we have to populate the values at startup */
+ gpm_load_get_cpu_values (&load->priv->old_idle, &load->priv->old_total);
+}
+
+/**
+ * gpm_load_coldplug:
+ *
+ * @object: This load instance
+ */
+static void
+gpm_load_finalize (GObject *object)
+{
+ GpmLoad *load;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_LOAD (object));
+ load = GPM_LOAD (object);
+ g_return_if_fail (load->priv != NULL);
+ G_OBJECT_CLASS (gpm_load_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_load_new:
+ * Return value: new GpmLoad instance.
+ **/
+GpmLoad *
+gpm_load_new (void)
+{
+ if (gpm_load_object != NULL) {
+ g_object_ref (gpm_load_object);
+ } else {
+ gpm_load_object = g_object_new (GPM_TYPE_LOAD, NULL);
+ g_object_add_weak_pointer (gpm_load_object, &gpm_load_object);
+ }
+ return GPM_LOAD (gpm_load_object);
+}
+
diff --git a/src/gpm-load.h b/src/gpm-load.h
new file mode 100644
index 0000000..fcce544
--- /dev/null
+++ b/src/gpm-load.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_LOAD_H
+#define __GPM_LOAD_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_LOAD (gpm_load_get_type ())
+#define GPM_LOAD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_LOAD, GpmLoad))
+#define GPM_LOAD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_LOAD, GpmLoadClass))
+#define GPM_IS_LOAD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_LOAD))
+#define GPM_IS_LOAD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_LOAD))
+#define GPM_LOAD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_LOAD, GpmLoadClass))
+
+typedef struct GpmLoadPrivate GpmLoadPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmLoadPrivate *priv;
+} GpmLoad;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpmLoadClass;
+
+GType gpm_load_get_type (void);
+GpmLoad *gpm_load_new (void);
+
+gdouble gpm_load_get_current (GpmLoad *load);
+
+G_END_DECLS
+
+#endif /* __GPM_LOAD_H */
diff --git a/src/gpm-main.c b/src/gpm-main.c
new file mode 100644
index 0000000..5abff81
--- /dev/null
+++ b/src/gpm-main.c
@@ -0,0 +1,286 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Taken in part from:
+ * - lshal (C) 2003 David Zeuthen, <[email protected]>
+ * - notibat (C) 2004 Benjamin Kahn, <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <locale.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "gpm-stock-icons.h"
+#include "gpm-common.h"
+#include "gpm-manager.h"
+#include "gpm-session.h"
+
+#include "org.mate.PowerManager.h"
+
+#include "egg-debug.h"
+
+/**
+ * gpm_object_register:
+ * @connection: What we want to register to
+ * @object: The GObject we want to register
+ *
+ * Register org.mate.PowerManager on the session bus.
+ * This function MUST be called before DBUS service will work.
+ *
+ * Return value: success
+ **/
+static gboolean
+gpm_object_register (DBusGConnection *connection,
+ GObject *object)
+{
+ DBusGProxy *bus_proxy = NULL;
+ GError *error = NULL;
+ guint request_name_result;
+ gboolean ret;
+
+ bus_proxy = dbus_g_proxy_new_for_name (connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+
+ ret = dbus_g_proxy_call (bus_proxy, "RequestName", &error,
+ G_TYPE_STRING, GPM_DBUS_SERVICE,
+ G_TYPE_UINT, 0,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &request_name_result,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+ if (!ret) {
+ /* abort as the DBUS method failed */
+ egg_warning ("RequestName failed!");
+ return FALSE;
+ }
+
+ /* free the bus_proxy */
+ g_object_unref (G_OBJECT (bus_proxy));
+
+ /* already running */
+ if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ return FALSE;
+ }
+
+ dbus_g_object_type_install_info (GPM_TYPE_MANAGER, &dbus_glib_gpm_manager_object_info);
+ dbus_g_error_domain_register (GPM_MANAGER_ERROR, NULL, GPM_MANAGER_TYPE_ERROR);
+ dbus_g_connection_register_g_object (connection, GPM_DBUS_PATH, object);
+
+ return TRUE;
+}
+
+/**
+ * timed_exit_cb:
+ * @loop: The main loop
+ *
+ * Exits the main loop, which is helpful for valgrinding g-p-m.
+ *
+ * Return value: FALSE, as we don't want to repeat this action.
+ **/
+static gboolean
+timed_exit_cb (GMainLoop *loop)
+{
+ g_main_loop_quit (loop);
+ return FALSE;
+}
+
+/**
+ * gpm_main_stop_cb:
+ **/
+static void
+gpm_main_stop_cb (GpmSession *session, GMainLoop *loop)
+{
+ g_main_loop_quit (loop);
+}
+
+/**
+ * gpm_main_query_end_session_cb:
+ **/
+static void
+gpm_main_query_end_session_cb (GpmSession *session, guint flags, GMainLoop *loop)
+{
+ /* just send response */
+ gpm_session_end_session_response (session, TRUE, NULL);
+}
+
+/**
+ * gpm_main_end_session_cb:
+ **/
+static void
+gpm_main_end_session_cb (GpmSession *session, guint flags, GMainLoop *loop)
+{
+ /* send response */
+ gpm_session_end_session_response (session, TRUE, NULL);
+
+ /* exit loop, will unref manager */
+ g_main_loop_quit (loop);
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ GMainLoop *loop;
+ DBusGConnection *system_connection;
+ DBusGConnection *session_connection;
+ gboolean verbose = FALSE;
+ gboolean version = FALSE;
+ gboolean timed_exit = FALSE;
+ gboolean immediate_exit = FALSE;
+ GpmSession *session = NULL;
+ GpmManager *manager = NULL;
+ GError *error = NULL;
+ GOptionContext *context;
+ gint ret;
+
+ const GOptionEntry options[] = {
+ { "verbose", '\0', 0, G_OPTION_ARG_NONE, &verbose,
+ N_("Show extra debugging information"), NULL },
+ { "version", '\0', 0, G_OPTION_ARG_NONE, &version,
+ N_("Show version of installed program and exit"), NULL },
+ { "timed-exit", '\0', 0, G_OPTION_ARG_NONE, &timed_exit,
+ N_("Exit after a small delay (for debugging)"), NULL },
+ { "immediate-exit", '\0', 0, G_OPTION_ARG_NONE, &immediate_exit,
+ N_("Exit after the manager has loaded (for debugging)"), NULL },
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ if (! g_thread_supported ())
+ g_thread_init (NULL);
+ dbus_g_thread_init ();
+ g_type_init ();
+
+ context = g_option_context_new (N_("MATE Power Manager"));
+ /* TRANSLATORS: program name, a simple app to view pending updates */
+ g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+ g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
+ g_option_context_set_summary (context, _("MATE Power Manager"));
+ g_option_context_parse (context, &argc, &argv, NULL);
+
+ if (version) {
+ g_print ("Version %s\n", VERSION);
+ goto unref_program;
+ }
+
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+ dbus_g_thread_init ();
+
+ gtk_init (&argc, &argv);
+ egg_debug_init (verbose);
+
+ egg_debug ("MATE %s %s", GPM_NAME, VERSION);
+
+ /* check dbus connections, exit if not valid */
+ system_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (error) {
+ egg_warning ("%s", error->message);
+ g_error_free (error);
+ egg_error ("This program cannot start until you start "
+ "the dbus system service.\n"
+ "It is <b>strongly recommended</b> you reboot "
+ "your computer after starting this service.");
+ }
+
+ session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (error) {
+ egg_warning ("%s", error->message);
+ g_error_free (error);
+ egg_error ("This program cannot start until you start the "
+ "dbus session service.\n\n"
+ "This is usually started automatically in X "
+ "or mate startup when you start a new session.");
+ }
+
+ /* add application specific icons to search path */
+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
+ GPM_DATA G_DIR_SEPARATOR_S "icons");
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* optionally register with the session */
+ session = gpm_session_new ();
+ g_signal_connect (session, "stop", G_CALLBACK (gpm_main_stop_cb), loop);
+ g_signal_connect (session, "query-end-session", G_CALLBACK (gpm_main_query_end_session_cb), loop);
+ g_signal_connect (session, "end-session", G_CALLBACK (gpm_main_end_session_cb), loop);
+ gpm_session_register_client (session, "mate-power-manager", getenv ("DESKTOP_AUTOSTART_ID"));
+
+ /* create a new gui object */
+ manager = gpm_manager_new ();
+
+ if (!gpm_object_register (session_connection, G_OBJECT (manager))) {
+ egg_error ("%s is already running in this session.", GPM_NAME);
+ return 0;
+ }
+
+ /* register to be a policy agent, just like kpackagekit does */
+ ret = dbus_bus_request_name(dbus_g_connection_get_connection(system_connection),
+ "org.freedesktop.Policy.Power",
+ DBUS_NAME_FLAG_REPLACE_EXISTING, NULL);
+ switch (ret) {
+ case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ egg_debug ("Successfully acquired interface org.freedesktop.Policy.Power.");
+ break;
+ case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+ egg_debug ("Queued for interface org.freedesktop.Policy.Power.");
+ break;
+ default:
+ break;
+ };
+
+ /* Only timeout and close the mainloop if we have specified it
+ * on the command line */
+ if (timed_exit) {
+ g_timeout_add_seconds (20, (GSourceFunc) timed_exit_cb, loop);
+ }
+
+ if (immediate_exit == FALSE) {
+ g_main_loop_run (loop);
+ }
+
+ g_main_loop_unref (loop);
+
+ g_object_unref (session);
+ g_object_unref (manager);
+unref_program:
+ g_option_context_free (context);
+ return 0;
+}
diff --git a/src/gpm-manager.c b/src/gpm-manager.c
new file mode 100644
index 0000000..ec787be
--- /dev/null
+++ b/src/gpm-manager.c
@@ -0,0 +1,2110 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <mateconf/mateconf-client.h>
+#include <canberra-gtk.h>
+#include <libupower-glib/upower.h>
+#include <libmatenotify/notify.h>
+
+#include "egg-debug.h"
+#include "egg-console-kit.h"
+
+#include "gpm-button.h"
+#include "gpm-control.h"
+#include "gpm-common.h"
+#include "gpm-dpms.h"
+#include "gpm-idle.h"
+#include "gpm-manager.h"
+#include "gpm-screensaver.h"
+#include "gpm-backlight.h"
+#include "gpm-session.h"
+#include "gpm-stock-icons.h"
+#include "gpm-prefs-server.h"
+#include "gpm-tray-icon.h"
+#include "gpm-engine.h"
+#include "gpm-upower.h"
+#include "gpm-disks.h"
+
+#include "org.mate.PowerManager.Backlight.h"
+
+static void gpm_manager_finalize (GObject *object);
+
+#define GPM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_MANAGER, GpmManagerPrivate))
+#define GPM_MANAGER_RECALL_DELAY 30 /* seconds */
+#define GPM_MANAGER_NOTIFY_TIMEOUT_NEVER 0 /* ms */
+#define GPM_MANAGER_NOTIFY_TIMEOUT_SHORT 10 * 1000 /* ms */
+#define GPM_MANAGER_NOTIFY_TIMEOUT_LONG 30 * 1000 /* ms */
+
+#define GPM_MANAGER_CRITICAL_ALERT_TIMEOUT 5 /* seconds */
+
+struct GpmManagerPrivate
+{
+ GpmButton *button;
+ MateConfClient *conf;
+ GpmDisks *disks;
+ GpmDpms *dpms;
+ GpmIdle *idle;
+ GpmPrefsServer *prefs_server;
+ GpmControl *control;
+ GpmScreensaver *screensaver;
+ GpmTrayIcon *tray_icon;
+ GpmEngine *engine;
+ GpmBacklight *backlight;
+ EggConsoleKit *console;
+ guint32 screensaver_ac_throttle_id;
+ guint32 screensaver_dpms_throttle_id;
+ guint32 screensaver_lid_throttle_id;
+ guint32 critical_alert_timeout_id;
+ ca_proplist *critical_alert_loop_props;
+ UpClient *client;
+ gboolean on_battery;
+ gboolean just_resumed;
+ GtkStatusIcon *status_icon;
+ NotifyNotification *notification_general;
+ NotifyNotification *notification_warning_low;
+ NotifyNotification *notification_discharging;
+ NotifyNotification *notification_fully_charged;
+};
+
+typedef enum {
+ GPM_MANAGER_SOUND_POWER_PLUG,
+ GPM_MANAGER_SOUND_POWER_UNPLUG,
+ GPM_MANAGER_SOUND_LID_OPEN,
+ GPM_MANAGER_SOUND_LID_CLOSE,
+ GPM_MANAGER_SOUND_BATTERY_CAUTION,
+ GPM_MANAGER_SOUND_BATTERY_LOW,
+ GPM_MANAGER_SOUND_BATTERY_FULL,
+ GPM_MANAGER_SOUND_SUSPEND_START,
+ GPM_MANAGER_SOUND_SUSPEND_RESUME,
+ GPM_MANAGER_SOUND_SUSPEND_ERROR,
+ GPM_MANAGER_SOUND_LAST
+} GpmManagerSound;
+
+G_DEFINE_TYPE (GpmManager, gpm_manager, G_TYPE_OBJECT)
+
+/**
+ * gpm_manager_error_quark:
+ * Return value: Our personal error quark.
+ **/
+GQuark
+gpm_manager_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("gpm_manager_error");
+ return quark;
+}
+
+/**
+ * gpm_manager_error_get_type:
+ **/
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+GType
+gpm_manager_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] =
+ {
+ ENUM_ENTRY (GPM_MANAGER_ERROR_DENIED, "PermissionDenied"),
+ ENUM_ENTRY (GPM_MANAGER_ERROR_NO_HW, "NoHardwareSupport"),
+ { 0, 0, 0 }
+ };
+ etype = g_enum_register_static ("GpmManagerError", values);
+ }
+ return etype;
+}
+
+/**
+ * gpm_manager_play_loop_timeout_cb:
+ **/
+static gboolean
+gpm_manager_play_loop_timeout_cb (GpmManager *manager)
+{
+ ca_context *context;
+ context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
+ ca_context_play_full (context, 0,
+ manager->priv->critical_alert_loop_props,
+ NULL,
+ NULL);
+ return TRUE;
+}
+
+/**
+ * gpm_manager_play_loop_stop:
+ **/
+static gboolean
+gpm_manager_play_loop_stop (GpmManager *manager)
+{
+ if (manager->priv->critical_alert_timeout_id == 0) {
+ egg_warning ("no sound loop present to stop");
+ return FALSE;
+ }
+
+ g_source_remove (manager->priv->critical_alert_timeout_id);
+ ca_proplist_destroy (manager->priv->critical_alert_loop_props);
+
+ manager->priv->critical_alert_loop_props = NULL;
+ manager->priv->critical_alert_timeout_id = 0;
+
+ return TRUE;
+}
+
+/**
+ * gpm_manager_play_loop_start:
+ **/
+static gboolean
+gpm_manager_play_loop_start (GpmManager *manager, GpmManagerSound action, gboolean force, guint timeout)
+{
+ const gchar *id = NULL;
+ const gchar *desc = NULL;
+ gboolean ret;
+ gint retval;
+ ca_context *context;
+
+ ret = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_UI_ENABLE_SOUND, NULL);
+ if (!ret && !force) {
+ egg_debug ("ignoring sound due to policy");
+ return FALSE;
+ }
+
+ if (timeout == 0) {
+ egg_warning ("received invalid timeout");
+ return FALSE;
+ }
+
+ /* if a sound loop is already running, stop the existing loop */
+ if (manager->priv->critical_alert_timeout_id != 0) {
+ egg_warning ("was instructed to play a sound loop with one already playing");
+ gpm_manager_play_loop_stop (manager);
+ }
+
+ if (action == GPM_MANAGER_SOUND_BATTERY_LOW) {
+ id = "battery-low";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Battery is very low");
+ }
+
+ /* no match */
+ if (id == NULL) {
+ egg_warning ("no sound match for %i", action);
+ return FALSE;
+ }
+
+ ca_proplist_create (&(manager->priv->critical_alert_loop_props));
+ ca_proplist_sets (manager->priv->critical_alert_loop_props,
+ CA_PROP_EVENT_ID, id);
+ ca_proplist_sets (manager->priv->critical_alert_loop_props,
+ CA_PROP_EVENT_DESCRIPTION, desc);
+
+ manager->priv->critical_alert_timeout_id = g_timeout_add_seconds (timeout,
+ (GSourceFunc) gpm_manager_play_loop_timeout_cb,
+ manager);
+
+ /* play the sound, using sounds from the naming spec */
+ context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
+ retval = ca_context_play (context, 0,
+ CA_PROP_EVENT_ID, id,
+ CA_PROP_EVENT_DESCRIPTION, desc, NULL);
+ if (retval < 0)
+ egg_warning ("failed to play %s: %s", id, ca_strerror (retval));
+ return TRUE;
+}
+
+/**
+ * gpm_manager_play:
+ **/
+static gboolean
+gpm_manager_play (GpmManager *manager, GpmManagerSound action, gboolean force)
+{
+ const gchar *id = NULL;
+ const gchar *desc = NULL;
+ gboolean ret;
+ gint retval;
+ ca_context *context;
+
+ ret = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_UI_ENABLE_SOUND, NULL);
+ if (!ret && !force) {
+ egg_debug ("ignoring sound due to policy");
+ return FALSE;
+ }
+
+ if (action == GPM_MANAGER_SOUND_POWER_PLUG) {
+ id = "power-plug";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Power plugged in");
+ } else if (action == GPM_MANAGER_SOUND_POWER_UNPLUG) {
+ id = "power-unplug";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Power unplugged");
+ } else if (action == GPM_MANAGER_SOUND_LID_OPEN) {
+ id = "lid-open";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Lid has opened");
+ } else if (action == GPM_MANAGER_SOUND_LID_CLOSE) {
+ id = "lid-close";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Lid has closed");
+ } else if (action == GPM_MANAGER_SOUND_BATTERY_CAUTION) {
+ id = "battery-caution";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Battery is low");
+ } else if (action == GPM_MANAGER_SOUND_BATTERY_LOW) {
+ id = "battery-low";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Battery is very low");
+ } else if (action == GPM_MANAGER_SOUND_BATTERY_FULL) {
+ id = "battery-full";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Battery is full");
+ } else if (action == GPM_MANAGER_SOUND_SUSPEND_START) {
+ id = "suspend-start";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Suspend started");
+ } else if (action == GPM_MANAGER_SOUND_SUSPEND_RESUME) {
+ id = "suspend-resume";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Resumed");
+ } else if (action == GPM_MANAGER_SOUND_SUSPEND_ERROR) {
+ id = "suspend-error";
+ /* TRANSLATORS: this is the sound description */
+ desc = _("Suspend failed");
+ }
+
+ /* no match */
+ if (id == NULL) {
+ egg_warning ("no match");
+ return FALSE;
+ }
+
+ /* play the sound, using sounds from the naming spec */
+ context = ca_gtk_context_get_for_screen (gdk_screen_get_default ());
+ retval = ca_context_play (context, 0,
+ CA_PROP_EVENT_ID, id,
+ CA_PROP_EVENT_DESCRIPTION, desc, NULL);
+ if (retval < 0)
+ egg_warning ("failed to play %s: %s", id, ca_strerror (retval));
+ return TRUE;
+}
+
+/**
+ * gpm_manager_is_inhibit_valid:
+ * @manager: This class instance
+ * @action: The action we want to do, e.g. "suspend"
+ *
+ * Checks to see if the specific action has been inhibited by a program.
+ *
+ * Return value: TRUE if we can perform the action.
+ **/
+static gboolean
+gpm_manager_is_inhibit_valid (GpmManager *manager, gboolean user_action, const char *action)
+{
+ return TRUE;
+}
+
+/**
+ * gpm_manager_sync_policy_sleep:
+ * @manager: This class instance
+ *
+ * Changes the policy if required, setting brightness, display and computer
+ * timeouts.
+ * We have to make sure mate-screensaver disables screensaving, and enables
+ * monitor DPMS instead when on batteries to save power.
+ **/
+static void
+gpm_manager_sync_policy_sleep (GpmManager *manager)
+{
+ guint sleep_display;
+ guint sleep_computer;
+
+ if (!manager->priv->on_battery) {
+ sleep_computer = mateconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC, NULL);
+ sleep_display = mateconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC, NULL);
+ } else {
+ sleep_computer = mateconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT, NULL);
+ sleep_display = mateconf_client_get_int (manager->priv->conf, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT, NULL);
+ }
+
+ /* set the new sleep (inactivity) value */
+ gpm_idle_set_timeout_blank (manager->priv->idle, sleep_display);
+ gpm_idle_set_timeout_sleep (manager->priv->idle, sleep_computer);
+}
+
+/**
+ * gpm_manager_blank_screen:
+ * @manager: This class instance
+ *
+ * Turn off the backlight of the LCD when we shut the lid, and lock
+ * if required. This is required because some laptops do not turn off the
+ * LCD backlight when the lid is closed.
+ * See http://bugzilla.mate.org/show_bug.cgi?id=321313
+ *
+ * Return value: Success.
+ **/
+static gboolean
+gpm_manager_blank_screen (GpmManager *manager, GError **noerror)
+{
+ gboolean do_lock;
+ gboolean ret = TRUE;
+ GError *error = NULL;
+
+ do_lock = gpm_control_get_lock_policy (manager->priv->control,
+ GPM_CONF_LOCK_ON_BLANK_SCREEN);
+ if (do_lock) {
+ if (!gpm_screensaver_lock (manager->priv->screensaver))
+ egg_debug ("Could not lock screen via mate-screensaver");
+ }
+ gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_OFF, &error);
+ if (error) {
+ egg_debug ("Unable to set DPMS mode: %s", error->message);
+ g_error_free (error);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+/**
+ * gpm_manager_unblank_screen:
+ * @manager: This class instance
+ *
+ * Unblank the screen after we have opened the lid of the laptop
+ *
+ * Return value: Success.
+ **/
+static gboolean
+gpm_manager_unblank_screen (GpmManager *manager, GError **noerror)
+{
+ gboolean do_lock;
+ gboolean ret = TRUE;
+ GError *error = NULL;
+
+ gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
+ if (error) {
+ egg_debug ("Unable to set DPMS mode: %s", error->message);
+ g_error_free (error);
+ ret = FALSE;
+ }
+
+ do_lock = gpm_control_get_lock_policy (manager->priv->control, GPM_CONF_LOCK_ON_BLANK_SCREEN);
+ if (do_lock)
+ gpm_screensaver_poke (manager->priv->screensaver);
+ return ret;
+}
+
+/**
+ * gpm_manager_notify_close:
+ **/
+static gboolean
+gpm_manager_notify_close (GpmManager *manager, NotifyNotification *notification)
+{
+ gboolean ret = FALSE;
+ GError *error = NULL;
+
+ /* exists? */
+ if (notification == NULL)
+ goto out;
+
+ /* try to close */
+ ret = notify_notification_close (notification, &error);
+ if (!ret) {
+ egg_warning ("failed to close notification: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gpm_manager_notification_closed_cb:
+ **/
+static void
+gpm_manager_notification_closed_cb (NotifyNotification *notification, NotifyNotification **notification_class)
+{
+ egg_debug ("caught notification closed signal %p", notification);
+ /* the object is already unreffed in _close_signal_handler */
+ *notification_class = NULL;
+}
+
+/**
+ * gpm_manager_notify:
+ **/
+static gboolean
+gpm_manager_notify (GpmManager *manager, NotifyNotification **notification_class,
+ const gchar *title, const gchar *message,
+ guint timeout, const gchar *icon, NotifyUrgency urgency)
+{
+ gboolean ret;
+ GError *error = NULL;
+ NotifyNotification *notification;
+ GtkWidget *dialog;
+
+ /* close any existing notification of this class */
+ gpm_manager_notify_close (manager, *notification_class);
+
+ /* if the status icon is hidden, don't point at it */
+ if (manager->priv->status_icon != NULL &&
+ gtk_status_icon_is_embedded (manager->priv->status_icon))
+ notification = notify_notification_new_with_status_icon (title, message, icon, manager->priv->status_icon);
+ else
+ notification = notify_notification_new (title, message, icon, NULL);
+ notify_notification_set_timeout (notification, timeout);
+ notify_notification_set_urgency (notification, urgency);
+ g_signal_connect (notification, "closed", G_CALLBACK (gpm_manager_notification_closed_cb), notification_class);
+
+ egg_debug ("notification %p: %s : %s", notification, title, message);
+
+ /* try to show */
+ ret = notify_notification_show (notification, &error);
+ if (!ret) {
+ egg_warning ("failed to show notification: %s", error->message);
+ g_error_free (error);
+
+ /* show modal dialog as libmatenotify failed */
+ dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+ "<span size='larger'><b>%s</b></span>", title);
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+
+ /* wait async for close */
+ gtk_widget_show (dialog);
+ g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
+
+ g_object_unref (notification);
+ goto out;
+ }
+
+ /* save this local instance as the class instance */
+ g_object_add_weak_pointer (G_OBJECT (notification), (gpointer) &notification);
+ *notification_class = notification;
+out:
+ return ret;
+}
+
+
+/**
+ * gpm_manager_sleep_failure_response_cb:
+ **/
+static void
+gpm_manager_sleep_failure_response_cb (GtkDialog *dialog, gint response_id, GpmManager *manager)
+{
+ GdkScreen *screen;
+ GtkWidget *dialog_error;
+ GError *error = NULL;
+ gboolean ret;
+ gchar *uri = NULL;
+
+ /* user clicked the help button */
+ if (response_id == GTK_RESPONSE_HELP) {
+ uri = mateconf_client_get_string (manager->priv->conf, GPM_CONF_NOTIFY_SLEEP_FAILED_URI, NULL);
+ screen = gdk_screen_get_default();
+ ret = gtk_show_uri (screen, uri, gtk_get_current_event_time (), &error);
+ if (!ret) {
+ dialog_error = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
+ "Failed to show uri %s", error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog_error));
+ g_error_free (error);
+ }
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ g_free (uri);
+}
+
+/**
+ * gpm_manager_sleep_failure:
+ **/
+static void
+gpm_manager_sleep_failure (GpmManager *manager, gboolean is_suspend, const gchar *detail)
+{
+ gboolean show_sleep_failed;
+ GString *string = NULL;
+ const gchar *title;
+ gchar *uri = NULL;
+ const gchar *icon;
+ GtkWidget *dialog;
+
+ /* only show this if specified in mateconf */
+ show_sleep_failed = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_SLEEP_FAILED, NULL);
+
+ egg_debug ("sleep failed");
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_SUSPEND_ERROR, TRUE);
+
+ /* only emit if in MateConf */
+ if (!show_sleep_failed)
+ goto out;
+
+ /* TRANSLATORS: window title: there was a problem putting the machine to sleep */
+ string = g_string_new ("");
+ if (is_suspend) {
+ /* TRANSLATORS: message text */
+ g_string_append (string, _("Computer failed to suspend."));
+ /* TRANSLATORS: title text */
+ title = _("Failed to suspend");
+ icon = GPM_STOCK_SUSPEND;
+ } else {
+ /* TRANSLATORS: message text */
+ g_string_append (string, _("Computer failed to hibernate."));
+ /* TRANSLATORS: title text */
+ title = _("Failed to hibernate");
+ icon = GPM_STOCK_HIBERNATE;
+ }
+
+ /* TRANSLATORS: message text */
+ g_string_append_printf (string, "\n\n%s %s", _("Failure was reported as:"), detail);
+
+ /* show modal dialog */
+ dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+ "<span size='larger'><b>%s</b></span>", title);
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", string->str);
+ gtk_window_set_icon_name (GTK_WINDOW(dialog), icon);
+
+ /* show a button? */
+ uri = mateconf_client_get_string (manager->priv->conf, GPM_CONF_NOTIFY_SLEEP_FAILED_URI, NULL);
+ if (uri != NULL && uri[0] != '\0') {
+ /* TRANSLATORS: button text, visit the suspend help website */
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("Visit help page"), GTK_RESPONSE_HELP);
+ }
+
+ /* wait async for close */
+ gtk_widget_show (dialog);
+ g_signal_connect (dialog, "response", G_CALLBACK (gpm_manager_sleep_failure_response_cb), manager);
+out:
+ g_free (uri);
+ g_string_free (string, TRUE);
+}
+
+/**
+ * gpm_manager_action_suspend:
+ **/
+static gboolean
+gpm_manager_action_suspend (GpmManager *manager, const gchar *reason)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ /* check to see if we are inhibited */
+ if (gpm_manager_is_inhibit_valid (manager, FALSE, "suspend") == FALSE)
+ return FALSE;
+
+ egg_debug ("suspending, reason: %s", reason);
+ ret = gpm_control_suspend (manager->priv->control, &error);
+ if (!ret) {
+ gpm_manager_sleep_failure (manager, TRUE, error->message);
+ g_error_free (error);
+ }
+ gpm_button_reset_time (manager->priv->button);
+ return TRUE;
+}
+
+/**
+ * gpm_manager_action_hibernate:
+ **/
+static gboolean
+gpm_manager_action_hibernate (GpmManager *manager, const gchar *reason)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ /* check to see if we are inhibited */
+ if (gpm_manager_is_inhibit_valid (manager, FALSE, "hibernate") == FALSE)
+ return FALSE;
+
+ egg_debug ("hibernating, reason: %s", reason);
+ ret = gpm_control_hibernate (manager->priv->control, &error);
+ if (!ret) {
+ gpm_manager_sleep_failure (manager, TRUE, error->message);
+ g_error_free (error);
+ }
+ gpm_button_reset_time (manager->priv->button);
+ return TRUE;
+}
+
+/**
+ * gpm_manager_perform_policy:
+ * @manager: This class instance
+ * @policy: The policy that we should do, e.g. "suspend"
+ * @reason: The reason we are performing the policy action, e.g. "battery critical"
+ *
+ * Does one of the policy actions specified in mateconf.
+ **/
+static gboolean
+gpm_manager_perform_policy (GpmManager *manager, const gchar *policy_key, const gchar *reason)
+{
+ gchar *action = NULL;
+ GpmActionPolicy policy;
+
+ /* are we inhibited? */
+ if (gpm_manager_is_inhibit_valid (manager, FALSE, "policy action") == FALSE)
+ return FALSE;
+
+ action = mateconf_client_get_string (manager->priv->conf, policy_key, NULL);
+ egg_debug ("action: %s set to %s (%s)", policy_key, action, reason);
+ policy = gpm_action_policy_from_string (action);
+
+ if (policy == GPM_ACTION_POLICY_NOTHING) {
+ egg_debug ("doing nothing, reason: %s", reason);
+ } else if (policy == GPM_ACTION_POLICY_SUSPEND) {
+ gpm_manager_action_suspend (manager, reason);
+
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
+ gpm_manager_action_hibernate (manager, reason);
+
+ } else if (policy == GPM_ACTION_POLICY_BLANK) {
+ gpm_manager_blank_screen (manager, NULL);
+
+ } else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
+ egg_debug ("shutting down, reason: %s", reason);
+ gpm_control_shutdown (manager->priv->control, NULL);
+
+ } else if (policy == GPM_ACTION_POLICY_INTERACTIVE) {
+ GpmSession *session;
+ egg_debug ("logout, reason: %s", reason);
+ session = gpm_session_new ();
+ gpm_session_logout (session);
+ g_object_unref (session);
+ } else {
+ egg_warning ("unknown action %s", action);
+ }
+
+ g_free (action);
+ return TRUE;
+}
+
+/**
+ * gpm_manager_get_preferences_options:
+ **/
+gboolean
+gpm_manager_get_preferences_options (GpmManager *manager, gint *capability, GError **error)
+{
+ g_return_val_if_fail (manager != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_MANAGER (manager), FALSE);
+ return gpm_prefs_server_get_capability (manager->priv->prefs_server, capability);
+}
+
+/**
+ * gpm_manager_idle_do_sleep:
+ * @manager: This class instance
+ *
+ * This callback is called when we want to sleep. Use the users
+ * preference from mateconf, but change it if we can't do the action.
+ **/
+static void
+gpm_manager_idle_do_sleep (GpmManager *manager)
+{
+ gchar *action = NULL;
+ gboolean ret;
+ GError *error = NULL;
+ GpmActionPolicy policy;
+
+ if (!manager->priv->on_battery)
+ action = mateconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_SLEEP_TYPE_AC, NULL);
+ else
+ action = mateconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_SLEEP_TYPE_BATT, NULL);
+ policy = gpm_action_policy_from_string (action);
+
+ if (policy == GPM_ACTION_POLICY_NOTHING) {
+ egg_debug ("doing nothing as system idle action");
+
+ } else if (policy == GPM_ACTION_POLICY_SUSPEND) {
+ egg_debug ("suspending, reason: System idle");
+ ret = gpm_control_suspend (manager->priv->control, &error);
+ if (!ret) {
+ egg_warning ("cannot suspend (error: %s), so trying hibernate", error->message);
+ g_error_free (error);
+ error = NULL;
+ ret = gpm_control_hibernate (manager->priv->control, &error);
+ if (!ret) {
+ egg_warning ("cannot suspend or hibernate: %s", error->message);
+ g_error_free (error);
+ }
+ }
+
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
+ egg_debug ("hibernating, reason: System idle");
+ ret = gpm_control_hibernate (manager->priv->control, &error);
+ if (!ret) {
+ egg_warning ("cannot hibernate (error: %s), so trying suspend", error->message);
+ g_error_free (error);
+ error = NULL;
+ ret = gpm_control_suspend (manager->priv->control, &error);
+ if (!ret) {
+ egg_warning ("cannot suspend or hibernate: %s", error->message);
+ g_error_free (error);
+ }
+ }
+ }
+ g_free (action);
+}
+
+/**
+ * gpm_manager_idle_changed_cb:
+ * @idle: The idle class instance
+ * @mode: The idle mode, e.g. GPM_IDLE_MODE_BLANK
+ * @manager: This class instance
+ *
+ * This callback is called when the idle class detects that the idle state
+ * has changed. GPM_IDLE_MODE_BLANK is when the session has become inactive,
+ * and GPM_IDLE_MODE_SLEEP is where the session has become inactive, AND the
+ * session timeout has elapsed for the idle action.
+ **/
+static void
+gpm_manager_idle_changed_cb (GpmIdle *idle, GpmIdleMode mode, GpmManager *manager)
+{
+ /* ConsoleKit says we are not on active console */
+ if (!egg_console_kit_is_active (manager->priv->console)) {
+ egg_debug ("ignoring as not on active console");
+ return;
+ }
+
+ /* Ignore back-to-NORMAL events when the lid is closed, as the DPMS is
+ * already off, and we don't want to re-enable the screen when the user
+ * moves the mouse on systems that do not support hardware blanking. */
+ if (gpm_button_is_lid_closed (manager->priv->button) &&
+ mode == GPM_IDLE_MODE_NORMAL) {
+ egg_debug ("lid is closed, so we are ignoring ->NORMAL state changes");
+ return;
+ }
+
+ if (mode == GPM_IDLE_MODE_SLEEP) {
+ egg_debug ("Idle state changed: SLEEP");
+ if (gpm_manager_is_inhibit_valid (manager, FALSE, "timeout action") == FALSE)
+ return;
+ gpm_manager_idle_do_sleep (manager);
+ }
+}
+
+/**
+ * gpm_manager_lid_button_pressed:
+ * @manager: This class instance
+ * @state: TRUE for closed
+ *
+ * Does actions when the lid is closed, depending on if we are on AC or
+ * battery power.
+ **/
+static void
+gpm_manager_lid_button_pressed (GpmManager *manager, gboolean pressed)
+{
+ if (pressed)
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_LID_CLOSE, FALSE);
+ else
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_LID_OPEN, FALSE);
+
+ if (pressed == FALSE) {
+ /* we turn the lid dpms back on unconditionally */
+ gpm_manager_unblank_screen (manager, NULL);
+ return;
+ }
+
+ if (!manager->priv->on_battery) {
+ egg_debug ("Performing AC policy");
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_LID_AC,
+ "The lid has been closed on ac power.");
+ return;
+ }
+
+ egg_debug ("Performing battery policy");
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_LID_BATT,
+ "The lid has been closed on battery power.");
+}
+
+static void
+gpm_manager_update_dpms_throttle (GpmManager *manager)
+{
+ GpmDpmsMode mode;
+ gpm_dpms_get_mode (manager->priv->dpms, &mode, NULL);
+
+ /* Throttle the manager when DPMS is active since we can't see it anyway */
+ if (mode == GPM_DPMS_MODE_ON) {
+ if (manager->priv->screensaver_dpms_throttle_id != 0) {
+ gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_dpms_throttle_id);
+ manager->priv->screensaver_dpms_throttle_id = 0;
+ }
+ } else {
+ /* if throttle already exists then remove */
+ if (manager->priv->screensaver_dpms_throttle_id != 0) {
+ gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_dpms_throttle_id);
+ }
+ /* TRANSLATORS: this is the mate-screensaver throttle */
+ manager->priv->screensaver_dpms_throttle_id = gpm_screensaver_add_throttle (manager->priv->screensaver, _("Display DPMS activated"));
+ }
+}
+
+static void
+gpm_manager_update_ac_throttle (GpmManager *manager)
+{
+ /* Throttle the manager when we are not on AC power so we don't
+ waste the battery */
+ if (!manager->priv->on_battery) {
+ if (manager->priv->screensaver_ac_throttle_id != 0) {
+ gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_ac_throttle_id);
+ manager->priv->screensaver_ac_throttle_id = 0;
+ }
+ } else {
+ /* if throttle already exists then remove */
+ if (manager->priv->screensaver_ac_throttle_id != 0)
+ gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_ac_throttle_id);
+ /* TRANSLATORS: this is the mate-screensaver throttle */
+ manager->priv->screensaver_ac_throttle_id = gpm_screensaver_add_throttle (manager->priv->screensaver, _("On battery power"));
+ }
+}
+
+static void
+gpm_manager_update_lid_throttle (GpmManager *manager, gboolean lid_is_closed)
+{
+ /* Throttle the screensaver when the lid is close since we can't see it anyway
+ and it may overheat the laptop */
+ if (lid_is_closed == FALSE) {
+ if (manager->priv->screensaver_lid_throttle_id != 0) {
+ gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_lid_throttle_id);
+ manager->priv->screensaver_lid_throttle_id = 0;
+ }
+ } else {
+ /* if throttle already exists then remove */
+ if (manager->priv->screensaver_lid_throttle_id != 0)
+ gpm_screensaver_remove_throttle (manager->priv->screensaver, manager->priv->screensaver_lid_throttle_id);
+ manager->priv->screensaver_lid_throttle_id = gpm_screensaver_add_throttle (manager->priv->screensaver, _("Laptop lid is closed"));
+ }
+}
+
+/**
+ * gpm_manager_button_pressed_cb:
+ * @power: The power class instance
+ * @type: The button type, e.g. "power"
+ * @state: The state, where TRUE is depressed or closed
+ * @manager: This class instance
+ **/
+static void
+gpm_manager_button_pressed_cb (GpmButton *button, const gchar *type, GpmManager *manager)
+{
+ gchar *message;
+ egg_debug ("Button press event type=%s", type);
+
+ /* ConsoleKit says we are not on active console */
+ if (!egg_console_kit_is_active (manager->priv->console)) {
+ egg_debug ("ignoring as not on active console");
+ return;
+ }
+
+ if (g_strcmp0 (type, GPM_BUTTON_POWER) == 0) {
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_POWER, "The power button has been pressed.");
+ } else if (g_strcmp0 (type, GPM_BUTTON_SLEEP) == 0) {
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_SUSPEND, "The suspend button has been pressed.");
+ } else if (g_strcmp0 (type, GPM_BUTTON_SUSPEND) == 0) {
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_SUSPEND, "The suspend button has been pressed.");
+ } else if (g_strcmp0 (type, GPM_BUTTON_HIBERNATE) == 0) {
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_HIBERNATE, "The hibernate button has been pressed.");
+ } else if (g_strcmp0 (type, GPM_BUTTON_LID_OPEN) == 0) {
+ gpm_manager_lid_button_pressed (manager, FALSE);
+ } else if (g_strcmp0 (type, GPM_BUTTON_LID_CLOSED) == 0) {
+ gpm_manager_lid_button_pressed (manager, TRUE);
+ } else if (g_strcmp0 (type, GPM_BUTTON_BATTERY) == 0) {
+ message = gpm_engine_get_summary (manager->priv->engine);
+ gpm_manager_notify (manager, &manager->priv->notification_general,
+ _("Power Information"),
+ message,
+ GPM_MANAGER_NOTIFY_TIMEOUT_LONG,
+ GTK_STOCK_DIALOG_INFO,
+ NOTIFY_URGENCY_NORMAL);
+ g_free (message);
+ }
+
+ /* really belongs in mate-screensaver */
+ if (g_strcmp0 (type, GPM_BUTTON_LOCK) == 0)
+ gpm_screensaver_lock (manager->priv->screensaver);
+
+ /* disable or enable the fancy screensaver, as we don't want
+ * this starting when the lid is shut */
+ if (g_strcmp0 (type, GPM_BUTTON_LID_CLOSED) == 0)
+ gpm_manager_update_lid_throttle (manager, TRUE);
+ else if (g_strcmp0 (type, GPM_BUTTON_LID_OPEN) == 0)
+ gpm_manager_update_lid_throttle (manager, FALSE);
+}
+
+/**
+ * gpm_manager_get_spindown_timeout:
+ **/
+static gint
+gpm_manager_get_spindown_timeout (GpmManager *manager)
+{
+ gboolean enabled;
+ gint timeout;
+
+ /* get policy */
+ if (!manager->priv->on_battery) {
+ enabled = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_ENABLE_AC, NULL);
+ timeout = mateconf_client_get_int (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_TIMEOUT_AC, NULL);
+ } else {
+ enabled = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_ENABLE_BATT, NULL);
+ timeout = mateconf_client_get_int (manager->priv->conf, GPM_CONF_DISKS_SPINDOWN_TIMEOUT_BATT, NULL);
+ }
+ if (!enabled)
+ timeout = 0;
+ return timeout;
+}
+
+/**
+ * gpm_manager_client_changed_cb:
+ **/
+static void
+gpm_manager_client_changed_cb (UpClient *client, GpmManager *manager)
+{
+ gboolean event_when_closed;
+ gint timeout;
+ gboolean on_battery;
+ gboolean lid_is_closed;
+
+ /* get the client state */
+ g_object_get (client,
+ "on-battery", &on_battery,
+ "lid-is-closed", &lid_is_closed,
+ NULL);
+ if (on_battery == manager->priv->on_battery) {
+ egg_debug ("same state as before, ignoring");
+ return;
+ }
+
+ /* close any discharging notifications */
+ if (!on_battery) {
+ egg_debug ("clearing notify due ac being present");
+ gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
+ gpm_manager_notify_close (manager, manager->priv->notification_discharging);
+ }
+
+ /* if we are playing a critical charge sound loop, stop it */
+ if (!on_battery && manager->priv->critical_alert_timeout_id) {
+ egg_debug ("stopping alert loop due to ac being present");
+ gpm_manager_play_loop_stop (manager);
+ }
+
+ /* save in local cache */
+ manager->priv->on_battery = on_battery;
+
+ /* ConsoleKit says we are not on active console */
+ if (!egg_console_kit_is_active (manager->priv->console)) {
+ egg_debug ("ignoring as not on active console");
+ return;
+ }
+
+ egg_debug ("on_battery: %d", on_battery);
+
+ /* set disk spindown threshold */
+ timeout = gpm_manager_get_spindown_timeout (manager);
+ gpm_disks_set_spindown_timeout (manager->priv->disks, timeout);
+
+ gpm_manager_sync_policy_sleep (manager);
+
+ gpm_manager_update_ac_throttle (manager);
+
+ /* simulate user input, but only when the lid is open */
+ if (!lid_is_closed)
+ gpm_screensaver_poke (manager->priv->screensaver);
+
+ if (!on_battery)
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_POWER_PLUG, FALSE);
+ else
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_POWER_UNPLUG, FALSE);
+
+ /* We do the lid close on battery action if the ac adapter is removed
+ when the laptop is closed and on battery. Fixes #331655 */
+ event_when_closed = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_ACTIONS_SLEEP_WHEN_CLOSED, NULL);
+
+ /* We keep track of the lid state so we can do the
+ lid close on battery action if the ac adapter is removed when the laptop
+ is closed. Fixes #331655 */
+ if (event_when_closed && on_battery && lid_is_closed) {
+ gpm_manager_perform_policy (manager, GPM_CONF_BUTTON_LID_BATT,
+ "The lid has been closed, and the ac adapter "
+ "removed (and mateconf is okay).");
+ }
+}
+
+/**
+ * manager_critical_action_do:
+ * @manager: This class instance
+ *
+ * This is the stub function when we have waited a few seconds for the user to
+ * see the message, explaining what we are about to do.
+ *
+ * Return value: FALSE, as we don't want to repeat this action on resume.
+ **/
+static gboolean
+manager_critical_action_do (GpmManager *manager)
+{
+ /* stop playing the alert as it's too late to do anything now */
+ if (manager->priv->critical_alert_timeout_id)
+ gpm_manager_play_loop_stop (manager);
+
+ gpm_manager_perform_policy (manager, GPM_CONF_ACTIONS_CRITICAL_BATT, "Battery is critically low.");
+ return FALSE;
+}
+
+/**
+ * gpm_manager_class_init:
+ * @klass: The GpmManagerClass
+ **/
+static void
+gpm_manager_class_init (GpmManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_manager_finalize;
+ g_type_class_add_private (klass, sizeof (GpmManagerPrivate));
+}
+
+/**
+ * gpm_conf_mateconf_key_changed_cb:
+ *
+ * We might have to do things when the mateconf keys change; do them here.
+ **/
+static void
+gpm_conf_mateconf_key_changed_cb (MateConfClient *client, guint cnxn_id, MateConfEntry *entry, GpmManager *manager)
+{
+ MateConfValue *value;
+
+ value = mateconf_entry_get_value (entry);
+ if (value == NULL)
+ return;
+
+ if (g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT) == 0 ||
+ g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC) == 0 ||
+ g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT) == 0 ||
+ g_strcmp0 (entry->key, GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC) == 0)
+ gpm_manager_sync_policy_sleep (manager);
+}
+
+#if 0
+/**
+ * gpm_manager_screensaver_auth_request_cb:
+ * @manager: This manager class instance
+ * @auth: If we are trying to authenticate
+ *
+ * Called when the user is trying or has authenticated
+ **/
+static void
+gpm_manager_screensaver_auth_request_cb (GpmScreensaver *screensaver, gboolean auth_begin, GpmManager *manager)
+{
+ GError *error = NULL;
+
+ if (auth_begin) {
+ /* We turn on the monitor unconditionally, as we may be using
+ * a smartcard to authenticate and DPMS might still be on.
+ * See #350291 for more details */
+ gpm_dpms_set_mode (manager->priv->dpms, GPM_DPMS_MODE_ON, &error);
+ if (error != NULL) {
+ egg_warning ("Failed to turn on DPMS: %s", error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ }
+}
+#endif
+
+/**
+ * gpm_manager_perhaps_recall_response_cb:
+ */
+static void
+gpm_manager_perhaps_recall_response_cb (GtkDialog *dialog, gint response_id, GpmManager *manager)
+{
+ GdkScreen *screen;
+ GtkWidget *dialog_error;
+ GError *error = NULL;
+ gboolean ret;
+ const gchar *website;
+
+ /* don't show this again */
+ if (response_id == GTK_RESPONSE_CANCEL) {
+ mateconf_client_set_bool (manager->priv->conf, GPM_CONF_NOTIFY_PERHAPS_RECALL, FALSE, NULL);
+ goto out;
+ }
+
+ /* visit recall website */
+ if (response_id == GTK_RESPONSE_OK) {
+ screen = gdk_screen_get_default();
+ website = (const gchar *) g_object_get_data (G_OBJECT (manager), "recall-oem-website");
+ ret = gtk_show_uri (screen, website, gtk_get_current_event_time (), &error);
+ if (!ret) {
+ dialog_error = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
+ "Failed to show url %s", error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog_error));
+ g_error_free (error);
+ }
+ goto out;
+ }
+out:
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ return;
+}
+
+/**
+ * gpm_manager_perhaps_recall_delay_cb:
+ */
+static gboolean
+gpm_manager_perhaps_recall_delay_cb (GpmManager *manager)
+{
+ const gchar *oem_vendor;
+ gchar *title = NULL;
+ gchar *message = NULL;
+ GtkWidget *dialog;
+
+ oem_vendor = (const gchar *) g_object_get_data (G_OBJECT (manager), "recall-oem-vendor");
+
+ /* TRANSLATORS: the battery may be recalled by it's vendor */
+ title = g_strdup_printf ("%s: %s", GPM_NAME, _("Battery may be recalled"));
+ message = g_strdup_printf (_("A battery in your computer may have been "
+ "recalled by %s and you may be at risk.\n\n"
+ "For more information visit the battery recall website."), oem_vendor);
+ dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+ "<span size='larger'><b>%s</b></span>", title);
+
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+
+ /* TRANSLATORS: button text, visit the manufacturers recall website */
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("Visit recall website"), GTK_RESPONSE_OK);
+
+ /* TRANSLATORS: button text, do not show this bubble again */
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("Do not show me this again"), GTK_RESPONSE_CANCEL);
+
+ /* wait async for response */
+ gtk_widget_show (dialog);
+ g_signal_connect (dialog, "response", G_CALLBACK (gpm_manager_perhaps_recall_response_cb), manager);
+
+ g_free (title);
+ g_free (message);
+
+ /* never repeat */
+ return FALSE;
+}
+
+/**
+ * gpm_manager_engine_perhaps_recall_cb:
+ */
+static void
+gpm_manager_engine_perhaps_recall_cb (GpmEngine *engine, UpDevice *device, gchar *oem_vendor, gchar *website, GpmManager *manager)
+{
+ gboolean ret;
+
+ /* don't show when running under GDM */
+ if (g_getenv ("RUNNING_UNDER_GDM") != NULL) {
+ egg_debug ("running under gdm, so no notification");
+ return;
+ }
+
+ /* already shown, and dismissed */
+ ret = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_PERHAPS_RECALL, NULL);
+ if (!ret) {
+ egg_debug ("MateConf prevents notification: %s", GPM_CONF_NOTIFY_PERHAPS_RECALL);
+ return;
+ }
+
+ g_object_set_data_full (G_OBJECT (manager), "recall-oem-vendor", (gpointer) g_strdup (oem_vendor), (GDestroyNotify) g_free);
+ g_object_set_data_full (G_OBJECT (manager), "recall-oem-website", (gpointer) g_strdup (website), (GDestroyNotify) g_free);
+
+ /* delay by a few seconds so the panel can load */
+ g_timeout_add_seconds (GPM_MANAGER_RECALL_DELAY, (GSourceFunc) gpm_manager_perhaps_recall_delay_cb, manager);
+}
+
+/**
+ * gpm_manager_engine_icon_changed_cb:
+ */
+static void
+gpm_manager_engine_icon_changed_cb (GpmEngine *engine, gchar *icon, GpmManager *manager)
+{
+ gpm_tray_icon_set_icon (manager->priv->tray_icon, icon);
+}
+
+/**
+ * gpm_manager_engine_summary_changed_cb:
+ */
+static void
+gpm_manager_engine_summary_changed_cb (GpmEngine *engine, gchar *summary, GpmManager *manager)
+{
+ gpm_tray_icon_set_tooltip (manager->priv->tray_icon, summary);
+}
+
+/**
+ * gpm_manager_engine_low_capacity_cb:
+ */
+static void
+gpm_manager_engine_low_capacity_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
+{
+ gchar *message = NULL;
+ const gchar *title;
+ gdouble capacity;
+
+ /* don't show when running under GDM */
+ if (g_getenv ("RUNNING_UNDER_GDM") != NULL) {
+ egg_debug ("running under gdm, so no notification");
+ goto out;
+ }
+
+ /* get device properties */
+ g_object_get (device,
+ "capacity", &capacity,
+ NULL);
+
+ /* We should notify the user if the battery has a low capacity,
+ * where capacity is the ratio of the last_full capacity with that of
+ * the design capacity. (#326740) */
+
+ /* TRANSLATORS: battery is old or broken */
+ title = _("Battery may be broken");
+
+ /* TRANSLATORS: notify the user that that battery is broken as the capacity is very low */
+ message = g_strdup_printf (_("Battery has a very low capacity (%1.1f%%), "
+ "which means that it may be old or broken."), capacity);
+ gpm_manager_notify (manager, &manager->priv->notification_general, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_SHORT,
+ GTK_STOCK_DIALOG_INFO, NOTIFY_URGENCY_LOW);
+out:
+ g_free (message);
+}
+
+/**
+ * gpm_manager_engine_fully_charged_cb:
+ */
+static void
+gpm_manager_engine_fully_charged_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
+{
+ UpDeviceKind kind;
+ gchar *native_path = NULL;
+ gboolean ret;
+ guint plural = 1;
+ const gchar *title;
+
+ /* only action this if specified in mateconf */
+ ret = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_FULLY_CHARGED, NULL);
+ if (!ret) {
+ egg_debug ("no notification");
+ goto out;
+ }
+
+ /* don't show when running under GDM */
+ if (g_getenv ("RUNNING_UNDER_GDM") != NULL) {
+ egg_debug ("running under gdm, so no notification");
+ goto out;
+ }
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "native-path", &native_path,
+ NULL);
+
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ /* is this a dummy composite device, which is plural? */
+ if (g_str_has_prefix (native_path, "dummy"))
+ plural = 2;
+
+ /* hide the discharging notification */
+ gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
+ gpm_manager_notify_close (manager, manager->priv->notification_discharging);
+
+ /* TRANSLATORS: show the charged notification */
+ title = ngettext ("Battery Charged", "Batteries Charged", plural);
+ gpm_manager_notify (manager, &manager->priv->notification_fully_charged,
+ title, NULL, GPM_MANAGER_NOTIFY_TIMEOUT_SHORT,
+ GTK_STOCK_DIALOG_INFO, NOTIFY_URGENCY_LOW);
+ }
+out:
+ g_free (native_path);
+}
+
+/**
+ * gpm_manager_engine_discharging_cb:
+ */
+static void
+gpm_manager_engine_discharging_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
+{
+ UpDeviceKind kind;
+ gboolean ret;
+ const gchar *title;
+ const gchar *message;
+ gdouble percentage;
+ gint64 time_to_empty;
+ gchar *remaining_text = NULL;
+ gchar *icon = NULL;
+ const gchar *kind_desc;
+
+ /* only action this if specified in mateconf */
+ ret = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_NOTIFY_DISCHARGING, NULL);
+ if (!ret) {
+ egg_debug ("no notification");
+ goto out;
+ }
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "percentage", &percentage,
+ "time-to-empty", &time_to_empty,
+ NULL);
+
+ /* only show text if there is a valid time */
+ if (time_to_empty > 0)
+ remaining_text = gpm_get_timestring (time_to_empty);
+ kind_desc = gpm_device_kind_to_localised_text (kind, 1);
+
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ /* TRANSLATORS: laptop battery is now discharging */
+ title = _("Battery Discharging");
+
+ if (remaining_text != NULL) {
+ /* TRANSLATORS: tell the user how much time they have got */
+ message = g_strdup_printf (_("%s of battery power remaining (%.0f%%)"), remaining_text, percentage);
+ } else {
+ /* TRANSLATORS: the device is discharging, but we only have a percentage */
+ message = g_strdup_printf (_("%s discharging (%.0f%%)"),
+ kind_desc, percentage);
+ }
+ } else if (kind == UP_DEVICE_KIND_UPS) {
+ /* TRANSLATORS: UPS is now discharging */
+ title = _("UPS Discharging");
+
+ if (remaining_text != NULL) {
+ /* TRANSLATORS: tell the user how much time they have got */
+ message = g_strdup_printf (_("%s of UPS backup power remaining (%.0f%%)"), remaining_text, percentage);
+ } else {
+ /* TRANSLATORS: the device is discharging, but we only have a percentage */
+ message = g_strdup_printf (_("%s discharging (%.0f%%)"),
+ kind_desc, percentage);
+ }
+ } else {
+ /* nothing else of interest */
+ goto out;
+ }
+
+ icon = gpm_upower_get_device_icon (device);
+ /* show the notification */
+ gpm_manager_notify (manager, &manager->priv->notification_discharging, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_LONG,
+ icon, NOTIFY_URGENCY_NORMAL);
+out:
+ g_free (icon);
+ g_free (remaining_text);
+ return;
+}
+
+/**
+ * gpm_manager_engine_just_laptop_battery:
+ */
+static gboolean
+gpm_manager_engine_just_laptop_battery (GpmManager *manager)
+{
+ UpDevice *device;
+ UpDeviceKind kind;
+ GPtrArray *array;
+ gboolean ret = TRUE;
+ guint i;
+
+ /* find if there are any other device types that mean we have to
+ * be more specific in our wording */
+ array = gpm_engine_get_devices (manager->priv->engine);
+ for (i=0; i<array->len; i++) {
+ device = g_ptr_array_index (array, i);
+ g_object_get (device, "kind", &kind, NULL);
+ if (kind != UP_DEVICE_KIND_BATTERY) {
+ ret = FALSE;
+ break;
+ }
+ }
+ g_ptr_array_unref (array);
+ return ret;
+}
+
+/**
+ * gpm_manager_engine_charge_low_cb:
+ */
+static void
+gpm_manager_engine_charge_low_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
+{
+ const gchar *title = NULL;
+ gchar *message = NULL;
+ gchar *remaining_text;
+ gchar *icon = NULL;
+ UpDeviceKind kind;
+ gdouble percentage;
+ gint64 time_to_empty;
+ gboolean ret;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "percentage", &percentage,
+ "time-to-empty", &time_to_empty,
+ NULL);
+
+ /* check to see if the batteries have not noticed we are on AC */
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ if (!manager->priv->on_battery) {
+ egg_warning ("ignoring critically low message as we are not on battery power");
+ goto out;
+ }
+ }
+
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+
+ /* if the user has no other batteries, drop the "Laptop" wording */
+ ret = gpm_manager_engine_just_laptop_battery (manager);
+ if (ret) {
+ /* TRANSLATORS: laptop battery low, and we only have one battery */
+ title = _("Battery low");
+ } else {
+ /* TRANSLATORS: laptop battery low, and we have more than one kind of battery */
+ title = _("Laptop battery low");
+ }
+
+ remaining_text = gpm_get_timestring (time_to_empty);
+
+ /* TRANSLATORS: tell the user how much time they have got */
+ message = g_strdup_printf (_("Approximately <b>%s</b> remaining (%.0f%%)"), remaining_text, percentage);
+
+ } else if (kind == UP_DEVICE_KIND_UPS) {
+ /* TRANSLATORS: UPS is starting to get a little low */
+ title = _("UPS low");
+ remaining_text = gpm_get_timestring (time_to_empty);
+
+ /* TRANSLATORS: tell the user how much time they have got */
+ message = g_strdup_printf (_("Approximately <b>%s</b> of remaining UPS backup power (%.0f%%)"),
+ remaining_text, percentage);
+ } else if (kind == UP_DEVICE_KIND_MOUSE) {
+ /* TRANSLATORS: mouse is getting a little low */
+ title = _("Mouse battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("Wireless mouse is low in power (%.0f%%)"), percentage);
+
+ } else if (kind == UP_DEVICE_KIND_KEYBOARD) {
+ /* TRANSLATORS: keyboard is getting a little low */
+ title = _("Keyboard battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("Wireless keyboard is low in power (%.0f%%)"), percentage);
+
+ } else if (kind == UP_DEVICE_KIND_PDA) {
+ /* TRANSLATORS: PDA is getting a little low */
+ title = _("PDA battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("PDA is low in power (%.0f%%)"), percentage);
+
+ } else if (kind == UP_DEVICE_KIND_PHONE) {
+ /* TRANSLATORS: cell phone (mobile) is getting a little low */
+ title = _("Cell phone battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("Cell phone is low in power (%.0f%%)"), percentage);
+
+#if UP_CHECK_VERSION(0,9,5)
+ } else if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) {
+ /* TRANSLATORS: media player, e.g. mp3 is getting a little low */
+ title = _("Media player battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("Media player is low in power (%.0f%%)"), percentage);
+
+ } else if (kind == UP_DEVICE_KIND_TABLET) {
+ /* TRANSLATORS: graphics tablet, e.g. wacom is getting a little low */
+ title = _("Tablet battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("Tablet is low in power (%.0f%%)"), percentage);
+
+ } else if (kind == UP_DEVICE_KIND_COMPUTER) {
+ /* TRANSLATORS: computer, e.g. ipad is getting a little low */
+ title = _("Attached computer battery low");
+
+ /* TRANSLATORS: tell user more details */
+ message = g_strdup_printf (_("Attached computer is low in power (%.0f%%)"), percentage);
+#endif
+ }
+
+ /* get correct icon */
+ icon = gpm_upower_get_device_icon (device);
+ gpm_manager_notify (manager, &manager->priv->notification_warning_low, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_LONG, icon, NOTIFY_URGENCY_NORMAL);
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_BATTERY_CAUTION, TRUE);
+out:
+ g_free (icon);
+ g_free (message);
+}
+
+/**
+ * gpm_manager_engine_charge_critical_cb:
+ */
+static void
+gpm_manager_engine_charge_critical_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
+{
+ const gchar *title = NULL;
+ gchar *message = NULL;
+ gchar *action;
+ gchar *icon = NULL;
+ UpDeviceKind kind;
+ gdouble percentage;
+ gint64 time_to_empty;
+ GpmActionPolicy policy;
+ gboolean ret;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "percentage", &percentage,
+ "time-to-empty", &time_to_empty,
+ NULL);
+
+ /* check to see if the batteries have not noticed we are on AC */
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ if (!manager->priv->on_battery) {
+ egg_warning ("ignoring critically low message as we are not on battery power");
+ goto out;
+ }
+ }
+
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+
+ /* if the user has no other batteries, drop the "Laptop" wording */
+ ret = gpm_manager_engine_just_laptop_battery (manager);
+ if (ret) {
+ /* TRANSLATORS: laptop battery critically low, and only have one kind of battery */
+ title = _("Battery critically low");
+ } else {
+ /* TRANSLATORS: laptop battery critically low, and we have more than one type of battery */
+ title = _("Laptop battery critically low");
+ }
+
+ /* we have to do different warnings depending on the policy */
+ action = mateconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_CRITICAL_BATT, NULL);
+ policy = gpm_action_policy_from_string (action);
+
+ /* use different text for different actions */
+ if (policy == GPM_ACTION_POLICY_NOTHING) {
+ /* TRANSLATORS: tell the use to insert the plug, as we're not going to do anything */
+ message = g_strdup (_("Plug in your AC adapter to avoid losing data."));
+
+ } else if (policy == GPM_ACTION_POLICY_SUSPEND) {
+ /* TRANSLATORS: give the user a ultimatum */
+ message = g_strdup_printf (_("Computer will suspend very soon unless it is plugged in."));
+
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
+ /* TRANSLATORS: give the user a ultimatum */
+ message = g_strdup_printf (_("Computer will hibernate very soon unless it is plugged in."));
+
+ } else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
+ /* TRANSLATORS: give the user a ultimatum */
+ message = g_strdup_printf (_("Computer will shutdown very soon unless it is plugged in."));
+ }
+
+ g_free (action);
+ } else if (kind == UP_DEVICE_KIND_UPS) {
+ gchar *remaining_text;
+
+ /* TRANSLATORS: the UPS is very low */
+ title = _("UPS critically low");
+ remaining_text = gpm_get_timestring (time_to_empty);
+
+ /* TRANSLATORS: give the user a ultimatum */
+ message = g_strdup_printf (_("Approximately <b>%s</b> of remaining UPS power (%.0f%%). "
+ "Restore AC power to your computer to avoid losing data."),
+ remaining_text, percentage);
+ g_free (remaining_text);
+ } else if (kind == UP_DEVICE_KIND_MOUSE) {
+ /* TRANSLATORS: the mouse battery is very low */
+ title = _("Mouse battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("Wireless mouse is very low in power (%.0f%%). "
+ "This device will soon stop functioning if not charged."),
+ percentage);
+ } else if (kind == UP_DEVICE_KIND_KEYBOARD) {
+ /* TRANSLATORS: the keyboard battery is very low */
+ title = _("Keyboard battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("Wireless keyboard is very low in power (%.0f%%). "
+ "This device will soon stop functioning if not charged."),
+ percentage);
+ } else if (kind == UP_DEVICE_KIND_PDA) {
+
+ /* TRANSLATORS: the PDA battery is very low */
+ title = _("PDA battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("PDA is very low in power (%.0f%%). "
+ "This device will soon stop functioning if not charged."),
+ percentage);
+
+ } else if (kind == UP_DEVICE_KIND_PHONE) {
+
+ /* TRANSLATORS: the cell battery is very low */
+ title = _("Cell phone battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("Cell phone is very low in power (%.0f%%). "
+ "This device will soon stop functioning if not charged."),
+ percentage);
+
+#if UP_CHECK_VERSION(0,9,5)
+ } else if (kind == UP_DEVICE_KIND_MEDIA_PLAYER) {
+
+ /* TRANSLATORS: the cell battery is very low */
+ title = _("Cell phone battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("Media player is very low in power (%.0f%%). "
+ "This device will soon stop functioning if not charged."),
+ percentage);
+ } else if (kind == UP_DEVICE_KIND_TABLET) {
+
+ /* TRANSLATORS: the cell battery is very low */
+ title = _("Tablet battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("Tablet is very low in power (%.0f%%). "
+ "This device will soon stop functioning if not charged."),
+ percentage);
+ } else if (kind == UP_DEVICE_KIND_COMPUTER) {
+
+ /* TRANSLATORS: the cell battery is very low */
+ title = _("Attached computer battery low");
+
+ /* TRANSLATORS: the device is just going to stop working */
+ message = g_strdup_printf (_("Attached computer is very low in power (%.0f%%). "
+ "The device will soon shutdown if not charged."),
+ percentage);
+#endif
+ }
+
+ /* get correct icon */
+ icon = gpm_upower_get_device_icon (device);
+ gpm_manager_notify (manager, &manager->priv->notification_warning_low, title, message, GPM_MANAGER_NOTIFY_TIMEOUT_NEVER, icon, NOTIFY_URGENCY_CRITICAL);
+
+ switch (kind) {
+
+ case UP_DEVICE_KIND_BATTERY:
+ case UP_DEVICE_KIND_UPS:
+ egg_debug ("critical charge level reached, starting sound loop");
+ gpm_manager_play_loop_start (manager,
+ GPM_MANAGER_SOUND_BATTERY_LOW,
+ TRUE,
+ GPM_MANAGER_CRITICAL_ALERT_TIMEOUT);
+ break;
+
+ default:
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_BATTERY_LOW, TRUE);
+ }
+out:
+ g_free (icon);
+ g_free (message);
+}
+
+/**
+ * gpm_manager_engine_charge_action_cb:
+ */
+static void
+gpm_manager_engine_charge_action_cb (GpmEngine *engine, UpDevice *device, GpmManager *manager)
+{
+ const gchar *title = NULL;
+ gchar *action;
+ gchar *message = NULL;
+ gchar *icon = NULL;
+ UpDeviceKind kind;
+ GpmActionPolicy policy;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ NULL);
+
+ /* check to see if the batteries have not noticed we are on AC */
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ if (!manager->priv->on_battery) {
+ egg_warning ("ignoring critically low message as we are not on battery power");
+ goto out;
+ }
+ }
+
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+
+ /* TRANSLATORS: laptop battery is really, really, low */
+ title = _("Laptop battery critically low");
+
+ /* we have to do different warnings depending on the policy */
+ action = mateconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_CRITICAL_BATT, NULL);
+ policy = gpm_action_policy_from_string (action);
+
+ /* use different text for different actions */
+ if (policy == GPM_ACTION_POLICY_NOTHING) {
+ /* TRANSLATORS: computer will shutdown without saving data */
+ message = g_strdup (_("The battery is below the critical level and "
+ "this computer will <b>power-off</b> when the "
+ "battery becomes completely empty."));
+
+ } else if (policy == GPM_ACTION_POLICY_SUSPEND) {
+ /* TRANSLATORS: computer will suspend */
+ message = g_strdup (_("The battery is below the critical level and "
+ "this computer is about to suspend.<br>"
+ "<b>NOTE:</b> A small amount of power is required "
+ "to keep your computer in a suspended state."));
+
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
+ /* TRANSLATORS: computer will hibernate */
+ message = g_strdup (_("The battery is below the critical level and "
+ "this computer is about to hibernate."));
+
+ } else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
+ /* TRANSLATORS: computer will just shutdown */
+ message = g_strdup (_("The battery is below the critical level and "
+ "this computer is about to shutdown."));
+ }
+
+ g_free (action);
+
+ /* wait 20 seconds for user-panic */
+ g_timeout_add_seconds (20, (GSourceFunc) manager_critical_action_do, manager);
+
+ } else if (kind == UP_DEVICE_KIND_UPS) {
+ /* TRANSLATORS: UPS is really, really, low */
+ title = _("UPS critically low");
+
+ /* we have to do different warnings depending on the policy */
+ action = mateconf_client_get_string (manager->priv->conf, GPM_CONF_ACTIONS_CRITICAL_UPS, NULL);
+ policy = gpm_action_policy_from_string (action);
+
+ /* use different text for different actions */
+ if (policy == GPM_ACTION_POLICY_NOTHING) {
+ /* TRANSLATORS: computer will shutdown without saving data */
+ message = g_strdup (_("The UPS is below the critical level and "
+ "this computer will <b>power-off</b> when the "
+ "UPS becomes completely empty."));
+
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE) {
+ /* TRANSLATORS: computer will hibernate */
+ message = g_strdup (_("The UPS is below the critical level and "
+ "this computer is about to hibernate."));
+
+ } else if (policy == GPM_ACTION_POLICY_SHUTDOWN) {
+ /* TRANSLATORS: computer will just shutdown */
+ message = g_strdup (_("The UPS is below the critical level and "
+ "this computer is about to shutdown."));
+ }
+
+ /* wait 20 seconds for user-panic */
+ g_timeout_add_seconds (20, (GSourceFunc) manager_critical_action_do, manager);
+
+ g_free (action);
+ }
+
+ /* not all types have actions */
+ if (title == NULL)
+ return;
+
+ /* get correct icon */
+ icon = gpm_upower_get_device_icon (device);
+ gpm_manager_notify (manager, &manager->priv->notification_warning_low,
+ title, message, GPM_MANAGER_NOTIFY_TIMEOUT_NEVER,
+ icon, NOTIFY_URGENCY_CRITICAL);
+ gpm_manager_play (manager, GPM_MANAGER_SOUND_BATTERY_LOW, TRUE);
+out:
+ g_free (icon);
+ g_free (message);
+}
+
+/**
+ * gpm_manager_dpms_mode_changed_cb:
+ * @mode: The DPMS mode, e.g. GPM_DPMS_MODE_OFF
+ * @info: This class instance
+ *
+ * Log when the DPMS mode is changed.
+ **/
+static void
+gpm_manager_dpms_mode_changed_cb (GpmDpms *dpms, GpmDpmsMode mode, GpmManager *manager)
+{
+ egg_debug ("DPMS mode changed: %d", mode);
+
+ if (mode == GPM_DPMS_MODE_ON)
+ egg_debug ("dpms on");
+ else if (mode == GPM_DPMS_MODE_STANDBY)
+ egg_debug ("dpms standby");
+ else if (mode == GPM_DPMS_MODE_SUSPEND)
+ egg_debug ("suspend");
+ else if (mode == GPM_DPMS_MODE_OFF)
+ egg_debug ("dpms off");
+
+ gpm_manager_update_dpms_throttle (manager);
+}
+
+/*
+ * gpm_manager_reset_just_resumed_cb
+ */
+static gboolean
+gpm_manager_reset_just_resumed_cb (gpointer user_data)
+{
+ GpmManager *manager = GPM_MANAGER (user_data);
+
+ if (manager->priv->notification_general != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_general);
+ if (manager->priv->notification_warning_low != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
+ if (manager->priv->notification_discharging != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_discharging);
+ if (manager->priv->notification_fully_charged != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_fully_charged);
+
+ manager->priv->just_resumed = FALSE;
+ return FALSE;
+}
+
+/**
+ * gpm_manager_control_resume_cb
+ **/
+static void
+gpm_manager_control_resume_cb (GpmControl *control, GpmControlAction action, GpmManager *manager)
+{
+ manager->priv->just_resumed = TRUE;
+ g_timeout_add_seconds (1, gpm_manager_reset_just_resumed_cb, manager);
+}
+
+/**
+ * gpm_manager_init:
+ * @manager: This class instance
+ **/
+static void
+gpm_manager_init (GpmManager *manager)
+{
+ gboolean check_type_cpu;
+ gint timeout;
+ DBusGConnection *connection;
+ GError *error = NULL;
+ guint version;
+
+ manager->priv = GPM_MANAGER_GET_PRIVATE (manager);
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ /* init to unthrottled */
+ manager->priv->screensaver_ac_throttle_id = 0;
+ manager->priv->screensaver_dpms_throttle_id = 0;
+ manager->priv->screensaver_lid_throttle_id = 0;
+
+ manager->priv->critical_alert_timeout_id = 0;
+ manager->priv->critical_alert_loop_props = NULL;
+
+ /* init to not just_resumed */
+ manager->priv->just_resumed = FALSE;
+
+ /* don't apply policy when not active, so listen to ConsoleKit */
+ manager->priv->console = egg_console_kit_new ();
+
+ /* this is a singleton, so we keep a master copy open here */
+ manager->priv->prefs_server = gpm_prefs_server_new ();
+
+ manager->priv->notification_general = NULL;
+ manager->priv->notification_warning_low = NULL;
+ manager->priv->notification_discharging = NULL;
+ manager->priv->notification_fully_charged = NULL;
+ manager->priv->disks = gpm_disks_new ();
+ manager->priv->conf = mateconf_client_get_default ();
+ manager->priv->client = up_client_new ();
+ g_signal_connect (manager->priv->client, "changed",
+ G_CALLBACK (gpm_manager_client_changed_cb), manager);
+
+ /* use libmatenotify */
+ notify_init (GPM_NAME);
+
+ /* watch mate-power-manager keys */
+ mateconf_client_add_dir (manager->priv->conf, GPM_CONF_DIR,
+ MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+ mateconf_client_notify_add (manager->priv->conf, GPM_CONF_DIR,
+ (MateConfClientNotifyFunc) gpm_conf_mateconf_key_changed_cb,
+ manager, NULL, NULL);
+
+ /* check to see if the user has installed the schema properly */
+ version = mateconf_client_get_int (manager->priv->conf, GPM_CONF_SCHEMA_VERSION, NULL);
+ if (version != GPM_CONF_SCHEMA_ID) {
+ gpm_manager_notify (manager, &manager->priv->notification_general,
+ /* TRANSLATORS: there was in install problem */
+ _("Install problem!"),
+ /* TRANSLATORS: the MateConf schema was not installed properly */
+ _("The configuration defaults for MATE Power Manager have not been installed correctly.\n"
+ "Please contact your computer administrator."),
+ GPM_MANAGER_NOTIFY_TIMEOUT_LONG,
+ GTK_STOCK_DIALOG_WARNING,
+ NOTIFY_URGENCY_NORMAL);
+ egg_error ("no mateconf schema installed!");
+ }
+
+ /* coldplug so we are in the correct state at startup */
+ g_object_get (manager->priv->client,
+ "on-battery", &manager->priv->on_battery,
+ NULL);
+
+ manager->priv->button = gpm_button_new ();
+ g_signal_connect (manager->priv->button, "button-pressed",
+ G_CALLBACK (gpm_manager_button_pressed_cb), manager);
+
+ /* try and start an interactive service */
+ manager->priv->screensaver = gpm_screensaver_new ();
+#if 0
+ g_signal_connect (manager->priv->screensaver, "auth-request",
+ G_CALLBACK (gpm_manager_screensaver_auth_request_cb), manager);
+#endif
+
+ /* try an start an interactive service */
+ manager->priv->backlight = gpm_backlight_new ();
+ if (manager->priv->backlight != NULL) {
+ /* add the new brightness lcd DBUS interface */
+ dbus_g_object_type_install_info (GPM_TYPE_BACKLIGHT,
+ &dbus_glib_gpm_backlight_object_info);
+ dbus_g_connection_register_g_object (connection, GPM_DBUS_PATH_BACKLIGHT,
+ G_OBJECT (manager->priv->backlight));
+ }
+
+ manager->priv->idle = gpm_idle_new ();
+ g_signal_connect (manager->priv->idle, "idle-changed",
+ G_CALLBACK (gpm_manager_idle_changed_cb), manager);
+
+ /* set up the check_type_cpu, so we can disable the CPU load check */
+ check_type_cpu = mateconf_client_get_bool (manager->priv->conf, GPM_CONF_IDLE_CHECK_CPU, NULL);
+ gpm_idle_set_check_cpu (manager->priv->idle, check_type_cpu);
+
+ manager->priv->dpms = gpm_dpms_new ();
+ g_signal_connect (manager->priv->dpms, "mode-changed",
+ G_CALLBACK (gpm_manager_dpms_mode_changed_cb), manager);
+
+ /* use the control object */
+ egg_debug ("creating new control instance");
+ manager->priv->control = gpm_control_new ();
+ g_signal_connect (manager->priv->control, "resume",
+ G_CALLBACK (gpm_manager_control_resume_cb), manager);
+
+ egg_debug ("creating new tray icon");
+ manager->priv->tray_icon = gpm_tray_icon_new ();
+
+ /* keep a reference for the notifications */
+ manager->priv->status_icon = gpm_tray_icon_get_status_icon (manager->priv->tray_icon);
+
+ gpm_manager_sync_policy_sleep (manager);
+
+ manager->priv->engine = gpm_engine_new ();
+ g_signal_connect (manager->priv->engine, "perhaps-recall",
+ G_CALLBACK (gpm_manager_engine_perhaps_recall_cb), manager);
+ g_signal_connect (manager->priv->engine, "low-capacity",
+ G_CALLBACK (gpm_manager_engine_low_capacity_cb), manager);
+ g_signal_connect (manager->priv->engine, "icon-changed",
+ G_CALLBACK (gpm_manager_engine_icon_changed_cb), manager);
+ g_signal_connect (manager->priv->engine, "summary-changed",
+ G_CALLBACK (gpm_manager_engine_summary_changed_cb), manager);
+ g_signal_connect (manager->priv->engine, "fully-charged",
+ G_CALLBACK (gpm_manager_engine_fully_charged_cb), manager);
+ g_signal_connect (manager->priv->engine, "discharging",
+ G_CALLBACK (gpm_manager_engine_discharging_cb), manager);
+ g_signal_connect (manager->priv->engine, "charge-low",
+ G_CALLBACK (gpm_manager_engine_charge_low_cb), manager);
+ g_signal_connect (manager->priv->engine, "charge-critical",
+ G_CALLBACK (gpm_manager_engine_charge_critical_cb), manager);
+ g_signal_connect (manager->priv->engine, "charge-action",
+ G_CALLBACK (gpm_manager_engine_charge_action_cb), manager);
+
+ /* set disk spindown threshold */
+ timeout = gpm_manager_get_spindown_timeout (manager);
+ gpm_disks_set_spindown_timeout (manager->priv->disks, timeout);
+
+ /* update ac throttle */
+ gpm_manager_update_ac_throttle (manager);
+}
+
+/**
+ * gpm_manager_finalize:
+ * @object: The object to finalize
+ *
+ * Finalise the manager, by unref'ing all the depending modules.
+ **/
+static void
+gpm_manager_finalize (GObject *object)
+{
+ GpmManager *manager;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_MANAGER (object));
+
+ manager = GPM_MANAGER (object);
+
+ g_return_if_fail (manager->priv != NULL);
+
+ /* close any notifications (also unrefs them) */
+ if (manager->priv->notification_general != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_general);
+ if (manager->priv->notification_warning_low != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_warning_low);
+ if (manager->priv->notification_discharging != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_discharging);
+ if (manager->priv->notification_fully_charged != NULL)
+ gpm_manager_notify_close (manager, manager->priv->notification_fully_charged);
+ if (manager->priv->critical_alert_timeout_id != 0)
+ g_source_remove (manager->priv->critical_alert_timeout_id);
+
+ g_object_unref (manager->priv->conf);
+ g_object_unref (manager->priv->disks);
+ g_object_unref (manager->priv->dpms);
+ g_object_unref (manager->priv->idle);
+ g_object_unref (manager->priv->engine);
+ g_object_unref (manager->priv->tray_icon);
+ g_object_unref (manager->priv->screensaver);
+ g_object_unref (manager->priv->prefs_server);
+ g_object_unref (manager->priv->control);
+ g_object_unref (manager->priv->button);
+ g_object_unref (manager->priv->backlight);
+ g_object_unref (manager->priv->console);
+ g_object_unref (manager->priv->client);
+ g_object_unref (manager->priv->status_icon);
+
+ G_OBJECT_CLASS (gpm_manager_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_manager_new:
+ *
+ * Return value: a new GpmManager object.
+ **/
+GpmManager *
+gpm_manager_new (void)
+{
+ GpmManager *manager;
+ manager = g_object_new (GPM_TYPE_MANAGER, NULL);
+ return GPM_MANAGER (manager);
+}
diff --git a/src/gpm-manager.h b/src/gpm-manager.h
new file mode 100644
index 0000000..1d31b75
--- /dev/null
+++ b/src/gpm-manager.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_MANAGER_H
+#define __GPM_MANAGER_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_MANAGER (gpm_manager_get_type ())
+#define GPM_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_MANAGER, GpmManager))
+#define GPM_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_MANAGER, GpmManagerClass))
+#define GPM_IS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_MANAGER))
+#define GPM_IS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_MANAGER))
+#define GPM_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_MANAGER, GpmManagerClass))
+#define GPM_MANAGER_ERROR (gpm_manager_error_quark ())
+#define GPM_MANAGER_TYPE_ERROR (gpm_manager_error_get_type ())
+
+typedef struct GpmManagerPrivate GpmManagerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmManagerPrivate *priv;
+} GpmManager;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpmManagerClass;
+
+typedef enum
+{
+ GPM_MANAGER_ERROR_DENIED,
+ GPM_MANAGER_ERROR_NO_HW,
+ GPM_MANAGER_ERROR_LAST
+} GpmManagerError;
+
+
+GQuark gpm_manager_error_quark (void);
+GType gpm_manager_error_get_type (void);
+GType gpm_manager_get_type (void);
+GpmManager *gpm_manager_new (void);
+
+gboolean gpm_manager_suspend (GpmManager *manager,
+ GError **error);
+gboolean gpm_manager_hibernate (GpmManager *manager,
+ GError **error);
+gboolean gpm_manager_can_suspend (GpmManager *manager,
+ gboolean *can_suspend,
+ GError **error);
+gboolean gpm_manager_can_hibernate (GpmManager *manager,
+ gboolean *can_hibernate,
+ GError **error);
+gboolean gpm_manager_get_preferences_options (GpmManager *manager,
+ gint *capability,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GPM_MANAGER_H */
diff --git a/src/gpm-marshal.list b/src/gpm-marshal.list
new file mode 100644
index 0000000..1a94c6a
--- /dev/null
+++ b/src/gpm-marshal.list
@@ -0,0 +1,16 @@
+NONE:INT,BOXED
+NONE:STRING,STRING
+NONE:POINTER,STRING,STRING
+NONE:UINT,UINT,BOOL
+NONE:STRING,STRING,STRING
+NONE:STRING,BOOLEAN
+NONE:STRING,STRING,BOOLEAN
+NONE:STRING,STRING,BOOLEAN,BOOLEAN,BOOLEAN
+NONE:INT
+NONE:STRING
+NONE:INT,LONG,BOOLEAN,BOOLEAN
+NONE:BOOLEAN,BOOLEAN
+NONE:UINT
+NONE:UINT,UINT
+NONE:UINT,POINTER
+
diff --git a/src/gpm-networkmanager.c b/src/gpm-networkmanager.c
new file mode 100644
index 0000000..3b62406
--- /dev/null
+++ b/src/gpm-networkmanager.c
@@ -0,0 +1,102 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include "gpm-networkmanager.h"
+#include "egg-debug.h"
+
+#define NM_LISTENER_SERVICE "org.freedesktop.NetworkManager"
+#define NM_LISTENER_PATH "/org/freedesktop/NetworkManager"
+#define NM_LISTENER_INTERFACE "org.freedesktop.NetworkManager"
+
+/**
+ * gpm_networkmanager_sleep:
+ *
+ * Tell NetworkManager to put the network devices to sleep
+ *
+ * Return value: TRUE if NetworkManager is now sleeping.
+ **/
+gboolean
+gpm_networkmanager_sleep (void)
+{
+ DBusGConnection *connection = NULL;
+ DBusGProxy *nm_proxy = NULL;
+ GError *error = NULL;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (error) {
+ egg_warning ("%s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ nm_proxy = dbus_g_proxy_new_for_name (connection,
+ NM_LISTENER_SERVICE,
+ NM_LISTENER_PATH,
+ NM_LISTENER_INTERFACE);
+ if (!nm_proxy) {
+ egg_warning ("Failed to get name owner");
+ return FALSE;
+ }
+ dbus_g_proxy_call_no_reply (nm_proxy, "sleep", G_TYPE_INVALID);
+ g_object_unref (G_OBJECT (nm_proxy));
+ return TRUE;
+}
+
+/**
+ * gpm_networkmanager_wake:
+ *
+ * Tell NetworkManager to wake up all the network devices
+ *
+ * Return value: TRUE if NetworkManager is now awake.
+ **/
+gboolean
+gpm_networkmanager_wake (void)
+{
+ DBusGConnection *connection = NULL;
+ DBusGProxy *nm_proxy = NULL;
+ GError *error = NULL;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (error) {
+ egg_warning ("%s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ nm_proxy = dbus_g_proxy_new_for_name (connection,
+ NM_LISTENER_SERVICE,
+ NM_LISTENER_PATH,
+ NM_LISTENER_INTERFACE);
+ if (!nm_proxy) {
+ egg_warning ("Failed to get name owner");
+ return FALSE;
+ }
+ dbus_g_proxy_call_no_reply (nm_proxy, "wake", G_TYPE_INVALID);
+ g_object_unref (G_OBJECT (nm_proxy));
+ return TRUE;
+}
diff --git a/src/gpm-networkmanager.h b/src/gpm-networkmanager.h
new file mode 100644
index 0000000..b60208b
--- /dev/null
+++ b/src/gpm-networkmanager.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_NETWORKMANAGER_H
+#define __GPM_NETWORKMANAGER_H
+
+G_BEGIN_DECLS
+
+gboolean gpm_networkmanager_sleep (void);
+gboolean gpm_networkmanager_wake (void);
+
+G_END_DECLS
+
+#endif /* __GPM_NETWORKMANAGER_H */
diff --git a/src/gpm-phone.c b/src/gpm-phone.c
new file mode 100644
index 0000000..e5455f7
--- /dev/null
+++ b/src/gpm-phone.c
@@ -0,0 +1,508 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include <mateconf/mateconf-client.h>
+#include "gpm-phone.h"
+#include "egg-debug.h"
+#include "gpm-marshal.h"
+
+#include "egg-dbus-monitor.h"
+
+static void gpm_phone_finalize (GObject *object);
+
+#define GPM_PHONE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_PHONE, GpmPhonePrivate))
+
+struct GpmPhonePrivate
+{
+ DBusGProxy *proxy;
+ DBusGConnection *connection;
+ EggDbusMonitor *monitor;
+ gboolean present;
+ guint percentage;
+ gboolean onac;
+};
+
+enum {
+ DEVICE_ADDED,
+ DEVICE_REMOVED,
+ DEVICE_REFRESH,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_phone_object = NULL;
+
+G_DEFINE_TYPE (GpmPhone, gpm_phone, G_TYPE_OBJECT)
+
+/**
+ * gpm_phone_coldplug:
+ * Return value: Success value, or zero for failure
+ **/
+gboolean
+gpm_phone_coldplug (GpmPhone *phone)
+{
+ GError *error = NULL;
+ gboolean ret;
+
+ g_return_val_if_fail (phone != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);
+
+ if (phone->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ ret = dbus_g_proxy_call (phone->priv->proxy, "Coldplug", &error,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+ if (error != NULL) {
+ egg_warning ("DEBUG: ERROR: %s", error->message);
+ g_error_free (error);
+ }
+
+ return ret;
+}
+
+/**
+ * gpm_phone_coldplug:
+ * Return value: if present
+ **/
+gboolean
+gpm_phone_get_present (GpmPhone *phone, guint idx)
+{
+ g_return_val_if_fail (phone != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);
+ return phone->priv->present;
+}
+
+/**
+ * gpm_phone_coldplug:
+ * Return value: if present
+ **/
+guint
+gpm_phone_get_percentage (GpmPhone *phone, guint idx)
+{
+ g_return_val_if_fail (phone != NULL, 0);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), 0);
+ return phone->priv->percentage;
+}
+
+/**
+ * gpm_phone_coldplug:
+ * Return value: if present
+ **/
+gboolean
+gpm_phone_get_on_ac (GpmPhone *phone, guint idx)
+{
+ g_return_val_if_fail (phone != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);
+ return phone->priv->onac;
+}
+
+/**
+ * gpm_phone_get_num_batteries:
+ * Return value: number of phone batteries monitored
+ **/
+guint
+gpm_phone_get_num_batteries (GpmPhone *phone)
+{
+ g_return_val_if_fail (phone != NULL, 0);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), 0);
+ if (phone->priv->present) {
+ return 1;
+ }
+ return 0;
+}
+
+/** Invoked when we get the BatteryStateChanged
+ */
+static void
+gpm_phone_battery_state_changed (DBusGProxy *proxy, guint idx, guint percentage, gboolean on_ac, GpmPhone *phone)
+{
+ g_return_if_fail (GPM_IS_PHONE (phone));
+
+ egg_debug ("got BatteryStateChanged %i = %i (%i)", idx, percentage, on_ac);
+ phone->priv->percentage = percentage;
+ phone->priv->onac = on_ac;
+ phone->priv->present = TRUE;
+ egg_debug ("emitting device-refresh : (%i)", idx);
+ g_signal_emit (phone, signals [DEVICE_REFRESH], 0, idx);
+}
+
+/** Invoked when we get NumberBatteriesChanged
+ */
+static void
+gpm_phone_num_batteries_changed (DBusGProxy *proxy, guint number, GpmPhone *phone)
+{
+ g_return_if_fail (GPM_IS_PHONE (phone));
+
+ egg_debug ("got NumberBatteriesChanged %i", number);
+ if (number > 1) {
+ egg_warning ("number not 0 or 1, not valid!");
+ return;
+ }
+
+ /* are we removed? */
+ if (number == 0) {
+ phone->priv->present = FALSE;
+ phone->priv->percentage = 0;
+ phone->priv->onac = FALSE;
+ egg_debug ("emitting device-removed : (%i)", 0);
+ g_signal_emit (phone, signals [DEVICE_REMOVED], 0, 0);
+ return;
+ }
+
+ if (phone->priv->present) {
+ egg_warning ("duplicate NumberBatteriesChanged with no change");
+ return;
+ }
+
+ /* reset to defaults until we get BatteryStateChanged */
+ phone->priv->present = TRUE;
+ phone->priv->percentage = 0;
+ phone->priv->onac = FALSE;
+ egg_debug ("emitting device-added : (%i)", 0);
+ g_signal_emit (phone, signals [DEVICE_ADDED], 0, 0);
+}
+
+/**
+ * gpm_phone_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_phone_class_init (GpmPhoneClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_phone_finalize;
+ g_type_class_add_private (klass, sizeof (GpmPhonePrivate));
+
+ signals [DEVICE_ADDED] =
+ g_signal_new ("device-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmPhoneClass, device_added),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ signals [DEVICE_REMOVED] =
+ g_signal_new ("device-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmPhoneClass, device_removed),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ signals [DEVICE_REFRESH] =
+ g_signal_new ("device-refresh",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmPhoneClass, device_refresh),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+}
+
+/**
+ * gpm_phone_dbus_connect:
+ **/
+static gboolean
+gpm_phone_dbus_connect (GpmPhone *phone)
+{
+ GError *error = NULL;
+
+ g_return_val_if_fail (phone != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);
+
+ if (phone->priv->connection == NULL) {
+ egg_debug ("get connection");
+ g_clear_error (&error);
+ phone->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (error != NULL) {
+ egg_warning ("Could not connect to DBUS daemon: %s", error->message);
+ g_error_free (error);
+ phone->priv->connection = NULL;
+ return FALSE;
+ }
+ }
+ if (phone->priv->proxy == NULL) {
+ egg_debug ("get proxy");
+ g_clear_error (&error);
+ phone->priv->proxy = dbus_g_proxy_new_for_name_owner (phone->priv->connection,
+ MATE_PHONE_MANAGER_DBUS_SERVICE,
+ MATE_PHONE_MANAGER_DBUS_PATH,
+ MATE_PHONE_MANAGER_DBUS_INTERFACE,
+ &error);
+ if (error != NULL) {
+ egg_warning ("Cannot connect, maybe the daemon is not running: %s", error->message);
+ g_error_free (error);
+ phone->priv->proxy = NULL;
+ return FALSE;
+ }
+
+ /* complicated type. ick */
+ dbus_g_object_register_marshaller(gpm_marshal_VOID__UINT_UINT_BOOLEAN,
+ G_TYPE_NONE, G_TYPE_UINT, G_TYPE_UINT,
+ G_TYPE_BOOLEAN, G_TYPE_INVALID);
+
+ /* get BatteryStateChanged */
+ dbus_g_proxy_add_signal (phone->priv->proxy, "BatteryStateChanged",
+ G_TYPE_UINT, G_TYPE_UINT, G_TYPE_BOOLEAN, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (phone->priv->proxy, "BatteryStateChanged",
+ G_CALLBACK (gpm_phone_battery_state_changed),
+ phone, NULL);
+
+ /* get NumberBatteriesChanged */
+ dbus_g_proxy_add_signal (phone->priv->proxy, "NumberBatteriesChanged",
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (phone->priv->proxy, "NumberBatteriesChanged",
+ G_CALLBACK (gpm_phone_num_batteries_changed),
+ phone, NULL);
+
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_phone_dbus_disconnect:
+ **/
+static gboolean
+gpm_phone_dbus_disconnect (GpmPhone *phone)
+{
+ g_return_val_if_fail (phone != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PHONE (phone), FALSE);
+
+ if (phone->priv->proxy != NULL) {
+ egg_debug ("removing proxy");
+ g_object_unref (phone->priv->proxy);
+ phone->priv->proxy = NULL;
+ if (phone->priv->present) {
+ phone->priv->present = FALSE;
+ phone->priv->percentage = 0;
+ egg_debug ("emitting device-removed : (%i)", 0);
+ g_signal_emit (phone, signals [DEVICE_REMOVED], 0, 0);
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * monitor_connection_cb:
+ * @proxy: The dbus raw proxy
+ * @status: The status of the service, where TRUE is connected
+ * @screensaver: This class instance
+ **/
+static void
+monitor_connection_cb (EggDbusMonitor *monitor,
+ gboolean status,
+ GpmPhone *phone)
+{
+ if (status)
+ gpm_phone_dbus_connect (phone);
+ else
+ gpm_phone_dbus_disconnect (phone);
+}
+
+/**
+ * gpm_phone_init:
+ * @phone: This class instance
+ **/
+static void
+gpm_phone_init (GpmPhone *phone)
+{
+ DBusGConnection *connection;
+ phone->priv = GPM_PHONE_GET_PRIVATE (phone);
+
+ phone->priv->connection = NULL;
+ phone->priv->proxy = NULL;
+ phone->priv->present = FALSE;
+ phone->priv->percentage = 0;
+ phone->priv->onac = FALSE;
+
+ phone->priv->monitor = egg_dbus_monitor_new ();
+ g_signal_connect (phone->priv->monitor, "connection-changed",
+ G_CALLBACK (monitor_connection_cb), phone);
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ egg_dbus_monitor_assign (phone->priv->monitor, connection, MATE_PHONE_MANAGER_DBUS_SERVICE);
+ gpm_phone_dbus_connect (phone);
+}
+
+/**
+ * gpm_phone_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_phone_finalize (GObject *object)
+{
+ GpmPhone *phone;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_PHONE (object));
+
+ phone = GPM_PHONE (object);
+ phone->priv = GPM_PHONE_GET_PRIVATE (phone);
+
+ gpm_phone_dbus_disconnect (phone);
+ if (phone->priv->monitor != NULL)
+ g_object_unref (phone->priv->monitor);
+
+ G_OBJECT_CLASS (gpm_phone_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_phone_new:
+ * Return value: new GpmPhone instance.
+ **/
+GpmPhone *
+gpm_phone_new (void)
+{
+ if (gpm_phone_object != NULL) {
+ g_object_ref (gpm_phone_object);
+ } else {
+ gpm_phone_object = g_object_new (GPM_TYPE_PHONE, NULL);
+ g_object_add_weak_pointer (gpm_phone_object, &gpm_phone_object);
+ }
+ return GPM_PHONE (gpm_phone_object);
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+static gboolean test_got_refresh = FALSE;
+
+static void
+egg_test_mainloop_wait (guint ms)
+{
+ GMainLoop *loop;
+ loop = g_main_loop_new (NULL, FALSE);
+ g_timeout_add (ms, (GSourceFunc) g_main_loop_quit, loop);
+ g_main_loop_run (loop);
+}
+
+static void
+phone_device_refresh_cb (GpmPhone *phone, guint idx, gpointer *data)
+{
+ g_debug ("idx refresh = %i", idx);
+ if (idx == 0 && GPOINTER_TO_UINT (data) == 44)
+ test_got_refresh = TRUE;
+}
+
+void
+gpm_phone_test (gpointer data)
+{
+ GpmPhone *phone;
+ guint value;
+ gboolean ret;
+ EggTest *test = (EggTest *) data;
+
+ if (egg_test_start (test, "GpmPhone") == FALSE)
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get a non null phone");
+ phone = gpm_phone_new ();
+ if (phone != NULL)
+ egg_test_success (test, "got GpmPhone");
+ else
+ egg_test_failed (test, "could not get GpmPhone");
+
+ /* connect signals */
+ g_signal_connect (phone, "device-refresh",
+ G_CALLBACK (phone_device_refresh_cb), GUINT_TO_POINTER(44));
+
+ /************************************************************/
+ egg_test_title (test, "make sure we got a connection");
+ if (phone->priv->proxy != NULL) {
+ egg_test_success (test, "got connection");
+ } else {
+ /* skip this part of the test */
+ egg_test_success (test, "could not get a connection!");
+ goto out;
+ }
+
+ /************************************************************/
+ egg_test_title (test, "coldplug the data");
+ ret = gpm_phone_coldplug (phone);
+ if (ret) {
+ egg_test_success (test, "coldplug okay");
+ } else {
+ egg_test_failed (test, "could not coldplug");
+ }
+
+ egg_test_mainloop_wait (500);
+
+ /************************************************************/
+ egg_test_title (test, "got refresh");
+ if (test_got_refresh) {
+ egg_test_success (test, NULL);
+ } else {
+ egg_test_failed (test, "did not get refresh");
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check the connected phones");
+ value = gpm_phone_get_num_batteries (phone);
+ if (value == 1) {
+ egg_test_success (test, "connected phone");
+ } else {
+ egg_test_failed (test, "not connected with %i (phone not connected?)", value);
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check the present value");
+ ret = gpm_phone_get_present (phone, 0);
+ if (ret) {
+ egg_test_success (test, "we are here!");
+ } else {
+ egg_test_failed (test, "not here...");
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check the percentage");
+ value = gpm_phone_get_percentage (phone, 0);
+ if (value != 0) {
+ egg_test_success (test, "percentage is %i", phone->priv->percentage);
+ } else {
+ egg_test_failed (test, "could not get value");
+ }
+
+ /************************************************************/
+ egg_test_title (test, "check the ac value");
+ ret = gpm_phone_get_on_ac (phone, 0);
+ if (!ret) {
+ egg_test_success (test, "not charging, correct");
+ } else {
+ egg_test_failed (test, "charging?");
+ }
+out:
+ g_object_unref (phone);
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/gpm-phone.h b/src/gpm-phone.h
new file mode 100644
index 0000000..1d7c3fd
--- /dev/null
+++ b/src/gpm-phone.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPMPHONE_H
+#define __GPMPHONE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_PHONE (gpm_phone_get_type ())
+#define GPM_PHONE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_PHONE, GpmPhone))
+#define GPM_PHONE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_PHONE, GpmPhoneClass))
+#define GPM_IS_PHONE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_PHONE))
+#define GPM_IS_PHONE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_PHONE))
+#define GPM_PHONE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_PHONE, GpmPhoneClass))
+
+#define MATE_PHONE_MANAGER_DBUS_SERVICE "org.mate.phone"
+#define MATE_PHONE_MANAGER_DBUS_PATH "/org/mate/phone/Manager"
+#define MATE_PHONE_MANAGER_DBUS_INTERFACE "org.mate.phone.Manager"
+
+typedef struct GpmPhonePrivate GpmPhonePrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmPhonePrivate *priv;
+} GpmPhone;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* device_added) (GpmPhone *phone,
+ guint idx);
+ void (* device_removed) (GpmPhone *phone,
+ guint idx);
+ void (* device_refresh) (GpmPhone *phone,
+ guint idx);
+} GpmPhoneClass;
+
+GType gpm_phone_get_type (void);
+GpmPhone *gpm_phone_new (void);
+
+gboolean gpm_phone_get_present (GpmPhone *phone,
+ guint idx);
+guint gpm_phone_get_percentage (GpmPhone *phone,
+ guint idx);
+gboolean gpm_phone_get_on_ac (GpmPhone *phone,
+ guint idx);
+guint gpm_phone_get_num_batteries (GpmPhone *phone);
+gboolean gpm_phone_coldplug (GpmPhone *phone);
+#ifdef EGG_TEST
+void gpm_phone_test (gpointer data);
+#endif
+
+G_END_DECLS
+
+#endif /* __GPMPHONE_H */
diff --git a/src/gpm-point-obj.c b/src/gpm-point-obj.c
new file mode 100644
index 0000000..b3bfa5c
--- /dev/null
+++ b/src/gpm-point-obj.c
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <glib.h>
+
+#include "egg-debug.h"
+#include "gpm-point-obj.h"
+
+/**
+ * gpm_point_obj_copy:
+ **/
+GpmPointObj *
+gpm_point_obj_copy (const GpmPointObj *cobj)
+{
+ GpmPointObj *obj;
+ obj = g_new0 (GpmPointObj, 1);
+ obj->x = cobj->x;
+ obj->y = cobj->y;
+ obj->color = cobj->color;
+ return obj;
+}
+
+/**
+ * gpm_point_obj_new:
+ **/
+GpmPointObj *
+gpm_point_obj_new (void)
+{
+ GpmPointObj *obj;
+ obj = g_new0 (GpmPointObj, 1);
+ obj->x = 0.0f;
+ obj->y = 0.0f;
+ obj->color = 0x0;
+ return obj;
+}
+
+/**
+ * gpm_point_obj_free:
+ **/
+void
+gpm_point_obj_free (GpmPointObj *obj)
+{
+ if (obj == NULL)
+ return;
+ g_free (obj);
+}
+
diff --git a/src/gpm-point-obj.h b/src/gpm-point-obj.h
new file mode 100644
index 0000000..a37e2a6
--- /dev/null
+++ b/src/gpm-point-obj.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __GPM_POINT_OBJ_H__
+#define __GPM_POINT_OBJ_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ gfloat x;
+ gfloat y;
+ guint32 color;
+} GpmPointObj;
+
+GpmPointObj *gpm_point_obj_new (void);
+GpmPointObj *gpm_point_obj_copy (const GpmPointObj *cobj);
+void gpm_point_obj_free (GpmPointObj *obj);
+
+G_END_DECLS
+
+#endif /* __GPM_POINT_OBJ_H__ */
+
diff --git a/src/gpm-prefs-core.c b/src/gpm-prefs-core.c
new file mode 100644
index 0000000..0e3a06f
--- /dev/null
+++ b/src/gpm-prefs-core.c
@@ -0,0 +1,1024 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 Jaap Haitsma <[email protected]>
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <gtk/gtk.h>
+#include <dbus/dbus-glib.h>
+#include <math.h>
+#include <string.h>
+#include <mateconf/mateconf-client.h>
+#include <libupower-glib/upower.h>
+
+#include "egg-debug.h"
+#include "egg-console-kit.h"
+
+#include "gpm-tray-icon.h"
+#include "gpm-common.h"
+#include "gpm-prefs-core.h"
+#include "gpm-stock-icons.h"
+#include "gpm-prefs-server.h"
+
+static void gpm_prefs_finalize (GObject *object);
+
+#define GPM_PREFS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_PREFS, GpmPrefsPrivate))
+
+struct GpmPrefsPrivate
+{
+ UpClient *client;
+ GtkBuilder *builder;
+ gboolean has_batteries;
+ gboolean has_lcd;
+ gboolean has_ups;
+ gboolean has_button_lid;
+ gboolean has_button_suspend;
+ gboolean can_shutdown;
+ gboolean can_suspend;
+ gboolean can_hibernate;
+ guint idle_delay;
+ MateConfClient *conf;
+ EggConsoleKit *console;
+};
+
+enum {
+ ACTION_HELP,
+ ACTION_CLOSE,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GpmPrefs, gpm_prefs, G_TYPE_OBJECT)
+
+/**
+ * gpm_prefs_class_init:
+ * @klass: This prefs class instance
+ **/
+static void
+gpm_prefs_class_init (GpmPrefsClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_prefs_finalize;
+ g_type_class_add_private (klass, sizeof (GpmPrefsPrivate));
+
+ signals [ACTION_HELP] =
+ g_signal_new ("action-help",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmPrefsClass, action_help),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals [ACTION_CLOSE] =
+ g_signal_new ("action-close",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmPrefsClass, action_close),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * gpm_prefs_activate_window:
+ * @prefs: This prefs class instance
+ *
+ * Activates (shows) the window.
+ **/
+void
+gpm_prefs_activate_window (GpmPrefs *prefs)
+{
+ GtkWindow *window;
+ window = GTK_WINDOW (gtk_builder_get_object (prefs->priv->builder, "dialog_preferences"));
+ gtk_window_present (window);
+}
+
+/**
+ * gpm_dbus_get_caps:
+ * @method: The g-p-m DBUS method name, e.g. "AllowedSuspend"
+ **/
+static gint
+gpm_dbus_get_caps (GpmPrefs *prefs)
+{
+ DBusGConnection *connection;
+ DBusGProxy *proxy = NULL;
+ GError *error = NULL;
+ gboolean ret;
+ gint value = 0;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (connection == NULL) {
+ egg_warning ("Couldn't connect to g-p-m %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (connection,
+ GPM_DBUS_SERVICE,
+ GPM_DBUS_PATH,
+ GPM_DBUS_INTERFACE);
+ ret = dbus_g_proxy_call (proxy, "GetPreferencesOptions", &error,
+ G_TYPE_INVALID,
+ G_TYPE_INT, &value,
+ G_TYPE_INVALID);
+ if (!ret) {
+ /* abort as the DBUS method failed */
+ egg_warning ("GetPreferencesOptions failed: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ if (proxy != NULL)
+ g_object_unref (proxy);
+ return value;
+}
+
+/**
+ * gpm_prefs_help_cb:
+ * @widget: The GtkWidget object
+ * @prefs: This prefs class instance
+ **/
+static void
+gpm_prefs_help_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ egg_debug ("emitting action-help");
+ g_signal_emit (prefs, signals [ACTION_HELP], 0);
+}
+
+/**
+ * gpm_prefs_icon_radio_cb:
+ * @widget: The GtkWidget object
+ **/
+static void
+gpm_prefs_icon_radio_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ const gchar *str;
+ gint policy;
+
+ policy = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "policy"));
+ str = gpm_icon_policy_to_string (policy);
+ egg_debug ("Changing %s to %s", GPM_CONF_UI_ICON_POLICY, str);
+ mateconf_client_set_string (prefs->priv->conf, GPM_CONF_UI_ICON_POLICY, str, NULL);
+}
+
+/**
+ * gpm_prefs_format_percentage_cb:
+ * @scale: The GtkScale object
+ * @value: The value in %.
+ **/
+static gchar *
+gpm_prefs_format_percentage_cb (GtkScale *scale, gdouble value)
+{
+ return g_strdup_printf ("%.0f%%", value);
+}
+
+/**
+ * gpm_prefs_brightness_slider_changed_cb:
+ * @range: The GtkRange object
+ * @gpm_pref_key: The MateConf key for this preference setting.
+ **/
+static void
+gpm_prefs_brightness_slider_changed_cb (GtkRange *range, GpmPrefs *prefs)
+{
+ gdouble value;
+ gchar *gpm_pref_key;
+
+ value = gtk_range_get_value (range);
+ gpm_pref_key = (char *) g_object_get_data (G_OBJECT (range), "conf_key");
+
+ g_object_set_data (G_OBJECT (range), "conf_key", (gpointer) gpm_pref_key);
+ egg_debug ("Changing %s to %i", gpm_pref_key, (int) value);
+ mateconf_client_set_int (prefs->priv->conf, gpm_pref_key, (gint) value, NULL);
+}
+
+/**
+ * gpm_prefs_setup_brightness_slider:
+ * @prefs: This prefs class instance
+ * @widget_name: The GtkWidget name
+ * @gpm_pref_key: The MateConf key for this preference setting.
+ **/
+static GtkWidget *
+gpm_prefs_setup_brightness_slider (GpmPrefs *prefs, const gchar *widget_name, const gchar *gpm_pref_key)
+{
+ GtkWidget *widget;
+ int value;
+ gboolean is_writable;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, widget_name));
+
+ g_signal_connect (G_OBJECT (widget), "format-value",
+ G_CALLBACK (gpm_prefs_format_percentage_cb), NULL);
+
+ value = mateconf_client_get_int (prefs->priv->conf, gpm_pref_key, NULL);
+ is_writable = mateconf_client_key_is_writable (prefs->priv->conf, gpm_pref_key, NULL);
+
+ gtk_widget_set_sensitive (widget, is_writable);
+
+ gtk_range_set_value (GTK_RANGE (widget), value);
+
+ g_object_set_data (G_OBJECT (widget), "conf_key", (gpointer) gpm_pref_key);
+
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (gpm_prefs_brightness_slider_changed_cb),
+ prefs);
+ return widget;
+}
+
+/**
+ * gpm_prefs_action_combo_changed_cb:
+ **/
+static void
+gpm_prefs_action_combo_changed_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ GpmActionPolicy policy;
+ const GpmActionPolicy *actions;
+ const gchar *gpm_pref_key;
+ const gchar *action;
+ guint active;
+
+ actions = (const GpmActionPolicy *) g_object_get_data (G_OBJECT (widget), "actions");
+ gpm_pref_key = (const gchar *) g_object_get_data (G_OBJECT (widget), "conf_key");
+
+ active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+ policy = actions[active];
+ action = gpm_action_policy_to_string (policy);
+ egg_debug ("Changing %s to %s", gpm_pref_key, action);
+ mateconf_client_set_string (prefs->priv->conf, gpm_pref_key, action, NULL);
+}
+
+/**
+ * gpm_prefs_action_time_changed_cb:
+ **/
+static void
+gpm_prefs_action_time_changed_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ guint value;
+ const gint *values;
+ const gchar *gpm_pref_key;
+ guint active;
+
+ values = (const gint *) g_object_get_data (G_OBJECT (widget), "values");
+ gpm_pref_key = (const gchar *) g_object_get_data (G_OBJECT (widget), "conf_key");
+
+ active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+ value = values[active];
+
+ egg_debug ("Changing %s to %i", gpm_pref_key, value);
+ mateconf_client_set_int (prefs->priv->conf, gpm_pref_key, value, NULL);
+}
+
+/**
+ * gpm_prefs_set_combo_simple_text:
+ **/
+static void
+gpm_prefs_set_combo_simple_text (GtkWidget *combo_box)
+{
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
+ "text", 0,
+ NULL);
+}
+
+/**
+ * gpm_prefs_actions_destroy_cb:
+ **/
+static void
+gpm_prefs_actions_destroy_cb (GpmActionPolicy *array)
+{
+ g_free (array);
+}
+
+/**
+ * gpm_prefs_setup_action_combo:
+ * @prefs: This prefs class instance
+ * @widget_name: The GtkWidget name
+ * @gpm_pref_key: The MateConf key for this preference setting.
+ * @actions: The actions to associate in an array.
+ **/
+static void
+gpm_prefs_setup_action_combo (GpmPrefs *prefs, const gchar *widget_name,
+ const gchar *gpm_pref_key, const GpmActionPolicy *actions)
+{
+ gchar *value_txt;
+ gint i;
+ gboolean is_writable;
+ GtkWidget *widget;
+ GpmActionPolicy policy;
+ GpmActionPolicy value;
+ GPtrArray *array;
+ GpmActionPolicy *actions_added;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, widget_name));
+ gpm_prefs_set_combo_simple_text (widget);
+
+ value_txt = mateconf_client_get_string (prefs->priv->conf, gpm_pref_key, NULL);
+ is_writable = mateconf_client_key_is_writable (prefs->priv->conf, gpm_pref_key, NULL);
+ value = gpm_action_policy_from_string (value_txt);
+
+ gtk_widget_set_sensitive (widget, is_writable);
+
+ array = g_ptr_array_new ();
+ g_object_set_data (G_OBJECT (widget), "conf_key", (gpointer) gpm_pref_key);
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (gpm_prefs_action_combo_changed_cb), prefs);
+
+ for (i=0; actions[i] != -1; i++) {
+ policy = actions[i];
+ if (policy == GPM_ACTION_POLICY_SHUTDOWN && !prefs->priv->can_shutdown) {
+ egg_debug ("Cannot add option, as cannot shutdown.");
+ } else if (policy == GPM_ACTION_POLICY_SHUTDOWN && prefs->priv->can_shutdown) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Shutdown"));
+ g_ptr_array_add (array, GINT_TO_POINTER (policy));
+ } else if (policy == GPM_ACTION_POLICY_SUSPEND && !prefs->priv->can_suspend) {
+ egg_debug ("Cannot add option, as cannot suspend.");
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE && !prefs->priv->can_hibernate) {
+ egg_debug ("Cannot add option, as cannot hibernate.");
+ } else if (policy == GPM_ACTION_POLICY_SUSPEND && prefs->priv->can_suspend) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Suspend"));
+ g_ptr_array_add (array, GINT_TO_POINTER (policy));
+ } else if (policy == GPM_ACTION_POLICY_HIBERNATE && prefs->priv->can_hibernate) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Hibernate"));
+ g_ptr_array_add (array, GINT_TO_POINTER (policy));
+ } else if (policy == GPM_ACTION_POLICY_BLANK) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Blank screen"));
+ g_ptr_array_add (array, GINT_TO_POINTER (policy));
+ } else if (policy == GPM_ACTION_POLICY_INTERACTIVE) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Ask me"));
+ g_ptr_array_add (array, GINT_TO_POINTER (policy));
+ } else if (policy == GPM_ACTION_POLICY_NOTHING) {
+ /* we only add do nothing in the GUI if the user has explicitly specified this in MateConf */
+ if (value == GPM_ACTION_POLICY_NOTHING) {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Do nothing"));
+ g_ptr_array_add (array, GINT_TO_POINTER (policy));
+ }
+ } else {
+ egg_warning ("Unknown action read from conf: %i", policy);
+ }
+ }
+
+ /* save as array _only_ the actions we could add */
+ actions_added = g_new0 (GpmActionPolicy, array->len+1);
+ for (i=0; i<array->len; i++)
+ actions_added[i] = GPOINTER_TO_INT (g_ptr_array_index (array, i));
+ actions_added[i] = -1;
+
+ g_object_set_data_full (G_OBJECT (widget), "actions", (gpointer) actions_added, (GDestroyNotify) gpm_prefs_actions_destroy_cb);
+
+ /* set what we have in MateConf */
+ for (i=0; actions_added[i] != -1; i++) {
+ policy = actions_added[i];
+ egg_debug ("added: %s", gpm_action_policy_to_string (policy));
+ if (value == policy)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), i);
+ }
+
+ g_ptr_array_unref (array);
+ g_free (value_txt);
+}
+
+/**
+ * gpm_prefs_setup_time_combo:
+ * @prefs: This prefs class instance
+ * @widget_name: The GtkWidget name
+ * @gpm_pref_key: The MateConf key for this preference setting.
+ * @actions: The actions to associate in an array.
+ **/
+static void
+gpm_prefs_setup_time_combo (GpmPrefs *prefs, const gchar *widget_name,
+ const gchar *gpm_pref_key, const gint *values)
+{
+ guint value;
+ gchar *text;
+ guint i;
+ gboolean is_writable;
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, widget_name));
+ gpm_prefs_set_combo_simple_text (widget);
+
+ value = mateconf_client_get_int (prefs->priv->conf, gpm_pref_key, NULL);
+ is_writable = mateconf_client_key_is_writable (prefs->priv->conf, gpm_pref_key, NULL);
+ gtk_widget_set_sensitive (widget, is_writable);
+
+ g_object_set_data (G_OBJECT (widget), "conf_key", (gpointer) gpm_pref_key);
+ g_object_set_data (G_OBJECT (widget), "values", (gpointer) values);
+
+ /* add each time */
+ for (i=0; values[i] != -1; i++) {
+
+ /* get translation for number of seconds */
+ if (values[i] != 0) {
+ text = gpm_get_timestring (values[i]);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), text);
+ g_free (text);
+ } else {
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Never"));
+ }
+
+ /* matches, so set default */
+ if (value == values[i])
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), i);
+ }
+
+ /* connect after set */
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (gpm_prefs_action_time_changed_cb), prefs);
+}
+
+/**
+ * gpm_prefs_checkbox_lock_cb:
+ * @widget: The GtkWidget object
+ * @gpm_pref_key: The MateConf key for this preference setting.
+ **/
+static void
+gpm_prefs_checkbox_lock_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ gboolean checked;
+ gchar *gpm_pref_key;
+
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ gpm_pref_key = (char *) g_object_get_data (G_OBJECT (widget), "conf_key");
+ egg_debug ("Changing %s to %i", gpm_pref_key, checked);
+ mateconf_client_set_bool (prefs->priv->conf, gpm_pref_key, checked, NULL);
+}
+
+/**
+ * gpm_prefs_setup_checkbox:
+ * @prefs: This prefs class instance
+ * @widget_name: The GtkWidget name
+ * @gpm_pref_key: The MateConf key for this preference setting.
+ **/
+static GtkWidget *
+gpm_prefs_setup_checkbox (GpmPrefs *prefs, const gchar *widget_name, const gchar *gpm_pref_key)
+{
+ gboolean checked;
+ GtkWidget *widget;
+
+ egg_debug ("Setting up %s", gpm_pref_key);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, widget_name));
+
+ checked = mateconf_client_get_bool (prefs->priv->conf, gpm_pref_key, NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
+
+ g_object_set_data (G_OBJECT (widget), "conf_key", (gpointer) gpm_pref_key);
+
+ /* manually do the callback in case we hide elements in the cb */
+ gpm_prefs_checkbox_lock_cb (widget, prefs);
+
+ /* setup after set */
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_prefs_checkbox_lock_cb), prefs);
+
+ return widget;
+}
+
+/**
+ * gpm_prefs_close_cb:
+ * @widget: The GtkWidget object
+ * @prefs: This prefs class instance
+ **/
+static void
+gpm_prefs_close_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ egg_debug ("emitting action-close");
+ g_signal_emit (prefs, signals [ACTION_CLOSE], 0);
+}
+
+/**
+ * gpm_prefs_delete_event_cb:
+ * @widget: The GtkWidget object
+ * @event: The event type, unused.
+ * @prefs: This prefs class instance
+ **/
+static gboolean
+gpm_prefs_delete_event_cb (GtkWidget *widget, GdkEvent *event, GpmPrefs *prefs)
+{
+ gpm_prefs_close_cb (widget, prefs);
+ return FALSE;
+}
+
+/**
+ * gpm_conf_mateconf_key_changed_cb:
+ *
+ * We might have to do things when the mateconf keys change; do them here.
+ **/
+static void
+gpm_conf_mateconf_key_changed_cb (MateConfClient *client, guint cnxn_id, MateConfEntry *entry, GpmPrefs *prefs)
+{
+ MateConfValue *value;
+ gint brightness;
+ GtkWidget *widget;
+ gboolean enabled;
+
+ value = mateconf_entry_get_value (entry);
+ if (value == NULL)
+ return;
+
+ if (g_strcmp0 (entry->key, GPM_CONF_BACKLIGHT_BRIGHTNESS_AC) == 0) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "hscale_ac_brightness"));
+ brightness = mateconf_value_get_int (value);
+ gtk_range_set_value (GTK_RANGE (widget), brightness);
+ }
+
+ if (g_strcmp0 (entry->key, GPM_CONF_DISKS_SPINDOWN_ENABLE_AC) == 0) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "checkbutton_ac_spindown"));
+ enabled = mateconf_value_get_bool (value);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), enabled);
+
+ } else if (g_strcmp0 (entry->key, GPM_CONF_DISKS_SPINDOWN_ENABLE_BATT) == 0) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "checkbutton_battery_spindown"));
+ enabled = mateconf_value_get_bool (value);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), enabled);
+ }
+}
+
+/** setup the notification page */
+static void
+prefs_setup_notification (GpmPrefs *prefs)
+{
+ gchar *icon_policy_str;
+ gint icon_policy;
+ GtkWidget *radiobutton_icon_always;
+ GtkWidget *radiobutton_icon_present;
+ GtkWidget *radiobutton_icon_charge;
+ GtkWidget *radiobutton_icon_low;
+ GtkWidget *radiobutton_icon_never;
+ gboolean is_writable;
+
+ icon_policy_str = mateconf_client_get_string (prefs->priv->conf, GPM_CONF_UI_ICON_POLICY, NULL);
+ icon_policy = gpm_icon_policy_from_string (icon_policy_str);
+ g_free (icon_policy_str);
+
+ radiobutton_icon_always = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
+ "radiobutton_notification_always"));
+ radiobutton_icon_present = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
+ "radiobutton_notification_present"));
+ radiobutton_icon_charge = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
+ "radiobutton_notification_charge"));
+ radiobutton_icon_low = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
+ "radiobutton_notification_low"));
+ radiobutton_icon_never = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder,
+ "radiobutton_notification_never"));
+
+ is_writable = mateconf_client_key_is_writable (prefs->priv->conf, GPM_CONF_UI_ICON_POLICY, NULL);
+ gtk_widget_set_sensitive (radiobutton_icon_always, is_writable);
+ gtk_widget_set_sensitive (radiobutton_icon_present, is_writable);
+ gtk_widget_set_sensitive (radiobutton_icon_charge, is_writable);
+ gtk_widget_set_sensitive (radiobutton_icon_low, is_writable);
+ gtk_widget_set_sensitive (radiobutton_icon_never, is_writable);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_icon_always),
+ icon_policy == GPM_ICON_POLICY_ALWAYS);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_icon_present),
+ icon_policy == GPM_ICON_POLICY_PRESENT);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_icon_charge),
+ icon_policy == GPM_ICON_POLICY_CHARGE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_icon_low),
+ icon_policy == GPM_ICON_POLICY_LOW);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radiobutton_icon_never),
+ icon_policy == GPM_ICON_POLICY_NEVER);
+
+ g_object_set_data (G_OBJECT (radiobutton_icon_always), "policy",
+ GINT_TO_POINTER (GPM_ICON_POLICY_ALWAYS));
+ g_object_set_data (G_OBJECT (radiobutton_icon_present), "policy",
+ GINT_TO_POINTER (GPM_ICON_POLICY_PRESENT));
+ g_object_set_data (G_OBJECT (radiobutton_icon_charge), "policy",
+ GINT_TO_POINTER (GPM_ICON_POLICY_CHARGE));
+ g_object_set_data (G_OBJECT (radiobutton_icon_low), "policy",
+ GINT_TO_POINTER (GPM_ICON_POLICY_LOW));
+ g_object_set_data (G_OBJECT (radiobutton_icon_never), "policy",
+ GINT_TO_POINTER (GPM_ICON_POLICY_NEVER));
+
+ /* only connect the callbacks after we set the value, else the conf
+ * keys gets written to (for a split second), and the icon flickers. */
+ g_signal_connect (radiobutton_icon_always, "clicked",
+ G_CALLBACK (gpm_prefs_icon_radio_cb), prefs);
+ g_signal_connect (radiobutton_icon_present, "clicked",
+ G_CALLBACK (gpm_prefs_icon_radio_cb), prefs);
+ g_signal_connect (radiobutton_icon_charge, "clicked",
+ G_CALLBACK (gpm_prefs_icon_radio_cb), prefs);
+ g_signal_connect (radiobutton_icon_low, "clicked",
+ G_CALLBACK (gpm_prefs_icon_radio_cb), prefs);
+ g_signal_connect (radiobutton_icon_never, "clicked",
+ G_CALLBACK (gpm_prefs_icon_radio_cb), prefs);
+}
+
+static void
+prefs_setup_ac (GpmPrefs *prefs)
+{
+ GtkWidget *widget;
+ const GpmActionPolicy button_lid_actions[] =
+ {GPM_ACTION_POLICY_NOTHING,
+ GPM_ACTION_POLICY_BLANK,
+ GPM_ACTION_POLICY_SUSPEND,
+ GPM_ACTION_POLICY_HIBERNATE,
+ GPM_ACTION_POLICY_SHUTDOWN,
+ -1};
+
+ static const gint computer_times[] =
+ {10*60,
+ 30*60,
+ 1*60*60,
+ 2*60*60,
+ 0, /* never */
+ -1};
+ static const gint display_times[] =
+ {1*60,
+ 5*60,
+ 10*60,
+ 30*60,
+ 1*60*60,
+ 0, /* never */
+ -1};
+
+ gpm_prefs_setup_time_combo (prefs, "combobox_ac_computer",
+ GPM_CONF_TIMEOUT_SLEEP_COMPUTER_AC,
+ computer_times);
+ gpm_prefs_setup_time_combo (prefs, "combobox_ac_display",
+ GPM_CONF_TIMEOUT_SLEEP_DISPLAY_AC,
+ display_times);
+
+ gpm_prefs_setup_action_combo (prefs, "combobox_ac_lid",
+ GPM_CONF_BUTTON_LID_AC,
+ button_lid_actions);
+
+ gpm_prefs_setup_brightness_slider (prefs, "hscale_ac_brightness",
+ GPM_CONF_BACKLIGHT_BRIGHTNESS_AC);
+
+ gpm_prefs_setup_checkbox (prefs, "checkbutton_ac_display_dim",
+ GPM_CONF_BACKLIGHT_IDLE_DIM_AC);
+ gpm_prefs_setup_checkbox (prefs, "checkbutton_ac_spindown",
+ GPM_CONF_DISKS_SPINDOWN_ENABLE_AC);
+
+ if (prefs->priv->has_button_lid == FALSE) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "hbox_ac_lid"));
+ gtk_widget_hide_all (widget);
+ }
+ if (prefs->priv->has_lcd == FALSE) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "hbox_ac_brightness"));
+ gtk_widget_hide_all (widget);
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "checkbutton_ac_display_dim"));
+ gtk_widget_hide_all (widget);
+ }
+}
+
+static void
+prefs_setup_battery (GpmPrefs *prefs)
+{
+ GtkWidget *widget;
+ GtkNotebook *notebook;
+ gint page;
+
+ const GpmActionPolicy button_lid_actions[] =
+ {GPM_ACTION_POLICY_NOTHING,
+ GPM_ACTION_POLICY_BLANK,
+ GPM_ACTION_POLICY_SUSPEND,
+ GPM_ACTION_POLICY_HIBERNATE,
+ GPM_ACTION_POLICY_SHUTDOWN,
+ -1};
+ const GpmActionPolicy battery_critical_actions[] =
+ {GPM_ACTION_POLICY_NOTHING,
+ GPM_ACTION_POLICY_SUSPEND,
+ GPM_ACTION_POLICY_HIBERNATE,
+ GPM_ACTION_POLICY_SHUTDOWN,
+ -1};
+
+ static const gint computer_times[] =
+ {10*60,
+ 30*60,
+ 1*60*60,
+ 2*60*60,
+ 0, /* never */
+ -1};
+ static const gint display_times[] =
+ {1*60,
+ 5*60,
+ 10*60,
+ 30*60,
+ 1*60*60,
+ 0, /* never */
+ -1};
+
+ gpm_prefs_setup_time_combo (prefs, "combobox_battery_computer",
+ GPM_CONF_TIMEOUT_SLEEP_COMPUTER_BATT,
+ computer_times);
+ gpm_prefs_setup_time_combo (prefs, "combobox_battery_display",
+ GPM_CONF_TIMEOUT_SLEEP_DISPLAY_BATT,
+ display_times);
+
+ if (prefs->priv->has_batteries == FALSE) {
+ notebook = GTK_NOTEBOOK (gtk_builder_get_object (prefs->priv->builder, "notebook_preferences"));
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "vbox_battery"));
+ page = gtk_notebook_page_num (notebook, GTK_WIDGET (widget));
+ gtk_notebook_remove_page (notebook, page);
+ return;
+ }
+
+ gpm_prefs_setup_action_combo (prefs, "combobox_battery_lid",
+ GPM_CONF_BUTTON_LID_BATT,
+ button_lid_actions);
+ gpm_prefs_setup_action_combo (prefs, "combobox_battery_critical",
+ GPM_CONF_ACTIONS_CRITICAL_BATT,
+ battery_critical_actions);
+
+ /* set up the battery reduce checkbox */
+ gpm_prefs_setup_checkbox (prefs, "checkbutton_battery_display_reduce",
+ GPM_CONF_BACKLIGHT_BATTERY_REDUCE);
+ gpm_prefs_setup_checkbox (prefs, "checkbutton_battery_display_dim",
+ GPM_CONF_BACKLIGHT_IDLE_DIM_BATT);
+ gpm_prefs_setup_checkbox (prefs, "checkbutton_battery_spindown",
+ GPM_CONF_DISKS_SPINDOWN_ENABLE_BATT);
+
+ if (prefs->priv->has_button_lid == FALSE) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "hbox_battery_lid"));
+ gtk_widget_hide_all (widget);
+ }
+ if (prefs->priv->has_lcd == FALSE) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "checkbutton_battery_display_dim"));
+ gtk_widget_hide_all (widget);
+ }
+}
+
+static void
+prefs_setup_ups (GpmPrefs *prefs)
+{
+ GtkWidget *widget;
+ GtkNotebook *notebook;
+ gint page;
+
+ const GpmActionPolicy ups_low_actions[] =
+ {GPM_ACTION_POLICY_NOTHING,
+ GPM_ACTION_POLICY_HIBERNATE,
+ GPM_ACTION_POLICY_SHUTDOWN,
+ -1};
+
+ static const gint computer_times[] =
+ {10*60,
+ 30*60,
+ 1*60*60,
+ 2*60*60,
+ 0, /* never */
+ -1};
+ static const gint display_times[] =
+ {1*60,
+ 5*60,
+ 10*60,
+ 30*60,
+ 1*60*60,
+ 0, /* never */
+ -1};
+
+ gpm_prefs_setup_time_combo (prefs, "combobox_ups_computer",
+ GPM_CONF_TIMEOUT_SLEEP_COMPUTER_UPS,
+ computer_times);
+ gpm_prefs_setup_time_combo (prefs, "combobox_ups_display",
+ GPM_CONF_TIMEOUT_SLEEP_DISPLAY_UPS,
+ display_times);
+
+ if (prefs->priv->has_ups == FALSE) {
+ notebook = GTK_NOTEBOOK (gtk_builder_get_object (prefs->priv->builder, "notebook_preferences"));
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "vbox_ups"));
+ page = gtk_notebook_page_num (notebook, GTK_WIDGET (widget));
+ gtk_notebook_remove_page (notebook, page);
+ return;
+ }
+
+ gpm_prefs_setup_action_combo (prefs, "combobox_ups_low",
+ GPM_CONF_ACTIONS_LOW_UPS,
+ ups_low_actions);
+ gpm_prefs_setup_action_combo (prefs, "combobox_ups_critical",
+ GPM_CONF_ACTIONS_CRITICAL_UPS,
+ ups_low_actions);
+}
+
+static void
+prefs_setup_general (GpmPrefs *prefs)
+{
+ GtkWidget *widget;
+ const GpmActionPolicy power_button_actions[] =
+ {GPM_ACTION_POLICY_INTERACTIVE,
+ GPM_ACTION_POLICY_SUSPEND,
+ GPM_ACTION_POLICY_HIBERNATE,
+ GPM_ACTION_POLICY_SHUTDOWN,
+ -1};
+ const GpmActionPolicy suspend_button_actions[] =
+ {GPM_ACTION_POLICY_NOTHING,
+ GPM_ACTION_POLICY_SUSPEND,
+ GPM_ACTION_POLICY_HIBERNATE,
+ -1};
+
+ gpm_prefs_setup_action_combo (prefs, "combobox_general_power",
+ GPM_CONF_BUTTON_POWER,
+ power_button_actions);
+ gpm_prefs_setup_action_combo (prefs, "combobox_general_suspend",
+ GPM_CONF_BUTTON_SUSPEND,
+ suspend_button_actions);
+
+ if (prefs->priv->has_button_suspend == FALSE) {
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "hbox_general_suspend"));
+ gtk_widget_hide_all (widget);
+ }
+}
+
+/**
+ * gpm_prefs_set_defaults_cb:
+ **/
+static void
+gpm_prefs_set_defaults_cb (GtkWidget *widget, GpmPrefs *prefs)
+{
+ MateConfClient *client;
+ DBusGProxy *proxy;
+ DBusGConnection *connection;
+ GError *error = NULL;
+ const gchar *keys[5] = {
+ "/apps/mate-power-manager/actions",
+ "/apps/mate-power-manager/ui",
+ "/apps/mate-power-manager/buttons",
+ "/apps/mate-power-manager/backlight",
+ "/apps/mate-power-manager/timeout"
+ };
+
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (error != NULL) {
+ g_warning ("failed to get system bus connection: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (connection,
+ "org.mate.MateConf.Defaults",
+ "/",
+ "org.mate.MateConf.Defaults");
+ if (proxy == NULL) {
+ g_warning ("Cannot connect to defaults mechanism");
+ return;
+ }
+
+ client = mateconf_client_get_default ();
+ mateconf_client_suggest_sync (client, NULL);
+ g_object_unref (client);
+ dbus_g_proxy_call (proxy, "SetSystem", &error,
+ G_TYPE_STRV, keys,
+ G_TYPE_STRV, NULL,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+
+ g_object_unref (proxy);
+}
+
+/**
+ * gpm_prefs_init:
+ * @prefs: This prefs class instance
+ **/
+static void
+gpm_prefs_init (GpmPrefs *prefs)
+{
+ GtkWidget *main_window;
+ GtkWidget *widget;
+ gint caps;
+ guint retval;
+ GError *error = NULL;
+
+ prefs->priv = GPM_PREFS_GET_PRIVATE (prefs);
+
+ prefs->priv->client = up_client_new ();
+ prefs->priv->console = egg_console_kit_new ();
+ prefs->priv->conf = mateconf_client_get_default ();
+ /* watch mate-power-manager keys */
+ mateconf_client_add_dir (prefs->priv->conf, GPM_CONF_DIR,
+ MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+ mateconf_client_notify_add (prefs->priv->conf, GPM_CONF_DIR,
+ (MateConfClientNotifyFunc) gpm_conf_mateconf_key_changed_cb,
+ prefs, NULL, NULL);
+
+ /* get value of delay in mate-session */
+ prefs->priv->idle_delay = mateconf_client_get_int (prefs->priv->conf, GPM_CONF_IDLE_DELAY, NULL);
+
+ caps = gpm_dbus_get_caps (prefs);
+ egg_debug ("caps=%i", caps);
+
+ /* get properties from mate-power-manager */
+ prefs->priv->has_batteries = ((caps & GPM_PREFS_SERVER_BATTERY) > 0);
+ prefs->priv->has_ups = ((caps & GPM_PREFS_SERVER_UPS) > 0);
+ prefs->priv->has_lcd = ((caps & GPM_PREFS_SERVER_BACKLIGHT) > 0);
+ prefs->priv->has_button_lid = ((caps & GPM_PREFS_SERVER_LID) > 0);
+ prefs->priv->has_button_suspend = TRUE;
+
+ /* are we allowed to shutdown? */
+ prefs->priv->can_shutdown = TRUE;
+ egg_console_kit_can_stop (prefs->priv->console, &prefs->priv->can_shutdown, NULL);
+
+ /* get values from UpClient */
+ g_object_get (prefs->priv->client,
+ "can-suspend", &prefs->priv->can_suspend,
+ "can-hibernate", &prefs->priv->can_hibernate,
+ NULL);
+
+ prefs->priv->builder = gtk_builder_new ();
+ retval = gtk_builder_add_from_file (prefs->priv->builder, GPM_DATA "/gpm-prefs.ui", &error);
+ if (retval == 0) {
+ egg_warning ("failed to load ui: %s", error->message);
+ g_error_free (error);
+ }
+
+ main_window = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "dialog_preferences"));
+
+ /* Hide window first so that the dialogue resizes itself without redrawing */
+ gtk_widget_hide (main_window);
+ gtk_window_set_default_icon_name (GPM_STOCK_APP_ICON);
+
+ /* Get the main window quit */
+ g_signal_connect (main_window, "delete_event",
+ G_CALLBACK (gpm_prefs_delete_event_cb), prefs);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "button_close"));
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_prefs_close_cb), prefs);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "button_help"));
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_prefs_help_cb), prefs);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (prefs->priv->builder, "button_defaults"));
+#ifdef HAVE_MATECONF_DEFAULTS
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_prefs_set_defaults_cb), prefs);
+#else
+ gtk_widget_hide (widget);
+#endif
+
+ prefs_setup_ac (prefs);
+ prefs_setup_battery (prefs);
+ prefs_setup_ups (prefs);
+ prefs_setup_general (prefs);
+ prefs_setup_notification (prefs);
+
+ gtk_widget_show (main_window);
+}
+
+/**
+ * gpm_prefs_finalize:
+ * @object: This prefs class instance
+ **/
+static void
+gpm_prefs_finalize (GObject *object)
+{
+ GpmPrefs *prefs;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_PREFS (object));
+
+ prefs = GPM_PREFS (object);
+ prefs->priv = GPM_PREFS_GET_PRIVATE (prefs);
+
+ g_object_unref (prefs->priv->conf);
+ g_object_unref (prefs->priv->client);
+ g_object_unref (prefs->priv->console);
+
+ G_OBJECT_CLASS (gpm_prefs_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_prefs_new:
+ * Return value: new GpmPrefs instance.
+ **/
+GpmPrefs *
+gpm_prefs_new (void)
+{
+ GpmPrefs *prefs;
+ prefs = g_object_new (GPM_TYPE_PREFS, NULL);
+ return GPM_PREFS (prefs);
+}
diff --git a/src/gpm-prefs-core.h b/src/gpm-prefs-core.h
new file mode 100644
index 0000000..39c536c
--- /dev/null
+++ b/src/gpm-prefs-core.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPMPREFS_H
+#define __GPMPREFS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_PREFS (gpm_prefs_get_type ())
+#define GPM_PREFS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_PREFS, GpmPrefs))
+#define GPM_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_PREFS, GpmPrefsClass))
+#define GPM_IS_PREFS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_PREFS))
+#define GPM_IS_PREFS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_PREFS))
+#define GPM_PREFS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_PREFS, GpmPrefsClass))
+
+typedef struct GpmPrefsPrivate GpmPrefsPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmPrefsPrivate *priv;
+} GpmPrefs;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* action_help) (GpmPrefs *prefs);
+ void (* action_close) (GpmPrefs *prefs);
+} GpmPrefsClass;
+
+GType gpm_prefs_get_type (void);
+GpmPrefs *gpm_prefs_new (void);
+void gpm_prefs_activate_window (GpmPrefs *prefs);
+
+G_END_DECLS
+
+#endif /* __GPMPREFS_H */
diff --git a/src/gpm-prefs-server.c b/src/gpm-prefs-server.c
new file mode 100644
index 0000000..2ced9ff
--- /dev/null
+++ b/src/gpm-prefs-server.c
@@ -0,0 +1,138 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include "gpm-prefs-server.h"
+#include "egg-debug.h"
+
+#define GPM_PREFS_SERVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_PREFS_SERVER, GpmPrefsServerPrivate))
+
+struct GpmPrefsServerPrivate
+{
+ guint capability;
+};
+
+enum {
+ CAPABILITY_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_prefs_server_object = NULL;
+
+G_DEFINE_TYPE (GpmPrefsServer, gpm_prefs_server, G_TYPE_OBJECT)
+
+/**
+ * gpm_prefs_server_get_capability:
+ **/
+gboolean
+gpm_prefs_server_get_capability (GpmPrefsServer *server,
+ gint *capability)
+{
+ g_return_val_if_fail (server != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PREFS_SERVER (server), FALSE);
+ *capability = server->priv->capability;
+ return TRUE;
+}
+
+/**
+ * gpm_prefs_server_set_capability:
+ **/
+gboolean
+gpm_prefs_server_set_capability (GpmPrefsServer *server,
+ gint capability)
+{
+ g_return_val_if_fail (server != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_PREFS_SERVER (server), FALSE);
+ server->priv->capability = server->priv->capability + capability;
+ egg_debug ("capability now %i", server->priv->capability);
+ return TRUE;
+}
+
+/**
+ * gpm_prefs_server_class_init:
+ * @klass: This prefs class instance
+ **/
+static void
+gpm_prefs_server_class_init (GpmPrefsServerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ g_type_class_add_private (klass, sizeof (GpmPrefsServerPrivate));
+ signals [CAPABILITY_CHANGED] =
+ g_signal_new ("capability-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmPrefsServerClass, capability_changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * gpm_prefs_server_init:
+ * @server: This server class instance
+ *
+ * initialises the server class. NOTE: We expect prefs_server objects
+ * to *NOT* be removed or added during the session.
+ * We only control the first prefs_server object if there are more than one.
+ **/
+static void
+gpm_prefs_server_init (GpmPrefsServer *server)
+{
+ server->priv = GPM_PREFS_SERVER_GET_PRIVATE (server);
+ server->priv->capability = 0;
+}
+
+/**
+ * gpm_prefs_server_new:
+ * Return value: A new server class instance.
+ * Can return NULL if no suitable hardware is found.
+ **/
+GpmPrefsServer *
+gpm_prefs_server_new (void)
+{
+ if (gpm_prefs_server_object != NULL) {
+ g_object_ref (gpm_prefs_server_object);
+ } else {
+ gpm_prefs_server_object = g_object_new (GPM_TYPE_PREFS_SERVER, NULL);
+ g_object_add_weak_pointer (gpm_prefs_server_object, &gpm_prefs_server_object);
+ }
+ return GPM_PREFS_SERVER (gpm_prefs_server_object);
+}
diff --git a/src/gpm-prefs-server.h b/src/gpm-prefs-server.h
new file mode 100644
index 0000000..62cadb6
--- /dev/null
+++ b/src/gpm-prefs-server.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_PREFS_SERVER_H
+#define __GPM_PREFS_SERVER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_PREFS_SERVER (gpm_prefs_server_get_type ())
+#define GPM_PREFS_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_PREFS_SERVER, GpmPrefsServer))
+#define GPM_PREFS_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_PREFS_SERVER, GpmPrefsServerClass))
+#define GPM_IS_PREFS_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_PREFS_SERVER))
+#define GPM_IS_PREFS_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_PREFS_SERVER))
+#define GPM_PREFS_SERVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_PREFS_SERVER, GpmPrefsServerClass))
+
+#define GPM_PREFS_SERVER_BACKLIGHT 1
+#define GPM_PREFS_SERVER_LID 4
+#define GPM_PREFS_SERVER_BATTERY 8
+#define GPM_PREFS_SERVER_UPS 16
+#define GPM_PREFS_SERVER_KEYLIGHT 32
+
+typedef struct GpmPrefsServerPrivate GpmPrefsServerPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmPrefsServerPrivate *priv;
+} GpmPrefsServer;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* capability_changed) (GpmPrefsServer *server,
+ gint capability);
+} GpmPrefsServerClass;
+
+GType gpm_prefs_server_get_type (void);
+GpmPrefsServer *gpm_prefs_server_new (void);
+
+gboolean gpm_prefs_server_get_capability (GpmPrefsServer *server,
+ gint *capability);
+gboolean gpm_prefs_server_set_capability (GpmPrefsServer *server,
+ gint capability);
+
+G_END_DECLS
+
+#endif /* __GPM_PREFS_SERVER_H */
diff --git a/src/gpm-prefs.c b/src/gpm-prefs.c
new file mode 100644
index 0000000..b209641
--- /dev/null
+++ b/src/gpm-prefs.c
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 Jaap Haitsma <[email protected]>
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+/* local .la */
+#include <egg-unique.h>
+
+#include "gpm-common.h"
+#include "egg-debug.h"
+#include "gpm-prefs-core.h"
+
+/**
+ * gpm_prefs_help_cb
+ * @prefs: This prefs class instance
+ *
+ * What to do when help is requested
+ **/
+static void
+gpm_prefs_help_cb (GpmPrefs *prefs)
+{
+ gpm_help_display ("preferences");
+}
+
+/**
+ * gpm_prefs_close_cb
+ * @prefs: This prefs class instance
+ *
+ * What to do when we are asked to close for whatever reason
+ **/
+static void
+gpm_prefs_close_cb (GpmPrefs *prefs)
+{
+ gtk_main_quit ();
+}
+
+/**
+ * gpm_prefs_activated_cb
+ * @prefs: This prefs class instance
+ *
+ * We have been asked to show the window
+ **/
+static void
+gpm_prefs_activated_cb (EggUnique *egg_unique, GpmPrefs *prefs)
+{
+ gpm_prefs_activate_window (prefs);
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char **argv)
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ GpmPrefs *prefs = NULL;
+ gboolean ret;
+ EggUnique *egg_unique;
+
+ const GOptionEntry options[] = {
+ { "verbose", '\0', 0, G_OPTION_ARG_NONE, &verbose,
+ N_("Show extra debugging information"), NULL },
+ { NULL}
+ };
+
+ context = g_option_context_new (N_("MATE Power Preferences"));
+
+ bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ g_option_context_set_translation_domain(context, GETTEXT_PACKAGE);
+ g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+ g_option_context_add_group (context, gtk_get_option_group (FALSE));
+ g_option_context_parse (context, &argc, &argv, NULL);
+
+ gtk_init (&argc, &argv);
+ egg_debug_init (verbose);
+
+ /* are we already activated? */
+ egg_unique = egg_unique_new ();
+ ret = egg_unique_assign (egg_unique, "org.mate.PowerManager.Preferences");
+ if (!ret) {
+ goto unique_out;
+ }
+
+ prefs = gpm_prefs_new ();
+
+ g_signal_connect (egg_unique, "activated",
+ G_CALLBACK (gpm_prefs_activated_cb), prefs);
+ g_signal_connect (prefs, "action-help",
+ G_CALLBACK (gpm_prefs_help_cb), prefs);
+ g_signal_connect (prefs, "action-close",
+ G_CALLBACK (gpm_prefs_close_cb), prefs);
+ gtk_main ();
+ g_object_unref (prefs);
+
+unique_out:
+ g_object_unref (egg_unique);
+
+/* seems to not work...
+ g_option_context_free (context); */
+
+ return 0;
+}
diff --git a/src/gpm-screensaver.c b/src/gpm-screensaver.c
new file mode 100644
index 0000000..b4f9ad7
--- /dev/null
+++ b/src/gpm-screensaver.c
@@ -0,0 +1,453 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <mateconf/mateconf-client.h>
+
+#include "gpm-screensaver.h"
+#include "gpm-common.h"
+#include "egg-debug.h"
+
+static void gpm_screensaver_finalize (GObject *object);
+
+#define GPM_SCREENSAVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_SCREENSAVER, GpmScreensaverPrivate))
+
+#define GS_LISTENER_SERVICE "org.mate.ScreenSaver"
+#define GS_LISTENER_PATH "/"
+#define GS_LISTENER_INTERFACE "org.mate.ScreenSaver"
+
+struct GpmScreensaverPrivate
+{
+ DBusGProxy *proxy;
+ MateConfClient *conf;
+};
+
+enum {
+ AUTH_REQUEST,
+ LAST_SIGNAL
+};
+
+#if 0
+static guint signals [LAST_SIGNAL] = { 0 };
+#endif
+static gpointer gpm_screensaver_object = NULL;
+
+G_DEFINE_TYPE (GpmScreensaver, gpm_screensaver, G_TYPE_OBJECT)
+
+#if 0
+
+/** Invoked when we get the AuthenticationRequestBegin from g-s when the user
+ * has moved their mouse and we are showing the authentication box.
+ */
+static void
+gpm_screensaver_auth_begin (DBusGProxy *proxy,
+ GpmScreensaver *screensaver)
+{
+ egg_debug ("emitting auth-request : (%i)", TRUE);
+ g_signal_emit (screensaver, signals [AUTH_REQUEST], 0, TRUE);
+}
+
+/** Invoked when we get the AuthenticationRequestEnd from g-s when the user
+ * has entered a valid password or re-authenticated.
+ */
+static void
+gpm_screensaver_auth_end (DBusGProxy *proxy,
+ GpmScreensaver *screensaver)
+{
+ egg_debug ("emitting auth-request : (%i)", FALSE);
+ g_signal_emit (screensaver, signals [AUTH_REQUEST], 0, FALSE);
+}
+
+/**
+ * gpm_screensaver_proxy_connect_more:
+ * @screensaver: This class instance
+ **/
+static gboolean
+gpm_screensaver_proxy_connect_more (GpmScreensaver *screensaver)
+{
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ /* get AuthenticationRequestBegin */
+ dbus_g_proxy_add_signal (screensaver->priv->proxy,
+ "AuthenticationRequestBegin", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (screensaver->priv->proxy,
+ "AuthenticationRequestBegin",
+ G_CALLBACK (gpm_screensaver_auth_begin),
+ screensaver, NULL);
+
+ /* get AuthenticationRequestEnd */
+ dbus_g_proxy_add_signal (screensaver->priv->proxy,
+ "AuthenticationRequestEnd", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (screensaver->priv->proxy,
+ "AuthenticationRequestEnd",
+ G_CALLBACK (gpm_screensaver_auth_end),
+ screensaver, NULL);
+
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_proxy_disconnect_more:
+ * @screensaver: This class instance
+ **/
+static gboolean
+gpm_screensaver_proxy_disconnect_more (GpmScreensaver *screensaver)
+{
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+ egg_debug ("mate-screensaver disconnected from the session DBUS");
+ return TRUE;
+}
+#endif
+
+/**
+ * gpm_screensaver_lock_enabled:
+ * @screensaver: This class instance
+ * Return value: If mate-screensaver is set to lock the screen on screensave
+ **/
+gboolean
+gpm_screensaver_lock_enabled (GpmScreensaver *screensaver)
+{
+ gboolean enabled;
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+ enabled = mateconf_client_get_bool (screensaver->priv->conf, GS_PREF_LOCK_ENABLED, NULL);
+ return enabled;
+}
+
+/**
+ * gpm_screensaver_lock
+ * @screensaver: This class instance
+ * Return value: Success value
+ **/
+gboolean
+gpm_screensaver_lock (GpmScreensaver *screensaver)
+{
+ guint sleepcount = 0;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ egg_debug ("doing mate-screensaver lock");
+ dbus_g_proxy_call_no_reply (screensaver->priv->proxy,
+ "Lock", G_TYPE_INVALID);
+
+ /* When we send the Lock signal to g-ss it takes maybe a second
+ or so to fade the screen and lock. If we suspend mid fade then on
+ resume the X display is still present for a split second
+ (since fade is gamma) and as such it can leak information.
+ Instead we wait until g-ss reports running and thus blanked
+ solidly before we continue from the screensaver_lock action.
+ The interior of g-ss is async, so we cannot get the dbus method
+ to block until lock is complete. */
+ while (! gpm_screensaver_check_running (screensaver)) {
+ /* Sleep for 1/10s */
+ g_usleep (1000 * 100);
+ if (sleepcount++ > 50) {
+ egg_debug ("timeout waiting for mate-screensaver");
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_add_throttle:
+ * @screensaver: This class instance
+ * @reason: The reason for throttling
+ * Return value: Success value, or zero for failure
+ **/
+guint
+gpm_screensaver_add_throttle (GpmScreensaver *screensaver,
+ const char *reason)
+{
+ GError *error = NULL;
+ gboolean ret;
+ guint32 cookie;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), 0);
+ g_return_val_if_fail (reason != NULL, 0);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return 0;
+ }
+
+ ret = dbus_g_proxy_call (screensaver->priv->proxy,
+ "Throttle", &error,
+ G_TYPE_STRING, "Power screensaver",
+ G_TYPE_STRING, reason,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &cookie,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+ if (!ret) {
+ /* abort as the DBUS method failed */
+ egg_warning ("Throttle failed!");
+ return 0;
+ }
+
+ egg_debug ("adding throttle reason: '%s': id %u", reason, cookie);
+ return cookie;
+}
+
+/**
+ * gpm_screensaver_remove_throttle:
+ **/
+gboolean
+gpm_screensaver_remove_throttle (GpmScreensaver *screensaver, guint cookie)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ egg_debug ("removing throttle: id %u", cookie);
+ ret = dbus_g_proxy_call (screensaver->priv->proxy,
+ "UnThrottle", &error,
+ G_TYPE_UINT, cookie,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+ if (!ret) {
+ /* abort as the DBUS method failed */
+ egg_warning ("UnThrottle failed!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_check_running:
+ * @screensaver: This class instance
+ * Return value: TRUE if mate-screensaver is running
+ **/
+gboolean
+gpm_screensaver_check_running (GpmScreensaver *screensaver)
+{
+ gboolean ret;
+ gboolean temp = TRUE;
+ GError *error = NULL;
+
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ ret = dbus_g_proxy_call (screensaver->priv->proxy,
+ "GetActive", &error,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &temp,
+ G_TYPE_INVALID);
+ if (error) {
+ egg_debug ("ERROR: %s", error->message);
+ g_error_free (error);
+ }
+
+ return ret;
+}
+
+/**
+ * gpm_screensaver_poke:
+ * @screensaver: This class instance
+ *
+ * Pokes MATE Screensaver simulating hardware events. This displays the unlock
+ * dialogue when we resume, so the user doesn't have to move the mouse or press
+ * any key before the window comes up.
+ **/
+gboolean
+gpm_screensaver_poke (GpmScreensaver *screensaver)
+{
+ g_return_val_if_fail (GPM_IS_SCREENSAVER (screensaver), FALSE);
+
+ if (screensaver->priv->proxy == NULL) {
+ egg_warning ("not connected");
+ return FALSE;
+ }
+
+ egg_debug ("poke");
+ dbus_g_proxy_call_no_reply (screensaver->priv->proxy,
+ "SimulateUserActivity",
+ G_TYPE_INVALID);
+ return TRUE;
+}
+
+/**
+ * gpm_screensaver_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_screensaver_class_init (GpmScreensaverClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_screensaver_finalize;
+ g_type_class_add_private (klass, sizeof (GpmScreensaverPrivate));
+
+#if 0
+ signals [AUTH_REQUEST] =
+ g_signal_new ("auth-request",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmScreensaverClass, auth_request),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+#endif
+}
+
+/**
+ * gpm_screensaver_init:
+ * @screensaver: This class instance
+ **/
+static void
+gpm_screensaver_init (GpmScreensaver *screensaver)
+{
+ DBusGConnection *connection;
+
+ screensaver->priv = GPM_SCREENSAVER_GET_PRIVATE (screensaver);
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ screensaver->priv->proxy = dbus_g_proxy_new_for_name (connection,
+ GS_LISTENER_SERVICE,
+ GS_LISTENER_PATH,
+ GS_LISTENER_INTERFACE);
+ screensaver->priv->conf = mateconf_client_get_default ();
+}
+
+/**
+ * gpm_screensaver_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_screensaver_finalize (GObject *object)
+{
+ GpmScreensaver *screensaver;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_SCREENSAVER (object));
+
+ screensaver = GPM_SCREENSAVER (object);
+ screensaver->priv = GPM_SCREENSAVER_GET_PRIVATE (screensaver);
+
+ g_object_unref (screensaver->priv->conf);
+ g_object_unref (screensaver->priv->proxy);
+
+ G_OBJECT_CLASS (gpm_screensaver_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_screensaver_new:
+ * Return value: new GpmScreensaver instance.
+ **/
+GpmScreensaver *
+gpm_screensaver_new (void)
+{
+ if (gpm_screensaver_object != NULL) {
+ g_object_ref (gpm_screensaver_object);
+ } else {
+ gpm_screensaver_object = g_object_new (GPM_TYPE_SCREENSAVER, NULL);
+ g_object_add_weak_pointer (gpm_screensaver_object, &gpm_screensaver_object);
+ }
+ return GPM_SCREENSAVER (gpm_screensaver_object);
+}
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+#if 0
+static gboolean test_got_request = FALSE;
+static void
+gpm_screensaver_test_auth_request_cb (GpmScreensaver *screensaver, gboolean auth, EggTest *test)
+{
+ egg_debug ("auth request = %i", auth);
+ test_got_request = auth;
+
+ egg_test_loop_quit (test);
+}
+#endif
+
+void
+gpm_screensaver_test (gpointer data)
+{
+ GpmScreensaver *screensaver;
+// guint value;
+ gboolean ret;
+ EggTest *test = (EggTest *) data;
+
+ if (egg_test_start (test, "GpmScreensaver") == FALSE)
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "make sure we get a non null screensaver");
+ screensaver = gpm_screensaver_new ();
+ egg_test_assert (test, (screensaver != NULL));
+
+#if 0
+ /* connect signals */
+ g_signal_connect (screensaver, "auth-request",
+ G_CALLBACK (gpm_screensaver_test_auth_request_cb), test);
+#endif
+ /************************************************************/
+ egg_test_title (test, "lock screensaver");
+ ret = gpm_screensaver_lock (screensaver);
+ egg_test_assert (test, ret);
+
+ /************************************************************/
+ egg_test_title (test, "poke screensaver");
+ ret = gpm_screensaver_poke (screensaver);
+ egg_test_assert (test, ret);
+
+ g_object_unref (screensaver);
+
+ egg_test_end (test);
+}
+
+#endif
+
diff --git a/src/gpm-screensaver.h b/src/gpm-screensaver.h
new file mode 100644
index 0000000..b4c5733
--- /dev/null
+++ b/src/gpm-screensaver.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPMSCREENSAVER_H
+#define __GPMSCREENSAVER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_SCREENSAVER (gpm_screensaver_get_type ())
+#define GPM_SCREENSAVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_SCREENSAVER, GpmScreensaver))
+#define GPM_SCREENSAVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_SCREENSAVER, GpmScreensaverClass))
+#define GPM_IS_SCREENSAVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_SCREENSAVER))
+#define GPM_IS_SCREENSAVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_SCREENSAVER))
+#define GPM_SCREENSAVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_SCREENSAVER, GpmScreensaverClass))
+
+typedef struct GpmScreensaverPrivate GpmScreensaverPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmScreensaverPrivate *priv;
+} GpmScreensaver;
+
+typedef struct
+{
+ GObjectClass parent_class;
+#if 0
+ void (* auth_request) (GpmScreensaver *screensaver,
+ gboolean auth);
+#endif
+} GpmScreensaverClass;
+
+GType gpm_screensaver_get_type (void);
+GpmScreensaver *gpm_screensaver_new (void);
+void gpm_screensaver_test (gpointer data);
+
+gboolean gpm_screensaver_lock (GpmScreensaver *screensaver);
+gboolean gpm_screensaver_lock_enabled (GpmScreensaver *screensaver);
+guint32 gpm_screensaver_add_throttle (GpmScreensaver *screensaver,
+ const gchar *reason);
+gboolean gpm_screensaver_remove_throttle (GpmScreensaver *screensaver,
+ guint32 cookie);
+gboolean gpm_screensaver_check_running (GpmScreensaver *screensaver);
+gboolean gpm_screensaver_poke (GpmScreensaver *screensaver);
+
+G_END_DECLS
+
+#endif /* __GPMSCREENSAVER_H */
diff --git a/src/gpm-self-test.c b/src/gpm-self-test.c
new file mode 100644
index 0000000..ef8c769
--- /dev/null
+++ b/src/gpm-self-test.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "egg-test.h"
+#include "egg-debug.h"
+
+#include "gpm-screensaver.h"
+
+/* prototypes */
+void egg_precision_test (EggTest *test);
+void egg_discrete_test (EggTest *test);
+void egg_color_test (EggTest *test);
+void egg_array_float_test (EggTest *test);
+void egg_idletime_test (EggTest *test);
+
+void gpm_common_test (EggTest *test);
+void gpm_idle_test (EggTest *test);
+void gpm_phone_test (EggTest *test);
+void gpm_dpms_test (EggTest *test);
+void gpm_graph_widget_test (EggTest *test);
+void gpm_proxy_test (EggTest *test);
+void gpm_hal_manager_test (EggTest *test);
+void gpm_device_test (EggTest *test);
+void gpm_device_teststore (EggTest *test);
+
+int
+main (int argc, char **argv)
+{
+ EggTest *test;
+
+ g_type_init ();
+ test = egg_test_init ();
+ egg_debug_init (TRUE);
+
+ /* needed for DPMS checks */
+ gtk_init (&argc, &argv);
+
+ /* tests go here */
+ egg_precision_test (test);
+ egg_discrete_test (test);
+ egg_color_test (test);
+ egg_array_float_test (test);
+// egg_idletime_test (test);
+
+ gpm_common_test (test);
+ gpm_idle_test (test);
+ gpm_phone_test (test);
+// gpm_dpms_test (test);
+// gpm_graph_widget_test (test);
+// gpm_screensaver_test (test);
+
+#if 0
+ gpm_proxy_test (test);
+ gpm_hal_manager_test (test);
+ gpm_device_test (test);
+ gpm_device_teststore (test);
+#endif
+
+ return (egg_test_finish (test));
+}
+
diff --git a/src/gpm-session.c b/src/gpm-session.c
new file mode 100644
index 0000000..ffe3f61
--- /dev/null
+++ b/src/gpm-session.c
@@ -0,0 +1,551 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include "gpm-session.h"
+#include "gpm-common.h"
+#include "egg-debug.h"
+#include "gpm-marshal.h"
+
+static void gpm_session_finalize (GObject *object);
+
+#define GPM_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_SESSION, GpmSessionPrivate))
+
+#define GPM_SESSION_MANAGER_SERVICE "org.mate.SessionManager"
+#define GPM_SESSION_MANAGER_PATH "/org/mate/SessionManager"
+#define GPM_SESSION_MANAGER_INTERFACE "org.mate.SessionManager"
+#define GPM_SESSION_MANAGER_PRESENCE_PATH "/org/mate/SessionManager/Presence"
+#define GPM_SESSION_MANAGER_PRESENCE_INTERFACE "org.mate.SessionManager.Presence"
+#define GPM_SESSION_MANAGER_CLIENT_PRIVATE_INTERFACE "org.mate.SessionManager.ClientPrivate"
+#define GPM_DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
+
+typedef enum {
+ GPM_SESSION_STATUS_ENUM_AVAILABLE = 0,
+ GPM_SESSION_STATUS_ENUM_INVISIBLE,
+ GPM_SESSION_STATUS_ENUM_BUSY,
+ GPM_SESSION_STATUS_ENUM_IDLE,
+ GPM_SESSION_STATUS_ENUM_UNKNOWN
+} GpmSessionStatusEnum;
+
+typedef enum {
+ GPM_SESSION_INHIBIT_MASK_LOGOUT = 1,
+ GPM_SESSION_INHIBIT_MASK_SWITCH = 2,
+ GPM_SESSION_INHIBIT_MASK_SUSPEND = 4,
+ GPM_SESSION_INHIBIT_MASK_IDLE = 8
+} GpmSessionInhibitMask;
+
+struct GpmSessionPrivate
+{
+ DBusGProxy *proxy;
+ DBusGProxy *proxy_presence;
+ DBusGProxy *proxy_client_private;
+ DBusGProxy *proxy_prop;
+ gboolean is_idle_old;
+ gboolean is_idle_inhibited_old;
+ gboolean is_suspend_inhibited_old;
+};
+
+enum {
+ IDLE_CHANGED,
+ INHIBITED_CHANGED,
+ STOP,
+ QUERY_END_SESSION,
+ END_SESSION,
+ CANCEL_END_SESSION,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpm_session_object = NULL;
+
+G_DEFINE_TYPE (GpmSession, gpm_session, G_TYPE_OBJECT)
+
+/**
+ * gpm_session_logout:
+ **/
+gboolean
+gpm_session_logout (GpmSession *session)
+{
+ g_return_val_if_fail (GPM_IS_SESSION (session), FALSE);
+
+ /* no mate-session */
+ if (session->priv->proxy == NULL) {
+ egg_warning ("no mate-session");
+ return FALSE;
+ }
+
+ /* we have to use no reply, as the SM calls into g-p-m to get the can_suspend property */
+ dbus_g_proxy_call_no_reply (session->priv->proxy, "Shutdown", G_TYPE_INVALID);
+ return TRUE;
+}
+
+/**
+ * gpm_session_get_idle:
+ **/
+gboolean
+gpm_session_get_idle (GpmSession *session)
+{
+ g_return_val_if_fail (GPM_IS_SESSION (session), FALSE);
+ return session->priv->is_idle_old;
+}
+
+/**
+ * gpm_session_get_idle_inhibited:
+ **/
+gboolean
+gpm_session_get_idle_inhibited (GpmSession *session)
+{
+ g_return_val_if_fail (GPM_IS_SESSION (session), FALSE);
+ return session->priv->is_idle_inhibited_old;
+}
+
+/**
+ * gpm_session_get_suspend_inhibited:
+ **/
+gboolean
+gpm_session_get_suspend_inhibited (GpmSession *session)
+{
+ g_return_val_if_fail (GPM_IS_SESSION (session), FALSE);
+ return session->priv->is_suspend_inhibited_old;
+}
+
+/**
+ * gpm_session_presence_status_changed_cb:
+ **/
+static void
+gpm_session_presence_status_changed_cb (DBusGProxy *proxy, guint status, GpmSession *session)
+{
+ gboolean is_idle;
+ is_idle = (status == GPM_SESSION_STATUS_ENUM_IDLE);
+ if (is_idle != session->priv->is_idle_old) {
+ egg_debug ("emitting idle-changed : (%i)", is_idle);
+ session->priv->is_idle_old = is_idle;
+ g_signal_emit (session, signals [IDLE_CHANGED], 0, is_idle);
+ }
+}
+
+/**
+ * gpm_session_is_idle:
+ **/
+static gboolean
+gpm_session_is_idle (GpmSession *session)
+{
+ gboolean ret;
+ gboolean is_idle = FALSE;
+ GError *error = NULL;
+ GValue *value;
+
+ /* no mate-session */
+ if (session->priv->proxy_prop == NULL) {
+ egg_warning ("no mate-session");
+ goto out;
+ }
+
+ value = g_new0(GValue, 1);
+ /* find out if this change altered the inhibited state */
+ ret = dbus_g_proxy_call (session->priv->proxy_prop, "Get", &error,
+ G_TYPE_STRING, GPM_SESSION_MANAGER_PRESENCE_INTERFACE,
+ G_TYPE_STRING, "status",
+ G_TYPE_INVALID,
+ G_TYPE_VALUE, value,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to get idle status: %s", error->message);
+ g_error_free (error);
+ is_idle = FALSE;
+ goto out;
+ }
+ is_idle = (g_value_get_uint (value) == GPM_SESSION_STATUS_ENUM_IDLE);
+ g_free (value);
+out:
+ return is_idle;
+}
+
+/**
+ * gpm_session_is_idle_inhibited:
+ **/
+static gboolean
+gpm_session_is_idle_inhibited (GpmSession *session)
+{
+ gboolean ret;
+ gboolean is_inhibited = FALSE;
+ GError *error = NULL;
+
+ /* no mate-session */
+ if (session->priv->proxy == NULL) {
+ egg_warning ("no mate-session");
+ goto out;
+ }
+
+ /* find out if this change altered the inhibited state */
+ ret = dbus_g_proxy_call (session->priv->proxy, "IsInhibited", &error,
+ G_TYPE_UINT, GPM_SESSION_INHIBIT_MASK_IDLE,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &is_inhibited,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to get inhibit status: %s", error->message);
+ g_error_free (error);
+ is_inhibited = FALSE;
+ }
+out:
+ return is_inhibited;
+}
+
+/**
+ * gpm_session_is_suspend_inhibited:
+ **/
+static gboolean
+gpm_session_is_suspend_inhibited (GpmSession *session)
+{
+ gboolean ret;
+ gboolean is_inhibited = FALSE;
+ GError *error = NULL;
+
+ /* no mate-session */
+ if (session->priv->proxy == NULL) {
+ egg_warning ("no mate-session");
+ goto out;
+ }
+
+ /* find out if this change altered the inhibited state */
+ ret = dbus_g_proxy_call (session->priv->proxy, "IsInhibited", &error,
+ G_TYPE_UINT, GPM_SESSION_INHIBIT_MASK_SUSPEND,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &is_inhibited,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to get inhibit status: %s", error->message);
+ g_error_free (error);
+ is_inhibited = FALSE;
+ }
+out:
+ return is_inhibited;
+}
+
+/**
+ * gpm_session_stop_cb:
+ **/
+static void
+gpm_session_stop_cb (DBusGProxy *proxy, GpmSession *session)
+{
+ egg_debug ("emitting ::stop()");
+ g_signal_emit (session, signals [STOP], 0);
+}
+
+/**
+ * gpm_session_query_end_session_cb:
+ **/
+static void
+gpm_session_query_end_session_cb (DBusGProxy *proxy, guint flags, GpmSession *session)
+{
+ egg_debug ("emitting ::query-end-session(%i)", flags);
+ g_signal_emit (session, signals [QUERY_END_SESSION], 0, flags);
+}
+
+/**
+ * gpm_session_end_session_cb:
+ **/
+static void
+gpm_session_end_session_cb (DBusGProxy *proxy, guint flags, GpmSession *session)
+{
+ egg_debug ("emitting ::end-session(%i)", flags);
+ g_signal_emit (session, signals [END_SESSION], 0, flags);
+}
+
+/**
+ * gpm_session_end_session_response:
+ **/
+gboolean
+gpm_session_end_session_response (GpmSession *session, gboolean is_okay, const gchar *reason)
+{
+ gboolean ret = FALSE;
+ GError *error = NULL;
+
+ g_return_val_if_fail (GPM_IS_SESSION (session), FALSE);
+ g_return_val_if_fail (session->priv->proxy_client_private != NULL, FALSE);
+
+ /* no mate-session */
+ if (session->priv->proxy_client_private == NULL) {
+ egg_warning ("no mate-session proxy");
+ goto out;
+ }
+
+ /* send response */
+ ret = dbus_g_proxy_call (session->priv->proxy_client_private, "EndSessionResponse", &error,
+ G_TYPE_BOOLEAN, is_okay,
+ G_TYPE_STRING, reason,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to send session response: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gpm_session_register_client:
+ **/
+gboolean
+gpm_session_register_client (GpmSession *session, const gchar *app_id, const gchar *client_startup_id)
+{
+ gboolean ret = FALSE;
+ gchar *client_id = NULL;
+ GError *error = NULL;
+ DBusGConnection *connection;
+
+ g_return_val_if_fail (GPM_IS_SESSION (session), FALSE);
+
+ /* no mate-session */
+ if (session->priv->proxy == NULL) {
+ egg_warning ("no mate-session");
+ goto out;
+ }
+
+ /* find out if this change altered the inhibited state */
+ ret = dbus_g_proxy_call (session->priv->proxy, "RegisterClient", &error,
+ G_TYPE_STRING, app_id,
+ G_TYPE_STRING, client_startup_id,
+ G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &client_id,
+ G_TYPE_INVALID);
+ if (!ret) {
+ egg_warning ("failed to register client '%s': %s", client_startup_id, error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get org.mate.Session.ClientPrivate interface */
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ session->priv->proxy_client_private = dbus_g_proxy_new_for_name_owner (connection, GPM_SESSION_MANAGER_SERVICE,
+ client_id, GPM_SESSION_MANAGER_CLIENT_PRIVATE_INTERFACE, &error);
+ if (session->priv->proxy_client_private == NULL) {
+ egg_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get Stop */
+ dbus_g_proxy_add_signal (session->priv->proxy_client_private, "Stop", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy_client_private, "Stop", G_CALLBACK (gpm_session_stop_cb), session, NULL);
+
+ /* get QueryEndSession */
+ dbus_g_proxy_add_signal (session->priv->proxy_client_private, "QueryEndSession", G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy_client_private, "QueryEndSession", G_CALLBACK (gpm_session_query_end_session_cb), session, NULL);
+
+ /* get EndSession */
+ dbus_g_proxy_add_signal (session->priv->proxy_client_private, "EndSession", G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy_client_private, "EndSession", G_CALLBACK (gpm_session_end_session_cb), session, NULL);
+
+ egg_debug ("registered startup '%s' to client id '%s'", client_startup_id, client_id);
+out:
+ g_free (client_id);
+ return ret;
+}
+
+/**
+ * gpm_session_inhibit_changed_cb:
+ **/
+static void
+gpm_session_inhibit_changed_cb (DBusGProxy *proxy, const gchar *id, GpmSession *session)
+{
+ gboolean is_idle_inhibited;
+ gboolean is_suspend_inhibited;
+
+ is_idle_inhibited = gpm_session_is_idle_inhibited (session);
+ is_suspend_inhibited = gpm_session_is_suspend_inhibited (session);
+ if (is_idle_inhibited != session->priv->is_idle_inhibited_old || is_suspend_inhibited != session->priv->is_suspend_inhibited_old) {
+ egg_debug ("emitting inhibited-changed : idle=(%i), suspend=(%i)", is_idle_inhibited, is_suspend_inhibited);
+ session->priv->is_idle_inhibited_old = is_idle_inhibited;
+ session->priv->is_suspend_inhibited_old = is_suspend_inhibited;
+ g_signal_emit (session, signals [INHIBITED_CHANGED], 0, is_idle_inhibited, is_suspend_inhibited);
+ }
+}
+
+/**
+ * gpm_session_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpm_session_class_init (GpmSessionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpm_session_finalize;
+ g_type_class_add_private (klass, sizeof (GpmSessionPrivate));
+
+ signals [IDLE_CHANGED] =
+ g_signal_new ("idle-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmSessionClass, idle_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals [INHIBITED_CHANGED] =
+ g_signal_new ("inhibited-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmSessionClass, inhibited_changed),
+ NULL, NULL, gpm_marshal_VOID__BOOLEAN_BOOLEAN,
+ G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+ signals [STOP] =
+ g_signal_new ("stop",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmSessionClass, stop),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals [QUERY_END_SESSION] =
+ g_signal_new ("query-end-session",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmSessionClass, query_end_session),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+ signals [END_SESSION] =
+ g_signal_new ("end-session",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmSessionClass, end_session),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+ signals [CANCEL_END_SESSION] =
+ g_signal_new ("cancel-end-session",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpmSessionClass, cancel_end_session),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * gpm_session_init:
+ * @session: This class instance
+ **/
+static void
+gpm_session_init (GpmSession *session)
+{
+ DBusGConnection *connection;
+ GError *error = NULL;
+
+ session->priv = GPM_SESSION_GET_PRIVATE (session);
+ session->priv->is_idle_old = FALSE;
+ session->priv->is_idle_inhibited_old = FALSE;
+ session->priv->is_suspend_inhibited_old = FALSE;
+ session->priv->proxy_client_private = NULL;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+
+ /* get org.mate.Session interface */
+ session->priv->proxy = dbus_g_proxy_new_for_name_owner (connection, GPM_SESSION_MANAGER_SERVICE,
+ GPM_SESSION_MANAGER_PATH,
+ GPM_SESSION_MANAGER_INTERFACE, &error);
+ if (session->priv->proxy == NULL) {
+ egg_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get org.mate.Session.Presence interface */
+ session->priv->proxy_presence = dbus_g_proxy_new_for_name_owner (connection, GPM_SESSION_MANAGER_SERVICE,
+ GPM_SESSION_MANAGER_PRESENCE_PATH,
+ GPM_SESSION_MANAGER_PRESENCE_INTERFACE, &error);
+ if (session->priv->proxy_presence == NULL) {
+ egg_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get properties interface */
+ session->priv->proxy_prop = dbus_g_proxy_new_for_name_owner (connection, GPM_SESSION_MANAGER_SERVICE,
+ GPM_SESSION_MANAGER_PRESENCE_PATH,
+ GPM_DBUS_PROPERTIES_INTERFACE, &error);
+ if (session->priv->proxy_prop == NULL) {
+ egg_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get StatusChanged */
+ dbus_g_proxy_add_signal (session->priv->proxy_presence, "StatusChanged", G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy_presence, "StatusChanged", G_CALLBACK (gpm_session_presence_status_changed_cb), session, NULL);
+
+ /* get InhibitorAdded */
+ dbus_g_proxy_add_signal (session->priv->proxy, "InhibitorAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy, "InhibitorAdded", G_CALLBACK (gpm_session_inhibit_changed_cb), session, NULL);
+
+ /* get InhibitorRemoved */
+ dbus_g_proxy_add_signal (session->priv->proxy, "InhibitorRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy, "InhibitorRemoved", G_CALLBACK (gpm_session_inhibit_changed_cb), session, NULL);
+
+ /* coldplug */
+ session->priv->is_idle_inhibited_old = gpm_session_is_idle_inhibited (session);
+ session->priv->is_suspend_inhibited_old = gpm_session_is_suspend_inhibited (session);
+ session->priv->is_idle_old = gpm_session_is_idle (session);
+ egg_debug ("idle: %i, idle_inhibited: %i, suspend_inhibited: %i", session->priv->is_idle_old, session->priv->is_idle_inhibited_old, session->priv->is_suspend_inhibited_old);
+}
+
+/**
+ * gpm_session_finalize:
+ * @object: This class instance
+ **/
+static void
+gpm_session_finalize (GObject *object)
+{
+ GpmSession *session;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_SESSION (object));
+
+ session = GPM_SESSION (object);
+ session->priv = GPM_SESSION_GET_PRIVATE (session);
+
+ g_object_unref (session->priv->proxy);
+ g_object_unref (session->priv->proxy_presence);
+ if (session->priv->proxy_client_private != NULL)
+ g_object_unref (session->priv->proxy_client_private);
+ g_object_unref (session->priv->proxy_prop);
+
+ G_OBJECT_CLASS (gpm_session_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_session_new:
+ * Return value: new GpmSession instance.
+ **/
+GpmSession *
+gpm_session_new (void)
+{
+ if (gpm_session_object != NULL) {
+ g_object_ref (gpm_session_object);
+ } else {
+ gpm_session_object = g_object_new (GPM_TYPE_SESSION, NULL);
+ g_object_add_weak_pointer (gpm_session_object, &gpm_session_object);
+ }
+ return GPM_SESSION (gpm_session_object);
+}
diff --git a/src/gpm-session.h b/src/gpm-session.h
new file mode 100644
index 0000000..ad45e46
--- /dev/null
+++ b/src/gpm-session.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_SESSION_H
+#define __GPM_SESSION_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_SESSION (gpm_session_get_type ())
+#define GPM_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_SESSION, GpmSession))
+#define GPM_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_SESSION, GpmSessionClass))
+#define GPM_IS_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_SESSION))
+#define GPM_IS_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_SESSION))
+#define GPM_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_SESSION, GpmSessionClass))
+
+typedef struct GpmSessionPrivate GpmSessionPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmSessionPrivate *priv;
+} GpmSession;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* idle_changed) (GpmSession *session,
+ gboolean is_idle);
+ void (* inhibited_changed) (GpmSession *session,
+ gboolean is_idle_inhibited,
+ gboolean is_suspend_inhibited);
+ /* just exit */
+ void (* stop) (GpmSession *session);
+ /* reply with EndSessionResponse */
+ void (* query_end_session) (GpmSession *session,
+ guint flags);
+ /* reply with EndSessionResponse */
+ void (* end_session) (GpmSession *session,
+ guint flags);
+ void (* cancel_end_session) (GpmSession *session);
+} GpmSessionClass;
+
+GType gpm_session_get_type (void);
+GpmSession *gpm_session_new (void);
+
+gboolean gpm_session_logout (GpmSession *session);
+gboolean gpm_session_get_idle (GpmSession *session);
+gboolean gpm_session_get_idle_inhibited (GpmSession *session);
+gboolean gpm_session_get_suspend_inhibited (GpmSession *session);
+gboolean gpm_session_register_client (GpmSession *session,
+ const gchar *app_id,
+ const gchar *client_startup_id);
+gboolean gpm_session_end_session_response (GpmSession *session,
+ gboolean is_okay,
+ const gchar *reason);
+
+G_END_DECLS
+
+#endif /* __GPM_SESSION_H */
diff --git a/src/gpm-statistics.c b/src/gpm-statistics.c
new file mode 100644
index 0000000..7ac6f2e
--- /dev/null
+++ b/src/gpm-statistics.c
@@ -0,0 +1,1829 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <locale.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <gtk/gtk.h>
+#include <dbus/dbus-glib.h>
+#include <mateconf/mateconf-client.h>
+#include <libupower-glib/upower.h>
+
+#include "egg-debug.h"
+#include "egg-color.h"
+#include "egg-array-float.h"
+#include "egg-unique.h"
+
+#include "gpm-common.h"
+#include "gpm-stock-icons.h"
+#include "gpm-upower.h"
+#include "gpm-graph-widget.h"
+
+static GtkBuilder *builder = NULL;
+static GtkListStore *list_store_info = NULL;
+static GtkListStore *list_store_devices = NULL;
+static GtkListStore *list_store_wakeups = NULL;
+gchar *current_device = NULL;
+static const gchar *history_type;
+static const gchar *stats_type;
+static guint history_time;
+static MateConfClient *mateconf_client;
+static gfloat sigma_smoothing = 0.0f;
+static UpWakeups *wakeups = NULL;
+static GtkWidget *graph_history = NULL;
+static GtkWidget *graph_statistics = NULL;
+
+enum {
+ GPM_INFO_COLUMN_TEXT,
+ GPM_INFO_COLUMN_VALUE,
+ GPM_INFO_COLUMN_LAST
+};
+
+enum {
+ GPM_DEVICES_COLUMN_ICON,
+ GPM_DEVICES_COLUMN_TEXT,
+ GPM_DEVICES_COLUMN_ID,
+ GPM_DEVICES_COLUMN_LAST
+};
+
+enum {
+ GPM_WAKEUPS_COLUMN_ICON,
+ GPM_WAKEUPS_COLUMN_ID,
+ GPM_WAKEUPS_COLUMN_VALUE,
+ GPM_WAKEUPS_COLUMN_CMDLINE,
+ GPM_WAKEUPS_COLUMN_DETAILS,
+ GPM_WAKEUPS_COLUMN_LAST
+};
+
+#define GPM_HISTORY_RATE_TEXT _("Rate")
+#define GPM_HISTORY_CHARGE_TEXT _("Charge")
+#define GPM_HISTORY_TIME_FULL_TEXT _("Time to full")
+#define GPM_HISTORY_TIME_EMPTY_TEXT _("Time to empty")
+
+#define GPM_HISTORY_RATE_VALUE "rate"
+#define GPM_HISTORY_CHARGE_VALUE "charge"
+#define GPM_HISTORY_TIME_FULL_VALUE "time-full"
+#define GPM_HISTORY_TIME_EMPTY_VALUE "time-empty"
+
+#define GPM_HISTORY_MINUTE_TEXT _("10 minutes")
+#define GPM_HISTORY_HOUR_TEXT _("2 hours")
+#define GPM_HISTORY_HOURS_TEXT _("6 hours")
+#define GPM_HISTORY_DAY_TEXT _("1 day")
+#define GPM_HISTORY_WEEK_TEXT _("1 week")
+
+#define GPM_HISTORY_MINUTE_VALUE 10*60
+#define GPM_HISTORY_HOUR_VALUE 2*60*60
+#define GPM_HISTORY_HOURS_VALUE 6*60*60
+#define GPM_HISTORY_DAY_VALUE 24*60*60
+#define GPM_HISTORY_WEEK_VALUE 7*24*60*60
+
+/* TRANSLATORS: what we've observed about the device */
+#define GPM_STATS_CHARGE_DATA_TEXT _("Charge profile")
+#define GPM_STATS_DISCHARGE_DATA_TEXT _("Discharge profile")
+/* TRANSLATORS: how accurately we can predict the time remaining of the battery */
+#define GPM_STATS_CHARGE_ACCURACY_TEXT _("Charge accuracy")
+#define GPM_STATS_DISCHARGE_ACCURACY_TEXT _("Discharge accuracy")
+
+#define GPM_STATS_CHARGE_DATA_VALUE "charge-data"
+#define GPM_STATS_CHARGE_ACCURACY_VALUE "charge-accuracy"
+#define GPM_STATS_DISCHARGE_DATA_VALUE "discharge-data"
+#define GPM_STATS_DISCHARGE_ACCURACY_VALUE "discharge-accuracy"
+
+/**
+ * gpm_stats_button_help_cb:
+ **/
+static void
+gpm_stats_button_help_cb (GtkWidget *widget, gboolean data)
+{
+ gpm_help_display ("statistics");
+}
+
+/**
+ * gpm_stats_add_info_columns:
+ **/
+static void
+gpm_stats_add_info_columns (GtkTreeView *treeview)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ /* image */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Attribute"), renderer,
+ "markup", GPM_INFO_COLUMN_TEXT, NULL);
+ gtk_tree_view_column_set_sort_column_id (column, GPM_INFO_COLUMN_TEXT);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* column for text */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Value"), renderer,
+ "markup", GPM_INFO_COLUMN_VALUE, NULL);
+ gtk_tree_view_append_column (treeview, column);
+}
+
+/**
+ * gpm_stats_add_devices_columns:
+ **/
+static void
+gpm_stats_add_devices_columns (GtkTreeView *treeview)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ /* image */
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
+ column = gtk_tree_view_column_new_with_attributes (_("Image"), renderer,
+ "icon-name", GPM_DEVICES_COLUMN_ICON, NULL);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* column for text */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Description"), renderer,
+ "markup", GPM_DEVICES_COLUMN_TEXT, NULL);
+ gtk_tree_view_column_set_sort_column_id (column, GPM_INFO_COLUMN_TEXT);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+}
+
+/**
+ * gpm_stats_add_wakeups_columns:
+ **/
+static void
+gpm_stats_add_wakeups_columns (GtkTreeView *treeview)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ /* image */
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
+ column = gtk_tree_view_column_new_with_attributes (_("Type"), renderer,
+ "icon-name", GPM_WAKEUPS_COLUMN_ICON, NULL);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* column for id */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("ID"), renderer,
+ "markup", GPM_WAKEUPS_COLUMN_ID, NULL);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+
+ /* column for value */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Wakeups"), renderer,
+ "markup", GPM_WAKEUPS_COLUMN_VALUE, NULL);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+
+ /* column for cmdline */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Command"), renderer,
+ "markup", GPM_WAKEUPS_COLUMN_CMDLINE, NULL);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+
+ /* column for details */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Details"), renderer,
+ "markup", GPM_WAKEUPS_COLUMN_DETAILS, NULL);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+}
+
+/**
+ * gpm_stats_add_info_data:
+ **/
+static void
+gpm_stats_add_info_data (const gchar *attr, const gchar *text)
+{
+ GtkTreeIter iter;
+ gtk_list_store_append (list_store_info, &iter);
+ gtk_list_store_set (list_store_info, &iter,
+ GPM_INFO_COLUMN_TEXT, attr,
+ GPM_INFO_COLUMN_VALUE, text, -1);
+}
+
+/**
+ * gpm_stats_update_smooth_data:
+ **/
+static GPtrArray *
+gpm_stats_update_smooth_data (GPtrArray *list)
+{
+ guint i;
+ GpmPointObj *point;
+ GpmPointObj *point_new;
+ GPtrArray *new;
+ EggArrayFloat *raw;
+ EggArrayFloat *convolved;
+ EggArrayFloat *outliers;
+ EggArrayFloat *gaussian = NULL;
+
+ /* convert the y data to a EggArrayFloat array */
+ raw = egg_array_float_new (list->len);
+ for (i=0; i<list->len; i++) {
+ point = (GpmPointObj *) g_ptr_array_index (list, i);
+ egg_array_float_set (raw, i, point->y);
+ }
+
+ /* remove any outliers */
+ outliers = egg_array_float_remove_outliers (raw, 3, 0.1);
+
+ /* convolve with gaussian */
+ gaussian = egg_array_float_compute_gaussian (15, sigma_smoothing);
+ convolved = egg_array_float_convolve (outliers, gaussian);
+
+ /* add the smoothed data back into a new array */
+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
+ for (i=0; i<list->len; i++) {
+ point = (GpmPointObj *) g_ptr_array_index (list, i);
+ point_new = g_new0 (GpmPointObj, 1);
+ point_new->color = point->color;
+ point_new->x = point->x;
+ point_new->y = egg_array_float_get (convolved, i);
+ g_ptr_array_add (new, point_new);
+ }
+
+ /* free data */
+ egg_array_float_free (gaussian);
+ egg_array_float_free (raw);
+ egg_array_float_free (convolved);
+ egg_array_float_free (outliers);
+
+ return new;
+}
+
+/**
+ * gpm_stats_time_to_string:
+ **/
+static gchar *
+gpm_stats_time_to_string (gint seconds)
+{
+ gfloat value = seconds;
+
+ if (value < 0) {
+ /* TRANSLATORS: this is when the stats time is not known */
+ return g_strdup (_("Unknown"));
+ }
+ if (value < 60) {
+ /* TRANSLATORS: this is a time value, usually to show on a graph */
+ return g_strdup_printf (ngettext ("%.0f second", "%.0f seconds", value), value);
+ }
+ value /= 60.0;
+ if (value < 60) {
+ /* TRANSLATORS: this is a time value, usually to show on a graph */
+ return g_strdup_printf (ngettext ("%.1f minute", "%.1f minutes", value), value);
+ }
+ value /= 60.0;
+ if (value < 60) {
+ /* TRANSLATORS: this is a time value, usually to show on a graph */
+ return g_strdup_printf (ngettext ("%.1f hour", "%.1f hours", value), value);
+ }
+ value /= 24.0;
+ /* TRANSLATORS: this is a time value, usually to show on a graph */
+ return g_strdup_printf (ngettext ("%.1f day", "%.1f days", value), value);
+}
+
+/**
+ * gpm_stats_bool_to_string:
+ **/
+static const gchar *
+gpm_stats_bool_to_string (gboolean ret)
+{
+ return ret ? _("Yes") : _("No");
+}
+
+/**
+ * gpm_stats_get_printable_device_path:
+ **/
+static gchar *
+gpm_stats_get_printable_device_path (UpDevice *device)
+{
+ const gchar *object_path;
+ gchar *device_path = NULL;
+
+ /* get object path */
+ object_path = up_device_get_object_path (device);
+ if (object_path != NULL)
+ device_path = g_filename_display_basename (object_path);
+
+ return device_path;
+}
+
+/**
+ * gpm_stats_update_info_page_details:
+ **/
+static void
+gpm_stats_update_info_page_details (UpDevice *device)
+{
+ struct tm *time_tm;
+ time_t t;
+ gchar time_buf[256];
+ gchar *text;
+ guint refreshed;
+ UpDeviceKind kind;
+ UpDeviceState state;
+ UpDeviceTechnology technology;
+ gdouble percentage;
+ gdouble capacity;
+ gdouble energy;
+ gdouble energy_empty;
+ gdouble energy_full;
+ gdouble energy_full_design;
+ gdouble energy_rate;
+ gdouble voltage;
+ gboolean online;
+ gboolean is_present;
+ gboolean power_supply;
+ gboolean is_rechargeable;
+ guint64 update_time;
+ gint64 time_to_full;
+ gint64 time_to_empty;
+ gchar *vendor = NULL;
+ gchar *serial = NULL;
+ gchar *model = NULL;
+ gchar *device_path = NULL;
+
+ gtk_list_store_clear (list_store_info);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "percentage", &percentage,
+ "online", &online,
+ "update_time", &update_time,
+ "power_supply", &power_supply,
+ "is_rechargeable", &is_rechargeable,
+ "is-present", &is_present,
+ "time-to-full", &time_to_full,
+ "time-to-empty", &time_to_empty,
+ "technology", &technology,
+ "capacity", &capacity,
+ "energy", &energy,
+ "energy-empty", &energy_empty,
+ "energy-full", &energy_full,
+ "energy-full-design", &energy_full_design,
+ "energy-rate", &energy_rate,
+ "voltage", &voltage,
+ "vendor", &vendor,
+ "serial", &serial,
+ "model", &model,
+ NULL);
+
+ /* get a human readable time */
+ t = (time_t) update_time;
+ time_tm = localtime (&t);
+ strftime (time_buf, sizeof time_buf, "%c", time_tm);
+
+ /* remove prefix */
+ device_path = gpm_stats_get_printable_device_path (device);
+ /* TRANSLATORS: the device ID of the current device, e.g. "battery0" */
+ gpm_stats_add_info_data (_("Device"), device_path);
+ g_free (device_path);
+
+ gpm_stats_add_info_data (_("Type"), gpm_device_kind_to_localised_text (kind, 1));
+ if (vendor != NULL && vendor[0] != '\0')
+ gpm_stats_add_info_data (_("Vendor"), vendor);
+ if (model != NULL && model[0] != '\0')
+ gpm_stats_add_info_data (_("Model"), model);
+ if (serial != NULL && serial[0] != '\0')
+ gpm_stats_add_info_data (_("Serial number"), serial);
+
+ /* TRANSLATORS: a boolean attribute that means if the device is supplying the
+ * main power for the computer. For instance, an AC adapter or laptop battery
+ * would be TRUE, but a mobile phone or mouse taking power is FALSE */
+ gpm_stats_add_info_data (_("Supply"), gpm_stats_bool_to_string (power_supply));
+
+ refreshed = (int) (time (NULL) - update_time);
+ text = g_strdup_printf (ngettext ("%d second", "%d seconds", refreshed), refreshed);
+
+ /* TRANSLATORS: when the device was last updated with new data. It's
+ * usually a few seconds when a device is discharging or charging. */
+ gpm_stats_add_info_data (_("Refreshed"), text);
+ g_free (text);
+
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD ||
+ kind == UP_DEVICE_KIND_UPS) {
+ /* TRANSLATORS: Present is whether the device is currently attached
+ * to the computer, as some devices (e.g. laptop batteries) can
+ * be removed, but still observed as devices on the system */
+ gpm_stats_add_info_data (_("Present"), gpm_stats_bool_to_string (is_present));
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD) {
+ /* TRANSLATORS: If the device can be recharged, e.g. lithium
+ * batteries rather than alkaline ones */
+ gpm_stats_add_info_data (_("Rechargeable"), gpm_stats_bool_to_string (is_rechargeable));
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD) {
+ /* TRANSLATORS: The state of the device, e.g. "Changing" or "Fully charged" */
+ gpm_stats_add_info_data (_("State"), gpm_device_state_to_localised_string (state));
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ text = g_strdup_printf ("%.1f Wh", energy);
+ gpm_stats_add_info_data (_("Energy"), text);
+ g_free (text);
+ text = g_strdup_printf ("%.1f Wh", energy_empty);
+ gpm_stats_add_info_data (_("Energy when empty"), text);
+ g_free (text);
+ text = g_strdup_printf ("%.1f Wh", energy_full);
+ gpm_stats_add_info_data (_("Energy when full"), text);
+ g_free (text);
+ text = g_strdup_printf ("%.1f Wh", energy_full_design);
+ gpm_stats_add_info_data (_("Energy (design)"), text);
+ g_free (text);
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_MONITOR) {
+ text = g_strdup_printf ("%.1f W", energy_rate);
+ /* TRANSLATORS: the rate of discharge for the device */
+ gpm_stats_add_info_data (_("Rate"), text);
+ g_free (text);
+ }
+ if (kind == UP_DEVICE_KIND_UPS ||
+ kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_MONITOR) {
+ text = g_strdup_printf ("%.1f V", voltage);
+ gpm_stats_add_info_data (_("Voltage"), text);
+ g_free (text);
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_UPS) {
+ if (time_to_full >= 0) {
+ text = gpm_stats_time_to_string (time_to_full);
+ gpm_stats_add_info_data (_("Time to full"), text);
+ g_free (text);
+ }
+ if (time_to_empty >= 0) {
+ text = gpm_stats_time_to_string (time_to_empty);
+ gpm_stats_add_info_data (_("Time to empty"), text);
+ g_free (text);
+ }
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY ||
+ kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD ||
+ kind == UP_DEVICE_KIND_UPS) {
+ text = g_strdup_printf ("%.1f%%", percentage);
+ /* TRANSLATORS: the amount of charge the cell contains */
+ gpm_stats_add_info_data (_("Percentage"), text);
+ g_free (text);
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ text = g_strdup_printf ("%.1f%%", capacity);
+ /* TRANSLATORS: the capacity of the device, which is basically a measure
+ * of how full it can get, relative to the design capacity */
+ gpm_stats_add_info_data (_("Capacity"), text);
+ g_free (text);
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ /* TRANSLATORS: the type of battery, e.g. lithium or nikel metal hydroxide */
+ gpm_stats_add_info_data (_("Technology"), gpm_device_technology_to_localised_string (technology));
+ }
+ if (kind == UP_DEVICE_KIND_LINE_POWER) {
+ /* TRANSLATORS: this is when the device is plugged in, typically
+ * only shown for the ac adaptor device */
+ gpm_stats_add_info_data (_("Online"), gpm_stats_bool_to_string (online));
+ }
+
+ g_free (vendor);
+ g_free (serial);
+ g_free (model);
+}
+
+/**
+ * gpm_stats_set_graph_data:
+ **/
+static void
+gpm_stats_set_graph_data (GtkWidget *widget, GPtrArray *data, gboolean use_smoothed, gboolean use_points)
+{
+ GPtrArray *smoothed;
+
+ gpm_graph_widget_data_clear (GPM_GRAPH_WIDGET (widget));
+
+ /* add correct data */
+ if (!use_smoothed) {
+ if (use_points)
+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_BOTH, data);
+ else
+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_LINE, data);
+ } else {
+ smoothed = gpm_stats_update_smooth_data (data);
+ if (use_points)
+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_POINTS, data);
+ gpm_graph_widget_data_assign (GPM_GRAPH_WIDGET (widget), GPM_GRAPH_WIDGET_PLOT_LINE, smoothed);
+ g_ptr_array_unref (smoothed);
+ }
+
+ /* show */
+ gtk_widget_show (widget);
+}
+
+/**
+ * gpm_stats_update_info_page_history:
+ **/
+static void
+gpm_stats_update_info_page_history (UpDevice *device)
+{
+ GPtrArray *array;
+ guint i;
+ UpHistoryItem *item;
+ GtkWidget *widget;
+ gboolean checked;
+ gboolean points;
+ GpmPointObj *point;
+ GPtrArray *new;
+ gint32 offset = 0;
+ GTimeVal timeval;
+
+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
+ if (g_strcmp0 (history_type, GPM_HISTORY_CHARGE_VALUE) == 0) {
+ g_object_set (graph_history,
+ "type-x", GPM_GRAPH_WIDGET_TYPE_TIME,
+ "type-y", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
+ "autorange-x", FALSE,
+ "start-x", -history_time,
+ "stop-x", 0,
+ "autorange-y", FALSE,
+ "start-y", 0,
+ "stop-y", 100,
+ NULL);
+ } else if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0) {
+ g_object_set (graph_history,
+ "type-x", GPM_GRAPH_WIDGET_TYPE_TIME,
+ "type-y", GPM_GRAPH_WIDGET_TYPE_POWER,
+ "autorange-x", FALSE,
+ "start-x", -history_time,
+ "stop-x", 0,
+ "autorange-y", TRUE,
+ NULL);
+ } else {
+ g_object_set (graph_history,
+ "type-x", GPM_GRAPH_WIDGET_TYPE_TIME,
+ "type-y", GPM_GRAPH_WIDGET_TYPE_TIME,
+ "autorange-x", FALSE,
+ "start-x", -history_time,
+ "stop-x", 0,
+ "autorange-y", TRUE,
+ NULL);
+ }
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_history_nodata"));
+ array = up_device_get_history_sync (device, history_type, history_time, 150, NULL, NULL);
+ if (array == NULL) {
+ /* show no data label and hide graph */
+ gtk_widget_hide (graph_history);
+ gtk_widget_show (widget);
+ goto out;
+ }
+
+ /* hide no data and show graph */
+ gtk_widget_hide (widget);
+ gtk_widget_show (graph_history);
+
+ g_get_current_time (&timeval);
+ offset = timeval.tv_sec;
+
+ for (i=0; i<array->len; i++) {
+ item = (UpHistoryItem *) g_ptr_array_index (array, i);
+
+ /* abandon this point */
+ if (up_history_item_get_state (item) == UP_DEVICE_STATE_UNKNOWN)
+ continue;
+
+ point = gpm_point_obj_new ();
+ point->x = (gint32) up_history_item_get_time (item) - offset;
+ point->y = up_history_item_get_value (item);
+ if (up_history_item_get_state (item) == UP_DEVICE_STATE_CHARGING)
+ point->color = egg_color_from_rgb (255, 0, 0);
+ else if (up_history_item_get_state (item) == UP_DEVICE_STATE_DISCHARGING)
+ point->color = egg_color_from_rgb (0, 0, 255);
+ else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_CHARGE)
+ point->color = egg_color_from_rgb (200, 0, 0);
+ else if (up_history_item_get_state (item) == UP_DEVICE_STATE_PENDING_DISCHARGE)
+ point->color = egg_color_from_rgb (0, 0, 200);
+ else {
+ if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
+ point->color = egg_color_from_rgb (255, 255, 255);
+ else
+ point->color = egg_color_from_rgb (0, 255, 0);
+ }
+ g_ptr_array_add (new, point);
+ }
+
+ /* render */
+ sigma_smoothing = 2.0;
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_history"));
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_history"));
+ points = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ /* present data to graph */
+ gpm_stats_set_graph_data (graph_history, new, checked, points);
+
+ g_ptr_array_unref (array);
+ g_ptr_array_unref (new);
+out:
+ return;
+}
+
+/**
+ * gpm_stats_update_info_page_stats:
+ **/
+static void
+gpm_stats_update_info_page_stats (UpDevice *device)
+{
+ GPtrArray *array;
+ guint i;
+ UpStatsItem *item;
+ GtkWidget *widget;
+ gboolean checked;
+ gboolean points;
+ GpmPointObj *point;
+ GPtrArray *new;
+ gboolean use_data = FALSE;
+ const gchar *type = NULL;
+
+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) gpm_point_obj_free);
+ if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0) {
+ type = "charging";
+ use_data = TRUE;
+ } else if (g_strcmp0 (stats_type, GPM_STATS_DISCHARGE_DATA_VALUE) == 0) {
+ type = "discharging";
+ use_data = TRUE;
+ } else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_ACCURACY_VALUE) == 0) {
+ type = "charging";
+ use_data = FALSE;
+ } else if (g_strcmp0 (stats_type, GPM_STATS_DISCHARGE_ACCURACY_VALUE) == 0) {
+ type = "discharging";
+ use_data = FALSE;
+ } else {
+ g_assert_not_reached ();
+ }
+
+ if (use_data) {
+ g_object_set (graph_statistics,
+ "type-x", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
+ "type-y", GPM_GRAPH_WIDGET_TYPE_FACTOR,
+ "autorange-x", TRUE,
+ "autorange-y", TRUE,
+ NULL);
+ } else {
+ g_object_set (graph_statistics,
+ "type-x", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
+ "type-y", GPM_GRAPH_WIDGET_TYPE_PERCENTAGE,
+ "autorange-x", TRUE,
+ "autorange-y", TRUE,
+ NULL);
+ }
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_stats_nodata"));
+ array = up_device_get_statistics_sync (device, type, NULL, NULL);
+ if (array == NULL) {
+ /* show no data label and hide graph */
+ gtk_widget_hide (graph_statistics);
+ gtk_widget_show (widget);
+ goto out;
+ }
+
+ /* hide no data and show graph */
+ gtk_widget_hide (widget);
+ gtk_widget_show (graph_statistics);
+
+ for (i=0; i<array->len; i++) {
+ item = (UpStatsItem *) g_ptr_array_index (array, i);
+ point = gpm_point_obj_new ();
+ point->x = i;
+ if (use_data)
+ point->y = up_stats_item_get_value (item);
+ else
+ point->y = up_stats_item_get_accuracy (item);
+ point->color = egg_color_from_rgb (255, 0, 0);
+ g_ptr_array_add (new, point);
+ }
+
+ /* render */
+ sigma_smoothing = 1.1;
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_stats"));
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_stats"));
+ points = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+
+ /* present data to graph */
+ gpm_stats_set_graph_data (graph_statistics, new, checked, points);
+
+ g_ptr_array_unref (array);
+ g_ptr_array_unref (new);
+out:
+ return;
+}
+
+/**
+ * gpm_stats_update_info_data_page:
+ **/
+static void
+gpm_stats_update_info_data_page (UpDevice *device, gint page)
+{
+ if (page == 0)
+ gpm_stats_update_info_page_details (device);
+ else if (page == 1)
+ gpm_stats_update_info_page_history (device);
+ else if (page == 2)
+ gpm_stats_update_info_page_stats (device);
+}
+
+/**
+ * gpm_stats_update_info_data:
+ **/
+static void
+gpm_stats_update_info_data (UpDevice *device)
+{
+ gint page;
+ GtkNotebook *notebook;
+ GtkWidget *page_widget;
+ gboolean has_history;
+ gboolean has_statistics;
+
+ /* get properties */
+ g_object_get (device,
+ "has-history", &has_history,
+ "has-statistics", &has_statistics,
+ NULL);
+
+
+ notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "notebook1"));
+
+ /* show info page */
+ page_widget = gtk_notebook_get_nth_page (notebook, 0);
+ gtk_widget_show (page_widget);
+
+ /* hide history if no support */
+ page_widget = gtk_notebook_get_nth_page (notebook, 1);
+ if (has_history)
+ gtk_widget_show (page_widget);
+ else
+ gtk_widget_hide (page_widget);
+
+ /* hide statistics if no support */
+ page_widget = gtk_notebook_get_nth_page (notebook, 2);
+ if (has_statistics)
+ gtk_widget_show (page_widget);
+ else
+ gtk_widget_hide (page_widget);
+
+ /* hide wakeups page */
+ page_widget = gtk_notebook_get_nth_page (notebook, 3);
+ gtk_widget_hide (page_widget);
+
+ page = gtk_notebook_get_current_page (notebook);
+ gpm_stats_update_info_data_page (device, page);
+
+ return;
+}
+
+/**
+ * gpm_stats_format_cmdline:
+ **/
+static gchar *
+gpm_stats_format_cmdline (UpWakeupItem *item)
+{
+ gchar *found;
+ gchar *temp = NULL;
+ gchar *cmdline;
+ const gchar *temp_ptr;
+
+ /* nothing */
+ if (up_wakeup_item_get_cmdline (item) == NULL) {
+ /* TRANSLATORS: the command line was not provided */
+ temp_ptr = _("No data");
+ goto out;
+ }
+
+ /* common kernel cmd names */
+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "insmod") == 0) {
+ /* TRANSLATORS: kernel module, usually a device driver */
+ temp_ptr = _("Kernel module");
+ goto out;
+ }
+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "modprobe") == 0) {
+ /* TRANSLATORS: kernel module, usually a device driver */
+ temp_ptr = _("Kernel module");
+ goto out;
+ }
+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "swapper") == 0) {
+ /* TRANSLATORS: kernel housekeeping */
+ temp_ptr = _("Kernel core");
+ goto out;
+ }
+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "kernel-ipi") == 0) {
+ /* TRANSLATORS: interrupt between processors */
+ temp_ptr = _("Interprocessor interrupt");
+ goto out;
+ }
+ if (g_strcmp0 (up_wakeup_item_get_cmdline (item), "interrupt") == 0) {
+ /* TRANSLATORS: unknown interrupt */
+ temp_ptr = _("Interrupt");
+ goto out;
+ }
+
+ /* truncate at first space or ':' */
+ temp = g_strdup (up_wakeup_item_get_cmdline (item));
+ found = strstr (temp, ":");
+ if (found != NULL)
+ *found = '\0';
+ found = strstr (temp, " ");
+ if (found != NULL)
+ *found = '\0';
+
+ /* remove path */
+ found = g_strrstr (temp, "/");
+ if (found != NULL && strncmp (temp, "event", 5) != 0)
+ temp_ptr = found + 1;
+ else
+ temp_ptr = temp;
+
+out:
+ /* format command line */
+ if (up_wakeup_item_get_is_userspace (item))
+ cmdline = g_markup_escape_text (temp_ptr, -1);
+ else
+ cmdline = g_markup_printf_escaped ("<i>%s</i>", temp_ptr);
+ g_free (temp);
+
+ /* return */
+ return cmdline;
+}
+
+/**
+ * gpm_stats_format_details:
+ **/
+static gchar *
+gpm_stats_format_details (UpWakeupItem *item)
+{
+ gchar *details;
+ const gchar *data;
+
+ /* get this once to avoid a load of derefs */
+ data = up_wakeup_item_get_details (item);
+
+ /* replace common driver names */
+ if (g_strcmp0 (data, "i8042") == 0) {
+ /* TRANSLATORS: the keyboard and mouse device event */
+ details = g_strdup (_("PS/2 keyboard/mouse/touchpad"));
+ } else if (g_strcmp0 (data, "acpi") == 0) {
+ /* TRANSLATORS: ACPI, the Intel power standard on laptops and desktops */
+ details = g_strdup (_("ACPI"));
+ } else if (g_strcmp0 (data, "ata_piix") == 0) {
+ /* TRANSLATORS: serial ATA is a new style of hard disk interface */
+ details = g_strdup (_("Serial ATA"));
+ } else if (g_strcmp0 (data, "libata") == 0) {
+ /* TRANSLATORS: this is the old-style ATA interface */
+ details = g_strdup (_("ATA host controller"));
+ } else if (g_strcmp0 (data, "iwl3945") == 0 || g_strcmp0 (data, "iwlagn") == 0) {
+ /* TRANSLATORS: 802.11 wireless adaptor */
+ details = g_strdup (_("Intel wireless adaptor"));
+
+ /* try to make the wakeup type nicer */
+ } else if (g_str_has_prefix (data, "__mod_timer")) {
+ /* TRANSLATORS: a timer is something that fires periodically.
+ * The parameter is a process name, e.g. "firefox-bin".
+ * This is shown when the timer wakes up. */
+ details = g_strdup_printf (_("Timer %s"), data+12);
+ } else if (g_str_has_prefix (data, "mod_timer")) {
+ /* TRANSLATORS: a timer is something that fires periodically.
+ * The parameter is a process name, e.g. "firefox-bin".
+ * This is shown when the timer wakes up. */
+ details = g_strdup_printf (_("Timer %s"), data+10);
+ } else if (g_str_has_prefix (data, "hrtimer_start_expires")) {
+ /* TRANSLATORS: a timer is something that fires periodically.
+ * The parameter is a process name, e.g. "firefox-bin".
+ * This is shown when the timer wakes up. */
+ details = g_strdup_printf (_("Timer %s"), data+22);
+ } else if (g_str_has_prefix (data, "hrtimer_start")) {
+ /* TRANSLATORS: a timer is something that fires periodically.
+ * The parameter is a process name, e.g. "firefox-bin".
+ * This is shown when the timer wakes up. */
+ details = g_strdup_printf (_("Timer %s"), data+14);
+ } else if (g_str_has_prefix (data, "do_setitimer")) {
+ /* TRANSLATORS: a timer is something that fires periodically.
+ * The parameter is a process name, e.g. "firefox-bin".
+ * This is shown when the timer wakes up. */
+ details = g_strdup_printf (_("Timer %s"), data+10);
+ } else if (g_str_has_prefix (data, "do_nanosleep")) {
+ /* TRANSLATORS: the parameter is the name of task that's woken up from sleeping.
+ * This is shown when the task wakes up. */
+ details = g_strdup_printf (_("Sleep %s"), data+13);
+ } else if (g_str_has_prefix (data, "enqueue_task_rt")) {
+ /* TRANSLATORS: this is the name of a new realtime task. */
+ details = g_strdup_printf (_("New task %s"), data+16);
+ } else if (g_str_has_prefix (data, "futex_wait")) {
+ /* TRANSLATORS: this is the name of a task that's woken to check state.
+ * This is shown when the task wakes up. */
+ details = g_strdup_printf (_("Wait %s"), data+11);
+ } else if (g_str_has_prefix (data, "queue_delayed_work_on")) {
+ /* TRANSLATORS: this is the name of a work queue.
+ * A work queue is a list of work that has to be done. */
+ details = g_strdup_printf (_("Work queue %s"), data+22);
+ } else if (g_str_has_prefix (data, "queue_delayed_work")) {
+ /* TRANSLATORS: this is the name of a work queue.
+ * A work queue is a list of work that has to be done. */
+ details = g_strdup_printf (_("Work queue %s"), data+19);
+ } else if (g_str_has_prefix (data, "dst_run_gc")) {
+ /* TRANSLATORS: this is when the networking subsystem clears out old entries */
+ details = g_strdup_printf (_("Network route flush %s"), data+11);
+ } else if (g_str_has_prefix (data, "usb_hcd_poll_rh_status")) {
+ /* TRANSLATORS: this is the name of an activity on the USB bus */
+ details = g_strdup_printf (_("USB activity %s"), data+23);
+ } else if (g_str_has_prefix (data, "schedule_hrtimeout_range")) {
+ /* TRANSLATORS: we've timed out of an aligned timer, with the name */
+ details = g_strdup_printf (_("Wakeup %s"), data+25);
+ } else if (g_str_has_prefix (data, "Local timer interrupts")) {
+ /* TRANSLATORS: interupts on the system required for basic operation */
+ details = g_strdup (_("Local interrupts"));
+ } else if (g_str_has_prefix (data, "Rescheduling interrupts")) {
+ /* TRANSLATORS: interrupts when a task gets moved from one core to another */
+ details = g_strdup (_("Rescheduling interrupts"));
+ } else
+ details = g_markup_escape_text (data, -1);
+
+ return details;
+}
+/**
+ * gpm_stats_add_wakeups_item:
+ **/
+static void
+gpm_stats_add_wakeups_item (UpWakeupItem *item)
+{
+ const gchar *icon;
+ gchar *value;
+ gchar *id;
+ gchar *details;
+ gchar *cmdline;
+ GtkTreeIter iter;
+
+ if (up_wakeup_item_get_is_userspace (item)) {
+ icon = "application-x-executable";
+ id = g_strdup_printf ("%i", up_wakeup_item_get_id (item));
+ } else {
+ icon = "applications-system";
+ if (up_wakeup_item_get_id (item) < 0xff0)
+ id = g_strdup_printf ("IRQ%i", up_wakeup_item_get_id (item));
+ else
+ id = g_strdup ("IRQx");
+ }
+
+ /* formate value to one decimal place */
+ value = g_strdup_printf ("%.1f", up_wakeup_item_get_value (item));
+
+ /* get formatted lines */
+ cmdline = gpm_stats_format_cmdline (item);
+ details = gpm_stats_format_details (item);
+
+ gtk_list_store_append (list_store_wakeups, &iter);
+ gtk_list_store_set (list_store_wakeups, &iter,
+ GPM_WAKEUPS_COLUMN_ID, id,
+ GPM_WAKEUPS_COLUMN_VALUE, value,
+ GPM_WAKEUPS_COLUMN_CMDLINE, cmdline,
+ GPM_WAKEUPS_COLUMN_DETAILS, details,
+ GPM_WAKEUPS_COLUMN_ICON, icon, -1);
+ g_free (cmdline);
+ g_free (details);
+ g_free (value);
+ g_free (id);
+}
+
+/**
+ * gpm_stats_update_wakeups_data:
+ **/
+static void
+gpm_stats_update_wakeups_data (void)
+{
+ GtkWidget *widget;
+ GtkWidget *page_widget;
+ guint total;
+ UpWakeupItem *item;
+ gchar *text;
+ guint i;
+ GError *error = NULL;
+ GPtrArray *array;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "notebook1"));
+
+ /* hide other pages */
+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 0);
+ gtk_widget_hide (page_widget);
+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 1);
+ gtk_widget_hide (page_widget);
+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 2);
+ gtk_widget_hide (page_widget);
+
+ /* show wakeups page */
+ page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK(widget), 3);
+ gtk_widget_show (page_widget);
+
+ /* show total */
+ total = up_wakeups_get_total_sync (wakeups, NULL, &error);
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_total_wakeups"));
+ if (error == NULL) {
+ text = g_strdup_printf ("%i", total);
+ gtk_label_set_label (GTK_LABEL(widget), text);
+ g_free (text);
+ } else {
+ gtk_label_set_label (GTK_LABEL(widget), error->message);
+ g_error_free (error);
+ }
+
+ /* get data */
+ gtk_list_store_clear (list_store_wakeups);
+ array = up_wakeups_get_data_sync (wakeups, NULL, NULL);
+ if (array == NULL)
+ return;
+ for (i=0; i<array->len; i++) {
+ item = g_ptr_array_index (array, i);
+ gpm_stats_add_wakeups_item (item);
+ }
+ g_ptr_array_unref (array);
+}
+
+static void
+gpm_stats_set_title (GtkWindow *window, gint page_num)
+{
+ gchar *title;
+ const gchar * const page_titles[] = {
+ /* TRANSLATORS: shown on the titlebar */
+ N_("Device Information"),
+ /* TRANSLATORS: shown on the titlebar */
+ N_("Device History"),
+ /* TRANSLATORS: shown on the titlebar */
+ N_("Device Profile"),
+ /* TRANSLATORS: shown on the titlebar */
+ N_("Processor Wakeups")
+ };
+
+ /* TRANSLATORS: shown on the titlebar */
+ title = g_strdup_printf ("%s - %s", _("Power Statistics"), _(page_titles[page_num]));
+ gtk_window_set_title (window, title);
+ g_free (title);
+}
+
+/**
+ * gpm_stats_notebook_changed_cb:
+ **/
+static void
+gpm_stats_notebook_changed_cb (GtkNotebook *notebook, gpointer page, gint page_num, gpointer user_data)
+{
+ UpDevice *device;
+ GtkWidget *widget;
+
+ /* set the window title depending on the mode */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stats"));
+ gpm_stats_set_title (GTK_WINDOW (widget), page_num);
+
+ /* save page in mateconf */
+ mateconf_client_set_int (mateconf_client, GPM_CONF_INFO_PAGE_NUMBER, page_num, NULL);
+
+ if (current_device == NULL)
+ return;
+
+ if (g_strcmp0 (current_device, "wakeups") == 0)
+ return;
+
+ device = up_device_new ();
+ up_device_set_object_path_sync (device, current_device, NULL, NULL);
+ gpm_stats_update_info_data_page (device, page_num);
+ gpm_stats_update_info_data (device);
+ g_object_unref (device);
+}
+
+/**
+ * gpm_stats_button_update_ui:
+ **/
+static void
+gpm_stats_button_update_ui (void)
+{
+ UpDevice *device;
+ device = up_device_new ();
+ up_device_set_object_path_sync (device, current_device, NULL, NULL);
+ gpm_stats_update_info_data (device);
+ g_object_unref (device);
+}
+
+/**
+ * gpm_stats_devices_treeview_clicked_cb:
+ **/
+static void
+gpm_stats_devices_treeview_clicked_cb (GtkTreeSelection *selection, gboolean data)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ UpDevice *device;
+
+ /* This will only work in single or browse selection mode! */
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ g_free (current_device);
+ gtk_tree_model_get (model, &iter, GPM_DEVICES_COLUMN_ID, &current_device, -1);
+
+ /* save device in mateconf */
+ mateconf_client_set_string (mateconf_client, GPM_CONF_INFO_LAST_DEVICE, current_device, NULL);
+
+ /* show transaction_id */
+ egg_debug ("selected row is: %s", current_device);
+
+ /* is special device */
+ if (g_strcmp0 (current_device, "wakeups") == 0) {
+ gpm_stats_update_wakeups_data ();
+ } else {
+ device = up_device_new ();
+ up_device_set_object_path_sync (device, current_device, NULL, NULL);
+ gpm_stats_update_info_data (device);
+ g_object_unref (device);
+ }
+
+ } else {
+ egg_debug ("no row selected");
+ }
+}
+
+/**
+ * gpm_stats_window_activated_cb
+ **/
+static void
+gpm_stats_window_activated_cb (EggUnique *egg_unique, gpointer data)
+{
+ GtkWidget *widget;
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stats"));
+ gtk_window_present (GTK_WINDOW (widget));
+}
+
+/**
+ * gpm_stats_add_device:
+ **/
+static void
+gpm_stats_add_device (UpDevice *device)
+{
+ const gchar *id;
+ GtkTreeIter iter;
+ const gchar *text;
+ const gchar *icon;
+ UpDeviceKind kind;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ NULL);
+
+ id = up_device_get_object_path (device);
+ text = gpm_device_kind_to_localised_text (kind, 1);
+ icon = gpm_upower_get_device_icon (device);
+
+ gtk_list_store_append (list_store_devices, &iter);
+ gtk_list_store_set (list_store_devices, &iter,
+ GPM_DEVICES_COLUMN_ID, id,
+ GPM_DEVICES_COLUMN_TEXT, text,
+ GPM_DEVICES_COLUMN_ICON, icon, -1);
+}
+
+/**
+ * gpm_stats_data_changed_cb:
+ **/
+static void
+gpm_stats_data_changed_cb (UpClient *client, gpointer user_data)
+{
+ if (g_strcmp0 (current_device, "wakeups") == 0)
+ gpm_stats_update_wakeups_data ();
+}
+
+/**
+ * gpm_stats_device_added_cb:
+ **/
+static void
+gpm_stats_device_added_cb (UpClient *client, UpDevice *device, gpointer user_data)
+{
+ const gchar *object_path;
+ object_path = up_device_get_object_path (device);
+ egg_debug ("added: %s", object_path);
+ gpm_stats_add_device (device);
+}
+
+/**
+ * gpm_stats_device_changed_cb:
+ **/
+static void
+gpm_stats_device_changed_cb (UpClient *client, UpDevice *device, gpointer user_data)
+{
+ const gchar *object_path;
+ object_path = up_device_get_object_path (device);
+ if (object_path == NULL || current_device == NULL)
+ return;
+ egg_debug ("changed: %s", object_path);
+ if (g_strcmp0 (current_device, object_path) == 0)
+ gpm_stats_update_info_data (device);
+}
+
+/**
+ * gpm_stats_device_removed_cb:
+ **/
+static void
+gpm_stats_device_removed_cb (UpClient *client, UpDevice *device, gpointer user_data)
+{
+ const gchar *object_path;
+ GtkTreeIter iter;
+ gchar *id = NULL;
+ gboolean ret;
+
+ object_path = up_device_get_object_path (device);
+ egg_debug ("removed: %s", object_path);
+ if (g_strcmp0 (current_device, object_path) == 0) {
+ gtk_list_store_clear (list_store_info);
+ }
+
+ /* search the list and remove the object path entry */
+ ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store_devices), &iter);
+ while (ret) {
+ gtk_tree_model_get (GTK_TREE_MODEL (list_store_devices), &iter, GPM_DEVICES_COLUMN_ID, &id, -1);
+ if (g_strcmp0 (id, object_path) == 0) {
+ gtk_list_store_remove (list_store_devices, &iter);
+ break;
+ }
+ g_free (id);
+ ret = gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store_devices), &iter);
+ };
+}
+
+/**
+ * gpm_stats_history_type_combo_changed_cb:
+ **/
+static void
+gpm_stats_history_type_combo_changed_cb (GtkWidget *widget, gpointer data)
+{
+ gchar *value;
+ const gchar *axis_x = NULL;
+ const gchar *axis_y = NULL;
+ value = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
+ if (g_strcmp0 (value, GPM_HISTORY_RATE_TEXT) == 0) {
+ history_type = GPM_HISTORY_RATE_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph */
+ axis_x = _("Time elapsed");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Power");
+ } else if (g_strcmp0 (value, GPM_HISTORY_CHARGE_TEXT) == 0) {
+ history_type = GPM_HISTORY_CHARGE_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph */
+ axis_x = _("Time elapsed");
+ /* TRANSLATORS: this is the Y axis on the graph for the whole battery device */
+ axis_y = _("Cell charge");
+ } else if (g_strcmp0 (value, GPM_HISTORY_TIME_FULL_TEXT) == 0) {
+ history_type = GPM_HISTORY_TIME_FULL_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph */
+ axis_x = _("Time elapsed");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Predicted time");
+ } else if (g_strcmp0 (value, GPM_HISTORY_TIME_EMPTY_TEXT) == 0) {
+ history_type = GPM_HISTORY_TIME_EMPTY_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph */
+ axis_x = _("Time elapsed");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Predicted time");
+ } else {
+ g_assert (FALSE);
+ }
+
+ /* set axis */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_history_x"));
+ gtk_label_set_label (GTK_LABEL(widget), axis_x);
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_history_y"));
+ gtk_label_set_label (GTK_LABEL(widget), axis_y);
+
+ gpm_stats_button_update_ui ();
+ g_free (value);
+
+ /* save to mateconf */
+ mateconf_client_set_string (mateconf_client, GPM_CONF_INFO_HISTORY_TYPE, history_type, NULL);
+}
+
+/**
+ * gpm_stats_type_combo_changed_cb:
+ **/
+static void
+gpm_stats_type_combo_changed_cb (GtkWidget *widget, gpointer data)
+{
+ gchar *value;
+ const gchar *axis_x = NULL;
+ const gchar *axis_y = NULL;
+ value = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
+ if (g_strcmp0 (value, GPM_STATS_CHARGE_DATA_TEXT) == 0) {
+ stats_type = GPM_STATS_CHARGE_DATA_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
+ axis_x = _("Cell charge");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Correction factor");
+ } else if (g_strcmp0 (value, GPM_STATS_CHARGE_ACCURACY_TEXT) == 0) {
+ stats_type = GPM_STATS_CHARGE_ACCURACY_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
+ axis_x = _("Cell charge");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Prediction accuracy");
+ } else if (g_strcmp0 (value, GPM_STATS_DISCHARGE_DATA_TEXT) == 0) {
+ stats_type = GPM_STATS_DISCHARGE_DATA_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
+ axis_x = _("Cell charge");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Correction factor");
+ } else if (g_strcmp0 (value, GPM_STATS_DISCHARGE_ACCURACY_TEXT) == 0) {
+ stats_type = GPM_STATS_DISCHARGE_ACCURACY_VALUE;
+ /* TRANSLATORS: this is the X axis on the graph for the whole battery device */
+ axis_x = _("Cell charge");
+ /* TRANSLATORS: this is the Y axis on the graph */
+ axis_y = _("Prediction accuracy");
+ } else {
+ g_assert (FALSE);
+ }
+
+ /* set axis */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_stats_x"));
+ gtk_label_set_label (GTK_LABEL(widget), axis_x);
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "label_axis_stats_y"));
+ gtk_label_set_label (GTK_LABEL(widget), axis_y);
+
+ gpm_stats_button_update_ui ();
+ g_free (value);
+
+ /* save to mateconf */
+ mateconf_client_set_string (mateconf_client, GPM_CONF_INFO_STATS_TYPE, stats_type, NULL);
+}
+
+/**
+ * gpm_stats_range_combo_changed:
+ **/
+static void
+gpm_stats_range_combo_changed (GtkWidget *widget, gpointer data)
+{
+ gchar *value;
+ value = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget));
+ if (g_strcmp0 (value, GPM_HISTORY_MINUTE_TEXT) == 0)
+ history_time = GPM_HISTORY_MINUTE_VALUE;
+ else if (g_strcmp0 (value, GPM_HISTORY_HOUR_TEXT) == 0)
+ history_time = GPM_HISTORY_HOUR_VALUE;
+ else if (g_strcmp0 (value, GPM_HISTORY_HOURS_TEXT) == 0)
+ history_time = GPM_HISTORY_HOURS_VALUE;
+ else if (g_strcmp0 (value, GPM_HISTORY_DAY_TEXT) == 0)
+ history_time = GPM_HISTORY_DAY_VALUE;
+ else if (g_strcmp0 (value, GPM_HISTORY_WEEK_TEXT) == 0)
+ history_time = GPM_HISTORY_WEEK_VALUE;
+ else
+ g_assert (FALSE);
+
+ /* save to mateconf */
+ mateconf_client_set_int (mateconf_client, GPM_CONF_INFO_HISTORY_TIME, history_time, NULL);
+
+ gpm_stats_button_update_ui ();
+ g_free (value);
+}
+
+/**
+ * gpm_stats_smooth_checkbox_history_cb:
+ * @widget: The GtkWidget object
+ **/
+static void
+gpm_stats_smooth_checkbox_history_cb (GtkWidget *widget, gpointer data)
+{
+ gboolean checked;
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ mateconf_client_set_bool (mateconf_client, GPM_CONF_INFO_HISTORY_GRAPH_SMOOTH, checked, NULL);
+ gpm_stats_button_update_ui ();
+}
+
+/**
+ * gpm_stats_smooth_checkbox_stats_cb:
+ * @widget: The GtkWidget object
+ **/
+static void
+gpm_stats_smooth_checkbox_stats_cb (GtkWidget *widget, gpointer data)
+{
+ gboolean checked;
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ mateconf_client_set_bool (mateconf_client, GPM_CONF_INFO_STATS_GRAPH_SMOOTH, checked, NULL);
+ gpm_stats_button_update_ui ();
+}
+
+/**
+ * gpm_stats_points_checkbox_history_cb:
+ * @widget: The GtkWidget object
+ **/
+static void
+gpm_stats_points_checkbox_history_cb (GtkWidget *widget, gpointer data)
+{
+ gboolean checked;
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ mateconf_client_set_bool (mateconf_client, GPM_CONF_INFO_HISTORY_GRAPH_POINTS, checked, NULL);
+ gpm_stats_button_update_ui ();
+}
+
+/**
+ * gpm_stats_points_checkbox_stats_cb:
+ * @widget: The GtkWidget object
+ **/
+static void
+gpm_stats_points_checkbox_stats_cb (GtkWidget *widget, gpointer data)
+{
+ gboolean checked;
+ checked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ mateconf_client_set_bool (mateconf_client, GPM_CONF_INFO_STATS_GRAPH_POINTS, checked, NULL);
+ gpm_stats_button_update_ui ();
+}
+
+/**
+ * gpm_stats_set_combo_simple_text:
+ **/
+static void
+gpm_stats_set_combo_simple_text (GtkWidget *combo_box)
+{
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
+ "text", 0,
+ NULL);
+}
+
+/**
+ * gpm_stats_highlight_device:
+ **/
+static void
+gpm_stats_highlight_device (const gchar *object_path)
+{
+ gboolean ret;
+ gchar *id = NULL;
+ gchar *path_str;
+ guint i;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkWidget *widget;
+
+ /* check valid */
+ if (!g_str_has_prefix (object_path, "/"))
+ return;
+
+ /* we have to reuse the treeview data as it may be sorted */
+ ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store_devices), &iter);
+ for (i=0; ret; i++) {
+ gtk_tree_model_get (GTK_TREE_MODEL (list_store_devices), &iter,
+ GPM_DEVICES_COLUMN_ID, &id,
+ -1);
+ if (g_strcmp0 (id, object_path) == 0) {
+ path_str = g_strdup_printf ("%i", i);
+ path = gtk_tree_path_new_from_string (path_str);
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_devices"));
+ gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (widget), path, NULL, NULL, FALSE);
+ g_free (path_str);
+ gtk_tree_path_free (path);
+ }
+ g_free (id);
+ ret = gtk_tree_model_iter_next (GTK_TREE_MODEL (list_store_devices), &iter);
+ }
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ GtkBox *box;
+ GtkWidget *widget;
+ GtkTreeSelection *selection;
+ EggUnique *egg_unique;
+ gboolean ret;
+ UpClient *client;
+ GPtrArray *devices;
+ UpDevice *device;
+ UpDeviceKind kind;
+ guint i, j;
+ gint page;
+ gboolean checked;
+ gchar *last_device = NULL;
+ guint retval;
+ GError *error = NULL;
+
+ const GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+ /* TRANSLATORS: show verbose debugging */
+ N_("Show extra debugging information"), NULL },
+ { "device", '\0', 0, G_OPTION_ARG_STRING, &last_device,
+ /* TRANSLATORS: show a device by default */
+ N_("Select this device at startup"), NULL },
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+
+ bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ if (! g_thread_supported ())
+ g_thread_init (NULL);
+ dbus_g_thread_init ();
+ g_type_init ();
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: the program name */
+ g_option_context_set_summary (context, _("Power Statistics"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ egg_debug_init (verbose);
+ gtk_init (&argc, &argv);
+
+ /* are we already activated? */
+ egg_unique = egg_unique_new ();
+ ret = egg_unique_assign (egg_unique, "org.mate.PowerManager.Statistics");
+ if (!ret)
+ goto unique_out;
+ g_signal_connect (egg_unique, "activated",
+ G_CALLBACK (gpm_stats_window_activated_cb), NULL);
+
+ /* add application specific icons to search path */
+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
+ GPM_DATA G_DIR_SEPARATOR_S "icons");
+
+ /* get data from mateconf */
+ mateconf_client = mateconf_client_get_default ();
+
+ /* get UI */
+ builder = gtk_builder_new ();
+ retval = gtk_builder_add_from_file (builder, GPM_DATA "/gpm-statistics.ui", &error);
+ if (retval == 0) {
+ egg_warning ("failed to load ui: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* add history graph */
+ box = GTK_BOX (gtk_builder_get_object (builder, "hbox_history"));
+ graph_history = gpm_graph_widget_new ();
+ gtk_box_pack_start (box, graph_history, TRUE, TRUE, 0);
+ gtk_widget_set_size_request (graph_history, 400, 250);
+ gtk_widget_show (graph_history);
+
+ /* add statistics graph */
+ box = GTK_BOX (gtk_builder_get_object (builder, "hbox_statistics"));
+ graph_statistics = gpm_graph_widget_new ();
+ gtk_box_pack_start (box, graph_statistics, TRUE, TRUE, 0);
+ gtk_widget_set_size_request (graph_statistics, 400, 250);
+ gtk_widget_show (graph_statistics);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stats"));
+ gtk_window_set_default_size (GTK_WINDOW(widget), 800, 500);
+ gtk_window_set_default_icon_name (GPM_STOCK_APP_ICON);
+
+ /* Get the main window quit */
+ g_signal_connect_swapped (widget, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
+ g_signal_connect_swapped (widget, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_grab_default (widget);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_help"));
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_stats_button_help_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_history"));
+ checked = mateconf_client_get_bool (mateconf_client, GPM_CONF_INFO_HISTORY_GRAPH_SMOOTH, NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_stats_smooth_checkbox_history_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_smooth_stats"));
+ checked = mateconf_client_get_bool (mateconf_client, GPM_CONF_INFO_STATS_GRAPH_SMOOTH, NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_stats_smooth_checkbox_stats_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_history"));
+ checked = mateconf_client_get_bool (mateconf_client, GPM_CONF_INFO_HISTORY_GRAPH_POINTS, NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_stats_points_checkbox_history_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "checkbutton_points_stats"));
+ checked = mateconf_client_get_bool (mateconf_client, GPM_CONF_INFO_STATS_GRAPH_POINTS, NULL);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), checked);
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (gpm_stats_points_checkbox_stats_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "notebook1"));
+ page = mateconf_client_get_int (mateconf_client, GPM_CONF_INFO_PAGE_NUMBER, NULL);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), page);
+ g_signal_connect (widget, "switch-page",
+ G_CALLBACK (gpm_stats_notebook_changed_cb), NULL);
+
+ /* create list stores */
+ list_store_info = gtk_list_store_new (GPM_INFO_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING);
+ list_store_devices = gtk_list_store_new (GPM_DEVICES_COLUMN_LAST, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING);
+ list_store_wakeups = gtk_list_store_new (GPM_WAKEUPS_COLUMN_LAST, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /* create transaction_id tree view */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_info"));
+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+ GTK_TREE_MODEL (list_store_info));
+
+ /* add columns to the tree view */
+ gpm_stats_add_info_columns (GTK_TREE_VIEW (widget));
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); /* show */
+
+ /* create transaction_id tree view */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_devices"));
+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+ GTK_TREE_MODEL (list_store_devices));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (gpm_stats_devices_treeview_clicked_cb), NULL);
+
+ /* add columns to the tree view */
+ gpm_stats_add_devices_columns (GTK_TREE_VIEW (widget));
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); /* show */
+
+ /* create wakeups tree view */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_wakeups"));
+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+ GTK_TREE_MODEL (list_store_wakeups));
+
+ /* add columns to the tree view */
+ gpm_stats_add_wakeups_columns (GTK_TREE_VIEW (widget));
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget)); /* show */
+
+ history_type = mateconf_client_get_string (mateconf_client, GPM_CONF_INFO_HISTORY_TYPE, NULL);
+ history_time = mateconf_client_get_int (mateconf_client, GPM_CONF_INFO_HISTORY_TIME, NULL);
+ if (history_type == NULL)
+ history_type = GPM_HISTORY_CHARGE_VALUE;
+ if (history_time == 0)
+ history_time = GPM_HISTORY_HOUR_VALUE;
+
+ stats_type = mateconf_client_get_string (mateconf_client, GPM_CONF_INFO_STATS_TYPE, NULL);
+ if (stats_type == NULL)
+ stats_type = GPM_STATS_CHARGE_DATA_VALUE;
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_history_type"));
+ gpm_stats_set_combo_simple_text (widget);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_RATE_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_CHARGE_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_TIME_FULL_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_TIME_EMPTY_TEXT);
+ if (g_strcmp0 (history_type, GPM_HISTORY_RATE_VALUE) == 0)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (gpm_stats_history_type_combo_changed_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_stats_type"));
+ gpm_stats_set_combo_simple_text (widget);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_STATS_CHARGE_DATA_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_STATS_CHARGE_ACCURACY_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_STATS_DISCHARGE_DATA_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_STATS_DISCHARGE_ACCURACY_TEXT);
+ if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+ else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
+ else if (g_strcmp0 (stats_type, GPM_STATS_CHARGE_DATA_VALUE) == 0)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (gpm_stats_type_combo_changed_cb), NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_history_time"));
+ gpm_stats_set_combo_simple_text (widget);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_MINUTE_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_HOUR_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_HOURS_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_DAY_TEXT);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), GPM_HISTORY_WEEK_TEXT);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+ if (history_time == GPM_HISTORY_MINUTE_VALUE)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
+ else if (history_time == GPM_HISTORY_HOUR_VALUE)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (gpm_stats_range_combo_changed), NULL);
+
+ client = up_client_new ();
+
+ wakeups = up_wakeups_new ();
+ g_signal_connect (wakeups, "data-changed", G_CALLBACK (gpm_stats_data_changed_cb), NULL);
+
+ /* coldplug */
+ ret = up_client_enumerate_devices_sync (client, NULL, NULL);
+ if (!ret)
+ goto out;
+ devices = up_client_get_devices (client);
+
+ /* add devices in visually pleasing order */
+ for (j=0; j<UP_DEVICE_KIND_LAST; j++) {
+ for (i=0; i < devices->len; i++) {
+ device = g_ptr_array_index (devices, i);
+ g_object_get (device, "kind", &kind, NULL);
+ if (kind == j)
+ gpm_stats_add_device (device);
+ }
+ }
+
+ /* connect now the coldplug is done */
+ g_signal_connect (client, "device-added", G_CALLBACK (gpm_stats_device_added_cb), NULL);
+ g_signal_connect (client, "device-removed", G_CALLBACK (gpm_stats_device_removed_cb), NULL);
+ g_signal_connect (client, "device-changed", G_CALLBACK (gpm_stats_device_changed_cb), NULL);
+
+ /* set current device */
+ if (devices->len > 0) {
+ device = g_ptr_array_index (devices, 0);
+ gpm_stats_update_info_data (device);
+ current_device = g_strdup (up_device_get_object_path (device));
+ }
+
+ if (last_device == NULL)
+ last_device = mateconf_client_get_string (mateconf_client, GPM_CONF_INFO_LAST_DEVICE, NULL);
+
+ /* has capability to measure wakeups */
+ ret = up_wakeups_get_has_capability (wakeups);
+ if (ret) {
+ GtkTreeIter iter;
+ gtk_list_store_append (list_store_devices, &iter);
+ gtk_list_store_set (list_store_devices, &iter,
+ GPM_DEVICES_COLUMN_ID, "wakeups",
+ /* TRANSLATORS: the icon for the CPU */
+ GPM_DEVICES_COLUMN_TEXT, _("Processor"),
+ GPM_DEVICES_COLUMN_ICON, "computer", -1);
+ }
+
+ /* set the correct focus on the last device */
+ if (last_device != NULL)
+ gpm_stats_highlight_device (last_device);
+
+ g_ptr_array_unref (devices);
+
+ /* set axis */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_history_type"));
+ gpm_stats_history_type_combo_changed_cb (widget, NULL);
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_stats_type"));
+ gpm_stats_type_combo_changed_cb (widget, NULL);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_stats"));
+ gtk_widget_show (widget);
+
+ gtk_main ();
+
+out:
+ g_object_unref (mateconf_client);
+ g_object_unref (client);
+ g_object_unref (wakeups);
+ g_object_unref (builder);
+ g_object_unref (list_store_info);
+unique_out:
+ g_object_unref (egg_unique);
+ g_free (last_device);
+ return 0;
+}
diff --git a/src/gpm-stock-icons.h b/src/gpm-stock-icons.h
new file mode 100644
index 0000000..395d612
--- /dev/null
+++ b/src/gpm-stock-icons.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2002 Jorn Baayen
+ * Copyright (C) 2003,2004 Colin Walters <[email protected]>
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_STOCK_ICONS_H
+#define __GPM_STOCK_ICONS_H
+
+G_BEGIN_DECLS
+
+#define GPM_STOCK_APP_ICON "mate-power-manager"
+#define GPM_STOCK_AC_ADAPTER "gpm-ac-adapter"
+#define GPM_STOCK_BATTERY_CHARGED "gpm-primary-charged"
+#define GPM_STOCK_HIBERNATE "gpm-hibernate"
+#define GPM_STOCK_SUSPEND "gpm-suspend"
+#define GPM_STOCK_STATISTICS "mate-power-statistics"
+#define GPM_STOCK_BRIGHTNESS_LCD "gpm-brightness-lcd"
+#define GPM_STOCK_BRIGHTNESS_KBD "gpm-brightness-kbd"
+#define GPM_STOCK_INHIBIT "gpm-inhibit"
+
+G_END_DECLS
+
+#endif /* __GPM_STOCK_ICONS_H */
diff --git a/src/gpm-tray-icon.c b/src/gpm-tray-icon.c
new file mode 100644
index 0000000..8edddce
--- /dev/null
+++ b/src/gpm-tray-icon.c
@@ -0,0 +1,430 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2009 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <mateconf/mateconf-client.h>
+#include <libupower-glib/upower.h>
+
+#include "egg-debug.h"
+
+#include "gpm-upower.h"
+#include "gpm-engine.h"
+#include "gpm-common.h"
+#include "gpm-stock-icons.h"
+#include "gpm-tray-icon.h"
+
+static void gpm_tray_icon_finalize (GObject *object);
+
+#define GPM_TRAY_ICON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_TRAY_ICON, GpmTrayIconPrivate))
+
+struct GpmTrayIconPrivate
+{
+ MateConfClient *conf;
+ GpmEngine *engine;
+ GtkStatusIcon *status_icon;
+ gboolean show_actions;
+};
+
+G_DEFINE_TYPE (GpmTrayIcon, gpm_tray_icon, G_TYPE_OBJECT)
+
+/**
+ * gpm_tray_icon_enable_actions:
+ **/
+static void
+gpm_tray_icon_enable_actions (GpmTrayIcon *icon, gboolean enabled)
+{
+ g_return_if_fail (GPM_IS_TRAY_ICON (icon));
+ icon->priv->show_actions = enabled;
+}
+
+/**
+ * gpm_tray_icon_show:
+ * @enabled: If we should show the tray
+ **/
+static void
+gpm_tray_icon_show (GpmTrayIcon *icon, gboolean enabled)
+{
+ g_return_if_fail (GPM_IS_TRAY_ICON (icon));
+ gtk_status_icon_set_visible (icon->priv->status_icon, enabled);
+}
+
+/**
+ * gpm_tray_icon_set_tooltip:
+ * @tooltip: The tooltip text, e.g. "Batteries charged"
+ **/
+gboolean
+gpm_tray_icon_set_tooltip (GpmTrayIcon *icon, const gchar *tooltip)
+{
+ g_return_val_if_fail (icon != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), FALSE);
+ g_return_val_if_fail (tooltip != NULL, FALSE);
+
+#if GTK_CHECK_VERSION(2,15,0)
+ gtk_status_icon_set_tooltip_text (icon->priv->status_icon, tooltip);
+#else
+ gtk_status_icon_set_tooltip (icon->priv->status_icon, tooltip);
+#endif
+ return TRUE;
+}
+
+/**
+ * gpm_tray_icon_get_status_icon:
+ **/
+GtkStatusIcon *
+gpm_tray_icon_get_status_icon (GpmTrayIcon *icon)
+{
+ g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), NULL);
+ return g_object_ref (icon->priv->status_icon);
+}
+
+/**
+ * gpm_tray_icon_set_image_from_stock:
+ * @filename: The icon name, e.g. GPM_STOCK_APP_ICON, or NULL to remove.
+ *
+ * Loads a pixmap from disk, and sets as the tooltip icon
+ **/
+gboolean
+gpm_tray_icon_set_icon (GpmTrayIcon *icon, const gchar *filename)
+{
+ g_return_val_if_fail (icon != NULL, FALSE);
+ g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), FALSE);
+
+ if (filename != NULL) {
+ egg_debug ("Setting icon to %s", filename);
+ gtk_status_icon_set_from_icon_name (icon->priv->status_icon, filename);
+
+ /* make sure that we are visible */
+ gpm_tray_icon_show (icon, TRUE);
+ } else {
+ /* remove icon */
+ egg_debug ("no icon will be displayed");
+
+ /* make sure that we are hidden */
+ gpm_tray_icon_show (icon, FALSE);
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_tray_icon_show_info_cb:
+ **/
+static void
+gpm_tray_icon_show_info_cb (GtkMenuItem *item, gpointer data)
+{
+ gchar *path;
+ const gchar *object_path;
+
+ object_path = g_object_get_data (G_OBJECT (item), "object-path");
+ path = g_strdup_printf ("%s/mate-power-statistics --device %s", BINDIR, object_path);
+ if (!g_spawn_command_line_async (path, NULL))
+ egg_warning ("Couldn't execute command: %s", path);
+ g_free (path);
+}
+
+/**
+ * gpm_tray_icon_show_preferences_cb:
+ * @action: A valid GtkAction
+ **/
+static void
+gpm_tray_icon_show_preferences_cb (GtkMenuItem *item, gpointer data)
+{
+ const gchar *command = "mate-power-preferences";
+
+ if (g_spawn_command_line_async (command, NULL) == FALSE)
+ egg_warning ("Couldn't execute command: %s", command);
+}
+
+/**
+ * gpm_tray_icon_popup_cleared_cd:
+ * @widget: The popup Gtkwidget
+ *
+ * We have to re-enable the tooltip when the popup is removed
+ **/
+static void
+gpm_tray_icon_popup_cleared_cd (GtkWidget *widget, GpmTrayIcon *icon)
+{
+ g_return_if_fail (GPM_IS_TRAY_ICON (icon));
+ egg_debug ("clear tray");
+ g_object_ref_sink (widget);
+ g_object_unref (widget);
+}
+
+/**
+ * gpm_tray_icon_class_init:
+ **/
+static void
+gpm_tray_icon_class_init (GpmTrayIconClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gpm_tray_icon_finalize;
+ g_type_class_add_private (klass, sizeof (GpmTrayIconPrivate));
+}
+
+/**
+ * gpm_tray_icon_add_device:
+ **/
+static guint
+gpm_tray_icon_add_device (GpmTrayIcon *icon, GtkMenu *menu, const GPtrArray *array, UpDeviceKind kind)
+{
+ guint i;
+ guint added = 0;
+ gchar *icon_name;
+ gchar *label;
+ GtkWidget *item;
+ GtkWidget *image;
+ const gchar *object_path;
+ const gchar *desc;
+ UpDevice *device;
+ UpDeviceKind kind_tmp;
+ gdouble percentage;
+
+ /* find type */
+ for (i=0;i<array->len;i++) {
+ device = g_ptr_array_index (array, i);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind_tmp,
+ "percentage", &percentage,
+ NULL);
+
+ if (kind != kind_tmp)
+ continue;
+
+ object_path = up_device_get_object_path (device);
+ egg_debug ("adding device %s", object_path);
+ added++;
+
+ /* generate the label */
+ desc = gpm_device_kind_to_localised_text (kind, 1);
+ label = g_strdup_printf ("%s (%.1f%%)", desc, percentage);
+ item = gtk_image_menu_item_new_with_label (label);
+
+ /* generate the image */
+ icon_name = gpm_upower_get_device_icon (device);
+ image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+ gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (item), TRUE);
+
+ /* callback and add the the menu */
+ g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (gpm_tray_icon_show_info_cb), icon);
+ g_object_set_data (G_OBJECT (item), "object-path", (gpointer) object_path);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+ g_free (icon_name);
+ g_free (label);
+ }
+ return added;
+}
+
+/**
+ * gpm_tray_icon_create_menu:
+ *
+ * Display the popup menu.
+ **/
+static void
+gpm_tray_icon_create_menu (GpmTrayIcon *icon, guint32 timestamp)
+{
+ GtkMenu *menu = (GtkMenu*) gtk_menu_new ();
+ GtkWidget *item;
+ GtkWidget *image;
+ guint dev_cnt = 0;
+ GPtrArray *array;
+
+ /* add all device types to the drop down menu */
+ array = gpm_engine_get_devices (icon->priv->engine);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_BATTERY);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_UPS);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_MOUSE);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_KEYBOARD);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_PDA);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_PHONE);
+#if UP_CHECK_VERSION(0,9,5)
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_MEDIA_PLAYER);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_TABLET);
+ dev_cnt += gpm_tray_icon_add_device (icon, menu, array, UP_DEVICE_KIND_COMPUTER);
+#endif
+ g_ptr_array_unref (array);
+
+ /* skip for things like live-cd's and GDM */
+ if (!icon->priv->show_actions)
+ goto skip_prefs;
+
+ /* only do the seporator if we have at least one device */
+ if (dev_cnt != 0) {
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ }
+
+ /* preferences */
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Preferences"));
+ 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 (gpm_tray_icon_show_preferences_cb), icon);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+
+skip_prefs:
+ /* show the menu */
+ gtk_widget_show_all (GTK_WIDGET (menu));
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
+ gtk_status_icon_position_menu, icon->priv->status_icon,
+ 1, timestamp);
+
+ g_signal_connect (GTK_WIDGET (menu), "hide",
+ G_CALLBACK (gpm_tray_icon_popup_cleared_cd), icon);
+}
+
+/**
+ * gpm_tray_icon_popup_menu_cb:
+ *
+ * Display the popup menu.
+ **/
+static void
+gpm_tray_icon_popup_menu_cb (GtkStatusIcon *status_icon, guint button, guint32 timestamp, GpmTrayIcon *icon)
+{
+ egg_debug ("icon right clicked");
+ gpm_tray_icon_create_menu (icon, timestamp);
+}
+
+
+/**
+ * gpm_tray_icon_activate_cb:
+ * @button: Which buttons are pressed
+ *
+ * Callback when the icon is clicked
+ **/
+static void
+gpm_tray_icon_activate_cb (GtkStatusIcon *status_icon, GpmTrayIcon *icon)
+{
+ egg_debug ("icon left clicked");
+ gpm_tray_icon_create_menu (icon, gtk_get_current_event_time());
+}
+
+/**
+ * gpm_conf_mateconf_key_changed_cb:
+ *
+ * We might have to do things when the mateconf keys change; do them here.
+ **/
+static void
+gpm_conf_mateconf_key_changed_cb (MateConfClient *client, guint cnxn_id, MateConfEntry *entry, GpmTrayIcon *icon)
+{
+ MateConfValue *value;
+ gboolean allowed_in_menu;
+
+ value = mateconf_entry_get_value (entry);
+ if (value == NULL)
+ return;
+
+ if (strcmp (entry->key, GPM_CONF_UI_SHOW_ACTIONS) == 0) {
+ allowed_in_menu = mateconf_value_get_bool (value);
+ gpm_tray_icon_enable_actions (icon, allowed_in_menu);
+ }
+}
+
+/**
+ * gpm_tray_icon_init:
+ *
+ * Initialise the tray object
+ **/
+static void
+gpm_tray_icon_init (GpmTrayIcon *icon)
+{
+ gboolean allowed_in_menu;
+
+ icon->priv = GPM_TRAY_ICON_GET_PRIVATE (icon);
+
+ icon->priv->engine = gpm_engine_new ();
+
+ icon->priv->conf = mateconf_client_get_default ();
+ /* watch mate-power-manager keys */
+ mateconf_client_add_dir (icon->priv->conf, GPM_CONF_DIR,
+ MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+ mateconf_client_notify_add (icon->priv->conf, GPM_CONF_DIR,
+ (MateConfClientNotifyFunc) gpm_conf_mateconf_key_changed_cb,
+ icon, NULL, NULL);
+
+ icon->priv->status_icon = gtk_status_icon_new ();
+ g_signal_connect_object (G_OBJECT (icon->priv->status_icon),
+ "popup_menu",
+ G_CALLBACK (gpm_tray_icon_popup_menu_cb),
+ icon, 0);
+ g_signal_connect_object (G_OBJECT (icon->priv->status_icon),
+ "activate",
+ G_CALLBACK (gpm_tray_icon_activate_cb),
+ icon, 0);
+
+ allowed_in_menu = mateconf_client_get_bool (icon->priv->conf, GPM_CONF_UI_SHOW_ACTIONS, NULL);
+ gpm_tray_icon_enable_actions (icon, allowed_in_menu);
+}
+
+/**
+ * gpm_tray_icon_finalize:
+ * @object: This TrayIcon class instance
+ **/
+static void
+gpm_tray_icon_finalize (GObject *object)
+{
+ GpmTrayIcon *tray_icon;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPM_IS_TRAY_ICON (object));
+
+ tray_icon = GPM_TRAY_ICON (object);
+
+ g_object_unref (tray_icon->priv->status_icon);
+ g_object_unref (tray_icon->priv->engine);
+ g_return_if_fail (tray_icon->priv != NULL);
+
+ G_OBJECT_CLASS (gpm_tray_icon_parent_class)->finalize (object);
+}
+
+/**
+ * gpm_tray_icon_new:
+ * Return value: A new TrayIcon object.
+ **/
+GpmTrayIcon *
+gpm_tray_icon_new (void)
+{
+ GpmTrayIcon *tray_icon;
+ tray_icon = g_object_new (GPM_TYPE_TRAY_ICON, NULL);
+ return GPM_TRAY_ICON (tray_icon);
+}
+
diff --git a/src/gpm-tray-icon.h b/src/gpm-tray-icon.h
new file mode 100644
index 0000000..5ff828f
--- /dev/null
+++ b/src/gpm-tray-icon.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <[email protected]>
+ * Copyright (C) 2005-2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_TRAY_ICON_H
+#define __GPM_TRAY_ICON_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPM_TYPE_TRAY_ICON (gpm_tray_icon_get_type ())
+#define GPM_TRAY_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPM_TYPE_TRAY_ICON, GpmTrayIcon))
+#define GPM_TRAY_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPM_TYPE_TRAY_ICON, GpmTrayIconClass))
+#define GPM_IS_TRAY_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPM_TYPE_TRAY_ICON))
+#define GPM_IS_TRAY_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPM_TYPE_TRAY_ICON))
+#define GPM_TRAY_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPM_TYPE_TRAY_ICON, GpmTrayIconClass))
+
+typedef struct GpmTrayIconPrivate GpmTrayIconPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpmTrayIconPrivate *priv;
+} GpmTrayIcon;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* suspend) (GpmTrayIcon *tray_icon);
+ void (* hibernate) (GpmTrayIcon *tray_icon);
+} GpmTrayIconClass;
+
+GType gpm_tray_icon_get_type (void);
+GpmTrayIcon *gpm_tray_icon_new (void);
+
+gboolean gpm_tray_icon_set_tooltip (GpmTrayIcon *icon,
+ const gchar *tooltip);
+gboolean gpm_tray_icon_set_icon (GpmTrayIcon *icon,
+ const gchar *filename);
+GtkStatusIcon *gpm_tray_icon_get_status_icon (GpmTrayIcon *icon);
+
+G_END_DECLS
+
+#endif /* __GPM_TRAY_ICON_H */
diff --git a/src/gpm-upower.c b/src/gpm-upower.c
new file mode 100644
index 0000000..f659c51
--- /dev/null
+++ b/src/gpm-upower.c
@@ -0,0 +1,661 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <libupower-glib/upower.h>
+
+#include "egg-debug.h"
+#include "egg-precision.h"
+
+#include "gpm-upower.h"
+#include "gpm-common.h"
+
+#define GPM_UP_TIME_PRECISION 5*60
+#define GPM_UP_TEXT_MIN_TIME 120
+
+/**
+ * gpm_upower_get_device_icon_index:
+ * @percent: The charge of the device
+ *
+ * The index value depends on the percentage charge:
+ * 00-10 = 000
+ * 10-30 = 020
+ * 30-50 = 040
+ * 50-70 = 060
+ * 70-90 = 080
+ * 90-100 = 100
+ *
+ * Return value: The character string for the filename suffix.
+ **/
+static const gchar *
+gpm_upower_get_device_icon_index (UpDevice *device)
+{
+ gdouble percentage;
+ /* get device properties */
+ g_object_get (device, "percentage", &percentage, NULL);
+ if (percentage < 10)
+ return "000";
+ else if (percentage < 30)
+ return "020";
+ else if (percentage < 50)
+ return "040";
+ else if (percentage < 70)
+ return "060";
+ else if (percentage < 90)
+ return "080";
+ return "100";
+}
+
+/**
+ * gpm_upower_get_device_icon:
+ *
+ * Need to free the return value
+ *
+ **/
+gchar *
+gpm_upower_get_device_icon (UpDevice *device)
+{
+ gchar *filename = NULL;
+ const gchar *prefix = NULL;
+ const gchar *index_str;
+ UpDeviceKind kind;
+ UpDeviceState state;
+ gboolean is_present;
+ gdouble percentage;
+
+ g_return_val_if_fail (device != NULL, NULL);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "percentage", &percentage,
+ "is-present", &is_present,
+ NULL);
+
+ /* get correct icon prefix */
+ prefix = up_device_kind_to_string (kind);
+
+ /* get the icon from some simple rules */
+ if (kind == UP_DEVICE_KIND_LINE_POWER) {
+ filename = g_strdup ("gpm-ac-adapter");
+ } else if (kind == UP_DEVICE_KIND_MONITOR) {
+ filename = g_strdup ("gpm-monitor");
+ } else if (kind == UP_DEVICE_KIND_UPS) {
+ if (!is_present) {
+ /* battery missing */
+ filename = g_strdup_printf ("gpm-%s-missing", prefix);
+
+ } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) {
+ filename = g_strdup_printf ("gpm-%s-100", prefix);
+
+ } else if (state == UP_DEVICE_STATE_CHARGING) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ filename = g_strdup_printf ("gpm-%s-%s-charging", prefix, index_str);
+
+ } else if (state == UP_DEVICE_STATE_DISCHARGING) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ filename = g_strdup_printf ("gpm-%s-%s", prefix, index_str);
+ }
+ } else if (kind == UP_DEVICE_KIND_BATTERY) {
+ if (!is_present) {
+ /* battery missing */
+ filename = g_strdup_printf ("gpm-%s-missing", prefix);
+
+ } else if (state == UP_DEVICE_STATE_EMPTY) {
+ filename = g_strdup_printf ("gpm-%s-empty", prefix);
+
+ } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) {
+ filename = g_strdup_printf ("gpm-%s-charged", prefix);
+
+ } else if (state == UP_DEVICE_STATE_CHARGING) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ filename = g_strdup_printf ("gpm-%s-%s-charging", prefix, index_str);
+
+ } else if (state == UP_DEVICE_STATE_DISCHARGING) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ filename = g_strdup_printf ("gpm-%s-%s", prefix, index_str);
+
+ } else if (state == UP_DEVICE_STATE_PENDING_CHARGE) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ /* FIXME: do new grey icons */
+ filename = g_strdup_printf ("gpm-%s-%s-charging", prefix, index_str);
+
+ } else if (state == UP_DEVICE_STATE_PENDING_DISCHARGE) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ filename = g_strdup_printf ("gpm-%s-%s", prefix, index_str);
+ } else {
+ filename = g_strdup ("gpm-battery-missing");
+ }
+
+ } else if (kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD ||
+ kind == UP_DEVICE_KIND_PHONE) {
+ if (!is_present) {
+ /* battery missing */
+ filename = g_strdup_printf ("gpm-%s-000", prefix);
+
+ } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) {
+ filename = g_strdup_printf ("gpm-%s-100", prefix);
+
+ } else if (state == UP_DEVICE_STATE_DISCHARGING) {
+ index_str = gpm_upower_get_device_icon_index (device);
+ filename = g_strdup_printf ("gpm-%s-%s", prefix, index_str);
+ }
+ }
+
+ /* nothing matched */
+ if (filename == NULL) {
+ egg_warning ("nothing matched, falling back to default icon");
+ filename = g_strdup ("dialog-warning");
+ }
+
+ egg_debug ("got filename: %s", filename);
+ return filename;
+}
+
+/**
+ * gpm_upower_get_device_summary:
+ **/
+gchar *
+gpm_upower_get_device_summary (UpDevice *device)
+{
+ const gchar *kind_desc = NULL;
+ gchar *description = NULL;
+ guint time_to_full_round;
+ guint time_to_empty_round;
+ gchar *time_to_full_str;
+ gchar *time_to_empty_str;
+ UpDeviceKind kind;
+ UpDeviceState state;
+ gdouble percentage;
+ gboolean is_present;
+ gint64 time_to_full;
+ gint64 time_to_empty;
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "percentage", &percentage,
+ "is-present", &is_present,
+ "time-to-full", &time_to_full,
+ "time-to-empty", &time_to_empty,
+ NULL);
+
+ if (!is_present)
+ return NULL;
+
+ kind_desc = gpm_device_kind_to_localised_text (kind, 1);
+
+ /* don't display all the extra stuff for keyboards and mice */
+ if (kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD ||
+ kind == UP_DEVICE_KIND_PDA)
+ return g_strdup_printf ("%s (%.1f%%)", kind_desc, percentage);
+
+ /* we care if we are on AC */
+ if (kind == UP_DEVICE_KIND_PHONE) {
+ if (state == UP_DEVICE_STATE_CHARGING || !state == UP_DEVICE_STATE_DISCHARGING) {
+ /* TRANSLATORS: a phone is charging */
+ return g_strdup_printf (_("%s charging (%.1f%%)"), kind_desc, percentage);
+ }
+ return g_strdup_printf ("%s (%.1f%%)", kind_desc, percentage);
+ }
+
+ /* precalculate so we don't get Unknown time remaining */
+ time_to_full_round = egg_precision_round_down (time_to_full, GPM_UP_TIME_PRECISION);
+ time_to_empty_round = egg_precision_round_down (time_to_empty, GPM_UP_TIME_PRECISION);
+
+ /* we always display "Laptop battery 16 minutes remaining" as we need to clarify what device we are refering to */
+ if (state == UP_DEVICE_STATE_FULLY_CHARGED) {
+
+ if (kind == UP_DEVICE_KIND_BATTERY && time_to_empty_round > GPM_UP_TEXT_MIN_TIME) {
+ time_to_empty_str = gpm_get_timestring (time_to_empty_round);
+ /* TRANSLATORS: The laptop battery is fully charged, and we know a time */
+ description = g_strdup_printf (_("Battery is fully charged.\nProvides %s laptop runtime"),
+ time_to_empty_str);
+ g_free (time_to_empty_str);
+ } else {
+ /* TRANSLATORS: the device is fully charged */
+ description = g_strdup_printf (_("%s is fully charged"), kind_desc);
+ }
+
+ } else if (state == UP_DEVICE_STATE_DISCHARGING) {
+
+ if (time_to_empty_round > GPM_UP_TEXT_MIN_TIME) {
+ time_to_empty_str = gpm_get_timestring (time_to_empty_round);
+ /* TRANSLATORS: the device is discharging, and we have a time remaining */
+ description = g_strdup_printf (_("%s %s remaining (%.1f%%)"),
+ kind_desc, time_to_empty_str, percentage);
+ g_free (time_to_empty_str);
+ } else {
+ /* TRANSLATORS: the device is discharging, but we only have a percentage */
+ description = g_strdup_printf (_("%s discharging (%.1f%%)"),
+ kind_desc, percentage);
+ }
+
+ } else if (state == UP_DEVICE_STATE_CHARGING) {
+
+ if (time_to_full_round > GPM_UP_TEXT_MIN_TIME &&
+ time_to_empty_round > GPM_UP_TEXT_MIN_TIME) {
+
+ /* display both discharge and charge time */
+ time_to_full_str = gpm_get_timestring (time_to_full_round);
+ time_to_empty_str = gpm_get_timestring (time_to_empty_round);
+
+ /* TRANSLATORS: the device is charging, and we have a time to full and empty */
+ description = g_strdup_printf (_("%s %s until charged (%.1f%%)\nProvides %s battery runtime"),
+ kind_desc, time_to_full_str, percentage, time_to_empty_str);
+ g_free (time_to_full_str);
+ g_free (time_to_empty_str);
+
+ } else if (time_to_full_round > GPM_UP_TEXT_MIN_TIME) {
+
+ /* display only charge time */
+ time_to_full_str = gpm_get_timestring (time_to_full_round);
+
+ /* TRANSLATORS: device is charging, and we have a time to full and a percentage */
+ description = g_strdup_printf (_("%s %s until charged (%.1f%%)"),
+ kind_desc, time_to_full_str, percentage);
+ g_free (time_to_full_str);
+ } else {
+
+ /* TRANSLATORS: device is charging, but we only have a percentage */
+ description = g_strdup_printf (_("%s charging (%.1f%%)"),
+ kind_desc, percentage);
+ }
+
+ } else if (state == UP_DEVICE_STATE_PENDING_DISCHARGE) {
+
+ /* TRANSLATORS: this is only shown for laptops with multiple batteries */
+ description = g_strdup_printf (_("%s waiting to discharge (%.1f%%)"),
+ kind_desc, percentage);
+
+ } else if (state == UP_DEVICE_STATE_PENDING_CHARGE) {
+
+ /* TRANSLATORS: this is only shown for laptops with multiple batteries */
+ description = g_strdup_printf (_("%s waiting to charge (%.1f%%)"), kind_desc, percentage);
+
+ } else {
+ egg_warning ("in an undefined state we are not charging or "
+ "discharging and the batteries are also not charged");
+ description = g_strdup_printf ("%s (%.1f%%)", kind_desc, percentage);
+ }
+ return description;
+}
+
+/**
+ * gpm_upower_get_device_description:
+ **/
+gchar *
+gpm_upower_get_device_description (UpDevice *device)
+{
+ GString *details;
+ const gchar *text;
+ gchar *time_str;
+ UpDeviceKind kind;
+ UpDeviceState state;
+ UpDeviceTechnology technology;
+ gdouble percentage;
+ gdouble capacity;
+ gdouble energy;
+ gdouble energy_full;
+ gdouble energy_full_design;
+ gdouble energy_rate;
+ gboolean is_present;
+ gint64 time_to_full;
+ gint64 time_to_empty;
+ gchar *vendor = NULL;
+ gchar *serial = NULL;
+ gchar *model = NULL;
+
+ g_return_val_if_fail (device != NULL, NULL);
+
+ /* get device properties */
+ g_object_get (device,
+ "kind", &kind,
+ "state", &state,
+ "percentage", &percentage,
+ "is-present", &is_present,
+ "time-to-full", &time_to_full,
+ "time-to-empty", &time_to_empty,
+ "technology", &technology,
+ "capacity", &capacity,
+ "energy", &energy,
+ "energy-full", &energy_full,
+ "energy-full-design", &energy_full_design,
+ "energy-rate", &energy_rate,
+ "vendor", &vendor,
+ "serial", &serial,
+ "model", &model,
+ NULL);
+
+ details = g_string_new ("");
+ text = gpm_device_kind_to_localised_text (kind, 1);
+ /* TRANSLATORS: the type of data, e.g. Laptop battery */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Product:"), text);
+
+ if (!is_present) {
+ /* TRANSLATORS: device is missing */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Status:"), _("Missing"));
+ } else if (state == UP_DEVICE_STATE_FULLY_CHARGED) {
+ /* TRANSLATORS: device is charged */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Status:"), _("Charged"));
+ } else if (state == UP_DEVICE_STATE_CHARGING) {
+ /* TRANSLATORS: device is charging */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Status:"), _("Charging"));
+ } else if (state == UP_DEVICE_STATE_DISCHARGING) {
+ /* TRANSLATORS: device is discharging */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Status:"), _("Discharging"));
+ }
+
+ if (percentage >= 0) {
+ /* TRANSLATORS: percentage */
+ g_string_append_printf (details, "<b>%s</b> %.1f%%\n", _("Percentage charge:"), percentage);
+ }
+ if (vendor) {
+ /* TRANSLATORS: manufacturer */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Vendor:"), vendor);
+ }
+ if (technology != UP_DEVICE_TECHNOLOGY_UNKNOWN) {
+ text = gpm_device_technology_to_localised_string (technology);
+ /* TRANSLATORS: how the battery is made, e.g. Lithium Ion */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Technology:"), text);
+ }
+ if (serial) {
+ /* TRANSLATORS: serial number of the battery */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Serial number:"), serial);
+ }
+ if (model) {
+ /* TRANSLATORS: model number of the battery */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Model:"), model);
+ }
+ if (time_to_full > 0) {
+ time_str = gpm_get_timestring (time_to_full);
+ /* TRANSLATORS: time to fully charged */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Charge time:"), time_str);
+ g_free (time_str);
+ }
+ if (time_to_empty > 0) {
+ time_str = gpm_get_timestring (time_to_empty);
+ /* TRANSLATORS: time to empty */
+ g_string_append_printf (details, "<b>%s</b> %s\n", _("Discharge time:"), time_str);
+ g_free (time_str);
+ }
+ if (capacity > 0) {
+ const gchar *condition;
+ if (capacity > 99) {
+ /* TRANSLATORS: Excellent, Good, Fair and Poor are all related to battery Capacity */
+ condition = _("Excellent");
+ } else if (capacity > 90) {
+ condition = _("Good");
+ } else if (capacity > 70) {
+ condition = _("Fair");
+ } else {
+ condition = _("Poor");
+ }
+ /* TRANSLATORS: %.1f is a percentage and %s the condition (Excellent, Good, ...) */
+ g_string_append_printf (details, "<b>%s</b> %.1f%% (%s)\n",
+ _("Capacity:"), capacity, condition);
+ }
+ if (kind == UP_DEVICE_KIND_BATTERY) {
+ if (energy > 0) {
+ /* TRANSLATORS: current charge */
+ g_string_append_printf (details, "<b>%s</b> %.1f Wh\n",
+ _("Current charge:"), energy);
+ }
+ if (energy_full > 0 &&
+ energy_full_design != energy_full) {
+ /* TRANSLATORS: last full is the charge the battery was seen to charge to */
+ g_string_append_printf (details, "<b>%s</b> %.1f Wh\n",
+ _("Last full charge:"), energy_full);
+ }
+ if (energy_full_design > 0) {
+ /* Translators: */
+ /* TRANSLATORS: Design charge is the amount of charge the battery is designed to have when brand new */
+ g_string_append_printf (details, "<b>%s</b> %.1f Wh\n",
+ _("Design charge:"), energy_full_design);
+ }
+ if (energy_rate > 0) {
+ /* TRANSLATORS: the charge or discharge rate */
+ g_string_append_printf (details, "<b>%s</b> %.1f W\n",
+ _("Charge rate:"), energy_rate);
+ }
+ }
+ if (kind == UP_DEVICE_KIND_MOUSE ||
+ kind == UP_DEVICE_KIND_KEYBOARD) {
+ if (energy > 0) {
+ /* TRANSLATORS: the current charge for CSR devices */
+ g_string_append_printf (details, "<b>%s</b> %.0f/7\n",
+ _("Current charge:"), energy);
+ }
+ if (energy_full_design > 0) {
+ /* TRANSLATORS: the design charge for CSR devices */
+ g_string_append_printf (details, "<b>%s</b> %.0f/7\n",
+ _("Design charge:"), energy_full_design);
+ }
+ }
+ /* remove the last \n */
+ g_string_truncate (details, details->len-1);
+
+ g_free (vendor);
+ g_free (serial);
+ g_free (model);
+ return g_string_free (details, FALSE);
+}
+
+/**
+ * gpm_device_kind_to_localised_text:
+ **/
+const gchar *
+gpm_device_kind_to_localised_text (UpDeviceKind kind, guint number)
+{
+ const gchar *text = NULL;
+ switch (kind) {
+ case UP_DEVICE_KIND_LINE_POWER:
+ /* TRANSLATORS: system power cord */
+ text = ngettext ("AC adapter", "AC adapters", number);
+ break;
+ case UP_DEVICE_KIND_BATTERY:
+ /* TRANSLATORS: laptop primary battery */
+ text = ngettext ("Laptop battery", "Laptop batteries", number);
+ break;
+ case UP_DEVICE_KIND_UPS:
+ /* TRANSLATORS: battery-backed AC power source */
+ text = ngettext ("UPS", "UPSs", number);
+ break;
+ case UP_DEVICE_KIND_MONITOR:
+ /* TRANSLATORS: a monitor is a device to measure voltage and current */
+ text = ngettext ("Monitor", "Monitors", number);
+ break;
+ case UP_DEVICE_KIND_MOUSE:
+ /* TRANSLATORS: wireless mice with internal batteries */
+ text = ngettext ("Mouse", "Mice", number);
+ break;
+ case UP_DEVICE_KIND_KEYBOARD:
+ /* TRANSLATORS: wireless keyboard with internal battery */
+ text = ngettext ("Keyboard", "Keyboards", number);
+ break;
+ case UP_DEVICE_KIND_PDA:
+ /* TRANSLATORS: portable device */
+ text = ngettext ("PDA", "PDAs", number);
+ break;
+ case UP_DEVICE_KIND_PHONE:
+ /* TRANSLATORS: cell phone (mobile...) */
+ text = ngettext ("Cell phone", "Cell phones", number);
+ break;
+#if UP_CHECK_VERSION(0,9,5)
+ case UP_DEVICE_KIND_MEDIA_PLAYER:
+ /* TRANSLATORS: media player, mp3 etc */
+ text = ngettext ("Media player", "Media players", number);
+ break;
+ case UP_DEVICE_KIND_TABLET:
+ /* TRANSLATORS: tablet device */
+ text = ngettext ("Tablet", "Tablets", number);
+ break;
+ case UP_DEVICE_KIND_COMPUTER:
+ /* TRANSLATORS: tablet device */
+ text = ngettext ("Computer", "Computers", number);
+ break;
+#endif
+ default:
+ egg_warning ("enum unrecognised: %i", kind);
+ text = up_device_kind_to_string (kind);
+ }
+ return text;
+}
+
+/**
+ * gpm_device_kind_to_icon:
+ **/
+const gchar *
+gpm_device_kind_to_icon (UpDeviceKind kind)
+{
+ const gchar *icon = NULL;
+ switch (kind) {
+ case UP_DEVICE_KIND_LINE_POWER:
+ icon = "gpm-ac-adapter";
+ break;
+ case UP_DEVICE_KIND_BATTERY:
+ icon = "battery";
+ break;
+ case UP_DEVICE_KIND_UPS:
+ icon = "network-wired";
+ break;
+ case UP_DEVICE_KIND_MONITOR:
+ icon = "application-certificate";
+ break;
+ case UP_DEVICE_KIND_MOUSE:
+ icon = "input-mouse";
+ break;
+ case UP_DEVICE_KIND_KEYBOARD:
+ icon = "input-keyboard";
+ break;
+ case UP_DEVICE_KIND_PDA:
+ icon = "pda";
+ break;
+ case UP_DEVICE_KIND_PHONE:
+ icon = "phone";
+ break;
+#if UP_CHECK_VERSION(0,9,5)
+ case UP_DEVICE_KIND_MEDIA_PLAYER:
+ icon = "multimedia-player";
+ break;
+ case UP_DEVICE_KIND_TABLET:
+ icon = "input-tablet";
+ break;
+ case UP_DEVICE_KIND_COMPUTER:
+ icon = "computer-apple-ipad";
+ break;
+#endif
+ default:
+ egg_warning ("enum unrecognised: %i", kind);
+ icon = "gtk-help";
+ }
+ return icon;
+}
+
+/**
+ * gpm_device_technology_to_localised_string:
+ **/
+const gchar *
+gpm_device_technology_to_localised_string (UpDeviceTechnology technology_enum)
+{
+ const gchar *technology = NULL;
+ switch (technology_enum) {
+ case UP_DEVICE_TECHNOLOGY_LITHIUM_ION:
+ /* TRANSLATORS: battery technology */
+ technology = _("Lithium Ion");
+ break;
+ case UP_DEVICE_TECHNOLOGY_LITHIUM_POLYMER:
+ /* TRANSLATORS: battery technology */
+ technology = _("Lithium Polymer");
+ break;
+ case UP_DEVICE_TECHNOLOGY_LITHIUM_IRON_PHOSPHATE:
+ /* TRANSLATORS: battery technology */
+ technology = _("Lithium Iron Phosphate");
+ break;
+ case UP_DEVICE_TECHNOLOGY_LEAD_ACID:
+ /* TRANSLATORS: battery technology */
+ technology = _("Lead acid");
+ break;
+ case UP_DEVICE_TECHNOLOGY_NICKEL_CADMIUM:
+ /* TRANSLATORS: battery technology */
+ technology = _("Nickel Cadmium");
+ break;
+ case UP_DEVICE_TECHNOLOGY_NICKEL_METAL_HYDRIDE:
+ /* TRANSLATORS: battery technology */
+ technology = _("Nickel metal hydride");
+ break;
+ case UP_DEVICE_TECHNOLOGY_UNKNOWN:
+ /* TRANSLATORS: battery technology */
+ technology = _("Unknown technology");
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ return technology;
+}
+
+/**
+ * gpm_device_state_to_localised_string:
+ **/
+const gchar *
+gpm_device_state_to_localised_string (UpDeviceState state)
+{
+ const gchar *state_string = NULL;
+
+ switch (state) {
+ case UP_DEVICE_STATE_CHARGING:
+ /* TRANSLATORS: battery state */
+ state_string = _("Charging");
+ break;
+ case UP_DEVICE_STATE_DISCHARGING:
+ /* TRANSLATORS: battery state */
+ state_string = _("Discharging");
+ break;
+ case UP_DEVICE_STATE_EMPTY:
+ /* TRANSLATORS: battery state */
+ state_string = _("Empty");
+ break;
+ case UP_DEVICE_STATE_FULLY_CHARGED:
+ /* TRANSLATORS: battery state */
+ state_string = _("Charged");
+ break;
+ case UP_DEVICE_STATE_PENDING_CHARGE:
+ /* TRANSLATORS: battery state */
+ state_string = _("Waiting to charge");
+ break;
+ case UP_DEVICE_STATE_PENDING_DISCHARGE:
+ /* TRANSLATORS: battery state */
+ state_string = _("Waiting to discharge");
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ return state_string;
+}
+
diff --git a/src/gpm-upower.h b/src/gpm-upower.h
new file mode 100644
index 0000000..3f43e64
--- /dev/null
+++ b/src/gpm-upower.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <[email protected]>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPM_DEVICEKIT_H
+#define __GPM_DEVICEKIT_H
+
+#include <glib-object.h>
+#include <libupower-glib/upower.h>
+
+G_BEGIN_DECLS
+
+const gchar *gpm_device_kind_to_localised_text (UpDeviceKind kind,
+ guint number);
+const gchar *gpm_device_kind_to_icon (UpDeviceKind kind);
+const gchar *gpm_device_technology_to_localised_string (UpDeviceTechnology technology_enum);
+const gchar *gpm_device_state_to_localised_string (UpDeviceState state);
+gchar *gpm_upower_get_device_icon (UpDevice *device);
+gchar *gpm_upower_get_device_summary (UpDevice *device);
+gchar *gpm_upower_get_device_description (UpDevice *device);
+
+G_END_DECLS
+
+#endif /* __GPM_DEVICEKIT_H */
diff --git a/src/gsd-media-keys-window.c b/src/gsd-media-keys-window.c
new file mode 100644
index 0000000..fdc1ea1
--- /dev/null
+++ b/src/gsd-media-keys-window.c
@@ -0,0 +1,1079 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2007 William Jon McCann <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "gsd-media-keys-window.h"
+
+#define DIALOG_TIMEOUT 2000 /* dialog timeout in ms */
+#define DIALOG_FADE_TIMEOUT 1500 /* timeout before fade starts */
+#define FADE_TIMEOUT 10 /* timeout in ms between each frame of the fade */
+
+#define BG_ALPHA 0.75
+#define FG_ALPHA 1.00
+
+#define GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowPrivate))
+
+struct GsdMediaKeysWindowPrivate
+{
+ guint is_composited : 1;
+ guint hide_timeout_id;
+ guint fade_timeout_id;
+ double fade_out_alpha;
+ GsdMediaKeysWindowAction action;
+ char *icon_name;
+ gboolean show_level;
+
+ guint volume_muted : 1;
+ int volume_level;
+
+ GtkImage *image;
+ GtkWidget *progress;
+};
+
+G_DEFINE_TYPE (GsdMediaKeysWindow, gsd_media_keys_window, GTK_TYPE_WINDOW)
+
+static gboolean
+fade_timeout (GsdMediaKeysWindow *window)
+{
+ if (window->priv->fade_out_alpha <= 0.0) {
+ gtk_widget_hide (GTK_WIDGET (window));
+
+ /* Reset it for the next time */
+ window->priv->fade_out_alpha = 1.0;
+ window->priv->fade_timeout_id = 0;
+
+ return FALSE;
+ } else {
+ GdkRectangle rect;
+ GtkWidget *win = GTK_WIDGET (window);
+ GtkAllocation allocation;
+
+ window->priv->fade_out_alpha -= 0.10;
+
+ rect.x = 0;
+ rect.y = 0;
+ gtk_widget_get_allocation (win, &allocation);
+ rect.width = allocation.width;
+ rect.height = allocation.height;
+
+ gtk_widget_realize (win);
+ gdk_window_invalidate_rect (gtk_widget_get_window (win), &rect, FALSE);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+hide_timeout (GsdMediaKeysWindow *window)
+{
+ if (window->priv->is_composited) {
+ window->priv->hide_timeout_id = 0;
+ window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT,
+ (GSourceFunc) fade_timeout,
+ window);
+ } else {
+ gtk_widget_hide (GTK_WIDGET (window));
+ }
+
+ return FALSE;
+}
+
+static void
+remove_hide_timeout (GsdMediaKeysWindow *window)
+{
+ if (window->priv->hide_timeout_id != 0) {
+ g_source_remove (window->priv->hide_timeout_id);
+ window->priv->hide_timeout_id = 0;
+ }
+
+ if (window->priv->fade_timeout_id != 0) {
+ g_source_remove (window->priv->fade_timeout_id);
+ window->priv->fade_timeout_id = 0;
+ window->priv->fade_out_alpha = 1.0;
+ }
+}
+
+static void
+add_hide_timeout (GsdMediaKeysWindow *window)
+{
+ int timeout;
+
+ if (window->priv->is_composited) {
+ timeout = DIALOG_FADE_TIMEOUT;
+ } else {
+ timeout = DIALOG_TIMEOUT;
+ }
+ window->priv->hide_timeout_id = g_timeout_add (timeout,
+ (GSourceFunc) hide_timeout,
+ window);
+}
+
+static void
+update_window (GsdMediaKeysWindow *window)
+{
+ remove_hide_timeout (window);
+ add_hide_timeout (window);
+
+ if (window->priv->is_composited) {
+ gtk_widget_queue_draw (GTK_WIDGET (window));
+ }
+}
+
+static void
+volume_controls_set_visible (GsdMediaKeysWindow *window,
+ gboolean visible)
+{
+ if (window->priv->progress == NULL)
+ return;
+
+ if (visible) {
+ gtk_widget_show (window->priv->progress);
+ } else {
+ gtk_widget_hide (window->priv->progress);
+ }
+}
+
+static void
+window_set_icon_name (GsdMediaKeysWindow *window,
+ const char *name)
+{
+ if (window->priv->image == NULL)
+ return;
+
+ gtk_image_set_from_icon_name (window->priv->image,
+ name, GTK_ICON_SIZE_DIALOG);
+}
+
+static void
+action_changed (GsdMediaKeysWindow *window)
+{
+ if (! window->priv->is_composited) {
+ switch (window->priv->action) {
+ case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME:
+ volume_controls_set_visible (window, TRUE);
+
+ if (window->priv->volume_muted) {
+ window_set_icon_name (window, "audio-volume-muted");
+ } else {
+ window_set_icon_name (window, "audio-volume-high");
+ }
+
+ break;
+ case GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM:
+ volume_controls_set_visible (window, window->priv->show_level);
+ window_set_icon_name (window, window->priv->icon_name);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+
+ update_window (window);
+}
+
+static void
+volume_level_changed (GsdMediaKeysWindow *window)
+{
+ update_window (window);
+
+ if (!window->priv->is_composited && window->priv->progress != NULL) {
+ double fraction;
+
+ fraction = (double) window->priv->volume_level / 100.0;
+
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress),
+ fraction);
+ }
+}
+
+static void
+volume_muted_changed (GsdMediaKeysWindow *window)
+{
+ update_window (window);
+
+ if (! window->priv->is_composited) {
+ if (window->priv->volume_muted) {
+ window_set_icon_name (window, "audio-volume-muted");
+ } else {
+ window_set_icon_name (window, "audio-volume-high");
+ }
+ }
+}
+
+void
+gsd_media_keys_window_set_action (GsdMediaKeysWindow *window,
+ GsdMediaKeysWindowAction action)
+{
+ g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+ g_return_if_fail (action == GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+
+ if (window->priv->action != action) {
+ window->priv->action = action;
+ action_changed (window);
+ } else {
+ update_window (window);
+ }
+}
+
+void
+gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow *window,
+ const char *icon_name,
+ gboolean show_level)
+{
+ g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+ g_return_if_fail (icon_name != NULL);
+
+ if (window->priv->action != GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM ||
+ g_strcmp0 (window->priv->icon_name, icon_name) != 0 ||
+ window->priv->show_level != show_level) {
+ window->priv->action = GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM;
+ g_free (window->priv->icon_name);
+ window->priv->icon_name = g_strdup (icon_name);
+ window->priv->show_level = show_level;
+ action_changed (window);
+ } else {
+ update_window (window);
+ }
+}
+
+void
+gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window,
+ gboolean muted)
+{
+ g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+ if (window->priv->volume_muted != muted) {
+ window->priv->volume_muted = muted;
+ volume_muted_changed (window);
+ }
+}
+
+void
+gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window,
+ int level)
+{
+ g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window));
+
+ if (window->priv->volume_level != level) {
+ window->priv->volume_level = level;
+ volume_level_changed (window);
+ }
+}
+
+static void
+rounded_rectangle (cairo_t* cr,
+ gdouble aspect,
+ gdouble x,
+ gdouble y,
+ gdouble corner_radius,
+ gdouble width,
+ gdouble height)
+{
+ gdouble radius = corner_radius / aspect;
+
+ cairo_move_to (cr, x + radius, y);
+
+ cairo_line_to (cr,
+ x + width - radius,
+ y);
+ cairo_arc (cr,
+ x + width - radius,
+ y + radius,
+ radius,
+ -90.0f * G_PI / 180.0f,
+ 0.0f * G_PI / 180.0f);
+ cairo_line_to (cr,
+ x + width,
+ y + height - radius);
+ cairo_arc (cr,
+ x + width - radius,
+ y + height - radius,
+ radius,
+ 0.0f * G_PI / 180.0f,
+ 90.0f * G_PI / 180.0f);
+ cairo_line_to (cr,
+ x + radius,
+ y + height);
+ cairo_arc (cr,
+ x + radius,
+ y + height - radius,
+ radius,
+ 90.0f * G_PI / 180.0f,
+ 180.0f * G_PI / 180.0f);
+ cairo_line_to (cr,
+ x,
+ y + radius);
+ cairo_arc (cr,
+ x + radius,
+ y + radius,
+ radius,
+ 180.0f * G_PI / 180.0f,
+ 270.0f * G_PI / 180.0f);
+ cairo_close_path (cr);
+}
+
+static GdkPixbuf *
+load_pixbuf (GsdMediaKeysWindow *window,
+ const char *name,
+ int icon_size)
+{
+ GtkIconTheme *theme;
+ GdkPixbuf *pixbuf;
+
+ if (window != NULL && gtk_widget_has_screen (GTK_WIDGET (window))) {
+ theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
+ } else {
+ theme = gtk_icon_theme_get_default ();
+ }
+
+ pixbuf = gtk_icon_theme_load_icon (theme,
+ name,
+ icon_size,
+ GTK_ICON_LOOKUP_FORCE_SVG,
+ NULL);
+
+ /* make sure the pixbuf is close to the requested size
+ * this is necessary because GTK_ICON_LOOKUP_FORCE_SVG
+ * seems to be broken */
+ if (pixbuf != NULL) {
+ int width;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ if (width < (float)icon_size * 0.75) {
+ g_object_unref (pixbuf);
+ pixbuf = NULL;
+ }
+ }
+
+ return pixbuf;
+}
+
+static void
+draw_eject (cairo_t *cr,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ int box_height;
+ int tri_height;
+ int separation;
+
+ box_height = height * 0.2;
+ separation = box_height / 3;
+ tri_height = height - box_height - separation;
+
+ cairo_rectangle (cr, _x0, _y0 + height - box_height, width, box_height);
+
+ cairo_move_to (cr, _x0, _y0 + tri_height);
+ cairo_rel_line_to (cr, width, 0);
+ cairo_rel_line_to (cr, -width / 2, -tri_height);
+ cairo_rel_line_to (cr, -width / 2, tri_height);
+ cairo_close_path (cr);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+}
+
+static void
+draw_waves (cairo_t *cr,
+ double cx,
+ double cy,
+ double max_radius,
+ int volume_level)
+{
+ const int n_waves = 3;
+ int last_wave;
+ int i;
+
+ last_wave = n_waves * volume_level / 100;
+
+ for (i = 0; i < n_waves; i++) {
+ double angle1;
+ double angle2;
+ double radius;
+ double alpha;
+
+ angle1 = -M_PI / 4;
+ angle2 = M_PI / 4;
+
+ if (i < last_wave)
+ alpha = 1.0;
+ else if (i > last_wave)
+ alpha = 0.1;
+ else alpha = 0.1 + 0.9 * (n_waves * volume_level % 100) / 100.0;
+
+ radius = (i + 1) * (max_radius / n_waves);
+ cairo_arc (cr, cx, cy, radius, angle1, angle2);
+ cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, alpha / 2);
+ cairo_set_line_width (cr, 14);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke_preserve (cr);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, alpha);
+ cairo_set_line_width (cr, 10);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke (cr);
+ }
+}
+
+static void
+draw_cross (cairo_t *cr,
+ double cx,
+ double cy,
+ double size)
+{
+ cairo_move_to (cr, cx, cy - size/2.0);
+ cairo_rel_line_to (cr, size, size);
+
+ cairo_move_to (cr, cx, cy + size/2.0);
+ cairo_rel_line_to (cr, size, -size);
+
+ cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2);
+ cairo_set_line_width (cr, 14);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke_preserve (cr);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA);
+ cairo_set_line_width (cr, 10);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+ cairo_stroke (cr);
+}
+
+static void
+draw_speaker (cairo_t *cr,
+ double cx,
+ double cy,
+ double width,
+ double height)
+{
+ double box_width;
+ double box_height;
+ double _x0;
+ double _y0;
+
+ box_width = width / 3;
+ box_height = height / 3;
+
+ _x0 = cx - (width / 2) + box_width;
+ _y0 = cy - box_height / 2;
+
+ cairo_move_to (cr, _x0, _y0);
+ cairo_rel_line_to (cr, - box_width, 0);
+ cairo_rel_line_to (cr, 0, box_height);
+ cairo_rel_line_to (cr, box_width, 0);
+
+ cairo_line_to (cr, cx + box_width, cy + height / 2);
+ cairo_rel_line_to (cr, 0, -height);
+ cairo_line_to (cr, _x0, _y0);
+ cairo_close_path (cr);
+
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, FG_ALPHA);
+ cairo_fill_preserve (cr);
+
+ cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, FG_ALPHA / 2);
+ cairo_set_line_width (cr, 2);
+ cairo_stroke (cr);
+}
+
+static gboolean
+render_speaker (GsdMediaKeysWindow *window,
+ cairo_t *cr,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ GdkPixbuf *pixbuf;
+ int icon_size;
+ int n;
+ static const char *icon_names[] = {
+ "audio-volume-muted",
+ "audio-volume-low",
+ "audio-volume-medium",
+ "audio-volume-high",
+ NULL
+ };
+
+ if (window->priv->volume_muted) {
+ n = 0;
+ } else {
+ /* select image */
+ n = 3 * window->priv->volume_level / 100 + 1;
+ if (n < 1) {
+ n = 1;
+ } else if (n > 3) {
+ n = 3;
+ }
+ }
+
+ icon_size = (int)width;
+
+ pixbuf = load_pixbuf (window, icon_names[n], icon_size);
+
+ if (pixbuf == NULL) {
+ return FALSE;
+ }
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
+ cairo_paint_with_alpha (cr, FG_ALPHA);
+
+ g_object_unref (pixbuf);
+
+ return TRUE;
+}
+
+static void
+color_reverse (const GdkColor *a,
+ GdkColor *b)
+{
+ gdouble red;
+ gdouble green;
+ gdouble blue;
+ gdouble h;
+ gdouble s;
+ gdouble v;
+
+ red = (gdouble) a->red / 65535.0;
+ green = (gdouble) a->green / 65535.0;
+ blue = (gdouble) a->blue / 65535.0;
+
+ gtk_rgb_to_hsv (red, green, blue, &h, &s, &v);
+
+ v = 0.5 + (0.5 - v);
+ if (v > 1.0)
+ v = 1.0;
+ else if (v < 0.0)
+ v = 0.0;
+
+ gtk_hsv_to_rgb (h, s, v, &red, &green, &blue);
+
+ b->red = red * 65535.0;
+ b->green = green * 65535.0;
+ b->blue = blue * 65535.0;
+}
+
+static void
+draw_volume_boxes (GsdMediaKeysWindow *window,
+ cairo_t *cr,
+ double percentage,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ gdouble x1;
+ GdkColor color;
+ double r, g, b;
+ GtkStyle *style;
+
+ _x0 += 0.5;
+ _y0 += 0.5;
+ height = round (height) - 1;
+ width = round (width) - 1;
+ x1 = round ((width - 1) * percentage);
+ style = gtk_widget_get_style (GTK_WIDGET (window));
+
+ /* bar background */
+ color_reverse (&style->dark[GTK_STATE_NORMAL], &color);
+ r = (float)color.red / 65535.0;
+ g = (float)color.green / 65535.0;
+ b = (float)color.blue / 65535.0;
+ rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height);
+ cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2);
+ cairo_fill_preserve (cr);
+
+ /* bar border */
+ color_reverse (&style->light[GTK_STATE_NORMAL], &color);
+ r = (float)color.red / 65535.0;
+ g = (float)color.green / 65535.0;
+ b = (float)color.blue / 65535.0;
+ cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+
+ /* bar progress */
+ if (percentage < 0.01)
+ return;
+ color = style->bg[GTK_STATE_NORMAL];
+ r = (float)color.red / 65535.0;
+ g = (float)color.green / 65535.0;
+ b = (float)color.blue / 65535.0;
+ rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1);
+ cairo_set_source_rgba (cr, r, g, b, FG_ALPHA);
+ cairo_fill (cr);
+}
+
+static void
+draw_action_volume (GsdMediaKeysWindow *window,
+ cairo_t *cr)
+{
+ int window_width;
+ int window_height;
+ double icon_box_width;
+ double icon_box_height;
+ double icon_box_x0;
+ double icon_box_y0;
+ double volume_box_x0;
+ double volume_box_y0;
+ double volume_box_width;
+ double volume_box_height;
+ gboolean res;
+
+ gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
+
+ icon_box_width = round (window_width * 0.65);
+ icon_box_height = round (window_height * 0.65);
+ volume_box_width = icon_box_width;
+ volume_box_height = round (window_height * 0.05);
+
+ icon_box_x0 = (window_width - icon_box_width) / 2;
+ icon_box_y0 = (window_height - icon_box_height - volume_box_height) / 2;
+ volume_box_x0 = round (icon_box_x0);
+ volume_box_y0 = round (icon_box_height + icon_box_y0);
+
+#if 0
+ g_message ("icon box: w=%f h=%f _x0=%f _y0=%f",
+ icon_box_width,
+ icon_box_height,
+ icon_box_x0,
+ icon_box_y0);
+ g_message ("volume box: w=%f h=%f _x0=%f _y0=%f",
+ volume_box_width,
+ volume_box_height,
+ volume_box_x0,
+ volume_box_y0);
+#endif
+
+ res = render_speaker (window,
+ cr,
+ icon_box_x0, icon_box_y0,
+ icon_box_width, icon_box_height);
+ if (! res) {
+ double speaker_width;
+ double speaker_height;
+ double speaker_cx;
+ double speaker_cy;
+
+ speaker_width = icon_box_width * 0.5;
+ speaker_height = icon_box_height * 0.75;
+ speaker_cx = icon_box_x0 + speaker_width / 2;
+ speaker_cy = icon_box_y0 + speaker_height / 2;
+
+#if 0
+ g_message ("speaker box: w=%f h=%f cx=%f cy=%f",
+ speaker_width,
+ speaker_height,
+ speaker_cx,
+ speaker_cy);
+#endif
+
+ /* draw speaker symbol */
+ draw_speaker (cr, speaker_cx, speaker_cy, speaker_width, speaker_height);
+
+ if (! window->priv->volume_muted) {
+ /* draw sound waves */
+ double wave_x0;
+ double wave_y0;
+ double wave_radius;
+
+ wave_x0 = window_width / 2;
+ wave_y0 = speaker_cy;
+ wave_radius = icon_box_width / 2;
+
+ draw_waves (cr, wave_x0, wave_y0, wave_radius, window->priv->volume_level);
+ } else {
+ /* draw 'mute' cross */
+ double cross_x0;
+ double cross_y0;
+ double cross_size;
+
+ cross_size = speaker_width * 3 / 4;
+ cross_x0 = icon_box_x0 + icon_box_width - cross_size;
+ cross_y0 = speaker_cy;
+
+ draw_cross (cr, cross_x0, cross_y0, cross_size);
+ }
+ }
+
+ /* draw volume meter */
+ draw_volume_boxes (window,
+ cr,
+ (double)window->priv->volume_level / 100.0,
+ volume_box_x0,
+ volume_box_y0,
+ volume_box_width,
+ volume_box_height);
+}
+
+static gboolean
+render_custom (GsdMediaKeysWindow *window,
+ cairo_t *cr,
+ double _x0,
+ double _y0,
+ double width,
+ double height)
+{
+ GdkPixbuf *pixbuf;
+ int icon_size;
+
+ icon_size = (int)width;
+
+ pixbuf = load_pixbuf (window, window->priv->icon_name, icon_size);
+
+ if (pixbuf == NULL) {
+ char *name;
+ if (gtk_widget_get_direction (GTK_WIDGET (window)) == GTK_TEXT_DIR_RTL)
+ name = g_strdup_printf ("%s-rtl", window->priv->icon_name);
+ else
+ name = g_strdup_printf ("%s-ltr", window->priv->icon_name);
+ pixbuf = load_pixbuf (window, name, icon_size);
+ g_free (name);
+ if (pixbuf == NULL)
+ return FALSE;
+ }
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0);
+ cairo_paint_with_alpha (cr, FG_ALPHA);
+
+ g_object_unref (pixbuf);
+
+ return TRUE;
+}
+
+static void
+draw_action_custom (GsdMediaKeysWindow *window,
+ cairo_t *cr)
+{
+ int window_width;
+ int window_height;
+ double icon_box_width;
+ double icon_box_height;
+ double icon_box_x0;
+ double icon_box_y0;
+ double bright_box_x0;
+ double bright_box_y0;
+ double bright_box_width;
+ double bright_box_height;
+ gboolean res;
+
+ gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height);
+
+ icon_box_width = round (window_width * 0.65);
+ icon_box_height = round (window_height * 0.65);
+ bright_box_width = round (icon_box_width);
+ bright_box_height = round (window_height * 0.05);
+
+ icon_box_x0 = (window_width - icon_box_width) / 2;
+ icon_box_y0 = (window_height - icon_box_height - bright_box_height) / 2;
+ bright_box_x0 = round (icon_box_x0);
+ bright_box_y0 = round (icon_box_height + icon_box_y0);
+
+#if 0
+ g_message ("icon box: w=%f h=%f _x0=%f _y0=%f",
+ icon_box_width,
+ icon_box_height,
+ icon_box_x0,
+ icon_box_y0);
+ g_message ("brightness box: w=%f h=%f _x0=%f _y0=%f",
+ bright_box_width,
+ bright_box_height,
+ bright_box_x0,
+ bright_box_y0);
+#endif
+
+ res = render_custom (window,
+ cr,
+ icon_box_x0, icon_box_y0,
+ icon_box_width, icon_box_height);
+ if (! res && g_strcmp0 (window->priv->icon_name, "media-eject") == 0) {
+ /* draw eject symbol */
+ draw_eject (cr,
+ icon_box_x0, icon_box_y0,
+ icon_box_width, icon_box_height);
+ }
+
+ if (window->priv->show_level != FALSE) {
+ /* draw volume meter */
+ draw_volume_boxes (window,
+ cr,
+ (double)window->priv->volume_level / 100.0,
+ bright_box_x0,
+ bright_box_y0,
+ bright_box_width,
+ bright_box_height);
+ }
+}
+
+static void
+draw_action (GsdMediaKeysWindow *window,
+ cairo_t *cr)
+{
+ switch (window->priv->action) {
+ case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME:
+ draw_action_volume (window, cr);
+ break;
+ case GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM:
+ draw_action_custom (window, cr);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+on_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ GsdMediaKeysWindow *window)
+{
+ cairo_t *context;
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ int width;
+ int height;
+ GtkStyle *style;
+ GdkColor color;
+ double r, g, b;
+
+ context = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ style = gtk_widget_get_style (widget);
+ cairo_set_operator (context, CAIRO_OPERATOR_SOURCE);
+ gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
+
+ surface = cairo_surface_create_similar (cairo_get_target (context),
+ CAIRO_CONTENT_COLOR_ALPHA,
+ width,
+ height);
+
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) {
+ goto done;
+ }
+
+ cr = cairo_create (surface);
+ if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
+ goto done;
+ }
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_paint (cr);
+
+ /* draw a box */
+ rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1);
+ color_reverse (&style->bg[GTK_STATE_NORMAL], &color);
+ r = (float)color.red / 65535.0;
+ g = (float)color.green / 65535.0;
+ b = (float)color.blue / 65535.0;
+ cairo_set_source_rgba (cr, r, g, b, BG_ALPHA);
+ cairo_fill_preserve (cr);
+
+ color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color);
+ r = (float)color.red / 65535.0;
+ g = (float)color.green / 65535.0;
+ b = (float)color.blue / 65535.0;
+ cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+
+ /* draw action */
+ draw_action (window, cr);
+
+ cairo_destroy (cr);
+
+ /* Make sure we have a transparent background */
+ cairo_rectangle (context, 0, 0, width, height);
+ cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0);
+ cairo_fill (context);
+
+ cairo_set_source_surface (context, surface, 0, 0);
+ cairo_paint_with_alpha (context, window->priv->fade_out_alpha);
+
+ done:
+ if (surface != NULL) {
+ cairo_surface_destroy (surface);
+ }
+ cairo_destroy (context);
+
+ return FALSE;
+}
+
+static void
+gsd_media_keys_window_real_show (GtkWidget *widget)
+{
+ GsdMediaKeysWindow *window;
+
+ if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->show) {
+ GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->show (widget);
+ }
+
+ window = GSD_MEDIA_KEYS_WINDOW (widget);
+ remove_hide_timeout (window);
+ add_hide_timeout (window);
+}
+
+static void
+gsd_media_keys_window_real_hide (GtkWidget *widget)
+{
+ GsdMediaKeysWindow *window;
+
+ if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide) {
+ GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->hide (widget);
+ }
+
+ window = GSD_MEDIA_KEYS_WINDOW (widget);
+ remove_hide_timeout (window);
+}
+
+static void
+gsd_media_keys_window_real_realize (GtkWidget *widget)
+{
+ GdkColormap *colormap;
+ GtkAllocation allocation;
+ GdkBitmap *mask;
+ cairo_t *cr;
+
+ colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget));
+
+ if (colormap != NULL) {
+ gtk_widget_set_colormap (widget, colormap);
+ }
+
+ if (GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize) {
+ GTK_WIDGET_CLASS (gsd_media_keys_window_parent_class)->realize (widget);
+ }
+
+ gtk_widget_get_allocation (widget, &allocation);
+ mask = gdk_pixmap_new (gtk_widget_get_window (widget),
+ allocation.width,
+ allocation.height,
+ 1);
+ cr = gdk_cairo_create (mask);
+
+ cairo_set_source_rgba (cr, 1., 1., 1., 0.);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+
+ /* make the whole window ignore events */
+ gdk_window_input_shape_combine_mask (gtk_widget_get_window (widget), mask, 0, 0);
+ g_object_unref (mask);
+ cairo_destroy (cr);
+}
+
+static void
+gsd_media_keys_window_class_init (GsdMediaKeysWindowClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->show = gsd_media_keys_window_real_show;
+ widget_class->hide = gsd_media_keys_window_real_hide;
+ widget_class->realize = gsd_media_keys_window_real_realize;
+
+ g_type_class_add_private (klass, sizeof (GsdMediaKeysWindowPrivate));
+}
+
+gboolean
+gsd_media_keys_window_is_valid (GsdMediaKeysWindow *window)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
+ return gdk_screen_is_composited (screen) == window->priv->is_composited;
+}
+
+static void
+gsd_media_keys_window_init (GsdMediaKeysWindow *window)
+{
+ GdkScreen *screen;
+
+ window->priv = GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE (window);
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (window));
+
+ window->priv->is_composited = gdk_screen_is_composited (screen);
+
+ if (window->priv->is_composited) {
+ gdouble scalew, scaleh, scale;
+ gint size;
+
+ gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
+ gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
+
+ /* assume 130x130 on a 640x480 display and scale from there */
+ scalew = gdk_screen_get_width (screen) / 640.0;
+ scaleh = gdk_screen_get_height (screen) / 480.0;
+ scale = MIN (scalew, scaleh);
+ size = 130 * MAX (1, scale);
+
+ gtk_window_set_default_size (GTK_WINDOW (window), size, size);
+ g_signal_connect (window, "expose-event", G_CALLBACK (on_expose_event), window);
+
+ window->priv->fade_out_alpha = 1.0;
+ } else {
+ GtkBuilder *builder;
+ const gchar *objects[] = {"acme_frame", NULL};
+ GtkWidget *frame;
+
+ builder = gtk_builder_new ();
+ gtk_builder_add_objects_from_file (builder,
+ GTKBUILDERDIR "/acme.ui",
+ (char **) objects,
+ NULL);
+
+ window->priv->image = GTK_IMAGE (gtk_builder_get_object (builder, "acme_image"));
+ window->priv->progress = GTK_WIDGET (gtk_builder_get_object (builder, "acme_volume_progressbar"));
+ frame = GTK_WIDGET (gtk_builder_get_object (builder,
+ "acme_frame"));
+
+ if (frame != NULL) {
+ gtk_container_add (GTK_CONTAINER (window), frame);
+ gtk_widget_show_all (frame);
+ }
+
+ /* The builder needs to stay alive until the window
+ takes ownership of the frame (and its children) */
+ g_object_unref (builder);
+ }
+}
+
+GtkWidget *
+gsd_media_keys_window_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (GSD_TYPE_MEDIA_KEYS_WINDOW,
+ "type", GTK_WINDOW_POPUP,
+ "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION,
+ "skip-taskbar-hint", TRUE,
+ "skip-pager-hint", TRUE,
+ "focus-on-map", FALSE,
+ NULL);
+
+ return GTK_WIDGET (object);
+}
diff --git a/src/gsd-media-keys-window.h b/src/gsd-media-keys-window.h
new file mode 100644
index 0000000..9c74bf5
--- /dev/null
+++ b/src/gsd-media-keys-window.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef GSD_MEDIA_KEYS_WINDOW_H
+#define GSD_MEDIA_KEYS_WINDOW_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_MEDIA_KEYS_WINDOW (gsd_media_keys_window_get_type ())
+#define GSD_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindow))
+#define GSD_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowClass))
+#define GSD_IS_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_MEDIA_KEYS_WINDOW))
+#define GSD_IS_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), GSD_TYPE_MEDIA_KEYS_WINDOW))
+
+typedef struct GsdMediaKeysWindow GsdMediaKeysWindow;
+typedef struct GsdMediaKeysWindowClass GsdMediaKeysWindowClass;
+typedef struct GsdMediaKeysWindowPrivate GsdMediaKeysWindowPrivate;
+
+struct GsdMediaKeysWindow {
+ GtkWindow parent;
+
+ GsdMediaKeysWindowPrivate *priv;
+};
+
+struct GsdMediaKeysWindowClass {
+ GtkWindowClass parent_class;
+};
+
+typedef enum {
+ GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME,
+ GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM
+} GsdMediaKeysWindowAction;
+
+GType gsd_media_keys_window_get_type (void);
+
+GtkWidget * gsd_media_keys_window_new (void);
+void gsd_media_keys_window_set_action (GsdMediaKeysWindow *window,
+ GsdMediaKeysWindowAction action);
+void gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow *window,
+ const char *icon_name,
+ gboolean show_level);
+void gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window,
+ gboolean muted);
+void gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window,
+ int level);
+gboolean gsd_media_keys_window_is_valid (GsdMediaKeysWindow *window);
+
+G_END_DECLS
+
+#endif
diff --git a/src/org.mate.PowerManager.Backlight.xml b/src/org.mate.PowerManager.Backlight.xml
new file mode 100644
index 0000000..0d1ae87
--- /dev/null
+++ b/src/org.mate.PowerManager.Backlight.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.mate.PowerManager.Backlight">
+ <method name="GetBrightness">
+ <arg type="u" name="percentage_brightness" direction="out"/>
+ </method>
+ <method name="SetBrightness">
+ <arg type="u" name="percentage_brightness" direction="in"/>
+ </method>
+ <signal name="BrightnessChanged">
+ <arg type="u" name="percentage_brightness" direction="out"/>
+ </signal>
+ </interface>
+</node>
+
diff --git a/src/org.mate.PowerManager.xml b/src/org.mate.PowerManager.xml
new file mode 100644
index 0000000..a5ca988
--- /dev/null
+++ b/src/org.mate.PowerManager.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/">
+ <interface name="org.mate.PowerManager">
+ <method name="GetPreferencesOptions">
+ <arg type="i" name="capability" direction="out"/>
+ </method>
+ </interface>
+</node>
+