Move/clean up input event code to its own file.
authorLaurent Aimar <fenrir@videolan.org>
Thu, 20 Nov 2008 20:49:51 +0000 (21:49 +0100)
committerLaurent Aimar <fenrir@videolan.org>
Sat, 22 Nov 2008 15:29:54 +0000 (16:29 +0100)
There is no functionnal changes except a few missing events added.

include/vlc_input.h
src/Makefile.am
src/input/control.c
src/input/es_out.c
src/input/event.c [new file with mode: 0644]
src/input/event.h [new file with mode: 0644]
src/input/input.c
src/input/input_internal.h
src/input/item.c
src/input/var.c
src/libvlccore.sym

index 2ea1686..28973ee 100644 (file)
@@ -179,7 +179,8 @@ VLC_EXPORT( void,   input_item_MetaMerge, ( input_item_t *p_i, const vlc_meta_t
 #define input_item_GetSetting( item )        input_item_GetMeta( item, vlc_meta_Setting )
 
 VLC_EXPORT( char *, input_item_GetInfo, ( input_item_t *p_i, const char *psz_cat,const char *psz_name ) );
-VLC_EXPORT(int, input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) LIBVLC_FORMAT( 4, 5 ) );
+VLC_EXPORT( int, input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) LIBVLC_FORMAT( 4, 5 ) );
+VLC_EXPORT( int, input_item_DelInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name ) );
 
 #define input_item_New( a,b,c ) input_item_NewExt( a, b, c, 0, NULL, -1 )
 #define input_item_NewExt(a,b,c,d,e,f) __input_item_NewExt( VLC_OBJECT(a),b,c,d,e,f)
index b2de04b..106cfaf 100644 (file)
@@ -310,6 +310,7 @@ SOURCES_libvlc_common = \
        input/demux.c \
        input/es_out.c \
        input/es_out_timeshift.c \
+       input/event.c \
        input/input.c \
        input/meta.c \
        input/access.h \
@@ -318,6 +319,7 @@ SOURCES_libvlc_common = \
        input/demux.h \
        input/es_out.h \
        input/es_out_timeshift.h \
+       input/event.h \
        input/stream.h \
        input/input_internal.h \
        input/vlm_internal.h \
index ed3d12e..953fd0b 100644 (file)
@@ -31,6 +31,7 @@
 #include <stdlib.h>
 
 #include "input_internal.h"
+#include "event.h"
 
 
 static void UpdateBookmarksOption( input_thread_t * );
@@ -139,143 +140,30 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
             char *psz_name = (char *)va_arg( args, char * );
             char *psz_format = (char *)va_arg( args, char * );
 
-            info_category_t *p_cat;
-            info_t *p_info;
-            int i;
-
-            vlc_mutex_lock( &p_input->p->input.p_item->lock );
-            for( i = 0; i < p_input->p->input.p_item->i_categories; i++ )
-            {
-                if( !strcmp( p_input->p->input.p_item->pp_categories[i]->psz_name,
-                             psz_cat ) ) break;
-            }
-
-            if( i == p_input->p->input.p_item->i_categories )
-            {
-                p_cat = malloc( sizeof( info_category_t ) );
-                if( !p_cat )
-                {
-                    vlc_mutex_unlock( &p_input->p->input.p_item->lock );
-                    return VLC_EGENERIC;
-                }
-                p_cat->psz_name = strdup( psz_cat );
-                p_cat->i_infos = 0;
-                p_cat->pp_infos = NULL;
-                INSERT_ELEM( p_input->p->input.p_item->pp_categories,
-                             p_input->p->input.p_item->i_categories,
-                             p_input->p->input.p_item->i_categories, p_cat );
-            }
-
-            p_cat = p_input->p->input.p_item->pp_categories[i];
-
-            for( i = 0; i < p_cat->i_infos; i++ )
-            {
-                if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
-                {
-                    if( p_cat->pp_infos[i]->psz_value )
-                        free( p_cat->pp_infos[i]->psz_value );
-                    break;
-                }
-            }
-
-            if( i == p_cat->i_infos )
-            {
-                p_info = malloc( sizeof( info_t ) );
-                if( !p_info )
-                {
-                    vlc_mutex_unlock( &p_input->p->input.p_item->lock );
-                    return VLC_EGENERIC;
-                }
-
-                INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos,
-                             p_cat->i_infos, p_info );
-                p_info->psz_name = strdup( psz_name );
-            }
-
-            p_info = p_cat->pp_infos[i];
-            if( vasprintf( &p_info->psz_value, psz_format, args ) == -1 )
-                p_info->psz_value = NULL;
+            char *psz_value;
+            
+            if( vasprintf( &psz_value, psz_format, args ) == -1 )
+                return VLC_EGENERIC;
 
-            vlc_mutex_unlock( &p_input->p->input.p_item->lock );
+            int i_ret = input_item_AddInfo( p_input->p->input.p_item,
+                                            psz_cat, psz_name, "%s", psz_value );
 
-            if( !p_input->b_preparsing )
-            {
-                vlc_event_t event;
-                event.type = vlc_InputItemInfoChanged;
-                vlc_event_send( &p_input->p->input.p_item->event_manager, &event );
-            }
+            if( !p_input->b_preparsing && !i_ret )
+                input_SendEventMetaInfo( p_input );
+            return i_ret;
         }
-        return VLC_SUCCESS;
 
         case INPUT_DEL_INFO:
         {
             char *psz_cat = (char *)va_arg( args, char * );
             char *psz_name = (char *)va_arg( args, char * );
 
-            info_category_t *p_cat = NULL;
-            int i_cat;
-            int i;
+            int i_ret = input_item_DelInfo( p_input->p->input.p_item,
+                                            psz_cat, psz_name );
 
-            vlc_mutex_lock( &p_input->p->input.p_item->lock );
-            for( i_cat = 0; i_cat < p_input->p->input.p_item->i_categories; i_cat++ )
-            {
-                if( !strcmp( p_input->p->input.p_item->pp_categories[i_cat]->psz_name,
-                             psz_cat ) )
-                {
-                    p_cat = p_input->p->input.p_item->pp_categories[i_cat];
-                    break;
-                }
-            }
-            if( p_cat == NULL )
-            {
-                vlc_mutex_unlock( &p_input->p->input.p_item->lock );
-                return VLC_EGENERIC;
-            }
-
-            if( psz_name )
-            {
-                /* Remove a specific info */
-                for( i = 0; i < p_cat->i_infos; i++ )
-                {
-                    if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
-                    {
-                        free( p_cat->pp_infos[i]->psz_name );
-                        if( p_cat->pp_infos[i]->psz_value )
-                            free( p_cat->pp_infos[i]->psz_value );
-                        free( p_cat->pp_infos[i] );
-                        REMOVE_ELEM( p_cat->pp_infos, p_cat->i_infos, i );
-                        break;
-                    }
-                }
-                if( i >= p_cat->i_infos )
-                {
-                    vlc_mutex_unlock( &p_input->p->input.p_item->lock );
-                    return VLC_EGENERIC;
-                }
-            }
-            else
-            {
-                /* Remove the complete categorie */
-                for( i = 0; i < p_cat->i_infos; i++ )
-                {
-                    free( p_cat->pp_infos[i]->psz_name );
-                    if( p_cat->pp_infos[i]->psz_value )
-                        free( p_cat->pp_infos[i]->psz_value );
-                    free( p_cat->pp_infos[i] );
-                }
-                if( p_cat->pp_infos )
-                    free( p_cat->pp_infos );
-                REMOVE_ELEM( p_input->p->input.p_item->pp_categories, p_input->p->input.p_item->i_categories, i_cat );
-            }
-            vlc_mutex_unlock( &p_input->p->input.p_item->lock );
-
-            if( !p_input->b_preparsing )
-            {
-                vlc_event_t event;
-                event.type = vlc_InputItemInfoChanged;
-                vlc_event_send( &p_input->p->input.p_item->event_manager, &event );
-            }
-            return VLC_SUCCESS;
+            if( !p_input->b_preparsing && !i_ret )
+                input_SendEventMetaInfo( p_input );
+            return i_ret;
         }
 
 
