* Preamble
*****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <vlc/vlc.h>
+#include <vlc_plugin.h>
#include <vlc_interface.h>
#include <vlc_meta.h>
#include <vlc_playlist.h>
char *psz_format;
DBusConnection *p_conn;
int i_id;
+ int i_item_changes;
};
/*****************************************************************************
static int ItemChange( vlc_object_t *, const char *,
vlc_value_t, vlc_value_t, void * );
+static int StateChange( vlc_object_t *, const char *,
+ vlc_value_t, vlc_value_t, void * );
static int SendToTelepathy( intf_thread_t *, const char * );
/*****************************************************************************
set_description( _("Telepathy \"Now Playing\" using MissionControl") );
add_string( "telepathy-format", FORMAT_DEFAULT, NULL,
- FORMAT_TEXT, FORMAT_LONGTEXT, VLC_FALSE );
+ FORMAT_TEXT, FORMAT_LONGTEXT, false );
set_capability( "interface", 0 );
set_callbacks( Open, Close );
MALLOC_ERR( p_intf->p_sys, intf_sys_t );
+ /* connect to the session bus */
+ dbus_error_init( &error );
+ p_conn = dbus_bus_get( DBUS_BUS_SESSION, &error );
+ if( !p_conn )
+ {
+ msg_Err( p_this, "Failed to connect to the DBus session daemon: %s",
+ error.message );
+ dbus_error_free( &error );
+ free( p_intf->p_sys );
+ return VLC_EGENERIC;
+ }
+ p_intf->p_sys->p_conn = p_conn;
+
p_intf->p_sys->psz_format = config_GetPsz( p_intf, "telepathy-format" );
if( !p_intf->p_sys->psz_format )
{
var_AddCallback( p_playlist, "playlist-current", ItemChange, p_intf );
pl_Release( p_intf );
- dbus_error_init( &error );
-
- /* connect to the session bus */
- p_conn = dbus_bus_get( DBUS_BUS_SESSION, &error );
- if( !p_conn )
- {
- msg_Err( p_this, "Failed to connect to the DBus session daemon: %s",
- error.message );
- dbus_error_free( &error );
- free( p_intf->p_sys );
- return VLC_EGENERIC;
- }
- p_intf->p_sys->p_conn = p_conn;
return VLC_SUCCESS;
}
*****************************************************************************/
static void Close( vlc_object_t *p_this )
{
+ p_this->b_dead = true;
intf_thread_t *p_intf = (intf_thread_t *)p_this;
playlist_t *p_playlist = pl_Yield( p_this );
/* Do not check for VLC_ENOMEM as we're closing */
SendToTelepathy( p_intf, "" );
+ PL_LOCK;
var_DelCallback( p_playlist, "item-change", ItemChange, p_intf );
var_DelCallback( p_playlist, "playlist-current", ItemChange, p_intf );
+ if( p_playlist->p_input )
+ var_DelCallback( p_playlist->p_input, "state", StateChange, p_intf );
+ PL_UNLOCK;
pl_Release( p_this );
/* we won't use the DBus connection anymore */
static int ItemChange( vlc_object_t *p_this, const char *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *param )
{
+ VLC_UNUSED(oldval);
intf_thread_t *p_intf = (intf_thread_t *)param;
char *psz_buf = NULL;
input_thread_t *p_input;
+ if( p_intf->b_dead )
+ return VLC_EGENERIC;
+
/* Don't update Telepathy presence each time an item has been preparsed */
if( !strncmp( "playlist-current", psz_var, 16 ) )
{ /* stores the current input item id */
p_intf->p_sys->i_id = newval.i_int;
+ p_intf->p_sys->i_item_changes = 0;
+ }
+ else
+ {
+ if( newval.i_int != p_intf->p_sys->i_id ) /* "item-change" */
+ return VLC_SUCCESS;
+ /* Some variable bitrate inputs call "item-change callbacks each time
+ * their length is updated, that is several times per second.
+ * We'll limit the number of changes to 10 per input. */
+ if( p_intf->p_sys->i_item_changes > 10 )
+ return VLC_SUCCESS;
+ p_intf->p_sys->i_item_changes++;
}
- else if( newval.i_int != p_intf->p_sys->i_id ) /* "item-change" */
- return VLC_SUCCESS;
playlist_t *p_playlist = pl_Yield( p_this );
switch( SendToTelepathy( p_intf, "" ) )
{
case VLC_ENOMEM:
- Close( p_this );
return VLC_ENOMEM;
default:
return VLC_SUCCESS;
}
}
+ if( !strncmp( "playlist-current", psz_var, 16 ) )
+ var_AddCallback( p_input, "state", StateChange, p_intf );
+
/* We format the string to be displayed */
psz_buf = str_format_meta( p_this, p_intf->p_sys->psz_format );
+
/* We don't need the input anymore */
vlc_object_release( p_input );
if( SendToTelepathy( p_intf, psz_buf ) == VLC_ENOMEM )
{
free( psz_buf );
- Close( p_this );
return VLC_ENOMEM;
}
free( psz_buf );
return VLC_SUCCESS;
}
+/*****************************************************************************
+ * StateChange: State change callback
+ *****************************************************************************/
+static int StateChange( vlc_object_t *p_this, const char *psz_var,
+ vlc_value_t oldval, vlc_value_t newval, void *param )
+{
+ VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(oldval);
+ intf_thread_t *p_intf = (intf_thread_t *)param;
+ if( p_intf->b_dead )
+ return VLC_EGENERIC;
+ if( newval.i_int >= END_S )
+ return SendToTelepathy( p_intf, "" );
+ return VLC_SUCCESS;
+}
+
/*****************************************************************************
* SendToTelepathy
*****************************************************************************/