Exemple #1
0
static int vlclua_sd_add( lua_State *L )
{
    const char *psz_sd = luaL_checkstring( L, 1 );
    playlist_t *p_playlist = vlclua_get_playlist_internal( L );
    int i_ret = playlist_ServicesDiscoveryAdd( p_playlist, psz_sd );
    return vlclua_push_ret( L, i_ret );
}
Exemple #2
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 )
        return;

    assert( ( i_type == PL_TYPE || i_type == ML_TYPE || i_type == SD_TYPE ) );
    if( i_type == SD_TYPE )
    {
        QString qs = item->data( 0, NAME_ROLE ).toString();
        if( !playlist_IsServicesDiscoveryLoaded( THEPL, qtu( qs ) ) )
        {
            playlist_ServicesDiscoveryAdd( THEPL, qtu( qs ) );
#warning FIXME
            playlist_item_t *pl_item =
                    THEPL->p_root_category->pp_children[THEPL->p_root_category->i_children-1];
            item->setData( 0, PPL_ITEM_ROLE, QVariant::fromValue( pl_item ) );

            emit activated( pl_item );
            return;
        }
    }

    if( i_type == SD_TYPE )
        msg_Dbg( p_intf, "SD already loaded, reloading" );

    playlist_item_t *pl_item =
            item->data( 0, PPL_ITEM_ROLE ).value<playlist_item_t *>();
    if( pl_item )
            emit activated( pl_item );
}
Exemple #3
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 );
}
Exemple #4
0
/**
 * Create playlist
 *
 * Create a playlist structure.
 * \param p_parent the vlc object that is to be the parent of this playlist
 * \return a pointer to the created playlist, or NULL on error
 */
static playlist_t *playlist_Create( vlc_object_t *p_parent )
{
    playlist_t *p_playlist;
    playlist_private_t *p;

    /* Allocate structure */
    p = vlc_custom_create( p_parent, sizeof( *p ), "playlist" );
    if( !p )
        return NULL;

    assert( offsetof( playlist_private_t, public_data ) == 0 );
    p_playlist = &p->public_data;
    TAB_INIT( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds );

    VariablesInit( p_playlist );
    vlc_mutex_init( &p->lock );
    vlc_cond_init( &p->signal );
    p->killed = false;

    /* Initialise data structures */
    pl_priv(p_playlist)->i_last_playlist_id = 0;
    pl_priv(p_playlist)->p_input = NULL;

    ARRAY_INIT( p_playlist->items );
    ARRAY_INIT( p_playlist->all_items );
    ARRAY_INIT( pl_priv(p_playlist)->items_to_delete );
    ARRAY_INIT( p_playlist->current );

    p_playlist->i_current_index = 0;
    pl_priv(p_playlist)->b_reset_currently_playing = true;

    pl_priv(p_playlist)->b_tree = var_InheritBool( p_parent, "playlist-tree" );

    pl_priv(p_playlist)->b_doing_ml = false;

    pl_priv(p_playlist)->b_auto_preparse =
        var_InheritBool( p_parent, "auto-preparse" );

   /* Preparser (and meta retriever) */
   p->p_preparser = playlist_preparser_New( VLC_OBJECT(p_playlist) );
   if( unlikely(p->p_preparser == NULL) )
       msg_Err( p_playlist, "cannot create preparser" );

    /* Create the root node */
    PL_LOCK;
    p_playlist->p_root = playlist_NodeCreate( p_playlist, NULL, NULL,
                                    PLAYLIST_END, 0, NULL );
    PL_UNLOCK;
    if( !p_playlist->p_root ) return NULL;

    /* Create currently playing items node */
    PL_LOCK;
    p_playlist->p_playing = playlist_NodeCreate(
        p_playlist, _( "Playlist" ), p_playlist->p_root,
        PLAYLIST_END, PLAYLIST_RO_FLAG, NULL );

    PL_UNLOCK;

    if( !p_playlist->p_playing ) return NULL;

    /* Create media library node */
    const bool b_ml = var_InheritBool( p_parent, "media-library");
    if( b_ml )
    {
        PL_LOCK;
        p_playlist->p_media_library = playlist_NodeCreate(
            p_playlist, _( "Media Library" ), p_playlist->p_root,
            PLAYLIST_END, PLAYLIST_RO_FLAG, NULL );
        PL_UNLOCK;
    }
    else
    {
        p_playlist->p_media_library = NULL;
    }

    p_playlist->p_root_category = p_playlist->p_root;
    p_playlist->p_root_onelevel = p_playlist->p_root;
    p_playlist->p_local_category = p_playlist->p_playing;
    p_playlist->p_local_onelevel = p_playlist->p_playing;
    p_playlist->p_ml_category = p_playlist->p_media_library;
    p_playlist->p_ml_onelevel = p_playlist->p_media_library;;

    /* Initial status */
    pl_priv(p_playlist)->status.p_item = NULL;
    pl_priv(p_playlist)->status.p_node = p_playlist->p_playing;
    pl_priv(p_playlist)->request.b_request = false;
    pl_priv(p_playlist)->status.i_status = PLAYLIST_STOPPED;

    if(b_ml)
    {
        const bool b_auto_preparse = pl_priv(p_playlist)->b_auto_preparse;
        pl_priv(p_playlist)->b_auto_preparse = false;
        playlist_MLLoad( p_playlist );
        pl_priv(p_playlist)->b_auto_preparse = b_auto_preparse;
    }

    /* Input resources */
    p->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) );
    if( unlikely(p->p_input_resource == NULL) )
        abort();

    /* Audio output (needed for volume and device controls). */
    audio_output_t *aout = input_resource_GetAout( p->p_input_resource );
    if( aout != NULL )
        input_resource_PutAout( p->p_input_resource, aout );

    /* Thread */
    playlist_Activate (p_playlist);

    /* Add service discovery modules */
    char *mods = var_InheritString( p_playlist, "services-discovery" );
    if( mods != NULL )
    {
        char *p = mods, *m;
        while( (m = strsep( &p, " :," )) != NULL )
            playlist_ServicesDiscoveryAdd( p_playlist, m );
        free( mods );
    }

    return p_playlist;
}
Exemple #5
0
/**
 * Initialize a libvlc instance
 * This function initializes a previously allocated libvlc instance:
 *  - CPU detection
 *  - gettext initialization
 *  - message queue, module bank and playlist initialization
 *  - configuration and commandline parsing
 */