@@ -305,12 +193,7 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
             vlc_mutex_unlock( &p_input->p->input.p_item->lock );
 
             if( !p_input->b_preparsing )
-            {
-                vlc_event_t event;
-                event.type = vlc_InputItemNameChanged;
-                event.u.input_item_name_changed.new_name = psz_name;
-                vlc_event_send( &p_input->p->input.p_item->event_manager, &event );
-            }
+                input_SendEventMetaName( p_input, psz_name );
             return VLC_SUCCESS;
         }
 
index bfbfcef..37e6035 100644 (file)
@@ -42,6 +42,7 @@
 #include "clock.h"
 #include "decoder.h"
 #include "es_out.h"
+#include "event.h"
 
 #include "../stream_output/stream_output.h"
 
@@ -797,30 +798,25 @@ static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt,
     const  bool b_teletext = fmt->i_cat == SPU_ES && fmt->i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' );
     vlc_value_t       val, text;
 
-    const char *psz_var;
-
-    if( fmt->i_cat == AUDIO_ES )
-        psz_var = "audio-es";
-    else if( fmt->i_cat == VIDEO_ES )
-        psz_var = "video-es";
-    else if( fmt->i_cat == SPU_ES )
-        psz_var = "spu-es";
-    else
-        return;
-
     if( b_delete )
     {
+        /* TODO event */
         if( b_teletext )
             var_SetInteger( p_sys->p_input, "teletext-es", -1 );
 
-        val.i_int = i_id;
-        var_Change( p_input, psz_var, VLC_VAR_DELCHOICE, &val, NULL );
-
-        var_SetBool( p_sys->p_input, "intf-change", true );
+        input_SendEventEsDel( p_input, SPU_ES, i_id );
         return;
     }
 
     /* Get the number of ES already added */
+    const char *psz_var;
+    if( fmt->i_cat == AUDIO_ES )
+        psz_var = "audio-es";
+    else if( fmt->i_cat == VIDEO_ES )
+        psz_var = "video-es";
+    else
+        psz_var = "spu-es";
+
     var_Change( p_input, psz_var, VLC_VAR_CHOICESCOUNT, &val, NULL );
     if( val.i_int == 0 )
     {
@@ -858,18 +854,16 @@ static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt,
         }
     }
 
-    val.i_int = i_id;
-    var_Change( p_input, psz_var, VLC_VAR_ADDCHOICE, &val, &text );
+    input_SendEventEsAdd( p_input, fmt->i_cat, i_id, text.psz_string );
 
     free( text.psz_string );
 
     if( b_teletext )
     {
+        /* TODO event */
         if( var_GetInteger( p_sys->p_input, "teletext-es" ) < 0 )
             var_SetInteger( p_sys->p_input, "teletext-es", i_id );
     }
-
-    var_SetBool( p_sys->p_input, "intf-change", true );
 }
 
 static void EsOutESVarUpdate( es_out_t *out, es_out_id_t *es,
@@ -885,7 +879,6 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
 {
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
-    vlc_value_t       val;
     int               i;
 
     if( p_sys->p_pgrm == p_pgrm )
@@ -917,14 +910,16 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
     p_sys->p_pgrm = p_pgrm;
 
     /* Update "program" */
-    val.i_int = p_pgrm->i_id;
-    var_Change( p_input, "program", VLC_VAR_SETVALUE, &val, NULL );
+    input_SendEventProgramSelect( p_input, p_pgrm->i_id );
 
     /* Update "es-*" */
-    var_Change( p_input, "audio-es", VLC_VAR_CLEARCHOICES, NULL, NULL );
-    var_Change( p_input, "video-es", VLC_VAR_CLEARCHOICES, NULL, NULL );
-    var_Change( p_input, "spu-es",   VLC_VAR_CLEARCHOICES, NULL, NULL );
+    input_SendEventEsDel( p_input, AUDIO_ES, -1 );
+    input_SendEventEsDel( p_input, VIDEO_ES, -1 );
+    input_SendEventEsDel( p_input, SPU_ES, -1 );
+
+    /* TODO event */
     var_SetInteger( p_input, "teletext-es", -1 );
+
     for( i = 0; i < p_sys->i_es; i++ )
     {
         if( p_sys->es[i]->p_pgrm == p_sys->p_pgrm )
@@ -938,7 +933,7 @@ static void EsOutProgramSelect( es_out_t *out, es_out_pgrm_t *p_pgrm )
     input_item_SetPublisher( p_input->p->input.p_item,
                              p_pgrm->psz_publisher );
 
-    var_SetBool( p_sys->p_input, "intf-change", true );
+    input_SendEventMeta( p_input );
 }
 
 /* EsOutAddProgram:
@@ -948,7 +943,6 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group )
 {
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
-    vlc_value_t       val;
 
     es_out_pgrm_t *p_pgrm = malloc( sizeof( es_out_pgrm_t ) );
     if( !p_pgrm )
@@ -973,17 +967,11 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group )
     TAB_APPEND( p_sys->i_pgrm, p_sys->pgrm, p_pgrm );
 
     /* Update "program" variable */
-    val.i_int = i_group;
-    var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, NULL );
+    input_SendEventProgramAdd( p_input, i_group, NULL );
 
     if( i_group == var_GetInteger( p_input, "program" ) )
-    {
         EsOutProgramSelect( out, p_pgrm );
-    }
-    else
-    {
-        var_SetBool( p_sys->p_input, "intf-change", true );
-    }
+
     return p_pgrm;
 }
 
@@ -995,7 +983,6 @@ static int EsOutProgramDel( es_out_t *out, int i_group )
     es_out_sys_t      *p_sys = out->p_sys;
     input_thread_t    *p_input = p_sys->p_input;
     es_out_pgrm_t     *p_pgrm = NULL;
-    vlc_value_t       val;
     int               i;
 
     for( i = 0; i < p_sys->i_pgrm; i++ )
@@ -1033,10 +1020,7 @@ static int EsOutProgramDel( es_out_t *out, int i_group )
     free( p_pgrm );
 
     /* Update "program" variable */
-    val.i_int = i_group;
-    var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
-
-    var_SetBool( p_sys->p_input, "intf-change", true );
+    input_SendEventProgramDel( p_input, i_group );
 
     return VLC_SUCCESS;
 }
