* ALL: experimental code for stream (dvd) navigation through object variables.
authorGildas Bazin <gbazin@videolan.org>
Tue, 11 Mar 2003 23:56:54 +0000 (23:56 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 11 Mar 2003 23:56:54 +0000 (23:56 +0000)
12 files changed:
include/input_ext-plugins.h
include/variables.h
modules/access/dvd/access.c
modules/access/dvdplay/access.c
modules/access/dvdread/input.c
modules/access/satellite/access.c
modules/access/vcd/vcd.c
modules/gui/wxwindows/popup.cpp
src/input/input.c
src/input/input_ext-intf.c
src/input/input_programs.c
src/misc/variables.c

index 75edd15..ab0dce9 100644 (file)
@@ -3,7 +3,7 @@
  *                      but exported to plug-ins
  *****************************************************************************
  * Copyright (C) 1999-2002 VideoLAN
- * $Id: input_ext-plugins.h,v 1.40 2003/03/04 13:21:19 massiot Exp $
+ * $Id: input_ext-plugins.h,v 1.41 2003/03/11 23:56:53 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -44,7 +44,7 @@ VLC_EXPORT( pgrm_descriptor_t *, input_FindProgram,( input_thread_t *, uint16_t
 VLC_EXPORT( pgrm_descriptor_t *, input_AddProgram, ( input_thread_t *, uint16_t, size_t ) );
 VLC_EXPORT( void, input_DelProgram,( input_thread_t *, pgrm_descriptor_t * ) );
 VLC_EXPORT( int, input_SetProgram,( input_thread_t *, pgrm_descriptor_t * ) );
-VLC_EXPORT( input_area_t *, input_AddArea,( input_thread_t * ) );
+VLC_EXPORT( input_area_t *, input_AddArea,( input_thread_t *, uint16_t, uint16_t ) );
 VLC_EXPORT( void, input_DelArea,   ( input_thread_t *, input_area_t * ) );
 VLC_EXPORT( es_descriptor_t *, input_FindES,( input_thread_t *, uint16_t ) );
 VLC_EXPORT( es_descriptor_t *, input_AddES, ( input_thread_t *, pgrm_descriptor_t *, uint16_t, size_t ) );
index 84febb1..a34267e 100644 (file)
@@ -2,7 +2,7 @@
  * variables.h: variables handling
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: variables.h,v 1.11 2002/12/14 19:34:07 gbazin Exp $
+ * $Id: variables.h,v 1.12 2003/03/11 23:56:53 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -75,6 +75,7 @@ struct variable_t
 #define VLC_VAR_MODULE    0x0041
 #define VLC_VAR_FILE      0x0042
 #define VLC_VAR_DIRECTORY 0x0043
+#define VLC_VAR_VARIABLE  0x0044
 #define VLC_VAR_FLOAT     0x0050
 #define VLC_VAR_TIME      0x0060
 #define VLC_VAR_ADDRESS   0x0070
@@ -97,11 +98,14 @@ struct variable_t
 #define VLC_VAR_SETMAX        0x0011
 #define VLC_VAR_SETSTEP       0x0012
 
+#define VLC_VAR_SETVALUE      0x0013
+
 #define VLC_VAR_ADDCHOICE     0x0020
 #define VLC_VAR_DELCHOICE     0x0021
-#define VLC_VAR_SETDEFAULT    0x0022
-#define VLC_VAR_GETLIST       0x0023
-#define VLC_VAR_FREELIST      0x0024
+#define VLC_VAR_CLEARCHOICES  0x0022
+#define VLC_VAR_SETDEFAULT    0x0023
+#define VLC_VAR_GETLIST       0x0024
+#define VLC_VAR_FREELIST      0x0025
 
 /*****************************************************************************
  * Prototypes
index 04c00df..0ce1fae 100644 (file)
@@ -8,7 +8,7 @@
  *  -udf.* to find files
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: access.c,v 1.10 2003/02/08 22:20:28 massiot Exp $
+ * $Id: access.c,v 1.11 2003/03/11 23:56:53 gbazin Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -206,10 +206,8 @@ int E_(DVDOpen) ( vlc_object_t *p_this )
      * is reserved for video_ts.vob */
     for( i = 1 ; i <= title_inf.i_title_nb ; i++ )
     {
-        input_AddArea( p_input );
-
         /* Titles are Program Chains */
-        area[i]->i_id = i;
+        input_AddArea( p_input, i, title_inf.p_attr[i-1].i_chapter_nb );
 
         /* Absolute start offset and size
          * We can only set that with vts ifo, so we do it during the
@@ -217,8 +215,7 @@ int E_(DVDOpen) ( vlc_object_t *p_this )
         area[i]->i_start = 0;
         area[i]->i_size = 0;
 
-        /* Number of chapters */
-        area[i]->i_part_nb = title_inf.p_attr[i-1].i_chapter_nb;
+        /* Default Chapter */
         area[i]->i_part = 1;
 
         /* Offset to vts_i_0.ifo */
@@ -291,6 +288,7 @@ static int DVDSetProgram( input_thread_t    * p_input,
     {
         thread_dvd_data_t *  p_dvd;
         int                  i_angle;
+        vlc_value_t          val;
 
         p_dvd   = (thread_dvd_data_t*)(p_input->p_access_data);
         i_angle = p_program->i_number;
@@ -325,6 +323,10 @@ static int DVDSetProgram( input_thread_t    * p_input,
         }
 #undef title
         msg_Dbg( p_input, "angle %d selected", p_dvd->i_angle );
+
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_program->i_number;
+        var_Change( p_input, "program", VLC_VAR_SETVALUE, &val );
     }
 
     return 0;
@@ -390,6 +392,7 @@ static int DVDReadAngle( input_thread_t * p_input )
 static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
 {
     thread_dvd_data_t *  p_dvd;
+    vlc_value_t          val;
 
     p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
 
@@ -401,6 +404,7 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
         int     i_vts_title;
         u32     i_first;
         u32     i_last;
+        unsigned int i;
 
         /* Reset the Chapter position of the old title */
         p_input->stream.p_selected_area->i_part = 1;
@@ -495,6 +499,16 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
             DVDLaunchDecoders( p_input );
         }
 
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_area->i_id;
+        var_Change( p_input, "title", VLC_VAR_SETVALUE, &val );
+        var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL );
+       for( i = 1; i <= p_area->i_part_nb; i++ )
+       {
+           val.i_int = i;
+           var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val );
+       }
+
     } /* i_title >= 0 */
     else
     {
@@ -510,6 +524,10 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
     p_input->stream.b_seekable = 1;
     p_input->stream.b_changed  = 1;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_area->i_part;
+    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val );
+
     return 0;
 }
 #undef vts
index a770eb7..035ae57 100644 (file)
@@ -2,7 +2,7 @@
  * access.c: access capabilities for dvdplay plugin.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: access.c,v 1.12 2003/03/09 19:25:09 gbazin Exp $
+ * $Id: access.c,v 1.13 2003/03/11 23:56:53 gbazin Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
 #   include <strings.h>
 #endif
 
-#if defined( WIN32 )
-#   include <io.h>                                                 /* read() */
-#endif
-
 #include "dvd.h"
 #include "es.h"
 #include "tools.h"
@@ -147,17 +143,12 @@ int E_(OpenDVD) ( vlc_object_t *p_this )
 
     /* Area 0 for menu */
     area[0]->i_plugin_data = 0;
+    input_DelArea( p_input, p_input->stream.pp_areas[0] );
+    input_AddArea( p_input, 0, 1 );
 
     for( i = 1 ; i <= i_title_nr ; i++ )
     {
-        input_AddArea( p_input );
-
-        /* Titles id */
-        area[i]->i_id = i;
-
-        /* Number of chapters */
-        area[i]->i_part_nb = dvdplay_chapter_nr( p_dvd->vmg, i );
-
+        input_AddArea( p_input, i, dvdplay_chapter_nr( p_dvd->vmg, i ) );
         area[i]->i_plugin_data = 0;
     }
 #undef area
@@ -244,6 +235,7 @@ static int dvdplay_SetProgram( input_thread_t *     p_input,
     {
         dvd_data_t *    p_dvd;
         int             i_angle;
+        vlc_value_t     val;
 
         p_dvd = (dvd_data_t*)(p_input->p_access_data);
         i_angle = p_program->i_number;
@@ -257,6 +249,10 @@ static int dvdplay_SetProgram( input_thread_t *     p_input,
 
             msg_Dbg( p_input, "angle %d selected", i_angle );
         }
+
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_program->i_number;
+        var_Change( p_input, "program", VLC_VAR_SETVALUE, &val );
     }
 
     return 0;
@@ -272,6 +268,7 @@ static int dvdplay_SetProgram( input_thread_t *     p_input,
 static int dvdplay_SetArea( input_thread_t * p_input, input_area_t * p_area )
 {
     dvd_data_t *    p_dvd;
+    vlc_value_t     val;
 
     p_dvd = (dvd_data_t*)p_input->p_access_data;
 
@@ -322,6 +319,10 @@ static int dvdplay_SetArea( input_thread_t * p_input, input_area_t * p_area )
         LB2OFF( dvdplay_position( p_dvd->vmg ) ) - p_area->i_start;
     p_input->stream.b_changed = 1;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_area->i_part;
+    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val );
+
     return 0;
 }
 
@@ -395,7 +396,6 @@ static void pf_vmg_callback( void* p_args, dvdplay_event_t event )
     case NEW_VTS:
         break;
     case NEW_FILE:
-
         break;
     case NEW_PGC:
         /* prevent intf to try to seek  by default */
@@ -428,6 +428,10 @@ static void pf_vmg_callback( void* p_args, dvdplay_event_t event )
 
         /* warn interface that something has changed */
         p_input->stream.b_changed = 1;
+
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_input->stream.p_selected_area->i_part;
+        var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val );
         break;
     case NEW_CELL:
         p_dvd->b_end_of_cell = 0;
@@ -497,6 +501,7 @@ static int dvdNewArea( input_thread_t * p_input, input_area_t * p_area )
 {
     dvd_data_t *    p_dvd;
     int             i_angle_nb, i_angle;
+    vlc_value_t     val;
     int             i;
 
     p_dvd = (dvd_data_t*)p_input->p_access_data;
@@ -526,6 +531,20 @@ static int dvdNewArea( input_thread_t * p_input, input_area_t * p_area )
     /* No PSM to read in DVD mode, we already have all information */
     p_input->stream.p_selected_program->b_is_ok = 1;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_area->i_id;
+    var_Change( p_input, "title", VLC_VAR_SETVALUE, &val );
+    var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL );
+    for( i = 1; (unsigned int)i <= p_area->i_part_nb; i++ )
+    {
+        val.i_int = i;
+        var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val );
+    }
+
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_area->i_part;
+    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val );
+
     return 0;
 }
 
