From: Mike Brady Date: Sat, 24 Mar 2018 17:48:32 +0000 (+0000) Subject: Add some more D-Bus facilities. Countermand faulty D-Bus commands. X-Git-Tag: 3.2RC1~7^2~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbbe84d8ba5bdd9f88fb9358275d3a8f52d280f9;p=thirdparty%2Fshairport-sync.git Add some more D-Bus facilities. Countermand faulty D-Bus commands. --- diff --git a/dacp.c b/dacp.c index cafe1636..542f9890 100644 --- a/dacp.c +++ b/dacp.c @@ -328,7 +328,8 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { pthread_cond_wait(&dacp_server_information_cv, &dacp_server_information_lock); } scan_index++; - result = dacp_get_volume(NULL); // just want the http code + int32_t the_volume; + result = dacp_get_volume(&the_volume); // just want the http code if ((result == 496) || (result == 403) || (result == 501)) { // debug(1,"Stopping scan because the response to \"dacp_get_volume(NULL)\" is %d.",result); dacp_server.scan_enable = 0; @@ -351,6 +352,13 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { metadata_hub_modify_epilog(diff); if (result == 200) { + + metadata_hub_modify_prolog(); + int diff = metadata_store.speaker_volume != the_volume; + if (diff) + metadata_store.speaker_volume = the_volume; + metadata_hub_modify_epilog(diff); + ssize_t le; char *response = NULL; int32_t item_size; @@ -360,17 +368,17 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { // debug(1,"Command: \"%s\"",command); result = dacp_send_command(command, &response, &le); // debug(1,"Response to \"%s\" is %d.",command,result); - // if (result == 200) { - if (0) { + if (result == 200) { + // if (0) { char *sp = response; if (le >= 8) { // here start looking for the contents of the status update if (dacp_tlv_crawl(&sp, &item_size) == 'cmst') { // status // here, we know that we are receiving playerstatusupdates, so set a flag metadata_hub_modify_prolog(); - debug(1, "playstatusupdate release track metadata"); - metadata_hub_reset_track_metadata(); - metadata_store.playerstatusupdates_are_received = 1; + // debug(1, "playstatusupdate release track metadata"); + // metadata_hub_reset_track_metadata(); + // metadata_store.playerstatusupdates_are_received = 1; sp -= item_size; // drop down into the array -- don't skip over it le -= 8; // char typestring[5]; @@ -454,18 +462,18 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { r = *(unsigned char *)(t); switch (r) { case 0: - if (metadata_store.repeat_status != RS_NONE) { - metadata_store.repeat_status = RS_NONE; + if (metadata_store.repeat_status != RS_OFF) { + metadata_store.repeat_status = RS_OFF; metadata_store.repeat_status_changed = 1; debug(1, "Repeat status changed to \"none\"."); metadata_store.changed = 1; } break; case 1: - if (metadata_store.repeat_status != RS_SINGLE) { - metadata_store.repeat_status = RS_SINGLE; + if (metadata_store.repeat_status != RS_ONE) { + metadata_store.repeat_status = RS_ONE; metadata_store.repeat_status_changed = 1; - debug(1, "Repeat status changed to \"single\"."); + debug(1, "Repeat status changed to \"one\"."); metadata_store.changed = 1; } break; @@ -482,6 +490,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { break; } break; + /* case 'cann': // track name t = sp - item_size; if ((metadata_store.track_name == NULL) || @@ -551,6 +560,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { metadata_store.changed = 1; } break; + */ case 'astm': t = sp - item_size; r = ntohl(*(uint32_t *)(t)); diff --git a/dbus-service.c b/dbus-service.c index 2de21564..5a1689de 100644 --- a/dbus-service.c +++ b/dbus-service.c @@ -20,14 +20,10 @@ ShairportSyncRemoteControl *shairportSyncRemoteControlSkeleton; ShairportSyncAdvancedRemoteControl *shairportSyncAdvancedRemoteControlSkeleton; void dbus_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused)) void *userdata) { - // debug(1, "DBUS metadata watcher called"); + shairport_sync_advanced_remote_control_set_volume(shairportSyncAdvancedRemoteControlSkeleton, argc->speaker_volume); - // debug(1, "No diagnostics watcher required"); - - // debug(1, "DBUS remote control watcher called"); - shairport_sync_remote_control_set_airplay_volume(shairportSyncRemoteControlSkeleton, argc->airplay_volume); @@ -47,6 +43,81 @@ void dbus_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused)) FALSE); } + switch (argc->player_state) { + case PS_NOT_AVAILABLE: + shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, + "Not Available"); + case PS_STOPPED: + shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, "Stopped"); + break; + case PS_PAUSED: + shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, "Paused"); + break; + case PS_PLAYING: + shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, "Playing"); + break; + default: + debug(1, "This should never happen."); + } + + switch (argc->play_status) { + case PS_NOT_AVAILABLE: + shairport_sync_advanced_remote_control_set_playback_status( + shairportSyncAdvancedRemoteControlSkeleton, "Not Available"); + case PS_STOPPED: + shairport_sync_advanced_remote_control_set_playback_status( + shairportSyncAdvancedRemoteControlSkeleton, "Stopped"); + break; + case PS_PAUSED: + shairport_sync_advanced_remote_control_set_playback_status( + shairportSyncAdvancedRemoteControlSkeleton, "Paused"); + break; + case PS_PLAYING: + shairport_sync_advanced_remote_control_set_playback_status( + shairportSyncAdvancedRemoteControlSkeleton, "Playing"); + break; + default: + debug(1, "This should never happen."); + } + + switch (argc->repeat_status) { + case RS_NOT_AVAILABLE: + shairport_sync_advanced_remote_control_set_loop_status( + shairportSyncAdvancedRemoteControlSkeleton, "Not Available"); + break; + case RS_OFF: + shairport_sync_advanced_remote_control_set_loop_status( + shairportSyncAdvancedRemoteControlSkeleton, "Off"); + break; + case RS_ONE: + shairport_sync_advanced_remote_control_set_loop_status( + shairportSyncAdvancedRemoteControlSkeleton, "One"); + break; + case RS_ALL: + shairport_sync_advanced_remote_control_set_loop_status( + shairportSyncAdvancedRemoteControlSkeleton, "All"); + break; + default: + debug(1, "This should never happen."); + } + + switch (argc->shuffle_status) { + case SS_NOT_AVAILABLE: + shairport_sync_advanced_remote_control_set_shuffle(shairportSyncAdvancedRemoteControlSkeleton, + FALSE); + break; + case SS_OFF: + shairport_sync_advanced_remote_control_set_shuffle(shairportSyncAdvancedRemoteControlSkeleton, + FALSE); + break; + case SS_ON: + shairport_sync_advanced_remote_control_set_shuffle(shairportSyncAdvancedRemoteControlSkeleton, + TRUE); + break; + default: + debug(1, "This should never happen."); + } + GVariantBuilder *dict_builder, *aa; /* Build the metadata array */ @@ -276,6 +347,7 @@ gboolean notify_verbosity_callback(ShairportSyncDiagnostics *skeleton, debug(1, ">> log verbosity set to %d.", th); } else { debug(1, ">> invalid log verbosity: %d. Ignored.", th); + shairport_sync_diagnostics_set_verbosity(skeleton, debuglev); } return TRUE; } @@ -301,6 +373,7 @@ gboolean notify_loudness_threshold_callback(ShairportSync *skeleton, config.loudness_reference_volume_db = th; } else { debug(1, "Invalid loudness threshhold: %f. Ignored.", th); + shairport_sync_set_loudness_threshold(skeleton, config.loudness_reference_volume_db); } return TRUE; } @@ -313,17 +386,25 @@ gboolean notify_alacdecoder_callback(ShairportSync *skeleton, config.use_apple_decoder = 0; else if (strcasecmp(th, "apple") == 0) config.use_apple_decoder = 1; - else - warn("Unrecognised ALAC decoder: \"%s\".", th); + else { + warn("An unrecognised ALAC decoder: \"%s\" was requested via D-Bus interface.", th); + if (config.use_apple_decoder == 0) + shairport_sync_set_alacdecoder(skeleton, "hammerton"); + else + shairport_sync_set_alacdecoder(skeleton, "apple"); + } // debug(1,"Using the %s ALAC decoder.", ((config.use_apple_decoder==0) ? "Hammerton" : "Apple")); #else if (strcasecmp(th, "hammerton") == 0) { config.use_apple_decoder = 0; // debug(1,"Using the Hammerton ALAC decoder."); - } else - warn("Unrecognised ALAC decoder: \"%s\" (or else support for this decoder was not compiled " - "into this version of Shairport Sync).", + } else { + warn("An unrecognised ALAC decoder: \"%s\" was requested via D-Bus interface. (Possibly " + "support for this decoder was not compiled " + "into this version of Shairport Sync.)", th); + shairport_sync_set_alacdecoder(skeleton, "hammerton"); + } #endif return TRUE; } @@ -336,35 +417,106 @@ gboolean notify_interpolation_callback(ShairportSync *skeleton, config.packet_stuffing = ST_basic; else if (strcasecmp(th, "soxr") == 0) config.packet_stuffing = ST_soxr; - else - warn("Unrecognised interpolation: \"%s\".", th); + else { + warn("An unrecognised interpolation method: \"%s\" was requested via the D-Bus interface.", th); + switch (config.packet_stuffing) { + case ST_basic: + shairport_sync_set_interpolation(skeleton, "basic"); + break; + case ST_soxr: + shairport_sync_set_interpolation(skeleton, "soxr"); + break; + default: + debug(1, "This should never happen!"); + shairport_sync_set_interpolation(skeleton, "basic"); + break; + } + } #else if (strcasecmp(th, "basic") == 0) config.packet_stuffing = ST_basic; -} -else warn("Unrecognised interpolation method: \"%s\" (or else support for this interolation method " - "was not compiled into this version of Shairport Sync).", - th); + else { + warn("An unrecognised interpolation method: \"%s\" was requested via the D-Bus interface. " + "(Possibly support for this method was not compiled " + "into this version of Shairport Sync.)", + th); + shairport_sync_set_interpolation(skeleton, "basic"); + } #endif - debug(1, "Using %s interpolation (aka \"stuffing\").", - ((config.packet_stuffing == ST_basic) ? "basic" : "soxr")); return TRUE; } gboolean notify_volume_control_profile_callback(ShairportSync *skeleton, __attribute__((unused)) gpointer user_data) { char *th = (char *)shairport_sync_get_volume_control_profile(skeleton); - enum volume_control_profile_type previous_volume_control_profile = config.volume_control_profile; + // enum volume_control_profile_type previous_volume_control_profile = + // config.volume_control_profile; if (strcasecmp(th, "standard") == 0) config.volume_control_profile = VCP_standard; else if (strcasecmp(th, "flat") == 0) config.volume_control_profile = VCP_flat; - else + else { warn("Unrecognised Volume Control Profile: \"%s\".", th); - debug(1, "Using the %s Volume Control Profile.", - ((config.volume_control_profile == VCP_standard) ? "Standard" : "Flat")); - if (previous_volume_control_profile != config.volume_control_profile) - debug(1, "Should really reset volume now, maybe?"); + switch (config.volume_control_profile) { + case VCP_standard: + shairport_sync_set_volume_control_profile(skeleton, "standard"); + break; + case VCP_flat: + shairport_sync_set_volume_control_profile(skeleton, "flat"); + break; + default: + debug(1, "This should never happen!"); + shairport_sync_set_volume_control_profile(skeleton, "standard"); + break; + } + } + return TRUE; +} + +gboolean notify_shuffle_callback(ShairportSyncAdvancedRemoteControl *skeleton, + __attribute__((unused)) gpointer user_data) { + // debug(1,"notify_shuffle_callback called"); + if (shairport_sync_advanced_remote_control_get_shuffle(skeleton)) + send_simple_dacp_command("setproperty?dacp.shufflestate=1"); + else + send_simple_dacp_command("setproperty?dacp.shufflestate=0"); + ; + return TRUE; +} + +gboolean notify_loop_status_callback(ShairportSyncAdvancedRemoteControl *skeleton, + __attribute__((unused)) gpointer user_data) { + // debug(1,"notify_loop_status_callback called"); + char *th = (char *)shairport_sync_advanced_remote_control_get_loop_status(skeleton); + // enum volume_control_profile_type previous_volume_control_profile = + // config.volume_control_profile; + if (strcasecmp(th, "off") == 0) + send_simple_dacp_command("setproperty?dacp.repeatstate=0"); + else if (strcasecmp(th, "one") == 0) + send_simple_dacp_command("setproperty?dacp.repeatstate=1"); + else if (strcasecmp(th, "all") == 0) + send_simple_dacp_command("setproperty?dacp.repeatstate=2"); + else if (strcasecmp(th, "not available") != 0) { + warn("Illegal Loop Request: \"%s\".", th); + switch (metadata_store.repeat_status) { + case RS_NOT_AVAILABLE: + shairport_sync_advanced_remote_control_set_loop_status(skeleton, "Not Available"); + break; + case RS_OFF: + shairport_sync_advanced_remote_control_set_loop_status(skeleton, "Off"); + break; + case RS_ONE: + shairport_sync_advanced_remote_control_set_loop_status(skeleton, "One"); + break; + case RS_ALL: + shairport_sync_advanced_remote_control_set_loop_status(skeleton, "All"); + break; + default: + debug(1, "This should never happen!"); + shairport_sync_advanced_remote_control_set_loop_status(skeleton, "Off"); + break; + } + } return TRUE; } @@ -457,6 +609,12 @@ static void on_dbus_name_acquired(GDBusConnection *connection, const gchar *name g_signal_connect(shairportSyncAdvancedRemoteControlSkeleton, "handle-set-volume", G_CALLBACK(on_handle_set_volume), NULL); + g_signal_connect(shairportSyncAdvancedRemoteControlSkeleton, "notify::shuffle", + G_CALLBACK(notify_shuffle_callback), NULL); + + g_signal_connect(shairportSyncAdvancedRemoteControlSkeleton, "notify::loop-status", + G_CALLBACK(notify_loop_status_callback), NULL); + add_metadata_watcher(dbus_metadata_watcher, NULL); shairport_sync_set_loudness_threshold(SHAIRPORT_SYNC(shairportSyncSkeleton), @@ -532,6 +690,11 @@ static void on_dbus_name_acquired(GDBusConnection *connection, const gchar *name // debug(1, ">> delta time is not included in log entries"); } + shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, + "Not Available"); + shairport_sync_advanced_remote_control_set_playback_status( + shairportSyncAdvancedRemoteControlSkeleton, "Not Available"); + debug(1, "Shairport Sync native D-Bus service started at \"%s\" on the %s bus.", name, (config.dbus_service_bus_type == DBT_session) ? "session" : "system"); } diff --git a/metadata_hub.c b/metadata_hub.c index 2d024f83..910de544 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -455,6 +455,8 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin metadata_hub_modify_epilog(1); } break; + // these could tell us about play / pause etc. but will only occur if metadata is enabled, so + // we'll just ignore them case 'pbeg': case 'pend': case 'pfls': diff --git a/metadata_hub.h b/metadata_hub.h index 36dd8207..ce0505d8 100644 --- a/metadata_hub.h +++ b/metadata_hub.h @@ -6,19 +6,22 @@ #define number_of_watchers 2 enum play_status_type { - PS_STOPPED = 0, + PS_NOT_AVAILABLE = 0, + PS_STOPPED, PS_PAUSED, PS_PLAYING, } play_status_type; enum shuffle_status_type { - SS_OFF = 0, + SS_NOT_AVAILABLE = 0, + SS_OFF, SS_ON, } shuffle_status_type; enum repeat_status_type { - RS_NONE = 0, - RS_SINGLE, + RS_NOT_AVAILABLE = 0, + RS_OFF, + RS_ONE, RS_ALL, } repeat_status_type; diff --git a/mpris-service.c b/mpris-service.c index dd24f848..7db1206d 100644 --- a/mpris-service.c +++ b/mpris-service.c @@ -19,10 +19,13 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused) char response[100]; switch (argc->repeat_status) { - case RS_NONE: + case RS_NOT_AVAILABLE: + strcpy(response, "Not Available"); + break; + case RS_OFF: strcpy(response, "None"); break; - case RS_SINGLE: + case RS_ONE: strcpy(response, "Track"); break; case RS_ALL: @@ -30,10 +33,12 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused) break; } - // debug(1,"Set loop status to \"%s\"",response); media_player2_player_set_loop_status(mprisPlayerPlayerSkeleton, response); switch (argc->player_state) { + case PS_NOT_AVAILABLE: + strcpy(response, "Not Available"); + break; case PS_STOPPED: strcpy(response, "Stopped"); break; @@ -45,9 +50,38 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused) break; } - // debug(1,"From player_state, set playback status to \"%s\"",response); media_player2_player_set_playback_status(mprisPlayerPlayerSkeleton, response); + /* + switch (argc->shuffle_state) { + case SS_NOT_AVAILABLE: + strcpy(response, "Not Available"); + break; + case SS_OFF: + strcpy(response, "Off"); + break; + case SS_ON: + strcpy(response, "On"); + break; + } + + media_player2_player_set_shuffle_status(mprisPlayerPlayerSkeleton, response); + */ + + switch (argc->shuffle_status) { + case SS_NOT_AVAILABLE: + media_player2_player_set_shuffle(mprisPlayerPlayerSkeleton, FALSE); + break; + case SS_OFF: + media_player2_player_set_shuffle(mprisPlayerPlayerSkeleton, FALSE); + break; + case SS_ON: + media_player2_player_set_shuffle(mprisPlayerPlayerSkeleton, TRUE); + break; + default: + debug(1, "This should never happen."); + } + GVariantBuilder *dict_builder, *aa; /* Build the metadata array */ diff --git a/org.gnome.ShairportSync.xml b/org.gnome.ShairportSync.xml index 9d520f18..ae404be7 100644 --- a/org.gnome.ShairportSync.xml +++ b/org.gnome.ShairportSync.xml @@ -18,7 +18,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -40,9 +40,11 @@ - + + + diff --git a/player.c b/player.c index 4a3e82ee..e8e5a052 100644 --- a/player.c +++ b/player.c @@ -829,8 +829,9 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { // say we have started playing here #ifdef HAVE_METADATA_HUB metadata_hub_modify_prolog(); + int changed = (metadata_store.player_state != PS_PLAYING); metadata_store.player_state = PS_PLAYING; - metadata_hub_modify_epilog(1); + metadata_hub_modify_epilog(changed); #endif if (reference_timestamp) { // if we have a reference time // debug(1,"First frame seen with timestamp..."); @@ -1064,8 +1065,9 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { #endif #ifdef HAVE_METADATA_HUB metadata_hub_modify_prolog(); + int changed = (metadata_store.player_state != PS_PLAYING); metadata_store.player_state = PS_PLAYING; - metadata_hub_modify_epilog(1); + metadata_hub_modify_epilog(changed); #endif } } @@ -1659,7 +1661,7 @@ static void *player_thread_func(void *arg) { player_volume(config.airplay_volume, conn); int64_t frames_to_drop = 0; - debug(1, "Play begin"); + // debug(1, "Play begin"); if (play_number % 100 == 0) debug(3, "Play frame %d.", play_number); while (!conn->player_thread_please_stop) { @@ -2551,8 +2553,9 @@ void player_flush(int64_t timestamp, rtsp_conn_info *conn) { #ifdef HAVE_METADATA_HUB metadata_hub_modify_prolog(); + int changed = (metadata_store.player_state != PS_PAUSED); metadata_store.player_state = PS_PAUSED; - metadata_hub_modify_epilog(1); + metadata_hub_modify_epilog(changed); #endif } @@ -2581,8 +2584,9 @@ int player_play(rtsp_conn_info *conn) { pthread_attr_destroy(&tattr); #ifdef HAVE_METADATA_HUB metadata_hub_modify_prolog(); + int changed = (metadata_store.player_state != PS_PLAYING); metadata_store.player_state = PS_PLAYING; - metadata_hub_modify_epilog(1); + metadata_hub_modify_epilog(changed); #endif return 0; } diff --git a/shairport-sync-dbus-test-client.c b/shairport-sync-dbus-test-client.c index ae2dabf1..469c98cd 100644 --- a/shairport-sync-dbus-test-client.c +++ b/shairport-sync-dbus-test-client.c @@ -7,8 +7,7 @@ GMainLoop *loop; void on_properties_changed(__attribute__((unused)) GDBusProxy *proxy, GVariant *changed_properties, - const gchar *const *invalidated_properties, - __attribute__((unused)) gpointer user_data) { + const gchar *const *invalidated_properties, gpointer user_data) { /* Note that we are guaranteed that changed_properties and * invalidated_properties are never NULL */ @@ -17,13 +16,15 @@ void on_properties_changed(__attribute__((unused)) GDBusProxy *proxy, GVariant * 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); + if (user_data) + g_print(" %s.%s -> %s\n", (char *)user_data, key, value_str); + else + g_print(" %s -> %s\n", key, value_str); g_free(value_str); } g_variant_iter_free(iter); @@ -116,20 +117,20 @@ int main(int argc, char *argv[]) { pthread_create(&dbus_thread, NULL, &dbus_thread_func, NULL); - ShairportSyncAdvancedRemoteControl *proxy; + ShairportSync *proxy; GError *error = NULL; - proxy = shairport_sync_advanced_remote_control_proxy_new_for_bus_sync( - gbus_type_selected, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ShairportSync", - "/org/gnome/ShairportSync", NULL, &error); + proxy = shairport_sync_proxy_new_for_bus_sync(gbus_type_selected, 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, "g-properties-changed", G_CALLBACK(on_properties_changed), + "ShairportSync"); 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_CALLBACK(notify_loudness_threshold_callback), "ShairportSync"); // Now, add notification of changes in diagnostics @@ -138,7 +139,8 @@ int main(int argc, char *argv[]) { proxy2 = shairport_sync_diagnostics_proxy_new_for_bus_sync( gbus_type_selected, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ShairportSync", "/org/gnome/ShairportSync", NULL, &error2); - g_signal_connect(proxy2, "g-properties-changed", G_CALLBACK(on_properties_changed), NULL); + g_signal_connect(proxy2, "g-properties-changed", G_CALLBACK(on_properties_changed), + "ShairportSync.Diagnostics"); // Now, add notification of changes in remote control @@ -147,21 +149,32 @@ int main(int argc, char *argv[]) { proxy3 = shairport_sync_remote_control_proxy_new_for_bus_sync( gbus_type_selected, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ShairportSync", "/org/gnome/ShairportSync", NULL, &error3); - g_signal_connect(proxy3, "g-properties-changed", G_CALLBACK(on_properties_changed), NULL); + g_signal_connect(proxy3, "g-properties-changed", G_CALLBACK(on_properties_changed), + "ShairportSync.RemoteControl"); + + ShairportSyncAdvancedRemoteControl *proxy4; + GError *error4 = NULL; + proxy4 = shairport_sync_advanced_remote_control_proxy_new_for_bus_sync( + gbus_type_selected, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ShairportSync", + "/org/gnome/ShairportSync", NULL, &error4); + g_signal_connect(proxy4, "g-properties-changed", G_CALLBACK(on_properties_changed), + "ShairportSync.AdvancedRemoteControl"); + g_signal_connect(proxy4, "notify::volume", G_CALLBACK(notify_volume_callback), + "ShairportSync.AdvancedRemoteControl"); g_print("Starting test...\n"); shairport_sync_advanced_remote_control_call_set_volume( - SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy), 20, NULL, NULL, 0); + SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy4), 20, NULL, NULL, 0); sleep(5); shairport_sync_advanced_remote_control_call_set_volume( - SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy), 100, NULL, NULL, 0); + SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy4), 100, NULL, NULL, 0); sleep(5); shairport_sync_advanced_remote_control_call_set_volume( - SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy), 40, NULL, NULL, 0); + SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy4), 40, NULL, NULL, 0); sleep(5); shairport_sync_advanced_remote_control_call_set_volume( - SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy), 60, NULL, NULL, 0); + SHAIRPORT_SYNC_ADVANCED_REMOTE_CONTROL(proxy4), 60, NULL, NULL, 0); /* // sleep(1); shairport_sync_set_loudness_filter_active(SHAIRPORT_SYNC(proxy), TRUE);