@@ -1098,9 +1082,6 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta )
     /* Update the description text of the program */
     if( psz_title && *psz_title )
     {
-        vlc_value_t val;
-        vlc_value_t text;
-
         if( !p_pgrm->psz_name || strcmp( p_pgrm->psz_name, psz_title ) )
         {
             char *psz_cat = EsOutProgramGetMetaName( p_pgrm );
@@ -1113,22 +1094,24 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta )
         free( p_pgrm->psz_name );
         p_pgrm->psz_name = strdup( psz_title );
 
-        /* ugly but it works */
-        val.i_int = i_group;
-        var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
-
+        char *psz_text;
         if( psz_provider && *psz_provider )
         {
-            if( asprintf( &text.psz_string, "%s [%s]", psz_title, psz_provider ) != -1 )
-            {
-                var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text );
-                free( text.psz_string );
-            }
+            if( asprintf( &psz_text, "%s [%s]", psz_title, psz_provider ) < 0 )
+                psz_text = NULL;
         }
         else
         {
-            text.psz_string = (char *)psz_title;
-            var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text );
+            psz_text = strdup( psz_title );
+        }
+
+        /* ugly but it works */
+        if( psz_text )
+        {
+            input_SendEventProgramDel( p_input, i_group );
+            input_SendEventProgramAdd( p_input, i_group, psz_text );
+
+            free( psz_text );
         }
     }
 
@@ -1136,7 +1119,10 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta )
     if( psz_provider )
     {
         if( p_sys->p_pgrm == p_pgrm )
+        {
             input_item_SetPublisher( p_input->p->input.p_item, psz_provider );
+            input_SendEventMeta( p_input );
+        }
         input_Control( p_input, INPUT_ADD_INFO, psz_cat, input_MetaTypeToLocalizedString(vlc_meta_Publisher), psz_provider );
     }
     char ** ppsz_all_keys = vlc_dictionary_all_keys( &p_meta->extra_tags );
@@ -1259,7 +1245,10 @@ static void EsOutProgramEpg( es_out_t *out, int i_group, vlc_epg_t *p_epg )
         p_pgrm->psz_now_playing = strdup( p_epg->p_current->psz_name );
 
     if( p_pgrm == p_sys->p_pgrm )
+    {
         input_item_SetNowPlaying( p_input->p->input.p_item, p_pgrm->psz_now_playing );
+        input_SendEventMeta( p_input );
+    }
 
     if( p_pgrm->psz_now_playing )
     {
@@ -1468,7 +1457,6 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
     es_out_sys_t   *p_sys = out->p_sys;
     input_thread_t *p_input = p_sys->p_input;
     vlc_value_t    val;
-    const char     *psz_var;
 
     if( EsIsSelected( es ) )
     {
@@ -1524,28 +1512,14 @@ static void EsSelect( es_out_t *out, es_out_id_t *es )
             return;
     }
 
-    if( es->fmt.i_cat == VIDEO_ES )
-        psz_var = "video-es";
-    else if( es->fmt.i_cat == AUDIO_ES )
-        psz_var = "audio-es";
-    else if( es->fmt.i_cat == SPU_ES )
-        psz_var = "spu-es";
-    else
-        return;
-
     /* Mark it as selected */
-    val.i_int = es->i_id;
-    var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL );
-
-    var_SetBool( p_sys->p_input, "intf-change", true );
+    input_SendEventEsSelect( p_input, es->fmt.i_cat, es->i_id );
 }
 
 static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update )
 {
     es_out_sys_t   *p_sys = out->p_sys;
     input_thread_t *p_input = p_sys->p_input;
-    vlc_value_t    val;
-    const char     *psz_var;
 
     if( !EsIsSelected( es ) )
     {
@@ -1574,10 +1548,7 @@ static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update )
             if( i_spu_id == es->pp_cc_es[i]->i_id )
             {
                 /* Force unselection of the CC */
-                val.i_int = -1;
-                var_Change( p_input, "spu-es", VLC_VAR_SETVALUE, &val, NULL );
-                if( !b_update )
-                    var_SetBool( p_sys->p_input, "intf-change", true );
+                input_SendEventEsSelect( p_input, SPU_ES, -1 );
             }
             EsOutDel( out, es->pp_cc_es[i] );
 
@@ -1592,20 +1563,9 @@ static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update )
     /* Update var */
     if( es->p_dec == NULL )
         return;
-    if( es->fmt.i_cat == VIDEO_ES )
-        psz_var = "video-es";
-    else if( es->fmt.i_cat == AUDIO_ES )
-        psz_var = "audio-es";
-    else if( es->fmt.i_cat == SPU_ES )
-        psz_var = "spu-es";
-    else
-        return;
 
     /* Mark it as unselected */
-    val.i_int = -1;
-    var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL );
-
-    var_SetBool( p_sys->p_input, "intf-change", true );
+    input_SendEventEsSelect( p_input, es->fmt.i_cat, -1 );
 }
 
 /**
@@ -1836,7 +1796,6 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
 
     /* Check CC status */
     bool pb_cc[4];
-    bool b_cc_new = false;
 
     input_DecoderIsCcPresent( es->p_dec, pb_cc );
     for( int i = 0; i < 4; i++ )
@@ -1864,10 +1823,7 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
 
         /* */
         es->pb_cc_present[i] = true;
-        b_cc_new = true;
     }
-    if( b_cc_new )
-        var_SetBool( p_sys->p_input, "intf-change", true );
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -1963,7 +1919,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
 {
     es_out_sys_t *p_sys = out->p_sys;
     bool  b, *pb;
-    int         i, *pi;
+    int         i;
 
     es_out_id_t *es;
 
@@ -1995,9 +1951,6 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
         {
             b = (bool) va_arg( args, int );
             p_sys->b_active = b;
-            /* Needed ? */
-            if( b )
-                var_SetBool( p_sys->p_input, "intf-change", true );
             return VLC_SUCCESS;
         }
 
@@ -2076,12 +2029,6 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
                     }
                 }
             }
-            if( i_query == ES_OUT_SET_ES )
-            {
-                vlc_event_t event;
-                event.type = vlc_InputSelectedStreamChanged;
-                vlc_event_send( &p_sys->p_input->p->event_manager, &event );
-            }
             return VLC_SUCCESS;
         }
  
@@ -2533,6 +2480,7 @@ static void EsOutAddInfo( es_out_t *out, es_out_id_t *es )
         {
             input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Sample rate"),
                            _("%u Hz"), fmt->audio.i_rate );
+            /* FIXME that should be removed or improved ! (used by text/strings.c) */
             var_SetInteger( p_input, "sample-rate", fmt->audio.i_rate );
         }
 
@@ -2545,6 +2493,7 @@ static void EsOutAddInfo( es_out_t *out, es_out_id_t *es )
         {
             input_Control( p_input, INPUT_ADD_INFO, psz_cat, _("Bitrate"),
                            _("%u kb/s"), fmt->i_bitrate / 1000 );
+            /* FIXME that should be removed or improved ! (used by text/strings.c) */
             var_SetInteger( p_input, "bit-rate", fmt->i_bitrate );
         }
         break;
