summaryrefslogtreecommitdiff
path: root/sensors-applet
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2011-11-21 23:44:15 +0100
committerStefano Karapetsas <[email protected]>2011-11-21 23:44:15 +0100
commit69ecddf1317e71f35b1c1de00392dc76f8f1701c (patch)
treeaba29401d8d4b88f14d67aac2b0e60980a78fa2e /sensors-applet
downloadmate-sensors-applet-69ecddf1317e71f35b1c1de00392dc76f8f1701c.tar.bz2
mate-sensors-applet-69ecddf1317e71f35b1c1de00392dc76f8f1701c.tar.xz
Initial release bases on sensors-applet
Diffstat (limited to 'sensors-applet')
-rw-r--r--sensors-applet/Makefile.am50
-rw-r--r--sensors-applet/Makefile.in678
-rw-r--r--sensors-applet/about-dialog.c56
-rw-r--r--sensors-applet/about-dialog.h27
-rw-r--r--sensors-applet/active-sensor-libnotify.c113
-rw-r--r--sensors-applet/active-sensor-libnotify.h35
-rw-r--r--sensors-applet/active-sensor.c835
-rw-r--r--sensors-applet/active-sensor.h73
-rw-r--r--sensors-applet/config.h.in134
-rw-r--r--sensors-applet/main.c46
-rw-r--r--sensors-applet/prefs-dialog.c1009
-rw-r--r--sensors-applet/prefs-dialog.h70
-rw-r--r--sensors-applet/sensor-config-dialog.c918
-rw-r--r--sensors-applet/sensor-config-dialog.h28
-rw-r--r--sensors-applet/sensors-applet-gconf.c492
-rw-r--r--sensors-applet/sensors-applet-gconf.h91
-rw-r--r--sensors-applet/sensors-applet-plugin.h72
-rw-r--r--sensors-applet/sensors-applet-plugins.c157
-rw-r--r--sensors-applet/sensors-applet-plugins.h36
-rw-r--r--sensors-applet/sensors-applet-sensor.h64
-rw-r--r--sensors-applet/sensors-applet.c1451
-rw-r--r--sensors-applet/sensors-applet.h186
22 files changed, 6621 insertions, 0 deletions
diff --git a/sensors-applet/Makefile.am b/sensors-applet/Makefile.am
new file mode 100644
index 0000000..a87feb0
--- /dev/null
+++ b/sensors-applet/Makefile.am
@@ -0,0 +1,50 @@
+## Process this file with automake to produce Makefile.in
+INCLUDES = -DGNOMELOCALEDIR=\""$(datadir)/locale/"\" \
+ -DG_LOG_DOMAIN=\""Sensors Applet"\" \
+ -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(libdir)"\" \
+ -DSENSORS_APPLET_PLUGIN_DIR=\""$(libdir)/$(PACKAGE)/plugins/"\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DPREFIX=\""$(prefix)"\" \
+ -I$(top_srcdir) \
+ $(GLIB_CFLAGS) $(GTK_CFLAGS) $(GNOME_CFLAGS) $(CAIRO_CFLAGS) $(LIBNOTIFY_CFLAGS)
+
+
+LIBS = $(GLIB_LIBS) $(GTK_LIBS) $(GNOME_LIBS) $(CAIRO_LIBS) $(LIBNOTIFY_LIBS)
+
+if LIBNOTIFY
+libnotify_SRC = active-sensor-libnotify.c \
+ active-sensor-libnotify.h
+else
+libnotify_SRC =
+endif
+
+libexec_PROGRAMS = sensors-applet
+sensors_applet_SOURCES = main.c \
+ about-dialog.c \
+ about-dialog.h \
+ active-sensor.c \
+ active-sensor.h \
+ prefs-dialog.c \
+ prefs-dialog.h \
+ sensor-config-dialog.c \
+ sensor-config-dialog.h \
+ sensors-applet.c \
+ sensors-applet.h \
+ sensors-applet-sensor.h \
+ sensors-applet-plugins.c \
+ sensors-applet-plugins.h \
+ sensors-applet-gconf.c \
+ sensors-applet-gconf.h \
+ $(libnotify_SRC)
+
+# install headers for plugins to use
+INST_H_FILES = sensors-applet-plugin.h sensors-applet-sensor.h
+
+headerdir = $(prefix)/include/sensors-applet
+
+header_DATA = $(INST_H_FILES)
+
+# since it is separate
+EXTRA_DIST = sensors-applet-plugin.h \ No newline at end of file
diff --git a/sensors-applet/Makefile.in b/sensors-applet/Makefile.in
new file mode 100644
index 0000000..dd6765f
--- /dev/null
+++ b/sensors-applet/Makefile.in
@@ -0,0 +1,678 @@
+# 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@
+libexec_PROGRAMS = sensors-applet$(EXEEXT)
+subdir = sensors-applet
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/config.h.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(headerdir)"
+PROGRAMS = $(libexec_PROGRAMS)
+am__sensors_applet_SOURCES_DIST = main.c about-dialog.c about-dialog.h \
+ active-sensor.c active-sensor.h prefs-dialog.c prefs-dialog.h \
+ sensor-config-dialog.c sensor-config-dialog.h sensors-applet.c \
+ sensors-applet.h sensors-applet-sensor.h \
+ sensors-applet-plugins.c sensors-applet-plugins.h \
+ sensors-applet-gconf.c sensors-applet-gconf.h \
+ active-sensor-libnotify.c active-sensor-libnotify.h
+@LIBNOTIFY_TRUE@am__objects_1 = active-sensor-libnotify.$(OBJEXT)
+am_sensors_applet_OBJECTS = main.$(OBJEXT) about-dialog.$(OBJEXT) \
+ active-sensor.$(OBJEXT) prefs-dialog.$(OBJEXT) \
+ sensor-config-dialog.$(OBJEXT) sensors-applet.$(OBJEXT) \
+ sensors-applet-plugins.$(OBJEXT) \
+ sensors-applet-gconf.$(OBJEXT) $(am__objects_1)
+sensors_applet_OBJECTS = $(am_sensors_applet_OBJECTS)
+sensors_applet_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I.@am__isrc@
+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) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(sensors_applet_SOURCES)
+DIST_SOURCES = $(am__sensors_applet_SOURCES_DIST)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+DATA = $(header_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AR = @AR@
+ATICONFIG_EXE = @ATICONFIG_EXE@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUSGLIB_CFLAGS = @DBUSGLIB_CFLAGS@
+DBUSGLIB_LIBS = @DBUSGLIB_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
+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@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_LIBS = @GLIB_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GNOME_CFLAGS = @GNOME_CFLAGS@
+GNOME_LIBS = @GNOME_LIBS@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+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@
+LIBATASMART_CFLAGS = @LIBATASMART_CFLAGS@
+LIBATASMART_LIBS = @LIBATASMART_LIBS@
+LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@
+LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = $(GLIB_LIBS) $(GTK_LIBS) $(GNOME_LIBS) $(CAIRO_LIBS) $(LIBNOTIFY_LIBS)
+LIBSENSORS_CFLAGS = @LIBSENSORS_CFLAGS@
+LIBSENSORS_LIBS = @LIBSENSORS_LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NVIDIA_CFLAGS = @NVIDIA_CFLAGS@
+NVIDIA_LIBS = @NVIDIA_LIBS@
+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@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PLUGIN_LIBTOOL_FLAGS = @PLUGIN_LIBTOOL_FLAGS@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XSLTPROC = @XSLTPROC@
+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@
+INCLUDES = -DGNOMELOCALEDIR=\""$(datadir)/locale/"\" \
+ -DG_LOG_DOMAIN=\""Sensors Applet"\" \
+ -DPIXMAPS_DIR=\""$(datadir)/pixmaps/$(PACKAGE)/"\" \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(libdir)"\" \
+ -DSENSORS_APPLET_PLUGIN_DIR=\""$(libdir)/$(PACKAGE)/plugins/"\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DPREFIX=\""$(prefix)"\" \
+ -I$(top_srcdir) \
+ $(GLIB_CFLAGS) $(GTK_CFLAGS) $(GNOME_CFLAGS) $(CAIRO_CFLAGS) $(LIBNOTIFY_CFLAGS)
+
+@LIBNOTIFY_FALSE@libnotify_SRC =
+@LIBNOTIFY_TRUE@libnotify_SRC = active-sensor-libnotify.c \
+@LIBNOTIFY_TRUE@ active-sensor-libnotify.h
+
+sensors_applet_SOURCES = main.c \
+ about-dialog.c \
+ about-dialog.h \
+ active-sensor.c \
+ active-sensor.h \
+ prefs-dialog.c \
+ prefs-dialog.h \
+ sensor-config-dialog.c \
+ sensor-config-dialog.h \
+ sensors-applet.c \
+ sensors-applet.h \
+ sensors-applet-sensor.h \
+ sensors-applet-plugins.c \
+ sensors-applet-plugins.h \
+ sensors-applet-gconf.c \
+ sensors-applet-gconf.h \
+ $(libnotify_SRC)
+
+
+# install headers for plugins to use
+INST_H_FILES = sensors-applet-plugin.h sensors-applet-sensor.h
+headerdir = $(prefix)/include/sensors-applet
+header_DATA = $(INST_H_FILES)
+
+# since it is separate
+EXTRA_DIST = sensors-applet-plugin.h
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu sensors-applet/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu sensors-applet/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status sensors-applet/config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || 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)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || 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)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_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
+sensors-applet$(EXEEXT): $(sensors_applet_OBJECTS) $(sensors_applet_DEPENDENCIES)
+ @rm -f sensors-applet$(EXEEXT)
+ $(LINK) $(sensors_applet_OBJECTS) $(sensors_applet_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/about-dialog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/active-sensor-libnotify.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/active-sensor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefs-dialog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sensor-config-dialog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sensors-applet-gconf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sensors-applet-plugins.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sensors-applet.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@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@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@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 $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-headerDATA: $(header_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(headerdir)" || $(MKDIR_P) "$(DESTDIR)$(headerdir)"
+ @list='$(header_DATA)'; test -n "$(headerdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(headerdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(headerdir)" || exit $$?; \
+ done
+
+uninstall-headerDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(header_DATA)'; test -n "$(headerdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(headerdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(headerdir)" && rm -f $$files
+
+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) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(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) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA) config.h
+installdirs:
+ for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(headerdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(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:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-headerDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libexecPROGRAMS
+
+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-headerDATA uninstall-libexecPROGRAMS
+
+.MAKE: all install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libexecPROGRAMS clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-headerDATA install-html \
+ install-html-am install-info install-info-am \
+ install-libexecPROGRAMS install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-headerDATA \
+ uninstall-libexecPROGRAMS
+
+
+# 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/sensors-applet/about-dialog.c b/sensors-applet/about-dialog.c
new file mode 100644
index 0000000..27a86f1
--- /dev/null
+++ b/sensors-applet/about-dialog.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <gnome.h>
+#include "about-dialog.h"
+
+void about_dialog_open(SensorsApplet *sensors_applet) {
+ gchar *translator;
+ const gchar *authors[] = {
+ "Alex Murray <[email protected]>",
+ NULL
+ };
+
+ if (_("Translator") == "Translator") {
+ translator = NULL;
+ } else {
+ translator = g_strdup(_("To translator: Put your name here to show up in the About dialog as the translator"));
+ }
+
+ /* Construct the about dialog */
+ gtk_show_about_dialog(NULL,
+ "program-name", PACKAGE_NAME,
+ "version", PACKAGE_VERSION,
+ "copyright", "(C) 2005-2009, Alex Murray <[email protected]>",
+ "authors", authors,
+ "documenters", authors,
+ "translator-credits", translator,
+ "logo-icon-name", SENSORS_APPLET_ICON,
+ "website", "http://sensors-applet.sourceforge.net/",
+ NULL);
+
+
+ if (translator != NULL) {
+ g_free(translator);
+ }
+
+}
diff --git a/sensors-applet/about-dialog.h b/sensors-applet/about-dialog.h
new file mode 100644
index 0000000..01537e0
--- /dev/null
+++ b/sensors-applet/about-dialog.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 ABOUT_DIALOG_H
+#define ABOUT_DIALOG_H
+
+#include "sensors-applet.h"
+
+/* function prototypes */
+void about_dialog_open(SensorsApplet *sensors_applet);
+
+#endif /* ABOUT_DIALOG_H */
diff --git a/sensors-applet/active-sensor-libnotify.c b/sensors-applet/active-sensor-libnotify.c
new file mode 100644
index 0000000..e69b005
--- /dev/null
+++ b/sensors-applet/active-sensor-libnotify.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_LIBNOTIFY
+#include <libnotify/notify.h>
+#endif
+
+#include "active-sensor-libnotify.h"
+
+static void notif_closed_cb(NotifyNotification *notification,
+ ActiveSensor *active_sensor)
+{
+ g_assert(notification != NULL && active_sensor != NULL);
+
+ int i;
+
+ g_debug("Notification was closed.. setting reference to NULL so we can show again if needed.");
+
+ // set notif reference to NULL
+ for (i = 0; i < NUM_NOTIFS; i++) {
+ if (active_sensor->notification[i] == notification) {
+ active_sensor->notification[i] = NULL;
+ break;
+ }
+ }
+}
+
+
+void active_sensor_libnotify_notify_end(ActiveSensor *active_sensor,
+ NotifType notif_type) {
+ GError *error = NULL;
+ if (active_sensor->notification[notif_type]) {
+ g_debug("Closing notification");
+ if(!notify_notification_close(active_sensor->notification[notif_type],
+ &error)) {
+ g_warning("Error closing notification: %s", error->message);
+ g_error_free(error);
+ }
+ g_object_unref(active_sensor->notification[notif_type]);
+ active_sensor->notification[notif_type] = NULL;
+ }
+}
+
+void active_sensor_libnotify_notify(ActiveSensor *active_sensor,
+ NotifType notif_type,
+ const gchar *summary,
+ const gchar *message,
+ const gchar *icon_filename,
+ gint timeout_msecs,
+ GtkWidget *attach) {
+ GError *error = NULL;
+
+ if (!notify_is_initted()) {
+ if (!notify_init(PACKAGE)) {
+ return;
+ }
+ }
+ g_debug("Doing notification %s: %s: %s", (notif_type == SENSOR_INTERFACE_ERROR ? "interface-error" : "other") ,summary, message);
+
+ /* leave any existing notification since most likely hasn't changed */
+ if (active_sensor->notification[notif_type] != NULL) {
+ return;
+/* active_sensor_libnotify_notify_end(active_sensor, notif_type); */
+ }
+
+ /* now create a new one */
+ g_debug("Creating new notification");
+ active_sensor->notification[notif_type] = notify_notification_new(summary,
+ message,
+ icon_filename,
+ attach);
+ g_signal_connect(active_sensor->notification[notif_type], "closed",
+ G_CALLBACK(notif_closed_cb),
+ active_sensor);
+
+ notify_notification_set_urgency(active_sensor->notification[notif_type],
+ NOTIFY_URGENCY_CRITICAL);
+
+
+ /* timeout may have changed so update it */
+ notify_notification_set_timeout(active_sensor->notification[notif_type],
+ timeout_msecs);
+
+
+ g_debug("showing notification");
+ if (!notify_notification_show(active_sensor->notification[notif_type], &error)) {
+ g_debug("Error showing notification: %s", error->message);
+ g_error_free(error);
+ }
+
+
+
+}
+
diff --git a/sensors-applet/active-sensor-libnotify.h b/sensors-applet/active-sensor-libnotify.h
new file mode 100644
index 0000000..3c81c88
--- /dev/null
+++ b/sensors-applet/active-sensor-libnotify.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 ACTIVE_SESNOR_LIBNOTIFY_H
+#define ACTIVE_SENSOR_LIBNOTIFY_H
+
+#include "sensors-applet.h"
+#include "active-sensor.h"
+
+void active_sensor_libnotify_notify(ActiveSensor *active_sensor,
+ NotifType notif_type,
+ const gchar *summary,
+ const gchar *message,
+ const gchar *icon_filename,
+ gint timeout_msecs,
+ GtkWidget *attach);
+void active_sensor_libnotify_notify_end(ActiveSensor *active_sensor,
+ NotifType notif_type);
+
+#endif /* SENSORS_APPLET_LIBNOTIFY_H */
diff --git a/sensors-applet/active-sensor.c b/sensors-applet/active-sensor.c
new file mode 100644
index 0000000..84b84cc
--- /dev/null
+++ b/sensors-applet/active-sensor.c
@@ -0,0 +1,835 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+
+#include <gconf/gconf-client.h>
+#include <gnome.h>
+
+#include "active-sensor.h"
+#include "sensors-applet-plugins.h"
+#include "sensors-applet-gconf.h"
+
+typedef enum {
+ VERY_LOW_SENSOR_VALUE = 0,
+ LOW_SENSOR_VALUE,
+ NORMAL_SENSOR_VALUE,
+ HIGH_SENSOR_VALUE,
+ VERY_HIGH_SENSOR_VALUE
+} SensorValueRange;
+
+/* Cast a given value to a valid SensorValueRange */
+#define SENSOR_VALUE_RANGE(x) ((SensorValueRange)(CLAMP(x, VERY_LOW_SENSOR_VALUE, VERY_HIGH_SENSOR_VALUE)))
+
+#define CAIRO_GRAPH_COLOR_GRADIENT 0.4
+
+static const gchar * const temp_overlay_icons[] = {
+ PIXMAPS_DIR "very-low-temp-icon.png",
+ PIXMAPS_DIR "low-temp-icon.png",
+ PIXMAPS_DIR "normal-temp-icon.png",
+ PIXMAPS_DIR "high-temp-icon.png",
+ PIXMAPS_DIR "very-high-temp-icon.png"
+};
+
+static gdouble sensor_value_range_normalised(gdouble value,
+ gdouble low_value,
+ gdouble high_value) {
+ return ((value - low_value)/(high_value - low_value));
+}
+
+static SensorValueRange sensor_value_range(gdouble sensor_value,
+ gdouble low_value,
+ gdouble high_value) {
+ gdouble range;
+ range = sensor_value_range_normalised(sensor_value, low_value, high_value)*(gdouble)(VERY_HIGH_SENSOR_VALUE);
+
+ /* check if need to round up, otherwise let int conversion
+ * round down for us and make sure it is a valid range
+ * value */
+ return SENSOR_VALUE_RANGE(((gint)range + ((range - ((gint)range)) >= 0.5)));
+}
+
+
+static gboolean active_sensor_execute_alarm(ActiveSensor *active_sensor,
+ NotifType notif_type) {
+ int pid;
+
+ sensors_applet_notify_active_sensor(active_sensor, notif_type);
+ g_debug("EXECUTING %s ALARM: %s",
+ (notif_type == LOW_ALARM ?
+ "LOW" : "HIGH"),
+ active_sensor->alarm_command[notif_type]);
+ pid = gnome_execute_shell(NULL,
+ active_sensor->alarm_command[notif_type]);
+ g_debug("Command executed in shell with pid %d", pid);
+
+ return (pid != -1);
+}
+
+static gboolean active_sensor_execute_low_alarm(ActiveSensor *active_sensor) {
+ return active_sensor_execute_alarm(active_sensor, LOW_ALARM);
+}
+
+static gboolean active_sensor_execute_high_alarm(ActiveSensor *active_sensor) {
+ return active_sensor_execute_alarm(active_sensor, HIGH_ALARM);
+}
+
+/* needs to be able to be called by the config dialog when the alarm
+ * command changes */
+void active_sensor_alarm_off(ActiveSensor *active_sensor,
+ NotifType notif_type) {
+ g_assert(active_sensor);
+
+ if (active_sensor->alarm_timeout_id[notif_type] != -1) {
+ g_debug("Disabling %s alarm.",
+ (notif_type == LOW_ALARM ? "LOW" : "HIGH"));
+ if (!g_source_remove(active_sensor->alarm_timeout_id[notif_type])) {
+ g_debug("Error removing alarm source");
+ }
+ g_free(active_sensor->alarm_command[notif_type]);
+ active_sensor->alarm_timeout_id[notif_type] = -1;
+
+ }
+ sensors_applet_notify_end(active_sensor, notif_type);
+}
+
+static void active_sensor_all_alarms_off(ActiveSensor *active_sensor) {
+ /* turn off any alarms */
+ int i;
+ for (i = 0; i < NUM_ALARMS; i++) {
+ if (active_sensor->alarm_timeout_id[i] >= 0) {
+ g_debug("-- turning off notif with type %d ---", i);
+ active_sensor_alarm_off(active_sensor, i);
+ }
+ }
+}
+
+static void active_sensor_alarm_on(ActiveSensor *active_sensor,
+ NotifType notif_type) {
+ GtkTreeModel *model;
+ GtkTreePath *tree_path;
+ GtkTreeIter iter;
+
+ g_assert(active_sensor);
+
+ model = gtk_tree_row_reference_get_model(active_sensor->sensor_row);
+ tree_path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
+
+ if (gtk_tree_model_get_iter(model, &iter, tree_path)) {
+
+ if (active_sensor->alarm_timeout_id[notif_type] == -1) {
+ /* alarm is not currently on */
+ gtk_tree_model_get(model,
+ &iter,
+ (notif_type == LOW_ALARM ?
+ LOW_ALARM_COMMAND_COLUMN :
+ HIGH_ALARM_COMMAND_COLUMN),
+ &(active_sensor->alarm_command[notif_type]),
+ ALARM_TIMEOUT_COLUMN, &(active_sensor->alarm_timeout),
+ -1);
+ g_debug("Activating alarm to repeat every %d seconds", active_sensor->alarm_timeout);
+
+ /* execute alarm once, then add to time to
+ keep repeating it */
+ active_sensor_execute_alarm(active_sensor, notif_type);
+ int timeout = (active_sensor->alarm_timeout <= 0 ?
+ G_MAXINT :
+ active_sensor->alarm_timeout);
+ switch (notif_type) {
+ case LOW_ALARM:
+ active_sensor->alarm_timeout_id[notif_type] = g_timeout_add_seconds(timeout,
+ (GSourceFunc)active_sensor_execute_low_alarm,
+ active_sensor);
+ break;
+ case HIGH_ALARM:
+ active_sensor->alarm_timeout_id[notif_type] = g_timeout_add_seconds(timeout,
+ (GSourceFunc)active_sensor_execute_high_alarm,
+ active_sensor);
+ break;
+ default:
+ g_debug("Unkown notif type: %d", notif_type);
+ }
+
+
+ }
+ }
+ gtk_tree_path_free(tree_path);
+
+}
+
+/**
+ * Compares two ActiveSensors and returns -1 if a comes before b in the tree,
+ * 0 if refer to same row, 1 if b comes before a
+ */
+gint active_sensor_compare(ActiveSensor *a, ActiveSensor *b) {
+ GtkTreePath *a_tree_path, *b_tree_path;
+ gint ret_val;
+
+ g_assert(a);
+ g_assert(b);
+
+ a_tree_path = gtk_tree_row_reference_get_path(a->sensor_row);
+ b_tree_path = gtk_tree_row_reference_get_path(b->sensor_row);
+
+ ret_val = gtk_tree_path_compare(a_tree_path, b_tree_path);
+
+ gtk_tree_path_free(a_tree_path);
+ gtk_tree_path_free(b_tree_path);
+
+ return ret_val;
+}
+
+static void active_sensor_update_icon(ActiveSensor *active_sensor,
+ GdkPixbuf *base_icon,
+ SensorType sensor_type) {
+
+ GdkPixbuf *overlay_icon, *new_icon;
+ const gchar *overlay_icon_filename = NULL;
+ SensorValueRange value_range;
+
+ g_assert(active_sensor);
+
+ /* select overlay icon
+ * depending on sensor
+ * value */
+ value_range = sensor_value_range(active_sensor->sensor_values[0],
+ active_sensor->sensor_low_value,
+ active_sensor->sensor_high_value);
+
+ if (sensor_type == TEMP_SENSOR) {
+ overlay_icon_filename = temp_overlay_icons[value_range];
+ }
+
+ /* load base icon */
+ new_icon = gdk_pixbuf_copy(base_icon);
+
+ /* only load overlay if required */
+ if (overlay_icon_filename) {
+ overlay_icon = gdk_pixbuf_new_from_file_at_size(overlay_icon_filename,
+ DEFAULT_ICON_SIZE,
+ DEFAULT_ICON_SIZE,
+ NULL);
+ if (overlay_icon) {
+ gdk_pixbuf_composite(overlay_icon, new_icon,
+ 0, 0,
+ DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE,
+ 0, 0,
+ 1.0, 1.0,
+ GDK_INTERP_BILINEAR,
+ 255);
+
+ g_object_unref(overlay_icon);
+ }
+ }
+ gtk_image_set_from_pixbuf(GTK_IMAGE(active_sensor->icon),
+ new_icon);
+ g_object_unref(new_icon);
+
+}
+
+static void active_sensor_update_graph(ActiveSensor *as) {
+ gdouble line_height;
+ gdouble width, height;
+ gdouble x, y;
+ cairo_t *cr;
+ cairo_pattern_t *pattern;
+ gint i;
+ GdkPixmap *pixmap;
+
+ width = as->graph->allocation.width;
+ height = as->graph->allocation.height;
+
+ /* only do if drawable - will not be drawable if not currently
+ * displayed on screen */
+ if (GDK_IS_DRAWABLE(as->graph->window)) {
+ /* use pixmap, draw to it, then use gdk to draw the
+ * pixmap onto the drawable surface of the graph to
+ * stop flickering */
+ pixmap = gdk_pixmap_new(as->graph->window,
+ width, height, -1);
+
+ cr = gdk_cairo_create(pixmap);
+
+ /* so we can set a clipping area, as well as fill the
+ * back of the graph black */
+ cairo_rectangle(cr,
+ 0, 0,
+ width,
+ height);
+ /* clip to rectangle and keep it as a path so can be
+ * filled below */
+ cairo_clip_preserve(cr);
+
+ /* use black for bg color of graphs */
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ cairo_fill(cr);
+
+
+ /* determine height to scale line at for each value -
+ * only do as many as will fit or the number of
+ * samples that we have */
+ for (i = 0; i < MIN(as->num_samples, width); i++) {
+ /* need to remove one more to make it line up
+ * properly when drawing */
+ x = width - i - 1;
+ y = height;
+
+ line_height = sensor_value_range_normalised(as->sensor_values[i],
+ as->sensor_low_value,
+ as->sensor_high_value) * height;
+
+
+
+ if (line_height > 0) {
+ cairo_move_to(cr,
+ x,
+ y);
+ cairo_line_to(cr, x,
+ y - line_height);
+ }
+
+ }
+ /* make lines a gradient from slightly darker than
+ * chosen color at bottom of graph, to slightly
+ * lighter than chosen color at top of graph */
+ pattern = cairo_pattern_create_linear(x, y,
+ x, 0);
+ cairo_pattern_add_color_stop_rgb(pattern,
+ 0,
+ as->graph_color.red / 65535.0 - CAIRO_GRAPH_COLOR_GRADIENT,
+ as->graph_color.green / 65535.0 - CAIRO_GRAPH_COLOR_GRADIENT,
+ as->graph_color.blue / 65535.0 - CAIRO_GRAPH_COLOR_GRADIENT);
+
+ cairo_pattern_add_color_stop_rgb(pattern,
+ height,
+ as->graph_color.red / 65535.0 + CAIRO_GRAPH_COLOR_GRADIENT,
+ as->graph_color.green / 65535.0 + CAIRO_GRAPH_COLOR_GRADIENT,
+ as->graph_color.blue / 65535.0 + CAIRO_GRAPH_COLOR_GRADIENT);
+
+ cairo_set_source(cr, pattern);
+ cairo_stroke(cr);
+ cairo_pattern_destroy(pattern);
+ cairo_destroy(cr);
+
+ /* now draw pixmap onto drawable surface */
+ gdk_draw_drawable(as->graph->window,
+ as->graph->style->fg_gc[GTK_WIDGET_STATE(as->graph)],
+ pixmap,
+ 0, 0,
+ 0, 0,
+ -1, -1);
+ /* don't need pixmap anymore */
+ g_object_unref(pixmap);
+ }
+}
+
+void active_sensor_destroy(ActiveSensor *active_sensor) {
+ g_debug("-- destroying active sensor label...");
+ gtk_object_destroy(GTK_OBJECT(active_sensor->label));
+
+ g_debug("-- destroying active sensor icon..");
+ gtk_object_destroy(GTK_OBJECT(active_sensor->icon));
+
+ g_debug("-- destroying active sensor value...");
+ gtk_object_destroy(GTK_OBJECT(active_sensor->value));
+
+ g_debug("-- destroying active sensor graph and frame...");
+ gtk_object_destroy(GTK_OBJECT(active_sensor->graph));
+ gtk_object_destroy(GTK_OBJECT(active_sensor->graph_frame));
+
+ g_debug("-- destroying active sensor values...");
+ g_free(active_sensor->sensor_values);
+
+ active_sensor_all_alarms_off(active_sensor);
+
+ g_free(active_sensor);
+}
+
+
+gboolean graph_expose_event_cb(GtkWidget *graph,
+ GdkEventExpose *event,
+ gpointer data) {
+ ActiveSensor *as;
+
+ as = (ActiveSensor *)data;
+
+ active_sensor_update_graph(as);
+ /* propagate event onwards */
+ return FALSE;
+}
+
+static void active_sensor_set_graph_dimensions(ActiveSensor *as,
+ gint width,
+ gint height) {
+ gdouble *old_values;
+ gint num_samples, old_num_samples;
+ gint graph_width, graph_height;
+
+ /* dimensions are really for graph frame, so need to remove
+ * extra width added by graph frame - make sure not less than
+ * 1 - always need atleast 1 sample */
+ graph_width = CLAMP(width - GRAPH_FRAME_EXTRA_WIDTH, 1, width - GRAPH_FRAME_EXTRA_WIDTH);
+ graph_height = CLAMP(height - GRAPH_FRAME_EXTRA_WIDTH, 1 , height - GRAPH_FRAME_EXTRA_WIDTH);
+
+ g_debug("setting graph dimensions to %d x %d", graph_width, graph_height);
+ num_samples = graph_width;
+
+ if (as->sensor_values) {
+ old_values = as->sensor_values;
+ old_num_samples = as->num_samples;
+
+ as->num_samples = num_samples;
+ as->sensor_values = g_malloc0(sizeof(gdouble)*as->num_samples);
+ memcpy(as->sensor_values,
+ old_values,
+ MIN(old_num_samples, as->num_samples)*sizeof(gdouble));
+
+ g_free(old_values);
+ } else {
+ as->sensor_values = g_malloc0(sizeof(gdouble)*num_samples);
+ as->num_samples = num_samples;
+ }
+
+ /* update graph frame size request */
+ gtk_widget_set_size_request(as->graph,
+ graph_width,
+ graph_height);
+}
+
+void active_sensor_update_graph_dimensions(ActiveSensor *as,
+ gint sizes[2]) {
+ active_sensor_set_graph_dimensions(as, sizes[0], sizes[1]);
+ active_sensor_update_graph(as);
+}
+
+ActiveSensor *active_sensor_new(SensorsApplet *sensors_applet,
+ GtkTreeRowReference *sensor_row) {
+ ActiveSensor *active_sensor;
+ PanelAppletOrient orient;
+ gint graph_size;
+ gboolean horizontal;
+
+ g_assert(sensors_applet);
+ g_assert(sensor_row);
+
+ g_debug("creating new active sensor");
+
+ active_sensor = g_new0(ActiveSensor, 1);
+ active_sensor->sensors_applet = sensors_applet;
+
+ active_sensor->sensor_row = sensor_row;
+
+ int i;
+ for (i = 0; i < NUM_NOTIFS; i++) {
+ active_sensor->alarm_timeout_id[i] = -1;
+ }
+
+ active_sensor->label = gtk_label_new("");
+ active_sensor->value = gtk_label_new("");
+ active_sensor->icon = gtk_image_new();
+
+ active_sensor->graph = gtk_drawing_area_new();
+ active_sensor->graph_frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(active_sensor->graph_frame),
+ GTK_SHADOW_IN);
+ gtk_container_add(GTK_CONTAINER(active_sensor->graph_frame),
+ active_sensor->graph);
+ gtk_widget_add_events(active_sensor->graph_frame,
+ GDK_ALL_EVENTS_MASK);
+
+ /* need to set size according to orientation */
+ orient = panel_applet_get_orient(active_sensor->sensors_applet->applet);
+ graph_size = panel_applet_gconf_get_int(active_sensor->sensors_applet->applet,
+ GRAPH_SIZE, NULL);
+
+ horizontal = ((orient == PANEL_APPLET_ORIENT_UP) ||
+ (orient == PANEL_APPLET_ORIENT_DOWN));
+
+ active_sensor_set_graph_dimensions(active_sensor,
+ (horizontal ? graph_size : sensors_applet->size),
+ (horizontal ? sensors_applet->size : graph_size));
+
+ g_signal_connect(G_OBJECT(active_sensor->graph),
+ "expose_event",
+ G_CALLBACK(graph_expose_event_cb),
+ active_sensor);
+
+ active_sensor->updated = FALSE;
+ return active_sensor;
+}
+
+static void active_sensor_update_sensor_value(ActiveSensor *as,
+ gdouble sensor_value) {
+
+ /* only if have more than 1 sample stored */
+ if (as->num_samples > 1) {
+ memmove(&(as->sensor_values[1]),
+ as->sensor_values,
+ (as->num_samples - 1)*sizeof(gdouble));
+ }
+
+ as->sensor_values[0] = sensor_value;
+}
+
+void active_sensor_update(ActiveSensor *active_sensor,
+ SensorsApplet *sensors_applet) {
+
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ /* instance data from the tree for this sensor */
+ gchar *sensor_path = NULL;
+ gchar *sensor_id = NULL;
+ gchar *sensor_label = NULL;
+ SensorType sensor_type;
+ gchar *sensor_interface;
+ gboolean sensor_enabled;
+ gdouble sensor_low_value;
+ gdouble sensor_high_value;
+ gboolean sensor_alarm_enabled;
+ gdouble sensor_multiplier;
+ gdouble sensor_offset;
+ gdouble sensor_value;
+ GdkPixbuf *icon_pixbuf;
+ gchar *graph_color;
+
+ /* to build the list of labels as we go */
+ gchar *value_text = NULL;
+ gchar *old_value_text;
+
+ TemperatureScale scale;
+ DisplayMode display_mode;
+
+ GError *error = NULL;
+
+ gchar *tooltip = NULL;
+ gchar *value_tooltip = NULL;
+
+ /* hidden gconf options */
+ GConfClient *client;
+ gint font_size = 0;
+ gboolean hide_units = FALSE;
+
+ g_assert(active_sensor);
+ g_assert(active_sensor->sensor_row);
+ g_assert(sensors_applet);
+
+ model = gtk_tree_row_reference_get_model(active_sensor->sensor_row);
+ path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
+
+ /* if can successfully get iter can proceed */
+ if (gtk_tree_model_get_iter(model, &iter, path)) {
+ gtk_tree_path_free(path);
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors),
+ &iter,
+ PATH_COLUMN, &sensor_path,
+ ID_COLUMN, &sensor_id,
+ LABEL_COLUMN, &sensor_label,
+ INTERFACE_COLUMN, &sensor_interface,
+ SENSOR_TYPE_COLUMN, &sensor_type,
+ ENABLE_COLUMN, &sensor_enabled,
+ LOW_VALUE_COLUMN, &sensor_low_value,
+ HIGH_VALUE_COLUMN, &sensor_high_value,
+ ALARM_ENABLE_COLUMN, &sensor_alarm_enabled,
+ MULTIPLIER_COLUMN, &sensor_multiplier,
+ OFFSET_COLUMN, &sensor_offset,
+ ICON_PIXBUF_COLUMN, &icon_pixbuf,
+ GRAPH_COLOR_COLUMN, &graph_color,
+ -1);
+
+
+ SensorsAppletPluginGetSensorValue get_sensor_value;
+ /* only call function if is in hash table for plugin */
+ if ((get_sensor_value = sensors_applet_plugins_get_sensor_value_func(sensors_applet, sensor_interface)) != NULL) {
+ sensor_value = get_sensor_value(sensor_path,
+ sensor_id,
+ sensor_type,
+ &error);
+
+
+ if (error) {
+ g_debug("Error updating active sensor: %s", error->message);
+ sensors_applet_notify_active_sensor(active_sensor,
+ SENSOR_INTERFACE_ERROR);
+
+ /* hard code text as ERROR */
+ value_text = g_strdup(_("ERROR"));
+ value_tooltip = g_strdup_printf("- %s", error->message);
+ g_error_free(error);
+ error = NULL;
+
+ /* set sensor value to an error code -
+ * note this is not unique */
+ sensor_value = -1;
+ } else {
+ /* use hidden gconf key for hide_units */
+
+ if ((client = gconf_client_get_default()) != NULL) {
+ hide_units = gconf_client_get_bool(client,
+ "/apps/sensors-applet/" HIDE_UNITS,
+ &error);
+ if (error) {
+ g_debug("Could not get hide units from GConf - assuming false");
+ hide_units = FALSE;
+ g_error_free(error);
+ error = NULL;
+ }
+
+ g_object_unref(client);
+ }
+
+
+ /* scale value and set text using this
+ * value */
+ switch (sensor_type) {
+ case TEMP_SENSOR:
+
+ scale = (TemperatureScale)panel_applet_gconf_get_int(sensors_applet->applet, TEMPERATURE_SCALE, NULL);
+ /* scale value */
+ sensor_value = sensors_applet_convert_temperature(sensor_value,
+ CELSIUS,
+ scale);
+
+ sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
+ switch (scale) {
+ case FAHRENHEIT:
+ value_text = g_strdup_printf("%2.0f %s", sensor_value, (hide_units ? "" : UNITS_FAHRENHEIT));
+ /* tooltip should
+ * always display
+ * units */
+ value_tooltip = g_strdup_printf("%2.0f %s", sensor_value, UNITS_FAHRENHEIT);
+
+ break;
+ case CELSIUS:
+ value_text = g_strdup_printf("%2.0f %s", sensor_value, (hide_units ? "" : UNITS_CELSIUS));
+ value_tooltip = g_strdup_printf("%2.0f %s", sensor_value, UNITS_CELSIUS);
+ break;
+ case KELVIN:
+ value_text = g_strdup_printf("%2.0f", sensor_value);
+ value_tooltip = g_strdup(value_text);
+ break;
+ }
+ break;
+
+ case FAN_SENSOR:
+ sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
+ value_text = g_strdup_printf("%4.0f %s", sensor_value, (hide_units ? "" : UNITS_RPM));
+ value_tooltip = g_strdup_printf("%4.0f %s", sensor_value, UNITS_RPM);
+
+ break;
+
+ case VOLTAGE_SENSOR:
+ sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
+ value_text = g_strdup_printf("%4.2f %s", sensor_value, (hide_units ? "" : UNITS_VOLTAGE));
+ value_tooltip = g_strdup_printf("%4.2f %s", sensor_value, UNITS_VOLTAGE);
+
+ break;
+
+ case CURRENT_SENSOR:
+ sensor_value = (sensor_value * sensor_multiplier) + sensor_offset;
+ value_text = g_strdup_printf("%4.2f %s", sensor_value, (hide_units ? "" : UNITS_CURRENT));
+ value_tooltip = g_strdup_printf("%4.2f %s", sensor_value, UNITS_CURRENT);
+ break;
+
+ } /* end switch(sensor_type) */
+ } /* end else on error */
+
+ /* setup for tooltips */
+ tooltip = g_strdup_printf("%s %s", sensor_label, value_tooltip);
+ g_free(value_tooltip);
+
+ /* only do icons and labels / graphs if needed */
+ display_mode = panel_applet_gconf_get_int(sensors_applet->applet,
+ DISPLAY_MODE,
+ NULL);
+
+ /* most users wont have a font size set */
+ if ((client = gconf_client_get_default()) != NULL) {
+ font_size = gconf_client_get_int(client,
+ "/apps/sensors-applet/" FONT_SIZE,
+ &error);
+ if (error) {
+ g_debug("Could not get font size from GConf - assuming default size");
+ font_size = 0;
+ g_error_free(error);
+ error = NULL;
+ }
+
+ g_object_unref(client);
+ }
+
+
+ /* do icon if needed */
+ if (display_mode == DISPLAY_ICON ||
+ display_mode == DISPLAY_ICON_WITH_VALUE) {
+ /* update icon if icon range has changed if no
+ * update has been done before */
+ if ((sensor_value_range(sensor_value, sensor_low_value, sensor_high_value) != sensor_value_range(active_sensor->sensor_values[0], active_sensor->sensor_low_value, active_sensor->sensor_high_value)) || !(active_sensor->updated)) {
+ active_sensor_update_sensor_value(active_sensor,
+ sensor_value);
+ active_sensor->sensor_low_value = sensor_low_value;
+ active_sensor->sensor_high_value = sensor_high_value;
+ active_sensor_update_icon(active_sensor, icon_pixbuf, sensor_type);
+ }
+ /* always update tooltip */
+ gtk_widget_set_tooltip_text(active_sensor->icon,
+ tooltip);
+ }
+ active_sensor_update_sensor_value(active_sensor,
+ sensor_value);
+ active_sensor->sensor_low_value = sensor_low_value;
+ active_sensor->sensor_high_value = sensor_high_value;
+
+ /* do graph if needed */
+ if (display_mode == DISPLAY_GRAPH) {
+ /* update graph color in case has changed */
+ gdk_color_parse(graph_color,
+ &(active_sensor->graph_color));
+
+ active_sensor_update_graph(active_sensor);
+ gtk_widget_set_tooltip_text(active_sensor->graph,
+ tooltip);
+
+ }
+
+ old_value_text = value_text;
+
+ if (sensor_alarm_enabled) {
+ if (sensor_value >= sensor_high_value ||
+ sensor_value <= sensor_low_value) {
+ /* make value text red and
+ * activate alarm */
+ if (display_mode == DISPLAY_LABEL_WITH_VALUE ||
+ display_mode == DISPLAY_ICON_WITH_VALUE ||
+ display_mode == DISPLAY_VALUE) {
+ value_text = g_markup_printf_escaped("<span foreground=\"#FF0000\">%s</span>", old_value_text);
+
+ g_free(old_value_text);
+ }
+ /* could have both coditions at once */
+ if (sensor_value >= sensor_high_value) {
+ active_sensor_alarm_on(active_sensor, HIGH_ALARM);
+ }
+
+ if (sensor_value <= sensor_low_value) {
+ active_sensor_alarm_on(active_sensor, LOW_ALARM);
+ }
+
+ } else {
+ /* make sure alarms are off */
+ active_sensor_all_alarms_off(active_sensor);
+ }
+ } else { /* else for if alarm enabled */
+ /* make sure all alarms are off */
+ active_sensor_all_alarms_off(active_sensor);
+ }
+
+ /* do value label */
+ if (display_mode == DISPLAY_LABEL_WITH_VALUE ||
+ display_mode == DISPLAY_ICON_WITH_VALUE ||
+ display_mode == DISPLAY_VALUE) {
+ if (font_size) {
+ old_value_text = value_text;
+
+ value_text = g_strdup_printf("<span font_desc=\"%d\">%s</span>", font_size, old_value_text);
+ g_free(old_value_text);
+ }
+ gtk_label_set_markup(GTK_LABEL(active_sensor->value),
+ value_text);
+
+
+ gtk_widget_set_tooltip_text(active_sensor->value,
+ tooltip);
+ }
+ /* finished with value text */
+ g_free(value_text);
+
+ /* do label label */
+ if (display_mode == DISPLAY_LABEL_WITH_VALUE) {
+ if (font_size) {
+ old_value_text = sensor_label;
+ sensor_label = g_strdup_printf("<span font_desc=\"%d\">%s</span>", font_size, old_value_text);
+ g_free(old_value_text);
+ }
+ gtk_label_set_markup(GTK_LABEL(active_sensor->label),
+ sensor_label);
+ gtk_widget_set_tooltip_text(active_sensor->label,
+ tooltip);
+
+ }
+
+ g_free(tooltip);
+ } else {
+ g_debug("no get_sensor_value function yet installed for interface %s.", sensor_interface);
+ }
+ g_free(sensor_path);
+ g_free(sensor_id);
+ g_free(sensor_label);
+ g_free(sensor_interface);
+ g_free(graph_color);
+ g_object_unref(icon_pixbuf);
+
+ } else {
+ g_debug("Error getting iter when updating sensor...");
+
+ }
+ active_sensor->updated = TRUE;
+
+}
+
+/* to be called when the icon within the GtkRowReference that this
+ * sensor references is changed - updates icon based upon value in the
+ * ActiveSensor */
+void active_sensor_icon_changed(ActiveSensor *active_sensor,
+ SensorsApplet *sensors_applet) {
+
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ SensorType sensor_type;
+ GdkPixbuf *icon_pixbuf;
+
+ g_assert(active_sensor);
+ g_assert(sensors_applet);
+
+ model = gtk_tree_row_reference_get_model(active_sensor->sensor_row);
+ path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
+
+ /* if can successfully get iter can proceed */
+ if (gtk_tree_model_get_iter(model, &iter, path)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors),
+ &iter,
+ SENSOR_TYPE_COLUMN, &sensor_type,
+ ICON_PIXBUF_COLUMN, &icon_pixbuf,
+ -1);
+
+ active_sensor_update_icon(active_sensor,
+ icon_pixbuf,
+ sensor_type);
+ g_object_unref(icon_pixbuf);
+ }
+ gtk_tree_path_free(path);
+}
diff --git a/sensors-applet/active-sensor.h b/sensors-applet/active-sensor.h
new file mode 100644
index 0000000..2d4674b
--- /dev/null
+++ b/sensors-applet/active-sensor.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 ACTIVE_SENSOR_H
+#define ACTIVE_SENSOR_H
+
+#ifdef HAVE_LIBNOTIFY
+#include <libnotify/notify.h>
+#include "active-sensor-libnotify.h"
+#endif
+
+#include "sensors-applet.h"
+
+struct _ActiveSensor {
+ SensorsApplet *sensors_applet;
+
+ /* widgets to render to display the sensor */
+ GtkWidget *label;
+ GtkWidget *icon;
+ GtkWidget *value;
+ GtkWidget *graph;
+ GtkWidget *graph_frame;
+
+ GdkColor graph_color;
+
+ GtkTreeRowReference *sensor_row;
+
+#ifdef HAVE_LIBNOTIFY
+ NotifyNotification *notification[NUM_NOTIFS];
+#endif
+
+ gboolean updated;
+
+ /* alarm related stuff */
+ gint alarm_timeout_id[NUM_ALARMS];
+ gchar *alarm_command[NUM_ALARMS];
+ gint alarm_timeout;
+
+ /* buffer of sensor values */
+ gdouble *sensor_values;
+
+ /* length of sensor_values buffer */
+ gint num_samples;
+
+ gdouble sensor_low_value;
+ gdouble sensor_high_value;
+};
+
+ActiveSensor *active_sensor_new(SensorsApplet *sensors_applet,
+ GtkTreeRowReference *sensor_row);
+void active_sensor_destroy(ActiveSensor *active_sensor);
+gint active_sensor_compare(ActiveSensor *a, ActiveSensor *b);
+void active_sensor_update(ActiveSensor *sensor, SensorsApplet *sensors_applet);
+void active_sensor_icon_changed(ActiveSensor *sensor, SensorsApplet *sensors_applet);
+void active_sensor_update_graph_dimensions(ActiveSensor *as,
+ gint dimensions[2]);
+void active_sensor_alarm_off(ActiveSensor *active_sensor, NotifType notif_type);
+#endif /* ACTIVE_SENSOR_H */
diff --git a/sensors-applet/config.h.in b/sensors-applet/config.h.in
new file mode 100644
index 0000000..a32469b
--- /dev/null
+++ b/sensors-applet/config.h.in
@@ -0,0 +1,134 @@
+/* sensors-applet/config.h.in. Generated from configure.ac by autoheader. */
+
+/* aticonfig executable */
+#undef ATICONFIG_EXE
+
+/* always defined to indicate that i18n is enabled */
+#undef ENABLE_NLS
+
+/* Package name for gettext */
+#undef GETTEXT_PACKAGE
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* using aticonfig */
+#undef HAVE_ATICONFIG
+
+/* Define to 1 if you have the `bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Define to 1 if you have the `dcgettext' function. */
+#undef HAVE_DCGETTEXT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* libnotify available */
+#undef HAVE_LIBNOTIFY
+
+/* libsensors is available */
+#undef HAVE_LIBSENSORS
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <NVCtrl/NVCtrlLib.h> header file. */
+#undef HAVE_NVCTRL_NVCTRLLIB_H
+
+/* Define to 1 if you have the <NVCtrl/NVCtrl.h> header file. */
+#undef HAVE_NVCTRL_NVCTRL_H
+
+/* nvidia sensors available */
+#undef HAVE_NVIDIA
+
+/* Define to 1 if you have the <regex.h> header file. */
+#undef HAVE_REGEX_H
+
+/* Define to 1 if you have the <sensors/sensors.h> header file. */
+#undef HAVE_SENSORS_SENSORS_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <X11/Xlib.h> header file. */
+#undef HAVE_X11_XLIB_H
+
+/* Define to 1 if you have the <\> header file. */
+#undef HAVE__
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
diff --git a/sensors-applet/main.c b/sensors-applet/main.c
new file mode 100644
index 0000000..b04e9eb
--- /dev/null
+++ b/sensors-applet/main.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <panel-applet.h>
+#include <string.h>
+#include "sensors-applet.h"
+
+static gboolean sensors_applet_fill(PanelApplet *applet,
+ const gchar *iid,
+ gpointer data) {
+ SensorsApplet *sensors_applet;
+ gboolean retval = FALSE;
+ if (strcmp(iid, "OAFIID:SensorsApplet") == 0) {
+ sensors_applet = g_new0(SensorsApplet, 1);
+ sensors_applet->applet = applet;
+ sensors_applet_init(sensors_applet);
+ retval = TRUE;
+ }
+ return retval;
+}
+
+PANEL_APPLET_BONOBO_FACTORY ("OAFIID:SensorsApplet_Factory",
+ PANEL_TYPE_APPLET,
+ PACKAGE,
+ PACKAGE_VERSION,
+ sensors_applet_fill,
+ NULL);
diff --git a/sensors-applet/prefs-dialog.c b/sensors-applet/prefs-dialog.c
new file mode 100644
index 0000000..fc7d3ac
--- /dev/null
+++ b/sensors-applet/prefs-dialog.c
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <libgnome/libgnome.h>
+#include "sensors-applet-gconf.h"
+#include "prefs-dialog.h"
+#include "sensor-config-dialog.h"
+
+#define OLD_TEMP_SCALE 0
+#define NEW_TEMP_SCALE 1
+
+/* when a user closes the prefs-dialog we assume that applet is now
+ setup, so store all values in gconf */
+void prefs_dialog_close(SensorsApplet *sensors_applet) {
+
+ if (sensors_applet->sensors != NULL) {
+ if (sensors_applet_gconf_save_sensors(sensors_applet))
+ panel_applet_gconf_set_bool(sensors_applet->applet,
+ IS_SETUP, TRUE, NULL);
+ }
+ if (sensors_applet->prefs_dialog) {
+ gtk_widget_destroy(GTK_WIDGET(sensors_applet->prefs_dialog->dialog));
+ g_free(sensors_applet->prefs_dialog);
+ sensors_applet->prefs_dialog = NULL;
+
+ }
+ if (sensors_applet->timeout_id == 0) {
+ sensors_applet->timeout_id = g_timeout_add_seconds(panel_applet_gconf_get_int(sensors_applet->applet, TIMEOUT, NULL) / 1000, (GSourceFunc)sensors_applet_update_active_sensors, sensors_applet);
+ }
+
+
+}
+
+void prefs_dialog_response(GtkDialog *prefs_dialog,
+ gint response,
+ gpointer data) {
+
+ SensorsApplet *sensors_applet;
+ GError *error = NULL;
+ gint current_page;
+ gchar *uri;
+
+ sensors_applet = (SensorsApplet *)data;
+
+ switch (response) {
+ case GTK_RESPONSE_HELP:
+ g_debug("loading help in prefs");
+ current_page = gtk_notebook_get_current_page(sensors_applet->prefs_dialog->notebook);
+ uri = g_strdup_printf("ghelp:sensors-applet?%s",
+ ((current_page == 0) ?
+ "sensors-applet-general-options" :
+ ((current_page == 1) ?
+ "sensors-applet-sensors" :
+ NULL)));
+ gtk_show_uri(NULL, uri, gtk_get_current_event_time(), &error);
+ g_free(uri);
+
+ if (error) {
+ g_debug("Could not open help document: %s ",error->message);
+ g_error_free (error);
+ }
+ break;
+ default:
+ g_debug("closing prefs dialog");
+ prefs_dialog_close(sensors_applet);
+ }
+}
+
+
+static gboolean prefs_dialog_convert_low_and_high_values(GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ TemperatureScale scales[2]) {
+ SensorType sensor_type;
+ gdouble low_value, high_value;
+
+ gtk_tree_model_get(model,
+ iter,
+ SENSOR_TYPE_COLUMN, &sensor_type,
+ LOW_VALUE_COLUMN, &low_value,
+ HIGH_VALUE_COLUMN, &high_value,
+ -1);
+
+ if (sensor_type == TEMP_SENSOR)
+ {
+ low_value = sensors_applet_convert_temperature(low_value,
+ scales[OLD_TEMP_SCALE],
+ scales[NEW_TEMP_SCALE]);
+
+ high_value = sensors_applet_convert_temperature(high_value,
+ scales[OLD_TEMP_SCALE],
+ scales[NEW_TEMP_SCALE]);
+
+
+ gtk_tree_store_set(GTK_TREE_STORE(model),
+ iter,
+ LOW_VALUE_COLUMN, low_value,
+ HIGH_VALUE_COLUMN, high_value,
+ -1);
+ }
+ return FALSE;
+}
+
+
+static void prefs_dialog_timeout_changed(GtkSpinButton *button,
+ PrefsDialog *prefs_dialog) {
+ gint value;
+ value = (gint)(gtk_spin_button_get_value(button) * 1000);
+ panel_applet_gconf_set_int(prefs_dialog->sensors_applet->applet, TIMEOUT, value, NULL);
+}
+
+static void prefs_dialog_display_mode_changed(GtkComboBox *display_mode_combo_box,
+ PrefsDialog *prefs_dialog) {
+
+ int display_mode;
+
+ display_mode = gtk_combo_box_get_active(display_mode_combo_box);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->layout_mode_label),
+ (display_mode != DISPLAY_ICON) &&
+ (display_mode != DISPLAY_VALUE) &&
+ (display_mode != DISPLAY_GRAPH));
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->layout_mode_combo_box),
+ (display_mode != DISPLAY_ICON) &&
+ (display_mode != DISPLAY_VALUE) &&
+ (display_mode != DISPLAY_GRAPH));
+
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->graph_size_label),
+ (display_mode == DISPLAY_GRAPH));
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->graph_size_spinbutton),
+ (display_mode == DISPLAY_GRAPH));
+
+ panel_applet_gconf_set_int(prefs_dialog->sensors_applet->applet,
+ DISPLAY_MODE,
+ gtk_combo_box_get_active(display_mode_combo_box),
+ NULL);
+
+ sensors_applet_display_layout_changed(prefs_dialog->sensors_applet);
+}
+
+static void prefs_dialog_layout_mode_changed(GtkComboBox *layout_mode_combo_box,
+ PrefsDialog *prefs_dialog) {
+
+ panel_applet_gconf_set_int(prefs_dialog->sensors_applet->applet,
+ LAYOUT_MODE,
+ gtk_combo_box_get_active(layout_mode_combo_box),
+ NULL);
+
+ sensors_applet_display_layout_changed(prefs_dialog->sensors_applet);
+}
+
+
+static void prefs_dialog_temperature_scale_changed(GtkComboBox *temperature_scale_combo_box,
+ PrefsDialog *prefs_dialog) {
+ /* get old temp scale value */
+ TemperatureScale scales[2];
+ GtkTreeModel *model;
+
+ scales[OLD_TEMP_SCALE] = (TemperatureScale)panel_applet_gconf_get_int(prefs_dialog->sensors_applet->applet,
+ TEMPERATURE_SCALE,
+ NULL);
+
+ scales[NEW_TEMP_SCALE] = (TemperatureScale)gtk_combo_box_get_active(temperature_scale_combo_box);
+
+ panel_applet_gconf_set_int(prefs_dialog->sensors_applet->applet,
+ TEMPERATURE_SCALE,
+ scales[NEW_TEMP_SCALE],
+ NULL);
+
+ /* now go thru and convert all low and high sensor values in
+ * the tree to either celcius or Fahrenheit */
+ model = gtk_tree_view_get_model(prefs_dialog->view);
+ gtk_tree_model_foreach(model,
+ (GtkTreeModelForeachFunc)prefs_dialog_convert_low_and_high_values,
+ scales);
+
+ /* finally update display of active sensors */
+ sensors_applet_update_active_sensors(prefs_dialog->sensors_applet);
+}
+
+
+#ifdef HAVE_LIBNOTIFY
+static void prefs_dialog_display_notifications_toggled(GtkCheckButton *display_notifications,
+ PrefsDialog *prefs_dialog) {
+
+ gboolean notify;
+
+ notify = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(display_notifications));
+ panel_applet_gconf_set_bool(prefs_dialog->sensors_applet->applet,
+ DISPLAY_NOTIFICATIONS,
+ notify,
+ NULL);
+
+ if (notify) {
+ sensors_applet_update_active_sensors(prefs_dialog->sensors_applet);
+ } else {
+ sensors_applet_notify_end_all(prefs_dialog->sensors_applet);
+ }
+}
+#endif
+
+static void prefs_dialog_graph_size_changed(GtkSpinButton *button,
+ PrefsDialog *prefs_dialog) {
+ gint value;
+ value = (gint)(gtk_spin_button_get_value(button));
+ panel_applet_gconf_set_int(prefs_dialog->sensors_applet->applet, GRAPH_SIZE, value, NULL);
+
+ /* notify change of number of samples */
+ sensors_applet_graph_size_changed(prefs_dialog->sensors_applet);
+
+}
+
+/* callbacks for the tree of sensors */
+static void prefs_dialog_sensor_toggled(GtkCellRenderer *renderer, gchar *path_str, PrefsDialog *prefs_dialog) {
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ gboolean old_value;
+
+ path = gtk_tree_path_new_from_string(path_str);
+
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(prefs_dialog->sensors_applet->sensors), &iter, path);
+ gtk_tree_model_get(GTK_TREE_MODEL(prefs_dialog->sensors_applet->sensors),
+ &iter,
+ ENABLE_COLUMN, &old_value,
+ -1);
+
+ if (old_value) {
+ sensors_applet_sensor_disabled(prefs_dialog->sensors_applet,
+ path);
+ } else {
+ sensors_applet_sensor_enabled(prefs_dialog->sensors_applet,
+ path);
+ }
+
+ gtk_tree_store_set(prefs_dialog->sensors_applet->sensors, &iter,
+ ENABLE_COLUMN, !old_value,
+ -1);
+
+ gtk_tree_path_free(path);
+}
+
+static void prefs_dialog_sensor_name_changed(GtkCellRenderer *renderer, gchar *path_str, gchar *new_text, PrefsDialog *prefs_dialog) {
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
+
+ gtk_tree_model_get_iter(GTK_TREE_MODEL(prefs_dialog->sensors_applet->sensors), &iter, path);
+
+ gtk_tree_store_set(prefs_dialog->sensors_applet->sensors, &iter, LABEL_COLUMN, new_text, -1);
+
+ sensors_applet_update_sensor(prefs_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void prefs_dialog_row_activated(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, PrefsDialog *prefs_dialog) {
+ /* only bring up dialog this if is a sensor - ie has no
+ * children */
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model(view);
+ /* make sure can set iter first */
+ if (gtk_tree_model_get_iter(model, &iter, path) && !gtk_tree_model_iter_has_child(model, &iter)) {
+ sensor_config_dialog_create(prefs_dialog->sensors_applet);
+ }
+}
+
+
+static void prefs_dialog_sensor_up_button_clicked(GtkButton *button, PrefsDialog *prefs_dialog) {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ if (gtk_tree_selection_get_selected(prefs_dialog->sensors_applet->selection, &model, &iter)) {
+ /* if has no prev node set up button insentive */
+ path = gtk_tree_model_get_path(model, &iter);
+ if (gtk_tree_path_prev(path)) {
+ GtkTreeIter prev_iter;
+ /* check is a valid node in out model */
+ if (gtk_tree_model_get_iter(model, &prev_iter, path)) {
+ gtk_tree_store_move_before(GTK_TREE_STORE(model),
+ &iter,
+ &prev_iter);
+ g_signal_emit_by_name(prefs_dialog->sensors_applet->selection,
+ "changed");
+
+ sensors_applet_reorder_sensors(prefs_dialog->sensors_applet);
+
+
+ }
+ }
+
+ gtk_tree_path_free(path);
+
+ }
+}
+
+static void prefs_dialog_sensor_down_button_clicked(GtkButton *button, PrefsDialog *prefs_dialog) {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeIter iter_next;
+
+ if (gtk_tree_selection_get_selected(prefs_dialog->sensors_applet->selection, &model, &iter)) {
+ iter_next = iter;
+ /* if has no next node set down button insentive */
+ if (gtk_tree_model_iter_next(model, &iter_next)) {
+ gtk_tree_store_move_after(GTK_TREE_STORE(model),
+ &iter,
+ &iter_next);
+ g_signal_emit_by_name(prefs_dialog->sensors_applet->selection,
+ "changed");
+ sensors_applet_reorder_sensors(prefs_dialog->sensors_applet);
+
+ }
+ }
+}
+
+
+
+static void prefs_dialog_sensor_config_button_clicked(GtkButton *button, PrefsDialog *prefs_dialog) {
+ sensor_config_dialog_create(prefs_dialog->sensors_applet);
+}
+
+
+/* if a sensor is selected, make config sure button is able to be
+ * clicked and also set the sensitivities properly for the up and down
+ * buttons */
+static void prefs_dialog_selection_changed(GtkTreeSelection *selection,
+ PrefsDialog *prefs_dialog) {
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeModel *model;
+ /* if there is a selection with no children make config button
+ * sensitive */
+ if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
+ if (!gtk_tree_model_iter_has_child(model, &iter)) {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_config_button), TRUE);
+ } else {
+ /* otherwise make insensitive */
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_config_button), FALSE);
+ }
+
+ /* if has no prev node set up button insentive */
+ path = gtk_tree_model_get_path(model, &iter);
+ if (gtk_tree_path_prev(path)) {
+ GtkTreeIter prev_iter;
+ /* check is a valid node in out model */
+ if (gtk_tree_model_get_iter(model, &prev_iter, path)) {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_up_button), TRUE);
+ } else {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_up_button), FALSE);
+ }
+ } else {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_up_button), FALSE);
+ }
+
+ gtk_tree_path_free(path);
+
+ /* if has no next node set down button insentive */
+ if (gtk_tree_model_iter_next(model, &iter)) {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_down_button), TRUE);
+ } else {
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_down_button), FALSE);
+ }
+
+ } else {
+ /* otherwise make all insensitive */
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_config_button), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_up_button), FALSE);
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_down_button), FALSE);
+
+ }
+}
+
+void prefs_dialog_open(SensorsApplet *sensors_applet) {
+ gchar *header_text;
+ PrefsDialog *prefs_dialog;
+ DisplayMode display_mode;
+
+ g_assert(sensors_applet->prefs_dialog == NULL);
+
+ /* while prefs dialog is open, stop the updating of sensors so
+ * we don't get any race conditions due to concurrent updates
+ * of the labels, values and icons linked lists etc. */
+ if (sensors_applet->timeout_id != 0) {
+ if (g_source_remove(sensors_applet->timeout_id)) {
+ sensors_applet->timeout_id = 0;
+ }
+ }
+
+ sensors_applet->prefs_dialog = g_new0(PrefsDialog, 1);
+ prefs_dialog = sensors_applet->prefs_dialog;
+
+ prefs_dialog->sensors_applet = sensors_applet;
+
+ prefs_dialog->dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Sensors Applet Preferences"),
+ NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_HELP,
+ GTK_RESPONSE_HELP,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL));
+ g_object_set(prefs_dialog->dialog,
+ "border-width", 12,
+ "default-width", 480,
+ "default-height", 350,
+ NULL);
+
+ gtk_box_set_homogeneous(GTK_BOX(prefs_dialog->dialog->vbox), FALSE);
+
+ gtk_box_set_spacing(GTK_BOX(prefs_dialog->dialog->vbox), 5);
+
+
+ g_signal_connect(prefs_dialog->dialog,
+ "response", G_CALLBACK(prefs_dialog_response),
+ sensors_applet);
+
+ g_signal_connect_swapped(prefs_dialog->dialog,
+ "delete-event", G_CALLBACK(prefs_dialog_close),
+ sensors_applet);
+
+ g_signal_connect_swapped(prefs_dialog->dialog,
+ "destroy", G_CALLBACK(prefs_dialog_close),
+ sensors_applet);
+
+ /* if no SensorsList's have been created, this is because
+ we haven't been able to access any sensors */
+ if (sensors_applet->sensors == NULL) {
+ GtkWidget *label;
+ label = gtk_label_new(_("No sensors found!"));
+ gtk_box_pack_start_defaults(GTK_BOX(prefs_dialog->dialog->vbox), label);
+ return;
+ }
+
+
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Display"));
+ prefs_dialog->display_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+ prefs_dialog->display_mode_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_text());
+
+
+ gtk_combo_box_append_text(prefs_dialog->display_mode_combo_box, _("label with value"));
+ gtk_combo_box_append_text(prefs_dialog->display_mode_combo_box, _("icon with value"));
+ gtk_combo_box_append_text(prefs_dialog->display_mode_combo_box, _("value only"));
+ gtk_combo_box_append_text(prefs_dialog->display_mode_combo_box, _("icon only"));
+ gtk_combo_box_append_text(prefs_dialog->display_mode_combo_box, _("graph only"));
+
+
+ display_mode = panel_applet_gconf_get_int(sensors_applet->applet, DISPLAY_MODE, NULL);
+ gtk_combo_box_set_active(prefs_dialog->display_mode_combo_box, display_mode);
+
+ g_signal_connect(prefs_dialog->display_mode_combo_box,
+ "changed",
+ G_CALLBACK(prefs_dialog_display_mode_changed),
+ prefs_dialog);
+
+
+
+ /* use spaces in label to indent */
+ prefs_dialog->display_mode_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("_Display sensors in panel as"),
+ "mnemonic-widget", prefs_dialog->display_mode_combo_box,
+ "xalign", 0.0,
+ NULL);
+
+
+
+
+ prefs_dialog->layout_mode_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_text());
+
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->layout_mode_combo_box),
+ (display_mode != DISPLAY_ICON) &&
+ (display_mode != DISPLAY_VALUE) &&
+ (display_mode != DISPLAY_GRAPH));
+
+ gtk_combo_box_append_text(prefs_dialog->layout_mode_combo_box, _("beside labels / icons"));
+ gtk_combo_box_append_text(prefs_dialog->layout_mode_combo_box, _("below labels / icons"));
+
+ gtk_combo_box_set_active(prefs_dialog->layout_mode_combo_box, panel_applet_gconf_get_int(sensors_applet->applet, LAYOUT_MODE, NULL));
+
+ g_signal_connect(prefs_dialog->layout_mode_combo_box,
+ "changed",
+ G_CALLBACK(prefs_dialog_layout_mode_changed),
+ prefs_dialog);
+
+ prefs_dialog->layout_mode_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("Preferred _position of sensor values"),
+ "mnemonic-widget", prefs_dialog->layout_mode_combo_box,
+ "xalign", 0.0,
+ NULL);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->layout_mode_label),
+ (display_mode != DISPLAY_ICON) &&
+ (display_mode != DISPLAY_VALUE) &&
+ (display_mode != DISPLAY_GRAPH));
+
+ prefs_dialog->temperature_scale_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_text());
+
+ gtk_combo_box_append_text(prefs_dialog->temperature_scale_combo_box, _("Kelvin"));
+ gtk_combo_box_append_text(prefs_dialog->temperature_scale_combo_box, _("Celsius"));
+ gtk_combo_box_append_text(prefs_dialog->temperature_scale_combo_box, _("Fahrenheit"));
+
+ gtk_combo_box_set_active(prefs_dialog->temperature_scale_combo_box, panel_applet_gconf_get_int(sensors_applet->applet, TEMPERATURE_SCALE, NULL));
+
+ g_signal_connect(prefs_dialog->temperature_scale_combo_box,
+ "changed",
+ G_CALLBACK(prefs_dialog_temperature_scale_changed),
+ prefs_dialog);
+
+ prefs_dialog->temperature_scale_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("_Temperature scale"),
+ "mnemonic-widget", prefs_dialog->temperature_scale_combo_box,
+ "xalign", 0.0,
+ NULL);
+
+ prefs_dialog->graph_size_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", (gdouble)panel_applet_gconf_get_int(sensors_applet->applet,
+ GRAPH_SIZE,
+ NULL),
+ "lower", 1.0,
+ "upper", 100.0,
+ "step-increment", 1.0,
+ "page-increment", 10.0,
+ "page-size", 0.0,
+ NULL);
+
+ prefs_dialog->graph_size_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", prefs_dialog->graph_size_adjust,
+ "climb-rate", 1.0,
+ "digits", 0,
+ "value", (gdouble)panel_applet_gconf_get_int(sensors_applet->applet,
+ GRAPH_SIZE,
+ NULL),
+ "width-chars", 4,
+ NULL);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->graph_size_spinbutton),
+ (display_mode == DISPLAY_GRAPH));
+
+ prefs_dialog->graph_size_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("Graph _size (pixels)"),
+ "mnemonic-widget", prefs_dialog->graph_size_spinbutton,
+ "xalign", 0.0,
+ NULL);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->graph_size_label),
+ (display_mode == DISPLAY_GRAPH));
+
+ g_signal_connect(prefs_dialog->graph_size_spinbutton, "value-changed",
+ G_CALLBACK(prefs_dialog_graph_size_changed),
+ prefs_dialog);
+
+
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Update"));
+ prefs_dialog->update_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+
+ prefs_dialog->timeout_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", 2.0,
+ "lower", 1.5,
+ "upper", 10.0,
+ "step-increment", 0.5,
+ "page-increment", 1.0,
+ "page-size", 0.0,
+ NULL);
+
+ prefs_dialog->timeout_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", prefs_dialog->timeout_adjust,
+ "climb-rate", 0.5,
+ "digits", 1,
+ "value", (gdouble) panel_applet_gconf_get_int(sensors_applet->applet, TIMEOUT, NULL) / 1000.0,
+ "width-chars", 4,
+ NULL);
+
+
+ prefs_dialog->timeout_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("Update _interval (secs)"),
+ "mnemonic-widget", prefs_dialog->timeout_spinbutton,
+ "xalign", 0.0,
+ NULL);
+
+ g_signal_connect(prefs_dialog->timeout_spinbutton, "value-changed",
+ G_CALLBACK(prefs_dialog_timeout_changed),
+ prefs_dialog);
+
+#ifdef HAVE_LIBNOTIFY
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Notifications"));
+ prefs_dialog->notifications_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+ prefs_dialog->display_notifications = g_object_new(GTK_TYPE_CHECK_BUTTON,
+ "use-underline", TRUE,
+ "label", _("Display _notifications"),
+ NULL);
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(prefs_dialog->display_notifications),
+ panel_applet_gconf_get_bool(sensors_applet->applet,
+ DISPLAY_NOTIFICATIONS,
+ NULL));
+ g_signal_connect(prefs_dialog->display_notifications,
+ "toggled",
+ G_CALLBACK(prefs_dialog_display_notifications_toggled),
+ prefs_dialog);
+#endif
+
+ /* SIZE AND LAYOUT */
+ /* keep all widgets same size */
+ prefs_dialog->size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+ gtk_size_group_add_widget(prefs_dialog->size_group,
+ GTK_WIDGET(prefs_dialog->display_mode_combo_box));
+
+ gtk_size_group_add_widget(prefs_dialog->size_group,
+ GTK_WIDGET(prefs_dialog->layout_mode_combo_box));
+
+ gtk_size_group_add_widget(prefs_dialog->size_group,
+ GTK_WIDGET(prefs_dialog->temperature_scale_combo_box));
+
+ gtk_size_group_add_widget(prefs_dialog->size_group,
+ GTK_WIDGET(prefs_dialog->timeout_spinbutton));
+
+ g_object_unref(prefs_dialog->size_group);
+
+ prefs_dialog->globals_table = g_object_new(GTK_TYPE_TABLE,
+ "homogeneous", FALSE,
+ "n-columns", 3,
+#ifdef HAVE_LIBNOTIFY
+ "n-rows", 9,
+#else
+ "n-rows", 7,
+#endif
+ "row-spacing", 6,
+ "column-spacing", 12,
+ NULL);
+
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->display_header),
+ 0, 2,
+ 0, 1,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->display_mode_label),
+ 1, 2,
+ 1, 2,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->display_mode_combo_box),
+ 2, 3,
+ 1, 2,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->layout_mode_label),
+ 1, 2,
+ 2, 3,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->layout_mode_combo_box),
+ 2, 3,
+ 2, 3,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->graph_size_label),
+ 1, 2,
+ 3, 4,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->graph_size_spinbutton),
+ 2, 3,
+ 3, 4,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->temperature_scale_label),
+ 1, 2,
+ 4, 5,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->temperature_scale_combo_box),
+ 2, 3,
+ 4, 5,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->update_header),
+ 0, 2,
+ 5, 6,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->timeout_label),
+ 1, 2,
+ 6, 7,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->timeout_spinbutton),
+ 2, 3,
+ 6, 7,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+
+#ifdef HAVE_LIBNOTIFY
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->notifications_header),
+ 0, 2,
+ 7, 8,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+
+ gtk_table_attach(prefs_dialog->globals_table,
+ GTK_WIDGET(prefs_dialog->display_notifications),
+ 1, 2,
+ 8, 9,
+ GTK_FILL,
+ GTK_FILL,
+ 0,
+ 0);
+#endif
+
+
+ prefs_dialog->view = g_object_new(GTK_TYPE_TREE_VIEW,
+ "model", GTK_TREE_MODEL(sensors_applet->sensors),
+ "rules-hint", TRUE,
+ "reorderable", FALSE,
+ "enable-search", TRUE,
+ "search-column", LABEL_COLUMN,
+ NULL);
+
+ /* get double clicks on rows - do same as configure sensor
+ * button clicks */
+ g_signal_connect(prefs_dialog->view, "row-activated",
+ G_CALLBACK(prefs_dialog_row_activated),
+ prefs_dialog);
+
+ prefs_dialog->id_renderer = gtk_cell_renderer_text_new();
+ prefs_dialog->label_renderer = gtk_cell_renderer_text_new();
+ g_object_set(prefs_dialog->label_renderer,
+ "editable", TRUE,
+ NULL);
+
+ g_signal_connect(prefs_dialog->label_renderer, "edited",
+ G_CALLBACK(prefs_dialog_sensor_name_changed),
+ prefs_dialog);
+
+ prefs_dialog->enable_renderer = gtk_cell_renderer_toggle_new();
+ g_signal_connect(prefs_dialog->enable_renderer, "toggled",
+ G_CALLBACK(prefs_dialog_sensor_toggled),
+ prefs_dialog);
+ prefs_dialog->icon_renderer = gtk_cell_renderer_pixbuf_new();
+
+ prefs_dialog->id_column = gtk_tree_view_column_new_with_attributes(_("Sensor"),
+ prefs_dialog->id_renderer,
+ "text", ID_COLUMN,
+ NULL);
+
+ gtk_tree_view_column_set_min_width(prefs_dialog->id_column, 90);
+
+ prefs_dialog->label_column = gtk_tree_view_column_new_with_attributes(_("Label"),
+ prefs_dialog->label_renderer,
+ "text", LABEL_COLUMN,
+ "visible", VISIBLE_COLUMN,
+ NULL);
+
+ gtk_tree_view_column_set_min_width(prefs_dialog->label_column, 100);
+
+ /* create the tooltip */
+ gtk_widget_set_tooltip_text(GTK_WIDGET(prefs_dialog->view),
+ _("Labels can be edited directly by clicking on them."));
+ prefs_dialog->enable_column = gtk_tree_view_column_new_with_attributes(_("Enabled"),
+ prefs_dialog->enable_renderer,
+ "active", ENABLE_COLUMN,
+ "visible", VISIBLE_COLUMN,
+ NULL);
+
+ prefs_dialog->icon_column = gtk_tree_view_column_new_with_attributes(_("Icon"),
+ prefs_dialog->icon_renderer,
+ "pixbuf", ICON_PIXBUF_COLUMN,
+ "visible", VISIBLE_COLUMN,
+ NULL);
+ gtk_tree_view_append_column(prefs_dialog->view,
+ prefs_dialog->id_column);
+ gtk_tree_view_append_column(prefs_dialog->view,
+ prefs_dialog->icon_column);
+ gtk_tree_view_append_column(prefs_dialog->view,
+ prefs_dialog->label_column);
+ gtk_tree_view_append_column(prefs_dialog->view,
+ prefs_dialog->enable_column);
+
+ gtk_tree_view_columns_autosize(prefs_dialog->view);
+
+ prefs_dialog->scrolled_window = g_object_new(GTK_TYPE_SCROLLED_WINDOW,
+ "hadjustment", NULL,
+ "height-request", 200,
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "vadjustment",NULL,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+
+ gtk_container_add(GTK_CONTAINER(prefs_dialog->scrolled_window), GTK_WIDGET(prefs_dialog->view));
+
+ /* GtkTree Selection */
+ sensors_applet->selection = gtk_tree_view_get_selection(prefs_dialog->view);
+ /* allow user to only select one row at a time at most */
+ gtk_tree_selection_set_mode(sensors_applet->selection, GTK_SELECTION_SINGLE);
+ /* when selection is changed, make sure sensor_config button is
+ activated */
+
+ /* Create buttons for user to interact with sensors tree */
+ prefs_dialog->sensor_up_button = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_GO_UP));
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_up_button), FALSE);
+
+ g_signal_connect(prefs_dialog->sensor_up_button, "clicked",
+ G_CALLBACK(prefs_dialog_sensor_up_button_clicked),
+ prefs_dialog);
+
+ prefs_dialog->sensor_down_button = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_GO_DOWN));
+ gtk_widget_set_sensitive(GTK_WIDGET(prefs_dialog->sensor_down_button), FALSE);
+
+ g_signal_connect(prefs_dialog->sensor_down_button, "clicked",
+ G_CALLBACK(prefs_dialog_sensor_down_button_clicked),
+ prefs_dialog);
+
+
+ prefs_dialog->buttons_box = GTK_VBUTTON_BOX(gtk_vbutton_box_new());
+
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(prefs_dialog->buttons_box),
+ GTK_BUTTONBOX_SPREAD);
+
+ gtk_box_pack_start(GTK_BOX(prefs_dialog->buttons_box), GTK_WIDGET(prefs_dialog->sensor_up_button), FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(prefs_dialog->buttons_box), GTK_WIDGET(prefs_dialog->sensor_down_button), FALSE, FALSE, 0);
+
+ prefs_dialog->sensors_hbox = g_object_new(GTK_TYPE_HBOX,
+ "border-width", 5,
+ "homogeneous", FALSE,
+ "spacing", 5,
+ NULL);
+
+ gtk_box_pack_start(prefs_dialog->sensors_hbox,
+ GTK_WIDGET(prefs_dialog->scrolled_window),
+ TRUE, TRUE, 0); /* make sure window takes
+ * up most of room */
+
+ gtk_box_pack_start(prefs_dialog->sensors_hbox,
+ GTK_WIDGET(prefs_dialog->buttons_box),
+ FALSE, FALSE, 0);
+
+
+ /* Sensor Config button */
+ /* initially make button insensitive until user selects a row
+ from the sensors tree */
+ prefs_dialog->sensor_config_button = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_PROPERTIES));
+ g_object_set(prefs_dialog->sensor_config_button,
+ "sensitive", FALSE,
+ NULL);
+
+
+ g_signal_connect(sensors_applet->selection,
+ "changed",
+ G_CALLBACK(prefs_dialog_selection_changed),
+ prefs_dialog);
+
+ /* pass selection to signal handler so we can give user a
+ sensors_applet->prefs_dialog with the selected rows alarm
+ value and enable */
+ g_signal_connect(prefs_dialog->sensor_config_button, "clicked",
+ G_CALLBACK(prefs_dialog_sensor_config_button_clicked),
+ prefs_dialog);
+
+ prefs_dialog->sensor_config_hbox = g_object_new(GTK_TYPE_HBOX,
+ "border-width", 5,
+ "homogeneous", FALSE,
+ "spacing", 0,
+ NULL);
+ gtk_box_pack_end(prefs_dialog->sensor_config_hbox,
+ GTK_WIDGET(prefs_dialog->sensor_config_button),
+ FALSE, FALSE, 0);
+
+ /* pack sensors_vbox */
+ prefs_dialog->sensors_vbox = g_object_new(GTK_TYPE_VBOX,
+ "border-width", 5,
+ "homogeneous", FALSE,
+ "spacing", 0,
+ NULL);
+
+ gtk_box_pack_start(prefs_dialog->sensors_vbox,
+ GTK_WIDGET(prefs_dialog->sensors_hbox),
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(prefs_dialog->sensors_vbox,
+ GTK_WIDGET(prefs_dialog->sensor_config_hbox),
+ FALSE, FALSE, 0);
+
+ prefs_dialog->globals_alignment = g_object_new(GTK_TYPE_ALIGNMENT,
+ "xalign", 0.5,
+ "yalign", 0.0,
+ "top-padding", 12,
+ "left-padding", 12,
+ "bottom-padding", 12,
+ "right-padding", 12,
+ NULL);
+ gtk_container_add(GTK_CONTAINER(prefs_dialog->globals_alignment),
+ GTK_WIDGET(prefs_dialog->globals_table));
+
+ prefs_dialog->notebook = g_object_new(GTK_TYPE_NOTEBOOK,
+ NULL);
+
+ gtk_notebook_append_page(prefs_dialog->notebook,
+ GTK_WIDGET(prefs_dialog->globals_alignment),
+ gtk_label_new(_("General Options")));
+
+ gtk_notebook_append_page(prefs_dialog->notebook,
+ GTK_WIDGET(prefs_dialog->sensors_vbox),
+ gtk_label_new(_("Sensors")));
+
+ /* pack notebook into prefs_dialog */
+ gtk_box_pack_start_defaults(GTK_BOX(prefs_dialog->dialog->vbox),
+ GTK_WIDGET(prefs_dialog->notebook));
+
+
+ gtk_widget_show_all(GTK_WIDGET(prefs_dialog->dialog));
+}
diff --git a/sensors-applet/prefs-dialog.h b/sensors-applet/prefs-dialog.h
new file mode 100644
index 0000000..5d1270b
--- /dev/null
+++ b/sensors-applet/prefs-dialog.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 PREFS_DIALOG_H
+#define PREFS_DIALOG_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sensors-applet.h"
+
+typedef struct {
+ SensorsApplet *sensors_applet;
+ GtkDialog *dialog;
+ GtkNotebook *notebook;
+
+ /* widgets for global prefs */
+ GtkSpinButton *timeout_spinbutton, *graph_size_spinbutton;
+ GtkTable *globals_table;
+ GtkHSeparator *globals_separator;
+ GtkComboBox *display_mode_combo_box, *layout_mode_combo_box, *temperature_scale_combo_box;
+ GtkLabel *timeout_label, *display_mode_label, *layout_mode_label, *temperature_scale_label, *graph_size_label, *update_header, *display_header;
+ GtkAdjustment *timeout_adjust, *graph_size_adjust;
+
+#ifdef HAVE_LIBNOTIFY
+ GtkCheckButton *display_notifications;
+ GtkLabel *notifications_header;
+#endif
+
+ /* widgets for sensors tree */
+ GtkTreeView *view;
+ GtkTreeViewColumn *id_column, *label_column, *enable_column, *icon_column;
+ GtkCellRenderer *id_renderer, *label_renderer, *enable_renderer, *icon_renderer;
+ GtkScrolledWindow *scrolled_window;
+
+ GtkVButtonBox *buttons_box; /* holds sensor reorder buttons */
+ GtkBox *sensors_hbox; /* holds scrolled window and
+ * buttons_vbox */
+ GtkAlignment *globals_alignment;
+ GtkBox *sensors_vbox; /* holds sensors_hbox and sensor_config_hbox */
+ GtkBox *sensor_config_hbox; /* holds config button */
+ GtkSizeGroup *size_group; /* so comboboxes all
+ * request the same size */
+
+ GtkButton *sensor_up_button;
+ GtkButton *sensor_down_button;
+ GtkButton *sensor_config_button;
+} PrefsDialog;
+
+/* function prototypes */
+void prefs_dialog_open(SensorsApplet *sensors_applet);
+void prefs_dialog_close(SensorsApplet *sensors_applet);
+
+#endif /* PREFS_DIALOG_H */
diff --git a/sensors-applet/sensor-config-dialog.c b/sensors-applet/sensor-config-dialog.c
new file mode 100644
index 0000000..bd55836
--- /dev/null
+++ b/sensors-applet/sensor-config-dialog.c
@@ -0,0 +1,918 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <gnome.h>
+#include "sensor-config-dialog.h"
+#include "sensors-applet.h"
+
+#define SPINBUTTON_WIDTH_CHARS 8
+#define VALUE_DECIMAL_PLACES 3
+
+typedef struct {
+ SensorsApplet *sensors_applet;
+
+ GtkWidget *dialog;
+ /* icon widgets */
+ GtkLabel *icon_header, *icon_type_label;
+ GtkComboBox *icon_type_combo_box;
+ GtkAlignment *icon_type_combo_box_aligner;
+ GtkCellRenderer *icon_renderer;
+
+ /* Graph Color chooser */
+ GtkColorButton *graph_color_button;
+ GtkAlignment *graph_color_button_aligner;
+ GtkLabel *graph_color_label, *graph_header;
+
+ /* multiplier and offset widgets */
+ GtkLabel *scale_header, *multiplier_label, *offset_label;
+ GtkAlignment *multiplier_spinbutton_aligner, *offset_spinbutton_aligner;
+ GtkAdjustment *multiplier_adjust, *offset_adjust;
+ GtkSpinButton *multiplier_spinbutton, *offset_spinbutton;
+
+ GtkLabel *limits_header;
+ GtkLabel *low_value_label, *high_value_label;
+ GtkAlignment *low_value_spinbutton_aligner, *high_value_spinbutton_aligner;
+ GtkAdjustment *low_value_adjust, *high_value_adjust;
+ GtkSpinButton *low_value_spinbutton, *high_value_spinbutton;
+
+ /* alarm widgets */
+ GtkLabel *alarm_header;
+ GtkLabel *low_alarm_command_label, *high_alarm_command_label, *alarm_timeout_label;
+ GtkAlignment *alarm_timeout_spinbutton_aligner;
+ GtkAdjustment *alarm_timeout_adjust;
+ GtkSpinButton *alarm_timeout_spinbutton;
+ GtkTable *table;
+ GtkAlignment *alarm_enable_aligner;
+ GtkCheckButton *alarm_enable_checkbutton;
+ GtkEntry *low_alarm_command_entry, *high_alarm_command_entry;
+
+ GtkSizeGroup *size_group;
+} SensorConfigDialog;
+
+static void sensor_config_dialog_response(GtkDialog *dialog,
+ gint response,
+ gpointer data) {
+ SensorConfigDialog *config_dialog;
+ GError *error = NULL;
+
+ config_dialog = (SensorConfigDialog *)data;
+
+ switch (response) {
+ case GTK_RESPONSE_HELP:
+ g_debug("loading help in config dialog");
+ gtk_show_uri(NULL,
+ "ghelp:sensors-applet?sensors-applet-sensors",
+ gtk_get_current_event_time(),
+ &error);
+
+ if (error) {
+ g_debug("Could not open help document: %s ",error->message);
+ g_error_free (error);
+ }
+ break;
+ default:
+ g_debug("destroying config dialog");
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ }
+}
+
+static void sensor_config_dialog_multiplier_changed(GtkSpinButton *spinbutton, SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gdouble value;
+
+ value = gtk_spin_button_get_value(spinbutton);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ MULTIPLIER_COLUMN, value,
+ -1);
+
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_offset_changed(GtkSpinButton *spinbutton, SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gdouble value;
+
+ value = gtk_spin_button_get_value(spinbutton);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ OFFSET_COLUMN, value,
+ -1);
+
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_low_value_changed(GtkSpinButton *spinbutton, SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gdouble value;
+
+ value = gtk_spin_button_get_value(spinbutton);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ LOW_VALUE_COLUMN, value,
+ -1);
+
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_high_value_changed(GtkSpinButton *spinbutton, SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gdouble value;
+
+ value = gtk_spin_button_get_value(spinbutton);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ HIGH_VALUE_COLUMN, value,
+ -1);
+
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_alarm_toggled(GtkToggleButton *button, SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ gboolean value;
+ value = gtk_toggle_button_get_active(button);
+
+ /* update state of alarm widgets */
+ gtk_widget_set_sensitive(GTK_WIDGET(config_dialog->alarm_timeout_label), value);
+ gtk_widget_set_sensitive(GTK_WIDGET(config_dialog->alarm_timeout_spinbutton), value);
+ gtk_widget_set_sensitive(GTK_WIDGET(config_dialog->low_alarm_command_label), value);
+ gtk_widget_set_sensitive(GTK_WIDGET(config_dialog->low_alarm_command_entry), value);
+ gtk_widget_set_sensitive(GTK_WIDGET(config_dialog->high_alarm_command_label), value);
+ gtk_widget_set_sensitive(GTK_WIDGET(config_dialog->high_alarm_command_entry), value);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ ALARM_ENABLE_COLUMN, value,
+ -1);
+
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_alarm_timeout_changed(GtkSpinButton *spinbutton, SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gint value;
+
+ value = gtk_spin_button_get_value_as_int(spinbutton);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+
+ sensors_applet_all_alarms_off(config_dialog->sensors_applet, path);
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ ALARM_TIMEOUT_COLUMN, value,
+ -1);
+
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_alarm_command_edited(GtkEntry *command_entry, SensorConfigDialog *config_dialog, NotifType notif_type) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ gchar *value;
+ g_object_get(command_entry, "text", &value, NULL);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+
+ sensors_applet_alarm_off(config_dialog->sensors_applet, path, notif_type);
+
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ (notif_type == LOW_ALARM ?
+ LOW_ALARM_COMMAND_COLUMN : HIGH_ALARM_COMMAND_COLUMN),
+ value,
+ -1);
+ g_free(value);
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+static void sensor_config_dialog_low_alarm_command_edited(GtkEntry *command_entry, SensorConfigDialog *config_dialog) {
+ sensor_config_dialog_alarm_command_edited(command_entry,
+ config_dialog,
+ LOW_ALARM);
+}
+
+static void sensor_config_dialog_high_alarm_command_edited(GtkEntry *command_entry, SensorConfigDialog *config_dialog) {
+ sensor_config_dialog_alarm_command_edited(command_entry,
+ config_dialog,
+ HIGH_ALARM);
+}
+
+static void sensor_config_dialog_icon_type_changed(GtkComboBox *icon_type_combo_box,
+ SensorConfigDialog *config_dialog) {
+ GtkTreeModel *icons_model;
+ GtkTreeIter icons_iter;
+
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+
+ GdkPixbuf *new_icon;
+ IconType icon_type;
+
+ icons_model = gtk_combo_box_get_model(icon_type_combo_box);
+ if (gtk_combo_box_get_active_iter(icon_type_combo_box,
+ &icons_iter)) {
+
+ gtk_tree_model_get(icons_model, &icons_iter,
+ 0, &new_icon,
+ -1);
+
+ icon_type = gtk_combo_box_get_active(icon_type_combo_box);
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+
+ path = gtk_tree_model_get_path(model, &iter);
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ ICON_TYPE_COLUMN, icon_type,
+ ICON_PIXBUF_COLUMN, new_icon,
+ -1);
+ g_object_unref(new_icon);
+ sensors_applet_icon_changed(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+ }
+}
+
+static void sensor_config_dialog_graph_color_set(GtkColorButton *color_button,
+ SensorConfigDialog *config_dialog) {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GdkColor color;
+ gchar *color_string;
+
+ gtk_color_button_get_color(color_button,
+ &color);
+
+ color_string = g_strdup_printf("#%02X%02X%02X", color.red / 256,
+ color.green / 256, color.blue / 256);
+
+ gtk_tree_selection_get_selected(config_dialog->sensors_applet->selection,
+ &model,
+ &iter);
+
+ gtk_tree_store_set(config_dialog->sensors_applet->sensors,
+ &iter,
+ GRAPH_COLOR_COLUMN, color_string,
+ -1);
+
+ g_free(color_string);
+
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(config_dialog->sensors_applet->sensors),
+ &iter);
+ sensors_applet_update_sensor(config_dialog->sensors_applet, path);
+ gtk_tree_path_free(path);
+}
+
+void sensor_config_dialog_create(SensorsApplet *sensors_applet) {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ SensorConfigDialog *config_dialog;
+
+ GtkListStore *icon_store;
+ IconType count;
+ GdkPixbuf *pixbuf;
+
+ GdkColor graph_color;
+ gchar *sensor_label;
+ gchar *header_text;
+
+ /* instance variables for data */
+ gdouble low_value, high_value, multiplier, offset;
+ gboolean alarm_enable;
+ gchar *low_alarm_command, *high_alarm_command;
+ gint alarm_timeout;
+ IconType icon_type;
+ gchar *graph_color_string;
+
+ config_dialog = g_new0(SensorConfigDialog, 1);
+ config_dialog->sensors_applet = sensors_applet;
+
+ gtk_tree_selection_get_selected(sensors_applet->selection,
+ &model,
+ &iter);
+ /* get current values of alarm and its enable */
+ gtk_tree_model_get(model, &iter,
+ LOW_VALUE_COLUMN, &low_value,
+ HIGH_VALUE_COLUMN, &high_value,
+ ALARM_ENABLE_COLUMN, &alarm_enable,
+ LOW_ALARM_COMMAND_COLUMN, &low_alarm_command,
+ HIGH_ALARM_COMMAND_COLUMN, &high_alarm_command,
+ ALARM_TIMEOUT_COLUMN, &alarm_timeout,
+ MULTIPLIER_COLUMN, &multiplier,
+ OFFSET_COLUMN, &offset,
+ ICON_TYPE_COLUMN, &icon_type,
+ GRAPH_COLOR_COLUMN, &graph_color_string,
+ LABEL_COLUMN, &sensor_label,
+ -1);
+ header_text = g_strdup_printf("%s - %s", _("Sensor Properties"), sensor_label);
+
+ config_dialog->dialog = gtk_dialog_new_with_buttons(header_text,
+ GTK_WINDOW(sensors_applet->prefs_dialog->dialog),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_HELP,
+ GTK_RESPONSE_HELP,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL);
+
+ g_free(header_text);
+ g_free(sensor_label);
+
+ g_object_set(config_dialog->dialog,
+ "border-width", 12,
+ NULL);
+
+ g_signal_connect(config_dialog->dialog,
+ "response",
+ G_CALLBACK(sensor_config_dialog_response),
+ config_dialog);
+
+
+ /* graph stuff */
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Graph"));
+ config_dialog->graph_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+
+ gdk_color_parse(graph_color_string,
+ &graph_color);
+
+ config_dialog->graph_color_button = GTK_COLOR_BUTTON(gtk_color_button_new_with_color(&graph_color));
+ config_dialog->graph_color_button_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->graph_color_button,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ gtk_color_button_set_title(config_dialog->graph_color_button, _("Graph Color"));
+
+ config_dialog->graph_color_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Graph _color"),
+ "mnemonic-widget", config_dialog->graph_color_button,
+ "use-underline", TRUE,
+ "xalign", 0.0,
+ NULL);
+
+ g_signal_connect(config_dialog->graph_color_button, "color-set",
+ G_CALLBACK(sensor_config_dialog_graph_color_set),
+ config_dialog);
+
+ /* icon stuff */
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Icon"));
+ config_dialog->icon_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+ /* icon type */
+ icon_store = gtk_list_store_new(1, GDK_TYPE_PIXBUF);
+
+ /* populate list with icons */
+ for (count = CPU_ICON; count < NUM_ICONS; count++) {
+ pixbuf = sensors_applet_load_icon(count);
+ if (pixbuf) {
+ gtk_list_store_insert(icon_store, &iter, count);
+ gtk_list_store_set(icon_store, &iter,
+ 0, pixbuf,
+ -1);
+ /* let list hold icons */
+ g_object_unref(pixbuf);
+ }
+ }
+
+ config_dialog->icon_type_combo_box = GTK_COMBO_BOX(gtk_combo_box_new_with_model(GTK_TREE_MODEL(icon_store)));
+
+ config_dialog->icon_type_combo_box_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->icon_type_combo_box,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ config_dialog->icon_renderer = gtk_cell_renderer_pixbuf_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(config_dialog->icon_type_combo_box),
+ GTK_CELL_RENDERER(config_dialog->icon_renderer),
+ FALSE);
+
+ gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(config_dialog->icon_type_combo_box),
+ GTK_CELL_RENDERER(config_dialog->icon_renderer),
+ "pixbuf", 0);
+
+ gtk_combo_box_set_active(config_dialog->icon_type_combo_box,
+ icon_type);
+
+ g_signal_connect(config_dialog->icon_type_combo_box, "changed",
+ G_CALLBACK(sensor_config_dialog_icon_type_changed),
+ config_dialog);
+
+
+
+ config_dialog->icon_type_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Sensor _icon"),
+ "mnemonic-widget", config_dialog->icon_type_combo_box,
+ "use-underline", TRUE,
+ "xalign", 0.0,
+ NULL);
+
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Scaling Parameters"));
+ config_dialog->scale_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+ /* do multiplier and offset widgets */
+ config_dialog->multiplier_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", 1.0,
+ "lower", 0.001,
+ "upper", 1000.0,
+ "step-increment", 0.1,
+ "page-increment", 1.0,
+ "page-size", 1.0,
+ NULL);
+
+
+ config_dialog->multiplier_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", config_dialog->multiplier_adjust,
+ "digits", VALUE_DECIMAL_PLACES,
+ "value", multiplier,
+ "width-chars", SPINBUTTON_WIDTH_CHARS,
+ NULL);
+
+ config_dialog->multiplier_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->multiplier_spinbutton,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ config_dialog->multiplier_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Sensor value _multiplier"),
+ "mnemonic-widget", config_dialog->multiplier_spinbutton,
+ "use-underline", TRUE,
+ "xalign", 0.0,
+ NULL);
+
+
+ g_signal_connect(config_dialog->multiplier_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_multiplier_changed), config_dialog);
+
+
+ config_dialog->offset_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", 0.0,
+ "lower", -1000.000,
+ "upper", 1000.000,
+ "step-increment", 0.01,
+ "page-increment", 1.0,
+ "page-size", 1.0,
+ NULL);
+
+ config_dialog->offset_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", config_dialog->offset_adjust,
+ "digits", VALUE_DECIMAL_PLACES,
+ "value", (gdouble)offset,
+ "width-chars", SPINBUTTON_WIDTH_CHARS,
+ NULL);
+
+ config_dialog->offset_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->offset_spinbutton,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ config_dialog->offset_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Sensor value _offset"),
+ "mnemonic-widget", config_dialog->offset_spinbutton,
+ "use-underline", TRUE,
+ "xalign", 0.0,
+ NULL);
+
+ g_signal_connect(config_dialog->offset_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_offset_changed), config_dialog);
+
+
+ /* now do alarm widgets */
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Sensor Limits"));
+ config_dialog->limits_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+ config_dialog->low_value_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", 0.0,
+ "lower", -100000.0,
+ "upper", 100000.0,
+ "step-increment", 1.0,
+ "page-increment", 10.0,
+ "page-size", 100.0,
+ NULL);
+
+
+ config_dialog->low_value_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", config_dialog->low_value_adjust,
+ "digits", VALUE_DECIMAL_PLACES,
+ "value", low_value,
+ "width-chars", SPINBUTTON_WIDTH_CHARS,
+
+ NULL);
+
+ config_dialog->low_value_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->low_value_spinbutton,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ config_dialog->low_value_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Sensor _low value"),
+ "mnemonic-widget", config_dialog->low_value_spinbutton,
+ "use-underline", TRUE,
+ "xalign", 0.0,
+
+ NULL);
+
+
+ g_signal_connect(config_dialog->low_value_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_low_value_changed), config_dialog);
+
+ config_dialog->high_value_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", 0.0,
+ "lower", -100000.0,
+ "upper", 100000.0,
+ "step-increment", 1.0,
+ "page-increment", 10.0,
+ "page-size", 100.0,
+ NULL);
+
+
+ config_dialog->high_value_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", config_dialog->high_value_adjust,
+ "digits", VALUE_DECIMAL_PLACES,
+ "value", high_value,
+ "width-chars", SPINBUTTON_WIDTH_CHARS,
+
+ NULL);
+
+ config_dialog->high_value_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->high_value_spinbutton,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ config_dialog->high_value_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Sensor _high value"),
+ "mnemonic-widget", config_dialog->high_value_spinbutton,
+ "use-underline", TRUE,
+ "xalign", 0.0,
+
+ NULL);
+
+
+ g_signal_connect(config_dialog->high_value_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_high_value_changed), config_dialog);
+
+
+ header_text = g_markup_printf_escaped("<b>%s</b>", _("Alarm"));
+ config_dialog->alarm_header = g_object_new(GTK_TYPE_LABEL,
+ "use-markup", TRUE,
+ "label", header_text,
+ "xalign", 0.0,
+ NULL);
+ g_free(header_text);
+
+ config_dialog->alarm_timeout_adjust = g_object_new(GTK_TYPE_ADJUSTMENT,
+ "value", 0.0,
+ "lower", 0.0,
+ "upper", 10000.0,
+ "step-increment", 1.0,
+ "page-increment", 10.0,
+ "page-size", 100.0,
+ NULL);
+
+ config_dialog->alarm_timeout_spinbutton = g_object_new(GTK_TYPE_SPIN_BUTTON,
+ "adjustment", config_dialog->alarm_timeout_adjust,
+ "digits", 0,
+ "value", (gdouble)alarm_timeout,
+ "width-chars", SPINBUTTON_WIDTH_CHARS,
+ "sensitive", alarm_enable,
+
+ NULL);
+ config_dialog->alarm_timeout_spinbutton_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->alarm_timeout_spinbutton,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ config_dialog->alarm_timeout_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("Alarm _repeat interval (secs)"),
+ "mnemonic-widget", config_dialog->alarm_timeout_spinbutton,
+
+ "use-underline", TRUE,
+ "xalign", 0.0,
+ "sensitive", alarm_enable,
+ NULL);
+
+ g_signal_connect(config_dialog->alarm_timeout_spinbutton, "value-changed", G_CALLBACK(sensor_config_dialog_alarm_timeout_changed), config_dialog);
+
+ config_dialog->low_alarm_command_entry = g_object_new(GTK_TYPE_ENTRY,
+ "text", low_alarm_command,
+ "width-chars", 25,
+ "sensitive", alarm_enable,
+ NULL);
+
+ g_free(low_alarm_command);
+
+ config_dialog->low_alarm_command_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("Lo_w alarm command"),
+ "mnemonic-widget", config_dialog->low_alarm_command_entry,
+ "xalign", 0.0,
+ "sensitive", alarm_enable,
+
+ NULL);
+
+ g_signal_connect(config_dialog->low_alarm_command_entry,
+ "changed",
+ G_CALLBACK(sensor_config_dialog_low_alarm_command_edited),
+ config_dialog);
+
+ config_dialog->high_alarm_command_entry = g_object_new(GTK_TYPE_ENTRY,
+ "text", high_alarm_command,
+ "width-chars", 25,
+ "sensitive", alarm_enable,
+ NULL);
+
+ g_free(high_alarm_command);
+
+ config_dialog->high_alarm_command_label = g_object_new(GTK_TYPE_LABEL,
+ "use-underline", TRUE,
+ "label", _("Hi_gh alarm command"),
+ "mnemonic-widget", config_dialog->high_alarm_command_entry,
+ "xalign", 0.0,
+ "sensitive", alarm_enable,
+
+ NULL);
+
+ g_signal_connect(config_dialog->high_alarm_command_entry,
+ "changed",
+ G_CALLBACK(sensor_config_dialog_high_alarm_command_edited),
+ config_dialog);
+
+ config_dialog->alarm_enable_checkbutton = g_object_new(GTK_TYPE_CHECK_BUTTON,
+ "use-underline", TRUE,
+ "label", _("_Enable alarm"),
+ "active", alarm_enable,
+ "xalign", 0.0,
+ NULL);
+
+ config_dialog->alarm_enable_aligner = g_object_new(GTK_TYPE_ALIGNMENT,
+ "child", config_dialog->alarm_enable_checkbutton,
+ "xalign", 0.0,
+ "xscale", 0.0,
+ NULL);
+
+ g_signal_connect(config_dialog->alarm_enable_checkbutton, "toggled", G_CALLBACK(sensor_config_dialog_alarm_toggled), config_dialog);
+
+
+
+ config_dialog->size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->multiplier_spinbutton));
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->offset_spinbutton));
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->low_value_spinbutton));
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->high_value_spinbutton));
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->alarm_timeout_spinbutton));
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->icon_type_combo_box));
+ gtk_size_group_add_widget(config_dialog->size_group,
+ GTK_WIDGET(config_dialog->graph_color_button));
+ g_object_unref(config_dialog->size_group);
+
+ config_dialog->table = g_object_new(GTK_TYPE_TABLE,
+ "column-spacing", 5,
+ "homogeneous", FALSE,
+ "n-columns", 3,
+ "n-rows", 15,
+ "row-spacing", 6,
+ "column-spacing", 12,
+ NULL);
+
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->scale_header),
+ 0, 2,
+ 0, 1);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->multiplier_label),
+ 1, 2,
+ 1, 2);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->multiplier_spinbutton_aligner),
+ 2, 3,
+ 1, 2);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->offset_label),
+ 1, 2,
+ 2, 3);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->offset_spinbutton_aligner),
+ 2, 3,
+ 2, 3);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->limits_header),
+ 0, 2,
+ 3, 4);
+
+ /* now pack alarm widgets */
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->low_value_label),
+ 1, 2,
+ 4, 5);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->low_value_spinbutton_aligner),
+ 2, 3,
+ 4, 5);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->high_value_label),
+ 1, 2,
+ 5, 6);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->high_value_spinbutton_aligner),
+ 2, 3,
+ 5, 6);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->alarm_header),
+ 0, 2,
+ 6, 7);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->alarm_enable_aligner),
+ 1, 2,
+ 7, 8);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->alarm_timeout_label),
+ 1, 2,
+ 8, 9);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->alarm_timeout_spinbutton_aligner),
+ 2, 3,
+ 8, 9);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->low_alarm_command_label),
+ 1, 2,
+ 9, 10);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->low_alarm_command_entry),
+ 2, 3,
+ 9, 10);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->high_alarm_command_label),
+ 1, 2,
+ 10, 11);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->high_alarm_command_entry),
+ 2, 3,
+ 10, 11);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->icon_header),
+ 0, 2,
+ 11, 12);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->icon_type_label),
+ 1, 2,
+ 12, 13);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->icon_type_combo_box_aligner),
+ 2, 3,
+ 12, 13);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->graph_header),
+ 0, 2,
+ 13, 14);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->graph_color_label),
+ 1, 2,
+ 14, 15);
+
+ gtk_table_attach_defaults(config_dialog->table,
+ GTK_WIDGET(config_dialog->graph_color_button_aligner),
+ 2, 3,
+ 14, 15);
+
+ gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(config_dialog->dialog)->vbox), GTK_WIDGET(config_dialog->table));
+ gtk_widget_show_all(config_dialog->dialog);
+
+}
diff --git a/sensors-applet/sensor-config-dialog.h b/sensors-applet/sensor-config-dialog.h
new file mode 100644
index 0000000..53929f6
--- /dev/null
+++ b/sensors-applet/sensor-config-dialog.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 SENSOR_CONFIG_DIALOG_H
+#define SENSOR_CONFIG_DIALOG_H
+
+#include "sensors-applet.h"
+
+/* function definition */
+
+void sensor_config_dialog_create(SensorsApplet *sensors_applet);
+
+#endif /* SENSOR_CONFIG_DIALOG_H */
diff --git a/sensors-applet/sensors-applet-gconf.c b/sensors-applet/sensors-applet-gconf.c
new file mode 100644
index 0000000..852a3fc
--- /dev/null
+++ b/sensors-applet/sensors-applet-gconf.c
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "sensors-applet.h"
+#include "sensors-applet-gconf.h"
+
+#define DEFAULT_TIMEOUT 2000
+#define DEFAULT_GRAPH_SIZE 42
+
+static const gchar * const compatible_versions[] = {
+ PACKAGE_VERSION, /* always list current version */
+ "2.2.6",
+ "2.2.5",
+ "2.2.4",
+ "2.2.3",
+ "2.2.2",
+};
+
+#define NUM_COMPATIBLE_VERSIONS G_N_ELEMENTS(compatible_versions)
+
+typedef enum {
+ SENSORS_APPLET_GCONF_ERROR = 0,
+ SENSORS_APPLET_VERSION_ERROR,
+} SensorsAppletGConfError;
+
+static const gchar * const error_titles[] = {
+ N_("An error occurred loading the stored sensors data"),
+ N_("Incompatible sensors configuration found")
+};
+
+static const gchar * const error_messages[] = {
+ N_("An error has occurred when loading the stored sensors data. "
+ "The default values will be used to recover from this error."),
+
+ N_("Unfortunately the previous configuration for GNOME Sensors Applet "
+ "is not compatible with this version. The existing sensors data "
+ "will be overwritten with the default values for this new version.")
+};
+
+/* function to be called if an error occurs
+ when loading values from gconf */
+static void sensors_applet_gconf_error_occurred(SensorsAppletGConfError error) {
+ GtkWidget *dialog;
+ gchar *markup;
+
+ g_debug("Error occurred: %s", error_titles[error]);
+ markup = g_markup_printf_escaped("<span size=\"large\" weight=\"bold\">%s</span>\n\n%s", _(error_titles[error]), _(error_messages[error]));
+
+ dialog = gtk_message_dialog_new_with_markup(NULL, /* no parent window */
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ "%s", markup);
+
+ g_free(markup);
+
+ /* runs dialog as modal and doesn't return until user clicks
+ * button */
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+}
+
+
+static void sensors_applet_gconf_set_defaults(SensorsApplet *sensors_applet) {
+ panel_applet_gconf_set_int(sensors_applet->applet, DISPLAY_MODE, DISPLAY_ICON_WITH_VALUE, NULL);
+ panel_applet_gconf_set_int(sensors_applet->applet, LAYOUT_MODE, VALUE_BESIDE_LABEL, NULL);
+ panel_applet_gconf_set_int(sensors_applet->applet, TEMPERATURE_SCALE, CELSIUS, NULL);
+ panel_applet_gconf_set_int(sensors_applet->applet, TIMEOUT, DEFAULT_TIMEOUT, NULL);
+ panel_applet_gconf_set_int(sensors_applet->applet, GRAPH_SIZE, DEFAULT_GRAPH_SIZE, NULL);
+#ifdef HAVE_LIBNOTIFY
+ panel_applet_gconf_set_bool(sensors_applet->applet, DISPLAY_NOTIFICATIONS, TRUE, NULL);
+#endif
+ panel_applet_gconf_set_bool(sensors_applet->applet, IS_SETUP, FALSE, NULL);
+
+}
+
+/**
+ * Returns TRUE is old_version is one of the compatible versions
+ */
+static gboolean sensors_applet_gconf_is_compatible(const gchar *old_version) {
+ guint i;
+ for (i = 0; i < NUM_COMPATIBLE_VERSIONS; i++) {
+ if (g_ascii_strcasecmp(old_version, compatible_versions[i]) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void sensors_applet_gconf_setup(SensorsApplet *sensors_applet) {
+ gboolean setup = FALSE;
+ gchar *old_version;
+ GError *error = NULL;
+
+ /* need to convert old num_samples value to new GRAPH_SIZE
+ * parameter */
+ gint num_samples;
+ if ((num_samples = panel_applet_gconf_get_int(sensors_applet->applet,
+ "num_samples",
+ NULL))) {
+ g_debug("Convering old num_samples value %d into graph_size", num_samples);
+ panel_applet_gconf_set_int(sensors_applet->applet,
+ GRAPH_SIZE,
+ (num_samples + GRAPH_FRAME_EXTRA_WIDTH),
+ NULL);
+ /* reset num_samples to zero */
+ panel_applet_gconf_set_int(sensors_applet->applet,
+ "num_samples",
+ 0,
+ NULL);
+
+ }
+
+ /* convert old alarm_commands to high and low if exist */
+ GSList *alarm_commands;
+ if ((alarm_commands = panel_applet_gconf_get_list(sensors_applet->applet,
+ "alarm_commands",
+ GCONF_VALUE_STRING,
+ NULL))) {
+
+ g_debug("Converting old alarm commands to new high and low commands");
+
+ panel_applet_gconf_set_list(sensors_applet->applet,
+ LOW_ALARM_COMMANDS,
+ GCONF_VALUE_STRING,
+ alarm_commands,
+ NULL);
+ panel_applet_gconf_set_list(sensors_applet->applet,
+ HIGH_ALARM_COMMANDS,
+ GCONF_VALUE_STRING,
+ alarm_commands,
+ NULL);
+ /* reset old list to null */
+ panel_applet_gconf_set_list(sensors_applet->applet,
+ "alarm_commands",
+ GCONF_VALUE_STRING,
+ NULL,
+ NULL);
+ g_slist_foreach(alarm_commands, (GFunc)g_free, NULL);
+ g_slist_free(alarm_commands);
+
+ }
+
+ setup = panel_applet_gconf_get_bool(sensors_applet->applet,
+ IS_SETUP, &error);
+ if (error) {
+ g_debug("Previous configuration not found: %s, setting up manually", error->message);
+ g_error_free(error);
+ error = NULL;
+ setup = FALSE;
+ }
+
+
+ if (setup) {
+ /* see if setup version matches */
+ old_version = panel_applet_gconf_get_string(sensors_applet->applet,
+ SENSORS_APPLET_VERSION,
+ &error);
+ /* if versions don't match or there is no saved
+ * version string then need to overwrite old config */
+ if (error) {
+ g_debug("Error getting old version string: %s", error->message);
+ g_error_free(error);
+ error = NULL;
+ old_version = NULL;
+ }
+
+ if (old_version) {
+ if (sensors_applet_gconf_is_compatible(old_version)) {
+ /* previously setup and versions match so use
+ * old values */
+ g_debug("GConf data is compatible. Trying to set up sensors from gconf data");
+ if (sensors_applet_gconf_setup_sensors(sensors_applet)) {
+ g_debug("done setting up from gconf");
+ } else {
+ g_debug("Setting gconf defaults only");
+ sensors_applet_gconf_set_defaults(sensors_applet);
+ }
+ g_free(old_version);
+
+ return;
+
+
+ }
+ g_free(old_version);
+
+ }
+ sensors_applet_notify(sensors_applet, GCONF_READ_ERROR);
+
+
+ sensors_applet_gconf_error_occurred(SENSORS_APPLET_VERSION_ERROR);
+ }
+
+ /* use defaults */
+ g_debug("Setting gconf defaults only");
+ sensors_applet_gconf_set_defaults(sensors_applet);
+}
+
+enum {
+ PATHS_INDEX = 0,
+ IDS_INDEX,
+ LABELS_INDEX,
+ INTERFACES_INDEX,
+ SENSOR_TYPES_INDEX,
+ ENABLES_INDEX,
+ LOW_VALUES_INDEX,
+ HIGH_VALUES_INDEX,
+ ALARM_ENABLES_INDEX,
+ LOW_ALARM_COMMANDS_INDEX,
+ HIGH_ALARM_COMMANDS_INDEX,
+ ALARM_TIMEOUTS_INDEX,
+ MULTIPLIERS_INDEX,
+ OFFSETS_INDEX,
+ ICON_TYPES_INDEX,
+ GRAPH_COLORS_INDEX,
+ NUM_KEYS
+};
+
+const gchar * const keys[NUM_KEYS] = {
+ PATHS,
+ IDS,
+ LABELS,
+ INTERFACES,
+ SENSOR_TYPES,
+ ENABLES,
+ LOW_VALUES,
+ HIGH_VALUES,
+ ALARM_ENABLES,
+ LOW_ALARM_COMMANDS,
+ HIGH_ALARM_COMMANDS,
+ ALARM_TIMEOUTS,
+ MULTIPLIERS,
+ OFFSETS,
+ ICON_TYPES,
+ GRAPH_COLORS,
+};
+
+/* MUST CORRESPOND TO ABOVE KEYS */
+const GConfValueType key_types[NUM_KEYS] = {
+ GCONF_VALUE_STRING, /* PATHS */
+ GCONF_VALUE_STRING, /* IDS, */
+ GCONF_VALUE_STRING, /* LABELS */
+ GCONF_VALUE_STRING, /* INTERFACES, */
+ GCONF_VALUE_INT, /* SENSOR_TYPES, */
+ GCONF_VALUE_BOOL, /* ENABLES, */
+ GCONF_VALUE_INT, /* LOW_VALUES, */
+ GCONF_VALUE_INT, /* HIGH_VALUES, */
+ GCONF_VALUE_BOOL, /* ALARM_ENABLES, */
+ GCONF_VALUE_STRING, /* LOW_ALARM_COMMANDS, */
+ GCONF_VALUE_STRING, /* HIGH_ALARM_COMMANDS, */
+ GCONF_VALUE_INT, /* ALARM_TIMEOUTS, */
+ GCONF_VALUE_INT, /* MULTIPLIERS, */
+ GCONF_VALUE_INT, /* OFFSETS, */
+ GCONF_VALUE_INT, /* ICON_TYPES, */
+ GCONF_VALUE_STRING /* GRAPH_COLORS, */
+};
+
+void sensors_applet_gconf_set_current_to_lists(GSList *current[],
+ GSList *lists[],
+ int len) {
+ for (len--; len >= 0; len--) {
+ current[len] = lists[len];
+ }
+}
+
+int sensors_applet_gconf_current_not_null(GSList *current[],
+ int len) {
+ for (len--; len >= 0; len--) {
+ if (NULL == current[len]) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+void sensors_applet_gconf_current_get_next(GSList *current[],
+ int len) {
+ for (len--; len >= 0; len--) {
+ current[len] = g_slist_next(current[len]);
+ }
+}
+
+void sensors_applet_gconf_free_lists(GSList *lists[],
+ int len) {
+ for (len--; len >= 0; len--) {
+ if (key_types[len] == GCONF_VALUE_STRING) {
+ g_slist_foreach(lists[len], (GFunc)g_free, NULL);
+ }
+ g_slist_free(lists[len]);
+ }
+
+}
+
+/* gets called if are already setup so we don't have to manually go
+ through and find sensors etc again */
+gboolean sensors_applet_gconf_setup_sensors(SensorsApplet *sensors_applet) {
+ /* everything gets stored except alarm timeout indexes, which
+ we set to -1, and visible which we set to false for all
+ parent nodes and true for all child nodes */
+ int i;
+ GSList *lists[NUM_KEYS] = {NULL};
+
+ GSList *current[NUM_KEYS] = {NULL};
+
+ GError *error = NULL;
+
+ for (i = 0; i < NUM_KEYS; i++) {
+ lists[i] = panel_applet_gconf_get_list(sensors_applet->applet,
+ keys[i],
+ key_types[i],
+ &error);
+ if (error || NULL == lists[i]) {
+ sensors_applet_notify(sensors_applet, GCONF_READ_ERROR);
+
+ sensors_applet_gconf_error_occurred(SENSORS_APPLET_GCONF_ERROR);
+ if (error) {
+ g_error_free(error);
+ }
+ return FALSE;
+ }
+ }
+
+ for (sensors_applet_gconf_set_current_to_lists(current,
+ lists,
+ NUM_KEYS);
+ sensors_applet_gconf_current_not_null(current,
+ NUM_KEYS);
+ sensors_applet_gconf_current_get_next(current,
+ NUM_KEYS)) {
+
+
+ g_debug("trying to add sensor from gconf data: %s\n", (gchar *)(current[IDS_INDEX]->data));
+ /* need to ensure correct order */
+ sensors_applet_add_sensor(sensors_applet,
+ (gchar *)(current[PATHS_INDEX]->data),
+ (gchar *)(current[IDS_INDEX]->data),
+ (gchar *)(current[LABELS_INDEX]->data),
+ (gchar *)(current[INTERFACES_INDEX]->data),
+ GPOINTER_TO_UINT(current[SENSOR_TYPES_INDEX]->data),
+ GPOINTER_TO_INT(current[ENABLES_INDEX]->data),
+ (gdouble)(GPOINTER_TO_INT(current[LOW_VALUES_INDEX]->data) / 1000.0),
+ (gdouble)(GPOINTER_TO_INT(current[HIGH_VALUES_INDEX]->data) / 1000.0),
+ GPOINTER_TO_INT(current[ALARM_ENABLES_INDEX]->data),
+ (gchar *)(current[LOW_ALARM_COMMANDS_INDEX]->data),
+ (gchar *)(current[HIGH_ALARM_COMMANDS_INDEX]->data),
+ GPOINTER_TO_INT(current[ALARM_TIMEOUTS_INDEX]->data),
+ (gdouble)(GPOINTER_TO_INT(current[MULTIPLIERS_INDEX]->data) / 1000.0),
+ (gdouble)(GPOINTER_TO_INT(current[OFFSETS_INDEX]->data) / 1000.0),
+ (SensorType)GPOINTER_TO_UINT(current[ICON_TYPES_INDEX]->data),
+ (gchar *)(current[GRAPH_COLORS_INDEX]->data)
+
+ );
+
+ }
+ sensors_applet_gconf_free_lists(lists,
+ NUM_KEYS);
+
+ return TRUE;
+}
+
+
+gboolean sensors_applet_gconf_save_sensors(SensorsApplet *sensors_applet) {
+ /* write everything to gconf except VISIBLE and
+ ALARM_TIMEOUT_INDEX */
+ /* for stepping through GtkTreeStore data structure */
+ GtkTreeIter interfaces_iter, sensors_iter;
+ gboolean not_end_of_interfaces = TRUE, not_end_of_sensors = TRUE;
+
+ /* make sure all are initialized to null - since list of
+ * intializers is horter than number of element, rest get set
+ * to 0 (ie NULL) */
+ GSList *lists[NUM_KEYS] = {NULL};
+ int i;
+ gchar *current_path, *current_id, *current_label, *current_interface,
+ *current_low_alarm_command, *current_high_alarm_command,
+ *current_graph_color;
+ gboolean current_enable, current_alarm_enable;
+ gdouble current_low_value, current_high_value, current_multiplier,
+ current_offset;
+ guint current_alarm_timeout, current_sensor_type,
+ current_icon_type;
+
+ GError *error = NULL;
+
+ /* now step through the GtkTreeStore sensors to
+ find which sensors are enabled */
+ for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); not_end_of_interfaces; not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter)) {
+ // store a gconf key for this interface
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors),
+ &interfaces_iter,
+ ID_COLUMN, &current_id,
+ -1);
+
+ panel_applet_gconf_set_bool(sensors_applet->applet, current_id, TRUE, NULL);
+ g_free(current_id);
+
+ /* reset sensors sentinel */
+ not_end_of_sensors = TRUE;
+
+ for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); not_end_of_sensors; not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors),
+ &sensors_iter,
+ PATH_COLUMN, &current_path,
+ ID_COLUMN, &current_id,
+ LABEL_COLUMN, &current_label,
+ INTERFACE_COLUMN, &current_interface,
+ SENSOR_TYPE_COLUMN, &current_sensor_type,
+ ENABLE_COLUMN, &current_enable,
+ LOW_VALUE_COLUMN, &current_low_value,
+ HIGH_VALUE_COLUMN, &current_high_value,
+ ALARM_ENABLE_COLUMN, &current_alarm_enable,
+ LOW_ALARM_COMMAND_COLUMN, &current_low_alarm_command,
+ HIGH_ALARM_COMMAND_COLUMN, &current_high_alarm_command,
+ ALARM_TIMEOUT_COLUMN, &current_alarm_timeout,
+ MULTIPLIER_COLUMN, &current_multiplier,
+ OFFSET_COLUMN, &current_offset,
+ ICON_TYPE_COLUMN, &current_icon_type,
+ GRAPH_COLOR_COLUMN, &current_graph_color,
+ -1);
+
+ /* prepend values as this is faster then just
+ reverse list when finished */
+ lists[PATHS_INDEX] = g_slist_prepend(lists[PATHS_INDEX], current_path);
+ lists[IDS_INDEX] = g_slist_prepend(lists[IDS_INDEX], current_id);
+ lists[LABELS_INDEX] = g_slist_prepend(lists[LABELS_INDEX], current_label);
+ lists[INTERFACES_INDEX] = g_slist_prepend(lists[INTERFACES_INDEX], current_interface);
+ lists[ENABLES_INDEX] = g_slist_prepend(lists[ENABLES_INDEX], GINT_TO_POINTER(current_enable));
+ lists[LOW_VALUES_INDEX] = g_slist_prepend(lists[LOW_VALUES_INDEX], GINT_TO_POINTER((gint)(current_low_value * 1000)));
+ lists[HIGH_VALUES_INDEX] = g_slist_prepend(lists[HIGH_VALUES_INDEX], GINT_TO_POINTER((gint)(current_high_value * 1000)));
+ lists[ALARM_ENABLES_INDEX] = g_slist_prepend(lists[ALARM_ENABLES_INDEX], GINT_TO_POINTER(current_alarm_enable));
+ lists[LOW_ALARM_COMMANDS_INDEX] = g_slist_prepend(lists[LOW_ALARM_COMMANDS_INDEX], current_low_alarm_command);
+ lists[HIGH_ALARM_COMMANDS_INDEX] = g_slist_prepend(lists[HIGH_ALARM_COMMANDS_INDEX], current_high_alarm_command);
+ lists[ALARM_TIMEOUTS_INDEX] = g_slist_prepend(lists[ALARM_TIMEOUTS_INDEX], GINT_TO_POINTER(current_alarm_timeout));
+ lists[SENSOR_TYPES_INDEX] = g_slist_prepend(lists[SENSOR_TYPES_INDEX], GUINT_TO_POINTER(current_sensor_type));
+ lists[MULTIPLIERS_INDEX] = g_slist_prepend(lists[MULTIPLIERS_INDEX], GINT_TO_POINTER((gint)(current_multiplier * 1000)));
+ lists[OFFSETS_INDEX] = g_slist_prepend(lists[OFFSETS_INDEX], GINT_TO_POINTER((gint)(current_offset * 1000)));
+ lists[ICON_TYPES_INDEX] = g_slist_prepend(lists[ICON_TYPES_INDEX], GUINT_TO_POINTER(current_icon_type));
+ lists[GRAPH_COLORS_INDEX] = g_slist_prepend(lists[GRAPH_COLORS_INDEX], current_graph_color);
+ }
+ }
+
+ /* keep lists in original order */
+ for (i = 0; i < NUM_KEYS; i++) {
+ if (lists[i] != NULL) {
+ lists[i] = g_slist_reverse(lists[i]);
+
+ panel_applet_gconf_set_list(sensors_applet->applet,
+ keys[i],
+ key_types[i],
+ lists[i], &error);
+ if (error) {
+ sensors_applet_notify(sensors_applet, GCONF_WRITE_ERROR);
+
+ g_error_free(error);
+ return FALSE;
+ }
+ } else {
+ g_debug("list %s is NULL", keys[i]);
+ }
+
+ }
+
+ sensors_applet_gconf_free_lists(lists,
+ NUM_KEYS);
+
+ /* store current version to identify config data */
+ panel_applet_gconf_set_string(sensors_applet->applet,
+ SENSORS_APPLET_VERSION,
+ PACKAGE_VERSION, &error);
+
+ return TRUE;
+}
+
diff --git a/sensors-applet/sensors-applet-gconf.h b/sensors-applet/sensors-applet-gconf.h
new file mode 100644
index 0000000..527e364
--- /dev/null
+++ b/sensors-applet/sensors-applet-gconf.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 SENSORS_APPLET_GCONF_H
+#define SENSORS_APPLET_GCONF_H
+
+#include "sensors-applet.h"
+#include <panel-applet-gconf.h>
+
+#define FONT_SIZE "font-size" /* hidden gconf option specifying font
+ * size in points */
+
+#define HIDE_UNITS "hide-units" /* hidden gconf option specifying not to
+ * show sensor units */
+
+#define IS_SETUP "setup" /* have we actually set up this instance of
+ * the applet (gets set to true after
+ * closing prefences dialog) */
+
+#define DISPLAY_MODE "display_mode" /* display icons or text labels?*/
+
+#define LAYOUT_MODE "layout_mode" /* value beside or below label */
+#define TEMPERATURE_SCALE "temperature_scale" /* Kelvin,
+ Celsius or
+ Fahrenheit */
+#define DISPLAY_NOTIFICATIONS "display_notifications" /* whether to
+ * display
+ * notifications */
+#define TIMEOUT "timeout_delay" /* delay (in ms) between refreshes */
+#define GRAPH_SIZE "graph_size" /* the size of the graph in pixels -
+ * either width if horizontal, or
+ * height if vertical */
+#define PATHS "paths" /* full paths to filenames */
+#define IDS "ids" /* a list of the sensor device ids */
+#define INTERFACES "interfaces" /* a list of the sensor device
+ * interface for each sensor */
+#define LABELS "labels" /* user defined labels for each sensor */
+#define ENABLES "sensor_enables" /* list of booleans corresponding to
+ * the filenames of whether a sensor
+ * is enabled or not */
+#define LOW_VALUES "low_values" /* stored as ints (1000 * double
+ * value) for accuracy, since can
+ * only do ints easily */
+#define HIGH_VALUES "high_values" /* stored as ints (1000 * double
+ * value) for accuracy, since can
+ * only do ints easily */
+#define ALARM_ENABLES "alarm_enables" /* list of whether each sensor
+ * has its alarm enabled */
+#define LOW_ALARM_COMMANDS "low_alarm_commands" /* list of commands to execute
+ * when each alarm is
+ * activated */
+#define HIGH_ALARM_COMMANDS "high_alarm_commands" /* list of commands to execute
+ * when each alarm is
+ * activated */
+
+#define ALARM_TIMEOUTS "alarm_timeouts" /* list of how often each
+ alarm should be sounded (in
+ seconds) */
+
+#define SENSOR_TYPES "sensor_types" /* used to identify a sensor in a
+ list */
+
+#define MULTIPLIERS "multipliers"
+#define OFFSETS "offsets"
+#define ICON_TYPES "icon_types"
+#define GRAPH_COLORS "graph_colors"
+
+#define SENSORS_APPLET_VERSION "sensors_applet_version" /* version of
+ * config
+ * data */
+
+gboolean sensors_applet_gconf_save_sensors(SensorsApplet *sensors_applet);
+gboolean sensors_applet_gconf_setup_sensors(SensorsApplet *sensors_applet);
+void sensors_applet_gconf_setup(SensorsApplet *sensors_applet);
+
+#endif /* SENSORS_APPLET_GCONF_H*/
diff --git a/sensors-applet/sensors-applet-plugin.h b/sensors-applet/sensors-applet-plugin.h
new file mode 100644
index 0000000..9c664b5
--- /dev/null
+++ b/sensors-applet/sensors-applet-plugin.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 SENSORS_APPLET_PLUGIN_H
+#define SENSORS_APPLET_PLUGIN_H
+
+#include <sensors-applet/sensors-applet-sensor.h>
+
+GQuark sensors_applet_plugin_error_quark(void);
+
+/* for error handling */
+#define SENSORS_APPLET_PLUGIN_ERROR (sensors_applet_plugin_error_quark())
+
+
+/**
+ * Initialises the plugin, and returns the list of SensorsAppletSensorInfo
+ * structs to create the sensors for this plugin from
+ */
+GList *sensors_applet_plugin_init(void);
+gdouble sensors_applet_plugin_get_sensor_value(const gchar *path,
+ const gchar *id,
+ SensorType type,
+ GError **error);
+
+typedef void SensorsAppletPluginTestSensorFunc(GList **sensors,
+ const gchar *path);
+void sensors_applet_plugin_find_sensors(GList **sensors,
+ const gchar *path,
+ SensorsAppletPluginTestSensorFunc);
+
+void sensors_applet_plugin_default_sensor_limits(SensorType type,
+ gdouble *low_value,
+ gdouble *high_value);
+
+void sensors_applet_plugin_add_sensor(GList **sensors,
+ const gchar *path,
+ const gchar *id,
+ const gchar *label,
+ SensorType type,
+ gboolean enable,
+ IconType icon,
+ const gchar *graph_color);
+
+
+void sensors_applet_plugin_add_sensor_with_limits(GList **sensors,
+ const gchar *path,
+ const gchar *id,
+ const gchar *label,
+ SensorType type,
+ gboolean enable,
+ gdouble low_value,
+ gdouble high_value,
+ IconType icon,
+ const gchar *graph_color);
+
+
+#endif // SENSORS_APPLET_PLUGIN_H
diff --git a/sensors-applet/sensors-applet-plugins.c b/sensors-applet/sensors-applet-plugins.c
new file mode 100644
index 0000000..7dfad78
--- /dev/null
+++ b/sensors-applet/sensors-applet-plugins.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif /* HAVE_DLFCN_H */
+
+#include "sensors-applet-plugins.h"
+#include "sensors-applet-sensor.h"
+
+#define SENSORS_APPLET_USER_PLUGIN_DIR ".gnome2/sensors-applet/plugins"
+
+static void load_all_plugins(SensorsApplet *sensors_applet,
+ const gchar *path)
+{
+ if (g_file_test(path,
+ G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+ GDir *dir;
+ if ((dir = g_dir_open(path, 0, NULL)) != NULL) {
+ const gchar *file;
+ while ((file = g_dir_read_name(dir)) != NULL) {
+ // try and open plugin
+ gchar *plugin_file;
+ void *handle;
+ SensorsAppletPluginName name_fn;
+ SensorsAppletPluginInit init_fn;
+ SensorsAppletPluginGetSensorValue get_value_fn;
+
+ plugin_file = g_strdup_printf("%s/%s", path, file);
+ g_debug("found %s in plugin directory", plugin_file);
+ if ((handle = dlopen(plugin_file, RTLD_NOW)) != NULL) {
+
+ if ((name_fn = dlsym(handle, "sensors_applet_plugin_name")) != NULL &&
+ (init_fn = dlsym(handle, "sensors_applet_plugin_init")) != NULL &&
+ (get_value_fn = dlsym(handle, "sensors_applet_plugin_get_sensor_value")) != NULL) {
+ GList *sensors;
+ g_debug("calling init function for plugin file %s", plugin_file);
+
+ if ((sensors = init_fn()) != NULL) {
+ GList *sensor;
+
+ g_debug("registering plugin %s", name_fn());
+ g_hash_table_insert(sensors_applet->plugins,
+ g_strdup(name_fn()),
+ get_value_fn);
+ for (sensor = g_list_first(sensors);
+ sensor != NULL;
+ sensor = g_list_next(sensor)) {
+ SensorsAppletSensorInfo *sensor_info = (SensorsAppletSensorInfo *)sensor->data;
+ sensors_applet_add_sensor(sensors_applet,
+ sensor_info->path,
+ sensor_info->id,
+ sensor_info->label,
+ name_fn(),
+ sensor_info->type,
+ sensor_info->enable,
+ sensor_info->low_value,
+ sensor_info->high_value,
+ FALSE, // ALARM OFF
+ "", // no alarm commands
+ "", // no alarm commands
+ 0, // alarm_timeout
+ sensor_info->multiplier,
+ sensor_info->offset,
+ sensor_info->icon,
+ sensor_info->graph_color);
+
+ g_free(sensor_info->path);
+ g_free(sensor_info->id);
+ g_free(sensor_info->label);
+ g_free(sensor_info->graph_color);
+ g_free(sensor_info);
+ }
+ g_list_free(sensors);
+ } else {
+ g_debug("plugin could not find any sensors");
+ if (g_hash_table_lookup(sensors_applet->required_plugins,
+ name_fn()))
+ {
+ g_debug("plugin is required - registering even though no sensors detected");
+ g_debug("registering plugin %s", name_fn());
+ g_hash_table_insert(sensors_applet->plugins,
+ g_strdup(name_fn()),
+ get_value_fn);
+ } else {
+ g_debug("unloading plugin");
+ }
+ }
+
+
+
+ } else {
+ g_debug("plugin file %s does not contain the required interface", plugin_file);
+ if (dlclose(handle) != 0) {
+ g_debug("error closing plugin file %s", plugin_file);
+ }
+ }
+ } else {
+ g_debug("Could not dlopen: %s: %s", plugin_file, dlerror());
+ }
+ g_free(plugin_file);
+ }
+ g_dir_close(dir);
+ } else {
+ g_debug("error opening plugin dir %s", path);
+ }
+ } else {
+ g_debug("path %s is not a valid directory", path);
+ }
+}
+
+void sensors_applet_plugins_load_all(SensorsApplet *sensors_applet)
+{
+ const gchar *home;
+
+ if ((home = g_get_home_dir()) != NULL) {
+ gchar *path;
+ path = g_build_filename(home,
+ SENSORS_APPLET_USER_PLUGIN_DIR,
+ NULL);
+ load_all_plugins(sensors_applet, path);
+ g_free(path);
+ } else {
+ g_warning("could not get home dir of user");
+ }
+
+
+ load_all_plugins(sensors_applet, SENSORS_APPLET_PLUGIN_DIR);
+}
+
+SensorsAppletPluginGetSensorValue sensors_applet_plugins_get_sensor_value_func(SensorsApplet *sensors_applet,
+ const gchar *plugin)
+{
+ return g_hash_table_lookup(sensors_applet->plugins,
+ plugin);
+}
+
+
diff --git a/sensors-applet/sensors-applet-plugins.h b/sensors-applet/sensors-applet-plugins.h
new file mode 100644
index 0000000..2f6dd3d
--- /dev/null
+++ b/sensors-applet/sensors-applet-plugins.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 SENSORS_APPLET_PLUGINS_H
+#define SENSORS_APPLET_PLUGINS_H
+
+#include "sensors-applet.h"
+
+typedef const gchar *(*SensorsAppletPluginName)(void);
+typedef GList *(*SensorsAppletPluginInit)(void);
+typedef gdouble (*SensorsAppletPluginGetSensorValue)(const gchar *path,
+ const gchar *id,
+ SensorType type,
+ GError **error);
+
+void sensors_applet_plugins_load_all(SensorsApplet *sensors_applet);
+void sensors_applet_plugins_unload_all(SensorsApplet *sensors_applet);
+SensorsAppletPluginGetSensorValue sensors_applet_plugins_get_sensor_value_func(SensorsApplet *sensors_applet,
+ const gchar *plugin);
+
+#endif // SENSORS_APPLET_PLUGINS_H
diff --git a/sensors-applet/sensors-applet-sensor.h b/sensors-applet/sensors-applet-sensor.h
new file mode 100644
index 0000000..2314a52
--- /dev/null
+++ b/sensors-applet/sensors-applet-sensor.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 SENSORS_APPLET_SENSOR_H
+#define SENSORS_APPLET_SENSOR_H
+
+#include <glib.h>
+
+// forward declare for plugins to use
+typedef struct _SensorsApplet SensorsApplet;
+
+#define DEFAULT_GRAPH_COLOR "#ff0000"
+
+/* device icons */
+typedef enum {
+ CPU_ICON = 0,
+ HDD_ICON,
+ BATTERY_ICON,
+ MEMORY_ICON,
+ GPU_ICON,
+ GENERIC_ICON,
+ FAN_ICON,
+ CASE_ICON,
+ NUM_ICONS,
+} IconType;
+
+typedef enum {
+ CURRENT_SENSOR = 0,
+ FAN_SENSOR,
+ TEMP_SENSOR,
+ VOLTAGE_SENSOR
+} SensorType;
+
+typedef struct _SensorsAppletSensorInfo {
+ gchar *path; // must be dynamically allocated
+ gchar *id; // must be dynamically allocated
+ gchar *label; // must be dynamically allocated
+ SensorType type;
+ gboolean enable;
+ gdouble low_value;
+ gdouble high_value;
+ gdouble multiplier;
+ gdouble offset;
+ IconType icon;
+ gchar *graph_color; // must be dynamically allocated
+} SensorsAppletSensorInfo;
+
+
+#endif // SENSORS_APPLET_SENSOR_H
diff --git a/sensors-applet/sensors-applet.c b/sensors-applet/sensors-applet.c
new file mode 100644
index 0000000..9486173
--- /dev/null
+++ b/sensors-applet/sensors-applet.c
@@ -0,0 +1,1451 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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
+ */
+
+/** Contain the functions for operating on the SensorsApplet structure
+ * (represents the applet itself, and its associated variables.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <gnome.h>
+#include <glib/gprintf.h>
+#include "sensors-applet.h"
+#include "active-sensor.h"
+#include "sensors-applet-gconf.h"
+#include "sensors-applet-plugins.h"
+
+#ifdef HAVE_LIBNOTIFY
+#include "active-sensor-libnotify.h"
+#define DEFAULT_NOTIFY_TIMEOUT 3000
+#endif
+
+#include "prefs-dialog.h"
+#include "about-dialog.h"
+
+#define SENSORS_APPLET_MENU_FILE "SensorsApplet.xml"
+#define DEFAULT_APPLET_SIZE 24 /* initially set as
+ * sensors_applet->size to ensure a
+ * real value is stored */
+#define COLUMN_SPACING 2
+#define ROW_SPACING 0
+
+/* callbacks for panel menu */
+static void prefs_cb(BonoboUIComponent *uic,
+ gpointer *data,
+ const gchar *verbname) {
+
+ SensorsApplet *sensors_applet;
+ sensors_applet = (SensorsApplet *)data;
+
+ if (sensors_applet->prefs_dialog) {
+ gtk_window_present(GTK_WINDOW(sensors_applet->prefs_dialog->dialog));
+ return;
+ }
+ prefs_dialog_open(sensors_applet);
+}
+
+static void about_cb(BonoboUIComponent *uic,
+ gpointer data,
+ const gchar *verbname) {
+ SensorsApplet *sensors_applet;
+ sensors_applet = (SensorsApplet *)data;
+
+ about_dialog_open(sensors_applet);
+}
+
+static void help_cb(BonoboUIComponent *uic,
+ gpointer data,
+ const gchar *verbname) {
+
+ GError *error = NULL;
+
+ gtk_show_uri(NULL, "ghelp:sensors-applet",
+ gtk_get_current_event_time(),
+ &error);
+
+ if (error) {
+ g_debug("Could not open help document: %s ",error->message);
+ g_error_free(error);
+ }
+}
+
+static void destroy_cb(GtkWidget *widget, gpointer data) {
+ SensorsApplet *sensors_applet;
+ sensors_applet = (SensorsApplet *)data;
+
+ /* destory dialogs, remove timeout and clear sensors tree and finally
+ * the applet */
+ if (sensors_applet->prefs_dialog != NULL) {
+ // destroy's dialog too
+ prefs_dialog_close(sensors_applet);
+ }
+
+ if (sensors_applet->timeout_id) {
+ g_source_remove(sensors_applet->timeout_id);
+ }
+
+ // destroy all active sensors
+ g_list_foreach(sensors_applet->active_sensors,
+ (GFunc)active_sensor_destroy,
+ NULL);
+
+ if (sensors_applet->sensors != NULL) {
+ gtk_tree_store_clear(sensors_applet->sensors);
+ }
+
+ gtk_widget_destroy(GTK_WIDGET(sensors_applet->applet));
+
+ g_free(sensors_applet);
+ return;
+}
+
+static void change_background_cb(PanelApplet *applet,
+ PanelAppletBackgroundType type,
+ GdkColor *color,
+ GdkPixmap *pixmap,
+ gpointer *data) {
+ GtkRcStyle *rc_style;
+ GtkStyle *style;
+
+ g_debug("change-background occurred");
+
+ /* reset style */
+ gtk_widget_set_style(GTK_WIDGET(applet), NULL);
+ rc_style = gtk_rc_style_new();
+ gtk_widget_modify_style(GTK_WIDGET(applet), rc_style);
+ gtk_rc_style_unref(rc_style);
+
+ switch(type) {
+ case PANEL_COLOR_BACKGROUND:
+ gtk_widget_modify_bg(GTK_WIDGET(applet),
+ GTK_STATE_NORMAL, color);
+ break;
+
+ case PANEL_PIXMAP_BACKGROUND:
+ style = gtk_style_copy(GTK_WIDGET(applet)->style);
+ if (style->bg_pixmap[GTK_STATE_NORMAL]) {
+ g_object_unref(style->bg_pixmap[GTK_STATE_NORMAL]);
+ }
+ style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref(pixmap);
+ gtk_widget_set_style(GTK_WIDGET(applet), style);
+ g_object_unref(style);
+ break;
+
+ case PANEL_NO_BACKGROUND:
+ /* fall through */
+ default:
+ break;
+ }
+}
+
+static void change_orient_cb (PanelApplet *applet,
+ PanelAppletOrient orient,
+ gpointer data) {
+ SensorsApplet *sensors_applet;
+ sensors_applet = (SensorsApplet *)data;
+
+ sensors_applet_display_layout_changed(sensors_applet);
+}
+
+static void size_allocate_cb(PanelApplet *applet,
+ GtkAllocation *allocation,
+ gpointer data) {
+ SensorsApplet *sensors_applet;
+ PanelAppletOrient orient;
+
+ g_debug("size-allocate occurred");
+ sensors_applet = (SensorsApplet *)data;
+ orient = panel_applet_get_orient(sensors_applet->applet);
+
+ if ((orient == PANEL_APPLET_ORIENT_LEFT) ||
+ (orient == PANEL_APPLET_ORIENT_RIGHT)) {
+ if (sensors_applet->size == allocation->width)
+ return;
+ sensors_applet->size = allocation->width;
+ } else {
+ if (sensors_applet->size == allocation->height)
+ return;
+ sensors_applet->size = allocation->height;
+ }
+ /* update if new value */
+ sensors_applet_graph_size_changed(sensors_applet);
+ sensors_applet_display_layout_changed(sensors_applet);
+}
+
+static void style_set_cb(GtkWidget *widget,
+ GtkStyle *old_style,
+ gpointer data) {
+
+ /* update all icons in the sensors tree and update all active
+ * sensors */
+ GtkTreeIter interfaces_iter, sensors_iter;
+ GtkTreePath *path;
+ gboolean not_end_of_interfaces = TRUE, not_end_of_sensors = TRUE;
+ IconType icon_type;
+ GdkPixbuf *new_icon;
+ gboolean enabled;
+ SensorsApplet *sensors_applet;
+ DisplayMode display_mode;
+
+ sensors_applet = (SensorsApplet *)data;
+
+ g_debug("set-style occurred");
+
+ display_mode = panel_applet_gconf_get_int(sensors_applet->applet,
+ DISPLAY_MODE,
+ NULL);
+ if (sensors_applet->sensors) {
+ for (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); not_end_of_interfaces; not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter)) {
+
+ /* reset sensors sentinel */
+ not_end_of_sensors = TRUE;
+
+ for (gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); not_end_of_sensors; not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors),
+ &sensors_iter,
+ ENABLE_COLUMN, &enabled,
+ ICON_TYPE_COLUMN, &icon_type,
+ -1);
+ /* update icons */
+ new_icon = sensors_applet_load_icon(icon_type);
+
+ gtk_tree_store_set(sensors_applet->sensors,
+ &sensors_iter,
+ ICON_PIXBUF_COLUMN, new_icon,
+ -1);
+ g_object_unref(new_icon);
+
+ /* update icons only if currently being
+ * displayed */
+ if (enabled &&
+ (display_mode == DISPLAY_ICON ||
+ display_mode == DISPLAY_ICON_WITH_VALUE)) {
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors),
+ &sensors_iter);
+ sensors_applet_icon_changed(sensors_applet,
+ path);
+ gtk_tree_path_free(path);
+ }
+ }
+ }
+ /* now update layout as size may have changed */
+ sensors_applet_display_layout_changed(sensors_applet);
+ }
+
+}
+
+static const BonoboUIVerb sensors_applet_menu_verbs[] = {
+ BONOBO_UI_UNSAFE_VERB("Preferences", prefs_cb),
+ BONOBO_UI_UNSAFE_VERB ("Help", help_cb),
+ BONOBO_UI_UNSAFE_VERB("About", about_cb),
+ BONOBO_UI_VERB_END
+};
+
+#ifdef HAVE_LIBNOTIFY
+static void notif_closed_cb(NotifyNotification *notification,
+ SensorsApplet *sensors_applet)
+{
+ g_assert(sensors_applet);
+
+ sensors_applet->notification = NULL;
+}
+#endif // HAVE_LIBNOTIFY
+
+void sensors_applet_notify(SensorsApplet *sensors_applet,
+ NotifType notif_type)
+{
+#ifdef HAVE_LIBNOTIFY
+ gchar *message;
+ gchar *summary;
+ GError *error = NULL;
+ g_assert(sensors_applet);
+
+ if (!notify_is_initted()) {
+ if (!notify_init(PACKAGE)) {
+ return;
+ }
+ }
+
+ if (sensors_applet->notification) {
+ g_debug("notification already shown, not showing another one...");
+ return;
+ }
+
+ switch (notif_type) {
+ case GCONF_READ_ERROR:
+ summary = g_strdup_printf(_("Error restoring saved sensor configuration."));
+ message = g_strdup_printf(_("An error occurred while trying to restore the saved sensor configuration. The previous configuration has been lost and will need to be re-entered."));
+ break;
+
+ case GCONF_WRITE_ERROR:
+ summary = g_strdup_printf(_("Error saving sensor configuration."));
+ message = g_strdup_printf(_("An error occurred while trying to save the current sensor configuration. "));
+ break;
+ }
+
+ sensors_applet->notification = notify_notification_new(summary,
+ message,
+ GTK_STOCK_DIALOG_WARNING,
+ GTK_WIDGET(sensors_applet->applet));
+ g_free(summary);
+ g_free(message);
+
+ g_signal_connect(sensors_applet->notification,
+ "closed",
+ G_CALLBACK(notif_closed_cb),
+ sensors_applet);
+ g_debug("showing notification");
+ if (!notify_notification_show(sensors_applet->notification, &error)) {
+ g_debug("Error showing notification: %s", error->message);
+ g_error_free(error);
+ }
+#endif // HAVE_LIBNOTIFY
+}
+
+
+void sensors_applet_notify_active_sensor(ActiveSensor *active_sensor, NotifType notif_type) {
+#ifdef HAVE_LIBNOTIFY
+
+ SensorsApplet *sensors_applet;
+ GList *table_children;
+ GtkWidget *attach = NULL;
+ gchar *summary, *message;
+ gint timeout_msecs;
+ gchar *sensor_label;
+ gchar *sensor_path;
+ SensorType sensor_type;
+ TemperatureScale temp_scale;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ const gchar *unit_type = NULL;
+ const gchar *unit_type_title = NULL;
+ const gchar *relation = NULL;
+ const gchar *limit_type = NULL;
+ const gchar *units = NULL;
+ gdouble limit_value;
+
+ sensors_applet = active_sensor->sensors_applet;
+
+ if (!panel_applet_gconf_get_bool(sensors_applet->applet,
+ DISPLAY_NOTIFICATIONS,
+ NULL)) {
+ g_debug("Wanted to display notification, but user has disabled them");
+ return;
+ }
+
+ table_children = gtk_container_get_children(GTK_CONTAINER(sensors_applet->table));
+
+ if (g_list_find(table_children, active_sensor->icon)) {
+ attach = GTK_WIDGET(active_sensor->icon);
+ } else if (g_list_find(table_children, active_sensor->label)) {
+ attach = GTK_WIDGET(active_sensor->label);
+ } else if (g_list_find(table_children, active_sensor->value)) {
+ attach = GTK_WIDGET(active_sensor->value);
+ } else if (g_list_find(table_children, active_sensor->graph)) {
+ attach = GTK_WIDGET(active_sensor->graph);
+ } else {
+ g_warning("Wanted to do notify for a sensor which has no elements in the table!!!");
+ return;
+ }
+ g_list_free(table_children);
+
+ path = gtk_tree_row_reference_get_path(active_sensor->sensor_row);
+ if (gtk_tree_model_get_iter(GTK_TREE_MODEL(sensors_applet->sensors),
+ &iter, path)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &iter,
+ LABEL_COLUMN, &sensor_label,
+ PATH_COLUMN, &sensor_path,
+ SENSOR_TYPE_COLUMN, &sensor_type,
+ -1);
+ } else {
+ g_warning("Error getting data from tree for notification...");
+ gtk_tree_path_free(path);
+ return;
+ }
+ gtk_tree_path_free(path);
+
+ // do different stuff for different notif types
+ switch (notif_type) {
+ case LOW_ALARM: // fall thru
+ case HIGH_ALARM:
+ if (active_sensor->sensor_values[0] <= active_sensor->sensor_low_value &&
+ notif_type == LOW_ALARM) {
+ relation = _("is very low");
+ limit_type = _("lower limit");
+ limit_value = active_sensor->sensor_low_value;
+ } else if (active_sensor->sensor_values[0] >= active_sensor->sensor_high_value &&
+ notif_type == HIGH_ALARM) {
+ /* assume high alarm condition */
+ relation = _("is very high");
+ limit_type = _("upper limit");
+ limit_value = active_sensor->sensor_high_value;
+ } else {
+ g_warning("Alarm notify called when no alarm condition!");
+ g_free(sensor_path);
+ g_free(sensor_label);
+ return;
+ }
+
+ switch ((SensorType)sensor_type) {
+ case TEMP_SENSOR:
+ unit_type_title = _("Temperature");
+ unit_type = _("temperature");
+ temp_scale = (TemperatureScale)panel_applet_gconf_get_int(active_sensor->sensors_applet->applet,
+ TEMPERATURE_SCALE,
+ NULL);
+
+ switch (temp_scale) {
+ case CELSIUS:
+ units = UNITS_CELSIUS;
+ break;
+ case FAHRENHEIT:
+ units = UNITS_FAHRENHEIT;
+ break;
+ case KELVIN:
+ units = UNITS_KELVIN;
+ break;
+ default:
+ units = NULL;
+ }
+
+ break;
+ case VOLTAGE_SENSOR:
+ unit_type_title = _("Voltage");
+ unit_type = _("voltage");
+ units = UNITS_VOLTAGE;
+ break;
+ case FAN_SENSOR:
+ unit_type_title = _("Fan Speed");
+ unit_type = _("fan speed");
+ units = UNITS_RPM;
+ break;
+ case CURRENT_SENSOR:
+ unit_type_title = _("Current");
+ unit_type = _("current");
+ units = UNITS_CURRENT;
+ break;
+ }
+
+ timeout_msecs = (active_sensor->alarm_timeout ? MIN(DEFAULT_NOTIFY_TIMEOUT, (active_sensor->alarm_timeout * 1000)) : DEFAULT_NOTIFY_TIMEOUT);
+
+ summary = g_strdup_printf("%s %s %s", sensor_label, unit_type_title, _("Alarm"));
+ message = g_strdup_printf("%s %s %s (%s %2.0f%s)", sensor_label, unit_type,
+ relation, limit_type, limit_value, units);
+ break;
+
+ case SENSOR_INTERFACE_ERROR:
+ summary = g_strdup_printf(_("Error updating sensor %s"), sensor_label);
+ message = g_strdup_printf(_("An error occurred while trying to update the value of the sensor %s located at %s."), sensor_label, sensor_path);
+ timeout_msecs = panel_applet_gconf_get_int(active_sensor->sensors_applet->applet,
+ TIMEOUT,
+ NULL);
+
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ active_sensor_libnotify_notify(active_sensor,
+ notif_type,
+ summary,
+ message,
+ GTK_STOCK_DIALOG_WARNING,
+ timeout_msecs,
+ attach);
+
+ g_free(sensor_path);
+ g_free(sensor_label);
+ g_free(summary);
+ g_free(message);
+#endif
+}
+
+void sensors_applet_notify_end(ActiveSensor *active_sensor,
+ NotifType notif_type) {
+#ifdef HAVE_LIBNOTIFY
+ active_sensor_libnotify_notify_end(active_sensor, notif_type);
+#endif
+}
+
+#ifdef HAVE_LIBNOTIFY
+static void sensors_applet_notify_end_all_gfunc(ActiveSensor *active_sensor,
+ gpointer data) {
+ active_sensor_libnotify_notify_end(active_sensor, LOW_ALARM);
+ active_sensor_libnotify_notify_end(active_sensor, HIGH_ALARM);
+}
+#endif
+
+void sensors_applet_notify_end_all(SensorsApplet *sensors_applet) {
+#ifdef HAVE_LIBNOTIFY
+ g_list_foreach(sensors_applet->active_sensors,
+ (GFunc)sensors_applet_notify_end_all_gfunc,
+ NULL);
+#endif
+}
+
+/* internal helper functions for updating display etc*/
+
+
+/* should be called as a g_container_foreach at the start of
+ * pack_display if ythe table already exists to remove but keep alive
+ * all children of the table before repacking it */
+static void sensors_applet_pack_display_empty_table_cb(GtkWidget *widget,
+ gpointer data) {
+ GtkContainer *container;
+
+ container = GTK_CONTAINER(data);
+
+ /* ref then remove widget */
+ g_object_ref(widget);
+ gtk_container_remove(container, widget);
+}
+
+/* should be called as a g_container_foreach at the end of
+ * pack_display to unref any of the old children that we have readdded
+ * to the table to stop reference creep from the g_object_ref called
+ * on each child at the start of pack labels */
+static void sensors_applet_pack_display_cleanup_refs_cb(GtkWidget *widget,
+ gpointer data) {
+
+ GList *old_children;
+
+ old_children = (GList *)data;
+ if (g_list_find(old_children, widget)) {
+ g_object_unref(widget);
+ }
+}
+
+static void sensors_applet_pack_display(SensorsApplet *sensors_applet) {
+ /* note the if () around each widget is to ensure we only
+ * operate on those that actually exist */
+ GtkLabel *no_sensors_enabled_label = NULL;
+ gint num_active_sensors = 0, num_sensors_per_group, rows, cols, i, j;
+ GList *old_table_children = NULL;
+
+ GList *current_sensor;
+
+ DisplayMode display_mode;
+ LayoutMode layout_mode;
+
+ gboolean horizontal;
+ gint label_width, icon_width, value_width;
+ gint label_height, icon_height, value_height;
+
+ GtkRequisition req;
+
+ ActiveSensor *first_sensor;
+
+ /* it is possible that there could be no active sensors so
+ * handle that case first - make sure we dont do a NULL
+ * pointer access first though */
+ if (sensors_applet->active_sensors == NULL ||
+ g_list_length(sensors_applet->active_sensors) == 0) {
+ g_debug("no active sensors to pack in table");
+ no_sensors_enabled_label = g_object_new(GTK_TYPE_LABEL,
+ "label", _("No sensors enabled!"),
+ NULL);
+
+ if (sensors_applet->table == NULL) {
+ /* only need 1 row and 1 col */
+ sensors_applet->table = gtk_table_new(1, 1, FALSE);
+ gtk_table_set_col_spacings(GTK_TABLE(sensors_applet->table), COLUMN_SPACING);
+ gtk_table_set_row_spacings(GTK_TABLE(sensors_applet->table), ROW_SPACING);
+ /* add table to applet */
+ gtk_container_add(GTK_CONTAINER(sensors_applet->applet), sensors_applet->table);
+
+ } else {
+ /* destroy existing widgets - could be an
+ * existing version of no sensors label - okay
+ * to just add again though if destory fist */
+ g_debug("destorying any existing widgets in container");
+ gtk_container_foreach(GTK_CONTAINER(sensors_applet->table),
+ (GtkCallback)gtk_widget_destroy,
+ NULL);
+ /* make sure only 1x1 table */
+ gtk_table_resize(GTK_TABLE(sensors_applet->table),
+ 1, 1);
+ }
+ g_debug("packing no sensors enabled label");
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ GTK_WIDGET(no_sensors_enabled_label),
+ 0, 1,
+ 0, 1);
+ gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet));
+ return;
+
+ }
+ /* otherwise can acess active_sensors without any worries */
+ num_active_sensors = g_list_length(sensors_applet->active_sensors);
+
+ display_mode = (DisplayMode)panel_applet_gconf_get_int(sensors_applet->applet,
+ DISPLAY_MODE, NULL);
+ layout_mode = (LayoutMode)panel_applet_gconf_get_int(sensors_applet->applet,
+ LAYOUT_MODE, NULL);
+
+
+ horizontal = (((panel_applet_get_orient(sensors_applet->applet) == PANEL_APPLET_ORIENT_UP) ||
+ (panel_applet_get_orient(sensors_applet->applet) == PANEL_APPLET_ORIENT_DOWN)));
+
+ /* figure out num rows / cols by how high / wide sensors
+ * labels / icons are and how much size we have to put them
+ * in */
+
+ /* get the first active sensor */
+ first_sensor = (ActiveSensor *)sensors_applet->active_sensors->data;
+
+
+ switch (display_mode) {
+ case DISPLAY_VALUE:
+ gtk_widget_size_request(GTK_WIDGET(first_sensor->value),
+ &req);
+ value_width = req.width + COLUMN_SPACING;
+ value_height = req.height + ROW_SPACING;
+
+ /* make sure all widths and heights are non zero,
+ * otherwise will get a divide by zero exception below
+ * - is a non critical error since can happen when
+ * elements first added to list, so simply return - is
+ * not a programming error */
+ if (value_width == 0 && value_height == 0) {
+ return;
+ }
+
+ num_sensors_per_group = (sensors_applet->size /
+ (horizontal ? value_height :
+ value_width));
+ break;
+
+ case DISPLAY_LABEL_WITH_VALUE:
+ /* even though we end up packing the event boxes into the
+ * panel, these dont give back request sizes, so need to ask
+ * widgets directly */
+ gtk_widget_size_request(GTK_WIDGET(first_sensor->value),
+ &req);
+ value_width = req.width + COLUMN_SPACING;
+ value_height = req.height + ROW_SPACING;
+
+ gtk_widget_size_request(GTK_WIDGET(first_sensor->label),
+ &req);
+ label_width = req.width + COLUMN_SPACING;
+ label_height = req.height + ROW_SPACING;
+
+ /* make sure all widths and heights are non zero, otherwise
+ * will get a divide by zero exception below
+ * - is a non critical error since can happen when
+ * elements first added to list, so simply return - is
+ * not a programming error */
+ if (!(label_width && label_height &&
+ value_width && value_height)) {
+ return;
+ }
+
+ switch (layout_mode) {
+ case VALUE_BESIDE_LABEL:
+ num_sensors_per_group = (sensors_applet->size /
+ (horizontal ? MAX(label_height, value_height) :
+ (label_width + value_width)));
+ break;
+ case VALUE_BELOW_LABEL:
+ num_sensors_per_group = (sensors_applet->size /
+ (horizontal ? (label_height + value_height) :
+ MAX(label_width, value_width)));
+
+
+ break;
+ }
+ break;
+
+ case DISPLAY_ICON_WITH_VALUE:
+ gtk_widget_size_request(GTK_WIDGET(first_sensor->value),
+ &req);
+ value_width = req.width + COLUMN_SPACING;
+ value_height = req.height + ROW_SPACING;
+
+ gtk_widget_size_request(GTK_WIDGET(first_sensor->icon),
+ &req);
+ icon_width = req.width + COLUMN_SPACING;
+ icon_height = req.height + ROW_SPACING;
+
+ if (!(icon_width && icon_height &&
+ value_width && value_height)) {
+ return;
+ }
+
+ switch (layout_mode) {
+ case VALUE_BESIDE_LABEL:
+ num_sensors_per_group = (sensors_applet->size /
+ (horizontal ? MAX(icon_height, value_height) :
+ (icon_width + value_width)));
+ break;
+ case VALUE_BELOW_LABEL:
+ num_sensors_per_group = (sensors_applet->size /
+ (horizontal ? (icon_height + value_height) :
+ MAX(icon_width, value_width)));
+
+
+ break;
+ }
+ break;
+
+ case DISPLAY_ICON:
+ gtk_widget_size_request(GTK_WIDGET(first_sensor->icon),
+ &req);
+ icon_width = req.width + COLUMN_SPACING;
+ icon_height = req.height + ROW_SPACING;
+ if (!(icon_width && icon_height)) {
+ return;
+ }
+
+ num_sensors_per_group = (sensors_applet->size /
+ (horizontal ? icon_height :
+ icon_width));
+ break;
+
+ case DISPLAY_GRAPH:
+ /* only show graphs in a line like System Monitor
+ * applet */
+ num_sensors_per_group = 1;
+ break;
+ }
+ /* ensure always atleast 1 sensor per group */
+ if (num_sensors_per_group < 1) {
+ /* force a better layout */
+ if (horizontal && layout_mode == VALUE_BELOW_LABEL) {
+ layout_mode = VALUE_BESIDE_LABEL;
+ } else if (!horizontal && layout_mode == VALUE_BESIDE_LABEL) {
+ layout_mode = VALUE_BELOW_LABEL;
+ }
+ num_sensors_per_group = 1;
+ }
+
+ if (horizontal) {
+ /* if oriented horizontally, want as many
+ sensors per column as user has defined, then
+ enough columns to hold all the widgets */
+ rows = num_sensors_per_group;
+ cols = num_active_sensors / num_sensors_per_group;
+ while (rows * cols < num_active_sensors || cols == 0) {
+ cols++;
+ }
+
+ } else {
+ /* if oriented vertically, want as many
+ sensors per row as user has defined, then
+ enough rows to hold all the widgets*/
+ cols = num_sensors_per_group;
+ rows = num_active_sensors / num_sensors_per_group;
+ while (rows * cols < num_active_sensors || rows == 0) {
+ rows++;
+ }
+
+ }
+
+ /* if displaying labels / icons and values need to modify
+ number of rows / colums to accomodate this */
+ if (display_mode == DISPLAY_LABEL_WITH_VALUE ||
+ display_mode == DISPLAY_ICON_WITH_VALUE) {
+ if (layout_mode == VALUE_BESIDE_LABEL) {
+ /* to display labels next to values need twice
+ as many columns */
+ cols *= 2;
+ } else {
+ /* to display labels above values, we need
+ * twice as many rows as without */
+ rows *= 2;
+ }
+ }
+
+ if (sensors_applet->table == NULL) {
+ /* create table and add to applet */
+ sensors_applet->table = gtk_table_new(rows, cols, FALSE);
+ gtk_table_set_col_spacings(GTK_TABLE(sensors_applet->table), COLUMN_SPACING);
+ gtk_table_set_row_spacings(GTK_TABLE(sensors_applet->table), ROW_SPACING);
+ gtk_container_add(GTK_CONTAINER(sensors_applet->applet), sensors_applet->table);
+ } else {
+ /* remove all children if table already exists so we can start
+ * again */
+ /* save a list of the old children for later */
+ old_table_children = gtk_container_get_children(GTK_CONTAINER(sensors_applet->table));
+
+ gtk_container_foreach(GTK_CONTAINER(sensors_applet->table),
+ sensors_applet_pack_display_empty_table_cb,
+ sensors_applet->table);
+
+ /* then resize table */
+ gtk_table_resize(GTK_TABLE(sensors_applet->table), rows, cols);
+ }
+
+ /* pack icons / labels and values into table */
+ current_sensor = sensors_applet->active_sensors;
+
+ /* if showing labels / icons and values, need to pack labels /
+ * icons these first */
+ if (display_mode == DISPLAY_ICON_WITH_VALUE ||
+ display_mode == DISPLAY_LABEL_WITH_VALUE) {
+ /* loop through columns */
+ for (i = 0; current_sensor != NULL && i < cols; /* increments depends on how we lay them out - see below */) {
+
+ /* loop through rows in a column */
+ for (j = 0; current_sensor && j < rows; /* see bottom of for loop*/) {
+ /* attach label / icon at this point */
+ if (display_mode == DISPLAY_ICON_WITH_VALUE) {
+ if (((ActiveSensor *)(current_sensor->data))->icon) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->icon,
+ i, i + 1,
+ j, j + 1);
+ }
+ } else {
+ if (((ActiveSensor *)(current_sensor->data))->label) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->label,
+ i, i + 1,
+ j, j + 1);
+ }
+ }
+ /* now attach sensor value to either
+ row below or column next to */
+ if (layout_mode == VALUE_BESIDE_LABEL) {
+ /* left align labels */
+ if (((ActiveSensor *)(current_sensor->data))->icon) {
+ gtk_misc_set_alignment(GTK_MISC(((ActiveSensor *)(current_sensor->data))->icon), 0.0, 0.5);
+ }
+ if (((ActiveSensor *)(current_sensor->data))->label) {
+ gtk_misc_set_alignment(GTK_MISC(((ActiveSensor *)(current_sensor->data))->label), 0.0, 0.5);
+ }
+ if (((ActiveSensor *)(current_sensor->data))->value) {
+ gtk_misc_set_alignment(GTK_MISC(((ActiveSensor *)(current_sensor->data))->value), 0.0, 0.5);
+ }
+
+
+ /* place value next to label */
+ if (((ActiveSensor *)(current_sensor->data))->value) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->value,
+ i + 1, i + 2,
+ j, j + 1);
+ }
+ j++;
+ } else { /* place value below label */
+ /* center align labels */
+ if (((ActiveSensor *)(current_sensor->data))->icon) {
+ gtk_misc_set_alignment(GTK_MISC(((ActiveSensor *)(current_sensor->data))->icon), 0.5, 0.5);
+ }
+ if (((ActiveSensor *)(current_sensor->data))->label) {
+ gtk_misc_set_alignment(GTK_MISC(((ActiveSensor *)(current_sensor->data))->label), 0.5, 0.5);
+ }
+ if (((ActiveSensor *)(current_sensor->data))->value) {
+ gtk_misc_set_alignment(GTK_MISC(((ActiveSensor *)(current_sensor->data))->value), 0.5, 0.5);
+ }
+
+ if (((ActiveSensor *)(current_sensor->data))->value) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->value,
+ i, i + 1,
+ j + 1, j + 2);
+ }
+ j += 2;
+ }
+ current_sensor = g_list_next(current_sensor);
+
+ } /* end row loop */
+ /* now increment column index as needed */
+ if (layout_mode == VALUE_BESIDE_LABEL) { /* place value next to label */
+ i += 2;
+ } else {
+ i++;
+ }
+
+
+ } /* end column loop */
+
+
+ } else { /* not showing labels and icons with values, so just
+ * pack either only icons or values */
+ for (i = 0; current_sensor != NULL && i < cols; ++i) {
+ for (j = 0; current_sensor!= NULL && j < rows; ++j) {
+ if (display_mode == DISPLAY_VALUE) {
+
+ if (((ActiveSensor *)(current_sensor->data))->value) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->value,
+ i, i + 1,
+ j, j + 1);
+ }
+ } else if (display_mode == DISPLAY_ICON) {
+ if (((ActiveSensor *)(current_sensor->data))->value) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->icon,
+ i, i + 1,
+ j, j + 1);
+ }
+ } else if (display_mode == DISPLAY_GRAPH) {
+ if (((ActiveSensor *)(current_sensor->data))->graph) {
+ gtk_table_attach_defaults(GTK_TABLE(sensors_applet->table),
+ ((ActiveSensor *)(current_sensor->data))->graph_frame,
+ i, i + 1,
+ j, j + 1);
+ }
+ }
+
+
+ current_sensor = g_list_next(current_sensor);
+ }
+ }
+
+ }
+ if (old_table_children != NULL) {
+ gtk_container_foreach(GTK_CONTAINER(sensors_applet->table),
+ sensors_applet_pack_display_cleanup_refs_cb,
+ old_table_children);
+ g_list_free(old_table_children);
+ }
+ gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet));
+
+}
+
+/* must unref when done with returned pixbuf */
+GdkPixbuf *sensors_applet_load_icon(IconType icon_type) {
+ GtkIconTheme *icon_theme;
+ GdkPixbuf *icon = NULL;
+ GError *error = NULL;
+
+ /* try to load the icon */
+
+ /* not allowed to unref or ref icon_theme once we have it */
+ icon_theme = gtk_icon_theme_get_default();
+ icon = gtk_icon_theme_load_icon(icon_theme,
+ stock_icons[icon_type],
+ DEFAULT_ICON_SIZE,
+ GTK_ICON_LOOKUP_USE_BUILTIN,
+ &error);
+ if (error) {
+ g_warning ("Could not load icon: %s", error->message);
+ g_error_free(error);
+ error = NULL;
+
+ /* try again with default icon */
+ icon = gtk_icon_theme_load_icon(icon_theme,
+ GTK_STOCK_MISSING_IMAGE,
+ DEFAULT_ICON_SIZE,
+ GTK_ICON_LOOKUP_USE_BUILTIN,
+ &error);
+ if (error) {
+ /* this will quit sensors-applet but
+ * it is a pretty major error so may
+ * as well */
+
+ g_error("Could not load GTK_STOCK_MISSING_IMAGE - major error!!!: %s", error->message);
+
+ g_error_free(error);
+ error = NULL;
+ }
+
+ }
+ return icon;
+}
+
+gboolean sensors_applet_add_sensor(SensorsApplet *sensors_applet,
+ const gchar *path,
+ const gchar *id,
+ const gchar *label,
+ const gchar *interface,
+ SensorType type,
+ gboolean enable,
+ gdouble low_value,
+ gdouble high_value,
+ gboolean alarm_enable,
+ const gchar *low_alarm_command,
+ const gchar *high_alarm_command,
+ gint alarm_timeout,
+ gdouble multiplier,
+ gdouble offset,
+ IconType icon_type,
+ const gchar *graph_color) {
+
+
+ GtkTreeIter interfaces_iter, sensors_iter;
+ gboolean not_empty_tree;
+
+ gchar *node_interface;
+ gboolean not_end_of_interfaces = TRUE, interface_exists = FALSE;
+ gboolean not_end_of_sensors = TRUE;
+ gchar *sensor_id;
+ gchar *sensor_path;
+ SensorType sensor_type;
+ GdkPixbuf *icon;
+ GtkTreePath *tree_path;
+
+ g_assert(sensors_applet);
+
+ /* assume tree is not empty */
+ not_empty_tree = TRUE;
+
+
+ if (NULL == sensors_applet->sensors) {
+
+ sensors_applet->sensors = gtk_tree_store_new(N_COLUMNS,
+ G_TYPE_STRING, /* path */
+ G_TYPE_STRING, /* id */
+ G_TYPE_STRING, /* label */
+ G_TYPE_STRING, /* interface */
+ G_TYPE_UINT, /* sensor
+ * type */
+ G_TYPE_BOOLEAN, /* enable */
+ G_TYPE_BOOLEAN, /* visible */
+ G_TYPE_DOUBLE, /* low value */
+ G_TYPE_DOUBLE, /* high type */
+ G_TYPE_BOOLEAN, /* alarm enable */
+ G_TYPE_STRING, /* low alarm command */
+ G_TYPE_STRING, /* high alarm command */
+ G_TYPE_UINT, /* alarm timeout */
+ G_TYPE_DOUBLE, /* multiplier */
+ G_TYPE_DOUBLE, /* offset */
+ G_TYPE_UINT, /* icon type */
+ GDK_TYPE_PIXBUF, /* icon pixbuf */
+ G_TYPE_STRING); /* graph color */
+
+
+ g_debug("Sensor tree created.");
+
+ /* we know tree is actually empty since we just created it */
+ not_empty_tree = FALSE;
+ }
+
+ /* search sensor tree for the parent interface to place this
+ * sensor under */
+ for (not_empty_tree = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter); not_empty_tree && not_end_of_interfaces && !interface_exists; not_end_of_interfaces = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &interfaces_iter,
+ INTERFACE_COLUMN, &node_interface,
+ -1);
+ if (g_ascii_strcasecmp(interface, node_interface) == 0) {
+ /* found interface in tree */
+ interface_exists = TRUE;
+
+ /* now see if this actual sensor already
+ * exists within this interface - don't want
+ * to add duplicates */
+ /* see if have children */
+ for (not_end_of_sensors = gtk_tree_model_iter_children(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter, &interfaces_iter); not_end_of_sensors; not_end_of_sensors = gtk_tree_model_iter_next(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter)) {
+ gtk_tree_model_get(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter,
+ PATH_COLUMN, &sensor_path,
+ ID_COLUMN, &sensor_id,
+ SENSOR_TYPE_COLUMN, &sensor_type,
+ -1);
+ if (g_ascii_strcasecmp(sensor_id, id) == 0 &&
+ g_ascii_strcasecmp(sensor_path, path) == 0 &&
+ sensor_type == type) {
+ /* sensor already exists so
+ * dont add a second time */
+ g_debug("sensor with path: %s, id: %s already exists in tree, not adding a second time", sensor_path, sensor_id);
+ g_free(sensor_id);
+ g_free(sensor_path);
+ g_free(node_interface);
+ return FALSE;
+ }
+ g_free(sensor_id);
+ g_free(sensor_path);
+ }
+ g_free(node_interface);
+ break;
+ }
+ g_free(node_interface);
+ }
+
+
+
+ if (!interface_exists) {
+ /* add to required plugins hash table so we ensure this
+ plugin stays loaded to make sure we have a get sensor
+ value function if possible */
+ g_hash_table_insert(sensors_applet->required_plugins,
+ g_strdup(interface),
+ GINT_TO_POINTER(TRUE));
+ g_debug("added interface %s to required plugins", interface);
+
+ /* wasn't able to find interface root node so create it */
+ gtk_tree_store_append(sensors_applet->sensors,
+ &interfaces_iter,
+ NULL);
+
+ gtk_tree_store_set(sensors_applet->sensors,
+ &interfaces_iter,
+ ID_COLUMN, interface,
+ INTERFACE_COLUMN, interface,
+ VISIBLE_COLUMN, FALSE,
+ -1);
+ g_debug("Added sensor interface %s to tree", interface);
+ }
+
+ icon = sensors_applet_load_icon(icon_type);
+
+
+ /* then add sensor as a child under interface node - ie assume
+ * we either found it or created it - the inteface node that
+ * is */
+
+ /* for now just add sensors all in a single list */
+ gtk_tree_store_append(sensors_applet->sensors,
+ &sensors_iter,
+ &interfaces_iter);
+
+ gtk_tree_store_set(sensors_applet->sensors,
+ &sensors_iter,
+ PATH_COLUMN, path,
+ ID_COLUMN, id,
+ LABEL_COLUMN, label,
+ INTERFACE_COLUMN, interface,
+ SENSOR_TYPE_COLUMN, type,
+ ENABLE_COLUMN, enable,
+ VISIBLE_COLUMN, TRUE,
+ LOW_VALUE_COLUMN, low_value,
+ HIGH_VALUE_COLUMN, high_value,
+ ALARM_ENABLE_COLUMN, alarm_enable,
+ ALARM_TIMEOUT_COLUMN, alarm_timeout,
+ LOW_ALARM_COMMAND_COLUMN, low_alarm_command,
+ HIGH_ALARM_COMMAND_COLUMN, high_alarm_command,
+ MULTIPLIER_COLUMN, multiplier,
+ OFFSET_COLUMN, offset,
+ ICON_TYPE_COLUMN, icon_type,
+ ICON_PIXBUF_COLUMN, icon,
+ GRAPH_COLOR_COLUMN, graph_color,
+ -1);
+ g_debug("added sensor %s to tree", path);
+
+ /* remove reference to icon as tree now has ref */
+ g_object_unref(icon);
+
+ /* create the active sensor */
+ if (enable) {
+ tree_path = gtk_tree_model_get_path(GTK_TREE_MODEL(sensors_applet->sensors), &sensors_iter);
+ sensors_applet_sensor_enabled(sensors_applet, tree_path);
+ gtk_tree_path_free(tree_path);
+ }
+ return TRUE;
+}
+
+
+static ActiveSensor *sensors_applet_find_active_sensor(SensorsApplet *sensors_applet,
+ GtkTreePath *path) {
+ GtkTreePath *sensor_tree_path;
+ GList *current_sensor;
+
+ for (current_sensor = sensors_applet->active_sensors; current_sensor != NULL; current_sensor = g_list_next(current_sensor)) {
+ sensor_tree_path = gtk_tree_row_reference_get_path(((ActiveSensor *)(current_sensor->data))->sensor_row);
+
+ if (gtk_tree_path_compare(path, sensor_tree_path) == 0) {
+ gtk_tree_path_free(sensor_tree_path);
+ return ((ActiveSensor *)(current_sensor->data));
+ }
+ gtk_tree_path_free(sensor_tree_path);
+ }
+ return NULL;
+}
+
+
+/* path should be the full path to a file representing the sensor (eg
+ * /dev/hda or /sys/devices/platform/i2c-0/0-0290/temp1_input) */
+
+void sensors_applet_display_layout_changed(SensorsApplet *sensors_applet) {
+ /* update sensors since will need to update icons / graphs etc
+ * if weren't displayed before */
+ GList *list = NULL;
+ for (list = sensors_applet->active_sensors;
+ list != NULL;
+ list = list->next) {
+ ActiveSensor *as = (ActiveSensor *)list->data;
+ as->updated = FALSE;
+ }
+ sensors_applet_update_active_sensors(sensors_applet);
+ sensors_applet_pack_display(sensors_applet);
+}
+
+void sensors_applet_alarm_off(SensorsApplet *sensors_applet,
+ GtkTreePath *path,
+ NotifType notif_type) {
+ ActiveSensor *active_sensor;
+
+ if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet,
+ path)) != NULL) {
+ active_sensor_alarm_off(active_sensor, notif_type);
+ }
+}
+
+void sensors_applet_all_alarms_off(SensorsApplet *sensors_applet,
+ GtkTreePath *path) {
+ sensors_applet_alarm_off(sensors_applet, path, LOW_ALARM);
+ sensors_applet_alarm_off(sensors_applet, path, HIGH_ALARM);
+}
+
+
+void sensors_applet_sensor_enabled(SensorsApplet *sensors_applet,
+ GtkTreePath *path) {
+ ActiveSensor *active_sensor;
+
+ g_assert(sensors_applet);
+ g_assert(path);
+
+ active_sensor = active_sensor_new(sensors_applet,
+ gtk_tree_row_reference_new(GTK_TREE_MODEL(sensors_applet->sensors), path));
+
+ active_sensor_update(active_sensor, sensors_applet);
+
+ /* keep list sorted */
+ sensors_applet->active_sensors = g_list_insert_sorted(sensors_applet->active_sensors,
+ active_sensor,
+ (GCompareFunc)active_sensor_compare);
+
+ sensors_applet_pack_display(sensors_applet);
+}
+
+void sensors_applet_reorder_sensors(SensorsApplet *sensors_applet) {
+ sensors_applet->active_sensors = g_list_sort(sensors_applet->active_sensors, (GCompareFunc)active_sensor_compare);
+
+ sensors_applet_pack_display(sensors_applet);
+}
+
+void sensors_applet_sensor_disabled(SensorsApplet *sensors_applet,
+ GtkTreePath *path) {
+
+ ActiveSensor *active_sensor;
+
+ g_assert(sensors_applet);
+ g_assert(path);
+
+ if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet,
+ path)) != NULL) {
+ g_debug("Destroying active sensor...");
+
+ g_debug("-- removing from list...");
+ sensors_applet->active_sensors = g_list_remove(sensors_applet->active_sensors,
+ active_sensor);
+ g_debug("-- repacking display....");
+ sensors_applet_pack_display(sensors_applet);
+
+ active_sensor_destroy(active_sensor);
+ }
+}
+
+
+void sensors_applet_update_sensor(SensorsApplet *sensors_applet,
+ GtkTreePath *path) {
+ ActiveSensor *active_sensor;
+
+ g_assert(sensors_applet);
+ g_assert(path);
+
+ if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet,
+ path)) != NULL) {
+ active_sensor_update(active_sensor,
+ sensors_applet);
+ }
+}
+
+void sensors_applet_icon_changed(SensorsApplet *sensors_applet,
+ GtkTreePath *path) {
+ ActiveSensor *active_sensor;
+
+ g_assert(sensors_applet);
+ g_assert(path);
+
+ if ((active_sensor = sensors_applet_find_active_sensor(sensors_applet,
+ path)) != NULL) {
+ active_sensor_icon_changed(active_sensor,
+ sensors_applet);
+ }
+}
+
+/**
+ * Cycle thru ActiveSensors and update them all
+ */
+gboolean sensors_applet_update_active_sensors(SensorsApplet *sensors_applet) {
+ g_assert(sensors_applet);
+
+ if (sensors_applet->active_sensors) {
+ g_list_foreach(sensors_applet->active_sensors,
+ (GFunc)active_sensor_update,
+ sensors_applet);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Cycle thru ActiveSensors and set new graph dimensions
+ */
+void sensors_applet_graph_size_changed(SensorsApplet *sensors_applet) {
+ gint dimensions[2];
+ gint graph_size;
+ g_assert(sensors_applet);
+
+ if (sensors_applet->active_sensors) {
+
+ graph_size = panel_applet_gconf_get_int(sensors_applet->applet,
+ GRAPH_SIZE,
+ NULL);
+ if (panel_applet_get_orient(sensors_applet->applet) ==
+ PANEL_APPLET_ORIENT_UP ||
+ panel_applet_get_orient(sensors_applet->applet) ==
+ PANEL_APPLET_ORIENT_DOWN) {
+ /* is horizontal so set graph_size as width */
+ dimensions[0] = graph_size;
+ dimensions[1] = sensors_applet->size;
+ } else {
+ dimensions[0] = sensors_applet->size;
+ dimensions[1] = graph_size;
+ }
+
+ g_list_foreach(sensors_applet->active_sensors,
+ (GFunc)active_sensor_update_graph_dimensions,
+ &dimensions);
+ }
+
+}
+
+gdouble sensors_applet_convert_temperature(gdouble value,
+ TemperatureScale old,
+ TemperatureScale new) {
+
+ switch (old) {
+ case KELVIN:
+ switch (new) {
+ case CELSIUS:
+ value = value - 273.0;
+ break;
+ case FAHRENHEIT:
+ value = (9.0 * (value - 273) / 5.0) + 32.0;
+ break;
+ case KELVIN:
+ break;
+ }
+ break;
+ case CELSIUS:
+ switch (new) {
+ case FAHRENHEIT:
+ value = (9.0 * value / 5.0) + 32.0;
+ break;
+ case KELVIN:
+ value = value + 273.0;
+ break;
+ case CELSIUS:
+ break;
+ }
+ break;
+
+ case FAHRENHEIT:
+ switch (new) {
+ case CELSIUS:
+ value = (5.0 * (value - 32.0) / 9.0);
+ break;
+ case KELVIN:
+ value = (5.0 * (value - 32.0) / 9.0) + 273.0;
+ break;
+ case FAHRENHEIT:
+ break;
+ }
+ break;
+ }
+ return value;
+}
+
+void sensors_applet_init(SensorsApplet *sensors_applet) {
+
+ g_assert(sensors_applet);
+ g_assert(sensors_applet->applet);
+
+ /* plugin functions are stored as name -> get_value_function pairs so
+ * use standard string functions on hash table */
+ sensors_applet->plugins = g_hash_table_new(g_str_hash,
+ g_str_equal);
+
+ sensors_applet->required_plugins = g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+
+ /* initialise size */
+ sensors_applet->size = DEFAULT_APPLET_SIZE;
+
+ panel_applet_set_flags(sensors_applet->applet,
+ PANEL_APPLET_EXPAND_MINOR);
+
+ g_signal_connect(sensors_applet->applet, "destroy",
+ G_CALLBACK(destroy_cb),
+ sensors_applet);
+
+
+ /* if not setup, write defaults to gconf */
+ sensors_applet_gconf_setup(sensors_applet);
+
+ /* now do any setup needed manually */
+ sensors_applet_plugins_load_all(sensors_applet);
+
+ /* should have created sensors tree above, but if have
+ not was because we couldn't find any sensors */
+ if (NULL == sensors_applet->sensors) {
+ GtkWidget *label;
+ label = gtk_label_new(_("No sensors found!"));
+ gtk_container_add(GTK_CONTAINER(sensors_applet->applet), label);
+ gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet));
+ return;
+ }
+
+ /* only do menu and signal connections if sensors are found */
+ panel_applet_setup_menu_from_file(sensors_applet->applet,
+ DATADIR,
+ SENSORS_APPLET_MENU_FILE,
+ NULL,
+ sensors_applet_menu_verbs,
+ sensors_applet);
+
+ g_signal_connect(sensors_applet->applet, "style-set",
+ G_CALLBACK(style_set_cb),
+ sensors_applet);
+
+ g_signal_connect(sensors_applet->applet, "change_background",
+ G_CALLBACK(change_background_cb),
+ sensors_applet);
+
+ g_signal_connect(G_OBJECT(sensors_applet->applet), "change_orient",
+ G_CALLBACK(change_orient_cb),
+ sensors_applet);
+
+ g_signal_connect(G_OBJECT(sensors_applet->applet), "size_allocate",
+ G_CALLBACK(size_allocate_cb),
+ sensors_applet);
+
+
+
+ sensors_applet_update_active_sensors(sensors_applet);
+ sensors_applet_pack_display(sensors_applet);
+
+ sensors_applet->timeout_id = g_timeout_add_seconds(panel_applet_gconf_get_int(sensors_applet->applet, TIMEOUT, NULL) / 1000,
+ (GSourceFunc)sensors_applet_update_active_sensors,
+ sensors_applet);
+ gtk_widget_show_all(GTK_WIDGET(sensors_applet->applet));
+}
+
+
+
diff --git a/sensors-applet/sensors-applet.h b/sensors-applet/sensors-applet.h
new file mode 100644
index 0000000..ac56dc4
--- /dev/null
+++ b/sensors-applet/sensors-applet.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2005-2009 Alex Murray <[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 SENSORS_APPLET_H
+#define SENSORS_APPLET_H
+
+#include <gtk/gtk.h>
+#include <panel-applet.h>
+#include "sensors-applet-sensor.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#ifdef HAVE_LIBNOTIFY
+#include <libnotify/notify.h>
+#endif
+
+typedef struct _ActiveSensor ActiveSensor;
+
+#include "prefs-dialog.h"
+
+#define GRAPH_FRAME_EXTRA_WIDTH 6
+#define SENSORS_APPLET_ICON "sensors-applet"
+
+static const gchar * const stock_icons[NUM_ICONS] = {
+ "sensors-applet-cpu",
+ "sensors-applet-drive-harddisk",
+ "sensors-applet-battery",
+ "sensors-applet-memory",
+ "sensors-applet-gpu",
+ "sensors-applet-chip",
+ "sensors-applet-fan",
+ "sensors-applet-case"
+};
+
+#define DEFAULT_ICON_SIZE 22
+
+#define UNITS_CELSIUS "\302\260C"
+#define UNITS_FAHRENHEIT "\302\260F"
+#define UNITS_KELVIN ""
+#define UNITS_RPM _("RPM")
+#define UNITS_VOLTAGE _("V")
+#define UNITS_CURRENT _("A")
+
+
+/* enumeration used to identify columns in the GtkTreeStore data
+ * structure and to access specific gconf keys too.
+ */
+enum {
+ PATH_COLUMN = 0,
+ ID_COLUMN,
+ LABEL_COLUMN,
+ INTERFACE_COLUMN,
+ SENSOR_TYPE_COLUMN,
+ ENABLE_COLUMN,
+ VISIBLE_COLUMN,
+ LOW_VALUE_COLUMN,
+ HIGH_VALUE_COLUMN,
+ ALARM_ENABLE_COLUMN,
+ LOW_ALARM_COMMAND_COLUMN,
+ HIGH_ALARM_COMMAND_COLUMN,
+ ALARM_TIMEOUT_COLUMN,
+ MULTIPLIER_COLUMN,
+ OFFSET_COLUMN,
+ ICON_TYPE_COLUMN,
+ ICON_PIXBUF_COLUMN,
+ GRAPH_COLOR_COLUMN,
+ N_COLUMNS
+};
+
+
+/* for display mode */
+typedef enum {
+ DISPLAY_LABEL_WITH_VALUE = 0,
+ DISPLAY_ICON_WITH_VALUE,
+ DISPLAY_VALUE,
+ DISPLAY_ICON,
+ DISPLAY_GRAPH
+} DisplayMode;
+
+typedef enum {
+ VALUE_BESIDE_LABEL = 0,
+ VALUE_BELOW_LABEL
+} LayoutMode;
+
+typedef enum {
+ KELVIN = 0,
+ CELSIUS,
+ FAHRENHEIT
+} TemperatureScale;
+
+/* types of Notifs - low and high alarm warnings and error conditions*/
+typedef enum {
+ LOW_ALARM = 0,
+ HIGH_ALARM,
+ SENSOR_INTERFACE_ERROR,
+ GCONF_READ_ERROR,
+ GCONF_WRITE_ERROR,
+ NUM_NOTIFS
+} NotifType;
+
+/* only always two type of alarms - may have more notif types */
+#define NUM_ALARMS 2
+
+struct _SensorsApplet {
+ /* the actual applet for this instance */
+ PanelApplet* applet;
+ gint size;
+
+ GtkTreeStore *sensors;
+ GtkTreeSelection *selection;
+
+ GHashTable *required_plugins;
+ GHashTable *plugins;
+
+ guint timeout_id;
+ /* preferences and about windows (if Gtk < 2.6)*/
+ PrefsDialog *prefs_dialog;
+
+ /* primary table to contain the panel dispay - we pack the
+ * list of labels and sensor values into this container */
+ GtkWidget *table;
+ GList *active_sensors;
+#ifdef HAVE_LIBNOTIFY
+ NotifyNotification *notification;
+#endif // HAVE_LIBNOTIFY
+};
+
+
+
+/* non-static function prototypes */
+void sensors_applet_init(SensorsApplet *sensors_applet);
+void sensors_applet_sensor_enabled(SensorsApplet *sensors_applet,
+ GtkTreePath *path);
+void sensors_applet_sensor_disabled(SensorsApplet *sensors_applet,
+ GtkTreePath *path);
+gboolean sensors_applet_update_active_sensors(SensorsApplet *sensors_applet);
+/**
+ * to be called by things like prefs dialog to turn off a sensor alarm
+ */
+void sensors_applet_alarm_off(SensorsApplet *sensors_applet,
+ GtkTreePath *path,
+ NotifType notif_type);
+void sensors_applet_all_alarms_off(SensorsApplet *sensors_applet,
+ GtkTreePath *path);
+void sensors_applet_icon_changed(SensorsApplet *sensors_applet,
+ GtkTreePath *path);
+void sensors_applet_update_sensor(SensorsApplet *sensors_applet,
+ GtkTreePath *path);
+
+void sensors_applet_display_layout_changed(SensorsApplet *sensors_applet);
+void sensors_applet_reorder_sensors(SensorsApplet *sensors_applet);
+gdouble sensors_applet_convert_temperature(gdouble value,
+ TemperatureScale old,
+ TemperatureScale new);
+void sensors_applet_notify(SensorsApplet *sensors_applet,
+ NotifType notif_type);
+void sensors_applet_notify_end(ActiveSensor *active_sensor, NotifType notif_type);
+void sensors_applet_notify_end_all(SensorsApplet *sensors_applet);
+void sensors_applet_notify_active_sensor(ActiveSensor *active_sensor, NotifType notif_type);
+GdkPixbuf *sensors_applet_load_icon(IconType icon_type);
+void sensors_applet_graph_size_changed(SensorsApplet *sensors_applet);
+
+typedef void SensorsInterfaceTestSensorFunc(SensorsApplet *sensors_applet,
+ const gchar *path);
+void sensors_applet_find_sensors(SensorsApplet *sensors_applet,
+ const gchar *path,
+ SensorsInterfaceTestSensorFunc test_sensor);
+
+#endif /* SENSORS_APPLET_H */