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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * intf.c: Video CD interface to handle user interaction and still time
  3.  *****************************************************************************
  4.  * Copyright (C) 2002,2003 VideoLAN
  5.  * $Id: intf.c 7936 2004-06-07 18:32:12Z fenrir $
  6.  *
  7.  * Author: Rocky Bernstein <rocky@panix.com>
  8.  *   from DVD code by St閜hane Borel <stef@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <vlc/vlc.h>
  28. #include <vlc/intf.h>
  29. #include "stream_control.h"
  30. #include "input_ext-intf.h"
  31. #include "input_ext-dec.h"
  32. #include "vlc_keys.h"
  33. #include "vcd.h"
  34. #include "vcdplayer.h"
  35. #include "intf.h"
  36. /*****************************************************************************
  37.  * Local prototypes.
  38.  *****************************************************************************/
  39. static int  InitThread     ( intf_thread_t *p_intf );
  40. static int  KeyEvent       ( vlc_object_t *, char const *,
  41.                              vlc_value_t, vlc_value_t, void * );
  42. /* Exported functions */
  43. static void RunIntf        ( intf_thread_t *p_intf );
  44. /*****************************************************************************
  45.  * OpenIntf: initialize dummy interface
  46.  *****************************************************************************/
  47. int E_(OpenIntf) ( vlc_object_t *p_this )
  48. {
  49.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  50.     msg_Dbg( p_intf, "VCDOpenIntf" );
  51.     /* Allocate instance and initialize some members */
  52.     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  53.     if( p_intf->p_sys == NULL )
  54.     {
  55.         return( 1 );
  56.     };
  57.     p_intf->pf_run = RunIntf;
  58.     var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
  59.     p_intf->p_sys->m_still_time = 0;
  60.     p_intf->p_sys->b_inf_still = 0;
  61.     p_intf->p_sys->b_still = 0;
  62.     return( 0 );
  63. }
  64. /*****************************************************************************
  65.  * CloseIntf: destroy dummy interface
  66.  *****************************************************************************/
  67. void E_(CloseIntf) ( vlc_object_t *p_this )
  68. {
  69.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  70.     var_DelCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
  71.     /* Destroy structure */
  72.     free( p_intf->p_sys );
  73. }
  74. /*****************************************************************************
  75.  * RunIntf: main loop
  76.  *****************************************************************************/
  77. static void RunIntf( intf_thread_t *p_intf )
  78. {
  79.     vlc_object_t      * p_vout = NULL;
  80.     mtime_t             mtime = 0;
  81.     mtime_t             mlast = 0;
  82.     thread_vcd_data_t * p_vcd;
  83.     input_thread_t    * p_input;
  84.     /* What you add to the last input number entry. It accumulates all of
  85.        the 10_ADD keypresses */
  86.     int number_addend = 0;
  87.     if( InitThread( p_intf ) < 0 )
  88.     {
  89.         msg_Err( p_intf, "can't initialize intf" );
  90.         return;
  91.     }
  92.     p_input = p_intf->p_sys->p_input;
  93.     p_vcd   = p_intf->p_sys->p_vcd =
  94.       (thread_vcd_data_t *) p_input->p_access_data;
  95.     dbg_print( INPUT_DBG_CALL, "intf initialized" );
  96.     /* Main loop */
  97.     while( !p_intf->b_die )
  98.     {
  99.       vlc_mutex_lock( &p_intf->change_lock );
  100.         /*
  101.          * Have we timed-out in showing a still frame?
  102.          */
  103.         if( p_intf->p_sys->b_still && !p_intf->p_sys->b_inf_still )
  104.         {
  105.             if( p_intf->p_sys->m_still_time > 0 )
  106.             {
  107.                 /* Update remaining still time */
  108.                 dbg_print(INPUT_DBG_STILL, "updating still time");
  109.                 mtime = mdate();
  110.                 if( mlast )
  111.                 {
  112.                     p_intf->p_sys->m_still_time -= mtime - mlast;
  113.                 }
  114.                 mlast = mtime;
  115.             }
  116.             else
  117.             {
  118.                 /* Still time has elasped; set to continue playing. */
  119.                 dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
  120.                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  121.                 p_intf->p_sys->m_still_time = 0;
  122.                 p_intf->p_sys->b_still = 0;
  123.                 mlast = 0;
  124.             }
  125.         }
  126.       /*
  127.        * Do we have a keyboard event?
  128.        */
  129.       if( p_vout && p_intf->p_sys->b_key_pressed )
  130.         {
  131.           vlc_value_t val;
  132.           int i, i_action = -1;
  133.           struct hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
  134.           p_intf->p_sys->b_key_pressed = VLC_FALSE;
  135.           /* Find action triggered by hotkey (if any) */
  136.           var_Get( p_intf->p_vlc, "key-pressed", &val );
  137.           dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
  138.           for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
  139.             {
  140.               if( p_hotkeys[i].i_key == val.i_int )
  141.                 {
  142.                   i_action = p_hotkeys[i].i_action;
  143.                 }
  144.             }
  145.           if( i_action != -1) {
  146.             switch (i_action) {
  147.             case ACTIONID_NAV_LEFT:
  148.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
  149.                          number_addend );
  150.               do {
  151.                 vcdplayer_play_prev( p_input );
  152.               }        while (number_addend-- > 0);
  153.               break;
  154.             case ACTIONID_NAV_RIGHT:
  155.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
  156.                          number_addend );
  157.               do {
  158.                 vcdplayer_play_next( p_input );
  159.               } while (number_addend-- > 0);
  160.               break;
  161.             case ACTIONID_NAV_UP:
  162.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
  163.               do {
  164.                 vcdplayer_play_return( p_input );
  165.               } while (number_addend-- > 0);
  166.               break;
  167.             case ACTIONID_NAV_DOWN:
  168.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default"  );
  169.               vcdplayer_play_default( p_input );
  170.               break;
  171.             case ACTIONID_NAV_ACTIVATE:
  172.               {
  173.                 vcdinfo_itemid_t itemid;
  174.                 itemid.type=p_vcd->play_item.type;
  175.                 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
  176.                 if ( vcdplayer_pbc_is_on( p_vcd ) && number_addend != 0 ) {
  177.                   lid_t next_num=vcdinfo_selection_get_lid(p_vcd->vcd,
  178.                                                            p_vcd->cur_lid,
  179.                                                            number_addend);
  180.                   if (VCDINFO_INVALID_LID != next_num) {
  181.                     itemid.num  = next_num;
  182.                     itemid.type = VCDINFO_ITEM_TYPE_LID;
  183.                     VCDPlay( p_input, itemid );
  184.                   }
  185.                 } else {
  186.                   itemid.num = number_addend;
  187.                   VCDPlay( p_input, itemid );
  188.                 }
  189.                 break;
  190.               }
  191.             }
  192.             number_addend = 0;
  193.             /* Any keypress gets rid of still frame waiting.
  194.                FIXME - should handle just the ones that cause an action.
  195.             */
  196.             if( p_intf->p_sys->b_still )
  197.               {
  198.                 dbg_print(INPUT_DBG_STILL, "Playing still after activate");
  199.                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  200.                 p_intf->p_sys->b_still = 0;
  201.                 p_intf->p_sys->b_inf_still = 0;
  202.                 p_intf->p_sys->m_still_time = 0;
  203.               }
  204.           } else {
  205.             unsigned int digit_entered=0;
  206.             switch (val.i_int) {
  207.             case '9':
  208.               digit_entered++;
  209.             case '8':
  210.               digit_entered++;
  211.             case '7':
  212.               digit_entered++;
  213.             case '6':
  214.               digit_entered++;
  215.             case '5':
  216.               digit_entered++;
  217.             case '4':
  218.               digit_entered++;
  219.             case '3':
  220.               digit_entered++;
  221.             case '2':
  222.               digit_entered++;
  223.             case '1':
  224.               digit_entered++;
  225.             case '0':
  226.               {
  227.                 number_addend *= 10;
  228.                 number_addend += digit_entered;
  229.                 dbg_print( INPUT_DBG_EVENT,
  230.                            "Added %d. Number is now: %dn",
  231.                            digit_entered, number_addend);
  232.                 break;
  233.               }
  234.             }
  235.           }
  236.         }
  237.       vlc_mutex_unlock( &p_intf->change_lock );
  238.       if( p_vout == NULL )
  239.         {
  240.           p_vout = vlc_object_find( p_intf->p_sys->p_input,
  241.                                     VLC_OBJECT_VOUT, FIND_CHILD );
  242.           if( p_vout )
  243.             {
  244.               var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
  245.             }
  246.         }
  247.       /* Wait a bit */
  248.       msleep( INTF_IDLE_SLEEP );
  249.     }
  250.     if( p_vout )
  251.     {
  252.         var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
  253.         vlc_object_release( p_vout );
  254.     }
  255.     vlc_object_release( p_intf->p_sys->p_input );
  256. }
  257. /*****************************************************************************
  258.  * InitThread:
  259.  *****************************************************************************/
  260. static int InitThread( intf_thread_t * p_intf )
  261. {
  262.     /* We might need some locking here */
  263.     if( !p_intf->b_die )
  264.     {
  265.         input_thread_t * p_input;
  266.         p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
  267.         /* Maybe the input just died */
  268.         if( p_input == NULL )
  269.         {
  270.             return VLC_EGENERIC;
  271.         }
  272.         vlc_mutex_lock( &p_intf->change_lock );
  273.         p_intf->p_sys->p_input = p_input;
  274.         p_intf->p_sys->b_move = VLC_FALSE;
  275.         p_intf->p_sys->b_click = VLC_FALSE;
  276.         p_intf->p_sys->b_key_pressed = VLC_FALSE;
  277.         vlc_mutex_unlock( &p_intf->change_lock );
  278.         return VLC_SUCCESS;
  279.     }
  280.     else
  281.     {
  282.         return VLC_EGENERIC;
  283.     }
  284. }
  285. /*****************************************************************************
  286.  * KeyEvent: callback for keyboard events
  287.  *****************************************************************************/
  288. static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
  289.                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
  290. {
  291.     intf_thread_t *p_intf = (intf_thread_t *)p_data;
  292.     vlc_mutex_lock( &p_intf->change_lock );
  293.     p_intf->p_sys->b_key_pressed = VLC_TRUE;
  294.     vlc_mutex_unlock( &p_intf->change_lock );
  295.     return VLC_SUCCESS;
  296. }
  297. /*****************************************************************************
  298.  * vcdIntfStillTime: function provided to demux plugin to request
  299.  * still images
  300.  *****************************************************************************/
  301. int vcdIntfStillTime( intf_thread_t *p_intf, int i_sec )
  302. {
  303.     vlc_mutex_lock( &p_intf->change_lock );
  304.     if( i_sec == -1 )
  305.     {
  306.         p_intf->p_sys->b_still     = 1;
  307.         p_intf->p_sys->b_inf_still = 1;
  308.     }
  309.     else if( i_sec > 0 )
  310.     {
  311.         p_intf->p_sys->b_still = 1;
  312.         p_intf->p_sys->m_still_time = 1000000 * i_sec;
  313.     }
  314.     vlc_mutex_unlock( &p_intf->change_lock );
  315.     return VLC_SUCCESS;
  316. }
  317. /*****************************************************************************
  318.  * vcdIntfStillTime: function provided to reset still image
  319.  *****************************************************************************/
  320. int vcdIntfResetStillTime( intf_thread_t *p_intf )
  321. {
  322.     vlc_mutex_lock( &p_intf->change_lock );
  323.     p_intf->p_sys->m_still_time = 0;
  324.     var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  325.     vlc_mutex_unlock( &p_intf->change_lock );
  326.     return VLC_SUCCESS;
  327. }