diff --git a/src/input/event.c b/src/input/event.c
new file mode 100644 (file)
index 0000000..90f029f
--- /dev/null
@@ -0,0 +1,291 @@
+/*****************************************************************************
+ * event.c: Events
+ *****************************************************************************
+ * Copyright (C) 2008 Laurent Aimar
+ * $Id$
+ *
+ * Authors: Laurent Aimar < fenrir _AT_ videolan _DOT_ org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_input.h>
+#include "input_internal.h"
+#include "event.h"
+
+/*****************************************************************************
+ * Event for input.c
+ *****************************************************************************/
+void input_SendEventTimes( input_thread_t *p_input, const input_event_times_t *p_times )
+{
+    vlc_value_t val;
+
+    /* */
+    val.f_float = p_times->f_position;
+    var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
+
+    /* */
+    val.i_time = p_times->i_time;
+    var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
+
+       /* FIXME ugly + what about meta change event ? */
+    if( var_GetTime( p_input, "length" ) != p_times->i_length )
+        input_item_SetDuration( p_input->p->input.p_item, p_times->i_length );
+    val.i_time = p_times->i_length;
+    var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
+
+    //var_SetBool( p_input, "intf-change-times", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+}
+void input_SendEventStatistics( input_thread_t *p_input )
+{
+    var_TriggerCallback( p_input, "stats-change" ); /* FIXME rename */
+}
+void input_SendEventRate( input_thread_t *p_input, int i_rate )
+{
+       vlc_value_t val;
+
+       val.i_int = i_rate;
+       var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
+
+       var_TriggerCallback( p_input, "rate-change" ); /* TODO rename */
+}
+void input_SendEventAudioDelay( input_thread_t *p_input, mtime_t i_delay )
+{
+       vlc_value_t val;
+
+       val.i_time = i_delay;
+       var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
+
+       //var_SetBool( p_input, "intf-change-delay" ); /* TODO */
+}
+
+void input_SendEventSubtitleDelay( input_thread_t *p_input, mtime_t i_delay )
+{
+       vlc_value_t val;
+
+       val.i_time = i_delay;
+       var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
+
+       //var_SetBool( p_input, "intf-change-delay" ); /* TODO */
+}
+
+/* TODO and file name ? */
+void input_SendEventRecord( input_thread_t *p_input, bool b_recording )
+{
+       vlc_value_t val;
+
+       val.b_bool = b_recording;
+       var_Change( p_input, "record", VLC_VAR_SETVALUE, &val, NULL );
+
+       var_TriggerCallback( p_input, "intf-change" ); /* FIXME */
+}
+
+void input_SendEventTitle( input_thread_t *p_input, int i_title )
+{
+       vlc_value_t val;
+
+       val.i_int = i_title;
+       var_Change( p_input, "title", VLC_VAR_SETVALUE, &val, NULL );
+
+       input_ControlVarTitle( p_input, i_title ); /* FIXME ??? */
+
+       //var_SetBool( p_input, "intf-change-title" ); /* TODO */
+}
+
+void input_SendEventSeekpoint( input_thread_t *p_input, int i_title, int i_seekpoint )
+{
+       vlc_value_t val;
+
+       VLC_UNUSED( i_title );
+       val.i_int = i_seekpoint;
+       var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val, NULL);
+
+       //var_SetBool( p_input, "intf-change-seekpoint" ); /* TODO. Merge with intf-change-title ?  */
+}
+
+void input_SendEventSignal( input_thread_t *p_input, double f_quality, double f_strength )
+{
+       var_SetFloat( p_input, "signal-quality", f_quality );
+       var_SetFloat( p_input, "signal-strength", f_strength );
+
+       /* TODO use Change and then a intf-change-signal instead ? */
+}
+
+void input_SendEventState( input_thread_t *p_input, int i_state )
+{
+    vlc_value_t val;
+
+    val.i_int = i_state;
+    var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
+
+    var_TriggerCallback( p_input, "intf-change" );
+
+       /* FIXME remove this ugliness */
+    vlc_event_t event;
+
+    event.type = vlc_InputStateChanged;
+    event.u.input_state_changed.new_state = i_state;
+    vlc_event_send( &p_input->p->event_manager, &event );
+}
+
+#warning "TODO meta"
+/* FIXME: review them because vlc_event_send might be
+ * moved inside input_item* functions.
+ */
+void input_SendEventMeta( input_thread_t *p_input )
+{
+    var_TriggerCallback( p_input, "intf-change" ); /* TODO intf-change-item-meta */
+
+       /* FIXME remove this ugliness ? */
+       vlc_event_t event;
+
+       event.type = vlc_InputItemMetaChanged;
+       event.u.input_item_meta_changed.meta_type = vlc_meta_ArtworkURL;
+       vlc_event_send( &p_input->p->input.p_item->event_manager, &event );
+}
+
+void input_SendEventMetaInfo( input_thread_t *p_input )
+{
+    var_TriggerCallback( p_input, "intf-change" ); /* TODO intf-change-item-info */
+
+       /* FIXME remove this ugliness */
+    vlc_event_t event;
+
+    event.type = vlc_InputItemInfoChanged;
+    vlc_event_send( &p_input->p->input.p_item->event_manager, &event );
+}
+
+void input_SendEventMetaName( input_thread_t *p_input, const char *psz_name )
+{
+    var_TriggerCallback( p_input, "intf-change" ); /* TODO intf-change-item-name */
+
+       /* FIXME remove this ugliness */
+    vlc_event_t event;
+
+    event.type = vlc_InputItemNameChanged;
+    event.u.input_item_name_changed.new_name = psz_name;
+    vlc_event_send( &p_input->p->input.p_item->event_manager, &event );
+}
+
+/*****************************************************************************
+ * Event for es_out.c
+ *****************************************************************************/
+void input_SendEventProgramAdd( input_thread_t *p_input,
+                                int i_program, const char *psz_text )
+{
+    vlc_value_t val;
+    vlc_value_t text;
+
+    val.i_int = i_program;
+    text.psz_string = (char*)psz_text;
+
+    var_Change( p_input, "program", VLC_VAR_ADDCHOICE,
+                &val, psz_text ? &text : NULL );
+
+    //var_SetBool( p_input, "intf-change-program", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+}
+void input_SendEventProgramDel( input_thread_t *p_input, int i_program )
+{
+    vlc_value_t val;
+
+    val.i_int = i_program;
+    var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );
+
+    //var_SetBool( p_input, "intf-change-program", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+}
+void input_SendEventProgramSelect( input_thread_t *p_input, int i_program )
+{
+    vlc_value_t val;
+
+    val.i_int = i_program;
+    var_Change( p_input, "program", VLC_VAR_SETVALUE, &val, NULL );
+
+    //var_SetBool( p_input, "intf-change-program", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+}
+
+static const char *GetEsVarName( int i_cat )
+{
+    switch( i_cat )
+    {
+    case VIDEO_ES:
+        return "video-es";
+    case AUDIO_ES:
+        return "audio-es";
+    default:
+        assert( i_cat == SPU_ES );
+        return "spu-es";
+    }
+}
+void input_SendEventEsDel( input_thread_t *p_input, int i_cat, int i_id )
+{
+    vlc_value_t val;
+
+    if( i_id >= 0 )
+    {
+        val.i_int = i_id;
+        var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_DELCHOICE, &val, NULL );
+    }
+    else
+    {
+        var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_CLEARCHOICES, NULL, NULL );
+    }
+
+    //var_SetBool( p_input, "intf-change-es", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+}
+void input_SendEventEsAdd( input_thread_t *p_input, int i_cat, int i_id, const char *psz_text )
+{
+    vlc_value_t val;
+    vlc_value_t text;
+
+    val.i_int = i_id;
+    text.psz_string = (char*)psz_text;
+
+    var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_ADDCHOICE,
+                &val, psz_text ? &text : NULL );
+
+    //var_SetBool( p_input, "intf-change-es", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+}
+
+/* i_id == -1 will unselect */
+void input_SendEventEsSelect( input_thread_t *p_input, int i_cat, int i_id )
+{
+    vlc_value_t val;
+
+    val.i_int = i_id;
+    var_Change( p_input, GetEsVarName( i_cat ), VLC_VAR_SETVALUE, &val, NULL );
+
+    //var_SetBool( p_input, "intf-change-es", true ); /* TODO */
+    var_TriggerCallback( p_input, "intf-change" );
+
+    /* FIXME to remove this ugliness */
+    vlc_event_t event;
+    event.type = vlc_InputSelectedStreamChanged;
+    vlc_event_send( &p_input->p->event_manager, &event );
+}
+
diff --git a/src/input/event.h b/src/input/event.h
new file mode 100644 (file)
index 0000000..6c4d959
--- /dev/null
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * event.h: Input event functions
+ *****************************************************************************
+ * Copyright (C) 2008 Laurent Aimar
+ * $Id$
+ *
+ * Authors: Laurent Aimar <fenrir _AT_ videolan _DOT_ fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#if defined(__PLUGIN__) || defined(__BUILTIN__) || !defined(__LIBVLC__)
+# error This header file can only be included from LibVLC.
+#endif
+
+#ifndef _INPUT_EVENT_H
+#define _INPUT_EVENT_H 1
+
+#include <vlc_common.h>
+
+/*****************************************************************************
+ * Event for input.c
+ *****************************************************************************/
+typedef struct
+{
+    double  f_position;
+    mtime_t i_time;
+    mtime_t i_length;
+} input_event_times_t;
+
+void input_SendEventTimes( input_thread_t *p_input, const input_event_times_t *p_times );
+void input_SendEventStatistics( input_thread_t *p_input );
+void input_SendEventRate( input_thread_t *p_input, int i_rate );
+void input_SendEventAudioDelay( input_thread_t *p_input, mtime_t i_delay );
+void input_SendEventSubtitleDelay( input_thread_t *p_input, mtime_t i_delay );
+void input_SendEventRecord( input_thread_t *p_input, bool b_recording );
+void input_SendEventTitle( input_thread_t *p_input, int i_title );
+void input_SendEventSeekpoint( input_thread_t *p_input, int i_title, int i_seekpoint );
+void input_SendEventSignal( input_thread_t *p_input, double f_quality, double f_strength );
+void input_SendEventState( input_thread_t *p_input, int i_state );
+
+/* TODO rename Item* */
+void input_SendEventMeta( input_thread_t *p_input );
+void input_SendEventMetaInfo( input_thread_t *p_input );
+void input_SendEventMetaName( input_thread_t *p_input, const char *psz_name );
+
+/*****************************************************************************
+ * Event for es_out.c
+ *****************************************************************************/
+void input_SendEventProgramAdd( input_thread_t *p_input,
+                                int i_program, const char *psz_text );
+void input_SendEventProgramDel( input_thread_t *p_input, int i_program );
+void input_SendEventProgramSelect( input_thread_t *p_input, int i_program );
+void input_SendEventEsDel( input_thread_t *p_input, int i_cat, int i_id );
+void input_SendEventEsAdd( input_thread_t *p_input, int i_cat, int i_id, const char *psz_text );
+void input_SendEventEsSelect( input_thread_t *p_input, int i_cat, int i_id ); /* i_id == -1 will unselect */
+
+#endif
+
index b054373..81ea306 100644 (file)
@@ -36,6 +36,7 @@
 #include <assert.h>
 
 #include "input_internal.h"
+#include "event.h"
 #include "es_out.h"
 #include "es_out_timeshift.h"
 #include "access.h"
@@ -76,8 +77,6 @@ static bool Control( input_thread_t *, int, vlc_value_t );
 static int  UpdateFromAccess( input_thread_t * );
 static int  UpdateFromDemux( input_thread_t * );
 
-static void UpdateItemLength( input_thread_t *, int64_t i_length );
-
 static void MRLSections( input_thread_t *, char *, int *, int *, int *, int *);
 
 static input_source_t *InputSourceNew( input_thread_t *);
@@ -101,6 +100,8 @@ static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_atta
 
 static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_forced );
 
