aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2013-08-27 10:58:07 -0500
committerTed Gould <ted@gould.cx>2013-08-27 10:58:07 -0500
commit3f3f5915a4ade92a74633e1b4d7dc19822223213 (patch)
tree73430e480c436187ea247b2830f3c5c9cb1f6fea
parentf21921053ac8cf50438ff418539cf22d9a86c8bb (diff)
parentdc721ac25d910a08fc3806330b2f8bd8d3b2a4dd (diff)
downloadayatana-indicator-sound-3f3f5915a4ade92a74633e1b4d7dc19822223213.tar.gz
ayatana-indicator-sound-3f3f5915a4ade92a74633e1b4d7dc19822223213.tar.bz2
ayatana-indicator-sound-3f3f5915a4ade92a74633e1b4d7dc19822223213.zip
Merge Trunk
-rw-r--r--.bzrignore28
-rw-r--r--CMakeLists.txt69
-rw-r--r--Makefile.am12
-rw-r--r--Makefile.am.coverage48
-rwxr-xr-xautogen.sh12
-rw-r--r--cmake/COPYING-CMAKE-SCRIPTS22
-rw-r--r--cmake/Coverage.cmake37
-rw-r--r--cmake/FindGObjectIntrospection.cmake61
-rw-r--r--cmake/FindVala.cmake57
-rw-r--r--cmake/UseGObjectIntrospection.cmake100
-rw-r--r--cmake/UseGSettings.cmake42
-rw-r--r--cmake/UseVala.cmake241
-rw-r--r--config.h.in25
-rw-r--r--configure.ac115
-rw-r--r--data/CMakeLists.txt43
-rw-r--r--data/Makefile.am20
-rw-r--r--data/com.canonical.indicator.sound6
-rw-r--r--data/com.canonical.indicator.sound.gschema.xml2
-rw-r--r--data/indicator-sound.conf.in2
-rw-r--r--debian/changelog90
-rw-r--r--debian/control3
-rwxr-xr-xdebian/rules9
-rw-r--r--m4/gcov.m486
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/CMakeLists.txt128
-rw-r--r--src/Makefile.am36
-rw-r--r--src/service.vala198
-rw-r--r--src/sound-menu.vala167
-rw-r--r--tests/CMakeLists.txt0
-rw-r--r--tests/Makefile.am1
30 files changed, 1150 insertions, 511 deletions
diff --git a/.bzrignore b/.bzrignore
index 96aa111..166a1ca 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1,33 +1,7 @@
-Makefile
-Makefile.in
-Makefile.in.in
-.deps
-.libs
-*.gschema.valid
-
-/INSTALL
-/aclocal.m4
-/autom4te.cache
-/compile
-/config.guess
-/config.h
-/config.h.in
-/config.log
-/config.status
-/config.sub
-/configure
-/depcomp
-/install-sh
-/libtool
-/ltmain.sh
-/missing
-/stamp-h1
-/m4/*
-
/po/POTFILES
/po/stamp-it
-/data/indicator-sound.service
+/data/indicator-sound.conf
/src/indicator-sound-service
/src/indicator_sound_service_vala.stamp
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..98dccef
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,69 @@
+project(indicator-sound C CXX)
+cmake_minimum_required(VERSION 2.8.9)
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
+
+set(PACKAGE ${CMAKE_PROJECT_NAME})
+set(GETTEXT_PACKAGE ${CMAKE_PROJECT_NAME})
+set(GNOMELOCALEDIR "${CMAKE_INSTALL_FULL_DATADIR}/locale")
+
+add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" )
+
+find_package(PkgConfig REQUIRED)
+include(GNUInstallDirs)
+include(Coverage)
+include(UseVala)
+
+# Workaround for libexecdir on debian
+if (EXISTS "/etc/debian_version")
+ set(CMAKE_INSTALL_LIBEXECDIR ${CMAKE_INSTALL_LIBDIR})
+ set(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}")
+endif()
+
+set(SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
+set(SOURCE_BINARY_DIR "${CMAKE_BINARY_DIR}/src")
+
+set(PULSE_AUDIO_REQUIRED_VERSION 0.9.19)
+set(GIO_2_0_REQUIRED_VERSION 2.25.13)
+
+pkg_check_modules(
+ PULSEAUDIO REQUIRED
+ libpulse-mainloop-glib>=${PULSE_AUDIO_REQUIRED_VERSION}
+ gio-unix-2.0
+)
+include_directories(${PULSEAUDIO_INCLUDE_DIRS})
+
+pkg_check_modules(
+ SOUNDSERVICE REQUIRED
+ gee-1.0
+ gio-2.0>=${GIO_2_0_REQUIRED_VERSION}
+ gio-unix-2.0
+ libxml-2.0
+)
+include_directories(${SOUNDSERVICE_INCLUDE_DIRS})
+
+find_package(Vala 0.18)
+
+find_package(GObjectIntrospection 0.9.12)
+
+include_directories(${SOURCE_DIR})
+include_directories(${SOURCE_BINARY_DIR})
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+add_definitions(
+ -Wall
+)
+
+configure_file(
+ "config.h.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/config.h"
+)
+
+add_subdirectory(data)
+add_subdirectory(src)
+
+enable_testing()
+add_subdirectory(tests)
+
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 3544dc4..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,12 +0,0 @@
-
-SUBDIRS = \
- src \
- data \
- po \
- tests
-
-EXTRA_DIST = \
- autogen.sh \
- vapi/config.vapi
-
-include $(top_srcdir)/Makefile.am.coverage
diff --git a/Makefile.am.coverage b/Makefile.am.coverage
deleted file mode 100644
index fb97747..0000000
--- a/Makefile.am.coverage
+++ /dev/null
@@ -1,48 +0,0 @@
-
-# Coverage targets
-
-.PHONY: clean-gcno clean-gcda \
- coverage-html generate-coverage-html clean-coverage-html \
- coverage-gcovr generate-coverage-gcovr clean-coverage-gcovr
-
-clean-local: clean-gcno clean-coverage-html clean-coverage-gcovr
-
-if HAVE_GCOV
-
-clean-gcno:
- @echo Removing old coverage instrumentation
- -find -name '*.gcno' -print | xargs -r rm
-
-clean-gcda:
- @echo Removing old coverage results
- -find -name '*.gcda' -print | xargs -r rm
-
-coverage-html: clean-gcda
- -$(MAKE) $(AM_MAKEFLAGS) -k check
- $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html
-
-generate-coverage-html:
- @echo Collecting coverage data
- $(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool
- LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info
-
-clean-coverage-html: clean-gcda
- -$(LCOV) --directory $(top_builddir) -z
- -rm -rf coverage.info coveragereport
-
-if HAVE_GCOVR
-
-coverage-gcovr: clean-gcda
- -$(MAKE) $(AM_MAKEFLAGS) -k check
- $(MAKE) $(AM_MAKEFLAGS) generate-coverage-gcovr
-
-generate-coverage-gcovr:
- @echo Generating coverage GCOVR report
- $(GCOVR) -x -r $(top_builddir) -o $(top_builddir)/coverage.xml
-
-clean-coverage-gcovr: clean-gcda
- -rm -rf $(top_builddir)/coverage.xml
-
-endif # HAVE_GCOVR
-
-endif # HAVE_GCOV
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index b3b80df..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-PKG_NAME="indicator-sound"
-
-which gnome-autogen.sh || {
- echo "You need gnome-common from GNOME SVN"
- exit 1
-}
-
-USE_GNOME2_MACROS=1 \
-. gnome-autogen.sh
-
diff --git a/cmake/COPYING-CMAKE-SCRIPTS b/cmake/COPYING-CMAKE-SCRIPTS
new file mode 100644
index 0000000..4b41776
--- /dev/null
+++ b/cmake/COPYING-CMAKE-SCRIPTS
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake
new file mode 100644
index 0000000..22a0d29
--- /dev/null
+++ b/cmake/Coverage.cmake
@@ -0,0 +1,37 @@
+if (CMAKE_BUILD_TYPE MATCHES coverage)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --coverage")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
+
+ find_program(GCOVR_EXECUTABLE gcovr HINTS ${GCOVR_ROOT} "${GCOVR_ROOT}/bin")
+ if (NOT GCOVR_EXECUTABLE)
+ message(STATUS "Gcovr binary was not found, can not generate XML coverage info.")
+ else ()
+ message(STATUS "Gcovr found, can generate XML coverage info.")
+ add_custom_target (coverage-xml
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMAND "${GCOVR_EXECUTABLE}" --exclude="test.*" --exclude="obj.*" -x -r "${CMAKE_SOURCE_DIR}"
+ --object-directory=${CMAKE_BINARY_DIR} -o coverage.xml)
+ endif()
+
+ find_program(LCOV_EXECUTABLE lcov HINTS ${LCOV_ROOT} "${GCOVR_ROOT}/bin")
+ find_program(GENHTML_EXECUTABLE genhtml HINTS ${GENHTML_ROOT})
+ if (NOT LCOV_EXECUTABLE)
+ message(STATUS "Lcov binary was not found, can not generate HTML coverage info.")
+ else ()
+ if(NOT GENHTML_EXECUTABLE)
+ message(STATUS "Genthml binary not found, can not generate HTML coverage info.")
+ else()
+ message(STATUS "Lcov and genhtml found, can generate HTML coverage info.")
+ add_custom_target (coverage-html
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMAND "${LCOV_EXECUTABLE}" --capture --output-file "${CMAKE_BINARY_DIR}/coverage.info" --no-checksum --directory "${CMAKE_BINARY_DIR}"
+ COMMAND "${LCOV_EXECUTABLE}" --remove "${CMAKE_BINARY_DIR}/coverage.info" '/usr/*' --output-file "${CMAKE_BINARY_DIR}/coverage.info"
+ COMMAND "${LCOV_EXECUTABLE}" --remove "${CMAKE_BINARY_DIR}/coverage.info" '${CMAKE_BINARY_DIR}/*' --output-file "${CMAKE_BINARY_DIR}/coverage.info"
+ COMMAND "${LCOV_EXECUTABLE}" --remove "${CMAKE_BINARY_DIR}/coverage.info" '${CMAKE_SOURCE_DIR}/tests/*' --output-file "${CMAKE_BINARY_DIR}/coverage.info"
+ COMMAND "${GENHTML_EXECUTABLE}" --prefix "${CMAKE_BINARY_DIR}" --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info
+ )
+ endif()
+ endif()
+endif()
diff --git a/cmake/FindGObjectIntrospection.cmake b/cmake/FindGObjectIntrospection.cmake
new file mode 100644
index 0000000..2073c3c
--- /dev/null
+++ b/cmake/FindGObjectIntrospection.cmake
@@ -0,0 +1,61 @@
+# - try to find gobject-introspection
+#
+# Once done this will define
+#
+# INTROSPECTION_FOUND - system has gobject-introspection
+# INTROSPECTION_SCANNER - the gobject-introspection scanner, g-ir-scanner
+# INTROSPECTION_COMPILER - the gobject-introspection compiler, g-ir-compiler
+# INTROSPECTION_GENERATE - the gobject-introspection generate, g-ir-generate
+# INTROSPECTION_GIRDIR
+# INTROSPECTION_TYPELIBDIR
+# INTROSPECTION_CFLAGS
+# INTROSPECTION_LIBS
+#
+# Copyright (C) 2010, Pino Toscano, <pino@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+macro(_GIR_GET_PKGCONFIG_VAR _outvar _varname)
+ execute_process(
+ COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_varname} gobject-introspection-1.0
+ OUTPUT_VARIABLE _result
+ RESULT_VARIABLE _null
+ )
+
+ if (_null)
+ else()
+ string(REGEX REPLACE "[\r\n]" " " _result "${_result}")
+ string(REGEX REPLACE " +$" "" _result "${_result}")
+ separate_arguments(_result)
+ set(${_outvar} ${_result} CACHE INTERNAL "")
+ endif()
+endmacro(_GIR_GET_PKGCONFIG_VAR)
+
+find_package(PkgConfig)
+if(PKG_CONFIG_FOUND)
+ if(PACKAGE_FIND_VERSION_COUNT GREATER 0)
+ set(_gir_version_cmp ">=${PACKAGE_FIND_VERSION}")
+ endif()
+ pkg_check_modules(_pc_gir gobject-introspection-1.0${_gir_version_cmp})
+ if(_pc_gir_FOUND)
+ set(INTROSPECTION_FOUND TRUE)
+ _gir_get_pkgconfig_var(INTROSPECTION_SCANNER "g_ir_scanner")
+ _gir_get_pkgconfig_var(INTROSPECTION_COMPILER "g_ir_compiler")
+ _gir_get_pkgconfig_var(INTROSPECTION_GENERATE "g_ir_generate")
+ _gir_get_pkgconfig_var(INTROSPECTION_GIRDIR "girdir")
+ _gir_get_pkgconfig_var(INTROSPECTION_TYPELIBDIR "typelibdir")
+ set(INTROSPECTION_CFLAGS "${_pc_gir_CFLAGS}")
+ set(INTROSPECTION_LIBS "${_pc_gir_LIBS}")
+ endif()
+endif()
+
+mark_as_advanced(
+ INTROSPECTION_SCANNER
+ INTROSPECTION_COMPILER
+ INTROSPECTION_GENERATE
+ INTROSPECTION_GIRDIR
+ INTROSPECTION_TYPELIBDIR
+ INTROSPECTION_CFLAGS
+ INTROSPECTION_LIBS
+)
diff --git a/cmake/FindVala.cmake b/cmake/FindVala.cmake
new file mode 100644
index 0000000..a638735
--- /dev/null
+++ b/cmake/FindVala.cmake
@@ -0,0 +1,57 @@
+# - Find Vala
+# This module looks for valac.
+# This module defines the following values:
+# VALA_FOUND
+# VALA_COMPILER
+# VALA_VERSION
+# VAPI_GEN
+# VAPI_GEN_VERSION
+
+#=============================================================================
+# Copyright Přemysl Janouch 2011
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+# OF SUCH DAMAGE.
+#=============================================================================
+
+find_program (VALA_COMPILER "valac")
+
+if (VALA_COMPILER)
+ execute_process (COMMAND ${VALA_COMPILER} --version
+ OUTPUT_VARIABLE VALA_VERSION)
+ string (REGEX MATCH "[.0-9]+" VALA_VERSION "${VALA_VERSION}")
+endif (VALA_COMPILER)
+
+find_program (VAPI_GEN "vapigen")
+
+if (VAPI_GEN)
+ execute_process (COMMAND ${VAPI_GEN} --version
+ OUTPUT_VARIABLE VAPI_GEN_VERSION)
+ string (REGEX MATCH "[.0-9]+" VAPI_GEN_VERSION "${VAPI_GEN_VERSION}")
+endif (VAPI_GEN)
+
+include (FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS (Vala
+ REQUIRED_VARS VALA_COMPILER
+ VERSION_VAR VALA_VERSION)
+
+mark_as_advanced (VALA_COMPILER VALA_VERSION VAPI_GEN)
+
diff --git a/cmake/UseGObjectIntrospection.cmake b/cmake/UseGObjectIntrospection.cmake
new file mode 100644
index 0000000..d6d1810
--- /dev/null
+++ b/cmake/UseGObjectIntrospection.cmake
@@ -0,0 +1,100 @@
+# Copyright (C) 2010, Pino Toscano, <pino@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+include(ListOperations)
+
+macro(_gir_list_prefix _outvar _listvar _prefix)
+ set(${_outvar})
+ foreach(_item IN LISTS ${_listvar})
+ list(APPEND ${_outvar} ${_prefix}${_item})
+ endforeach()
+endmacro(_gir_list_prefix)
+
+macro(gir_add_introspections introspections_girs)
+
+ foreach(gir IN LISTS ${introspections_girs})
+
+ set(_gir_name "${gir}")
+
+ ## Transform the gir filename to something which can reference through a variable
+ ## without automake/make complaining, eg Gtk-2.0.gir -> Gtk_2_0_gir
+ string(REPLACE "-" "_" _gir_name "${_gir_name}")
+ string(REPLACE "." "_" _gir_name "${_gir_name}")
+
+ # Namespace and Version is either fetched from the gir filename
+ # or the _NAMESPACE/_VERSION variable combo
+ set(_gir_namespace "${${_gir_name}_NAMESPACE}")
+ if (_gir_namespace STREQUAL "")
+ string(REGEX REPLACE "([^-]+)-.*" "\\1" _gir_namespace "${gir}")
+ endif ()
+ set(_gir_version "${${_gir_name}_VERSION}")
+ if (_gir_version STREQUAL "")
+ string(REGEX REPLACE ".*-([^-]+).gir" "\\1" _gir_version "${gir}")
+ endif ()
+
+ # _PROGRAM is an optional variable which needs it's own --program argument
+ set(_gir_program "${${_gir_name}_PROGRAM}")
+ if (NOT _gir_program STREQUAL "")
+ set(_gir_program "--program=${_gir_program}")
+ endif ()
+
+ # Variables which provides a list of things
+ _gir_list_prefix(_gir_libraries ${_gir_name}_LIBS "--library=")
+ _gir_list_prefix(_gir_packages ${_gir_name}_PACKAGES "--pkg=")
+ _gir_list_prefix(_gir_includes ${_gir_name}_INCLUDES "--include=")
+ _gir_list_prefix(_gir_export_packages ${_gir_name}_EXPORT_PACKAGES "--pkg-export=")
+
+ # Reuse the LIBTOOL variable from by automake if it's set
+ set(_gir_libtool "--no-libtool")
+
+ add_custom_command(
+ COMMAND ${INTROSPECTION_SCANNER}
+ ${INTROSPECTION_SCANNER_ARGS}
+ --namespace=${_gir_namespace}
+ --nsversion=${_gir_version}
+ ${_gir_libtool}
+ ${_gir_program}
+ ${_gir_libraries}
+ ${_gir_packages}
+ ${_gir_includes}
+ ${_gir_export_packages}
+ ${${_gir_name}_SCANNERFLAGS}
+ ${${_gir_name}_CFLAGS}
+ ${${_gir_name}_FILES}
+ --output ${CMAKE_CURRENT_BINARY_DIR}/${gir}
+ DEPENDS ${${_gir_name}_FILES}
+ ${${_gir_name}_LIBS}
+ OUTPUT ${gir}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ VERBATIM
+ )
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${gir} DESTINATION share/gir-1.0)
+
+ string(REPLACE ".gir" ".typelib" _typelib "${gir}")
+ add_custom_command(
+ COMMAND ${INTROSPECTION_COMPILER}
+ ${INTROSPECTION_COMPILER_ARGS}
+ --includedir=.
+ ${CMAKE_CURRENT_BINARY_DIR}/${gir}
+ -o ${CMAKE_CURRENT_BINARY_DIR}/${_typelib}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${gir}
+ OUTPUT ${_typelib}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_typelib} DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0)
+
+ add_custom_target(gir-${gir} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${gir})
+ add_custom_target(gir-typelibs-${_typelib} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_typelib})
+ endforeach()
+
+endmacro(gir_add_introspections)
+
+macro(gir_get_cflags _output)
+ get_directory_property(_tmp_includes INCLUDE_DIRECTORIES)
+ list_prefix(_includes _tmp_includes "-I")
+ get_directory_property(_tmp_compile_definitions COMPILE_DEFINITIONS)
+ list_prefix(_compile_definitions _tmp_compile_definitions "-D")
+ set(${_output} ${_includes} ${_compile_definitions})
+endmacro(gir_get_cflags)
diff --git a/cmake/UseGSettings.cmake b/cmake/UseGSettings.cmake
new file mode 100644
index 0000000..e109692
--- /dev/null
+++ b/cmake/UseGSettings.cmake
@@ -0,0 +1,42 @@
+# GSettings.cmake, CMake macros written for Marlin, feel free to re-use them.
+
+option (GSETTINGS_LOCALINSTALL "Install GSettings Schemas locally instead of to the GLib prefix" OFF)
+
+option (GSETTINGS_COMPILE "Compile GSettings Schemas after installation" OFF)
+
+if(GSETTINGS_LOCALINSTALL)
+ message(STATUS "GSettings schemas will be installed locally.")
+endif()
+
+if(GSETTINGS_COMPILE)
+ message(STATUS "GSettings shemas will be compiled.")
+endif()
+
+macro(add_schema SCHEMA_NAME)
+
+ set(PKG_CONFIG_EXECUTABLE pkg-config)
+ # Have an option to not install the schema into where GLib is
+ if (GSETTINGS_LOCALINSTALL)
+ SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/")
+ else (GSETTINGS_LOCALINSTALL)
+ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE)
+ SET (GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/")
+ endif (GSETTINGS_LOCALINSTALL)
+
+ # Run the validator and error if it fails
+ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process (COMMAND ${_glib_comple_schemas} --dry-run --schema-file=${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if (_schemas_invalid)
+ message (SEND_ERROR "Schema validation error: ${_schemas_invalid}")
+ endif (_schemas_invalid)
+
+ # Actually install and recomple schemas
+ message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}")
+ install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL)
+
+ if (GSETTINGS_COMPILE)
+ install (CODE "message (STATUS \"Compiling GSettings schemas\")")
+ install (CODE "execute_process (COMMAND ${_glib_comple_schemas} ${GSETTINGS_DIR})")
+ endif ()
+endmacro()
diff --git a/cmake/UseVala.cmake b/cmake/UseVala.cmake
new file mode 100644
index 0000000..f092769
--- /dev/null
+++ b/cmake/UseVala.cmake
@@ -0,0 +1,241 @@
+# - Precompilation of Vala/Genie source files into C sources
+# Makes use of the parallel build ability introduced in Vala 0.11. Derived
+# from a similar module by Jakob Westhoff and the original GNU Make rules.
+# Might be a bit oversimplified.
+#
+# This module defines three functions. The first one:
+#
+# vala_init (id
+# [DIRECTORY dir] - Output directory (binary dir by default)
+# [PACKAGES package...] - Package dependencies
+# [OPTIONS option...] - Extra valac options
+# [CUSTOM_VAPIS file...]) - Custom vapi files to include in the build
+# [DEPENDS targets...]) - Extra dependencies for code generation
+#
+# initializes a single precompilation unit using the given arguments.
+# You can put files into it via the following function:
+#
+# vala_add (id source.vala
+# [DEPENDS source...]) - Vala/Genie source or .vapi dependencies
+#
+# Finally retrieve paths for generated C files by calling:
+#
+# vala_finish (id
+# [SOURCES sources_var] - Input Vala/Genie sources
+# [OUTPUTS outputs_var] - Output C sources
+# [GENERATE_HEADER id.h - Generate id.h and id_internal.h
+# [GENERATE_VAPI id.vapi] - Generate a vapi file
+# [GENERATE_SYMBOLS id.def]]) - Generate a list of public symbols
+#
+
+#=============================================================================
+# Copyright Přemysl Janouch 2011
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+# OF SUCH DAMAGE.
+#=============================================================================
+
+find_package (Vala 0.18 REQUIRED)
+include (CMakeParseArguments)
+
+function (vala_init id)
+ set (_multi_value PACKAGES OPTIONS CUSTOM_VAPIS DEPENDS)
+ cmake_parse_arguments (arg "" "DIRECTORY" "${_multi_value}" ${ARGN})
+
+ if (arg_DIRECTORY)
+ set (directory ${arg_DIRECTORY})
+ if (NOT IS_DIRECTORY ${directory})
+ file (MAKE_DIRECTORY ${directory})
+ endif (NOT IS_DIRECTORY ${directory})
+ else (arg_DIRECTORY)
+ set (directory ${CMAKE_CURRENT_BINARY_DIR})
+ endif (arg_DIRECTORY)
+
+ set (pkg_opts)
+ foreach (pkg ${arg_PACKAGES})
+ list (APPEND pkg_opts "--pkg=${pkg}")
+ endforeach (pkg)
+
+ set (VALA_${id}_DIR "${directory}" PARENT_SCOPE)
+ set (VALA_${id}_ARGS ${pkg_opts} ${arg_OPTIONS}
+ ${arg_CUSTOM_VAPIS} PARENT_SCOPE)
+ set (VALA_${id}_DEPENDS ${arg_DEPENDS}
+ PARENT_SCOPE)
+
+ set (VALA_${id}_SOURCES "" PARENT_SCOPE)
+ set (VALA_${id}_OUTPUTS "" PARENT_SCOPE)
+ set (VALA_${id}_FAST_VAPI_FILES "" PARENT_SCOPE)
+ set (VALA_${id}_FAST_VAPI_ARGS "" PARENT_SCOPE)
+endfunction (vala_init)
+
+function (vala_add id file)
+ cmake_parse_arguments (arg "" "" "DEPENDS" ${ARGN})
+
+ if (NOT IS_ABSOLUTE "${file}")
+ set (file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
+ endif (NOT IS_ABSOLUTE "${file}")
+
+ get_filename_component (output_name "${file}" NAME)
+ get_filename_component (output_base "${file}" NAME_WE)
+ set (output_base "${VALA_${id}_DIR}/${output_base}")
+
+ # XXX: It would be best to have it working without touching the vapi
+ # but it appears this cannot be done in CMake.
+ add_custom_command (OUTPUT "${output_base}.vapi"
+ COMMAND ${VALA_COMPILER} "${file}" "--fast-vapi=${output_base}.vapi"
+ COMMAND ${CMAKE_COMMAND} -E touch "${output_base}.vapi"
+ DEPENDS "${file}"
+ COMMENT "Generating a fast vapi for ${output_name}" VERBATIM)
+
+ set (vapi_opts)
+ set (vapi_depends)
+ foreach (vapi ${arg_DEPENDS})
+ if (NOT IS_ABSOLUTE "${vapi}")
+ set (vapi "${VALA_${id}_DIR}/${vapi}.vapi")
+ endif (NOT IS_ABSOLUTE "${vapi}")
+
+ list (APPEND vapi_opts "--use-fast-vapi=${vapi}")
+ list (APPEND vapi_depends "${vapi}")
+ endforeach (vapi)
+
+ add_custom_command (OUTPUT "${output_base}.c"
+ COMMAND ${VALA_COMPILER} "${file}" -C ${vapi_opts} ${VALA_${id}_ARGS}
+ COMMAND ${CMAKE_COMMAND} -E touch "${output_base}.c"
+ DEPENDS "${file}" ${vapi_depends} ${VALA_${id}_DEPENDS}
+ WORKING_DIRECTORY "${VALA_${id}_DIR}"
+ COMMENT "Precompiling ${output_name}" VERBATIM)
+
+ set (VALA_${id}_SOURCES ${VALA_${id}_SOURCES}
+ "${file}" PARENT_SCOPE)
+ set (VALA_${id}_OUTPUTS ${VALA_${id}_OUTPUTS}
+ "${output_base}.c" PARENT_SCOPE)
+ set (VALA_${id}_FAST_VAPI_FILES ${VALA_${id}_FAST_VAPI_FILES}
+ "${output_base}.vapi" PARENT_SCOPE)
+ set (VALA_${id}_FAST_VAPI_ARGS ${VALA_${id}_FAST_VAPI_ARGS}
+ "--use-fast-vapi=${output_base}.vapi" PARENT_SCOPE)
+endfunction (vala_add)
+
+function (vala_finish id)
+ set (_one_value SOURCES OUTPUTS
+ GENERATE_VAPI GENERATE_HEADER GENERATE_SYMBOLS)
+ cmake_parse_arguments (arg "" "${_one_value}" "" ${ARGN})
+
+ if (arg_SOURCES)
+ set (${arg_SOURCES} ${VALA_${id}_SOURCES} PARENT_SCOPE)
+ endif (arg_SOURCES)
+
+ if (arg_OUTPUTS)
+ set (${arg_OUTPUTS} ${VALA_${id}_OUTPUTS} PARENT_SCOPE)
+ endif (arg_OUTPUTS)
+
+ set (outputs)
+ set (export_args)
+
+ if (arg_GENERATE_VAPI)
+ if (NOT IS_ABSOLUTE "${arg_GENERATE_VAPI}")
+ set (arg_GENERATE_VAPI
+ "${VALA_${id}_DIR}/${arg_GENERATE_VAPI}")
+ endif (NOT IS_ABSOLUTE "${arg_GENERATE_VAPI}")
+
+ list (APPEND outputs "${arg_GENERATE_VAPI}")
+ list (APPEND export_args "--internal-vapi=${arg_GENERATE_VAPI}")
+
+ if (NOT arg_GENERATE_HEADER)
+ message (FATAL_ERROR "Header generation required for vapi")
+ endif (NOT arg_GENERATE_HEADER)
+ endif (arg_GENERATE_VAPI)
+
+ if (arg_GENERATE_SYMBOLS)
+ if (NOT IS_ABSOLUTE "${arg_GENERATE_SYMBOLS}")
+ set (arg_GENERATE_SYMBOLS
+ "${VALA_${id}_DIR}/${arg_GENERATE_SYMBOLS}")
+ endif (NOT IS_ABSOLUTE "${arg_GENERATE_SYMBOLS}")
+
+ list (APPEND outputs "${arg_GENERATE_SYMBOLS}")
+ list (APPEND export_args "--symbols=${arg_GENERATE_SYMBOLS}")
+
+ if (NOT arg_GENERATE_HEADER)
+ message (FATAL_ERROR "Header generation required for symbols")
+ endif (NOT arg_GENERATE_HEADER)
+ endif (arg_GENERATE_SYMBOLS)
+
+ if (arg_GENERATE_HEADER)
+ if (NOT IS_ABSOLUTE "${arg_GENERATE_HEADER}")
+ set (arg_GENERATE_HEADER
+ "${VALA_${id}_DIR}/${arg_GENERATE_HEADER}")
+ endif (NOT IS_ABSOLUTE "${arg_GENERATE_HEADER}")
+
+ get_filename_component (header_path "${arg_GENERATE_HEADER}" PATH)
+ get_filename_component (header_name "${arg_GENERATE_HEADER}" NAME_WE)
+ set (header_base "${header_path}/${header_name}")
+ get_filename_component (header_ext "${arg_GENERATE_HEADER}" EXT)
+
+ list (APPEND outputs
+ "${header_base}${header_ext}"
+ "${header_base}_internal${header_ext}")
+ list (APPEND export_args
+ "--header=${header_base}${header_ext}"
+ "--internal-header=${header_base}_internal${header_ext}")
+ endif (arg_GENERATE_HEADER)
+
+ if (outputs)
+ add_custom_command (OUTPUT ${outputs}
+ COMMAND ${VALA_COMPILER} -C ${VALA_${id}_ARGS}
+ ${export_args} ${VALA_${id}_FAST_VAPI_ARGS}
+ DEPENDS ${VALA_${id}_FAST_VAPI_FILES}
+ COMMENT "Generating vapi/headers/symbols" VERBATIM)
+ endif (outputs)
+endfunction (vala_finish id)
+
+
+function (vapi_gen id)
+ set (_one_value LIBRARY INPUT)
+ set (_multi_value PACKAGES)
+ cmake_parse_arguments (arg "" "${_one_value}" "${_multi_value}" ${ARGN})
+
+ set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${id}.vapi")
+ if (arg_LIBRARY)
+ set (OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${arg_LIBRARY}.vapi")
+ endif (arg_LIBRARY)
+
+ set("${id}_OUTPUT" ${OUTPUT} PARENT_SCOPE)
+
+ set(PACKAGE_LIST)
+ foreach(PACKAGE ${arg_PACKAGES})
+ list(APPEND PACKAGE_LIST "--pkg" ${PACKAGE})
+ endforeach()
+
+ add_custom_command(
+ OUTPUT
+ ${OUTPUT}
+ COMMAND
+ ${VAPI_GEN}
+ ${PACKAGE_LIST}
+ --library=${arg_LIBRARY}
+ ${arg_INPUT}
+ DEPENDS
+ ${arg_INPUT}
+ VERBATIM
+ )
+
+ add_custom_target(${id} ALL DEPENDS ${OUTPUT})
+endfunction (vapi_gen id)
+
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..af72a99
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Pete Woods <pete.woods@canonical.com>
+ */
+
+#ifndef INDICATOR_SOUND_CONFIG_H_
+#define INDICATOR_SOUND_CONFIG_H_
+
+#define GETTEXT_PACKAGE "@GETTEXT_PACKAGE@"
+#define GNOMELOCALEDIR "@GNOMELOCALEDIR@"
+
+#endif // INDICATOR_SOUND_CONFIG_H_
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index 5c0be0f..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,115 +0,0 @@
-AC_INIT([indicator-sound],[12.10.1],[conor.curran@canonical.com])
-AM_INIT_AUTOMAKE([check-news])
-AC_CONFIG_HEADERS([config.h])
-
-AC_PREREQ(2.53)
-
-AM_MAINTAINER_MODE
-
-IT_PROG_INTLTOOL([0.35.0])
-AM_PROG_VALAC([0.18])
-
-AC_ISC_POSIX
-AC_PROG_CC
-AM_PROG_CC_C_O
-AC_STDC_HEADERS
-AC_PROG_LIBTOOL
-
-AC_SUBST(VERSION)
-AC_CONFIG_MACRO_DIR([m4])
-
-m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
-
-###########################
-# Dependencies
-###########################
-
-PULSE_AUDIO_REQUIRED_VERSION=0.9.19
-GIO_2_0_REQUIRED_VERSION=2.25.13
-
-PKG_CHECK_MODULES(PULSEAUDIO, libpulse-mainloop-glib >= $PULSE_AUDIO_REQUIRED_VERSION
- gio-unix-2.0)
-
-PKG_CHECK_MODULES(SOUNDSERVICE, gee-1.0
- gio-unix-2.0
- libxml-2.0)
-
-###########################
-# gcov coverage reporting
-###########################
-
-m4_include([m4/gcov.m4])
-AC_TDD_GCOV
-AM_CONDITIONAL([HAVE_GCOV], [test "x$ac_cv_check_gcov" = xyes])
-AM_CONDITIONAL([HAVE_LCOV], [test "x$ac_cv_check_lcov" = xyes])
-AM_CONDITIONAL([HAVE_GCOVR], [test "x$ac_cv_check_gcovr" = xyes])
-AC_SUBST(COVERAGE_CFLAGS)
-AC_SUBST(COVERAGE_CXXFLAGS)
-AC_SUBST(COVERAGE_LDFLAGS)
-
-###########################
-# Grab the GSettings Macros
-###########################
-
-GLIB_GSETTINGS
-
-###########################
-# DBus Service Info
-###########################
-
-AC_ARG_WITH([indicator-dir],
- [AS_HELP_STRING([--with-indicator-dir=DIR], [Indicator directory [default=$datadir/unity/indicators]])],
- [],
- [with_indicator_dir=$datadir/unity/indicators])
-AC_SUBST([INDICATOR_DIR], [$with_indicator_dir])
-
-##############################
-# Custom Junk
-##############################
-
-AC_DEFUN([AC_DEFINE_PATH], [
- test "x$prefix" = xNONE && prefix="$ac_default_prefix"
- test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
- ac_define_path=`eval echo [$]$2`
- ac_define_path=`eval echo [$]ac_define_path`
- $1="$ac_define_path"
- AC_SUBST($1)
- ifelse($3, ,
- AC_DEFINE_UNQUOTED($1, "$ac_define_path"),
- AC_DEFINE_UNQUOTED($1, "$ac_define_path", $3))
-])
-
-###########################
-# Internationalization
-###########################
-
-GETTEXT_PACKAGE=indicator-sound
-AC_SUBST(GETTEXT_PACKAGE)
-AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Name of the default get text domain])
-AC_DEFINE_PATH(GNOMELOCALEDIR, "${datadir}/locale", [locale directory])
-
-AM_GLIB_GNU_GETTEXT
-
-###########################
-# Files
-###########################
-
-AC_OUTPUT([
-Makefile
-src/Makefile
-data/Makefile
-po/Makefile.in
-tests/Makefile
-])
-
-###########################
-# Results
-###########################
-
-AC_MSG_NOTICE([
-
-SUS Indicator Configuration:
-
- Prefix: $prefix
- gcov: $use_gcov
-])
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
new file mode 100644
index 0000000..e71051e
--- /dev/null
+++ b/data/CMakeLists.txt
@@ -0,0 +1,43 @@
+
+include(UseGSettings)
+
+###########################
+# Indicator service
+###########################
+
+set(
+ INDICATOR_DIR
+ "${CMAKE_INSTALL_DATADIR}/unity/indicators"
+ CACHE FILEPATH "Indicator directory"
+)
+
+install(
+ FILES "com.canonical.indicator.sound"
+ DESTINATION "${INDICATOR_DIR}"
+)
+
+###########################
+# Dbus Service
+###########################
+
+set(
+ INDICATOR_SOUND_CONF
+ "${CMAKE_CURRENT_BINARY_DIR}/indicator-sound.conf"
+)
+
+configure_file(
+ "indicator-sound.conf.in"
+ ${INDICATOR_SOUND_CONF}
+ @ONLY
+)
+
+install(
+ FILES "${INDICATOR_SOUND_CONF}"
+ DESTINATION "${CMAKE_INSTALL_DATADIR}/upstart/sessions/"
+)
+
+###########################
+# GSettings
+###########################
+
+add_schema ("com.canonical.indicator.sound.gschema.xml")
diff --git a/data/Makefile.am b/data/Makefile.am
deleted file mode 100644
index d71a585..0000000
--- a/data/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-gsettings_SCHEMAS = \
- com.canonical.indicator.sound.gschema.xml
-@GSETTINGS_RULES@
-
-upstart_jobsdir = $(datadir)/upstart/sessions
-upstart_jobs_DATA = indicator-sound.conf
-
-%.conf: %.conf.in
- sed -e "s|\@pkglibexecdir\@|$(pkglibexecdir)|" $< > $@
-
-indicatordir = $(INDICATOR_DIR)
-dist_indicator_DATA = com.canonical.indicator.sound
-
-EXTRA_DIST = \
- $(gsettings_SCHEMAS) \
- indicator-sound.conf.in
-
-CLEANFILES = \
- $(dbus_services_DATA)
-
diff --git a/data/com.canonical.indicator.sound b/data/com.canonical.indicator.sound
index 0831462..adefae9 100644
--- a/data/com.canonical.indicator.sound
+++ b/data/com.canonical.indicator.sound
@@ -5,3 +5,9 @@ Position=30
[desktop]
ObjectPath=/com/canonical/indicator/sound/desktop
+
+[phone]
+ObjectPath=/com/canonical/indicator/sound/phone
+
+[desktop_greeter]
+ObjectPath=/com/canonical/indicator/sound/desktop
diff --git a/data/com.canonical.indicator.sound.gschema.xml b/data/com.canonical.indicator.sound.gschema.xml
index 86de36a..102a1db 100644
--- a/data/com.canonical.indicator.sound.gschema.xml
+++ b/data/com.canonical.indicator.sound.gschema.xml
@@ -11,7 +11,7 @@
</key>
<key name="interested-media-players" type="as">
<summary>A list of applications which at some point have registered with the sound menu</summary>
- <default>[ 'rhythmbox' ]</default>
+ <default>[]</default>
<description>
Each media player which abides by the MPRIS2 spec will automatically appear in the menu.
This array should contain the desktop file names (minus .desktop suffix) of applications which
diff --git a/data/indicator-sound.conf.in b/data/indicator-sound.conf.in
index 73d2a7d..6d5c870 100644
--- a/data/indicator-sound.conf.in
+++ b/data/indicator-sound.conf.in
@@ -11,4 +11,4 @@ export G_MESSAGES_DEBUG
respawn
-exec @pkglibexecdir@/indicator-sound-service
+exec @CMAKE_INSTALL_FULL_LIBEXECDIR@/indicator-sound/indicator-sound-service
diff --git a/debian/changelog b/debian/changelog
index 40d8cc9..8e259d3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,93 @@
+indicator-sound (12.10.2+13.10.20130822-0ubuntu1) saucy; urgency=low
+
+ [ Charles Kerr ]
+ * Don't use deprecated GSimpleActionGroup APIs.
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 369
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 22 Aug 2013 20:29:51 +0000
+
+indicator-sound (12.10.2+13.10.20130820-0ubuntu1) saucy; urgency=low
+
+ [ Pete Woods ]
+ * Re-write build scripts using cmake.
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 367
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 20 Aug 2013 10:08:24 +0000
+
+indicator-sound (12.10.2+13.10.20130812.1-0ubuntu1) saucy; urgency=low
+
+ [ Charles Kerr ]
+ * Add back an accessible_desc property to the sound indicator.
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 365
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 12 Aug 2013 06:06:47 +0000
+
+indicator-sound (12.10.2+13.10.20130731-0ubuntu1) saucy; urgency=low
+
+ [ Charles Kerr ]
+ * add Recommends: u-s-s | g-c-c to debian/control.
+
+ [ Nick Dedekind ]
+ * Fixed max-icon on volume control slider. (LP: #1206534)
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 363
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Wed, 31 Jul 2013 02:02:57 +0000
+
+indicator-sound (12.10.2+13.10.20130726-0ubuntu1) saucy; urgency=low
+
+ [ Lars Uebernickel ]
+ * Actually export a phone menu.
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 360
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 26 Jul 2013 02:03:50 +0000
+
+indicator-sound (12.10.2+13.10.20130725-0ubuntu1) saucy; urgency=low
+
+ [ Lars Uebernickel ]
+ * Specify fallback icons The *-panel suffix is only used by the
+ ubuntu-mono icon themes. . (LP: #1202932)
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 358
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Thu, 25 Jul 2013 02:03:43 +0000
+
+indicator-sound (12.10.2+13.10.20130722-0ubuntu1) saucy; urgency=low
+
+ [ Lars Uebernickel ]
+ * Remove Rhythmbox from the default of the 'interested-media-players'
+ setting The sound menu should only contain players that have been
+ started before. (LP: #1202933)
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 356
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 22 Jul 2013 02:03:34 +0000
+
+indicator-sound (12.10.2+13.10.20130716-0ubuntu1) saucy; urgency=low
+
+ [ Ted Gould ]
+ * Add phone profile to indicator config.
+
+ [ Lars Uebernickel ]
+ * Remove gtk and dbusmenu. Sorry for the big changeset. I'd appreciate
+ a good deal of testing before merging this into the wild ;).
+
+ [ Ubuntu daily release ]
+ * Automatic snapshot from revision 354
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Tue, 16 Jul 2013 02:02:55 +0000
+
indicator-sound (12.10.2daily13.06.07-0ubuntu1) saucy; urgency=low
[ Jeremy Bicha ]
diff --git a/debian/control b/debian/control
index 8abcf59..2c263a3 100644
--- a/debian/control
+++ b/debian/control
@@ -4,7 +4,7 @@ Priority: extra
Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com>
XSBC-Original-Maintainer: Conor Curran <conor.curran@canonical.com>
Build-Depends: debhelper (>= 9.0),
- dh-autoreconf,
+ cmake,
dh-translations,
gnome-common,
autotools-dev,
@@ -27,6 +27,7 @@ Architecture: any
Depends: ${shlibs:Depends},
${misc:Depends},
pulseaudio,
+Recommends: ubuntu-system-settings | gnome-control-center,
Description: System sound indicator.
System sound indicator which provides easy control of the PulseAudio sound
daemon.
diff --git a/debian/rules b/debian/rules
index 2ce3519..9a276dc 100755
--- a/debian/rules
+++ b/debian/rules
@@ -3,12 +3,5 @@
export DPKG_GENSYMBOLS_CHECK_LEVEL=4
%:
- dh $@ --with translations,autoreconf
+ dh $@ --parallel --fail-missing --with translations
-override_dh_autoreconf:
- NOCONFIGURE=1 dh_autoreconf ./autogen.sh
-
-override_dh_install:
- find debian/indicator-sound/usr/lib -name *.la -delete
- find debian/indicator-sound/usr/lib -name *.a -delete
- dh_install --fail-missing
diff --git a/m4/gcov.m4 b/m4/gcov.m4
deleted file mode 100644
index 3163584..0000000
--- a/m4/gcov.m4
+++ /dev/null
@@ -1,86 +0,0 @@
-# Checks for existence of coverage tools:
-# * gcov
-# * lcov
-# * genhtml
-# * gcovr
-#
-# Sets ac_cv_check_gcov to yes if tooling is present
-# and reports the executables to the variables LCOV, GCOVR and GENHTML.
-AC_DEFUN([AC_TDD_GCOV],
-[
- AC_ARG_ENABLE(gcov,
- AS_HELP_STRING([--enable-gcov],
- [enable coverage testing with gcov]),
- [use_gcov=$enableval], [use_gcov=no])
-
- if test "x$use_gcov" = "xyes"; then
- # we need gcc:
- if test "$GCC" != "yes"; then
- AC_MSG_ERROR([GCC is required for --enable-gcov])
- fi
-
- # Check if ccache is being used
- AC_CHECK_PROG(SHTOOL, shtool, shtool)
- case `$SHTOOL path $CC` in
- *ccache*[)] gcc_ccache=yes;;
- *[)] gcc_ccache=no;;
- esac
-
- if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
- AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
- fi
-
- lcov_version_list="1.6 1.7 1.8 1.9"
- AC_CHECK_PROG(LCOV, lcov, lcov)
- AC_CHECK_PROG(GENHTML, genhtml, genhtml)
-
- if test "$LCOV"; then
- AC_CACHE_CHECK([for lcov version], glib_cv_lcov_version, [
- glib_cv_lcov_version=invalid
- lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
- for lcov_check_version in $lcov_version_list; do
- if test "$lcov_version" = "$lcov_check_version"; then
- glib_cv_lcov_version="$lcov_check_version (ok)"
- fi
- done
- ])
- else
- lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
- AC_MSG_ERROR([$lcov_msg])
- fi
-
- case $glib_cv_lcov_version in
- ""|invalid[)]
- lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
- AC_MSG_ERROR([$lcov_msg])
- LCOV="exit 0;"
- ;;
- esac
-
- if test -z "$GENHTML"; then
- AC_MSG_ERROR([Could not find genhtml from the lcov package])
- fi
-
- ac_cv_check_gcov=yes
- ac_cv_check_lcov=yes
-
- # Remove all optimization flags from CFLAGS
- changequote({,})
- CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'`
- changequote([,])
-
- # Add the special gcc flags
- COVERAGE_CFLAGS="-O0 -fprofile-arcs -ftest-coverage"
- COVERAGE_CXXFLAGS="-O0 -fprofile-arcs -ftest-coverage"
- COVERAGE_LDFLAGS="-lgcov"
-
- # Check availability of gcovr
- AC_CHECK_PROG(GCOVR, gcovr, gcovr)
- if test -z "$GCOVR"; then
- ac_cv_check_gcovr=no
- else
- ac_cv_check_gcovr=yes
- fi
-
-fi
-]) # AC_TDD_GCOV
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 09797c8..39a320f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,3 +1,4 @@
[encoding: UTF-8]
src/service.vala
src/service.c
+src/sound-menu.c
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..ec43b8f
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,128 @@
+
+###########################
+# Vala Generation
+###########################
+
+set(HEADER_PATH "${CMAKE_CURRENT_BINARY_DIR}/indicator-sound-service.h")
+set(SYMBOLS_PATH "${CMAKE_CURRENT_BINARY_DIR}/indicator-sound-service.def")
+
+vala_init(indicator-sound-service
+ PACKAGES
+ config
+ gio-2.0
+ gio-unix-2.0
+ libxml-2.0
+ libpulse
+ libpulse-mainloop-glib
+ OPTIONS
+ --ccode
+ --thread
+ --vapidir=${CMAKE_SOURCE_DIR}/vapi/
+ --vapidir=.
+ --target-glib=2.36
+)
+
+vala_add(indicator-sound-service
+ service.vala
+ DEPENDS
+ sound-menu
+ volume-control
+ media-player
+ media-player-list
+)
+vala_add(indicator-sound-service
+ main.vala
+ DEPENDS
+ service
+)
+vala_add(indicator-sound-service
+ volume-control.vala
+)
+vala_add(indicator-sound-service
+ media-player.vala
+ DEPENDS
+ mpris2-interfaces
+)
+vala_add(indicator-sound-service
+ media-player-list.vala
+ DEPENDS
+ media-player
+ mpris2-watcher
+)
+vala_add(indicator-sound-service
+ mpris2-interfaces.vala
+)
+vala_add(indicator-sound-service
+ mpris2-watcher.vala
+ DEPENDS
+ media-player
+ mpris2-interfaces
+ freedesktop-interfaces
+)
+vala_add(indicator-sound-service
+ freedesktop-interfaces.vala
+)
+vala_add(indicator-sound-service
+ sound-menu.vala
+ DEPENDS
+ media-player
+)
+
+vala_finish(indicator-sound-service
+ SOURCES
+ project_VALA_SOURCES
+ OUTPUTS
+ project_VALA_C
+ GENERATE_HEADER
+ ${HEADER_PATH}
+ GENERATE_SYMBOLS
+ ${SYMBOLS_PATH}
+)
+
+set_source_files_properties(
+ ${project_VALA_SOURCES}
+ PROPERTIES
+ HEADER_FILE_ONLY TRUE
+)
+
+set(
+ INDICATOR_SOUND_SOURCES
+ ${project_VALA_SOURCES}
+ ${project_VALA_C}
+ ${SYMBOLS_PATH}
+)
+
+###########################
+# Executable
+###########################
+
+add_definitions(
+ -w
+)
+
+add_executable(
+ indicator-sound-service-bin
+ ${INDICATOR_SOUND_SOURCES}
+)
+
+set_target_properties(
+ indicator-sound-service-bin
+ PROPERTIES
+ OUTPUT_NAME "indicator-sound-service"
+)
+
+target_link_libraries(
+ indicator-sound-service-bin
+ ${PULSEAUDIO_LIBRARIES}
+ ${SOUNDSERVICE_LIBRARIES}
+)
+
+###########################
+# Installation
+###########################
+
+install(
+ TARGETS indicator-sound-service-bin
+ RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/indicator-sound/
+)
+
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644
index da3df5b..0000000
--- a/src/Makefile.am
+++ /dev/null
@@ -1,36 +0,0 @@
-pkglibexec_PROGRAMS = indicator-sound-service
-
-indicator_sound_service_SOURCES = \
- service.vala \
- main.vala \
- volume-control.vala \
- media-player.vala \
- media-player-list.vala \
- mpris2-interfaces.vala \
- mpris2-watcher.vala \
- freedesktop-interfaces.vala
-
-indicator_sound_service_VALAFLAGS = \
- --ccode \
- --vapidir=$(top_srcdir)/vapi/ \
- --vapidir=./ \
- --thread \
- --pkg config \
- --pkg gio-2.0 \
- --pkg gio-unix-2.0 \
- --pkg libxml-2.0 \
- --pkg libpulse \
- --pkg libpulse-mainloop-glib \
- --target-glib=2.36
-
-# -w to disable warnings for vala-generated code
-indicator_sound_service_CFLAGS = $(PULSEAUDIO_CFLAGS) \
- $(SOUNDSERVICE_CFLAGS) \
- $(GCONF_CFLAGS) \
- $(COVERAGE_CFLAGS) \
- -DLIBEXECDIR=\"$(libexecdir)\" \
- -w \
- -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
-
-indicator_sound_service_LDADD = $(PULSEAUDIO_LIBS) $(SOUNDSERVICE_LIBS) $(GCONF_LIBS)
-indicator_sound_service_LDFLAGS = $(COVERAGE_LDFLAGS)
diff --git a/src/service.vala b/src/service.vala
index 3d14d5e..4d64502 100644
--- a/src/service.vala
+++ b/src/service.vala
@@ -17,28 +17,29 @@
* Lars Uebernickel <lars.uebernickel@canonical.com>
*/
-/* Icon.serialize() is not yet in gio-2.0.vapi; remove this when it is */
-extern Variant? g_icon_serialize (Icon icon);
-
public class IndicatorSound.Service {
public Service () {
this.settings = new Settings ("com.canonical.indicator.sound");
this.volume_control = new VolumeControl ();
- this.volume_control.notify["active-mic"].connect (active_mic_changed);
this.players = new MediaPlayerList ();
this.players.player_added.connect (this.player_added);
this.players.player_removed.connect (this.player_removed);
this.actions = new SimpleActionGroup ();
- this.actions.add_entries (action_entries, this);
+ this.actions.add_action_entries (action_entries, this);
this.actions.add_action (this.create_mute_action ());
this.actions.add_action (this.create_volume_action ());
this.actions.add_action (this.create_mic_volume_action ());
- this.menu = create_menu ();
- this.root_menu = create_root_menu (this.menu);
+ this.menus = new HashTable<string, SoundMenu> (str_hash, str_equal);
+ this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings"));
+ this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings"));
+
+ this.menus.@foreach ( (profile, menu) => {
+ this.volume_control.bind_property ("active-mic", menu, "show-mic-volume", BindingFlags.SYNC_CREATE);
+ });
this.players.sync (settings.get_strv ("interested-media-players"));
this.settings.changed["interested-media-players"].connect ( () => {
@@ -62,20 +63,20 @@ public class IndicatorSound.Service {
}
const ActionEntry[] action_entries = {
- { "root", null, null, "{ 'icon': <'audio-volume-high-panel'> }", null },
- { "settings", activate_settings, null, null, null },
+ { "root", null, null, "@a{sv} {}", null },
+ { "desktop-settings", activate_desktop_settings, null, null, null },
+ { "phone-settings", activate_phone_settings, null, null, null },
};
MainLoop loop;
SimpleActionGroup actions;
- Menu root_menu;
- Menu menu;
+ HashTable<string, SoundMenu> menus;
Settings settings;
VolumeControl volume_control;
MediaPlayerList players;
uint player_action_update_id;
- void activate_settings (SimpleAction action, Variant? param) {
+ void activate_desktop_settings (SimpleAction action, Variant? param) {
var env = Environment.get_variable ("DESKTOP_SESSION");
string cmd;
if (env == "unity")
@@ -92,55 +93,19 @@ public class IndicatorSound.Service {
}
}
- static Menu create_root_menu (Menu submenu) {
- var root = new MenuItem (null, "indicator.root");
- root.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root");
- root.set_submenu (submenu);
-
- var menu = new Menu ();
- menu.append_item (root);
-
- return menu;
- }
-
- static Menu create_menu () {
- var volume_section = new Menu ();
- volume_section.append (_("Mute"), "indicator.mute");
-
- var slider = new MenuItem (null, "indicator.volume");
- slider.set_attribute ("x-canonical-type", "s", "com.canonical.unity.slider");
- slider.set_attribute_value ("min-icon", g_icon_serialize (new ThemedIcon ("audio-volume-low-zero-panel")));
- slider.set_attribute_value ("max-icon", g_icon_serialize (new ThemedIcon ("audio-volume-high-panel")));
- slider.set_attribute ("min-value", "d", 0.0);
- slider.set_attribute ("max-value", "d", 1.0);
- slider.set_attribute ("step", "d", 0.01);
- volume_section.append_item (slider);
-
- var menu = new Menu ();
- menu.append_section (null, volume_section);
- menu.append (_("Sound Settings…"), "indicator.settings");
-
- return menu;
+ void activate_phone_settings (SimpleAction action, Variant? param) {
+ try {
+ Process.spawn_command_line_async ("system-settings sound");
+ } catch (Error e) {
+ warning ("unable to launch sound settings: %s", e.message);
+ }
}
- void active_mic_changed () {
- var volume_section = this.menu.get_item_link (0, "section") as Menu;
- if (this.volume_control.active_mic) {
- if (volume_section.get_n_items () < 3) {
- var slider = new MenuItem (null, "indicator.mic-volume");
- slider.set_attribute ("x-canonical-type", "s", "com.canonical.unity.slider");
- slider.set_attribute_value ("min-icon", g_icon_serialize (new ThemedIcon ("audio-input-microphone-low-zero-panel")));
- slider.set_attribute_value ("max-icon", g_icon_serialize (new ThemedIcon ("audio-input-microphone-high-panel")));
- slider.set_attribute ("min-value", "d", 0.0);
- slider.set_attribute ("max-value", "d", 1.0);
- slider.set_attribute ("step", "d", 0.01);
- volume_section.append_item (slider);
- }
- }
- else {
- if (volume_section.get_n_items () > 2)
- volume_section.remove (2);
- }
+ /* Returns a serialized version of @icon_name suited for the panel */
+ static Variant serialize_themed_icon (string icon_name)
+ {
+ var icon = new ThemedIcon.with_default_fallbacks (icon_name);
+ return g_icon_serialize (icon);
}
void update_root_icon () {
@@ -157,8 +122,20 @@ public class IndicatorSound.Service {
else
icon = "audio-volume-high-panel";
- var root_action = this.actions.lookup ("root") as SimpleAction;
- root_action.set_state (new Variant.parsed ("{ 'icon': <%s> }", icon));
+ string accessible_name;
+ if (this.volume_control.mute) {
+ accessible_name = "Volume (muted)";
+ } else {
+ int volume_int = (int)(volume * 100);
+ accessible_name = @"Volume ($volume_int%)";
+ }
+
+ var root_action = actions.lookup_action ("root") as SimpleAction;
+ var builder = new VariantBuilder (new VariantType ("a{sv}"));
+ builder.add ("{sv}", "accessible-desc", new Variant.string (accessible_name));
+ builder.add ("{sv}", "icon", serialize_themed_icon (icon));
+ builder.add ("{sv}", "visible", new Variant.boolean (true));
+ root_action.set_state (builder.end());
}
Action create_mute_action () {
@@ -181,7 +158,7 @@ public class IndicatorSound.Service {
}
void volume_changed (double volume) {
- var volume_action = this.actions.lookup ("volume") as SimpleAction;
+ var volume_action = this.actions.lookup_action ("volume") as SimpleAction;
volume_action.set_state (volume);
this.update_root_icon ();
@@ -220,10 +197,11 @@ public class IndicatorSound.Service {
void bus_acquired (DBusConnection connection, string name) {
try {
connection.export_action_group ("/com/canonical/indicator/sound", this.actions);
- connection.export_menu_model ("/com/canonical/indicator/sound/desktop", this.root_menu);
} catch (Error e) {
critical ("%s", e.message);
}
+
+ this.menus.@foreach ( (profile, menu) => menu.export (connection, @"/com/canonical/indicator/sound/$profile"));
}
void name_lost (DBusConnection connection, string name) {
@@ -245,7 +223,7 @@ public class IndicatorSound.Service {
bool update_player_actions () {
foreach (var player in this.players) {
- SimpleAction? action = this.actions.lookup (player.id) as SimpleAction;
+ SimpleAction? action = this.actions.lookup_action (player.id) as SimpleAction;
if (action != null)
action.set_state (this.action_state_for_player (player));
}
@@ -266,61 +244,16 @@ public class IndicatorSound.Service {
this.settings.set_value ("interested-media-players", builder.end ());
}
- void update_playlists (MediaPlayer player) {
- int index = find_player_section (player);
- if (index < 0)
- return;
-
- var section = this.menu.get_item_link (index, Menu.LINK_SECTION) as Menu;
-
- /* if a section has three items, the playlists menu is in it */
- if (section.get_n_items () == 3)
- section.remove (2);
-
- if (!player.is_running)
- return;
-
- var count = player.get_n_playlists ();
- if (count == 0)
- return;
-
- var playlists_section = new Menu ();
- for (int i = 0; i < count; i++) {
- var playlist_id = player.get_playlist_id (i);
- playlists_section.append (player.get_playlist_name (i),
- @"indicator.play-playlist.$(player.id)::$playlist_id");
-
- }
-
- var submenu = new Menu ();
- submenu.append_section (null, playlists_section);
- section.append_submenu ("Choose Playlist", submenu);
- }
-
void player_added (MediaPlayer player) {
- var player_item = new MenuItem (player.name, "indicator." + player.id);
- player_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.media-player");
- player_item.set_attribute_value ("icon", g_icon_serialize (player.icon));
-
- var playback_item = new MenuItem (null, null);
- playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item");
- playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
- playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
- playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
-
- var section = new Menu ();
- section.append_item (player_item);
- section.append_item (playback_item);
-
- this.menu.insert_section (this.menu.get_n_items () -1, null, section);
+ this.menus.@foreach ( (profile, menu) => menu.add_player (player));
SimpleAction action = new SimpleAction.stateful (player.id, null, this.action_state_for_player (player));
action.activate.connect ( () => { player.launch (); });
- this.actions.insert (action);
+ this.actions.add_action (action);
var play_action = new SimpleAction.stateful ("play." + player.id, null, player.state);
play_action.activate.connect ( () => player.play_pause () );
- this.actions.insert (play_action);
+ this.actions.add_action (play_action);
player.notify.connect ( (object, pspec) => {
if (pspec.name == "state")
play_action.set_state (player.state);
@@ -328,50 +261,29 @@ public class IndicatorSound.Service {
var next_action = new SimpleAction ("next." + player.id, null);
next_action.activate.connect ( () => player.next () );
- this.actions.insert (next_action);
+ this.actions.add_action (next_action);
var prev_action = new SimpleAction ("previous." + player.id, null);
prev_action.activate.connect ( () => player.previous () );
- this.actions.insert (prev_action);
+ this.actions.add_action (prev_action);
var playlist_action = new SimpleAction ("play-playlist." + player.id, VariantType.STRING);
playlist_action.activate.connect ( (parameter) => player.activate_playlist_by_name (parameter.get_string ()) );
- this.actions.insert (playlist_action);
+ this.actions.add_action (playlist_action);
player.notify.connect (this.eventually_update_player_actions);
- player.playlists_changed.connect (this.update_playlists);
- player.notify["is-running"].connect ( () => this.update_playlists (player) );
- update_playlists (player);
-
this.update_preferred_players ();
}
- /* returns the position in this.menu of the section that's associated with @player */
- int find_player_section (MediaPlayer player) {
- string action_name = @"indicator.$(player.id)";
- int n = this.menu.get_n_items () -1;
- for (int i = 1; i < n; i++) {
- var section = this.menu.get_item_link (i, Menu.LINK_SECTION);
- string action;
- section.get_item_attribute (0, "action", "s", out action);
- if (action == action_name)
- return i;
- }
-
- return -1;
- }
-
void player_removed (MediaPlayer player) {
- this.actions.remove (player.id);
- this.actions.remove ("play." + player.id);
- this.actions.remove ("next." + player.id);
- this.actions.remove ("previous." + player.id);
- this.actions.remove ("play-playlist." + player.id);
-
- int index = this.find_player_section (player);
- if (index >= 0)
- this.menu.remove (index);
+ this.actions.remove_action (player.id);
+ this.actions.remove_action ("play." + player.id);
+ this.actions.remove_action ("next." + player.id);
+ this.actions.remove_action ("previous." + player.id);
+ this.actions.remove_action ("play-playlist." + player.id);
+
+ this.menus.@foreach ( (profile, menu) => menu.remove_player (player));
this.update_preferred_players ();
}
diff --git a/src/sound-menu.vala b/src/sound-menu.vala
new file mode 100644
index 0000000..415a5be
--- /dev/null
+++ b/src/sound-menu.vala
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2013 Canonical Ltd.
+ *
+ * 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; version 3.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Lars Uebernickel <lars.uebernickel@canonical.com>
+ */
+
+/* Icon.serialize() is not yet in gio-2.0.vapi; remove this when it is */
+extern Variant? g_icon_serialize (Icon icon);
+
+class SoundMenu: Object
+{
+ public SoundMenu (string settings_action) {
+ /* A sound menu always has at least two sections: the volume section (this.volume_section)
+ * at the start of the menu, and the settings section at the end. Between those two,
+ * it has a dynamic amount of player sections, one for each registered player.
+ */
+
+ this.volume_section = new Menu ();
+ volume_section.append (_("Mute"), "indicator.mute");
+ volume_section.append_item (this.create_slider_menu_item ("indicator.volume", 0.0, 1.0, 0.01,
+ "audio-volume-low-zero-panel",
+ "audio-volume-high-panel"));
+
+ this.menu = new Menu ();
+ this.menu.append_section (null, volume_section);
+ this.menu.append (_("Sound Settings…"), settings_action);
+
+ var root_item = new MenuItem (null, "indicator.root");
+ root_item.set_attribute ("x-canonical-type", "s", "com.canonical.indicator.root");
+ root_item.set_submenu (this.menu);
+
+ this.root = new Menu ();
+ root.append_item (root_item);
+ }
+
+ public void export (DBusConnection connection, string object_path) {
+ try {
+ connection.export_menu_model (object_path, this.root);
+ } catch (Error e) {
+ critical ("%s", e.message);
+ }
+ }
+
+ public bool show_mic_volume {
+ get {
+ return this.volume_section.get_n_items () == 3;
+ }
+ set {
+ if (value && this.volume_section.get_n_items () < 3) {
+ var slider = this.create_slider_menu_item ("indicator.mic-volume", 0.0, 1.0, 0.01,
+ "audio-input-microphone-low-zero-panel",
+ "audio-input-microphone-high-panel");
+ volume_section.append_item (slider);
+ }
+ else if (!value && this.volume_section.get_n_items () > 2) {
+ this.volume_section.remove (2);
+ }
+ }
+ }
+
+ public void add_player (MediaPlayer player) {
+ /* Add new players to the end of the player sections, just before the settings */
+ var player_item = new MenuItem (player.name, "indicator." + player.id);
+ player_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.media-player");
+ player_item.set_attribute_value ("icon", g_icon_serialize (player.icon));
+
+ var playback_item = new MenuItem (null, null);
+ playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item");
+ playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
+ playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
+ playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
+
+ var section = new Menu ();
+ section.append_item (player_item);
+ section.append_item (playback_item);
+
+ player.playlists_changed.connect (this.update_playlists);
+ player.notify["is-running"].connect ( () => this.update_playlists (player) );
+ update_playlists (player);
+
+ this.menu.insert_section (this.menu.get_n_items () -1, null, section);
+ }
+
+ public void remove_player (MediaPlayer player) {
+ int index = this.find_player_section (player);
+ if (index >= 0)
+ this.menu.remove (index);
+ }
+
+ Menu root;
+ Menu menu;
+ Menu volume_section;
+
+ /* returns the position in this.menu of the section that's associated with @player */
+ int find_player_section (MediaPlayer player) {
+ string action_name = @"indicator.$(player.id)";
+ int n = this.menu.get_n_items () -1;
+ for (int i = 1; i < n; i++) {
+ var section = this.menu.get_item_link (i, Menu.LINK_SECTION);
+ string action;
+ section.get_item_attribute (0, "action", "s", out action);
+ if (action == action_name)
+ return i;
+ }
+
+ return -1;
+ }
+
+ void update_playlists (MediaPlayer player) {
+ int index = find_player_section (player);
+ if (index < 0)
+ return;
+
+ var player_section = this.menu.get_item_link (index, Menu.LINK_SECTION) as Menu;
+
+ /* if a section has three items, the playlists menu is in it */
+ if (player_section.get_n_items () == 3)
+ player_section.remove (2);
+
+ if (!player.is_running)
+ return;
+
+ var count = player.get_n_playlists ();
+ if (count == 0)
+ return;
+
+ var playlists_section = new Menu ();
+ for (int i = 0; i < count; i++) {
+ var playlist_id = player.get_playlist_id (i);
+ playlists_section.append (player.get_playlist_name (i),
+ @"indicator.play-playlist.$(player.id)::$playlist_id");
+
+ }
+
+ var submenu = new Menu ();
+ submenu.append_section (null, playlists_section);
+ player_section.append_submenu ("Choose Playlist", submenu);
+ }
+
+ MenuItem create_slider_menu_item (string action, double min, double max, double step, string min_icon_name, string max_icon_name) {
+ var min_icon = new ThemedIcon.with_default_fallbacks (min_icon_name);
+ var max_icon = new ThemedIcon.with_default_fallbacks (max_icon_name);
+
+ var slider = new MenuItem (null, action);
+ slider.set_attribute ("x-canonical-type", "s", "com.canonical.unity.slider");
+ slider.set_attribute_value ("min-icon", g_icon_serialize (min_icon));
+ slider.set_attribute_value ("max-icon", g_icon_serialize (max_icon));
+ slider.set_attribute ("min-value", "d", min);
+ slider.set_attribute ("max-value", "d", max);
+ slider.set_attribute ("step", "d", step);
+
+ return slider;
+ }
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/CMakeLists.txt
diff --git a/tests/Makefile.am b/tests/Makefile.am
deleted file mode 100644
index 8b13789..0000000
--- a/tests/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-