From: Olivier Teulière Date: Wed, 12 Feb 2003 02:11:58 +0000 (+0000) Subject: * compilation fix X-Git-Tag: 0.5.1~51 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0562366c67d03fc8fb9cb2f0866c79513a4e6aa9;p=vlc * compilation fix * all files are stored in dos mode, or Borland won't compile some of them... --- diff --git a/modules/gui/win32/about.cpp b/modules/gui/win32/about.cpp index 03fc28751c..d73dd1985f 100644 --- a/modules/gui/win32/about.cpp +++ b/modules/gui/win32/about.cpp @@ -1,47 +1,47 @@ -/***************************************************************************** - * about.cpp: The "About" dialog box - ***************************************************************************** - * Copyright (C) 2002 VideoLAN - * - * Authors: Olivier Teuliere - * - * 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 -#pragma hdrstop - -#include -#include - -#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 + * + * 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 +#pragma hdrstop + +#include +#include + +#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 ); +} +//--------------------------------------------------------------------------- + diff --git a/modules/gui/win32/mainframe.cpp b/modules/gui/win32/mainframe.cpp index ef3b286219..4e841dd8b2 100644 --- a/modules/gui/win32/mainframe.cpp +++ b/modules/gui/win32/mainframe.cpp @@ -1,722 +1,728 @@ -/***************************************************************************** - * mainframe.cpp: Win32 interface plugin for vlc - ***************************************************************************** - * Copyright (C) 2002 VideoLAN - * - * Authors: Olivier Teulière - * - * 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 -#pragma hdrstop - -#include -#include -#include - -#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 Teulière + * + * 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 +#pragma hdrstop + +#include +#include +#include +#include + +#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(); +} +//--------------------------------------------------------------------------- + + diff --git a/modules/gui/win32/menu.cpp b/modules/gui/win32/menu.cpp index 8edd1d5963..ec132b963a 100644 --- a/modules/gui/win32/menu.cpp +++ b/modules/gui/win32/menu.cpp @@ -1,1020 +1,1020 @@ -/***************************************************************************** - * 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 - * - * 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 - -#include -#include - -#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 + * + * 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 + +#include +#include + +#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; +} + diff --git a/modules/gui/win32/menu.h b/modules/gui/win32/menu.h index 3ba58e7fae..4757d1a036 100644 --- a/modules/gui/win32/menu.h +++ b/modules/gui/win32/menu.h @@ -1,98 +1,98 @@ -/***************************************************************************** - * 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 - * - * 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 + * + * 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 diff --git a/modules/gui/win32/sout.h b/modules/gui/win32/sout.h index a4037fd358..cd8155c307 100644 --- a/modules/gui/win32/sout.h +++ b/modules/gui/win32/sout.h @@ -1,69 +1,69 @@ -/***************************************************************************** - * 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 - * - * 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 -#include -#include -#include -#include -#include "CSPIN.h" -#include -#include -//--------------------------------------------------------------------------- -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 + * + * 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 +#include +#include +#include +#include +#include "CSPIN.h" +#include +#include +//--------------------------------------------------------------------------- +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 diff --git a/modules/gui/win32/subtitles.cpp b/modules/gui/win32/subtitles.cpp index 69815e037c..6197d879b1 100644 --- a/modules/gui/win32/subtitles.cpp +++ b/modules/gui/win32/subtitles.cpp @@ -1,65 +1,65 @@ -/***************************************************************************** - * 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 - * - * 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 -#pragma hdrstop - -#include -#include - -#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 + * + * 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 +#pragma hdrstop + +#include +#include + +#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 ); +} +//--------------------------------------------------------------------------- + diff --git a/modules/gui/win32/subtitles.h b/modules/gui/win32/subtitles.h index 5d1368b207..bb4e369d1c 100644 --- a/modules/gui/win32/subtitles.h +++ b/modules/gui/win32/subtitles.h @@ -1,55 +1,55 @@ -/***************************************************************************** - * 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 - * - * 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 -#include -#include -#include -#include -#include -//--------------------------------------------------------------------------- -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 + * + * 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 +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +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 diff --git a/modules/gui/win32/win32.bpf b/modules/gui/win32/win32.bpf index c961f06c2b..7738c64e15 100644 --- a/modules/gui/win32/win32.bpf +++ b/modules/gui/win32/win32.bpf @@ -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 diff --git a/modules/gui/win32/win32.cpp b/modules/gui/win32/win32.cpp index ccf337f79f..2633aa9f5e 100644 --- a/modules/gui/win32/win32.cpp +++ b/modules/gui/win32/win32.cpp @@ -1,315 +1,315 @@ -/***************************************************************************** - * 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 Teulière - * - * 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 -#include /* malloc(), free() */ -#include /* ENOMEM */ -#include - -#include -#include - -#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 Teulière + * + * 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 +#include /* malloc(), free() */ +#include /* ENOMEM */ +#include + +#include +#include + +#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();