+static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */
+
 /*****************************************************************************
  * This function creates a new input, and returns a pointer
  * to its description. On error, it returns NULL.
@@ -119,7 +120,7 @@ static void SubtitleAdd( input_thread_t *p_input, char *psz_subtitle, bool b_for
  * * Get only:
  *  - length
  *  - bookmarks
- *  - seekable (if you can seek, it doesn't say if 'bar display' has be shown
+ *  - seekable (if you can seek, it doesn't say if 'bar display' has be shown FIXME rename can-seek
  *    or not, for that check position != 0.0)
  *  - can-pause
  *  - can-record (if a stream can be recorded while playing)
@@ -307,6 +308,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
 
     /* Remove 'Now playing' info as it is probably outdated */
     input_item_SetNowPlaying( p_item, NULL );
+    input_SendEventMeta( p_input );
 
     /* */
     if( p_input->b_preparsing )
@@ -667,39 +669,26 @@ static void MainLoopDemux( input_thread_t *p_input, bool *pb_changed, mtime_t *p
  */
 static void MainLoopInterface( input_thread_t *p_input )
 {
-    vlc_value_t val;
-    double f_pos;
-    int64_t i_time, i_length;
+    input_event_times_t ev;
+
+    ev.f_position = 0.0;
+    ev.i_time = 0;
+    ev.i_length = 0;
 
     /* update input status variables */
-    if( !demux_Control( p_input->p->input.p_demux,
-                         DEMUX_GET_POSITION, &f_pos ) )
-    {
-        val.f_float = (float)f_pos;
-        var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL );
-    }
-    if( !demux_Control( p_input->p->input.p_demux,
-                         DEMUX_GET_TIME, &i_time ) )
-    {
-        p_input->i_time = i_time;
-        val.i_time = i_time;
-        var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL );
-    }
-    if( !demux_Control( p_input->p->input.p_demux,
-                         DEMUX_GET_LENGTH, &i_length ) )
-    {
-        vlc_value_t old_val;
-        var_Get( p_input, "length", &old_val );
-        val.i_time = i_length;
-        var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
+    if( demux_Control( p_input->p->input.p_demux,
+                       DEMUX_GET_POSITION, &ev.f_position ) )
+        ev.f_position = 0.0;
 
-        if( old_val.i_time != val.i_time )
-        {
-            UpdateItemLength( p_input, i_length );
-        }
-    }
+    if( demux_Control( p_input->p->input.p_demux,
+                       DEMUX_GET_TIME, &ev.i_time ) )
+        ev.i_time = 0;
+
+    if( demux_Control( p_input->p->input.p_demux,
+                       DEMUX_GET_LENGTH, &ev.i_length ) )
+        ev.i_length = 0;
 
