diff --git a/Makefile.am b/Makefile.am index ae2adb35..e30e1362 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,19 @@ SUBDIRS = man +if USE_DBUS + SUBDIRS += dbus/src dbus/data +else +if USE_DBUS_CLIENT + SUBDIRS += dbus/src dbus/data +endif +endif + bin_PROGRAMS = shairport-sync + +if USE_DBUS_CLIENT +noinst_PROGRAMS = dbus/src/shairport-sync-dbus-client +endif + shairport_sync_SOURCES = shairport.c rtsp.c mdns.c mdns_external.c common.c rtp.c player.c alac.c audio.c loudness.c AM_CFLAGS = -Wno-multichar -DSYSCONFDIR=\"$(sysconfdir)\" @@ -77,11 +90,18 @@ if USE_DNS_SD shairport_sync_SOURCES += mdns_dns_sd.c endif +if USE_DBUS +shairport_sync_SOURCES += dbus/src/dbus_service.c dbus/src/shairportsync.c +endif + install-exec-hook: if INSTALL_CONFIG_FILES [ -e $(DESTDIR)$(sysconfdir) ] || mkdir $(DESTDIR)$(sysconfdir) cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf.sample [ -f $(DESTDIR)$(sysconfdir)/shairport-sync.conf ] || cp scripts/shairport-sync.conf $(DESTDIR)$(sysconfdir)/shairport-sync.conf +if USE_DBUS + cp dbus/config/system-bus-policy/shairport-sync.conf $(DESTDIR)$(sysconfdir)/dbus-1/system.d/shairport-sync.conf +endif endif if INSTALL_SYSTEMV getent group shairport-sync &>/dev/null || groupadd -r shairport-sync >/dev/null diff --git a/configure.ac b/configure.ac index 0678afe3..c0851950 100644 --- a/configure.ac +++ b/configure.ac @@ -6,6 +6,7 @@ AC_INIT([shairport-sync], [3.2d6], [mikebrady@eircom.net]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([shairport.c]) AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) # Derived from the Avahi configure.ac file # Specifying the OS type, defaulting to linux. @@ -287,6 +288,29 @@ AC_ARG_WITH(dns_sd, [ --with-dns_sd = choose dns_sd mDNS support], [ AC_SEARCH_LIBS([DNSServiceRefDeallocate], [dns_sd], , AC_MSG_ERROR(dns_sd support requires the dns_sd library!))], ) AM_CONDITIONAL([USE_DNS_SD], [test "x$HAS_DNS_SD" = "x1"]) +# Look for dbus flag +AC_ARG_WITH(dbus, [ --with-dbus = choose dbus support], [ + AC_MSG_RESULT(>>Including dbus support) + HAS_DBUS=1 + AC_DEFINE([HAVE_DBUS], 1, [Needed by the compiler.]) + PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.30.0],[CFLAGS="${GIO_UNIX_CFLAGS} ${CFLAGS}" LIBS="${GIO_UNIX_LIBS} ${LIBS}"]) + ], ) +AM_CONDITIONAL([USE_DBUS], [test "x$HAS_DBUS" = "x1"]) + +# Look for dbus test client flag +AC_ARG_WITH(dbus-test-client, [ --with-dbus-test-client = compile dbus test client], [ + AC_MSG_RESULT(>>Including dbus test client) + HAS_DBUS_CLIENT=1 + AC_DEFINE([HAVE_DBUS_CLIENT], 1, [Needed by the compiler.]) + PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.30.0],[CFLAGS="${GIO_UNIX_CFLAGS} ${CFLAGS}" LIBS="${GIO_UNIX_LIBS} ${LIBS}"]) + ], ) +AM_CONDITIONAL([USE_DBUS_CLIENT], [test "x$HAS_DBUS_CLIENT" = "x1"]) + +AS_AC_EXPAND(DATADIR, $datadir) +DBUS_SERVICES_DIR="$DATADIR/dbus-1/services" +AC_SUBST(DBUS_SERVICES_DIR) +AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [This is where the local services directory for DBUS is located]) + if test "x${with_systemd}" = xyes ; then # Find systemd unit dir AC_ARG_WITH([systemdsystemunitdir], @@ -338,6 +362,6 @@ AC_FUNC_ERROR_AT_LINE AC_FUNC_FORK AC_CHECK_FUNCS([atexit clock_gettime gethostname inet_ntoa memchr memmove memset mkfifo pow select socket stpcpy strcasecmp strchr strdup strerror strstr strtol strtoul]) -AC_CONFIG_FILES([Makefile man/Makefile scripts/shairport-sync.service]) +AC_CONFIG_FILES([Makefile man/Makefile dbus/src/Makefile dbus/data/Makefile scripts/shairport-sync.service]) AC_CONFIG_FILES([scripts/shairport-sync],[chmod +x scripts/shairport-sync]) AC_OUTPUT diff --git a/dbus/config/system-bus-policy/shairport-sync.conf b/dbus/config/system-bus-policy/shairport-sync.conf new file mode 100644 index 00000000..0bbb97b8 --- /dev/null +++ b/dbus/config/system-bus-policy/shairport-sync.conf @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/dbus/data/Makefile.am b/dbus/data/Makefile.am new file mode 100644 index 00000000..aa407bc7 --- /dev/null +++ b/dbus/data/Makefile.am @@ -0,0 +1,16 @@ +# Dbus service file + +if USE_DBUS +servicedir = $(DBUS_SERVICES_DIR) +service_in_files = org.gnome.ShairportSync.service.in +service_DATA = $(service_in_files:.service.in=.service) +EXTRA_DIST = $(service_in_files) + +# Rule to make the service file with bindir expanded +$(service_DATA): $(service_in_files) Makefile + @sed -e "s|\@bindir\@|$(bindir)|" $<> $@ + +clean-local: + rm -rf $(service_DATA) + +endif diff --git a/dbus/data/org.gnome.ShairportSync.service.in b/dbus/data/org.gnome.ShairportSync.service.in new file mode 100644 index 00000000..99640f9b --- /dev/null +++ b/dbus/data/org.gnome.ShairportSync.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.gnome.ShairportSync +Exec=@bindir@/shairport-sync diff --git a/dbus/sample dbus-send calls b/dbus/sample dbus-send calls new file mode 100644 index 00000000..7732d803 --- /dev/null +++ b/dbus/sample dbus-send calls @@ -0,0 +1,42 @@ +dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync \ +org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" \ +string:"LoudnessFilterActive" variant:boolean:true + + + + +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync \ +> org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" \ +> string:"LoudnessFilterActive" variant:boolean:true +method return time=1505039217.715753 sender=:1.87 -> destination=:1.91 serial=27 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"LoudnessThreshold" variant:double:-10.0 +method return time=1505039378.650185 sender=:1.87 -> destination=:1.92 serial=61 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-13.5 +method return time=1505039453.757603 sender=:1.87 -> destination=:1.93 serial=73 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-13.5 +method return time=1505039476.152207 sender=:1.87 -> destination=:1.94 serial=75 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-10.0 +method return time=1505039495.549155 sender=:1.87 -> destination=:1.95 serial=76 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-10.0 +method return time=1505039508.765168 sender=:1.87 -> destination=:1.96 serial=78 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-6 +method return time=1505039515.416719 sender=:1.87 -> destination=:1.97 serial=79 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-10 +method return time=1505039537.148590 sender=:1.87 -> destination=:1.98 serial=81 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:0 +method return time=1505039553.095614 sender=:1.87 -> destination=:1.99 serial=83 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-30 +method return time=1505039569.235297 sender=:1.87 -> destination=:1.100 serial=85 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-29 +method return time=1505039585.083032 sender=:1.87 -> destination=:1.101 serial=87 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-20 +method return time=1505039591.981307 sender=:1.87 -> destination=:1.102 serial=89 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-15 +method return time=1505039605.035592 sender=:1.87 -> destination=:1.103 serial=91 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-144 +method return time=1505039689.227557 sender=:1.87 -> destination=:1.104 serial=93 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-143 +method return time=1505039702.614409 sender=:1.87 -> destination=:1.105 serial=95 reply_serial=2 +mike@ubuntu:~/sps$ dbus-send --system --print-reply --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:"org.gnome.ShairportSync" string:"Volume" variant:double:-10 +method return time=1505039728.154118 sender=:1.87 -> destination=:1.106 serial=97 reply_serial=2 + diff --git a/dbus/src/Makefile.am b/dbus/src/Makefile.am new file mode 100644 index 00000000..6ff20c44 --- /dev/null +++ b/dbus/src/Makefile.am @@ -0,0 +1,20 @@ +if USE_DBUS_CLIENT + noinst_PROGRAMS = shairport-sync-dbus-client + shairport_sync_dbus_client_SOURCES = shairportsync.c shairportsync.h shairport-sync-dbus-client.c +endif + +BUILT_SOURCES = shairportsync.h shairportsync.c +# We don't want to install this header +noinst_HEADERS = $(BUILT_SOURCES) + +# Correctly clean the generated headers, but keep the xml description +CLEANFILES = $(BUILT_SOURCES) +EXTRA_DIST = org.gnome.ShairportSync.xml + +#Rule to generate the binding headers +shairportsync.h: org.gnome.ShairportSync.xml + gdbus-codegen --interface-prefix org.gnome --generate-c-code shairportsync org.gnome.ShairportSync.xml + +shairportsync.c: org.gnome.ShairportSync.xml + gdbus-codegen --interface-prefix org.gnome --generate-c-code shairportsync org.gnome.ShairportSync.xml + diff --git a/dbus/src/dbus_service.c b/dbus/src/dbus_service.c new file mode 100644 index 00000000..029a5c5a --- /dev/null +++ b/dbus/src/dbus_service.c @@ -0,0 +1,74 @@ +#include + +#include "../../config.h" + +#include "../../common.h" +#include "../../player.h" +#include "../../rtsp.h" + +#include "dbus_service.h" + +void notify_loudness_filter_active_callback(ShairportSync *skeleton, gpointer user_data) { + debug(1,"\"notify_loudness_filter_active_callback\" called with a gpointer of %lx.",(int64_t)user_data); + if (shairport_sync_get_loudness_filter_active (skeleton)) { + debug(1,"activating loudness filter"); + config.loudness = 1; + } else { + debug(1,"deactivating loudness filter"); + config.loudness = 0; + } +} + +void notify_loudness_threshold_callback(ShairportSync *skeleton, gpointer user_data) { + gdouble th = shairport_sync_get_loudness_threshold (skeleton); + if ((th <= 0.0) && (th >= -100.0)) { + debug(1,"Setting loudness threshhold to %f.",th); + config.loudness_reference_volume_db = th; + } else { + debug(1,"Invalid loudness threshhold: %f. Ignored.",th); + } +} + +void notify_volume_callback(ShairportSync *skeleton, gpointer user_data) { + gdouble vo = shairport_sync_get_volume (skeleton); + if (((vo <= 0.0) && (vo >= -30.0)) || (vo == -144.0)) { + debug(1,"Setting volume to %f.",vo); + if (playing_conn) + player_volume_without_notification(vo,playing_conn); + else + debug(1,"no thread playing -- ignored."); + } else { + debug(1,"Invalid volume: %f -- ignored.",vo); + } +} + +static void on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data) { + + skeleton = shairport_sync_skeleton_new(); + + g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skeleton), connection, + "/org/gnome/ShairportSync", NULL); + + shairport_sync_set_loudness_threshold(SHAIRPORT_SYNC(skeleton), config.loudness_reference_volume_db); + debug(1,"Loudness threshold is %f.",config.loudness_reference_volume_db); + + if (config.loudness==0) { + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(skeleton), FALSE); + debug(1,"Loudness is off"); + } else { + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(skeleton), TRUE); + debug(1,"Loudness is on"); + } + + g_signal_connect(skeleton, "notify::loudness-filter-active", G_CALLBACK(notify_loudness_filter_active_callback), NULL); + g_signal_connect(skeleton, "notify::loudness-threshold", G_CALLBACK(notify_loudness_threshold_callback), NULL); + g_signal_connect(skeleton, "notify::volume", G_CALLBACK(notify_volume_callback), NULL); + +} + +int start_dbus_service() { + skeleton = NULL; + g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.gnome.ShairportSync", G_BUS_NAME_OWNER_FLAGS_NONE, NULL, + on_name_acquired, NULL, NULL, NULL); + // G_BUS_TYPE_SESSION or G_BUS_TYPE_SYSTEM +} diff --git a/dbus/src/dbus_service.h b/dbus/src/dbus_service.h new file mode 100644 index 00000000..91103123 --- /dev/null +++ b/dbus/src/dbus_service.h @@ -0,0 +1,11 @@ + +#ifndef DBUS_SERVICE_H +#define DBUS_SERVICE_H + +#include "shairportsync.h" + +ShairportSync *skeleton; + +int start_dbus_service(); + +#endif /* #ifndef DBUS_SERVICE_H */ diff --git a/dbus/src/org.gnome.ShairportSync.xml b/dbus/src/org.gnome.ShairportSync.xml new file mode 100644 index 00000000..d4a8e3ac --- /dev/null +++ b/dbus/src/org.gnome.ShairportSync.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/dbus/src/shairport-sync-dbus-client.c b/dbus/src/shairport-sync-dbus-client.c new file mode 100644 index 00000000..0237ac04 --- /dev/null +++ b/dbus/src/shairport-sync-dbus-client.c @@ -0,0 +1,128 @@ + +#include "shairportsync.h" +#include +#include + +GMainLoop *loop; + +void on_properties_changed (GDBusProxy *proxy, + GVariant *changed_properties, + const gchar* const *invalidated_properties, + gpointer user_data) +{ + /* Note that we are guaranteed that changed_properties and + * invalidated_properties are never NULL + */ + + if (g_variant_n_children (changed_properties) > 0) + { + GVariantIter *iter; + const gchar *key; + GVariant *value; + + g_print (" *** Properties Changed:\n"); + g_variant_get (changed_properties, + "a{sv}", + &iter); + while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) + { + gchar *value_str; + value_str = g_variant_print (value, TRUE); + g_print (" %s -> %s\n", key, value_str); + g_free (value_str); + } + g_variant_iter_free (iter); + } + + if (g_strv_length ((GStrv) invalidated_properties) > 0) + { + guint n; + g_print (" *** Properties Invalidated:\n"); + for (n = 0; invalidated_properties[n] != NULL; n++) + { + const gchar *key = invalidated_properties[n]; + g_print (" %s\n", key); + } + } +} + + +void notify_loudness_filter_active_callback(ShairportSync *proxy, gpointer user_data) { +// printf("\"notify_loudness_filter_active_callback\" called with a gpointer of %lx.\n",(int64_t)user_data); + gboolean ebl = shairport_sync_get_loudness_filter_active (proxy); + if (ebl == TRUE) + printf("Client reports loudness is enabled.\n"); + else + printf("Client reports loudness is disabled.\n"); +} + +void notify_loudness_threshold_callback(ShairportSync *proxy, gpointer user_data) { + gdouble th = shairport_sync_get_loudness_threshold (proxy); + printf("Client reports loudness threshold set to %.2f dB.\n",th); +} + +void notify_volume_callback(ShairportSync *proxy, gpointer user_data) { + gdouble th = shairport_sync_get_volume (proxy); + printf("Client reports volume set to %.2f dB.\n",th); +} + +pthread_t dbus_thread; +void *dbus_thread_func(void *arg) { + + loop = g_main_loop_new(NULL, FALSE); + + g_main_loop_run(loop); + +// dbus_service_main(); // let it run inside a thread +} + + +void main(void) { + + pthread_create(&dbus_thread, NULL, &dbus_thread_func, NULL); + + ShairportSync *proxy; + GError *error = NULL; + + proxy = shairport_sync_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.ShairportSync", "/org/gnome/ShairportSync", NULL, &error); + + + + // g_signal_connect(proxy, "notify::loudness-filter-active", G_CALLBACK(notify_loudness_filter_active_callback), NULL); + + g_signal_connect (proxy, + "g-properties-changed", + G_CALLBACK (on_properties_changed), + NULL); + g_signal_connect(proxy, "notify::loudness-threshold", G_CALLBACK(notify_loudness_threshold_callback), NULL); + g_signal_connect(proxy, "notify::volume", G_CALLBACK(notify_volume_callback), NULL); + + g_print("Starting test...\n"); + + shairport_sync_set_volume(SHAIRPORT_SYNC(proxy), -20.0); + sleep(10); + shairport_sync_set_volume(SHAIRPORT_SYNC(proxy), -10.0); + sleep(10); + shairport_sync_set_volume(SHAIRPORT_SYNC(proxy), 0.0); + sleep(10); + + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(proxy), FALSE); + sleep(15); + shairport_sync_set_loudness_threshold(SHAIRPORT_SYNC(proxy), -20.0); + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(proxy), TRUE); + sleep(15); + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(proxy), FALSE); + sleep(5); + shairport_sync_set_loudness_threshold(SHAIRPORT_SYNC(proxy), -10.0); + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(proxy), TRUE); + sleep(15); + shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(proxy), TRUE); + sleep(15); + g_print("Finished test...\n"); + g_main_loop_quit(loop); + pthread_join(dbus_thread,NULL); + printf("exiting program.\n"); + + g_object_unref(proxy); +} diff --git a/m4/acinclude.m4 b/m4/acinclude.m4 new file mode 100644 index 00000000..577e312f --- /dev/null +++ b/m4/acinclude.m4 @@ -0,0 +1,40 @@ +dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR) +dnl +dnl example +dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir) +dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local + +AC_DEFUN([AS_AC_EXPAND], +[ + EXP_VAR=[$1] + FROM_VAR=[$2] + + dnl first expand prefix and exec_prefix if necessary + prefix_save=$prefix + exec_prefix_save=$exec_prefix + + dnl if no prefix given, then use /usr/local, the default prefix + if test "x$prefix" = "xNONE"; then + prefix=$ac_default_prefix + fi + dnl if no exec_prefix given, then use prefix + if test "x$exec_prefix" = "xNONE"; then + exec_prefix=$prefix + fi + + full_var="$FROM_VAR" + dnl loop until it doesn't change anymore + while true; do + new_full_var="`eval echo $full_var`" + if test "x$new_full_var"="x$full_var"; then break; fi + full_var=$new_full_var + done + + dnl clean up + full_var=$new_full_var + AC_SUBST([$1], "$full_var") + + dnl restore prefix and exec_prefix + prefix=$prefix_save + exec_prefix=$exec_prefix_save +]) \ No newline at end of file diff --git a/player.c b/player.c index 091a193d..d50c3da3 100644 --- a/player.c +++ b/player.c @@ -69,6 +69,15 @@ #include #endif +#if defined(HAVE_DBUS) +#include +#endif + +#ifdef HAVE_DBUS +#include "dbus/src/dbus_service.h" +#include "dbus/src/shairportsync.h" +#endif + #include "common.h" #include "player.h" #include "rtp.h" @@ -2204,7 +2213,7 @@ static void *player_thread_func(void *arg) { } // takes the volume as specified by the airplay protocol -void player_volume(double airplay_volume, rtsp_conn_info *conn) { +void player_volume_without_notification(double airplay_volume, rtsp_conn_info *conn) { // The volume ranges -144.0 (mute) or -30 -- 0. See // http://git.zx2c4.com/Airtunes2/about/#setting-volume @@ -2236,7 +2245,6 @@ void player_volume(double airplay_volume, rtsp_conn_info *conn) { // Thus, we ask our vol2attn function for an appropriate dB between -96.3 and 0 dB and translate // it back to a number. - command_set_volume(airplay_volume); int32_t hw_min_db, hw_max_db, hw_range_db, range_to_use, min_db, max_db; // hw_range_db is a flag; if 0 means no mixer @@ -2427,6 +2435,14 @@ void player_volume(double airplay_volume, rtsp_conn_info *conn) { #endif } +void player_volume(double airplay_volume, rtsp_conn_info *conn) { + command_set_volume(airplay_volume); + #ifdef HAVE_DBUS + shairport_sync_set_volume(SHAIRPORT_SYNC(skeleton), airplay_volume); + #endif + player_volume_without_notification(airplay_volume, conn); +} + void player_flush(int64_t timestamp, rtsp_conn_info *conn) { debug(3, "Flush requested up to %u. It seems as if 0 is special.", timestamp); pthread_mutex_lock(&conn->flush_mutex); diff --git a/player.h b/player.h index db612e0b..a8661f57 100644 --- a/player.h +++ b/player.h @@ -165,6 +165,7 @@ int player_play(rtsp_conn_info *conn); void player_stop(rtsp_conn_info *conn); void player_volume(double f, rtsp_conn_info *conn); +void player_volume_without_notification(double f, rtsp_conn_info *conn); void player_flush(int64_t timestamp, rtsp_conn_info *conn); void player_put_packet(seq_t seqno, int64_t timestamp, uint8_t *data, int len, rtsp_conn_info *conn); diff --git a/rtsp.c b/rtsp.c index f1ae9a37..d937a09e 100644 --- a/rtsp.c +++ b/rtsp.c @@ -62,6 +62,7 @@ #include "mdns.h" #include "player.h" #include "rtp.h" +#include "rtsp.h" #ifdef AF_INET6 #define INETx_ADDRSTRLEN INET6_ADDRSTRLEN @@ -93,8 +94,6 @@ static pthread_mutex_t reference_counter_lock = PTHREAD_MUTEX_INITIALIZER; // static int please_shutdown = 0; // static pthread_t playing_thread = 0; -static rtsp_conn_info *playing_conn = - NULL; // the data structure representing the connection that has the player. static rtsp_conn_info **conns = NULL; int RTSP_connection_index = 0; @@ -1878,6 +1877,8 @@ void rtsp_listen_loop(void) { int *sockfd = NULL; int nsock = 0; int i, ret; + + playing_conn = NULL; // the data structure representing the connection that has the player. memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; diff --git a/rtsp.h b/rtsp.h index 5058c9a1..ec4d5525 100644 --- a/rtsp.h +++ b/rtsp.h @@ -1,6 +1,10 @@ #ifndef _RTSP_H #define _RTSP_H +#include "player.h" + +rtsp_conn_info *playing_conn; + void rtsp_listen_loop(void); // void rtsp_shutdown_stream(void); void rtsp_request_shutdown_stream(void); diff --git a/shairport.c b/shairport.c index 6249d636..8668f7bc 100644 --- a/shairport.c +++ b/shairport.c @@ -55,6 +55,14 @@ #include #endif +#if defined(HAVE_DBUS) +#include +#endif + +#ifdef HAVE_DBUS +#include "dbus/src/dbus_service.h" +#endif + #include "common.h" #include "mdns.h" #include "rtp.h" @@ -897,6 +905,16 @@ int parse_options(int argc, char **argv) { return optind + 1; } +#if defined(HAVE_DBUS) || defined (HAVE_MPRIS) +GMainLoop *loop; + +pthread_t dbus_thread; +void *dbus_thread_func(void *arg) { + loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(loop); +} +#endif + void signal_setup(void) { // mask off all signals before creating threads. // this way we control which thread gets which signals. @@ -1402,6 +1420,16 @@ int main(int argc, char **argv) { #ifdef CONFIG_METADATA metadata_init(); // create the metadata pipe if necessary #endif + +#if defined(HAVE_DBUS) + // Start up DBUS services after initial settings are all made + debug(1,"Starting up D-Bus services"); + pthread_create(&dbus_thread, NULL, &dbus_thread_func, NULL); + #ifdef HAVE_DBUS + start_dbus_service(); + #endif +#endif + daemon_log(LOG_INFO, "Successful Startup"); rtsp_listen_loop();