diff options
author | Stefano Karapetsas <[email protected]> | 2011-12-11 12:55:19 +0100 |
---|---|---|
committer | Stefano Karapetsas <[email protected]> | 2011-12-11 12:55:19 +0100 |
commit | 51175189c6d7313a3b84019e39496f957c4e6164 (patch) | |
tree | e4c2c130fa3140bca28685ef900f04a012e53dcd /src | |
download | mate-power-manager-51175189c6d7313a3b84019e39496f957c4e6164.tar.bz2 mate-power-manager-51175189c6d7313a3b84019e39496f957c4e6164.tar.xz |
moved from Mate-Extra
Diffstat (limited to 'src')
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, ¤t_state, ¤t_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, ¤t_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) ¬ification); + *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, ¤t_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> + |