-    var_SetBool( p_input, "intf-change", true );
+    input_SendEventTimes( p_input, &ev );
 }
 
 /**
@@ -715,7 +704,7 @@ static void MainLoopStatistic( input_thread_t *p_input )
         stats_ComputeGlobalStats( p_input->p_libvlc,
                                   p_input->p_libvlc->p_stats );
     }
-    var_SetBool( p_input, "stats-change", true );
+    input_SendEventStatistics( p_input );
 }
 
 /**
@@ -1159,7 +1148,6 @@ static void InitPrograms( input_thread_t * p_input )
 static int Init( input_thread_t * p_input )
 {
     vlc_meta_t *p_meta;
-    vlc_value_t val;
     int i, ret;
 
     for( i = 0; i < p_input->p->input.p_item->i_options; i++ )
@@ -1202,21 +1190,15 @@ static int Init( input_thread_t * p_input )
 
     /* Load master infos */
     /* Init length */
-    if( !demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH,
-                         &val.i_time ) && val.i_time > 0 )
-    {
-        var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
-        UpdateItemLength( p_input, val.i_time );
-    }
-    else
-    {
-        val.i_time = input_item_GetDuration( p_input->p->input.p_item );
-        if( val.i_time > 0 )
-        { /* fallback: gets length from metadata */
-            var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL );
-            UpdateItemLength( p_input, val.i_time );
-        }
-    }
+    input_event_times_t ev_times;
+    ev_times.f_position = 0;
+    ev_times.i_time = 0;
+    if( demux_Control( p_input->p->input.p_demux, DEMUX_GET_LENGTH,
+                         &ev_times.i_length ) )
+        ev_times.i_length = 0;
+    if( ev_times.i_length <= 0 )
+        ev_times.i_length = input_item_GetDuration( p_input->p->input.p_item );
+    input_SendEventTimes( p_input, &ev_times );
 
     StartTitle( p_input );
 
@@ -1529,7 +1511,7 @@ static void ControlPause( input_thread_t *p_input, mtime_t i_control_date )
     }
 
     /* Switch to new state */
-    input_ChangeStateWithVarCallback( p_input, i_state, false );
+    input_ChangeState( p_input, i_state );
 
 }
 
@@ -1556,7 +1538,7 @@ static void ControlUnpause( input_thread_t *p_input, mtime_t i_control_date )
     }
 
     /* Switch to play */
-    input_ChangeStateWithVarCallback( p_input, PLAYING_S, false );
+    input_ChangeState( p_input, PLAYING_S );
 
     /* */
     if( !i_ret )
@@ -1567,6 +1549,7 @@ static bool Control( input_thread_t *p_input, int i_type,
                            vlc_value_t val )
 {
     const mtime_t i_control_date = mdate();
+    /* FIXME b_force_update is abused, it should be carefully checked */
     bool b_force_update = false;
 
     if( !p_input )
@@ -1703,7 +1686,7 @@ static bool Control( input_thread_t *p_input, int i_type,
                 b_force_update = true;
 
                 /* Correct "state" value */
-                input_ChangeStateWithVarCallback( p_input, p_input->i_state, false );
+                input_ChangeState( p_input, p_input->i_state );
             }
             else if( val.i_int != PLAYING_S && val.i_int != PAUSE_S )
             {
@@ -1830,11 +1813,8 @@ static bool Control( input_thread_t *p_input, int i_type,
             /* */
             if( i_rate != p_input->p->i_rate )
             {
-                val.i_int = i_rate;
-                var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL );
-                var_SetBool( p_input, "rate-change", true );
-
                 p_input->p->i_rate = i_rate;
+                input_SendEventRate( p_input, i_rate );
 
                 if( p_input->p->input.b_rescale_ts )
                 {
@@ -1867,12 +1847,12 @@ static bool Control( input_thread_t *p_input, int i_type,
 
         case INPUT_CONTROL_SET_AUDIO_DELAY:
             if( !es_out_SetDelay( p_input->p->p_es_out_display, AUDIO_ES, val.i_time ) )
-                var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
+                input_SendEventAudioDelay( p_input, val.i_time );
             break;
 
         case INPUT_CONTROL_SET_SPU_DELAY:
             if( !es_out_SetDelay( p_input->p->p_es_out_display, SPU_ES, val.i_time ) )
-                var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
+                input_SendEventSubtitleDelay( p_input, val.i_time );
             break;
 
         case INPUT_CONTROL_SET_TITLE:
@@ -2087,7 +2067,7 @@ static bool Control( input_thread_t *p_input, int i_type,
                 }
                 p_input->p->b_recording = val.b_bool;
 
-                var_Change( p_input, "record", VLC_VAR_SETVALUE, &val, NULL );
+                input_SendEventRecord( p_input, val.b_bool );
 
                 b_force_update = true;
             }
@@ -2121,24 +2101,47 @@ static bool Control( input_thread_t *p_input, int i_type,
 /*****************************************************************************
  * UpdateFromDemux:
  *****************************************************************************/
+static int UpdateTitleSeekpoint( input_thread_t *p_input,
+                                 int i_title, int i_seekpoint )
+{
+    int i_title_end = p_input->p->input.i_title_end -
+                        p_input->p->input.i_title_offset;
+    int i_seekpoint_end = p_input->p->input.i_seekpoint_end -
+                            p_input->p->input.i_seekpoint_offset;
+
+    if( i_title_end >= 0 && i_seekpoint_end >= 0 )
+    {
+        if( i_title > i_title_end ||
+            ( i_title == i_title_end && i_seekpoint > i_seekpoint_end ) )
+            return 0;
+    }
+    else if( i_seekpoint_end >= 0 )
+    {
+        if( i_seekpoint > i_seekpoint_end )
+            return 0;
+    }
+    else if( i_title_end >= 0 )
+    {
+        if( i_title > i_title_end )
+            return 0;
+    }
+    return 1;
+}
 static int UpdateFromDemux( input_thread_t *p_input )
 {
     demux_t *p_demux = p_input->p->input.p_demux;
-    vlc_value_t v;
 
+    /* TODO event-like */
     if( p_demux->info.i_update & INPUT_UPDATE_TITLE )
     {
-        v.i_int = p_demux->info.i_title;
-        var_Change( p_input, "title", VLC_VAR_SETVALUE, &v, NULL );
-
-        input_ControlVarTitle( p_input, p_demux->info.i_title );
+        input_SendEventTitle( p_input, p_demux->info.i_title );
 
         p_demux->info.i_update &= ~INPUT_UPDATE_TITLE;
     }
     if( p_demux->info.i_update & INPUT_UPDATE_SEEKPOINT )
     {
-        v.i_int = p_demux->info.i_seekpoint;
-        var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &v, NULL);
+        input_SendEventSeekpoint( p_input,
+                                  p_demux->info.i_title, p_demux->info.i_seekpoint );
 
         p_demux->info.i_update &= ~INPUT_UPDATE_SEEKPOINT;
     }
@@ -2146,28 +2149,9 @@ static int UpdateFromDemux( input_thread_t *p_input )
 
     /* Hmmm only works with master input */
     if( p_input->p->input.p_demux == p_demux )
-    {
-        int i_title_end = p_input->p->input.i_title_end -
-            p_input->p->input.i_title_offset;
-        int i_seekpoint_end = p_input->p->input.i_seekpoint_end -
-            p_input->p->input.i_seekpoint_offset;
-
-        if( i_title_end >= 0 && i_seekpoint_end >= 0 )
-        {
-            if( p_demux->info.i_title > i_title_end ||
-                ( p_demux->info.i_title == i_title_end &&
-                  p_demux->info.i_seekpoint > i_seekpoint_end ) ) return 0;
-        }
-        else if( i_seekpoint_end >=0 )
-        {
-            if( p_demux->info.i_seekpoint > i_seekpoint_end ) return 0;
-        }
-        else if( i_title_end >= 0 )
-        {
-            if( p_demux->info.i_title > i_title_end ) return 0;
-        }
-    }
-
+        return UpdateTitleSeekpoint( p_input,
+                                     p_demux->info.i_title,
+                                     p_demux->info.i_seekpoint );
     return 1;
 }
 
@@ -2177,14 +2161,10 @@ static int UpdateFromDemux( input_thread_t *p_input )
 static int UpdateFromAccess( input_thread_t *p_input )
 {
     access_t *p_access = p_input->p->input.p_access;
-    vlc_value_t v;
 
     if( p_access->info.i_update & INPUT_UPDATE_TITLE )
     {
-        v.i_int = p_access->info.i_title;
-        var_Change( p_input, "title", VLC_VAR_SETVALUE, &v, NULL );
-
-        input_ControlVarTitle( p_input, p_access->info.i_title );
+        input_SendEventTitle( p_input, p_access->info.i_title );
 
         stream_AccessUpdate( p_input->p->input.p_stream );
 
@@ -2192,8 +2172,9 @@ static int UpdateFromAccess( input_thread_t *p_input )
     }
     if( p_access->info.i_update & INPUT_UPDATE_SEEKPOINT )
     {
-        v.i_int = p_access->info.i_seekpoint;
-        var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &v, NULL);
+        input_SendEventSeekpoint( p_input,
+                                  p_access->info.i_title, p_access->info.i_seekpoint );
+
         p_access->info.i_update &= ~INPUT_UPDATE_SEEKPOINT;
     }
     if( p_access->info.i_update & INPUT_UPDATE_META )
@@ -2212,8 +2193,7 @@ static int UpdateFromAccess( input_thread_t *p_input )
         if( access_Control( p_access, ACCESS_GET_SIGNAL, &f_quality, &f_strength ) )
             f_quality = f_strength = -1;
 
-        var_SetFloat( p_input, "signal-quality", f_quality );
-        var_SetFloat( p_input, "signal-strength", f_strength );
+        input_SendEventSignal( p_input, f_quality, f_strength );
 
         p_access->info.i_update &= ~INPUT_UPDATE_SIGNAL;
     }
@@ -2222,39 +2202,12 @@ static int UpdateFromAccess( input_thread_t *p_input )
 
     /* Hmmm only works with master input */
     if( p_input->p->input.p_access == p_access )
-    {
-        int i_title_end = p_input->p->input.i_title_end -
-            p_input->p->input.i_title_offset;
-        int i_seekpoint_end = p_input->p->input.i_seekpoint_end -
-            p_input->p->input.i_seekpoint_offset;
-
-        if( i_title_end >= 0 && i_seekpoint_end >=0 )
-        {
-            if( p_access->info.i_title > i_title_end ||
-                ( p_access->info.i_title == i_title_end &&
-                  p_access->info.i_seekpoint > i_seekpoint_end ) ) return 0;
-        }
-        else if( i_seekpoint_end >=0 )
-        {
-            if( p_access->info.i_seekpoint > i_seekpoint_end ) return 0;
-        }
-        else if( i_title_end >= 0 )
-        {
-            if( p_access->info.i_title > i_title_end ) return 0;
-        }
-    }
-
+        return UpdateTitleSeekpoint( p_input,
+                                     p_access->info.i_title,
+                                     p_access->info.i_seekpoint );
     return 1;
 }
 
-/*****************************************************************************
- * UpdateItemLength:
- *****************************************************************************/
-static void UpdateItemLength( input_thread_t *p_input, int64_t i_length )
-{
-    input_item_SetDuration( p_input->p->input.p_item, (mtime_t) i_length );
-}
-
 /*****************************************************************************
  * InputSourceNew:
  *****************************************************************************/
@@ -2807,7 +2760,6 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta )
     input_item_t *p_item = p_input->p->input.p_item;
     char * psz_arturl = NULL;
     char *psz_title = NULL;
-    int i_arturl_event = false;
 
     if( !p_meta )
         return;
@@ -2815,31 +2767,27 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta )
     psz_arturl = input_item_GetArtURL( p_item );
 
     vlc_mutex_lock( &p_item->lock );
+
     if( vlc_meta_Get( p_meta, vlc_meta_Title ) && !p_item->b_fixed_name )
         psz_title = strdup( vlc_meta_Get( p_meta, vlc_meta_Title ) );
 
     vlc_meta_Merge( p_item->p_meta, p_meta );
 
+    vlc_meta_Delete( p_meta );
+
     if( psz_arturl && *psz_arturl )
     {
         vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, psz_arturl );
-        i_arturl_event = true;
-    }
-
-    vlc_meta_Delete( p_meta );
 
-    if( psz_arturl && !strncmp( psz_arturl, "attachment://", strlen("attachment") ) )
-    {
-        /* Don't look for art cover if sout
-         * XXX It can change when sout has meta data support */
-        if( p_input->p->p_sout && !p_input->b_preparsing )
+        if( !strncmp( psz_arturl, "attachment://", strlen("attachment") ) )
         {
-            vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, "" );
-            i_arturl_event = true;
-
+            /* Don't look for art cover if sout
+             * XXX It can change when sout has meta data support */
+            if( p_input->p->p_sout && !p_input->b_preparsing )
+                vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, "" );
+            else
+                input_ExtractAttachmentAndCacheArt( p_input );
         }
-        else
-            input_ExtractAttachmentAndCacheArt( p_input );
     }
     free( psz_arturl );
 
@@ -2850,25 +2798,16 @@ static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta )
         p_meta = vlc_meta_New();
         vlc_meta_Merge( p_meta, input_item_GetMetaObject( p_item ) );
     }
+
+    if( psz_title )
+        input_item_SetName( p_item, psz_title );
+    free( psz_title );
+
     vlc_mutex_unlock( &p_item->lock );
 
     input_item_SetPreparsed( p_item, true );
 
-    if( i_arturl_event == true )
-    {
-        vlc_event_t event;
-
-        /* Notify interested third parties */
-        event.type = vlc_InputItemMetaChanged;
-        event.u.input_item_meta_changed.meta_type = vlc_meta_ArtworkURL;
-        vlc_event_send( &p_item->event_manager, &event );
-    }
-
-    if( psz_title )
-    {
-        input_Control( p_input, INPUT_SET_NAME, psz_title );
-        free( psz_title );
-    }
+    input_SendEventMeta( p_input );
 
     /** \todo handle sout meta */
 }
@@ -2920,7 +2859,6 @@ static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_d
     bool b_bool;
     module_t *p_id3;
 
-
 #if 0
     /* XXX I am not sure it is a great idea, besides, there is more than that
      * if we want to do it right */
@@ -2966,6 +2904,22 @@ static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_d
     free( p_demux->p_private );
 }
 
+static void input_ChangeState( input_thread_t *p_input, int i_state )
+{
+    const bool b_changed = p_input->i_state != i_state;
+
+    p_input->i_state = i_state;
+    if( i_state == ERROR_S )
+        p_input->b_error = true;
+    else if( i_state == END_S )
+        p_input->b_eof = true;
+
+    input_item_SetHasErrorWhenReading( p_input->p->input.p_item, (i_state == ERROR_S) );
+
+    if( b_changed )
+        input_SendEventState( p_input, i_state );
+}
+
 
 /*****************************************************************************
  * MRLSplit: parse the access, demux and url part of the
index 1c52d71..de16930 100644 (file)
@@ -332,42 +332,6 @@ void input_ConfigVarInit ( input_thread_t * );
 char **subtitles_Detect( input_thread_t *, char* path, const char *fname );
 int subtitles_Filter( const char *);
 
-static inline void input_ChangeStateWithVarCallback( input_thread_t *p_input, int i_state, bool callback )
-{
-    const bool changed = p_input->i_state != i_state;
-
-    p_input->i_state = i_state;
-    if( i_state == ERROR_S )
-        p_input->b_error = true;
-    else if( i_state == END_S )
-        p_input->b_eof = true;
-
-    input_item_SetHasErrorWhenReading( p_input->p->input.p_item, (i_state == ERROR_S) );
-
-    if( callback )
-    {
-        var_SetInteger( p_input, "state", i_state );
-    }
-    else
-    {
-        vlc_value_t val;
-        val.i_int = i_state;
-        var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL );
-    }
-    if( changed )
-    {
-        vlc_event_t event;
-        event.type = vlc_InputStateChanged;
-        event.u.input_state_changed.new_state = i_state;
-        vlc_event_send( &p_input->p->event_manager, &event );
-    }
-}
-
-static inline void input_ChangeState( input_thread_t *p_input, int state )
-{
-    input_ChangeStateWithVarCallback( p_input, state, true );
-}
-
 /* Helpers FIXME to export without input_ prefix */
 char *input_CreateFilename( vlc_object_t *p_obj, const char *psz_path, const char *psz_prefix, const char *psz_extension );
 
index 75477a2..482baa0 100644 (file)
@@ -312,6 +312,7 @@ bool input_item_IsArtFetched( input_item_t *p_i )
     return p_i->p_meta ? p_i->p_meta->i_status & ITEM_ART_FETCHED : false ;
 }
 
+/* FIXME dangerous, unlocked */
 const vlc_meta_t * input_item_GetMetaObject( input_item_t *p_i )
 {
     if( !p_i->p_meta )
@@ -320,6 +321,7 @@ const vlc_meta_t * input_item_GetMetaObject( input_item_t *p_i )
     return p_i->p_meta;
 }
 
+/* FIXME dangerous, unlocked */
 void input_item_MetaMerge( input_item_t *p_i, const vlc_meta_t * p_new_meta )
 {
     if( !p_i->p_meta )
@@ -472,8 +474,84 @@ int input_item_AddInfo( input_item_t *p_i,
 
     vlc_mutex_unlock( &p_i->lock );
 
+    if( p_info->psz_value )
+    {
+        vlc_event_t event;
+
+        event.type = vlc_InputItemInfoChanged;
+        vlc_event_send( &p_i->event_manager, &event );
+    }
     return p_info->psz_value ? VLC_SUCCESS : VLC_ENOMEM;
 }
+int input_item_DelInfo( input_item_t *p_i,
+                        const char *psz_cat,
+                        const char *psz_name )
+{
+    info_category_t *p_cat = NULL;
+    int i_cat;
+    int i;
+
+    vlc_mutex_lock( &p_i->lock );
+    for( i_cat = 0; i_cat < p_i->i_categories; i_cat++ )
+    {
+        if( !strcmp( p_i->pp_categories[i_cat]->psz_name,
+                     psz_cat ) )
+        {
+            p_cat = p_i->pp_categories[i_cat];
+            break;
+        }
+    }
+    if( p_cat == NULL )
+    {
+        vlc_mutex_unlock( &p_i->lock );
+        return VLC_EGENERIC;
+    }
+
+    if( psz_name )
+    {
+        /* Remove a specific info */
+        for( i = 0; i < p_cat->i_infos; i++ )
+        {
+            if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
+            {
+                free( p_cat->pp_infos[i]->psz_name );
+                if( p_cat->pp_infos[i]->psz_value )
+                    free( p_cat->pp_infos[i]->psz_value );
+                free( p_cat->pp_infos[i] );
+                REMOVE_ELEM( p_cat->pp_infos, p_cat->i_infos, i );
+                break;
+            }
+        }
+        if( i >= p_cat->i_infos )
+        {
+            vlc_mutex_unlock( &p_i->lock );
+            return VLC_EGENERIC;
+        }
+    }
+    else
+    {
+        /* Remove the complete categorie */
+        for( i = 0; i < p_cat->i_infos; i++ )
+        {
+            free( p_cat->pp_infos[i]->psz_name );
+            if( p_cat->pp_infos[i]->psz_value )
+                free( p_cat->pp_infos[i]->psz_value );
+            free( p_cat->pp_infos[i] );
+        }
+        if( p_cat->pp_infos )
+            free( p_cat->pp_infos );
+        REMOVE_ELEM( p_i->pp_categories, p_i->i_categories, i_cat );
+    }
+    vlc_mutex_unlock( &p_i->lock );
+
+
+    vlc_event_t event;
+    event.type = vlc_InputItemInfoChanged;
+    vlc_event_send( &p_i->event_manager, &event );
+
+    return VLC_SUCCESS;
+}
+
 
 input_item_t *__input_item_NewExt( vlc_object_t *p_obj, const char *psz_uri,
                                   const char *psz_name,
index 04e70d7..8218d6a 100644 (file)
@@ -232,16 +232,19 @@ void input_ControlVarInit ( input_thread_t *p_input )
          *
          * stats-change to inform when statistics are computed
          *
-         * TODO list all changes warn by this callbacks */
-        var_Create( p_input, "intf-change", VLC_VAR_BOOL );
-        var_SetBool( p_input, "intf-change", true );
-        var_Create( p_input, "rate-change", VLC_VAR_BOOL );
-        var_SetBool( p_input, "rate-change", true );
-        var_Create( p_input, "stats-change", VLC_VAR_BOOL );
-        var_SetBool( p_input, "stats-change", true );
-
-        var_Create( p_input, "intf-change-vout", VLC_VAR_BOOL );
-        var_SetBool( p_input, "intf-change-vout", true );
+         * TODO list all changes warn by these callbacks */
+        static const char *ppsz_event[] = {
+            "intf-change",
+            "rate-change",
+            "stats-change",
+            "intf-change-vout",
+            NULL
+        };
+        for( int i = 0; ppsz_event[i] != NULL; i++ )
+        {
+            var_Create( p_input, ppsz_event[i], VLC_VAR_BOOL );
+            var_SetBool( p_input, ppsz_event[i], true );
+        }
     }
 
     /* Add all callbacks
index dacec71..2c3cc31 100644 (file)
@@ -167,6 +167,7 @@ input_item_AddOpt
 input_item_AddOption
 input_item_AddSubItem
 input_item_CopyOptions
+input_item_DelInfo
 input_item_GetDuration
 input_item_GetInfo
 input_item_GetMeta