InterfaceWindow.cpp
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:46k
源码类别:

多媒体

开发平台:

MultiPlatform

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