Пример #1
0
bool PLSelector::dropMimeData ( QTreeWidgetItem * parent, int index,
  const QMimeData * data, Qt::DropAction action )
{
    if( !parent ) return false;

    QVariant type = parent->data( 0, TYPE_ROLE );
    if( type == QVariant() ) return false;
    int i_type = type.toInt();
    if( i_type != PL_TYPE && i_type != ML_TYPE ) return false;
    bool to_pl = i_type == PL_TYPE;

    if( data->hasFormat( "vlc/qt-playlist-item" ) )
    {
        QByteArray encodedData = data->data( "vlc/qt-playlist-item" );
        QDataStream stream( &encodedData, QIODevice::ReadOnly );
        playlist_Lock( THEPL );
        while( !stream.atEnd() )
        {
            PLItem *item;
            stream.readRawData( (char*)&item, sizeof(PLItem*) );
            input_item_t *pl_input =item->inputItem();
            playlist_AddExt ( THEPL,
                pl_input->psz_uri, pl_input->psz_name,
                PLAYLIST_APPEND | PLAYLIST_SPREPARSE, PLAYLIST_END,
                pl_input->i_duration,
                pl_input->i_options, pl_input->ppsz_options, pl_input->optflagc,
                to_pl, true );
        }
        playlist_Unlock( THEPL );
    }
    return true;
}
/*
 * Reads and updates the playlist's duration as [xx:xx] after the label in the tree
 * item - the treeview item to get the duration for
 * prefix - the string to use before the time (should be the category name)
 */
void PLSelector::updateTotalDuration( PLSelItem* item, const char* prefix )
{
    /* Getting  the playlist */
    QVariant playlistVariant = item->treeItem()->data( 0, PL_ITEM_ROLE );
    playlist_item_t* node = playlistVariant.value<playlist_item_t*>();

    /* Get the duration of the playlist item */
    playlist_Lock( THEPL );
    mtime_t mt_duration = playlist_GetNodeDuration( node );
    playlist_Unlock( THEPL );

    /* Formatting time */
    QString qs_timeLabel( prefix );

    int i_seconds = mt_duration / 1000000;
    int i_minutes = i_seconds / 60;
    i_seconds = i_seconds % 60;
    if( i_minutes >= 60 )
    {
        int i_hours = i_minutes / 60;
        i_minutes = i_minutes % 60;
        qs_timeLabel += QString(" [%1:%2:%3]").arg( i_hours ).arg( i_minutes, 2, 10, QChar('0') ).arg( i_seconds, 2, 10, QChar('0') );
    }
    else
        qs_timeLabel += QString( " [%1:%2]").arg( i_minutes, 2, 10, QChar('0') ).arg( i_seconds, 2, 10, QChar('0') );

    item->setText( qs_timeLabel );
}
Пример #3
0
static int
MarshalMetadata( intf_thread_t *p_intf, DBusMessageIter *container )
{
    playlist_t *playlist = pl_Get( p_intf );
    playlist_item_t *item;
    int result = VLC_SUCCESS;

    playlist_Lock( playlist );
    item = playlist_CurrentPlayingItem( playlist );

    if( item != NULL )
        result = GetInputMeta( item, container );
    else
    {   // avoid breaking the type marshalling
        DBusMessageIter a;

        if( !dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY,
                                               "{sv}", &a ) ||
            !dbus_message_iter_close_container( container, &a ) )
            result = VLC_ENOMEM;
    }

    playlist_Unlock( playlist );
    return result;
}
Пример #4
0
void Playtree::onUpdateItem( int id )
{
    Iterator it = findById( id );
    if( it != m_children.end() )
    {
        // Update the item
        playlist_Lock( m_pPlaylist );
        playlist_item_t *pNode =
            playlist_ItemGetById( m_pPlaylist, it->getId() );
        if( !pNode )
        {
            playlist_Unlock( m_pPlaylist );
            return;
        }

        UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
        playlist_Unlock( m_pPlaylist );

        if( *pName != *(it->getString()) )
        {
            it->setString( UStringPtr( pName ) );

            tree_update descr(
                tree_update::ItemUpdated, IteratorVisible( it, this ) );
            notify( &descr );
        }
    }
    else
    {
        msg_Warn( getIntf(), "cannot find node with id %d", id );
    }
}
Пример #5
0
void Playtree::delSelected()
{
    for( Iterator it = m_children.begin(); it != m_children.end(); )
    {
        if( it->isSelected() && !it->isReadonly() )
        {
            playlist_Lock( m_pPlaylist );

            playlist_item_t *pItem =
                playlist_ItemGetById( m_pPlaylist, it->getId() );
            if( pItem )
            {
                if( pItem->i_children == -1 )
                {
                    playlist_DeleteFromInput( m_pPlaylist, pItem->p_input,
                                              pl_Locked );
                }
                else
                {
                    playlist_NodeDelete( m_pPlaylist, pItem, true, false );
                }
            }
            playlist_Unlock( m_pPlaylist );

            it = it->getNextSiblingOrUncle();
        }
        else
        {
            it = getNextItem( it );
        }
    }
}
Пример #6
0
/**
 * Run the main control thread itself
 */
static void *Thread ( void *data )
{
    playlist_t *p_playlist = (playlist_t *)data;			// sunqueen modify
    playlist_private_t *p_sys = pl_priv(p_playlist);

    playlist_Lock( p_playlist );
    for( ;; )
    {
        while( p_sys->p_input != NULL )
            LoopInput( p_playlist );

        if( p_sys->killed )
            break; /* THE END */

        const int status = p_sys->request.b_request ?
                           p_sys->request.i_status : p_sys->status.i_status;

        /* Destroy any video display if the playlist is supposed to stop */
        if( status == PLAYLIST_STOPPED
         && input_resource_HasVout( p_sys->p_input_resource ) )
        {
            PL_UNLOCK; /* Mind: NO LOCKS while manipulating input resources! */
            input_resource_TerminateVout( p_sys->p_input_resource );
            PL_LOCK;
            continue; /* lost lock = lost state */
        }

        LoopRequest( p_playlist, status );
    }
    p_sys->status.i_status = PLAYLIST_STOPPED;
    playlist_Unlock( p_playlist );

    input_resource_Terminate( p_sys->p_input_resource );
    return NULL;
}
Пример #7
0
/**
 * Run the main control thread itself
 */