@@ -568,4 +587,3 @@ static int dvdNewPGC( input_thread_t * p_input )
 
     return 0;
 }
-
index 1c0e2b8..0d12856 100644 (file)
@@ -6,7 +6,7 @@
  * It depends on: libdvdread for ifo files and block reading.
  *****************************************************************************
  * Copyright (C) 2001, 2003 VideoLAN
- * $Id: input.c,v 1.16 2003/02/02 00:49:40 massiot Exp $
+ * $Id: input.c,v 1.17 2003/03/11 23:56:53 gbazin Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -383,10 +383,8 @@ int E_(OpenDVD) ( vlc_object_t *p_this )
      * is reserved for video_ts.vob */
     for( i = 1 ; i <= tt_srpt->nr_of_srpts ; i++ )
     {
-        input_AddArea( p_input );
-
         /* Titles are Program Chains */
-        area[i]->i_id = i;
+        input_AddArea( p_input, i, tt_srpt->title[i-1].nr_of_ptts );
 
         /* Absolute start offset and size
          * We can only set that with vts ifo, so we do it during the
@@ -394,8 +392,7 @@ int E_(OpenDVD) ( vlc_object_t *p_this )
         area[i]->i_start = 0;
         area[i]->i_size = 0;
 
-        /* Number of chapters */
-        area[i]->i_part_nb = tt_srpt->title[i-1].nr_of_ptts;
+        /* Default Chapter */
         area[i]->i_part = 1;
 
         area[i]->i_plugin_data = tt_srpt->title[i-1].title_set_nr;
@@ -465,6 +462,7 @@ static int DvdReadSetProgram( input_thread_t * p_input,
     if( p_input->stream.p_selected_program != p_program )
     {
         thread_dvd_data_t *  p_dvd;
+        vlc_value_t val;
 
         p_dvd = (thread_dvd_data_t*)(p_input->p_access_data);
         p_dvd->i_angle = p_program->i_number;
@@ -475,6 +473,10 @@ static int DvdReadSetProgram( input_thread_t * p_input,
         p_input->stream.p_selected_program = p_program;
 
         msg_Dbg( p_input, "angle %d selected", p_dvd->i_angle );
+
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_program->i_number;
+        var_Change( p_input, "program", VLC_VAR_SETVALUE, &val );
     }
 
     return VLC_SUCCESS;
@@ -494,6 +496,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
     thread_dvd_data_t *  p_dvd;
     int                  pgc_id = 0;
     int                  pgn = 0;
+    vlc_value_t          val;
 
     p_dvd = (thread_dvd_data_t*)p_input->p_access_data;
 
@@ -794,6 +797,16 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
             DvdReadLauchDecoders( p_input );
         }
 
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_area->i_id;
+        var_Change( p_input, "title", VLC_VAR_SETVALUE, &val );
+        var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL );
+        for( i = 1; i <= p_area->i_part_nb; i++ )
+        {
+            val.i_int = i;
+            var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val );
+        }
+
     } /* i_title >= 0 */
     else
     {
@@ -838,6 +851,10 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
     p_input->stream.b_seekable = VLC_TRUE;
     p_input->stream.b_changed = VLC_TRUE;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_area->i_part;
+    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val );
+
     return VLC_SUCCESS;
 }
 
index 8bdd9f3..d59d85c 100644 (file)
@@ -382,6 +382,7 @@ int SatelliteSetProgram( input_thread_t    * p_input,
                          pgrm_descriptor_t * p_new_prg )
 {
     unsigned int i_es_index;
+    vlc_value_t val;
 
     if ( p_input->stream.p_selected_program )
     {
@@ -434,6 +435,10 @@ int SatelliteSetProgram( input_thread_t    * p_input,
 
     p_input->stream.p_selected_program = p_new_prg;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_new_prg->i_number;
+    var_Change( p_input, "program", VLC_VAR_SETVALUE, &val );
+
     return 0;
 }
 
index 8e4b7af..14e84ed 100644 (file)
@@ -2,7 +2,7 @@
  * vcd.c : VCD input module for vlc
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: vcd.c,v 1.15 2003/02/12 17:13:33 jobi Exp $
+ * $Id: vcd.c,v 1.16 2003/03/11 23:56:54 gbazin Exp $
  *
  * Author: Johan Bilien <jobi@via.ecp.fr>
  *
@@ -224,18 +224,15 @@ static int VCDOpen( vlc_object_t *p_this )
 #define area p_input->stream.pp_areas
     for( i = 1 ; i <= p_vcd->i_nb_tracks - 1 ; i++ )
     {
-        input_AddArea( p_input );
-
         /* Titles are Program Chains */
-        area[i]->i_id = i;
+        input_AddArea( p_input, i, 1 );
 
         /* Absolute start offset and size */
         area[i]->i_start = (off_t)p_vcd->p_sectors[i] * (off_t)VCD_DATA_SIZE;
         area[i]->i_size = (off_t)(p_vcd->p_sectors[i+1] - p_vcd->p_sectors[i])
                            * (off_t)VCD_DATA_SIZE;
 
-        /* Number of chapters */
-        area[i]->i_part_nb = 1;   /* will be the entry points */
+        /* Default Chapter */
         area[i]->i_part = 1;
 
         /* i_plugin_data is used to store which entry point is the first
@@ -388,6 +385,7 @@ static int VCDSetProgram( input_thread_t * p_input,
 static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
 {
     thread_vcd_data_t *     p_vcd;
+    vlc_value_t val;
 
     p_vcd = (thread_vcd_data_t*)p_input->p_access_data;
 
@@ -396,6 +394,8 @@ static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
 
     if( p_area != p_input->stream.p_selected_area )
     {
+        unsigned int i;
+
         /* Reset the Chapter position of the current title */
         p_input->stream.p_selected_area->i_part = 1;
         p_input->stream.p_selected_area->i_tell = 0;
@@ -407,6 +407,16 @@ static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
         /* The first track is not a valid one  */
         p_vcd->i_track = p_area->i_id;
         p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track];
+
+        /* Update the navigation variables without triggering a callback */
+        val.i_int = p_area->i_id;
+        var_Change( p_input, "title", VLC_VAR_SETVALUE, &val );
+        var_Change( p_input, "chapter", VLC_VAR_CLEARCHOICES, NULL );
+        for( i = 1; i <= p_area->i_part_nb; i++ )
+        {
+            val.i_int = i;
+            var_Change( p_input, "chapter", VLC_VAR_ADDCHOICE, &val );
+        }
     }
 
     if( p_vcd->b_valid_ep )
@@ -427,6 +437,10 @@ static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
     p_input->stream.b_seekable = 1;
     p_input->stream.b_changed = 1;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_area->i_part;
+    var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &val );
+
     return 0;
 }
 
index 98e4757..07a7d33 100644 (file)
@@ -2,7 +2,7 @@
  * popup.cpp : wxWindows plugin for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: popup.cpp,v 1.3 2003/01/26 10:36:10 gbazin Exp $
+ * $Id: popup.cpp,v 1.4 2003/03/11 23:56:54 gbazin Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -118,6 +118,7 @@ PopupMenu::PopupMenu( intf_thread_t *_p_intf, Interface *_p_main_interface ):
 
     CreateMenuEntry( "title", p_object );
     CreateMenuEntry( "chapter", p_object );
+    CreateMenuEntry( "navigation", p_object );
 
     vlc_object_release( p_object );
 
@@ -207,43 +208,40 @@ wxMenu *PopupMenu::CreateSubMenu( char *psz_var, vlc_object_t *p_object )
 {
     wxMenu *menu = new wxMenu;
     vlc_value_t val;
-    char *psz_value;
+    vlc_value_t val_list;
     int i_type, i;
 
     /* Check the type of the object variable */
     i_type = var_Type( p_object, psz_var );
 
-    switch( i_type )
-    {
-    case VLC_VAR_VOID:
-    case VLC_VAR_STRING:
-        break;
-
-    default:
-        break;
-    }
-
     if( var_Get( p_object, psz_var, &val ) < 0 )
     {
         return NULL;
     }
-    psz_value = val.psz_string;
 
-    if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val ) < 0 )
+    if( var_Change( p_object, psz_var, VLC_VAR_GETLIST, &val_list ) < 0 )
     {
         return NULL;
     }
 
-    for( i = 0; i < val.p_list->i_count; i++ )
+    for( i = 0; i < val_list.p_list->i_count; i++ )
     {
         vlc_value_t another_val;
         wxMenuItemExt *menuitem;
 
         switch( i_type & VLC_VAR_TYPE )
         {
+        case VLC_VAR_VARIABLE:
+          menu->Append( MenuDummy_Event,
+                        val_list.p_list->p_values[i].psz_string,
+                        CreateSubMenu( val_list.p_list->p_values[i].psz_string,
+                                       p_object ),
+                        "YEAAAARRRGGGHHH HEEELLPPPPPP" );
+          break;
+
         case VLC_VAR_STRING:
           another_val.psz_string =
-              strdup(val.p_list->p_values[i].psz_string);
+              strdup(val_list.p_list->p_values[i].psz_string);
           menuitem =
               new wxMenuItemExt( this, i_item_id++, another_val.psz_string,
                                  "", wxITEM_RADIO, strdup(psz_var),
@@ -252,7 +250,8 @@ wxMenu *PopupMenu::CreateSubMenu( char *psz_var, vlc_object_t *p_object )
 
           menu->Append( menuitem );
 
-          if( !strcmp( psz_value, val.p_list->p_values[i].psz_string ) )
+          if( !strcmp( val.psz_string,
+                       val_list.p_list->p_values[i].psz_string ) )
               menu->Check( i_item_id - 1, TRUE );
           break;
 
@@ -260,12 +259,16 @@ wxMenu *PopupMenu::CreateSubMenu( char *psz_var, vlc_object_t *p_object )
           menuitem =
               new wxMenuItemExt( this, i_item_id++,
                                  wxString::Format(_("%d"),
-                                 val.p_list->p_values[i].i_int),
+                                 val_list.p_list->p_values[i].i_int),
                                  "", wxITEM_RADIO, strdup(psz_var),
                                  p_object->i_object_id,
-                                 val.p_list->p_values[i] );
+                                 val_list.p_list->p_values[i] );
 
           menu->Append( menuitem );
+
+          if( !((i_type & VLC_VAR_FLAGS) & VLC_VAR_ISCOMMAND) &&
+              val_list.p_list->p_values[i].i_int == val.i_int )
+              menu->Check( i_item_id - 1, TRUE );
           break;
 
         default:
@@ -273,7 +276,7 @@ wxMenu *PopupMenu::CreateSubMenu( char *psz_var, vlc_object_t *p_object )
         }
     }
 
-    var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val );
+    var_Change( p_object, psz_var, VLC_VAR_FREELIST, &val_list );
 
     return menu;
 }
index b175cf6..dfbf04c 100644 (file)
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.223 2003/02/08 22:43:02 massiot Exp $
+ * $Id: input.c,v 1.224 2003/03/11 23:56:54 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -126,7 +126,7 @@ input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
     p_input->stream.p_newly_selected_es = NULL;
 
     /* By default there is one area in a stream */
-    input_AddArea( p_input );
+    input_AddArea( p_input, 0, 1 );
     p_input->stream.p_selected_area = p_input->stream.pp_areas[0];
 
     /* Initialize stream control properties. */
index 1ded67d..72a94a8 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-intf.c: services to the interface
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ext-intf.c,v 1.47 2003/01/21 14:15:05 hartman Exp $
+ * $Id: input_ext-intf.c,v 1.48 2003/03/11 23:56:54 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -366,6 +366,7 @@ int input_ChangeArea( input_thread_t * p_input, input_area_t * p_area )
 int input_ChangeProgram( input_thread_t * p_input, uint16_t i_program_number )
 {
     pgrm_descriptor_t *       p_program;
+    vlc_value_t val;
 
     vlc_mutex_lock( &p_input->stream.stream_lock );
 
@@ -381,6 +382,10 @@ int input_ChangeProgram( input_thread_t * p_input, uint16_t i_program_number )
 
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = i_program_number;
+    var_Change( p_input, "program", VLC_VAR_SETVALUE, &val );
+
     return 0;
 }
 
index 96c2cdf..0ce4150 100644 (file)
@@ -2,7 +2,7 @@
  * input_programs.c: es_descriptor_t, pgrm_descriptor_t management
  *****************************************************************************
  * Copyright (C) 1999-2002 VideoLAN
- * $Id: input_programs.c,v 1.101 2003/01/31 11:23:37 massiot Exp $
+ * $Id: input_programs.c,v 1.102 2003/03/11 23:56:54 gbazin Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  * p_input->stream.lock
  */
 
+/* Navigation callbacks */
+static int ProgramCallback( vlc_object_t *, char const *,
+                            vlc_value_t, vlc_value_t, void * );
+static int TitleCallback( vlc_object_t *, char const *,
+                          vlc_value_t, vlc_value_t, void * );
+static int ChapterCallback( vlc_object_t *, char const *,
+                            vlc_value_t, vlc_value_t, void * );
+static int NavigationCallback( vlc_object_t *, char const *,
+                               vlc_value_t, vlc_value_t, void * );
+
 /*****************************************************************************
  * input_InitStream: init the stream descriptor of the given input
  *****************************************************************************/
@@ -72,6 +82,15 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len )
         p_input->stream.p_demux_data = NULL;
     }
 
+    /* Create a few object variables used for navigation in the interfaces */
+    var_Create( p_input, "program", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
+    var_Create( p_input, "title", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
+    var_Create( p_input, "chapter", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
+    var_Create( p_input, "navigation", VLC_VAR_VARIABLE | VLC_VAR_HASCHOICE );
+    var_AddCallback( p_input, "program", ProgramCallback, NULL );
+    var_AddCallback( p_input, "title", TitleCallback, NULL );
+    var_AddCallback( p_input, "chapter", ChapterCallback, NULL );
+
     return 0;
 }
 
@@ -80,6 +99,11 @@ int input_InitStream( input_thread_t * p_input, size_t i_data_len )
  *****************************************************************************/
 void input_EndStream( input_thread_t * p_input )
 {
+    /* Free navigation variables */
+    var_Destroy( p_input, "program" );
+    var_Destroy( p_input, "title" );
+    var_Destroy( p_input, "chapter" );
+
     /* Free all programs and associated ES, and associated decoders. */
     while( p_input->stream.i_pgrm_number )
     {
@@ -139,6 +163,7 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
 {
     /* Where to add the pgrm */
     pgrm_descriptor_t * p_pgrm = malloc( sizeof(pgrm_descriptor_t) );
+    vlc_value_t val;
 
     if( p_pgrm == NULL )
     {
@@ -179,6 +204,9 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
                  p_input->stream.i_pgrm_number,
                  p_pgrm );
 
+    val.i_int = i_pgrm_id;
+    var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val );
+
     return p_pgrm;
 }
 
@@ -190,6 +218,7 @@ pgrm_descriptor_t * input_AddProgram( input_thread_t * p_input,
 void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
 {
     unsigned int i_pgrm_index;
+    vlc_value_t val;
 
     /* Find the program in the programs table */
     for( i_pgrm_index = 0; i_pgrm_index < p_input->stream.i_pgrm_number;
@@ -206,6 +235,9 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
         return;
     }
 
+    val.i_int = i_pgrm_index;
+    var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val );
+
     /* Free the structures that describe the es that belongs to that program */
     while( p_pgrm->i_es_number )
     {
@@ -232,10 +264,13 @@ void input_DelProgram( input_thread_t * p_input, pgrm_descriptor_t * p_pgrm )
  *****************************************************************************
  * This area descriptor will be referenced in the given stream descriptor
  *****************************************************************************/
-input_area_t * input_AddArea( input_thread_t * p_input )
+input_area_t * input_AddArea( input_thread_t * p_input,
+                              uint16_t i_area_id, uint16_t i_part_nb )
 {
     /* Where to add the pgrm */
     input_area_t * p_area = malloc( sizeof(input_area_t) );
+    vlc_value_t val;
+    int i;
 
     if( p_area == NULL )
     {
@@ -244,13 +279,13 @@ input_area_t * input_AddArea( input_thread_t * p_input )
     }
 
     /* Init this entry */
-    p_area->i_id = 0;
+    p_area->i_id = i_area_id;
+    p_area->i_part_nb = i_part_nb;
+    p_area->i_part= 0;
     p_area->i_start = 0;
     p_area->i_size = 0;
     p_area->i_tell = 0;
     p_area->i_seek = NO_SEEK;
-    p_area->i_part_nb = 1;
-    p_area->i_part= 0;
 
     /* Add an entry to the list of program associated with the stream */
     INSERT_ELEM( p_input->stream.pp_areas,
@@ -258,6 +293,35 @@ input_area_t * input_AddArea( input_thread_t * p_input )
                  p_input->stream.i_area_nb,
                  p_area );
 
+    /* Don't add empty areas */
+    if( i_part_nb == 0 )
+        return NULL;
+
+    /* Take care of the navigation variables */
+    val.i_int = i_area_id;
+    var_Change( p_input, "title", VLC_VAR_ADDCHOICE, &val );
+
+    val.psz_string = malloc( sizeof("title ") + 5 );
+    if( val.psz_string )
+    {
+        vlc_value_t val2;
+
+        sprintf( val.psz_string, "title %2i", i_area_id );
+       var_Destroy( p_input, val.psz_string );
+       var_Create( p_input, val.psz_string, VLC_VAR_INTEGER |
+                   VLC_VAR_HASCHOICE | VLC_VAR_ISCOMMAND );
+       var_AddCallback( p_input, val.psz_string, NavigationCallback,
+                        (void *)(int)i_area_id );
+
+       var_Change( p_input, "navigation", VLC_VAR_ADDCHOICE, &val );
+
+       for( i = 1; i <= i_part_nb; i++ )
+       {
+           val2.i_int = i;
+           var_Change( p_input, val.psz_string, VLC_VAR_ADDCHOICE, &val2 );
+       }
+    }
+
     return p_area;
 }
 
@@ -271,6 +335,7 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
     int i_required_spu_es;
     int i_audio_es = 0;
     int i_spu_es = 0;
+    vlc_value_t val;
 
     if ( p_input->stream.p_selected_program )
     {
@@ -356,10 +421,13 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
 
     p_input->stream.p_selected_program = p_new_prg;
 
+    /* Update the navigation variables without triggering a callback */
+    val.i_int = p_new_prg->i_number;
+    var_Change( p_input, "program", VLC_VAR_SETVALUE, &val );
+
     return( 0 );
 }
 
-
 /*****************************************************************************
  * input_DelArea: destroy a area descriptor
  *****************************************************************************
@@ -368,6 +436,7 @@ int input_SetProgram( input_thread_t * p_input, pgrm_descriptor_t * p_new_prg )
 void input_DelArea( input_thread_t * p_input, input_area_t * p_area )
 {
     unsigned int i_area_index;
+    vlc_value_t val;
 
     /* Find the area in the areas table */
     for( i_area_index = 0; i_area_index < p_input->stream.i_area_nb;
@@ -384,6 +453,15 @@ void input_DelArea( input_thread_t * p_input, input_area_t * p_area )
         return;
     }
 
+    /* Take care of the navigation variables */
+    val.psz_string = malloc( sizeof("title ") + 5 );
+    if( val.psz_string )
+    {
+        sprintf( val.psz_string, "title %i", p_area->i_id );
+       var_Change( p_input, "navigation", VLC_VAR_DELCHOICE, &val );
+       var_Destroy( p_input, val.psz_string );
+    }
+
     /* Remove this area from the stream's list of areas */
     REMOVE_ELEM( p_input->stream.pp_areas,
                  p_input->stream.i_area_nb,
@@ -658,3 +736,101 @@ int input_UnselectES( input_thread_t * p_input, es_descriptor_t * p_es )
 
     return 0;
 }
+
+/*****************************************************************************
+ * 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, 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;
+}
index dbc59e7..72a59ca 100644 (file)
@@ -2,7 +2,7 @@
  * variables.c: routines for object variables handling
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: variables.c,v 1.20 2003/03/09 19:25:08 gbazin Exp $
+ * $Id: variables.c,v 1.21 2003/03/11 23:56:54 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -155,6 +155,8 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type )
         case VLC_VAR_STRING:
         case VLC_VAR_MODULE:
         case VLC_VAR_FILE:
+        case VLC_VAR_DIRECTORY:
+        case VLC_VAR_VARIABLE:
             p_var->pf_cmp = CmpString;
             p_var->pf_dup = DupString;
             p_var->pf_free = FreeString;
@@ -264,6 +266,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
 {
     int i_var, i;
     variable_t *p_var;
+    vlc_value_t oldval;
 
     vlc_mutex_lock( &p_this->var_lock );
 
@@ -364,6 +367,18 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
 
             CheckValue( p_var, &p_var->val );
             break;
+        case VLC_VAR_CLEARCHOICES:
+            for( i = 0 ; i < p_var->choices.i_count ; i++ )
+            {
+                p_var->pf_free( &p_var->choices.p_values[i] );
+            }
+            if( p_var->choices.i_count )
+                free( p_var->choices.p_values );
+
+            p_var->choices.i_count = 0;
+            p_var->choices.p_values = NULL;
+            p_var->i_default = -1;
+            break;
         case VLC_VAR_SETDEFAULT:
             /* FIXME: the list is sorted, dude. Use something cleverer. */
             for( i = 0 ; i < p_var->choices.i_count ; i++ )
@@ -383,7 +398,18 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name,
             p_var->i_default = i;
             CheckValue( p_var, &p_var->val );
             break;
-
+        case VLC_VAR_SETVALUE:
+            /* Duplicate data if needed */
+            p_var->pf_dup( p_val );
+            /* Backup needed stuff */
+            oldval = p_var->val;
+            /* Check boundaries and list */
+            CheckValue( p_var, p_val );
+            /* Set the variable */
+            p_var->val = *p_val;
+            /* Free data if needed */
+            p_var->pf_free( &oldval );
+            break;
         case VLC_VAR_GETLIST:
             p_val->p_list = malloc( sizeof(vlc_list_t) );
             if( p_var->choices.i_count )