int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
                         const char *ppsz_argv[] )
{
    libvlc_priv_t *priv = libvlc_priv (p_libvlc);
    char *       psz_modules = NULL;
    char *       psz_parser = NULL;
    char *       psz_control = NULL;
    playlist_t  *p_playlist = NULL;
    char        *psz_val;

    /* System specific initialization code */
    system_Init();

    /* Initialize the module bank and load the configuration of the
     * main module. We need to do this at this stage to be able to display
     * a short help if required by the user. (short help == main module
     * options) */
    module_InitBank ();

    /* Get command line options that affect module loading. */
    if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, NULL ) )
    {
        module_EndBank (false);
        return VLC_EGENERIC;
    }
    priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" );

    /* Find verbosity from VLC_VERBOSE environment variable */
    {
        char *env = getenv( "VLC_VERBOSE" );
        if( env != NULL )
            priv->i_verbose = atoi( env );
    }

    /* Announce who we are (TODO: only first instance?) */
    msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE );
    msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
    msg_Dbg( p_libvlc, "revision %s", psz_vlc_changeset );
    msg_Dbg( p_libvlc, "configured with %s", CONFIGURE_LINE );

    /* Load the builtins and plugins into the module_bank.
     * We have to do it before config_Load*() because this also gets the
     * list of configuration options exported by each module and loads their
     * default values. */
    size_t module_count = module_LoadPlugins (p_libvlc);

    /*
     * Override default configuration with config file settings
     */
    if( !var_InheritBool( p_libvlc, "ignore-config" ) )
    {
        if( var_InheritBool( p_libvlc, "reset-config" ) )
            config_SaveConfigFile( p_libvlc ); /* Save default config */
        else
            config_LoadConfigFile( p_libvlc );
    }

    /*
     * Override configuration with command line settings
     */
    int vlc_optind;
    if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) )
    {
#ifdef WIN32
        MessageBox (NULL, TEXT("The command line options could not be parsed.\n"
                    "Make sure they are valid."), TEXT("VLC media player"),
                    MB_OK|MB_ICONERROR);
#endif
        module_EndBank (true);
        return VLC_EGENERIC;
    }
    priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" );

    /*
     * Support for gettext
     */
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
    vlc_bindtextdomain (PACKAGE_NAME);