static void *Thread ( void *data )
{
    playlist_t *p_playlist = data;
    playlist_private_t *p_sys = pl_priv(p_playlist);

    playlist_Lock( p_playlist );
    while( vlc_object_alive( p_playlist ) || p_sys->p_input )
    {
        /* FIXME: what's that ! */
        if( p_sys->b_reset_currently_playing &&
            mdate() - p_sys->last_rebuild_date > 30000 ) // 30 ms
        {
            ResetCurrentlyPlaying( p_playlist,
                                   get_current_status_item( p_playlist ) );
            p_sys->last_rebuild_date = mdate();
        }

        /* If there is an input, check that it doesn't need to die. */
        while( !LoopInput( p_playlist ) )
            vlc_cond_wait( &p_sys->signal, &p_sys->lock );

        LoopRequest( p_playlist );
    }
    playlist_Unlock( p_playlist );

    return NULL;
}
Пример #8
0
void CmdPlay::execute()
{
    playlist_t *pPlaylist = getIntf()->p_sys->p_playlist;
    if( pPlaylist == NULL )
        return;

    // if already playing an input, reset rate to normal speed
    input_thread_t *pInput = playlist_CurrentInput( pPlaylist );
    if( pInput )
    {
        var_SetFloat( pPlaylist, "rate", 1.0 );
        vlc_object_release( pInput );
    }

    playlist_Lock( pPlaylist );
    const bool b_empty = playlist_IsEmpty( pPlaylist );
    playlist_Unlock( pPlaylist );

    if( !b_empty )
    {
        playlist_Play( pPlaylist );
    }
    else
    {
        // If the playlist is empty, open a file requester instead
        CmdDlgFile( getIntf() ).execute();
    }
}
Пример #9
0
void StandardPLPanel::browseInto( input_item_t *p_input )
{

    if( p_input->i_id != lastActivatedId ) return;

    playlist_Lock( THEPL );

    playlist_item_t *p_item = playlist_ItemGetByInput( THEPL, p_input );
    if( !p_item )
    {
        playlist_Unlock( THEPL );
        return;
    }

    QModelIndex index = model->index( p_item->i_id, 0 );

    playlist_Unlock( THEPL );

    if( currentView == treeView )
        treeView->setExpanded( index, true );
    else
        browseInto( index );

    lastActivatedId = -1;


}
Пример #10
0
void Playtree::onAppend( playlist_add_t *p_add )
{
    Iterator it_node = findById( p_add->i_node );
    if( it_node != m_children.end() )
    {
        playlist_Lock( m_pPlaylist );
        playlist_item_t *pItem =
            playlist_ItemGetById( m_pPlaylist, p_add->i_item );
        if( !pItem )
        {
            playlist_Unlock( m_pPlaylist );
            return;
        }

        int pos;
        for( pos = 0; pos < pItem->p_parent->i_children; pos++ )
            if( pItem->p_parent->pp_children[pos] == pItem ) break;

        UString *pName = getTitle( pItem->p_input );
        playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );

        Iterator it = it_node->add(
            p_add->i_item, UStringPtr( pName ), false, pItem == current,
            false, pItem->i_flags & PLAYLIST_RO_FLAG, pos );

        m_allItems[pItem->i_id] = &*it;

        playlist_Unlock( m_pPlaylist );

        tree_update descr(
            tree_update::ItemInserted,
            IteratorVisible( it, this ) );
        notify( &descr );
    }
}
Пример #11
0
void Playtree::insertItems( VarTree& elem, const list<string>& files, bool start )
{
    bool first = true;
    VarTree* p_elem = &elem;
    playlist_item_t* p_node = NULL;
    int i_pos = -1;

    playlist_Lock( m_pPlaylist );

    if( p_elem->getId() == m_pPlaylist->p_local_category->i_id )
    {
        p_node = m_pPlaylist->p_local_category;
        i_pos = 0;
    }
    else if( p_elem->getId() == m_pPlaylist->p_ml_category->i_id )
    {
        p_node = m_pPlaylist->p_ml_category;
        i_pos = 0;
    }
    else if( p_elem->size() && p_elem->isExpanded() )
    {
        p_node = playlist_ItemGetById( m_pPlaylist, p_elem->getId() );
        i_pos = 0;
    }
    else
    {
        p_node = playlist_ItemGetById( m_pPlaylist,
                                       p_elem->parent()->getId() );
        i_pos = p_elem->getIndex();
        i_pos++;
    }

    if( !p_node )
        goto fin;

    for( list<string>::const_iterator it = files.begin();
         it != files.end(); ++it, i_pos++, first = false )
    {
        char* psz_uri = make_URI( it->c_str(), NULL );
        if( !psz_uri )
            continue;

        input_item_t* pItem = input_item_New( psz_uri, NULL );
        if( pItem )
        {
            int i_mode = PLAYLIST_APPEND;
            if( first && start )
                i_mode |= PLAYLIST_GO;

            playlist_NodeAddInput( m_pPlaylist, pItem, p_node,
                                   i_mode, i_pos, pl_Locked );
        }
        free( psz_uri );
    }

fin:
    playlist_Unlock( m_pPlaylist );
}
Пример #12
0
mvar_t *mvar_PlaylistSetNew( intf_thread_t *p_intf, char *name,
                                 playlist_t *p_pl )
{
    mvar_t *s = mvar_New( name, "set" );
    playlist_Lock( p_pl );
    PlaylistListNode( p_intf, p_pl, p_pl->p_root_category , name, s, 0 );
    playlist_Unlock( p_pl );
    return s;
}
Пример #13
0
/* Define the Input used.
   Add the callbacks on input
   p_input is held once here */
