⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbus.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
    var_DelCallback( p_playlist, "item-append", TrackListChangeEmit, p_intf );    var_DelCallback( p_playlist, "item-deleted", TrackListChangeEmit, p_intf );    var_DelCallback( p_playlist, "random", StatusChangeEmit, p_intf );    var_DelCallback( p_playlist, "repeat", StatusChangeEmit, p_intf );    var_DelCallback( p_playlist, "loop", StatusChangeEmit, p_intf );    p_input = p_playlist->p_input;    if ( p_input )    {        vlc_object_yield( p_input );        var_DelCallback( p_input, "state", StateChange, p_intf );        vlc_object_release( p_input );    }    PL_UNLOCK;    pl_Release( p_intf );    dbus_connection_unref( p_intf->p_sys->p_conn );    free( p_intf->p_sys );}/***************************************************************************** * Run: main loop *****************************************************************************/static void Run          ( intf_thread_t *p_intf ){    while( !intf_ShouldDie( p_intf ) )    {        msleep( INTF_IDLE_SLEEP );        dbus_connection_read_write_dispatch( p_intf->p_sys->p_conn, 0 );    }}/****************************************************************************** * CapsChange: player capabilities change signal *****************************************************************************/DBUS_SIGNAL( CapsChangeSignal ){    SIGNAL_INIT( "CapsChange" );    OUT_ARGUMENTS;    ADD_INT32( &((intf_thread_t*)p_data)->p_sys->i_caps );    SIGNAL_SEND;}/****************************************************************************** * TrackListChange: tracklist order / length change signal  *****************************************************************************/DBUS_SIGNAL( TrackListChangeSignal ){ /* emit the new tracklist lengh */    SIGNAL_INIT("TrackListChange");    OUT_ARGUMENTS;    playlist_t *p_playlist = pl_Yield( (vlc_object_t*) p_data );    dbus_int32_t i_elements = p_playlist->current.i_size;    pl_Release( (vlc_object_t*) p_data );    ADD_INT32( &i_elements );    SIGNAL_SEND;}/***************************************************************************** * TrackListChangeEmit: Emits the TrackListChange signal *****************************************************************************//* FIXME: It is not called on tracklist reordering */static int TrackListChangeEmit( vlc_object_t *p_this, const char *psz_var,            vlc_value_t oldval, vlc_value_t newval, void *p_data ){    VLC_UNUSED(oldval);    intf_thread_t *p_intf = p_data;    if( !strcmp( psz_var, "item-append" ) || !strcmp( psz_var, "item-remove" ) )    {        /* don't signal when items are added/removed in p_category */        playlist_t *p_playlist = (playlist_t*)p_this;        playlist_add_t *p_add = newval.p_address;        playlist_item_t *p_item;        p_item = playlist_ItemGetById( p_playlist, p_add->i_node, pl_Locked );        assert( p_item );        while( p_item->p_parent )            p_item = p_item->p_parent;        if( p_item == p_playlist->p_root_category )            return VLC_SUCCESS;    }    if( p_intf->b_dead )        return VLC_SUCCESS;    UpdateCaps( p_intf, true );    TrackListChangeSignal( p_intf->p_sys->p_conn, p_data );    return VLC_SUCCESS;}/***************************************************************************** * TrackChange: Playlist item change callback *****************************************************************************/DBUS_SIGNAL( TrackChangeSignal ){ /* emit the metadata of the new item */    SIGNAL_INIT( "TrackChange" );    OUT_ARGUMENTS;    input_item_t *p_item = (input_item_t*) p_data;    GetInputMeta ( p_item, &args );    SIGNAL_SEND;}/***************************************************************************** * StatusChange: Player status change signal *****************************************************************************/DBUS_SIGNAL( StatusChangeSignal ){ /* send the updated status info on the bus */    SIGNAL_INIT( "StatusChange" );    OUT_ARGUMENTS;    /* we're called from a callback of input_thread_t, so it can not be     * destroyed before we return */    MarshalStatus( (intf_thread_t*) p_data, &args, false );    SIGNAL_SEND;}/***************************************************************************** * StateChange: callback on input "state" *****************************************************************************/static int StateChange( vlc_object_t *p_this, const char* psz_var,            vlc_value_t oldval, vlc_value_t newval, void *p_data ){    VLC_UNUSED(psz_var); VLC_UNUSED(oldval);    intf_thread_t       *p_intf     = ( intf_thread_t* ) p_data;    intf_sys_t          *p_sys      = p_intf->p_sys;    if( p_intf->b_dead )        return VLC_SUCCESS;    UpdateCaps( p_intf, true );    if( !p_sys->b_meta_read && newval.i_int == PLAYING_S )    {        input_item_t *p_item = input_GetItem( (input_thread_t*)p_this );        if( p_item )        {            p_sys->b_meta_read = true;            TrackChangeSignal( p_sys->p_conn, p_item );        }    }    if( newval.i_int == PLAYING_S || newval.i_int == PAUSE_S ||        newval.i_int == STOP_S ||  newval.i_int == END_S )    {        StatusChangeSignal( p_sys->p_conn, (void*) p_intf );    }    return VLC_SUCCESS;}/***************************************************************************** * StatusChangeEmit: Emits the StatusChange signal *****************************************************************************/static int StatusChangeEmit( vlc_object_t *p_this, const char *psz_var,            vlc_value_t oldval, vlc_value_t newval, void *p_data ){    VLC_UNUSED(p_this); VLC_UNUSED(psz_var);    VLC_UNUSED(oldval); VLC_UNUSED(newval);    intf_thread_t *p_intf = p_data;    if( p_intf->b_dead )        return VLC_SUCCESS;    UpdateCaps( p_intf, false );    StatusChangeSignal( p_intf->p_sys->p_conn, p_data );    return VLC_SUCCESS;}/***************************************************************************** * TrackChange: callback on playlist "playlist-current" *****************************************************************************/static int TrackChange( vlc_object_t *p_this, const char *psz_var,            vlc_value_t oldval, vlc_value_t newval, void *p_data ){    intf_thread_t       *p_intf     = ( intf_thread_t* ) p_data;    intf_sys_t          *p_sys      = p_intf->p_sys;    playlist_t          *p_playlist;    input_thread_t      *p_input    = NULL;    input_item_t        *p_item     = NULL;    VLC_UNUSED( p_this ); VLC_UNUSED( psz_var );    VLC_UNUSED( oldval ); VLC_UNUSED( newval );    if( p_intf->b_dead )        return VLC_SUCCESS;    p_sys->b_meta_read = false;    p_playlist = pl_Yield( p_intf );    p_input = p_playlist->p_input;    if( !p_input )    {        PL_UNLOCK;        pl_Release( p_intf );        return VLC_SUCCESS;    }    vlc_object_yield( p_input );    pl_Release( p_intf );    p_item = input_GetItem( p_input );    if( !p_item )    {        vlc_object_release( p_input );        return VLC_EGENERIC;    }    if( input_item_IsPreparsed( p_item ) )    {        p_sys->b_meta_read = true;        TrackChangeSignal( p_sys->p_conn, p_item );    }    var_AddCallback( p_input, "state", StateChange, p_intf );    vlc_object_release( p_input );    return VLC_SUCCESS;}/***************************************************************************** * UpdateCaps: update p_sys->i_caps ****************************************************************************/static int UpdateCaps( intf_thread_t* p_intf, bool b_playlist_locked ){    intf_sys_t* p_sys = p_intf->p_sys;    dbus_int32_t i_caps = CAPS_CAN_HAS_TRACKLIST;    playlist_t* p_playlist = pl_Yield( p_intf );    if( !b_playlist_locked ) PL_LOCK;        if( p_playlist->current.i_size > 0 )        i_caps |= CAPS_CAN_PLAY | CAPS_CAN_GO_PREV | CAPS_CAN_GO_NEXT;    if( p_playlist->p_input )    {        /* XXX: if UpdateCaps() is called too early, these are         * unconditionnaly true */        if( var_GetBool( p_playlist->p_input, "can-pause" ) )            i_caps |= CAPS_CAN_PAUSE;        if( var_GetBool( p_playlist->p_input, "seekable" ) )            i_caps |= CAPS_CAN_SEEK;    }    if( !b_playlist_locked ) PL_UNLOCK;    pl_Release( p_intf );    if( p_sys->b_meta_read )        i_caps |= CAPS_CAN_PROVIDE_METADATA;    if( i_caps != p_intf->p_sys->i_caps )    {        p_sys->i_caps = i_caps;        CapsChangeSignal( p_intf->p_sys->p_conn, (vlc_object_t*)p_intf );    }    return VLC_SUCCESS;}/***************************************************************************** * GetInputMeta: Fill a DBusMessage with the given input item metadata *****************************************************************************/#define ADD_META( entry, type, data ) \    if( data ) { \        dbus_message_iter_open_container( &dict, DBUS_TYPE_DICT_ENTRY, \                NULL, &dict_entry ); \        dbus_message_iter_append_basic( &dict_entry, DBUS_TYPE_STRING, \                &ppsz_meta_items[entry] ); \        dbus_message_iter_open_container( &dict_entry, DBUS_TYPE_VARIANT, \                type##_AS_STRING, &variant ); \        dbus_message_iter_append_basic( &variant, \                type, \                & data ); \        dbus_message_iter_close_container( &dict_entry, &variant ); \        dbus_message_iter_close_container( &dict, &dict_entry ); }#define ADD_VLC_META_STRING( entry, item ) \    { \        char * psz = input_item_Get##item( p_input );\        ADD_META( entry, DBUS_TYPE_STRING, \                  psz ); \        free( psz ); \    }static int GetInputMeta( input_item_t* p_input,                        DBusMessageIter *args ){    DBusMessageIter dict, dict_entry, variant;    /* We need the track length to be expressed in milli-seconds     * instead of µ-seconds */    dbus_int64_t i_length = ( input_item_GetDuration( p_input ) / 1000 );    const char* ppsz_meta_items[] =    {    "title", "artist", "genre", "copyright", "album", "tracknum",    "description", "rating", "date", "setting", "url", "language",    "nowplaying", "publisher", "encodedby", "arturl", "trackid",    "status", "location", "length", "video-codec", "audio-codec",    "video-bitrate", "audio-bitrate", "audio-samplerate"    };    dbus_message_iter_open_container( args, DBUS_TYPE_ARRAY, "{sv}", &dict );    ADD_VLC_META_STRING( 0,  Title );    ADD_VLC_META_STRING( 1,  Artist );    ADD_VLC_META_STRING( 2,  Genre );    ADD_VLC_META_STRING( 3,  Copyright );    ADD_VLC_META_STRING( 4,  Album );    ADD_VLC_META_STRING( 5,  TrackNum );    ADD_VLC_META_STRING( 6,  Description );    ADD_VLC_META_STRING( 7,  Rating );    ADD_VLC_META_STRING( 8,  Date );    ADD_VLC_META_STRING( 9,  Setting );    ADD_VLC_META_STRING( 10, URL );    ADD_VLC_META_STRING( 11, Language );    ADD_VLC_META_STRING( 12, NowPlaying );    ADD_VLC_META_STRING( 13, Publisher );    ADD_VLC_META_STRING( 14, EncodedBy );    ADD_VLC_META_STRING( 15, ArtURL );    ADD_VLC_META_STRING( 16, TrackID );    vlc_mutex_lock( &p_input->lock );    if( p_input->p_meta )        ADD_META( 17, DBUS_TYPE_INT32, p_input->p_meta->i_status );    vlc_mutex_unlock( &p_input->lock );    ADD_VLC_META_STRING( 18, URI );    ADD_META( 19, DBUS_TYPE_INT64, i_length );    dbus_message_iter_close_container( args, &dict );    return VLC_SUCCESS;}#undef ADD_META#undef ADD_VLC_META_STRING/***************************************************************************** * MarshalStatus: Fill a DBusMessage with the current player status *****************************************************************************/static int MarshalStatus( intf_thread_t* p_intf, DBusMessageIter* args,                          bool lock ){ /* This is NOT the right way to do that, it would be better to sore     the status information in p_sys and update it on change, thus     avoiding a long lock */    DBusMessageIter status;    dbus_int32_t i_state, i_random, i_repeat, i_loop;    vlc_value_t val;    playlist_t* p_playlist = NULL;    input_thread_t* p_input = NULL;    p_playlist = pl_Yield( p_intf );    if( lock )        PL_LOCK;    i_state = 2;    p_input = p_playlist->p_input;    if( p_input )    {        var_Get( p_input, "state", &val );        if( val.i_int >= END_S )            i_state = 2;        else if( val.i_int == PAUSE_S )            i_state = 1;        else if( val.i_int <= PLAYING_S )            i_state = 0;    }    i_random = var_CreateGetBool( p_playlist, "random" );    i_repeat = var_CreateGetBool( p_playlist, "repeat" );    i_loop = var_CreateGetBool( p_playlist, "loop" );    if( lock )        PL_UNLOCK;    pl_Release( p_intf );    dbus_message_iter_open_container( args, DBUS_TYPE_STRUCT, NULL, &status );    dbus_message_iter_append_basic( &status, DBUS_TYPE_INT32, &i_state );    dbus_message_iter_append_basic( &status, DBUS_TYPE_INT32, &i_random );    dbus_message_iter_append_basic( &status, DBUS_TYPE_INT32, &i_repeat );    dbus_message_iter_append_basic( &status, DBUS_TYPE_INT32, &i_loop );    dbus_message_iter_close_container( args, &status );    return VLC_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -