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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * intf.cpp: Qt interface
  3.  *****************************************************************************
  4.  * Copyright (C) 1999, 2000 VideoLAN
  5.  * $Id: intf.cpp 7945 2004-06-07 21:26:35Z fenrir $
  6.  *
  7.  * Authors: Samuel Hocevar <sam@zoy.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  * 
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <errno.h>                                                 /* ENOMEM */
  27. #include <stdlib.h>                                                /* free() */
  28. #include <string.h>                                            /* strerror() */
  29. #include <stdio.h>
  30. #include "intf.h"
  31. #define SLIDER_MIN    0x00000
  32. #define SLIDER_MAX    0x10000
  33. #define SLIDER_STEP   (SLIDER_MAX >> 4)
  34. /*****************************************************************************
  35.  * intf_sys_t: description and status of Qt interface
  36.  *****************************************************************************/
  37. struct intf_sys_t
  38. {
  39.     QApplication *p_app;
  40.     IntfWindow   *p_window;
  41.     input_thread_t *p_input;
  42. };
  43. /*****************************************************************************
  44.  * Local prototype
  45.  *****************************************************************************/
  46. static void Run ( intf_thread_t *p_intf );
  47. /*****************************************************************************
  48.  * Open: initialize and create window
  49.  *****************************************************************************/
  50. int E_(Open) ( vlc_object_t *p_this )
  51. {
  52.     intf_thread_t *p_intf = (intf_thread_t*) p_this;
  53.     char *pp_argv[] = { "" };
  54.     int   i_argc    = 1;
  55.     /* Allocate instance and initialize some members */
  56.     p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
  57.     if( p_intf->p_sys == NULL )
  58.     {
  59.         msg_Err( p_intf, "out of memory" );
  60.         return 1;
  61.     }
  62.     p_intf->pf_run = Run;
  63.     /* Create the C++ objects */
  64.     p_intf->p_sys->p_app = new QApplication( i_argc, pp_argv );
  65.     p_intf->p_sys->p_window = new IntfWindow( p_intf );
  66.     /* Tell the world we are here */
  67.     p_intf->p_sys->p_window->setCaption( VOUT_TITLE " (Qt interface)" );
  68.     p_intf->p_sys->p_input = NULL;
  69.     return 0;
  70. }
  71. /*****************************************************************************
  72.  * Close: destroy interface window
  73.  *****************************************************************************/
  74. void E_(Close) ( vlc_object_t *p_this )
  75. {
  76.     intf_thread_t *p_intf = (intf_thread_t*) p_this;
  77.     if( p_intf->p_sys->p_input )
  78.     {
  79.         vlc_object_release( p_intf->p_sys->p_input );
  80.     }
  81.     /* Get rid of the C++ objects */
  82.     delete p_intf->p_sys->p_window;
  83.     delete p_intf->p_sys->p_app;
  84.     /* Destroy structure */
  85.     free( p_intf->p_sys );
  86. }
  87. /*****************************************************************************
  88.  * Run: Qt thread
  89.  *****************************************************************************
  90.  * This part of the interface is in a separate thread so that we can call
  91.  * exec() from within it without annoying the rest of the program.
  92.  *****************************************************************************/
  93. static void Run( intf_thread_t *p_intf )
  94. {
  95.     p_intf->p_sys->p_window->show();
  96.     p_intf->p_sys->p_app->exec();
  97. }
  98. /* following functions are local */
  99. /*****************************************************************************
  100.  * IntfWindow: interface window creator
  101.  *****************************************************************************
  102.  * This function creates the interface window, and populates it with a
  103.  * menu bar, a toolbar and a slider.
  104.  *****************************************************************************/
  105. IntfWindow::IntfWindow( intf_thread_t *p_intf )
  106.            :QMainWindow( 0 )
  107. {
  108.     setUsesTextLabel( TRUE );
  109.     this->p_intf = p_intf;
  110.     /*
  111.      * Create the toolbar
  112.      */
  113.     p_toolbar = new QToolBar( this, "toolbar" );
  114.     p_toolbar->setHorizontalStretchable( TRUE );
  115.     QIconSet * set = new QIconSet();
  116.     QPixmap pixmap = set->pixmap( QIconSet::Automatic, QIconSet::Normal );
  117. #define addbut( l, t, s ) new QToolButton( pixmap, l, t, this, s, p_toolbar );
  118.     addbut( "Open", "Open a File", SLOT(FileOpen()) );
  119.     addbut( "Disc", "Open a DVD or VCD", SLOT(Unimplemented()) );
  120.     addbut( "Net", "Select a Network Stream", SLOT(Unimplemented()) );
  121.     p_toolbar->addSeparator();
  122.     addbut( "Back", "Rewind Stream", SLOT(Unimplemented()) );
  123.     addbut( "Stop", "Stop Stream", SLOT(Unimplemented()) );
  124.     addbut( "Play", "Play Stream", SLOT(PlaybackPlay()) );
  125.     addbut( "Pause", "Pause Stream", SLOT(PlaybackPause()) );
  126.     addbut( "Slow", "Play Slower", SLOT(PlaybackSlow()) );
  127.     addbut( "Fast", "Play Faster", SLOT(PlaybackFast()) );
  128.     p_toolbar->addSeparator();
  129.     addbut( "Playlist", "Open Playlist", SLOT(Unimplemented()) );
  130.     addbut( "Prev", "Previous File", SLOT(PlaylistPrev()) );
  131.     addbut( "Next", "Next File", SLOT(PlaylistNext()) );
  132. #undef addbut
  133.     /* 
  134.      * Create the menubar
  135.      */
  136.     QPopupMenu * p_tmpmenu = new QPopupMenu( this );
  137. #define instmp0( x, y )    p_tmpmenu->insertItem( x, this, y )
  138. #define instmp1( x, y, a ) p_tmpmenu->insertItem( x, this, y, a )
  139.     menuBar()->insertItem( "&File", p_tmpmenu );
  140.     instmp1( "&Open File...", SLOT(FileOpen()), Key_F3 );
  141.     instmp1( "Open &Disc...", SLOT(Unimplemented()), Key_F4 );
  142.     instmp1( "&Network Stream...", SLOT(Unimplemented()), Key_F5 );
  143.     p_tmpmenu->insertSeparator();
  144.     instmp1( "&Exit", SLOT(FileQuit()), CTRL+Key_Q );
  145.     p_tmpmenu = new QPopupMenu( this );
  146.     menuBar()->insertItem( "&View", p_tmpmenu );
  147.     instmp0( "&Playlist...", SLOT(Unimplemented()) );
  148.     instmp0( "&Modules...", SLOT(Unimplemented()) );
  149.     p_tmpmenu = new QPopupMenu( this );
  150.     menuBar()->insertItem( "&Settings", p_tmpmenu );
  151.     instmp0( "&Preferences...", SLOT(Unimplemented()) );
  152.     p_tmpmenu = new QPopupMenu( this );
  153.     menuBar()->insertItem( "&Help", p_tmpmenu );
  154.     instmp0( "&About...", SLOT(About()) );
  155.     /*
  156.      * Create the popup menu
  157.      */
  158.     p_popup = new QPopupMenu( /* floating menu */ );
  159. #define inspop0( x, y )    p_popup->insertItem( x, this, y )
  160. #define inspop1( x, y, a ) p_popup->insertItem( x, this, y, a )
  161.     inspop0( "&Play", SLOT(PlaybackPlay()) );
  162.     inspop0( "Pause", SLOT(PlaybackPause()) );
  163.     inspop0( "&Slow", SLOT(PlaybackSlow()) );
  164.     inspop0( "&Fast", SLOT(PlaybackFast()) );
  165.     p_popup->insertSeparator();
  166.     inspop1( "&Open File...", SLOT(FileOpen()), Key_F3 );
  167.     inspop1( "Open &Disc...", SLOT(Unimplemented()), Key_F4 );
  168.     inspop1( "&Network Stream...", SLOT(Unimplemented()), Key_F5 );
  169.     p_popup->insertSeparator();
  170.     inspop0( "&About...", SLOT(About()) );
  171.     inspop0( "&Exit", SLOT(FileQuit()) );
  172.     /* Activate the statusbar */
  173.     statusBar();
  174.     /* Add the vertical box */
  175.     QVBox * p_vbox = new QVBox( this );
  176.     setCentralWidget( p_vbox );
  177.         /* The horizontal box */
  178.         QHBox * p_hbox = new QHBox( p_vbox );
  179.             /* The date label */
  180.             p_date  = new QLabel( p_hbox );
  181.             p_date->setAlignment( AlignHCenter | AlignVCenter );
  182.             p_date->setText( "-:--:--" );
  183.             /* The status label */
  184.             QLabel *p_label  = new QLabel( p_hbox );
  185.             p_label->setAlignment( AlignHCenter | AlignVCenter );
  186.             p_label->setText( "Status: foo" );
  187.             /* The bar label */
  188.             p_label  = new QLabel( p_hbox );
  189.             p_label->setAlignment( AlignHCenter | AlignVCenter );
  190.             p_label->setText( "Bar: baz quux" );
  191.         /* Create the slider and connect it to the date label */
  192.         p_slider = new IntfSlider( p_intf, p_vbox );
  193.         connect( p_slider, SIGNAL(valueChanged(int)),
  194.                  this, SLOT(DateDisplay(int)) );
  195.     /* The timer */
  196.     QTimer *p_timer = new QTimer( this );
  197.     connect( p_timer, SIGNAL(timeout()), this, SLOT(Manage()) );
  198.     p_timer->start( INTF_IDLE_SLEEP / 1000 );
  199.     /* Everything worked fine */
  200.     resize( 620, 30 );
  201. }
  202. /*****************************************************************************
  203.  * ~IntfWindow: interface window destructor
  204.  *****************************************************************************
  205.  * This function is called when the interface window is destroyed.
  206.  *****************************************************************************/
  207. IntfWindow::~IntfWindow( void )
  208. {
  209.     /* FIXME: remove everything cleanly */
  210. }
  211. /*****************************************************************************
  212.  * DateDisplay: display date
  213.  *****************************************************************************
  214.  * This function displays the current date in the date label.
  215.  *****************************************************************************/
  216. void IntfWindow::DateDisplay( int i_range )
  217. {
  218.     if( p_intf->p_sys->p_input )
  219.     {
  220.         char psz_time[ MSTRTIME_MAX_SIZE ];
  221.         int64_t i_seconds;
  222.         i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
  223.         secstotimestr( psz_time, i_seconds );
  224.         p_date->setText( psz_time );
  225.     }
  226. }
  227. /*****************************************************************************
  228.  * FileOpen: open a file
  229.  *****************************************************************************
  230.  * This function opens a file requester and adds the selected file to
  231.  * the playlist.
  232.  *****************************************************************************/
  233. void IntfWindow::FileOpen( void )
  234. {
  235.     playlist_t *p_playlist;
  236.     QString file = QFileDialog::getOpenFileName( QString::null,
  237.                                                  QString::null, this );
  238.     if( file.isEmpty() )
  239.     {
  240.         statusBar()->message( "No file loaded", 2000 );
  241.     }
  242.     else
  243.     {
  244.         p_playlist = (playlist_t *)
  245.                 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  246.         if( p_playlist == NULL )
  247.         {
  248.             return;
  249.         }
  250.         playlist_Add( p_playlist, file.latin1(), file.latin1(),
  251.                       PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
  252.         vlc_object_release( p_playlist );
  253.     }
  254. }
  255. /*****************************************************************************
  256.  * FileQuit: terminate vlc
  257.  *****************************************************************************/
  258. void IntfWindow::FileQuit( void )
  259. {
  260.     p_intf->p_vlc->b_die = VLC_TRUE;
  261. }
  262. /*****************************************************************************
  263.  * About: display the "about" box
  264.  *****************************************************************************
  265.  * This function displays a simple "about" box with copyright information.
  266.  *****************************************************************************/
  267. void IntfWindow::About( void )
  268. {
  269.     QMessageBox::about( this, "About",
  270.         "VLC media playern"
  271.         "(C) 1996 - 2004 - the VideoLAN Teamn"
  272.         "n"
  273.         "This is the VLC media player, a DVD and MPEG player.n"
  274.         "It can play MPEG and MPEG 2 files from a file "
  275.             "or from a network source.n"
  276.         "n"
  277.         "More information: http://www.videolan.org/" );
  278. }
  279. /*****************************************************************************
  280.  * Manage: manage main thread messages
  281.  *****************************************************************************
  282.  * In this function, called approx. 10 times a second, we check what the
  283.  * main program wanted to tell us.
  284.  *****************************************************************************/
  285. void IntfWindow::Manage( void )
  286. {
  287.     /* Update the input */
  288.     if( p_intf->p_sys->p_input == NULL )
  289.     {
  290.         p_intf->p_sys->p_input = (input_thread_t *)
  291.                 vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_ANYWHERE );
  292.     }
  293.     else if( p_intf->p_sys->p_input->b_dead )
  294.     {
  295.         vlc_object_release( p_intf->p_sys->p_input );
  296.         p_intf->p_sys->p_input = NULL;
  297.     }
  298.     /* Manage the slider */
  299.     if( p_intf->p_sys->p_input && p_intf->p_sys->p_input->stream.b_seekable )
  300.     {
  301.         int i_value = p_slider->value();
  302. #define p_area p_intf->p_sys->p_input->stream.p_selected_area
  303.         /* If the user hasn't touched the slider since the last time,
  304.          * then the input can safely change it */
  305.         if( i_value == p_slider->oldvalue() )
  306.         {
  307.             i_value = ( SLIDER_MAX * p_area->i_tell ) / p_area->i_size;
  308.             p_slider->setValue( i_value );
  309.             p_slider->setOldValue( i_value );
  310.         }
  311.         /* Otherwise, send message to the input if the user has
  312.          * finished dragging the slider */
  313.         else if( p_slider->b_free )
  314.         {
  315.             double f_pos = (double)i_value / (double)SLIDER_MAX;
  316.             var_SetFloat( p_intf->p_sys->p_input, "position", f_pos );
  317.             /* Update the old value */
  318.             p_slider->setOldValue( i_value );
  319.         }
  320. #undef p_area
  321.     }
  322.     /* If the "display popup" flag has changed, popup the context menu */
  323.     if( p_intf->b_menu_change )
  324.     {
  325.         p_popup->popup( QCursor::pos() );
  326.         p_intf->b_menu_change = 0;
  327.     }
  328.     if( p_intf->b_die )
  329.     {
  330.         qApp->quit();
  331.     }
  332. }
  333. /*****************************************************************************
  334.  * PlaybackPlay: play
  335.  *****************************************************************************/
  336. void IntfWindow::PlaybackPlay( void )
  337. {
  338.     if( p_intf->p_sys->p_input != NULL )
  339.     {
  340.         var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  341.     }
  342. }
  343. /*****************************************************************************
  344.  * PlaybackPause: pause
  345.  *****************************************************************************/
  346. void IntfWindow::PlaybackPause( void )
  347. {
  348.     if( p_intf->p_sys->p_input != NULL )
  349.     {
  350.         var_SetInteger( p_intf->p_sys->p_input, "state", PAUSE_S );
  351.     }
  352. }
  353. /*****************************************************************************
  354.  * PlaybackSlow: slow
  355.  *****************************************************************************/
  356. void IntfWindow::PlaybackSlow( void )
  357. {
  358.     if( p_intf->p_sys->p_input != NULL )
  359.     {
  360.         var_SetVoid( p_intf->p_sys->p_input, "rate-slower" );
  361.     }
  362. }
  363. /*****************************************************************************
  364.  * PlaybackFast: fast
  365.  *****************************************************************************/
  366. void IntfWindow::PlaybackFast( void )
  367. {
  368.     if( p_intf->p_sys->p_input != NULL )
  369.     {
  370.         var_SetVoid( p_intf->p_sys->p_input, "rate-faster" );
  371.     }
  372. }
  373. /*****************************************************************************
  374.  * PlaylistPrev: previous playlist entry
  375.  *****************************************************************************/
  376. void IntfWindow::PlaylistPrev( void )
  377. {
  378.     playlist_t *p_playlist = (playlist_t *)
  379.         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  380.     if( p_playlist == NULL )
  381.     {
  382.         return;
  383.     }
  384.     playlist_Prev( p_playlist );
  385.     vlc_object_release( p_playlist );
  386. }
  387. /*****************************************************************************
  388.  * PlaylistNext: next playlist entry
  389.  *****************************************************************************/
  390. void IntfWindow::PlaylistNext( void )
  391. {
  392.     playlist_t *p_playlist = (playlist_t *)
  393.         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  394.     if( p_playlist == NULL )
  395.     {
  396.         return;
  397.     }
  398.     playlist_Next( p_playlist );
  399.     vlc_object_release( p_playlist );
  400. }
  401. /*****************************************************************************
  402.  * IntfSlider: slider creator
  403.  *****************************************************************************
  404.  * This function creates the slider, sets its default values, and connects
  405.  * the interesting signals.
  406.  *****************************************************************************/
  407. IntfSlider::IntfSlider( intf_thread_t *p_intf, QWidget *p_parent )
  408.            :QSlider( Horizontal, p_parent )
  409. {
  410.     this->p_intf = p_intf;
  411.     setRange( SLIDER_MIN, SLIDER_MAX );
  412.     setPageStep( SLIDER_STEP );
  413.     setValue( SLIDER_MIN );
  414.     setOldValue( SLIDER_MIN );
  415.     setTracking( TRUE );
  416.     b_free = TRUE;
  417.     connect( this, SIGNAL(sliderMoved(int)), this, SLOT(SlideStart()) );
  418.     connect( this, SIGNAL(sliderPressed()), this, SLOT(SlideStart()) );
  419.     connect( this, SIGNAL(sliderReleased()), this, SLOT(SlideStop()) );
  420. }
  421. /*****************************************************************************
  422.  * ~IntfSlider: slider destructor
  423.  *****************************************************************************
  424.  * This function is called when the interface slider is destroyed.
  425.  *****************************************************************************/
  426. IntfSlider::~IntfSlider( void )
  427. {
  428.     /* We don't need to remove anything */
  429. }