+
+/*****************************************************************************
+ * Navigation callback: a bunch of navigation variables are used as an
+ * alternative to the navigation API.
+ *****************************************************************************/
+static int ProgramCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ input_thread_t *p_input = (input_thread_t *)p_this;
+
+ if( oldval.i_int == newval.i_int )
+ return VLC_SUCCESS;
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ if( ( newval.i_int > 0 ) )
+ {
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ input_ChangeProgram( p_input, (uint16_t)newval.i_int );
+ input_SetStatus( p_input, INPUT_STATUS_PLAY );
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ }
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ return VLC_SUCCESS;
+}
+
+static int TitleCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ input_thread_t *p_input = (input_thread_t *)p_this;
+ input_area_t *p_area;
+
+ if( oldval.i_int == newval.i_int )
+ return VLC_SUCCESS;
+
+ /* Sanity check should have already be done by var_Set(). */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_area = p_input->stream.pp_areas[newval.i_int];
+ p_area->i_part = 1;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ input_ChangeArea( p_input, p_area );
+ input_SetStatus( p_input, INPUT_STATUS_PLAY );
+
+ return VLC_SUCCESS;
+}
+
+static int ChapterCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ input_thread_t *p_input = (input_thread_t *)p_this;
+ input_area_t *p_area;
+
+ if( oldval.i_int == newval.i_int )
+ return VLC_SUCCESS;
+
+ /* Sanity check will have already be done by var_Set(). */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_area = p_input->stream.p_selected_area;
+ p_input->stream.p_selected_area->i_part = newval.i_int;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ input_ChangeArea( p_input, p_area );
+ input_SetStatus( p_input, INPUT_STATUS_PLAY );
+
+ return VLC_SUCCESS;
+}
+
+static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ input_thread_t *p_input = (input_thread_t *)p_this;
+ uint16_t i_area_id = (int)p_data;
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+
+ if( p_input->stream.p_selected_area->i_id == i_area_id &&
+ oldval.i_int == newval.i_int )
+ {
+ /* Nothing to do */
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return VLC_SUCCESS;
+ }
+
+ if( ( i_area_id < p_input->stream.i_area_nb ) && ( newval.i_int > 0 ) &&
+ ( (uint16_t)newval.i_int <=
+ p_input->stream.pp_areas[i_area_id]->i_part_nb ) )
+ {
+ input_area_t *p_area = p_input->stream.pp_areas[i_area_id];
+ p_input->stream.p_selected_area->i_part = newval.i_int;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ input_ChangeArea( p_input, p_area );
+ input_SetStatus( p_input, INPUT_STATUS_PLAY );
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ }
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ return VLC_SUCCESS;
+}
+
+static int ESCallback( vlc_object_t *p_this, char const *psz_cmd,
+ vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+ input_thread_t *p_input = (input_thread_t *)p_this;
+ unsigned int i;
+
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+
+ /* Unselect old ES */
+ for( i = 0 ; i < p_input->stream.i_es_number ; i++ )
+ {
+ if( p_input->stream.pp_es[i]->i_id == oldval.i_int &&
+ p_input->stream.pp_es[i]->p_decoder_fifo != NULL )
+ {
+ input_UnselectES( p_input, p_input->stream.pp_es[i] );
+ }
+ }
+
+ /* Select new ES */
+ for( i = 0 ; i < p_input->stream.i_es_number ; i++ )
+ {
+ if( p_input->stream.pp_es[i]->i_id == newval.i_int &&
+ p_input->stream.pp_es[i]->p_decoder_fifo == NULL )
+ {
+ input_SelectES( p_input, p_input->stream.pp_es[i] );
+ }
+ }
+
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+ return VLC_SUCCESS;
+}