#endif
    /*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
    msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );

    if (config_PrintHelp (VLC_OBJECT(p_libvlc)))
    {
        module_EndBank (true);
        return VLC_EEXITSUCCESS;
    }

    if( module_count <= 1 )
    {
        msg_Err( p_libvlc, "No plugins found! Check your VLC installation.");
        module_EndBank (true);
        return VLC_ENOITEM;
    }

#ifdef HAVE_DAEMON
    /* Check for daemon mode */
    if( var_InheritBool( p_libvlc, "daemon" ) )
    {
        char *psz_pidfile = NULL;

        if( daemon( 1, 0) != 0 )
        {
            msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" );
            module_EndBank (true);
            return VLC_EEXIT;
        }
        b_daemon = true;

        /* lets check if we need to write the pidfile */
        psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" );
        if( psz_pidfile != NULL )
        {
            FILE *pidfile;
            pid_t i_pid = getpid ();
            msg_Dbg( p_libvlc, "PID is %d, writing it to %s",
                               i_pid, psz_pidfile );
            pidfile = vlc_fopen( psz_pidfile,"w" );
            if( pidfile != NULL )
            {
                utf8_fprintf( pidfile, "%d", (int)i_pid );
                fclose( pidfile );
            }
            else
            {
                msg_Err( p_libvlc, "cannot open pid file for writing: %s (%m)",
                         psz_pidfile );
            }
        }
        free( psz_pidfile );
    }
#endif

/* FIXME: could be replaced by using Unix sockets */
#ifdef HAVE_DBUS

#define MPRIS_APPEND "/org/mpris/MediaPlayer2/TrackList/Append"
#define MPRIS_BUS_NAME "org.mpris.MediaPlayer2.vlc"
#define MPRIS_OBJECT_PATH "/org/mpris/MediaPlayer2"
#define MPRIS_TRACKLIST_INTERFACE "org.mpris.MediaPlayer2.TrackList"

    dbus_threads_init_default();

    if( var_InheritBool( p_libvlc, "one-instance" )
    || ( var_InheritBool( p_libvlc, "one-instance-when-started-from-file" )
      && var_InheritBool( p_libvlc, "started-from-file" ) ) )
    {
        /* Initialise D-Bus interface, check for other instances */
        DBusConnection  *p_conn = NULL;
        DBusError       dbus_error;

        dbus_error_init( &dbus_error );

        /* connect to the session bus */
        p_conn = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error );
        if( !p_conn )
        {
            msg_Err( p_libvlc, "Failed to connect to D-Bus session daemon: %s",
                    dbus_error.message );
            dbus_error_free( &dbus_error );
        }
        else
        {
            /* check if VLC is available on the bus
             * if not: D-Bus control is not enabled on the other
             * instance and we can't pass MRLs to it */
            if( !dbus_bus_name_has_owner( p_conn, MPRIS_BUS_NAME, &dbus_error ) )
            {
                if( dbus_error_is_set( &dbus_error ) )
                {
                    msg_Err( p_libvlc, "D-Bus error: %s", dbus_error.message );
                    dbus_error_free( &dbus_error );
                }
                else
                    msg_Dbg( p_libvlc, "No Media Player is running. "
                            "Continuing normally." );
            }
            else
            {
                int i_input;
                DBusMessage* p_dbus_msg = NULL;
                DBusMessageIter dbus_args;
                DBusPendingCall* p_dbus_pending = NULL;
                dbus_bool_t b_play;

                msg_Warn( p_libvlc, "Another Media Player is running. Exiting");

                for( i_input = vlc_optind; i_input < i_argc;i_input++ )
                {
                    /* Skip input options, we can't pass them through D-Bus */
                    if( ppsz_argv[i_input][0] == ':' )
                    {
                        msg_Warn( p_libvlc, "Ignoring option %s",
                                  ppsz_argv[i_input] );
                        continue;
                    }

                    /* We need to resolve relative paths in this instance */
                    char *psz_mrl;
                    if( strstr( psz_mrl, "://" ) )
                        psz_mrl = strdup( ppsz_argv[i_input] );
                    else
                        psz_mrl = vlc_path2uri( ppsz_argv[i_input], NULL );
                    const char *psz_after_track = MPRIS_APPEND;

                    if( psz_mrl == NULL )
                        continue;
                    msg_Dbg( p_libvlc, "Adds %s to the running Media Player",
                             psz_mrl );

                    p_dbus_msg = dbus_message_new_method_call(
                        MPRIS_BUS_NAME, MPRIS_OBJECT_PATH,
                        MPRIS_TRACKLIST_INTERFACE, "AddTrack" );

                    if ( NULL == p_dbus_msg )
                    {
                        msg_Err( p_libvlc, "D-Bus problem" );
                        free( psz_mrl );
                        system_End( );
                        exit( 1 );
                    }

                    /* append MRLs */
                    dbus_message_iter_init_append( p_dbus_msg, &dbus_args );
                    if ( !dbus_message_iter_append_basic( &dbus_args,
                                DBUS_TYPE_STRING, &psz_mrl ) )
                    {
                        dbus_message_unref( p_dbus_msg );
                        free( psz_mrl );
                        system_End( );
                        exit( 1 );
                    }
                    free( psz_mrl );

                    if( !dbus_message_iter_append_basic( &dbus_args,
                                DBUS_TYPE_OBJECT_PATH, &psz_after_track ) )
                    {
                        dbus_message_unref( p_dbus_msg );
                        system_End( );
                        exit( 1 );
                    }

                    b_play = TRUE;
                    if( var_InheritBool( p_libvlc, "playlist-enqueue" ) )
                        b_play = FALSE;

                    if ( !dbus_message_iter_append_basic( &dbus_args,
                                DBUS_TYPE_BOOLEAN, &b_play ) )
                    {
                        dbus_message_unref( p_dbus_msg );
                        system_End( );
                        exit( 1 );
                    }

                    /* send message and get a handle for a reply */
                    if ( !dbus_connection_send_with_reply ( p_conn,
                                p_dbus_msg, &p_dbus_pending, -1 ) )
                    {
                        msg_Err( p_libvlc, "D-Bus problem" );
                        dbus_message_unref( p_dbus_msg );
                        system_End( );
                        exit( 1 );
                    }

                    if ( NULL == p_dbus_pending )
                    {
                        msg_Err( p_libvlc, "D-Bus problem" );
                        dbus_message_unref( p_dbus_msg );
                        system_End( );
                        exit( 1 );
                    }
                    dbus_connection_flush( p_conn );
                    dbus_message_unref( p_dbus_msg );
                    /* block until we receive a reply */
                    dbus_pending_call_block( p_dbus_pending );
                    dbus_pending_call_unref( p_dbus_pending );
                } /* processes all command line MRLs */

                /* bye bye */
                system_End( );
                exit( 0 );
            }
        }
        /* we unreference the connection when we've finished with it */
        if( p_conn ) dbus_connection_unref( p_conn );
    }

#undef MPRIS_APPEND
#undef MPRIS_BUS_NAME
#undef MPRIS_OBJECT_PATH
#undef MPRIS_TRACKLIST_INTERFACE

#endif // HAVE_DBUS

    /*
     * Message queue options
     */
    /* Last chance to set the verbosity. Once we start interfaces and other
     * threads, verbosity becomes read-only. */
    var_Create( p_libvlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
    if( var_InheritBool( p_libvlc, "quiet" ) )
    {
        var_SetInteger( p_libvlc, "verbose", -1 );
        priv->i_verbose = -1;
    }
    vlc_threads_setup( p_libvlc );

    if( priv->b_color )
        priv->b_color = var_InheritBool( p_libvlc, "color" );

    vlc_CPU_dump( VLC_OBJECT(p_libvlc) );
    vlc_object_set_name( p_libvlc, "main" );

    priv->b_stats = var_InheritBool( p_libvlc, "stats" );

    /*
     * Initialize hotkey handling
     */
    priv->actions = vlc_InitActions( p_libvlc );

    /* Create a variable for showing the fullscreen interface */
    var_Create( p_libvlc, "intf-toggle-fscontrol", VLC_VAR_BOOL );
    var_SetBool( p_libvlc, "intf-toggle-fscontrol", true );

    /* Create a variable for the Boss Key */
    var_Create( p_libvlc, "intf-boss", VLC_VAR_VOID );

    /* Create a variable for showing the main interface */
    var_Create( p_libvlc, "intf-show", VLC_VAR_BOOL );

    /* Create a variable for showing the right click menu */
    var_Create( p_libvlc, "intf-popupmenu", VLC_VAR_BOOL );

    /* variables for signalling creation of new files */
    var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING );
    var_Create( p_libvlc, "record-file", VLC_VAR_STRING );

    /* some default internal settings */
    var_Create( p_libvlc, "window", VLC_VAR_STRING );
    var_Create( p_libvlc, "user-agent", VLC_VAR_STRING );
    var_SetString( p_libvlc, "user-agent", "(LibVLC "VERSION")" );

    /* Initialize playlist and get commandline files */
    p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) );
    if( !p_playlist )
    {
        msg_Err( p_libvlc, "playlist initialization failed" );
        module_EndBank (true);
        return VLC_EGENERIC;
    }

    /* System specific configuration */
    system_Configure( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );

#if defined(MEDIA_LIBRARY)
    /* Get the ML */
    if( var_GetBool( p_libvlc, "load-media-library-on-startup" ) )
    {
        priv->p_ml = ml_Create( VLC_OBJECT( p_libvlc ), NULL );
        if( !priv->p_ml )
        {
            msg_Err( p_libvlc, "ML initialization failed" );
            return VLC_EGENERIC;
        }
    }
    else
    {
        priv->p_ml = NULL;
    }
#endif

    /* Add service discovery modules */
    psz_modules = var_InheritString( p_libvlc, "services-discovery" );
    if( psz_modules )
    {
        char *p = psz_modules, *m;
        while( ( m = strsep( &p, " :," ) ) != NULL )
            playlist_ServicesDiscoveryAdd( p_playlist, m );
        free( psz_modules );
    }

#ifdef ENABLE_VLM
    /* Initialize VLM if vlm-conf is specified */
    psz_parser = var_CreateGetNonEmptyString( p_libvlc, "vlm-conf" );
    if( psz_parser )
    {
        priv->p_vlm = vlm_New( p_libvlc );
        if( !priv->p_vlm )
            msg_Err( p_libvlc, "VLM initialization failed" );
    }
    free( psz_parser );
#endif

    /*
     * Load background interfaces
     */
    psz_modules = var_CreateGetNonEmptyString( p_libvlc, "extraintf" );
    psz_control = var_CreateGetNonEmptyString( p_libvlc, "control" );

    if( psz_modules && psz_control )
    {
        char* psz_tmp;
        if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
        {
            free( psz_modules );
            psz_modules = psz_tmp;
        }
    }
    else if( psz_control )
    {
        free( psz_modules );
        psz_modules = strdup( psz_control );
    }

    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
        char *psz_module, *psz_temp;
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ':' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
        if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
        {
            intf_Create( p_libvlc, psz_temp );
            free( psz_temp );
        }
    }
    free( psz_modules );
    free( psz_control );

    /*
     * Always load the hotkeys interface if it exists
     */
    intf_Create( p_libvlc, "hotkeys,none" );

    if( var_InheritBool( p_libvlc, "file-logging" )
#ifdef HAVE_SYSLOG_H
        && !var_InheritBool( p_libvlc, "syslog" )
#endif
        )
    {
        intf_Create( p_libvlc, "logger,none" );
    }
#ifdef HAVE_SYSLOG_H
    if( var_InheritBool( p_libvlc, "syslog" ) )
    {
        char *logmode = var_CreateGetNonEmptyString( p_libvlc, "logmode" );
        var_SetString( p_libvlc, "logmode", "syslog" );
        intf_Create( p_libvlc, "logger,none" );

        if( logmode )
        {
            var_SetString( p_libvlc, "logmode", logmode );
            free( logmode );
        }
        var_Destroy( p_libvlc, "logmode" );
    }
#endif

    if( var_InheritBool( p_libvlc, "network-synchronisation") )
    {
        intf_Create( p_libvlc, "netsync,none" );
    }

#ifdef __APPLE__
    var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-view-bottom", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-view-right", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-top", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-left", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-bottom", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-right", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-nsobject", VLC_VAR_ADDRESS );
#endif
#if defined (WIN32) || defined (__OS2__)
    var_Create( p_libvlc, "drawable-hwnd", VLC_VAR_INTEGER );
#endif

    /*
     * Get input filenames given as commandline arguments.
     * We assume that the remaining parameters are filenames
     * and their input options.
     */
    GetFilenames( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );

    /*
     * Get --open argument
     */
    psz_val = var_InheritString( p_libvlc, "open" );
    if ( psz_val != NULL )
    {
        playlist_AddExt( p_playlist, psz_val, NULL, PLAYLIST_INSERT, 0,
                         -1, 0, NULL, 0, true, pl_Unlocked );
        free( psz_val );
    }

    return VLC_SUCCESS;
}
Exemple #6
0
/**
 * Create playlist
 *
 * Create a playlist structure.
 * \param p_parent the vlc object that is to be the parent of this playlist
 * \return a pointer to the created playlist, or NULL on error
 */
