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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * var.c: object variables for input thread
  3.  *****************************************************************************
  4.  * Copyright (C) 2004 VideoLAN
  5.  * $Id: input.c 7955 2004-06-07 22:21:33Z fenrir $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  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>
  27. #include <vlc/vlc.h>
  28. #include <vlc/input.h>
  29. #include "input_internal.h"
  30. /*****************************************************************************
  31.  * Exported prototypes
  32.  *****************************************************************************/
  33. void input_ControlVarInit ( input_thread_t * );
  34. void input_ControlVarClean( input_thread_t * );
  35. void input_ControlVarNavigation( input_thread_t * );
  36. void input_ControlVarTitle( input_thread_t *p_input, int i_title );
  37. void input_ConfigVarInit ( input_thread_t *p_input );
  38. /*****************************************************************************
  39.  * Callbacks
  40.  *****************************************************************************/
  41. static int StateCallback   ( vlc_object_t *p_this, char const *psz_cmd,
  42.                              vlc_value_t oldval, vlc_value_t newval, void * );
  43. static int RateCallback    ( vlc_object_t *p_this, char const *psz_cmd,
  44.                              vlc_value_t oldval, vlc_value_t newval, void * );
  45. static int PositionCallback( vlc_object_t *p_this, char const *psz_cmd,
  46.                              vlc_value_t oldval, vlc_value_t newval, void * );
  47. static int TimeCallback    ( vlc_object_t *p_this, char const *psz_cmd,
  48.                              vlc_value_t oldval, vlc_value_t newval, void * );
  49. static int ProgramCallback ( vlc_object_t *p_this, char const *psz_cmd,
  50.                              vlc_value_t oldval, vlc_value_t newval, void * );
  51. static int TitleCallback   ( vlc_object_t *p_this, char const *psz_cmd,
  52.                              vlc_value_t oldval, vlc_value_t newval, void * );
  53. static int SeekpointCallback( vlc_object_t *p_this, char const *psz_cmd,
  54.                              vlc_value_t oldval, vlc_value_t newval, void * );
  55. static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,
  56.                              vlc_value_t oldval, vlc_value_t newval, void * );
  57. static int ESCallback      ( vlc_object_t *p_this, char const *psz_cmd,
  58.                              vlc_value_t oldval, vlc_value_t newval, void * );
  59. static int EsDelayCallback ( vlc_object_t *p_this, char const *psz_cmd,
  60.                              vlc_value_t oldval, vlc_value_t newval, void * );
  61. static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
  62.                              vlc_value_t oldval, vlc_value_t newval, void * );
  63. /*****************************************************************************
  64.  * input_ControlVarInit:
  65.  *  Create all control object variables with their callbacks
  66.  *****************************************************************************/
  67. void input_ControlVarInit ( input_thread_t *p_input )
  68. {
  69.     vlc_value_t val, text;
  70.     /* State */
  71.     var_Create( p_input, "state", VLC_VAR_INTEGER );
  72.     val.i_int = p_input->i_state;
  73.     var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
  74.     var_AddCallback( p_input, "state", StateCallback, NULL );
  75.     /* Rate */
  76.     var_Create( p_input, "rate", VLC_VAR_INTEGER );
  77.     val.i_int = p_input->i_rate;
  78.     var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
  79.     var_AddCallback( p_input, "rate", RateCallback, NULL );
  80.     var_Create( p_input, "rate-slower", VLC_VAR_VOID );
  81.     var_AddCallback( p_input, "rate-slower", RateCallback, NULL );
  82.     var_Create( p_input, "rate-faster", VLC_VAR_VOID );
  83.     var_AddCallback( p_input, "rate-faster", RateCallback, NULL );
  84.     /* Position */
  85.     var_Create( p_input, "position",  VLC_VAR_FLOAT );
  86.     var_Create( p_input, "position-offset",  VLC_VAR_FLOAT );
  87.     val.f_float = 0.0;
  88.     var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
  89.     var_AddCallback( p_input, "position", PositionCallback, NULL );
  90.     var_AddCallback( p_input, "position-offset", PositionCallback, NULL );
  91.     /* Time */
  92.     var_Create( p_input, "time",  VLC_VAR_TIME );
  93.     var_Create( p_input, "time-offset",  VLC_VAR_TIME );    /* relative */
  94.     val.i_time = 0;
  95.     var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
  96.     var_AddCallback( p_input, "time", TimeCallback, NULL );
  97.     var_AddCallback( p_input, "time-offset", TimeCallback, NULL );
  98.     /* Bookmark */
  99.     var_Create( p_input, "bookmark", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE |
  100.                 VLC_VAR_ISCOMMAND );
  101.     val.psz_string = _("Bookmark");
  102.     var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, &val, NULL );
  103.     var_AddCallback( p_input, "bookmark", BookmarkCallback, NULL );
  104.     /* Program */
  105.     var_Create( p_input, "program", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE |
  106.                 VLC_VAR_DOINHERIT );
  107.     var_Get( p_input, "program", &val );
  108.     if( val.i_int <= 0 )
  109.         var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
  110.     text.psz_string = _("Program");
  111.     var_Change( p_input, "program", VLC_VAR_SETTEXT, &text, NULL );
  112.     var_AddCallback( p_input, "program", ProgramCallback, NULL );
  113.     /* Programs */
  114.     var_Create( p_input, "programs", VLC_VAR_LIST | VLC_VAR_DOINHERIT );
  115.     text.psz_string = _("Programs");
  116.     var_Change( p_input, "programs", VLC_VAR_SETTEXT, &text, NULL );
  117.     /* Title */
  118.     var_Create( p_input, "title", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
  119.     text.psz_string = _("Title");
  120.     var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL );
  121.     var_AddCallback( p_input, "title", TitleCallback, NULL );
  122.     /* Chapter */
  123.     var_Create( p_input, "chapter", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
  124.     text.psz_string = _("Chapter");
  125.     var_Change( p_input, "chapter", VLC_VAR_SETTEXT, &text, NULL );
  126.     var_AddCallback( p_input, "chapter", SeekpointCallback, NULL );
  127.     /* Navigation The callback is added after */
  128.     var_Create( p_input, "navigation", VLC_VAR_VARIABLE | VLC_VAR_HASCHOICE );
  129.     text.psz_string = _("Navigation");
  130.     var_Change( p_input, "navigation", VLC_VAR_SETTEXT, &text, NULL );
  131.     /* Delay */
  132.     var_Create( p_input, "audio-delay", VLC_VAR_TIME );
  133.     val.i_time = 0;
  134.     var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
  135.     var_AddCallback( p_input, "audio-delay", EsDelayCallback, NULL );
  136.     var_Create( p_input, "spu-delay", VLC_VAR_TIME );
  137.     val.i_time = 0;
  138.     var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
  139.     var_AddCallback( p_input, "spu-delay", EsDelayCallback, NULL );
  140.     /* Video ES */
  141.     var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
  142.     text.psz_string = _("Video Track");
  143.     var_Change( p_input, "video-es", VLC_VAR_SETTEXT, &text, NULL );
  144.     var_AddCallback( p_input, "video-es", ESCallback, NULL );
  145.     /* Audio ES */
  146.     var_Create( p_input, "audio-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
  147.     text.psz_string = _("Audio Track");
  148.     var_Change( p_input, "audio-es", VLC_VAR_SETTEXT, &text, NULL );
  149.     var_AddCallback( p_input, "audio-es", ESCallback, NULL );
  150.     /* Spu ES */
  151.     var_Create( p_input, "spu-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
  152.     text.psz_string = _("Subtitles Track");
  153.     var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, &text, NULL );
  154.     var_AddCallback( p_input, "spu-es", ESCallback, NULL );
  155.     /* Special read only objects variables for intf */
  156.     var_Create( p_input, "bookmarks", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  157.     var_Create( p_input, "length",  VLC_VAR_TIME );
  158.     val.i_time = 0;
  159.     var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
  160.    /* Special "intf-change" variable, it allows intf to set up a callback
  161.      * to be notified of some changes.
  162.      * TODO list all changes warn by this callbacks */
  163.     var_Create( p_input, "intf-change", VLC_VAR_BOOL );
  164.     var_SetBool( p_input, "intf-change", VLC_TRUE );
  165. }
  166. /*****************************************************************************
  167.  * input_ControlVarClean:
  168.  *****************************************************************************/
  169. void input_ControlVarClean( input_thread_t *p_input )
  170. {
  171.     var_Destroy( p_input, "state" );
  172.     var_Destroy( p_input, "rate" );
  173.     var_Destroy( p_input, "rate-slower" );
  174.     var_Destroy( p_input, "rate-faster" );
  175.     var_Destroy( p_input, "position" );
  176.     var_Destroy( p_input, "position-offset" );
  177.     var_Destroy( p_input, "time" );
  178.     var_Destroy( p_input, "time-offset" );
  179.     var_Destroy( p_input, "audio-delay" );
  180.     var_Destroy( p_input, "spu-delay" );
  181.     var_Destroy( p_input, "bookmark" );
  182.     var_Destroy( p_input, "program" );
  183.     if( p_input->i_title > 1 )
  184.     {
  185.         /* TODO Destroy sub navigation var ? */
  186.         var_Destroy( p_input, "next-title" );
  187.         var_Destroy( p_input, "prev-title" );
  188.     }
  189.     if( p_input->i_title > 0 )
  190.     {
  191.         /* FIXME title > 0 doesn't mean current title has more than 1 seekpoint */
  192.         var_Destroy( p_input, "next-chapter" );
  193.         var_Destroy( p_input, "prev-chapter" );
  194.     }
  195.     var_Destroy( p_input, "title" );
  196.     var_Destroy( p_input, "chapter" );
  197.     var_Destroy( p_input, "navigation" );
  198.     var_Destroy( p_input, "video-es" );
  199.     var_Destroy( p_input, "audio-es" );
  200.     var_Destroy( p_input, "spu-es" );
  201.     var_Destroy( p_input, "bookmarks" );
  202.     var_Destroy( p_input, "length" );
  203.     var_Destroy( p_input, "intf-change" );
  204.  }
  205. /*****************************************************************************
  206.  * input_ControlVarNavigation:
  207.  *  Create all remaining control object variables
  208.  *****************************************************************************/
  209. void input_ControlVarNavigation( input_thread_t *p_input )
  210. {
  211.     vlc_value_t val, text;
  212.     int  i;
  213.     /* Create more command variables */
  214.     if( p_input->i_title > 1 )
  215.     {
  216.         var_Create( p_input, "next-title", VLC_VAR_VOID );
  217.         text.psz_string = _("Next title");
  218.         var_Change( p_input, "next-title", VLC_VAR_SETTEXT, &text, NULL );
  219.         var_AddCallback( p_input, "next-title", TitleCallback, NULL );
  220.         var_Create( p_input, "prev-title", VLC_VAR_VOID );
  221.         text.psz_string = _("Previous title");
  222.         var_Change( p_input, "prev-title", VLC_VAR_SETTEXT, &text, NULL );
  223.         var_AddCallback( p_input, "prev-title", TitleCallback, NULL );
  224.     }
  225.     /* Create title and navigation */
  226.     val.psz_string = malloc( sizeof("title ") + 5 );
  227.     for( i = 0; i < p_input->i_title; i++ )
  228.     {
  229.         vlc_value_t val2, text, text2;
  230.         int j;
  231.         /* Add Navigation entries */
  232.         sprintf( val.psz_string,  "title %2i", i );
  233.         var_Destroy( p_input, val.psz_string );
  234.         var_Create( p_input, val.psz_string,
  235.                     VLC_VAR_INTEGER|VLC_VAR_HASCHOICE|VLC_VAR_ISCOMMAND );
  236.         var_AddCallback( p_input, val.psz_string,
  237.                          NavigationCallback, (void *)i );
  238.         if( p_input->title[i]->psz_name == NULL ||
  239.             *p_input->title[i]->psz_name == '' )
  240.         {
  241.             asprintf( &text.psz_string, _("Title %i"),
  242.                       i + p_input->i_title_offset );
  243.         }
  244.         else
  245.         {
  246.             text.psz_string = strdup( p_input->title[i]->psz_name );
  247.         }
  248.         var_Change( p_input, "navigation", VLC_VAR_ADDCHOICE, &val, &text );
  249.         /* Add title choice */
  250.         val2.i_int = i;
  251.         var_Change( p_input, "title", VLC_VAR_ADDCHOICE, &val2, &text );
  252.         free( text.psz_string );
  253.         for( j = 0; j < p_input->title[i]->i_seekpoint; j++ )
  254.         {
  255.             val2.i_int = j;
  256.             if( p_input->title[i]->seekpoint[j]->psz_name == NULL ||
  257.                 *p_input->title[i]->seekpoint[j]->psz_name == '' )
  258.             {
  259.                 /* Default value */
  260.                 asprintf( &text2.psz_string, _("Chapter %i"),
  261.                           j + p_input->i_seekpoint_offset );
  262.             }
  263.             else
  264.             {
  265.                 text2.psz_string =
  266.                     strdup( p_input->title[i]->seekpoint[j]->psz_name );
  267.             }
  268.             var_Change( p_input, val.psz_string, VLC_VAR_ADDCHOICE,
  269.                         &val2, &text2 );
  270.             if( text2.psz_string ) free( text2.psz_string );
  271.         }
  272.     }
  273.     free( val.psz_string );
  274. }
  275. /*****************************************************************************
  276.  * input_ControlVarTitle:
  277.  *  Create all variables for a title
  278.  *****************************************************************************/
  279. void input_ControlVarTitle( input_thread_t *p_input, int i_title )
  280. {
  281.     input_title_t *t = p_input->title[i_title];
  282.     vlc_value_t val;
  283.     int  i;
  284.     /* Create/Destroy command variables */
  285.     if( t->i_seekpoint <= 1 )
  286.     {
  287.         var_Destroy( p_input, "next-chapter" );
  288.         var_Destroy( p_input, "prev-chapter" );
  289.     }
  290.     else if( var_Get( p_input, "next-chapter", &val ) != VLC_SUCCESS )
  291.     {
  292.         vlc_value_t text;
  293.         var_Create( p_input, "next-chapter", VLC_VAR_VOID );
  294.         text.psz_string = _("Next chapter");
  295.         var_Change( p_input, "next-chapter", VLC_VAR_SETTEXT, &text, NULL );
  296.         var_AddCallback( p_input, "next-chapter", SeekpointCallback, NULL );
  297.         var_Create( p_input, "prev-chapter", VLC_VAR_VOID );
  298.         text.psz_string = _("Previous chapter");
  299.         var_Change( p_input, "prev-chapter", VLC_VAR_SETTEXT, &text, NULL );
  300.         var_AddCallback( p_input, "prev-chapter", SeekpointCallback, NULL );
  301.     }
  302.     /* Build chapter list */
  303.     var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL, NULL );
  304.     for( i = 0; i <  t->i_seekpoint; i++ )
  305.     {
  306.         vlc_value_t text;
  307.         val.i_int = i;
  308.         if( t->seekpoint[i]->psz_name == NULL ||
  309.             *t->seekpoint[i]->psz_name == '' )
  310.         {
  311.             /* Default value */
  312.             asprintf( &text.psz_string, _("Chapter %i"),
  313.                       i + p_input->i_seekpoint_offset );
  314.         }
  315.         else
  316.         {
  317.             text.psz_string = strdup( t->seekpoint[i]->psz_name );
  318.         }
  319.         var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val, &text );
  320.         if( text.psz_string ) free( text.psz_string );
  321.     }
  322. }
  323. /*****************************************************************************
  324.  * input_ConfigVarInit:
  325.  *  Create all config object variables
  326.  *****************************************************************************/
  327. void input_ConfigVarInit ( input_thread_t *p_input )
  328. {
  329.     vlc_value_t val;
  330.     /* Create Object Variables for private use only */
  331.     var_Create( p_input, "video", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  332.     var_Create( p_input, "audio", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  333.     var_Create( p_input, "audio-channel", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  334.     var_Create( p_input, "spu-channel", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  335.     var_Create( p_input, "sub-file", VLC_VAR_FILE | VLC_VAR_DOINHERIT );
  336.     var_Create( p_input, "sub-autodetect-file", VLC_VAR_BOOL |
  337.                 VLC_VAR_DOINHERIT );
  338.     var_Create( p_input, "sub-autodetect-path", VLC_VAR_STRING |
  339.                 VLC_VAR_DOINHERIT );
  340.     var_Create( p_input, "sub-autodetect-fuzzy", VLC_VAR_INTEGER |
  341.                 VLC_VAR_DOINHERIT );
  342.     var_Create( p_input, "sout", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  343.     var_Create( p_input, "sout-all",   VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  344.     var_Create( p_input, "sout-audio", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  345.     var_Create( p_input, "sout-video", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  346.     var_Create( p_input, "sout-keep",  VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
  347.     var_Create( p_input, "input-repeat", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  348.     var_Create( p_input, "start-time", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  349.     var_Create( p_input, "stop-time", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
  350.     var_Create( p_input, "minimize-threads", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
  351.     var_Create( p_input, "demuxed-id3", VLC_VAR_BOOL ); /* FIXME beurk */
  352.     val.b_bool = VLC_FALSE;
  353.     var_Change( p_input, "demuxed-id3", VLC_VAR_SETVALUE, &val, NULL );
  354.     var_Create( p_input, "audio-desync", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  355.     var_Create( p_input, "cr-average", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  356.     var_Create( p_input, "seekable", VLC_VAR_BOOL );
  357.     val.b_bool = VLC_TRUE; /* Fixed later*/
  358.     var_Change( p_input, "seekable", VLC_VAR_SETVALUE, &val, NULL );
  359.     var_Create( p_input, "input-slave", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  360.     /* Meta */
  361.     var_Create( p_input, "meta-title", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  362.     var_Create( p_input, "meta-author", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  363.     var_Create( p_input, "meta-artist", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  364.     var_Create( p_input, "meta-genre", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  365.     var_Create( p_input, "meta-copyright", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
  366.     var_Create( p_input, "meta-description", VLC_VAR_STRING|VLC_VAR_DOINHERIT);
  367.     var_Create( p_input, "meta-date", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  368.     var_Create( p_input, "meta-url", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
  369. }
  370. /*****************************************************************************
  371.  * All Callbacks:
  372.  *****************************************************************************/
  373. static int StateCallback( vlc_object_t *p_this, char const *psz_cmd,
  374.                           vlc_value_t oldval, vlc_value_t newval,
  375.                           void *p_data )
  376. {
  377.     input_thread_t *p_input = (input_thread_t*)p_this;
  378.     if( newval.i_int == PLAYING_S || newval.i_int == PAUSE_S )
  379.     {
  380.         input_ControlPush( p_input, INPUT_CONTROL_SET_STATE, &newval );
  381.         return VLC_SUCCESS;
  382.     }
  383.     return VLC_EGENERIC;
  384. }
  385. static int RateCallback( vlc_object_t *p_this, char const *psz_cmd,
  386.                          vlc_value_t oldval, vlc_value_t newval, void *p_data )
  387. {
  388.     input_thread_t *p_input = (input_thread_t*)p_this;
  389.     vlc_value_t val;
  390.     int i_rate;
  391.     /* Problem with this way: the "rate" variable is update after the input thread do the change */
  392.     if( !strcmp( psz_cmd, "rate-slower" ) )
  393.     {
  394.         input_ControlPush( p_input, INPUT_CONTROL_SET_RATE_SLOWER, NULL );
  395.         /* Fix "rate" value */
  396.         i_rate = var_GetInteger( p_input, "rate" ) * 2;
  397.         if( i_rate < INPUT_RATE_MIN ) i_rate = INPUT_RATE_MIN;
  398.         val.i_int = i_rate;
  399.         var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
  400.     }
  401.     else if( !strcmp( psz_cmd, "rate-faster" ) )
  402.     {
  403.         input_ControlPush( p_input, INPUT_CONTROL_SET_RATE_FASTER, NULL );
  404.         i_rate = var_GetInteger( p_input, "rate" ) / 2;
  405.         if( i_rate > INPUT_RATE_MAX ) i_rate = INPUT_RATE_MAX;
  406.         val.i_int = i_rate;
  407.         var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
  408.     }
  409.     else
  410.     {
  411.         input_ControlPush( p_input, INPUT_CONTROL_SET_RATE, &newval );
  412.     }
  413.     return VLC_SUCCESS;
  414. }
  415. static int PositionCallback( vlc_object_t *p_this, char const *psz_cmd,
  416.                              vlc_value_t oldval, vlc_value_t newval,
  417.                              void *p_data )
  418. {
  419.     input_thread_t *p_input = (input_thread_t*)p_this;
  420.     vlc_value_t val, length;
  421.     if( !strcmp( psz_cmd, "position-offset" ) )
  422.     {
  423.         input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION_OFFSET, &newval );
  424.         val.f_float = var_GetFloat( p_input, "position" ) + newval.f_float;
  425.         if( val.f_float < 0.0 ) val.f_float = 0.0;
  426.         if( val.f_float > 1.0 ) val.f_float = 1.0;
  427.         var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
  428.     }
  429.     else
  430.     {
  431.         val.f_float = newval.f_float;
  432.         input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION, &newval );
  433.     }
  434.     /* Update "position" for better intf behavour */
  435.     var_Get( p_input, "length", &length );
  436.     if( length.i_time > 0 && val.f_float >= 0.0 && val.f_float <= 1.0 )
  437.     {
  438.         val.i_time = length.i_time * val.f_float;
  439.         var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
  440.     }
  441.     return VLC_SUCCESS;
  442. }
  443. static int TimeCallback( vlc_object_t *p_this, char const *psz_cmd,
  444.                          vlc_value_t oldval, vlc_value_t newval, void *p_data )
  445. {
  446.     input_thread_t *p_input = (input_thread_t*)p_this;
  447.     vlc_value_t val, length;
  448.     if( !strcmp( psz_cmd, "time-offset" ) )
  449.     {
  450.         input_ControlPush( p_input, INPUT_CONTROL_SET_TIME_OFFSET, &newval );
  451.         val.i_time = var_GetTime( p_input, "time" ) + newval.i_time;
  452.         if( val.i_time < 0 ) val.i_time = 0;
  453.         /* TODO maybe test against i_length ? */
  454.         var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
  455.     }
  456.     else
  457.     {
  458.         val.i_time = newval.i_time;
  459.         input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &newval );
  460.     }
  461.     /* Update "position" for better intf behavour */
  462.     var_Get( p_input, "length", &length );
  463.     if( length.i_time > 0 && val.i_time >= 0 && val.i_time <= length.i_time )
  464.     {
  465.         val.f_float = (double)val.i_time/(double)length.i_time;
  466.         var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
  467.     }
  468.     return VLC_SUCCESS;
  469. }
  470. static int ProgramCallback( vlc_object_t *p_this, char const *psz_cmd,
  471.                             vlc_value_t oldval, vlc_value_t newval,
  472.                             void *p_data )
  473. {
  474.     input_thread_t *p_input = (input_thread_t*)p_this;
  475.     input_ControlPush( p_input, INPUT_CONTROL_SET_PROGRAM, &newval );
  476.     return VLC_SUCCESS;
  477. }
  478. static int TitleCallback( vlc_object_t *p_this, char const *psz_cmd,
  479.                           vlc_value_t oldval, vlc_value_t newval,
  480.                           void *p_data )
  481. {
  482.     input_thread_t *p_input = (input_thread_t*)p_this;
  483.     vlc_value_t val, count;
  484.     if( !strcmp( psz_cmd, "next-title" ) )
  485.     {
  486.         input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE_NEXT, NULL );
  487.         val.i_int = var_GetInteger( p_input, "title" ) + 1;
  488.         var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &count, NULL );
  489.         if( val.i_int < count.i_int )
  490.             var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );
  491.     }
  492.     else if( !strcmp( psz_cmd, "prev-title" ) )
  493.     {
  494.         input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE_PREV, NULL );
  495.         val.i_int = var_GetInteger( p_input, "title" ) - 1;
  496.         if( val.i_int >= 0 )
  497.             var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );
  498.     }
  499.     else
  500.     {
  501.         input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &newval );
  502.     }
  503.     return VLC_SUCCESS;
  504. }
  505. static int SeekpointCallback( vlc_object_t *p_this, char const *psz_cmd,
  506.                               vlc_value_t oldval, vlc_value_t newval,
  507.                               void *p_data )
  508. {
  509.     input_thread_t *p_input = (input_thread_t*)p_this;
  510.     vlc_value_t val, count;
  511.     if( !strcmp( psz_cmd, "next-chapter" ) )
  512.     {
  513.         input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT_NEXT, NULL );
  514.         val.i_int = var_GetInteger( p_input, "chapter" ) + 1;
  515.         var_Change( p_input, "chapter", VLC_VAR_CHOICESCOUNT, &count, NULL );
  516.         if( val.i_int < count.i_int )
  517.             var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL );
  518.     }
  519.     else if( !strcmp( psz_cmd, "prev-chapter" ) )
  520.     {
  521.         input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT_PREV, NULL );
  522.         val.i_int = var_GetInteger( p_input, "chapter" ) - 1;
  523.         if( val.i_int >= 0 )
  524.             var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL );
  525.     }
  526.     else
  527.     {
  528.         input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT, &newval );
  529.     }
  530.     return VLC_SUCCESS;
  531. }
  532. static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,
  533.                                vlc_value_t oldval, vlc_value_t newval,
  534.                                void *p_data )
  535. {
  536.     input_thread_t *p_input = (input_thread_t*)p_this;
  537.     vlc_value_t     val;
  538.     /* Issue a title change */
  539.     val.i_int = (int)p_data;
  540.     input_ControlPush( p_input, INPUT_CONTROL_SET_TITLE, &val );
  541.     var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );
  542.     /* And a chapter change */
  543.     input_ControlPush( p_input, INPUT_CONTROL_SET_SEEKPOINT, &newval );
  544.     var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &newval, NULL );
  545.     return VLC_SUCCESS;
  546. }
  547. static int ESCallback( vlc_object_t *p_this, char const *psz_cmd,
  548.                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
  549. {
  550.     input_thread_t *p_input = (input_thread_t*)p_this;
  551.     if( newval.i_int < 0 )
  552.     {
  553.         vlc_value_t v;
  554.         /* Hack */
  555.         if( !strcmp( psz_cmd, "audio-es" ) )
  556.             v.i_int = -AUDIO_ES;
  557.         else if( !strcmp( psz_cmd, "video-es" ) )
  558.             v.i_int = -VIDEO_ES;
  559.         else if( !strcmp( psz_cmd, "spu-es" ) )
  560.             v.i_int = -SPU_ES;
  561.         else
  562.             v.i_int = 0;
  563.         if( v.i_int != 0 )
  564.             input_ControlPush( p_input, INPUT_CONTROL_SET_ES, &v );
  565.     }
  566.     else
  567.     {
  568.         input_ControlPush( p_input, INPUT_CONTROL_SET_ES, &newval );
  569.     }
  570.     return VLC_SUCCESS;
  571. }
  572. static int EsDelayCallback ( vlc_object_t *p_this, char const *psz_cmd,
  573.                              vlc_value_t oldval, vlc_value_t newval, void *p )
  574. {
  575.     input_thread_t *p_input = (input_thread_t*)p_this;
  576.     if( !strcmp( psz_cmd, "audio-delay" ) )
  577.         input_ControlPush( p_input, INPUT_CONTROL_SET_AUDIO_DELAY, &newval );
  578.     else if( !strcmp( psz_cmd, "spu-delay" ) )
  579.         input_ControlPush( p_input, INPUT_CONTROL_SET_SPU_DELAY, &newval );
  580.     return VLC_SUCCESS;
  581. }
  582. static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
  583.                              vlc_value_t oldval, vlc_value_t newval,
  584.                              void *p_data )
  585. {
  586.     input_thread_t *p_input = (input_thread_t*)p_this;
  587.     input_ControlPush( p_input, INPUT_CONTROL_SET_BOOKMARK, &newval );
  588.     return VLC_SUCCESS;
  589. }