InterfaceWindow.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:46k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * InterfaceWindow.cpp: beos interface
  3.  *****************************************************************************
  4.  * Copyright (C) 1999, 2000, 2001 the VideoLAN team
  5.  * $Id: 12220de4dda95bb26fb7e1f04ad39889cbc1f322 $
  6.  *
  7.  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  8.  *          Samuel Hocevar <sam@zoy.org>
  9.  *          Tony Castley <tony@castley.net>
  10.  *          Richard Shepherd <richard@rshepherd.demon.co.uk>
  11.  *          Stephan Aßmus <superstippi@gmx.de>
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  *****************************************************************************/
  27. /* System headers */
  28. #include <kernel/OS.h>
  29. #include <InterfaceKit.h>
  30. #include <AppKit.h>
  31. #include <StorageKit.h>
  32. #include <SupportKit.h>
  33. #include <malloc.h>
  34. #include <scsi.h>
  35. #include <scsiprobe_driver.h>
  36. #include <fs_info.h>
  37. /* VLC headers */
  38. #ifdef HAVE_CONFIG_H
  39. # include "config.h"
  40. #endif
  41. #include <vlc_common.h>
  42. #include <vlc_aout.h>
  43. #include <vlc_interface.h>
  44. /* BeOS interface headers */
  45. #include "MsgVals.h"
  46. #include "MediaControlView.h"
  47. #include "PlayListWindow.h"
  48. #include "PreferencesWindow.h"
  49. #include "MessagesWindow.h"
  50. #include "InterfaceWindow.h"
  51. #define INTERFACE_UPDATE_TIMEOUT  80000 // 2 frames if at 25 fps
  52. #define INTERFACE_LOCKING_TIMEOUT 5000
  53. // make_sure_frame_is_on_screen
  54. bool
  55. make_sure_frame_is_on_screen( BRect& frame )
  56. {
  57.     BScreen screen( B_MAIN_SCREEN_ID );
  58.     if (frame.IsValid() && screen.IsValid()) {
  59.         if (!screen.Frame().Contains(frame)) {
  60.             // make sure frame fits in the screen
  61.             if (frame.Width() > screen.Frame().Width())
  62.                 frame.right -= frame.Width() - screen.Frame().Width() + 10.0;
  63.             if (frame.Height() > screen.Frame().Height())
  64.                 frame.bottom -= frame.Height() - screen.Frame().Height() + 30.0;
  65.             // frame is now at the most the size of the screen
  66.             if (frame.right > screen.Frame().right)
  67.                 frame.OffsetBy(-(frame.right - screen.Frame().right), 0.0);
  68.             if (frame.bottom > screen.Frame().bottom)
  69.                 frame.OffsetBy(0.0, -(frame.bottom - screen.Frame().bottom));
  70.             if (frame.left < screen.Frame().left)
  71.                 frame.OffsetBy((screen.Frame().left - frame.left), 0.0);
  72.             if (frame.top < screen.Frame().top)
  73.                 frame.OffsetBy(0.0, (screen.Frame().top - frame.top));
  74.         }
  75.         return true;
  76.     }
  77.     return false;
  78. }
  79. // make_sure_frame_is_within_limits
  80. void
  81. make_sure_frame_is_within_limits( BRect& frame, float minWidth, float minHeight,
  82.                                   float maxWidth, float maxHeight )
  83. {
  84.     if ( frame.Width() < minWidth )
  85.         frame.right = frame.left + minWidth;
  86.     if ( frame.Height() < minHeight )
  87.         frame.bottom = frame.top + minHeight;
  88.     if ( frame.Width() > maxWidth )
  89.         frame.right = frame.left + maxWidth;
  90.     if ( frame.Height() > maxHeight )
  91.         frame.bottom = frame.top + maxHeight;
  92. }
  93. // get_volume_info
  94. bool
  95. get_volume_info( BVolume& volume, BString& volumeName, bool& isCDROM, BString& deviceName )
  96. {
  97.     bool success = false;
  98.     isCDROM = false;
  99.     deviceName = "";
  100.     volumeName = "";
  101.     char name[B_FILE_NAME_LENGTH];
  102.     if ( volume.GetName( name ) >= B_OK )    // disk is currently mounted
  103.     {
  104.         volumeName = name;
  105.         dev_t dev = volume.Device();
  106.         fs_info info;
  107.         if ( fs_stat_dev( dev, &info ) == B_OK )
  108.         {
  109.             success = true;
  110.             deviceName = info.device_name;
  111.             if ( volume.IsReadOnly() )
  112.             {
  113.                 int i_dev = open( info.device_name, O_RDONLY );
  114.                 if ( i_dev >= 0 )
  115.                 {
  116.                     device_geometry g;
  117.                     if ( ioctl( i_dev, B_GET_GEOMETRY, &g, sizeof( g ) ) >= 0 )
  118.                         isCDROM = ( g.device_type == B_CD );
  119.                     close( i_dev );
  120.                 }
  121.             }
  122.         }
  123.      }
  124.      return success;
  125. }
  126. // collect_folder_contents
  127. void
  128. collect_folder_contents( BDirectory& dir, BList& list, bool& deep, bool& asked, BEntry& entry )
  129. {
  130.     while ( dir.GetNextEntry( &entry, true ) == B_OK )
  131.     {
  132.         if ( !entry.IsDirectory() )
  133.         {
  134.             BPath path;
  135.             // since the directory will give us the entries in reverse order,
  136.             // we put them each at the same index, effectively reversing the
  137.             // items while adding them
  138.             if ( entry.GetPath( &path ) == B_OK )
  139.             {
  140.                 BString* string = new BString( path.Path() );
  141.                 if ( !list.AddItem( string, 0 ) )
  142.                     delete string;    // at least don't leak
  143.             }
  144.         }
  145.         else
  146.         {
  147.             if ( !asked )
  148.             {
  149.                 // ask user if we should parse sub-folders as well
  150.                 BAlert* alert = new BAlert( "sub-folders?",
  151.                                             _("Open files from all sub-folders as well?"),
  152.                                             _("Cancel"), _("Open"), NULL, B_WIDTH_AS_USUAL,
  153.                                             B_IDEA_ALERT );
  154.                 int32 buttonIndex = alert->Go();
  155.                 deep = buttonIndex == 1;
  156.                 asked = true;
  157.                 // never delete BAlerts!!
  158.             }
  159.             if ( deep )
  160.             {
  161.                 BDirectory subDir( &entry );
  162.                 if ( subDir.InitCheck() == B_OK )
  163.                     collect_folder_contents( subDir, list,
  164.                                              deep, asked, entry );
  165.             }
  166.         }
  167.     }
  168. }
  169. static int PlaylistChanged( vlc_object_t *p_this, const char * psz_variable,
  170.                             vlc_value_t old_val, vlc_value_t new_val,
  171.                             void * param )
  172. {
  173.     InterfaceWindow * w = (InterfaceWindow *) param;
  174.     w->UpdatePlaylist();
  175.     return VLC_SUCCESS;
  176. }
  177. /*****************************************************************************
  178.  * InterfaceWindow
  179.  *****************************************************************************/
  180. InterfaceWindow::InterfaceWindow( intf_thread_t * _p_intf, BRect frame,
  181.                                   const char * name )
  182.     : BWindow( frame, name, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
  183.                B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS ),
  184.       /* Initializations */
  185.       p_intf( _p_intf ),
  186.       p_input( NULL ),
  187.       p_playlist( NULL ),
  188.       fFilePanel( NULL ),
  189.       fLastUpdateTime( system_time() ),
  190.       fSettings( new BMessage( 'sett' ) )
  191. {
  192.     p_playlist = pl_Hold( p_intf );
  193.     var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
  194.     var_AddCallback( p_playlist, "item-change", PlaylistChanged, this );
  195.     var_AddCallback( p_playlist, "playlist-item-append", PlaylistChanged, this );
  196.     var_AddCallback( p_playlist, "playlist-item-deleted", PlaylistChanged, this );
  197.     var_AddCallback( p_playlist, "item-current", PlaylistChanged, this );
  198.     char psz_tmp[1024];
  199. #define ADD_ELLIPSIS( a ) 
  200.     memset( psz_tmp, 0, 1024 ); 
  201.     snprintf( psz_tmp, 1024, "%s%s", a, B_UTF8_ELLIPSIS );
  202.     BScreen screen;
  203.     BRect screen_rect = screen.Frame();
  204.     BRect window_rect;
  205.     window_rect.Set( ( screen_rect.right - PREFS_WINDOW_WIDTH ) / 2,
  206.                      ( screen_rect.bottom - PREFS_WINDOW_HEIGHT ) / 2,
  207.                      ( screen_rect.right + PREFS_WINDOW_WIDTH ) / 2,
  208.                      ( screen_rect.bottom + PREFS_WINDOW_HEIGHT ) / 2 );
  209.     fPreferencesWindow = new PreferencesWindow( p_intf, window_rect, _("Preferences") );
  210.     window_rect.Set( screen_rect.right - 500,
  211.                      screen_rect.top + 50,
  212.                      screen_rect.right - 150,
  213.                      screen_rect.top + 250 );
  214. #if 0
  215.     fPlaylistWindow = new PlayListWindow( window_rect, _("Playlist"), this, p_intf );
  216.     window_rect.Set( screen_rect.right - 550,
  217.                      screen_rect.top + 300,
  218.                      screen_rect.right - 150,
  219.                      screen_rect.top + 500 );
  220. #endif
  221.     fMessagesWindow = new MessagesWindow( p_intf, window_rect, _("Messages") );
  222.     // the media control view
  223.     p_mediaControl = new MediaControlView( p_intf, BRect( 0.0, 0.0, 250.0, 50.0 ) );
  224.     p_mediaControl->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
  225.     float width, height;
  226.     p_mediaControl->GetPreferredSize( &width, &height );
  227.     // set up the main menu
  228.     fMenuBar = new BMenuBar( BRect(0.0, 0.0, width, 15.0), "main menu",
  229.                              B_FOLLOW_NONE, B_ITEMS_IN_ROW, false );
  230.     // make menu bar resize to correct height
  231.     float menuWidth, menuHeight;
  232.     fMenuBar->GetPreferredSize( &menuWidth, &menuHeight );
  233.     fMenuBar->ResizeTo( width, menuHeight );    // don't change! it's a workarround!
  234.     // take care of proper size for ourself
  235.     height += fMenuBar->Bounds().Height();
  236.     ResizeTo( width, height );
  237.     p_mediaControl->MoveTo( fMenuBar->Bounds().LeftBottom() + BPoint(0.0, 1.0) );
  238.     AddChild( fMenuBar );
  239.     // Add the file Menu
  240.     BMenu* fileMenu = new BMenu( _("File") );
  241.     fMenuBar->AddItem( fileMenu );
  242.     ADD_ELLIPSIS( _("Open File") );
  243.     fileMenu->AddItem( new BMenuItem( psz_tmp, new BMessage( OPEN_FILE ), 'O') );
  244.     fileMenu->AddItem( new CDMenu( _("Open Disc") ) );
  245.     ADD_ELLIPSIS( _("Open Subtitles") );
  246.     fileMenu->AddItem( new BMenuItem( psz_tmp, new BMessage( LOAD_SUBFILE ) ) );
  247.     fileMenu->AddSeparatorItem();
  248.     ADD_ELLIPSIS( _("About") );
  249.     BMenuItem* item = new BMenuItem( psz_tmp, new BMessage( B_ABOUT_REQUESTED ), 'A');
  250.     item->SetTarget( be_app );
  251.     fileMenu->AddItem( item );
  252.     fileMenu->AddItem( new BMenuItem( _("Quit"), new BMessage( B_QUIT_REQUESTED ), 'Q') );
  253.     fLanguageMenu = new LanguageMenu( p_intf, _("Language"), "audio-es" );
  254.     fSubtitlesMenu = new LanguageMenu( p_intf, _("Subtitles"), "spu-es" );
  255.     /* Add the Audio menu */
  256.     fAudioMenu = new BMenu( _("Audio") );
  257.     fMenuBar->AddItem ( fAudioMenu );
  258.     fAudioMenu->AddItem( fLanguageMenu );
  259.     fAudioMenu->AddItem( fSubtitlesMenu );
  260.     fPrevTitleMI = new BMenuItem( _("Prev Title"), new BMessage( PREV_TITLE ) );
  261.     fNextTitleMI = new BMenuItem( _("Next Title"), new BMessage( NEXT_TITLE ) );
  262.     fPrevChapterMI = new BMenuItem( _("Previous chapter"), new BMessage( PREV_CHAPTER ) );
  263.     fNextChapterMI = new BMenuItem( _("Next chapter"), new BMessage( NEXT_CHAPTER ) );
  264.     /* Add the Navigation menu */
  265.     fNavigationMenu = new BMenu( _("Navigation") );
  266.     fMenuBar->AddItem( fNavigationMenu );
  267.     fNavigationMenu->AddItem( fPrevTitleMI );
  268.     fNavigationMenu->AddItem( fNextTitleMI );
  269.     fNavigationMenu->AddItem( fTitleMenu = new TitleMenu( _("Go to Title"), p_intf ) );
  270.     fNavigationMenu->AddSeparatorItem();
  271.     fNavigationMenu->AddItem( fPrevChapterMI );
  272.     fNavigationMenu->AddItem( fNextChapterMI );
  273.     fNavigationMenu->AddItem( fChapterMenu = new ChapterMenu( _("Go to Chapter"), p_intf ) );
  274.     /* Add the Speed menu */
  275.     fSpeedMenu = new BMenu( _("Speed") );
  276.     fSpeedMenu->SetRadioMode( true );
  277.     fSpeedMenu->AddItem(
  278.         fHeighthMI = new BMenuItem( "1/8x", new BMessage( HEIGHTH_PLAY ) ) );
  279.     fSpeedMenu->AddItem(
  280.         fQuarterMI = new BMenuItem( "1/4x", new BMessage( QUARTER_PLAY ) ) );
  281.     fSpeedMenu->AddItem(
  282.         fHalfMI = new BMenuItem( "1/2x", new BMessage( HALF_PLAY ) ) );
  283.     fSpeedMenu->AddItem(
  284.         fNormalMI = new BMenuItem( "1x", new BMessage( NORMAL_PLAY ) ) );
  285.     fSpeedMenu->AddItem(
  286.         fTwiceMI = new BMenuItem( "2x", new BMessage( TWICE_PLAY ) ) );
  287.     fSpeedMenu->AddItem(
  288.         fFourMI = new BMenuItem( "4x", new BMessage( FOUR_PLAY ) ) );
  289.     fSpeedMenu->AddItem(
  290.         fHeightMI = new BMenuItem( "8x", new BMessage( HEIGHT_PLAY ) ) );
  291.     fMenuBar->AddItem( fSpeedMenu );
  292.     /* Add the Show menu */
  293.     fShowMenu = new BMenu( _("Window") );
  294. #if 0
  295.     ADD_ELLIPSIS( _("Playlist") );
  296.     fShowMenu->AddItem( new BMenuItem( psz_tmp, new BMessage( OPEN_PLAYLIST ), 'P') );
  297. #endif
  298.     ADD_ELLIPSIS( _("Messages") );
  299.     fShowMenu->AddItem( new BMenuItem( psz_tmp, new BMessage( OPEN_MESSAGES ), 'M' ) );
  300.     ADD_ELLIPSIS( _("Preferences") );
  301.     fShowMenu->AddItem( new BMenuItem( psz_tmp, new BMessage( OPEN_PREFERENCES ), 'S' ) );
  302.     fMenuBar->AddItem( fShowMenu );
  303.     // add the media control view after the menubar is complete
  304.     // because it will set the window size limits in AttachedToWindow()
  305.     // and the menubar needs to report the correct PreferredSize()
  306.     AddChild( p_mediaControl );
  307.     /* Prepare fow showing */
  308.     _SetMenusEnabled( false );
  309.     p_mediaControl->SetEnabled( false );
  310.     _RestoreSettings();
  311.     Show();
  312. }
  313. InterfaceWindow::~InterfaceWindow()
  314. {
  315.     if( p_input )
  316.     {
  317.         vlc_object_release( p_input );
  318.     }
  319.     if( p_playlist )
  320.     {
  321.         vlc_object_release( p_playlist );
  322.     }
  323. #if 0
  324.     if( fPlaylistWindow )
  325.     {
  326.         fPlaylistWindow->ReallyQuit();
  327.     }
  328. #endif
  329.     if( fMessagesWindow )
  330.     {
  331.         fMessagesWindow->ReallyQuit();
  332.     }
  333.     if( fPreferencesWindow )
  334.     {
  335.         fPreferencesWindow->ReallyQuit();
  336.     }
  337.     delete fFilePanel;
  338.     delete fSettings;
  339. }
  340. /*****************************************************************************
  341.  * InterfaceWindow::FrameResized
  342.  *****************************************************************************/
  343. void
  344. InterfaceWindow::FrameResized(float width, float height)
  345. {
  346.     BRect r(Bounds());
  347.     fMenuBar->MoveTo(r.LeftTop());
  348.     fMenuBar->ResizeTo(r.Width(), fMenuBar->Bounds().Height());
  349.     r.top += fMenuBar->Bounds().Height() + 1.0;
  350.     p_mediaControl->MoveTo(r.LeftTop());
  351.     p_mediaControl->ResizeTo(r.Width(), r.Height());
  352. }
  353. /*****************************************************************************
  354.  * InterfaceWindow::MessageReceived
  355.  *****************************************************************************/
  356. void InterfaceWindow::MessageReceived( BMessage * p_message )
  357. {
  358.     switch( p_message->what )
  359.     {
  360.         case B_ABOUT_REQUESTED:
  361.         {
  362.             BAlert * alert;
  363.             alert = new BAlert( "VLC media player" VERSION,
  364.                                 "VLC media player" VERSION " (BeOS interface)nn"
  365.                                 "The VideoLAN team <videolan@videolan.org>n"
  366.                                 "http://www.videolan.org/", _("OK") );
  367.             alert->Go();
  368.             break;
  369.         }
  370.         case TOGGLE_ON_TOP:
  371.             break;
  372.         case OPEN_FILE:
  373.             _ShowFilePanel( B_REFS_RECEIVED, _("VLC media player: Open Media Files") );
  374.             break;
  375.         case LOAD_SUBFILE:
  376.             _ShowFilePanel( SUBFILE_RECEIVED, _("VLC media player: Open Subtitle File") );
  377.             break;
  378. #if 0
  379.         case OPEN_PLAYLIST:
  380.             if (fPlaylistWindow->Lock())
  381.             {
  382.                 if (fPlaylistWindow->IsHidden())
  383.                     fPlaylistWindow->Show();
  384.                 else
  385.                     fPlaylistWindow->Activate();
  386.                 fPlaylistWindow->Unlock();
  387.             }
  388.             break;
  389. #endif
  390.         case OPEN_DVD:
  391.             {
  392.                 const char * psz_device;
  393.                 if( p_playlist &&
  394.                     p_message->FindString( "device", &psz_device ) == B_OK )
  395.                 {
  396.                     char psz_uri[1024];
  397.                     memset( psz_uri, 0, 1024 );
  398.                     snprintf( psz_uri, 1024, "dvdnav:%s", psz_device );
  399.                     playlist_Add( p_playlist, psz_uri, psz_device,
  400.                         PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END, true );
  401.                 }
  402.                 UpdatePlaylist();
  403.             }
  404.             break;
  405.         case SUBFILE_RECEIVED:
  406.         {
  407.             entry_ref ref;
  408.             if( p_message->FindRef( "refs", 0, &ref ) == B_OK )
  409.             {
  410.                 BPath path( &ref );
  411.                 if ( path.InitCheck() == B_OK )
  412.                     config_PutPsz( p_intf, "sub-file", path.Path() );
  413.             }
  414.             break;
  415.         }
  416.         case STOP_PLAYBACK:
  417.             if( p_playlist )
  418.             {
  419.                 playlist_Stop( p_playlist );
  420.             }
  421.             p_mediaControl->SetStatus(-1, INPUT_RATE_DEFAULT);
  422.             break;
  423.         case START_PLAYBACK:
  424.         case PAUSE_PLAYBACK:
  425.         {
  426.             vlc_value_t val;
  427.             val.i_int = PLAYING_S;
  428.             if( p_input )
  429.             {
  430.                 var_Get( p_input, "state", &val );
  431.             }
  432.             if( p_input && val.i_int != PAUSE_S )
  433.             {
  434.                 val.i_int = PAUSE_S;
  435.                 var_Set( p_input, "state", val );
  436.             }
  437.             else
  438.             {
  439.                 playlist_Play( p_playlist );
  440.             }
  441.             break;
  442.         }
  443.         case HEIGHTH_PLAY:
  444.             if( p_input )
  445.             {
  446.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT * 8 );
  447.             }
  448.             break;
  449.         case QUARTER_PLAY:
  450.             if( p_input )
  451.             {
  452.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT * 4 );
  453.             }
  454.             break;
  455.         case HALF_PLAY:
  456.             if( p_input )
  457.             {
  458.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT * 2 );
  459.             }
  460.             break;
  461.         case NORMAL_PLAY:
  462.             if( p_input )
  463.             {
  464.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT );
  465.             }
  466.             break;
  467.         case TWICE_PLAY:
  468.             if( p_input )
  469.             {
  470.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT / 2 );
  471.             }
  472.             break;
  473.         case FOUR_PLAY:
  474.             if( p_input )
  475.             {
  476.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT / 4 );
  477.             }
  478.             break;
  479.         case HEIGHT_PLAY:
  480.             if( p_input )
  481.             {
  482.                 var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT / 8 );
  483.             }
  484.             break;
  485.         case SEEK_PLAYBACK:
  486.             /* handled by semaphores */
  487.             break;
  488.         case VOLUME_CHG:
  489.             aout_VolumeSet( p_intf, p_mediaControl->GetVolume() );
  490.             break;
  491.         case VOLUME_MUTE:
  492.             aout_VolumeMute( p_intf, NULL );
  493.             break;
  494.         case SELECT_CHANNEL:
  495.         {
  496.             int32 channel;
  497.             if( p_input )
  498.             {
  499.                 if( p_message->FindInt32( "audio-es", &channel ) == B_OK )
  500.                 {
  501.                     var_SetInteger( p_input, "audio-es", channel );
  502.                 }
  503.                 else if( p_message->FindInt32( "spu-es", &channel ) == B_OK )
  504.                 {
  505.                     var_SetInteger( p_input, "spu-es", channel );
  506.                 }
  507.             }
  508.             break;
  509.         }
  510.         case PREV_TITLE:
  511.             if( p_input )
  512.             {
  513.                 var_SetVoid( p_input, "prev-title" );
  514.             }
  515.             break;
  516.         case NEXT_TITLE:
  517.             if( p_input )
  518.             {
  519.                 var_SetVoid( p_input, "next-title" );
  520.             }
  521.             break;
  522.         case TOGGLE_TITLE:
  523.         {
  524.             int32 index;
  525.             if( p_input &&
  526.                 p_message->FindInt32( "index", &index ) == B_OK )
  527.             {
  528.                 var_SetInteger( p_input, "title", index );
  529.             }
  530.             break;
  531.         }
  532.         case PREV_CHAPTER:
  533.             if( p_input )
  534.             {
  535.                 var_SetVoid( p_input, "prev-chapter" );
  536.             }
  537.             break;
  538.         case NEXT_CHAPTER:
  539.             if( p_input )
  540.             {
  541.                 var_SetVoid( p_input, "next-chapter" );
  542.             }
  543.             break;
  544.         case TOGGLE_CHAPTER:
  545.         {
  546.             int32 index;
  547.             if( p_input &&
  548.                 p_message->FindInt32( "index", &index ) == B_OK )
  549.             {
  550.                 var_SetInteger( p_input, "chapter", index );
  551.             }
  552.             break;
  553.         }
  554.         case PREV_FILE:
  555.             if( p_playlist )
  556.             {
  557.                 playlist_Prev( p_playlist );
  558.             }
  559.             break;
  560.         case NEXT_FILE:
  561.             if( p_playlist )
  562.             {
  563.                 playlist_Next( p_playlist );
  564.             }
  565.             break;
  566.         case NAVIGATE_PREV:
  567.             if( p_input )
  568.             {
  569.                 vlc_value_t val;
  570.                 /* First try to go to previous chapter */
  571.                 if( !var_Get( p_input, "chapter", &val ) )
  572.                 {
  573.                     if( val.i_int > 1 )
  574.                     {
  575.                         var_SetVoid( p_input, "prev-chapter" );
  576.                         break;
  577.                     }
  578.                 }
  579.                 /* Try to go to previous title */
  580.                 if( !var_Get( p_input, "title", &val ) )
  581.                 {
  582.                     if( val.i_int > 1 )
  583.                     {
  584.                         var_SetVoid( p_input, "prev-title" );
  585.                         break;
  586.                     }
  587.                 }
  588.                 /* Try to go to previous file */
  589.                 if( p_playlist )
  590.                 {
  591.                     playlist_Prev( p_playlist );
  592.                 }
  593.             }
  594.             break;
  595.         case NAVIGATE_NEXT:
  596.             if( p_input )
  597.             {
  598.                 vlc_value_t val, val_list;
  599.                 /* First try to go to next chapter */
  600.                 if( !var_Get( p_input, "chapter", &val ) )
  601.                 {
  602.                     var_Change( p_input, "chapter", VLC_VAR_GETCHOICES,
  603.                                 &val_list, NULL );
  604.                     if( val_list.p_list->i_count > val.i_int )
  605.                     {
  606.                         var_Change( p_input, "chapter", VLC_VAR_FREELIST,
  607.                                     &val_list, NULL );
  608.                         var_SetVoid( p_input, "next-chapter" );
  609.                         break;
  610.                     }
  611.                     var_Change( p_input, "chapter", VLC_VAR_FREELIST,
  612.                                 &val_list, NULL );
  613.                 }
  614.                 /* Try to go to next title */
  615.                 if( !var_Get( p_input, "title", &val ) )
  616.                 {
  617.                     var_Change( p_input, "title", VLC_VAR_GETCHOICES,
  618.                                 &val_list, NULL );
  619.                     if( val_list.p_list->i_count > val.i_int )
  620.                     {
  621.                         var_Change( p_input, "title", VLC_VAR_FREELIST,
  622.                                     &val_list, NULL );
  623.                         var_SetVoid( p_input, "next-title" );
  624.                         break;
  625.                     }
  626.                     var_Change( p_input, "title", VLC_VAR_FREELIST,
  627.                                 &val_list, NULL );
  628.                 }
  629.                 /* Try to go to next file */
  630.                 if( p_playlist )
  631.                 {
  632.                     playlist_Next( p_playlist );
  633.                 }
  634.             }
  635.             break;
  636.         // drag'n'drop and system messages
  637.         case MSG_SOUNDPLAY:
  638.             // convert soundplay drag'n'drop message (containing paths)
  639.             // to normal message (containing refs)
  640.             {
  641.                 const char* path;
  642.                 for ( int32 i = 0; p_message->FindString( "path", i, &path ) == B_OK; i++ )
  643.                 {
  644.                     entry_ref ref;
  645.                     if ( get_ref_for_path( path, &ref ) == B_OK )
  646.                         p_message->AddRef( "refs", &ref );
  647.                 }
  648.             }
  649.             // fall through
  650.         case B_REFS_RECEIVED:
  651.         case B_SIMPLE_DATA:
  652.         {
  653.             /* file(s) opened by the File menu -> append to the playlist;
  654.                file(s) opened by drag & drop -> replace playlist;
  655.                file(s) opened by 'shift' + drag & drop -> append */
  656.             int32 count;
  657.             type_code dummy;
  658.             if( p_message->GetInfo( "refs", &dummy, &count ) != B_OK ||
  659.                 count < 1 )
  660.             {
  661.                 break;
  662.             }
  663.             bool b_remove = ( p_message->WasDropped() &&
  664.                                     !( modifiers() & B_SHIFT_KEY ) );
  665.             if( b_remove && p_playlist )
  666.             {
  667.                 playlist_Clear( p_playlist, true );
  668.             }
  669.             entry_ref ref;
  670.             for( int i = 0; p_message->FindRef( "refs", i, &ref ) == B_OK; i++ )
  671.             {
  672.                 BPath path( &ref );
  673.                 /* TODO: find out if this is a DVD icon */
  674.                 if( p_playlist )
  675.                 {
  676.                     playlist_Add( p_playlist, path.Path(), NULL,
  677.                        PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END, true );
  678.                 }
  679.             }
  680.             UpdatePlaylist();
  681.             break;
  682.         }
  683.         case OPEN_PREFERENCES:
  684.         {
  685.             if( fPreferencesWindow->Lock() )
  686.             {
  687.                 if (fPreferencesWindow->IsHidden())
  688.                     fPreferencesWindow->Show();
  689.                 else
  690.                     fPreferencesWindow->Activate();
  691.                 fPreferencesWindow->Unlock();
  692.             }
  693.             break;
  694.         }
  695.         case OPEN_MESSAGES:
  696.         {
  697.             if( fMessagesWindow->Lock() )
  698.             {
  699.                 if (fMessagesWindow->IsHidden())
  700.                     fMessagesWindow->Show();
  701.                 else
  702.                     fMessagesWindow->Activate();
  703.                 fMessagesWindow->Unlock();
  704.             }
  705.             break;
  706.         }
  707.         case MSG_UPDATE:
  708.             UpdateInterface();
  709.             break;
  710.         default:
  711.             BWindow::MessageReceived( p_message );
  712.             break;
  713.     }
  714. }
  715. /*****************************************************************************
  716.  * InterfaceWindow::QuitRequested
  717.  *****************************************************************************/
  718. bool InterfaceWindow::QuitRequested()
  719. {
  720.     if( p_playlist )
  721.     {
  722.         playlist_Stop( p_playlist );
  723.     }
  724.     p_mediaControl->SetStatus(-1, INPUT_RATE_DEFAULT);
  725.      _StoreSettings();
  726.     vlc_object_kill( p_intf );
  727.     return( true );
  728. }
  729. /*****************************************************************************
  730.  * InterfaceWindow::UpdateInterface
  731.  *****************************************************************************/
  732. void InterfaceWindow::UpdateInterface()
  733. {
  734.     if( !p_input )
  735.     {
  736.         p_input = (input_thread_t *)
  737.             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  738.     }
  739.     else if( p_input->b_dead )
  740.     {
  741.         vlc_object_release( p_input );
  742.         p_input = NULL;
  743.     }
  744.     /* Get ready to update the interface */
  745.     if( LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) != B_OK )
  746.     {
  747.         return;
  748.     }
  749.     if( b_playlist_update )
  750.     {
  751. #if 0
  752.         if( fPlaylistWindow->Lock() )
  753.         {
  754.             fPlaylistWindow->UpdatePlaylist( true );
  755.             fPlaylistWindow->Unlock();
  756.             b_playlist_update = false;
  757.         }
  758. #endif
  759.         p_mediaControl->SetEnabled( !playlist_IsEmpty( p_playlist ) );
  760.     }
  761.     if( p_input )
  762.     {
  763.         vlc_value_t val;
  764.         p_mediaControl->SetEnabled( true );
  765.         bool hasTitles   = !var_Get( p_input, "title", &val );
  766.         bool hasChapters = !var_Get( p_input, "chapter", &val );
  767.         p_mediaControl->SetStatus( var_GetInteger( p_input, "state" ),
  768.                                    var_GetInteger( p_input, "rate" ) );
  769.         var_Get( p_input, "position", &val );
  770.         p_mediaControl->SetProgress( val.f_float );
  771.         _SetMenusEnabled( true, hasChapters, hasTitles );
  772.         _UpdateSpeedMenu( var_GetInteger( p_input, "rate" ) );
  773.         // enable/disable skip buttons
  774. #if 0
  775.         bool canSkipPrev;
  776.         bool canSkipNext;
  777.         p_wrapper->GetNavCapabilities( &canSkipPrev, &canSkipNext );
  778.         p_mediaControl->SetSkippable( canSkipPrev, canSkipNext );
  779. #endif
  780.         audio_volume_t i_volume;
  781.         aout_VolumeGet( p_intf, &i_volume );
  782.         p_mediaControl->SetAudioEnabled( true );
  783.         p_mediaControl->SetMuted( i_volume );
  784.     }
  785.     else
  786.     {
  787.         p_mediaControl->SetAudioEnabled( false );
  788.         _SetMenusEnabled( false );
  789.         if( !playlist_IsEmpty( p_playlist ) )
  790.         {
  791.             p_mediaControl->SetProgress( 0 );
  792. #if 0
  793.             // enable/disable skip buttons
  794.             bool canSkipPrev;
  795.             bool canSkipNext;
  796.             p_wrapper->GetNavCapabilities( &canSkipPrev, &canSkipNext );
  797.             p_mediaControl->SetSkippable( canSkipPrev, canSkipNext );
  798. #endif
  799.         }
  800.         else
  801.         {
  802.             p_mediaControl->SetEnabled( false );
  803.         }
  804.     }
  805.     Unlock();
  806.     fLastUpdateTime = system_time();
  807. }
  808. /*****************************************************************************
  809.  * InterfaceWindow::UpdatePlaylist
  810.  *****************************************************************************/
  811. void
  812. InterfaceWindow::UpdatePlaylist()
  813. {
  814.     b_playlist_update = true;
  815. }
  816. /*****************************************************************************
  817.  * InterfaceWindow::IsStopped
  818.  *****************************************************************************/
  819. bool
  820. InterfaceWindow::IsStopped() const
  821. {
  822.     return (system_time() - fLastUpdateTime > INTERFACE_UPDATE_TIMEOUT);
  823. }
  824. /*****************************************************************************
  825.  * InterfaceWindow::_SetMenusEnabled
  826.  *****************************************************************************/
  827. void
  828. InterfaceWindow::_SetMenusEnabled(bool hasFile, bool hasChapters, bool hasTitles)
  829. {
  830.     if (!hasFile)
  831.     {
  832.         hasChapters = false;
  833.         hasTitles = false;
  834.     }
  835.     if ( LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK)
  836.     {
  837.         if ( fNextChapterMI->IsEnabled() != hasChapters )
  838.              fNextChapterMI->SetEnabled( hasChapters );
  839.         if ( fPrevChapterMI->IsEnabled() != hasChapters )
  840.              fPrevChapterMI->SetEnabled( hasChapters );
  841.         if ( fChapterMenu->IsEnabled() != hasChapters )
  842.              fChapterMenu->SetEnabled( hasChapters );
  843.         if ( fNextTitleMI->IsEnabled() != hasTitles )
  844.              fNextTitleMI->SetEnabled( hasTitles );
  845.         if ( fPrevTitleMI->IsEnabled() != hasTitles )
  846.              fPrevTitleMI->SetEnabled( hasTitles );
  847.         if ( fTitleMenu->IsEnabled() != hasTitles )
  848.              fTitleMenu->SetEnabled( hasTitles );
  849.         if ( fAudioMenu->IsEnabled() != hasFile )
  850.              fAudioMenu->SetEnabled( hasFile );
  851.         if ( fNavigationMenu->IsEnabled() != hasFile )
  852.              fNavigationMenu->SetEnabled( hasFile );
  853.         if ( fLanguageMenu->IsEnabled() != hasFile )
  854.              fLanguageMenu->SetEnabled( hasFile );
  855.         if ( fSubtitlesMenu->IsEnabled() != hasFile )
  856.              fSubtitlesMenu->SetEnabled( hasFile );
  857.         if ( fSpeedMenu->IsEnabled() != hasFile )
  858.              fSpeedMenu->SetEnabled( hasFile );
  859.         Unlock();
  860.     }
  861. }
  862. /*****************************************************************************
  863.  * InterfaceWindow::_UpdateSpeedMenu
  864.  *****************************************************************************/
  865. void
  866. InterfaceWindow::_UpdateSpeedMenu( int rate )
  867. {
  868.     BMenuItem * toMark = NULL;
  869.     switch( rate )
  870.     {
  871.         case ( INPUT_RATE_DEFAULT * 8 ):
  872.             toMark = fHeighthMI;
  873.             break;
  874.         case ( INPUT_RATE_DEFAULT * 4 ):
  875.             toMark = fQuarterMI;
  876.             break;
  877.         case ( INPUT_RATE_DEFAULT * 2 ):
  878.             toMark = fHalfMI;
  879.             break;
  880.         case ( INPUT_RATE_DEFAULT ):
  881.             toMark = fNormalMI;
  882.             break;
  883.         case ( INPUT_RATE_DEFAULT / 2 ):
  884.             toMark = fTwiceMI;
  885.             break;
  886.         case ( INPUT_RATE_DEFAULT / 4 ):
  887.             toMark = fFourMI;
  888.             break;
  889.         case ( INPUT_RATE_DEFAULT / 8 ):
  890.             toMark = fHeightMI;
  891.             break;
  892.     }
  893.     if ( toMark && !toMark->IsMarked() )
  894.     {
  895.         toMark->SetMarked( true );
  896.     }
  897. }
  898. /*****************************************************************************
  899.  * InterfaceWindow::_ShowFilePanel
  900.  *****************************************************************************/
  901. void
  902. InterfaceWindow::_ShowFilePanel( uint32 command, const char* windowTitle )
  903. {
  904.     if( !fFilePanel )
  905.     {
  906.         fFilePanel = new BFilePanel( B_OPEN_PANEL, NULL, NULL,
  907.                                      B_FILE_NODE | B_DIRECTORY_NODE );
  908.         fFilePanel->SetTarget( this );
  909.     }
  910.     fFilePanel->Window()->SetTitle( windowTitle );
  911.     BMessage message( command );
  912.     fFilePanel->SetMessage( &message );
  913.     if ( !fFilePanel->IsShowing() )
  914.     {
  915.         fFilePanel->Refresh();
  916.         fFilePanel->Show();
  917.     }
  918. }
  919. // set_window_pos
  920. void
  921. set_window_pos( BWindow* window, BRect frame )
  922. {
  923.     // sanity checks: make sure window is not too big/small
  924.     // and that it's not off-screen
  925.     float minWidth, maxWidth, minHeight, maxHeight;
  926.     window->GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
  927.     make_sure_frame_is_within_limits( frame,
  928.                                       minWidth, minHeight, maxWidth, maxHeight );
  929.     if ( make_sure_frame_is_on_screen( frame ) )
  930.     {
  931.         window->MoveTo( frame.LeftTop() );
  932.         window->ResizeTo( frame.Width(), frame.Height() );
  933.     }
  934. }
  935. // set_window_pos
  936. void
  937. launch_window( BWindow* window, bool showing )
  938. {
  939.     if ( window->Lock() )
  940.     {
  941.         if ( showing )
  942.         {
  943.             if ( window->IsHidden() )
  944.                 window->Show();
  945.         }
  946.         else
  947.         {
  948.             if ( !window->IsHidden() )
  949.                 window->Hide();
  950.         }
  951.         window->Unlock();
  952.     }
  953. }
  954. /*****************************************************************************
  955.  * InterfaceWindow::_RestoreSettings
  956.  *****************************************************************************/
  957. void
  958. InterfaceWindow::_RestoreSettings()
  959. {
  960.     if ( load_settings( fSettings, "interface_settings", "VideoLAN Client" ) == B_OK )
  961.     {
  962.         BRect frame;
  963.         if ( fSettings->FindRect( "main frame", &frame ) == B_OK )
  964.             set_window_pos( this, frame );
  965. #if 0
  966.         if (fSettings->FindRect( "playlist frame", &frame ) == B_OK )
  967.             set_window_pos( fPlaylistWindow, frame );
  968. #endif
  969.         if (fSettings->FindRect( "messages frame", &frame ) == B_OK )
  970.             set_window_pos( fMessagesWindow, frame );
  971.         if (fSettings->FindRect( "settings frame", &frame ) == B_OK )
  972.         {
  973.             /* FIXME: Preferences resizing doesn't work correctly yet */
  974.             frame.right = frame.left + fPreferencesWindow->Frame().Width();
  975.             frame.bottom = frame.top + fPreferencesWindow->Frame().Height();
  976.             set_window_pos( fPreferencesWindow, frame );
  977.         }
  978.         bool showing;
  979. #if 0
  980.         if ( fSettings->FindBool( "playlist showing", &showing ) == B_OK )
  981.             launch_window( fPlaylistWindow, showing );
  982. #endif
  983.         if ( fSettings->FindBool( "messages showing", &showing ) == B_OK )
  984.             launch_window( fMessagesWindow, showing );
  985.         if ( fSettings->FindBool( "settings showing", &showing ) == B_OK )
  986.             launch_window( fPreferencesWindow, showing );
  987. #if 0
  988.         uint32 displayMode;
  989.         if ( fSettings->FindInt32( "playlist display mode", (int32*)&displayMode ) == B_OK )
  990.             fPlaylistWindow->SetDisplayMode( displayMode );
  991. #endif
  992.     }
  993. }
  994. /*****************************************************************************
  995.  * InterfaceWindow::_StoreSettings
  996.  *****************************************************************************/
  997. void
  998. InterfaceWindow::_StoreSettings()
  999. {
  1000.     /* Save the volume */
  1001.     config_PutInt( p_intf, "volume", p_mediaControl->GetVolume() );
  1002.     /* Save the windows positions */
  1003.     if ( fSettings->ReplaceRect( "main frame", Frame() ) != B_OK )
  1004.         fSettings->AddRect( "main frame", Frame() );
  1005. #if 0
  1006.     if ( fPlaylistWindow->Lock() )
  1007.     {
  1008.         if (fSettings->ReplaceRect( "playlist frame", fPlaylistWindow->Frame() ) != B_OK)
  1009.             fSettings->AddRect( "playlist frame", fPlaylistWindow->Frame() );
  1010.         if (fSettings->ReplaceBool( "playlist showing", !fPlaylistWindow->IsHidden() ) != B_OK)
  1011.             fSettings->AddBool( "playlist showing", !fPlaylistWindow->IsHidden() );
  1012.         fPlaylistWindow->Unlock();
  1013.     }
  1014. #endif
  1015.     if ( fMessagesWindow->Lock() )
  1016.     {
  1017.         if (fSettings->ReplaceRect( "messages frame", fMessagesWindow->Frame() ) != B_OK)
  1018.             fSettings->AddRect( "messages frame", fMessagesWindow->Frame() );
  1019.         if (fSettings->ReplaceBool( "messages showing", !fMessagesWindow->IsHidden() ) != B_OK)
  1020.             fSettings->AddBool( "messages showing", !fMessagesWindow->IsHidden() );
  1021.         fMessagesWindow->Unlock();
  1022.     }
  1023.     if ( fPreferencesWindow->Lock() )
  1024.     {
  1025.         if (fSettings->ReplaceRect( "settings frame", fPreferencesWindow->Frame() ) != B_OK)
  1026.             fSettings->AddRect( "settings frame", fPreferencesWindow->Frame() );
  1027.         if (fSettings->ReplaceBool( "settings showing", !fPreferencesWindow->IsHidden() ) != B_OK)
  1028.             fSettings->AddBool( "settings showing", !fPreferencesWindow->IsHidden() );
  1029.         fPreferencesWindow->Unlock();
  1030.     }
  1031. #if 0
  1032.     uint32 displayMode = fPlaylistWindow->DisplayMode();
  1033.     if (fSettings->ReplaceInt32( "playlist display mode", displayMode ) != B_OK )
  1034.         fSettings->AddInt32( "playlist display mode", displayMode );
  1035. #endif
  1036.     save_settings( fSettings, "interface_settings", "VideoLAN Client" );
  1037. }
  1038. /*****************************************************************************
  1039.  * CDMenu::CDMenu
  1040.  *****************************************************************************/
  1041. CDMenu::CDMenu(const char *name)
  1042.       : BMenu(name)
  1043. {
  1044. }
  1045. /*****************************************************************************
  1046.  * CDMenu::~CDMenu
  1047.  *****************************************************************************/
  1048. CDMenu::~CDMenu()
  1049. {
  1050. }
  1051. /*****************************************************************************
  1052.  * CDMenu::AttachedToWindow
  1053.  *****************************************************************************/
  1054. void CDMenu::AttachedToWindow(void)
  1055. {
  1056.     // remove all items
  1057.     while ( BMenuItem* item = RemoveItem( 0L ) )
  1058.         delete item;
  1059.     GetCD( "/dev/disk" );
  1060.     BMenu::AttachedToWindow();
  1061. }
  1062. /*****************************************************************************
  1063.  * CDMenu::GetCD
  1064.  *****************************************************************************/
  1065. int CDMenu::GetCD( const char *directory )
  1066. {
  1067.     BVolumeRoster volRoster;
  1068.     BVolume vol;
  1069.     BDirectory dir;
  1070.     status_t status = volRoster.GetNextVolume( &vol );
  1071.     while ( status ==  B_NO_ERROR )
  1072.     {
  1073.         BString deviceName;
  1074.         BString volumeName;
  1075.         bool isCDROM;
  1076.         if ( get_volume_info( vol, volumeName, isCDROM, deviceName )
  1077.              && isCDROM )
  1078.         {
  1079.             BMessage* msg = new BMessage( OPEN_DVD );
  1080.             msg->AddString( "device", deviceName.String() );
  1081.             BMenuItem* item = new BMenuItem( volumeName.String(), msg );
  1082.             AddItem( item );
  1083.         }
  1084.          vol.Unset();
  1085.         status = volRoster.GetNextVolume( &vol );
  1086.     }
  1087.     return 0;
  1088. }
  1089. /*****************************************************************************
  1090.  * LanguageMenu::LanguageMenu
  1091.  *****************************************************************************/
  1092. LanguageMenu::LanguageMenu( intf_thread_t * _p_intf, const char * psz_name,
  1093.                             char * _psz_variable )
  1094.     : BMenu( psz_name )
  1095. {
  1096.     p_intf       = _p_intf;
  1097.     psz_variable = strdup( _psz_variable );
  1098. }
  1099. /*****************************************************************************
  1100.  * LanguageMenu::~LanguageMenu
  1101.  *****************************************************************************/
  1102. LanguageMenu::~LanguageMenu()
  1103. {
  1104.     free( psz_variable );
  1105. }
  1106. /*****************************************************************************
  1107.  * LanguageMenu::AttachedToWindow
  1108.  *****************************************************************************/
  1109. void LanguageMenu::AttachedToWindow()
  1110. {
  1111.     BMenuItem * item;
  1112.     // remove all items
  1113.     while( ( item = RemoveItem( 0L ) ) )
  1114.     {
  1115.         delete item;
  1116.     }
  1117.     SetRadioMode( true );
  1118.     input_thread_t * p_input = (input_thread_t *)
  1119.             vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  1120.     if( !p_input )
  1121.     {
  1122.         return;
  1123.     }
  1124.     vlc_value_t val_list, text_list;
  1125.     BMessage * message;
  1126.     int i_current;
  1127.     i_current = var_GetInteger( p_input, psz_variable );
  1128.     var_Change( p_input, psz_variable, VLC_VAR_GETLIST, &val_list, &text_list );
  1129.     for( int i = 0; i < val_list.p_list->i_count; i++ )
  1130.     {
  1131.         message = new BMessage( SELECT_CHANNEL );
  1132.         message->AddInt32( psz_variable, val_list.p_list->p_values[i].i_int );
  1133.         item = new BMenuItem( text_list.p_list->p_values[i].psz_string, message );
  1134.         if( val_list.p_list->p_values[i].i_int == i_current )
  1135.         {
  1136.             item->SetMarked( true );
  1137.         }
  1138.         AddItem( item );
  1139.     }
  1140.     var_Change( p_input, psz_variable, VLC_VAR_FREELIST, &val_list, &text_list );
  1141.     vlc_object_release( p_input );
  1142.     BMenu::AttachedToWindow();
  1143. }
  1144. /*****************************************************************************
  1145.  * TitleMenu::TitleMenu
  1146.  *****************************************************************************/
  1147. TitleMenu::TitleMenu( const char *name, intf_thread_t  *p_interface )
  1148.     : BMenu(name),
  1149.     p_intf( p_interface )
  1150. {
  1151. }
  1152. /*****************************************************************************
  1153.  * TitleMenu::~TitleMenu
  1154.  *****************************************************************************/
  1155. TitleMenu::~TitleMenu()
  1156. {
  1157. }
  1158. /*****************************************************************************
  1159.  * TitleMenu::AttachedToWindow
  1160.  *****************************************************************************/
  1161. void TitleMenu::AttachedToWindow()
  1162. {
  1163.     BMenuItem * item;
  1164.     while( ( item = RemoveItem( 0L ) ) )
  1165.     {
  1166.         delete item;
  1167.     }
  1168.     input_thread_t * p_input;
  1169.     p_input = (input_thread_t *)
  1170.         vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  1171.     if( !p_input )
  1172.     {
  1173.         return;
  1174.     }
  1175.     vlc_value_t val;
  1176.     BMessage * message;
  1177.     if( !var_Get( p_input, "title", &val ) )
  1178.     {
  1179.         vlc_value_t val_list, text_list;
  1180.         var_Change( p_input, "title", VLC_VAR_GETCHOICES,
  1181.                     &val_list, &text_list );
  1182.         for( int i = 0; i < val_list.p_list->i_count; i++ )
  1183.         {
  1184.             message = new BMessage( TOGGLE_TITLE );
  1185.             message->AddInt32( "index", val_list.p_list->p_values[i].i_int );
  1186.             item = new BMenuItem( text_list.p_list->p_values[i].psz_string,
  1187.                                   message );
  1188.             if( val_list.p_list->p_values[i].i_int == val.i_int )
  1189.             {
  1190.                 item->SetMarked( true );
  1191.             }
  1192.             AddItem( item );
  1193.         }
  1194.         var_Change( p_input, "title", VLC_VAR_FREELIST,
  1195.                     &val_list, &text_list );
  1196.     }
  1197.     vlc_object_release( p_input );
  1198.     BMenu::AttachedToWindow();
  1199. }
  1200. /*****************************************************************************
  1201.  * ChapterMenu::ChapterMenu
  1202.  *****************************************************************************/
  1203. ChapterMenu::ChapterMenu( const char *name, intf_thread_t  *p_interface )
  1204.     : BMenu(name),
  1205.     p_intf( p_interface )
  1206. {
  1207. }
  1208. /*****************************************************************************
  1209.  * ChapterMenu::~ChapterMenu
  1210.  *****************************************************************************/
  1211. ChapterMenu::~ChapterMenu()
  1212. {
  1213. }
  1214. /*****************************************************************************
  1215.  * ChapterMenu::AttachedToWindow
  1216.  *****************************************************************************/
  1217. void ChapterMenu::AttachedToWindow()
  1218. {
  1219.     BMenuItem * item;
  1220.     while( ( item = RemoveItem( 0L ) ) )
  1221.     {
  1222.         delete item;
  1223.     }
  1224.     input_thread_t * p_input;
  1225.     p_input = (input_thread_t *)
  1226.         vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  1227.     if( !p_input )
  1228.     {
  1229.         return;
  1230.     }
  1231.     vlc_value_t val;
  1232.     BMessage * message;
  1233.     if( !var_Get( p_input, "chapter", &val ) )
  1234.     {
  1235.         vlc_value_t val_list, text_list;
  1236.         var_Change( p_input, "chapter", VLC_VAR_GETCHOICES,
  1237.                     &val_list, &text_list );
  1238.         for( int i = 0; i < val_list.p_list->i_count; i++ )
  1239.         {
  1240.             message = new BMessage( TOGGLE_CHAPTER );
  1241.             message->AddInt32( "index", val_list.p_list->p_values[i].i_int );
  1242.             item = new BMenuItem( text_list.p_list->p_values[i].psz_string,
  1243.                                   message );
  1244.             if( val_list.p_list->p_values[i].i_int == val.i_int )
  1245.             {
  1246.                 item->SetMarked( true );
  1247.             }
  1248.             AddItem( item );
  1249.         }
  1250.         var_Change( p_input, "chapter", VLC_VAR_FREELIST,
  1251.                     &val_list, &text_list );
  1252.     }
  1253.     vlc_object_release( p_input );
  1254.     BMenu::AttachedToWindow();
  1255. }
  1256. /*****************************************************************************
  1257.  * load_settings
  1258.  *****************************************************************************/
  1259. status_t
  1260. load_settings( BMessage* message, const char* fileName, const char* folder )
  1261. {
  1262.     status_t ret = B_BAD_VALUE;
  1263.     if ( message )
  1264.     {
  1265.         BPath path;
  1266.         if ( ( ret = find_directory( B_USER_SETTINGS_DIRECTORY, &path ) ) == B_OK )
  1267.         {
  1268.             // passing folder is optional
  1269.             if ( folder )
  1270.                 ret = path.Append( folder );
  1271.             if ( ret == B_OK && ( ret = path.Append( fileName ) ) == B_OK )
  1272.             {
  1273.                 BFile file( path.Path(), B_READ_ONLY );
  1274.                 if ( ( ret = file.InitCheck() ) == B_OK )
  1275.                 {
  1276.                     ret = message->Unflatten( &file );
  1277.                     file.Unset();
  1278.                 }
  1279.             }
  1280.         }
  1281.     }
  1282.     return ret;
  1283. }
  1284. /*****************************************************************************
  1285.  * save_settings
  1286.  *****************************************************************************/
  1287. status_t
  1288. save_settings( BMessage* message, const char* fileName, const char* folder )
  1289. {
  1290.     status_t ret = B_BAD_VALUE;
  1291.     if ( message )
  1292.     {
  1293.         BPath path;
  1294.         if ( ( ret = find_directory( B_USER_SETTINGS_DIRECTORY, &path ) ) == B_OK )
  1295.         {
  1296.             // passing folder is optional
  1297.             if ( folder && ( ret = path.Append( folder ) ) == B_OK )
  1298.                 ret = create_directory( path.Path(), 0777 );
  1299.             if ( ret == B_OK && ( ret = path.Append( fileName ) ) == B_OK )
  1300.             {
  1301.                 BFile file( path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE );
  1302.                 if ( ( ret = file.InitCheck() ) == B_OK )
  1303.                 {
  1304.                     ret = message->Flatten( &file );
  1305.                     file.Unset();
  1306.                 }
  1307.             }
  1308.         }
  1309.     }
  1310.     return ret;
  1311. }