summaryrefslogtreecommitdiff
path: root/sound-theme
diff options
context:
space:
mode:
Diffstat (limited to 'sound-theme')
-rw-r--r--sound-theme/Makefile.am38
-rw-r--r--sound-theme/Makefile.in757
-rw-r--r--sound-theme/gvc-sound-theme-chooser.c1191
-rw-r--r--sound-theme/gvc-sound-theme-chooser.h54
-rw-r--r--sound-theme/gvc-sound-theme-editor.c1397
-rw-r--r--sound-theme/gvc-sound-theme-editor.h54
-rw-r--r--sound-theme/sound-theme-file-utils.c305
-rw-r--r--sound-theme/sound-theme-file-utils.h37
-rw-r--r--sound-theme/sounds/Makefile.am29
-rw-r--r--sound-theme/sounds/Makefile.in524
-rw-r--r--sound-theme/sounds/bark.oggbin0 -> 13322 bytes
-rw-r--r--sound-theme/sounds/drip.oggbin0 -> 8495 bytes
-rw-r--r--sound-theme/sounds/glass.oggbin0 -> 18999 bytes
-rw-r--r--sound-theme/sounds/mate-sounds-default.xml.in.in27
-rw-r--r--sound-theme/sounds/sonar.oggbin0 -> 20011 bytes
15 files changed, 4413 insertions, 0 deletions
diff --git a/sound-theme/Makefile.am b/sound-theme/Makefile.am
new file mode 100644
index 0000000..7a9cd4b
--- /dev/null
+++ b/sound-theme/Makefile.am
@@ -0,0 +1,38 @@
+NULL =
+
+SUBDIRS = sounds
+
+noinst_LTLIBRARIES = libsoundtheme.la
+
+AM_CPPFLAGS = \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED) \
+ $(SOUND_THEME_CFLAGS) \
+ -DSOUND_DATA_DIR="\"$(datadir)/sounds\"" \
+ -DSOUND_SET_DIR="\"$(pkgdatadir)/sounds\"" \
+ $(NULL)
+
+libsoundtheme_la_SOURCES = \
+ gvc-sound-theme-chooser.h \
+ gvc-sound-theme-chooser.c \
+ sound-theme-file-utils.h \
+ sound-theme-file-utils.c \
+ $(NULL)
+
+libsoundtheme_la_LIBADD = $(SOUND_THEME_LIBS)
+libsoundtheme_la_LDFLAGS = -no-undefined
+
+BUILT_SOURCES = \
+ $(NULL)
+
+EXTRA_DIST = gvc-sound-theme-editor.c gvc-sound-theme-editor.h
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
+
+-include $(top_srcdir)/git.mk
diff --git a/sound-theme/Makefile.in b/sound-theme/Makefile.in
new file mode 100644
index 0000000..8af7478
--- /dev/null
+++ b/sound-theme/Makefile.in
@@ -0,0 +1,757 @@
+# 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@
+subdir = sound-theme
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/m4/as-compiler-flag.m4 \
+ $(top_srcdir)/m4/as-version.m4 $(top_srcdir)/m4/intltool.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mate-doc-utils.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libsoundtheme_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_1 =
+am_libsoundtheme_la_OBJECTS = gvc-sound-theme-chooser.lo \
+ sound-theme-file-utils.lo $(am__objects_1)
+libsoundtheme_la_OBJECTS = $(am_libsoundtheme_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libsoundtheme_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libsoundtheme_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libsoundtheme_la_SOURCES)
+DIST_SOURCES = $(libsoundtheme_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
+DLLTOOL = @DLLTOOL@
+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@
+GLADEUI_CATALOG_DIR = @GLADEUI_CATALOG_DIR@
+GLADEUI_CFLAGS = @GLADEUI_CFLAGS@
+GLADEUI_LIBS = @GLADEUI_LIBS@
+GLADEUI_MODULE_DIR = @GLADEUI_MODULE_DIR@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GMOFILES = @GMOFILES@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_LIBS = @GMP_LIBS@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+GSR_CFLAGS = @GSR_CFLAGS@
+GSR_LIBS = @GSR_LIBS@
+GSTMIXER_CFLAGS = @GSTMIXER_CFLAGS@
+GSTMIXER_LIBS = @GSTMIXER_LIBS@
+GSTPROPS_CFLAGS = @GSTPROPS_CFLAGS@
+GSTPROPS_LIBS = @GSTPROPS_LIBS@
+GST_MAJORMINOR = @GST_MAJORMINOR@
+HAVE_PULSEAUDIO = @HAVE_PULSEAUDIO@
+HAVE_SOUND_THEME = @HAVE_SOUND_THEME@
+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@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MATECC_DESKTOP_DIR = @MATECC_DESKTOP_DIR@
+MATECONFTOOL = @MATECONFTOOL@
+MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@
+MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMF_DIR = @OMF_DIR@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MICRO = @PACKAGE_VERSION_MICRO@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PROGRAMS_GSTPROPS = @PROGRAMS_GSTPROPS@
+PULSEAUDIO_CFLAGS = @PULSEAUDIO_CFLAGS@
+PULSEAUDIO_LIBS = @PULSEAUDIO_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOUNDTHEME_CFLAGS = @SOUNDTHEME_CFLAGS@
+SOUNDTHEME_LIBS = @SOUNDTHEME_LIBS@
+SOUND_THEME_CFLAGS = @SOUND_THEME_CFLAGS@
+SOUND_THEME_LIBS = @SOUND_THEME_LIBS@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+VOLUME_CONTROL_CFLAGS = @VOLUME_CONTROL_CFLAGS@
+VOLUME_CONTROL_LIBS = @VOLUME_CONTROL_LIBS@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_CXXFLAGS = @WARN_CXXFLAGS@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_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@
+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@
+NULL =
+SUBDIRS = sounds
+noinst_LTLIBRARIES = libsoundtheme.la
+AM_CPPFLAGS = \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED) \
+ $(SOUND_THEME_CFLAGS) \
+ -DSOUND_DATA_DIR="\"$(datadir)/sounds\"" \
+ -DSOUND_SET_DIR="\"$(pkgdatadir)/sounds\"" \
+ $(NULL)
+
+libsoundtheme_la_SOURCES = \
+ gvc-sound-theme-chooser.h \
+ gvc-sound-theme-chooser.c \
+ sound-theme-file-utils.h \
+ sound-theme-file-utils.c \
+ $(NULL)
+
+libsoundtheme_la_LIBADD = $(SOUND_THEME_LIBS)
+libsoundtheme_la_LDFLAGS = -no-undefined
+BUILT_SOURCES = \
+ $(NULL)
+
+EXTRA_DIST = gvc-sound-theme-editor.c gvc-sound-theme-editor.h
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sound-theme/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign sound-theme/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):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libsoundtheme.la: $(libsoundtheme_la_OBJECTS) $(libsoundtheme_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libsoundtheme_la_LINK) $(libsoundtheme_la_OBJECTS) $(libsoundtheme_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-sound-theme-chooser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sound-theme-file-utils.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+ ctags-recursive install install-am install-strip \
+ tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+
+-include $(top_srcdir)/git.mk
+
+# 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/sound-theme/gvc-sound-theme-chooser.c b/sound-theme/gvc-sound-theme-chooser.c
new file mode 100644
index 0000000..75f23bb
--- /dev/null
+++ b/sound-theme/gvc-sound-theme-chooser.c
@@ -0,0 +1,1191 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Bastien Nocera <[email protected]>
+ * Copyright (C) 2008 William Jon McCann
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <utime.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <canberra-gtk.h>
+#include <libxml/tree.h>
+
+#include <mateconf/mateconf-client.h>
+
+#include "gvc-sound-theme-chooser.h"
+#include "sound-theme-file-utils.h"
+
+#define GVC_SOUND_THEME_CHOOSER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_SOUND_THEME_CHOOSER, GvcSoundThemeChooserPrivate))
+
+struct GvcSoundThemeChooserPrivate
+{
+ GtkWidget *combo_box;
+ GtkWidget *treeview;
+ GtkWidget *theme_box;
+ GtkWidget *selection_box;
+ GtkWidget *click_feedback_button;
+ MateConfClient *client;
+ guint sounds_dir_id;
+ guint marco_dir_id;
+};
+
+static void gvc_sound_theme_chooser_class_init (GvcSoundThemeChooserClass *klass);
+static void gvc_sound_theme_chooser_init (GvcSoundThemeChooser *sound_theme_chooser);
+static void gvc_sound_theme_chooser_finalize (GObject *object);
+
+G_DEFINE_TYPE (GvcSoundThemeChooser, gvc_sound_theme_chooser, GTK_TYPE_VBOX)
+
+#define KEY_SOUNDS_DIR "/desktop/mate/sound"
+#define EVENT_SOUNDS_KEY KEY_SOUNDS_DIR "/event_sounds"
+#define INPUT_SOUNDS_KEY KEY_SOUNDS_DIR "/input_feedback_sounds"
+#define SOUND_THEME_KEY KEY_SOUNDS_DIR "/theme_name"
+#define KEY_MARCO_DIR "/apps/marco/general"
+#define AUDIO_BELL_KEY KEY_MARCO_DIR "/audible_bell"
+
+#define DEFAULT_ALERT_ID "__default"
+#define CUSTOM_THEME_NAME "__custom"
+#define NO_SOUNDS_THEME_NAME "__no_sounds"
+
+enum {
+ THEME_DISPLAY_COL,
+ THEME_IDENTIFIER_COL,
+ THEME_PARENT_ID_COL,
+ THEME_NUM_COLS
+};
+
+enum {
+ ALERT_DISPLAY_COL,
+ ALERT_IDENTIFIER_COL,
+ ALERT_SOUND_TYPE_COL,
+ ALERT_ACTIVE_COL,
+ ALERT_NUM_COLS
+};
+
+enum {
+ SOUND_TYPE_UNSET,
+ SOUND_TYPE_OFF,
+ SOUND_TYPE_DEFAULT_FROM_THEME,
+ SOUND_TYPE_BUILTIN,
+ SOUND_TYPE_CUSTOM
+};
+
+static void
+on_combobox_changed (GtkComboBox *widget,
+ GvcSoundThemeChooser *chooser)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ char *theme_name;
+
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser->priv->combo_box), &iter) == FALSE) {
+ return;
+ }
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser->priv->combo_box));
+ gtk_tree_model_get (model, &iter, THEME_IDENTIFIER_COL, &theme_name, -1);
+
+ g_assert (theme_name != NULL);
+
+ /* special case for no sounds */
+ if (strcmp (theme_name, NO_SOUNDS_THEME_NAME) == 0) {
+ mateconf_client_set_bool (chooser->priv->client, EVENT_SOUNDS_KEY, FALSE, NULL);
+ return;
+ } else {
+ mateconf_client_set_bool (chooser->priv->client, EVENT_SOUNDS_KEY, TRUE, NULL);
+ }
+
+ mateconf_client_set_string (chooser->priv->client, SOUND_THEME_KEY, theme_name, NULL);
+
+ g_free (theme_name);
+
+ /* FIXME: reset alert model */
+}
+
+static char *
+load_index_theme_name (const char *index,
+ char **parent)
+{
+ GKeyFile *file;
+ char *indexname = NULL;
+ gboolean hidden;
+
+ file = g_key_file_new ();
+ if (g_key_file_load_from_file (file, index, G_KEY_FILE_KEEP_TRANSLATIONS, NULL) == FALSE) {
+ g_key_file_free (file);
+ return NULL;
+ }
+ /* Don't add hidden themes to the list */
+ hidden = g_key_file_get_boolean (file, "Sound Theme", "Hidden", NULL);
+ if (!hidden) {
+ indexname = g_key_file_get_locale_string (file,
+ "Sound Theme",
+ "Name",
+ NULL,
+ NULL);
+
+ /* Save the parent theme, if there's one */
+ if (parent != NULL) {
+ *parent = g_key_file_get_string (file,
+ "Sound Theme",
+ "Inherits",
+ NULL);
+ }
+ }
+
+ g_key_file_free (file);
+ return indexname;
+}
+
+static void
+sound_theme_in_dir (GHashTable *hash,
+ const char *dir)
+{
+ GDir *d;
+ const char *name;
+
+ d = g_dir_open (dir, 0, NULL);
+ if (d == NULL) {
+ return;
+ }
+
+ while ((name = g_dir_read_name (d)) != NULL) {
+ char *dirname, *index, *indexname;
+
+ /* Look for directories */
+ dirname = g_build_filename (dir, name, NULL);
+ if (g_file_test (dirname, G_FILE_TEST_IS_DIR) == FALSE) {
+ g_free (dirname);
+ continue;
+ }
+
+ /* Look for index files */
+ index = g_build_filename (dirname, "index.theme", NULL);
+ g_free (dirname);
+
+ /* Check the name of the theme in the index.theme file */
+ indexname = load_index_theme_name (index, NULL);
+ g_free (index);
+ if (indexname == NULL) {
+ continue;
+ }
+
+ g_hash_table_insert (hash, g_strdup (name), indexname);
+ }
+
+ g_dir_close (d);
+}
+
+static void
+add_theme_to_store (const char *key,
+ const char *value,
+ GtkListStore *store)
+{
+ char *parent;
+
+ parent = NULL;
+
+ /* Get the parent, if we're checking the custom theme */
+ if (strcmp (key, CUSTOM_THEME_NAME) == 0) {
+ char *name, *path;
+
+ path = custom_theme_dir_path ("index.theme");
+ name = load_index_theme_name (path, &parent);
+ g_free (name);
+ g_free (path);
+ }
+ gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
+ THEME_DISPLAY_COL, value,
+ THEME_IDENTIFIER_COL, key,
+ THEME_PARENT_ID_COL, parent,
+ -1);
+ g_free (parent);
+}
+
+static void
+set_combox_for_theme_name (GvcSoundThemeChooser *chooser,
+ const char *name)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gboolean found;
+
+ /* If the name is empty, use "freedesktop" */
+ if (name == NULL || *name == '\0') {
+ name = "freedesktop";
+ }
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser->priv->combo_box));
+
+ if (gtk_tree_model_get_iter_first (model, &iter) == FALSE) {
+ return;
+ }
+
+ do {
+ char *value;
+
+ gtk_tree_model_get (model, &iter, THEME_IDENTIFIER_COL, &value, -1);
+ found = (value != NULL && strcmp (value, name) == 0);
+ g_free (value);
+
+ } while (!found && gtk_tree_model_iter_next (model, &iter));
+
+ /* When we can't find the theme we need to set, try to set the default
+ * one "freedesktop" */
+ if (found) {
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (chooser->priv->combo_box), &iter);
+ } else if (strcmp (name, "freedesktop") != 0) {
+ g_debug ("not found, falling back to fdo");
+ set_combox_for_theme_name (chooser, "freedesktop");
+ }
+}
+
+static void
+set_input_feedback_enabled (GvcSoundThemeChooser *chooser,
+ gboolean enabled)
+{
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser->priv->click_feedback_button),
+ enabled);
+}
+
+static void
+setup_theme_selector (GvcSoundThemeChooser *chooser)
+{
+ GHashTable *hash;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ const char * const *data_dirs;
+ const char *data_dir;
+ char *dir;
+ guint i;
+
+ /* Add the theme names and their display name to a hash table,
+ * makes it easy to avoid duplicate themes */
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ data_dirs = g_get_system_data_dirs ();
+ for (i = 0; data_dirs[i] != NULL; i++) {
+ dir = g_build_filename (data_dirs[i], "sounds", NULL);
+ sound_theme_in_dir (hash, dir);
+ g_free (dir);
+ }
+
+ data_dir = g_get_user_data_dir ();
+ dir = g_build_filename (data_dir, "sounds", NULL);
+ sound_theme_in_dir (hash, dir);
+ g_free (dir);
+
+ /* If there isn't at least one theme, make everything
+ * insensitive, LAME! */
+ if (g_hash_table_size (hash) == 0) {
+ gtk_widget_set_sensitive (GTK_WIDGET (chooser), FALSE);
+ g_warning ("Bad setup, install the freedesktop sound theme");
+ g_hash_table_destroy (hash);
+ return;
+ }
+
+ /* Setup the tree model, 3 columns:
+ * - internal theme name/directory
+ * - display theme name
+ * - the internal id for the parent theme, used for the custom theme */
+ store = gtk_list_store_new (THEME_NUM_COLS,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ /* Add the themes to a combobox */
+ gtk_list_store_insert_with_values (store,
+ NULL,
+ G_MAXINT,
+ THEME_DISPLAY_COL, _("No sounds"),
+ THEME_IDENTIFIER_COL, "__no_sounds",
+ THEME_PARENT_ID_COL, NULL,
+ -1);
+ g_hash_table_foreach (hash, (GHFunc) add_theme_to_store, store);
+ g_hash_table_destroy (hash);
+
+ /* Set the display */
+ gtk_combo_box_set_model (GTK_COMBO_BOX (chooser->priv->combo_box),
+ GTK_TREE_MODEL (store));
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (chooser->priv->combo_box),
+ renderer,
+ TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (chooser->priv->combo_box),
+ renderer,
+ "text", THEME_DISPLAY_COL,
+ NULL);
+
+ g_signal_connect (chooser->priv->combo_box,
+ "changed",
+ G_CALLBACK (on_combobox_changed),
+ chooser);
+}
+
+#define GVC_SOUND_SOUND (xmlChar *) "sound"
+#define GVC_SOUND_NAME (xmlChar *) "name"
+#define GVC_SOUND_FILENAME (xmlChar *) "filename"
+
+/* Adapted from yelp-toc-pager.c */
+static xmlChar *
+xml_get_and_trim_names (xmlNodePtr node)
+{
+ xmlNodePtr cur, keep = NULL;
+ xmlChar *keep_lang = NULL;
+ xmlChar *value;
+ int j, keep_pri = INT_MAX;
+
+ const gchar * const * langs = g_get_language_names ();
+
+ value = NULL;
+
+ for (cur = node->children; cur; cur = cur->next) {
+ if (! xmlStrcmp (cur->name, GVC_SOUND_NAME)) {
+ xmlChar *cur_lang = NULL;
+ int cur_pri = INT_MAX;
+
+ cur_lang = xmlNodeGetLang (cur);
+
+ if (cur_lang) {
+ for (j = 0; langs[j]; j++) {
+ if (g_str_equal (cur_lang, langs[j])) {
+ cur_pri = j;
+ break;
+ }
+ }
+ } else {
+ cur_pri = INT_MAX - 1;
+ }
+
+ if (cur_pri <= keep_pri) {
+ if (keep_lang)
+ xmlFree (keep_lang);
+ if (value)
+ xmlFree (value);
+
+ value = xmlNodeGetContent (cur);
+
+ keep_lang = cur_lang;
+ keep_pri = cur_pri;
+ keep = cur;
+ } else {
+ if (cur_lang)
+ xmlFree (cur_lang);
+ }
+ }
+ }
+
+ /* Delete all GVC_SOUND_NAME nodes */
+ cur = node->children;
+ while (cur) {
+ xmlNodePtr this = cur;
+ cur = cur->next;
+ if (! xmlStrcmp (this->name, GVC_SOUND_NAME)) {
+ xmlUnlinkNode (this);
+ xmlFreeNode (this);
+ }
+ }
+
+ return value;
+}
+
+static void
+populate_model_from_node (GvcSoundThemeChooser *chooser,
+ GtkTreeModel *model,
+ xmlNodePtr node)
+{
+ xmlNodePtr child;
+ xmlChar *filename;
+ xmlChar *name;
+
+ filename = NULL;
+ name = xml_get_and_trim_names (node);
+ for (child = node->children; child; child = child->next) {
+ if (xmlNodeIsText (child)) {
+ continue;
+ }
+
+ if (xmlStrcmp (child->name, GVC_SOUND_FILENAME) == 0) {
+ filename = xmlNodeGetContent (child);
+ } else if (xmlStrcmp (child->name, GVC_SOUND_NAME) == 0) {
+ /* EH? should have been trimmed */
+ }
+ }
+
+ if (filename != NULL && name != NULL) {
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (model),
+ NULL,
+ G_MAXINT,
+ ALERT_IDENTIFIER_COL, filename,
+ ALERT_DISPLAY_COL, name,
+ ALERT_SOUND_TYPE_COL, _("Built-in"),
+ ALERT_ACTIVE_COL, FALSE,
+ -1);
+ }
+
+ xmlFree (filename);
+ xmlFree (name);
+}
+
+static void
+populate_model_from_file (GvcSoundThemeChooser *chooser,
+ GtkTreeModel *model,
+ const char *filename)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root;
+ xmlNodePtr child;
+ gboolean exists;
+
+ exists = g_file_test (filename, G_FILE_TEST_EXISTS);
+ if (! exists) {
+ return;
+ }
+
+ doc = xmlParseFile (filename);
+ if (doc == NULL) {
+ return;
+ }
+
+ root = xmlDocGetRootElement (doc);
+
+ for (child = root->children; child; child = child->next) {
+ if (xmlNodeIsText (child)) {
+ continue;
+ }
+ if (xmlStrcmp (child->name, GVC_SOUND_SOUND) != 0) {
+ continue;
+ }
+
+ populate_model_from_node (chooser, model, child);
+ }
+
+ xmlFreeDoc (doc);
+}
+
+static void
+populate_model_from_dir (GvcSoundThemeChooser *chooser,
+ GtkTreeModel *model,
+ const char *dirname)
+{
+ GDir *d;
+ const char *name;
+
+ d = g_dir_open (dirname, 0, NULL);
+ if (d == NULL) {
+ return;
+ }
+
+ while ((name = g_dir_read_name (d)) != NULL) {
+ char *path;
+
+ if (! g_str_has_suffix (name, ".xml")) {
+ continue;
+ }
+
+ path = g_build_filename (dirname, name, NULL);
+ populate_model_from_file (chooser, model, path);
+ g_free (path);
+ }
+}
+
+static gboolean
+save_alert_sounds (GvcSoundThemeChooser *chooser,
+ const char *id)
+{
+ const char *sounds[3] = { "bell-terminal", "bell-window-system", NULL };
+ char *path;
+
+ if (strcmp (id, DEFAULT_ALERT_ID) == 0) {
+ delete_old_files (sounds);
+ delete_disabled_files (sounds);
+ } else {
+ delete_old_files (sounds);
+ delete_disabled_files (sounds);
+ add_custom_file (sounds, id);
+ }
+
+ /* And poke the directory so the theme gets updated */
+ path = custom_theme_dir_path (NULL);
+ if (utime (path, NULL) != 0) {
+ g_warning ("Failed to update mtime for directory '%s': %s",
+ path, g_strerror (errno));
+ }
+ g_free (path);
+
+ return FALSE;
+}
+
+
+static void
+update_alert_model (GvcSoundThemeChooser *chooser,
+ const char *id)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ gboolean toggled;
+ char *this_id;
+
+ gtk_tree_model_get (model, &iter,
+ ALERT_IDENTIFIER_COL, &this_id,
+ -1);
+
+ if (strcmp (this_id, id) == 0) {
+ toggled = TRUE;
+ } else {
+ toggled = FALSE;
+ }
+ g_free (this_id);
+
+ gtk_list_store_set (GTK_LIST_STORE (model),
+ &iter,
+ ALERT_ACTIVE_COL, toggled,
+ -1);
+ } while (gtk_tree_model_iter_next (model, &iter));
+}
+
+static void
+update_alert (GvcSoundThemeChooser *chooser,
+ const char *alert_id)
+{
+ GtkTreeModel *theme_model;
+ GtkTreeIter iter;
+ char *theme;
+ char *parent;
+ gboolean is_custom;
+ gboolean is_default;
+ gboolean add_custom;
+ gboolean remove_custom;
+
+ theme_model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser->priv->combo_box));
+ /* Get the current theme's name, and set the parent */
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser->priv->combo_box), &iter) == FALSE) {
+ return;
+ }
+
+ gtk_tree_model_get (theme_model, &iter,
+ THEME_IDENTIFIER_COL, &theme,
+ THEME_IDENTIFIER_COL, &parent,
+ -1);
+ is_custom = strcmp (theme, CUSTOM_THEME_NAME) == 0;
+ is_default = strcmp (alert_id, DEFAULT_ALERT_ID) == 0;
+
+ /* So a few possibilities:
+ * 1. Named theme, default alert selected: noop
+ * 2. Named theme, alternate alert selected: create new custom with sound
+ * 3. Custom theme, default alert selected: remove sound and possibly custom
+ * 4. Custom theme, alternate alert selected: update custom sound
+ */
+ add_custom = FALSE;
+ remove_custom = FALSE;
+ if (! is_custom && is_default) {
+ /* remove custom just in case */
+ remove_custom = TRUE;
+ } else if (! is_custom && ! is_default) {
+ create_custom_theme (parent);
+ save_alert_sounds (chooser, alert_id);
+ add_custom = TRUE;
+ } else if (is_custom && is_default) {
+ save_alert_sounds (chooser, alert_id);
+ /* after removing files check if it is empty */
+ if (custom_theme_dir_is_empty ()) {
+ remove_custom = TRUE;
+ }
+ } else if (is_custom && ! is_default) {
+ save_alert_sounds (chooser, alert_id);
+ }
+
+ if (add_custom) {
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (theme_model),
+ NULL,
+ G_MAXINT,
+ THEME_DISPLAY_COL, _("Custom"),
+ THEME_IDENTIFIER_COL, CUSTOM_THEME_NAME,
+ THEME_PARENT_ID_COL, theme,
+ -1);
+ set_combox_for_theme_name (chooser, CUSTOM_THEME_NAME);
+ } else if (remove_custom) {
+ gtk_tree_model_get_iter_first (theme_model, &iter);
+ do {
+ char *this_parent;
+
+ gtk_tree_model_get (theme_model, &iter,
+ THEME_PARENT_ID_COL, &this_parent,
+ -1);
+ if (this_parent != NULL && strcmp (this_parent, CUSTOM_THEME_NAME) != 0) {
+ g_free (this_parent);
+ gtk_list_store_remove (GTK_LIST_STORE (theme_model), &iter);
+ break;
+ }
+ g_free (this_parent);
+ } while (gtk_tree_model_iter_next (theme_model, &iter));
+
+ delete_custom_theme_dir ();
+
+ set_combox_for_theme_name (chooser, parent);
+ }
+
+ update_alert_model (chooser, alert_id);
+
+ g_free (theme);
+ g_free (parent);
+}
+
+static void
+on_alert_toggled (GtkCellRendererToggle *renderer,
+ char *path_str,
+ GvcSoundThemeChooser *chooser)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ gboolean toggled;
+ char *id;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
+
+ path = gtk_tree_path_new_from_string (path_str);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+
+ id = NULL;
+ gtk_tree_model_get (model, &iter,
+ ALERT_IDENTIFIER_COL, &id,
+ ALERT_ACTIVE_COL, &toggled,
+ -1);
+
+ toggled ^= 1;
+ if (toggled) {
+ update_alert (chooser, id);
+ }
+
+ g_free (id);
+}
+
+static void
+play_preview_for_path (GvcSoundThemeChooser *chooser,
+ GtkTreePath *path)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeIter theme_iter;
+ char *id;
+ char *parent_theme;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
+ if (gtk_tree_model_get_iter (model, &iter, path) == FALSE) {
+ return;
+ }
+
+ id = NULL;
+ gtk_tree_model_get (model, &iter,
+ ALERT_IDENTIFIER_COL, &id,
+ -1);
+ if (id == NULL) {
+ return;
+ }
+
+ parent_theme = NULL;
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser->priv->combo_box), &theme_iter)) {
+ GtkTreeModel *theme_model;
+ char *theme_id;
+ char *parent_id;
+
+ theme_model = gtk_combo_box_get_model (GTK_COMBO_BOX (chooser->priv->combo_box));
+ theme_id = NULL;
+ parent_id = NULL;
+ gtk_tree_model_get (theme_model, &theme_iter,
+ THEME_IDENTIFIER_COL, &theme_id,
+ THEME_PARENT_ID_COL, &parent_id, -1);
+ if (theme_id && strcmp (theme_id, CUSTOM_THEME_NAME) == 0) {
+ parent_theme = g_strdup (parent_id);
+ }
+ g_free (theme_id);
+ g_free (parent_id);
+ }
+
+ /* special case: for the default item on custom themes
+ * play the alert for the parent theme */
+ if (strcmp (id, DEFAULT_ALERT_ID) == 0) {
+ if (parent_theme != NULL) {
+ ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
+ CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+ CA_PROP_EVENT_ID, "bell-window-system",
+ CA_PROP_CANBERRA_XDG_THEME_NAME, parent_theme,
+ CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+ CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+ CA_PROP_APPLICATION_ID, "org.mate.VolumeControl",
+#ifdef CA_PROP_CANBERRA_ENABLE
+ CA_PROP_CANBERRA_ENABLE, "1",
+#endif
+ NULL);
+ } else {
+ ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
+ CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+ CA_PROP_EVENT_ID, "bell-window-system",
+ CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+ CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+ CA_PROP_APPLICATION_ID, "org.mate.VolumeControl",
+#ifdef CA_PROP_CANBERRA_ENABLE
+ CA_PROP_CANBERRA_ENABLE, "1",
+#endif
+ NULL);
+ }
+ } else {
+ ca_gtk_play_for_widget (GTK_WIDGET (chooser), 0,
+ CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+ CA_PROP_MEDIA_FILENAME, id,
+ CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+ CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+ CA_PROP_APPLICATION_ID, "org.mate.VolumeControl",
+#ifdef CA_PROP_CANBERRA_ENABLE
+ CA_PROP_CANBERRA_ENABLE, "1",
+#endif
+ NULL);
+
+ }
+ g_free (parent_theme);
+ g_free (id);
+}
+
+static void
+on_treeview_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GvcSoundThemeChooser *chooser)
+{
+ play_preview_for_path (chooser, path);
+}
+
+static void
+on_treeview_selection_changed (GtkTreeSelection *selection,
+ GvcSoundThemeChooser *chooser)
+{
+ GList *paths;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+
+ if (chooser->priv->treeview == NULL) {
+ return;
+ }
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->priv->treeview));
+
+ paths = gtk_tree_selection_get_selected_rows (selection, &model);
+ if (paths == NULL) {
+ return;
+ }
+
+ path = paths->data;
+ play_preview_for_path (chooser, path);
+
+ g_list_foreach (paths, (GFunc)gtk_tree_path_free, NULL);
+ g_list_free (paths);
+}
+
+static GtkWidget *
+create_alert_treeview (GvcSoundThemeChooser *chooser)
+{
+ GtkListStore *store;
+ GtkWidget *treeview;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *selection;
+
+ treeview = gtk_tree_view_new ();
+ g_signal_connect (treeview,
+ "row-activated",
+ G_CALLBACK (on_treeview_row_activated),
+ chooser);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ g_signal_connect (selection,
+ "changed",
+ G_CALLBACK (on_treeview_selection_changed),
+ chooser);
+
+ /* Setup the tree model, 3 columns:
+ * - display name
+ * - sound id
+ * - sound type
+ */
+ store = gtk_list_store_new (ALERT_NUM_COLS,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN);
+
+ gtk_list_store_insert_with_values (store,
+ NULL,
+ G_MAXINT,
+ ALERT_IDENTIFIER_COL, DEFAULT_ALERT_ID,
+ ALERT_DISPLAY_COL, _("Default"),
+ ALERT_SOUND_TYPE_COL, _("From theme"),
+ ALERT_ACTIVE_COL, TRUE,
+ -1);
+
+ populate_model_from_dir (chooser, GTK_TREE_MODEL (store), SOUND_SET_DIR);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
+ GTK_TREE_MODEL (store));
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer),
+ TRUE);
+ column = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer,
+ "active", ALERT_ACTIVE_COL,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+ g_signal_connect (renderer,
+ "toggled",
+ G_CALLBACK (on_alert_toggled),
+ chooser);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Name"),
+ renderer,
+ "text", ALERT_DISPLAY_COL,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Type"),
+ renderer,
+ "text", ALERT_SOUND_TYPE_COL,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
+ return treeview;
+}
+
+static int
+get_file_type (const char *sound_name,
+ char **linked_name)
+{
+ char *name, *filename;
+
+ *linked_name = NULL;
+
+ name = g_strdup_printf ("%s.disabled", sound_name);
+ filename = custom_theme_dir_path (name);
+ g_free (name);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) != FALSE) {
+ g_free (filename);
+ return SOUND_TYPE_OFF;
+ }
+ g_free (filename);
+
+ /* We only check for .ogg files because those are the
+ * only ones we create */
+ name = g_strdup_printf ("%s.ogg", sound_name);
+ filename = custom_theme_dir_path (name);
+ g_free (name);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_SYMLINK) != FALSE) {
+ *linked_name = g_file_read_link (filename, NULL);
+ g_free (filename);
+ return SOUND_TYPE_CUSTOM;
+ }
+ g_free (filename);
+
+ return SOUND_TYPE_BUILTIN;
+}
+
+static void
+update_alerts_from_theme_name (GvcSoundThemeChooser *chooser,
+ const char *name)
+{
+ if (strcmp (name, CUSTOM_THEME_NAME) != 0) {
+ /* reset alert to default */
+ update_alert (chooser, DEFAULT_ALERT_ID);
+ } else {
+ int sound_type;
+ char *linkname;
+
+ linkname = NULL;
+ sound_type = get_file_type ("bell-terminal", &linkname);
+ g_debug ("Found link: %s", linkname);
+ if (sound_type == SOUND_TYPE_CUSTOM) {
+ update_alert (chooser, linkname);
+ }
+ }
+}
+
+static void
+update_theme (GvcSoundThemeChooser *chooser)
+{
+ char *theme_name;
+ gboolean events_enabled;
+ gboolean bell_enabled;
+ gboolean feedback_enabled;
+
+ bell_enabled = mateconf_client_get_bool (chooser->priv->client, AUDIO_BELL_KEY, NULL);
+ //set_audible_bell_enabled (chooser, bell_enabled);
+
+ feedback_enabled = mateconf_client_get_bool (chooser->priv->client, INPUT_SOUNDS_KEY, NULL);
+ set_input_feedback_enabled (chooser, feedback_enabled);
+
+ events_enabled = mateconf_client_get_bool (chooser->priv->client, EVENT_SOUNDS_KEY, NULL);
+ if (events_enabled) {
+ theme_name = mateconf_client_get_string (chooser->priv->client, SOUND_THEME_KEY, NULL);
+ } else {
+ theme_name = g_strdup (NO_SOUNDS_THEME_NAME);
+ }
+
+ gtk_widget_set_sensitive (chooser->priv->selection_box, events_enabled);
+ gtk_widget_set_sensitive (chooser->priv->click_feedback_button, events_enabled);
+
+ set_combox_for_theme_name (chooser, theme_name);
+
+ update_alerts_from_theme_name (chooser, theme_name);
+
+ g_free (theme_name);
+}
+
+static GObject *
+gvc_sound_theme_chooser_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ GvcSoundThemeChooser *self;
+
+ object = G_OBJECT_CLASS (gvc_sound_theme_chooser_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+ self = GVC_SOUND_THEME_CHOOSER (object);
+
+ setup_theme_selector (self);
+
+ update_theme (self);
+
+ return object;
+}
+
+static void
+gvc_sound_theme_chooser_class_init (GvcSoundThemeChooserClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = gvc_sound_theme_chooser_constructor;
+ object_class->finalize = gvc_sound_theme_chooser_finalize;
+
+ g_type_class_add_private (klass, sizeof (GvcSoundThemeChooserPrivate));
+}
+
+static void
+on_click_feedback_toggled (GtkToggleButton *button,
+ GvcSoundThemeChooser *chooser)
+{
+ gboolean enabled;
+
+ enabled = gtk_toggle_button_get_active (button);
+
+ mateconf_client_set_bool (chooser->priv->client, INPUT_SOUNDS_KEY, enabled, NULL);
+}
+
+static void
+on_key_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ GvcSoundThemeChooser *chooser)
+{
+ const char *key;
+ MateConfValue *value;
+
+ key = mateconf_entry_get_key (entry);
+
+ if (! g_str_has_prefix (key, KEY_SOUNDS_DIR)
+ && ! g_str_has_prefix (key, KEY_MARCO_DIR)) {
+ return;
+ }
+
+ value = mateconf_entry_get_value (entry);
+ if (strcmp (key, EVENT_SOUNDS_KEY) == 0) {
+ update_theme (chooser);
+ } else if (strcmp (key, SOUND_THEME_KEY) == 0) {
+ update_theme (chooser);
+ } else if (strcmp (key, INPUT_SOUNDS_KEY) == 0) {
+ update_theme (chooser);
+ } else if (strcmp (key, AUDIO_BELL_KEY) == 0) {
+ update_theme (chooser);
+ }
+}
+
+static void
+constrain_list_size (GtkWidget *widget,
+ GtkRequisition *requisition,
+ GtkWidget *to_size)
+{
+ GtkRequisition req;
+ int max_height;
+
+ /* constrain height to be the tree height up to a max */
+ max_height = (gdk_screen_get_height (gtk_widget_get_screen (widget))) / 4;
+
+ gtk_widget_size_request (to_size, &req);
+
+ requisition->height = MIN (req.height, max_height);
+}
+
+static void
+setup_list_size_constraint (GtkWidget *widget,
+ GtkWidget *to_size)
+{
+ g_signal_connect (widget,
+ "size-request",
+ G_CALLBACK (constrain_list_size),
+ to_size);
+}
+
+static void
+gvc_sound_theme_chooser_init (GvcSoundThemeChooser *chooser)
+{
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *scrolled_window;
+ GtkWidget *alignment;
+ char *str;
+
+ chooser->priv = GVC_SOUND_THEME_CHOOSER_GET_PRIVATE (chooser);
+
+ chooser->priv->theme_box = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (chooser),
+ chooser->priv->theme_box, FALSE, FALSE, 0);
+
+ label = gtk_label_new_with_mnemonic (_("Sound _theme:"));
+ gtk_box_pack_start (GTK_BOX (chooser->priv->theme_box), label, FALSE, FALSE, 0);
+ chooser->priv->combo_box = gtk_combo_box_new ();
+ gtk_box_pack_start (GTK_BOX (chooser->priv->theme_box), chooser->priv->combo_box, FALSE, FALSE, 6);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), chooser->priv->combo_box);
+
+ chooser->priv->client = mateconf_client_get_default ();
+
+ str = g_strdup_printf ("<b>%s</b>", _("C_hoose an alert sound:"));
+ chooser->priv->selection_box = box = gtk_frame_new (str);
+ g_free (str);
+ label = gtk_frame_get_label_widget (GTK_FRAME (box));
+ gtk_label_set_use_underline (GTK_LABEL (label), TRUE);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_frame_set_shadow_type (GTK_FRAME (box), GTK_SHADOW_NONE);
+
+ alignment = gtk_alignment_new (0, 0, 1, 1);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
+ gtk_container_add (GTK_CONTAINER (alignment), box);
+ gtk_box_pack_start (GTK_BOX (chooser), alignment, TRUE, TRUE, 6);
+
+ alignment = gtk_alignment_new (0, 0, 1, 1);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 6, 0, 0, 0);
+ gtk_container_add (GTK_CONTAINER (box), alignment);
+
+ chooser->priv->treeview = create_alert_treeview (chooser);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), chooser->priv->treeview);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ setup_list_size_constraint (scrolled_window, chooser->priv->treeview);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), chooser->priv->treeview);
+ gtk_container_add (GTK_CONTAINER (alignment), scrolled_window);
+
+ chooser->priv->click_feedback_button = gtk_check_button_new_with_mnemonic (_("Enable _window and button sounds"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chooser->priv->click_feedback_button),
+ mateconf_client_get_bool (chooser->priv->client, INPUT_SOUNDS_KEY, NULL));
+ gtk_box_pack_start (GTK_BOX (chooser),
+ chooser->priv->click_feedback_button,
+ FALSE, FALSE, 0);
+ g_signal_connect (chooser->priv->click_feedback_button,
+ "toggled",
+ G_CALLBACK (on_click_feedback_toggled),
+ chooser);
+
+
+ mateconf_client_add_dir (chooser->priv->client, KEY_SOUNDS_DIR,
+ MATECONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+ chooser->priv->sounds_dir_id = mateconf_client_notify_add (chooser->priv->client,
+ KEY_SOUNDS_DIR,
+ (MateConfClientNotifyFunc)on_key_changed,
+ chooser, NULL, NULL);
+ mateconf_client_add_dir (chooser->priv->client, KEY_MARCO_DIR,
+ MATECONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+ chooser->priv->marco_dir_id = mateconf_client_notify_add (chooser->priv->client,
+ KEY_MARCO_DIR,
+ (MateConfClientNotifyFunc)on_key_changed,
+ chooser, NULL, NULL);
+
+ /* FIXME: should accept drag and drop themes. should also
+ add an "Add Theme..." item to the theme combobox */
+}
+
+static void
+gvc_sound_theme_chooser_finalize (GObject *object)
+{
+ GvcSoundThemeChooser *sound_theme_chooser;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GVC_IS_SOUND_THEME_CHOOSER (object));
+
+ sound_theme_chooser = GVC_SOUND_THEME_CHOOSER (object);
+
+ if (sound_theme_chooser->priv != NULL) {
+ if (sound_theme_chooser->priv->sounds_dir_id > 0) {
+ mateconf_client_notify_remove (sound_theme_chooser->priv->client,
+ sound_theme_chooser->priv->sounds_dir_id);
+ sound_theme_chooser->priv->sounds_dir_id = 0;
+ }
+ if (sound_theme_chooser->priv->marco_dir_id > 0) {
+ mateconf_client_notify_remove (sound_theme_chooser->priv->client,
+ sound_theme_chooser->priv->marco_dir_id);
+ sound_theme_chooser->priv->marco_dir_id = 0;
+ }
+ g_object_unref (sound_theme_chooser->priv->client);
+ sound_theme_chooser->priv->client = NULL;
+ }
+
+ G_OBJECT_CLASS (gvc_sound_theme_chooser_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gvc_sound_theme_chooser_new (void)
+{
+ GObject *chooser;
+ chooser = g_object_new (GVC_TYPE_SOUND_THEME_CHOOSER,
+ "spacing", 6,
+ NULL);
+ return GTK_WIDGET (chooser);
+}
diff --git a/sound-theme/gvc-sound-theme-chooser.h b/sound-theme/gvc-sound-theme-chooser.h
new file mode 100644
index 0000000..6701aad
--- /dev/null
+++ b/sound-theme/gvc-sound-theme-chooser.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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 __GVC_SOUND_THEME_CHOOSER_H
+#define __GVC_SOUND_THEME_CHOOSER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GVC_TYPE_SOUND_THEME_CHOOSER (gvc_sound_theme_chooser_get_type ())
+#define GVC_SOUND_THEME_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_SOUND_THEME_CHOOSER, GvcSoundThemeChooser))
+#define GVC_SOUND_THEME_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_SOUND_THEME_CHOOSER, GvcSoundThemeChooserClass))
+#define GVC_IS_SOUND_THEME_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_SOUND_THEME_CHOOSER))
+#define GVC_IS_SOUND_THEME_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_SOUND_THEME_CHOOSER))
+#define GVC_SOUND_THEME_CHOOSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_SOUND_THEME_CHOOSER, GvcSoundThemeChooserClass))
+
+typedef struct GvcSoundThemeChooserPrivate GvcSoundThemeChooserPrivate;
+
+typedef struct
+{
+ GtkVBox parent;
+ GvcSoundThemeChooserPrivate *priv;
+} GvcSoundThemeChooser;
+
+typedef struct
+{
+ GtkVBoxClass parent_class;
+} GvcSoundThemeChooserClass;
+
+GType gvc_sound_theme_chooser_get_type (void);
+
+GtkWidget * gvc_sound_theme_chooser_new (void);
+
+G_END_DECLS
+
+#endif /* __GVC_SOUND_THEME_CHOOSER_H */
diff --git a/sound-theme/gvc-sound-theme-editor.c b/sound-theme/gvc-sound-theme-editor.c
new file mode 100644
index 0000000..0453150
--- /dev/null
+++ b/sound-theme/gvc-sound-theme-editor.c
@@ -0,0 +1,1397 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Bastien Nocera <[email protected]>
+ * Copyright (C) 2008 William Jon McCann
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <canberra-gtk.h>
+
+#include <mateconf/mateconf-client.h>
+
+#include "gvc-sound-theme-editor.h"
+#include "sound-theme-file-utils.h"
+
+#define GVC_SOUND_THEME_EDITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_SOUND_THEME_EDITOR, GvcSoundThemeEditorPrivate))
+
+struct GvcSoundThemeEditorPrivate
+{
+ GtkWidget *treeview;
+ GtkWidget *theme_box;
+ GtkWidget *selection_box;
+ GtkWidget *click_feedback_button;
+ MateConfClient *client;
+ guint sounds_dir_id;
+ guint marco_dir_id;
+};
+
+static void gvc_sound_theme_editor_class_init (GvcSoundThemeEditorClass *klass);
+static void gvc_sound_theme_editor_init (GvcSoundThemeEditor *sound_theme_editor);
+static void gvc_sound_theme_editor_finalize (GObject *object);
+
+G_DEFINE_TYPE (GvcSoundThemeEditor, gvc_sound_theme_editor, GTK_TYPE_VBOX)
+
+typedef enum {
+ CATEGORY_INVALID,
+ CATEGORY_BELL,
+ CATEGORY_WINDOWS_BUTTONS,
+ CATEGORY_DESKTOP,
+ CATEGORY_ALERTS,
+ NUM_CATEGORIES
+} CategoryType;
+
+typedef enum {
+ SOUND_TYPE_NORMAL,
+ SOUND_TYPE_AUDIO_BELL,
+ SOUND_TYPE_FEEDBACK
+} SoundType;
+
+static struct {
+ CategoryType category;
+ SoundType type;
+ const char *display_name;
+ const char *names[6];
+} sounds[20] = {
+ /* Bell */
+ { CATEGORY_BELL, SOUND_TYPE_AUDIO_BELL, NC_("Sound event", "Alert sound"), { "bell-terminal", "bell-window-system", NULL } },
+ /* Windows and buttons */
+ { CATEGORY_WINDOWS_BUTTONS, -1, NC_("Sound event", "Windows and Buttons"), { NULL } },
+ { CATEGORY_WINDOWS_BUTTONS, SOUND_TYPE_FEEDBACK, NC_("Sound event", "Button clicked"), { "button-pressed", "menu-click", "menu-popup", "menu-popdown", "menu-replace", NULL } },
+ { CATEGORY_WINDOWS_BUTTONS, SOUND_TYPE_FEEDBACK, NC_("Sound event", "Toggle button clicked"), { "button-toggle-off", "button-toggle-on", NULL } },
+ { CATEGORY_WINDOWS_BUTTONS, SOUND_TYPE_FEEDBACK, NC_("Sound event", "Window maximized"), { "window-maximized", NULL } },
+ { CATEGORY_WINDOWS_BUTTONS, SOUND_TYPE_FEEDBACK, NC_("Sound event", "Window unmaximized"), { "window-unmaximized", NULL } },
+ { CATEGORY_WINDOWS_BUTTONS, SOUND_TYPE_FEEDBACK, NC_("Sound event", "Window minimised"), { "window-minimized", NULL } },
+ /* Desktop */
+ { CATEGORY_DESKTOP, -1, NC_("Sound event", "Desktop"), { NULL } },
+ { CATEGORY_DESKTOP, SOUND_TYPE_NORMAL, NC_("Sound event", "Login"), { "desktop-login", NULL } },
+ { CATEGORY_DESKTOP, SOUND_TYPE_NORMAL, NC_("Sound event", "Logout"), { "desktop-logout", NULL } },
+ { CATEGORY_DESKTOP, SOUND_TYPE_NORMAL, NC_("Sound event", "New e-mail"), { "message-new-email", NULL } },
+ { CATEGORY_DESKTOP, SOUND_TYPE_NORMAL, NC_("Sound event", "Empty trash"), { "trash-empty", NULL } },
+ { CATEGORY_DESKTOP, SOUND_TYPE_NORMAL, NC_("Sound event", "Long action completed (download, CD burning, etc.)"), { "complete-copy", "complete-download", "complete-media-burn", "complete-media-rip", "complete-scan", NULL } },
+ /* Alerts? */
+ { CATEGORY_ALERTS, -1, NC_("Sound event", "Alerts"), { NULL } },
+ { CATEGORY_ALERTS, SOUND_TYPE_NORMAL, NC_("Sound event", "Information or question"), { "dialog-information", "dialog-question", NULL } },
+ { CATEGORY_ALERTS, SOUND_TYPE_NORMAL, NC_("Sound event", "Warning"), { "dialog-warning", NULL } },
+ { CATEGORY_ALERTS, SOUND_TYPE_NORMAL, NC_("Sound event", "Error"), { "dialog-error", NULL } },
+ { CATEGORY_ALERTS, SOUND_TYPE_NORMAL, NC_("Sound event", "Battery warning"), { "power-unplug-battery-low", "battery-low", "battery-caution", NULL } },
+ /* Finish off */
+ { -1, -1, NULL, { NULL } }
+};
+
+#define KEY_SOUNDS_DIR "/desktop/mate/sound"
+#define EVENT_SOUNDS_KEY KEY_SOUNDS_DIR "/event_sounds"
+#define INPUT_SOUNDS_KEY KEY_SOUNDS_DIR "/input_feedback_sounds"
+#define SOUND_THEME_KEY KEY_SOUNDS_DIR "/theme_name"
+#define KEY_MARCO_DIR "/apps/marco/general"
+#define AUDIO_BELL_KEY KEY_MARCO_DIR "/audible_bell"
+
+#define CUSTOM_THEME_NAME "__custom"
+#define NO_SOUNDS_THEME_NAME "__no_sounds"
+#define PREVIEW_BUTTON_XPAD 5
+
+enum {
+ THEME_DISPLAY_COL,
+ THEME_IDENTIFIER_COL,
+ THEME_PARENT_ID_COL,
+ THEME_NUM_COLS
+};
+
+enum {
+ SOUND_UNSET,
+ SOUND_OFF,
+ SOUND_BUILTIN,
+ SOUND_CUSTOM,
+ SOUND_CUSTOM_OLD
+};
+
+enum {
+ DISPLAY_COL,
+ SETTING_COL,
+ TYPE_COL,
+ SENSITIVE_COL,
+ HAS_PREVIEW_COL,
+ FILENAME_COL,
+ SOUND_NAMES_COL,
+ NUM_COLS
+};
+
+static gboolean
+theme_changed_custom_reinit (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int type;
+ gboolean sensitive;
+
+ gtk_tree_model_get (model,
+ iter,
+ TYPE_COL, &type,
+ SENSITIVE_COL, &sensitive, -1);
+ if (type != -1) {
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ SETTING_COL, SOUND_BUILTIN,
+ HAS_PREVIEW_COL, sensitive,
+ -1);
+ }
+ return FALSE;
+}
+
+static void
+on_theme_changed ()
+{
+ /* Don't reinit a custom theme */
+ if (strcmp (theme_name, CUSTOM_THEME_NAME) != 0) {
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ gtk_tree_model_foreach (model, theme_changed_custom_reinit, NULL);
+
+ /* Delete the custom dir */
+ delete_custom_theme_dir ();
+
+ /* And the combo box entry */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (editor->priv->combo_box));
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ char *parent;
+ gtk_tree_model_get (model, &iter, THEME_PARENT_ID_COL, &parent, -1);
+ if (parent != NULL && strcmp (parent, CUSTOM_THEME_NAME) != 0) {
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ g_free (parent);
+ break;
+ }
+ g_free (parent);
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+}
+
+static char *
+load_index_theme_name (const char *index,
+ char **parent)
+{
+ GKeyFile *file;
+ char *indexname = NULL;
+ gboolean hidden;
+
+ file = g_key_file_new ();
+ if (g_key_file_load_from_file (file, index, G_KEY_FILE_KEEP_TRANSLATIONS, NULL) == FALSE) {
+ g_key_file_free (file);
+ return NULL;
+ }
+ /* Don't add hidden themes to the list */
+ hidden = g_key_file_get_boolean (file, "Sound Theme", "Hidden", NULL);
+ if (!hidden) {
+ indexname = g_key_file_get_locale_string (file,
+ "Sound Theme",
+ "Name",
+ NULL,
+ NULL);
+
+ /* Save the parent theme, if there's one */
+ if (parent != NULL) {
+ *parent = g_key_file_get_string (file,
+ "Sound Theme",
+ "Inherits",
+ NULL);
+ }
+ }
+
+ g_key_file_free (file);
+ return indexname;
+}
+
+static void
+sound_theme_in_dir (GHashTable *hash,
+ const char *dir)
+{
+ GDir *d;
+ const char *name;
+
+ d = g_dir_open (dir, 0, NULL);
+ if (d == NULL) {
+ return;
+ }
+
+ while ((name = g_dir_read_name (d)) != NULL) {
+ char *dirname, *index, *indexname;
+
+ /* Look for directories */
+ dirname = g_build_filename (dir, name, NULL);
+ if (g_file_test (dirname, G_FILE_TEST_IS_DIR) == FALSE) {
+ g_free (dirname);
+ continue;
+ }
+
+ /* Look for index files */
+ index = g_build_filename (dirname, "index.theme", NULL);
+ g_free (dirname);
+
+ /* Check the name of the theme in the index.theme file */
+ indexname = load_index_theme_name (index, NULL);
+ g_free (index);
+ if (indexname == NULL) {
+ continue;
+ }
+
+ g_hash_table_insert (hash, g_strdup (name), indexname);
+ }
+
+ g_dir_close (d);
+}
+
+static void
+add_theme_to_store (const char *key,
+ const char *value,
+ GtkListStore *store)
+{
+ char *parent;
+
+ parent = NULL;
+
+ /* Get the parent, if we're checking the custom theme */
+ if (strcmp (key, CUSTOM_THEME_NAME) == 0) {
+ char *name, *path;
+
+ path = custom_theme_dir_path ("index.theme");
+ name = load_index_theme_name (path, &parent);
+ g_free (name);
+ g_free (path);
+ }
+ gtk_list_store_insert_with_values (store, NULL, G_MAXINT,
+ THEME_DISPLAY_COL, value,
+ THEME_IDENTIFIER_COL, key,
+ THEME_PARENT_ID_COL, parent,
+ -1);
+ g_free (parent);
+}
+
+static void
+set_theme_name (GvcSoundThemeEditor *editor,
+ const char *name)
+{
+ MateConfClient *client;
+
+ g_debug ("setting theme %s", name ? name : "(null)");
+
+ /* If the name is empty, use "freedesktop" */
+ if (name == NULL || *name == '\0') {
+ name = "freedesktop";
+ }
+
+ mateconf_client_set_string (editor->priv->client, SOUND_THEME_KEY, theme_name, NULL);
+}
+
+/* Functions to toggle whether the audible bell sound is editable */
+static gboolean
+audible_bell_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int type;
+ int setting;
+ gboolean enabled = GPOINTER_TO_INT (data);
+
+ setting = enabled ? SOUND_BUILTIN : SOUND_OFF;
+
+ gtk_tree_model_get (model, iter, TYPE_COL, &type, -1);
+ if (type == SOUND_TYPE_AUDIO_BELL) {
+ gtk_tree_store_set (GTK_TREE_STORE (model),
+ iter,
+ SETTING_COL, setting,
+ HAS_PREVIEW_COL, enabled,
+ -1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+set_audible_bell_enabled (GvcSoundThemeEditor *editor,
+ gboolean enabled)
+{
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ gtk_tree_model_foreach (model, audible_bell_foreach, GINT_TO_POINTER (enabled));
+}
+
+/* Functions to toggle whether the Input feedback sounds are editable */
+static gboolean
+input_feedback_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int type;
+ gboolean enabled = GPOINTER_TO_INT (data);
+
+ gtk_tree_model_get (model, iter, TYPE_COL, &type, -1);
+ if (type == SOUND_TYPE_FEEDBACK) {
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ SENSITIVE_COL, enabled,
+ HAS_PREVIEW_COL, enabled,
+ -1);
+ }
+ return FALSE;
+}
+
+static void
+set_input_feedback_enabled (GvcSoundThemeEditor *editor,
+ gboolean enabled)
+{
+ GtkTreeModel *model;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->priv->click_feedback_button),
+ enabled);
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ gtk_tree_model_foreach (model, input_feedback_foreach, GINT_TO_POINTER (enabled));
+}
+
+static int
+get_file_type (const char *sound_name,
+ char **linked_name)
+{
+ char *name, *filename;
+
+ *linked_name = NULL;
+
+ name = g_strdup_printf ("%s.disabled", sound_name);
+ filename = custom_theme_dir_path (name);
+ g_free (name);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_REGULAR) != FALSE) {
+ g_free (filename);
+ return SOUND_OFF;
+ }
+ g_free (filename);
+
+ /* We only check for .ogg files because those are the
+ * only ones we create */
+ name = g_strdup_printf ("%s.ogg", sound_name);
+ filename = custom_theme_dir_path (name);
+ g_free (name);
+
+ if (g_file_test (filename, G_FILE_TEST_IS_SYMLINK) != FALSE) {
+ *linked_name = g_file_read_link (filename, NULL);
+ g_free (filename);
+ return SOUND_CUSTOM;
+ }
+ g_free (filename);
+
+ return SOUND_BUILTIN;
+}
+
+static gboolean
+theme_changed_custom_init (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ char **sound_names;
+
+ gtk_tree_model_get (model, iter, SOUND_NAMES_COL, &sound_names, -1);
+ if (sound_names != NULL) {
+ char *filename;
+ int type;
+
+ type = get_file_type (sound_names[0], &filename);
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ SETTING_COL, type,
+ HAS_PREVIEW_COL, type != SOUND_OFF,
+ FILENAME_COL, filename,
+ -1);
+ g_strfreev (sound_names);
+ g_free (filename);
+ }
+ return FALSE;
+}
+
+static void
+update_theme (GvcSoundThemeEditor *editor)
+{
+ char *theme_name;
+ gboolean events_enabled;
+ gboolean bell_enabled;
+ MateConfClient *client;
+ gboolean feedback_enabled;
+
+ client = editor->priv->client;
+
+ bell_enabled = mateconf_client_get_bool (client, AUDIO_BELL_KEY, NULL);
+ set_audible_bell_enabled (editor, bell_enabled);
+
+ feedback_enabled = mateconf_client_get_bool (client, INPUT_SOUNDS_KEY, NULL);
+ set_input_feedback_enabled (editor, feedback_enabled);
+
+ events_enabled = mateconf_client_get_bool (client, EVENT_SOUNDS_KEY, NULL);
+ if (events_enabled) {
+ theme_name = mateconf_client_get_string (client, SOUND_THEME_KEY, NULL);
+ } else {
+ theme_name = g_strdup (NO_SOUNDS_THEME_NAME);
+ }
+
+ gtk_widget_set_sensitive (editor->priv->selection_box, events_enabled);
+
+ set_theme_name (editor, theme_name);
+
+ /* Setup the default values if we're using the custom theme */
+ if (theme_name != NULL && strcmp (theme_name, CUSTOM_THEME_NAME) == 0) {
+ GtkTreeModel *model;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ gtk_tree_model_foreach (model,
+ theme_changed_custom_init,
+ NULL);
+ }
+ g_free (theme_name);
+}
+
+static void
+setup_theme_selector (GvcSoundThemeEditor *editor)
+{
+ GHashTable *hash;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ const char * const *data_dirs;
+ const char *data_dir;
+ char *dir;
+ guint i;
+
+ /* Add the theme names and their display name to a hash table,
+ * makes it easy to avoid duplicate themes */
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ data_dirs = g_get_system_data_dirs ();
+ for (i = 0; data_dirs[i] != NULL; i++) {
+ dir = g_build_filename (data_dirs[i], "sounds", NULL);
+ sound_theme_in_dir (hash, dir);
+ g_free (dir);
+ }
+
+ data_dir = g_get_user_data_dir ();
+ dir = g_build_filename (data_dir, "sounds", NULL);
+ sound_theme_in_dir (hash, dir);
+ g_free (dir);
+
+ /* If there isn't at least one theme, make everything
+ * insensitive, LAME! */
+ if (g_hash_table_size (hash) == 0) {
+ gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
+ g_warning ("Bad setup, install the freedesktop sound theme");
+ g_hash_table_destroy (hash);
+ return;
+ }
+
+ /* Setup the tree model, 3 columns:
+ * - internal theme name/directory
+ * - display theme name
+ * - the internal id for the parent theme, used for the custom theme */
+ store = gtk_list_store_new (THEME_NUM_COLS,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ /* Add the themes to a combobox */
+ gtk_list_store_insert_with_values (store,
+ NULL,
+ G_MAXINT,
+ THEME_DISPLAY_COL, _("No sounds"),
+ THEME_IDENTIFIER_COL, "__no_sounds",
+ THEME_PARENT_ID_COL, NULL,
+ -1);
+ g_hash_table_foreach (hash, (GHFunc) add_theme_to_store, store);
+ g_hash_table_destroy (hash);
+
+ /* Set the display */
+ gtk_combo_box_set_model (GTK_COMBO_BOX (editor->priv->combo_box),
+ GTK_TREE_MODEL (store));
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (editor->priv->combo_box),
+ renderer,
+ TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (editor->priv->combo_box),
+ renderer,
+ "text", THEME_DISPLAY_COL,
+ NULL);
+
+ g_signal_connect (editor->priv->combo_box,
+ "changed",
+ G_CALLBACK (on_combobox_changed),
+ editor);
+}
+
+static void
+play_sound_preview (GtkFileEditor *editor,
+ gpointer user_data)
+{
+ char *filename;
+
+ filename = gtk_file_editor_get_preview_filename (GTK_FILE_EDITOR (editor));
+ if (filename == NULL) {
+ return;
+ }
+
+ ca_gtk_play_for_widget (GTK_WIDGET (editor), 0,
+ CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+ CA_PROP_MEDIA_FILENAME, filename,
+ CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+ CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+ CA_PROP_APPLICATION_ID, "org.mate.VolumeControl",
+#ifdef CA_PROP_CANBERRA_ENABLE
+ CA_PROP_CANBERRA_ENABLE, "1",
+#endif
+ NULL);
+ g_free (filename);
+}
+
+static char *
+get_sound_filename (GvcSoundThemeEditor *editor)
+{
+ GtkWidget *file_editor;
+ GtkWidget *toplevel;
+ GtkWindow *parent;
+ int response;
+ char *filename;
+ char *path;
+ const char * const *data_dirs, *data_dir;
+ GtkFileFilter *filter;
+ guint i;
+
+ /* Try to get the parent window of the widget */
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (editor));
+ if (gtk_widget_is_toplevel (toplevel) != FALSE)
+ parent = GTK_WINDOW (toplevel);
+ else
+ parent = NULL;
+
+ file_editor = gtk_file_editor_dialog_new (_("Select Sound File"),
+ parent,
+ GTK_FILE_EDITOR_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_file_editor_set_local_only (GTK_FILE_EDITOR (file_editor), TRUE);
+ gtk_file_editor_set_select_multiple (GTK_FILE_EDITOR (file_editor), FALSE);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("Sound files"));
+ gtk_file_filter_add_mime_type (filter, "audio/x-vorbis+ogg");
+ gtk_file_filter_add_mime_type (filter, "audio/x-wav");
+ gtk_file_editor_add_filter (GTK_FILE_EDITOR (file_editor), filter);
+ gtk_file_editor_set_filter (GTK_FILE_EDITOR (file_editor), filter);
+
+ g_signal_connect (file_editor, "update-preview",
+ G_CALLBACK (play_sound_preview), NULL);
+
+ data_dirs = g_get_system_data_dirs ();
+ for (i = 0; data_dirs[i] != NULL; i++) {
+ path = g_build_filename (data_dirs[i], "sounds", NULL);
+ gtk_file_editor_add_shortcut_folder (GTK_FILE_EDITOR (file_editor), path, NULL);
+ g_free (path);
+ }
+ data_dir = g_get_user_special_dir (G_USER_DIRECTORY_MUSIC);
+ if (data_dir != NULL)
+ gtk_file_editor_add_shortcut_folder (GTK_FILE_EDITOR (file_editor), data_dir, NULL);
+
+ gtk_file_editor_set_current_folder (GTK_FILE_EDITOR (file_editor), SOUND_DATA_DIR);
+
+ response = gtk_dialog_run (GTK_DIALOG (file_editor));
+ filename = NULL;
+ if (response == GTK_RESPONSE_ACCEPT)
+ filename = gtk_file_editor_get_filename (GTK_FILE_EDITOR (file_editor));
+
+ gtk_widget_destroy (file_editor);
+
+ return filename;
+}
+
+
+static gboolean
+count_customised_sounds (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ int *num_custom)
+{
+ int type;
+ int setting;
+
+ gtk_tree_model_get (model, iter, TYPE_COL, &type, SETTING_COL, &setting, -1);
+ if (setting == SOUND_OFF || setting == SOUND_CUSTOM || setting == SOUND_CUSTOM_OLD) {
+ (*num_custom)++;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+save_sounds (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int type;
+ int setting;
+ char *filename;
+ char **sounds;
+
+ gtk_tree_model_get (model, iter,
+ TYPE_COL, &type,
+ SETTING_COL, &setting,
+ FILENAME_COL, &filename,
+ SOUND_NAMES_COL, &sounds,
+ -1);
+
+ if (setting == SOUND_BUILTIN) {
+ delete_old_files (sounds);
+ delete_disabled_files (sounds);
+ } else if (setting == SOUND_OFF) {
+ delete_old_files (sounds);
+ add_disabled_file (sounds);
+ } else if (setting == SOUND_CUSTOM || setting == SOUND_CUSTOM_OLD) {
+ delete_old_files (sounds);
+ delete_disabled_files (sounds);
+ add_custom_file (sounds, filename);
+ }
+ g_free (filename);
+ g_strfreev (sounds);
+
+ return FALSE;
+}
+
+static void
+save_custom_theme (GtkTreeModel *model,
+ const char *parent)
+{
+ GKeyFile *keyfile;
+ char *data;
+ char *path;
+
+ /* Create the custom directory */
+ path = custom_theme_dir_path (NULL);
+ g_mkdir_with_parents (path, 0755);
+ g_free (path);
+
+ /* Save the sounds themselves */
+ gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) save_sounds, NULL);
+
+ /* Set the data for index.theme */
+ keyfile = g_key_file_new ();
+ g_key_file_set_string (keyfile, "Sound Theme", "Name", _("Custom"));
+ g_key_file_set_string (keyfile, "Sound Theme", "Inherits", parent);
+ g_key_file_set_string (keyfile, "Sound Theme", "Directories", ".");
+ data = g_key_file_to_data (keyfile, NULL, NULL);
+ g_key_file_free (keyfile);
+
+ /* Save the index.theme */
+ path = custom_theme_dir_path ("index.theme");
+ g_file_set_contents (path, data, -1, NULL);
+ g_free (path);
+ g_free (data);
+
+ custom_theme_update_time ();
+}
+
+static void
+dump_theme (GvcSoundThemeEditor *editor)
+{
+ int num_custom;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ char *parent;
+
+ num_custom = 0;
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) count_customised_sounds, &num_custom);
+
+ g_debug ("%d customised sounds", num_custom);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (editor->priv->combo_box));
+ /* Get the current theme's name, and set the parent */
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (editor->priv->combo_box), &iter) == FALSE)
+ return;
+
+ if (num_custom == 0) {
+ gtk_tree_model_get (model, &iter, THEME_PARENT_ID_COL, &parent, -1);
+ if (parent != NULL) {
+ set_theme_name (editor, parent);
+ g_free (parent);
+ }
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ gtk_tree_model_get (model, &iter, THEME_PARENT_ID_COL, &parent, -1);
+ if (parent != NULL && strcmp (parent, CUSTOM_THEME_NAME) != 0) {
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ delete_custom_theme_dir ();
+ } else {
+ gtk_tree_model_get (model, &iter, THEME_IDENTIFIER_COL, &parent, -1);
+ if (strcmp (parent, CUSTOM_THEME_NAME) != 0) {
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (model), NULL, G_MAXINT,
+ THEME_DISPLAY_COL, _("Custom"),
+ THEME_IDENTIFIER_COL, CUSTOM_THEME_NAME,
+ THEME_PARENT_ID_COL, parent,
+ -1);
+ } else {
+ g_free (parent);
+ gtk_tree_model_get (model, &iter, THEME_PARENT_ID_COL, &parent, -1);
+ }
+
+ g_debug ("The parent theme is: %s", parent);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ save_custom_theme (model, parent);
+ g_free (parent);
+
+ set_theme_name (editor, CUSTOM_THEME_NAME);
+ }
+}
+
+static void
+on_setting_column_edited (GtkCellRendererText *renderer,
+ char *path,
+ char *new_text,
+ GvcSoundThemeEditor *editor)
+{
+ GtkTreeModel *model;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ GtkTreeIter tree_iter;
+ SoundType type;
+ char *text;
+ char *old_filename;
+ int setting;
+
+ if (new_text == NULL) {
+ return;
+ }
+
+ g_object_get (renderer,
+ "model", &model,
+ NULL);
+
+ tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ if (gtk_tree_model_get_iter_from_string (tree_model, &tree_iter, path) == FALSE)
+ return;
+
+ gtk_tree_model_get (tree_model, &tree_iter,
+ TYPE_COL, &type,
+ FILENAME_COL, &old_filename,
+ -1);
+
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ int cmp;
+
+ gtk_tree_model_get (model, &iter,
+ 0, &text,
+ 1, &setting,
+ -1);
+ cmp = g_utf8_collate (text, new_text);
+ g_free (text);
+
+ if (cmp != 0) {
+ continue;
+ }
+
+ if (type == SOUND_TYPE_NORMAL
+ || type == SOUND_TYPE_FEEDBACK
+ || type == SOUND_TYPE_AUDIO_BELL) {
+
+ if (setting == SOUND_CUSTOM
+ || (setting == SOUND_CUSTOM_OLD
+ && old_filename == NULL)) {
+
+ char *filename = get_sound_filename (editor);
+
+ if (filename == NULL) {
+ break;
+ }
+ gtk_tree_store_set (GTK_TREE_STORE (tree_model),
+ &tree_iter,
+ SETTING_COL, setting,
+ HAS_PREVIEW_COL, setting != SOUND_OFF,
+ FILENAME_COL, filename,
+ -1);
+ g_free (filename);
+ } else if (setting == SOUND_CUSTOM_OLD) {
+ gtk_tree_store_set (GTK_TREE_STORE (tree_model),
+ &tree_iter,
+ SETTING_COL, setting,
+ HAS_PREVIEW_COL, setting != SOUND_OFF,
+ FILENAME_COL, old_filename,
+ -1);
+ } else {
+ gtk_tree_store_set (GTK_TREE_STORE (tree_model),
+ &tree_iter,
+ SETTING_COL, setting,
+ HAS_PREVIEW_COL, setting != SOUND_OFF,
+ -1);
+ }
+
+ g_debug ("Something changed, dump theme");
+ dump_theme (editor);
+
+ break;
+ }
+
+ g_assert_not_reached ();
+
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ g_free (old_filename);
+}
+
+static void
+fill_custom_model (GtkListStore *store,
+ const char *prev_filename)
+{
+ GtkTreeIter iter;
+
+ gtk_list_store_clear (store);
+
+ if (prev_filename != NULL) {
+ char *display;
+ display = g_filename_display_basename (prev_filename);
+ gtk_list_store_insert_with_values (store, &iter, G_MAXINT,
+ 0, display,
+ 1, SOUND_CUSTOM_OLD,
+ -1);
+ g_free (display);
+ }
+
+ gtk_list_store_insert_with_values (store, &iter, G_MAXINT,
+ 0, _("Default"),
+ 1, SOUND_BUILTIN,
+ -1);
+ gtk_list_store_insert_with_values (store, &iter, G_MAXINT,
+ 0, _("Disabled"),
+ 1, SOUND_OFF,
+ -1);
+ gtk_list_store_insert_with_values (store, &iter, G_MAXINT,
+ 0, _("Custom…"),
+ 1, SOUND_CUSTOM, -1);
+}
+
+static void
+on_combobox_editing_started (GtkCellRenderer *renderer,
+ GtkCellEditable *editable,
+ gchar *path,
+ GvcSoundThemeEditor *editor)
+{
+ GtkTreeModel *model;
+ GtkTreeModel *store;
+ GtkTreeIter iter;
+ SoundType type;
+ char *filename;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (editor->priv->treeview));
+ if (gtk_tree_model_get_iter_from_string (model, &iter, path) == FALSE) {
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, TYPE_COL, &type, FILENAME_COL, &filename, -1);
+ g_object_get (renderer, "model", &store, NULL);
+ fill_custom_model (GTK_LIST_STORE (store), filename);
+ g_free (filename);
+}
+
+static gboolean
+play_sound_at_path (GtkWidget *tree_view,
+ GtkTreePath *path)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ char **sound_names;
+ gboolean sensitive;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
+ if (gtk_tree_model_get_iter (model, &iter, path) == FALSE) {
+ return FALSE;
+ }
+
+ gtk_tree_model_get (model, &iter,
+ SOUND_NAMES_COL, &sound_names,
+ SENSITIVE_COL, &sensitive,
+ -1);
+ if (!sensitive || sound_names == NULL) {
+ return FALSE;
+ }
+
+ ca_gtk_play_for_widget (GTK_WIDGET (tree_view), 0,
+ CA_PROP_APPLICATION_NAME, _("Sound Preferences"),
+ CA_PROP_EVENT_ID, sound_names[0],
+ CA_PROP_EVENT_DESCRIPTION, _("Testing event sound"),
+ CA_PROP_CANBERRA_CACHE_CONTROL, "never",
+ CA_PROP_APPLICATION_ID, "org.mate.VolumeControl",
+#ifdef CA_PROP_CANBERRA_ENABLE
+ CA_PROP_CANBERRA_ENABLE, "1",
+#endif
+ NULL);
+
+ g_strfreev (sound_names);
+
+ return TRUE;
+}
+
+static void
+setting_set_func (GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ int setting;
+ char *filename;
+ SoundType type;
+
+ gtk_tree_model_get (model, iter,
+ SETTING_COL, &setting,
+ FILENAME_COL, &filename,
+ TYPE_COL, &type,
+ -1);
+
+ if (setting == SOUND_UNSET) {
+ g_object_set (cell,
+ "visible", FALSE,
+ NULL);
+ g_free (filename);
+ return;
+ }
+
+ if (setting == SOUND_OFF) {
+ g_object_set (cell,
+ "text", _("Disabled"),
+ NULL);
+ } else if (setting == SOUND_BUILTIN) {
+ g_object_set (cell,
+ "text", _("Default"),
+ NULL);
+ } else if (setting == SOUND_CUSTOM || setting == SOUND_CUSTOM_OLD) {
+ char *display;
+
+ display = g_filename_display_basename (filename);
+ g_object_set (cell,
+ "text", display,
+ NULL);
+ g_free (display);
+ }
+
+ g_free (filename);
+}
+
+typedef GtkCellRendererPixbuf ActivatableCellRendererPixbuf;
+typedef GtkCellRendererPixbufClass ActivatableCellRendererPixbufClass;
+
+GType activatable_cell_renderer_pixbuf_get_type (void);
+#define ACTIVATABLE_TYPE_CELL_RENDERER_PIXBUF (activatable_cell_renderer_pixbuf_get_type ())
+G_DEFINE_TYPE (ActivatableCellRendererPixbuf, activatable_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER_PIXBUF);
+
+static gboolean
+activatable_cell_renderer_pixbuf_activate (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path_string,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags)
+{
+ GtkTreePath *path;
+ gboolean res;
+
+ g_debug ("Activating pixbuf");
+
+ path = gtk_tree_path_new_from_string (path_string);
+ res = play_sound_at_path (widget, path);
+ gtk_tree_path_free (path);
+
+ return res;
+}
+
+static void
+activatable_cell_renderer_pixbuf_init (ActivatableCellRendererPixbuf *cell)
+{
+}
+
+static void
+activatable_cell_renderer_pixbuf_class_init (ActivatableCellRendererPixbufClass *class)
+{
+ GtkCellRendererClass *cell_class;
+
+ cell_class = GTK_CELL_RENDERER_CLASS (class);
+
+ cell_class->activate = activatable_cell_renderer_pixbuf_activate;
+}
+
+static void
+setup_theme_custom_selector (GvcSoundThemeEditor *editor,
+ gboolean have_xkb )
+{
+ GtkTreeStore *store;
+ GtkTreeModel *custom_model;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeIter iter;
+ GtkTreeIter parent;
+ CategoryType type;
+ guint i;
+
+ /* Set up the model for the custom view */
+ store = gtk_tree_store_new (NUM_COLS,
+ G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_STRV);
+
+ /* The first column with the categories/sound names */
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Display", renderer,
+ "text", DISPLAY_COL,
+ "sensitive", SENSITIVE_COL,
+ "ellipsize", PANGO_ELLIPSIZE_START,
+ "ellipsize-set", TRUE,
+ NULL);
+ g_object_set (G_OBJECT (column), "expand", TRUE, NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (editor->priv->treeview), column);
+
+ /* The 2nd column with the sound settings */
+ renderer = gtk_cell_renderer_combo_new ();
+ g_signal_connect (renderer,
+ "edited",
+ G_CALLBACK (on_setting_column_edited),
+ editor);
+ g_signal_connect (renderer,
+ "editing-started",
+ G_CALLBACK (on_combobox_editing_started),
+ editor);
+ custom_model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT));
+ fill_custom_model (GTK_LIST_STORE (custom_model), NULL);
+
+ g_object_set (renderer,
+ "model", custom_model,
+ "has-entry", FALSE,
+ "editable", TRUE,
+ "text-column", 0,
+ NULL);
+ column = gtk_tree_view_column_new_with_attributes ("Setting", renderer,
+ "editable", SENSITIVE_COL,
+ "sensitive", SENSITIVE_COL,
+ "visible", TRUE,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (editor->priv->treeview), column);
+ gtk_tree_view_column_set_cell_data_func (column, renderer, setting_set_func, NULL, NULL);
+
+ /* The 3rd column with the preview pixbuf */
+ renderer = g_object_new (ACTIVATABLE_TYPE_CELL_RENDERER_PIXBUF, NULL);
+ g_object_set (renderer,
+ "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
+ "icon-name", "media-playback-start",
+ "stock-size", GTK_ICON_SIZE_MENU,
+ NULL);
+ column = gtk_tree_view_column_new_with_attributes ("Preview", renderer,
+ "visible", HAS_PREVIEW_COL,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (editor->priv->treeview), column);
+ g_object_set_data (G_OBJECT (editor->priv->treeview), "preview-column", column);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (editor->priv->treeview), GTK_TREE_MODEL (store));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (editor->priv->treeview), FALSE);
+
+ /* Fill in the model */
+ type = CATEGORY_INVALID;
+
+ for (i = 0; ; i++) {
+ GtkTreeIter *_parent;
+
+ if (sounds[i].category == -1) {
+ break;
+ }
+
+ /* Is it a new type of sound? */
+ if (sounds[i].category == type
+ && type != CATEGORY_INVALID
+ && type != CATEGORY_BELL) {
+ _parent = &parent;
+ } else {
+ _parent = NULL;
+ }
+
+ if (sounds[i].type != -1) {
+ gtk_tree_store_insert_with_values (store, &iter, _parent, G_MAXINT,
+ DISPLAY_COL, g_dpgettext2 (NULL, "Sound event", sounds[i].display_name),
+ SETTING_COL, SOUND_BUILTIN,
+ TYPE_COL, sounds[i].type,
+ SOUND_NAMES_COL, sounds[i].names,
+ HAS_PREVIEW_COL, TRUE,
+ SENSITIVE_COL, TRUE,
+ -1);
+ } else {
+ /* Category */
+ gtk_tree_store_insert_with_values (store, &iter, _parent, G_MAXINT,
+ DISPLAY_COL, g_dpgettext2 (NULL, "Sound event", sounds[i].display_name),
+ SETTING_COL, SOUND_UNSET,
+ TYPE_COL, sounds[i].type,
+ SENSITIVE_COL, TRUE,
+ HAS_PREVIEW_COL, FALSE,
+ -1);
+ }
+
+ /* If we didn't set a parent already, set one in case we need it later */
+ if (_parent == NULL) {
+ parent = iter;
+ }
+ type = sounds[i].category;
+ }
+
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (editor->priv->treeview));
+}
+
+static GObject *
+gvc_sound_theme_editor_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ GvcSoundThemeEditor *self;
+
+ object = G_OBJECT_CLASS (gvc_sound_theme_editor_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+ self = GVC_SOUND_THEME_EDITOR (object);
+
+ setup_theme_selector (self);
+ setup_theme_custom_selector (self, TRUE);
+
+ update_theme (self);
+
+ return object;
+}
+
+static void
+gvc_sound_theme_editor_class_init (GvcSoundThemeEditorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = gvc_sound_theme_editor_constructor;
+ object_class->finalize = gvc_sound_theme_editor_finalize;
+
+ g_type_class_add_private (klass, sizeof (GvcSoundThemeEditorPrivate));
+}
+
+static void
+on_click_feedback_toggled (GtkToggleButton *button,
+ GvcSoundThemeEditor *editor)
+{
+ MateConfClient *client;
+ gboolean enabled;
+
+ enabled = gtk_toggle_button_get_active (button);
+
+ client = mateconf_client_get_default ();
+ mateconf_client_set_bool (client, INPUT_SOUNDS_KEY, enabled, NULL);
+ g_object_unref (client);
+}
+
+static void
+on_key_changed (MateConfClient *client,
+ guint cnxn_id,
+ MateConfEntry *entry,
+ GvcSoundThemeEditor *editor)
+{
+ const char *key;
+ MateConfValue *value;
+
+ key = mateconf_entry_get_key (entry);
+
+ if (! g_str_has_prefix (key, KEY_SOUNDS_DIR)
+ && ! g_str_has_prefix (key, KEY_MARCO_DIR)) {
+ return;
+ }
+
+ value = mateconf_entry_get_value (entry);
+ if (strcmp (key, EVENT_SOUNDS_KEY) == 0) {
+ update_theme (editor);
+ } else if (strcmp (key, SOUND_THEME_KEY) == 0) {
+ update_theme (editor);
+ } else if (strcmp (key, INPUT_SOUNDS_KEY) == 0) {
+ update_theme (editor);
+ } else if (strcmp (key, AUDIO_BELL_KEY) == 0) {
+ update_theme (editor);
+ }
+}
+
+static void
+on_treeview_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ GvcSoundThemeEditor *editor)
+{
+ g_debug ("row activated");
+ play_sound_at_path (GTK_WIDGET (treeview), path);
+}
+
+static void
+constrain_list_size (GtkWidget *widget,
+ GtkRequisition *requisition,
+ GtkWidget *to_size)
+{
+ GtkRequisition req;
+ int max_height;
+
+ /* constrain height to be the tree height up to a max */
+ max_height = (gdk_screen_get_height (gtk_widget_get_screen (widget))) / 4;
+
+ gtk_widget_size_request (to_size, &req);
+
+ requisition->height = MIN (req.height, max_height);
+}
+
+static void
+setup_list_size_constraint (GtkWidget *widget,
+ GtkWidget *to_size)
+{
+ g_signal_connect (widget,
+ "size-request",
+ G_CALLBACK (constrain_list_size),
+ to_size);
+}
+
+static void
+gvc_sound_theme_editor_init (GvcSoundThemeEditor *editor)
+{
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *scrolled_window;
+
+ editor->priv = GVC_SOUND_THEME_EDITOR_GET_PRIVATE (editor);
+
+ editor->priv->theme_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (editor),
+ editor->priv->theme_box, FALSE, FALSE, 0);
+
+ label = gtk_label_new (_("Sound Theme:"));
+ gtk_box_pack_start (GTK_BOX (editor->priv->theme_box), label, FALSE, FALSE, 6);
+ editor->priv->combo_box = gtk_combo_box_new ();
+ gtk_box_pack_start (GTK_BOX (editor->priv->theme_box), editor->priv->combo_box, FALSE, FALSE, 0);
+
+
+ editor->priv->client = mateconf_client_get_default ();
+
+ editor->priv->selection_box = box = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (editor), box, TRUE, TRUE, 0);
+
+ editor->priv->treeview = gtk_tree_view_new ();
+ g_signal_connect (editor->priv->treeview,
+ "row-activated",
+ G_CALLBACK (on_treeview_row_activated),
+ editor);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ setup_list_size_constraint (scrolled_window, editor->priv->treeview);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), editor->priv->treeview);
+ gtk_container_add (GTK_CONTAINER (box), scrolled_window);
+
+ editor->priv->click_feedback_button = gtk_check_button_new_with_mnemonic (_("Enable window and button sounds"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->priv->click_feedback_button),
+ mateconf_client_get_bool (editor->priv->client, INPUT_SOUNDS_KEY, NULL));
+ gtk_box_pack_start (GTK_BOX (box),
+ editor->priv->click_feedback_button,
+ FALSE, FALSE, 0);
+ g_signal_connect (editor->priv->click_feedback_button,
+ "toggled",
+ G_CALLBACK (on_click_feedback_toggled),
+ editor);
+
+
+ mateconf_client_add_dir (editor->priv->client, KEY_SOUNDS_DIR,
+ MATECONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+ editor->priv->sounds_dir_id = mateconf_client_notify_add (editor->priv->client,
+ KEY_SOUNDS_DIR,
+ (MateConfClientNotifyFunc)on_key_changed,
+ editor, NULL, NULL);
+ mateconf_client_add_dir (editor->priv->client, KEY_MARCO_DIR,
+ MATECONF_CLIENT_PRELOAD_ONELEVEL,
+ NULL);
+ editor->priv->marco_dir_id = mateconf_client_notify_add (editor->priv->client,
+ KEY_MARCO_DIR,
+ (MateConfClientNotifyFunc)on_key_changed,
+ editor, NULL, NULL);
+
+ /* FIXME: should accept drag and drop themes. should also
+ add an "Add Theme..." item to the theme combobox */
+}
+
+static void
+gvc_sound_theme_editor_finalize (GObject *object)
+{
+ GvcSoundThemeEditor *sound_theme_editor;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GVC_IS_SOUND_THEME_EDITOR (object));
+
+ sound_theme_editor = GVC_SOUND_THEME_EDITOR (object);
+
+ if (sound_theme_editor->priv != NULL) {
+ if (sound_theme_editor->priv->sounds_dir_id > 0) {
+ mateconf_client_notify_remove (sound_theme_editor->priv->client,
+ sound_theme_editor->priv->sounds_dir_id);
+ sound_theme_editor->priv->sounds_dir_id = 0;
+ }
+ if (sound_theme_editor->priv->marco_dir_id > 0) {
+ mateconf_client_notify_remove (sound_theme_editor->priv->client,
+ sound_theme_editor->priv->marco_dir_id);
+ sound_theme_editor->priv->marco_dir_id = 0;
+ }
+ g_object_unref (sound_theme_editor->priv->client);
+ sound_theme_editor->priv->client = NULL;
+ }
+
+ G_OBJECT_CLASS (gvc_sound_theme_editor_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gvc_sound_theme_editor_new (void)
+{
+ GObject *editor;
+ editor = g_object_new (GVC_TYPE_SOUND_THEME_EDITOR,
+ "spacing", 6,
+ NULL);
+ return GTK_WIDGET (editor);
+}
diff --git a/sound-theme/gvc-sound-theme-editor.h b/sound-theme/gvc-sound-theme-editor.h
new file mode 100644
index 0000000..5e4330d
--- /dev/null
+++ b/sound-theme/gvc-sound-theme-editor.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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 __GVC_SOUND_THEME_EDITOR_H
+#define __GVC_SOUND_THEME_EDITOR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GVC_TYPE_SOUND_THEME_EDITOR (gvc_sound_theme_editor_get_type ())
+#define GVC_SOUND_THEME_EDITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_SOUND_THEME_EDITOR, GvcSoundThemeEditor))
+#define GVC_SOUND_THEME_EDITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_SOUND_THEME_EDITOR, GvcSoundThemeEditorClass))
+#define GVC_IS_SOUND_THEME_EDITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_SOUND_THEME_EDITOR))
+#define GVC_IS_SOUND_THEME_EDITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_SOUND_THEME_EDITOR))
+#define GVC_SOUND_THEME_EDITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_SOUND_THEME_EDITOR, GvcSoundThemeEditorClass))
+
+typedef struct GvcSoundThemeEditorPrivate GvcSoundThemeEditorPrivate;
+
+typedef struct
+{
+ GtkVBox parent;
+ GvcSoundThemeEditorPrivate *priv;
+} GvcSoundThemeEditor;
+
+typedef struct
+{
+ GtkVBoxClass parent_class;
+} GvcSoundThemeEditorClass;
+
+GType gvc_sound_theme_editor_get_type (void);
+
+GtkWidget * gvc_sound_theme_editor_new (void);
+
+G_END_DECLS
+
+#endif /* __GVC_SOUND_THEME_EDITOR_H */
diff --git a/sound-theme/sound-theme-file-utils.c b/sound-theme/sound-theme-file-utils.c
new file mode 100644
index 0000000..962b617
--- /dev/null
+++ b/sound-theme/sound-theme-file-utils.c
@@ -0,0 +1,305 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ * Copyright (C) 2008 Bastien Nocera <[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, 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.
+ */
+
+#include <config.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <utime.h>
+#include <strings.h>
+
+#include "sound-theme-file-utils.h"
+
+#define CUSTOM_THEME_NAME "__custom"
+
+/* This function needs to be called after each individual
+ * changeset to the theme */
+void
+custom_theme_update_time (void)
+{
+ char *path;
+
+ path = custom_theme_dir_path (NULL);
+ utime (path, NULL);
+ g_free (path);
+}
+
+char *
+custom_theme_dir_path (const char *child)
+{
+ static char *dir = NULL;
+ const char *data_dir;
+
+ if (dir == NULL) {
+ data_dir = g_get_user_data_dir ();
+ dir = g_build_filename (data_dir, "sounds", CUSTOM_THEME_NAME, NULL);
+ }
+ if (child == NULL)
+ return g_strdup (dir);
+
+ return g_build_filename (dir, child, NULL);
+}
+
+static gboolean
+directory_delete_recursive (GFile *directory, GError **error)
+{
+ GFileEnumerator *enumerator;
+ GFileInfo *info;
+ gboolean success = TRUE;
+
+ enumerator = g_file_enumerate_children (directory,
+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, error);
+ if (enumerator == NULL)
+ return FALSE;
+
+ while (success &&
+ (info = g_file_enumerator_next_file (enumerator, NULL, NULL))) {
+ GFile *child;
+
+ child = g_file_get_child (directory, g_file_info_get_name (info));
+
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) {
+ success = directory_delete_recursive (child, error);
+ }
+ g_object_unref (info);
+
+ if (success)
+ success = g_file_delete (child, NULL, error);
+ }
+ g_file_enumerator_close (enumerator, NULL, NULL);
+
+ if (success)
+ success = g_file_delete (directory, NULL, error);
+
+ return success;
+}
+
+/**
+ * capplet_file_delete_recursive :
+ * @file :
+ * @error :
+ *
+ * A utility routine to delete files and/or directories,
+ * including non-empty directories.
+ **/
+static gboolean
+capplet_file_delete_recursive (GFile *file, GError **error)
+{
+ GFileInfo *info;
+ GFileType type;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, error);
+ if (info == NULL)
+ return FALSE;
+
+ type = g_file_info_get_file_type (info);
+ g_object_unref (info);
+
+ if (type == G_FILE_TYPE_DIRECTORY)
+ return directory_delete_recursive (file, error);
+ else
+ return g_file_delete (file, NULL, error);
+}
+
+void
+delete_custom_theme_dir (void)
+{
+ char *dir;
+ GFile *file;
+
+ dir = custom_theme_dir_path (NULL);
+ file = g_file_new_for_path (dir);
+ g_free (dir);
+ capplet_file_delete_recursive (file, NULL);
+ g_object_unref (file);
+
+ g_debug ("deleted the custom theme dir");
+}
+
+gboolean
+custom_theme_dir_is_empty (void)
+{
+ char *dir;
+ GFile *file;
+ gboolean is_empty;
+ GFileEnumerator *enumerator;
+ GFileInfo *info;
+ GError *error = NULL;
+
+ dir = custom_theme_dir_path (NULL);
+ file = g_file_new_for_path (dir);
+ g_free (dir);
+
+ is_empty = TRUE;
+
+ enumerator = g_file_enumerate_children (file,
+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+ if (enumerator == NULL) {
+ g_warning ("Unable to enumerate files: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ while (is_empty &&
+ (info = g_file_enumerator_next_file (enumerator, NULL, NULL))) {
+
+ if (strcmp ("index.theme", g_file_info_get_name (info)) != 0) {
+ is_empty = FALSE;
+ }
+
+ g_object_unref (info);
+ }
+ g_file_enumerator_close (enumerator, NULL, NULL);
+
+ out:
+ g_object_unref (file);
+
+ return is_empty;
+}
+
+static void
+delete_one_file (const char *sound_name, const char *pattern)
+{
+ GFile *file;
+ char *name, *filename;
+
+ name = g_strdup_printf (pattern, sound_name);
+ filename = custom_theme_dir_path (name);
+ g_free (name);
+ file = g_file_new_for_path (filename);
+ g_free (filename);
+ capplet_file_delete_recursive (file, NULL);
+ g_object_unref (file);
+}
+
+void
+delete_old_files (const char **sounds)
+{
+ guint i;
+
+ for (i = 0; sounds[i] != NULL; i++) {
+ delete_one_file (sounds[i], "%s.ogg");
+ }
+}
+
+void
+delete_disabled_files (const char **sounds)
+{
+ guint i;
+
+ for (i = 0; sounds[i] != NULL; i++)
+ delete_one_file (sounds[i], "%s.disabled");
+}
+
+static void
+create_one_file (GFile *file)
+{
+ GFileOutputStream* stream;
+
+ stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, NULL);
+ if (stream != NULL) {
+ g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
+ g_object_unref (stream);
+ }
+}
+
+void
+add_disabled_file (const char **sounds)
+{
+ guint i;
+
+ for (i = 0; sounds[i] != NULL; i++) {
+ GFile *file;
+ char *name, *filename;
+
+ name = g_strdup_printf ("%s.disabled", sounds[i]);
+ filename = custom_theme_dir_path (name);
+ g_free (name);
+ file = g_file_new_for_path (filename);
+ g_free (filename);
+
+ create_one_file (file);
+ g_object_unref (file);
+ }
+}
+
+void
+add_custom_file (const char **sounds, const char *filename)
+{
+ guint i;
+
+ for (i = 0; sounds[i] != NULL; i++) {
+ GFile *file;
+ char *name, *path;
+
+ /* We use *.ogg because it's the first type of file that
+ * libcanberra looks at */
+ name = g_strdup_printf ("%s.ogg", sounds[i]);
+ path = custom_theme_dir_path (name);
+ g_free (name);
+ /* In case there's already a link there, delete it */
+ g_unlink (path);
+ file = g_file_new_for_path (path);
+ g_free (path);
+
+ /* Create the link */
+ g_file_make_symbolic_link (file, filename, NULL, NULL);
+ g_object_unref (file);
+ }
+}
+
+void
+create_custom_theme (const char *parent)
+{
+ GKeyFile *keyfile;
+ char *data;
+ char *path;
+
+ /* Create the custom directory */
+ path = custom_theme_dir_path (NULL);
+ g_mkdir_with_parents (path, 0755);
+ g_free (path);
+
+ /* Set the data for index.theme */
+ keyfile = g_key_file_new ();
+ g_key_file_set_string (keyfile, "Sound Theme", "Name", _("Custom"));
+ g_key_file_set_string (keyfile, "Sound Theme", "Inherits", parent);
+ g_key_file_set_string (keyfile, "Sound Theme", "Directories", ".");
+ data = g_key_file_to_data (keyfile, NULL, NULL);
+ g_key_file_free (keyfile);
+
+ /* Save the index.theme */
+ path = custom_theme_dir_path ("index.theme");
+ g_file_set_contents (path, data, -1, NULL);
+ g_free (path);
+ g_free (data);
+
+ custom_theme_update_time ();
+}
diff --git a/sound-theme/sound-theme-file-utils.h b/sound-theme/sound-theme-file-utils.h
new file mode 100644
index 0000000..7fc3a58
--- /dev/null
+++ b/sound-theme/sound-theme-file-utils.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ * Copyright (C) 2008 Bastien Nocera <[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, 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 __SOUND_THEME_FILE_UTILS_HH__
+#define __SOUND_THEME_FILE_UTILS_HH__
+
+#include <gio/gio.h>
+
+char *custom_theme_dir_path (const char *child);
+gboolean custom_theme_dir_is_empty (void);
+void create_custom_theme (const char *parent);
+
+void delete_custom_theme_dir (void);
+void delete_old_files (const char **sounds);
+void delete_disabled_files (const char **sounds);
+
+void add_disabled_file (const char **sounds);
+void add_custom_file (const char **sounds, const char *filename);
+
+void custom_theme_update_time (void);
+
+#endif /* __SOUND_THEME_FILE_UTILS_HH__ */
diff --git a/sound-theme/sounds/Makefile.am b/sound-theme/sounds/Makefile.am
new file mode 100644
index 0000000..0c31fe7
--- /dev/null
+++ b/sound-theme/sounds/Makefile.am
@@ -0,0 +1,29 @@
+NULL =
+
+sounddir = $(datadir)/sounds/mate/default/alerts
+
+sound_DATA = \
+ bark.ogg \
+ drip.ogg \
+ glass.ogg \
+ sonar.ogg \
+ $(NULL)
+
+metadata_in_files = mate-sounds-default.xml.in
+metadatadir = $(pkgdatadir)/sounds
+metadata_DATA = $(metadata_in_files:.xml.in=.xml)
+@INTLTOOL_XML_RULE@
+
+noinst_DATA = mate-sounds-default.xml.in
+CLEANFILES = mate-sounds-default.xml mate-sounds-default.xml.in
+
+EXTRA_DIST = $(sound_DATA) mate-sounds-default.xml.in.in
+
+mate-sounds-default.xml.in: mate-sounds-default.xml.in.in Makefile
+ $(AM_V_GEN)sed -e 's^\@datadir\@^$(datadir)^g' < $(srcdir)/mate-sounds-default.xml.in.in > mate-sounds-default.xml.in.tmp \
+ && mv mate-sounds-default.xml.in.tmp mate-sounds-default.xml.in
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+-include $(top_srcdir)/git.mk
diff --git a/sound-theme/sounds/Makefile.in b/sound-theme/sounds/Makefile.in
new file mode 100644
index 0000000..deb8bc3
--- /dev/null
+++ b/sound-theme/sounds/Makefile.in
@@ -0,0 +1,524 @@
+# 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@
+subdir = sound-theme/sounds
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \
+ $(top_srcdir)/m4/as-compiler-flag.m4 \
+ $(top_srcdir)/m4/as-version.m4 $(top_srcdir)/m4/intltool.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mate-doc-utils.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(metadatadir)" "$(DESTDIR)$(sounddir)"
+DATA = $(metadata_DATA) $(noinst_DATA) $(sound_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
+DLLTOOL = @DLLTOOL@
+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@
+GLADEUI_CATALOG_DIR = @GLADEUI_CATALOG_DIR@
+GLADEUI_CFLAGS = @GLADEUI_CFLAGS@
+GLADEUI_LIBS = @GLADEUI_LIBS@
+GLADEUI_MODULE_DIR = @GLADEUI_MODULE_DIR@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GMOFILES = @GMOFILES@
+GMP_CFLAGS = @GMP_CFLAGS@
+GMP_LIBS = @GMP_LIBS@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+GSR_CFLAGS = @GSR_CFLAGS@
+GSR_LIBS = @GSR_LIBS@
+GSTMIXER_CFLAGS = @GSTMIXER_CFLAGS@
+GSTMIXER_LIBS = @GSTMIXER_LIBS@
+GSTPROPS_CFLAGS = @GSTPROPS_CFLAGS@
+GSTPROPS_LIBS = @GSTPROPS_LIBS@
+GST_MAJORMINOR = @GST_MAJORMINOR@
+HAVE_PULSEAUDIO = @HAVE_PULSEAUDIO@
+HAVE_SOUND_THEME = @HAVE_SOUND_THEME@
+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@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MATECC_DESKTOP_DIR = @MATECC_DESKTOP_DIR@
+MATECONFTOOL = @MATECONFTOOL@
+MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@
+MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OMF_DIR = @OMF_DIR@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MICRO = @PACKAGE_VERSION_MICRO@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PROGRAMS_GSTPROPS = @PROGRAMS_GSTPROPS@
+PULSEAUDIO_CFLAGS = @PULSEAUDIO_CFLAGS@
+PULSEAUDIO_LIBS = @PULSEAUDIO_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOUNDTHEME_CFLAGS = @SOUNDTHEME_CFLAGS@
+SOUNDTHEME_LIBS = @SOUNDTHEME_LIBS@
+SOUND_THEME_CFLAGS = @SOUND_THEME_CFLAGS@
+SOUND_THEME_LIBS = @SOUND_THEME_LIBS@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+VOLUME_CONTROL_CFLAGS = @VOLUME_CONTROL_CFLAGS@
+VOLUME_CONTROL_LIBS = @VOLUME_CONTROL_LIBS@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_CXXFLAGS = @WARN_CXXFLAGS@
+XGETTEXT = @XGETTEXT@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_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@
+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@
+NULL =
+sounddir = $(datadir)/sounds/mate/default/alerts
+sound_DATA = \
+ bark.ogg \
+ drip.ogg \
+ glass.ogg \
+ sonar.ogg \
+ $(NULL)
+
+metadata_in_files = mate-sounds-default.xml.in
+metadatadir = $(pkgdatadir)/sounds
+metadata_DATA = $(metadata_in_files:.xml.in=.xml)
+noinst_DATA = mate-sounds-default.xml.in
+CLEANFILES = mate-sounds-default.xml mate-sounds-default.xml.in
+EXTRA_DIST = $(sound_DATA) mate-sounds-default.xml.in.in
+MAINTAINERCLEANFILES = \
+ Makefile.in
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign sound-theme/sounds/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign sound-theme/sounds/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):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-metadataDATA: $(metadata_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(metadatadir)" || $(MKDIR_P) "$(DESTDIR)$(metadatadir)"
+ @list='$(metadata_DATA)'; test -n "$(metadatadir)" || 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)$(metadatadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(metadatadir)" || exit $$?; \
+ done
+
+uninstall-metadataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(metadata_DATA)'; test -n "$(metadatadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(metadatadir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(metadatadir)" && rm -f $$files
+install-soundDATA: $(sound_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(sounddir)" || $(MKDIR_P) "$(DESTDIR)$(sounddir)"
+ @list='$(sound_DATA)'; test -n "$(sounddir)" || 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)$(sounddir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sounddir)" || exit $$?; \
+ done
+
+uninstall-soundDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sound_DATA)'; test -n "$(sounddir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sounddir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sounddir)" && rm -f $$files
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(metadatadir)" "$(DESTDIR)$(sounddir)"; 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:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-metadataDATA install-soundDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-metadataDATA uninstall-soundDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-metadataDATA \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-soundDATA install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am uninstall uninstall-am uninstall-metadataDATA \
+ uninstall-soundDATA
+
+@INTLTOOL_XML_RULE@
+
+mate-sounds-default.xml.in: mate-sounds-default.xml.in.in Makefile
+ $(AM_V_GEN)sed -e 's^\@datadir\@^$(datadir)^g' < $(srcdir)/mate-sounds-default.xml.in.in > mate-sounds-default.xml.in.tmp \
+ && mv mate-sounds-default.xml.in.tmp mate-sounds-default.xml.in
+
+-include $(top_srcdir)/git.mk
+
+# 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/sound-theme/sounds/bark.ogg b/sound-theme/sounds/bark.ogg
new file mode 100644
index 0000000..480950c
--- /dev/null
+++ b/sound-theme/sounds/bark.ogg
Binary files differ
diff --git a/sound-theme/sounds/drip.ogg b/sound-theme/sounds/drip.ogg
new file mode 100644
index 0000000..144d2b3
--- /dev/null
+++ b/sound-theme/sounds/drip.ogg
Binary files differ
diff --git a/sound-theme/sounds/glass.ogg b/sound-theme/sounds/glass.ogg
new file mode 100644
index 0000000..902a3c8
--- /dev/null
+++ b/sound-theme/sounds/glass.ogg
Binary files differ
diff --git a/sound-theme/sounds/mate-sounds-default.xml.in.in b/sound-theme/sounds/mate-sounds-default.xml.in.in
new file mode 100644
index 0000000..517c619
--- /dev/null
+++ b/sound-theme/sounds/mate-sounds-default.xml.in.in
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<sounds>
+ <sound deleted="false">
+ <!-- Translators: This is the name of an audio file that sounds like the bark of a dog.
+ You might want to translate it into the equivalent words of your language. -->
+ <_name>Bark</_name>
+ <filename>@datadir@/sounds/mate/default/alerts/bark.ogg</filename>
+ </sound>
+ <sound deleted="false">
+ <!-- Translators: This is the name of an audio file that sounds like a water drip.
+ You might want to translate it into the equivalent words of your language. -->
+ <_name>Drip</_name>
+ <filename>@datadir@/sounds/mate/default/alerts/drip.ogg</filename>
+ </sound>
+ <sound deleted="false">
+ <!-- Translators: This is the name of an audio file that sounds like tapping glass.
+ You might want to translate it into the equivalent words of your language. -->
+ <_name>Glass</_name>
+ <filename>@datadir@/sounds/mate/default/alerts/glass.ogg</filename>
+ </sound>
+ <sound deleted="false">
+ <!-- Translators: This is the name of an audio file that sounds sort of like a submarine sonar ping.
+ You might want to translate it into the equivalent words of your language. -->
+ <_name>Sonar</_name>
+ <filename>@datadir@/sounds/mate/default/alerts/sonar.ogg</filename>
+ </sound>
+</sounds>
diff --git a/sound-theme/sounds/sonar.ogg b/sound-theme/sounds/sonar.ogg
new file mode 100644
index 0000000..77aadec
--- /dev/null
+++ b/sound-theme/sounds/sonar.ogg
Binary files differ