playlist_t *playlist_Create( vlc_object_t *p_parent )
{
    playlist_t *p_playlist;
    playlist_private_t *p;

    /* Allocate structure */
    p = vlc_custom_create( p_parent, sizeof( *p ), "playlist" );
    if( !p )
        return NULL;

    assert( offsetof( playlist_private_t, public_data ) == 0 );
    p_playlist = &p->public_data;
    TAB_INIT( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds );

    VariablesInit( p_playlist );
    vlc_mutex_init( &p->lock );
    vlc_cond_init( &p->signal );
    p->killed = false;

    /* Initialise data structures */
    pl_priv(p_playlist)->i_last_playlist_id = 0;
    pl_priv(p_playlist)->p_input = NULL;

    ARRAY_INIT( p_playlist->items );
    ARRAY_INIT( p_playlist->all_items );
    ARRAY_INIT( pl_priv(p_playlist)->items_to_delete );
    ARRAY_INIT( p_playlist->current );

    p_playlist->i_current_index = 0;
    pl_priv(p_playlist)->b_reset_currently_playing = true;

    pl_priv(p_playlist)->b_tree = var_InheritBool( p_parent, "playlist-tree" );
    pl_priv(p_playlist)->b_preparse = var_InheritBool( p_parent, "auto-preparse" );

    /* Create the root, playing items and meida library nodes */
    playlist_item_t *root, *playing, *ml;

    PL_LOCK;
    root = playlist_NodeCreate( p_playlist, NULL, NULL,
                                PLAYLIST_END, 0, NULL );
    playing = playlist_NodeCreate( p_playlist, _( "Playlist" ), root,
                                   PLAYLIST_END, PLAYLIST_RO_FLAG | PLAYLIST_NO_INHERIT_FLAG, NULL );
    if( var_InheritBool( p_parent, "media-library") )
        ml = playlist_NodeCreate( p_playlist, _( "Media Library" ), root,
                                  PLAYLIST_END, PLAYLIST_RO_FLAG | PLAYLIST_NO_INHERIT_FLAG, NULL );
    else
        ml = NULL;
    PL_UNLOCK;

    if( unlikely(root == NULL || playing == NULL) )
        abort();

    p_playlist->p_root = root;
    p_playlist->p_playing = playing;
    p_playlist->p_media_library = ml;
    p_playlist->p_root_category = p_playlist->p_root;
    p_playlist->p_root_onelevel = p_playlist->p_root;
    p_playlist->p_local_category = p_playlist->p_playing;
    p_playlist->p_local_onelevel = p_playlist->p_playing;
    p_playlist->p_ml_category = p_playlist->p_media_library;
    p_playlist->p_ml_onelevel = p_playlist->p_media_library;;

    /* Initial status */
    pl_priv(p_playlist)->status.p_item = NULL;
    pl_priv(p_playlist)->status.p_node = p_playlist->p_playing;
    pl_priv(p_playlist)->request.b_request = false;

    if (ml != NULL)
        playlist_MLLoad( p_playlist );

    /* Input resources */
    p->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) );
    if( unlikely(p->p_input_resource == NULL) )
        abort();

    /* Audio output (needed for volume and device controls). */
    audio_output_t *aout = input_resource_GetAout( p->p_input_resource );
    if( aout != NULL )
        input_resource_PutAout( p->p_input_resource, aout );

    /* Initialize the shared HTTP cookie jar */
    vlc_value_t cookies;
    cookies.p_address = vlc_http_cookies_new();
    if ( likely(cookies.p_address) )
    {
        var_Create( p_playlist, "http-cookies", VLC_VAR_ADDRESS );
        var_SetChecked( p_playlist, "http-cookies", VLC_VAR_ADDRESS, cookies );
    }

    /* Thread */
    playlist_Activate (p_playlist);

    /* Add service discovery modules */
    char *mods = var_InheritString( p_playlist, "services-discovery" );
    if( mods != NULL )
    {
        char *s = mods, *m;
        while( (m = strsep( &s, " :," )) != NULL )
            playlist_ServicesDiscoveryAdd( p_playlist, m );
        free( mods );
    }

    return p_playlist;
}
Exemple #7
0
Fichier : rpn.c Projet : 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 );
        }
    }
}