void InputManager::setInput( input_thread_t *_p_input )
{
    delInput();
    p_input = _p_input;
    if( p_input != NULL )
    {
        msg_Dbg( p_intf, "IM: Setting an input" );
        vlc_object_hold( p_input );
        addCallbacks();

        UpdateStatus();
        UpdateName();
        UpdateArt();
        UpdateTeletext();
        UpdateNavigation();
        UpdateVout();

        p_item = input_GetItem( p_input );
        emit rateChanged( var_GetFloat( p_input, "rate" ) );

        /* Get Saved Time */
        if( p_item->i_type == ITEM_TYPE_FILE )
        {
            char *uri = input_item_GetURI( p_item );

            int i_time = RecentsMRL::getInstance( p_intf )->time( qfu(uri) );
            if( i_time > 0 && qfu( uri ) != lastURI &&
                    !var_GetFloat( p_input, "run-time" ) &&
                    !var_GetFloat( p_input, "start-time" ) &&
                    !var_GetFloat( p_input, "stop-time" ) )
            {
                emit resumePlayback( (int64_t)i_time * 1000 );
            }
            playlist_Lock( THEPL );
            // Add root items only
            playlist_item_t* p_node = playlist_CurrentPlayingItem( THEPL );
            if ( p_node != NULL && p_node->p_parent != NULL && p_node->p_parent->i_id == THEPL->p_playing->i_id )
            {
                // Save the latest URI to avoid asking to restore the
                // position on the same input file.
                lastURI = qfu( uri );
                RecentsMRL::getInstance( p_intf )->addRecent( lastURI );
            }
            playlist_Unlock( THEPL );
            free( uri );
        }
    }
    else
    {
        p_item = NULL;
        lastURI.clear();
        assert( !p_input_vbi );
        emit rateChanged( var_InheritFloat( p_intf, "rate" ) );
    }
}
Пример #14
0
void Playtree::buildTree()
{
    clear();
    playlist_Lock( m_pPlaylist );

    for( int i = 0; i < m_pPlaylist->p_root->i_children; i++ )
    {
        buildNode( m_pPlaylist->p_root->pp_children[i], *this );
    }

    playlist_Unlock( m_pPlaylist );
}
Пример #15
0
void Playtree::action( VarTree *pElem )
{
    playlist_Lock( m_pPlaylist );

    playlist_item_t *pItem =
        playlist_ItemGetById( m_pPlaylist, pElem->getId() );
    if( pItem )
    {
        playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY,
                          pl_Locked, pItem->p_parent, pItem );
    }

    playlist_Unlock( m_pPlaylist );
}
Пример #16
0
int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
                     bool b_playlist, const char *psz_type )
{
    playlist_export_t *p_export =
        vlc_custom_create( p_playlist, sizeof( *p_export ), "playlist export" );
    if( unlikely(p_export == NULL) )
        return VLC_ENOMEM;

    msg_Dbg( p_export, "saving %s to file %s",
             b_playlist ? "playlist" : "media library", psz_filename );

    int ret = VLC_EGENERIC;

    /* Prepare the playlist_export_t structure */
    p_export->base_url = vlc_path2uri( psz_filename, NULL );
    p_export->p_file = vlc_fopen( psz_filename, "wt" );
    if( p_export->p_file == NULL )
    {
        msg_Err( p_export, "could not create playlist file %s: %s",
                 psz_filename, vlc_strerror_c(errno) );
        goto out;
    }

    module_t *p_module;

    /* And call the module ! All work is done now */
    playlist_Lock( p_playlist );
    p_export->p_root = b_playlist ? p_playlist->p_playing
                                  : p_playlist->p_media_library;

    p_module = module_need( p_export, "playlist export", psz_type, true );
    playlist_Unlock( p_playlist );

    if( p_module != NULL )
    {
        module_unneed( p_export, p_module );
        if( !ferror( p_export->p_file ) )
            ret = VLC_SUCCESS;
        else
            msg_Err( p_playlist, "could not write playlist file: %s",
                     vlc_strerror_c(errno) );
    }
    else
        msg_Err( p_playlist, "could not export playlist" );
   fclose( p_export->p_file );
out:
   free( p_export->base_url );
   vlc_object_release( p_export );
   return ret;
}
Пример #17
0
int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
                     playlist_item_t *p_export_root, const char *psz_type )
{
    if( p_export_root == NULL ) return VLC_EGENERIC;

    playlist_export_t *p_export =
        vlc_custom_create( p_playlist, sizeof( *p_export ), "playlist export" );
    if( unlikely(p_export == NULL) )
        return VLC_ENOMEM;

    msg_Dbg( p_export, "saving %s to file %s",
             p_export_root->p_input->psz_name, psz_filename );

    int ret = VLC_EGENERIC;

    /* Prepare the playlist_export_t structure */
    p_export->p_root = p_export_root;
    p_export->psz_filename = psz_filename;
    p_export->p_file = vlc_fopen( psz_filename, "wt" );
    if( p_export->p_file == NULL )
    {
        msg_Err( p_export, "could not create playlist file %s: %s",
                 psz_filename, vlc_strerror_c(errno) );
        goto out;
    }

    module_t *p_module;

    /* And call the module ! All work is done now */
    playlist_Lock( p_playlist );
    p_module = module_need( p_export, "playlist export", psz_type, true );
    playlist_Unlock( p_playlist );

    if( p_module != NULL )
    {
        module_unneed( p_export, p_module );
        if( !ferror( p_export->p_file ) )
            ret = VLC_SUCCESS;
        else
            msg_Err( p_playlist, "could not write playlist file: %s",
                     vlc_strerror_c(errno) );
    }
    else
        msg_Err( p_playlist, "could not export playlist" );
   fclose( p_export->p_file );
out:
   vlc_object_release( p_export );
   return ret;
}
Пример #18
0
void StandardPLPanel::activate( const QModelIndex &index )
{
    if( !index.data( PLModel::IsLeafNodeRole ).toBool() )
    {
        if( currentView != treeView )
            browseInto( index );
    }
    else
    {
        playlist_Lock( THEPL );
        playlist_item_t *p_item = playlist_ItemGetById( THEPL, model->itemId( index ) );
        p_item->i_flags |= PLAYLIST_SUBITEM_STOP_FLAG;
        lastActivatedId = p_item->p_input->i_id;
        playlist_Unlock( THEPL );
        model->activateItem( index );
    }
}
Пример #19
0
void PLSelector::setSource( QTreeWidgetItem *item )
{
    if( !item )
        return;

    bool b_ok;
    int i_type = item->data( 0, TYPE_ROLE ).toInt( &b_ok );
    if( !b_ok || i_type == CATEGORY_TYPE )
        return;

    bool sd_loaded;
    if( i_type == SD_TYPE )
    {
        QString qs = item->data( 0, NAME_ROLE ).toString();
        sd_loaded = playlist_IsServicesDiscoveryLoaded( THEPL, qtu( qs ) );
        if( !sd_loaded )
            playlist_ServicesDiscoveryAdd( THEPL, qtu( qs ) );
    }

    playlist_Lock( THEPL );

    playlist_item_t *pl_item = NULL;

    if( i_type == SD_TYPE )
    {
        pl_item = playlist_ChildSearchName( THEPL->p_root, qtu( item->data(0, LONGNAME_ROLE ).toString() ) );
        if( item->data( 0, SPECIAL_ROLE ).toInt() == IS_PODCAST )
        {
            if( pl_item && !sd_loaded )
            {
                podcastsParentId = pl_item->i_id;
                for( int i=0; i < pl_item->i_children; i++ )
                    addPodcastItem( pl_item->pp_children[i] );
            }
            pl_item = NULL; //to prevent activating it
        }
    }
    else
        pl_item = item->data( 0, PL_ITEM_ROLE ).value<playlist_item_t*>();

    playlist_Unlock( THEPL );

    if( pl_item )
        emit activated( pl_item );
}
Пример #20
0
/** **************************************************************************
 * \brief Add a media to the playlist
 *
 * \param id the item id
 * @todo this code must definitely be done by the ML core
 *****************************************************************************/
