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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * input_manager.cpp : Manage an input and interact with its GUI elements
  3.  ****************************************************************************
  4.  * Copyright (C) 2006-2008 the VideoLAN team
  5.  * $Id: d032f55b19d2e55dbf8a58fc3d9d70e9470c861e $
  6.  *
  7.  * Authors: Clément Stenac <zorglub@videolan.org>
  8.  *          Ilkka Ollakka  <ileoo@videolan.org>
  9.  *          Jean-Baptiste <jb@videolan.org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. #ifdef HAVE_CONFIG_H
  26. # include "config.h"
  27. #endif
  28. #include "input_manager.hpp"
  29. #include <vlc_keys.h>
  30. #include <vlc_url.h>
  31. #include <QApplication>
  32. #include <assert.h>
  33. static int ItemChanged( vlc_object_t *, const char *,
  34.                         vlc_value_t, vlc_value_t, void * );
  35. static int PLItemChanged( vlc_object_t *, const char *,
  36.                         vlc_value_t, vlc_value_t, void * );
  37. static int VolumeChanged( vlc_object_t *, const char *,
  38.                         vlc_value_t, vlc_value_t, void * );
  39. static int InputEvent( vlc_object_t *, const char *,
  40.                        vlc_value_t, vlc_value_t, void * );
  41. static int VbiEvent( vlc_object_t *, const char *,
  42.                      vlc_value_t, vlc_value_t, void * );
  43. /**********************************************************************
  44.  * InputManager implementation
  45.  **********************************************************************
  46.  * The Input Manager can be the main one around the playlist
  47.  * But can also be used for VLM dialog or similar
  48.  **********************************************************************/
  49. InputManager::InputManager( QObject *parent, intf_thread_t *_p_intf) :
  50.                            QObject( parent ), p_intf( _p_intf )
  51. {
  52.     i_old_playing_status = END_S;
  53.     oldName      = "";
  54.     artUrl       = "";
  55.     p_input      = NULL;
  56.     i_rate       = 0;
  57.     i_input_id   = 0;
  58.     b_video      = false;
  59.     timeA        = 0;
  60.     timeB        = 0;
  61.     f_cache      = -1.; /* impossible initial value, different from all */
  62. }
  63. InputManager::~InputManager()
  64. {
  65.     delInput();
  66. }
  67. /* Define the Input used.
  68.    Add the callbacks on input
  69.    p_input is held once here */
  70. void InputManager::setInput( input_thread_t *_p_input )
  71. {
  72.     delInput();
  73.     p_input = _p_input;
  74.     if( p_input && !( p_input->b_dead || !vlc_object_alive (p_input) ) )
  75.     {
  76.         msg_Dbg( p_intf, "IM: Setting an input" );
  77.         vlc_object_hold( p_input );
  78.         emit statusChanged( PLAYING_S );
  79.         UpdateName();
  80.         UpdateArt();
  81.         UpdateTeletext();
  82.         UpdateNavigation();
  83.         UpdateVout();
  84.         addCallbacks();
  85.         i_input_id = input_GetItem( p_input )->i_id;
  86.     }
  87.     else
  88.     {
  89.         p_input = NULL;
  90.         i_input_id = 0;
  91.         emit rateChanged( INPUT_RATE_DEFAULT );
  92.     }
  93. }
  94. /* delete Input if it ever existed.
  95.    Delete the callbacls on input
  96.    p_input is released once here */
  97. void InputManager::delInput()
  98. {
  99.     if( !p_input ) return;
  100.     msg_Dbg( p_intf, "IM: Deleting the input" );
  101.     delCallbacks();
  102.     i_old_playing_status = END_S;
  103.     i_input_id           = 0;
  104.     oldName              = "";
  105.     artUrl               = "";
  106.     b_video              = false;
  107.     timeA                = 0;
  108.     timeB                = 0;
  109.     vlc_object_release( p_input );
  110.     p_input = NULL;
  111.     emit positionUpdated( -1.0, 0 ,0 );
  112.     emit rateChanged( INPUT_RATE_DEFAULT ); /* TODO: Do we want this ? */
  113.     emit nameChanged( "" );
  114.     emit chapterChanged( 0 );
  115.     emit titleChanged( 0 );
  116.     emit statusChanged( END_S );
  117.     emit teletextPossible( false );
  118.     emit AtoBchanged( false, false );
  119.     emit voutChanged( false );
  120.     emit voutListChanged( NULL, 0 );
  121.     /* Reset all InfoPanels but stats */
  122.     emit artChanged( NULL );
  123.     emit infoChanged( NULL );
  124.     emit metaChanged( (input_item_t *)NULL );
  125.     emit encryptionChanged( false );
  126.     emit recordingStateChanged( false );
  127. }
  128. /* Convert the event from the callbacks in actions */
  129. void InputManager::customEvent( QEvent *event )
  130. {
  131.     int i_type = event->type();
  132.     IMEvent *ple = static_cast<IMEvent *>(event);
  133.     if( i_type == ItemChanged_Type )
  134.         UpdateMeta( ple->i_id );
  135.     if( !hasInput() )
  136.         return;
  137. #ifndef NDEBUG
  138.     if( i_type != PositionUpdate_Type &&
  139.         i_type != StatisticsUpdate_Type &&
  140.         i_type != ItemChanged_Type )
  141.         msg_Dbg( p_intf, "New Event: type %i", i_type );
  142. #endif
  143.     /* Actions */
  144.     switch( i_type )
  145.     {
  146.     case PositionUpdate_Type:
  147.         UpdatePosition();
  148.         break;
  149.     case StatisticsUpdate_Type:
  150.         UpdateStats();
  151.         break;
  152.     case ItemChanged_Type:
  153.         /* Ignore ItemChanged_Type event that does not apply to our input */
  154.         if( i_input_id == ple->i_id )
  155.         {
  156.             UpdateStatus();
  157.             // UpdateName();
  158.             UpdateArt();
  159.             /* Update duration of file */
  160.         }
  161.         break;
  162.     case ItemStateChanged_Type:
  163.         // TODO: Fusion with above state
  164.         UpdateStatus();
  165.         // UpdateName();
  166.         // UpdateNavigation(); This shouldn't be useful now
  167.         // UpdateTeletext(); Same
  168.         break;
  169.     case NameChanged_Type:
  170.         UpdateName();
  171.         break;
  172.     case MetaChanged_Type:
  173.         UpdateMeta();
  174.         UpdateName(); /* Needed for NowPlaying */
  175.         UpdateArt(); /* Art is part of meta in the core */
  176.         break;
  177.     case InfoChanged_Type:
  178.         UpdateInfo();
  179.         break;
  180.     case ItemTitleChanged_Type:
  181.         UpdateNavigation();
  182.         UpdateName(); /* Display the name of the Chapter, if exists */
  183.         break;
  184.     case ItemRateChanged_Type:
  185.         UpdateRate();
  186.         break;
  187.     case ItemEsChanged_Type:
  188.         UpdateTeletext();
  189.         // We don't do anything ES related. Why ?
  190.         break;
  191.     case ItemTeletextChanged_Type:
  192.         UpdateTeletext();
  193.         break;
  194.     case InterfaceVoutUpdate_Type:
  195.         UpdateVout();
  196.         break;
  197.     case SynchroChanged_Type:
  198.         emit synchroChanged();
  199.         break;
  200.     case CachingEvent_Type:
  201.         UpdateCaching();
  202.         break;
  203.     case BookmarksChanged_Type:
  204.         emit bookmarksChanged();
  205.         break;
  206.     case InterfaceAoutUpdate_Type:
  207.         UpdateAout();
  208.         break;
  209.     case RecordingEvent_Type:
  210.         UpdateRecord();
  211.         break;
  212.     case ProgramChanged_Type:
  213.         UpdateProgramEvent();
  214.         break;
  215.     default:
  216.         msg_Warn( p_intf, "This shouldn't happen: %i", i_type );
  217.         assert(0);
  218.     }
  219. }
  220. /* Add the callbacks on Input. Self explanatory */
  221. inline void InputManager::addCallbacks()
  222. {
  223.     var_AddCallback( p_input, "intf-event", InputEvent, this );
  224. }
  225. /* Delete the callbacks on Input. Self explanatory */
  226. inline void InputManager::delCallbacks()
  227. {
  228.     var_DelCallback( p_input, "intf-event", InputEvent, this );
  229. }
  230. /* Static callbacks for IM */
  231. static int ItemChanged( vlc_object_t *p_this, const char *psz_var,
  232.                         vlc_value_t oldval, vlc_value_t newval, void *param )
  233. {
  234.     InputManager *im = (InputManager*)param;
  235.     IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int );
  236.     QApplication::postEvent( im, event );
  237.     return VLC_SUCCESS;
  238. }
  239. static int InputEvent( vlc_object_t *p_this, const char *,
  240.                        vlc_value_t, vlc_value_t newval, void *param )
  241. {
  242.     InputManager *im = (InputManager*)param;
  243.     IMEvent *event;
  244.     switch( newval.i_int )
  245.     {
  246.     case INPUT_EVENT_STATE:
  247.         event = new IMEvent( ItemStateChanged_Type, 0 );
  248.         break;
  249.     case INPUT_EVENT_RATE:
  250.         event = new IMEvent( ItemRateChanged_Type, 0 );
  251.         break;
  252.     case INPUT_EVENT_TIMES:
  253.         event = new IMEvent( PositionUpdate_Type, 0 );
  254.         break;
  255.     case INPUT_EVENT_TITLE:
  256.     case INPUT_EVENT_CHAPTER:
  257.         event = new IMEvent( ItemTitleChanged_Type, 0 );
  258.         break;
  259.     case INPUT_EVENT_ES:
  260.         event = new IMEvent( ItemEsChanged_Type, 0 );
  261.         break;
  262.     case INPUT_EVENT_TELETEXT:
  263.         event = new IMEvent( ItemTeletextChanged_Type, 0 );
  264.         break;
  265.     case INPUT_EVENT_STATISTICS:
  266.         event = new IMEvent( StatisticsUpdate_Type, 0 );
  267.         break;
  268.     case INPUT_EVENT_VOUT:
  269.         event = new IMEvent( InterfaceVoutUpdate_Type, 0 );
  270.         break;
  271.     case INPUT_EVENT_AOUT:
  272.         event = new IMEvent( InterfaceAoutUpdate_Type, 0 );
  273.         break;
  274.     case INPUT_EVENT_ITEM_META: /* Codec MetaData + Art */
  275.         event = new IMEvent( MetaChanged_Type, 0 );
  276.         break;
  277.     case INPUT_EVENT_ITEM_INFO: /* Codec Info */
  278.         event = new IMEvent( InfoChanged_Type, 0 );
  279.         break;
  280.     case INPUT_EVENT_ITEM_NAME:
  281.         event = new IMEvent( NameChanged_Type, 0 );
  282.         break;
  283.     case INPUT_EVENT_AUDIO_DELAY:
  284.     case INPUT_EVENT_SUBTITLE_DELAY:
  285.         event = new IMEvent( SynchroChanged_Type, 0 );
  286.         break;
  287.     case INPUT_EVENT_CACHE:
  288.         event = new IMEvent( CachingEvent_Type, 0 );
  289.         break;
  290.     case INPUT_EVENT_BOOKMARK:
  291.         event = new IMEvent( BookmarksChanged_Type, 0 );
  292.         break;
  293.     case INPUT_EVENT_RECORD:
  294.         event = new IMEvent( RecordingEvent_Type, 0 );
  295.         break;
  296.     case INPUT_EVENT_PROGRAM:
  297.         /* This is for PID changes */
  298.         event = new IMEvent( ProgramChanged_Type, 0 );
  299.         break;
  300.     case INPUT_EVENT_SIGNAL:
  301.         /* This is for capture-card signals */
  302.         /* event = new IMEvent( SignalChanged_Type, 0 );
  303.         break; */
  304.     default:
  305.         event = NULL;
  306.         break;
  307.     }
  308.     if( event )
  309.         QApplication::postEvent( im, event );
  310.     return VLC_SUCCESS;
  311. }
  312. static int VbiEvent( vlc_object_t *, const char *,
  313.                      vlc_value_t, vlc_value_t, void *param )
  314. {
  315.     InputManager *im = (InputManager*)param;
  316.     IMEvent *event = new IMEvent( ItemTeletextChanged_Type, 0 );
  317.     QApplication::postEvent( im, event );
  318.     return VLC_SUCCESS;
  319. }
  320. void InputManager::UpdatePosition()
  321. {
  322.     /* Update position */
  323.     int i_length, i_time; /* Int is enough, since we store seconds */
  324.     float f_pos;
  325.     i_length = var_GetTime(  p_input , "length" ) / 1000000;
  326.     i_time = var_GetTime(  p_input , "time") / 1000000;
  327.     f_pos = var_GetFloat(  p_input , "position" );
  328.     emit positionUpdated( f_pos, i_time, i_length );
  329. }
  330. void InputManager::UpdateNavigation()
  331. {
  332.     /* Update navigation status */
  333.     vlc_value_t val; val.i_int = 0;
  334.     if( hasInput() )
  335.         var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
  336.     if( val.i_int > 0 )
  337.     {
  338.         emit titleChanged( true );
  339.         msg_Dbg( p_intf, "Title %i", val.i_int );
  340.         /* p_input != NULL since val.i_int != 0 */
  341.         val.i_int = 0;
  342.         var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
  343.         emit chapterChanged( (val.i_int > 0) );
  344.         msg_Dbg( p_intf, "Chapter: %i", val.i_int );
  345.     }
  346.     else
  347.         emit titleChanged( false );
  348. }
  349. void InputManager::UpdateStatus()
  350. {
  351.     /* Update playing status */
  352.     vlc_value_t val; val.i_int = 0;
  353.     var_Get( p_input, "state", &val );
  354.     if( i_old_playing_status != val.i_int )
  355.     {
  356.         i_old_playing_status = val.i_int;
  357.         emit statusChanged( val.i_int );
  358.     }
  359. }
  360. void InputManager::UpdateRate()
  361. {
  362.     /* Update Rate */
  363.     int i_new_rate = var_GetInteger( p_input, "rate");
  364.     if( i_new_rate != i_rate )
  365.     {
  366.         i_rate = i_new_rate;
  367.         /* Update rate */
  368.         emit rateChanged( i_rate );
  369.     }
  370. }
  371. void InputManager::UpdateName()
  372. {
  373.     /* Update text, name and nowplaying */
  374.     QString text;
  375.     /* Try to get the Title, then the Name */
  376.     char *psz_name = input_item_GetTitleFbName( input_GetItem( p_input ) );
  377.     /* Try to get the nowplaying */
  378.     char *psz_nowplaying =
  379.         input_item_GetNowPlaying( input_GetItem( p_input ) );
  380.     if( !EMPTY_STR( psz_nowplaying ) )
  381.     {
  382.         text.sprintf( "%s - %s", psz_nowplaying, psz_name );
  383.     }
  384.     else  /* Do it ourself */
  385.     {
  386.         char *psz_artist = input_item_GetArtist( input_GetItem( p_input ) );
  387.         if( !EMPTY_STR( psz_artist ) )
  388.             text.sprintf( "%s - %s", psz_artist, psz_name );
  389.         else
  390.             text.sprintf( "%s", psz_name );
  391.         free( psz_artist );
  392.     }
  393.     /* Free everything */
  394.     free( psz_name );
  395.     free( psz_nowplaying );
  396.     /* If we have Nothing */
  397.     if( text.isEmpty() )
  398.     {
  399.         psz_name = input_item_GetURI( input_GetItem( p_input ) );
  400.         text.sprintf( "%s", psz_name );
  401.         text = text.remove( 0, text.lastIndexOf( DIR_SEP ) + 1 );
  402.         free( psz_name );
  403.     }
  404.     if( oldName != text )
  405.     {
  406.         emit nameChanged( text );
  407.         oldName = text;
  408.     }
  409. }
  410. bool InputManager::hasAudio()
  411. {
  412.     if( hasInput() )
  413.     {
  414.         vlc_value_t val;
  415.         var_Change( p_input, "audio-es", VLC_VAR_CHOICESCOUNT, &val, NULL );
  416.         return val.i_int > 0;
  417.     }
  418.     return false;
  419. }
  420. void InputManager::UpdateTeletext()
  421. {
  422.     if( hasInput() )
  423.     {
  424.         const bool b_enabled = var_CountChoices( p_input, "teletext-es" ) > 0;
  425.         const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
  426.         /* Teletext is possible. Show the buttons */
  427.         emit teletextPossible( b_enabled );
  428.         /* If Teletext is selected */
  429.         if( b_enabled && i_teletext_es >= 0 )
  430.         {
  431.             /* Then, find the current page */
  432.             int i_page = 100;
  433.             bool b_transparent = false;
  434.             vlc_object_t *p_vbi = (vlc_object_t *)
  435.                 vlc_object_find_name( p_input, "zvbi", FIND_CHILD );
  436.             if( p_vbi )
  437.             {
  438.                 /* We deleted it (if not here, it does not harm), because
  439.                  * var_AddCallback will silently add a duplicated one */
  440.                 var_DelCallback( p_vbi, "vbi-page", VbiEvent, this );
  441.                 /* This callback is not remove explicitly, but interfaces
  442.                  * are guaranted to outlive input */
  443.                 var_AddCallback( p_vbi, "vbi-page", VbiEvent, this );
  444.                 i_page = var_GetInteger( p_vbi, "vbi-page" );
  445.                 b_transparent = !var_GetBool( p_vbi, "vbi-opaque" );
  446.                 vlc_object_release( p_vbi );
  447.             }
  448.             emit newTelexPageSet( i_page );
  449.             emit teletextTransparencyActivated( b_transparent );
  450.         }
  451.         emit teletextActivated( b_enabled && i_teletext_es >= 0 );
  452.     }
  453.     else
  454.     {
  455.         emit teletextActivated( false );
  456.         emit teletextPossible( false );
  457.     }
  458. }
  459. void InputManager::UpdateVout()
  460. {
  461.     if( hasInput() )
  462.     {
  463.         /* Get current vout lists from input */
  464.         int i_vout;
  465.         vout_thread_t **pp_vout;
  466.         if( input_Control( p_input, INPUT_GET_VOUTS, &pp_vout, &i_vout ) )
  467.         {
  468.             i_vout = 0;
  469.             pp_vout = NULL;
  470.         }
  471.         /* */
  472.         emit voutListChanged( pp_vout, i_vout );
  473.         /* */
  474.         bool b_old_video = b_video;
  475.         b_video = i_vout > 0;
  476.         if( !!b_old_video != !!b_video )
  477.             emit voutChanged( b_video );
  478.         /* Release the vout list */
  479.         for( int i = 0; i < i_vout; i++ )
  480.             vlc_object_release( (vlc_object_t*)pp_vout[i] );
  481.         free( pp_vout );
  482.     }
  483. }
  484. void InputManager::UpdateAout()
  485. {
  486.     if( hasInput() )
  487.     {
  488.         /* TODO */
  489.     }
  490. }
  491. void InputManager::UpdateCaching()
  492. {
  493.     if(!hasInput()) return;
  494.     float f_newCache = var_GetFloat ( p_input, "cache" );
  495.     if( f_newCache != f_cache )
  496.     {
  497.         f_cache = f_newCache;
  498.         /* Update rate */
  499.         emit cachingChanged( f_cache );
  500.     }
  501. }
  502. void InputManager::requestArtUpdate()
  503. {
  504.     if( hasInput() )
  505.     {
  506.         playlist_t *p_playlist = pl_Hold( p_intf );
  507.         playlist_AskForArtEnqueue( p_playlist, input_GetItem( p_input ), pl_Unlocked );
  508.         pl_Release( p_intf );
  509.     }
  510.     else
  511.     {
  512.         /* No input will signal the cover art to update,
  513.          * let's do it ourself */
  514.         UpdateArt();
  515.     }
  516. }
  517. void InputManager::UpdateArt()
  518. {
  519.     QString url;
  520.     if( hasInput() )
  521.     {
  522.         char *psz_art = input_item_GetArtURL( input_GetItem( p_input ) );
  523.         if( psz_art && !strncmp( psz_art, "file://", 7 ) &&
  524.                 decode_URI( psz_art + 7 ) )
  525. #ifdef WIN32
  526.             url = qfu( psz_art + 8 ); // Remove extra / starting on Win32.
  527. #else
  528.             url = qfu( psz_art + 7 );
  529. #endif
  530.         free( psz_art );
  531.     }
  532.     /* Update Art meta */
  533.     emit artChanged( url );
  534. }
  535. inline void InputManager::UpdateStats()
  536. {
  537.     emit statisticsUpdated( input_GetItem( p_input ) );
  538. }
  539. inline void InputManager::UpdateMeta( int id )
  540. {
  541.     emit metaChanged( id );
  542. }
  543. inline void InputManager::UpdateMeta()
  544. {
  545.     emit metaChanged( input_GetItem( p_input ) );
  546. }
  547. inline void InputManager::UpdateInfo()
  548. {
  549.     emit infoChanged( input_GetItem( p_input ) );
  550. }
  551. void InputManager::UpdateRecord()
  552. {
  553.     if( hasInput() )
  554.     {
  555.         emit recordingStateChanged( var_GetBool( p_input, "record" ) );
  556.     }
  557. }
  558. void InputManager::UpdateProgramEvent()
  559. {
  560.     if( hasInput() )
  561.     {
  562.         bool b_scrambled = var_GetBool( p_input, "program-scrambled" );
  563.         emit encryptionChanged( b_scrambled );
  564.     }
  565. }
  566. /* User update of the slider */
  567. void InputManager::sliderUpdate( float new_pos )
  568. {
  569.     if( hasInput() )
  570.         var_SetFloat( p_input, "position", new_pos );
  571. }
  572. /* User togglePlayPause */
  573. void InputManager::togglePlayPause()
  574. {
  575.     if( hasInput() )
  576.     {
  577.         int state = var_GetInteger( p_input, "state" );
  578.         state = ( state != PLAYING_S ) ? PLAYING_S : PAUSE_S;
  579.         var_SetInteger( p_input, "state", state );
  580.         emit statusChanged( state );
  581.     }
  582. }
  583. void InputManager::sectionPrev()
  584. {
  585.     if( hasInput() )
  586.     {
  587.         int i_type = var_Type( p_input, "next-chapter" );
  588.         var_SetVoid( p_input, (i_type & VLC_VAR_TYPE) != 0 ?
  589.                             "prev-chapter":"prev-title" );
  590.     }
  591. }
  592. void InputManager::sectionNext()
  593. {
  594.     if( hasInput() )
  595.     {
  596.         int i_type = var_Type( p_input, "next-chapter" );
  597.         var_SetVoid( p_input, (i_type & VLC_VAR_TYPE) != 0 ?
  598.                             "next-chapter":"next-title" );
  599.     }
  600. }
  601. void InputManager::sectionMenu()
  602. {
  603.     if( hasInput() )
  604.     {
  605.         vlc_value_t val, text;
  606.         if( var_Change( p_input, "title  0", VLC_VAR_GETLIST, &val, &text ) < 0 )
  607.             return;
  608.         /* XXX is it "Root" or "Title" we want here ?" (set 0 by default) */
  609.         int root = 0;
  610.         for( int i = 0; i < val.p_list->i_count; i++ )
  611.         {
  612.             if( !strcmp( text.p_list->p_values[i].psz_string, "Title" ) )
  613.                 root = i;
  614.         }
  615.         var_Change( p_input, "title  0", VLC_VAR_FREELIST, &val, &text );
  616.         var_SetInteger( p_input, "title  0", root );
  617.     }
  618. }
  619. /*
  620.  *  Teletext Functions
  621.  */
  622. /* Set a new Teletext Page */
  623. void InputManager::telexSetPage( int page )
  624. {
  625.     if( hasInput() )
  626.     {
  627.         const int i_teletext_es = var_GetInteger( p_input, "teletext-es" );
  628.         if( i_teletext_es >= 0 )
  629.         {
  630.             vlc_object_t *p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
  631.                         "zvbi", FIND_CHILD );
  632.             if( p_vbi )
  633.             {
  634.                 var_SetInteger( p_vbi, "vbi-page", page );
  635.                 vlc_object_release( p_vbi );
  636.                 emit newTelexPageSet( page );
  637.             }
  638.         }
  639.     }
  640. }
  641. /* Set the transparency on teletext */
  642. void InputManager::telexSetTransparency( bool b_transparentTelextext )
  643. {
  644.     if( hasInput() )
  645.     {
  646.         vlc_object_t *p_vbi = (vlc_object_t *) vlc_object_find_name( p_input,
  647.                     "zvbi", FIND_CHILD );
  648.         if( p_vbi )
  649.         {
  650.             var_SetBool( p_vbi, "vbi-opaque", !b_transparentTelextext );
  651.             vlc_object_release( p_vbi );
  652.             emit teletextTransparencyActivated( b_transparentTelextext );
  653.         }
  654.     }
  655. }
  656. void InputManager::activateTeletext( bool b_enable )
  657. {
  658.     vlc_value_t list;
  659.     vlc_value_t text;
  660.     if( hasInput() && !var_Change( p_input, "teletext-es", VLC_VAR_GETLIST, &list, &text ) )
  661.     {
  662.         if( list.p_list->i_count > 0 )
  663.         {
  664.             /* Prefer the page 100 if it is present */
  665.             int i;
  666.             for( i = 0; i < text.p_list->i_count; i++ )
  667.             {
  668.                 /* The description is the page number as a string */
  669.                 const char *psz_page = text.p_list->p_values[i].psz_string;
  670.                 if( psz_page && !strcmp( psz_page, "100" ) )
  671.                     break;
  672.             }
  673.             if( i >= list.p_list->i_count )
  674.                 i = 0;
  675.             var_SetInteger( p_input, "spu-es", b_enable ? list.p_list->p_values[i].i_int : -1 );
  676.         }
  677.         var_Change( p_input, "teletext-es", VLC_VAR_FREELIST, &list, &text );
  678.     }
  679. }
  680. void InputManager::reverse()
  681. {
  682.     if( hasInput() )
  683.     {
  684.         int i_rate = var_GetInteger( p_input, "rate" );
  685.         var_SetInteger( p_input, "rate", -i_rate );
  686.     }
  687. }
  688. void InputManager::slower()
  689. {
  690.     if( hasInput() )
  691.         var_SetVoid( p_input, "rate-slower" );
  692. }
  693. void InputManager::faster()
  694. {
  695.     if( hasInput() )
  696.         var_SetVoid( p_input, "rate-faster" );
  697. }
  698. void InputManager::littlefaster()
  699. {
  700.     var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_RATE_FASTER_FINE );
  701. }
  702. void InputManager::littleslower()
  703. {
  704.     var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_RATE_SLOWER_FINE );
  705. }
  706. void InputManager::normalRate()
  707. {
  708.     if( hasInput() )
  709.         var_SetInteger( p_input, "rate", INPUT_RATE_DEFAULT );
  710. }
  711. void InputManager::setRate( int new_rate )
  712. {
  713.     if( hasInput() )
  714.         var_SetInteger( p_input, "rate", new_rate );
  715. }
  716. void InputManager::jumpFwd()
  717. {
  718.     int i_interval = config_GetInt( p_input, "short-jump-size" );
  719.     if( i_interval > 0 )
  720.     {
  721.         mtime_t val = (mtime_t)(i_interval) * 1000000L;
  722.         var_SetTime( p_input, "time-offset", val );
  723.     }
  724. }
  725. void InputManager::jumpBwd()
  726. {
  727.     int i_interval = config_GetInt( p_input, "short-jump-size" );
  728.     if( i_interval > 0 )
  729.     {
  730.         mtime_t val = -1 *(mtime_t)(i_interval) * 1000000L;
  731.         var_SetTime( p_input, "time-offset", val );
  732.     }
  733. }
  734. void InputManager::setAtoB()
  735. {
  736.     if( !timeA )
  737.     {
  738.         timeA = var_GetTime( THEMIM->getInput(), "time"  );
  739.     }
  740.     else if( !timeB )
  741.     {
  742.         timeB = var_GetTime( THEMIM->getInput(), "time"  );
  743.         var_SetTime( THEMIM->getInput(), "time" , timeA );
  744.         CONNECT( this, positionUpdated( float, int, int ),
  745.                  this, AtoBLoop( float, int, int ) );
  746.     }
  747.     else
  748.     {
  749.         timeA = 0;
  750.         timeB = 0;
  751.         disconnect( this, SIGNAL( positionUpdated( float, int, int ) ),
  752.                     this, SLOT( AtoBLoop( float, int, int ) ) );
  753.     }
  754.     emit AtoBchanged( (timeA != 0 ), (timeB != 0 ) );
  755. }
  756. /* Function called regularly when in an AtoB loop */
  757. void InputManager::AtoBLoop( float, int i_time, int )
  758. {
  759.     if( timeB )
  760.     {
  761.         if( ( i_time >= (int)( timeB/1000000 ) )
  762.             || ( i_time < (int)( timeA/1000000 ) ) )
  763.             var_SetTime( THEMIM->getInput(), "time" , timeA );
  764.     }
  765. }
  766. /**********************************************************************
  767.  * MainInputManager implementation. Wrap an input manager and
  768.  * take care of updating the main playlist input.
  769.  * Used in the main playlist Dialog
  770.  **********************************************************************/
  771. MainInputManager * MainInputManager::instance = NULL;
  772. MainInputManager::MainInputManager( intf_thread_t *_p_intf )
  773.                  : QObject(NULL), p_intf( _p_intf )
  774. {
  775.     p_input = NULL;
  776.     im = new InputManager( this, p_intf );
  777.     var_AddCallback( THEPL, "item-change", ItemChanged, im );
  778.     var_AddCallback( THEPL, "item-current", PLItemChanged, this );
  779.     var_AddCallback( THEPL, "activity", PLItemChanged, this );
  780.     var_AddCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this );
  781.     /* Warn our embedded IM about input changes */
  782.     CONNECT( this, inputChanged( input_thread_t * ),
  783.              im, setInput( input_thread_t * ) );
  784.     /* emit check if playlist has already started playing */
  785.     IMEvent *event = new IMEvent( ItemChanged_Type,
  786.                                   var_GetInteger( THEPL, "item-current" ) );
  787.     customEvent( event );
  788.     delete event;
  789. }
  790. MainInputManager::~MainInputManager()
  791. {
  792.     if( p_input )
  793.     {
  794.        emit inputChanged( NULL );
  795.        var_DelCallback( p_input, "state", PLItemChanged, this );
  796.        vlc_object_release( p_input );
  797.     }
  798.     var_DelCallback( p_intf->p_libvlc, "volume-change", VolumeChanged, this );
  799.     var_DelCallback( THEPL, "activity", PLItemChanged, this );
  800.     var_DelCallback( THEPL, "item-change", ItemChanged, im );
  801.     var_DelCallback( THEPL, "item-current", PLItemChanged, this );
  802. }
  803. vout_thread_t* MainInputManager::getVout()
  804. {
  805.     return p_input ? input_GetVout( p_input ) : NULL;
  806. }
  807. aout_instance_t * MainInputManager::getAout()
  808. {
  809.     return p_input ? input_GetAout( p_input ) : NULL;
  810. }
  811. void MainInputManager::customEvent( QEvent *event )
  812. {
  813.     int type = event->type();
  814.     if ( type != ItemChanged_Type && type != VolumeChanged_Type )
  815.         return;
  816.     // msg_Dbg( p_intf, "New MainIM Event of type: %i", type );
  817.     if( type == VolumeChanged_Type )
  818.     {
  819.         emit volumeChanged();
  820.         return;
  821.     }
  822.     /* Should be PLItemChanged Event */
  823.     if( !p_intf->p_sys->b_isDialogProvider )
  824.     {
  825.         if( p_input && ( p_input->b_dead || !vlc_object_alive (p_input) ) )
  826.         {
  827.             emit inputChanged( p_input );
  828.             var_DelCallback( p_input, "state", PLItemChanged, this );
  829.             vlc_object_release( p_input );
  830.             p_input = NULL;
  831.             return;
  832.         }
  833.         if( !p_input )
  834.         {
  835.             p_input = playlist_CurrentInput(THEPL);
  836.             if( p_input )
  837.             {
  838.                 var_AddCallback( p_input, "state", PLItemChanged, this );
  839.                 emit inputChanged( p_input );
  840.             }
  841.         }
  842.     }
  843.     else
  844.     {
  845.         /* remove previous stored p_input */
  846.         if( p_input )
  847.         {
  848.             vlc_object_release( p_input );
  849.             p_input = NULL;
  850.         }
  851.         /* we are working as a dialogs provider */
  852.         playlist_t *p_playlist = pl_Hold( p_intf );
  853.         p_input = playlist_CurrentInput( p_playlist );
  854.         if( p_input )
  855.         {
  856.             emit inputChanged( p_input );
  857.         }
  858.         pl_Release( p_intf );
  859.     }
  860. }
  861. /* Playlist Control functions */
  862. void MainInputManager::stop()
  863. {
  864.    playlist_Stop( THEPL );
  865. }
  866. void MainInputManager::next()
  867. {
  868.    playlist_Next( THEPL );
  869. }
  870. void MainInputManager::prev()
  871. {
  872.    playlist_Prev( THEPL );
  873. }
  874. void MainInputManager::togglePlayPause()
  875. {
  876.     /* No input, play */
  877.     if( !p_input )
  878.         playlist_Play( THEPL );
  879.     else
  880.         getIM()->togglePlayPause();
  881. }
  882. void MainInputManager::activatePlayQuit( bool b_exit )
  883. {
  884.     var_SetBool( THEPL, "play-and-exit", b_exit );
  885. }
  886. /* Static callbacks for MIM */
  887. static int PLItemChanged( vlc_object_t *p_this, const char *psz_var,
  888.                         vlc_value_t oldval, vlc_value_t newval, void *param )
  889. {
  890.     MainInputManager *mim = (MainInputManager*)param;
  891.     IMEvent *event = new IMEvent( ItemChanged_Type, newval.i_int );
  892.     QApplication::postEvent( mim, event );
  893.     return VLC_SUCCESS;
  894. }
  895. static int VolumeChanged( vlc_object_t *p_this, const char *psz_var,
  896.                         vlc_value_t oldval, vlc_value_t newval, void *param )
  897. {
  898.     MainInputManager *mim = (MainInputManager*)param;
  899.     IMEvent *event = new IMEvent( VolumeChanged_Type, newval.i_int );
  900.     QApplication::postEvent( mim, event );
  901.     return VLC_SUCCESS;
  902. }