-/*****************************************************************************
- * menu.cpp: functions to handle menu items
- *****************************************************************************
- * Copyright (C) 2002-2003 VideoLAN
- * $Id: menu.cpp,v 1.5 2003/01/16 09:02:46 sam Exp $
- *
- * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-#include <vcl.h>
-
-#include <vlc/vlc.h>
-#include <vlc/intf.h>
-
-#include "menu.h"
-#include "win32_common.h"
-
-/*****************************************************************************
- * TMenusGen::*Click: callbacks for the menuitems
- ****************************************************************************/
-
-/*
- * Variables
- */
-
-/* variables of the audio output */
-void __fastcall TMenusGen::AoutVarClick( TObject *Sender )
-{
- TMenuItem * Item = (TMenuItem *)Sender;
-
- vlc_object_t * p_aout;
- p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,
- FIND_ANYWHERE );
- if( p_aout == NULL )
- {
- msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
- return;
- }
-
- if( Item->Parent == MenuADevice || Item->Parent == PopupADevice )
- {
- VarChange( p_aout, "audio-device", MenuADevice, PopupADevice, Item );
- }
- else if( Item->Parent == MenuChannel || Item->Parent == PopupChannel )
- {
- VarChange( p_aout, "audio-channels", MenuChannel, PopupChannel, Item );
- }
-
- vlc_object_release( p_aout );
-}
-
-/* variables of the video output */
-void __fastcall TMenusGen::VoutVarClick( TObject *Sender )
-{
- TMenuItem * Item = (TMenuItem *)Sender;
-
- vlc_object_t * p_vout;
- p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
- FIND_ANYWHERE );
- if( p_vout == NULL )
- {
- msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );
- return;
- }
-
- if( Item->Parent == MenuVDevice || Item->Parent == PopupVDevice )
- {
- VarChange( p_vout, "video-device", MenuVDevice, PopupVDevice, Item );
- }
-
- vlc_object_release( p_vout );
-}
-
-/*
- * 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;
- int i_title = Item->Tag;
-
- input_ChangeArea( p_intf->p_sys->p_input,
- p_intf->p_sys->p_input->stream.pp_areas[i_title] );
- 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;
- int i_title;
- int i_chapter = Item->Tag;
-
- p_area = p_intf->p_sys->p_input->stream.p_selected_area;
- p_area->i_part = i_chapter;
-
- input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
-
- i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;
- ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );
- Index2Item( ItemTitle, i_chapter - 1, 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;
- int i_title = Data2Title( Item->Tag );
- int i_chapter = Data2Chapter( Item->Tag );
-
- p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];
- p_area->i_part = i_chapter;
-
- input_ChangeArea( p_intf->p_sys->p_input, (input_area_t*)p_area );
-
- Item->Checked = true;
- ItemTitle = Index2Item( MenuTitle, i_title - 1, false );
- if( ItemTitle->Checked )
- {
- /* same title, new chapter */
- Index2Item( MenuChapter, i_chapter - 1, 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;
-}
-
-
-/*****************************************************************************
- * 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 = 0;
- }
-
- if( p_intf->p_sys->b_title_update )
- {
-// why "-1" ?
- 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 = 0;
- }
-
- if( p_intf->p_sys->b_chapter_update )
- {
- RadioMenu( MenuChapter, "Chapter",
- p_input->stream.p_selected_area->i_part_nb,
- 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 = 0;
- }
-
- /* 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 = 0;
- }
-
- /* 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 = 0;
- }
-
- 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 = 0;
-
- 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 = 0;
- }
-
- 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 = 0;
-
- 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 = 0;
- }
-
- 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 ));
-}
-
-/****************************************************************************
- * 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;
-
- /* We must delete all the '&' characters in the caption string, because
- * Borland automatically adds one when (and only when!) you click on
- * the menuitem. Grrrrr... */
- AnsiString Caption = Item->Caption;
- while( Caption.LastDelimiter( "&" ) != 0 )
+/*****************************************************************************\r
+ * menu.cpp: functions to handle menu items\r
+ *****************************************************************************\r
+ * Copyright (C) 2002-2003 VideoLAN\r
+ * $Id: menu.cpp,v 1.15 2003/05/04 22:42:16 gbazin Exp $\r
+ *\r
+ * Authors: Olivier Teuliere <ipkiss@via.ecp.fr>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.\r
+ *****************************************************************************/\r
+\r
+#include <vcl.h>\r
+\r
+#include <vlc/vlc.h>\r
+#include <vlc/intf.h>\r
+\r
+#include "menu.h"\r
+#include "win32_common.h"\r
+\r
+/*****************************************************************************\r
+ * TMenusGen::*Click: callbacks for the menuitems\r
+ ****************************************************************************/\r
+\r
+/*\r
+ * Variables\r
+ */\r
+\r
+/* variables of the audio output */\r
+void __fastcall TMenusGen::AoutVarClick( TObject *Sender )\r
+{\r
+ TMenuItem * Item = (TMenuItem *)Sender;\r
+\r
+ vlc_object_t * p_aout;\r
+ p_aout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,\r
+ FIND_ANYWHERE );\r
+ if( p_aout == NULL )\r
+ {\r
+ msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );\r
+ return;\r
+ }\r
+\r
+#error fixme! look at rc.c line 823\r
+ if( Item->Parent == MenuADevice || Item->Parent == PopupADevice )\r
+ {\r
+ VarChange( p_aout, "audio-device", MenuADevice, PopupADevice, Item );\r
+ }\r
+ else if( Item->Parent == MenuChannel || Item->Parent == PopupChannel )\r
+ {\r
+ VarChange( p_aout, "audio-channels", MenuChannel, PopupChannel, Item );\r
+ }\r
+\r
+ vlc_object_release( p_aout );\r
+}\r
+\r
+/* variables of the video output */\r
+void __fastcall TMenusGen::VoutVarClick( TObject *Sender )\r
+{\r
+ TMenuItem * Item = (TMenuItem *)Sender;\r
+\r
+ vlc_object_t * p_vout;\r
+ p_vout = (vlc_object_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,\r
+ FIND_ANYWHERE );\r
+ if( p_vout == NULL )\r
+ {\r
+ msg_Warn( p_intf, "cannot set variable (%s)", Item->Caption.c_str() );\r
+ return;\r
+ }\r
+\r
+ if( Item->Parent == MenuVDevice || Item->Parent == PopupVDevice )\r
+ {\r
+ VarChange( p_vout, "video-device", MenuVDevice, PopupVDevice, Item );\r
+ }\r
+\r
+ vlc_object_release( p_vout );\r
+}\r
+\r
+/*\r
+ * Modules\r
+ */\r
+\r
+/* Interface modules: we spawn a new interface */\r
+void __fastcall TMenusGen::InterfaceModuleClick( TObject *Sender )\r
+{\r
+ TMenuItem * Item = (TMenuItem *)Sender;\r
+\r
+ AnsiString IntfName = CleanCaption( Item->Caption );\r
+\r
+ intf_thread_t *p_newintf;\r
+\r
+ p_newintf = intf_Create( p_intf->p_vlc, IntfName.c_str() );\r
+\r
+ if( p_newintf )\r
+ {\r
+ p_newintf->b_block = VLC_FALSE;\r
+ if( intf_RunThread( p_newintf ) )\r
+ {\r
+ vlc_object_detach( p_newintf );\r
+ intf_Destroy( p_newintf );\r
+ }\r
+ }\r
+}\r
+\r
+/*\r
+ * Audio\r
+ */\r
+\r
+void __fastcall TMenusGen::MenuLanguageClick( TObject *Sender )\r
+{\r
+ LangChange( MenuLanguage, (TMenuItem *)Sender, PopupLanguage, AUDIO_ES );\r
+}\r
+\r
+void __fastcall TMenusGen::PopupLanguageClick( TObject *Sender )\r
+{\r
+ LangChange( PopupLanguage, (TMenuItem *)Sender, MenuLanguage, AUDIO_ES );\r
+}\r
+\r
+/*\r
+ * Subtitles\r
+ */\r
+\r
+void __fastcall TMenusGen::MenuSubtitleClick( TObject *Sender )\r
+{\r
+ LangChange( MenuSubtitles, (TMenuItem *)Sender, PopupSubtitles, SPU_ES );\r
+}\r
+\r
+void __fastcall TMenusGen::PopupSubtitleClick( TObject *Sender )\r
+{\r
+ LangChange( PopupSubtitles, (TMenuItem *)Sender, MenuSubtitles, SPU_ES );\r
+}\r
+\r
+/*\r
+ * Program\r
+ */\r
+\r
+void __fastcall TMenusGen::MenuProgramClick( TObject *Sender )\r
+{\r
+ ProgramChange( (TMenuItem *)Sender, PopupProgram );\r
+}\r
+\r
+void __fastcall TMenusGen::PopupProgramClick( TObject *Sender )\r
+{\r
+ ProgramChange( (TMenuItem *)Sender, MenuProgram );\r
+}\r
+\r
+/*\r
+ * Title\r
+ */\r
+\r
+void __fastcall TMenusGen::MenuTitleClick( TObject *Sender )\r
+{\r
+ TMenuItem * Item = (TMenuItem *)Sender;\r
+ TMenuItem * ItemTitle;\r
+ input_area_t * p_area;\r
+ unsigned int i_title = Item->Tag;\r
+\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ i_title = __MIN( i_title,\r
+ p_intf->p_sys->p_input->stream.i_area_nb - 1 );\r
+ i_title = __MAX( i_title, 1 );\r
+ p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+\r
+ input_ChangeArea( p_intf->p_sys->p_input, p_area );\r
+\r
+ Item->Checked = true;\r
+ ItemTitle = Index2Item( PopupNavigation, i_title - 1, false );\r
+ Index2Item( ItemTitle, 0, false )->Checked = true;\r
+\r
+ input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
+}\r
+\r
+/*\r
+ * Chapter\r
+ */\r
+\r
+void __fastcall TMenusGen::MenuChapterClick( TObject *Sender )\r
+{\r
+ TMenuItem * Item = (TMenuItem *)Sender;\r
+ TMenuItem * ItemTitle;\r
+ input_area_t * p_area;\r
+ unsigned int i_title;\r
+ unsigned int i_chapter = Item->Tag;\r
+\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ p_area = p_intf->p_sys->p_input->stream.p_selected_area;\r
+ i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );\r
+ i_chapter = __MAX( i_chapter, 1 );\r
+ p_area->i_part = i_chapter;\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+\r
+ input_ChangeArea( p_intf->p_sys->p_input, p_area );\r
+\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ i_title = p_intf->p_sys->p_input->stream.p_selected_area->i_id;\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+\r
+ ItemTitle = Index2Item( PopupNavigation, i_title, false );\r
+ Index2Item( ItemTitle, i_chapter, false )->Checked = true;\r
+\r
+ input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
+}\r
+\r
+/*\r
+ * Navigation\r
+ */\r
+\r
+void __fastcall TMenusGen::PopupNavigationClick( TObject *Sender )\r
+{\r
+ TMenuItem * Item = (TMenuItem *)Sender;\r
+ TMenuItem * ItemTitle;\r
+ input_area_t * p_area;\r
+ unsigned int i_title = Data2Title( Item->Tag );\r
+ unsigned int i_chapter = Data2Chapter( Item->Tag );\r
+\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ i_title = __MIN( i_title,\r
+ p_intf->p_sys->p_input->stream.i_area_nb - 1 );\r
+ i_title = __MAX( i_title, 1 );\r
+ p_area = p_intf->p_sys->p_input->stream.pp_areas[i_title];\r
+ i_chapter = __MIN( i_chapter, p_area->i_part_nb - 1 );\r
+ i_chapter = __MAX( i_chapter, 1 );\r
+ p_area->i_part = i_chapter;\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+\r
+ input_ChangeArea( p_intf->p_sys->p_input, p_area );\r
+\r
+ Item->Checked = true;\r
+ ItemTitle = Index2Item( MenuTitle, i_title, false );\r
+ if( ItemTitle->Checked )\r
+ {\r
+ /* same title, new chapter */\r
+ Index2Item( MenuChapter, i_chapter, false )->Checked = true;\r
+ }\r
+ else\r
+ {\r
+ /* new title => we must rebuild the chapter menu */\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ RadioMenu(\r
+ MenuChapter, "Chapter",\r
+ p_intf->p_sys->p_input->stream.p_selected_area->i_part_nb,\r
+ i_chapter, MenuChapterClick );\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ }\r
+\r
+ input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
+}\r
+\r
+\r
+__fastcall TMenusGen::TMenusGen( intf_thread_t *_p_intf ) : TObject()\r
+{\r
+ p_intf = _p_intf;\r
+\r
+ /* Initialize local pointers to menu items of the main window */\r
+ TMainFrameDlg * p_window = p_intf->p_sys->p_window;\r
+ if( p_window == NULL )\r
+ {\r
+ msg_Warn( p_intf, "Main window wasn't created, expect problems..." );\r
+ return;\r
+ }\r
+\r
+ MenuChannel = p_window->MenuChannel;\r
+ PopupChannel = p_window->PopupChannel;\r
+ MenuADevice = p_window->MenuADevice;\r
+ PopupADevice = p_window->PopupADevice;\r
+ MenuVDevice = p_window->MenuVDevice;\r
+ PopupVDevice = p_window->PopupVDevice;\r
+ MenuLanguage = p_window->MenuLanguage;\r
+ PopupLanguage = p_window->PopupLanguage;\r
+ MenuSubtitles = p_window->MenuSubtitles;\r
+ PopupSubtitles = p_window->PopupSubtitles;\r
+ MenuProgram = p_window->MenuProgram;\r
+ PopupProgram = p_window->PopupProgram;\r
+ MenuTitle = p_window->MenuTitle;\r
+ MenuChapter = p_window->MenuChapter;\r
+ PopupNavigation = p_window->PopupNavigation;\r
+ MenuAddInterface = p_window->MenuAddInterface;\r
+\r
+ /* Create the "Add interface" menu */\r
+ SetupModuleMenu( "interface", MenuAddInterface, InterfaceModuleClick );\r
+}\r
+\r
+\r
+/*****************************************************************************\r
+ * SetupMenus: This function dynamically generates some menus\r
+ *****************************************************************************\r
+ * The lock on p_input->stream must be taken before you call this function\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::SetupMenus()\r
+{\r
+ TMainFrameDlg * p_window = p_intf->p_sys->p_window;\r
+ input_thread_t * p_input = p_intf->p_sys->p_input;\r
+ es_descriptor_t * p_audio_es;\r
+ es_descriptor_t * p_spu_es;\r
+\r
+ p_intf->p_sys->b_chapter_update |= p_intf->p_sys->b_title_update;\r
+ p_intf->p_sys->b_audio_update |= p_intf->p_sys->b_program_update |\r
+ p_intf->p_sys->b_title_update;\r
+ p_intf->p_sys->b_spu_update |= p_intf->p_sys->b_program_update |\r
+ p_intf->p_sys->b_title_update;\r
+\r
+ if( p_intf->p_sys->b_program_update )\r
+ {\r
+ pgrm_descriptor_t * p_pgrm;\r
+\r
+ if( p_input->stream.p_new_program )\r
+ {\r
+ p_pgrm = p_input->stream.p_new_program;\r
+ }\r
+ else\r
+ {\r
+ p_pgrm = p_input->stream.p_selected_program;\r
+ }\r
+\r
+ ProgramMenu( MenuProgram, p_pgrm, MenuProgramClick );\r
+ ProgramMenu( PopupProgram, p_pgrm, PopupProgramClick );\r
+\r
+ p_intf->p_sys->b_program_update = VLC_FALSE;\r
+ }\r
+\r
+ if( p_intf->p_sys->b_title_update )\r
+ {\r
+// why "-1" ?\r
+// because if the titles go from 1 to X-1, there are X-1 titles\r
+ RadioMenu( MenuTitle, "Title",\r
+ p_input->stream.i_area_nb - 1,\r
+ p_input->stream.p_selected_area->i_id,\r
+ MenuTitleClick );\r
+\r
+ AnsiString CurrentTitle;\r
+ CurrentTitle.sprintf( "%d", p_input->stream.p_selected_area->i_id );\r
+ p_window->LabelTitleCurrent->Caption = CurrentTitle;\r
+\r
+ p_intf->p_sys->b_title_update = VLC_FALSE;\r
+ }\r
+\r
+ if( p_intf->p_sys->b_chapter_update )\r
+ {\r
+ RadioMenu( MenuChapter, "Chapter",\r
+ p_input->stream.p_selected_area->i_part_nb - 1,\r
+ p_input->stream.p_selected_area->i_part,\r
+ MenuChapterClick );\r
+\r
+ NavigationMenu( PopupNavigation, PopupNavigationClick );\r
+\r
+ AnsiString CurrentChapter;\r
+ CurrentChapter.sprintf( "%d", p_input->stream.p_selected_area->i_part );\r
+ p_window->LabelChapterCurrent->Caption = CurrentChapter;\r
+\r
+ p_intf->p_sys->i_part = p_input->stream.p_selected_area->i_part;\r
+\r
+ p_intf->p_sys->b_chapter_update = VLC_FALSE;\r
+ }\r
+\r
+ /* look for selected ES */\r
+ p_audio_es = NULL;\r
+ p_spu_es = NULL;\r
+\r
+ for( unsigned int i = 0; i < p_input->stream.i_selected_es_number; i++ )\r
+ {\r
+ if( p_input->stream.pp_selected_es[i]->i_cat == AUDIO_ES )\r
+ {\r
+ p_audio_es = p_input->stream.pp_selected_es[i];\r
+ }\r
+\r
+ if( p_input->stream.pp_selected_es[i]->i_cat == SPU_ES )\r
+ {\r
+ p_spu_es = p_input->stream.pp_selected_es[i];\r
+ }\r
+ }\r
+ this->p_audio_es_old = p_audio_es;\r
+ this->p_spu_es_old = p_spu_es;\r
+\r
+ vlc_mutex_unlock( &p_input->stream.stream_lock );\r
+\r
+ /* audio menus */\r
+ if( p_intf->p_sys->b_audio_update )\r
+ {\r
+ LanguageMenu( MenuLanguage, p_audio_es, AUDIO_ES, MenuLanguageClick );\r
+ LanguageMenu( PopupLanguage, p_audio_es, AUDIO_ES, PopupLanguageClick );\r
+\r
+ p_intf->p_sys->b_audio_update = VLC_FALSE;\r
+ }\r
+\r
+ /* sub picture menus */\r
+ if( p_intf->p_sys->b_spu_update )\r
+ {\r
+ LanguageMenu( PopupSubtitles, p_spu_es, SPU_ES, PopupSubtitleClick );\r
+ LanguageMenu( MenuSubtitles, p_spu_es, SPU_ES, MenuSubtitleClick );\r
+\r
+ p_intf->p_sys->b_spu_update = VLC_FALSE;\r
+ }\r
+\r
+ if( p_intf->p_sys->b_aout_update )\r
+ {\r
+ aout_instance_t * p_aout;\r
+ p_aout = (aout_instance_t *)vlc_object_find( p_intf, VLC_OBJECT_AOUT,\r
+ FIND_ANYWHERE );\r
+\r
+ if( p_aout != NULL )\r
+ {\r
+ vlc_value_t val;\r
+ val.b_bool = VLC_FALSE;\r
+\r
+ var_Set( (vlc_object_t *)p_aout, "intf-change", val );\r
+\r
+#error fixme! look at rc.c line 823\r
+ SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",\r
+ MenuChannel, AoutVarClick );\r
+ SetupVarMenu( (vlc_object_t *)p_aout, "audio-channels",\r
+ PopupChannel, AoutVarClick );\r
+\r
+ SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",\r
+ MenuADevice, AoutVarClick );\r
+ SetupVarMenu( (vlc_object_t *)p_aout, "audio-device",\r
+ PopupADevice, AoutVarClick );\r
+\r
+ vlc_object_release( (vlc_object_t *)p_aout );\r
+ }\r
+\r
+ p_intf->p_sys->b_aout_update = VLC_FALSE;\r
+ }\r
+\r
+ if( p_intf->p_sys->b_vout_update )\r
+ {\r
+ vout_thread_t * p_vout;\r
+ p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,\r
+ FIND_ANYWHERE );\r
+\r
+ if( p_vout != NULL )\r
+ {\r
+ vlc_value_t val;\r
+ val.b_bool = VLC_FALSE;\r
+\r
+ var_Set( (vlc_object_t *)p_vout, "intf-change", val );\r
+\r
+ SetupVarMenu( (vlc_object_t *)p_vout, "video-device",\r
+ MenuVDevice, VoutVarClick );\r
+ SetupVarMenu( (vlc_object_t *)p_vout, "video-device",\r
+ PopupVDevice, VoutVarClick );\r
+\r
+ vlc_object_release( (vlc_object_t *)p_vout );\r
+ }\r
+\r
+ p_intf->p_sys->b_vout_update = VLC_FALSE;\r
+ }\r
+\r
+ vlc_mutex_lock( &p_input->stream.stream_lock );\r
+}\r
+\r
+\r
+/*****************************************************************************\r
+ * Private functions\r
+ *****************************************************************************/\r
+TMenuItem * TMenusGen::Index2Item( TMenuItem *Root, int i_index,\r
+ bool SingleColumn )\r
+{\r
+ if( SingleColumn || ( i_index < 20 ) )\r
+ return Root->Items[i_index];\r
+ else\r
+ return Root->Items[i_index / 10]->Items[i_index % 10];\r
+}\r
+\r
+int TMenusGen::Item2Index( TMenuItem *Root, TMenuItem *Item )\r
+{\r
+ if( Item->Parent == Root )\r
+ return Item->MenuIndex;\r
+ else\r
+ return( 10 * Item->Parent->MenuIndex + Item->MenuIndex );\r
+}\r
+\r
+int __fastcall TMenusGen::Data2Title( int data )\r
+{\r
+ return (int) (data >> 16 );\r
+}\r
+\r
+int __fastcall TMenusGen::Data2Chapter( int data )\r
+{\r
+ return (int) (data & 0xffff);\r
+}\r
+\r
+int __fastcall TMenusGen::Pos2Data( int title, int chapter )\r
+{\r
+ return (int) (( title << 16 ) | ( chapter & 0xffff ));\r
+}\r
+\r
+/* This function deletes all the '&' characters in the caption string,\r
+ * because Borland automatically adds one when (and only when!) you click on\r
+ * the menuitem. Grrrrr... */\r
+AnsiString __fastcall TMenusGen::CleanCaption( AnsiString Caption )\r
+{\r
+ while( Caption.LastDelimiter( "&" ) != 0 )\r
{\r
Caption.Delete( Caption.LastDelimiter( "&" ), 1 );\r
}\r
- 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 = 1;
- p_intf->p_sys->b_spu_update = 1;
- 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 = 0;
- p_intf->p_sys->b_spu_update = 0;
-
- 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 );
-}
-
-/*****************************************************************************
- * 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 = 0; i_item < i_nb; i_item++ )
- {
- /* we group titles/chapters in packets of ten for small screens */
- if( ( i_item % 10 == 0 ) && ( i_nb > 20 ) )
- {
- if( i_item != 0 )
- {
- Root->Add( ItemGroup );
- }
-
- Name.sprintf( "%ss %d to %d", ItemName, i_item + 1, i_item + 10 );
- 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 + 1 );
- 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 + 1;
-
- /* check the currently selected chapter */
- if( i_selected == i_item + 1 )
- {
- 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;
-
- /* 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 );
- {
- 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;
-
- /* loop on chapters */
- for( unsigned int i_chapter = 0; i_chapter < i_chapter_nb;
- i_chapter++ )
- {
- /* we group chapters in packets of ten for small screens */
- if( ( i_chapter % 10 == 0 ) && ( i_chapter_nb > 20 ) )
- {
- if( i_chapter != 0 )
- {
- TitleItem->Add( ChapterGroup );
- }
-
- Name.sprintf( "%d - %d", i_chapter + 1, i_chapter + 10 );
- ChapterGroup = new TMenuItem( TitleItem );
- ChapterGroup->RadioItem = true;
- ChapterGroup->Hint = Name;
- ChapterGroup->Caption = Name;
- }
-
- Name.sprintf( "Chapter %d", i_chapter + 1 );
-
- 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 + 1 );
-
-#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 + 1 ) )
- {
- 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;
-}
-
-
+\r
+ return Caption;\r
+}\r
+\r
+/****************************************************************************\r
+ * VarChange: change a variable in a vlc_object_t\r
+ ****************************************************************************\r
+ * Change the variable and update the menuitems.\r
+ ****************************************************************************/\r
+void __fastcall TMenusGen::VarChange( vlc_object_t *p_object,\r
+ const char *psz_variable, TMenuItem *RootMenu, TMenuItem *RootPopup,\r
+ TMenuItem *Item )\r
+{\r
+ vlc_value_t val;\r
+ int i_index;\r
+\r
+ AnsiString Caption = CleanCaption( Item->Caption );\r
+ val.psz_string = Caption.c_str();\r
+\r
+ /* set the new value */\r
+ if( var_Set( p_object, psz_variable, val ) < 0 )\r
+ {\r
+ msg_Warn( p_object, "cannot set variable (%s)", val.psz_string );\r
+ }\r
+\r
+ i_index = Item->MenuIndex;\r
+ RootMenu->Items[i_index]->Checked = true;\r
+ RootPopup->Items[i_index]->Checked = true;\r
+}\r
+\r
+/****************************************************************************\r
+ * LangChange: change audio or subtitles languages\r
+ ****************************************************************************\r
+ * Toggle the language, and update the selected menuitems.\r
+ ****************************************************************************/\r
+void __fastcall TMenusGen::LangChange( TMenuItem *RootCurrent, TMenuItem *Item,\r
+ TMenuItem *RootOther, int i_cat )\r
+{\r
+ es_descriptor_t * p_es;\r
+ es_descriptor_t * p_es_old;\r
+ int i_index;\r
+ int i_es;\r
+\r
+ /* find the selected ES */\r
+ i_es = Item->Tag;\r
+\r
+ /* find selected menu item */\r
+ i_index = Item2Index( RootCurrent, Item ) - 1;\r
+ if( i_index < 0 )\r
+ {\r
+ /* 'None' was selected */\r
+ p_es = NULL;\r
+ }\r
+ else\r
+ {\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ p_es = p_intf->p_sys->p_input->stream.pp_es[i_es];\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ }\r
+\r
+ /* find the current ES */\r
+ if( i_cat == AUDIO_ES )\r
+ {\r
+ p_es_old = this->p_audio_es_old;\r
+ this->p_audio_es_old = p_es;\r
+ }\r
+ else\r
+ {\r
+ p_es_old = this->p_spu_es_old;\r
+ this->p_spu_es_old = p_es;\r
+ }\r
+\r
+ /* exchange them */\r
+ input_ToggleES( p_intf->p_sys->p_input, p_es_old, false );\r
+ input_ToggleES( p_intf->p_sys->p_input, p_es, true );\r
+\r
+ Item->Checked = true;\r
+ Index2Item( RootOther, i_index + 1, true )->Checked = true;\r
+}\r
+\r
+/****************************************************************************\r
+ * ProgramChange: change the program\r
+ ****************************************************************************\r
+ * Toggle the program, and update the selected menuitems.\r
+ ****************************************************************************/\r
+void __fastcall TMenusGen::ProgramChange( TMenuItem *Item,\r
+ TMenuItem *RootOther )\r
+{\r
+ int i_program = Item->Tag;\r
+\r
+ /* toggle the program */\r
+ input_ChangeProgram( p_intf->p_sys->p_input, (uint16_t)i_program );\r
+\r
+ /* check selected menu items */\r
+ Item->Checked = true;\r
+ Index2Item( RootOther, i_program - 1, true )->Checked = true;\r
+\r
+ /* update audio/subtitles menus */\r
+ p_intf->p_sys->b_audio_update = VLC_TRUE;\r
+ p_intf->p_sys->b_spu_update = VLC_TRUE;\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ SetupMenus();\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+ p_intf->p_sys->b_audio_update = VLC_FALSE;\r
+ p_intf->p_sys->b_spu_update = VLC_FALSE;\r
+\r
+ input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY );\r
+}\r
+\r
+/*****************************************************************************\r
+ * SetupVarMenu: build a menu allowing to change a variable\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::SetupVarMenu( vlc_object_t *p_object,\r
+ const char *psz_variable, TMenuItem *Root, TNotifyEvent MenuItemClick )\r
+{\r
+ TMenuItem * Item;\r
+ vlc_value_t val;\r
+ char * psz_value = NULL;\r
+ int i;\r
+\r
+ /* remove previous menu */\r
+ Root->Clear();\r
+\r
+ /* get the current value */\r
+ if( var_Get( p_object, psz_variable, &val ) < 0 )\r
+ {\r
+ return;\r
+ }\r
+ psz_value = val.psz_string;\r
+\r
+ if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST, &val, NULL ) < 0 )\r
+ {\r
+ free( psz_value );\r
+ return;\r
+ }\r
+\r
+ /* append a menuitem for each option */\r
+ for( i = 0; i < val.p_list->i_count; i++ )\r
+ {\r
+ Item = new TMenuItem( Root );\r
+ Item->Caption = val.p_list->p_values[i].psz_string;\r
+ Item->Hint = val.p_list->p_values[i].psz_string;\r
+ Item->RadioItem = true;\r
+ Item->OnClick = MenuItemClick;\r
+ if( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )\r
+ Item->Checked = true;\r
+\r
+ /* Add the item to the submenu */\r
+ Root->Add( Item );\r
+ }\r
+\r
+ /* enable the menu if there is at least 1 item */\r
+ Root->Enabled = ( val.p_list->i_count > 0 );\r
+\r
+ /* clean up everything */\r
+ var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val, NULL );\r
+// free( psz_value );\r
+}\r
+\r
+/*****************************************************************************\r
+ * SetupModuleMenu: build a menu listing all the modules of a given\r
+ capability\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::SetupModuleMenu( const char *psz_capability,\r
+ TMenuItem *Root, TNotifyEvent MenuItemClick )\r
+{\r
+ module_t * p_parser;\r
+ vlc_list_t *p_list;\r
+ int i_index;\r
+\r
+ /* remove previous menu */\r
+ Root->Clear();\r
+ Root->Enabled = false;\r
+\r
+ p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );\r
+ for( i_index = 0; i_index < p_list->i_count; i_index++ )\r
+ {\r
+ p_parser = (module_t *)p_list->p_values[i_index].p_object ;\r
+\r
+ if( !strcmp( p_parser->psz_capability, psz_capability ) )\r
+ {\r
+ TMenuItem *Item = new TMenuItem( Root );\r
+ Item->Caption = p_parser->psz_object_name;\r
+ Item->Hint = Item->Caption;\r
+ Item->OnClick = MenuItemClick;\r
+ Root->Add( Item );\r
+ }\r
+ }\r
+\r
+ vlc_list_release( p_list );\r
+\r
+ /* be sure that menu is enabled, if there is at least one item */\r
+ if( i_index > 0 )\r
+ Root->Enabled = true;\r
+}\r
+\r
+/*****************************************************************************\r
+ * ProgramMenu: update the programs menu of the interface\r
+ *****************************************************************************\r
+ * Builds the program menu according to what have been found in the PAT\r
+ * by the input. Useful for multi-programs streams such as DVB ones.\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::ProgramMenu( TMenuItem *Root,\r
+ pgrm_descriptor_t *p_pgrm, TNotifyEvent MenuItemClick )\r
+{\r
+ TMenuItem * Item;\r
+\r
+ /* remove previous menu */\r
+ Root->Clear();\r
+ Root->Enabled = false;\r
+\r
+ /* create a set of program buttons and append them to the container */\r
+ for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_pgrm_number;\r
+ i++ )\r
+ {\r
+ AnsiString Name;\r
+ Name.sprintf( "id %d",\r
+ p_intf->p_sys->p_input->stream.pp_programs[i]->i_number );\r
+\r
+ Item = new TMenuItem( Root );\r
+ Item->Caption = Name;\r
+ Item->Hint = Name;\r
+ Item->RadioItem = true;\r
+ Item->OnClick = MenuItemClick;\r
+\r
+ /* FIXME: temporary hack to save the program id with the Item\r
+ * It will be used in the callback. */\r
+ Item->Tag = i + 1;\r
+\r
+ /* check the currently selected program */\r
+ if( p_pgrm == p_intf->p_sys->p_input->stream.pp_programs[i] )\r
+ Item->Checked = true;\r
+\r
+ /* add the item to the submenu */\r
+ Root->Add( Item );\r
+ }\r
+\r
+ /* be sure that menu is enabled if more than 1 program */\r
+ if( p_intf->p_sys->p_input->stream.i_pgrm_number > 1 )\r
+ Root->Enabled = true;\r
+}\r
+\r
+/*****************************************************************************\r
+ * RadioMenu: update interactive menus of the interface\r
+ *****************************************************************************\r
+ * Sets up menus with information from input\r
+ * Warning: since this function is designed to be called by management\r
+ * function, the interface lock has to be taken\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::RadioMenu( TMenuItem *Root, AnsiString ItemName,\r
+ int i_nb, int i_selected, TNotifyEvent MenuItemClick )\r
+{\r
+ TMenuItem * ItemGroup;\r
+ TMenuItem * Item;\r
+ AnsiString Name;\r
+\r
+ /* remove previous menu */\r
+ Root->Enabled = false;\r
+ Root->Clear();\r
+\r
+ for( int i_item = 1; i_item <= i_nb; i_item++ )\r
+ {\r
+ /* we group titles/chapters in packets of ten for small screens */\r
+ if( ( i_item % 10 == 1 ) && ( i_nb > 20 ) )\r
+ {\r
+ if( i_item != 1 )\r
+ Root->Add( ItemGroup );\r
+\r
+ Name.sprintf( "%ss %d to %d", ItemName, i_item, i_item + 9 );\r
+ ItemGroup = new TMenuItem( Root );\r
+ ItemGroup->Hint = Name;\r
+ ItemGroup->RadioItem = true;\r
+\r
+ /* set the accelerator character */\r
+ Name.Insert( "&", Name.Length() - 1 );\r
+ ItemGroup->Caption = Name;\r
+ }\r
+\r
+ Name.sprintf( "%s %d", ItemName, i_item );\r
+ Item = new TMenuItem( Root );\r
+ Item->RadioItem = true;\r
+ Item->Hint = Name;\r
+\r
+ /* set the accelerator character */\r
+ Name.Insert( "&", Name.Length() );\r
+ Item->Caption = Name;\r
+\r
+ /* FIXME: temporary hack to save i_item with the Item\r
+ * It will be used in the callback. */\r
+ Item->Tag = i_item;\r
+\r
+ /* check the currently selected chapter */\r
+ if( i_selected == i_item )\r
+ Item->Checked = true;\r
+\r
+ /* setup signal handling */\r
+ Item->OnClick = MenuItemClick;\r
+\r
+ if( i_nb > 20 )\r
+ ItemGroup->Add( Item );\r
+ else\r
+ Root->Add( Item );\r
+ }\r
+\r
+// if( ( i_nb > 20 ) && ( i_item % 10 ) ) ?\r
+ if( i_nb > 20 )\r
+ Root->Add( ItemGroup );\r
+\r
+ /* be sure that menu is enabled, if there are several items */\r
+ if( i_nb > 1 )\r
+ Root->Enabled = true;\r
+}\r
+\r
+/*****************************************************************************\r
+ * LanguageMenus: update interactive menus of the interface\r
+ *****************************************************************************\r
+ * Sets up menus with information from input:\r
+ * - languages\r
+ * - sub-pictures\r
+ * Warning: since this function is designed to be called by management\r
+ * function, the interface lock has to be taken\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::LanguageMenu( TMenuItem *Root, es_descriptor_t *p_es,\r
+ int i_cat, TNotifyEvent MenuItemClick )\r
+{\r
+ TMenuItem * Separator;\r
+ TMenuItem * Item;\r
+ AnsiString Name;\r
+\r
+ /* remove previous menu */\r
+ Root->Clear();\r
+ Root->Enabled = false;\r
+\r
+ /* special case for "off" item */\r
+ Name = "None";\r
+ Item = new TMenuItem( Root );\r
+ Item->RadioItem = true;\r
+ Item->Hint = Name;\r
+ Item->Caption = Name;\r
+ Item->OnClick = MenuItemClick;\r
+ Item->Tag = -1;\r
+ Root->Add( Item );\r
+\r
+ /* separator item */\r
+ Separator = new TMenuItem( Root );\r
+ Separator->Caption = "-";\r
+ Root->Add( Separator );\r
+\r
+ int i_item = 0;\r
+\r
+ vlc_mutex_lock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+\r
+#define ES p_intf->p_sys->p_input->stream.pp_es[i]\r
+ /* create a set of language buttons and append them to the Root */\r
+ for( unsigned int i = 0; i < p_intf->p_sys->p_input->stream.i_es_number;\r
+ i++ )\r
+ {\r
+ if( ( ES->i_cat == i_cat ) &&\r
+ ( !ES->p_pgrm ||\r
+ ES->p_pgrm ==\r
+ p_intf->p_sys->p_input->stream.p_selected_program ) )\r
+ {\r
+ i_item++;\r
+ Name = p_intf->p_sys->p_input->stream.pp_es[i]->psz_desc;\r
+ if( Name.IsEmpty() )\r
+ Name.sprintf( "Language %d", i_item );\r
+\r
+ Item = new TMenuItem( Root );\r
+ Item->RadioItem = true;\r
+ Item->Hint = Name;\r
+ Item->Caption = Name;\r
+ Item->Tag = i;\r
+\r
+ /* check the currently selected item */\r
+ if( p_es == p_intf->p_sys->p_input->stream.pp_es[i] )\r
+ Item->Checked = true;\r
+\r
+ /* setup signal hanling */\r
+ Item->OnClick = MenuItemClick;\r
+ Root->Add( Item );\r
+ }\r
+ }\r
+#undef ES\r
+\r
+ vlc_mutex_unlock( &p_intf->p_sys->p_input->stream.stream_lock );\r
+\r
+ /* be sure that menu is enabled if non empty */\r
+ if( i_item > 0 )\r
+ Root->Enabled = true;\r
+}\r
+\r
+/*****************************************************************************\r
+ * NavigationMenu: sets menus for titles and chapters selection\r
+ *****************************************************************************\r
+ * Generates two types of menus:\r
+ * -simple list of titles\r
+ * -cascaded lists of chapters for each title\r
+ *****************************************************************************/\r
+void __fastcall TMenusGen::NavigationMenu( TMenuItem *Root,\r
+ TNotifyEvent MenuItemClick )\r
+{\r
+ TMenuItem * TitleGroup;\r
+ TMenuItem * TitleItem;\r
+ TMenuItem * ChapterGroup;\r
+ TMenuItem * ChapterItem;\r
+ AnsiString Name;\r
+ unsigned int i_title_nb;\r
+ unsigned int i_chapter_nb;\r
+\r
+\r
+ /* remove previous menu */\r
+ Root->Enabled = false;\r
+ Root->Clear();\r
+\r
+ i_title_nb = p_intf->p_sys->p_input->stream.i_area_nb - 1;\r
+\r
+ /* loop on titles */\r
+ for( unsigned int i_title = 1; i_title <= i_title_nb; i_title++ )\r
+ {\r
+ /* we group titles in packets of ten for small screens */\r
+ if( ( i_title % 10 == 1 ) && ( i_title_nb > 20 ) )\r
+ {\r
+ if( i_title != 1 )\r
+ Root->Add( TitleGroup );\r
+\r
+ Name.sprintf( "%d - %d", i_title, i_title + 9 );\r
+ TitleGroup = new TMenuItem( Root );\r
+ TitleGroup->RadioItem = true;\r
+ TitleGroup->Hint = Name;\r
+ TitleGroup->Caption = Name;\r
+ }\r
+\r
+ Name.sprintf( "Title %d (%d)", i_title,\r
+ p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1 );\r
+ {\r
+ TitleItem = new TMenuItem( Root );\r
+ TitleItem->RadioItem = true;\r
+ TitleItem->Hint = Name;\r
+ TitleItem->Caption = Name;\r
+\r
+ i_chapter_nb =\r
+ p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb - 1;\r
+\r
+ /* loop on chapters */\r
+ for( unsigned int i_chapter = 1; i_chapter <= i_chapter_nb;\r
+ i_chapter++ )\r
+ {\r
+ /* we group chapters in packets of ten for small screens */\r
+ if( ( i_chapter % 10 == 1 ) && ( i_chapter_nb > 20 ) )\r
+ {\r
+ if( i_chapter != 1 )\r
+ TitleItem->Add( ChapterGroup );\r
+\r
+ Name.sprintf( "%d - %d", i_chapter, i_chapter + 9 );\r
+ ChapterGroup = new TMenuItem( TitleItem );\r
+ ChapterGroup->RadioItem = true;\r
+ ChapterGroup->Hint = Name;\r
+ ChapterGroup->Caption = Name;\r
+ }\r
+\r
+ Name.sprintf( "Chapter %d", i_chapter );\r
+\r
+ ChapterItem = new TMenuItem( TitleItem );\r
+ ChapterItem->RadioItem = true;\r
+ ChapterItem->Hint = Name;\r
+ ChapterItem->Caption = Name;\r
+\r
+ /* FIXME: temporary hack to save i_title and i_chapter with\r
+ * ChapterItem, since we will need them in the callback */\r
+ ChapterItem->Tag = Pos2Data( i_title, i_chapter );\r
+\r
+#define p_area p_intf->p_sys->p_input->stream.pp_areas[i_title]\r
+ /* check the currently selected chapter */\r
+ if( ( p_area ==\r
+ p_intf->p_sys->p_input->stream.p_selected_area ) &&\r
+ ( p_area->i_part == i_chapter ) )\r
+ {\r
+ ChapterItem->Checked = true;\r
+ }\r
+#undef p_area\r
+\r
+ /* setup signal handling */\r
+ ChapterItem->OnClick = MenuItemClick;\r
+\r
+ if( i_chapter_nb > 20 )\r
+ ChapterGroup->Add( ChapterItem );\r
+ else\r
+ TitleItem->Add( ChapterItem );\r
+ }\r
+\r
+ if( i_chapter_nb > 20 )\r
+ {\r
+ TitleItem->Add( ChapterGroup );\r
+ }\r
+\r
+ if( p_intf->p_sys->p_input->stream.pp_areas[i_title]->i_part_nb\r
+ > 1 )\r
+ {\r
+ /* be sure that menu is sensitive */\r
+ Root->Enabled = true;\r
+ }\r
+ }\r
+\r
+ if( i_title_nb > 20 )\r
+ TitleGroup->Add( TitleItem );\r
+ else\r
+ Root->Add( TitleItem );\r
+ }\r
+\r
+ if( i_title_nb > 20 )\r
+ Root->Add( TitleGroup );\r
+\r
+ /* be sure that menu is sensitive */\r
+ Root->Enabled = true;\r
+}\r
+\r