static void AddItemToPlaylist( int i_media_id, bool bPlay, media_library_t* p_ml,
        bool bRenew )
{

    input_item_t *p_item = ml_CreateInputItem( p_ml, i_media_id );
    if( !p_item )
    {
        msg_Dbg( p_ml, "unable to create input item for media %d",
                 i_media_id );
        return;
    }
    playlist_t *p_playlist = pl_Get( p_ml );
    playlist_item_t *p_playlist_item = NULL;

    playlist_Lock( p_playlist );
    if( !bRenew )
    {
        p_playlist_item = playlist_ItemGetByInput( p_playlist, p_item );
    }

    if( !p_playlist_item || p_playlist_item->i_id == 1 )
    {
        playlist_AddInput( p_playlist, p_item,
                           PLAYLIST_APPEND,
                           PLAYLIST_END, true, true );

        p_playlist_item = playlist_ItemGetByInput( p_playlist, p_item );
    }
    playlist_Unlock( p_playlist );

    if( !p_playlist_item || p_playlist_item->i_id == 1 )
    {
        msg_Dbg( p_ml, "could not find playlist item %s (%s:%d)",
                 p_item->psz_name, __FILE__, __LINE__ );
        return;
    }

    /* Auto play item */
    if( bPlay ) // || p_playlist->status.i_status == PLAYLIST_STOPPED )
    {
        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, false,
                          NULL, p_playlist_item );
    }
    vlc_gc_decref( p_item );
}
Пример #21
0
int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
                     playlist_item_t *p_export_root, const char *psz_type )
{
    if( p_export_root == NULL ) return VLC_EGENERIC;

    playlist_export_t *p_export =
        vlc_custom_create( p_playlist, sizeof( *p_export ), VLC_OBJECT_GENERIC,
                           "playlist export" );
    if( !p_export )
        return VLC_ENOMEM;

    vlc_object_attach( p_export, p_playlist );
    msg_Dbg( p_export, "saving %s to file %s",
             p_export_root->p_input->psz_name, psz_filename );

    int ret = VLC_EGENERIC;

    /* Prepare the playlist_export_t structure */
    p_export->p_root = p_export_root;
    p_export->psz_filename = psz_filename;
    p_export->p_file = vlc_fopen( psz_filename, "wt" );
    if( p_export->p_file == NULL )
        msg_Err( p_export, "could not create playlist file %s (%m)",
                 psz_filename );
    else
    {
        module_t *p_module;

        /* And call the module ! All work is done now */
        playlist_Lock( p_playlist );
        p_module = module_need( p_export, "playlist export", psz_type, true );
        playlist_Unlock( p_playlist );

        if( p_module == NULL )
            msg_Err( p_playlist, "could not export playlist" );
        else
        {
            module_unneed( p_export, p_module );
            ret = VLC_SUCCESS;
        }
        fclose( p_export->p_file );
    }
    vlc_object_release( p_export );
    return ret;
}
Пример #22
0
playlist_item_t *RecentsMRL::toPlaylist(int length)
{
    playlist_Lock(THEPL);
    playlist_item_t *p_node_recent = playlist_NodeCreate(THEPL, _("Recently Played"), THEPL->p_root, PLAYLIST_END, PLAYLIST_RO_FLAG, NULL);
    playlist_Unlock(THEPL);

    if ( p_node_recent == NULL )  return NULL;

    if (length == 0 || recents.count() < length)
        length = recents.count();

    for (int i = 0; i < length; i++)
    {
        input_item_t *p_input = input_item_New(qtu(recents.at(i)), NULL);
        playlist_NodeAddInput(THEPL, p_input, p_node_recent, PLAYLIST_APPEND, PLAYLIST_END, false);
    }

    return p_node_recent;
}
Пример #23
0
void Playtree::onUpdateCurrent( bool b_active )
{
    if( b_active )
    {
        playlist_Lock( m_pPlaylist );

        playlist_item_t* current = playlist_CurrentPlayingItem( m_pPlaylist );
        if( !current )
        {
            playlist_Unlock( m_pPlaylist );
            return;
        }

        Iterator it = findById( current->i_id );
        if( it != m_children.end() )
        {
            it->setPlaying( true );

            tree_update descr(
                tree_update::ItemUpdated, IteratorVisible( it, this ) );
            notify( &descr );
        }

        playlist_Unlock( m_pPlaylist );
    }
    else
    {
        for( Iterator it = m_children.begin(); it != m_children.end();
             it = getNextItem( it ) )
        {
            if( it->isPlaying() )
            {
                it->setPlaying( false );

                tree_update descr(
                    tree_update::ItemUpdated, IteratorVisible( it, this ) );
                notify( &descr );
                break;
            }
        }
    }
}
Пример #24
0
Файл: rpn.c Проект: Kafay/vlc
void EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
                      rpn_stack_t *st, char *exp )
{
    intf_sys_t    *p_sys = p_intf->p_sys;

    while( exp != NULL && *exp != '\0' )
    {
        char *p, *s;

        /* skip space */
        while( *exp == ' ' )
        {
            exp++;
        }

        if( *exp == '\'' )
        {
            /* extract string */
            p = FirstWord( exp, exp );
            SSPush( st, exp );
            exp = p;
            continue;
        }

        /* extract token */
        p = FirstWord( exp, exp );
        s = exp;
        if( p == NULL )
        {
            exp += strlen( exp );
        }
        else
        {
            exp = p;
        }

        if( *s == '\0' )
        {
            break;
        }

        /* 1. Integer function */
        if( !strcmp( s, "!" ) )
        {
            SSPushN( st, ~SSPopN( st, vars ) );
        }
        else if( !strcmp( s, "^" ) )
        {
            SSPushN( st, SSPopN( st, vars ) ^ SSPopN( st, vars ) );
        }
        else if( !strcmp( s, "&" ) )
        {
            SSPushN( st, SSPopN( st, vars ) & SSPopN( st, vars ) );
        }
        else if( !strcmp( s, "|" ) )
        {
            SSPushN( st, SSPopN( st, vars ) | SSPopN( st, vars ) );
        }
        else if( !strcmp( s, "+" ) )
        {
            SSPushN( st, SSPopN( st, vars ) + SSPopN( st, vars ) );
        }
        else if( !strcmp( s, "-" ) )
        {
            int j = SSPopN( st, vars );
            int i = SSPopN( st, vars );
            SSPushN( st, i - j );
        }
        else if( !strcmp( s, "*" ) )
        {
            SSPushN( st, SSPopN( st, vars ) * SSPopN( st, vars ) );
        }
        else if( !strcmp( s, "/" ) )
        {
            int i, j;

            j = SSPopN( st, vars );
            i = SSPopN( st, vars );

            SSPushN( st, j != 0 ? i / j : 0 );
        }
        else if( !strcmp( s, "%" ) )
        {
            int i, j;

            j = SSPopN( st, vars );
            i = SSPopN( st, vars );

            SSPushN( st, j != 0 ? i % j : 0 );
        }
        /* 2. integer tests */
        else if( !strcmp( s, "=" ) )
        {
            SSPushN( st, SSPopN( st, vars ) == SSPopN( st, vars ) ? -1 : 0 );
        }
        else if( !strcmp( s, "!=" ) )
        {
            SSPushN( st, SSPopN( st, vars ) != SSPopN( st, vars ) ? -1 : 0 );
        }
        else if( !strcmp( s, "<" ) )
        {
            int j = SSPopN( st, vars );
            int i = SSPopN( st, vars );

            SSPushN( st, i < j ? -1 : 0 );
        }
        else if( !strcmp( s, ">" ) )
        {
            int j = SSPopN( st, vars );
            int i = SSPopN( st, vars );

            SSPushN( st, i > j ? -1 : 0 );
        }
        else if( !strcmp( s, "<=" ) )
        {
            int j = SSPopN( st, vars );
            int i = SSPopN( st, vars );

            SSPushN( st, i <= j ? -1 : 0 );
        }
        else if( !strcmp( s, ">=" ) )
        {
            int j = SSPopN( st, vars );
            int i = SSPopN( st, vars );

            SSPushN( st, i >= j ? -1 : 0 );
        }
        /* 3. string functions */
        else if( !strcmp( s, "strcat" ) )
        {
            char *s2 = SSPop( st );
            char *s1 = SSPop( st );
            char *str = malloc( strlen( s1 ) + strlen( s2 ) + 1 );

            strcpy( str, s1 );
            strcat( str, s2 );

            SSPush( st, str );
            free( s1 );
            free( s2 );
            free( str );
        }
        else if( !strcmp( s, "strcmp" ) )
        {
            char *s2 = SSPop( st );
            char *s1 = SSPop( st );

            SSPushN( st, strcmp( s1, s2 ) );
            free( s1 );
            free( s2 );
        }
        else if( !strcmp( s, "strncmp" ) )
        {
            int n = SSPopN( st, vars );
            char *s2 = SSPop( st );
            char *s1 = SSPop( st );

            SSPushN( st, strncmp( s1, s2 , n ) );
            free( s1 );
            free( s2 );
        }
        else if( !strcmp( s, "strsub" ) )
        {
            int n = SSPopN( st, vars );
            int m = SSPopN( st, vars );
            int i_len;
            char *s = SSPop( st );
            char *str;

            if( n >= m )
            {
                i_len = n - m + 1;
            }
            else
            {
                i_len = 0;
            }

            str = malloc( i_len + 1 );

            memcpy( str, s + m - 1, i_len );
            str[ i_len ] = '\0';

            SSPush( st, str );
            free( s );
            free( str );
        }
        else if( !strcmp( s, "strlen" ) )
        {
            char *str = SSPop( st );

            SSPushN( st, strlen( str ) );
            free( str );
        }
        else if( !strcmp( s, "str_replace" ) )
        {
            char *psz_to = SSPop( st );
            char *psz_from = SSPop( st );
            char *psz_in = SSPop( st );
            char *psz_in_current = psz_in;
            char *psz_out = malloc( strlen(psz_in) * strlen(psz_to) + 1 );
            char *psz_out_current = psz_out;

            while( (p = strstr( psz_in_current, psz_from )) != NULL )
            {
                memcpy( psz_out_current, psz_in_current, p - psz_in_current );
                psz_out_current += p - psz_in_current;
                strcpy( psz_out_current, psz_to );
                psz_out_current += strlen(psz_to);
                psz_in_current = p + strlen(psz_from);
            }
            strcpy( psz_out_current, psz_in_current );
            psz_out_current += strlen(psz_in_current);
            *psz_out_current = '\0';

            SSPush( st, psz_out );
            free( psz_to );
            free( psz_from );
            free( psz_in );
            free( psz_out );
        }
        else if( !strcmp( s, "url_extract" ) )
        {
            const char *url = mvar_GetValue( vars, "url_value" );
            char *name = SSPop( st );
            char *value = ExtractURIString( url, name );
            if( value != NULL )
            {
                decode_URI( value );
                SSPush( st, value );
                free( value );
            }
            else
                SSPush( st, "" );

            free( name );
        }
        else if( !strcmp( s, "url_encode" ) )
        {
            char *url = SSPop( st );
            char *value = vlc_UrlEncode( url );
            free( url );
            SSPush( st, value );
            free( value );
        }
        else if( !strcmp( s, "xml_encode" )
              || !strcmp( s, "htmlspecialchars" ) )
        {
            char *url = SSPop( st );
            char *value = convert_xml_special_chars( url );
            free( url );
            SSPush( st, value );
            free( value );
        }
        else if( !strcmp( s, "addslashes" ) )
        {
            char *psz_src = SSPop( st );
            char *psz_dest;
            char *str = psz_src;

            p = psz_dest = malloc( strlen( str ) * 2 + 1 );

            while( *str != '\0' )
            {
                if( *str == '"' || *str == '\'' || *str == '\\' )
                {
                    *p++ = '\\';
                }
                *p++ = *str;
                str++;
            }
            *p = '\0';

            SSPush( st, psz_dest );
            free( psz_src );
            free( psz_dest );
        }
        else if( !strcmp( s, "stripslashes" ) )
        {
            char *psz_src = SSPop( st );
            char *psz_dest;
            char *str = psz_src;

            p = psz_dest = strdup( psz_src );

            while( *str )
            {
                if( *str == '\\' && *(str + 1) )
                {
                    str++;
                }
                *p++ = *str++;
            }
            *p = '\0';

            SSPush( st, psz_dest );
            free( psz_src );
            free( psz_dest );
        }
        else if( !strcmp( s, "realpath" ) )
        {
            char *psz_src = SSPop( st );
            char *psz_dir = RealPath( psz_src );

            SSPush( st, psz_dir );
            free( psz_src );
            free( psz_dir );
        }
        /* 4. stack functions */
        else if( !strcmp( s, "dup" ) )
        {
            char *str = SSPop( st );
            SSPush( st, str );
            SSPush( st, str );
            free( str );
        }
        else if( !strcmp( s, "drop" ) )
        {
            char *str = SSPop( st );
            free( str );
        }
        else if( !strcmp( s, "swap" ) )
        {
            char *s1 = SSPop( st );
            char *s2 = SSPop( st );

            SSPush( st, s1 );
            SSPush( st, s2 );
            free( s1 );
            free( s2 );
        }
        else if( !strcmp( s, "flush" ) )
        {
            SSClean( st );
            SSInit( st );
        }
        else if( !strcmp( s, "store" ) )
        {
            char *value = SSPop( st );
            char *name  = SSPop( st );

            mvar_PushNewVar( vars, name, value );
            free( name );
            free( value );
        }
        else if( !strcmp( s, "value" ) )
        {
            char *name  = SSPop( st );
            const char *value = mvar_GetValue( vars, name );

            SSPush( st, value );

            free( name );
        }
        /* 5. player control */
        else if( !strcmp( s, "vlc_play" ) )
        {
            int i_id = SSPopN( st, vars );
            int i_ret;

            playlist_Lock( p_sys->p_playlist );
            i_ret = playlist_Control( p_sys->p_playlist, PLAYLIST_VIEWPLAY,
                                      pl_Locked, NULL,
                                      playlist_ItemGetById( p_sys->p_playlist,
                                      i_id ) );
            playlist_Unlock( p_sys->p_playlist );
            msg_Dbg( p_intf, "requested playlist item: %i", i_id );
            SSPushN( st, i_ret );
        }
        else if( !strcmp( s, "vlc_stop" ) )
        {
            playlist_Control( p_sys->p_playlist, PLAYLIST_STOP, pl_Unlocked );
            msg_Dbg( p_intf, "requested playlist stop" );
        }
        else if( !strcmp( s, "vlc_pause" ) )
        {
            playlist_Control( p_sys->p_playlist, PLAYLIST_PAUSE, pl_Unlocked );
            msg_Dbg( p_intf, "requested playlist pause" );
        }
        else if( !strcmp( s, "vlc_next" ) )
        {
            playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, pl_Unlocked, 1 );
            msg_Dbg( p_intf, "requested playlist next" );
        }
        else if( !strcmp( s, "vlc_previous" ) )
        {
            playlist_Control( p_sys->p_playlist, PLAYLIST_SKIP, pl_Unlocked, -1 );
            msg_Dbg( p_intf, "requested playlist previous" );
        }
        else if( !strcmp( s, "vlc_seek" ) )
        {
            char *psz_value = SSPop( st );
            HandleSeek( p_intf, psz_value );
            msg_Dbg( p_intf, "requested playlist seek: %s", psz_value );
            free( psz_value );
        }
        else if( !strcmp( s, "vlc_var_type" )
                  || !strcmp( s, "vlc_config_type" ) )
        {
            vlc_object_t *p_object;
            const char *psz_type = NULL;
            int i_type = 0;

            if( !strcmp( s, "vlc_var_type" ) )
            {
                char *psz_object = SSPop( st );
                char *psz_variable = SSPop( st );
                bool b_need_release;

                p_object = GetVLCObject( p_intf, psz_object, &b_need_release );

                if( p_object != NULL )
                    i_type = var_Type( p_object, psz_variable );
                free( psz_variable );
                free( psz_object );
                if( b_need_release && p_object != NULL )
                    vlc_object_release( p_object );
            }
            else
            {
                char *psz_variable = SSPop( st );
                p_object = VLC_OBJECT(p_intf);
                i_type = config_GetType( p_object, psz_variable );
                free( psz_variable );
            }

            if( p_object != NULL )
            {
                switch( i_type & VLC_VAR_TYPE )
                {
                case VLC_VAR_BOOL:
                    psz_type = "VLC_VAR_BOOL";
                    break;
                case VLC_VAR_INTEGER:
                    psz_type = "VLC_VAR_INTEGER";
                    break;
                case VLC_VAR_HOTKEY:
                    psz_type = "VLC_VAR_HOTKEY";
                    break;
                case VLC_VAR_STRING:
                    psz_type = "VLC_VAR_STRING";
                    break;
                case VLC_VAR_MODULE:
                    psz_type = "VLC_VAR_MODULE";
                    break;
                case VLC_VAR_FILE:
                    psz_type = "VLC_VAR_FILE";
                    break;
                case VLC_VAR_DIRECTORY:
                    psz_type = "VLC_VAR_DIRECTORY";
                    break;
                case VLC_VAR_VARIABLE:
                    psz_type = "VLC_VAR_VARIABLE";
                    break;
                case VLC_VAR_FLOAT:
                    psz_type = "VLC_VAR_FLOAT";
                    break;
                default:
                    psz_type = "UNDEFINED";
                }
            }
            else
                psz_type = "INVALID";

            SSPush( st, psz_type );
        }
        else if( !strcmp( s, "vlc_var_set" ) )
        {
            char *psz_object = SSPop( st );
            char *psz_variable = SSPop( st );
            bool b_need_release;

            vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
                                                   &b_need_release );

            if( p_object != NULL )
            {
                bool b_error = false;
                char *psz_value = NULL;
                vlc_value_t val;
                int i_type;

                i_type = var_Type( p_object, psz_variable );

                switch( i_type & VLC_VAR_TYPE )
                {
                case VLC_VAR_BOOL:
                    val.b_bool = SSPopN( st, vars );
                    msg_Dbg( p_intf, "requested %s var change: %s->%d",
                             psz_object, psz_variable, val.b_bool );
                    break;
                case VLC_VAR_INTEGER:
                case VLC_VAR_HOTKEY:
                    val.i_int = SSPopN( st, vars );
                    msg_Dbg( p_intf, "requested %s var change: %s->%d",
                             psz_object, psz_variable, val.i_int );
                    break;
                case VLC_VAR_STRING:
                case VLC_VAR_MODULE:
                case VLC_VAR_FILE:
                case VLC_VAR_DIRECTORY:
                case VLC_VAR_VARIABLE:
                    val.psz_string = psz_value = SSPop( st );
                    msg_Dbg( p_intf, "requested %s var change: %s->%s",
                             psz_object, psz_variable, psz_value );
                    break;
                case VLC_VAR_FLOAT:
                    psz_value = SSPop( st );
                    val.f_float = atof( psz_value );
                    msg_Dbg( p_intf, "requested %s var change: %s->%f",
                             psz_object, psz_variable, val.f_float );
                    break;
                default:
                    SSPopN( st, vars );
                    msg_Warn( p_intf, "invalid %s variable type %d (%s)",
                              psz_object, i_type & VLC_VAR_TYPE, psz_variable );
                    b_error = true;
                }

                if( !b_error )
                    var_Set( p_object, psz_variable, val );
                if( psz_value != NULL )
                    free( psz_value );
            }
            else
                msg_Warn( p_intf, "vlc_var_set called without an object" );
            free( psz_variable );
            free( psz_object );

            if( b_need_release && p_object != NULL )
                vlc_object_release( p_object );
        }
        else if( !strcmp( s, "vlc_var_get" ) )
        {
            char *psz_object = SSPop( st );
            char *psz_variable = SSPop( st );
            bool b_need_release;

            vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
                                                   &b_need_release );

            if( p_object != NULL )
            {
                vlc_value_t val;
                int i_type;

                i_type = var_Type( p_object, psz_variable );
                var_Get( p_object, psz_variable, &val );

                switch( i_type & VLC_VAR_TYPE )
                {
                case VLC_VAR_BOOL:
                    SSPushN( st, val.b_bool );
                    break;
                case VLC_VAR_INTEGER:
                case VLC_VAR_HOTKEY:
                    SSPushN( st, val.i_int );
                    break;
                case VLC_VAR_STRING:
                case VLC_VAR_MODULE:
                case VLC_VAR_FILE:
                case VLC_VAR_DIRECTORY:
                case VLC_VAR_VARIABLE:
                    SSPush( st, val.psz_string );
                    free( val.psz_string );
                    break;
                case VLC_VAR_FLOAT:
                {
                    char psz_value[20];
                    lldiv_t value = lldiv( val.f_float * 1000000, 1000000 );
                    snprintf( psz_value, sizeof(psz_value), "%lld.%06u",
                                    value.quot, (unsigned int)value.rem );
                    SSPush( st, psz_value );
                    break;
                }
                default:
                    msg_Warn( p_intf, "invalid %s variable type %d (%s)",
                              psz_object, i_type & VLC_VAR_TYPE, psz_variable );
                    SSPush( st, "" );
                }
            }
            else
            {
                msg_Warn( p_intf, "vlc_var_get called without an object" );
                SSPush( st, "" );
            }
            free( psz_variable );
            free( psz_object );

            if( b_need_release && p_object != NULL )
                vlc_object_release( p_object );
        }
        else if( !strcmp( s, "vlc_object_exists" ) )
        {
            char *psz_object = SSPop( st );
            bool b_need_release;

            vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
                                                   &b_need_release );
            if( b_need_release && p_object != NULL )
                vlc_object_release( p_object );

            if( p_object != NULL )
                SSPush( st, "1" );
            else
                SSPush( st, "0" );
        }
        else if( !strcmp( s, "vlc_config_set" ) )
        {
            char *psz_variable = SSPop( st );
            int i_type = config_GetType( p_intf, psz_variable );

            switch( i_type & VLC_VAR_TYPE )
            {
            case VLC_VAR_BOOL:
            case VLC_VAR_INTEGER:
                config_PutInt( p_intf, psz_variable, SSPopN( st, vars ) );
                break;
            case VLC_VAR_STRING:
            case VLC_VAR_MODULE:
            case VLC_VAR_FILE:
            case VLC_VAR_DIRECTORY:
            {
                char *psz_string = SSPop( st );
                config_PutPsz( p_intf, psz_variable, psz_string );
                free( psz_string );
                break;
            }
            case VLC_VAR_FLOAT:
            {
                char *psz_string = SSPop( st );
                config_PutFloat( p_intf, psz_variable, atof(psz_string) );
                free( psz_string );
                break;
            }
            default:
                msg_Warn( p_intf, "vlc_config_set called on unknown var (%s)",
                          psz_variable );
            }
            free( psz_variable );
        }
        else if( !strcmp( s, "vlc_config_get" ) )
        {
            char *psz_variable = SSPop( st );
            int i_type = config_GetType( p_intf, psz_variable );

            switch( i_type & VLC_VAR_TYPE )
            {
            case VLC_VAR_BOOL:
            case VLC_VAR_INTEGER:
                SSPushN( st, config_GetInt( p_intf, psz_variable ) );
                break;
            case VLC_VAR_STRING:
            case VLC_VAR_MODULE:
            case VLC_VAR_FILE:
            case VLC_VAR_DIRECTORY:
            {
                char *psz_string = config_GetPsz( p_intf, psz_variable );
                SSPush( st, psz_string );
                free( psz_string );
                break;
            }
            case VLC_VAR_FLOAT:
            {
                char psz_string[20];
                lldiv_t value = lldiv( config_GetFloat( p_intf, psz_variable )
                                       * 1000000, 1000000 );
                snprintf( psz_string, sizeof(psz_string), "%lld.%06u",
                          value.quot, (unsigned int)value.rem );
                SSPush( st, psz_string );
                break;
            }
            default:
                msg_Warn( p_intf, "vlc_config_get called on unknown var (%s)",
                          psz_variable );
                SSPush( st, "" );
            }
            free( psz_variable );
        }
        else if( !strcmp( s, "vlc_config_save" ) )
        {
            char *psz_module = SSPop( st );
            int i_result;

            if( !*psz_module )
            {
                free( psz_module );
                psz_module = NULL;
            }
            i_result = config_SaveConfigFile( p_intf, psz_module );

            if( psz_module != NULL )
                free( psz_module );
            SSPushN( st, i_result );
        }
        else if( !strcmp( s, "vlc_config_reset" ) )
        {
            config_ResetAll( p_intf );
        }
        /* 6. playlist functions */
        else if( !strcmp( s, "playlist_add" ) )
        {
            char *psz_name = SSPop( st );
            char *mrl = SSPop( st );
            input_item_t *p_input;
            int i_ret;

            p_input = MRLParse( p_intf, mrl, psz_name );

            char *psz_uri = input_item_GetURI( p_input );
            if( !p_input || !psz_uri || !*psz_uri )
            {
                i_ret = VLC_EGENERIC;
                msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
            }
            else
            {
                i_ret = playlist_AddInput( p_sys->p_playlist, p_input,
                                   PLAYLIST_APPEND, PLAYLIST_END, true,
                                   pl_Unlocked );
                if( i_ret == VLC_SUCCESS )
                {
                    playlist_item_t *p_item;
                    msg_Dbg( p_intf, "requested mrl add: %s", mrl );
                    playlist_Lock( p_sys->p_playlist );
                    p_item = playlist_ItemGetByInput( p_sys->p_playlist,
                                                      p_input );
                    if( p_item )
                        i_ret = p_item->i_id;
                    playlist_Unlock( p_sys->p_playlist );
                }
                else
                    msg_Warn( p_intf, "adding mrl %s failed", mrl );
                vlc_gc_decref( p_input );
            }
            free( psz_uri );
            SSPushN( st, i_ret );

            free( mrl );
            free( psz_name );
        }
        else if( !strcmp( s, "playlist_empty" ) )
        {
            playlist_Clear( p_sys->p_playlist, pl_Unlocked );
            msg_Dbg( p_intf, "requested playlist empty" );
        }
        else if( !strcmp( s, "playlist_delete" ) )
        {
            int i_id = SSPopN( st, vars );
            playlist_Lock( p_sys->p_playlist );
            playlist_item_t *p_item = playlist_ItemGetById( p_sys->p_playlist,
                                                            i_id );
            if( p_item )
            {
                playlist_DeleteFromInput( p_sys->p_playlist,
                                          p_item->p_input, pl_Locked );
                msg_Dbg( p_intf, "requested playlist delete: %d", i_id );
            }
            else
            {
                msg_Dbg( p_intf, "couldn't find playlist item to delete (%d)",
                         i_id );
            }
            playlist_Unlock( p_sys->p_playlist );
        }
        else if( !strcmp( s, "playlist_move" ) )
        {
            /*int i_newpos =*/ SSPopN( st, vars );
            /*int i_pos =*/ SSPopN( st, vars );
            /* FIXME FIXME TODO TODO XXX XXX
            do not release before fixing this
            if ( i_pos < i_newpos )
            {
                playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
            }
            else
            {
                playlist_Move( p_sys->p_playlist, i_pos, i_newpos );
            }
            msg_Dbg( p_intf, "requested to move playlist item %d to %d",
                     i_pos, i_newpos);
               FIXME FIXME TODO TODO XXX XXX */
            msg_Err( p_intf, "moving using indexes is obsolete. We need to update this function" );
        }
        else if( !strcmp( s, "playlist_sort" ) )
        {
            int i_order = SSPopN( st, vars );
            int i_sort = SSPopN( st, vars );
            i_order = i_order % 2;
            i_sort = i_sort % 9;
            /* FIXME FIXME TODO TODO XXX XXX
            do not release before fixing this
            playlist_RecursiveNodeSort(  p_sys->p_playlist,
                                         p_sys->p_playlist->p_general,
                                         i_sort, i_order );
            msg_Dbg( p_intf, "requested sort playlist by : %d in order : %d",
                     i_sort, i_order );
               FIXME FIXME TODO TODO XXX XXX */
            msg_Err( p_intf, "this needs to be fixed to use the new playlist framework" );
        }
        else if( !strcmp( s, "services_discovery_add" ) )
        {
            char *psz_sd = SSPop( st );
            playlist_ServicesDiscoveryAdd( p_sys->p_playlist, psz_sd );
            free( psz_sd );
        }
        else if( !strcmp( s, "services_discovery_remove" ) )
        {
            char *psz_sd = SSPop( st );
            playlist_ServicesDiscoveryRemove( p_sys->p_playlist, psz_sd );
            free( psz_sd );
        }
        else if( !strcmp( s, "services_discovery_is_loaded" ) )
        {
            char *psz_sd = SSPop( st );
            SSPushN( st,
            playlist_IsServicesDiscoveryLoaded( p_sys->p_playlist, psz_sd ) );
            free( psz_sd );
        }
        else if( !strcmp( s, "vlc_volume_set" ) )
        {
            char *psz_vol = SSPop( st );
            int i_value;
            audio_volume_t i_volume;
            aout_VolumeGet( p_intf, &i_volume );
            if( psz_vol[0] == '+' )
            {
                i_value = atoi( psz_vol );
                if( (i_volume + i_value) > AOUT_VOLUME_MAX )
                    aout_VolumeSet( p_intf, AOUT_VOLUME_MAX );
                else
                    aout_VolumeSet( p_intf, i_volume + i_value );
            }
            else if( psz_vol[0] == '-' )
            {
                i_value = atoi( psz_vol );
                if( (i_volume + i_value) < AOUT_VOLUME_MIN )
                    aout_VolumeSet( p_intf, AOUT_VOLUME_MIN );
                else
                    aout_VolumeSet( p_intf, i_volume + i_value );
            }
            else if( strstr( psz_vol, "%") != NULL )
            {
                i_value = atoi( psz_vol );
                if( i_value < 0 ) i_value = 0;
                if( i_value > 400 ) i_value = 400;
                aout_VolumeSet( p_intf, (i_value * (AOUT_VOLUME_MAX - AOUT_VOLUME_MIN))/400+AOUT_VOLUME_MIN);
            }
            else
            {
                i_value = atoi( psz_vol );
                if( i_value > AOUT_VOLUME_MAX ) i_value = AOUT_VOLUME_MAX;
                if( i_value < AOUT_VOLUME_MIN ) i_value = AOUT_VOLUME_MIN;
                aout_VolumeSet( p_intf, i_value );
            }
            aout_VolumeGet( p_intf, &i_volume );
            free( psz_vol );
        }
        else if( !strcmp( s, "vlc_get_meta" ) )
        {
            char *psz_meta = SSPop( st );
            char *psz_val = NULL;
            if( p_sys->p_input && input_GetItem(p_sys->p_input) )
            {
#define p_item input_GetItem( p_sys->p_input )
                if( !strcmp( psz_meta, "ARTIST" ) )
                {
                    psz_val = input_item_GetArtist( p_item );
                }
                else if( !strcmp( psz_meta, "TITLE" ) )
                {
                    psz_val = input_item_GetTitle( p_item );
                    if( !psz_val )
                        psz_val = input_item_GetName( p_item );
                }
                else if( !strcmp( psz_meta, "ALBUM" ) )
                {
                    psz_val = input_item_GetAlbum( p_item );
                }
                else if( !strcmp( psz_meta, "GENRE" ) )
                {
                    psz_val = input_item_GetGenre( p_item );
                }
                else if( !strcmp( psz_meta, "COPYRIGHT" ) )
                {
                     psz_val = input_item_GetCopyright( p_item );
                }
                else if( !strcmp( psz_meta, "TRACK_NUMBER" ) )
                {
                    psz_val = input_item_GetTrackNum( p_item );
                }
                else if( !strcmp( psz_meta, "DESCRIPTION" ) )
                {
                    psz_val = input_item_GetDescription( p_item );
                }
                else if( !strcmp( psz_meta, "RATING" ) )
                {
                    psz_val = input_item_GetRating( p_item );
                }
                else if( !strcmp( psz_meta, "DATE" ) )
                {
                    psz_val = input_item_GetDate( p_item );
                }
                else if( !strcmp( psz_meta, "URL" ) )
                {
                    psz_val = input_item_GetURL( p_item );
                }
                else if( !strcmp( psz_meta, "LANGUAGE" ) )
                {
                    psz_val = input_item_GetLanguage( p_item );
                }
                else if( !strcmp( psz_meta, "NOW_PLAYING" ) )
                {
                    psz_val = input_item_GetNowPlaying( p_item );
                }
                else if( !strcmp( psz_meta, "PUBLISHER" ) )
                {
                    psz_val = input_item_GetPublisher( p_item );
                }
                else if( !strcmp( psz_meta, "ENCODED_BY" ) )
                {
                    psz_val = input_item_GetEncodedBy( p_item );
                }
                else if( !strcmp( psz_meta, "ART_URL" ) )
                {
                    psz_val = input_item_GetEncodedBy( p_item );
                }
                else if( !strcmp( psz_meta, "TRACK_ID" ) )
                {
                    psz_val = input_item_GetTrackID( p_item );
                }
#undef p_item
            }
            if( psz_val == NULL ) psz_val = strdup( "" );
            SSPush( st, psz_val );
            free( psz_meta );
            free( psz_val );
        }
#ifdef ENABLE_VLM
        else if( !strcmp( s, "vlm_command" ) || !strcmp( s, "vlm_cmd" ) )
        {
            char *psz_elt;
            char *psz_cmd = strdup( "" );
            char *psz_error;
            vlm_message_t *vlm_answer;

            /* make sure that we have a vlm object */
            if( p_intf->p_sys->p_vlm == NULL )
                p_intf->p_sys->p_vlm = vlm_New( p_intf );


            /* vlm command uses the ';' delimiter
             * (else we can't know when to stop) */
            while( strcmp( psz_elt = SSPop( st ), "" )
                   && strcmp( psz_elt, ";" ) )
            {
                char* psz_buf;
                if( asprintf( &psz_buf, "%s %s", psz_cmd, psz_elt ) == -1 )
                    psz_buf = NULL;
                free( psz_cmd );
                free( psz_elt );
                psz_cmd = psz_buf;
            }

            msg_Dbg( p_intf, "executing vlm command: %s", psz_cmd );
            vlm_ExecuteCommand( p_intf->p_sys->p_vlm, psz_cmd, &vlm_answer );

            if( vlm_answer->psz_value == NULL )
            {
                psz_error = strdup( "" );
            }
            else
            {
                if( asprintf( &psz_error , "%s : %s" , vlm_answer->psz_name,
                              vlm_answer->psz_value ) == -1 )
                    psz_error = NULL;
            }

            mvar_AppendNewVar( vars, "vlm_error", psz_error );
            /* this is kind of a duplicate but we need to have the message
             * without the command name for the "export" command */
            mvar_AppendNewVar( vars, "vlm_value", vlm_answer->psz_value );
            vlm_MessageDelete( vlm_answer );

            free( psz_cmd );
            free( psz_error );
        }
#endif /* ENABLE_VLM */
        else if( !strcmp( s, "snapshot" ) )
        {
            if( p_sys->p_input )
            {
                vout_thread_t *p_vout = input_GetVout( p_sys->p_input );
                if( p_vout )
                {
                    var_TriggerCallback( p_vout, "video-snapshot" );
                    vlc_object_release( p_vout );
                    msg_Dbg( p_intf, "requested snapshot" );
                }
            }
            break;

        }
        else
        {
            SSPush( st, s );
        }
    }
}
Пример #25
0
int  ArtCallback( httpd_handler_sys_t *p_args,
                          httpd_handler_t *p_handler, char *_p_url,
                          uint8_t *p_request, int i_type,
                          uint8_t *p_in, int i_in,
                          char *psz_remote_addr, char *psz_remote_host,
                          uint8_t **pp_data, int *pi_data )
{
    VLC_UNUSED(p_handler); VLC_UNUSED(_p_url); VLC_UNUSED(i_type); 
    VLC_UNUSED(p_in); VLC_UNUSED(i_in); VLC_UNUSED(psz_remote_addr); 
    VLC_UNUSED(psz_remote_host); 

    char *psz_art = NULL;
    intf_thread_t *p_intf = p_args->file.p_intf;
    intf_sys_t *p_sys = p_intf->p_sys;
    char psz_id[16];
    input_item_t *p_item = NULL;
    int i_id;

    psz_id[0] = '\0';
    if( p_request )
        ExtractURIValue( (char *)p_request, "id", psz_id, 15 );
    i_id = atoi( psz_id );
    if( i_id )
    {
        playlist_Lock( p_sys->p_playlist );
        playlist_item_t *p_pl_item = playlist_ItemGetById( p_sys->p_playlist,
                                                           i_id );
        if( p_pl_item )
            p_item = p_pl_item->p_input;
        playlist_Unlock( p_sys->p_playlist );
    }
    else
    {
        /* FIXME: Workarround a stupid assert in input_GetItem */
        if( p_sys->p_input && p_sys->p_input->p )
            p_item = input_GetItem( p_sys->p_input );
    }

    if( p_item )
    {
        psz_art = input_item_GetArtURL( p_item );
    }

    if( psz_art )
    {
        char *psz = make_path( psz_art );
        free( psz_art );
        psz_art = psz;
    }

    if( psz_art == NULL )
    {
        msg_Dbg( p_intf, "No album art found" );
        Callback404( &p_args->file, (char**)pp_data, pi_data );
        return VLC_SUCCESS;
    }

    FILE *f = vlc_fopen( psz_art, "r" );
    if( f == NULL )
    {
        msg_Dbg( p_intf, "Couldn't open album art file %s", psz_art );
        Callback404( &p_args->file, (char**)pp_data, pi_data );
        free( psz_art );
        return VLC_SUCCESS;
    }
    free( psz_art );

    char *p_data = NULL;
    int i_data;
    FileLoad( f, &p_data, &i_data );
    fclose( f );

    char *psz_ext = strrchr( psz_art, '.' );
    if( psz_ext ) psz_ext++;

#define HEADER  "Content-Type: image/%s\n" \
                "Content-Length: %d\n" \
                "\n"
    char *psz_header;
    int i_header_size = asprintf( &psz_header, HEADER, psz_ext, i_data );
#undef HEADER
    if( likely(i_header_size != -1) )
    {
        *pp_data = malloc( i_header_size + i_data );
        if( likely(*pp_data != NULL) )
        {
            *pi_data = i_header_size + i_data;
            memcpy( *pp_data, psz_header, i_header_size );
            memcpy( *pp_data+i_header_size, p_data, i_data );
        }
        free( psz_header );
    }
    free( p_data );

    return VLC_SUCCESS;
}
Пример #26
0
 vlc_playlist_locker( playlist_t* p_playlist )
     : p_playlist( p_playlist )
 {
     playlist_Lock( p_playlist ); 
 }
Пример #27
0
void Playtree::insertItems( VarTree& elem, const std::list<std::string>& files, bool start )
{
    bool first = true;
    VarTree* p_elem = &elem;
    playlist_item_t* p_node = NULL;
    int i_pos = -1;

    playlist_Lock( m_pPlaylist );

    if( p_elem == this )
    {
        for( Iterator it = m_children.begin(); it != m_children.end(); ++it )
        {
            if( it->getId() == m_pPlaylist->p_playing->i_id )
            {
                p_elem = &*it;
                break;
            }
        }
    }

    if( p_elem->getId() == m_pPlaylist->p_playing->i_id )
    {
        p_node = m_pPlaylist->p_playing;
        i_pos = 0;
        p_elem->setExpanded( true );
    }
    else if( p_elem->getId() == m_pPlaylist->p_media_library->i_id )
    {
        p_node = m_pPlaylist->p_media_library;
        i_pos = 0;
        p_elem->setExpanded( true );
    }
    else if( p_elem->size() && p_elem->isExpanded() )
    {
        p_node = playlist_ItemGetById( m_pPlaylist, p_elem->getId() );
        i_pos = 0;
    }
    else
    {
        p_node = playlist_ItemGetById( m_pPlaylist,
                                       p_elem->parent()->getId() );
        i_pos = p_elem->getIndex();
        i_pos++;
    }

    if( !p_node )
        goto fin;

    for( std::list<std::string>::const_iterator it = files.begin();
         it != files.end(); ++it, i_pos++, first = false )
    {
        input_item_t *pItem;

        if( strstr( it->c_str(), "://" ) )
            pItem = input_item_New( it->c_str(), NULL );
        else
        {
            char *psz_uri = vlc_path2uri( it->c_str(), NULL );
            if( psz_uri == NULL )
                continue;
            pItem = input_item_New( psz_uri, NULL );
            free( psz_uri );
        }

        if( pItem == NULL)
            continue;

        int i_mode = 0;
        if( first && start )
            i_mode |= PLAYLIST_GO;

        playlist_NodeAddInput( m_pPlaylist, pItem, p_node,
                               i_mode, i_pos );
    }

fin:
    playlist_Unlock( m_pPlaylist );
}