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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * intf.c: Video CD interface to handle user interaction and still time
  3.  *****************************************************************************
  4.  * Copyright (C) 2002,2003 the VideoLAN team
  5.  * $Id: 6cf596dc6b84490feb854ffff169802bd6eea96f $
  6.  *
  7.  * Author: Rocky Bernstein <rocky@panix.com>
  8.  *   from DVD code by Stéphane 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_interface.h>
  32. #include <vlc_access.h>
  33. #include "vlc_keys.h"
  34. #include "vcd.h"
  35. #include "vcdplayer.h"
  36. #include "intf.h"
  37. /*****************************************************************************
  38.  * Local prototypes.
  39.  *****************************************************************************/
  40. static int  InitThread     ( intf_thread_t *p_intf );
  41. static int  KeyEvent       ( vlc_object_t *, char const *,
  42.                              vlc_value_t, vlc_value_t, void * );
  43. /* Exported functions */
  44. static void RunIntf        ( intf_thread_t *p_intf );
  45. /*****************************************************************************
  46.  * OpenIntf: initialize dummy interface
  47.  *****************************************************************************/
  48. int VCDOpenIntf ( vlc_object_t *p_this )
  49. {
  50.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  51.     msg_Dbg( p_intf, "VCDOpenIntf" );
  52.     /* Allocate instance and initialize some members */
  53.     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  54.     if( p_intf->p_sys == NULL )
  55.     {
  56.         return( VLC_EGENERIC );
  57.     };
  58.     vlc_mutex_init( &p_intf->p_sys->lock );
  59.     p_intf->pf_run = RunIntf;
  60.     var_AddCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf );
  61.     p_intf->p_sys->m_still_time = 0;
  62.     p_intf->p_sys->b_infinite_still = 0;
  63.     p_intf->p_sys->b_still = 0;
  64.     return( VLC_SUCCESS );
  65. }
  66. /*****************************************************************************
  67.  * CloseIntf: destroy dummy interface
  68.  *****************************************************************************/
  69. void VCDCloseIntf ( vlc_object_t *p_this )
  70. {
  71.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  72.     var_DelCallback( p_intf->p_libvlc, "key-pressed", KeyEvent, p_intf );
  73.     /* Destroy structure */
  74.     vlc_mutex_destroy( &p_intf->p_sys->lock );
  75.     free( p_intf->p_sys );
  76. }
  77. /*****************************************************************************
  78.  * RunIntf: main loop
  79.  *****************************************************************************/
  80. static void
  81. RunIntf( intf_thread_t *p_intf )
  82. {
  83.     vlc_object_t      * p_vout = NULL;
  84.     mtime_t             mtime = 0;
  85.     mtime_t             mlast = 0;
  86.     vcdplayer_t       * p_vcdplayer;
  87.     input_thread_t    * p_input;
  88.     access_t          * p_access;
  89.     /* What you add to the last input number entry. It accumulates all of
  90.        the 10_ADD keypresses */
  91.     int number_addend = 0;
  92.     int canc = vlc_savecancel();
  93.     if( InitThread( p_intf ) < 0 )
  94.     {
  95.         msg_Err( p_intf, "can't initialize intf" );
  96.         return;
  97.     }
  98.     p_input = p_intf->p_sys->p_input;
  99.     while ( !p_intf->p_sys->p_vcdplayer )
  100.     {
  101.         msleep( INTF_IDLE_SLEEP );
  102.     }
  103.  
  104.     p_vcdplayer = p_intf->p_sys->p_vcdplayer;
  105.     p_access    = p_vcdplayer->p_access;
  106.     canc = vlc_savecancel();
  107.     dbg_print( INPUT_DBG_CALL, "intf initialized" );
  108.     /* Main loop */
  109.     while( vlc_object_alive (p_intf) )
  110.     {
  111.       vlc_mutex_lock( &p_intf->p_sys->lock );
  112.         /*
  113.          * Have we timed-out in showing a still frame?
  114.          */
  115.         if( p_intf->p_sys->b_still && !p_intf->p_sys->b_infinite_still )
  116.         {
  117.             if( p_intf->p_sys->m_still_time > 0 )
  118.             {
  119.                 /* Update remaining still time */
  120.                 dbg_print(INPUT_DBG_STILL, "updating still time");
  121.                 mtime = mdate();
  122.                 if( mlast )
  123.                 {
  124.                     p_intf->p_sys->m_still_time -= mtime - mlast;
  125.                 }
  126.                 mlast = mtime;
  127.             }
  128.             else
  129.             {
  130.                 /* Still time has elapsed; set to continue playing. */
  131.                 dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
  132.                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  133.                 p_intf->p_sys->m_still_time = 0;
  134.                 p_intf->p_sys->b_still = 0;
  135.                 mlast = 0;
  136.             }
  137.         }
  138.       /*
  139.        * Do we have a keyboard event?
  140.        */
  141.       if( p_vout && p_intf->p_sys->b_key_pressed )
  142.         {
  143.           vlc_value_t val;
  144.           int i, i_action = -1;
  145.           struct hotkey *p_hotkeys = p_intf->p_libvlc->p_hotkeys;
  146.           p_intf->p_sys->b_key_pressed = false;
  147.           /* Find action triggered by hotkey (if any) */
  148.           var_Get( p_intf->p_libvlc, "key-pressed", &val );
  149.           dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
  150.           for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
  151.             {
  152.               if( p_hotkeys[i].i_key == val.i_int )
  153.                 {
  154.                   i_action = p_hotkeys[i].i_action;
  155.                 }
  156.             }
  157.           if( i_action != -1) {
  158.             switch (i_action) {
  159.             case ACTIONID_NAV_LEFT:
  160.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
  161.                          number_addend );
  162.               do {
  163.                 vcdplayer_play_prev( p_access );
  164.               }        while (number_addend-- > 0);
  165.               break;
  166.             case ACTIONID_NAV_RIGHT:
  167.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
  168.                          number_addend );
  169.               do {
  170.                 vcdplayer_play_next( p_access );
  171.               } while (number_addend-- > 0);
  172.               break;
  173.             case ACTIONID_NAV_UP:
  174.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
  175.               do {
  176.                 vcdplayer_play_return( p_access );
  177.               } while (number_addend-- > 0);
  178.               break;
  179.             case ACTIONID_NAV_DOWN:
  180.               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default"  );
  181.               vcdplayer_play_default( p_access );
  182.               break;
  183.             case ACTIONID_NAV_ACTIVATE:
  184.               {
  185.                 vcdinfo_itemid_t itemid;
  186.                 itemid.type=p_vcdplayer->play_item.type;
  187.                 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
  188.                 if ( vcdplayer_pbc_is_on( p_vcdplayer )
  189.              && number_addend != 0 ) {
  190.                   lid_t next_num=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
  191.                                                            p_vcdplayer->i_lid,
  192.                                                            number_addend);
  193.                   if (VCDINFO_INVALID_LID != next_num) {
  194.                     itemid.num  = next_num;
  195.                     itemid.type = VCDINFO_ITEM_TYPE_LID;
  196.                     vcdplayer_play( p_access, itemid );
  197.                   }
  198.                 } else {
  199.                   itemid.num = number_addend;
  200.                   vcdplayer_play( p_access, itemid );
  201.                 }
  202.                 break;
  203.               }
  204.             }
  205.             number_addend = 0;
  206.             /* Any keypress gets rid of still frame waiting.
  207.                FIXME - should handle just the ones that cause an action.
  208.             */
  209.             if( p_intf->p_sys->b_still )
  210.               {
  211.                 dbg_print(INPUT_DBG_STILL, "Playing still after activate");
  212.                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  213.                 p_intf->p_sys->b_still = 0;
  214.                 p_intf->p_sys->b_infinite_still = 0;
  215.                 p_intf->p_sys->m_still_time = 0;
  216.               }
  217.           } else {
  218.             unsigned int digit_entered=0;
  219.             switch (val.i_int) {
  220.             case '9':
  221.               digit_entered++;
  222.             case '8':
  223.               digit_entered++;
  224.             case '7':
  225.               digit_entered++;
  226.             case '6':
  227.               digit_entered++;
  228.             case '5':
  229.               digit_entered++;
  230.             case '4':
  231.               digit_entered++;
  232.             case '3':
  233.               digit_entered++;
  234.             case '2':
  235.               digit_entered++;
  236.             case '1':
  237.               digit_entered++;
  238.             case '0':
  239.               {
  240.                 number_addend *= 10;
  241.                 number_addend += digit_entered;
  242.                 dbg_print( INPUT_DBG_EVENT,
  243.                            "Added %d. Number is now: %dn",
  244.                            digit_entered, number_addend);
  245.                 break;
  246.               }
  247.             }
  248.           }
  249.         }
  250.       vlc_mutex_unlock( &p_intf->p_sys->lock );
  251.       if( p_vout == NULL )
  252.         {
  253.           p_vout = vlc_object_find( p_intf->p_sys->p_input,
  254.                                     VLC_OBJECT_VOUT, FIND_CHILD );
  255.           if( p_vout )
  256.             {
  257.               var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
  258.             }
  259.         }
  260.         /* Wait a bit */
  261.         msleep( INTF_IDLE_SLEEP );
  262.     }
  263.     if( p_vout )
  264.     {
  265.         var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
  266.         vlc_object_release( p_vout );
  267.     }
  268.     vlc_object_release( p_intf->p_sys->p_input );
  269.     vlc_restorecancel( canc );
  270. }
  271. /*****************************************************************************
  272.  * InitThread:
  273.  *****************************************************************************/
  274. static int InitThread( intf_thread_t * p_intf )
  275. {
  276.     /* We might need some locking here */
  277.     input_thread_t * p_input;
  278.     p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
  279.     /* Maybe the input just died */
  280.     if( p_input == NULL )
  281.         return VLC_EGENERIC;
  282.     vlc_mutex_lock( &p_intf->p_sys->lock );
  283.     p_intf->p_sys->p_input     = p_input;
  284.     p_intf->p_sys->p_vcdplayer = NULL;
  285.     p_intf->p_sys->b_move  = false;
  286.     p_intf->p_sys->b_click = false;
  287.     p_intf->p_sys->b_key_pressed = false;
  288.     vlc_mutex_unlock( &p_intf->p_sys->lock );
  289.     /* make sure we return a value */
  290.     return 0;
  291. }
  292. /*****************************************************************************
  293.  * KeyEvent: callback for keyboard events
  294.  *****************************************************************************/
  295. static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
  296.                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
  297. {
  298.     intf_thread_t *p_intf = (intf_thread_t *)p_data;
  299.     vlc_mutex_lock( &p_intf->p_sys->lock );
  300.     p_intf->p_sys->b_key_pressed = true;
  301.     vlc_mutex_unlock( &p_intf->p_sys->lock );
  302.     return VLC_SUCCESS;
  303. }
  304. /*****************************************************************************
  305.  * vcdIntfStillTime: function provided to demux plugin to request
  306.  * still images
  307.  *****************************************************************************/
  308. int vcdIntfStillTime( intf_thread_t *p_intf, uint8_t i_sec )
  309. {
  310.     vlc_mutex_lock( &p_intf->p_sys->lock );
  311.     p_intf->p_sys->b_still = 1;
  312.     if( 255 == i_sec )
  313.     {
  314.         p_intf->p_sys->b_infinite_still = true;
  315.     }
  316.     else
  317.     {
  318.         p_intf->p_sys->m_still_time = MILLISECONDS_PER_SEC * i_sec;
  319.     }
  320.     vlc_mutex_unlock( &p_intf->p_sys->lock );
  321.     return VLC_SUCCESS;
  322. }
  323. /*****************************************************************************
  324.  * vcdIntfStillTime: function provided to reset still image
  325.  *****************************************************************************/
  326. int vcdIntfResetStillTime( intf_thread_t *p_intf )
  327. {
  328.     vlc_mutex_lock( &p_intf->p_sys->lock );
  329.     p_intf->p_sys->m_still_time = 0;
  330.     var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
  331.     vlc_mutex_unlock( &p_intf->p_sys->lock );
  332.     return VLC_SUCCESS;
  333. }