--- /dev/null
+/*****************************************************************************
+ * stream.cpp : wxWindows plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2000-2001 VideoLAN
+ * $Id: stream.cpp,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h> /* malloc(), free() */
+#include <errno.h> /* ENOMEM */
+#include <string.h> /* strerror() */
+#include <stdio.h>
+
+#include <vlc/vlc.h>
+#include <vlc/intf.h>
+
+#include "wxwindows.h"
+
+#include <wx/statline.h>
+
+
+#define STREAM_INTRO N_( "Stream with VLC in three steps" )
+#define STREAM_STEP1 N_( "Step 1 : Select what to stream" )
+#define STREAM_STEP2 N_( "Step 2 : Define streaming method" )
+#define STREAM_STEP3 N_( "Step 3 : Start streaming" )
+
+
+/*****************************************************************************
+ * Event Table.
+ *****************************************************************************/
+
+/* IDs for the controls and the menu commands */
+enum
+{
+ Open_Event,
+ Sout_Event,
+ Start_Event,
+ Close_Event
+};
+
+BEGIN_EVENT_TABLE(StreamDialog, wxFrame)
+ /* Button events */
+ EVT_BUTTON(wxID_OK, StreamDialog::OnClose)
+
+ EVT_BUTTON(Open_Event,StreamDialog::OnOpen)
+ EVT_BUTTON(Sout_Event,StreamDialog::OnSout)
+ EVT_BUTTON(Start_Event,StreamDialog::OnStart)
+
+ /* Hide the window when the user closes the window */
+ EVT_CLOSE(StreamDialog::OnClose)
+
+END_EVENT_TABLE()
+
+/*****************************************************************************
+ * Constructor.
+ *****************************************************************************/
+StreamDialog::StreamDialog( intf_thread_t *_p_intf, wxWindow *p_parent ):
+ wxFrame( p_parent, -1, wxU(_("Stream")), wxDefaultPosition,
+ wxDefaultSize, wxDEFAULT_FRAME_STYLE )
+{
+ /* Initializations */
+ p_intf = _p_intf;
+ SetIcon( *p_intf->p_sys->p_icon );
+ SetAutoLayout( TRUE );
+
+ p_open_dialog = NULL;
+ p_sout_dialog = NULL;
+
+ /* Create a panel to put everything in */
+ wxPanel *panel = new wxPanel( this, -1 );
+ panel->SetAutoLayout( TRUE );
+
+ wxStaticText *intro_label = new wxStaticText( panel,
+ -1 , wxU(_( STREAM_INTRO )));
+
+
+ wxStaticText *step1_label = new wxStaticText( panel,
+ -1 , wxU(_( STREAM_STEP1 )));
+
+ step2_label = new wxStaticText( panel,
+ -1 , wxU(_( STREAM_STEP2 )));
+
+ step3_label = new wxStaticText( panel,
+ -1 , wxU(_( STREAM_STEP3 )));
+
+ wxButton *open_button = new wxButton( panel,
+ Open_Event, wxU(_("Open...")));
+
+ sout_button = new wxButton( panel,
+ Sout_Event, wxU(_("Choose...")));
+
+ start_button = new wxButton( panel,
+ Start_Event, wxU(_("Start !")));
+
+
+ step2_label->Disable();
+ step3_label->Disable();
+
+ sout_button->Disable();
+ start_button->Disable();
+
+ /* Place everything in sizers */
+ wxBoxSizer *main_sizer = new wxBoxSizer( wxVERTICAL );
+ wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer *step1_sizer = new wxBoxSizer( wxHORIZONTAL );
+ wxBoxSizer *step2_sizer = new wxBoxSizer( wxHORIZONTAL );
+ wxBoxSizer *step3_sizer = new wxBoxSizer( wxHORIZONTAL );
+
+ step1_sizer->Add( step1_label, 1, wxALL | wxEXPAND | wxALIGN_LEFT, 10 );
+ step1_sizer->Add( open_button, 1, wxALL | wxEXPAND | wxALIGN_RIGHT, 10 );
+
+ step2_sizer->Add( step2_label, 1, wxALL | wxEXPAND | wxALIGN_LEFT, 10 );
+ step2_sizer->Add( sout_button, 1, wxALL | wxEXPAND | wxALIGN_RIGHT, 10 );
+
+ step3_sizer->Add( step3_label, 1, wxALL | wxEXPAND | wxLEFT, 10 );
+ step3_sizer->Add( start_button, 1, wxALL | wxEXPAND | wxLEFT, 10 );
+
+ panel_sizer->Add( intro_label, 0, wxEXPAND | wxALL, 10 );
+
+ panel_sizer->Add( new wxStaticLine( panel, 0), 0,
+ wxEXPAND | wxLEFT | wxRIGHT, 2 );
+ panel_sizer->Add( step1_sizer, 0, wxEXPAND, 10 );
+ panel_sizer->Add( new wxStaticLine( panel, 0), 0,
+ wxEXPAND | wxLEFT | wxRIGHT, 2 );
+ panel_sizer->Add( step2_sizer, 0, wxEXPAND, 10 );
+ panel_sizer->Add( new wxStaticLine( panel, 0), 0,
+ wxEXPAND | wxLEFT | wxRIGHT, 2 );
+ panel_sizer->Add( step3_sizer, 0, wxEXPAND, 10 );
+
+ panel_sizer->Layout();
+ panel->SetSizerAndFit( panel_sizer );
+ main_sizer->Add( panel, 1, wxEXPAND, 0 );
+ main_sizer->Layout();
+ SetSizerAndFit( main_sizer );
+
+}
+
+/*****************************************************************************
+ * Destructor.
+ *****************************************************************************/
+StreamDialog::~StreamDialog()
+{
+ if( p_open_dialog ) delete p_open_dialog;
+ if( p_sout_dialog ) delete p_sout_dialog;
+}
+
+void StreamDialog::OnOpen( wxCommandEvent& event )
+{
+ if( !p_open_dialog )
+ {
+ p_open_dialog = new OpenDialog(
+ p_intf, this, FILE_ACCESS, 1 , OPEN_STREAM );
+ }
+
+ if( p_open_dialog)
+ {
+ p_open_dialog->Show();
+ mrl = p_open_dialog->mrl;
+ sout_button->Enable();
+ step2_label->Enable();
+ }
+}
+
+void StreamDialog::OnSout( wxCommandEvent& event )
+{
+ /* Show/hide the sout dialog */
+ if( p_sout_dialog == NULL )
+ p_sout_dialog = new SoutDialog( p_intf, this );
+
+ if( p_sout_dialog && p_sout_dialog->ShowModal() == wxID_OK )
+ {
+ sout_mrl = p_sout_dialog->GetOptions();
+ start_button->Enable();
+ step3_label->Enable();
+ }
+}
+
+void StreamDialog::OnStart( wxCommandEvent& event )
+{
+ /* Update the playlist */
+ playlist_t *p_playlist =
+ (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+ if( p_playlist == NULL ) return;
+
+ for( int i = 0; i < (int)p_open_dialog->mrl.GetCount(); i++ )
+ {
+ int i_options = 0, i_total_options;
+ char **ppsz_options = NULL;
+
+ /* Count the input options */
+ while( i + i_options + 1 < (int)p_open_dialog->mrl.GetCount() &&
+ ((const char *)p_open_dialog->mrl[i + i_options + 1].
+ mb_str())[0] == ':' )
+ {
+ i_options++;
+ }
+
+ /* Allocate ppsz_options */
+ for( int j = 0; j < i_options; j++ )
+ {
+ if( !ppsz_options )
+ ppsz_options = (char **)malloc( sizeof(char *) * i_options );
+
+ ppsz_options[j] = strdup( p_open_dialog->mrl[i + j + 1].mb_str() );
+ }
+
+ i_total_options = i_options;
+
+ /* Get the options from the stream output dialog */
+ if( sout_mrl.GetCount() )
+ {
+ ppsz_options = (char **)realloc( ppsz_options, sizeof(char *) *
+ (i_total_options + sout_mrl.GetCount()) );
+
+ for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
+ {
+ ppsz_options[i_total_options + j] =
+ strdup( sout_mrl[j].mb_str() );
+ }
+
+ i_total_options += sout_mrl.GetCount();
+
+ }
+ msg_Dbg(p_intf,"playings %s",p_open_dialog->mrl[i].mb_str());
+ playlist_Add( p_playlist, (const char *)p_open_dialog->mrl[i].mb_str(),
+ (const char **)ppsz_options, i_total_options,
+ PLAYLIST_APPEND | (i ? 0 : PLAYLIST_GO), PLAYLIST_END );
+ /* clean up */
+ for( int j = 0; j < i_total_options; j++ )
+ free( ppsz_options[j] );
+ if( ppsz_options ) free( ppsz_options );
+
+ i += i_options;
+ }
+ vlc_object_release( p_playlist );
+
+ Hide();
+}
+
+
+void StreamDialog::OnClose( wxCommandEvent& event )
+{
+ Hide();
+}
--- /dev/null
+/*****************************************************************************
+ * playlist.c : Playlist groups management functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: group.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "vlc_playlist.h"
+
+
+/**
+ * Create a group
+ *
+ * Create a new group
+ * \param p_playlist pointer to a playlist
+ * \param psz_name the name of the group to be created
+ * \return a pointer to the created group, or NULL on error
+ */
+playlist_group_t * playlist_CreateGroup(playlist_t * p_playlist, char *psz_name)
+{
+ playlist_group_t *p_group;
+
+ int i;
+ for( i=0 ; i< p_playlist->i_groups; i++ )
+ {
+ if( !strcasecmp(p_playlist->pp_groups[i]->psz_name , psz_name ) )
+ {
+ msg_Info( p_playlist, "This group already exists !");
+ return NULL;
+ }
+ }
+
+ /* Allocate the group structure */
+ p_group = (playlist_group_t *)malloc( sizeof(playlist_group_t) );
+ if( !p_group )
+ {
+ msg_Err( p_playlist, "out of memory" );
+ return NULL;
+ }
+
+ p_group->psz_name = strdup( psz_name );
+ p_group->i_id = ++p_playlist->i_max_id;
+
+ msg_Dbg(p_playlist,"Creating group %s with id %i at position %i",
+ p_group->psz_name,
+ p_group->i_id,
+ p_playlist->i_groups);
+
+ INSERT_ELEM ( p_playlist->pp_groups,
+ p_playlist->i_groups,
+ p_playlist->i_groups,
+ p_group );
+
+ return p_group;
+}
+
+/**
+ * Destroy a group
+ *
+ * \param p_playlist the playlist to remove the group from
+ * \param i_id the identifier of the group to remove
+ * \return 0 on success
+ */
+int playlist_DeleteGroup( playlist_t *p_playlist, int i_id )
+{
+ int i;
+
+ for( i=0 ; i<= p_playlist->i_groups; i++ )
+ {
+ if( p_playlist->pp_groups[i]->i_id == i_id )
+ {
+ if( p_playlist->pp_groups[i]->psz_name )
+ {
+ free( p_playlist->pp_groups[i]->psz_name );
+ }
+ REMOVE_ELEM( p_playlist->pp_groups,
+ p_playlist->i_groups,
+ i);
+ }
+ }
+ return 0;
+}
+
+/**
+ * Find the name with the ID
+ *
+ * \param p_playlist the playlist where to find the group
+ * \param i_id the ID to search for
+ * \return the name of the group
+ */
+char *playlist_FindGroup( playlist_t *p_playlist, int i_id )
+{
+ int i;
+ for( i=0 ; i<= p_playlist->i_groups; i++ )
+ {
+ if( p_playlist->pp_groups[i]->i_id == i_id )
+ {
+ if( p_playlist->pp_groups[i]->psz_name)
+ return strdup( p_playlist->pp_groups[i]->psz_name );
+ }
+ }
+ return NULL;
+}
--- /dev/null
+/*****************************************************************************
+ * item.c : Playlist item functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: item.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "vlc_playlist.h"
+
+/**
+ * Add an MRL to the playlist. This is a simplified version of
+ * playlist_AddExt inculded for convenince. It equals calling playlist_AddExt
+ * with psz_name == psz_target and i_duration == -1
+ */
+
+int playlist_Add( playlist_t *p_playlist, const char *psz_target,
+ const char **ppsz_options, int i_options,
+ int i_mode, int i_pos )
+{
+ return playlist_AddExt( p_playlist, psz_target, psz_target, -1,
+ ppsz_options, i_options, i_mode, i_pos );
+}
+
+/**
+ * Add a MRL into the playlist.
+ *
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_duration a hint about the duration of this item, in miliseconds, or
+ * -1 if unknown.
+ * \param ppsz_options array of options
+ * \param i_options number of items in ppsz_options
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ * PLAYLIST_END the item will be added at the end of the playlist
+ * regardless of it's size
+ * \return always returns 0
+*/
+int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
+ const char * psz_name, mtime_t i_duration,
+ const char **ppsz_options, int i_options, int i_mode,
+ int i_pos )
+{
+ playlist_item_t * p_item;
+
+ p_item = malloc( sizeof( playlist_item_t ) );
+ if( p_item == NULL )
+ {
+ msg_Err( p_playlist, "out of memory" );
+ }
+
+ p_item->psz_name = strdup( psz_name );
+ p_item->psz_uri = strdup( psz_uri );
+ p_item->psz_author = strdup( "" );
+ p_item->i_duration = i_duration;
+ p_item->i_type = 0;
+ p_item->i_status = 0;
+ p_item->b_autodeletion = VLC_FALSE;
+ p_item->b_enabled = VLC_TRUE;
+ p_item->i_group = PLAYLIST_TYPE_MANUAL;
+
+ p_item->ppsz_options = NULL;
+ p_item->i_options = i_options;
+
+ if( i_options )
+ {
+ int i;
+
+ p_item->ppsz_options = (char **)malloc( i_options * sizeof(char *) );
+ for( i = 0; i < i_options; i++ )
+ p_item->ppsz_options[i] = strdup( ppsz_options[i] );
+
+ }
+
+ return playlist_AddItem( p_playlist, p_item, i_mode, i_pos );
+}
+
+/**
+ * Add a playlist item into a playlist
+ *
+ * \param p_playlist the playlist to insert into
+ * \param p_item the playlist item to insert
+ * \param i_mode the mode used when adding
+ * \param i_pos the possition in the playlist where to add. If this is
+ * PLAYLIST_END the item will be added at the end of the playlist
+ * regardless of it's size
+ * \return always returns 0
+*/
+int playlist_AddItem( playlist_t *p_playlist, playlist_item_t * p_item,
+ int i_mode, int i_pos)
+{
+ vlc_value_t val;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ /*
+ * CHECK_INSERT : checks if the item is already enqued before
+ * enqueing it
+ */
+ if ( i_mode & PLAYLIST_CHECK_INSERT )
+ {
+ int j;
+
+ if ( p_playlist->pp_items )
+ {
+ for ( j = 0; j < p_playlist->i_size; j++ )
+ {
+ if ( !strcmp( p_playlist->pp_items[j]->psz_uri, p_item->psz_uri ) )
+ {
+ if( p_item->psz_name )
+ {
+ free( p_item->psz_name );
+ }
+ if( p_item->psz_uri )
+ {
+ free( p_item->psz_uri );
+ }
+ free( p_item );
+ vlc_mutex_unlock( &p_playlist->object_lock );
+ return 0;
+ }
+ }
+ }
+ i_mode &= ~PLAYLIST_CHECK_INSERT;
+ i_mode |= PLAYLIST_APPEND;
+ }
+
+
+ msg_Dbg( p_playlist, "adding playlist item « %s » ( %s )", p_item->psz_name, p_item->psz_uri);
+
+ /* Create the new playlist item */
+
+
+ /* Do a few boundary checks and allocate space for the item */
+ if( i_pos == PLAYLIST_END )
+ {
+ if( i_mode & PLAYLIST_INSERT )
+ {
+ i_mode &= ~PLAYLIST_INSERT;
+ i_mode |= PLAYLIST_APPEND;
+ }
+
+ i_pos = p_playlist->i_size - 1;
+ }
+
+ if( !(i_mode & PLAYLIST_REPLACE)
+ || i_pos < 0 || i_pos >= p_playlist->i_size )
+ {
+ /* Additional boundary checks */
+ if( i_mode & PLAYLIST_APPEND )
+ {
+ i_pos++;
+ }
+
+ if( i_pos < 0 )
+ {
+ i_pos = 0;
+ }
+ else if( i_pos > p_playlist->i_size )
+ {
+ i_pos = p_playlist->i_size;
+ }
+
+ INSERT_ELEM( p_playlist->pp_items,
+ p_playlist->i_size,
+ i_pos,
+ p_item );
+ p_playlist->i_enabled ++;
+
+ if( p_playlist->i_index >= i_pos )
+ {
+ p_playlist->i_index++;
+ }
+ }
+ else
+ {
+ /* i_mode == PLAYLIST_REPLACE and 0 <= i_pos < p_playlist->i_size */
+ if( p_playlist->pp_items[i_pos]->psz_name )
+ {
+ free( p_playlist->pp_items[i_pos]->psz_name );
+ }
+ if( p_playlist->pp_items[i_pos]->psz_uri )
+ {
+ free( p_playlist->pp_items[i_pos]->psz_uri );
+ }
+ /* XXX: what if the item is still in use? */
+ free( p_playlist->pp_items[i_pos] );
+ p_playlist->pp_items[i_pos] = p_item;
+ }
+
+ if( i_mode & PLAYLIST_GO )
+ {
+ p_playlist->i_index = i_pos;
+ if( p_playlist->p_input )
+ {
+ input_StopThread( p_playlist->p_input );
+ }
+ p_playlist->i_status = PLAYLIST_RUNNING;
+ }
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
+
+/**
+ * delete an item from a playlist.
+ *
+ * \param p_playlist the playlist to remove from.
+ * \param i_pos the position of the item to remove
+ * \return returns 0
+ */
+int playlist_Delete( playlist_t * p_playlist, int i_pos )
+{
+ vlc_value_t val;
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ if( i_pos >= 0 && i_pos < p_playlist->i_size )
+ {
+ msg_Dbg( p_playlist, "deleting playlist item « %s »",
+ p_playlist->pp_items[i_pos]->psz_name );
+
+ if( p_playlist->pp_items[i_pos]->psz_name )
+ {
+ free( p_playlist->pp_items[i_pos]->psz_name );
+ }
+ if( p_playlist->pp_items[i_pos]->psz_uri )
+ {
+ free( p_playlist->pp_items[i_pos]->psz_uri );
+ }
+ if( p_playlist->pp_items[i_pos]->psz_author )
+ {
+ free( p_playlist->pp_items[i_pos]->psz_author );
+ }
+ if( p_playlist->pp_items[i_pos]->i_options )
+ {
+ int i;
+
+ for( i = 0; i < p_playlist->pp_items[i_pos]->i_options; i++ )
+ free( p_playlist->pp_items[i_pos]->ppsz_options[i] );
+
+ free( p_playlist->pp_items[i_pos]->ppsz_options );
+ }
+
+ /* XXX: what if the item is still in use? */
+ free( p_playlist->pp_items[i_pos] );
+
+ if( i_pos <= p_playlist->i_index )
+ {
+ p_playlist->i_index--;
+ }
+
+ /* Renumber the playlist */
+ REMOVE_ELEM( p_playlist->pp_items,
+ p_playlist->i_size,
+ i_pos );
+ if( p_playlist->i_enabled > 0 )
+ p_playlist->i_enabled--;
+ }
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
+
+/**
+ * Disables a playlist item
+ *
+ * \param p_playlist the playlist to disable from.
+ * \param i_pos the position of the item to disable
+ * \return returns 0
+ */
+int playlist_Disable( playlist_t * p_playlist, int i_pos )
+{
+ vlc_value_t val;
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+
+ if( i_pos >= 0 && i_pos < p_playlist->i_size )
+ {
+ msg_Dbg( p_playlist, "disabling playlist item « %s »",
+ p_playlist->pp_items[i_pos]->psz_name );
+
+ if( p_playlist->pp_items[i_pos]->b_enabled == VLC_TRUE )
+ p_playlist->i_enabled--;
+ p_playlist->pp_items[i_pos]->b_enabled = VLC_FALSE;
+ }
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
+
+/**
+ * Enables a playlist item
+ *
+ * \param p_playlist the playlist to enable from.
+ * \param i_pos the position of the item to enable
+ * \return returns 0
+ */
+int playlist_Enable( playlist_t * p_playlist, int i_pos )
+{
+ vlc_value_t val;
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ if( i_pos >= 0 && i_pos < p_playlist->i_size )
+ {
+ msg_Dbg( p_playlist, "enabling playlist item « %s »",
+ p_playlist->pp_items[i_pos]->psz_name );
+
+ if( p_playlist->pp_items[i_pos]->b_enabled == VLC_FALSE )
+ p_playlist->i_enabled++;
+
+ p_playlist->pp_items[i_pos]->b_enabled = VLC_TRUE;
+ }
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
+
+/**
+ * Disables a playlist group
+ *
+ * \param p_playlist the playlist to disable from.
+ * \param i_pos the id of the group to disable
+ * \return returns 0
+ */
+int playlist_DisableGroup( playlist_t * p_playlist, int i_group)
+{
+ vlc_value_t val;
+ int i;
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ msg_Dbg(p_playlist,"Disabling group %i",i_group);
+ for( i = 0 ; i< p_playlist->i_size; i++ )
+ {
+ if( p_playlist->pp_items[i]->i_group == i_group )
+ {
+ msg_Dbg( p_playlist, "disabling playlist item « %s »",
+ p_playlist->pp_items[i]->psz_name );
+
+ if( p_playlist->pp_items[i]->b_enabled == VLC_TRUE )
+ p_playlist->i_enabled--;
+
+ p_playlist->pp_items[i]->b_enabled = VLC_FALSE;
+ }
+ }
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
+
+/**
+ * Enables a playlist group
+ *
+ * \param p_playlist the playlist to enable from.
+ * \param i_pos the id of the group to enable
+ * \return returns 0
+ */
+int playlist_EnableGroup( playlist_t * p_playlist, int i_group)
+{
+ vlc_value_t val;
+ int i;
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ for( i = 0 ; i< p_playlist->i_size; i++ )
+ {
+ if( p_playlist->pp_items[i]->i_group == i_group )
+ {
+ msg_Dbg( p_playlist, "enabling playlist item « %s »",
+ p_playlist->pp_items[i]->psz_name );
+
+ if( p_playlist->pp_items[i]->b_enabled == VLC_FALSE )
+ p_playlist->i_enabled++;
+
+ p_playlist->pp_items[i]->b_enabled = VLC_TRUE;
+ }
+ }
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
+
+/**
+ * Move an item in a playlist
+ *
+ * Move the item in the playlist with position i_pos before the current item
+ * at position i_newpos.
+ * \param p_playlist the playlist to move items in
+ * \param i_pos the position of the item to move
+ * \param i_newpos the position of the item that will be behind the moved item
+ * after the move
+ * \return returns 0
+ */
+int playlist_Move( playlist_t * p_playlist, int i_pos, int i_newpos)
+{
+ vlc_value_t val;
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ /* take into account that our own row disappears. */
+ if ( i_pos < i_newpos ) i_newpos--;
+
+ if( i_pos >= 0 && i_newpos >=0 && i_pos <= p_playlist->i_size
+ && i_newpos <= p_playlist->i_size )
+ {
+ playlist_item_t * temp;
+
+ msg_Dbg( p_playlist, "moving playlist item « %s » (%i -> %i)",
+ p_playlist->pp_items[i_pos]->psz_name, i_pos,
+ i_newpos );
+
+ if( i_pos == p_playlist->i_index )
+ {
+ p_playlist->i_index = i_newpos;
+ }
+ else if( i_pos > p_playlist->i_index && i_newpos <= p_playlist->i_index )
+ {
+ p_playlist->i_index++;
+ }
+ else if( i_pos < p_playlist->i_index && i_newpos >= p_playlist->i_index )
+ {
+ p_playlist->i_index--;
+ }
+
+ if ( i_pos < i_newpos )
+ {
+ temp = p_playlist->pp_items[i_pos];
+ while ( i_pos < i_newpos )
+ {
+ p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos+1];
+ i_pos++;
+ }
+ p_playlist->pp_items[i_newpos] = temp;
+ }
+ else if ( i_pos > i_newpos )
+ {
+ temp = p_playlist->pp_items[i_pos];
+ while ( i_pos > i_newpos )
+ {
+ p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos-1];
+ i_pos--;
+ }
+ p_playlist->pp_items[i_newpos] = temp;
+ }
+ }
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ val.b_bool = VLC_TRUE;
+ var_Set( p_playlist, "intf-change", val );
+
+ return 0;
+}
--- /dev/null
+/*****************************************************************************
+ * loadsave.c : Playlist loading / saving functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: loadsave.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "stream_control.h"
+#include "input_ext-intf.h"
+
+#include "vlc_playlist.h"
+
+#define PLAYLIST_FILE_HEADER_0_5 "# vlc playlist file version 0.5"
+#define PLAYLIST_FILE_HEADER_0_6 "# vlc playlist file version 0.6"
+
+
+/*****************************************************************************
+ * playlist_LoadFile: load a playlist file.
+ ****************************************************************************/
+int playlist_LoadFile( playlist_t * p_playlist, const char *psz_filename )
+{
+ FILE *file;
+ char line[1024];
+ int i_current_status;
+ int i_format;
+ int i;
+
+ msg_Dbg( p_playlist, "opening playlist file %s", psz_filename );
+
+ file = fopen( psz_filename, "rt" );
+ if( !file )
+ {
+ msg_Err( p_playlist, "playlist file %s does not exist", psz_filename );
+ return -1;
+ }
+ fseek( file, 0L, SEEK_SET );
+
+ /* check the file is not empty */
+ if ( ! fgets( line, 1024, file ) )
+ {
+ msg_Err( p_playlist, "playlist file %s is empty", psz_filename );
+ fclose( file );
+ return -1;
+ }
+
+ /* get rid of line feed */
+ if( line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r' )
+ {
+ line[strlen(line)-1] = (char)0;
+ if( line[strlen(line)-1] == '\r' ) line[strlen(line)-1] = (char)0;
+ }
+ /* check the file format is valid */
+ if ( !strcmp ( line , PLAYLIST_FILE_HEADER_0_5 ) )
+ {
+ i_format = 5;
+ }
+ else if( !strcmp ( line , PLAYLIST_FILE_HEADER_0_6 ) )
+ {
+ i_format = 6;
+ }
+ else
+ {
+ msg_Err( p_playlist, "playlist file %s format is unsupported"
+ , psz_filename );
+ fclose( file );
+ return -1;
+ }
+
+ /* stop playing */
+ i_current_status = p_playlist->i_status;
+ if ( p_playlist->i_status != PLAYLIST_STOPPED )
+ {
+ playlist_Stop ( p_playlist );
+ }
+
+ /* delete current content of the playlist */
+ for( i = p_playlist->i_size - 1; i >= 0; i-- )
+ {
+ playlist_Delete ( p_playlist , i );
+ }
+
+ /* simply add each line */
+ while( fgets( line, 1024, file ) )
+ {
+ /* ignore comments or empty lines */
+ if( (line[0] == '#') || (line[0] == '\r') || (line[0] == '\n')
+ || (line[0] == (char)0) )
+ continue;
+
+ /* get rid of line feed */
+ if( line[strlen(line)-1] == '\n' || line[strlen(line)-1] == '\r' )
+ {
+ line[strlen(line)-1] = (char)0;
+ if( line[strlen(line)-1] == '\r' ) line[strlen(line)-1] = (char)0;
+ }
+ if( i_format == 5 )
+ {
+ playlist_Add ( p_playlist , (char *)&line ,
+ 0, 0, PLAYLIST_APPEND , PLAYLIST_END );
+ }
+ else
+ {
+ msg_Warn( p_playlist, "Not supported yet");
+ }
+ }
+
+ /* start playing */
+ if ( i_current_status != PLAYLIST_STOPPED )
+ {
+ playlist_Play ( p_playlist );
+ }
+
+ fclose( file );
+
+ return 0;
+}
+
+/*****************************************************************************
+ * playlist_SaveFile: Save a playlist in a file.
+ *****************************************************************************/
+int playlist_SaveFile( playlist_t * p_playlist, const char * psz_filename )
+{
+ FILE *file;
+ int i;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ msg_Dbg( p_playlist, "saving playlist file %s", psz_filename );
+
+ file = fopen( psz_filename, "wt" );
+ if( !file )
+ {
+ msg_Err( p_playlist , "could not create playlist file %s"
+ , psz_filename );
+ return -1;
+ }
+ /* Save is done in 0_5 mode at the moment*/
+
+ fprintf( file , PLAYLIST_FILE_HEADER_0_5 "\n" );
+
+ for ( i = 0 ; i < p_playlist->i_size ; i++ )
+ {
+ fprintf( file , p_playlist->pp_items[i]->psz_uri );
+ fprintf( file , "\n" );
+ }
+#if 0
+ fprintf( file, PLAYLIST_FILE_HEADER_0_6 "\n" );
+
+ for ( i=0 ; i< p_playlist->i_size ; i++ )
+ {
+ fprintf( file, p_playlist->pp_items[i]->psz_uri );
+ fprintf( file, "||" );
+ fprintf( file, p_playlist->pp_items[i]->psz_name );
+ fprintf( file, "||" );
+ fprintf( file, "%i",p_playlist->pp_items[i]->b_enabled = VLC_TRUE ?
+ 1:0 );
+ fprintf( file, "||" );
+ fprintf( file, "%i", p_playlist->pp_items[i]->i_group );
+ fprintf( file, "||" );
+ fprintf( file, p_playlist->pp_items[i]->psz_author );
+ fprintf( file , "\n" );
+ }
+#endif
+ fclose( file );
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ return 0;
+}
--- /dev/null
+/*****************************************************************************
+ * sort.c : Playlist sorting functions
+ *****************************************************************************
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: sort.c,v 1.1 2003/10/29 18:00:46 zorglub Exp $
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+#include <stdlib.h> /* free(), strtol() */
+#include <stdio.h> /* sprintf() */
+#include <string.h> /* strerror() */
+
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+
+#include "vlc_playlist.h"
+
+/**
+ * Sort the playlist by title
+ * \param p_playlist the playlist
+ * \param i_type: SORT_NORMAL or SORT_REVERSE (reversed order)
+ * \return 0 on success
+ */
+int playlist_SortTitle( playlist_t * p_playlist , int i_type )
+{
+ int i , i_small , i_position;
+ playlist_item_t *p_temp;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ for( i_position = 0; i_position < p_playlist->i_size -1 ; i_position ++ )
+ {
+ i_small = i_position;
+ for( i = i_position + 1 ; i< p_playlist->i_size ; i++)
+ {
+ int i_test;
+
+ i_test = strcasecmp( p_playlist->pp_items[i]->psz_name,
+ p_playlist->pp_items[i_small]->psz_name );
+
+ if( ( i_type == SORT_NORMAL && i_test < 0 ) ||
+ ( i_type == SORT_REVERSE && i_test > 0 ) )
+ {
+ i_small = i;
+ }
+ }
+ /* Keep the correct current index */
+ if( i_small == p_playlist->i_index )
+ p_playlist->i_index = i_position;
+ else if( i_position == p_playlist->i_index )
+ p_playlist->i_index = i_small;
+
+ p_temp = p_playlist->pp_items[i_position];
+ p_playlist->pp_items[i_position] = p_playlist->pp_items[i_small];
+ p_playlist->pp_items[i_small] = p_temp;
+ }
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ return 0;
+}
+
+/**
+ * Sort the playlist by author
+ * \param p_playlist the playlist
+ * \param i_type: SORT_NORMAL or SORT_REVERSE (reversed order)
+ * \return 0 on success
+ */
+int playlist_SortAuthor( playlist_t * p_playlist , int i_type )
+{
+ int i , i_small , i_position;
+ playlist_item_t *p_temp;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ for( i_position = 0; i_position < p_playlist->i_size -1 ; i_position ++ )
+ {
+ i_small = i_position;
+ for( i = i_position + 1 ; i< p_playlist->i_size ; i++)
+ {
+ int i_test;
+
+ i_test = strcasecmp( p_playlist->pp_items[i]->psz_author,
+ p_playlist->pp_items[i_small]->psz_author );
+
+ if( ( i_type == SORT_NORMAL && i_test < 0 ) ||
+ ( i_type == SORT_REVERSE && i_test > 0 ) )
+ {
+ i_small = i;
+ }
+ }
+ /* Keep the correct current index */
+ if( i_small == p_playlist->i_index )
+ p_playlist->i_index = i_position;
+ else if( i_position == p_playlist->i_index )
+ p_playlist->i_index = i_small;
+
+ p_temp = p_playlist->pp_items[i_position];
+ p_playlist->pp_items[i_position] = p_playlist->pp_items[i_small];
+ p_playlist->pp_items[i_small] = p_temp;
+ }
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ return 0;
+}
+
+int playlist_SortGroup( playlist_t * p_playlist , int i_type )
+{
+ int i , i_small , i_position;
+ playlist_item_t *p_temp;
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ for( i_position = 0; i_position < p_playlist->i_size -1 ; i_position ++ )
+ {
+ i_small = i_position;
+ for( i = i_position + 1 ; i< p_playlist->i_size ; i++)
+ {
+ int i_test;
+
+ i_test = p_playlist->pp_items[i]->i_group -
+ p_playlist->pp_items[i_small]->i_group;
+
+ if( ( i_type == SORT_NORMAL && i_test < 0 ) ||
+ ( i_type == SORT_REVERSE && i_test > 0 ) )
+ {
+ i_small = i;
+ }
+ }
+ /* Keep the correct current index */
+ if( i_small == p_playlist->i_index )
+ p_playlist->i_index = i_position;
+ else if( i_position == p_playlist->i_index )
+ p_playlist->i_index = i_small;
+
+ p_temp = p_playlist->pp_items[i_position];
+ p_playlist->pp_items[i_position] = p_playlist->pp_items[i_small];
+ p_playlist->pp_items[i_small] = p_temp;
+ }
+ vlc_mutex_unlock( &p_playlist->object_lock );
+
+ return 0;
+}