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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * lirc.c : lirc module for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: lirc.c 7991 2004-06-17 03:37:03Z yoann $
  6.  *
  7.  * Author: Sigmund Augdal <sigmunau@idi.ntnu.no>
  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 <stdlib.h>                                      /* malloc(), free() */
  27. #include <string.h>
  28. #include <fcntl.h>
  29. #include <vlc/vlc.h>
  30. #include <vlc/intf.h>
  31. #include <vlc/vout.h>
  32. #include <vlc/aout.h>
  33. #include <osd.h>
  34. #include <lirc/lirc_client.h>
  35. /*****************************************************************************
  36.  * intf_sys_t: description and status of FB interface
  37.  *****************************************************************************/
  38. struct intf_sys_t
  39. {
  40.     struct lirc_config *config;
  41.     vlc_mutex_t         change_lock;
  42.     int                 i_osd_channel;
  43.     input_thread_t *    p_input;
  44.     vout_thread_t *     p_vout;
  45. };
  46. /*****************************************************************************
  47.  * Local prototypes
  48.  *****************************************************************************/
  49. static int  Open    ( vlc_object_t * );
  50. static void Close   ( vlc_object_t * );
  51. static void Run     ( intf_thread_t * );
  52. /*****************************************************************************
  53.  * Module descriptor
  54.  *****************************************************************************/
  55. vlc_module_begin();
  56.     set_description( _("Infrared remote control interface") );
  57.     set_capability( "interface", 0 );
  58.     set_callbacks( Open, Close );
  59. vlc_module_end();
  60. /*****************************************************************************
  61.  * Open: initialize interface
  62.  *****************************************************************************/
  63. static int Open( vlc_object_t *p_this )
  64. {
  65.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  66.     int i_fd;
  67.     /* Allocate instance and initialize some members */
  68.     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  69.     if( p_intf->p_sys == NULL )
  70.     {
  71.         msg_Err( p_intf, "out of memory" );
  72.         return 1;
  73.     }
  74.     p_intf->pf_run = Run;
  75.     i_fd = lirc_init( "vlc", 1 );
  76.     if( i_fd == -1 )
  77.     {
  78.         msg_Err( p_intf, "lirc_init failed" );
  79.         free( p_intf->p_sys );
  80.         return 1;
  81.     }
  82.     /* We want polling */
  83.     fcntl( i_fd, F_SETFL, fcntl( i_fd, F_GETFL ) | O_NONBLOCK );
  84.     if( lirc_readconfig( NULL, &p_intf->p_sys->config, NULL ) != 0 )
  85.     {
  86.         msg_Err( p_intf, "lirc_readconfig failed" );
  87.         lirc_deinit();
  88.         free( p_intf->p_sys );
  89.         return 1;
  90.     }
  91.     p_intf->p_sys->p_input = NULL;
  92.     return 0;
  93. }
  94. /*****************************************************************************
  95.  * Close: destroy interface
  96.  *****************************************************************************/
  97. static void Close( vlc_object_t *p_this )
  98. {
  99.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  100.     if( p_intf->p_sys->p_input )
  101.     {
  102.         vlc_object_release( p_intf->p_sys->p_input );
  103.     }
  104.     if( p_intf->p_sys->p_vout )
  105.     {
  106.         vlc_object_release( p_intf->p_sys->p_vout );
  107.     }
  108.     /* Destroy structure */
  109.     lirc_freeconfig( p_intf->p_sys->config );
  110.     lirc_deinit();
  111.     free( p_intf->p_sys );
  112. }
  113. /*****************************************************************************
  114.  * Run: main loop
  115.  *****************************************************************************/
  116. static void Run( intf_thread_t *p_intf )
  117. {
  118.     char *code, *c;
  119.     playlist_t *p_playlist;
  120.     input_thread_t *p_input;
  121.     vout_thread_t *p_vout = NULL;
  122.     while( !p_intf->b_die )
  123.     {
  124.         /* Sleep a bit */
  125.         msleep( INTF_IDLE_SLEEP );
  126.         /* Update the input */
  127.         if( p_intf->p_sys->p_input == NULL )
  128.         {
  129.             p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  130.                                                               FIND_ANYWHERE );
  131.         }
  132.         else if( p_intf->p_sys->p_input->b_dead )
  133.         {
  134.             vlc_object_release( p_intf->p_sys->p_input );
  135.             p_intf->p_sys->p_input = NULL;
  136.         }
  137.         p_input = p_intf->p_sys->p_input;
  138.         /* Update the vout */
  139.         if( p_vout == NULL )
  140.         {
  141.             p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT,
  142.                                       FIND_ANYWHERE );
  143.             p_intf->p_sys->p_vout = p_vout;
  144.         }
  145.         else if( p_vout->b_die )
  146.         {
  147.             vlc_object_release( p_vout );
  148.             p_vout = NULL;
  149.             p_intf->p_sys->p_vout = NULL;
  150.         }
  151.         /* We poll the lircsocket */
  152.         if( lirc_nextcode(&code) != 0 )
  153.         {
  154.             break;
  155.         }
  156.         if( code == NULL )
  157.         {
  158.             continue;
  159.         }
  160.         while( !p_intf->b_die
  161.                 && lirc_code2char( p_intf->p_sys->config, code, &c ) == 0
  162.                 && c != NULL )
  163.         {
  164.             if( !strcmp( c, "QUIT" ) )
  165.             {
  166.                 p_intf->p_vlc->b_die = VLC_TRUE;
  167.                 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Quit" ) );
  168.                 continue;
  169.             }
  170.             else if( !strcmp( c, "VOL_UP" ) )
  171.             {
  172.                 audio_volume_t i_newvol;
  173.                 aout_VolumeUp( p_intf, 1, &i_newvol );
  174.                 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Vol %%%d"),
  175.                                  i_newvol * 100 / AOUT_VOLUME_MAX );
  176.             }
  177.             else if( !strcmp( c, "VOL_DOWN" ) )
  178.             {
  179.                 audio_volume_t i_newvol;
  180.                 aout_VolumeDown( p_intf, 1, &i_newvol );
  181.                 vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Vol %%%d"),
  182.                                  i_newvol * 100 / AOUT_VOLUME_MAX );
  183.             }
  184.             else if( !strcmp( c, "MUTE" ) )
  185.             {
  186.                 audio_volume_t i_newvol = -1;
  187.                 aout_VolumeMute( p_intf, &i_newvol );
  188.                 if( i_newvol == 0 )
  189.                 {
  190.                     vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Mute" ) );
  191.                 }
  192.                 else
  193.                 {
  194.                     vout_OSDMessage( p_intf, DEFAULT_CHAN, _("Vol %d%%"),
  195.                                      i_newvol * 100 / AOUT_VOLUME_MAX );
  196.                 }
  197.             }
  198.             if( p_vout )
  199.             {
  200.                 if( !strcmp( c, "FULLSCREEN" ) )
  201.                 {
  202.                     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
  203.                     continue;
  204.                 }
  205.                 if( !strcmp( c, "ACTIVATE" ) )
  206.                 {
  207.                     vlc_value_t val;
  208.                     val.psz_string = "ENTER";
  209.                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
  210.                     {
  211.                         msg_Warn( p_intf, "key-press failed" );
  212.                     }
  213.                     continue;
  214.                 }
  215.                 if( !strcmp( c, "LEFT" ) )
  216.                 {
  217.                     vlc_value_t val;
  218.                     val.psz_string = "LEFT";
  219.                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
  220.                     {
  221.                         msg_Warn( p_intf, "key-press failed" );
  222.                     }
  223.                     continue;
  224.                 }
  225.                 if( !strcmp( c, "RIGHT" ) )
  226.                 {
  227.                     vlc_value_t val;
  228.                     val.psz_string = "RIGHT";
  229.                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
  230.                     {
  231.                         msg_Warn( p_intf, "key-press failed" );
  232.                     }
  233.                     continue;
  234.                 }
  235.                 if( !strcmp( c, "UP" ) )
  236.                 {
  237.                     vlc_value_t val;
  238.                     val.psz_string = "UP";
  239.                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
  240.                     {
  241.                         msg_Warn( p_intf, "key-press failed" );
  242.                     }
  243.                     continue;
  244.                 }
  245.                 if( !strcmp( c, "DOWN" ) )
  246.                 {
  247.                     vlc_value_t val;
  248.                     val.psz_string = "DOWN";
  249.                     if (var_Set( p_vout, "key-pressed", val ) != VLC_SUCCESS)
  250.                     {
  251.                         msg_Warn( p_intf, "key-press failed" );
  252.                     }
  253.                     continue;
  254.                 }
  255.             }
  256.             if( !strcmp( c, "PLAY" ) )
  257.             {
  258.                 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  259.                                               FIND_ANYWHERE );
  260.                 if( p_playlist )
  261.                 {
  262.                     playlist_Play( p_playlist );
  263.                     vlc_object_release( p_playlist );
  264.                 }
  265.                 continue;
  266.             }
  267.             if( !strcmp( c, "PLAYPAUSE" ) )
  268.             {
  269.                 vlc_value_t val;
  270.                 val.i_int = PLAYING_S;
  271.                 if( p_input )
  272.                 {
  273.                     var_Get( p_input, "state", &val );
  274.                 }
  275.                 if( p_input && val.i_int != PAUSE_S )
  276.                 {
  277.                     vout_OSDMessage( VLC_OBJECT(p_intf), DEFAULT_CHAN,
  278.                                      _( "Pause" ) );
  279.                     val.i_int = PAUSE_S;
  280.                     var_Set( p_input, "state", val );
  281.                 }
  282.                 else
  283.                 {
  284.                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  285.                                                   FIND_ANYWHERE );
  286.                     if( p_playlist )
  287.                     {
  288.                         vlc_mutex_lock( &p_playlist->object_lock );
  289.                         if( p_playlist->i_size )
  290.                         {
  291.                             vlc_mutex_unlock( &p_playlist->object_lock );
  292.                             vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Play" ) );
  293.                             playlist_Play( p_playlist );
  294.                             vlc_object_release( p_playlist );
  295.                         }
  296.                     }
  297.                 }
  298.                 continue;
  299.             }
  300.             else if( p_input )
  301.             {
  302.                 if( !strcmp( c, "AUDIO_TRACK" ) )
  303.                 {
  304.                     vlc_value_t val, list, list2;
  305.                     int i_count, i;
  306.                     var_Get( p_input, "audio-es", &val );
  307.                     var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES,
  308.                                 &list, &list2 );
  309.                     i_count = list.p_list->i_count;
  310.                     for( i = 0; i < i_count; i++ )
  311.                     {
  312.                         if( val.i_int == list.p_list->p_values[i].i_int )
  313.                         {
  314.                             break;
  315.                         }
  316.                     }
  317.                     /* value of audio-es was not in choices list */
  318.                     if( i == i_count )
  319.                     {
  320.                         msg_Warn( p_input,
  321.                                   "invalid current audio track, selecting 0" );
  322.                         var_Set( p_input, "audio-es",
  323.                                  list.p_list->p_values[0] );
  324.                         i = 0;
  325.                     }
  326.                     else if( i == i_count - 1 )
  327.                     {
  328.                         var_Set( p_input, "audio-es",
  329.                                  list.p_list->p_values[0] );
  330.                         i = 0;
  331.                     }
  332.                     else
  333.                     {
  334.                         var_Set( p_input, "audio-es",
  335.                                  list.p_list->p_values[i+1] );
  336.                         i++;
  337.                     }
  338.                     vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
  339.                                      _("Audio track: %s"),
  340.                                      list2.p_list->p_values[i].psz_string );
  341.                 }
  342.                 else if( !strcmp( c, "SUBTITLE_TRACK" ) )
  343.                 {
  344.                     vlc_value_t val, list, list2;
  345.                     int i_count, i;
  346.                     var_Get( p_input, "spu-es", &val );
  347.                     var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
  348.                                 &list, &list2 );
  349.                     i_count = list.p_list->i_count;
  350.                     for( i = 0; i < i_count; i++ )
  351.                     {
  352.                         if( val.i_int == list.p_list->p_values[i].i_int )
  353.                         {
  354.                             break;
  355.                         }
  356.                     }
  357.                     /* value of audio-es was not in choices list */
  358.                     if( i == i_count )
  359.                     {
  360.                         msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
  361.                         var_Set( p_input, "spu-es", list.p_list->p_values[0] );
  362.                         i = 0;
  363.                     }
  364.                     else if( i == i_count - 1 )
  365.                     {
  366.                         var_Set( p_input, "spu-es", list.p_list->p_values[0] );
  367.                         i = 0;
  368.                     }
  369.                     else
  370.                     {
  371.                         var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
  372.                         i = i + 1;
  373.                     }
  374.                     vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
  375.                                      _("Subtitle track: %s"),
  376.                                      list2.p_list->p_values[i].psz_string );
  377.                 }
  378.                 else if( !strcmp( c, "PAUSE" ) )
  379.                 {
  380.                     vlc_value_t val;
  381.                     vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Pause" ) );
  382.                     val.i_int = PAUSE_S;
  383.                     var_Set( p_input, "state", val );
  384.                 }
  385.                 else if( !strcmp( c, "NEXT" ) )
  386.                 {
  387.                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  388.                                                           FIND_ANYWHERE );
  389.                     if( p_playlist )
  390.                     {
  391.                         playlist_Next( p_playlist );
  392.                         vlc_object_release( p_playlist );
  393.                     }
  394.                 }
  395.                 else if( !strcmp( c, "PREV" ) )
  396.                 {
  397.                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  398.                                                           FIND_ANYWHERE );
  399.                     if( p_playlist )
  400.                     {
  401.                         playlist_Prev( p_playlist );
  402.                         vlc_object_release( p_playlist );
  403.                     }
  404.                 }
  405.                 else if( !strcmp( c, "STOP" ) )
  406.                 {
  407.                     p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
  408.                                                           FIND_ANYWHERE );
  409.                     if( p_playlist )
  410.                     {
  411.                         playlist_Stop( p_playlist );
  412.                         vlc_object_release( p_playlist );
  413.                     }
  414.                 }
  415.                 else if( !strcmp( c, "FAST" ) )
  416.                 {
  417.                     vlc_value_t val; val.b_bool = VLC_TRUE;
  418.                     var_Set( p_input, "rate-faster", val );
  419.                 }
  420.                 else if( !strcmp( c, "SLOW" ) )
  421.                 {
  422.                     vlc_value_t val; val.b_bool = VLC_TRUE;
  423.                     var_Set( p_input, "rate-slower", val );
  424.                 }
  425. /* beginning of modifications by stephane Thu Jun 19 15:29:49 CEST 2003 */
  426.                 else if ( !strcmp(c, "CHAPTER_N" ) ||
  427.                           !strcmp( c, "CHAPTER_P" ) )
  428.                 {
  429.                     unsigned int i_chapter = 0;
  430.                     if( !strcmp( c, "CHAPTER_N" ) )
  431.                     {
  432.                         var_SetVoid( p_input, "next-chapter" );
  433.                     }
  434.                     else if( !strcmp( c, "CHAPTER_P" ) )
  435.                     {
  436.                         var_SetVoid( p_input, "prev-chapter" );
  437.                     }
  438.                 }
  439. /* end of modification by stephane Thu Jun 19 15:29:49 CEST 2003 */
  440.             }
  441.         }
  442.         free( code );
  443.     }
  444. }