Commit 0562366c authored by Olivier Teulière's avatar Olivier Teulière

* compilation fix

 * all files are stored in dos mode, or Borland won't compile some of
   them...
parent 3fedb969
/*****************************************************************************
* about.cpp: The "About" dialog box
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "about.h"
#include "misc.h"
#include "win32_common.h"
//---------------------------------------------------------------------------
//#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TAboutDlg::TAboutDlg( TComponent* Owner, intf_thread_t *_p_intf )
: TForm( Owner )
{
p_intf = _p_intf;
Image1->Picture->Icon = p_intf->p_sys->p_window->Icon;
LabelVersion->Caption = "Version " VERSION;
Translate( this );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* about.cpp: The "About" dialog box
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "about.h"
#include "misc.h"
#include "win32_common.h"
//---------------------------------------------------------------------------
//#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TAboutDlg::TAboutDlg( TComponent* Owner, intf_thread_t *_p_intf )
: TForm( Owner )
{
p_intf = _p_intf;
Image1->Picture->Icon = p_intf->p_sys->p_window->Icon;
LabelVersion->Caption = "Version " VERSION;
Translate( this );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* mainframe.cpp: Win32 interface plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teulire <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include "dragdrop.h"
#include "mainframe.h"
#include "menu.h"
#include "disc.h"
#include "network.h"
#include "about.h"
#include "preferences.h"
#include "messages.h"
#include "playlist.h"
#include "sout.h"
#include "subtitles.h"
#include "misc.h"
#include "win32_common.h"
#include "netutils.h"
//---------------------------------------------------------------------------
#pragma link "CSPIN"
#pragma resource "*.dfm"
extern int Win32Manage( intf_thread_t *p_intf );
//---------------------------------------------------------------------------
__fastcall TMainFrameDlg::TMainFrameDlg(
TComponent* Owner, intf_thread_t *_p_intf ) : TForm( Owner )
{
p_intf = _p_intf;
Application->ShowHint = true;
Application->OnHint = DisplayHint;
TimerManage->Interval = INTF_IDLE_SLEEP / 1000;
TrackBar->Max = SLIDER_MAX_VALUE;
/* default height and caption */
ClientHeight = 37 + ToolBar->Height;
Caption = VOUT_TITLE " (Win32 interface)";
StringListPref = new TStringList();
Translate( this );
/* drag and drop stuff */
/* initialize the OLE library */
OleInitialize( NULL );
/* TDropTarget will send the WM_OLEDROP message to the form */
lpDropTarget = (LPDROPTARGET)new TDropTarget( this->Handle );
CoLockObjectExternal( lpDropTarget, true, true );
/* register the form as a drop target */
RegisterDragDrop( this->Handle, lpDropTarget );
}
//---------------------------------------------------------------------------
__fastcall TMainFrameDlg::~TMainFrameDlg()
{
delete StringListPref;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Event handlers
****************************************************************************/
void __fastcall TMainFrameDlg::TimerManageTimer( TObject *Sender )
{
Win32Manage( p_intf );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::DisplayHint( TObject *Sender )
{
StatusBar->SimpleText = GetLongHint( Application->Hint );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::TrackBarChange( TObject *Sender )
{
/* This function displays the current date related to the position in
* the stream. It is called whenever the slider changes its value.
* The lock has to be taken before the function is called */
if( p_intf->p_sys->p_input != NULL )
{
#define p_area p_intf->p_sys->p_input->stream.p_selected_area
char psz_time[ OFFSETTOTIME_MAX_SIZE ];
off_t Value = TrackBar->Position;
GroupBoxSlider->Caption =
input_OffsetToTime( p_intf->p_sys->p_input, psz_time,
( p_area->i_size * Value ) / (off_t)SLIDER_MAX_VALUE );
#undef p_area
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FormClose( TObject *Sender,
TCloseAction &Action )
{
vlc_mutex_lock( &p_intf->change_lock );
p_intf->p_vlc->b_die = VLC_TRUE;
vlc_mutex_unlock( &p_intf->change_lock );
/* remove the form from the list of drop targets */
RevokeDragDrop( this->Handle );
lpDropTarget->Release();
CoLockObjectExternal( lpDropTarget, false, true );
/* uninitialize the OLE library */
OleUninitialize();
/* we don't destroy the form immediatly */
Action = caHide;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Main callbacks
****************************************************************************/
void __fastcall TMainFrameDlg::OpenFileActionExecute( TObject *Sender )
{
if( OpenDialog1->Execute() )
{
/* add the new file to the interface playlist */
for( int i = 0; i < OpenDialog1->Files->Count; i++ )
p_intf->p_sys->p_playwin->Add( OpenDialog1->Files->Strings[i],
PLAYLIST_APPEND
| ( p_intf->p_sys->b_play_when_adding ? PLAYLIST_GO : 0 ),
PLAYLIST_END );
};
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::OpenDiscActionExecute( TObject *Sender )
{
TDiscDlg *p_disc = p_intf->p_sys->p_disc;
if( p_disc == NULL )
{
p_disc = new TDiscDlg( this, p_intf );
p_intf->p_sys->p_disc = p_disc;
}
p_disc->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NetworkStreamActionExecute( TObject *Sender )
{
TNetworkDlg *p_network = p_intf->p_sys->p_network;
if( p_network == NULL )
{
p_network = new TNetworkDlg( this, p_intf );
p_intf->p_sys->p_network = p_network;
}
p_network->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::AddSubtitlesActionsExecute( TObject *Sender )
{
TSubtitlesDlg *p_subtitles = new TSubtitlesDlg( this, p_intf );
p_subtitles->ShowModal();
delete p_subtitles;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::StreamOutputActionExecute( TObject *Sender )
{
TSoutDlg *p_sout = new TSoutDlg( this, p_intf );
p_sout->ShowModal();
delete p_sout;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::ExitActionExecute( TObject *Sender )
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FullscreenActionExecute( TObject *Sender )
{
vout_thread_t *p_vout;
p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
VLC_OBJECT_VOUT, FIND_CHILD );
if( p_vout == NULL )
{
return;
}
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
vlc_object_release( p_vout );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::OnTopActionExecute( TObject *Sender )
{
vlc_object_t *p_vout;
p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
if( var_Get( p_vout, "directx-on-top", &val ) >= 0 )
{
val.b_bool = ! val.b_bool;
var_Set( p_vout, "directx-on-top", val );
MenuOnTop->Checked = val.b_bool;
PopupOnTop->Checked = val.b_bool;
}
vlc_object_release( p_vout );
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PlaylistActionExecute( TObject *Sender )
{
TPlaylistDlg *p_playwin = p_intf->p_sys->p_playwin;
if( p_playwin->Visible )
{
p_playwin->Hide();
}
else
{
p_playwin->UpdateGrid();
p_playwin->Show();
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::MessagesActionExecute( TObject *Sender )
{
p_intf->p_sys->p_messages->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PreferencesActionExecute( TObject *Sender )
{
CreatePreferences( "main" );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::AboutActionExecute( TObject *Sender )
{
TAboutDlg *AboutDlg = new TAboutDlg( this, p_intf );
AboutDlg->ShowModal();
delete AboutDlg;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::BackActionExecute( TObject *Sender )
{
/* TODO */
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PlayActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Play();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PauseActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Pause();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::StopActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Stop();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::SlowActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Slow();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FastActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Fast();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PreviousActionExecute(TObject *Sender)
{
p_intf->p_sys->p_playwin->Previous();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NextActionExecute(TObject *Sender)
{
p_intf->p_sys->p_playwin->Next();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::EjectActionExecute( TObject *Sender )
{
AnsiString Device = "";
char * psz_current;
playlist_t * p_playlist;
p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
/*
* Get the active input
* Determine whether we can eject a media, ie it's a VCD or DVD
* If it's neither a VCD nor a DVD, then return
*/
vlc_mutex_lock( &p_playlist->object_lock );
psz_current = p_playlist->pp_items[ p_playlist->i_index ]->psz_name;
if( psz_current != NULL )
{
if( strncmp( psz_current, "dvd", 3 )
|| strncmp( psz_current, "vcd", 3 ) )
{
/* Determine the device name by omitting the first 4 characters
* and keeping 3 characters */
Device = strdup( ( psz_current + 4 ) );
Device = Device.SubString( 1, 2 );
}
}
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
if( Device == "" )
{
return;
}
/* If there's a stream playing, we aren't allowed to eject ! */
if( p_intf->p_sys->p_input == NULL )
{
msg_Dbg( p_intf, "ejecting %s", Device.c_str() );
intf_Eject( p_intf, Device.c_str() );
}
}
//--------------------------------------------------------------------------
void __fastcall TMainFrameDlg::VolumeUpActionExecute( TObject *Sender )
{
aout_VolumeUp( p_intf, 1, NULL );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::VolumeDownActionExecute( TObject *Sender )
{
aout_VolumeDown( p_intf, 1, NULL );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::MuteActionExecute( TObject *Sender )
{
aout_VolumeMute( p_intf, NULL );
// MenuMute->Checked = ! MenuMute->Checked;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* External drop handling
*****************************************************************************/
void __fastcall TMainFrameDlg::OnDrop( TMessage &Msg )
{
/* find the number of files dropped */
int num_files = DragQueryFile( (HDROP)Msg.WParam, 0xFFFFFFFF,
(LPSTR)NULL, NULL );
/* append each file to the playlist */
for( int i = 0; i < num_files; i++ )
{
/* find the length of the filename */
int name_length = DragQueryFile( (HDROP)Msg.WParam, i, NULL, NULL ) + 1;
/* get the filename */
char *FileName = new char[name_length];
DragQueryFile( (HDROP)Msg.WParam, i, FileName, name_length );
/* add the new file to the playlist */
if( config_GetInt( p_intf, "enqueue" ) )
{
p_intf->p_sys->p_playwin->Add( FileName,
PLAYLIST_APPEND, PLAYLIST_END );
}
else
{
p_intf->p_sys->p_playwin->Add( FileName,
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
}
delete[] FileName;
}
DragFinish( (HDROP)Msg.WParam );
Msg.Result = 0;
}
//--------------------------------------------------------------------------
/*****************************************************************************
* Menu and popup callbacks
*****************************************************************************/
void __fastcall TMainFrameDlg::MenuHideinterfaceClick( TObject *Sender )
{
this->SendToBack();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PopupToggleInterfaceClick( TObject *Sender )
{
this->BringToFront();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PopupCloseClick( TObject *Sender )
{
/* We do nothing, we just need a click on a menu item
* to close the popup. Don't ask me why... */
return;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PopupJumpClick( TObject *Sender )
{
/* TODO */
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Callbacks for DVD/VCD navigation
****************************************************************************/
void __fastcall TMainFrameDlg::PrevTitleActionExecute( TObject *Sender )
{
input_area_t * p_area;
int i_id;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
/* Disallow area 0 since it is used for video_ts.vob */
if( i_id > 0 )
{
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_title_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NextTitleActionExecute( TObject *Sender )
{
input_area_t * p_area;
unsigned int i_id;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
{
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_title_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PrevChapterActionExecute( TObject *Sender )
{
input_area_t * p_area;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
if( p_area->i_part - 1 > 0 )
{
p_area->i_part--;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_chapter_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NextChapterActionExecute( TObject *Sender )
{
input_area_t * p_area;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
if( p_area->i_part + 1 < p_area->i_part_nb )
{
p_area->i_part++;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_chapter_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Callback for the 'go!' button
****************************************************************************/
void __fastcall TMainFrameDlg::ButtonGoClick( TObject *Sender )
{
int i_channel;
i_channel = SpinEditChannel->Value;
msg_Dbg( p_intf, "joining channel %d", i_channel );
vlc_mutex_lock( &p_intf->change_lock );
network_ChannelJoin( p_intf, i_channel );
vlc_mutex_unlock( &p_intf->change_lock );
// input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* ModeManage: actualise the aspect of the interface whenever the input
* changes.
*****************************************************************************
* The lock has to be taken before you call the function.
*****************************************************************************/
void __fastcall TMainFrameDlg::ModeManage()
{
TGroupBox * ActiveGB;
int i_Height;
bool b_control;
/* hide all boxes */
GroupBoxFile->Visible = false;
GroupBoxNetwork->Visible = false;
GroupBoxDisc->Visible = false;
/* hide slider */
GroupBoxSlider->Hide();
/* controls unavailable */
b_control = 0;
/* show the box related to current input mode */
if( p_intf->p_sys->p_input != NULL )
{
switch( p_intf->p_sys->p_input->stream.i_method & 0xf0 )
{
case INPUT_METHOD_FILE:
GroupBoxFile->Visible = true;
ActiveGB = GroupBoxFile;
LabelFileName->Caption = p_intf->p_sys->p_input->psz_source;
break;
case INPUT_METHOD_DISC:
GroupBoxDisc->Visible = true;
ActiveGB = GroupBoxDisc;
break;
case INPUT_METHOD_NETWORK:
GroupBoxNetwork->Visible = true;
ActiveGB = GroupBoxNetwork;
LabelServer->Caption = p_intf->p_sys->p_input->psz_source;
if( config_GetInt( p_intf, "network-channel" ) )
{
LabelChannel->Visible = true;
}
else
{
LabelChannel->Visible = false;
}
break;
default:
msg_Warn( p_intf, "cannot determine input method" );
GroupBoxFile->Visible = true;
ActiveGB = GroupBoxFile;
LabelFileName->Caption = p_intf->p_sys->p_input->psz_source;
break;
}
i_Height = StatusBar->Height + ActiveGB->Height + ToolBar->Height + 54;
/* initialize and show slider for seekable streams */
if( p_intf->p_sys->p_input->stream.b_seekable )
{
TrackBar->Position = p_intf->p_sys->OldValue = 0;
GroupBoxSlider->Show();
i_Height += GroupBoxSlider->Height;
}
/* control buttons for free pace streams */
b_control = p_intf->p_sys->p_input->stream.b_pace_control;
/* get ready for menu regeneration */
p_intf->p_sys->b_program_update = 1;
p_intf->p_sys->b_title_update = 1;
p_intf->p_sys->b_chapter_update = 1;
p_intf->p_sys->b_audio_update = 1;
p_intf->p_sys->b_spu_update = 1;
p_intf->p_sys->i_part = 0;
p_intf->p_sys->p_input->stream.b_changed = 0;
msg_Dbg( p_intf, "stream has changed, refreshing interface" );
}
else
{
i_Height = StatusBar->Height + ToolBar->Height + 47;
if( config_GetInt( p_intf, "network-channel" ) )
{
GroupBoxNetwork->Visible = true;
LabelChannel->Visible = true;
i_Height += GroupBoxNetwork->Height + 7;
}
else
{
/* add space between tolbar and statusbar when
* nothing is displayed; isn't it nicer ? :) */
i_Height += 17;
}
/* unsensitize menus */
MenuProgram->Enabled = false;
MenuTitle->Enabled = false;
MenuChapter->Enabled = false;
MenuLanguage->Enabled = false;
MenuSubtitles->Enabled = false;
PopupNavigation->Enabled = false;
PopupLanguage->Enabled = false;
PopupSubtitles->Enabled = false;
}
/* resize main window */
this->Height = i_Height;
/* set control items */
ToolButtonBack->Enabled = false;
ToolButtonEject->Enabled = !b_control;
StopAction->Enabled = true;
PauseAction->Enabled = b_control;
SlowAction->Enabled = b_control;
FastAction->Enabled = b_control;
PopupBack->Enabled = false;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* CreateConfig: create a configuration dialog and save it for further use
*****************************************************************************
* Check if the dialog box is already opened, if so this will save us
* quite a bit of work. (the interface will be destroyed when you actually
* close the main window, but remember that it is only hidden if you
* clicked on the action buttons). This trick also allows us not to
* duplicate identical dialog windows.
*****************************************************************************/
void __fastcall TMainFrameDlg::CreatePreferences( AnsiString Name )
{
TPreferencesDlg *Preferences;
int i_index, i_pos;
i_index = StringListPref->IndexOf( Name );
if( i_index != -1 )
{
/* config dialog already exists */
Preferences = (TPreferencesDlg *)StringListPref->Objects[i_index];
}
else
{
/* create the config dialog */
Preferences = new TPreferencesDlg( this, p_intf );
Preferences->CreateConfigDialog( Name.c_str() );
/* save it */
i_pos = StringListPref->Add( Name );
StringListPref->Objects[i_pos] = Preferences;
}
/* display the dialog */
Preferences->Show();
}
//---------------------------------------------------------------------------
/*****************************************************************************
* mainframe.cpp: Win32 interface plugin for vlc
*****************************************************************************
* Copyright (C) 2002 VideoLAN
*
* Authors: Olivier Teulire <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include <vlc/vout.h>
#include <vlc/aout.h>
#include "dragdrop.h"
#include "mainframe.h"
#include "menu.h"
#include "disc.h"
#include "network.h"
#include "about.h"
#include "preferences.h"
#include "messages.h"
#include "playlist.h"
#include "sout.h"
#include "subtitles.h"
#include "misc.h"
#include "win32_common.h"
#include "netutils.h"
/*****************************************************************************
* BORLAND SUCKS
* If the following pragma doesn't end with \r\n instead of \n, the file
* doesn't compile anymore... Funny, isn't it?
* With vim, you can use ":set ff=dos" to correct it
*****************************************************************************/
#pragma link "CSPIN"
#pragma resource "*.dfm"
extern int Win32Manage( intf_thread_t *p_intf );
//---------------------------------------------------------------------------
__fastcall TMainFrameDlg::TMainFrameDlg(
TComponent* Owner, intf_thread_t *_p_intf ) : TForm( Owner )
{
p_intf = _p_intf;
Application->ShowHint = true;
Application->OnHint = DisplayHint;
TimerManage->Interval = INTF_IDLE_SLEEP / 1000;
TrackBar->Max = SLIDER_MAX_VALUE;
/* default height and caption */
ClientHeight = 37 + ToolBar->Height;
Caption = VOUT_TITLE " (Win32 interface)";
StringListPref = new TStringList();
Translate( this );
/* drag and drop stuff */
/* initialize the OLE library */
OleInitialize( NULL );
/* TDropTarget will send the WM_OLEDROP message to the form */
lpDropTarget = (LPDROPTARGET)new TDropTarget( this->Handle );
CoLockObjectExternal( lpDropTarget, true, true );
/* register the form as a drop target */
RegisterDragDrop( this->Handle, lpDropTarget );
}
//---------------------------------------------------------------------------
__fastcall TMainFrameDlg::~TMainFrameDlg()
{
delete StringListPref;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Event handlers
****************************************************************************/
void __fastcall TMainFrameDlg::TimerManageTimer( TObject *Sender )
{
Win32Manage( p_intf );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::DisplayHint( TObject *Sender )
{
StatusBar->SimpleText = GetLongHint( Application->Hint );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::TrackBarChange( TObject *Sender )
{
/* This function displays the current date related to the position in
* the stream. It is called whenever the slider changes its value.
* The lock has to be taken before the function is called */
if( p_intf->p_sys->p_input != NULL )
{
#define p_area p_intf->p_sys->p_input->stream.p_selected_area
char psz_time[ OFFSETTOTIME_MAX_SIZE ];
off_t Value = TrackBar->Position;
GroupBoxSlider->Caption =
input_OffsetToTime( p_intf->p_sys->p_input, psz_time,
( p_area->i_size * Value ) / (off_t)SLIDER_MAX_VALUE );
#undef p_area
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FormClose( TObject *Sender,
TCloseAction &Action )
{
vlc_mutex_lock( &p_intf->change_lock );
p_intf->p_vlc->b_die = VLC_TRUE;
vlc_mutex_unlock( &p_intf->change_lock );
/* remove the form from the list of drop targets */
RevokeDragDrop( this->Handle );
lpDropTarget->Release();
CoLockObjectExternal( lpDropTarget, false, true );
/* uninitialize the OLE library */
OleUninitialize();
/* we don't destroy the form immediatly */
Action = caHide;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Main callbacks
****************************************************************************/
void __fastcall TMainFrameDlg::OpenFileActionExecute( TObject *Sender )
{
if( OpenDialog1->Execute() )
{
/* add the new file to the interface playlist */
for( int i = 0; i < OpenDialog1->Files->Count; i++ )
p_intf->p_sys->p_playwin->Add( OpenDialog1->Files->Strings[i],
PLAYLIST_APPEND
| ( p_intf->p_sys->b_play_when_adding ? PLAYLIST_GO : 0 ),
PLAYLIST_END );
};
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::OpenDiscActionExecute( TObject *Sender )
{
TDiscDlg *p_disc = p_intf->p_sys->p_disc;
if( p_disc == NULL )
{
p_disc = new TDiscDlg( this, p_intf );
p_intf->p_sys->p_disc = p_disc;
}
p_disc->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NetworkStreamActionExecute( TObject *Sender )
{
TNetworkDlg *p_network = p_intf->p_sys->p_network;
if( p_network == NULL )
{
p_network = new TNetworkDlg( this, p_intf );
p_intf->p_sys->p_network = p_network;
}
p_network->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::AddSubtitlesActionsExecute( TObject *Sender )
{
TSubtitlesDlg *p_subtitles = new TSubtitlesDlg( this, p_intf );
p_subtitles->ShowModal();
delete p_subtitles;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::StreamOutputActionExecute( TObject *Sender )
{
TSoutDlg *p_sout = new TSoutDlg( this, p_intf );
p_sout->ShowModal();
delete p_sout;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::ExitActionExecute( TObject *Sender )
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FullscreenActionExecute( TObject *Sender )
{
vout_thread_t *p_vout;
p_vout = (vout_thread_t *)vlc_object_find( p_intf->p_sys->p_input,
VLC_OBJECT_VOUT, FIND_CHILD );
if( p_vout == NULL )
{
return;
}
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
vlc_object_release( p_vout );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::OnTopActionExecute( TObject *Sender )
{
vlc_object_t *p_vout;
p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
if( var_Get( p_vout, "directx-on-top", &val ) >= 0 )
{
val.b_bool = ! val.b_bool;
var_Set( p_vout, "directx-on-top", val );
MenuOnTop->Checked = val.b_bool;
PopupOnTop->Checked = val.b_bool;
}
vlc_object_release( p_vout );
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PlaylistActionExecute( TObject *Sender )
{
TPlaylistDlg *p_playwin = p_intf->p_sys->p_playwin;
if( p_playwin->Visible )
{
p_playwin->Hide();
}
else
{
p_playwin->UpdateGrid();
p_playwin->Show();
}
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::MessagesActionExecute( TObject *Sender )
{
p_intf->p_sys->p_messages->Show();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PreferencesActionExecute( TObject *Sender )
{
CreatePreferences( "main" );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::AboutActionExecute( TObject *Sender )
{
TAboutDlg *AboutDlg = new TAboutDlg( this, p_intf );
AboutDlg->ShowModal();
delete AboutDlg;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::BackActionExecute( TObject *Sender )
{
/* TODO */
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PlayActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Play();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PauseActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Pause();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::StopActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Stop();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::SlowActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Slow();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::FastActionExecute( TObject *Sender )
{
p_intf->p_sys->p_playwin->Fast();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PreviousActionExecute(TObject *Sender)
{
p_intf->p_sys->p_playwin->Previous();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NextActionExecute(TObject *Sender)
{
p_intf->p_sys->p_playwin->Next();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::EjectActionExecute( TObject *Sender )
{
AnsiString Device = "";
char * psz_current;
playlist_t * p_playlist;
p_playlist = (playlist_t *)vlc_object_find( p_intf,
VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
if( p_playlist == NULL )
{
return;
}
/*
* Get the active input
* Determine whether we can eject a media, ie it's a VCD or DVD
* If it's neither a VCD nor a DVD, then return
*/
vlc_mutex_lock( &p_playlist->object_lock );
psz_current = p_playlist->pp_items[ p_playlist->i_index ]->psz_name;
if( psz_current != NULL )
{
if( strncmp( psz_current, "dvd", 3 )
|| strncmp( psz_current, "vcd", 3 ) )
{
/* Determine the device name by omitting the first 4 characters
* and keeping 3 characters */
Device = strdup( ( psz_current + 4 ) );
Device = Device.SubString( 1, 2 );
}
}
vlc_mutex_unlock( &p_playlist->object_lock );
vlc_object_release( p_playlist );
if( Device == "" )
{
return;
}
/* If there's a stream playing, we aren't allowed to eject ! */
if( p_intf->p_sys->p_input == NULL )
{
msg_Dbg( p_intf, "ejecting %s", Device.c_str() );
intf_Eject( p_intf, Device.c_str() );
}
}
//--------------------------------------------------------------------------
void __fastcall TMainFrameDlg::VolumeUpActionExecute( TObject *Sender )
{
aout_VolumeUp( p_intf, 1, NULL );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::VolumeDownActionExecute( TObject *Sender )
{
aout_VolumeDown( p_intf, 1, NULL );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::MuteActionExecute( TObject *Sender )
{
aout_VolumeMute( p_intf, NULL );
// MenuMute->Checked = ! MenuMute->Checked;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* External drop handling
*****************************************************************************/
void __fastcall TMainFrameDlg::OnDrop( TMessage &Msg )
{
/* find the number of files dropped */
int num_files = DragQueryFile( (HDROP)Msg.WParam, 0xFFFFFFFF,
(LPSTR)NULL, NULL );
/* append each file to the playlist */
for( int i = 0; i < num_files; i++ )
{
/* find the length of the filename */
int name_length = DragQueryFile( (HDROP)Msg.WParam, i, NULL, NULL ) + 1;
/* get the filename */
char *FileName = new char[name_length];
DragQueryFile( (HDROP)Msg.WParam, i, FileName, name_length );
/* add the new file to the playlist */
if( config_GetInt( p_intf, "enqueue" ) )
{
p_intf->p_sys->p_playwin->Add( FileName,
PLAYLIST_APPEND, PLAYLIST_END );
}
else
{
p_intf->p_sys->p_playwin->Add( FileName,
PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
}
delete[] FileName;
}
DragFinish( (HDROP)Msg.WParam );
Msg.Result = 0;
}
//--------------------------------------------------------------------------
/*****************************************************************************
* Menu and popup callbacks
*****************************************************************************/
void __fastcall TMainFrameDlg::MenuHideinterfaceClick( TObject *Sender )
{
this->SendToBack();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PopupToggleInterfaceClick( TObject *Sender )
{
this->BringToFront();
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PopupCloseClick( TObject *Sender )
{
/* We do nothing, we just need a click on a menu item
* to close the popup. Don't ask me why... */
return;
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PopupJumpClick( TObject *Sender )
{
/* TODO */
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Callbacks for DVD/VCD navigation
****************************************************************************/
void __fastcall TMainFrameDlg::PrevTitleActionExecute( TObject *Sender )
{
input_area_t * p_area;
int i_id;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id - 1;
/* Disallow area 0 since it is used for video_ts.vob */
if( i_id > 0 )
{
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_title_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NextTitleActionExecute( TObject *Sender )
{
input_area_t * p_area;
unsigned int i_id;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_id = p_intf->p_sys->p_input->stream.p_selected_area->i_id + 1;
if( i_id < p_intf->p_sys->p_input->stream.i_area_nb )
{
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_id];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_title_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::PrevChapterActionExecute( TObject *Sender )
{
input_area_t * p_area;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
if( p_area->i_part - 1 > 0 )
{
p_area->i_part--;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_chapter_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
void __fastcall TMainFrameDlg::NextChapterActionExecute( TObject *Sender )
{
input_area_t * p_area;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
if( p_area->i_part + 1 < p_area->i_part_nb )
{
p_area->i_part++;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
p_intf->p_sys->b_chapter_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* Callback for the 'go!' button
****************************************************************************/
void __fastcall TMainFrameDlg::ButtonGoClick( TObject *Sender )
{
int i_channel;
i_channel = SpinEditChannel->Value;
msg_Dbg( p_intf, "joining channel %d", i_channel );
vlc_mutex_lock( &p_intf->change_lock );
network_ChannelJoin( p_intf, i_channel );
vlc_mutex_unlock( &p_intf->change_lock );
// input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* ModeManage: actualise the aspect of the interface whenever the input
* changes.
*****************************************************************************
* The lock has to be taken before you call the function.
*****************************************************************************/
void __fastcall TMainFrameDlg::ModeManage()
{
TGroupBox * ActiveGB;
int i_Height;
bool b_control;
/* hide all boxes */
GroupBoxFile->Visible = false;
GroupBoxNetwork->Visible = false;
GroupBoxDisc->Visible = false;
/* hide slider */
GroupBoxSlider->Hide();
/* controls unavailable */
b_control = 0;
/* show the box related to current input mode */
if( p_intf->p_sys->p_input != NULL )
{
switch( p_intf->p_sys->p_input->stream.i_method & 0xf0 )
{
case INPUT_METHOD_FILE:
GroupBoxFile->Visible = true;
ActiveGB = GroupBoxFile;
LabelFileName->Caption = p_intf->p_sys->p_input->psz_source;
break;
case INPUT_METHOD_DISC:
GroupBoxDisc->Visible = true;
ActiveGB = GroupBoxDisc;
break;
case INPUT_METHOD_NETWORK:
GroupBoxNetwork->Visible = true;
ActiveGB = GroupBoxNetwork;
LabelServer->Caption = p_intf->p_sys->p_input->psz_source;
if( config_GetInt( p_intf, "network-channel" ) )
{
LabelChannel->Visible = true;
}
else
{
LabelChannel->Visible = false;
}
break;
default:
msg_Warn( p_intf, "cannot determine input method" );
GroupBoxFile->Visible = true;
ActiveGB = GroupBoxFile;
LabelFileName->Caption = p_intf->p_sys->p_input->psz_source;
break;
}
i_Height = StatusBar->Height + ActiveGB->Height + ToolBar->Height + 54;
/* initialize and show slider for seekable streams */
if( p_intf->p_sys->p_input->stream.b_seekable )
{
TrackBar->Position = p_intf->p_sys->OldValue = 0;
GroupBoxSlider->Show();
i_Height += GroupBoxSlider->Height;
}
/* control buttons for free pace streams */
b_control = p_intf->p_sys->p_input->stream.b_pace_control;
/* get ready for menu regeneration */
p_intf->p_sys->b_program_update = 1;
p_intf->p_sys->b_title_update = 1;
p_intf->p_sys->b_chapter_update = 1;
p_intf->p_sys->b_audio_update = 1;
p_intf->p_sys->b_spu_update = 1;
p_intf->p_sys->i_part = 0;
p_intf->p_sys->p_input->stream.b_changed = 0;
msg_Dbg( p_intf, "stream has changed, refreshing interface" );
}
else
{
i_Height = StatusBar->Height + ToolBar->Height + 47;
if( config_GetInt( p_intf, "network-channel" ) )
{
GroupBoxNetwork->Visible = true;
LabelChannel->Visible = true;
i_Height += GroupBoxNetwork->Height + 7;
}
else
{
/* add space between tolbar and statusbar when
* nothing is displayed; isn't it nicer ? :) */
i_Height += 17;
}
/* unsensitize menus */
MenuProgram->Enabled = false;
MenuTitle->Enabled = false;
MenuChapter->Enabled = false;
MenuLanguage->Enabled = false;
MenuSubtitles->Enabled = false;
PopupNavigation->Enabled = false;
PopupLanguage->Enabled = false;
PopupSubtitles->Enabled = false;
}
/* resize main window */
this->Height = i_Height;
/* set control items */
ToolButtonBack->Enabled = false;
ToolButtonEject->Enabled = !b_control;
StopAction->Enabled = true;
PauseAction->Enabled = b_control;
SlowAction->Enabled = b_control;
FastAction->Enabled = b_control;
PopupBack->Enabled = false;
}
//---------------------------------------------------------------------------
/*****************************************************************************
* CreateConfig: create a configuration dialog and save it for further use
*****************************************************************************
* Check if the dialog box is already opened, if so this will save us
* quite a bit of work. (the interface will be destroyed when you actually
* close the main window, but remember that it is only hidden if you
* clicked on the action buttons). This trick also allows us not to
* duplicate identical dialog windows.
*****************************************************************************/
void __fastcall TMainFrameDlg::CreatePreferences( AnsiString Name )
{
TPreferencesDlg *Preferences;
int i_index, i_pos;
i_index = StringListPref->IndexOf( Name );
if( i_index != -1 )
{
/* config dialog already exists */
Preferences = (TPreferencesDlg *)StringListPref->Objects[i_index];
}
else
{
/* create the config dialog */
Preferences = new TPreferencesDlg( this, p_intf );
Preferences->CreateConfigDialog( Name.c_str() );
/* save it */
i_pos = StringListPref->Add( Name );
StringListPref->Objects[i_pos] = Preferences;
}
/* display the dialog */
Preferences->Show();
}
//---------------------------------------------------------------------------
/*****************************************************************************
* menu.cpp: functions to handle menu items
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: menu.cpp,v 1.13 2003/02/06 23:59:40 sam Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "menu.h"
#include "win32_common.h"
/*****************************************************************************
* TMenusGen::*Click: callbacks for the menuitems
****************************************************************************/
/*
* Variables
*/
/* variables of the audio output */
void __fastcall TMenusGen::AoutVarClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
vlc_object_t * p_aout;
p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout == NULL )
{
msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
return;
}
if( Item->Parent == MenuADevice || Item->Parent == PopupADevice )
{
VarChange( p_aout, "audio-device", MenuADevice, PopupADevice, Item );
}
else if( Item->Parent == MenuChannel || Item->Parent == PopupChannel )
{
VarChange( p_aout, "audio-channels", MenuChannel, PopupChannel, Item );
}
vlc_object_release( p_aout );
}
/* variables of the video output */
void __fastcall TMenusGen::VoutVarClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
vlc_object_t * p_vout;
p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout == NULL )
{
msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
return;
}
if( Item->Parent == MenuVDevice || Item->Parent == PopupVDevice )
{
VarChange( p_vout, "video-device", MenuVDevice, PopupVDevice, Item );
}
vlc_object_release( p_vout );
}
/*
* Modules
*/
/* Interface modules: we spawn a new interface */
void __fastcall TMenusGen::InterfaceModuleClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
AnsiString IntfName = CleanCaption( Item->Caption );
intf_thread_t *p_newintf;
p_newintf = intf_Create( p_intf->p_vlc, IntfName.c_str() );
if( p_newintf )
{
p_newintf->b_block = VLC_FALSE;
if( intf_RunThread( p_newintf ) )
{
vlc_object_detach( p_newintf );
intf_Destroy( p_newintf );
}
}
}
/*
* Audio
*/
void __fastcall TMenusGen::MenuLanguageClick( TObject *Sender )
{
LangChange( MenuLanguage, (TMenuItem *)Sender, PopupLanguage, AUDIO_ES );
}
void __fastcall TMenusGen::PopupLanguageClick( TObject *Sender )
{
LangChange( PopupLanguage, (TMenuItem *)Sender, MenuLanguage, AUDIO_ES );
}
/*
* Subtitles
*/
void __fastcall TMenusGen::MenuSubtitleClick( TObject *Sender )
{
LangChange( MenuSubtitles, (TMenuItem *)Sender, PopupSubtitles, SPU_ES );
}
void __fastcall TMenusGen::PopupSubtitleClick( TObject *Sender )
{
LangChange( PopupSubtitles, (TMenuItem *)Sender, MenuSubtitles, SPU_ES );
}
/*
* Program
*/
void __fastcall TMenusGen::MenuProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, PopupProgram );
}
void __fastcall TMenusGen::PopupProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, MenuProgram );
}
/*
* Title
*/
void __fastcall TMenusGen::MenuTitleClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
unsigned int i_title = Item->Tag;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_title = __MIN( i_title,
p_intf->p_sys->p_input->stream.i_area_nb - 1 );
i_title = __MAX( i_title, 1 );
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
Item->Checked = true;
ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
Index2Item( ItemTitle, 0, false )->Checked = true;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Chapter
*/
void __fastcall TMenusGen::MenuChapterClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
unsigned int i_title;
unsigned int i_chapter = Item->Tag;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
i_chapter = __MAX( i_chapter, 1 );
p_area->i_part = i_chapter;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
ItemTitle = Index2Item( PopupNavigation, i_title, false );
Index2Item( ItemTitle, i_chapter, false )->Checked = true;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Navigation
*/
void __fastcall TMenusGen::PopupNavigationClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
unsigned int i_title = Data2Title( Item->Tag );
unsigned int i_chapter = Data2Chapter( Item->Tag );
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_title = __MIN( i_title,
p_intf->p_sys->p_input->stream.i_area_nb - 1 );
i_title = __MAX( i_title, 1 );
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
i_chapter = __MAX( i_chapter, 1 );
p_area->i_part = i_chapter;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
Item->Checked = true;
ItemTitle = Index2Item( MenuTitle, i_title, false );
if( ItemTitle->Checked )
{
/* same title, new chapter */
Index2Item( MenuChapter, i_chapter, false )->Checked = true;
}
else
{
/* new title => we must rebuild the chapter menu */
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
RadioMenu(
MenuChapter, "Chapter",
p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb,
i_chapter, MenuChapterClick );
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
__fastcall TMenusGen::TMenusGen( intf_thread_t *_p_intf ) : TObject()
{
p_intf = _p_intf;
/* Initialize local pointers to menu items of the main window */
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
if( p_window == NULL )
{
msg_Warn( p_intf, "Main window wasn't created, expect problems..." );
return;
}
MenuChannel = p_window->MenuChannel;
PopupChannel = p_window->PopupChannel;
MenuADevice = p_window->MenuADevice;
PopupADevice = p_window->PopupADevice;
MenuVDevice = p_window->MenuVDevice;
PopupVDevice = p_window->PopupVDevice;
MenuLanguage = p_window->MenuLanguage;
PopupLanguage = p_window->PopupLanguage;
MenuSubtitles = p_window->MenuSubtitles;
PopupSubtitles = p_window->PopupSubtitles;
MenuProgram = p_window->MenuProgram;
PopupProgram = p_window->PopupProgram;
MenuTitle = p_window->MenuTitle;
MenuChapter = p_window->MenuChapter;
PopupNavigation = p_window->PopupNavigation;
MenuAddInterface = p_window->MenuAddInterface;
/* Create the "Add interface" menu */
SetupModuleMenu( "interface", MenuAddInterface, InterfaceModuleClick );
}
/*****************************************************************************
* SetupMenus: This function dynamically generates some menus
*****************************************************************************
* The lock on p_input->stream must be taken before you call this function
*****************************************************************************/
void __fastcall TMenusGen::SetupMenus()
{
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
input_thread_t * p_input = p_intf->p_sys->p_input;
es_descriptor_t * p_audio_es;
es_descriptor_t * p_spu_es;
p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_program_update |
p_intf->p_sys->b_title_update;
p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_program_update |
p_intf->p_sys->b_title_update;
if( p_intf->p_sys->b_program_update )
{
pgrm_descriptor_t * p_pgrm;
if( p_input->stream.p_new_program )
{
p_pgrm = p_input->stream.p_new_program;
}
else
{
p_pgrm = p_input->stream.p_selected_program;
}
ProgramMenu( MenuProgram, p_pgrm, MenuProgramClick );
ProgramMenu( PopupProgram, p_pgrm, PopupProgramClick );
p_intf->p_sys->b_program_update = VLC_FALSE;
}
if( p_intf->p_sys->b_title_update )
{
// why "-1" ?
// because if the titles go from 1 to X-1, there are X-1 titles
RadioMenu( MenuTitle, "Title",
p_input->stream.i_area_nb - 1,
p_input->stream.p_selected_area->i_id,
MenuTitleClick );
AnsiString CurrentTitle;
CurrentTitle.sprintf( "%d", p_input->stream.p_selected_area->i_id );
p_window->LabelTitleCurrent->Caption = CurrentTitle;
p_intf->p_sys->b_title_update = VLC_FALSE;
}
if( p_intf->p_sys->b_chapter_update )
{
RadioMenu( MenuChapter, "Chapter",
p_input->stream.p_selected_area->i_part_nb - 1,
p_input->stream.p_selected_area->i_part,
MenuChapterClick );
NavigationMenu( PopupNavigation, PopupNavigationClick );
AnsiString CurrentChapter;
CurrentChapter.sprintf( "%d", p_input->stream.p_selected_area->i_part );
p_window->LabelChapterCurrent->Caption = CurrentChapter;
p_intf->p_sys->i_part = p_input->stream.p_selected_area->i_part;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
}
/* look for selected ES */
p_audio_es = NULL;
p_spu_es = NULL;
for( unsigned int i = 0; i < p_input->stream.i_selected_es_number; i++ )
{
if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
{
p_audio_es = p_input->stream.pp_selected_es[i];
}
if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
{
p_spu_es = p_input->stream.pp_selected_es[i];
}
}
this->p_audio_es_old = p_audio_es;
this->p_spu_es_old = p_spu_es;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* audio menus */
if( p_intf->p_sys->b_audio_update )
{
LanguageMenu( MenuLanguage, p_audio_es, AUDIO_ES, MenuLanguageClick );
LanguageMenu( PopupLanguage, p_audio_es, AUDIO_ES, PopupLanguageClick );
p_intf->p_sys->b_audio_update = VLC_FALSE;
}
/* sub picture menus */
if( p_intf->p_sys->b_spu_update )
{
LanguageMenu( PopupSubtitles, p_spu_es, SPU_ES, PopupSubtitleClick );
LanguageMenu( MenuSubtitles, p_spu_es, SPU_ES, MenuSubtitleClick );
p_intf->p_sys->b_spu_update = VLC_FALSE;
}
if( p_intf->p_sys->b_aout_update )
{
aout_instance_t * p_aout;
p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
val.b_bool = VLC_FALSE;
var_Set( (vlc_object_t *)p_aout, "intf-change", val );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
MenuChannel, AoutVarClick );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
PopupChannel, AoutVarClick );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
MenuADevice, AoutVarClick );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
PopupADevice, AoutVarClick );
vlc_object_release( (vlc_object_t *)p_aout );
}
p_intf->p_sys->b_aout_update = VLC_FALSE;
}
if( p_intf->p_sys->b_vout_update )
{
vout_thread_t * p_vout;
p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
val.b_bool = VLC_FALSE;
var_Set( (vlc_object_t *)p_vout, "intf-change", val );
SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
MenuVDevice, VoutVarClick );
SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
PopupVDevice, VoutVarClick );
vlc_object_release( (vlc_object_t *)p_vout );
}
p_intf->p_sys->b_vout_update = VLC_FALSE;
}
vlc_mutex_lock( &p_input->stream.stream_lock );
}
/*****************************************************************************
* Private functions
*****************************************************************************/
TMenuItem * TMenusGen::Index2Item( TMenuItem *Root, int i_index,
bool SingleColumn )
{
if( SingleColumn || ( i_index < 20 ) )
return Root->Items[i_index];
else
return Root->Items[i_index / 10]->Items[i_index % 10];
}
int TMenusGen::Item2Index( TMenuItem *Root, TMenuItem *Item )
{
if( Item->Parent == Root )
return Item->MenuIndex;
else
return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );
}
int __fastcall TMenusGen::Data2Title( int data )
{
return (int) (data >> 16 );
}
int __fastcall TMenusGen::Data2Chapter( int data )
{
return (int) (data & 0xffff);
}
int __fastcall TMenusGen::Pos2Data( int title, int chapter )
{
return (int) (( title << 16 ) | ( chapter & 0xffff ));
}
/* This function deletes all the '&' characters in the caption string,
* because Borland automatically adds one when (and only when!) you click on
* the menuitem. Grrrrr... */
AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption )
{
while( Caption.LastDelimiter( "&" ) != 0 )
{
Caption.Delete( Caption.LastDelimiter( "&" ), 1 );
}
return Caption;
}
/****************************************************************************
* VarChange: change a variable in a vlc_object_t
****************************************************************************
* Change the variable and update the menuitems.
****************************************************************************/
void __fastcall TMenusGen::VarChange( vlc_object_t *p_object,
const char *psz_variable, TMenuItem *RootMenu, TMenuItem *RootPopup,
TMenuItem *Item )
{
vlc_value_t val;
int i_index;
AnsiString Caption = CleanCaption( Item->Caption );
val.psz_string = Caption.c_str();
/* set the new value */
if( var_Set( p_object, psz_variable, val ) < 0 )
{
msg_Warn( p_object, "cannot set variable (%s)", val.psz_string );
}
i_index = Item->MenuIndex;
RootMenu->Items[i_index]->Checked = true;
RootPopup->Items[i_index]->Checked = true;
}
/****************************************************************************
* LangChange: change audio or subtitles languages
****************************************************************************
* Toggle the language, and update the selected menuitems.
****************************************************************************/
void __fastcall TMenusGen::LangChange( TMenuItem *RootCurrent, TMenuItem *Item,
TMenuItem *RootOther, int i_cat )
{
es_descriptor_t * p_es;
es_descriptor_t * p_es_old;
int i_index;
int i_es;
/* find the selected ES */
i_es = Item->Tag;
/* find selected menu item */
i_index = Item2Index( RootCurrent, Item ) - 1;
if( i_index < 0 )
{
/* 'None' was selected */
p_es = NULL;
}
else
{
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_es = p_intf->p_sys->p_input->stream.pp_es[i_es];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
/* find the current ES */
if( i_cat == AUDIO_ES )
{
p_es_old = this->p_audio_es_old;
this->p_audio_es_old = p_es;
}
else
{
p_es_old = this->p_spu_es_old;
this->p_spu_es_old = p_es;
}
/* exchange them */
input_ToggleES( p_intf->p_sys->p_input, p_es_old, false );
input_ToggleES( p_intf->p_sys->p_input, p_es, true );
Item->Checked = true;
Index2Item( RootOther, i_index + 1, true )->Checked = true;
}
/****************************************************************************
* ProgramChange: change the program
****************************************************************************
* Toggle the program, and update the selected menuitems.
****************************************************************************/
void __fastcall TMenusGen::ProgramChange( TMenuItem *Item,
TMenuItem *RootOther )
{
int i_program = Item->Tag;
/* toggle the program */
input_ChangeProgram( p_intf->p_sys->p_input, (uint16_t)i_program );
/* check selected menu items */
Item->Checked = true;
Index2Item( RootOther, i_program - 1, true )->Checked = true;
/* update audio/subtitles menus */
p_intf->p_sys->b_audio_update = VLC_TRUE;
p_intf->p_sys->b_spu_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->b_audio_update = VLC_FALSE;
p_intf->p_sys->b_spu_update = VLC_FALSE;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*****************************************************************************
* SetupVarMenu: build a menu allowing to change a variable
*****************************************************************************/
void __fastcall TMenusGen::SetupVarMenu( vlc_object_t *p_object,
const char *psz_variable, TMenuItem *Root, TNotifyEvent MenuItemClick )
{
TMenuItem * Item;
vlc_value_t val;
char * psz_value = NULL;
int i;
/* remove previous menu */
Root->Clear();
/* get the current value */
if( var_Get( p_object, psz_variable, &val ) < 0 )
{
return;
}
psz_value = val.psz_string;
if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST, &val ) < 0 )
{
free( psz_value );
return;
}
/* append a menuitem for each option */
for( i = 0; i < val.p_list->i_count; i++ )
{
Item = new TMenuItem( Root );
Item->Caption = val.p_list->p_values[i].psz_string;
Item->Hint = val.p_list->p_values[i].psz_string;
Item->RadioItem = true;
Item->OnClick = MenuItemClick;
if( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
Item->Checked = true;
/* Add the item to the submenu */
Root->Add( Item );
}
/* enable the menu if there is at least 1 item */
Root->Enabled = ( val.p_list->i_count > 0 );
/* clean up everything */
var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val );
// free( psz_value );
}
/*****************************************************************************
* SetupModuleMenu: build a menu listing all the modules of a given
capability
*****************************************************************************/
void __fastcall TMenusGen::SetupModuleMenu( const char *psz_capability,
TMenuItem *Root, TNotifyEvent MenuItemClick )
{
module_t * p_parser;
vlc_list_t *p_list;
int i_index;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !strcmp( p_parser->psz_capability, psz_capability ) )
{
TMenuItem *Item = new TMenuItem( Root );
Item->Caption = p_parser->psz_object_name;
Item->Hint = Item->Caption;
Item->OnClick = MenuItemClick;
Root->Add( Item );
}
}
vlc_list_release( p_list );
/* be sure that menu is enabled, if there is at least one item */
if( i_index > 0 )
Root->Enabled = true;
}
/*****************************************************************************
* ProgramMenu: update the programs menu of the interface
*****************************************************************************
* Builds the program menu according to what have been found in the PAT
* by the input. Useful for multi-programs streams such as DVB ones.
*****************************************************************************/
void __fastcall TMenusGen::ProgramMenu( TMenuItem *Root,
pgrm_descriptor_t *p_pgrm, TNotifyEvent MenuItemClick )
{
TMenuItem * Item;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
/* create a set of program buttons and append them to the container */
for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_pgrm_number;
i++ )
{
AnsiString Name;
Name.sprintf( "id %d",
p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
Item = new TMenuItem( Root );
Item->Caption = Name;
Item->Hint = Name;
Item->RadioItem = true;
Item->OnClick = MenuItemClick;
/* FIXME: temporary hack to save the program id with the Item
* It will be used in the callback. */
Item->Tag = i + 1;
/* check the currently selected program */
if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
Item->Checked = true;
/* add the item to the submenu */
Root->Add( Item );
}
/* be sure that menu is enabled if more than 1 program */
if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
Root->Enabled = true;
}
/*****************************************************************************
* RadioMenu: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
void __fastcall TMenusGen::RadioMenu( TMenuItem *Root, AnsiString ItemName,
int i_nb, int i_selected, TNotifyEvent MenuItemClick )
{
TMenuItem * ItemGroup;
TMenuItem * Item;
AnsiString Name;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
for( int i_item = 1; i_item <= i_nb; i_item++ )
{
/* we group titles/chapters in packets of ten for small screens */
if( ( i_item % 10 == 1 ) && ( i_nb > 20 ) )
{
if( i_item != 1 )
Root->Add( ItemGroup );
Name.sprintf( "%ss %d to %d", ItemName, i_item, i_item + 9 );
ItemGroup = new TMenuItem( Root );
ItemGroup->Hint = Name;
ItemGroup->RadioItem = true;
/* set the accelerator character */
Name.Insert( "&", Name.Length() - 1 );
ItemGroup->Caption = Name;
}
Name.sprintf( "%s %d", ItemName, i_item );
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
/* set the accelerator character */
Name.Insert( "&", Name.Length() );
Item->Caption = Name;
/* FIXME: temporary hack to save i_item with the Item
* It will be used in the callback. */
Item->Tag = i_item;
/* check the currently selected chapter */
if( i_selected == i_item )
Item->Checked = true;
/* setup signal handling */
Item->OnClick = MenuItemClick;
if( i_nb > 20 )
ItemGroup->Add( Item );
else
Root->Add( Item );
}
// if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?
if( i_nb > 20 )
Root->Add( ItemGroup );
/* be sure that menu is enabled, if there are several items */
if( i_nb > 1 )
Root->Enabled = true;
}
/*****************************************************************************
* LanguageMenus: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input:
* - languages
* - sub-pictures
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
void __fastcall TMenusGen::LanguageMenu( TMenuItem *Root, es_descriptor_t *p_es,
int i_cat, TNotifyEvent MenuItemClick )
{
TMenuItem * Separator;
TMenuItem * Item;
AnsiString Name;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
/* special case for "off" item */
Name = "None";
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->OnClick = MenuItemClick;
Item->Tag = -1;
Root->Add( Item );
/* separator item */
Separator = new TMenuItem( Root );
Separator->Caption = "-";
Root->Add( Separator );
int i_item = 0;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
#define ES p_intf->p_sys->p_input->stream.pp_es[i]
/* create a set of language buttons and append them to the Root */
for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_es_number;
i++ )
{
if( ( ES->i_cat == i_cat ) &&
( !ES->p_pgrm ||
ES->p_pgrm ==
p_intf->p_sys->p_input->stream.p_selected_program ) )
{
i_item++;
Name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
if( Name.IsEmpty() )
Name.sprintf( "Language %d", i_item );
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->Tag = i;
/* check the currently selected item */
if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
Item->Checked = true;
/* setup signal hanling */
Item->OnClick = MenuItemClick;
Root->Add( Item );
}
}
#undef ES
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
/* be sure that menu is enabled if non empty */
if( i_item > 0 )
Root->Enabled = true;
}
/*****************************************************************************
* NavigationMenu: sets menus for titles and chapters selection
*****************************************************************************
* Generates two types of menus:
* -simple list of titles
* -cascaded lists of chapters for each title
*****************************************************************************/
void __fastcall TMenusGen::NavigationMenu( TMenuItem *Root,
TNotifyEvent MenuItemClick )
{
TMenuItem * TitleGroup;
TMenuItem * TitleItem;
TMenuItem * ChapterGroup;
TMenuItem * ChapterItem;
AnsiString Name;
unsigned int i_title_nb;
unsigned int i_chapter_nb;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb - 1;
/* loop on titles */
for( unsigned int i_title = 1; i_title <= i_title_nb; i_title++ )
{
/* we group titles in packets of ten for small screens */
if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
{
if( i_title != 1 )
Root->Add( TitleGroup );
Name.sprintf( "%d - %d", i_title, i_title + 9 );
TitleGroup = new TMenuItem( Root );
TitleGroup->RadioItem = true;
TitleGroup->Hint = Name;
TitleGroup->Caption = Name;
}
Name.sprintf( "Title %d (%d)", i_title,
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1 );
{
TitleItem = new TMenuItem( Root );
TitleItem->RadioItem = true;
TitleItem->Hint = Name;
TitleItem->Caption = Name;
i_chapter_nb =
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;
/* loop on chapters */
for( unsigned int i_chapter = 1; i_chapter <= i_chapter_nb;
i_chapter++ )
{
/* we group chapters in packets of ten for small screens */
if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )
{
if( i_chapter != 1 )
TitleItem->Add( ChapterGroup );
Name.sprintf( "%d - %d", i_chapter, i_chapter + 9 );
ChapterGroup = new TMenuItem( TitleItem );
ChapterGroup->RadioItem = true;
ChapterGroup->Hint = Name;
ChapterGroup->Caption = Name;
}
Name.sprintf( "Chapter %d", i_chapter );
ChapterItem = new TMenuItem( TitleItem );
ChapterItem->RadioItem = true;
ChapterItem->Hint = Name;
ChapterItem->Caption = Name;
/* FIXME: temporary hack to save i_title and i_chapter with
* ChapterItem, since we will need them in the callback */
ChapterItem->Tag = Pos2Data( i_title, i_chapter );
#define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
/* check the currently selected chapter */
if( ( p_area ==
p_intf->p_sys->p_input->stream.p_selected_area ) &&
( p_area->i_part == i_chapter ) )
{
ChapterItem->Checked = true;
}
#undef p_area
/* setup signal handling */
ChapterItem->OnClick = MenuItemClick;
if( i_chapter_nb > 20 )
ChapterGroup->Add( ChapterItem );
else
TitleItem->Add( ChapterItem );
}
if( i_chapter_nb > 20 )
{
TitleItem->Add( ChapterGroup );
}
if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb
> 1 )
{
/* be sure that menu is sensitive */
Root->Enabled = true;
}
}
if( i_title_nb > 20 )
TitleGroup->Add( TitleItem );
else
Root->Add( TitleItem );
}
if( i_title_nb > 20 )
Root->Add( TitleGroup );
/* be sure that menu is sensitive */
Root->Enabled = true;
}
/*****************************************************************************
* menu.cpp: functions to handle menu items
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: menu.cpp,v 1.14 2003/02/12 02:11:58 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "menu.h"
#include "win32_common.h"
/*****************************************************************************
* TMenusGen::*Click: callbacks for the menuitems
****************************************************************************/
/*
* Variables
*/
/* variables of the audio output */
void __fastcall TMenusGen::AoutVarClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
vlc_object_t * p_aout;
p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout == NULL )
{
msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
return;
}
if( Item->Parent == MenuADevice || Item->Parent == PopupADevice )
{
VarChange( p_aout, "audio-device", MenuADevice, PopupADevice, Item );
}
else if( Item->Parent == MenuChannel || Item->Parent == PopupChannel )
{
VarChange( p_aout, "audio-channels", MenuChannel, PopupChannel, Item );
}
vlc_object_release( p_aout );
}
/* variables of the video output */
void __fastcall TMenusGen::VoutVarClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
vlc_object_t * p_vout;
p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout == NULL )
{
msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
return;
}
if( Item->Parent == MenuVDevice || Item->Parent == PopupVDevice )
{
VarChange( p_vout, "video-device", MenuVDevice, PopupVDevice, Item );
}
vlc_object_release( p_vout );
}
/*
* Modules
*/
/* Interface modules: we spawn a new interface */
void __fastcall TMenusGen::InterfaceModuleClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
AnsiString IntfName = CleanCaption( Item->Caption );
intf_thread_t *p_newintf;
p_newintf = intf_Create( p_intf->p_vlc, IntfName.c_str() );
if( p_newintf )
{
p_newintf->b_block = VLC_FALSE;
if( intf_RunThread( p_newintf ) )
{
vlc_object_detach( p_newintf );
intf_Destroy( p_newintf );
}
}
}
/*
* Audio
*/
void __fastcall TMenusGen::MenuLanguageClick( TObject *Sender )
{
LangChange( MenuLanguage, (TMenuItem *)Sender, PopupLanguage, AUDIO_ES );
}
void __fastcall TMenusGen::PopupLanguageClick( TObject *Sender )
{
LangChange( PopupLanguage, (TMenuItem *)Sender, MenuLanguage, AUDIO_ES );
}
/*
* Subtitles
*/
void __fastcall TMenusGen::MenuSubtitleClick( TObject *Sender )
{
LangChange( MenuSubtitles, (TMenuItem *)Sender, PopupSubtitles, SPU_ES );
}
void __fastcall TMenusGen::PopupSubtitleClick( TObject *Sender )
{
LangChange( PopupSubtitles, (TMenuItem *)Sender, MenuSubtitles, SPU_ES );
}
/*
* Program
*/
void __fastcall TMenusGen::MenuProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, PopupProgram );
}
void __fastcall TMenusGen::PopupProgramClick( TObject *Sender )
{
ProgramChange( (TMenuItem *)Sender, MenuProgram );
}
/*
* Title
*/
void __fastcall TMenusGen::MenuTitleClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
unsigned int i_title = Item->Tag;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_title = __MIN( i_title,
p_intf->p_sys->p_input->stream.i_area_nb - 1 );
i_title = __MAX( i_title, 1 );
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
Item->Checked = true;
ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
Index2Item( ItemTitle, 0, false )->Checked = true;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Chapter
*/
void __fastcall TMenusGen::MenuChapterClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
unsigned int i_title;
unsigned int i_chapter = Item->Tag;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_area = p_intf->p_sys->p_input->stream.p_selected_area;
i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
i_chapter = __MAX( i_chapter, 1 );
p_area->i_part = i_chapter;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
ItemTitle = Index2Item( PopupNavigation, i_title, false );
Index2Item( ItemTitle, i_chapter, false )->Checked = true;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*
* Navigation
*/
void __fastcall TMenusGen::PopupNavigationClick( TObject *Sender )
{
TMenuItem * Item = (TMenuItem *)Sender;
TMenuItem * ItemTitle;
input_area_t * p_area;
unsigned int i_title = Data2Title( Item->Tag );
unsigned int i_chapter = Data2Chapter( Item->Tag );
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
i_title = __MIN( i_title,
p_intf->p_sys->p_input->stream.i_area_nb - 1 );
i_title = __MAX( i_title, 1 );
p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );
i_chapter = __MAX( i_chapter, 1 );
p_area->i_part = i_chapter;
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
input_ChangeArea( p_intf->p_sys->p_input, p_area );
Item->Checked = true;
ItemTitle = Index2Item( MenuTitle, i_title, false );
if( ItemTitle->Checked )
{
/* same title, new chapter */
Index2Item( MenuChapter, i_chapter, false )->Checked = true;
}
else
{
/* new title => we must rebuild the chapter menu */
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
RadioMenu(
MenuChapter, "Chapter",
p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb,
i_chapter, MenuChapterClick );
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
__fastcall TMenusGen::TMenusGen( intf_thread_t *_p_intf ) : TObject()
{
p_intf = _p_intf;
/* Initialize local pointers to menu items of the main window */
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
if( p_window == NULL )
{
msg_Warn( p_intf, "Main window wasn't created, expect problems..." );
return;
}
MenuChannel = p_window->MenuChannel;
PopupChannel = p_window->PopupChannel;
MenuADevice = p_window->MenuADevice;
PopupADevice = p_window->PopupADevice;
MenuVDevice = p_window->MenuVDevice;
PopupVDevice = p_window->PopupVDevice;
MenuLanguage = p_window->MenuLanguage;
PopupLanguage = p_window->PopupLanguage;
MenuSubtitles = p_window->MenuSubtitles;
PopupSubtitles = p_window->PopupSubtitles;
MenuProgram = p_window->MenuProgram;
PopupProgram = p_window->PopupProgram;
MenuTitle = p_window->MenuTitle;
MenuChapter = p_window->MenuChapter;
PopupNavigation = p_window->PopupNavigation;
MenuAddInterface = p_window->MenuAddInterface;
/* Create the "Add interface" menu */
SetupModuleMenu( "interface", MenuAddInterface, InterfaceModuleClick );
}
/*****************************************************************************
* SetupMenus: This function dynamically generates some menus
*****************************************************************************
* The lock on p_input->stream must be taken before you call this function
*****************************************************************************/
void __fastcall TMenusGen::SetupMenus()
{
TMainFrameDlg * p_window = p_intf->p_sys->p_window;
input_thread_t * p_input = p_intf->p_sys->p_input;
es_descriptor_t * p_audio_es;
es_descriptor_t * p_spu_es;
p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;
p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_program_update |
p_intf->p_sys->b_title_update;
p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_program_update |
p_intf->p_sys->b_title_update;
if( p_intf->p_sys->b_program_update )
{
pgrm_descriptor_t * p_pgrm;
if( p_input->stream.p_new_program )
{
p_pgrm = p_input->stream.p_new_program;
}
else
{
p_pgrm = p_input->stream.p_selected_program;
}
ProgramMenu( MenuProgram, p_pgrm, MenuProgramClick );
ProgramMenu( PopupProgram, p_pgrm, PopupProgramClick );
p_intf->p_sys->b_program_update = VLC_FALSE;
}
if( p_intf->p_sys->b_title_update )
{
// why "-1" ?
// because if the titles go from 1 to X-1, there are X-1 titles
RadioMenu( MenuTitle, "Title",
p_input->stream.i_area_nb - 1,
p_input->stream.p_selected_area->i_id,
MenuTitleClick );
AnsiString CurrentTitle;
CurrentTitle.sprintf( "%d", p_input->stream.p_selected_area->i_id );
p_window->LabelTitleCurrent->Caption = CurrentTitle;
p_intf->p_sys->b_title_update = VLC_FALSE;
}
if( p_intf->p_sys->b_chapter_update )
{
RadioMenu( MenuChapter, "Chapter",
p_input->stream.p_selected_area->i_part_nb - 1,
p_input->stream.p_selected_area->i_part,
MenuChapterClick );
NavigationMenu( PopupNavigation, PopupNavigationClick );
AnsiString CurrentChapter;
CurrentChapter.sprintf( "%d", p_input->stream.p_selected_area->i_part );
p_window->LabelChapterCurrent->Caption = CurrentChapter;
p_intf->p_sys->i_part = p_input->stream.p_selected_area->i_part;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
}
/* look for selected ES */
p_audio_es = NULL;
p_spu_es = NULL;
for( unsigned int i = 0; i < p_input->stream.i_selected_es_number; i++ )
{
if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )
{
p_audio_es = p_input->stream.pp_selected_es[i];
}
if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )
{
p_spu_es = p_input->stream.pp_selected_es[i];
}
}
this->p_audio_es_old = p_audio_es;
this->p_spu_es_old = p_spu_es;
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* audio menus */
if( p_intf->p_sys->b_audio_update )
{
LanguageMenu( MenuLanguage, p_audio_es, AUDIO_ES, MenuLanguageClick );
LanguageMenu( PopupLanguage, p_audio_es, AUDIO_ES, PopupLanguageClick );
p_intf->p_sys->b_audio_update = VLC_FALSE;
}
/* sub picture menus */
if( p_intf->p_sys->b_spu_update )
{
LanguageMenu( PopupSubtitles, p_spu_es, SPU_ES, PopupSubtitleClick );
LanguageMenu( MenuSubtitles, p_spu_es, SPU_ES, MenuSubtitleClick );
p_intf->p_sys->b_spu_update = VLC_FALSE;
}
if( p_intf->p_sys->b_aout_update )
{
aout_instance_t * p_aout;
p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
val.b_bool = VLC_FALSE;
var_Set( (vlc_object_t *)p_aout, "intf-change", val );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
MenuChannel, AoutVarClick );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",
PopupChannel, AoutVarClick );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
MenuADevice, AoutVarClick );
SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",
PopupADevice, AoutVarClick );
vlc_object_release( (vlc_object_t *)p_aout );
}
p_intf->p_sys->b_aout_update = VLC_FALSE;
}
if( p_intf->p_sys->b_vout_update )
{
vout_thread_t * p_vout;
p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
val.b_bool = VLC_FALSE;
var_Set( (vlc_object_t *)p_vout, "intf-change", val );
SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
MenuVDevice, VoutVarClick );
SetupVarMenu( (vlc_object_t *)p_vout, "video-device",
PopupVDevice, VoutVarClick );
vlc_object_release( (vlc_object_t *)p_vout );
}
p_intf->p_sys->b_vout_update = VLC_FALSE;
}
vlc_mutex_lock( &p_input->stream.stream_lock );
}
/*****************************************************************************
* Private functions
*****************************************************************************/
TMenuItem * TMenusGen::Index2Item( TMenuItem *Root, int i_index,
bool SingleColumn )
{
if( SingleColumn || ( i_index < 20 ) )
return Root->Items[i_index];
else
return Root->Items[i_index / 10]->Items[i_index % 10];
}
int TMenusGen::Item2Index( TMenuItem *Root, TMenuItem *Item )
{
if( Item->Parent == Root )
return Item->MenuIndex;
else
return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );
}
int __fastcall TMenusGen::Data2Title( int data )
{
return (int) (data >> 16 );
}
int __fastcall TMenusGen::Data2Chapter( int data )
{
return (int) (data & 0xffff);
}
int __fastcall TMenusGen::Pos2Data( int title, int chapter )
{
return (int) (( title << 16 ) | ( chapter & 0xffff ));
}
/* This function deletes all the '&' characters in the caption string,
* because Borland automatically adds one when (and only when!) you click on
* the menuitem. Grrrrr... */
AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption )
{
while( Caption.LastDelimiter( "&" ) != 0 )
{
Caption.Delete( Caption.LastDelimiter( "&" ), 1 );
}
return Caption;
}
/****************************************************************************
* VarChange: change a variable in a vlc_object_t
****************************************************************************
* Change the variable and update the menuitems.
****************************************************************************/
void __fastcall TMenusGen::VarChange( vlc_object_t *p_object,
const char *psz_variable, TMenuItem *RootMenu, TMenuItem *RootPopup,
TMenuItem *Item )
{
vlc_value_t val;
int i_index;
AnsiString Caption = CleanCaption( Item->Caption );
val.psz_string = Caption.c_str();
/* set the new value */
if( var_Set( p_object, psz_variable, val ) < 0 )
{
msg_Warn( p_object, "cannot set variable (%s)", val.psz_string );
}
i_index = Item->MenuIndex;
RootMenu->Items[i_index]->Checked = true;
RootPopup->Items[i_index]->Checked = true;
}
/****************************************************************************
* LangChange: change audio or subtitles languages
****************************************************************************
* Toggle the language, and update the selected menuitems.
****************************************************************************/
void __fastcall TMenusGen::LangChange( TMenuItem *RootCurrent, TMenuItem *Item,
TMenuItem *RootOther, int i_cat )
{
es_descriptor_t * p_es;
es_descriptor_t * p_es_old;
int i_index;
int i_es;
/* find the selected ES */
i_es = Item->Tag;
/* find selected menu item */
i_index = Item2Index( RootCurrent, Item ) - 1;
if( i_index < 0 )
{
/* 'None' was selected */
p_es = NULL;
}
else
{
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
p_es = p_intf->p_sys->p_input->stream.pp_es[i_es];
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
}
/* find the current ES */
if( i_cat == AUDIO_ES )
{
p_es_old = this->p_audio_es_old;
this->p_audio_es_old = p_es;
}
else
{
p_es_old = this->p_spu_es_old;
this->p_spu_es_old = p_es;
}
/* exchange them */
input_ToggleES( p_intf->p_sys->p_input, p_es_old, false );
input_ToggleES( p_intf->p_sys->p_input, p_es, true );
Item->Checked = true;
Index2Item( RootOther, i_index + 1, true )->Checked = true;
}
/****************************************************************************
* ProgramChange: change the program
****************************************************************************
* Toggle the program, and update the selected menuitems.
****************************************************************************/
void __fastcall TMenusGen::ProgramChange( TMenuItem *Item,
TMenuItem *RootOther )
{
int i_program = Item->Tag;
/* toggle the program */
input_ChangeProgram( p_intf->p_sys->p_input, (uint16_t)i_program );
/* check selected menu items */
Item->Checked = true;
Index2Item( RootOther, i_program - 1, true )->Checked = true;
/* update audio/subtitles menus */
p_intf->p_sys->b_audio_update = VLC_TRUE;
p_intf->p_sys->b_spu_update = VLC_TRUE;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
SetupMenus();
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
p_intf->p_sys->b_audio_update = VLC_FALSE;
p_intf->p_sys->b_spu_update = VLC_FALSE;
input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );
}
/*****************************************************************************
* SetupVarMenu: build a menu allowing to change a variable
*****************************************************************************/
void __fastcall TMenusGen::SetupVarMenu( vlc_object_t *p_object,
const char *psz_variable, TMenuItem *Root, TNotifyEvent MenuItemClick )
{
TMenuItem * Item;
vlc_value_t val;
char * psz_value = NULL;
int i;
/* remove previous menu */
Root->Clear();
/* get the current value */
if( var_Get( p_object, psz_variable, &val ) < 0 )
{
return;
}
psz_value = val.psz_string;
if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST, &val ) < 0 )
{
free( psz_value );
return;
}
/* append a menuitem for each option */
for( i = 0; i < val.p_list->i_count; i++ )
{
Item = new TMenuItem( Root );
Item->Caption = val.p_list->p_values[i].psz_string;
Item->Hint = val.p_list->p_values[i].psz_string;
Item->RadioItem = true;
Item->OnClick = MenuItemClick;
if( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
Item->Checked = true;
/* Add the item to the submenu */
Root->Add( Item );
}
/* enable the menu if there is at least 1 item */
Root->Enabled = ( val.p_list->i_count > 0 );
/* clean up everything */
var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val );
// free( psz_value );
}
/*****************************************************************************
* SetupModuleMenu: build a menu listing all the modules of a given
capability
*****************************************************************************/
void __fastcall TMenusGen::SetupModuleMenu( const char *psz_capability,
TMenuItem *Root, TNotifyEvent MenuItemClick )
{
module_t * p_parser;
vlc_list_t *p_list;
int i_index;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
for( i_index = 0; i_index < p_list->i_count; i_index++ )
{
p_parser = (module_t *)p_list->p_values[i_index].p_object ;
if( !strcmp( p_parser->psz_capability, psz_capability ) )
{
TMenuItem *Item = new TMenuItem( Root );
Item->Caption = p_parser->psz_object_name;
Item->Hint = Item->Caption;
Item->OnClick = MenuItemClick;
Root->Add( Item );
}
}
vlc_list_release( p_list );
/* be sure that menu is enabled, if there is at least one item */
if( i_index > 0 )
Root->Enabled = true;
}
/*****************************************************************************
* ProgramMenu: update the programs menu of the interface
*****************************************************************************
* Builds the program menu according to what have been found in the PAT
* by the input. Useful for multi-programs streams such as DVB ones.
*****************************************************************************/
void __fastcall TMenusGen::ProgramMenu( TMenuItem *Root,
pgrm_descriptor_t *p_pgrm, TNotifyEvent MenuItemClick )
{
TMenuItem * Item;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
/* create a set of program buttons and append them to the container */
for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_pgrm_number;
i++ )
{
AnsiString Name;
Name.sprintf( "id %d",
p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );
Item = new TMenuItem( Root );
Item->Caption = Name;
Item->Hint = Name;
Item->RadioItem = true;
Item->OnClick = MenuItemClick;
/* FIXME: temporary hack to save the program id with the Item
* It will be used in the callback. */
Item->Tag = i + 1;
/* check the currently selected program */
if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )
Item->Checked = true;
/* add the item to the submenu */
Root->Add( Item );
}
/* be sure that menu is enabled if more than 1 program */
if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )
Root->Enabled = true;
}
/*****************************************************************************
* RadioMenu: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
void __fastcall TMenusGen::RadioMenu( TMenuItem *Root, AnsiString ItemName,
int i_nb, int i_selected, TNotifyEvent MenuItemClick )
{
TMenuItem * ItemGroup;
TMenuItem * Item;
AnsiString Name;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
for( int i_item = 1; i_item <= i_nb; i_item++ )
{
/* we group titles/chapters in packets of ten for small screens */
if( ( i_item % 10 == 1 ) && ( i_nb > 20 ) )
{
if( i_item != 1 )
Root->Add( ItemGroup );
Name.sprintf( "%ss %d to %d", ItemName, i_item, i_item + 9 );
ItemGroup = new TMenuItem( Root );
ItemGroup->Hint = Name;
ItemGroup->RadioItem = true;
/* set the accelerator character */
Name.Insert( "&", Name.Length() - 1 );
ItemGroup->Caption = Name;
}
Name.sprintf( "%s %d", ItemName, i_item );
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
/* set the accelerator character */
Name.Insert( "&", Name.Length() );
Item->Caption = Name;
/* FIXME: temporary hack to save i_item with the Item
* It will be used in the callback. */
Item->Tag = i_item;
/* check the currently selected chapter */
if( i_selected == i_item )
Item->Checked = true;
/* setup signal handling */
Item->OnClick = MenuItemClick;
if( i_nb > 20 )
ItemGroup->Add( Item );
else
Root->Add( Item );
}
// if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?
if( i_nb > 20 )
Root->Add( ItemGroup );
/* be sure that menu is enabled, if there are several items */
if( i_nb > 1 )
Root->Enabled = true;
}
/*****************************************************************************
* LanguageMenus: update interactive menus of the interface
*****************************************************************************
* Sets up menus with information from input:
* - languages
* - sub-pictures
* Warning: since this function is designed to be called by management
* function, the interface lock has to be taken
*****************************************************************************/
void __fastcall TMenusGen::LanguageMenu( TMenuItem *Root, es_descriptor_t *p_es,
int i_cat, TNotifyEvent MenuItemClick )
{
TMenuItem * Separator;
TMenuItem * Item;
AnsiString Name;
/* remove previous menu */
Root->Clear();
Root->Enabled = false;
/* special case for "off" item */
Name = "None";
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->OnClick = MenuItemClick;
Item->Tag = -1;
Root->Add( Item );
/* separator item */
Separator = new TMenuItem( Root );
Separator->Caption = "-";
Root->Add( Separator );
int i_item = 0;
vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );
#define ES p_intf->p_sys->p_input->stream.pp_es[i]
/* create a set of language buttons and append them to the Root */
for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_es_number;
i++ )
{
if( ( ES->i_cat == i_cat ) &&
( !ES->p_pgrm ||
ES->p_pgrm ==
p_intf->p_sys->p_input->stream.p_selected_program ) )
{
i_item++;
Name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;
if( Name.IsEmpty() )
Name.sprintf( "Language %d", i_item );
Item = new TMenuItem( Root );
Item->RadioItem = true;
Item->Hint = Name;
Item->Caption = Name;
Item->Tag = i;
/* check the currently selected item */
if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )
Item->Checked = true;
/* setup signal hanling */
Item->OnClick = MenuItemClick;
Root->Add( Item );
}
}
#undef ES
vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );
/* be sure that menu is enabled if non empty */
if( i_item > 0 )
Root->Enabled = true;
}
/*****************************************************************************
* NavigationMenu: sets menus for titles and chapters selection
*****************************************************************************
* Generates two types of menus:
* -simple list of titles
* -cascaded lists of chapters for each title
*****************************************************************************/
void __fastcall TMenusGen::NavigationMenu( TMenuItem *Root,
TNotifyEvent MenuItemClick )
{
TMenuItem * TitleGroup;
TMenuItem * TitleItem;
TMenuItem * ChapterGroup;
TMenuItem * ChapterItem;
AnsiString Name;
unsigned int i_title_nb;
unsigned int i_chapter_nb;
/* remove previous menu */
Root->Enabled = false;
Root->Clear();
i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb - 1;
/* loop on titles */
for( unsigned int i_title = 1; i_title <= i_title_nb; i_title++ )
{
/* we group titles in packets of ten for small screens */
if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )
{
if( i_title != 1 )
Root->Add( TitleGroup );
Name.sprintf( "%d - %d", i_title, i_title + 9 );
TitleGroup = new TMenuItem( Root );
TitleGroup->RadioItem = true;
TitleGroup->Hint = Name;
TitleGroup->Caption = Name;
}
Name.sprintf( "Title %d (%d)", i_title,
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1 );
{
TitleItem = new TMenuItem( Root );
TitleItem->RadioItem = true;
TitleItem->Hint = Name;
TitleItem->Caption = Name;
i_chapter_nb =
p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;
/* loop on chapters */
for( unsigned int i_chapter = 1; i_chapter <= i_chapter_nb;
i_chapter++ )
{
/* we group chapters in packets of ten for small screens */
if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )
{
if( i_chapter != 1 )
TitleItem->Add( ChapterGroup );
Name.sprintf( "%d - %d", i_chapter, i_chapter + 9 );
ChapterGroup = new TMenuItem( TitleItem );
ChapterGroup->RadioItem = true;
ChapterGroup->Hint = Name;
ChapterGroup->Caption = Name;
}
Name.sprintf( "Chapter %d", i_chapter );
ChapterItem = new TMenuItem( TitleItem );
ChapterItem->RadioItem = true;
ChapterItem->Hint = Name;
ChapterItem->Caption = Name;
/* FIXME: temporary hack to save i_title and i_chapter with
* ChapterItem, since we will need them in the callback */
ChapterItem->Tag = Pos2Data( i_title, i_chapter );
#define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]
/* check the currently selected chapter */
if( ( p_area ==
p_intf->p_sys->p_input->stream.p_selected_area ) &&
( p_area->i_part == i_chapter ) )
{
ChapterItem->Checked = true;
}
#undef p_area
/* setup signal handling */
ChapterItem->OnClick = MenuItemClick;
if( i_chapter_nb > 20 )
ChapterGroup->Add( ChapterItem );
else
TitleItem->Add( ChapterItem );
}
if( i_chapter_nb > 20 )
{
TitleItem->Add( ChapterGroup );
}
if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb
> 1 )
{
/* be sure that menu is sensitive */
Root->Enabled = true;
}
}
if( i_title_nb > 20 )
TitleGroup->Add( TitleItem );
else
Root->Add( TitleItem );
}
if( i_title_nb > 20 )
Root->Add( TitleGroup );
/* be sure that menu is sensitive */
Root->Enabled = true;
}
/*****************************************************************************
* menu.h: prototypes for menu functions
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: menu.h,v 1.4 2003/01/23 03:33:34 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*****************************************************************************/
#ifndef menuH
#define menuH
//----------------------------------------------------------------------------
class TMenusGen : public TObject
{
private:
intf_thread_t *p_intf;
/* local pointers to main window menu items */
TMenuItem *MenuChannel;
TMenuItem *PopupChannel;
TMenuItem *MenuADevice;
TMenuItem *PopupADevice;
TMenuItem *MenuVDevice;
TMenuItem *PopupVDevice;
TMenuItem *MenuLanguage;
TMenuItem *PopupLanguage;
TMenuItem *MenuSubtitles;
TMenuItem *PopupSubtitles;
TMenuItem *MenuProgram;
TMenuItem *PopupProgram;
TMenuItem *MenuTitle;
TMenuItem *MenuChapter;
TMenuItem *PopupNavigation;
TMenuItem *MenuAddInterface;
/* Language information */
es_descriptor_t * p_audio_es_old;
es_descriptor_t * p_spu_es_old;
/* Helpful functions */
int Item2Index( TMenuItem *Root, TMenuItem *Item );
TMenuItem *Index2Item( TMenuItem *Root, int i_index, bool SingleColumn );
int __fastcall Data2Title( int data );
int __fastcall Data2Chapter( int data );
int __fastcall Pos2Data( int title, int chapter );
AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption );
void __fastcall VarChange( vlc_object_t *, const char *, TMenuItem *,
TMenuItem *, TMenuItem * );
void __fastcall LangChange( TMenuItem *, TMenuItem *, TMenuItem *, int );
void __fastcall ProgramChange( TMenuItem *, TMenuItem * );
void __fastcall SetupVarMenu( vlc_object_t *, const char *, TMenuItem *,
TNotifyEvent );
void __fastcall SetupModuleMenu( const char *, TMenuItem *, TNotifyEvent );
void __fastcall ProgramMenu( TMenuItem *, pgrm_descriptor_t *,
TNotifyEvent );
void __fastcall RadioMenu( TMenuItem *, AnsiString, int, int,
TNotifyEvent );
void __fastcall LanguageMenu( TMenuItem *, es_descriptor_t *, int,
TNotifyEvent );
void __fastcall NavigationMenu( TMenuItem *, TNotifyEvent );
public:
__fastcall TMenusGen( intf_thread_t *_p_intf );
/* menu generation */
void __fastcall SetupMenus();
/* callbacks for menuitems */
void __fastcall AoutVarClick( TObject *Sender );
void __fastcall VoutVarClick( TObject *Sender );
void __fastcall InterfaceModuleClick( TObject *Sender );
void __fastcall MenuLanguageClick( TObject *Sender );
void __fastcall PopupLanguageClick( TObject *Sender );
void __fastcall MenuSubtitleClick( TObject *Sender );
void __fastcall PopupSubtitleClick( TObject *Sender );
void __fastcall MenuProgramClick( TObject *Sender );
void __fastcall PopupProgramClick( TObject *Sender );
void __fastcall MenuTitleClick( TObject *Sender );
void __fastcall MenuChapterClick( TObject *Sender );
void __fastcall PopupNavigationClick( TObject *Sender );
};
//----------------------------------------------------------------------------
#endif
/*****************************************************************************
* menu.h: prototypes for menu functions
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: menu.h,v 1.5 2003/02/12 02:11:58 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*****************************************************************************/
#ifndef menuH
#define menuH
//----------------------------------------------------------------------------
class TMenusGen : public TObject
{
private:
intf_thread_t *p_intf;
/* local pointers to main window menu items */
TMenuItem *MenuChannel;
TMenuItem *PopupChannel;
TMenuItem *MenuADevice;
TMenuItem *PopupADevice;
TMenuItem *MenuVDevice;
TMenuItem *PopupVDevice;
TMenuItem *MenuLanguage;
TMenuItem *PopupLanguage;
TMenuItem *MenuSubtitles;
TMenuItem *PopupSubtitles;
TMenuItem *MenuProgram;
TMenuItem *PopupProgram;
TMenuItem *MenuTitle;
TMenuItem *MenuChapter;
TMenuItem *PopupNavigation;
TMenuItem *MenuAddInterface;
/* Language information */
es_descriptor_t * p_audio_es_old;
es_descriptor_t * p_spu_es_old;
/* Helpful functions */
int Item2Index( TMenuItem *Root, TMenuItem *Item );
TMenuItem *Index2Item( TMenuItem *Root, int i_index, bool SingleColumn );
int __fastcall Data2Title( int data );
int __fastcall Data2Chapter( int data );
int __fastcall Pos2Data( int title, int chapter );
AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption );
void __fastcall VarChange( vlc_object_t *, const char *, TMenuItem *,
TMenuItem *, TMenuItem * );
void __fastcall LangChange( TMenuItem *, TMenuItem *, TMenuItem *, int );
void __fastcall ProgramChange( TMenuItem *, TMenuItem * );
void __fastcall SetupVarMenu( vlc_object_t *, const char *, TMenuItem *,
TNotifyEvent );
void __fastcall SetupModuleMenu( const char *, TMenuItem *, TNotifyEvent );
void __fastcall ProgramMenu( TMenuItem *, pgrm_descriptor_t *,
TNotifyEvent );
void __fastcall RadioMenu( TMenuItem *, AnsiString, int, int,
TNotifyEvent );
void __fastcall LanguageMenu( TMenuItem *, es_descriptor_t *, int,
TNotifyEvent );
void __fastcall NavigationMenu( TMenuItem *, TNotifyEvent );
public:
__fastcall TMenusGen( intf_thread_t *_p_intf );
/* menu generation */
void __fastcall SetupMenus();
/* callbacks for menuitems */
void __fastcall AoutVarClick( TObject *Sender );
void __fastcall VoutVarClick( TObject *Sender );
void __fastcall InterfaceModuleClick( TObject *Sender );
void __fastcall MenuLanguageClick( TObject *Sender );
void __fastcall PopupLanguageClick( TObject *Sender );
void __fastcall MenuSubtitleClick( TObject *Sender );
void __fastcall PopupSubtitleClick( TObject *Sender );
void __fastcall MenuProgramClick( TObject *Sender );
void __fastcall PopupProgramClick( TObject *Sender );
void __fastcall MenuTitleClick( TObject *Sender );
void __fastcall MenuChapterClick( TObject *Sender );
void __fastcall PopupNavigationClick( TObject *Sender );
};
//----------------------------------------------------------------------------
#endif
/*****************************************************************************
* sout.h: the stream ouput dialog box
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: sout.h,v 1.3 2003/01/26 03:55:36 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*****************************************************************************/
#ifndef soutH
#define soutH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include "CSPIN.h"
#include <Dialogs.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class TSoutDlg : public TForm
{
__published: // IDE-managed Components
TGroupBox *GroupBoxStreamOut;
TEdit *EditMrl;
TPanel *PanelAccess;
TRadioButton *RadioButtonFile;
TRadioButton *RadioButtonUDP;
TRadioButton *RadioButtonRTP;
TOpenDialog *OpenDialog1;
TButton *ButtonBrowse;
TEdit *EditFile;
TCSpinEdit *SpinEditPort;
TEdit *EditAddress;
TLabel *LabelPort;
TLabel *LabelAddress;
TPanel *PanelMux;
TRadioButton *RadioButtonPS;
TRadioButton *RadioButtonTS;
TButton *ButtonOK;
TButton *ButtonCancel;
void __fastcall ButtonBrowseClick( TObject *Sender );
void __fastcall CustomEditChange( TObject *Sender );
void __fastcall RadioButtonMuxClick( TObject *Sender );
void __fastcall RadioButtonAccessClick( TObject *Sender );
void __fastcall ButtonOKClick( TObject *Sender );
private: // User declarations
void __fastcall RebuildMrl();
intf_thread_t *p_intf;
public: // User declarations
__fastcall TSoutDlg( TComponent* Owner, intf_thread_t *_p_intf );
};
//---------------------------------------------------------------------------
#endif
/*****************************************************************************
* sout.h: the stream ouput dialog box
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: sout.h,v 1.4 2003/02/12 02:11:58 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*****************************************************************************/
#ifndef soutH
#define soutH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include "CSPIN.h"
#include <Dialogs.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class TSoutDlg : public TForm
{
__published: // IDE-managed Components
TGroupBox *GroupBoxStreamOut;
TEdit *EditMrl;
TPanel *PanelAccess;
TRadioButton *RadioButtonFile;
TRadioButton *RadioButtonUDP;
TRadioButton *RadioButtonRTP;
TOpenDialog *OpenDialog1;
TButton *ButtonBrowse;
TEdit *EditFile;
TCSpinEdit *SpinEditPort;
TEdit *EditAddress;
TLabel *LabelPort;
TLabel *LabelAddress;
TPanel *PanelMux;
TRadioButton *RadioButtonPS;
TRadioButton *RadioButtonTS;
TButton *ButtonOK;
TButton *ButtonCancel;
void __fastcall ButtonBrowseClick( TObject *Sender );
void __fastcall CustomEditChange( TObject *Sender );
void __fastcall RadioButtonMuxClick( TObject *Sender );
void __fastcall RadioButtonAccessClick( TObject *Sender );
void __fastcall ButtonOKClick( TObject *Sender );
private: // User declarations
void __fastcall RebuildMrl();
intf_thread_t *p_intf;
public: // User declarations
__fastcall TSoutDlg( TComponent* Owner, intf_thread_t *_p_intf );
};
//---------------------------------------------------------------------------
#endif
/*****************************************************************************
* subtitles.cpp: Dialog box for divx subtitle selection
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: subtitles.cpp,v 1.2 2003/01/26 03:55:36 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "subtitles.h"
#include "misc.h"
#include "win32_common.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TSubtitlesDlg::TSubtitlesDlg( TComponent* Owner,
intf_thread_t *_p_intf ) : TForm( Owner )
{
p_intf = _p_intf;
Constraints->MinWidth = Width;
Constraints->MinHeight = Height;
Translate( this );
}
//---------------------------------------------------------------------------
void __fastcall TSubtitlesDlg::ButtonBrowseClick( TObject *Sender )
{
if( OpenDialog1->Execute() )
{
EditFile->Text = OpenDialog1->FileName;
}
}
//---------------------------------------------------------------------------
void __fastcall TSubtitlesDlg::ButtonOKClick( TObject *Sender )
{
int delay = (int) (10 * atof( EditDelay->Text.c_str() ));
float fps = atof( EditFPS->Text.c_str() );
config_PutPsz( p_intf, "sub-file", EditFile->Text.c_str() );
config_PutInt( p_intf, "sub-delay", delay );
config_PutFloat( p_intf, "sub-fps", fps );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* subtitles.cpp: Dialog box for divx subtitle selection
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: subtitles.cpp,v 1.3 2003/02/12 02:11:58 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#pragma hdrstop
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "subtitles.h"
#include "misc.h"
#include "win32_common.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TSubtitlesDlg::TSubtitlesDlg( TComponent* Owner,
intf_thread_t *_p_intf ) : TForm( Owner )
{
p_intf = _p_intf;
Constraints->MinWidth = Width;
Constraints->MinHeight = Height;
Translate( this );
}
//---------------------------------------------------------------------------
void __fastcall TSubtitlesDlg::ButtonBrowseClick( TObject *Sender )
{
if( OpenDialog1->Execute() )
{
EditFile->Text = OpenDialog1->FileName;
}
}
//---------------------------------------------------------------------------
void __fastcall TSubtitlesDlg::ButtonOKClick( TObject *Sender )
{
int delay = (int) (10 * atof( EditDelay->Text.c_str() ));
float fps = atof( EditFPS->Text.c_str() );
config_PutPsz( p_intf, "sub-file", EditFile->Text.c_str() );
config_PutInt( p_intf, "sub-delay", delay );
config_PutFloat( p_intf, "sub-fps", fps );
}
//---------------------------------------------------------------------------
/*****************************************************************************
* subtitles.h: Dialog box for divx subtitle selection
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: subtitles.h,v 1.2 2003/01/26 03:55:36 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*****************************************************************************/
#ifndef subtitlesH
#define subtitlesH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class TSubtitlesDlg : public TForm
{
__published: // IDE-managed Components
TOpenDialog *OpenDialog1;
TGroupBox *GroupBoxSubtitles;
TEdit *EditDelay;
TEdit *EditFPS;
TEdit *EditFile;
TButton *ButtonBrowse;
TLabel *LabelDelay;
TLabel *LabelFPS;
TButton *ButtonOK;
TButton *ButtonCancel;
void __fastcall ButtonBrowseClick( TObject *Sender );
void __fastcall ButtonOKClick( TObject *Sender );
private: // User declarations
intf_thread_t *p_intf;
public: // User declarations
__fastcall TSubtitlesDlg( TComponent* Owner, intf_thread_t *p_intf );
};
//---------------------------------------------------------------------------
#endif
/*****************************************************************************
* subtitles.h: Dialog box for divx subtitle selection
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: subtitles.h,v 1.3 2003/02/12 02:11:58 ipkiss Exp $
*
* Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
*
* 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.
*****************************************************************************/
#ifndef subtitlesH
#define subtitlesH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
class TSubtitlesDlg : public TForm
{
__published: // IDE-managed Components
TOpenDialog *OpenDialog1;
TGroupBox *GroupBoxSubtitles;
TEdit *EditDelay;
TEdit *EditFPS;
TEdit *EditFile;
TButton *ButtonBrowse;
TLabel *LabelDelay;
TLabel *LabelFPS;
TButton *ButtonOK;
TButton *ButtonCancel;
void __fastcall ButtonBrowseClick( TObject *Sender );
void __fastcall ButtonOKClick( TObject *Sender );
private: // User declarations
intf_thread_t *p_intf;
public: // User declarations
__fastcall TSubtitlesDlg( TComponent* Owner, intf_thread_t *p_intf );
};
//---------------------------------------------------------------------------
#endif
......@@ -14,5 +14,5 @@ USEFORM("sout.cpp", SoutDlg);
USEFORM("subtitles.cpp", SubtitlesDlg);
//---------------------------------------------------------------------------
This file is used by the project manager only and should be treated like the project file
DllEntryPoint
DllEntryPoint
/*****************************************************************************
* win32.cpp : Win32 interface plugin for vlc
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: win32.cpp,v 1.14 2003/02/01 22:21:44 ipkiss Exp $
*
* Authors: Olivier Teulire <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#include <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "mainframe.h"
#include "menu.h"
#include "win32_common.h"
/*****************************************************************************
* Exported interface functions.
*****************************************************************************/
extern "C" __declspec(dllexport)
int __VLC_SYMBOL( vlc_entry ) ( module_t *p_module );
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
int Win32Manage( void *p_data );
/*****************************************************************************
* Open: initialize interface
*****************************************************************************/
static int Open ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = (intf_sys_t *) malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return( 1 );
};
p_intf->pf_run = Run;
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
/* Initialize Win32 thread */
p_intf->p_sys->b_playing = 0;
p_intf->p_sys->b_popup_changed = 0;
p_intf->p_sys->p_input = NULL;
p_intf->p_sys->i_playing = -1;
p_intf->p_sys->b_play_when_adding = VLC_TRUE;
p_intf->p_sys->b_slider_free = 1;
p_intf->p_sys->b_aout_update = VLC_FALSE;
p_intf->p_sys->b_vout_update = VLC_FALSE;
p_intf->p_sys->b_program_update = VLC_FALSE;
p_intf->p_sys->b_title_update = VLC_FALSE;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
p_intf->p_sys->b_audio_update = VLC_FALSE;
p_intf->p_sys->b_spu_update = VLC_FALSE;
return( 0 );
}
/*****************************************************************************
* Close: destroy interface
*****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: main loop
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
p_intf->p_sys->p_window = new TMainFrameDlg( NULL, p_intf );
p_intf->p_sys->p_playwin = new TPlaylistDlg( NULL, p_intf );
p_intf->p_sys->p_messages = new TMessagesDlg( NULL, p_intf );
p_intf->p_sys->p_menus = new TMenusGen( p_intf );
/* show main window and wait until it is closed */
p_intf->p_sys->p_window->ShowModal();
if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;
if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;
if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;
delete p_intf->p_sys->p_menus;
delete p_intf->p_sys->p_messages;
delete p_intf->p_sys->p_playwin;
delete p_intf->p_sys->p_window;
}
/*****************************************************************************
* Win32Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
int Win32Manage( intf_thread_t *p_intf )
{
vlc_mutex_lock( &p_intf->change_lock );
/* If the "display popup" flag has changed */
if( p_intf->b_menu_change )
{
/* FIXME: It would be nice to close the popup when the user left-clicks
elsewhere, or to actualize the position when he right-clicks again,
but i couldn't find a way to close it :-( */
TPoint MousePos = Mouse->CursorPos;
p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );
p_intf->b_menu_change = 0;
}
/* Update the log window */
p_intf->p_sys->p_messages->UpdateLog();
/* Update the playlist */
p_intf->p_sys->p_playwin->Manage();
/* Update the input */
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input = (input_thread_t *)
vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
}
else if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
if( p_intf->p_sys->p_input != NULL && !p_intf->p_sys->p_input->b_die )
{
vlc_bool_t b_need_menus = VLC_FALSE;
input_thread_t * p_input = p_intf->p_sys->p_input;
vlc_object_t * p_aout = NULL;
vlc_object_t * p_vout = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
/* New input or stream map change */
if( p_input->stream.b_changed )
{
p_intf->p_sys->p_window->ModeManage();
b_need_menus = VLC_TRUE;
p_intf->p_sys->b_playing = 1;
}
/* Manage the slider */
if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )
{
TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;
off_t NewValue = TrackBar->Position;
#define p_area p_input->stream.p_selected_area
/* If the user hasn't touched the slider since the last time,
* then the input can safely change it */
if( NewValue == p_intf->p_sys->OldValue )
{
/* Update the value */
TrackBar->Position = p_intf->p_sys->OldValue =
( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /
p_area->i_size;
}
/* Otherwise, send message to the input if the user has
* finished dragging the slider */
else if( p_intf->p_sys->b_slider_free )
{
off_t i_seek = ( NewValue * p_area->i_size ) /
(off_t)SLIDER_MAX_VALUE;
/* release the lock to be able to seek */
vlc_mutex_unlock( &p_input->stream.stream_lock );
input_Seek( p_input, i_seek, INPUT_SEEK_SET );
vlc_mutex_lock( &p_input->stream.stream_lock );
/* Update the old value */
p_intf->p_sys->OldValue = NewValue;
}
# undef p_area
}
if( p_intf->p_sys->i_part != p_input->stream.p_selected_area->i_part )
{
p_intf->p_sys->b_chapter_update = 1;
b_need_menus = VLC_TRUE;
}
/* Does the audio output require to update the menus ? */
p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
if( var_Get( p_aout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_aout_update = 1;
b_need_menus = VLC_TRUE;
}
vlc_object_release( p_aout );
}
/* Does the video output require to update the menus ? */
p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
if( var_Get( p_vout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_vout_update = 1;
b_need_menus = VLC_TRUE;
}
if( var_Get( p_vout, "directx-on-top", &val ) >= 0 )
{
p_intf->p_sys->p_window->MenuOnTop->Checked = val.b_bool;
p_intf->p_sys->p_window->PopupOnTop->Checked = val.b_bool;
}
vlc_object_release( p_vout );
}
if( b_need_menus )
{
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
p_intf->p_sys->p_window->ModeManage();
p_intf->p_sys->b_playing = 0;
}
if( p_intf->b_die )
{
vlc_mutex_unlock( &p_intf->change_lock );
/* Prepare to die, young Skywalker */
p_intf->p_sys->p_window->ModalResult = mrOk;
/* Just in case */
return( FALSE );
}
vlc_mutex_unlock( &p_intf->change_lock );
return( TRUE );
}
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define MAX_LINES_TEXT N_("maximum number of lines in the log window")
#define MAX_LINES_LONGTEXT N_( \
"You can set the maximum number of lines that the log window will display."\
" Enter -1 if you want to keep all messages." )
vlc_module_begin();
add_category_hint( N_("Miscellaneous"), NULL );
add_integer( "intfwin-max-lines", 500, NULL, MAX_LINES_TEXT, MAX_LINES_LONGTEXT );
set_description( _("Native Windows interface module") );
set_capability( "interface", 100 );
set_callbacks( E_(Open), E_(Close) );
add_shortcut( "win" );
add_shortcut( "win32" );
vlc_module_end();
/*****************************************************************************
* win32.cpp : Win32 interface plugin for vlc
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
* $Id: win32.cpp,v 1.15 2003/02/12 02:11:58 ipkiss Exp $
*
* Authors: Olivier Teulire <ipkiss@via.ecp.fr>
*
* 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 <vcl.h>
#include <stdlib.h> /* malloc(), free() */
#include <errno.h> /* ENOMEM */
#include <string.h>
#include <vlc/vlc.h>
#include <vlc/intf.h>
#include "mainframe.h"
#include "menu.h"
#include "win32_common.h"
/*****************************************************************************
* Exported interface functions.
*****************************************************************************/
extern "C" __declspec(dllexport)
int __VLC_SYMBOL( vlc_entry ) ( module_t *p_module );
/*****************************************************************************
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
static void Run ( intf_thread_t * );
int Win32Manage( void *p_data );
/*****************************************************************************
* Open: initialize interface
*****************************************************************************/
static int Open ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
/* Allocate instance and initialize some members */
p_intf->p_sys = (intf_sys_t *) malloc( sizeof( intf_sys_t ) );
if( p_intf->p_sys == NULL )
{
msg_Err( p_intf, "out of memory" );
return( 1 );
};
p_intf->pf_run = Run;
p_intf->p_sys->p_sub = msg_Subscribe( p_intf );
/* Initialize Win32 thread */
p_intf->p_sys->b_playing = 0;
p_intf->p_sys->b_popup_changed = 0;
p_intf->p_sys->p_input = NULL;
p_intf->p_sys->i_playing = -1;
p_intf->p_sys->b_play_when_adding = VLC_TRUE;
p_intf->p_sys->b_slider_free = 1;
p_intf->p_sys->b_aout_update = VLC_FALSE;
p_intf->p_sys->b_vout_update = VLC_FALSE;
p_intf->p_sys->b_program_update = VLC_FALSE;
p_intf->p_sys->b_title_update = VLC_FALSE;
p_intf->p_sys->b_chapter_update = VLC_FALSE;
p_intf->p_sys->b_audio_update = VLC_FALSE;
p_intf->p_sys->b_spu_update = VLC_FALSE;
return( 0 );
}
/*****************************************************************************
* Close: destroy interface
*****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
intf_thread_t *p_intf = (intf_thread_t *)p_this;
if( p_intf->p_sys->p_input )
{
vlc_object_release( p_intf->p_sys->p_input );
}
msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
/* Destroy structure */
free( p_intf->p_sys );
}
/*****************************************************************************
* Run: main loop
*****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
p_intf->p_sys->p_window = new TMainFrameDlg( NULL, p_intf );
p_intf->p_sys->p_playwin = new TPlaylistDlg( NULL, p_intf );
p_intf->p_sys->p_messages = new TMessagesDlg( NULL, p_intf );
p_intf->p_sys->p_menus = new TMenusGen( p_intf );
/* show main window and wait until it is closed */
p_intf->p_sys->p_window->ShowModal();
if( p_intf->p_sys->p_disc ) delete p_intf->p_sys->p_disc;
if( p_intf->p_sys->p_network ) delete p_intf->p_sys->p_network;
if( p_intf->p_sys->p_preferences ) delete p_intf->p_sys->p_preferences;
delete p_intf->p_sys->p_menus;
delete p_intf->p_sys->p_messages;
delete p_intf->p_sys->p_playwin;
delete p_intf->p_sys->p_window;
}
/*****************************************************************************
* Win32Manage: manage main thread messages
*****************************************************************************
* In this function, called approx. 10 times a second, we check what the
* main program wanted to tell us.
*****************************************************************************/
int Win32Manage( intf_thread_t *p_intf )
{
vlc_mutex_lock( &p_intf->change_lock );
/* If the "display popup" flag has changed */
if( p_intf->b_menu_change )
{
/* FIXME: It would be nice to close the popup when the user left-clicks
elsewhere, or to actualize the position when he right-clicks again,
but i couldn't find a way to close it :-( */
TPoint MousePos = Mouse->CursorPos;
p_intf->p_sys->p_window->PopupMenuMain->Popup( MousePos.x, MousePos.y );
p_intf->b_menu_change = 0;
}
/* Update the log window */
p_intf->p_sys->p_messages->UpdateLog();
/* Update the playlist */
p_intf->p_sys->p_playwin->Manage();
/* Update the input */
if( p_intf->p_sys->p_input == NULL )
{
p_intf->p_sys->p_input = (input_thread_t *)
vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
}
else if( p_intf->p_sys->p_input->b_dead )
{
vlc_object_release( p_intf->p_sys->p_input );
p_intf->p_sys->p_input = NULL;
}
if( p_intf->p_sys->p_input != NULL && !p_intf->p_sys->p_input->b_die )
{
vlc_bool_t b_need_menus = VLC_FALSE;
input_thread_t * p_input = p_intf->p_sys->p_input;
vlc_object_t * p_aout = NULL;
vlc_object_t * p_vout = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
/* New input or stream map change */
if( p_input->stream.b_changed )
{
p_intf->p_sys->p_window->ModeManage();
b_need_menus = VLC_TRUE;
p_intf->p_sys->b_playing = 1;
}
/* Manage the slider */
if( p_input->stream.b_seekable && p_intf->p_sys->b_playing )
{
TTrackBar * TrackBar = p_intf->p_sys->p_window->TrackBar;
off_t NewValue = TrackBar->Position;
#define p_area p_input->stream.p_selected_area
/* If the user hasn't touched the slider since the last time,
* then the input can safely change it */
if( NewValue == p_intf->p_sys->OldValue )
{
/* Update the value */
TrackBar->Position = p_intf->p_sys->OldValue =
( (off_t)SLIDER_MAX_VALUE * p_area->i_tell ) /
p_area->i_size;
}
/* Otherwise, send message to the input if the user has
* finished dragging the slider */
else if( p_intf->p_sys->b_slider_free )
{
off_t i_seek = ( NewValue * p_area->i_size ) /
(off_t)SLIDER_MAX_VALUE;
/* release the lock to be able to seek */
vlc_mutex_unlock( &p_input->stream.stream_lock );
input_Seek( p_input, i_seek, INPUT_SEEK_SET );
vlc_mutex_lock( &p_input->stream.stream_lock );
/* Update the old value */
p_intf->p_sys->OldValue = NewValue;
}
# undef p_area
}
if( p_intf->p_sys->i_part != p_input->stream.p_selected_area->i_part )
{
p_intf->p_sys->b_chapter_update = 1;
b_need_menus = VLC_TRUE;
}
/* Does the audio output require to update the menus ? */
p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
vlc_value_t val;
if( var_Get( p_aout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_aout_update = 1;
b_need_menus = VLC_TRUE;
}
vlc_object_release( p_aout );
}
/* Does the video output require to update the menus ? */
p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
FIND_ANYWHERE );
if( p_vout != NULL )
{
vlc_value_t val;
if( var_Get( p_vout, "intf-change", &val ) >= 0
&& val.b_bool )
{
p_intf->p_sys->b_vout_update = 1;
b_need_menus = VLC_TRUE;
}
if( var_Get( p_vout, "directx-on-top", &val ) >= 0 )
{
p_intf->p_sys->p_window->MenuOnTop->Checked = val.b_bool;
p_intf->p_sys->p_window->PopupOnTop->Checked = val.b_bool;
}
vlc_object_release( p_vout );
}
if( b_need_menus )
{
p_intf->p_sys->p_menus->SetupMenus();
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
else if( p_intf->p_sys->b_playing && !p_intf->b_die )
{
p_intf->p_sys->p_window->ModeManage();
p_intf->p_sys->b_playing = 0;
}
if( p_intf->b_die )
{
vlc_mutex_unlock( &p_intf->change_lock );
/* Prepare to die, young Skywalker */
p_intf->p_sys->p_window->ModalResult = mrOk;
/* Just in case */
return( FALSE );
}
vlc_mutex_unlock( &p_intf->change_lock );
return( TRUE );
}
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define MAX_LINES_TEXT N_("maximum number of lines in the log window")
#define MAX_LINES_LONGTEXT N_( \
"You can set the maximum number of lines that the log window will display."\
" Enter -1 if you want to keep all messages." )
vlc_module_begin();
add_category_hint( N_("Miscellaneous"), NULL );
add_integer( "intfwin-max-lines", 500, NULL, MAX_LINES_TEXT, MAX_LINES_LONGTEXT );
set_description( _("Native Windows interface module") );
set_capability( "interface", 100 );
set_callbacks( E_(Open), E_(Close) );
add_shortcut( "win" );
add_shortcut( "win32" );
vlc_module_end();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment