]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add some more D-Bus facilities. Countermand faulty D-Bus commands.
authorMike Brady <mikebrady@eircom.net>
Sat, 24 Mar 2018 17:48:32 +0000 (17:48 +0000)
committerMike Brady <mikebrady@eircom.net>
Sat, 24 Mar 2018 17:48:32 +0000 (17:48 +0000)
dacp.c
dbus-service.c
metadata_hub.c
metadata_hub.h
mpris-service.c
org.gnome.ShairportSync.xml
player.c
shairport-sync-dbus-test-client.c

diff --git a/dacp.c b/dacp.c
index cafe16362bebf54a11466a025bdd4d2196ce0a36..542f9890b57193cce29079bd706ca30f55bfc0a5 100644 (file)
--- 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));
index 2de215645ec6d15d4190bfca0ca02a2e29329380..5a1689de9bdb6890f036a8a4e58655b5d371be33 100644 (file)
@@ -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");
 }
index 2d024f835ceba41700d741373293c35996f7252d..910de5447834b50dc326e09f53be3b4e397af421 100644 (file)
@@ -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':
index 36dd8207ca5f2b42cb74e99ce8751e9dbe21e8c7..ce0505d826f012094abc7d1971f8848ac38137fd 100644 (file)
@@ -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;
 
index dd24f84837175d1f727a359f1b1a10fd9b1fa24a..7db1206dc23e2e9ca8cc13da0ce74f7aef674793 100644 (file)
@@ -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 */
index 9d520f184522cb3668290d7276c2c2a419d4235b..ae404be779dd5e8c1c3905e4de8dd4ce758e2640 100644 (file)
@@ -18,7 +18,7 @@
     <property name="ElapsedTime" type="b" access="readwrite" />
     <property name="DeltaTime" type="b" access="readwrite" />
   </interface>
-  <interface name="org.gnome.ShairportSync.Remote.Control">
+  <interface name="org.gnome.ShairportSync.RemoteControl">
                <method name='FastForward'/>
                <method name='Rewind'/>
                <method name='ToggleMute'/>
@@ -32,7 +32,7 @@
                <method name='ShuffleSongs'/>
                <method name='VolumeUp'/>
                <method name='VolumeDown'/>
-               <property name='PlaybackStatus' type='s' access='read'/>
+               <property name='PlayerState' type='s' access='read'/>
                <property name='Server' type='s' access='read'/>
                <property name='AirplayVolume' type='d' access='read'/>
                <property name='Metadata' type='a{sv}' access='read'>
                </property>
                <property name='Available' type='b' access='read'/>
   </interface>
-  <interface name="org.gnome.ShairportSync.Advanced.Remote.Control">
+  <interface name="org.gnome.ShairportSync.AdvancedRemoteControl">
                <property name='Available' type='b' access='read'/>
                <property name='PlaybackStatus' type='s' access='read'/>
+               <property name='Shuffle' type='b' access='readwrite'/>
+               <property name='LoopStatus' type='s' access='readwrite'/>
     <property name="Volume" type="i" access="read" />
     <method name="SetVolume">
       <arg name="volume" type="i" direction="in" />
index 4a3e82eeda28ef996a600ad161f8b8f6fb54041d..e8e5a052f69c2dd9ac5fde0936ca5b87ccf99f4f 100644 (file)
--- 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;
 }
index ae2dabf18576b570d77d149d6e41c28e2b09d353..469c98cd4378bc44c3aa2e976a7998031b6f56f5 100644 (file)
@@ -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);