Imported Upstream version 0.4.5+svn3950~dfsg0
authorAlessio Treglia <alessio@debian.org>
Tue, 6 Mar 2012 22:40:10 +0000 (23:40 +0100)
committerAlessio Treglia <alessio@debian.org>
Tue, 6 Mar 2012 22:40:10 +0000 (23:40 +0100)
79 files changed:
Makefile
applications/Makefile
applications/mp4box/filedump.c
applications/mp4box/fileimport.c
applications/mp4box/live.c
applications/mp4box/main.c
applications/mp4client/main.c
bin/arm_ppc02_rel/install/do.bat [deleted file]
bin/arm_ppc02_rel/install/gpac.inf [deleted file]
bin/arm_ppc02_rel/install/gpac.ini [deleted file]
bin/arm_ppc02_rel/install/readme.txt [deleted file]
bin/arm_ppc03_rel/install/do.bat [deleted file]
bin/arm_ppc03_rel/install/gpac.inf [deleted file]
bin/arm_ppc03_rel/install/gpac.ini [deleted file]
bin/arm_ppc03_rel/install/readme.txt [deleted file]
configure
include/gpac/ait.h
include/gpac/dsmcc.h
include/gpac/internal/isomedia_dev.h
include/gpac/internal/smjs_api.h
include/gpac/isomedia.h
include/gpac/media_tools.h
include/gpac/rtp_streamer.h
include/gpac/setup.h
include/gpac/tools.h
modules/Makefile
modules/dx_hw/dx_2d.c
modules/dx_hw/dx_hw.h
modules/dx_hw/dx_video.c
modules/ffmpeg_in/ffmpeg_decode.c
modules/ffmpeg_in/ffmpeg_demux.c
modules/freenect/freenect.c
modules/gpac_js/gpac_js.c
modules/isom_in/read_ch.c
modules/mpd_in/mpd_in.c
modules/osd/osd.c
modules/oss_audio/Makefile
modules/platinum/Makefile
modules/widgetman/Makefile [new file with mode: 0644]
modules/widgetman/unzip.c [new file with mode: 0644]
modules/widgetman/unzip.h [new file with mode: 0644]
modules/widgetman/wgt_load.c [new file with mode: 0644]
modules/widgetman/wgt_load_base.js [new file with mode: 0644]
modules/widgetman/widget.c [new file with mode: 0644]
modules/widgetman/widgetman.c [new file with mode: 0644]
modules/widgetman/widgetman.h [new file with mode: 0644]
modules/x11_out/Makefile
src/Makefile
src/bifs/script.h
src/bifs/script_enc.c
src/compositor/compositor.c
src/compositor/mesh.c
src/export.cpp
src/ietf/rtp_streamer.c
src/isomedia/box_code_base.c
src/isomedia/box_dump.c
src/isomedia/box_funcs.c
src/isomedia/isom_intern.c
src/isomedia/isom_read.c
src/isomedia/isom_write.c
src/isomedia/movie_fragments.c
src/media_tools/filestreamer.c
src/media_tools/ismacryp.c
src/media_tools/isom_tools.c
src/media_tools/m2ts_mux.c
src/media_tools/media_export.c
src/media_tools/media_import.c
src/media_tools/mpd.c
src/media_tools/text_import.c
src/odf/ipmpx_dump.c
src/odf/odf_dump.c
src/odf/odf_parse.c
src/scene_manager/encode_isom.c
src/scene_manager/loader_isom.c
src/scene_manager/scene_dump.c
src/scene_manager/scene_engine.c
src/scenegraph/dom_smjs.c
src/scenegraph/vrml_smjs.c
src/utils/color.c

index d7635e504839ab2b27eb18c322fe386352dc28ab..0d13ebb7ed2320fc91d890753c7127542d1be73c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,9 @@ install:
        $(INSTALL) -d "$(DESTDIR)$(prefix)"
        $(INSTALL) -d "$(DESTDIR)$(prefix)/$(libdir)"
        $(INSTALL) -d "$(DESTDIR)$(prefix)/bin"
+ifeq ($(DISABLE_ISOFF), no)
        $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Box "$(DESTDIR)$(prefix)/bin"
+endif
        $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Client "$(DESTDIR)$(prefix)/bin"
        if [ -d  $(DESTDIR)$(prefix)/$(libdir)/pkgconfig ] ; then \
        $(INSTALL) $(INSTFLAGS) -m 644 gpac.pc "$(DESTDIR)$(prefix)/$(libdir)/pkgconfig" ; \
@@ -112,8 +114,9 @@ ifeq ($(CONFIG_DARWIN),yes)
        $(INSTALL) -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(VERSION).$(DYN_LIB_SUFFIX)
        ln -sf libgpac.$(VERSION).$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX)
 else
-       $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX).$(VERSION)
-       ln -sf libgpac.$(DYN_LIB_SUFFIX).$(VERSION) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX)
+       $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX).$(VERSION_SONAME)
+       ln -sf libgpac.$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.so.$(VERSION_MAJOR)
+       ln -sf libgpac.$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.so
 ifeq ($(DESTDIR)$(prefix),$(prefix))
        ldconfig || true
 endif
index 872a402e37259069309847550db54d38ae805d16..e93a736a449f7826aff09f733645cade09a8d355 100644 (file)
@@ -4,8 +4,10 @@ APPDIRS=mp4client
 
 ifeq ($(DISABLE_ISOFF), no)
 APPDIRS+=mp4box
+ifeq ($(DISABLE_M2TS), no)
 APPDIRS+=mp42ts
 endif
+endif
 
 V4STUDIODIR=
 INSTDIRS=mp4client
index dc7f8d7bceddb52168111bff9472e41ccf0bcbd7..de2b4a0d415958b802c7ab450572f2f3fe88b7f3 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <gpac/scene_manager.h>
 
-#ifdef GPAC_DISABLE_ISOM
+#if defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE)
 
 #error "Cannot compile MP4Box if GPAC is not built with ISO File Format support"
 
@@ -48,7 +48,7 @@ extern u32 get_file_type_by_ext(char *inName);
 
 void scene_coding_log(void *cbk, u32 log_level, u32 log_tool, const char *fmt, va_list vlist);
 
-#ifndef GPAC_DISABLE_ISOM_WRITE
+#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
 GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample);
 #endif
 
@@ -180,8 +180,14 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log)
        /*SAF*/
        else if (ftype==6) {
                load.isom = gf_isom_open("saf_conv", GF_ISOM_WRITE_EDIT, NULL);
-               if (load.isom) e = import_file(load.isom, file, 0, 0, 0);
-               else e = gf_isom_last_error(NULL);
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
+               if (load.isom)
+                       e = import_file(load.isom, file, 0, 0, 0);
+               else
+#else
+               fprintf(stderr, "Warning: GPAC was compiled without Media Import support\n");
+#endif
+                       e = gf_isom_last_error(NULL);
 
                if (e) {
                        fprintf(stdout, "Error importing file: %s\n", gf_error_to_string(e));
@@ -568,8 +574,13 @@ void PrintNode(const char *name, u32 graph_type)
                fprintf(stdout, "SVG node printing is not supported\n");
                return;
        } else if (graph_type==1) {
+#ifndef GPAC_DISABLE_X3D
                tag = gf_node_x3d_type_by_class_name(name);
                std_name = "X3D";
+#else
+                fprintf(stdout, "X3D node printing is not supported (X3D support disabled)\n");
+                return;
+#endif
        } else {
                tag = gf_node_mpeg4_type_by_class_name(name);
                std_name = "MPEG4";
@@ -676,12 +687,12 @@ void PrintBuiltInNodes(u32 graph_type)
        u32 i, nb_in, nb_not_in, start_tag, end_tag;
 
        if (graph_type==1) {
-#ifdef GPAC_DISABLE_VRML
+#if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_X3D)
+                start_tag = GF_NODE_RANGE_FIRST_X3D;
+                end_tag = TAG_LastImplementedX3D;
+#else
                fprintf(stdout, "X3D scene graph disabled in this build of GPAC\n");
                return;
-#else
-               start_tag = GF_NODE_RANGE_FIRST_X3D;
-               end_tag = TAG_LastImplementedX3D;
 #endif
        } else if (graph_type==2) {
 #ifdef GPAC_DISABLE_SVG
@@ -1760,7 +1771,7 @@ void DumpMovieInfo(GF_ISOFile *file)
        }
 }
 
-#endif /*GPAC_DISABLE_ISOM*/
+#endif /*defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE)*/
 
 
 #ifndef GPAC_DISABLE_MPEG2TS
@@ -2381,50 +2392,62 @@ static void mpd_start(GF_M2TS_IndexingInfo *index_info, Bool on_demand, const ch
        char duration_string[100];
        char buffer_string[100];
        u32 bandwidth, i;
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
        GF_MediaImporter import;
+#endif
        char szCodecs[1000];
        u32 width, height, sample_rate, nb_channels, langCode;
        GF_Err e;
        FILE *mpd = index_info->mpd_file;
 
        /*get codecs*/  
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
        memset(&import, 0, sizeof(GF_MediaImporter));
        import.trackID = 0;
        import.flags = GF_IMPORT_PROBE_ONLY;
        import.in_name = (char *)media_file_name;
        e = gf_media_import(&import);
+#else
+       fprintf(stdout, "Warning: generating MPD without media import support\n");
+#endif
        strcpy(szCodecs, "");
        width = height = sample_rate = nb_channels = langCode = 0;
 
+
+       bandwidth = (u32) (file_size * 8 / file_duration);      
+       mpd_duration(file_duration, duration_string);
+       mpd_duration(bufferTime, buffer_string);
+
+       if (!index_info->represantation_idx) {
+               fprintf(mpd, "<MPD type=\"%s\" xmlns=\"urn:mpeg:DASH:schema:MPD:2011\" profiles=\"urn:mpeg:dash:profile:mp2t-main:2011\" minBufferTime=\"%s\">\n", (on_demand ? "static": "dynamic"), buffer_string);
+               fprintf(mpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n");
+               fprintf(mpd, "  <Title>MPD for file %s generated with GPAC %s</Title>\n", media_file_name, GPAC_FULL_VERSION);
+               fprintf(mpd, " </ProgramInformation>\n");
+               fprintf(mpd, " <Period start=\"PT0S\" duration=\"%s\" minBufferTime=\"%s\">\n", duration_string, buffer_string);        
+               fprintf(mpd, "  <AdaptationSet segmentAlignment=\"true\" bitstreamSwitching=\"true\" subsegmentAlignment=\"true\">\n");
+       }
+
        if (!e) {
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                for (i=0; i<import.nb_tracks;i++) {
                        if (strlen(import.tk_info[i].szCodecProfile)) {
                                if (strlen(szCodecs)) strcat(szCodecs, ",");
                                strcat(szCodecs, import.tk_info[i].szCodecProfile);
                        }
+
                        if (import.tk_info[i].type==GF_ISOM_MEDIA_VISUAL) {
                                if (!width) width = import.tk_info[i].video_info.width;
                                if (!height) height = import.tk_info[i].video_info.height;
+                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"video\"/>\n", import.tk_info[i].track_num);
                        }
                        else if (import.tk_info[i].type==GF_ISOM_MEDIA_AUDIO) {
                                if (!sample_rate) sample_rate = import.tk_info[i].audio_info.sample_rate;
                                if (!nb_channels) nb_channels = import.tk_info[i].audio_info.nb_channels;
+                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"audio\"/>\n", import.tk_info[i].track_num);
                        }
                        if (!langCode && import.tk_info[i].lang) langCode = import.tk_info[i].lang;
                }
-       }
-
-       bandwidth = (u32) (file_size * 8 / file_duration);      
-       mpd_duration(file_duration, duration_string);
-       mpd_duration(bufferTime, buffer_string);
-
-       if (!index_info->represantation_idx) {
-               fprintf(mpd, "<MPD type=\"%s\" xmlns=\"urn:mpeg:DASH:schema:MPD:2011\" profiles=\"urn:mpeg:dash:profile:mp2t-main:2011\" minBufferTime=\"%s\">\n", (on_demand ? "static": "dynamic"), buffer_string);
-               fprintf(mpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n");
-               fprintf(mpd, "  <Title>MPD for file %s generated with GPAC %s</Title>\n", media_file_name, GPAC_FULL_VERSION);
-               fprintf(mpd, " </ProgramInformation>\n");
-               fprintf(mpd, " <Period start=\"PT0S\" duration=\"%s\" minBufferTime=\"%s\">\n", duration_string, buffer_string);        
-               fprintf(mpd, "  <AdaptationSet segmentAlignment=\"true\" bitstreamSwitching=\"true\" subsegmentAlignment=\"true\">\n");
+#endif
        }
 
        fprintf(mpd, "   <Representation id=\"%d\" mimeType=\"video/mp2t\" codecs=\"%s\"", index_info->represantation_idx+1, szCodecs);
@@ -2487,7 +2510,7 @@ static void write_mpd_segment_info(GF_M2TS_IndexingInfo *index_info, char *media
        /* add startIndex for live scenarios */
        
        if (index_info->init_seg_name) {
-               fprintf(index_info->mpd_file, "     <InitialisationSegment sourceURL=\"%s\"/>\n", index_info->init_seg_name);
+               fprintf(index_info->mpd_file, "     <Initialization sourceURL=\"%s\"/>\n", index_info->init_seg_name);
        }
 
 
@@ -2601,6 +2624,7 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num,
                dumper.index_info.index_file = NULL;
                dumper.index_info.index_bs = NULL;
                if (dumper.index_info.use_url_template!=2) {
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
                        dumper.index_info.index_file = gf_f64_open(dumper.index_info.index_file_name, "wb");
                        dumper.index_info.index_bs = gf_bs_from_file(dumper.index_info.index_file, GF_BITSTREAM_WRITE);
                        {
@@ -2614,6 +2638,7 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num,
                                gf_isom_box_write((GF_Box *)styp, dumper.index_info.index_bs);
                                gf_isom_box_del((GF_Box *)styp);
                        }
+#endif
                }
        }
        /*PES dumping*/
index 97fb414d56b1b2da369d04eb9e72e7b25b30da0d..7b180e5c3d8f437b899064ff17ccc8cba20442d7 100644 (file)
 
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
+#include <gpac/xml.h>
+
+typedef struct 
+{
+       const char *root_file;
+       const char *dir;
+       GF_List *imports;
+} WGTEnum;
+
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
+
 extern u32 swf_flags;
 extern Float swf_flatten_angle;
 extern Bool keep_sys_tracks;
@@ -1385,7 +1396,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                        u32 di;
                        samp = gf_isom_get_sample(orig, i+1, j+1, &di);
                        last_DTS = samp->DTS;
-                       samp->DTS =  (u64) (ts_scale * (s64)samp->DTS) + insert_dts;
+                       samp->DTS =  (u64) (ts_scale * samp->DTS + insert_dts);
                        samp->CTS_Offset =  (u32) (samp->CTS_Offset * ts_scale);
 
                        if (gf_isom_is_self_contained(orig, i+1, di)) {
@@ -1397,7 +1408,8 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou
                                gf_isom_sample_del(&s);
                        }
                        gf_isom_sample_del(&samp);
-                       if (e) goto err_exit;
+                       if (e)
+                               goto err_exit;
                        gf_set_progress("Appending", nb_done, nb_samp);
                        nb_done++;
                }
@@ -1565,7 +1577,9 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
        GF_SceneLoader load;
        GF_SceneManager *ctx;
        GF_SceneGraph *sg;
+#ifndef GPAC_DISABLE_SCENE_STATS
        GF_StatManager *statsman = NULL;
+#endif
        
        sg = gf_sg_new();
        ctx = gf_sm_new(sg);
@@ -1585,6 +1599,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
        e = gf_sm_load_run(&load);
        gf_sm_load_done(&load);
 
+#ifndef GPAC_DISABLE_SCENE_STATS
        if (opts->auto_quant) {
                fprintf(stdout, "Analysing Scene for Automatic Quantization\n");
                statsman = gf_sm_stats_new();
@@ -1655,6 +1670,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
 #endif
                }
        }
+#endif /*GPAC_DISABLE_SCENE_STATS*/
 
        if (e<0) {
                fprintf(stdout, "Error loading file %s\n", gf_error_to_string(e));
@@ -1676,7 +1692,9 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log
        gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1);
 
 err_exit:
+#ifndef GPAC_DISABLE_SCENE_STATS
        if (statsman) gf_sm_stats_del(statsman);
+#endif
        gf_sm_del(ctx);
        gf_sg_del(sg);
        return e;
@@ -1846,8 +1864,8 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa
  */
 GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *outputContext, const char *tmpdir) 
 {
-#ifdef GPAC_DISABLE_BIFS
-       fprintf(stdout, "BIFS is not supported in this build of GPAC\n");
+#if defined(GPAC_DISABLE_BIFS_ENC) || defined(GPAC_DISABLE_SCENE_ENCODER) || defined (GPAC_DISABLE_SCENE_DUMP)
+       fprintf(stdout, "BIFS encoding is not supported in this build of GPAC\n");
        return GF_NOT_SUPPORTED;
 #else
        GF_Err e;
@@ -1933,11 +1951,15 @@ exit:
                gf_sm_del(ctx);
                gf_sg_del(sg);
        }
+
        return e;
-#endif
+
+#endif /*defined(GPAC_DISABLE_BIFS_ENC) || defined(GPAC_DISABLE_SCENE_ENCODER) || defined (GPAC_DISABLE_SCENE_DUMP)*/
+
 }
 
-#include <gpac/xml.h>
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
+
 
 void sax_node_start(void *sax_cbck, const char *node_name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
 {
@@ -1960,13 +1982,6 @@ void sax_node_start(void *sax_cbck, const char *node_name, const char *name_spac
        }
 }
 
-typedef struct 
-{
-       const char *root_file;
-       const char *dir;
-       GF_List *imports;
-} WGTEnum;
-
 static Bool wgt_enum_files(void *cbck, char *file_name, char *file_path)
 {
        WGTEnum *wgt = (WGTEnum *)cbck;
index aafaf5b989fe350aec907848c826c16039cde6fb..efca9d6caf31b39612b8593ce317658fe1667f9d 100644 (file)
 #include <gpac/scene_engine.h>
 #include <gpac/rtp_streamer.h>
 
+#if defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE)
+
+#error "Cannot compile MP4Box if GPAC is not built with ISO File Format support"
+
+#else
+
+#ifndef GPAC_DISABLE_STREAMING
+
 void PrintStreamerUsage()
 {
        fprintf(stdout, "File Streamer Options\n"
@@ -797,3 +805,6 @@ exit:
 }
 
 
+#endif /*GPAC_DISABLE_STREAMING*/
+
+#endif /*defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE)*/
index a516aa9f85381728ad0fccc0c9b8c306347c7f16..bc2b0c70a8e5ffe01dba428f4a0ff6574823e8d7 100644 (file)
 
 /*in fileimport.c*/
 #ifndef GPAC_DISABLE_ISOM_WRITE
-void convert_file_info(char *inName, u32 trackID);
+
 GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample);
 GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start, Bool adjust_split_end, const char *tmpdir);
 GF_Err cat_isomedia_file(GF_ISOFile *mp4, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat);
 
-#ifndef GPAC_DISABLE_SCENE_ENCODER
+#if !defined(GPAC_DISABLE_MEDIA_IMPORT) && !defined(GPAC_DISABLE_SCENE_ENCODER)
+void convert_file_info(char *inName, u32 trackID);
 GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *logs);
 GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *outputContext, const char *tmpdir);
 #endif
 
-
 GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool make_wgt);
+
 #endif
 
 GF_Err dump_cover_art(GF_ISOFile *file, char *inName);
@@ -109,10 +110,10 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name, Bool prog_num,
 #ifndef GPAC_DISABLE_STREAMING
 void PrintStreamerUsage();
 int stream_file_rtp(int argc, char **argv);
-#endif
-
 int live_session(int argc, char **argv);
 void PrintLiveUsage();
+#endif
+
 int mp4boxTerminal(int argc, char **argv);
 
 u32 quiet = 0;
@@ -1203,8 +1204,10 @@ int mp4boxMain(int argc, char **argv)
 #ifndef GPAC_DISABLE_SCENE_ENCODER
        GF_SMEncodeOptions opts;
 #endif
-       Double InterleavingTime, split_duration, split_start, import_fps, dash_duration;
+#ifndef GPAC_DISABLE_STREAMING
        SDPLine sdp_lines[MAX_CUMUL_OPS];
+#endif
+       Double InterleavingTime, split_duration, split_start, import_fps, dash_duration;
        MetaAction metas[MAX_CUMUL_OPS];
        TrackAction tracks[MAX_CUMUL_OPS];
        TSELAction tsel_acts[MAX_CUMUL_OPS];
@@ -1793,7 +1796,7 @@ int mp4boxMain(int argc, char **argv)
                        nb_track_act++;
                        i++;
                }
-#ifndef GPAC_DISABLE_MEDIA_EXPORT
+#if !defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
                else if (!stricmp(arg, "-dref")) import_flags |= GF_IMPORT_USE_DATAREF;
                else if (!stricmp(arg, "-no-drop") || !stricmp(arg, "-nodrop")) import_flags |= GF_IMPORT_NO_FRAME_DROP;
                else if (!stricmp(arg, "-packed")) import_flags |= GF_IMPORT_FORCE_PACKED;
@@ -1816,7 +1819,7 @@ int mp4boxMain(int argc, char **argv)
                }
                else if (!stricmp(arg, "-agg")) { CHECK_NEXT_ARG agg_samples = atoi(argv[i+1]); i++; }
                else if (!stricmp(arg, "-keep-all") || !stricmp(arg, "-keepall")) import_flags |= GF_IMPORT_KEEP_ALL_TRACKS;
-#endif /*GPAC_DISABLE_MEDIA_EXPORT*/
+#endif /*!defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_MEDIA_IMPORT*/
                else if (!stricmp(arg, "-keep-sys") || !stricmp(arg, "-keepsys")) keep_sys_tracks = 1;
                else if (!stricmp(arg, "-ms")) { CHECK_NEXT_ARG mediaSource = argv[i+1]; i++; }
                else if (!stricmp(arg, "-mp4")) { encode = 1; open_edit = 1; }
@@ -1854,12 +1857,14 @@ int mp4boxMain(int argc, char **argv)
                        opts.resolution = atoi(argv[i+1]);
                        i++;
                }
+#ifndef GPAC_DISABLE_SCENE_STATS
                else if (!stricmp(arg, "-auto-quant")) {
                        CHECK_NEXT_ARG
                        opts.resolution = atoi(argv[i+1]);
                        opts.auto_quant = 1;
                        i++;
                }
+#endif
                else if (!stricmp(arg, "-coord-bits")) {
                        CHECK_NEXT_ARG
                        opts.coord_bits = atoi(argv[i+1]);
@@ -2095,8 +2100,10 @@ int mp4boxMain(int argc, char **argv)
                        else if (!strcmp(argv[i+1], "crypt")) PrintEncryptUsage();
                        else if (!strcmp(argv[i+1], "meta")) PrintMetaUsage();
                        else if (!strcmp(argv[i+1], "swf")) PrintSWFUsage();
+#ifndef GPAC_DISABLE_STREAMING
                        else if (!strcmp(argv[i+1], "rtp")) PrintStreamerUsage();
                        else if (!strcmp(argv[i+1], "live")) PrintLiveUsage     ();
+#endif
                        else if (!strcmp(argv[i+1], "all")) {
                                PrintGeneralUsage();
                                PrintExtractUsage();
@@ -2108,8 +2115,10 @@ int mp4boxMain(int argc, char **argv)
                                PrintEncryptUsage();
                                PrintMetaUsage();
                                PrintSWFUsage();
+#ifndef GPAC_DISABLE_STREAMING
                                PrintStreamerUsage();
                                PrintLiveUsage  ();
+#endif
                        }
                        else PrintUsage();
                        return 0;
@@ -2131,10 +2140,10 @@ int mp4boxMain(int argc, char **argv)
                return 1;
        }
 
+#ifndef GPAC_DISABLE_STREAMING
        if (live_scene) {
                return live_session(argc, argv);
        }
-#ifndef GPAC_DISABLE_STREAMING
        if (stream_rtp) {
                return stream_file_rtp(argc, argv);
        }
@@ -2357,7 +2366,7 @@ int mp4boxMain(int argc, char **argv)
        }
 #endif
 
-#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER)
+#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
        else if (chunk_mode) {
                if (!inName) {
                        fprintf(stdout, "chunk encoding syntax: [-outctx outDump] -inctx inScene auFile\n");
@@ -2369,7 +2378,7 @@ int mp4boxMain(int argc, char **argv)
        }
 #endif
        else if (encode) {
-#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER)
+#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
                FILE *logs = NULL;
                if (do_log) {
                        char logfile[5000];
@@ -2470,6 +2479,7 @@ int mp4boxMain(int argc, char **argv)
 #ifndef GPAC_DISABLE_ISOM_WRITE
                        else if (!open_edit && file_exists /* && !gf_isom_probe_file(inName) */ && !dump_mode) {
                /*************************************************************************************************/
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                                if(dvbhdemux)
                                {
                                        GF_MediaImporter import;
@@ -2486,6 +2496,7 @@ int mp4boxMain(int argc, char **argv)
                                                return 1;
                                        }
                                }
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
                                if (dash_duration) {
                                        if (subsegs_per_sidx<0) subsegs_per_sidx = 0;
@@ -2503,14 +2514,14 @@ int mp4boxMain(int argc, char **argv)
 #ifndef GPAC_DISABLE_MPEG2TS
                                        dump_mpeg2_ts(inName, pes_dump, program_number, 0, 0, 0, NULL, NULL, 0, 0, 0, 0);
 #endif
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                                } else {
                                        convert_file_info(inName, info_track_id);
+#endif
                                }
                                return 0;
                        }
-                               
-               
-#endif
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
                        else if (open_edit) {
                                file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, tmpdir);
                                if (!outName && file) outName = inName;
@@ -2640,7 +2651,7 @@ int mp4boxMain(int argc, char **argv)
                }
        }
 
-#ifndef GPAC_DISABLE_ISOM_WRITE
+#if !(definedGPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
        if (split_duration || split_size) {
                split_isomedia_file(file, split_duration, split_size, inName, InterleavingTime, split_start, adjust_split_end, tmpdir);
                /*never save file when splitting is desired*/
@@ -2825,6 +2836,7 @@ int mp4boxMain(int argc, char **argv)
                                strcat(outfile, ".m21");
                        }
                }
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                if ((conv_type == GF_ISOM_CONV_TYPE_ISMA) || (conv_type == GF_ISOM_CONV_TYPE_ISMA_EX)) {
                        fprintf(stdout, "Converting to ISMA Audio-Video MP4 file...\n");
                        /*keep ESIDs when doing ISMACryp*/
@@ -2844,6 +2856,7 @@ int mp4boxMain(int argc, char **argv)
                        if (e) goto err_exit;
                        needSave = 1;
                }
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
                if (conv_type == GF_ISOM_CONV_TYPE_IPOD) {
                        u32 major_brand = 0;
 
@@ -3253,7 +3266,7 @@ int mp4boxMain(int argc, char **argv)
                }
                if (!seg_name) use_url_template = 0;
 
-               gf_media_mpd_start(szMPD, (char *)gf_isom_get_filename(file), use_url_template, single_segment, dash_ctx, szInit, period_duration);
+               gf_media_mpd_start(szMPD, (char *)gf_isom_get_filename(file), use_url_template, single_segment, dash_ctx, init_seg, period_duration);
 
                for (i=0; i<nb_dash_inputs; i++) {
                        char szSegName[GF_MAX_PATH], *segment_name;
@@ -3280,7 +3293,12 @@ int mp4boxMain(int argc, char **argv)
                        if (nb_dash_inputs>1) {
                                fprintf(stdout, "DASHing file %s\n", dash_inputs[i]);
                        }
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
                        e = gf_media_fragment_file(in, outfile, szMPD, InterleavingTime, seg_at_rap ? 2 : 1, dash_duration, segment_name, seg_ext, subsegs_per_sidx, daisy_chain_sidx, use_url_template, single_segment, dash_ctx, init_seg, i+1);
+#else
+                       fprintf(stderr, "GPAC was compiled without fragment support\n");
+                       e = GF_NOT_SUPPORTED;
+#endif
                        if (e) {
                                fprintf(stdout, "Error while DASH-ing file: %s\n", gf_error_to_string(e));
                                break;
@@ -3301,6 +3319,7 @@ int mp4boxMain(int argc, char **argv)
                gf_isom_delete(file);
                gf_sys_close();
                return (e!=GF_OK) ? 1 : 0;
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        } else if (Frag) {
                if (!InterleavingTime) InterleavingTime = 0.5;
                if (HintIt) fprintf(stdout, "Warning: cannot hint and fragment - ignoring hint\n");
@@ -3314,6 +3333,7 @@ int mp4boxMain(int argc, char **argv)
                }
                gf_sys_close();
                return (e!=GF_OK) ? 1 : 0;
+#endif
        }
        
 #ifndef GPAC_DISABLE_ISOM_HINTING
@@ -3380,8 +3400,13 @@ int mp4boxMain(int argc, char **argv)
                if (e) goto err_exit;
        }
        if (chap_file) {
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                e = gf_media_import_chapters(file, chap_file, import_fps);
                needSave = 1;
+#else
+               fprintf(stdout, "Warning: GPAC compiled without Media Import, chapters can't be imported\n");
+               e = GF_NOT_SUPPORTED;
+#endif
                if (e) goto err_exit;
        }
 
index 7185f6966d9ac985570f22acd518663e3e5c0c01..f43d16bb414cbdb43b0259a796c5c619c325317b 100644 (file)
@@ -236,7 +236,8 @@ void PrintHelp()
                "\n"
                "\tp: play/pause the presentation\n"
                "\ts: step one frame ahead\n"
-               "\tz: seek into presentation\n"
+               "\tz: seek into presentation by percentage\n"
+               "\tT: seek into presentation by time\n"
                "\tt: print current timing\n"
                "\n"
                "\tu: sends a command (BIFS or LASeR) to the main scene\n"
@@ -1407,6 +1408,7 @@ force_input:
                        break;
 
                case 'z':
+               case 'T':
                        if (!CanSeek || (Duration<=2000)) {
                                fprintf(stdout, "scene not seekable\n");
                        } else {
@@ -1415,12 +1417,28 @@ force_input:
                                fprintf(stdout, "Duration: ");
                                PrintTime(Duration);
                                res = gf_term_get_time_in_ms(term);
-                               res *= 100; res /= (s64)Duration;
-                               fprintf(stdout, " (current %.2f %%)\nEnter Seek percentage:\n", res);
-                               if (scanf("%d", &seekTo) == 1) { 
-                                       if (seekTo > 100) seekTo = 100;
-                                       res = (Double)(s64)Duration; res /= 100; res *= seekTo;
-                                       gf_term_play_from_time(term, (u64) (s64) res, 0);
+                               if (c=='z') {
+                                       res *= 100; res /= (s64)Duration;
+                                       fprintf(stdout, " (current %.2f %%)\nEnter Seek percentage:\n", res);
+                                       if (scanf("%d", &seekTo) == 1) { 
+                                               if (seekTo > 100) seekTo = 100;
+                                               res = (Double)(s64)Duration; res /= 100; res *= seekTo;
+                                               gf_term_play_from_time(term, (u64) (s64) res, 0);
+                                       }
+                               } else {
+                                       u32 r, h, m, s;
+                                       fprintf(stdout, " - Current Time: ");
+                                       PrintTime((u64) res);
+                                       fprintf(stdout, "\nEnter seek time (Format: s, m:s or h:m:s):\n");
+                                       h = m = s = 0;
+                                       r =scanf("%d:%d:%d", &h, &m, &s);
+                                       if (r==2) { s = m; m = h; h = 0; }
+                                       else if (r==1) { s = h; m = h = 0;      }
+
+                                       if (r && (r<=3)) {
+                                               u64 time = h*3600 + m*60 + s;
+                                               gf_term_play_from_time(term, time*1000, 0);
+                                       }
                                }
                        }
                        break;
diff --git a/bin/arm_ppc02_rel/install/do.bat b/bin/arm_ppc02_rel/install/do.bat
deleted file mode 100644 (file)
index 18c79f4..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-CabWiz gpac.inf
-ezsetup -l english -i gpac.ini -r readme.txt -e ../../../COPYING -o GPAC_0.4.2_Setup_arm_ppc02.exe
-del *.cab
-del *.dat
diff --git a/bin/arm_ppc02_rel/install/gpac.inf b/bin/arm_ppc02_rel/install/gpac.inf
deleted file mode 100644 (file)
index 231ee09..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-[Version]
-Signature = "$Windows NT$"
-Provider = "GPAC 0.4.2"
-CESignature = "$Windows CE$"
-
-[CEStrings]
-;Osmo4 for PocketPC install, Osmophone for Smartphone install
-AppName = Osmo4
-InstallDir = \Program Files\GPAC
-
-[Strings]
-;Osmo4.exe for PocketPC install, Osmophone.exe for Smartphone install
-ExeName = Osmo4.exe
-
-[DefaultInstall]
-CopyFiles = BinFiles , Exefiles
-AddReg = GPACReg
-CEShortcuts = Shortcut , ProgLink
-CESelfRegister=GPAX.dll
-
-[SourceDisksNames]
-
-1 =, "Common Files",, ..
-2 =, "Extra Files",, .
-
-[SourceDisksFiles]
-libgpac.dll = 1
-%ExeName% = 1
-GPAX.dll = 1
-
-;comment this one if not using SpiderMonkey
-js.dll = 1
-
-;uncomment if your device doesn't have GX installed (I think most do)
-;gx.dll = 2
-
-;all gpac modules - comment the ones you haven't compiled
-gm_aac_in.dll = 1
-gm_amr_dec.dll = 1
-;gm_amr_float_dec.dll = 1
-gm_bifs_dec.dll = 1
-gm_ctx_load.dll = 1
-gm_dummy_in.dll = 1
-;gm_ffmpeg_in.dll = 1
-gm_ft_font.dll = 1
-gm_gapi.dll = 1
-gm_img_in.dll = 1
-gm_isom_in.dll = 1
-gm_mp3_in.dll = 1
-gm_odf_dec.dll = 1
-gm_render2d.dll = 1
-gm_rtp_in.dll = 1
-gm_timedtext.dll = 1
-gm_soft_raster.dll = 1
-gm_wav_out.dll = 1
-gm_xvid_dec.dll = 1
-;gm_ogg_xiph.dll = 1
-
-;these 2 go together
-;gm_render3d.dll = 1
-;libGLES_CM.dll = 1
-
-;these 2 go together
-gm_svg_loader.dll = 1
-libxml2.dll = 1
-
-;==================================================
-
-
-
-; Ouput directories for files & shortcuts
-
-[DestinationDirs]
-BinFiles = 0, %CE2% 
-Exefiles = 0, %InstallDir%
-Shortcut = 0, %CE17%
-ProgLink = 0, %CE11%
-DefaultDestDir = 0, %InstallDir%
-
-[BinFiles]
-;"gx.dll"
-"libgpac.dll"
-"GPAX.dll"
-"js.dll"
-"libGLES_CM.dll"
-;"libxml2.dll"
-
-
-[Exefiles]
-"gm_aac_in.dll"
-"gm_amr_dec.dll"
-;"gm_amr_float_dec.dll"
-"gm_bifs_dec.dll"
-"gm_ctx_load.dll"
-"gm_dummy_in.dll"
-;"gm_ffmpeg_in.dll"
-"gm_ft_font.dll"
-"gm_gapi.dll"
-"gm_img_in.dll"
-"gm_isom_in.dll"
-"gm_mp3_in.dll"
-"gm_odf_dec.dll"
-"gm_render2d.dll"
-"gm_rtp_in.dll"
-"gm_soft_raster.dll"
-"gm_timedtext.dll"
-"gm_wav_out.dll"
-"gm_xvid_dec.dll"
-;"gm_ogg_xiph.dll"
-
-"gm_render3d.dll"
-
-;"gm_svg_loader.dll"
-
-[GPACReg]
-;GPAC cfg file location
-HKCR,GPAC,InstallDir,0x00000000,%InstallDir%
-
-;UDP socket overwrite
-HKLM,Comm\Afd,DgramBuffer,0x00010001,16
-;GPAC cfg file association
-HKCR,.cfg,,0x00000000,txtfile
-;MP4 file association
-HKCR,.mp4,,0x00000000,mp4file
-HKCR,mp4file\Shell\Open\Command,,0x00000000,"""%InstallDir%\%ExeName%""" """%%L"""
-;Icon number is bin ID of ressource in app
-HKCR,mp4file\DefaultIcon,,0x00000000,"%InstallDir%\%ExeName%,-128"
-
-[Shortcut]
-"%AppName%", 0, "%ExeName%"
-
-[ProgLink]
-"AppName", 0, "%ExeName%"
-
diff --git a/bin/arm_ppc02_rel/install/gpac.ini b/bin/arm_ppc02_rel/install/gpac.ini
deleted file mode 100644 (file)
index 92ba500..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[CEAppManager]
-Version = 1.0
-Component = GPAC for PocketPC 2002
-
-[GPAC for PocketPC 2002]
-Description = GPAC Osmo4
-Uninstall = GPAC Osmo4
-IconFile = ..\..\w32_rel\Osmo4.ico
-IconIndex = 0
-CabFiles = GPAC.cab
diff --git a/bin/arm_ppc02_rel/install/readme.txt b/bin/arm_ppc02_rel/install/readme.txt
deleted file mode 100644 (file)
index 056b17b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-This will install Osmo4 / GPAC version 0.4.2 for PocketPC/SmartPhone 2002
-
-GPAC is an open source MPEG-4 framework developped by ENST and available at:
-       http://gpac.sourceforge.net
-
-WARNING: THIS RELEASE COMES WITH NO WARRANTY, AND MAY EVEN DAMAGE YOUR HANDHELD DEVICE. PLEASE READ CAREFULLY THE LICENSE HEREJOIN
diff --git a/bin/arm_ppc03_rel/install/do.bat b/bin/arm_ppc03_rel/install/do.bat
deleted file mode 100644 (file)
index 783f2ff..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-CabWiz gpac.inf
-ezsetup -l english -i gpac.ini -r readme.txt -e ../../../COPYING -o GPAC_0.4.5_Setup_arm_ppc03.exe
-del *.cab
-del *.dat
diff --git a/bin/arm_ppc03_rel/install/gpac.inf b/bin/arm_ppc03_rel/install/gpac.inf
deleted file mode 100644 (file)
index 81b6545..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-[Version]
-Signature = "$Windows NT$"
-Provider = "GPAC 0.4.5"
-CESignature = "$Windows CE$"
-
-[CEStrings]
-;Osmo4 for PocketPC install, Osmophone for Smartphone install
-AppName = Osmophone
-InstallDir = \Program Files\GPAC
-
-[Strings]
-;Osmo4.exe for PocketPC install, Osmophone.exe for Smartphone install
-ExeName = Osmophone.exe
-
-[DefaultInstall]
-CopyFiles = BinFiles , Exefiles
-AddReg = GPACReg
-CEShortcuts = Shortcut , ProgLink
-CESelfRegister=GPAX.dll
-
-
-[SourceDisksNames]
-
-1 =, "Common Files",, ..
-2 =, "Extra Files",, .
-3 =, "Doc Files",, ..\..\..\doc\
-
-[SourceDisksFiles]
-libgpac.dll = 1
-%ExeName% = 1
-;Osmo4.exe = 1
-GPAX.dll = 1
-gpac.mp4 = 3
-
-;comment this one if not using OpenGL
-libGLES_CM.dll = 1
-
-;comment this one if not using SpiderMonkey
-js.dll = 1
-
-;uncomment if your device doesn't have GX installed (I think most do)
-;gx.dll = 2
-
-;all gpac modules - comment the ones you haven't compiled
-gm_aac_in.dll = 1
-gm_amr_dec.dll = 1
-;gm_amr_float_dec.dll = 1
-gm_bifs_dec.dll = 1
-gm_ctx_load.dll = 1
-gm_dummy_in.dll = 1
-gm_ffmpeg_in.dll = 1
-gm_ft_font.dll = 1
-gm_gapi.dll = 1
-gm_img_in.dll = 1
-gm_ismacryp.dll = 1
-gm_isom_in.dll = 1
-gm_laser_dec.dll = 1
-gm_mp3_in.dll = 1
-gm_odf_dec.dll = 1
-gm_rtp_in.dll = 1
-gm_timedtext.dll = 1
-gm_soft_raster.dll = 1
-gm_svg_in.dll = 1
-gm_wav_out.dll = 1
-gm_xvid_dec.dll = 1
-;gm_ogg_xiph.dll = 1
-
-
-;ENST Proprietary modules
-;gm_upnp.dll = 1
-
-;==================================================
-
-
-
-; Ouput directories for files & shortcuts
-
-[DestinationDirs]
-BinFiles = 0, %CE2% 
-Exefiles = 0, %InstallDir%
-Shortcut = 0, %CE17%
-ProgLink = 0, %CE11%
-DefaultDestDir = 0, %InstallDir%
-
-[BinFiles]
-;"gx.dll"
-"libgpac.dll"
-"GPAX.dll"
-"js.dll"
-"libGLES_CM.dll"
-;"libxml2.dll"
-
-[Exefiles]
-"%ExeName%"
-;"Osmo4.exe"
-"gpac.mp4"
-"gm_aac_in.dll"
-"gm_amr_dec.dll"
-;"gm_amr_float_dec.dll"
-"gm_bifs_dec.dll"
-"gm_ctx_load.dll"
-"gm_dummy_in.dll"
-"gm_ffmpeg_in.dll"
-"gm_ft_font.dll"
-"gm_gapi.dll"
-"gm_img_in.dll"
-"gm_ismacryp.dll"
-"gm_isom_in.dll"
-"gm_laser_dec.dll"
-"gm_mp3_in.dll"
-"gm_odf_dec.dll"
-"gm_rtp_in.dll"
-"gm_soft_raster.dll"
-"gm_svg_in.dll"
-"gm_timedtext.dll"
-"gm_wav_out.dll"
-"gm_xvid_dec.dll"
-;"gm_ogg_xiph.dll"
-
-;"gm_upnp.dll"
-
-[GPACReg]
-;GPAC cfg file location
-HKCR,GPAC,InstallDir,0x00000000,%InstallDir%
-
-;GPAC cfg file association
-HKCR,.cfg,,0x00000000,txtfile
-
-;MP4 file association
-HKCR,.mp4,,0x00000000,mp4file
-HKCR,mp4file\Shell\Open\Command,,0x00000000,"""%InstallDir%\%ExeName%""" """%%L"""
-
-;Icon number is bin ID of ressource in app
-HKCR,mp4file\DefaultIcon,,0x00000000,"%InstallDir%\%ExeName%,-128"
-
-[Shortcut]
-"%AppName%", 0, "%ExeName%"
-
-[ProgLink]
-"%AppName%", 0, "%ExeName%"
-
diff --git a/bin/arm_ppc03_rel/install/gpac.ini b/bin/arm_ppc03_rel/install/gpac.ini
deleted file mode 100644 (file)
index 830a9c1..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[CEAppManager]
-Version = 1.0
-Component = GPAC for PocketPC 2003
-
-[GPAC for PocketPC 2003]
-Description = GPAC PocketPC MPEG-4 Player
-Uninstall = GPAC Osmo4
-IconFile = ..\..\w32_rel\Osmo4.ico
-IconIndex = 0
-CabFiles = GPAC.cab
diff --git a/bin/arm_ppc03_rel/install/readme.txt b/bin/arm_ppc03_rel/install/readme.txt
deleted file mode 100644 (file)
index 91f5956..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-This will install GPAC version 0.4.5 for ARM PocketPC/SmartPhones 2003 Platforms
-
-GPAC is an open source MPEG-4 framework developped by ENST and available at:
-       http://gpac.sourceforge.net
-
-WARNING: THIS RELEASE COMES WITH NO WARRANTY, AND MAY EVEN DAMAGE YOUR HANDHELD DEVICE. PLEASE READ CAREFULLY THE LICENSE HEREJOIN
index a117a4a3f6874c431b3230942dd601b8bb5bb0ea..4c956c1240c389aa9f1aa1f14584ba5aa1c847b8 100755 (executable)
--- a/configure
+++ b/configure
@@ -135,6 +135,7 @@ disable_loader_isoff="no"
 disable_loader_bt="no"
 disable_loader_xmt="no"
 disable_od_dump="no"
+disable_isom_dump="no"
 disable_mcrypt="no"
 disable_isoff="no"
 disable_isoff_write="no"
@@ -239,7 +240,8 @@ Configuration options for libgpac - all options can be enabled with --enable-opt
   --disable-vrml           disable MPEG-4/VRML/X3D
   --disable-x3d            disable X3D only
   --disable-odf            disable full support of MPEG-4 OD Framework
-  --disable-bifs           disable BIFS coder
+  --disable-bifs           disable BIFS
+  --disable-bifs-enc       disable BIFS coder
   --disable-laser          disable LASeR coder
   --disable-beng           disable scene encoder engine
   --disable-qtvr           disable import of Cubic QTVR files
@@ -255,12 +257,13 @@ Configuration options for libgpac - all options can be enabled with --enable-opt
   --disable-swf            disable SWF import
   --disable-scene-stats    disable scene graph statistics
   --disable-scene-dump     disable scene graph dump
-  --disable-od-dump        disable OD dump
-  --disable-mcrypt         disable mcrypt
   --disable-scene-encode   disable BIFS & LASeR to ISO File Format encoding
   --disable-loader-isoff   disable scene loading from ISO File Format
   --disable-loader-bt      disable scene loading from ISO File Format
   --disable-loader-xmt     disable scene loading from ISO File Format
+  --disable-od-dump        disable OD dump
+  --disable-isom-dump      disable ISOM dump
+  --disable-mcrypt         disable mcrypt
   --disable-isoff          disable ISO File Format
   --disable-isoff-write    disable ISO File Format edit/write
   --disable-isoff-hint     disable ISO File Format hinting
@@ -298,7 +301,7 @@ for opt do
             ;;
         --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
             ;;
-        --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` && echo "cross-prefix detected: $cross_prefix"
+        --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` && echo "\ncross-prefix detected: $cross_prefix"
             ;;
         --cc=*) cc=`echo $opt | cut -d '=' -f 2`
             ;;
@@ -402,8 +405,10 @@ pkg_config="${cross_prefix}${pkg_config}"
 
 
 #check pkg_config
-if ! $pkg_config --version >/dev/null 2>&1 ; then
-    echo "$pkg_config not found, configure may detect wrong libraries"
+if test "$cross_prefix" = "" ; then
+    if ! $pkg_config --version >/dev/null 2>&1 ; then
+        echo "$pkg_config not found, configure may detect wrong libraries"
+    fi
 fi
 
 
@@ -542,7 +547,7 @@ EOF
 
     Linux)
         js_flags="-DXP_UNIX -I/usr/include/js"
-        LDFLAGS="$LDFLAGS -Wl,--warn-common"
+        LDFLAGS="$LDFLAGS -Wl,--warn-common -Wl,-z,defs"
         #OSS_LDFLAGS="-laoss"
         linux="yes"
         case "$cpu" in
@@ -594,13 +599,9 @@ fi
 
 #GCC opt
 if test "$no_gcc_opt" = "no"; then
-    if $cc --version | grep 'sbox-arm-linux-gcc (GCC) 3.4.4'
-    then
-        echo "Detected buggy arm GCC (diablo), using -O2"
-        CFLAGS="-O2 $CFLAGS"
-    else
-        CFLAGS="-O3 $CFLAGS"
-    fi
+    CFLAGS="-O3 $CFLAGS"
+else
+    CFLAGS="-O0 $CFLAGS"
 fi
 
 
@@ -737,9 +738,10 @@ EOF
     fi
 fi
 
+new_js_api="no"
 if test "$has_js" != "no" ; then
     js_flags="-DSPIDERMONKEY_NEW_API $js_flags"
-    echo "SpiderMonkey new API detected" # (version > 1.8.0rc1)
+    new_js_api="yes"
 fi
 
 #spidermonkey test for regular API
@@ -807,20 +809,26 @@ EOF
 
 fi
 
-
 if test "$has_js" != "no" ; then
     if test "$linux" = "yes" ; then
         if test "$cpu" != "sh4"; then
-
             #WARNING: there is a bug in MOZJS packages, the MOZILLA_1_8_BRANCH macro is not signaled, there is no way of knowing
             #if the lib has been compiled with or without the macro. We currently just decide that if the macro is present
             #in the header, it was enabled in the build
-            if grep "MOZILLA_1_8_BRANCH" $js_inc/jsapi.h > /dev/null 2>&1 ; then
-                js_flags="-DMOZILLA_1_8_BRANCH $js_flags"
-                echo "WARNING: Turning on MOZILLA_1_8_BRANCH SpiderMonkey macro"
-                echo "If you have troubles with scripts in GPAC, disable this macro and recompile"
+            if test "$new_js_api" = "no" ; then
+              if grep MOZILLA_1_8_BRANCH $js_inc/jsapi.h > /dev/null 2>&1 ; then
+                  js_flags="-DMOZILLA_1_8_BRANCH $js_flags"
+                  echo "WARNING: Turning on MOZILLA_1_8_BRANCH SpiderMonkey macro"
+                  echo "If you have troubles with scripts in GPAC, disable this macro and recompile"
+              fi
+            else
+              #check presence of ***RuntimeThread
+              if grep RuntimeThread $js_inc/jsapi.h > /dev/null 2>&1 ; then
+                js_flags="$js_flags"
+              else
+                  js_flags="-DNO_JS_RUNTIMETHREAD $js_flags"
+              fi
             fi
-
         fi
     fi
 fi
@@ -837,7 +845,7 @@ cat > $TMPC << EOF
 #include <Platinum.h>
 int main( void ) { return 0; }
 EOF
-if $cpp -o $TMPO $TMPC -I$local_inc/platinum $LDFLAGS -L$local_lib -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib 2> /dev/null  ; then
+if $cpp -o $TMPO $TMPC -I$local_inc/platinum $LDFLAGS -L$local_lib -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib -lpthread 2> /dev/null  ; then
   has_platinum="yes"
 fi
 
@@ -854,7 +862,7 @@ int main( void ) {
   DeviceDescriptor* dd = 0;
   for (DeviceCollector::DeviceList::const_iterator i = dl.begin(); i != dl.end(); i++) {
     dd = *i;
-       std::cout << dd->getName().c_str() << "\n";
+    std::cout << dd->getName().c_str() << "\n";
   }
   return 0; 
 }
@@ -870,7 +878,7 @@ else
         avcap_ldflags="-lavcap -lpthread"
     fi
     if $cpp -o $TMPO $TMPC $avcap_cflags $LDFLAGS -L$local_lib $avcap_ldflags 2> /dev/null  ; then
-               has_avcap="yes"
+        has_avcap="yes"
         avcap_ldflags="-L../../$local_lib $avcap_ldflags"
     fi
 fi
@@ -1201,7 +1209,18 @@ fi
 
 
 
-#look for MAD support
+#look for FREENECT support
+freenect_flags=""
+freenect_ld="-lfreenect"
+
+if $pkg_config --exists libfreenect 2> /dev/null  ; then
+  freenect_flags=`$pkg_config --cflags libfreenect`
+  freenect_libs=`$pkg_config --libs libfreenect`
+  has_freenect="system"
+  freenect_flags="-DFREENECT_FLAT_HEADERS $freenect_flags" 
+
+else
+
 has_freenect="no"
 cat > $TMPC << EOF
 #include <libfreenect/libfreenect.h>
@@ -1214,15 +1233,21 @@ if test "$cross_prefix" = "" ; then
     elif test "$alt_macosx_dir" != "" ; then
         if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib $LDFLAGS -lfreenect 2> /dev/null ; then
             has_freenect="system"
+            freenect_flags=-I$alt_macosx_dir/include
+            freenect_ld=-L$alt_macosx_dir/lib -lfreenect
         fi
     fi
 fi
 if test "$has_freenect" = "no" ; then
-    if $cc -o $TMPO $TMPC -I$local_inc/mad -L$local_lib -lfreenect 2> /dev/null  ; then
+    if $cc -o $TMPO $TMPC -I$local_inc/freenect -L$local_lib -lfreenect 2> /dev/null  ; then
         has_freenect="local"
+        freenect_flags=-I$local_inc/freenect
+        freenect_ld=-L$local_lib -lfreenect
     fi
 fi
 
+fi
+
 
 #look for vorbis support
 cat > $TMPC << EOF
@@ -1283,13 +1308,14 @@ fi
 
 #look for OSS support
 if test "$darwin" = "yes" ; then
+
     cat > $TMPC << EOF
 #include <soundcard.h>
 int main( void ) { return 0; }
 EOF
 
     if $cc -o $TMPO $TMPC -DLIBOSS_INTERNAL -I$alt_macosx_dir/include/ -I$alt_macosx_dir/include/liboss -L$alt_macosx_dir/lib -loss $LDFLAGS 2> /dev/null ; then
-        has_oss_audio="SYS"
+        has_oss_audio="yes"
         OSS_CFLAGS="-DLIBOSS_INTERNAL -I$alt_macosx_dir/include/ -I$alt_macosx_dir/include/liboss"
         OSS_LDFLAGS="-L$alt_macosx_dir/lib -loss"
     fi
@@ -1305,7 +1331,7 @@ int main( void ) { return 0; }
 EOF
 
     if $cc -o $TMPO $TMPC 2> /dev/null  ; then
-        has_oss_audio="SYS"
+        has_oss_audio="yes"
     else
         cat > $TMPC << EOF
 #include <sys/ioctl.h>
@@ -1316,7 +1342,7 @@ int main( void ) { return 0; }
 EOF
 
         if $cc -o $TMPO $TMPC $LDFLAGS 2> /dev/null  ; then
-            has_oss_audio="YES"
+            has_oss_audio="yes"
         fi
     fi
 
@@ -1328,44 +1354,44 @@ fi
 has_wx="no"
 wx_too_old="no"
 
-if type wx-config >/dev/null 2>&1; then
+if test "$cross_prefix" = "" ; then
+    if type wx-config >/dev/null 2>&1; then
 
-    wx_version=`wx-config --version | sed 's/[^0-9]//g'`
+        wx_version=`wx-config --version | sed 's/[^0-9]//g'`
 
-    if test "$wx_version" -lt 250 ; then
-        wx_too_old="yes"
-        has_wx="yes"
-    else
-        if test "$wx_version" -lt 260 ; then
+        if test "$wx_version" -lt 250 ; then
+            wx_too_old="yes"
             has_wx="yes"
-            wx_cflags=`wx-config --cppflags`
-            wx_lflags=`wx-config --libs`
         else
-            has_wx="yes"
-            wx_cflags=`wx-config --cppflags core, base`
-            wx_lflags=`wx-config --libs core, base`
-        fi
+            if test "$wx_version" -lt 260 ; then
+                has_wx="yes"
+                wx_cflags=`wx-config --cppflags`
+                wx_lflags=`wx-config --libs`
+            else
+                has_wx="yes"
+                wx_cflags=`wx-config --cppflags core, base`
+                wx_lflags=`wx-config --libs core, base`
+            fi
 
-        if test "$darwin" = "yes" ; then
-            wx_lflags="-Wl,-bind_at_load $wx_lflags -lstdc++" #10.4 needs it, not sure about 10.3
+            if test "$darwin" = "yes" ; then
+                wx_lflags="-Wl,-bind_at_load $wx_lflags -lstdc++" #10.4 needs it, not sure about 10.3
+            fi
         fi
 
-    fi
-
-    cat > $TMPCPP << EOF
+        cat > $TMPCPP << EOF
 #include <wx/wx.h>
 int main( void ) { return 0; }
 EOF
 
-    if $cc $wx_cflags -o $TMPO $TMPCPP $wx_lflags > /dev/null 2>&1 ; then
-        wx_version=`wx-config --version | sed 's/[^0-9]//g'`
-        if test "$wx_version" -lt 254 ; then
-            wx_too_old="yes"
-        else
-            has_wx="yes"
+        if $cc $wx_cflags -o $TMPO $TMPCPP $wx_lflags > /dev/null 2>&1 ; then
+            wx_version=`wx-config --version | sed 's/[^0-9]//g'`
+            if test "$wx_version" -lt 254 ; then
+                wx_too_old="yes"
+            else
+                has_wx="yes"
+            fi
         fi
     fi
-
 fi
 #end wx test
 
@@ -1648,7 +1674,7 @@ for opt do
         --enable-pulseaudio=*) has_pulseaudio="yes"
             ;;
 
-        --disable-all) has_pulseaudio="no"; has_alsa="no"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_beng="yes"; disable_qtvr="yes";  disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"
+        --disable-all) has_pulseaudio="no"; has_alsa="no"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_beng="yes"; disable_qtvr="yes";  disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_isom_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"
             ;;
 
         --disable-3d) disable_3d="yes"
@@ -1757,6 +1783,10 @@ for opt do
             ;;
         --enable-od-dump) disable_od_dump="no"
             ;;
+        --disable-isom-dump) disable_isom_dump="yes"
+            ;;
+        --enable-isom-dump) disable_isom_dump="no"
+            ;;
         --disable-mcrypt) disable_mcrypt="yes"
             ;;
         --enable-mcrypt) disable_mcrypt="no"
@@ -1920,30 +1950,32 @@ if test "$sdl_local" = "yes"; then
     sdl_static="yes"
 fi
 
-if type $sdl_config >/dev/null 2>&1; then
 
-    cat > $TMPC << EOF
+if test "$cross_prefix" = "" ; then
+    if type $sdl_config >/dev/null 2>&1; then
+
+        cat > $TMPC << EOF
 #include <SDL.h>
 #undef main
 int main( void ) { return SDL_Init (SDL_INIT_VIDEO); }
 EOF
 
-    if test "$sdl_static" = "yes"; then
-        sdl_lib_flags=`$sdl_config --static-libs`
-    else
-        sdl_lib_flags=`$sdl_config --libs`
-    fi
-    sdl_cflags=`$sdl_config --cflags`
-
-    if $cc -o $TMPO $sdl_cflags $TMPC $LDFLAGS $sdl_lib_flags  > /dev/null 2>&1  ; then
-        _sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'`
-        if test "$_sdlversion" -lt 121 ; then
-            sdl_too_old=yes
+        if test "$sdl_static" = "yes"; then
+            sdl_lib_flags=`$sdl_config --static-libs`
         else
-            has_sdl=yes
+            sdl_lib_flags=`$sdl_config --libs`
         fi
-    fi
+        sdl_cflags=`$sdl_config --cflags`
 
+        if $cc -o $TMPO $sdl_cflags $TMPC $LDFLAGS $sdl_lib_flags  > /dev/null 2>&1  ; then
+            _sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'`
+            if test "$_sdlversion" -lt 121 ; then
+                sdl_too_old=yes
+            else
+                has_sdl=yes
+            fi
+        fi
+    fi
 fi
 #end SDL check
 
@@ -2009,6 +2041,10 @@ echo "#define GF_CONFIG_H" >> $TMPH
 echo "#define GPAC_CONFIGURATION \"$GPAC_CONFIGURATION\"" >> $TMPH
 
 version="`grep '#define GPAC_VERSION ' \"$source_path/include/gpac/tools.h\" | cut -d '"' -f 2`"
+version_major=`grep '#define GPAC_VERSION_MAJOR ' $source_path/include/gpac/tools.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
+version_minor=`grep '#define GPAC_VERSION_MINOR ' $source_path/include/gpac/tools.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
+version_micro=`grep '#define GPAC_VERSION_MICRO ' $source_path/include/gpac/tools.h | sed -e 's/.*\([0-9]\)\+$/\1/'`
+soname_version="${version_major}.${version_minor}.${version_micro}"
 
 if which svnversion >/dev/null
 then
@@ -2141,6 +2177,10 @@ if test "$disable_od_dump" = "yes" ; then
     echo "OD dump disabled"
     echo "#define GPAC_DISABLE_OD_DUMP" >> $TMPH
 fi
+if test "$disable_isom_dump" = "yes" ; then
+    echo "ISOM dump disabled"
+    echo "#define GPAC_DISABLE_ISOM_DUMP" >> $TMPH
+fi
 if test "$disable_mcrypt" = "yes" ; then
     echo "MCrypt disabled"
     echo "#define GPAC_DISABLE_MCRYPT" >> $TMPH
@@ -2244,8 +2284,8 @@ if test "$enable_renoir" = "yes" ; then
     echo "Renoir enabled - make sure the driver libraries are present in modules/viren_out directory"
 fi
 
-echo ""
 if test "$has_amr_nb_fixed" = "yes" ; then
+    echo ""
     echo "*** AMR NB FIXED-POINT NOTICE ***"
     echo "Make sure you have downloaded TS26.073 from:"
     echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-*.zip"
@@ -2254,8 +2294,8 @@ if test "$has_amr_nb_fixed" = "yes" ; then
     echo ""
 fi
 
-echo ""
 if test "$has_amr_nb" = "yes" ; then
+    echo ""
     echo "*** AMR NB NOTICE ***"
     echo "Make sure you have downloaded TS26.104 from:"
     echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-*.zip"
@@ -2265,8 +2305,8 @@ if test "$has_amr_nb" = "yes" ; then
 fi
 
 
-echo ""
 if test "$has_amr_wb" = "yes" ; then
+    echo ""
     echo "*** AMR WB NOTICE ***"
     echo "Make sure you have downloaded TS26.204 from:"
     echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-*.zip"
@@ -2275,6 +2315,7 @@ if test "$has_amr_wb" = "yes" ; then
     echo ""
 fi
 
+echo ""
 if test "$use_memory_tracking" = "yes"; then
     echo "!! WARNING: GPAC Memory tracking is enabled !!"
     echo "!! This may corrupt third-party tools using libgpac !!"
@@ -2349,6 +2390,8 @@ if test "$bigendian" = "yes" ; then
 fi
 echo "EXTRALIBS=$extralibs" >> config.mak
 echo "VERSION=$version" >>config.mak
+echo "VERSION_MAJOR=$version_major" >>config.mak
+echo "VERSION_SONAME=$soname_version" >>config.mak
 
 if test "$use_fixed_point" = "yes"; then
     echo "#define GPAC_FIXED_POINT" >> $TMPH
@@ -2446,19 +2489,29 @@ echo "CONFIG_JACK=$has_jack" >> config.mak
 echo "CONFIG_A52=$has_a52" >> config.mak
 echo "CONFIG_PULSEAUDIO=$has_pulseaudio" >> config.mak
 echo "CONFIG_FREENECT=$has_freenect" >> config.mak
+if test "$has_freenect" != "no"
+then
+    echo "FREENECT_CFLAGS=$freenect_flags" >> config.mak
+    echo "FREENECT_LDLAGS=$freenect_ld" >> config.mak
+fi
 
 echo "DISABLE_SVG=$disable_svg" >> config.mak
+echo "DISABLE_LOADER_BT=$disable_loader_bt" >> config.mak
 echo "HAS_LIBXML2=$has_libxml2" >> config.mak
 if test "$has_libxml2" = "yes"; then
     echo "XML2_CFLAGS=$libxml2_cflags" >> config.mak
     echo "XML2_LIBS=$libxml2_lib_flags" >> config.mak
 fi
-
+if test "$disable_m2ts_mux" = "yes" -o "$disable_m2ts" = "yes" ; then
+    echo "DISABLE_M2TS=yes" >> config.mak
+fi
 
 echo "GPAC_USE_TINYGL=$has_tinygl" >> config.mak
 echo "OGL_INCLS=$INCL3D" >> config.mak
 
-echo "DISABLE_ISOFF=$disable_isoff" >> config.mak
+if test "$disable_isoff" = "yes" -o "$disable_isoff_write" = "yes" ; then
+       echo "DISABLE_ISOFF=$disable_isoff" >> config.mak
+fi
 
 echo "HAS_OPENGL=$has_opengl" >> config.mak
 
index f393fa3bcd8f74ecea58e79a235d0b6ddabc089d..545148e3c60082c8048ed4e7bdb66f3e2021a814 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef _GF_AIT_H_\r
 #define _GF_AIT_H_\r
 \r
-#ifndef GPAC_DISABLE_MPEG2TS\r
-\r
 #ifdef __cplusplus\r
 extern "C" {\r
 #endif\r
@@ -17,6 +15,9 @@ extern "C" {
 #include <gpac/bitstream.h>\r
 \r
 \r
+#ifndef GPAC_DISABLE_MPEG2TS\r
+\r
+\r
 #define AIT_SECTION_LENGTH_MAX 1021\r
 #define APPLICATION_TYPE_HTTP_APPLICATION 16\r
 #define DSMCC_SECTION_LENGTH_MAX 4093\r
@@ -231,10 +232,11 @@ GF_M2TS_ES *gf_ait_section_new(u32 service_id);
 GF_M2TS_CHANNEL_APPLICATION_INFO* gf_m2ts_get_channel_application_info(GF_List* ChannelAppList, u32 ait_service_id);\r
 void  gf_m2ts_delete_channel_application_info(GF_M2TS_CHANNEL_APPLICATION_INFO* ChannelApp);\r
 \r
+#endif /*GPAC_DISABLE_MPEG2TS*/\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
-#endif\r
 \r
 #endif //_GF_CAROUSSEL_H_\r
 \r
index 4fd2add2950df7f71715b68efa98632119f0acc4..38127612178da78a0942e6489c592c402d665c2e 100644 (file)
@@ -7,9 +7,6 @@
 #ifndef _GF_DSMCC_H_\r
 #define _GF_DSMCC_H_\r
 \r
-#ifndef GPAC_DISABLE_MPEG2TS\r
-\r
-\r
 #ifdef __cplusplus\r
 extern "C" {\r
 #endif\r
@@ -18,6 +15,10 @@ extern "C" {
 #include <string.h>\r
 #include <gpac/bitstream.h>\r
 \r
+\r
+#ifndef GPAC_DISABLE_MPEG2TS\r
+\r
+\r
 #define DSMCC_SECTION_LENGTH_MAX 4093\r
 \r
 typedef enum{\r
@@ -626,7 +627,7 @@ typedef struct
        Bool get_index;\r
        /* Number of the application that uses the carousel*/\r
        u32 application_id;\r
-}GF_M2TS_DSMCC_OVERLORD;\r
+} GF_M2TS_DSMCC_OVERLORD;\r
 \r
 void on_dsmcc_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par);\r
 GF_Err gf_m2ts_process_dsmcc(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_SECTION *dsmcc, char  *data, u32 data_size, u32 table_id);\r
@@ -634,10 +635,11 @@ GF_M2TS_DSMCC_OVERLORD* gf_m2ts_init_dsmcc_overlord(u32 service_id);
 GF_M2TS_DSMCC_OVERLORD* gf_m2ts_get_dmscc_overlord(GF_List* Dsmcc_controller,u32 service_id);\r
 void gf_m2ts_delete_dsmcc_overlord(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord);\r
 \r
+#endif /*GPAC_DISABLE_MPEG2TS*/\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
-#endif\r
 \r
 #endif //_GF_CAROUSSEL_H_\r
 \r
index 41fd6bcf072212434978b9a66febfb6d26834641..fa6e92e80e3f75a7eb4e9155d05af314749ad764 100644 (file)
@@ -1865,7 +1865,6 @@ typedef struct __oma_kms_box
        GF_OMADRMAUFormatBox *fmt;
 } GF_OMADRMKMSBox;
 
-#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
 
 typedef struct
 {
@@ -1888,7 +1887,6 @@ typedef struct __sidx_box
        u32 nb_refs;
        GF_SIDXReference *refs;
 } GF_SegmentIndexBox;
-#endif
 
 
 
@@ -3421,12 +3419,14 @@ GF_Err subs_Size(GF_Box *s);
 GF_Err subs_Read(GF_Box *s, GF_BitStream *bs);
 GF_Err subs_dump(GF_Box *a, FILE * trace);
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
 GF_Box *tfdt_New();
 void tfdt_del(GF_Box *);
 GF_Err tfdt_Write(GF_Box *s, GF_BitStream *bs);
 GF_Err tfdt_Size(GF_Box *s);
 GF_Err tfdt_Read(GF_Box *s, GF_BitStream *bs);
 GF_Err tfdt_dump(GF_Box *a, FILE * trace);
+#endif
 
 GF_Box *rvcc_New();
 void rvcc_del(GF_Box *);
index 057dc49edff20a3cd0e0a2c78822014b9e38783f..03cd58bc624225367789f677e664c01d6b35289d 100644 (file)
 #define SMJS_FREE(__c, __str)  if (__str) JS_free(__c, __str)
 
 
-#define SMJS_OBJ_CONSTRUCTOR   JSObject *obj = NULL;\
-       if (!JS_IsConstructing_PossiblyWithGivenThisObject(c, argsvp, &obj)) {  \
-               return JS_FALSE;\
-       }\
-       if (obj == NULL) obj = JS_NewObjectForConstructor(c, argsvp);   \
+#define SMJS_OBJ_CONSTRUCTOR   \
+       JSObject *obj = JS_NewObjectForConstructor(c, argsvp);  \
        SMJS_SET_RVAL(OBJECT_TO_JSVAL(obj));\
 
 #define JS_GetFunctionName(_v) (JS_GetFunctionId(_v)!=NULL) ? SMJS_CHARS_FROM_STRING(c, JS_GetFunctionId(_v)) : NULL
index c64d5d77c5eddded3f8942d1ef291eb610698aa9..60107056b69a5425c0374ecac51f7a470c1d27a7 100644 (file)
@@ -1091,7 +1091,7 @@ GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables);
 if end_range>start_range, restricts the URL to the given byterange when parsing*/
 GF_Err gf_isom_open_segment(GF_ISOFile *movie, const char *fileName, u64 start_range, u64 end_range);
 
-#ifndef GPAC_DISBALE_ISOM_FRAGMENTS
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
 
 /*
                        Movie Fragments Writing API
@@ -1223,7 +1223,7 @@ GF_Err gf_isom_fragment_append_data(GF_ISOFile *the_file, u32 TrackID, char *dat
 
 void gf_isom_reset_fragment_info(GF_ISOFile *movie);
 
-#endif /*GPAC_DISBALE_ISOM_FRAGMENTS*/
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
 
 /******************************************************************
index 8c4a3f36514577c9f5dc93edfb036c1b233dcda6..a9bf5c7ceff26bc27481cb8082728a9b3d67c138 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 /*creates (if needed) a GF_ESD for the given track - THIS IS RESERVED for local playback
 only, since the OTI used when emulated is not standard...*/
 GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track);
+
 #endif
 
 
@@ -224,11 +225,6 @@ GF_Err gf_media_import(GF_MediaImporter *importer);
 /*adds chapter info contained in file - import_fps is optional (most formats don't use it), defaults to 25*/
 GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import_fps);
 
-
-/*save file as fragmented movie
-@dash_mode: 0 = DASH not used, 1 = DASH used without GOP spliting, 2 = DASH used with GOP spliting, */
-GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file_radical, const char *mpd_name, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, Bool use_single_segment, const char *dash_ctx, GF_ISOFile *sample_descs, u32 rep_id);
-
 /*make the file ISMA compliant: creates ISMA BIFS / OD tracks if needed, and update audio/video IDs
 the file should not contain more than one audio and one video track
 @keepImage: if set, generates system info if image is found - only used for image imports
@@ -243,9 +239,6 @@ GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file);
 */
 GF_Err gf_media_make_psp(GF_ISOFile *mp4file);
 
-/*changes pixel aspect ratio for visual tracks if supported. Negative values remove any PAR info*/
-GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den);
-
 /*changes the profile (if not 0) and level (if not 0) indication of the media - only AVC/H264 supported for now*/
 GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level);
 
@@ -255,6 +248,24 @@ GF_Err gf_media_avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size_i
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
 
+/*changes pixel aspect ratio for visual tracks if supported. Negative values remove any PAR info*/
+GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den);
+
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
+/*starts MPD file */
+GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bool single_segment, char *dash_ctx, GF_ISOFile *init_segment, Double period_duration);
+GF_Err gf_media_mpd_end(char *mpd_name);
+
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+/*save file as fragmented movie
+@dash_mode: 0 = DASH not used, 1 = DASH used without GOP spliting, 2 = DASH used with GOP spliting, */
+GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file_radical, const char *mpd_name, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, Bool use_single_segment, const char *dash_ctx, GF_ISOFile *sample_descs, u32 rep_id);
+#endif
+
+#endif
+
 
 #ifndef GPAC_DISABLE_MEDIA_EXPORT
 
@@ -391,8 +402,6 @@ if force_end_of_session is set, this flushes the SAF Session - no more operation
 GF_Err gf_saf_mux_for_time(GF_SAFMuxer *mux, u32 time_ms, Bool force_end_of_session, char **out_data, u32 *out_size);
 
 
-GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bool single_segment, char *dash_ctx, char *init_segment, Double period_duration);
-GF_Err gf_media_mpd_end(char *mpd_name);
 
 #ifdef __cplusplus
 }
index 7a96f2da8cb5613c7f1f9c11ceb81ac35c22c4ec..77584f3ffcedc4c812af86d1a3a628f7fc116984 100644 (file)
@@ -46,7 +46,7 @@ extern "C" {
 #include <gpac/ietf.h>
 #include <gpac/isomedia.h>
 
-#ifndef GPAC_DISABLE_STREAMING
+#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_ISOM)
     
 typedef struct __rtp_streamer GF_RTPStreamer;
 
@@ -108,7 +108,7 @@ GF_Err gf_rtp_streamer_send_rtcp(GF_RTPStreamer *streamer, Bool force_ts, u32 rt
 }
 #endif
 
-#endif //GPAC_DISABLE_STREAMING
+#endif //GPAC_DISABLE_ISOM && GPAC_DISABLE_STREAMING
 
 #endif         /*_GF_RTPSTREAMER_H_*/
 
index 437f8dd698034123691b1bab7c840e530eb82d0a..7c7c0a49f43ea7b87da289bfff043939f7d0c4bf 100644 (file)
@@ -449,6 +449,15 @@ void gf_memory_print(void); /*prints the state of current allocations*/
 # ifndef GPAC_DISABLE_MPEG2PS
 # define GPAC_DISABLE_MPEG2PS
 # endif
+# ifndef GPAC_DISABLE_ISOM_HINTING
+# define GPAC_DISABLE_ISOM_HINTING
+# endif
+# ifndef GPAC_DISABLE_MEDIA_IMPORT
+# define GPAC_DISABLE_MEDIA_IMPORT
+# endif
+# ifndef GPAC_DISABLE_MPEG2TS_MUX
+# define GPAC_DISABLE_MPEG2TS_MUX
+# endif
 #endif
 
 #ifdef GPAC_DISABLE_ISOM
@@ -467,12 +476,27 @@ void gf_memory_print(void); /*prints the state of current allocations*/
 # ifndef GPAC_DISABLE_ISOM_DUMP
 # define GPAC_DISABLE_ISOM_DUMP
 # endif
+# ifndef GPAC_DISABLE_LOADER_ISOM
+# define GPAC_DISABLE_LOADER_ISOM
+# endif
+# ifndef GPAC_DISABLE_MEDIA_EXPORT
+# define GPAC_DISABLE_MEDIA_EXPORT
+# endif
 #endif
 
 #ifdef GPAC_DISABLE_ISOM_WRITE
 # ifndef GPAC_DISABLE_MEDIA_IMPORT
 # define GPAC_DISABLE_MEDIA_IMPORT
 # endif
+# ifndef GPAC_DISABLE_QTVR
+# define GPAC_DISABLE_QTVR
+# endif
+# ifndef GPAC_DISABLE_ISOM_HINTING
+# define GPAC_DISABLE_ISOM_HINTING
+# endif
+# ifndef GPAC_DISABLE_SCENE_ENCODER
+# define GPAC_DISABLE_SCENE_ENCODER
+# endif
 #endif
 
 #ifdef GPAC_DISABLE_STREAMING
index 72b24600547a2394a4741ed20669564cb2b26d89..11af4052dc8b01534d784f548a221380e49a376b 100644 (file)
@@ -57,8 +57,14 @@ extern "C" {
  *
  *     Macro giving GPAC version expressed as a printable string
 */
-/*KEEP SPACE SEPARATORS FOR MAKE / GREP (SEE MAIN MAKEFILE)!!!, and NO SPACE in GPAC_VERSION for proper install*/
-#define GPAC_VERSION       "0.4.6-DEV"
+/* KEEP SPACE SEPARATORS FOR MAKE / GREP (SEE MAIN MAKEFILE)
+ * NO SPACE in GPAC_VERSION for proper install
+ * SONAME versions must be digits (not strings)
+ */
+#define GPAC_VERSION          "0.4.6-DEV"
+#define GPAC_VERSION_MAJOR    1
+#define GPAC_VERSION_MINOR    1
+#define GPAC_VERSION_MICRO    0
 
 #include <gpac/version.h>
 #define GPAC_FULL_VERSION       GPAC_VERSION"-rev"GPAC_SVN_REVISION
index acd7af063deef2b7f8979ef9d369ac088b53a9c7..5de07db72a6f2d8b09527f56b49d173719c139fc 100644 (file)
@@ -1,10 +1,13 @@
 include ../config.mak
 
 #all OS and lib independent
-PLUGDIRS=aac_in ac3_in audio_filter bifs_dec ctx_load dummy_in soft_raster mp3_in isom_in odf_dec rtp_in timedtext img_in svg_in saf_in mpegts_in ismacryp widgetman mpd_in osd
+PLUGDIRS=aac_in ac3_in audio_filter bifs_dec ctx_load dummy_in soft_raster mp3_in isom_in odf_dec rtp_in timedtext img_in svg_in saf_in mpegts_in ismacryp mpd_in
 
 ifeq ($(DISABLE_SVG), no)
-PLUGDIRS+=laser_dec svg_in
+PLUGDIRS+=laser_dec svg_in widgetman
+ifeq ($(DISABLE_LOADER_BT),no)
+PLUGDIRS+=osd
+endif
 endif
 
 ifeq ($(CONFIG_FT), no)
index 0ce8e5930f6bc867ebc97d9d260733612ab4dc77..6a21969a6c940f8de5b14cf3523d3394ace1f234 100644 (file)
@@ -122,10 +122,13 @@ GF_Err CreateBackBuffer(GF_VideoOutput *dr, u32 Width, u32 Height, Bool use_syst
        DDCONTEXT;
 
        opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "HardwareMemory");
-       if (use_system_memory) {
-               if (opt && !strcmp(opt, "Always")) use_system_memory = 0;
-       } else {
-               if (opt && !strcmp(opt, "Never")) use_system_memory = 1;
+       if (opt) {
+               if (use_system_memory) {
+                       if (!strcmp(opt, "Always")) use_system_memory = 0;
+               } else {
+                       if (!strcmp(opt, "Never")) use_system_memory = 1;
+                       else if (!strcmp(opt, "Auto")) dd->force_video_mem_for_yuv = 1;
+               }
        }
 
        force_reinit = 0;
@@ -190,6 +193,7 @@ GF_Err CreateBackBuffer(GF_VideoOutput *dr, u32 Width, u32 Height, Bool use_syst
        return GF_OK;
 }
 
+
 GF_Err InitDirectDraw(GF_VideoOutput *dr, u32 Width, u32 Height)
 {
        HRESULT hr;
@@ -210,6 +214,7 @@ GF_Err InitDirectDraw(GF_VideoOutput *dr, u32 Width, u32 Height)
        ddraw->lpVtbl->Release(ddraw);
        if (FAILED(hr)) return GF_IO_ERR;
 
+
        dd->switch_res = 0;
        cooplev = DDSCL_NORMAL;
        /*Setup FS*/
@@ -292,6 +297,7 @@ GF_Err InitDirectDraw(GF_VideoOutput *dr, u32 Width, u32 Height)
         return GF_IO_ERR;
     }
        pcClipper->lpVtbl->Release(pcClipper);
+
        dd->ddraw_init = 1;
        /*if YUV not initialize, init using HW video memory to setup HW caps*/
        return CreateBackBuffer(dr, Width, Height, dd->yuv_init);
@@ -393,6 +399,9 @@ static GF_Err DD_BlitSurface(DDContext *dd, DDSurface *src, GF_Window *src_wnd,
                if (key) flags |= DDBLT_KEYSRC;
                hr = dd->pBack->lpVtbl->Blt(dd->pBack, dst_wnd ? &r_dst : NULL, src->pSurface, src_wnd ? &r_src : NULL, flags, NULL);
        }
+
+       if (src->is_yuv && dd->force_video_mem_for_yuv && dd->systems_memory) return GF_IO_ERR;
+
        GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Hardware blit src w=%d,h=%d to dst w=%d,h=%d - result: %08x\n", src_w, src_h, dst_w, dst_h, hr));
        return FAILED(hr) ? GF_IO_ERR : GF_OK;
 }
@@ -422,6 +431,7 @@ static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 p
 
                        SAFE_DD_RELEASE(yuvp->pSurface);
                        memset(yuvp, 0, sizeof(DDSurface));
+                       yuvp->is_yuv = 1;
 
                        memset (&ddsd, 0, sizeof(ddsd));
                        ddsd.dwSize = sizeof(ddsd);
@@ -688,6 +698,7 @@ void DD_InitYUV(GF_VideoOutput *dr)
                        if (dd->yuv_pool.pSurface) {
                                SAFE_DD_RELEASE(dd->yuv_pool.pSurface);
                                memset(&dd->yuv_pool, 0, sizeof(DDSurface));
+                               dd->yuv_pool.is_yuv = 1;
                        }
 
                        dr->yuv_pixel_format = formats[i];
@@ -734,6 +745,7 @@ rem_fmt:
                if (dd->yuv_pool.pSurface) {
                        SAFE_DD_RELEASE(dd->yuv_pool.pSurface);
                        memset(&dd->yuv_pool, 0, sizeof(DDSurface));
+                       dd->yuv_pool.is_yuv = 1;
                }
 
                if (best_planar && (min_planar <= min_packed )) {
index d6ba1be8f4323d498bb28df255db779954b65f55..12bb34af0b13b4d753c0c43b7dae3b8a9089873f 100644 (file)
@@ -91,6 +91,7 @@ typedef struct
 {
     LPDDRAWSURFACE pSurface;
        u32 width, height, format, pitch;
+       Bool is_yuv;
 } DDSurface;
 
 
@@ -181,11 +182,10 @@ typedef struct
        Bool windowless, hidden;
 
        Bool dd_lost;
-
+       Bool force_video_mem_for_yuv;
 
        HMODULE hDDrawLib;
     DIRECTDRAWCREATEPROC DirectDrawCreate;
-
 } DDContext;
 
 void DD_SetupWindow(GF_VideoOutput *dr, Bool hide);
index 1280ba3f301baea39a206a5c48569f3c2c394fee..2ccce39dbd0369f1f53e48e1ecf386c01fe51e03 100644 (file)
@@ -167,6 +167,7 @@ void DestroyObjectsEx(DDContext *dd, Bool only_3d)
                memset(&dd->rgb_pool, 0, sizeof(DDSurface));
                SAFE_DD_RELEASE(dd->yuv_pool.pSurface);
                memset(&dd->yuv_pool, 0, sizeof(DDSurface));
+               dd->yuv_pool.is_yuv = 1;
 
                SAFE_DD_RELEASE(dd->pPrimary);
                SAFE_DD_RELEASE(dd->pBack);
index c2ff738ca496e36fe8ab93e51bf9b7074888ad1b..db7d65ecf4822c0095715e6677aa8113526b02e7 100644 (file)
@@ -1021,9 +1021,9 @@ static u32 FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, GF_ESD *e
 static const char *FFDEC_GetCodecName(GF_BaseDecoder *dec)
 {
        FFDec *ffd;
-        if (!dec)
-          return NULL;
-        ffd = dec->privateStack;
+       if (!dec)
+               return NULL;
+       ffd = dec->privateStack;
        if (ffd && ffd->base_codec) {
                sprintf(ffd->szCodec, "FFMPEG %s", ffd->base_codec->name ? ffd->base_codec->name : "unknown");
                return ffd->szCodec;
@@ -1038,10 +1038,12 @@ void *FFDEC_Load()
        FFDec *priv;
 
        /* Note for valgrind : those two functions cause a leak in valgrind */
-        GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[FFMPEG Decoder] Registering all ffmpeg codecs...\n") );
+       GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[FFMPEG Decoder] Registering all ffmpeg codecs...\n") );
+#ifdef FF_API_AVCODE_INIT /*commit ffmpeg 3211932c513338566b31d990d06957e15a644d13*/
        avcodec_init();
+#endif
        avcodec_register_all();
-        GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG Decoder] Done registering all ffmpeg codecs.\n") );
+       GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG Decoder] Done registering all ffmpeg codecs.\n") );
 
 
        GF_SAFEALLOC(ptr , GF_MediaDecoder);
index 6f0e71fe59bc1ac8c2591f1efb21d0f53f31e39c..9e801f950e420579186510f1a32d2b95ec548001 100644 (file)
@@ -90,7 +90,7 @@ static u32 FFDemux_Run(void *par)
 
                pkt.stream_index = -1;
                /*EOF*/
-        if (av_read_frame(ffd->ctx, &pkt) <0) break;
+               if (av_read_frame(ffd->ctx, &pkt) <0) break;
                if (pkt.pts == AV_NOPTS_VALUE) pkt.pts = pkt.dts;
                if (!pkt.dts) pkt.dts = pkt.pts;
 
@@ -230,8 +230,8 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url)
        Bool ret = 0;
        char *ext, szName[1000], szExt[20];
        const char *szExtList;
-        if (!plug || !url)
-          return 0;
+       if (!plug || !url)
+               return 0;
        /*disable RTP/RTSP from ffmpeg*/
        if (!strnicmp(url, "rtsp://", 7)) return 0;
        if (!strnicmp(url, "rtspu://", 8)) return 0;
@@ -294,19 +294,19 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url)
 
        /*figure out if we can use codecs or not*/
        has_video = has_audio = 0;
-    for(i = 0; i < (s32)ctx->nb_streams; i++) {
-        AVCodecContext *enc = ctx->streams[i]->codec;
-        switch(enc->codec_type) {
-        case AVMEDIA_TYPE_AUDIO:
-            if (!has_audio) has_audio = 1;
-            break;
-        case AVMEDIA_TYPE_VIDEO:
-            if (!has_video) has_video= 1;
-            break;
-        default:
-            break;
-        }
-    }
+       for(i = 0; i < (s32)ctx->nb_streams; i++) {
+               AVCodecContext *enc = ctx->streams[i]->codec;
+               switch(enc->codec_type) {
+               case AVMEDIA_TYPE_AUDIO:
+                       if (!has_audio) has_audio = 1;
+                       break;
+               case AVMEDIA_TYPE_VIDEO:
+                       if (!has_video) has_video= 1;
+                       break;
+               default:
+                       break;
+               }
+       }
        if (!has_audio && !has_video) goto exit;
        ret = 1;
 #if LIBAVFORMAT_VERSION_MAJOR < 53 && LIBAVFORMAT_VERSION_MINOR < 45
@@ -354,9 +354,9 @@ static GF_ESD *FFD_GetESDescriptor(FFDemux *ffd, Bool for_audio)
        /*remap std object types - depending on input formats, FFMPEG may not have separate DSI from initial frame.
        In this case we have no choice but using FFMPEG decoders*/
        if (for_audio) {
-        AVCodecContext *dec = ffd->ctx->streams[ffd->audio_st]->codec;
+       AVCodecContext *dec = ffd->ctx->streams[ffd->audio_st]->codec;
                esd->slConfig->timestampResolution = ffd->audio_tscale.den;
-               switch (dec->codec_id) {
+               switch (dec->codec_id) {
                case CODEC_ID_MP2:
                        esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1;
                        break;
@@ -395,7 +395,7 @@ opaque_audio:
                }
                dont_use_sl = ffd->unreliable_audio_timing;
        } else {
-        AVCodecContext *dec = ffd->ctx->streams[ffd->video_st]->codec;
+               AVCodecContext *dec = ffd->ctx->streams[ffd->video_st]->codec;
                esd->slConfig->timestampResolution = ffd->video_tscale.den;
                switch (dec->codec_id) {
                case CODEC_ID_MPEG4:
@@ -569,7 +569,7 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv,
        GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] opening file %s - local %d - av_in %08x\n", url, is_local, av_in));
 
        if (!is_local) {
-           AVProbeData   pd;
+               AVProbeData   pd;
 
                /*setup wraper for FFMPEG I/O*/
                ffd->buffer_size = 8192;
@@ -579,12 +579,8 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv,
 #ifdef FFMPEG_DUMP_REMOTE
                ffd->outdbg = gf_f64_open("ffdeb.raw", "wb");
 #endif
-/*#ifdef USE_PRE_0_7*/
-               init_put_byte(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL);
-/*#else
-                ffio_init_context(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL);
-#endif*/
 #ifdef USE_PRE_0_7
+               init_put_byte(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL);
                ffd->io.is_streamed = 1;
 #else
                ffd->io.seekable = 1;
@@ -616,7 +612,11 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv,
                        }
                        /*setup downloader*/
                        av_in->flags |= AVFMT_NOFILE;
+#if FF_API_FORMAT_PARAMETERS /*commit ffmpeg 603b8bc2a109978c8499b06d2556f1433306eca7*/
+                       res = avformat_open_input(&ffd->ctx, szName, av_in, NULL);
+#else
                        res = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL);
+#endif
                }
        } else {
                res = open_file(&ffd->ctx, szName, av_in);
@@ -645,25 +645,25 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv,
 
        /*figure out if we can use codecs or not*/
        ffd->audio_st = ffd->video_st = -1;
-    for (i = 0; i < ffd->ctx->nb_streams; i++) {
-        AVCodecContext *enc = ffd->ctx->streams[i]->codec;
-        switch(enc->codec_type) {
-        case AVMEDIA_TYPE_AUDIO:
-            if ((ffd->audio_st<0) && (ffd->service_type!=1)) {
+       for (i = 0; i < ffd->ctx->nb_streams; i++) {
+               AVCodecContext *enc = ffd->ctx->streams[i]->codec;
+               switch(enc->codec_type) {
+               case AVMEDIA_TYPE_AUDIO:
+                       if ((ffd->audio_st<0) && (ffd->service_type!=1)) {
                                ffd->audio_st = i;
                                ffd->audio_tscale = ffd->ctx->streams[i]->time_base;
                        }
-            break;
-        case AVMEDIA_TYPE_VIDEO:
-            if ((ffd->video_st<0) && (ffd->service_type!=2)) {
+                       break;
+               case AVMEDIA_TYPE_VIDEO:
+                       if ((ffd->video_st<0) && (ffd->service_type!=2)) {
                                ffd->video_st = i;
                                ffd->video_tscale = ffd->ctx->streams[i]->time_base;
                        }
-            break;
-        default:
-            break;
-        }
-    }
+                       break;
+               default:
+                       break;
+               }
+       }
        if ((ffd->service_type==1) && (ffd->video_st<0)) goto err_exit;
        if ((ffd->service_type==2) && (ffd->audio_st<0)) goto err_exit;
        if ((ffd->video_st<0) && (ffd->audio_st<0)) {
@@ -911,12 +911,12 @@ static Bool FFD_CanHandleURLInService(GF_InputService *plug, const char *url)
        char szURL[2048], *sep;
        FFDemux *ffd;
        const char *this_url;
-        if (!plug || !url)
-          return 0;
-        ffd = (FFDemux *)plug->priv;
-        this_url = gf_term_get_service_url(ffd->service);
+       if (!plug || !url)
+               return 0;
+       ffd = (FFDemux *)plug->priv;
+       this_url = gf_term_get_service_url(ffd->service);
        if (!this_url)
-          return 0;
+               return 0;
 
        strcpy(szURL, this_url);
        sep = strrchr(szURL, '#');
@@ -965,19 +965,19 @@ void Delete_FFMPEG_Demux(void *ifce)
 {
        FFDemux *ffd;
        GF_InputService *ptr = (GF_InputService *)ifce;
-        if (!ptr)
-          return;
+       if (!ptr)
+               return;
        ffd = ptr->priv;
-        if (ffd){
-          if (ffd->thread)
-            gf_th_del(ffd->thread);
-          ffd->thread = NULL;
-          if (ffd->mx)
-            gf_mx_del(ffd->mx);
-          ffd->mx = NULL;
-          gf_free(ffd);
-          ptr->priv = NULL;
-        }
+       if (ffd) {
+               if (ffd->thread)
+                       gf_th_del(ffd->thread);
+               ffd->thread = NULL;
+               if (ffd->mx)
+                       gf_mx_del(ffd->mx);
+               ffd->mx = NULL;
+               gf_free(ffd);
+               ptr->priv = NULL;
+       }
        gf_free(ptr);
 }
 
index bf4b9cf686f27d8811a9f3cffd9b5af24bdad572..d7dcdd35de471aae5ef9b7add34f9fd534f28d79 100644 (file)
 #include <gpac/constants.h>
 #include <gpac/download.h>
 
+#ifdef FREENECT_FLAT_HEADERS
+#include <libfreenect.h>
+#else
 #include <libfreenect/libfreenect.h>
+#endif
 
 #include <gpac/thread.h>
 
+
+#ifndef FREENECT_RESOLUTION_MEDIUM
+#define FREENECT_MINIMAL
+#endif
+
+
 typedef struct
 {
        /*the service we're responsible for*/
@@ -240,9 +250,10 @@ GF_Err Freenect_ConnectService(GF_InputService *plug, GF_ClientService *serv, co
 
        if (!vcap->f_ctx) {
                int i;
-               Bool use_depth = 1;
+#ifndef FREENECT_MINIMAL
                freenect_frame_mode frame_mode;
                freenect_resolution frame_format = FREENECT_RESOLUTION_MEDIUM;
+#endif
                char *name, *params;
                int res = freenect_init(&vcap->f_ctx, NULL);
                if (res < 0) {
@@ -251,8 +262,9 @@ GF_Err Freenect_ConnectService(GF_InputService *plug, GF_ClientService *serv, co
                }
                freenect_set_log_level(vcap->f_ctx, FREENECT_LOG_DEBUG);
                freenect_set_log_callback(vcap->f_ctx, Freenect_Logs);
+#ifndef FREENECT_MINIMAL
                freenect_select_subdevices(vcap->f_ctx, FREENECT_DEVICE_CAMERA);
-
+#endif
                res = freenect_num_devices (vcap->f_ctx);
                GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[Freenect] %d devices found\n", res));
                if (res<1) {
@@ -273,7 +285,6 @@ GF_Err Freenect_ConnectService(GF_InputService *plug, GF_ClientService *serv, co
                if (name) name += 3;
 
                if (!stricmp(name, "color")) {
-                       use_depth = 0;
                }
 
                if (params) {
@@ -287,12 +298,14 @@ GF_Err Freenect_ConnectService(GF_InputService *plug, GF_ClientService *serv, co
                        GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[VideoCapture] Set camera option %s\n", params));
 
                        if (!strnicmp(params, "resolution=", 11)) {
+#ifndef FREENECT_MINIMAL
                                u32 w, h;
                                if (sscanf(params+11, "%dx%d", &w, &h)==2) {
                                        if ((w<=320) || (h<=240)) frame_format = FREENECT_RESOLUTION_LOW;
                                        else if ((w<=640) || (h<=480)) frame_format = FREENECT_RESOLUTION_MEDIUM;
                                        else frame_format = FREENECT_RESOLUTION_HIGH;
                                }
+#endif
                        }
                        else if (!strnicmp(params, "format=", 7)) {
                                if (!stricmp(params+7, "standard")) vcap->depth_format = 0;
@@ -312,13 +325,20 @@ GF_Err Freenect_ConnectService(GF_InputService *plug, GF_ClientService *serv, co
                        params = sep+1;
                }
 
+#ifndef FREENECT_MINIMAL
                frame_mode = freenect_find_video_mode(frame_format, FREENECT_VIDEO_RGB);
                res = freenect_set_video_mode(vcap->f_dev, frame_mode);
                res = freenect_set_depth_mode(vcap->f_dev, freenect_find_depth_mode(frame_format, FREENECT_DEPTH_11BIT));
-
                vcap->width = frame_mode.width;
                vcap->height = frame_mode.height;
                vcap->fps = frame_mode.framerate;
+#else
+               freenect_set_video_format(vcap->f_dev, FREENECT_VIDEO_RGB);
+               res = freenect_set_depth_format(vcap->f_dev, FREENECT_DEPTH_11BIT);
+               vcap->width = FREENECT_FRAME_W;
+               vcap->height = FREENECT_FRAME_H;
+               vcap->fps = 30;
+#endif
                /*currently hardcoded*/
                vcap->color_pixel_format = GF_PIXEL_RGB_24;
                vcap->color_stride = 3*vcap->width;
@@ -353,7 +373,7 @@ GF_Err Freenect_ConnectService(GF_InputService *plug, GF_ClientService *serv, co
 
                res = freenect_set_video_buffer(vcap->f_dev, vcap->vid_buf);
 
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[Freenect] Device configured - resolution %dx%d - Frame Rate %d - Depth Pixel Format %s\n", vcap->width, vcap->height, vcap->fps, gf_4cc_to_str(vcap->depth_pixel_format) ));
+               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[Freenect] Device configured - resolution %dx%d - Frame Rate %d - Depth Pixel Format %s\n", vcap->width, vcap->height, vcap->fps, gf_4cc_to_str(vcap->depth_pixel_format) ));
 
 
                for (i=0; i<2048; i++) {
index 05910974f75bb6643f1ff4459753008a1c05d375..10937c15a630737a4f6ae8edec9050a9eeb19c79 100644 (file)
@@ -674,7 +674,9 @@ static JSBool gpacevt_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER,
                        *vp = INT_TO_JSVAL(evt->type);
                        break;
                case 1:
+#ifndef GPAC_DISABLE_SVG
                        *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, gf_dom_get_key_name(evt->key.key_code) )); 
+#endif
                        break;
                case 2:
                        *vp = INT_TO_JSVAL(evt->mouse.x); 
@@ -760,7 +762,7 @@ static JSBool SMJS_FUNCTION(gpac_set_event_filter)
        SMJS_ARGS
        GF_GPACJSExt *gjs = (GF_GPACJSExt *)JS_GetPrivate(c, obj);
        if (!argc || !JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;
-       if (gjs->evt_fun) return JS_TRUE;
+       if (JSVAL_IS_NULL(gjs->evt_fun) ) return JS_TRUE;
 
        gjs->evt_fun = argv[0];
        gjs->evt_filter_obj = obj;
@@ -814,13 +816,17 @@ static JSBool SMJS_FUNCTION(gpac_get_scene)
        if (!elt) return JS_TRUE;
        switch (elt->sgprivate->tag) {
        case TAG_MPEG4_Inline:
+#ifndef GPAC_DISABLE_X3D
        case TAG_X3D_Inline:
+#endif
                scene = (GF_Scene *)gf_node_get_private(elt);
                break;
+#ifndef GPAC_DISABLE_SVG
        case TAG_SVG_animation:
                sg = gf_sc_animation_get_scenegraph(elt);
                scene = (GF_Scene *)gf_sg_get_private(sg);
                break;
+#endif
        default:
                return JS_TRUE;
        }
index 8328e3c923c27a599c3d2cee9b4d3d6221f4b4a2..3011102810fdf5b5c305d5980003b6f528a82acd 100644 (file)
@@ -201,6 +201,7 @@ void isor_reader_get_sample(ISOMChannel *ch)
                                        gf_isom_sample_del(&ch->sample);
 
                                        if (s2 && s1) {
+                                               assert(s2->DTS >= s1->DTS);
                                                time_diff = (u32) (s2->DTS - s1->DTS);
                                                e = gf_isom_get_sample_for_movie_time(ch->owner->mov, ch->track, ch->sample_time + time_diff, &ivar, GF_ISOM_SEARCH_FORWARD, &ch->sample, &ch->sample_num);
                                        } else if (s1 && !s2) {
index c7734f1882fbe760454e10a4232199d6547d11c7..48d4751b0c3d4f04c4b35464de5562201f624363 100644 (file)
@@ -152,16 +152,17 @@ typedef struct __mpd_module {
     /* 0 not started, 1 download in progress */
     MPD_STATE mpd_is_running;
     Bool mpd_stop_request;
-
+       Bool in_period_setup;
 
     /* TODO - handle playback status for SPEED/SEEK through SIDX */
     Double playback_speed, playback_start_range, previous_start_range;
+       Double start_range_in_segment_at_next_period;
        Bool in_seek;
 } GF_MPD_In;
 
 void MPD_ResetGroups(GF_MPD_In *mpdin);
 GF_Err MPD_SetupPeriod(GF_MPD_In *mpdin);
-void MPD_SeekGroupsDownloads(GF_MPD_In *mpdin);
+
 
 
 static const char *MPD_GetMimeType(GF_MPD_SubRepresentation *subrep, GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set)
@@ -551,6 +552,7 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
                return GF_OK;
        }
        if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) {
+               Bool discard_first_cache_entry = 1;
         u32 timer = gf_sys_clock();
         GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Query Next request from terminal\n"));
         gf_mx_p(mpdin->dl_mutex);
@@ -560,6 +562,7 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
                if (mpdin->in_seek) {
                        mpdin->in_seek = 0;
                        param->url_query.discontinuity_type = 2;
+                       discard_first_cache_entry = 0;
                }
 
                for (i=0; i<gf_list_count(mpdin->groups); i++) {
@@ -578,7 +581,7 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
         while (mpdin->mpd_is_running && group->nb_cached_segments<2) {
             gf_mx_v(mpdin->dl_mutex);
                        if (group->done) {
-                               if (!mpdin->request_period_switch && (mpdin->active_period_index<gf_list_count(mpdin->mpd->periods))) {
+                               if (!mpdin->request_period_switch && (mpdin->active_period_index+1 < gf_list_count(mpdin->mpd->periods))) {
                                        GF_NetworkCommand com;
                                        memset(&com, 0, sizeof(GF_NetworkCommand));
                                        com.command_type = GF_NET_BUFFER_QUERY;
@@ -590,7 +593,7 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
                                                }
                                                gf_sleep(20);
                                        }
-                               }
+                               } 
                                return GF_EOS;
                        }
             gf_sleep(16);
@@ -603,25 +606,29 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param)
         } else {
             GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer)));
         }
-        if (group->cached[0].cache) {
-            if (group->urlToDeleteNext) {
-                               if (!group->local_files && !mpdin->keep_files)
-                                       gf_dm_delete_cached_file_entry_session(group->segment_dnload, group->urlToDeleteNext);
 
-                               gf_free( group->urlToDeleteNext);
-                group->urlToDeleteNext = NULL;
-            }
-            assert( group->cached[0].url );
-            GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] deleting cache file %s : %s\n", group->cached[0].url, group->cached[0].cache));
-            group->urlToDeleteNext = gf_strdup( group->cached[0].url );
-            gf_free(group->cached[0].cache);
-            gf_free(group->cached[0].url);
-            group->cached[0].url = NULL;
-            group->cached[0].cache = NULL;
-        }
-        memmove(&group->cached[0], &group->cached[1], sizeof(segment_cache_entry)*(group->nb_cached_segments-1));
-        memset(&(group->cached[group->nb_cached_segments-1]), 0, sizeof(segment_cache_entry));
-        group->nb_cached_segments--;
+               if (discard_first_cache_entry) {
+                       if (group->cached[0].cache) {
+                               if (group->urlToDeleteNext) {
+                                       if (!group->local_files && !mpdin->keep_files)
+                                               gf_dm_delete_cached_file_entry_session(group->segment_dnload, group->urlToDeleteNext);
+
+                                       gf_free( group->urlToDeleteNext);
+                                       group->urlToDeleteNext = NULL;
+                               }
+                               assert( group->cached[0].url );
+                               GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] deleting cache file %s : %s\n", group->cached[0].url, group->cached[0].cache));
+                               group->urlToDeleteNext = gf_strdup( group->cached[0].url );
+                               gf_free(group->cached[0].cache);
+                               gf_free(group->cached[0].url);
+                               group->cached[0].url = NULL;
+                               group->cached[0].cache = NULL;
+                       }
+                       memmove(&group->cached[0], &group->cached[1], sizeof(segment_cache_entry)*(group->nb_cached_segments-1));
+                       memset(&(group->cached[group->nb_cached_segments-1]), 0, sizeof(segment_cache_entry));
+                       group->nb_cached_segments--;
+               }
+
         param->url_query.next_url = group->cached[0].cache;
                param->url_query.start_range = group->cached[0].start_range;
                param->url_query.end_range = group->cached[0].end_range;
@@ -755,47 +762,14 @@ GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession **s
     }
 }
 
-static void MPD_SetGroupRepresentation(GF_MPD_Group *group, GF_MPD_Representation *rep)
+static void MPD_GetSegmentDuration(GF_MPD_Representation *rep, GF_MPD_AdaptationSet *set, GF_MPD_Period *period, GF_MPD *mpd, u32 *nb_segments, Double *seg_duration)
 {
-       u64 duration = 0;
-       u64 mediaDuration = 0;
-#ifndef GPAC_DISABLE_LOG
-       u32 width=0, height=0, samplerate=0;
-       GF_MPD_Fractional *framerate=NULL;
-#endif
-       u32 timescale = 1;
-       GF_MPD_AdaptationSet *set;
-       GF_MPD_Period *period;
-       u32 i = gf_list_find(group->adaptation_set->representations, rep);
-       assert((s32) i >= 0);
-
-       group->active_rep_index = i;
-       group->active_bitrate = rep->bandwidth;
-       group->nb_segments_in_rep = 1;
-
-       set = group->adaptation_set;
-       period = group->period;
-
-#ifndef GPAC_DISABLE_LOG
-
-#define GET_REP_ATTR(_a)       _a = rep->_a; if (!_a) _a = set->_a;
-
-       GET_REP_ATTR(width);
-       GET_REP_ATTR(height);
-       GET_REP_ATTR(samplerate);
-       GET_REP_ATTR(framerate);
-
-       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPDIn] Switched to representation bandwidth %d kbps\n", rep->bandwidth/1024));
-       if (group->max_bitrate) GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tmax download bandwidth: %d kbps\n", group->max_bitrate/1024));
-       if (width&&height) {
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tWidth %d Height %d", width, height));
-               if (framerate) GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("framerate %d/%d", framerate->num, framerate->den));
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\n"));
-       } else if (samplerate) {
-               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tsamplerate %d\n", samplerate));
-       }
-#endif
-
+       Double mediaDuration;
+       u32 timescale;
+       u64 duration;
+       *nb_segments = timescale = 0;
+       duration = 0;
+       
        /*single segment*/
        if (rep->segment_base || set->segment_base || period->segment_base) {
                return;
@@ -818,11 +792,11 @@ static void MPD_SetGroupRepresentation(GF_MPD_Group *group, GF_MPD_Representatio
                        if (rep->segment_list->segment_URLs) segments = rep->segment_list->segment_URLs;
                }
                if (segments) 
-                       group->nb_segments_in_rep = gf_list_count(segments);
+                       *nb_segments = gf_list_count(segments);
 
-               if (!timescale) timescale=1;
-               group->segment_duration = (Double) duration;
-               group->segment_duration /= timescale;
+               if (! timescale) timescale=1;
+               *seg_duration = (Double) duration;
+               *seg_duration /= timescale;
                return;
        }
 
@@ -839,22 +813,66 @@ static void MPD_SetGroupRepresentation(GF_MPD_Group *group, GF_MPD_Representatio
                if (rep->segment_template->timescale) timescale = rep->segment_template->timescale;
        }
        if (!timescale) timescale=1;
-       group->segment_duration = (Double) duration;
-       group->segment_duration /= timescale;
+       *seg_duration = (Double) duration;
+       *seg_duration /= timescale;
        mediaDuration = period->duration;
-       if (!mediaDuration) mediaDuration = group->mpd_in->mpd->media_presentation_duration;
+       if (!mediaDuration) mediaDuration = mpd->media_presentation_duration;
        if (mediaDuration && duration) {
                Double nb_seg = (Double) mediaDuration;
                /*duration is given in ms*/
                nb_seg /= 1000;
                nb_seg *= timescale;
                nb_seg /= duration;
-               group->nb_segments_in_rep = (u32) ceil(nb_seg);
-       } else {
-               group->nb_segments_in_rep = 0;
+               *nb_segments = (u32) ceil(nb_seg);
        }
 }
 
+
+static void MPD_SetGroupRepresentation(GF_MPD_Group *group, GF_MPD_Representation *rep)
+{
+       u64 duration = 0;
+       u64 mediaDuration = 0;
+#ifndef GPAC_DISABLE_LOG
+       u32 width=0, height=0, samplerate=0;
+       GF_MPD_Fractional *framerate=NULL;
+#endif
+       u32 timescale = 1;
+       GF_MPD_AdaptationSet *set;
+       GF_MPD_Period *period;
+       u32 i = gf_list_find(group->adaptation_set->representations, rep);
+       assert((s32) i >= 0);
+
+       group->active_rep_index = i;
+       group->active_bitrate = rep->bandwidth;
+       group->nb_segments_in_rep = 1;
+
+       set = group->adaptation_set;
+       period = group->period;
+
+#ifndef GPAC_DISABLE_LOG
+
+#define GET_REP_ATTR(_a)       _a = rep->_a; if (!_a) _a = set->_a;
+
+       GET_REP_ATTR(width);
+       GET_REP_ATTR(height);
+       GET_REP_ATTR(samplerate);
+       GET_REP_ATTR(framerate);
+
+       GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPDIn] Switched to representation bandwidth %d kbps\n", rep->bandwidth/1024));
+       if (group->max_bitrate) GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tmax download bandwidth: %d kbps\n", group->max_bitrate/1024));
+       if (width&&height) {
+               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tWidth %d Height %d", width, height));
+               if (framerate) GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("framerate %d/%d", framerate->num, framerate->den));
+               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\n"));
+       } else if (samplerate) {
+               GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("\tsamplerate %d\n", samplerate));
+       }
+#endif
+
+
+       MPD_GetSegmentDuration(rep, set, period, group->mpd_in->mpd, &group->nb_segments_in_rep, &group->segment_duration);
+}
+
 static void MPD_SwitchGroupRepresentation(GF_MPD_In *mpd, GF_MPD_Group *group)
 {
        u32 i, bandwidth, min_bandwidth;
@@ -1440,6 +1458,7 @@ static u32 download_segments(void *par)
     gf_mx_v(mpdin->dl_mutex);
 
 restart_period:
+       mpdin->in_period_setup = 1;
        e = GF_OK;
     period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index);
        group_count = gf_list_count(mpdin->groups);
@@ -1482,6 +1501,7 @@ restart_period:
        }
 
     gf_mx_p(mpdin->dl_mutex);
+       mpdin->in_period_setup = 0;
     mpdin->mpd_is_running = MPD_STATE_RUNNING;
     gf_mx_v(mpdin->dl_mutex);
 
@@ -1807,15 +1827,16 @@ static void MPD_DownloadStop(GF_MPD_In *mpdin)
 {
        u32 i;
     assert( mpdin );
-    if (mpdin->groups){
-       for (i=0; i<gf_list_count(mpdin->groups); i++) {
-               GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
-               assert( group );
-               if (group->selected && group->segment_dnload) {
-                       gf_dm_sess_abort(group->segment_dnload);
-                       group->done = 1;
+    if (mpdin->groups) {
+               for (i=0; i<gf_list_count(mpdin->groups); i++) {
+                       GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
+                       assert( group );
+                       if (! group->service_connected ) return;
+                       if (group->selected && group->segment_dnload) {
+                               gf_dm_sess_abort(group->segment_dnload);
+                               group->done = 1;
+                       }
                }
-       }
     }
     /* stop the download thread */
     gf_mx_p(mpdin->dl_mutex);
@@ -1844,6 +1865,8 @@ Bool MPD_SeekPeriods(GF_MPD_In *mpdin)
        u32 i, period_idx;
 
        gf_mx_p(mpdin->dl_mutex);
+       
+       mpdin->start_range_in_segment_at_next_period = 0;
        start_time = 0;
        period_idx = 0;
        for (i=0; i<=gf_list_count(mpdin->mpd->periods); i++) {
@@ -1862,6 +1885,23 @@ Bool MPD_SeekPeriods(GF_MPD_In *mpdin)
                mpdin->playback_start_range -= start_time;
                mpdin->active_period_index = period_idx;
                mpdin->request_period_switch = 2;
+
+               /*figure out default segment duration and substract from our start range request*/
+               if (mpdin->playback_start_range) {
+                       Double duration;
+                       u32 nb_segs;
+                       GF_MPD_Period *period = gf_list_get(mpdin->mpd->periods, period_idx);
+                       GF_MPD_AdaptationSet *set = gf_list_get(period->adaptation_sets, 0);
+                       GF_MPD_Representation *rep = gf_list_get(set->representations, 0);
+
+                       MPD_GetSegmentDuration(rep, set, period, mpdin->mpd, &nb_segs, &duration);
+
+                       if (duration) {
+                               while (mpdin->playback_start_range - mpdin->start_range_in_segment_at_next_period >= duration)
+                                       mpdin->start_range_in_segment_at_next_period += duration;
+                       }
+
+               }
        }
        gf_mx_v(mpdin->dl_mutex);
        
@@ -1874,6 +1914,7 @@ void MPD_SeekGroup(GF_MPD_In *mpdin, GF_MPD_Group *group)
        u32 first_downloaded, last_downloaded, segment_idx;
 
        group->force_segment_switch = 0;
+       if (!group->segment_duration) return;
 
        /*figure out where to seek*/
        segment_idx = 0;
@@ -1927,6 +1968,16 @@ void MPD_SeekGroupsDownloads(GF_MPD_In *mpdin)
        u32 i;
 
        gf_mx_p(mpdin->dl_mutex);
+
+       if (mpdin->active_period_index) {
+               Double dur = 0;
+               u32 i;
+               for (i=0; i<mpdin->active_period_index; i++) {
+                       GF_MPD_Period *period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index-1);
+                       dur += period->duration/1000.0;
+               }
+               mpdin->playback_start_range -= dur;
+       }
        for (i=0; i<gf_list_count(mpdin->groups); i++) {
                GF_MPD_Group *group = gf_list_get(mpdin->groups, i);
                MPD_SeekGroup(mpdin, group);
@@ -2486,7 +2537,7 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
     case GF_NET_CHAN_PLAY:
         GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Play command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service));
 
-               if (!com->play.dash_segment_switch && ! mpdin->in_seek) {
+               if (! mpdin->in_period_setup && !com->play.dash_segment_switch && ! mpdin->in_seek) {
                        Bool skip_seek;
                        
                        mpdin->in_seek = 1;
@@ -2511,6 +2562,10 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com)
                else if (mpdin->in_seek && (com->play.start_range==0)) {
 //                     mpdin->in_seek = 0;
                }
+               else if (mpdin->in_period_setup && (com->play.start_range==0)) {
+                       com->play.start_range = mpdin->playback_start_range;
+               }
+
                group->done = 0;
                com->play.dash_segment_switch = group->force_segment_switch;
                /*don't forward commands, we are killing the service anyway ...*/
index 74913f8920e76f3a069d85e4f61a6fcbe3c1be28..f4c6f6c0054a27408f1a6eb4b75fe7871f56fa11 100644 (file)
@@ -256,7 +256,7 @@ GF_TermExt *osd_new()
        GF_OSD *osd;\r
        dr = (GF_TermExt*)gf_malloc(sizeof(GF_TermExt));\r
        memset(dr, 0, sizeof(GF_TermExt));\r
-       GF_REGISTER_MODULE_INTERFACE(dr, GF_TERM_EXT_INTERFACE, "GPAC OnSscreen Display", "gpac distribution");\r
+       GF_REGISTER_MODULE_INTERFACE(dr, GF_TERM_EXT_INTERFACE, "GPAC OnScreen Display", "gpac distribution");\r
 \r
        GF_SAFEALLOC(osd, GF_OSD);\r
        dr->process = osd_process;\r
index 1582048a9ebd903f6e12b9fcec91fa59156d515e..2deafcd663e2d35a5c1c79f76a40bbe9648f9268 100644 (file)
@@ -15,7 +15,7 @@ CFLAGS+=-pg
 LDFLAGS+=-pg
 endif
 
-ifeq ($(OSS_INC_TYPE), SYS)
+ifeq ($(OSS_INC_TYPE), yes)
 else
 CFLAGS+=-DOSS_FIX_INC
 endif
index b6bc3d42298a00985b42a96c0e63ffb88bb607aa..5c8a44b925a87efe4be67988b564843cb41ae60b 100644 (file)
@@ -14,7 +14,7 @@ CFLAGS+=-pg
 LDFLAGS+=-pg
 endif
 
-LINKLIBS= -lgpac -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib
+LINKLIBS= -lgpac -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib -lpthread
 LOCAL_LIB=../../bin/gcc -L../../extra_lib/lib/gcc
 
 #common objects
diff --git a/modules/widgetman/Makefile b/modules/widgetman/Makefile
new file mode 100644 (file)
index 0000000..edb93f8
--- /dev/null
@@ -0,0 +1,75 @@
+include ../../config.mak
+
+vpath %.c $(SRC_PATH)/modules/widgetman
+
+CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include"
+
+ifeq ($(DEBUGBUILD), yes)
+CFLAGS+=-g
+LDFLAGS+=-g
+endif
+
+ifeq ($(GPROFBUILD), yes)
+CFLAGS+=-pg
+LDFLAGS+=-pg
+endif
+
+LINKLIBS= -lgpac -lz
+LOCAL_LIB=-L../../bin/gcc
+
+#common objects
+OBJS=widgetman.o unzip.o widget.o wgt_load.o
+
+ifeq ($(CONFIG_ZLIB), local)
+CFLAGS+=-I"$(LOCAL_INC_PATH)/zlib"
+LOCAL_LIB+= -L../../extra_lib/lib/gcc
+endif
+
+ifeq ($(CONFIG_JS),no)
+else
+CFLAGS+=$(JS_FLAGS)
+ifeq ($(CONFIG_JS),local)
+NEED_LOCAL_LIB="yes"
+LOCAL_LIB+= -L../../extra_lib/lib/gcc
+endif
+LINKLIBS+= $(JS_LIBS)
+endif
+
+SRCS := $(OBJS:.o=.c) 
+
+LIB=gm_widgetman.$(DYN_LIB_SUFFIX)
+ifeq ($(CONFIG_WIN32),yes)
+#LDFLAGS+=-export-symbols widgetman.def 
+endif
+
+
+all: $(LIB)
+
+
+$(LIB): $(OBJS)
+       $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) $(LOCAL_LIB) $(LINKLIBS)
+
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c -o $@ $< 
+
+
+clean: 
+       rm -f $(OBJS) ../../bin/gcc/$(LIB)
+
+dep: depend
+
+depend:
+       rm -f .depend   
+       $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend
+
+distclean: clean
+       rm -f Makefile.bak .depend
+
+
+
+# include dependency files if they exist
+#
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff --git a/modules/widgetman/unzip.c b/modules/widgetman/unzip.c
new file mode 100644 (file)
index 0000000..df1430c
--- /dev/null
@@ -0,0 +1,1372 @@
+/*
+   miniunz.c
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef _WIN32_WCE
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <utime.h>
+# include <sys/stat.h>
+#endif
+
+#endif
+
+#include "unzip.h"
+#include <gpac/tools.h>
+
+
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+voidpf ZCALLBACK fopen_file_func OF((
+   voidpf opaque,
+   const char* filename,
+   int mode));
+
+uLong ZCALLBACK fread_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   void* buf,
+   uLong size));
+
+uLong ZCALLBACK fwrite_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   const void* buf,
+   uLong size));
+
+long ZCALLBACK ftell_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+long ZCALLBACK fseek_file_func OF((
+   voidpf opaque,
+   voidpf stream,
+   uLong offset,
+   int origin));
+
+int ZCALLBACK fclose_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+int ZCALLBACK ferror_file_func OF((
+   voidpf opaque,
+   voidpf stream));
+
+
+voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
+   voidpf opaque;
+   const char* filename;
+   int mode;
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen(filename, mode_fopen);
+    return file;
+}
+
+
+uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
+   voidpf opaque;
+   voidpf stream;
+   void* buf;
+   uLong size;
+{
+    uLong ret;
+    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+
+uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
+   voidpf opaque;
+   voidpf stream;
+   const void* buf;
+   uLong size;
+{
+    uLong ret;
+    ret = (uLong)gf_fwrite(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+long ZCALLBACK ftell_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    long ret;
+    ret = ftell((FILE *)stream);
+    return ret;
+}
+
+long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
+   voidpf opaque;
+   voidpf stream;
+   uLong offset;
+   int origin;
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+    fseek((FILE *)stream, offset, fseek_origin);
+    return ret;
+}
+
+int ZCALLBACK fclose_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    int ret;
+    ret = fclose((FILE *)stream);
+    return ret;
+}
+
+int ZCALLBACK ferror_file_func (opaque, stream)
+   voidpf opaque;
+   voidpf stream;
+{
+    int ret;
+    ret = ferror((FILE *)stream);
+    return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+  zlib_filefunc_def* pzlib_filefunc_def;
+{
+    pzlib_filefunc_def->zopen_file = fopen_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell_file = ftell_file_func;
+    pzlib_filefunc_def->zseek_file = fseek_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+static int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    int *pi;
+{
+    unsigned char c;
+    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        if (ZERROR(*pzlib_filefunc_def,filestream))
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
+static int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong *pX;
+{
+    uLong x ;
+    int err;
+    int i = 0;
+
+    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+static int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+    uLong *pX;
+{
+    uLong x ;
+    int err;
+    int i = 0;
+
+    err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+static uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
+    const zlib_filefunc_def* pzlib_filefunc_def;
+    voidpf filestream;
+{
+    unsigned char* buf;
+    uLong uSizeFile;
+    uLong uBackRead;
+    uLong uMaxBack=0xffff; /* maximum size of global comment */
+    uLong uPosFound=0;
+
+    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize,uReadPos ;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
+        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    return uPosFound;
+}
+
+
+/*
+   Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
+    uLong ulDosDate;
+    tm_unz* ptm;
+{
+    uLong uDate;
+    uDate = (uLong)(ulDosDate>>16);
+    ptm->tm_mday = (uInt)(uDate&0x1f) ;
+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+static int unzlocal_GetCurrentFileInfoInternal (file,
+                                              pfile_info,
+                                              pfile_info_internal,
+                                              szFileName, fileNameBufferSize,
+                                              extraField, extraFieldBufferSize,
+                                              szComment,  commentBufferSize)
+    unzFile file;
+    unz_file_info *pfile_info;
+    unz_file_info_internal *pfile_info_internal;
+    char *szFileName;
+    uLong fileNameBufferSize;
+    void *extraField;
+    uLong extraFieldBufferSize;
+    char *szComment;
+    uLong commentBufferSize;
+{
+    unz_s* s;
+    unz_file_info file_info;
+    unz_file_info_internal file_info_internal;
+    int err=UNZ_OK;
+    uLong uMagic;
+    long lSeek=0;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (ZSEEK(s->z_filefunc, s->filestream,
+              s->pos_in_central_dir+s->byte_before_the_zipfile,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+
+    /* we check the magic */
+    if (err==UNZ_OK){
+        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+            err=UNZ_ERRNO;
+        else if (uMagic!=0x02014b50)
+            err=UNZ_BADZIPFILE;
+    }
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    lSeek+=file_info.size_filename;
+    if ((err==UNZ_OK) && (szFileName!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_filename<fileNameBufferSize)
+        {
+            *(szFileName+file_info.size_filename)='\0';
+            uSizeRead = file_info.size_filename;
+        }
+        else
+            uSizeRead = fileNameBufferSize;
+
+        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+            if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek -= uSizeRead;
+    }
+
+
+    if ((err==UNZ_OK) && (extraField!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_file_extra<extraFieldBufferSize)
+            uSizeRead = file_info.size_file_extra;
+        else
+            uSizeRead = extraFieldBufferSize;
+
+        if (lSeek!=0){
+            if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+       }
+        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+            if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek += file_info.size_file_extra - uSizeRead;
+    }
+    else
+        lSeek+=file_info.size_file_extra;
+
+
+    if ((err==UNZ_OK) && (szComment!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_file_comment<commentBufferSize)
+        {
+            *(szComment+file_info.size_file_comment)='\0';
+            uSizeRead = file_info.size_file_comment;
+        }
+        else
+            uSizeRead = commentBufferSize;
+
+        if (lSeek!=0){
+            if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+       }
+        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+            if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek+=file_info.size_file_comment - uSizeRead;
+    }
+    else
+        lSeek+=file_info.size_file_comment;
+
+    if ((err==UNZ_OK) && (pfile_info!=NULL))
+        *pfile_info=file_info;
+
+    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+        *pfile_info_internal=file_info_internal;
+
+    return err;
+}
+
+int unzGetCurrentFileInfo(unzFile file,
+                         unz_file_info *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize)
+{
+       return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize);
+}
+
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+int unzGoToNextFile (file)
+    unzFile file;
+{
+    unz_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
+      if (s->num_file+1==s->gi.number_entry)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+    s->num_file++;
+    err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+int unzGoToFirstFile (file)
+    unzFile file;
+{
+    int err=UNZ_OK;
+    unz_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    s->pos_in_central_dir=s->offset_central_dir;
+    s->num_file=0;
+    err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                             &s->cur_file_info_internal,
+                                             NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+int unzGetGlobalInfo (file,pglobal_info)
+    unzFile file;
+    unz_global_info *pglobal_info;
+{
+    unz_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    *pglobal_info=s->gi;
+    return UNZ_OK;
+}
+
+/*
+  Close the file in zip opened with unzipOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+int unzCloseCurrentFile (file)
+    unzFile file;
+{
+    int err=UNZ_OK;
+
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+        (!pfile_in_zip_read_info->raw))
+    {
+        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+            err=UNZ_CRCERROR;
+    }
+
+
+    TRYFREE(pfile_in_zip_read_info->read_buffer);
+    pfile_in_zip_read_info->read_buffer = NULL;
+    if (pfile_in_zip_read_info->stream_initialised)
+        inflateEnd(&pfile_in_zip_read_info->stream);
+
+    pfile_in_zip_read_info->stream_initialised = 0;
+    TRYFREE(pfile_in_zip_read_info);
+
+    s->pfile_in_zip_read=NULL;
+
+    return err;
+}
+
+
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+     "zlib/zlib114.zip".
+     If the zipfile cannot be opened (file doesn't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+*/
+extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
+    const char *path;
+    zlib_filefunc_def* pzlib_filefunc_def;
+{
+    unz_s us;
+    unz_s *s;
+    uLong central_pos,uL;
+
+    uLong number_disk;          /* number of the current dist, used for
+                                   spaning ZIP, unsupported, always 0*/
+    uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                   for spaning ZIP, unsupported, always 0*/
+    uLong number_entry_CD;      /* total number of entries in
+                                   the central dir
+                                   (same than number_entry on nospan) */
+
+    int err=UNZ_OK;
+
+    if (pzlib_filefunc_def==NULL)
+        fill_fopen_filefunc(&us.z_filefunc);
+    else
+        us.z_filefunc = *pzlib_filefunc_def;
+
+    us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
+                                                 path,
+                                                 ZLIB_FILEFUNC_MODE_READ |
+                                                 ZLIB_FILEFUNC_MODE_EXISTING);
+    if (us.filestream==NULL)
+        return NULL;
+
+    central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
+    if (central_pos==0)
+        err=UNZ_ERRNO;
+
+    if (ZSEEK(us.z_filefunc, us.filestream,
+                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+    /* the signature, already checked */
+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* number of this disk */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* number of the disk with the start of the central directory */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* total number of entries in the central dir on this disk */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* total number of entries in the central dir */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if ((number_entry_CD!=us.gi.number_entry) ||
+        (number_disk_with_CD!=0) ||
+        (number_disk!=0))
+        err=UNZ_BADZIPFILE;
+
+    /* size of the central directory */
+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* offset of start of central directory with respect to the
+          starting disk number */
+    if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    /* zipfile comment length */
+    if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+        (err==UNZ_OK))
+        err=UNZ_BADZIPFILE;
+
+    if (err!=UNZ_OK)
+    {
+        ZCLOSE(us.z_filefunc, us.filestream);
+        return NULL;
+    }
+
+    us.byte_before_the_zipfile = central_pos -
+                            (us.offset_central_dir+us.size_central_dir);
+    us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+    us.encrypted = 0;
+
+
+    s=(unz_s*)ALLOC(sizeof(unz_s));
+    *s=us;
+    unzGoToFirstFile((unzFile)s);
+    return (unzFile)s;
+}
+
+
+/*
+  Read bytes from the current file.
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+int unzReadCurrentFile  (file, buf, len)
+    unzFile file;
+    voidp buf;
+    unsigned len;
+{
+    int err=UNZ_OK;
+    uInt iRead = 0;
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->read_buffer == NULL))
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (len==0)
+        return 0;
+
+    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+    pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+        (!(pfile_in_zip_read_info->raw)))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+    if ((len>pfile_in_zip_read_info->rest_read_compressed+
+           pfile_in_zip_read_info->stream.avail_in) &&
+         (pfile_in_zip_read_info->raw))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_compressed+
+            pfile_in_zip_read_info->stream.avail_in;
+
+    while (pfile_in_zip_read_info->stream.avail_out>0)
+    {
+        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+            (pfile_in_zip_read_info->rest_read_compressed>0))
+        {
+            uInt uReadThis = UNZ_BUFSIZE;
+            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+            if (uReadThis == 0)
+                return UNZ_EOF;
+            if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->pos_in_zipfile +
+                         pfile_in_zip_read_info->byte_before_the_zipfile,
+                         ZLIB_FILEFUNC_SEEK_SET)!=0)
+                return UNZ_ERRNO;
+            if (ZREAD(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->read_buffer,
+                      uReadThis)!=uReadThis)
+                return UNZ_ERRNO;
+
+            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+            pfile_in_zip_read_info->stream.next_in =
+                (Bytef*)pfile_in_zip_read_info->read_buffer;
+            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+        }
+
+        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+        {
+            uInt uDoCopy,i ;
+
+            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                return (iRead==0) ? UNZ_EOF : iRead;
+
+            if (pfile_in_zip_read_info->stream.avail_out <
+                            pfile_in_zip_read_info->stream.avail_in)
+                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+            else
+                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+            for (i=0;i<uDoCopy;i++)
+                *(pfile_in_zip_read_info->stream.next_out+i) =
+                        *(pfile_in_zip_read_info->stream.next_in+i);
+
+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+                                pfile_in_zip_read_info->stream.next_out,
+                                uDoCopy);
+            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+            pfile_in_zip_read_info->stream.next_out += uDoCopy;
+            pfile_in_zip_read_info->stream.next_in += uDoCopy;
+            pfile_in_zip_read_info->stream.total_out += uDoCopy;
+            iRead += uDoCopy;
+        }
+        else
+        {
+            uLong uTotalOutBefore,uTotalOutAfter;
+            const Bytef *bufBefore;
+            uLong uOutThis;
+            int flush=Z_SYNC_FLUSH;
+
+            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+            bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+            /*
+            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+                     pfile_in_zip_read_info->stream.avail_out) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                flush = Z_FINISH;
+            */
+            err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+              err = Z_DATA_ERROR;
+
+            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+            uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+            pfile_in_zip_read_info->crc32 =
+                crc32(pfile_in_zip_read_info->crc32,bufBefore,
+                        (uInt)(uOutThis));
+
+            pfile_in_zip_read_info->rest_read_uncompressed -=
+                uOutThis;
+
+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+            if (err==Z_STREAM_END)
+                return (iRead==0) ? UNZ_EOF : iRead;
+            if (err!=Z_OK)
+                break;
+        }
+    }
+
+    if (err==Z_OK)
+        return iRead;
+    return err;
+}
+
+/*
+  Read the local header of the current zipfile
+  Check the coherency of the local header and info in the end of central
+        directory about this file
+  store in *piSizeVar the size of extra info in local header
+        (filename and size of extra field data)
+*/
+int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
+                                                    poffset_local_extrafield,
+                                                    psize_local_extrafield)
+    unz_s* s;
+    uInt* piSizeVar;
+    uLong *poffset_local_extrafield;
+    uInt  *psize_local_extrafield;
+{
+    uLong uMagic,uData,uFlags;
+    uLong size_filename;
+    uLong size_extra_field;
+    int err=UNZ_OK;
+
+    *piSizeVar = 0;
+    *poffset_local_extrafield = 0;
+    *psize_local_extrafield = 0;
+
+    if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+
+    if (err==UNZ_OK){
+        if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+            err=UNZ_ERRNO;
+        else if (uMagic!=0x04034b50)
+            err=UNZ_BADZIPFILE;
+    }
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+/*
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+        err=UNZ_BADZIPFILE;
+*/
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+        err=UNZ_BADZIPFILE;
+
+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+                         (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+        err=UNZ_ERRNO;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
+                              ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
+                              ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
+                              ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+        err=UNZ_BADZIPFILE;
+
+    *piSizeVar += (uInt)size_filename;
+
+    if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+        err=UNZ_ERRNO;
+    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+                                    SIZEZIPLOCALHEADER + size_filename;
+    *psize_local_extrafield = (uInt)size_extra_field;
+
+    *piSizeVar += (uInt)size_extra_field;
+
+    return err;
+}
+
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+int unzOpenCurrentFile3 (file, method, level, raw, password)
+    unzFile file;
+    int* method;
+    int* level;
+    int raw;
+    const char* password;
+{
+    int err=UNZ_OK;
+    uInt iSizeVar;
+    unz_s* s;
+    file_in_zip_read_info_s* pfile_in_zip_read_info;
+    uLong offset_local_extrafield;  /* offset of the local extra field */
+    uInt  size_local_extrafield;    /* size of the local extra field */
+
+       if (password != NULL)
+        return UNZ_PARAMERROR;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_PARAMERROR;
+
+    if (s->pfile_in_zip_read != NULL)
+        unzCloseCurrentFile(file);
+
+    if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
+                &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+        return UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info = (file_in_zip_read_info_s*)
+                                        ALLOC(sizeof(file_in_zip_read_info_s));
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_INTERNALERROR;
+
+    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+    pfile_in_zip_read_info->pos_local_extrafield=0;
+    pfile_in_zip_read_info->raw=raw;
+
+    if (pfile_in_zip_read_info->read_buffer==NULL)
+    {
+        TRYFREE(pfile_in_zip_read_info);
+        return UNZ_INTERNALERROR;
+    }
+
+    pfile_in_zip_read_info->stream_initialised=0;
+
+    if (method!=NULL)
+        *method = (int)s->cur_file_info.compression_method;
+
+    if (level!=NULL)
+    {
+        *level = 6;
+        switch (s->cur_file_info.flag & 0x06)
+        {
+          case 6 : *level = 1; break;
+          case 4 : *level = 2; break;
+          case 2 : *level = 9; break;
+        }
+    }
+
+    if ((s->cur_file_info.compression_method!=0) &&
+        (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+    pfile_in_zip_read_info->crc32=0;
+    pfile_in_zip_read_info->compression_method =
+            s->cur_file_info.compression_method;
+    pfile_in_zip_read_info->filestream=s->filestream;
+    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+    pfile_in_zip_read_info->stream.total_out = 0;
+
+    if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
+        (!raw))
+    {
+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
+
+      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+      if (err == Z_OK)
+        pfile_in_zip_read_info->stream_initialised=1;
+      else
+      {
+        TRYFREE(pfile_in_zip_read_info);
+        return err;
+      }
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END.
+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+         * size of both compressed and uncompressed data
+         */
+    }
+    pfile_in_zip_read_info->rest_read_compressed =
+            s->cur_file_info.compressed_size ;
+    pfile_in_zip_read_info->rest_read_uncompressed =
+            s->cur_file_info.uncompressed_size ;
+
+
+    pfile_in_zip_read_info->pos_in_zipfile =
+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+              iSizeVar;
+
+    pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+    s->pfile_in_zip_read = pfile_in_zip_read_info;
+
+    return UNZ_OK;
+}
+
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (file)
+    unzFile file;
+{
+    unz_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz_s*)file;
+
+    if (s->pfile_in_zip_read!=NULL)
+        unzCloseCurrentFile(file);
+
+    ZCLOSE(s->z_filefunc, s->filestream);
+    TRYFREE(s);
+    return UNZ_OK;
+}
+
+#ifndef _WIN32_WCE
+
+/* mymkdir and change_file_date are not 100 % portable
+   As I don't know well Unix, I wait feedback for the unix portion */
+
+int mymkdir(dirname)
+    const char* dirname;
+{
+    int ret=0;
+#if defined(WIN32) || defined(_WIN32_WCE)
+    return mkdir(dirname);
+#else
+    return mkdir (dirname, 700);
+#endif
+    return ret;
+}
+
+int makedir (newdir)
+    char *newdir;
+{
+  char *buffer ;
+  char *p;
+  int  len = (int)strlen(newdir);
+
+  if (len <= 0)
+    return 0;
+
+  buffer = (char*)gf_malloc(len+1);
+  strcpy(buffer,newdir);
+
+  if (buffer[len-1] == '/') {
+    buffer[len-1] = '\0';
+  }
+  if (mymkdir(buffer) == 0)
+    {
+      gf_free(buffer);
+      return 1;
+    }
+
+  p = buffer+1;
+  while (1)
+    {
+      char hold;
+
+      while(*p && *p != '\\' && *p != '/')
+        p++;
+      hold = *p;
+      *p = 0;
+      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
+        {
+          printf("couldn't create directory %s\n",buffer);
+          gf_free(buffer);
+          return 0;
+        }
+      if (hold == 0)
+        break;
+      *p++ = hold;
+    }
+  gf_free(buffer);
+  return 1;
+}
+#else
+int makedir (newdir)
+{
+       return 0;
+}
+#endif
+
+
+int do_extract_currentfile(uf)
+    unzFile uf;
+{
+    char filename_inzip[256];
+    char* filename_withoutpath;
+    char* p;
+    int err=UNZ_OK;
+    FILE *fout=NULL;
+    void* buf;
+    uInt size_buf;
+
+    unz_file_info file_info;
+    err = unzlocal_GetCurrentFileInfoInternal(uf,&file_info,NULL,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+    if (err!=UNZ_OK)
+    {
+        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+        return err;
+    }
+
+    size_buf = WRITEBUFFERSIZE;
+    buf = (void*)gf_malloc(size_buf);
+    if (buf==NULL)
+    {
+        printf("Error allocating memory\n");
+        return UNZ_INTERNALERROR;
+    }
+
+    p = filename_withoutpath = filename_inzip;
+    while ((*p) != '\0')
+    {
+        if (((*p)=='/') || ((*p)=='\\'))
+            filename_withoutpath = p+1;
+        p++;
+    }
+
+    if ((*filename_withoutpath)=='\0')
+    {
+#ifndef _WIN32_WCE
+               printf("creating directory: %s\n",filename_inzip);
+           mymkdir(filename_inzip);
+#endif
+       }
+    else
+    {
+        const char* write_filename;
+        int skip=0;
+
+        write_filename = filename_inzip;
+
+               err = unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/);
+        if (err!=UNZ_OK)
+        {
+            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+        }
+
+        if ((skip==0) && (err==UNZ_OK))
+        {
+            fout=fopen(write_filename,"wb");
+
+            /* some zipfile don't contain directory alone before file */
+            if ((fout==NULL) && (filename_withoutpath!=(char*)filename_inzip))
+            {
+                char c=*(filename_withoutpath-1);
+                *(filename_withoutpath-1)='\0';
+                makedir(write_filename);
+                *(filename_withoutpath-1)=c;
+                fout=fopen(write_filename,"wb");
+            }
+
+            if (fout==NULL)
+            {
+                printf("error opening %s\n",write_filename);
+            }
+        }
+
+        if (fout!=NULL)
+        {
+            printf(" extracting: %s\n",write_filename);
+
+            do
+            {
+                err = unzReadCurrentFile(uf,buf,size_buf);
+                if (err<0)
+                {
+                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
+                    break;
+                }
+                if (err>0)
+                    if (gf_fwrite(buf,err,1,fout)!=1)
+                    {
+                        printf("error in writing extracted file\n");
+                        err=UNZ_ERRNO;
+                        break;
+                    }
+            }
+            while (err>0);
+            if (fout)
+                    fclose(fout);
+        }
+
+        if (err==UNZ_OK)
+        {
+            err = unzCloseCurrentFile (uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+            }
+        }
+        else
+            unzCloseCurrentFile(uf); /* don't lose the error */
+    }
+
+    gf_free(buf);
+    return err;
+}
+
+
+int gf_unzip_archive(const char *zipfilename, const char *dirname)
+{
+    uLong i;
+    unz_global_info gi;
+    int err;
+
+    unzFile uf=NULL;
+
+    uf = unzOpen2(zipfilename, NULL);
+    if (uf==NULL)
+    {
+        printf("Cannot open %s\n", zipfilename);
+        return 1;
+    }
+#ifndef _WIN32_WCE
+       if (chdir(dirname)) 
+    {
+      printf("Error changing into %s, aborting\n", dirname);
+      exit(-1);
+    }
+#endif
+
+    err = unzGetGlobalInfo (uf,&gi);
+    if (err!=UNZ_OK)
+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+
+    for (i=0;i<gi.number_entry;i++)
+    {
+        if (do_extract_currentfile(uf) != UNZ_OK)
+            break;
+
+        if ((i+1)<gi.number_entry)
+        {
+            err = unzGoToNextFile(uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                break;
+            }
+        }
+    }
+        unzClose(uf);
+
+    return 0;
+}
+
+int gf_unzip_probe(const char *zipfilename)
+{
+       int ret = 0;
+       FILE *f = fopen(zipfilename, "r");
+       if (!f) return 0;
+       if (fgetc(f)=='P')
+               if (fgetc(f)=='K')
+                       if (fgetc(f)==3)
+                               if (fgetc(f)==4)
+                                       ret = 1;
+       fclose(f);
+       return ret;
+}
diff --git a/modules/widgetman/unzip.h b/modules/widgetman/unzip.h
new file mode 100644 (file)
index 0000000..0ebfd3e
--- /dev/null
@@ -0,0 +1,489 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
+     WinZip, InfoZip tools and compatible.
+
+   Multi volume ZipFile (span) are not supported.
+   Encryption compatible with pkzip 2.04g only supported
+   Old compressions used by old PKZip 1.x are not supported
+
+
+   I WAIT FEEDBACK at mail info@winimage.com
+   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
+
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+
+*/
+
+/* for more info about .ZIP format, see
+      http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
+      http://www.info-zip.org/pub/infozip/doc/
+   PkWare has also a specification at :
+      ftp://ftp.pkware.com/probdesc.zip
+*/
+
+#ifndef _unz_H
+#define _unz_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <zlib.h>
+
+#ifndef OF
+#define OF(x) x
+#endif
+
+#define ZCALLBACK
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ      (1)
+#define ZLIB_FILEFUNC_MODE_WRITE     (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE   (8)
+       
+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
+typedef uLong  (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong  (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef long   (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
+typedef long   (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+typedef int    (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
+typedef int    (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef struct zlib_filefunc_def_s
+{
+    open_file_func      zopen_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell_file_func      ztell_file;
+    seek_file_func      zseek_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc_def;
+
+
+
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
+#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
+#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
+#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
+#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (gf_malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) gf_free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+#define WRITEBUFFERSIZE (8192)
+
+
+
+
+#define UNZ_OK                          (0)
+#define UNZ_END_OF_LIST_OF_FILE         (-100)
+#define UNZ_ERRNO                       (Z_ERRNO)
+#define UNZ_EOF                         (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info_s
+{
+    uLong number_entry;         /* total number of entries in
+                       the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info_internal_s
+{
+    uLong offset_curfile;/* relative offset of local header 4 bytes */
+} unz_file_info_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+    when reading and decompress it */
+typedef struct
+{
+    char  *read_buffer;         /* internal buffer for compressed data */
+    z_stream stream;            /* zLib stream structure for inflate */
+
+    uLong pos_in_zipfile;       /* position in byte on the zipfile, for gf_f64_seek*/
+    uLong stream_initialised;   /* flag set if stream structure is initialised*/
+
+    uLong offset_local_extrafield;/* offset of the local extra field */
+    uInt  size_local_extrafield;/* size of the local extra field */
+    uLong pos_local_extrafield;   /* position in the local extra field in read*/
+
+    uLong crc32;                /* crc32 of all data uncompressed */
+    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
+    uLong rest_read_compressed; /* number of byte to be decompressed */
+    uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+    zlib_filefunc_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    uLong compression_method;   /* compression method (0==store) */
+    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    int   raw;
+} file_in_zip_read_info_s;
+
+
+/* unz_s contain internal information about the zipfile
+*/
+typedef struct
+{
+    zlib_filefunc_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    unz_global_info gi;       /* public global information */
+    uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    uLong num_file;             /* number of the current file in the zipfile*/
+    uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
+    uLong current_file_ok;      /* flag about the usability of the current file*/
+    uLong central_pos;          /* position of the beginning of the central dir*/
+
+    uLong size_central_dir;     /* size of the central directory  */
+    uLong offset_central_dir;   /* offset of start of central directory with
+                                   respect to the starting disk number */
+
+    unz_file_info cur_file_info; /* public info about the current file in zip*/
+    unz_file_info_internal cur_file_info_internal; /* private info about it*/
+    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
+                                        file if we are decompressing it */
+    int encrypted;
+#    ifndef NOUNCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const unsigned long* pcrc_32_tab;
+#    endif
+} unz_s;
+
+
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                 const char* fileName2,
+                                                 int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+    (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+     "zlib/zlib113.zip".
+     If the zipfile cannot be opened (file don't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+*/
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+                                    zlib_filefunc_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unzOpen, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                        unz_global_info *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                           char *szComment,
+                                           uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+                     const char *szFileName,
+                     int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+    uLong pos_in_zip_directory;   /* offset in zip file directory */
+    uLong num_of_file;            /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                         unz_file_info *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+        the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+            (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+            (extraFieldBufferSize is the size of the buffer).
+            This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+            (commentBufferSize is the size of the buffer)
+*/
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+                                                  const char* password));
+/*
+  Open for reading data the current file in the zipfile.
+  password is a crypting password
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw,
+                                           const char* password));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+                      voidp buf,
+                      unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                             voidp buf,
+                                             unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+int gf_unzip_probe(const char *zipfilename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz_H */
diff --git a/modules/widgetman/wgt_load.c b/modules/widgetman/wgt_load.c
new file mode 100644 (file)
index 0000000..7a87d28
--- /dev/null
@@ -0,0 +1,302 @@
+//This software module was originally developed by TelecomParisTech in the
+//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard.
+//
+//This software module is an implementation of a part of one or
+//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets
+//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets
+//(ISO/IEC 23007-1) free license to this software module or modifications
+//thereof for use in hardware or software products claiming conformance to
+//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software
+//module in hardware or software products are advised that its use may
+//infringe existing patents.
+//The original developer of this software module and his/her company, the
+//subsequent editors and their companies, and ISO/IEC have no liability
+//for use of this software module or modifications thereof in an implementation.
+//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming
+//products.
+//Telecom ParisTech retains full right to use the code for his/her own purpose,
+//assign or donate the code to a third party and to inhibit third parties from
+//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products.
+//
+//This copyright notice must be included in all copies or derivative works.
+//
+//Copyright (c) 2009.
+//
+// Alternatively, this software module may be redistributed and/or modified
+//  it under the terms of the GNU Lesser General Public License as published by
+//  the Free Software Foundation; either version 2, or (at your option)
+//  any later version.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+//     Authors:
+//                                     Cyril Concolato, Telecom ParisTech
+//                                     Jean Le Feuvre, Telecom ParisTech
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+#include <gpac/internal/terminal_dev.h>
+#include <gpac/internal/scenegraph_dev.h>
+#include <gpac/nodes_svg.h>
+#include <gpac/constants.h>
+
+#ifdef GPAC_HAS_SPIDERMONKEY
+
+typedef struct
+{
+       GF_Scene *scene;
+       u8 oti;
+       char *file_name;
+       u32 file_size;
+       Bool loaded;
+} WgtLoad;
+
+static GF_Err WGT_ProcessData(GF_SceneDecoder *plug, const char *inBuffer, u32 inBufferLength,
+                                                               u16 ES_ID, u32 stream_time, u32 mmlevel)
+{
+       GF_Err e = GF_OK;
+       WgtLoad *wgtload = (WgtLoad *)plug->privateStack;
+
+       if (stream_time==(u32)-1) {
+               gf_sg_reset(wgtload->scene->graph);
+               return GF_OK;
+       }
+
+       switch (wgtload->oti) {
+       case GPAC_OTI_PRIVATE_SCENE_WGT:
+               if (wgtload->file_name && !wgtload->loaded) {
+                       const char *path, *wmpath;
+                       char *tmp;
+                       GF_Node *n, *root;
+                       GF_FieldInfo info;
+                       FILE *jsfile;
+                       GF_ChildNodeItem *last;
+
+                       wgtload->loaded = 1;
+
+                       gf_sg_add_namespace(wgtload->scene->graph, "http://www.w3.org/2000/svg", NULL);
+                       gf_sg_add_namespace(wgtload->scene->graph, "http://www.w3.org/1999/xlink", "xlink");
+                       gf_sg_add_namespace(wgtload->scene->graph, "http://www.w3.org/2001/xml-events", "ev");
+                       gf_sg_set_scene_size_info(wgtload->scene->graph, 800, 600, 1);
+
+                       /* modify the scene with an Inline/Animation pointing to the widget start file URL */
+                       n = root = gf_node_new(wgtload->scene->graph, TAG_SVG_svg);
+                       gf_node_register(root, NULL);
+                       gf_sg_set_root_node(wgtload->scene->graph, root);
+                       gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_viewBox, 1, 0, &info);
+                       gf_svg_parse_attribute(n, &info, "0 0 320 240", 0);
+                       gf_node_get_attribute_by_name(n, "xmlns", 0, 1, 0, &info);
+                       gf_svg_parse_attribute(n, &info, "http://www.w3.org/2000/svg", 0);
+/*
+                       gf_sg_set_scene_size_info(wgtload->scene->graph, 800, 600, 1);
+                       gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_width, 1, 0, &info);
+                       gf_svg_parse_attribute(n, &info, "800", 0);
+                       gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_height, 1, 0, &info);
+                       gf_svg_parse_attribute(n, &info, "600", 0);
+*/
+                       gf_node_init(n);
+
+                       n = gf_node_new(wgtload->scene->graph, TAG_SVG_animation);
+                       gf_node_set_id(n, 1, "w_anim");
+                       gf_node_register(n, root);
+                       gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last);
+                       gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_width, 1, 0, &info);
+                       gf_svg_parse_attribute(n, &info, "320", 0);
+                       gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_height, 1, 0, &info);
+                       gf_svg_parse_attribute(n, &info, "240", 0);
+                       gf_node_init(n);
+
+                       tmp = wgtload->file_name;
+                       while ((tmp = strchr(tmp, '\\'))) {
+                               tmp[0] = '/';
+                               tmp++;
+                       }
+
+                       n = gf_node_new(wgtload->scene->graph, TAG_SVG_script);
+                       gf_node_register(n, root);
+                       gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last);
+                       path = gf_modules_get_option((GF_BaseInterface *)plug, "Widgets", "WidgetLoadScript");
+                       jsfile = path ? gf_f64_open(path, "rt") : NULL;
+                       if (jsfile) {
+                               fclose(jsfile);
+                               gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, 1, 0, &info);
+                               gf_svg_parse_attribute(n, &info, (char *) path, 0);
+                       } else {
+                               const char *load_fun = "function load_widget(wid_url) {\n"
+                                                                               "       var wid = WidgetManager.load(wid_url);\n"
+                                                                               "       var anim = document.getElementById('w_anim');\n"
+                                                                               "       if (wid != null) {\n"
+                                                                               "               wid.activate(anim);"
+                                                                               "               anim.setAttributeNS('http://www.w3.org/1999/xlink', 'href', wid.main);\n"
+                                                                               "       } else {\n"
+                                                                               "               alert('Widget ' + wid_url + ' is not valid');\n"
+                                                                               "       }\n"
+                                                                               "}\n";
+
+                               gf_dom_add_text_node(n, gf_strdup(load_fun) );
+                       }
+                       gf_node_init(n);
+
+
+                       wmpath = gf_modules_get_option((GF_BaseInterface *)plug, "Widgets", "WidgetManagerScript");
+                       jsfile = wmpath ? gf_f64_open(wmpath, "rt") : NULL;
+                       if (jsfile) {
+                               fclose(jsfile);
+                               n = gf_node_new(wgtload->scene->graph, TAG_SVG_script);
+                               gf_node_register(n, root);
+                               gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last);
+                               gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, 1, 0, &info);
+                               gf_svg_parse_attribute(n, &info, (char *) wmpath, 0);
+                               gf_node_init(n);
+
+                               n = gf_node_new(wgtload->scene->graph, TAG_SVG_script);
+                               gf_node_register(n, root);
+                               gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last);
+                               gf_dom_add_text_node(n, gf_strdup("widget_manager_init();") );
+                               gf_node_init(n);
+                       }
+
+                       tmp = gf_malloc(sizeof(char) * (strlen(wgtload->file_name)+50) );
+                       sprintf(tmp, "load_widget(\"%s\");\n", wgtload->file_name);
+
+                       n = gf_node_new(wgtload->scene->graph, TAG_SVG_script);
+                       gf_node_register(n, root);
+                       gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last);
+                       gf_dom_add_text_node(n, gf_strdup(tmp) );
+                       gf_free(tmp);
+
+                       gf_node_init(n);
+
+                       if ((wgtload->scene->graph_attached!=1) && (gf_sg_get_root_node(wgtload->scene->graph)!=NULL) ) {
+                               gf_scene_attach_to_compositor(wgtload->scene);
+                               e = GF_EOS;
+                       }
+               }
+               break;
+
+       default:
+               return GF_BAD_PARAM;
+       }
+       return e;
+}
+
+static GF_Err WGT_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder)
+{
+       WgtLoad *wgtload = (WgtLoad *)plug->privateStack;
+       wgtload->scene = scene;
+       return GF_OK;
+}
+
+static GF_Err WGT_ReleaseScene(GF_SceneDecoder *plug)
+{
+       WgtLoad *wgtload = (WgtLoad *)plug->privateStack;
+       wgtload->scene = NULL;
+       return GF_OK;
+}
+
+static GF_Err WGT_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd)
+{
+       GF_BitStream *bs;
+       WgtLoad *wgtload = (WgtLoad *)plug->privateStack;
+       if (esd->decoderConfig->upstream) return GF_NOT_SUPPORTED;
+
+       /* decSpecInfo is not null only when reading from an WGT file (local or distant, cached or not) */
+       switch (esd->decoderConfig->objectTypeIndication) {
+       case GPAC_OTI_PRIVATE_SCENE_WGT:
+       default:
+               if (!esd->decoderConfig->decoderSpecificInfo) return GF_NON_COMPLIANT_BITSTREAM;
+               bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ);
+               wgtload->file_size = gf_bs_read_u32(bs);
+               gf_bs_del(bs);
+               wgtload->file_name =  (char *) gf_malloc(sizeof(char)*(1 + esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32)) );
+               memcpy(wgtload->file_name, esd->decoderConfig->decoderSpecificInfo->data + sizeof(u32), esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32) );
+               wgtload->file_name[esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32) ] = 0;
+               break;
+       }
+       wgtload->oti = esd->decoderConfig->objectTypeIndication;
+       return GF_OK;
+}
+
+static GF_Err WGT_DetachStream(GF_BaseDecoder *plug, u16 ES_ID)
+{
+       WgtLoad *wgtload = (WgtLoad *)plug->privateStack;
+       if (wgtload->file_name) gf_free(wgtload->file_name);
+       wgtload->file_name = NULL;
+       return GF_OK;
+}
+
+const char *WGT_GetName(struct _basedecoder *plug)
+{
+       return "GPAC W3C Widget Loader";
+}
+
+static u32 WGT_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL)
+{
+       /*don't reply to media type query*/
+       if (!esd) return GF_CODEC_NOT_SUPPORTED;
+
+       if (StreamType==GF_STREAM_PRIVATE_SCENE) {
+               if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_PRIVATE_SCENE_WGT) return GF_CODEC_SUPPORTED;
+               return GF_CODEC_NOT_SUPPORTED;
+       }
+       return GF_CODEC_NOT_SUPPORTED;
+}
+
+static GF_Err WGT_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap)
+{
+       cap->cap.valueInt = 0;
+       if (cap->CapCode==GF_CODEC_PADDING_BYTES) {
+               /* Adding one byte of padding for \r\n problems*/
+               cap->cap.valueInt = 1;
+               return GF_OK;
+       }
+       return GF_NOT_SUPPORTED;
+}
+
+static GF_Err WGT_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability capability)
+{
+       return GF_OK;
+}
+
+/*interface create*/
+GF_BaseInterface *LoadWidgetReader()
+{
+       WgtLoad *wgtload;
+       GF_SceneDecoder *sdec;
+
+       GF_SAFEALLOC(sdec, GF_SceneDecoder)
+       GF_REGISTER_MODULE_INTERFACE(sdec, GF_SCENE_DECODER_INTERFACE, "GPAC W3C Widget Loader", "gpac distribution");
+
+       GF_SAFEALLOC(wgtload, WgtLoad);
+       sdec->privateStack = wgtload;
+       sdec->AttachStream = WGT_AttachStream;
+       sdec->CanHandleStream = WGT_CanHandleStream;
+       sdec->DetachStream = WGT_DetachStream;
+       sdec->AttachScene = WGT_AttachScene;
+       sdec->ReleaseScene = WGT_ReleaseScene;
+       sdec->ProcessData = WGT_ProcessData;
+       sdec->GetName = WGT_GetName;
+       sdec->SetCapabilities = WGT_SetCapabilities;
+       sdec->GetCapabilities = WGT_GetCapabilities;
+       return (GF_BaseInterface *)sdec;
+}
+
+
+/*interface destroy*/
+void ShutdownWidgetReader(GF_BaseInterface *ifce)
+{
+       GF_SceneDecoder *sdec = (GF_SceneDecoder *)ifce;
+       WgtLoad *wgtload;
+        if (!ifce)
+          return;
+        wgtload = (WgtLoad *) sdec->privateStack;
+        if (wgtload)
+          gf_free(wgtload);
+        sdec->privateStack = NULL;
+       gf_free(sdec);
+}
+
+#endif /*GPAC_HAS_SPIDERMONKEY*/
diff --git a/modules/widgetman/wgt_load_base.js b/modules/widgetman/wgt_load_base.js
new file mode 100644 (file)
index 0000000..bdaadbd
--- /dev/null
@@ -0,0 +1,84 @@
+var wid = null;
+var xmlns_xlink = 'http://www.w3.org/1999/xlink';
+
+function debug(s) {
+  alert('[Widget Loader] '+s);
+}
+
+function add_text_span(parent, string) {
+    var span = document.createElement('tspan');
+    span.textContent = string;
+    parent.appendChild(span);
+    parent.appendChild(document.createElement('tbreak'));
+}
+
+function load_widget(wid_url) {
+  debug('Loading Widget: '+wid_url);
+  wid = WidgetManager.load(wid_url);
+  var anim = document.getElementById('w_anim');
+  width = 320;
+  height = 240;
+  anim.setAttribute('height', height/3);
+  
+  var info = document.createElement('textArea');
+  document.documentElement.appendChild(info);
+  info.setAttribute('y', height/3);
+  info.setAttribute('width', width);
+  
+  info.setAttribute('font-size', '7');
+  info.setAttribute('font-family', 'Arial Unicode MS');
+  if (wid != null) {
+    debug('Loading scene: '+wid.main);
+    anim.setAttributeNS(xmlns_xlink, 'href', wid.main);
+    add_text_span(info, 'Widget Metadata');    
+    add_text_span(info, 'UA Locale: \'' + gpac.getOption('Systems', 'Language2CC') + '\'');
+    add_text_span(info, 'widget src (abs.): \'' + wid.url + '\'');
+    add_text_span(info, 'config src (abs.): \'' + wid.manifest + '\'');
+    add_text_span(info, 'content src (rel.&loc./abs.): \''+wid.main+'\' / \''+wid.localizedSrc+'\' ('+wid.mainMimeType+';'+wid.mainEncoding+')');
+    add_text_span(info, 'id: \'' + wid.identifier + '\'');
+    add_text_span(info, 'shortname/name: \''+wid.shortName+ '\' / \''+wid.name+'\'');
+    add_text_span(info, 'version: \''+wid.version+'\'');
+    add_text_span(info, 'license/href: \''+wid.license+'\' / \''+wid.licenseHref+'\'');
+    add_text_span(info, 'description: \''+wid.description+'\'');
+    add_text_span(info, 'author (name/email/href): \''+wid.authorName+ '\' / \''+wid.authorEmail +'\' / \''+wid.authorHref+'\'');
+    var s = 'icons src (rel.&loc./abs.): ';
+    for (var i=0; i<wid.icons.length; i++) {
+      if (i) s += ' , ';
+      s += '\'' + wid.icons[i].src + '\' / \'' + wid.icons[i].relocated_src + '\'' + ' ('+wid.icons[i].width+'x'+wid.icons[i].height+')';      
+    }
+    add_text_span(info, s);
+    
+    s = 'preferences: ';
+    for (var i=0; i<wid.preferences.length; i++) {
+      var p = wid.preferences[i];
+      if (i) s += ' , ';
+      s += '' + p.name + '=\'' + p.value + '\' (ro:'+p.readonly+')';      
+    }
+    add_text_span(info, s);
+    
+    s = 'features: ';
+    add_text_span(info, s);
+
+    for (var i=0; i<wid.features.length; i++) {
+      var f = wid.features[i];
+      s = 'feature: ';
+      s += '' + f.name + '(' + f.required + ')';
+      add_text_span(info, s);
+      if (f.params.length) {
+        s = '-params: ';
+        for (var j=0; j<f.params.length; j++) {
+          var p = f.params[j];
+          if (j != 0) s += ' , ';
+          s += '' + p.name + '=\'' + p.value + '\'';
+        }
+        add_text_span(info, s);
+      }
+    }      
+  
+    add_text_span(info, 'size: '+wid.defaultWidth+'x'+wid.defaultHeight);
+    add_text_span(info, 'viewmodes: \''+wid.viewmodes+'\'');
+  } else {
+    debug('Invalid Widget');
+    info.textContent = 'Invalid widget - no info available';
+  }
+}
diff --git a/modules/widgetman/widget.c b/modules/widgetman/widget.c
new file mode 100644 (file)
index 0000000..e5f8b07
--- /dev/null
@@ -0,0 +1,446 @@
+//This software module was originally developed by TelecomParisTech in the
+//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard.
+//
+//This software module is an implementation of a part of one or 
+//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets
+//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets
+//(ISO/IEC 23007-1) free license to this software module or modifications
+//thereof for use in hardware or software products claiming conformance to
+//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software
+//module in hardware or software products are advised that its use may
+//infringe existing patents.
+//The original developer of this software module and his/her company, the
+//subsequent editors and their companies, and ISO/IEC have no liability 
+//for use of this software module or modifications thereof in an implementation. 
+//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming 
+//products. 
+//Telecom ParisTech retains full right to use the code for his/her own purpose, 
+//assign or donate the code to a third party and to inhibit third parties from 
+//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. 
+//
+//This copyright notice must be included in all copies or derivative works.
+//
+//Copyright (c) 2009.
+//
+// Alternatively, this software module may be redistributed and/or modified
+//  it under the terms of the GNU Lesser General Public License as published by
+//  the Free Software Foundation; either version 2, or (at your option)
+//  any later version.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+//     Authors:        
+//                                     Jean Le Feuvre, Telecom ParisTech
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+#include "widgetman.h"
+
+#ifdef GPAC_HAS_SPIDERMONKEY
+
+JSBool SMJS_FUNCTION(widget_has_feature)
+{
+       char *feat_name;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE;
+
+       feat_name = SMJS_CHARS(c, argv[0]);
+       SMJS_SET_RVAL( BOOLEAN_TO_JSVAL( JS_FALSE ) );
+
+       if (!strcmp(feat_name, "urn:mpeg:systems:mpeg-u:2009")) SMJS_SET_RVAL( BOOLEAN_TO_JSVAL( JS_TRUE ));
+       SMJS_FREE(c, feat_name);
+       return JS_TRUE;
+}
+
+JSBool SMJS_FUNCTION(widget_open_url)
+{
+       GF_Event evt;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE;
+
+       memset(&evt, 0, sizeof(GF_Event));
+       evt.type = GF_EVENT_NAVIGATE;
+       evt.navigate.to_url = SMJS_CHARS(c, argv[0]);
+       gf_term_send_event(wid->widget->wm->term, &evt);
+       SMJS_FREE(c, (char *)evt.navigate.to_url);
+
+       return JS_TRUE;
+}
+
+JSBool SMJS_FUNCTION(widget_get_attention)
+{
+       jsval fval;
+       SMJS_OBJ
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_TRUE;
+
+       if ((JS_LookupProperty(c, wid->widget->wm->obj, "getAttention", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) {
+               jsval args[1];
+               args[0] = OBJECT_TO_JSVAL(wid->obj);
+               JS_CallFunctionValue(c, wid->widget->wm->obj, fval, 1, args, SMJS_GET_RVAL);
+       }
+       return JS_TRUE;
+}
+
+JSBool SMJS_FUNCTION(widget_show_notification)
+{
+       jsval fval;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_TRUE;
+
+       if ((JS_LookupProperty(c, wid->widget->wm->obj, "showNotification", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) {
+               jsval *vars;
+               u32 i;
+               vars = gf_malloc(sizeof(jsval)*(argc+1));
+               vars[0] = OBJECT_TO_JSVAL(wid->obj);
+               for (i=0; i<argc; i++) 
+                       vars[i+1] = argv[i];
+
+               JS_CallFunctionValue(c, wid->widget->wm->obj, fval, argc+1, vars, SMJS_GET_RVAL);
+       }
+       return JS_TRUE;
+}
+
+
+static JSBool SMJS_FUNCTION(widget_call_message_reply_callback)
+{
+       JSObject *list;
+       jsval *vals, fval;
+       u32 i, count;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetMessage *msg = JS_GetPrivate(c, obj);
+       if (!msg || !argc || !JSVAL_IS_OBJECT(argv[0]) ) return JS_FALSE;
+
+       if ((JS_LookupProperty(c, obj, "replyCallback", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) {
+               list = JSVAL_TO_OBJECT(argv[0]);
+               JS_GetArrayLength(c, list, (jsuint*) &count);
+               vals = gf_malloc(sizeof(jsval)*(count+1));
+               vals[0] = OBJECT_TO_JSVAL(obj);
+               for (i=0; i<count; i++) {
+                       JS_GetElement(c, list, (jsint) i, &vals[i+1]);
+               }
+               JS_CallFunctionValue(c, obj, fval, count, vals, SMJS_GET_RVAL);
+               gf_free(vals);
+       }
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(widget_message_handler_factory)
+{
+       char *msg_name;
+       u32 i, count;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInterfaceInstance *bifce = (GF_WidgetInterfaceInstance *)JS_GetPrivate(c, obj);
+       if (!bifce) return JS_FALSE;
+
+       if (!argc) return JS_FALSE;
+       if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE;
+
+       msg_name = SMJS_CHARS(c, argv[0]);
+       if (!msg_name ) return JS_FALSE;
+
+       SMJS_SET_RVAL( JSVAL_NULL );
+       count = gf_list_count(bifce->ifce->messages);
+       for (i=0; i<count; i++) {
+               GF_WidgetMessage *msg = gf_list_get(bifce->ifce->messages, i);
+               if (!strcmp(msg->name, msg_name)) {
+                       JSObject *an_obj = JS_NewObject(c, &bifce->wid->widget->wm->widgetAnyClass, 0, 0);
+                       JS_SetPrivate(c, an_obj, msg);
+                       JS_DefineProperty(c, an_obj, "msgName", STRING_TO_JSVAL( JS_NewStringCopyZ(c, msg->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       JS_DefineProperty(c, an_obj, "interfaceHandler", OBJECT_TO_JSVAL( obj ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       JS_DefineFunction(c, an_obj, "onInvokeReply", widget_call_message_reply_callback, 1, 0);
+
+                       if ((argc==2) && JSVAL_IS_OBJECT(argv[1]) && !JSVAL_IS_NULL(argv[1]))
+                               JS_DefineProperty(c, an_obj, "replyCallback", argv[1], 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       
+                       SMJS_SET_RVAL( OBJECT_TO_JSVAL(an_obj) );
+               }
+       }
+       SMJS_FREE(c, msg_name);
+       return JS_TRUE;
+}
+static JSBool SMJS_FUNCTION(widget_invoke_message)
+{
+       jsval oval;
+       GF_WidgetMessage *msg = NULL;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInterfaceInstance *bifce = (GF_WidgetInterfaceInstance *)JS_GetPrivate(c, obj);
+       if (!bifce) return JS_FALSE;
+
+       SMJS_SET_RVAL( JSVAL_NULL );
+
+       if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;
+       if (JSVAL_IS_NULL(argv[0])) return JS_FALSE;
+       msg = (GF_WidgetMessage *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+       if (!msg) return JS_FALSE;
+
+       /*look for JS Callback "invoke" in the widget manager script*/
+       if (JS_LookupProperty(c, bifce->ifce->obj, "invoke", &oval)==JS_TRUE) {
+               if (JSVAL_IS_OBJECT(oval)) {
+                       JS_CallFunctionValue(bifce->wid->widget->wm->ctx, bifce->ifce->obj, oval, argc, argv, SMJS_GET_RVAL );
+               }
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(widget_invoke_message_reply)
+{
+       jsval oval;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetMessage *msg = NULL;
+       GF_WidgetInterfaceInstance *bifce = (GF_WidgetInterfaceInstance *)JS_GetPrivate(c, obj);
+       if (!bifce) return JS_FALSE;
+
+       SMJS_SET_RVAL( JSVAL_NULL );
+
+       if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;
+       if (JSVAL_IS_NULL(argv[0])) return JS_FALSE;
+       msg = (GF_WidgetMessage *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+       if (!msg) return JS_FALSE;
+
+       /*look for JS Callback "invokeReply" in the widget manager script*/
+       if (JS_LookupProperty(c, bifce->ifce->obj, "invokeReply", &oval)==JS_TRUE) {
+               if (JSVAL_IS_OBJECT(oval)) {
+                       JS_CallFunctionValue(bifce->wid->widget->wm->ctx, bifce->ifce->obj, oval, argc, argv, SMJS_GET_RVAL);
+               }
+       }
+       return JS_TRUE;
+}
+
+static void widget_interface_js_bind(JSContext *c, GF_WidgetInterfaceInstance *ifce)
+{
+       if (!ifce->obj) {
+               ifce->obj = JS_NewObject(c, &ifce->wid->widget->wm->widgetAnyClass, 0, 0);
+               JS_SetPrivate(c, ifce->obj, ifce);
+               gf_js_add_root(c, &ifce->obj, GF_JSGC_OBJECT);
+               JS_DefineProperty(c, ifce->obj, "type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->ifce->type) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, ifce->obj, "bound", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->hostname) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineFunction(c, ifce->obj, "invoke", widget_invoke_message, 1, 0);
+               JS_DefineFunction(c, ifce->obj, "msgHandlerFactory", widget_message_handler_factory, 1, 0);
+               JS_DefineFunction(c, ifce->obj, "invokeReply", widget_invoke_message_reply, 1, 0);
+       }
+}
+
+static JSBool SMJS_FUNCTION(widget_get_interfaces)
+{
+       u32 i, count;
+       char *ifce_name;
+       JSObject *list;
+       jsuint idx;
+       jsval v;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE;
+       ifce_name = SMJS_CHARS(c, argv[0]);
+
+       list = JS_NewArrayObject(c, 0, 0);
+
+       count = gf_list_count(wid->bound_ifces);
+       for (i=0; i<count; i++) {
+               GF_WidgetInterfaceInstance *ifce = gf_list_get(wid->bound_ifces, i);
+               if (strcmp(ifce->ifce->type, ifce_name)) continue;
+
+               widget_interface_js_bind(c, ifce);
+
+               JS_GetArrayLength(c, list, &idx);
+               v = OBJECT_TO_JSVAL(ifce->obj);
+               JS_SetElement(c, list, idx, &v);
+       }
+       SMJS_SET_RVAL( OBJECT_TO_JSVAL(list) );
+       SMJS_FREE(c, ifce_name);
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION_EXT(widget_activate_component, Bool is_deactivate)
+{
+       u32 i, count;
+       char *comp_id;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE;
+       comp_id = SMJS_CHARS(c, argv[0]);
+
+       count = gf_list_count(wid->widget->main->components);
+       for (i=0; i<count; i++) {
+               GF_WidgetComponent *comp = gf_list_get(wid->widget->main->components, i);
+               if (!comp->id  || strcmp(comp->id, comp_id)) continue;
+               
+               if (is_deactivate) {
+                       wm_deactivate_component(c, wid, comp, NULL);
+               } else {
+                       wm_activate_component(c, wid, comp, 0);
+               }
+               break;
+       }
+       SMJS_FREE(c, comp_id);
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(widget_activate_widget)
+{
+       return widget_activate_component(SMJS_CALL_ARGS, 0);
+}
+
+static JSBool SMJS_FUNCTION(widget_deactivate_widget)
+{
+       return widget_activate_component(SMJS_CALL_ARGS, 1);
+}
+
+void widget_on_interface_bind(GF_WidgetInterfaceInstance *ifce, Bool unbind)
+{
+       jsval funval, rval, argv[1];
+
+       const char *fun_name = unbind ? "onInterfaceUnbind" : "onInterfaceBind";
+       if (!ifce || !ifce->wid || !ifce->wid->scene_context) return;
+
+       /*look for JS Callback "invoke" in the widget manager script*/
+       if (JS_LookupProperty(ifce->wid->scene_context, ifce->wid->scene_obj, fun_name, &funval)!=JS_TRUE) 
+               return;
+       if (!JSVAL_IS_OBJECT(funval)) return;
+
+       widget_interface_js_bind(ifce->wid->widget->wm->ctx, ifce);
+       argv[0] = OBJECT_TO_JSVAL(ifce->obj);
+       JS_CallFunctionValue(ifce->wid->widget->wm->ctx, ifce->ifce->obj, funval, 1, argv, &rval);
+
+}
+
+JSBool widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *rval)
+{
+       const char *opt;
+       char *prop_name;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       if (!SMJS_ID_IS_STRING(id)) return JS_TRUE;
+       prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id));
+       if (!prop_name) return JS_FALSE;
+
+       if (!strcmp(prop_name, "viewMode")) {
+               *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "floating") );
+       }
+       else if (!strcmp(prop_name, "locale")) {
+               opt = gf_cfg_get_key(wid->widget->wm->term->user->config, "Systems", "Language2CC");
+               if (!opt) opt = "und";
+               *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, opt) );
+       }
+       else if (!strcmp(prop_name, "identifier")) {
+               if (wid->widget->identifier) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->identifier) );
+       }
+       else if (!strcmp(prop_name, "authorName")) {
+               if (wid->widget->authorName) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorName) );
+       }
+       else if (!strcmp(prop_name, "authorEmail")) {
+               if (wid->widget->authorEmail) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorEmail) );
+       }
+       else if (!strcmp(prop_name, "authorHref")) {
+               if (wid->widget->authorHref) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->authorHref) );
+       }
+       else if (!strcmp(prop_name, "name")) {
+               if (wid->widget->name) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->name) );
+       }
+       else if (!strcmp(prop_name, "version")) {
+               if (wid->widget->version) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->version) );
+       }
+       else if (!strcmp(prop_name, "description")) {
+               if (wid->widget->description) *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, wid->widget->description) );
+       }
+       else if (!strcmp(prop_name, "width")) {
+               opt = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, "width");
+               *rval = INT_TO_JSVAL( (opt ? atoi(opt) : 0) );
+       }
+       else if (!strcmp(prop_name, "height")) {
+               opt = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, "height");
+               *rval = INT_TO_JSVAL( (opt ? atoi(opt) : 0) );
+       }
+       else if (!strcmp(prop_name, "preferences")) {
+       }
+       SMJS_FREE(c, prop_name);
+       return JS_TRUE;
+}
+
+JSBool widget_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
+{
+       return JS_TRUE;
+}
+
+void widget_load(GF_WidgetManager *wm, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload)
+{
+       u32 i, count;
+       GF_WidgetInstance *wi;
+
+       /*Is this scenegraph a widget or not ? To find out, browse all widget instances*/
+       i=0;
+       while ((wi = gf_list_enum(wm->widget_instances, &i))) {
+               if (!wi->scene || (wi->scene != scene)) continue;
+               break;
+       }
+       if (!wi) return;
+
+       /*OK we found our widget*/
+
+       if (unload) {
+               /*detach all bound interfaces from this script*/
+               count = gf_list_count(wi->bound_ifces);
+               for (i=0; i<count; i++) {
+                       GF_WidgetInterfaceInstance *ifce = gf_list_get(wi->bound_ifces, i);
+                       if (ifce->obj) {
+                               JS_SetPrivate(c, ifce->obj, NULL);
+                               gf_js_remove_root(c, &ifce->obj, GF_JSGC_OBJECT);
+                               ifce->obj = NULL;
+                       }
+               }
+               return;
+       } else {
+
+               JSPropertySpec widgetClassProps[] = {
+                       {0, 0, 0, 0, 0}
+               };
+               JSFunctionSpec widgetClassFuncs[] = {
+                       /*W3C*/
+                       SMJS_FUNCTION_SPEC("has_feature", widget_has_feature, 1),
+                       SMJS_FUNCTION_SPEC("openURL", widget_open_url, 1),
+                       SMJS_FUNCTION_SPEC("getAttention", widget_get_attention, 0),
+                       SMJS_FUNCTION_SPEC("showNotification", widget_show_notification, 0),
+                       /*MPEG*/
+                       SMJS_FUNCTION_SPEC("getInterfaceHandlersByType", widget_get_interfaces, 1),
+                       SMJS_FUNCTION_SPEC("activateComponentWidget", widget_activate_widget, 1),
+                       SMJS_FUNCTION_SPEC("deactivateComponentWidget", widget_deactivate_widget, 1),
+                       SMJS_FUNCTION_SPEC(0, 0, 0)
+               };
+
+               JS_InitClass(c, global, 0, &wm->widgetClass, 0, 0,widgetClassProps, widgetClassFuncs, 0, 0);
+
+               
+               wi->scene_obj = JS_DefineObject(c, global, "widget", &wm->widgetClass, 0, 0);
+               //JS_AliasProperty(c, global, "widget", "MPEGWidget");
+               JS_SetPrivate(c, wi->scene_obj, wi);
+               /*and remember the script*/
+               wi->scene_context = c;
+               wi->scene_global = global;
+       }
+}
+
+#endif
diff --git a/modules/widgetman/widgetman.c b/modules/widgetman/widgetman.c
new file mode 100644 (file)
index 0000000..75e3df3
--- /dev/null
@@ -0,0 +1,3648 @@
+//This software module was originally developed by TelecomParisTech in the
+//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard.
+//
+//This software module is an implementation of a part of one or
+//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets
+//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets
+//(ISO/IEC 23007-1) free license to this software module or modifications
+//thereof for use in hardware or software products claiming conformance to
+//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software
+//module in hardware or software products are advised that its use may
+//infringe existing patents.
+//The original developer of this software module and his/her company, the
+//subsequent editors and their companies, and ISO/IEC have no liability
+//for use of this software module or modifications thereof in an implementation.
+//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming
+//products.
+//Telecom ParisTech retains full right to use the code for his/her own purpose,
+//assign or donate the code to a third party and to inhibit third parties from
+//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products.
+//
+//This copyright notice must be included in all copies or derivative works.
+//
+//Copyright (c) 2009.
+//
+// Alternatively, this software module may be redistributed and/or modified
+//  it under the terms of the GNU Lesser General Public License as published by
+//  the Free Software Foundation; either version 2, or (at your option)
+//  any later version.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+//     Authors:
+//                                     Jean Le Feuvre, Telecom ParisTech
+//                                     Cyril Concolato, Telecom ParisTech
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+#include "widgetman.h"
+
+#ifdef GPAC_HAS_SPIDERMONKEY
+
+#if !defined(__GNUC__)
+#  pragma comment(lib, "js32")
+#endif
+
+
+JSBool gf_sg_js_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node);
+JSBool gf_sg_js_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node);
+
+
+
+static Bool is_same_path(const char *p1, const char *p2, u32 len)
+{
+       char c1, c2;
+       u32 i=0;
+       do {
+               if (len && (i==len))
+                       break;
+               c1 = p1[i];
+               c2 = p2[i];
+               if (p1[i] != p2[i]) {
+                       if ((c1=='/') && (c2=='\\')) {}
+                       else if ((c1=='\\') && (c2=='/')) {}
+                       else return 0;
+               }
+               i++;
+       } while (c1);
+       return 1;
+}
+
+static void widget_package_extract_file(GF_WidgetPackage *wpack, GF_WidgetPackageResource *res)
+{
+       u32 i, count;
+
+       if (wpack->is_zip) {
+               unz_global_info gi;
+               unzFile uf = unzOpen2(wpack->package_path, NULL);
+               if (!uf) return;
+
+               unzGetGlobalInfo(uf, &gi);
+               for (i=0; i<gi.number_entry; i++)  {
+                       char buf[8192];
+                       int err;
+                       FILE *fout;
+                       char filename_inzip[256];
+
+                       unz_file_info file_info;
+                       unzGetCurrentFileInfo(uf, &file_info, filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+                       if (strcmp(res->inner_path, filename_inzip)) {
+                               if ((i+1)<gi.number_entry)
+                                       unzGoToNextFile(uf);
+                               continue;
+                       }
+
+                       unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/);
+
+                       fout=gf_f64_open(res->extracted_path, "wb");
+                       if (!fout) break;
+                       do {
+                               err = unzReadCurrentFile(uf,buf,8192);
+                               if (err<0) break;
+                               if (err>0)
+                                       if (gf_fwrite(buf,err,1,fout)!=1) {
+                                               err=UNZ_ERRNO;
+                                               break;
+                                       }
+                       } while (err>0);
+                       if (fout) fclose(fout);
+
+                       res->extracted = 1;
+                       break;
+               }
+               unzClose(uf);
+       } else {
+               GF_ISOFile *isom = gf_isom_open(wpack->package_path, GF_ISOM_OPEN_READ, 0);
+               if (!isom ) return;
+
+               count = gf_isom_get_meta_item_count(isom, 1, 0);
+               for (i=0; i<count; i++)  {
+                       u32 ID;
+                       const char *url, *urn, *enc;
+                       Bool self_ref;
+                       const char *item_name;
+
+                       gf_isom_get_meta_item_info(isom, 1, 0, i+1, &ID, NULL, &self_ref, &item_name, NULL, &enc, &url, &urn);
+                       if (strcmp(res->inner_path, item_name)) continue;
+
+                       gf_isom_extract_meta_item(isom, 1, 0, ID, res->extracted_path);
+                       res->extracted = 1;
+                       break;
+               }
+               gf_isom_close(isom);
+       }
+
+}
+
+static Bool package_find_res(GF_WidgetPackage *wpack, char *res_path, char *relocated_path, char *localized_rel_path)
+{
+       u32 count, i;
+       count = gf_list_count(wpack->resources);
+       for (i=0;i<count;i++) {
+               GF_WidgetPackageResource *pack_res = gf_list_get(wpack->resources, i);
+               if (is_same_path(res_path, pack_res->inner_path, 0)) {
+                       strcpy(localized_rel_path, res_path);
+                       strcpy(relocated_path, pack_res->extracted_path);
+                       if (!pack_res->extracted) widget_package_extract_file(wpack, pack_res);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/* Checks if a resource in the package has the given rel_path, potentially in a localized sub-folder */
+static Bool widget_package_relocate_uri(void *__self, const char *parent_uri, const char *rel_path, char *relocated_path, char *localized_rel_path)
+{
+       char path[GF_MAX_PATH];
+       const char *opt;
+       GF_WidgetPackage *wpack = (GF_WidgetPackage *)__self;
+
+       assert(parent_uri);
+       /*resource belongs to our archive*/
+       if (strstr(rel_path, wpack->archive_id)) {
+               rel_path = strstr(rel_path, wpack->archive_id) + strlen(wpack->archive_id);
+       }
+       /*parent resource belongs to our archive*/
+       else if (strstr(parent_uri, wpack->archive_id)) {
+       }
+       /*resource doesn't belong to our archive*/
+       else {
+               return 0;
+       }
+
+       /* First try to locate the resource in the locales folder */
+       opt = gf_cfg_get_key(wpack->wm->term->user->config, "Systems", "Language2CC");
+       if (opt) {
+               if (!strcmp(opt, "*") || !strcmp(opt, "un") )
+                       opt = NULL;
+       }
+
+       while (opt) {
+               char lan[100];
+               char *sep;
+               char *sep_lang = strchr(opt, ';');
+               if (sep_lang) sep_lang[0] = 0;
+
+               while (strchr(" \t", opt[0]))
+                       opt++;
+               strcpy(lan, opt);
+
+               if (sep_lang) {
+                       sep_lang[0] = ';';
+                       opt = sep_lang+1;
+               } else {
+                       opt = NULL;
+               }
+
+               while (1) {
+                       sep = strstr(lan, "-*");
+                       if (!sep) break;
+                       strncpy(sep, sep+2, strlen(sep)-2);
+               }
+
+               sprintf(path, "locales/%s/%s", lan, rel_path);
+               if (package_find_res(wpack, path, relocated_path, localized_rel_path))
+                       return 1;
+
+               /*recursively remove region (sub)tags*/
+               while (1) {
+                       sep = strrchr(lan, '-');
+                       if (!sep) break;
+                       sep[0] = 0;
+                       sprintf(path, "locales/%s/%s", lan, rel_path);
+                       if (package_find_res(wpack, path, relocated_path, localized_rel_path))
+                               return 1;
+               }
+       }
+
+       /*no locale*/
+       if (package_find_res(wpack, (char*)rel_path, relocated_path, localized_rel_path))
+               return 1;
+
+       strcpy(localized_rel_path, "");
+       strcpy(relocated_path, "");
+       return 0;
+}
+
+static GF_WidgetPackage *widget_isom_new(GF_WidgetManager *wm, const char *path)
+{
+       GF_WidgetPackageResource *pack_res;
+       char szPath[GF_MAX_PATH];
+       const char *dir;
+       GF_WidgetPackage *wzip;
+       u32 brand = 0;
+       u32 i, count;
+       GF_ISOFile *isom = gf_isom_open(path, GF_ISOM_OPEN_READ, 0);
+       if (!isom ) return NULL;
+
+       brand = gf_isom_get_meta_type(isom, 1, 0);
+       if ((brand!=GF_4CC('m','w','g','t') )           || !gf_isom_has_meta_xml(isom, 1, 0) ) {
+               gf_isom_close(isom);
+               return NULL;
+       }
+
+       GF_SAFEALLOC(wzip, GF_WidgetPackage);
+
+       wzip->wm = wm;
+       wzip->relocate_uri = widget_package_relocate_uri;
+       wzip->resources = gf_list_new();
+       dir = gf_cfg_get_key(wm->term->user->config, "General", "CacheDirectory");
+       /* create the extracted path for the package root using:
+          the cache dir + a CRC of the file path and the instance*/
+       sprintf(wzip->root_extracted_path, "%s%08X", path, (unsigned int)((unsigned long) wzip));
+       i = gf_crc_32((char *)wzip->root_extracted_path, strlen(wzip->root_extracted_path));
+       sprintf(wzip->archive_id, "GWM_%08X_", i);
+       sprintf(wzip->root_extracted_path, "%s/%s", dir, wzip->archive_id);
+
+
+       strcpy(szPath, wzip->root_extracted_path);
+       strcat(szPath, "config.xml");
+       if (gf_isom_extract_meta_xml(isom, 1, 0, szPath, NULL) != GF_OK) {
+               gf_list_del(wzip->resources);
+               gf_free(wzip);
+               gf_isom_close(isom);
+               return NULL;
+       }
+
+       wzip->package_path = gf_strdup(path);
+
+       GF_SAFEALLOC(pack_res, GF_WidgetPackageResource);
+       pack_res->extracted_path = gf_strdup(szPath);
+       pack_res->inner_path = gf_strdup("config.xml");
+       pack_res->extracted = 1;
+       gf_list_add(wzip->resources, pack_res);
+
+
+       count = gf_isom_get_meta_item_count(isom, 1, 0);
+       for (i=0; i<count; i++)  {
+               u32 ID;
+               const char *url, *urn, *enc;
+               Bool self_ref;
+               char *sep;
+               const char *item_name;
+
+               gf_isom_get_meta_item_info(isom, 1, 0, i+1, &ID, NULL, &self_ref, &item_name, NULL, &enc, &url, &urn);
+
+               sep = strrchr(item_name, '/');
+               if (!sep) sep = strrchr(item_name, '\\');
+               if (sep) {
+                       sep[0] = 0;
+                       sprintf(szPath, "%s_%08X_%s", wzip->root_extracted_path, gf_crc_32((char*)item_name, strlen(item_name)), sep+1);
+                       sep[0] = '/';
+               } else {
+                       strcpy(szPath, wzip->root_extracted_path);
+                       strcat(szPath, item_name);
+               }
+               GF_SAFEALLOC(pack_res, GF_WidgetPackageResource);
+               pack_res->extracted_path = gf_strdup(szPath);
+               pack_res->inner_path = gf_strdup(item_name);
+               pack_res->extracted = 0;
+               gf_list_add(wzip->resources, pack_res);
+       }
+       gf_isom_close(isom);
+
+
+       /* register this widget package as a relocator to enable localization of resources inside this package */
+       gf_mx_p(wm->term->net_mx);
+       gf_list_add(wm->term->uri_relocators, wzip);
+       gf_mx_v(wm->term->net_mx);
+       return wzip;
+}
+
+static GF_WidgetPackage *widget_zip_new(GF_WidgetManager *wm, const char *path)
+{
+       unz_global_info gi;
+       const char *dir;
+       u32 i;
+       GF_WidgetPackage *wzip;
+       unzFile uf = unzOpen2(path, NULL);
+       if (!uf) return NULL;
+
+       GF_SAFEALLOC(wzip, GF_WidgetPackage);
+
+       wzip->wm = wm;
+       wzip->is_zip = 1;
+       wzip->relocate_uri = widget_package_relocate_uri;
+       wzip->resources = gf_list_new();
+       wzip->package_path = gf_strdup(path);
+       dir = gf_cfg_get_key(wm->term->user->config, "General", "CacheDirectory");
+       /* create the extracted path for the package root using:
+          the cache dir + a CRC of the file path and the instance*/
+       sprintf(wzip->root_extracted_path, "%s%08X", path, (unsigned int)((unsigned long) wzip));
+       i = gf_crc_32((char *)wzip->root_extracted_path, strlen(wzip->root_extracted_path));
+       sprintf(wzip->archive_id, "GWM_%08X_", i);
+       sprintf(wzip->root_extracted_path, "%s/%s", dir, wzip->archive_id);
+
+       unzGetGlobalInfo(uf, &gi);
+       for (i=0; i<gi.number_entry; i++)  {
+               char szPath[GF_MAX_PATH];
+               char *sep;
+               GF_WidgetPackageResource *pack_res;
+               char filename_inzip[256];
+               unz_file_info file_info;
+               unzGetCurrentFileInfo(uf, &file_info, filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+               sep = strrchr(filename_inzip, '/');
+               if (!sep) sep = strrchr(filename_inzip, '\\');
+               if (sep) {
+                       sep[0] = 0;
+                       sprintf(szPath, "%s_%08X_%s", wzip->root_extracted_path, gf_crc_32(filename_inzip, strlen(filename_inzip)), sep+1);
+                       sep[0] = '/';
+               } else {
+                       strcpy(szPath, wzip->root_extracted_path);
+                       strcat(szPath, filename_inzip);
+               }
+
+
+               if (!strcmp(filename_inzip, "config.xml")) {
+                       int err;
+                       char buf[8192];
+                       FILE *fout;
+                       unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/);
+
+                       fout=gf_f64_open(szPath,"wb");
+                       if (!fout) return NULL;
+
+                       do {
+                               err = unzReadCurrentFile(uf,buf,8192);
+                               if (err<0) break;
+
+                               if (err>0)
+                                       if (gf_fwrite(buf,err,1,fout)!=1) {
+                                               err=UNZ_ERRNO;
+                                               break;
+                                       }
+                       } while (err>0);
+                       if (fout) fclose(fout);
+                       if (err==0) {
+                               GF_SAFEALLOC(pack_res, GF_WidgetPackageResource);
+                               pack_res->extracted_path = gf_strdup(szPath);
+                               pack_res->inner_path = gf_strdup(filename_inzip);
+                               pack_res->extracted = 1;
+                               gf_list_add(wzip->resources, pack_res);
+                       }
+               } else {
+                       GF_SAFEALLOC(pack_res, GF_WidgetPackageResource);
+                       pack_res->extracted_path = gf_strdup(szPath);
+                       pack_res->inner_path = gf_strdup(filename_inzip);
+                       pack_res->extracted = 0;
+                       gf_list_add(wzip->resources, pack_res);
+               }
+
+               if ((i+1)<gi.number_entry)
+            unzGoToNextFile(uf);
+       }
+       unzClose(uf);
+
+       /* register this widget package as a relocator to enable localization of resources inside this package */
+       gf_mx_p(wm->term->net_mx);
+       gf_list_add(wm->term->uri_relocators, wzip);
+       gf_mx_v(wm->term->net_mx);
+       return wzip;
+}
+
+GF_WidgetPackage *widget_package_new(GF_WidgetManager *wm, const char *path)
+{
+       if (gf_unzip_probe(path)) {
+               return widget_zip_new(wm, path);
+       }
+       /*ISOFF-based packaged widget */
+       else if (gf_isom_probe_file(path)) {
+               return widget_isom_new(wm, path);
+       }
+       return NULL;
+}
+
+static void widget_package_del(GF_WidgetManager *wm, GF_WidgetPackage *wpackage)
+{
+       gf_mx_p(wm->term->net_mx);
+       gf_list_del_item(wm->term->uri_relocators, wpackage);
+       gf_mx_v(wm->term->net_mx);
+
+       while (gf_list_count(wpackage->resources)) {
+               GF_WidgetPackageResource *wu = gf_list_get(wpackage->resources, 0);
+               gf_list_rem(wpackage->resources, 0);
+               gf_delete_file(wu->extracted_path);
+               gf_free(wu->extracted_path);
+               gf_free(wu->inner_path);
+               gf_free(wu);
+       }
+       gf_list_del(wpackage->resources);
+       if (wpackage->sess) gf_dm_sess_del(wpackage->sess);
+       gf_free(wpackage->package_path);
+       gf_free(wpackage);
+}
+
+
+
+static void wm_delete_message_param(GF_WidgetPin *mp)
+{
+       if (!mp) return;
+       if (mp->node) gf_free(mp->node);
+       if (mp->attribute) gf_free(mp->attribute);
+       if (mp->default_value) gf_free(mp->default_value);
+       if (mp->name) gf_free(mp->name);
+       gf_free(mp);
+}
+
+static void wm_delete_widget_content(GF_WidgetContent *content)
+{
+       if (!content) return;
+
+       while (gf_list_count(content->interfaces)) {
+                GF_WidgetInterface*ifce = gf_list_last(content->interfaces);
+                gf_list_rem_last(content->interfaces);
+
+                while (gf_list_count(ifce->messages)) {
+                       GF_WidgetMessage *msg = gf_list_last(ifce->messages);
+                       gf_list_rem_last(ifce->messages);
+
+                       while (gf_list_count(msg->params)) {
+                               GF_WidgetPin *par = gf_list_last(msg->params);
+                               gf_list_rem_last(msg->params);
+                               wm_delete_message_param(par);
+                       }
+                       gf_list_del(msg->params);
+
+                       wm_delete_message_param(msg->input_action);
+                       wm_delete_message_param(msg->output_trigger);
+                       gf_free(msg->name);
+                       gf_free(msg);
+               }
+               gf_list_del(ifce->messages);
+               wm_delete_message_param(ifce->bind_action);
+               wm_delete_message_param(ifce->unbind_action);
+               if (ifce->obj) gf_js_remove_root(ifce->content->widget->wm->ctx, &ifce->obj, GF_JSGC_OBJECT);
+
+               if (ifce->connectTo) gf_free(ifce->connectTo);
+               gf_free(ifce->type);
+               gf_free(ifce);
+       }
+       gf_list_del(content->interfaces);
+
+       while (gf_list_count(content->components)) {
+                GF_WidgetComponent *comp = gf_list_last(content->components);
+                gf_list_rem_last(content->components);
+
+                wm_delete_message_param(comp->activateTrigger);
+                wm_delete_message_param(comp->deactivateTrigger);
+
+                while (gf_list_count(comp->required_interfaces)) {
+                       char *type = gf_list_last(comp->required_interfaces);
+                       gf_list_rem_last(comp->required_interfaces);
+                       if (type) gf_free(type);
+                }
+                gf_list_del(comp->required_interfaces);
+                if (comp->id) gf_free(comp->id);
+                if (comp->src) gf_free(comp->src);
+                gf_free(comp);
+       }
+       gf_list_del(content->components);
+
+       while (gf_list_count(content->preferences)) {
+                GF_WidgetPreference *pref = gf_list_last(content->preferences);
+                gf_list_rem_last(content->preferences);
+
+                wm_delete_message_param(pref->connectTo);
+                if (pref->value) gf_free(pref->value);
+                gf_free(pref->name);
+                gf_free(pref);
+       }
+       gf_list_del(content->preferences);
+
+       wm_delete_message_param(content->saveTrigger);
+       wm_delete_message_param(content->restoreTrigger);
+       wm_delete_message_param(content->savedAction);
+       wm_delete_message_param(content->restoredAction);
+
+       gf_free(content->src);
+       gf_free(content->relocated_src);
+       gf_free(content->mimetype);
+       gf_free(content->encoding);
+       gf_free(content);
+}
+
+static void wm_delete_widget(GF_WidgetManager *wm, GF_Widget *wid)
+{
+       gf_list_del_item(wm->widgets, wid);
+
+       if (wid->url) gf_free(wid->url);
+       if (wid->manifest_path) gf_free(wid->manifest_path);
+       wm_delete_widget_content(wid->main);
+       if (wid->local_path) gf_free(wid->local_path);
+       if (wid->name) gf_free(wid->name);
+       if (wid->shortname) gf_free(wid->shortname);
+       if (wid->identifier) gf_free(wid->identifier);
+       if (wid->authorName) gf_free(wid->authorName);
+       if (wid->authorEmail) gf_free(wid->authorEmail);
+       if (wid->authorHref) gf_free(wid->authorHref);
+       if (wid->description) gf_free(wid->description);
+       if (wid->license) gf_free(wid->license);
+       if (wid->licenseHref) gf_free(wid->licenseHref);
+       if (wid->viewmodes) gf_free(wid->viewmodes);
+       if (wid->version) gf_free(wid->version);
+       if (wid->uuid) gf_free(wid->uuid);
+
+
+       while (gf_list_count(wid->icons)) {
+               GF_WidgetContent *icon = gf_list_get(wid->icons, 0);
+               gf_list_rem(wid->icons, 0);
+               wm_delete_widget_content(icon);
+       }
+       gf_list_del(wid->icons);
+
+       while (gf_list_count(wid->features)) {
+               GF_WidgetFeature *f = gf_list_get(wid->features, 0);
+               gf_list_rem(wid->features, 0);
+               if (f->name) gf_free(f->name);
+               while (gf_list_count(f->params)) {
+                       GF_WidgetFeatureParam *p = gf_list_get(f->params, 0);
+                       gf_list_rem(f->params, 0);
+                       if (p->name) gf_free(p->name);
+                       if (p->value) gf_free(p->value);
+                       gf_free(p);
+               }
+               gf_free(f);
+       }
+       gf_list_del(wid->features);
+
+       if (wid->wpack) widget_package_del(wm, wid->wpack);
+       gf_free(wid);
+}
+
+static void wm_delete_interface_instance(GF_WidgetManager *wm, GF_WidgetInterfaceInstance *bifce)
+{
+       if (bifce->hostname) gf_free(bifce->hostname);
+       if (bifce->obj) {
+               JS_SetPrivate(wm->ctx, bifce->obj, NULL);
+               gf_js_remove_root(wm->ctx, &bifce->obj, GF_JSGC_OBJECT);
+       }
+       gf_free(bifce);
+}
+
+static void wm_delete_widget_instance(GF_WidgetManager *wm, GF_WidgetInstance *widg)
+{
+
+       while (gf_list_count(widg->components)) {
+               GF_WidgetComponentInstance *comp = gf_list_get(widg->components, 0);
+               gf_list_rem(widg->components, 0);
+               if (comp->wid) wm_delete_widget_instance(wm, comp->wid);
+               gf_free(comp);
+       }
+       gf_list_del(widg->components);
+
+       while (gf_list_count(widg->bound_ifces)) {
+               GF_WidgetInterfaceInstance *bifce = gf_list_get(widg->bound_ifces, 0);
+               gf_list_rem(widg->bound_ifces, 0);
+               wm_delete_interface_instance(wm, bifce);
+       }
+       gf_list_del(widg->bound_ifces);
+
+       gf_list_del(widg->output_triggers);
+
+       if (widg->obj) {
+               JS_SetPrivate(wm->ctx, widg->obj, NULL);
+               gf_js_remove_root(wm->ctx, &widg->obj, GF_JSGC_OBJECT);
+       }
+       gf_list_del_item(wm->widget_instances, widg);
+       widg->widget->nb_instances--;
+       if (!widg->widget->nb_instances) wm_delete_widget(wm, widg->widget);
+
+       if (!widg->permanent) {
+               gf_cfg_del_section(wm->term->user->config, widg->secname);
+               gf_cfg_set_key(wm->term->user->config, "Widgets", widg->secname, NULL);
+       }
+       if (widg->mpegu_context) gf_xml_dom_del(widg->mpegu_context);
+
+       gf_free(widg);
+}
+
+
+
+static JSBool wm_widget_call_script(GF_WidgetInstance *wid, GF_WidgetPin *pin, uintN argc, jsval *argv, jsval *rval)
+{
+       jsval fval;
+       if (!wid->scene_context || !wid->scene_global) return JS_FALSE;
+
+       /*if on_load property is assigned to this widget, add an event listener on the root.*/
+       JS_LookupProperty(wid->scene_context, wid->scene_global, pin->node, &fval);
+       if (JSVAL_IS_OBJECT(fval)) {
+               JS_CallFunctionValue(wid->scene_context, wid->scene_global, fval, argc, argv, rval);
+       }
+       return JS_TRUE;
+}
+
+static JSBool wm_widget_set_scene_input_value(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, u32 type, GF_WidgetInstance *wid, GF_WidgetPin *param, const char *value)
+{
+       char *str_val;
+       GF_Node *n;
+       GF_FieldInfo info;
+       GF_WidgetMessage *msg;
+       GF_WidgetInterface *ifce;
+
+       if (!wid && obj) wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+       if (!wid->scene) return JS_TRUE;
+
+       if (!param) {
+               if (!JSVAL_IS_OBJECT(argv[0])) return JS_TRUE;
+
+               switch (type) {
+               /*set_input*/
+               case 0:
+                       if (argc!=2) return JS_FALSE;
+                       param = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+                       break;
+               /*call_input_action*/
+               case 1:
+                       msg = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+                       param = msg ? msg->input_action : NULL;
+                       break;
+               /*bind_interface*/
+               case 2:
+                       ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+                       param = ifce ? ifce->bind_action : NULL;
+                       break;
+               /*unbind_interface*/
+               case 3:
+                       ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+                       param = ifce ? ifce->unbind_action : NULL;
+                       break;
+               }
+       }
+
+       if (!param  || !param->node) return JS_TRUE;
+       /*this is a script call*/
+       if (!param->attribute) {
+               return wm_widget_call_script(wid, param, 0, NULL, rval);
+       }
+
+       n = gf_sg_find_node_by_name(wid->scene, param->node);
+       if (!n) return JS_TRUE;
+
+       if (param->in_action) return JS_TRUE;
+
+       param->in_action = 1;
+
+#ifndef GPAC_DISABLE_SVG
+       if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) {
+               u32 evt_type;
+               if (!type) {
+                       char *_str_val = NULL;
+                       if (value) {
+                               str_val = (char *)value;
+                       } else {
+                               if (!JSVAL_IS_STRING(argv[1])) goto exit;
+                               str_val = _str_val = SMJS_CHARS(c, argv[1]);
+                       }
+
+                       /* first check if the set_input refers to an attribute name or to an event name */
+                       evt_type = gf_dom_event_type_by_name(param->attribute);
+
+                       /*events are not allowed for <input> and <output>*/
+                       if (evt_type == GF_EVENT_UNKNOWN) {
+                               /* modify an attribute */
+                               if (!strcmp(param->attribute, "textContent")) {
+                                       gf_dom_set_textContent(n, (char *)str_val);
+                                       gf_node_changed(n, NULL);
+                               }
+                               else {
+                                       if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) {
+                                               gf_svg_parse_attribute(n, &info, (char *)str_val, 0);
+                                               if (info.fieldType==XMLRI_datatype) gf_node_dirty_set(n, GF_SG_SVG_XLINK_HREF_DIRTY, 0);
+                                               gf_node_changed(n, &info);
+                                       }
+                               }
+                       }
+                       SMJS_FREE(c, _str_val);
+
+               } else {
+                       GF_DOM_Event evt;
+                       memset(&evt, 0, sizeof(GF_DOM_Event));
+                       /* first check if the set_input refers to an attribute name or to an event name */
+                       evt_type = gf_dom_event_type_by_name(param->attribute);
+                       /* launch an event */
+                       if (evt_type != GF_EVENT_UNKNOWN) {
+                               evt.type = evt_type;
+                               gf_dom_event_fire(n, &evt);
+                       } else {
+                               /*should we fire a DOMAttrModified event ? to clarify in the spec*/
+
+                               if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) {
+                                       evt.bubbles = 1;
+                                       evt.type = GF_EVENT_ATTR_MODIFIED;
+                                       evt.attr = &info;
+                                       gf_dom_event_fire(n, &evt);
+                               }
+                       }
+               }
+       } else
+#endif
+
+
+#ifndef GPAC_DISABLE_VRML
+       {
+               if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) return JS_TRUE;
+
+               if (!type) {
+                       char *_str_val = NULL;
+                       jsdouble val;
+
+                       switch (info.fieldType) {
+                       case GF_SG_VRML_SFSTRING:
+                               if (value) {
+                                       str_val = (char *)value;
+                               } else {
+                                       if (!JSVAL_IS_STRING(argv[1]))goto exit;
+                                       str_val = SMJS_CHARS(c, argv[1]);
+                               }
+                               if ( ((SFString*)info.far_ptr)->buffer) gf_free(((SFString*)info.far_ptr)->buffer);
+                               ((SFString*)info.far_ptr)->buffer = str_val ? gf_strdup(str_val) : NULL;
+                               break;
+                       case GF_SG_VRML_SFBOOL:
+                               if (value) *((SFBool*)info.far_ptr) = (!strcmp(value, "true")) ? 1 : 0;
+                               else if (JSVAL_IS_BOOLEAN(argv[1])) *((SFBool*)info.far_ptr) = JSVAL_TO_BOOLEAN(argv[1]);
+                               else if (JSVAL_IS_INT(argv[1])) *((SFBool*)info.far_ptr) = JSVAL_TO_INT(argv[1]);
+                               else if (JSVAL_IS_STRING(argv[1])) {
+                                       str_val = SMJS_CHARS(c, argv[1]);
+                                       *((SFBool*)info.far_ptr) = (str_val && !strcmp(str_val, "true")) ? 1 : 0;
+                                       SMJS_FREE(c, str_val);
+                               } else
+                                       goto exit;
+                               break;
+                       case GF_SG_VRML_SFINT32:
+                               if (value) *((SFInt32*)info.far_ptr) = (s32) atof(value);
+                               else if (JSVAL_IS_INT(argv[1])) *((SFInt32*)info.far_ptr) = JSVAL_TO_INT(argv[1]);
+                               else if (JSVAL_IS_NUMBER(argv[1])) {
+                                       JS_ValueToNumber(c, argv[1], &val);
+                                       *((SFInt32*)info.far_ptr) = (s32) val;
+                               } else if (JSVAL_IS_STRING(argv[1])) {
+                                       Double a_val;
+                                       str_val = SMJS_CHARS(c, argv[1]);
+                                       a_val = str_val ? atof(str_val) : 0;
+                                       *((SFInt32*)info.far_ptr) = (s32) a_val;
+                                       SMJS_FREE(c, str_val);
+                               } else
+                                       goto exit;
+                               break;
+                       case GF_SG_VRML_SFFLOAT:
+                               if (value) *((SFFloat*)info.far_ptr) = FLT2FIX(atof(value));
+                               else if (JSVAL_IS_INT(argv[1])) *((SFFloat *)info.far_ptr) = INT2FIX( JSVAL_TO_INT(argv[1]) );
+                               else if (JSVAL_IS_NUMBER(argv[1])) {
+                                       JS_ValueToNumber(c, argv[1], &val);
+                                       *((SFFloat *)info.far_ptr) = FLT2FIX( val );
+                               } else if (JSVAL_IS_STRING(argv[1])) {
+                                       Double a_val;
+                                       str_val = SMJS_CHARS(c, argv[1]);
+                                       a_val = str_val ? atof(str_val) : 0;
+                                       *((SFFloat*)info.far_ptr) = FLT2FIX(a_val);
+                                       SMJS_FREE(c, str_val);
+                               } else
+                                       goto exit;
+                               break;
+                       case GF_SG_VRML_SFTIME:
+                               if (value) *((SFTime*)info.far_ptr) = atof(value);
+                               else if (JSVAL_IS_INT(argv[1])) *((SFTime *)info.far_ptr) = JSVAL_TO_INT(argv[1]);
+                               else if (JSVAL_IS_NUMBER(argv[1])) {
+                                       JS_ValueToNumber(c, argv[1], &val);
+                                       *((SFTime *)info.far_ptr) = val;
+                               } else if (JSVAL_IS_STRING(argv[1])) {
+                                       Double a_val;
+                                       str_val = SMJS_CHARS(c, argv[1]);
+                                       a_val = str_val ? atof(str_val) : 0;
+                                       *((SFTime *)info.far_ptr) = a_val;
+                                       SMJS_FREE(c, str_val);
+                               } else
+                                       goto exit;
+                               break;
+                       case GF_SG_VRML_MFSTRING:
+                               if (value) {
+                                       str_val = (char *)value;
+                               } else {
+                                       if (!JSVAL_IS_STRING(argv[1])) goto exit;
+                                       str_val = _str_val = SMJS_CHARS(c, argv[1]);
+                               }
+                               if ( ((GenMFField *)info.far_ptr)->count != 1) {
+                                       gf_sg_vrml_mf_reset(info.far_ptr, GF_SG_VRML_MFSTRING);
+                                       gf_sg_vrml_mf_alloc(info.far_ptr, GF_SG_VRML_MFSTRING, 1);
+                               }
+                               if ( ((MFString*)info.far_ptr)->vals[0]) gf_free( ((MFString*)info.far_ptr)->vals[0] );
+                               ((MFString*)info.far_ptr)->vals[0] = str_val ? gf_strdup(str_val) : NULL;
+
+                               SMJS_FREE(c, _str_val);
+                               break;
+                       }
+               }
+
+               //if this is a script eventIn call directly script
+               if ((n->sgprivate->tag==TAG_MPEG4_Script)
+#ifndef GPAC_DISABLE_X3D
+                               || (n->sgprivate->tag==TAG_X3D_Script)
+#endif
+                               ) 
+                       gf_sg_script_event_in(n, &info);
+
+               gf_node_changed(n, &info);
+
+               /*if this is an exposedField, route it*/
+               if (info.eventType==GF_SG_EVENT_EXPOSED_FIELD) {
+                       gf_node_event_out(n, info.fieldIndex);
+               }
+       }
+#endif /*GPAC_DISABLE_VRML*/
+
+exit:
+       param->in_action = 0;
+       return JS_TRUE;
+}
+
+
+static JSBool SMJS_FUNCTION(wm_widget_set_input)
+{
+       SMJS_OBJ
+       SMJS_ARGS
+       SMJS_DECL_RVAL
+       return wm_widget_set_scene_input_value(c, obj, argc, argv, rval, 0, NULL, NULL, NULL);
+}
+static JSBool SMJS_FUNCTION(wm_widget_call_input_action)
+{
+       SMJS_OBJ
+       SMJS_ARGS
+       SMJS_DECL_RVAL
+       return wm_widget_set_scene_input_value(c, obj, 1, argv, rval, 1, NULL, NULL, NULL);
+}
+
+
+static JSBool SMJS_FUNCTION(wm_widget_call_input_script)
+{
+       GF_WidgetMessage *msg;
+       GF_WidgetPin *param;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || (argc!=2) ) return JS_FALSE;
+       if (!wid->scene) return JS_TRUE;
+
+       if (!JSVAL_IS_OBJECT(argv[0])) return JS_TRUE;
+       msg = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+       param = msg ? msg->input_action : NULL;
+       if (!param || !param->node || param->attribute) return JS_FALSE;
+
+       if (JSVAL_IS_OBJECT(argv[1])) {
+               jsval *args;
+               JSObject *list = JSVAL_TO_OBJECT(argv[1]);
+               u32 i, count;
+               JS_GetArrayLength(c, list, (jsuint*) &count);
+               args = gf_malloc(sizeof(jsval)*count);
+               for (i=0; i<count; i++) {
+                       JS_GetElement(c, list, (jsint) i, &args[i] );
+               }
+
+               wm_widget_call_script(wid, param, count, args, SMJS_GET_RVAL);
+
+               gf_free(args);
+       }
+       return JS_TRUE;
+}
+
+
+static void wm_handler_destroy(GF_Node *node, void *rs, Bool is_destroy)
+{
+       if (is_destroy) {
+               SVG_handlerElement *handler = (SVG_handlerElement *)node;
+               if (handler->js_fun_val) {
+                       gf_js_remove_root(handler->js_context, &handler->js_fun_val, GF_JSGC_VAL);
+                       handler->js_fun_val=0;
+               }
+       }
+}
+
+static SVG_handlerElement *wm_create_scene_listener(GF_WidgetInstance *wid, GF_WidgetPin *param)
+{
+       /*FIXME - we need to split SVG and base DOM !!*/
+#ifdef GPAC_DISABLE_SVG
+       return NULL;
+#else
+       u32 evt_type, att_name;
+       GF_Node *listener;
+       GF_FieldInfo info;
+       GF_Node *n = NULL;
+       SVG_handlerElement *handler;
+
+       evt_type = GF_EVENT_ATTR_MODIFIED;
+       n = gf_sg_find_node_by_name(wid->scene, param->node);
+       if (!n) 
+               return NULL;
+
+       att_name = 0;
+
+#ifndef GPAC_DISABLE_SVG
+       if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) {
+               /* first check if the set_input refers to an attribute name or to an event name */
+               evt_type = gf_dom_event_type_by_name(param->attribute);
+               if (evt_type == GF_EVENT_UNKNOWN) {
+                       evt_type = GF_EVENT_ATTR_MODIFIED;
+
+                       /* modify textContent */
+                       if (!strcmp(param->attribute, "textContent")) {
+                               att_name = (u32) -1;
+                       }
+                       /* modify an attribute */
+                       else if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) {
+                               att_name = info.fieldIndex;
+                       }
+                       else {
+                               return NULL;
+                       }
+               }
+       } else
+#endif
+       {
+               if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK)
+                       return NULL;
+               att_name = info.fieldIndex;
+       }
+
+       listener = gf_node_new(wid->scene, TAG_SVG_listener);
+
+       handler = (SVG_handlerElement *) gf_node_new(wid->scene, TAG_SVG_handler);
+       /*we register the handler with the listener node to avoid modifying the DOM*/
+       gf_node_register((GF_Node *)handler, listener);
+       gf_node_list_add_child(& ((GF_ParentNode *)listener)->children, (GF_Node*)handler);
+       handler->sgprivate->UserCallback = wm_handler_destroy;
+
+       /*create attributes if needed*/
+       gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_event, 1, 0, &info);
+       ((XMLEV_Event*)info.far_ptr)->type = evt_type;
+       ((XMLEV_Event*)info.far_ptr)->parameter = att_name;
+       gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_handler, 1, 0, &info);
+       ((XMLRI*)info.far_ptr)->target = (GF_Node*)handler;
+       gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_target, 1, 0, &info);
+       ((XMLRI*)info.far_ptr)->target = n;
+
+       gf_node_get_attribute_by_tag((GF_Node*)handler, TAG_XMLEV_ATT_event, 1, 0, &info);
+       ((XMLEV_Event*)info.far_ptr)->type = evt_type;
+       ((XMLEV_Event*)info.far_ptr)->parameter = att_name;
+
+       gf_node_dom_listener_add((GF_Node *) n, listener);
+
+       return handler;
+#endif
+}
+
+static void wm_component_activation_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer, Bool unload)
+{
+       JSObject *obj;
+       JSContext *c;
+       GF_WidgetInstance *wid;
+       GF_WidgetComponent *comp;
+       SVG_handlerElement *handler = (SVG_handlerElement *)hdl;
+
+       c = handler->js_context;
+       obj = handler->evt_listen_obj;
+       if (!c || !obj) return;
+       wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return;
+
+       comp = (GF_WidgetComponent *)handler->js_fun;
+       if (unload) {
+               wm_deactivate_component(c, wid, comp, NULL);
+       } else {
+               wm_activate_component(c, wid, comp, 0);
+       }
+}
+static void wm_component_activate_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer)
+{
+       wm_component_activation_event(hdl, evt, observer, 0);
+}
+static void wm_component_deactivate_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer)
+{
+       wm_component_activation_event(hdl, evt, observer, 1);
+}
+
+static void wm_widget_set_pref_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer)
+{
+       char *att;
+       SVG_handlerElement *handler = (SVG_handlerElement *)hdl;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *) handler->evt_listen_obj;
+       GF_WidgetPreference *pref = (GF_WidgetPreference *) handler->js_fun;
+
+       if (evt->type != GF_EVENT_ATTR_MODIFIED) return;
+
+       if (evt->detail == (u32) -1) {
+               att = gf_dom_flatten_textContent(evt->target);
+       } else {
+               att = gf_node_dump_attribute(evt->target, evt->attr);
+               if (!att) return;
+       }
+       gf_cfg_set_key(wid->widget->wm->term->user->config, wid->secname, pref->name, att);
+       gf_free(att);
+}
+
+static void on_widget_activated(JSContext *c, JSObject *obj)
+{
+       jsval funval, rval;
+       u32 i, count;
+       GF_XMLNode *context = NULL;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || wid->activated) return;
+
+       /*widget is now activated*/
+       wid->activated = 1;
+
+       /*for all components, setup bindings on activateTrigger & deactivateTrigger*/
+       count = gf_list_count(wid->widget->main->components);
+       for (i=0; i<count; i++) {
+               GF_WidgetComponent *comp = gf_list_get(wid->widget->main->components, i);
+               /*setup listener*/
+               if (comp->activateTrigger && comp->activateTrigger->attribute) {
+                       SVG_handlerElement *a_hdl = wm_create_scene_listener(wid, comp->activateTrigger);
+                       if (!a_hdl) return;
+                       a_hdl->evt_listen_obj = obj;
+                       a_hdl->js_context = c;
+                       a_hdl->js_fun = comp;
+                       a_hdl->handle_event = wm_component_activate_event;
+               }
+               /*setup listener*/
+               if (comp->deactivateTrigger && comp->deactivateTrigger->attribute) {
+                       SVG_handlerElement *a_hdl = wm_create_scene_listener(wid, comp->deactivateTrigger);
+                       if (!a_hdl) continue;
+                       a_hdl->evt_listen_obj = obj;
+                       a_hdl->js_context = c;
+                       a_hdl->js_fun = comp;
+                       a_hdl->handle_event = wm_component_deactivate_event;
+               }
+       }
+
+       if (wid->mpegu_context)
+               context = gf_xml_dom_get_root(wid->mpegu_context);
+
+       /*load preferences*/
+       count = gf_list_count(wid->widget->main->preferences);
+       for (i=0; i<count; i++) {
+               const char *value;
+               GF_WidgetPreference *pref = gf_list_get(wid->widget->main->preferences, i);
+
+
+               /*get stored value for this preference*/
+               value = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, pref->name);
+               /*if none found, use preference*/
+               if (!value) value = pref->value;
+
+               /*and overload with migrated context*/
+               if (context) {
+                       GF_XMLNode *pref_node;
+                       u32 j=0;
+                       while ((pref_node = gf_list_enum(context->content, &j))) {
+                               const char *att;
+                               if (pref_node->type != GF_XML_NODE_TYPE) continue;
+                               if (strcmp(pref_node->name, "preference")) continue;
+                               att = wm_xml_get_attr(pref_node, "name");
+                               if (!att) continue;
+                               if (strcmp(att, pref->name)) continue;
+
+                               att = wm_xml_get_attr(pref_node, "value");
+                               if (att) value = att;
+                               break;
+                       }
+               }
+
+               if (pref->connectTo) {
+                       SVG_handlerElement *hdl;
+
+                       if (value)
+                               wm_widget_set_scene_input_value(NULL, NULL, 0, 0, 0, 0, wid, pref->connectTo, value);
+
+                       /*preference is read only, do not setup listener*/
+                       if (pref->flags & GF_WM_PREF_READONLY) continue;
+                       /*preference is migratable only, do not setup listener*/
+                       if (!(pref->flags & GF_WM_PREF_SAVE)) continue;
+
+                       /*create the listener*/
+                       hdl = wm_create_scene_listener(wid, pref->connectTo);
+                       if (!hdl) continue;
+
+                       hdl->evt_listen_obj = wid;
+                       hdl->js_fun = pref;
+                       hdl->handle_event = wm_widget_set_pref_event;
+
+               }
+       }
+       if (count && wid->widget->main->restoredAction) {
+               wm_widget_set_scene_input_value(wid->widget->wm->ctx, wid->obj, 0, NULL, &rval, 0, wid, wid->widget->main->restoredAction, NULL);
+       }
+
+       if (wid->mpegu_context) {
+               gf_xml_dom_del(wid->mpegu_context);
+               wid->mpegu_context = NULL;
+       }
+
+       gf_sg_lock_javascript(wid->widget->wm->ctx, 1);
+       /*refresh all interface bindings*/
+       JS_LookupProperty(wid->widget->wm->ctx, wid->widget->wm->obj, "check_bindings", &funval);
+       if (JSVAL_IS_OBJECT(funval)) {
+               JS_CallFunctionValue(wid->widget->wm->ctx, wid->widget->wm->obj, funval, 0, 0, &rval);
+       }
+
+       /*if on_load property is assigned to this widget, call it.*/
+       JS_LookupProperty(c, obj, "on_load", &funval);
+       if (JSVAL_IS_OBJECT(funval)) {
+               JS_CallFunctionValue(wid->widget->wm->ctx, wid->obj, funval, 0, 0, &rval);
+       }
+       gf_sg_lock_javascript(wid->widget->wm->ctx, 0);
+}
+
+
+static void wm_widget_load_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer)
+{
+       JSObject *obj;
+       JSContext *c;
+       SVG_handlerElement *handler = (SVG_handlerElement *)hdl;
+
+       c = handler->js_context;
+       obj = handler->evt_listen_obj;
+       if (!c || !obj) return;
+
+       on_widget_activated(c, obj);
+}
+
+
+static JSBool SMJS_FUNCTION(wm_widget_activate)
+{
+       SVG_handlerElement *handler;
+       GF_MediaObject *mo;
+       Bool direct_trigger = 0;
+       MFURL url;
+       SFURL _url;
+       GF_Node *inl;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !argc) return JS_FALSE;
+
+       if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;
+
+       inl = gf_sg_js_get_node(c, JSVAL_TO_OBJECT(argv[0]) );
+       if (!inl) return JS_FALSE;
+
+       _url.OD_ID = 0;
+       _url.url = gf_url_concatenate(wid->widget->url, wid->widget->main->relocated_src);
+       url.count = 1;
+       url.vals = &_url;
+       mo = gf_mo_register(inl, &url, 0, 1);
+       if (mo) {
+               wid->scene = gf_mo_get_scenegraph(mo);
+               if (wid->scene && gf_sg_get_root_node(wid->scene)) direct_trigger = 1;
+       }
+       if (_url.url) gf_free(_url.url);
+
+       wid->anchor = inl;
+
+       if (direct_trigger) {
+               on_widget_activated(c, obj);
+       } else {
+#ifndef GPAC_DISABLE_SVG
+               handler = gf_dom_listener_build(inl, GF_EVENT_SCENE_ATTACHED, 0);
+               handler->handle_event = wm_widget_load_event;
+               handler->js_context = c;
+               handler->evt_listen_obj = obj;
+#endif
+       }
+
+       return JS_TRUE;
+}
+
+
+static void wm_handle_dom_event(GF_Node *hdl, GF_DOM_Event *event, GF_Node *observer)
+{
+       GF_FieldInfo info;
+       GF_Node *n;
+       jsval argv[1], rval, jsfun;
+       SVG_handlerElement *handler = (SVG_handlerElement *) hdl;
+       GF_WidgetPin *param = handler->js_fun;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)handler->evt_listen_obj;
+
+       if (!wid->scene)
+               return;
+
+       n = gf_sg_find_node_by_name(wid->scene, param->node);
+       if (!n) return;
+
+       /*this is a regular event output*/
+       if (event->type != GF_EVENT_ATTR_MODIFIED) {
+               jsfun = (jsval) handler->js_fun_val;
+               if (JSVAL_IS_OBJECT(jsfun))
+                       JS_CallFunctionValue(handler->js_context, wid->obj, (jsval) handler->js_fun_val, 0, 0, &rval);
+               return;
+       }
+
+       /*otherwise this is a node.attr output through DOMAttributeModified*/
+       argv[0] = JSVAL_NULL;
+
+#ifndef GPAC_DISABLE_SVG
+       if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) {
+               if (!strcmp(param->attribute, "textContent")) {
+                       char *txt = gf_dom_flatten_textContent(n);
+                       argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(handler->js_context, txt ? txt : "") );
+                       if (txt) gf_free(txt);
+               } else if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) {
+                       char *attValue;
+                       if (event->attr->fieldIndex != info.fieldIndex) return;
+
+                       attValue = gf_node_dump_attribute(n, &info);
+                       argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(handler->js_context, attValue) );
+                       if (attValue) gf_free(attValue);
+               } else {
+                       return;
+               }
+       } else
+#endif
+       {
+               if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) return;
+               if (event->attr->fieldIndex != info.fieldIndex) return;
+
+               switch (info.fieldType) {
+               case GF_SG_VRML_SFSTRING:
+                       argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(handler->js_context, ((SFString*)info.far_ptr)->buffer ) );
+                       break;
+               case GF_SG_VRML_SFINT32:
+                       argv[0] = INT_TO_JSVAL( *((SFInt32*)info.far_ptr) );
+                       break;
+               case GF_SG_VRML_SFBOOL:
+                       argv[0] = BOOLEAN_TO_JSVAL( *((SFBool*)info.far_ptr) );
+                       break;
+               case GF_SG_VRML_SFFLOAT:
+                       argv[0] = DOUBLE_TO_JSVAL( JS_NewDouble(handler->js_context, FIX2FLT( *((SFFloat*)info.far_ptr) ) ) );
+                       break;
+               case GF_SG_VRML_SFTIME:
+                       argv[0] = DOUBLE_TO_JSVAL( JS_NewDouble(handler->js_context, *((SFTime *)info.far_ptr) ) );
+                       break;
+               }
+       }
+
+       jsfun = (jsval) handler->js_fun_val;
+       if (JSVAL_IS_OBJECT(jsfun))
+               JS_CallFunctionValue(handler->js_context, wid->obj, (jsval) handler->js_fun_val, 1, argv, &rval);
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_get_param_value)
+{
+       GF_Node *n;
+       GF_FieldInfo info;
+       GF_WidgetPin *param;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !wid->scene || !argc || !JSVAL_IS_OBJECT(argv[0]) ) return JS_FALSE;
+
+       param = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+       if (!param) return JS_FALSE;
+
+       if (!param->node) {
+               if (param->default_value) {
+                       SMJS_SET_RVAL( STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->default_value) ) );
+                       return JS_TRUE;
+               }
+               return JS_FALSE;
+       }
+
+       n = gf_sg_find_node_by_name(wid->scene, param->node);
+       if (!n) return JS_FALSE;
+
+#ifndef GPAC_DISABLE_SVG
+       if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) {
+               if (!strcmp(param->attribute, "textContent")) {
+                       char *txt = gf_dom_flatten_textContent(n);
+                       SMJS_SET_RVAL( STRING_TO_JSVAL( JS_NewStringCopyZ(c, txt ? txt : "") ));
+                       if (txt) gf_free(txt);
+               } else if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) {
+                       char *attValue = gf_node_dump_attribute(n, &info);
+                       SMJS_SET_RVAL( STRING_TO_JSVAL( JS_NewStringCopyZ(c, attValue) ));
+                       if (attValue) gf_free(attValue);
+               } else {
+                       return JS_FALSE;
+               }
+       } else
+#endif
+       {
+               if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) return JS_FALSE;
+
+               switch (info.fieldType) {
+               case GF_SG_VRML_SFSTRING:
+                       SMJS_SET_RVAL( STRING_TO_JSVAL( JS_NewStringCopyZ(c, ((SFString*)info.far_ptr)->buffer ) ) );
+                       break;
+               case GF_SG_VRML_SFINT32:
+                       SMJS_SET_RVAL( INT_TO_JSVAL( *((SFInt32*)info.far_ptr) ));
+                       break;
+               case GF_SG_VRML_SFBOOL:
+                       SMJS_SET_RVAL(BOOLEAN_TO_JSVAL( *((SFBool*)info.far_ptr) ));
+                       break;
+               case GF_SG_VRML_SFFLOAT:
+                       SMJS_SET_RVAL( DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT( *((SFFloat*)info.far_ptr) ) ) ));
+                       break;
+               case GF_SG_VRML_SFTIME:
+                       SMJS_SET_RVAL( DOUBLE_TO_JSVAL( JS_NewDouble(c, *((SFTime *)info.far_ptr) ) ));
+                       break;
+               }
+       }
+
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_get_message_param)
+{
+       GF_WidgetPin *par = NULL;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetMessage *msg = (GF_WidgetMessage *)JS_GetPrivate(c, obj);
+       if (!msg || !argc  ) return JS_FALSE;
+
+       if (JSVAL_IS_INT(argv[0])) {
+               u32 idx = JSVAL_TO_INT(argv[0]);
+               par = gf_list_get(msg->params, idx);
+       } else if (JSVAL_IS_STRING(argv[0])) {
+               u32 i, count = gf_list_count(msg->params);
+               char *name =  SMJS_CHARS(c, argv[0]);
+               for (i=0; i<count; i++) {
+                       par = gf_list_get(msg->params, i);
+                       if (!strcmp(par->name, name)) break;
+                       par = NULL;
+               }
+               SMJS_FREE(c, name);
+       }
+
+       if (par) {
+               JSObject *obj = JS_NewObject(c, &msg->ifce->content->widget->wm->widgetAnyClass, 0, 0);
+               JS_SetPrivate(c, obj, par);
+               JS_DefineProperty(c, obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, par->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, obj, "is_input", BOOLEAN_TO_JSVAL( (par->type == GF_WM_PARAM_OUTPUT) ? JS_FALSE : JS_TRUE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               switch (par->script_type) {
+               case GF_WM_PARAM_SCRIPT_BOOL:
+                       JS_DefineProperty(c, obj, "script_type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, "boolean") ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       break;
+               case GF_WM_PARAM_SCRIPT_NUMBER:
+                       JS_DefineProperty(c, obj, "script_type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, "number") ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       break;
+               case GF_WM_PARAM_SCRIPT_STRING:
+               default:
+                       JS_DefineProperty(c, obj, "script_type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, "string") ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       break;
+               }
+               SMJS_SET_RVAL( OBJECT_TO_JSVAL(obj) );
+       }
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_get_message)
+{
+       GF_WidgetMessage *msg;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInterface *ifce = (GF_WidgetInterface*)JS_GetPrivate(c, obj);
+       if (!ifce || !argc) return JS_FALSE;
+       msg = NULL;
+
+       if (JSVAL_IS_INT(argv[0])) {
+               u32 idx;
+               idx = JSVAL_TO_INT(argv[0]);
+               msg = gf_list_get(ifce->messages, idx);
+       } else if (JSVAL_IS_STRING(argv[0])) {
+               u32 i, count = gf_list_count(ifce->messages);
+               char *name = SMJS_CHARS(c, argv[0]);
+               for (i=0; i<count; i++) {
+                       msg = gf_list_get(ifce->messages, i);
+                       if (!strcmp(msg->name, name)) break;
+                       msg = NULL;
+               }
+               SMJS_FREE(c, name);
+       }
+       if (msg) {
+               JSObject *obj = JS_NewObject(c, &ifce->content->widget->wm->widgetAnyClass, 0, 0);
+               JS_SetPrivate(c, obj, msg);
+               JS_DefineProperty(c, obj, "num_params", INT_TO_JSVAL( gf_list_count(msg->params) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, msg->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, obj, "is_input", BOOLEAN_TO_JSVAL( msg->is_output ? JS_FALSE : JS_TRUE ) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, obj, "has_output_trigger", BOOLEAN_TO_JSVAL( msg->output_trigger ? JS_TRUE : JS_FALSE) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, obj, "has_input_action", BOOLEAN_TO_JSVAL( (msg->input_action && msg->input_action->attribute) ? JS_TRUE : JS_FALSE) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineProperty(c, obj, "has_script_input", BOOLEAN_TO_JSVAL( (msg->input_action && !msg->input_action->attribute) ? JS_TRUE : JS_FALSE) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+               JS_DefineFunction(c, obj, "get_param", wm_widget_get_message_param, 1, 0);
+
+               SMJS_SET_RVAL( OBJECT_TO_JSVAL(obj) );
+       }
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_get_component)
+{
+       char *comp_id;
+       u32 i, count;
+       GF_WidgetComponentInstance *comp_inst;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !argc || !JSVAL_IS_STRING(argv[0]) ) return JS_FALSE;
+
+       comp_id = SMJS_CHARS(c, argv[0]);
+       count = gf_list_count(wid->components);
+       for (i=0; i<count;i++) {
+               comp_inst = gf_list_get(wid->components, i);
+               if (comp_inst->comp->id && !strcmp(comp_inst->comp->id, comp_id)) {
+                       SMJS_SET_RVAL( OBJECT_TO_JSVAL(comp_inst->wid->obj) );
+                       SMJS_FREE(c, comp_id);
+                       return JS_TRUE;
+               }
+       }
+       /*if requested load the component*/
+       if ((argc==2) && JSVAL_IS_BOOLEAN(argv[1]) && (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ) {
+               count = gf_list_count(wid->widget->main->components);
+               for (i=0; i<count; i++) {
+                       GF_WidgetComponent *comp = gf_list_get(wid->widget->main->components, i);
+                       if (!comp->id  || strcmp(comp->id, comp_id)) continue;
+
+                       comp_inst = wm_activate_component(c, wid, comp, 1);
+                       if (comp_inst) {
+                               SMJS_SET_RVAL( OBJECT_TO_JSVAL(comp_inst->wid->obj) );
+                               SMJS_FREE(c, comp_id);
+                               return JS_TRUE;
+                       }
+                       SMJS_FREE(c, comp_id);
+                       return JS_TRUE;
+               }
+       }
+
+       SMJS_FREE(c, comp_id);
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_get_interface)
+{
+       u32 idx;
+       GF_WidgetInterface *ifce;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !argc || !JSVAL_IS_INT(argv[0]) ) return JS_FALSE;
+
+       idx = JSVAL_TO_INT(argv[0]);
+       ifce = gf_list_get(wid->widget->main->interfaces, idx);
+
+       if (ifce) {
+               if (!ifce->obj) {
+                       ifce->obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                       JS_SetPrivate(c, ifce->obj, ifce);
+                       JS_DefineProperty(c, ifce->obj, "num_messages", INT_TO_JSVAL( gf_list_count(ifce->messages) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       JS_DefineProperty(c, ifce->obj, "type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->type) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       JS_DefineProperty(c, ifce->obj, "serviceProvider", BOOLEAN_TO_JSVAL( ifce->provider ? JS_TRUE : JS_FALSE ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       JS_DefineProperty(c, ifce->obj, "multipleBinding", BOOLEAN_TO_JSVAL( ifce->multiple_binding ? JS_TRUE : JS_FALSE ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                       JS_DefineFunction(c, ifce->obj, "get_message", wm_widget_get_message, 1, 0);
+                       gf_js_add_root(c, &ifce->obj, GF_JSGC_OBJECT);
+               }
+               SMJS_SET_RVAL( OBJECT_TO_JSVAL(ifce->obj) );
+       }
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_bind_output_trigger)
+{
+       GF_WidgetMessage *msg;
+       GF_WidgetPin *param;
+       SVG_handlerElement *handler;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+
+       SMJS_SET_RVAL( BOOLEAN_TO_JSVAL(JS_FALSE) );
+       if (!wid || !wid->scene || (argc!=3)) return JS_TRUE;
+
+       if (!JSVAL_IS_OBJECT(argv[0])) return JS_TRUE;
+       if (!JSVAL_IS_OBJECT(argv[1])) return JS_TRUE;
+       if (!JSVAL_IS_OBJECT(argv[2])) return JS_TRUE;
+
+       msg = (GF_WidgetMessage *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]));
+       if (!msg) return JS_TRUE;
+       param = msg->output_trigger;
+       if (!param) return JS_TRUE;
+
+
+       handler = wm_create_scene_listener(wid, param);
+       if (!handler) return JS_TRUE;
+       handler->js_fun_val = * (u64 *) & argv[1];
+       gf_js_add_root(c, &handler->js_fun_val, GF_JSGC_VAL);
+       handler->evt_listen_obj = wid;
+       handler->js_fun = param;
+       handler->js_context = c;
+       handler->handle_event = wm_handle_dom_event;
+       handler->sgprivate->UserPrivate = JSVAL_TO_OBJECT(argv[2]);
+
+       gf_list_add(wid->output_triggers, handler);
+       SMJS_SET_RVAL( BOOLEAN_TO_JSVAL(JS_TRUE) );
+
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_get_context)
+{
+       GF_BitStream *bs;
+       u32 i, count;
+       const char *str;
+       char *att;
+       SMJS_OBJ
+       //SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+       if (!wid->scene) {
+               SMJS_SET_RVAL(JSVAL_NULL);
+               return JS_TRUE;
+       }
+
+       bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
+       str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<contextInformation xmlns=\"urn:mpeg:mpegu:schema:widgets:contextinfo:2010\">\n";
+       gf_bs_write_data(bs, (u8 *) str, strlen(str) );
+
+       count = gf_list_count(wid->widget->main->preferences);
+       for (i=0; i<count; i++) {
+                GF_WidgetPreference *pref = gf_list_get(wid->widget->main->preferences, i);
+
+               /*preference is read only, do not include in context*/
+               if (pref->flags & GF_WM_PREF_READONLY) continue;
+               /*preference is not migratable, do not include in context*/
+               if (!(pref->flags & GF_WM_PREF_MIGRATE)) continue;
+
+               str = " <preference name=\"";
+               gf_bs_write_data(bs, (u8 *) str, strlen(str) );
+
+               gf_bs_write_data(bs, (u8 *) pref->name, strlen(pref->name) );
+
+               str = "\" value=\"";
+               gf_bs_write_data(bs, (u8 *) str, strlen(str) );
+
+               /*read from node*/
+               if (pref->connectTo && pref->connectTo->attribute) {
+                       GF_FieldInfo info;
+                       GF_Node *n = gf_sg_find_node_by_name(wid->scene, pref->connectTo->node);
+                       if (n) {
+
+#ifndef GPAC_DISABLE_SVG
+                               if ((n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) && !strcmp(pref->connectTo->attribute, "textContent")) {
+                                       char *txt = gf_dom_flatten_textContent(n);
+                                       gf_bs_write_data(bs, (u8 *) txt, strlen(txt) );
+                               } else
+#endif
+                               if (gf_node_get_field_by_name(n, pref->connectTo->attribute, &info)==GF_OK) {
+                                       att = gf_node_dump_attribute(n, &info);
+                                       if (att) {
+                                               gf_bs_write_data(bs, (u8 *) att, strlen(att) );
+                                               gf_free(att);
+                                       }
+                               }
+                       }
+               }
+               /*read from config*/
+               else {
+                       att = (char *)gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, pref->name);
+                       if (!att) att = pref->value;
+
+                       if (att) gf_bs_write_data(bs, (u8 *) att, strlen(att) );
+               }
+
+               str = "\"/>\n";
+               gf_bs_write_data(bs, (u8 *) str, strlen(str) );
+       }
+       str = "</contextInformation>\n";
+       gf_bs_write_data(bs, (u8 *) str, strlen(str) );
+
+       gf_bs_write_u8(bs, 0);
+       att = NULL;
+       gf_bs_get_content(bs, &att, &count);
+       gf_bs_del(bs);
+
+       SMJS_SET_RVAL( STRING_TO_JSVAL( JS_NewStringCopyZ(c, att) ) );
+       gf_free(att);
+
+       return JS_TRUE;
+}
+
+
+static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
+{
+       JSString *s;
+       char *prop_name;
+       const char *opt;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       if (!SMJS_ID_IS_STRING(id)) return JS_TRUE;
+       prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id));
+       if (!prop_name) return JS_FALSE;
+
+       /*
+                       Manifest properties
+       */
+       if (!strcmp(prop_name, "manifest")) {
+               s = JS_NewStringCopyZ(c, wid->widget->manifest_path);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "url")) {
+               s = JS_NewStringCopyZ(c, wid->widget->local_path ? wid->widget->local_path : wid->widget->url);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "main")) {
+               s = JS_NewStringCopyZ(c, wid->widget->main->relocated_src);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "localizedSrc")) {
+               s = JS_NewStringCopyZ(c, wid->widget->main->src);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "mainEncoding")) {
+               s = JS_NewStringCopyZ(c, wid->widget->main->encoding);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "mainMimeType")) {
+               s = JS_NewStringCopyZ(c, wid->widget->main->mimetype);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "defaultWidth")) {
+               *vp = INT_TO_JSVAL(wid->widget->width);
+       }
+       else if (!strcmp(prop_name, "defaultHeight")) {
+               *vp = INT_TO_JSVAL(wid->widget->height);
+       }
+       else if (!strcmp(prop_name, "icons")) {
+               u32 i, count;
+               JSObject *arr;
+               count = gf_list_count(wid->widget->icons);
+               arr = JS_NewArrayObject(c, count, NULL);
+               for (i = 0; i<count; i++) {
+                       GF_WidgetContent *icon = gf_list_get(wid->widget->icons, i);
+                       if (icon) {
+                               char *abs_reloc_url;
+                               jsval icon_obj_val;
+                               JSObject *icon_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                               JS_SetPrivate(c, icon_obj, icon);
+                               JS_DefineProperty(c, icon_obj, "src", STRING_TO_JSVAL( JS_NewStringCopyZ(c, icon->src) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               if (strlen(icon->relocated_src)) abs_reloc_url = gf_url_concatenate(wid->widget->url, icon->relocated_src);
+                               else abs_reloc_url = gf_strdup("");
+                               JS_DefineProperty(c, icon_obj, "relocated_src", STRING_TO_JSVAL( JS_NewStringCopyZ(c, abs_reloc_url) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               JS_DefineProperty(c, icon_obj, "width", INT_TO_JSVAL( icon->width ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               JS_DefineProperty(c, icon_obj, "height", INT_TO_JSVAL( icon->height ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               icon_obj_val = OBJECT_TO_JSVAL(icon_obj);
+                               JS_SetElement(c, arr, i, &icon_obj_val);
+                               gf_free(abs_reloc_url);
+                       }
+               }
+               *vp = OBJECT_TO_JSVAL(arr);
+       }
+       else if (!strcmp(prop_name, "preferences")) {
+               u32 i, count;
+               JSObject *arr;
+               count = gf_list_count(wid->widget->main->preferences);
+               arr = JS_NewArrayObject(c, count, NULL);
+               for (i = 0; i<count; i++) {
+                       GF_WidgetPreference *pref = gf_list_get(wid->widget->main->preferences, i);
+                       if (pref) {
+                               jsval pref_obj_val;
+                               JSObject *pref_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                               JS_SetPrivate(c, pref_obj, pref);
+                               JS_DefineProperty(c, pref_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, pref->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               JS_DefineProperty(c, pref_obj, "value", STRING_TO_JSVAL( JS_NewStringCopyZ(c, pref->value) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               JS_DefineProperty(c, pref_obj, "readonly", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ((pref->flags & GF_WM_PREF_READONLY)?"true":"false")) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               pref_obj_val = OBJECT_TO_JSVAL(pref_obj);
+                               JS_SetElement(c, arr, i, &pref_obj_val);
+                       }
+               }
+               *vp = OBJECT_TO_JSVAL(arr);
+       }
+       else if (!strcmp(prop_name, "features")) {
+               u32 i, count;
+               JSObject *arr;
+               count = gf_list_count(wid->widget->features);
+               arr = JS_NewArrayObject(c, count, NULL);
+               for (i = 0; i<count; i++) {
+                       GF_WidgetFeature *feat = gf_list_get(wid->widget->features, i);
+                       if (feat) {
+                               jsval feat_obj_val;
+                               JSObject *feat_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                               JS_SetPrivate(c, feat_obj, feat);
+                               JS_DefineProperty(c, feat_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, feat->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               JS_DefineProperty(c, feat_obj, "required", BOOLEAN_TO_JSVAL( (feat->required? JS_TRUE : JS_FALSE) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               {
+                                       u32 j, pcount;
+                                       JSObject *params_arr;
+                                       pcount = gf_list_count(feat->params);
+                                       params_arr = JS_NewArrayObject(c, pcount, NULL);
+                                       for (j=0; j < pcount; j++) {
+                                               GF_WidgetFeatureParam *param = gf_list_get(feat->params, j);
+                                               JSObject *param_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0);
+                                               jsval param_obj_val;
+                                               JS_SetPrivate(c, param_obj, param);
+                                               JS_DefineProperty(c, param_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                                               JS_DefineProperty(c, param_obj, "value", STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->value) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                                               param_obj_val = OBJECT_TO_JSVAL(param_obj);
+                                               JS_SetElement(c, params_arr, j, &param_obj_val);
+                                       }
+                                       JS_DefineProperty(c, feat_obj, "params", OBJECT_TO_JSVAL(params_arr), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
+                               }
+                               feat_obj_val = OBJECT_TO_JSVAL(feat_obj);
+                               JS_SetElement(c, arr, i, &feat_obj_val);
+                       }
+               }
+               *vp = OBJECT_TO_JSVAL(arr);
+       }
+
+       else if (!strcmp(prop_name, "components")) {
+               u32 i, count;
+               jsval val;
+               JSObject *arr;
+               count = gf_list_count(wid->components);
+               arr = JS_NewArrayObject(c, count, NULL);
+               for (i = 0; i<count; i++) {
+                       GF_WidgetComponentInstance *comp = gf_list_get(wid->components, i);
+                       val = OBJECT_TO_JSVAL(comp->wid->obj);
+                       JS_SetElement(c, arr, i, &val);
+               }
+               *vp = OBJECT_TO_JSVAL(arr);
+       }
+       else if (!strcmp(prop_name, "identifier")) {
+               s = JS_NewStringCopyZ(c, wid->widget->identifier);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "name")) {
+               s = JS_NewStringCopyZ(c, wid->widget->name);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "shortName")) {
+               s = JS_NewStringCopyZ(c, wid->widget->shortname);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "authorName")) {
+               s = JS_NewStringCopyZ(c, wid->widget->authorName);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "authorEmail")) {
+               s = JS_NewStringCopyZ(c, wid->widget->authorEmail);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "authorHref")) {
+               s = JS_NewStringCopyZ(c, wid->widget->authorHref);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "description")) {
+               s = JS_NewStringCopyZ(c, wid->widget->description);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "viewmodes")) {
+               if (wid->widget->viewmodes) s = JS_NewStringCopyZ(c, wid->widget->viewmodes);
+               else s = JS_NewStringCopyZ(c, "");
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "license")) {
+               s = JS_NewStringCopyZ(c, wid->widget->license);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "licenseHref")) {
+               s = JS_NewStringCopyZ(c, wid->widget->licenseHref);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "version")) {
+               s = JS_NewStringCopyZ(c, wid->widget->version);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "uuid")) {
+               s = JS_NewStringCopyZ(c, wid->widget->uuid);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "discardable")) {
+               *vp = BOOLEAN_TO_JSVAL( wid->widget->discardable ? JS_TRUE : JS_FALSE);
+       }
+       else if (!strcmp(prop_name, "multipleInstances")) {
+               *vp = BOOLEAN_TO_JSVAL( wid->widget->multipleInstance ? JS_TRUE : JS_FALSE);
+       }
+
+       /*
+                       Widget Manager special properties (common to all implementations)
+       */
+       else if (!strcmp(prop_name, "permanent")) {
+               *vp = BOOLEAN_TO_JSVAL( wid->permanent ? JS_TRUE : JS_FALSE);
+       }
+       else if (!strcmp(prop_name, "is_component")) {
+               *vp = BOOLEAN_TO_JSVAL( wid->parent ? JS_TRUE : JS_FALSE);
+       }
+       else if (!strcmp(prop_name, "parent")) {
+               *vp = wid->parent ? OBJECT_TO_JSVAL(wid->parent->obj) : JSVAL_NULL;
+       }
+       else if (!strcmp(prop_name, "activated")) {
+               *vp = BOOLEAN_TO_JSVAL( wid->activated ? JS_TRUE : JS_FALSE);
+       }
+       else if (!strcmp(prop_name, "section")) {
+               s = JS_NewStringCopyZ(c, wid->secname);
+               *vp = STRING_TO_JSVAL(s);
+       }
+       else if (!strcmp(prop_name, "num_instances")) {
+               *vp = INT_TO_JSVAL( wid->widget->nb_instances);
+       }
+       else if (!strcmp(prop_name, "num_interfaces")) {
+               *vp = INT_TO_JSVAL( gf_list_count(wid->widget->main->interfaces));
+       }
+       else if (!strcmp(prop_name, "num_components")) {
+               *vp = INT_TO_JSVAL( gf_list_count(wid->components));
+       }
+       else if (!strcmp(prop_name, "num_bound_interfaces")) {
+               *vp = INT_TO_JSVAL( gf_list_count(wid->bound_ifces));
+       }
+       /*all variables used by the WidgetManager script but not stored*/
+       else if (!strcmp(prop_name, "originating_device_ip")
+               || !strcmp(prop_name, "originating_device")
+               || !strcmp(prop_name, "device")
+       ) {
+       }
+       /*
+                       Widget properties, common to each implementation
+       */
+       else {
+               char szName[1024];
+               sprintf(szName, "WM:%s", prop_name);
+               opt = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, szName);
+               if (opt) {
+                       Double val=0;
+                       if (!strcmp(opt, "true")) *vp = BOOLEAN_TO_JSVAL(JS_TRUE);
+                       else if (!strcmp(opt, "false")) *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
+                       else if (sscanf(opt, "%lf", &val)==1) {
+                               *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, val) );
+                       } else {
+                               s = JS_NewStringCopyZ(c, opt);
+                               *vp = STRING_TO_JSVAL(s);
+                       }
+               }
+       }
+       SMJS_FREE(c, prop_name);
+       return JS_TRUE;
+}
+static JSBool wm_widget_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
+{
+       char szVal[32];
+       jsdouble val;
+       char *prop_name;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       if (!SMJS_ID_IS_STRING(id)) return JS_TRUE;
+       prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id));
+
+       /*internal to WidgetManager, never stored*/
+       if (!strcmp(prop_name, "permanent")) {
+               wid->permanent = (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? 1 : 0;
+       }
+
+       /*any widget properties*/
+       else {
+               char szName[1024], *value, *_val = NULL;
+
+               if (JSVAL_IS_STRING(*vp)) {
+                       value = _val = SMJS_CHARS(c, *vp);
+                       if (!value) value = "";
+               }
+               else if (JSVAL_IS_BOOLEAN(*vp)) {
+                       strcpy(szVal, (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? "true" : "false");
+                       value = szVal;
+               }
+               else if (JSVAL_IS_NUMBER(*vp)) {
+                       JS_ValueToNumber(c, *vp, &val);
+                       sprintf(szVal, "%f", val);
+                       value = szVal;
+               } else {
+                       SMJS_FREE(c, prop_name);
+                       return JS_TRUE;
+               }
+
+               sprintf(szName, "WM:%s", prop_name);
+               gf_cfg_set_key(wid->widget->wm->term->user->config, wid->secname, szName, value);
+               SMJS_FREE(c, _val);
+       }
+
+       SMJS_FREE(c, prop_name);
+       return JS_TRUE;
+}
+
+
+
+static JSBool wm_widget_bind_interface_ex(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, Bool is_unbind)
+{
+       u32 i, count;
+       GF_WidgetInterfaceInstance *bifce;
+       GF_WidgetInterface *ifce;
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !wid->scene) return JS_FALSE;
+
+       ifce = NULL;
+       if (argc) {
+               if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE;
+               ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+               if (!ifce) return JS_FALSE;
+       }
+
+       if (!is_unbind) {
+               char *hostname;
+               JSObject *cookie;
+               if ((argc<3) || !JSVAL_IS_OBJECT(argv[1]) || !JSVAL_IS_STRING(argv[2])) return JS_FALSE;
+
+               cookie = JSVAL_TO_OBJECT(argv[1]);
+               hostname = SMJS_CHARS(c, argv[2]);
+               count = gf_list_count(wid->bound_ifces);
+               for (i=0; i<count; i++) {
+                       bifce = gf_list_get(wid->bound_ifces, i);
+                       if (!strcmp(bifce->ifce->type, ifce->type) && (bifce->cookie==cookie) ) {
+                               SMJS_FREE(c, hostname);
+                               return JS_TRUE;
+                       }
+               }
+               GF_SAFEALLOC(bifce, GF_WidgetInterfaceInstance);
+               bifce->wid = wid;
+               bifce->ifce = ifce;
+               bifce->cookie = cookie;
+               bifce->hostname = gf_strdup(hostname);
+               SMJS_FREE(c, hostname);
+               gf_list_add(wid->bound_ifces, bifce);
+
+               if (ifce->bind_action) {
+                       return wm_widget_set_scene_input_value(c, obj, 1, argv, rval, 2, NULL, NULL, NULL);
+               } else {
+                       widget_on_interface_bind(bifce, 0);
+               }
+       } else {
+               JSObject *cookie = NULL;
+               if ((argc==2) && JSVAL_IS_OBJECT(argv[1])) cookie = JSVAL_TO_OBJECT(argv[1]);
+
+               count = gf_list_count(wid->bound_ifces);
+               for (i=0; i<count; i++) {
+                       bifce = gf_list_get(wid->bound_ifces, i);
+                       if (!ifce || ( !strcmp(bifce->ifce->type, ifce->type) && (bifce->cookie==cookie)) ) {
+                               gf_list_rem(wid->bound_ifces, i);
+                               if (bifce->ifce->unbind_action) {
+                                       wm_widget_set_scene_input_value(c, NULL, 0, NULL, rval, 3, wid, bifce->ifce->unbind_action, NULL);
+                               } else {
+                                       widget_on_interface_bind(bifce, 1);
+                               }
+                               if (ifce) {
+                                       /*unregister our message handlers*/
+                                       count = gf_list_count(wid->output_triggers);
+                                       for (i=0; i<count; i++) {
+                                               u32 j, c2, found;
+                                               GF_DOMHandler *handler = gf_list_get(wid->output_triggers, i);
+                                               GF_WidgetPin *param = handler->js_fun;
+
+                                               if (handler->sgprivate->UserPrivate != cookie) continue;
+                                               found = 0;
+                                               c2 = gf_list_count(bifce->ifce->messages);
+                                               for (j=0; j<c2; j++) {
+                                                       GF_WidgetMessage *msg = gf_list_get(bifce->ifce->messages, j);
+                                                       if (msg->output_trigger == param) {
+                                                               found = 1;
+                                                               break;
+                                                       }
+                                               }
+                                               if (found) {
+                                                       GF_Node *listener = handler->sgprivate->parents->node;
+                                                       gf_dom_listener_del(listener, listener->sgprivate->UserPrivate);
+                                                       gf_list_rem(wid->output_triggers, i);
+                                                       i--;
+                                                       count--;
+                                               }
+                                       }
+                               }
+                               wm_delete_interface_instance(wid->widget->wm, bifce);
+                               if (ifce) return JS_TRUE;
+                               i--;
+                               count--;
+                       }
+               }
+       }
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_bind_interface)
+{
+       SMJS_OBJ
+       SMJS_ARGS
+       SMJS_DECL_RVAL
+       return wm_widget_bind_interface_ex(c, obj, argc, argv, rval, 0);
+}
+static JSBool SMJS_FUNCTION(wm_widget_unbind_interface)
+{
+       SMJS_OBJ
+       SMJS_ARGS
+       SMJS_DECL_RVAL
+       return wm_widget_bind_interface_ex(c, obj, argc, argv, rval, 1);
+}
+
+
+static JSBool SMJS_FUNCTION(wm_widget_deactivate)
+{
+       u32 i, count;
+       jsval funval;
+       SMJS_OBJ
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid) return JS_FALSE;
+
+       /*widget is a component of another widget, unregister*/
+       if (wid->parent) {
+               GF_WidgetInstance *par_wid = wid->parent;
+               count = gf_list_count(par_wid->components);
+               for (i=0; i<count; i++) {
+                       GF_WidgetComponentInstance *comp = gf_list_get(par_wid->components, i);
+                       if (comp->wid == wid) {
+                               gf_list_rem(par_wid->components, i);
+                               gf_free(comp);
+                               break;
+                       }
+               }
+               wid->parent = NULL;
+       }
+
+       /*remove all components*/
+       while (gf_list_count(wid->components)) {
+               GF_WidgetComponentInstance *comp = gf_list_get(wid->components, 0);
+               wm_deactivate_component(c, wid, NULL, comp);
+               gf_list_rem(wid->components, 0);
+       }
+
+       /*mark the widget as deactivated, so it is no longer valid when checking all widgets bindings*/
+       wid->activated = 0;
+
+       /*unbind existing widgets*/
+       JS_LookupProperty(wid->widget->wm->ctx, wid->widget->wm->obj, "unbind_widget", &funval);
+       if (JSVAL_IS_OBJECT(funval)) {
+               jsval an_argv[1];
+               an_argv[0] = OBJECT_TO_JSVAL(obj);
+               JS_CallFunctionValue(wid->widget->wm->ctx, wid->widget->wm->obj, funval, 1, an_argv, SMJS_GET_RVAL );
+       }
+
+       /*unbind all interfaces of this widget*/
+       wm_widget_bind_interface_ex(c, obj, 0, NULL, SMJS_GET_RVAL, 1);
+
+       /*detach scene now that all unbind events have been sent*/
+       wid->scene = NULL;
+       return JS_TRUE;
+}
+
+
+static void wm_widget_jsbind(GF_WidgetManager *wm, GF_WidgetInstance *wid)
+{
+       if (wid->obj)
+               return;
+       wid->obj = JS_NewObject(wm->ctx, &wm->wmWidgetClass, 0, 0);
+       JS_SetPrivate(wm->ctx, wid->obj, wid);
+       /*protect from GC*/
+       gf_js_add_root(wm->ctx, &wid->obj, GF_JSGC_OBJECT);
+}
+
+void wm_deactivate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, GF_WidgetComponentInstance *comp_inst)
+{
+       jsval fval, rval;
+
+       if (!comp_inst) {
+               u32 i=0;
+               while ((comp_inst = gf_list_enum(wid->components, &i))) {
+                       if (comp_inst->comp == comp) break;
+                       comp_inst = NULL;
+               }
+       }
+       if (!comp_inst) return;
+
+       if ((JS_LookupProperty(c, wid->widget->wm->obj, "on_widget_remove", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) {
+               jsval argv[1];
+               argv[0] = OBJECT_TO_JSVAL(comp_inst->wid->obj);
+               JS_CallFunctionValue(wid->widget->wm->ctx, wid->obj, fval, 1, argv, &rval);
+       }
+}
+
+GF_WidgetComponentInstance *wm_activate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, Bool skip_wm_notification)
+{
+       u32 i, count;
+       const char *fun_name = NULL;
+       jsval fval, rval;
+       GF_WidgetComponentInstance *comp_inst;
+       GF_WidgetInstance *comp_wid;
+
+       comp_wid = NULL;
+       if (comp->src) {
+               char *url = gf_url_concatenate(wid->widget->url, comp->src);
+
+               count = gf_list_count(wid->widget->wm->widget_instances);
+               for (i=0; i<count; i++) {
+                       comp_wid = gf_list_get(wid->widget->wm->widget_instances, i);
+                       if (!strcmp(comp_wid->widget->url, url) && !comp_wid->parent) break;
+                       comp_wid = NULL;
+               }
+               if (!comp_wid) {
+                       comp_wid = wm_load_widget(wid->widget->wm, url, 0, 0);
+                       if (comp_wid) comp_wid->permanent = 0;
+               }
+               gf_free(url);
+       }
+       if (!comp_wid) return NULL;
+
+       if (!comp_wid->activated)
+               fun_name = "on_widget_add";
+
+       GF_SAFEALLOC(comp_inst, GF_WidgetComponentInstance);
+       comp_inst->comp = comp;
+       comp_inst->wid = comp_wid;
+       comp_wid->parent = wid;
+
+       gf_list_add(wid->components, comp_inst);
+
+       if (!comp_inst->wid->obj) wm_widget_jsbind(wid->widget->wm, comp_inst->wid);
+
+       if (!skip_wm_notification && fun_name && (JS_LookupProperty(c, wid->widget->wm->obj, fun_name, &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) {
+               jsval argv[1];
+               argv[0] = OBJECT_TO_JSVAL(comp_inst->wid->obj);
+               JS_CallFunctionValue(wid->widget->wm->ctx, wid->obj, fval, 1, argv, &rval);
+       }
+       if (comp_inst) return comp_inst;
+       return NULL;
+}
+
+static JSBool SMJS_FUNCTION(wm_widget_is_interface_bound)
+{
+       u32 i, count;
+       JSObject *cookie;
+       GF_WidgetInterface *ifce;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj);
+       if (!wid || !wid->scene || (argc<1) || !JSVAL_IS_OBJECT(argv[0]) ) return JS_FALSE;
+
+       ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+       if (!ifce) return JS_FALSE;
+       cookie = NULL;
+       if ((argc==2) && JSVAL_IS_OBJECT(argv[1]) )
+               cookie = JSVAL_TO_OBJECT(argv[1]);
+
+       SMJS_SET_RVAL(BOOLEAN_TO_JSVAL(JS_FALSE));
+       count = gf_list_count(wid->bound_ifces);
+       for (i=0; i<count; i++) {
+               GF_WidgetInterfaceInstance *bifce = gf_list_get(wid->bound_ifces, i);
+               if (!strcmp(bifce->ifce->type, ifce->type) && (!cookie || (bifce->cookie==cookie))) {
+                       SMJS_SET_RVAL( BOOLEAN_TO_JSVAL(JS_TRUE) );
+                       break;
+               }
+       }
+       return JS_TRUE;
+}
+
+
+static JSBool SMJS_FUNCTION(wm_load)
+{
+       u32 i, count;
+       char *manifest, *url, *widget_ctx;
+       GF_WidgetInstance *wid;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+       if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE;
+
+       manifest = SMJS_CHARS(c, argv[0]);
+
+       url = NULL;
+       if ((argc==2) && ! JSVAL_IS_NULL(argv[1]) && JSVAL_IS_OBJECT(argv[1])) {
+               GF_WidgetInstance *parent_widget;
+               if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[1]), &wm->wmWidgetClass, NULL) ) return JS_FALSE;
+               parent_widget = (GF_WidgetInstance *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[1]) );
+               
+               if (parent_widget->widget->url) url = gf_url_concatenate(parent_widget->widget->url, manifest);
+       }
+
+       widget_ctx = NULL;
+       if ((argc==3) && !JSVAL_IS_NULL(argv[2]) && JSVAL_IS_STRING(argv[2])) {
+               widget_ctx = SMJS_CHARS(c, argv[2]);
+       }
+
+       if (!url) {
+               url = gf_strdup(manifest);
+       }
+
+       wid=NULL;
+       count = gf_list_count(wm->widget_instances);
+       for (i=0; i<count; i++) {
+               wid = gf_list_get(wm->widget_instances, i);
+               if (!strcmp(wid->widget->url, url) && !wid->activated) break;
+               wid = NULL;
+       }
+       if (!wid) {
+               wid = wm_load_widget(wm, url, 0, 1);
+       }
+       if (url) gf_free(url);
+
+       /*parse context if any*/
+       if (wid && wid->mpegu_context) {
+               gf_xml_dom_del(wid->mpegu_context);
+               wid->mpegu_context = NULL;
+       }
+       if (wid && widget_ctx && strlen(widget_ctx)) {
+               GF_Err e;
+               GF_XMLNode *context = NULL;
+               wid->mpegu_context = gf_xml_dom_new();
+               e = gf_xml_dom_parse_string(wid->mpegu_context, widget_ctx);
+               if (!e) {
+                       context = gf_xml_dom_get_root(wid->mpegu_context);
+                       if (strcmp(context->name, "contextInformation")) context = NULL;
+               } else {
+               }
+
+               if (!context && wid->mpegu_context) {
+                       gf_xml_dom_del(wid->mpegu_context);
+                       wid->mpegu_context = NULL;
+               }
+       }
+
+       if (wid) {
+               wm_widget_jsbind(wm, wid);
+               SMJS_SET_RVAL(OBJECT_TO_JSVAL(wid->obj));
+       }
+       SMJS_FREE(c, manifest);
+       SMJS_FREE(c, widget_ctx);
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_unload)
+{
+       GF_WidgetInstance *wid;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+       if (!argc || !JSVAL_IS_OBJECT(argv[0])) return JS_TRUE;
+
+       if (!JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &wm->wmWidgetClass, NULL) ) return JS_FALSE;
+       wid = (GF_WidgetInstance *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) );
+       if (!wid) return JS_TRUE;
+
+       /*unless explecetely requested, remove the section*/
+       if ((argc!=2) || !JSVAL_IS_BOOLEAN(argv[1]) || (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ) {
+               /*create section*/
+               gf_cfg_del_section(wm->term->user->config, wid->secname);
+               gf_cfg_set_key(wm->term->user->config, "Widgets", wid->secname, NULL);
+       }
+       wm_delete_widget_instance(wm, wid);
+       return JS_TRUE;
+}
+
+
+
+static JSBool wm_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp)
+{
+       char *prop_name;
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+       if (!wm) return JS_FALSE;
+
+       if (!SMJS_ID_IS_STRING(id)) return JS_TRUE;
+       prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id));
+       if (!prop_name) return JS_FALSE;
+
+       if (!strcmp(prop_name, "num_widgets")) {
+               *vp = INT_TO_JSVAL(gf_list_count(wm->widget_instances));
+       }
+       else if (!strcmp(prop_name, "last_widget_dir")) {
+               const char *opt = gf_cfg_get_key(wm->term->user->config, "Widgets", "last_widget_dir");
+               if (!opt) opt = "/";
+               *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, opt));
+       }
+       SMJS_FREE(c, prop_name);
+       return JS_TRUE;
+}
+static JSBool wm_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp)
+{
+       char *prop_name;
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+       if (!wm) return JS_FALSE;
+
+       if (!JSVAL_IS_STRING(*vp)) return JS_TRUE;
+       if (!SMJS_ID_IS_STRING(id)) return JS_TRUE;
+       prop_name = SMJS_CHARS_FROM_STRING(c, SMJS_ID_TO_STRING(id));
+
+       if (!strcmp(prop_name, "last_widget_dir")) {
+               char *v = SMJS_CHARS(c, *vp);
+               gf_cfg_set_key(wm->term->user->config, "Widgets", "last_widget_dir", v);
+               SMJS_FREE(c, v);
+       }
+       SMJS_FREE(c, prop_name);
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_get)
+{
+       u32 i;
+       GF_WidgetInstance *wid;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+       if (!argc || !JSVAL_IS_INT(argv[0])) return JS_TRUE;
+
+       i = JSVAL_TO_INT(argv[0]);
+       wid = gf_list_get(wm->widget_instances, i);
+       if (wid) SMJS_SET_RVAL( OBJECT_TO_JSVAL(wid->obj) );
+       return JS_TRUE;
+}
+
+static JSBool SMJS_FUNCTION(wm_find_interface)
+{
+       char *ifce_name;
+       u32 i;
+       GF_WidgetInstance *wid;
+       SMJS_OBJ
+       SMJS_ARGS
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+       if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE;
+
+       ifce_name = SMJS_CHARS(c, argv[0]);
+       i=0;
+       while ( (wid = gf_list_enum(wm->widget_instances, &i) )) {
+               u32 j=0;
+               GF_WidgetInterface *wid_ifce;
+               while ((wid_ifce = gf_list_enum(wid->widget->main->interfaces, &j))) {
+                       if (!strcmp(wid_ifce->type, ifce_name)) {
+                               SMJS_SET_RVAL( OBJECT_TO_JSVAL(wid->obj) );
+                               SMJS_FREE(c, ifce_name);
+                               return JS_TRUE;
+                       }
+               }
+       }
+       SMJS_FREE(c, ifce_name);
+       return JS_TRUE;
+}
+
+
+const char *wm_xml_get_attr(GF_XMLNode *root, const char *name)
+{
+
+       u32 i, count;
+       count = gf_list_count(root->attributes);
+       for (i=0; i<count; i++) {
+               char *sep;
+               GF_XMLAttribute *att = gf_list_get(root->attributes, i);
+               if (!att->name) continue;
+               if (!strcmp(att->name, name)) return att->value;
+               sep = strchr(att->name, ':');
+               if (sep && !strcmp(sep+1, name)) return att->value;
+       }
+       return NULL;
+}
+
+/* TODO Implement real language check according to BCP 47*/
+static Bool wm_check_language(const char *xml_lang_value, const char *user_locale)
+{
+       Bool ret = 0;
+       char *sep, *val;
+       val = (char*)xml_lang_value;
+       while (!ret) {
+               sep = strchr(val, ';');
+               if (sep) sep[0] = 0;
+               if (strstr(user_locale, val)) ret = 1;
+               if (sep) {
+                       sep[0] = ';';
+                       val = sep+1;
+               } else {
+                       break;
+               }
+       }
+       return ret;
+}
+
+static GF_XMLNode *wm_xml_find(GF_XMLNode *root, const char *ns_prefix, const char *name, const char *user_locale)
+{
+       GF_XMLNode *localized = NULL;
+       GF_XMLNode *non_localized = NULL;
+       u32 i, count;
+
+       if (!root) return NULL;
+
+       count = gf_list_count(root->content);
+       for (i=0; i<count; i++) {
+               GF_XMLNode *n = gf_list_get(root->content, i);
+               if (n->type==GF_XML_NODE_TYPE && n->name && !strcmp(n->name, name) && ((!ns_prefix && !n->ns) || (ns_prefix && n->ns && !strcmp(ns_prefix, n->ns)))) {
+                       const char *lang = wm_xml_get_attr(n, "xml:lang");
+                       if (!lang) {
+                               if (!non_localized) non_localized = n;
+                       } else {
+                               if (user_locale && wm_check_language(lang, user_locale) && !localized) localized = n;
+                       }
+               }
+       }
+       if (localized) return localized;
+       else return non_localized;
+}
+
+static GF_WidgetPin *wm_parse_pin(const char *value, u16 type, const char *pin_name, const char *scriptType, const char *default_value)
+{
+       GF_WidgetPin *pin;
+       char *sep;
+
+       if (!value && !scriptType && !default_value) return NULL;
+
+       GF_SAFEALLOC(pin, GF_WidgetPin);
+       pin->type = type;
+       if (pin_name) pin->name = gf_strdup(pin_name);
+
+       if (value) {
+               sep = strrchr(value, '.');
+               if (!sep && (type==GF_WM_PREF_CONNECT)) {
+                       gf_free(pin);
+                       return NULL;
+               }
+
+               /*node.event || node.attribute*/
+               if (sep) {
+                       sep[0] = 0;
+                       pin->node = gf_strdup(value);
+                       pin->attribute = gf_strdup(sep+1);
+                       sep[0] = '.';
+               }
+               /*script function*/
+               else {
+                       pin->node = gf_strdup(value);
+               }
+       }
+
+       if (scriptType) {
+               if (!strcmp(scriptType, "boolean")) pin->script_type = GF_WM_PARAM_SCRIPT_BOOL;
+               else if (!strcmp(scriptType, "number")) pin->script_type = GF_WM_PARAM_SCRIPT_NUMBER;
+       } else if (default_value) {
+               pin->default_value = gf_strdup(default_value);
+       }
+       return pin;
+}
+
+static void wm_parse_mpegu_content_element(GF_WidgetContent *content, GF_XMLNode *root, const char *ns_prefix, GF_List *global_prefs)
+{
+       GF_XMLNode *ifces, *context, *pref_node;
+       GF_WidgetMessage *msg;
+       GF_WidgetInterface *ifce;
+       GF_XMLNode *ifce_node;
+       GF_WidgetPreference *pref;
+       const char *att;
+       u32 i = 0;
+
+       ifces = wm_xml_find(root, ns_prefix, "interfaces", NULL);
+       if (ifces) {
+
+               /*get all interface element*/
+               while ((ifce_node = gf_list_enum(ifces->content, &i))) {
+                       GF_XMLNode *msg_node;
+                       u32 j;
+                       const char *ifce_type, *act;
+                       if (ifce_node->type != GF_XML_NODE_TYPE) continue;
+                       if (strcmp(ifce_node->name, "interface")) continue;
+                       ifce_type = wm_xml_get_attr(ifce_node, "type");
+                       if (!ifce_type) continue;
+
+                       GF_SAFEALLOC(ifce, GF_WidgetInterface);
+                       ifce->type = gf_strdup(ifce_type);
+                       ifce->messages = gf_list_new();
+                       ifce->content = content;
+                       gf_list_add(content->interfaces, ifce);
+
+                       act = wm_xml_get_attr(ifce_node, "serviceProvider");
+                       if (act && !strcmp(act, "true")) ifce->provider = 1;
+
+                       act = wm_xml_get_attr(ifce_node, "multipleBindings");
+                       if (act && !strcmp(act, "true")) ifce->multiple_binding = 1;
+
+                       act = wm_xml_get_attr(ifce_node, "required");
+                       if (act && !strcmp(act, "true")) ifce->required = 1;
+
+                       act = wm_xml_get_attr(ifce_node, "connectTo");
+                       if (act) ifce->connectTo = gf_strdup(act);
+
+                       act = wm_xml_get_attr(ifce_node, "bindAction");
+                       if (act) {
+                               ifce->bind_action = wm_parse_pin(act, GF_WM_BIND_ACTION, NULL, NULL, NULL);
+                       }
+                       act = wm_xml_get_attr(ifce_node, "unbindAction");
+                       if (act) {
+                               ifce->unbind_action = wm_parse_pin(act, GF_WM_UNBIND_ACTION, NULL, NULL, NULL);
+                       }
+
+                       j=0;
+                       while ((msg_node = gf_list_enum(ifce_node->content, &j))) {
+                               u32 k;
+                               GF_XMLNode *par_node;
+                               const char *msg_name, *action;
+                               if (msg_node->type != GF_XML_NODE_TYPE) continue;
+                               if (strcmp(msg_node->name, "messageIn") && strcmp(msg_node->name, "messageOut")) continue;
+
+                               msg_name = wm_xml_get_attr(msg_node, "name");
+                               if (!msg_name) continue;
+                               GF_SAFEALLOC(msg, GF_WidgetMessage);
+                               msg->name = gf_strdup(msg_name);
+                               msg->params = gf_list_new();
+                               msg->ifce = ifce;
+                               if (!strcmp(msg_node->name, "messageOut")) msg->is_output = 1;
+
+                               gf_list_add(ifce->messages, msg);
+
+                               /*get inputAction*/
+                               action = wm_xml_get_attr(msg_node, "inputAction");
+                               if (action) {
+                                       msg->input_action = wm_parse_pin(action, GF_WM_INPUT_ACTION, NULL, NULL, NULL);
+                               }
+
+                               /*get outputTrigger*/
+                               action = wm_xml_get_attr(msg_node, "outputTrigger");
+                               if (action) {
+                                       msg->output_trigger = wm_parse_pin(action, GF_WM_OUTPUT_TRIGGER, NULL, NULL, NULL);
+                               }
+
+                               /*get params*/
+                               k=0;
+                               while ((par_node=gf_list_enum(msg_node->content, &k))) {
+                                       GF_WidgetPin *wpin;
+                                       u16 type;
+                                       const char *par_name, *att_name;
+                                       if (par_node->type != GF_XML_NODE_TYPE) continue;
+                                       if (strcmp(par_node->name, "input") && strcmp(par_node->name, "output")) continue;
+
+
+                                       par_name = wm_xml_get_attr(par_node, "name");
+                                       /*invalid param, discard message*/
+                                       if (!par_name) {
+                                               gf_list_del_item(ifce->messages, msg);
+                                               gf_list_del(msg->params);
+                                               gf_free(msg->name);
+                                               gf_free(msg);
+                                               break;
+                                       }
+
+                                       if (!strcmp(par_node->name, "output")) {
+                                               type = GF_WM_PARAM_OUTPUT;
+                                               att_name = wm_xml_get_attr(par_node, "attributeModified");
+                                       } else {
+                                               type = GF_WM_PARAM_INPUT;
+                                               att_name = wm_xml_get_attr(par_node, "setAttribute");
+                                       }
+                                       wpin = wm_parse_pin(att_name, type, par_name, wm_xml_get_attr(par_node, "scriptParamType"), wm_xml_get_attr(par_node, "default"));
+                                       if (!wpin) continue;
+                                       wpin->msg = msg;
+
+                                       gf_list_add(msg->params, wpin);
+                               }
+                       }
+               }
+       }
+
+       /*get all component elements*/
+       i=0;
+       while (root && (ifce_node = gf_list_enum(root->content, &i))) {
+               GF_XMLNode *req_node;
+               u32 j;
+               const char *src, *id, *act;
+               GF_WidgetComponent *comp;
+               if (ifce_node->type != GF_XML_NODE_TYPE) continue;
+               if (strcmp(ifce_node->name, "component")) continue;
+               src = wm_xml_get_attr(ifce_node, "src");
+               id = wm_xml_get_attr(ifce_node, "id");
+
+               GF_SAFEALLOC(comp, GF_WidgetComponent);
+               comp->required_interfaces = gf_list_new();
+               comp->content = content;
+               if (id) comp->id = gf_strdup(id);
+               if (src) comp->src = gf_strdup(src);
+               j=0;
+               while ((req_node=gf_list_enum(ifce_node->content, &j))) {
+                       const char *ifce_type;
+                       if (req_node->type != GF_XML_NODE_TYPE) continue;
+                       if (strcmp(req_node->name, "requiredInterface")) continue;
+                       ifce_type = wm_xml_get_attr(req_node, "type");
+                       if (!ifce_type) continue;
+                       gf_list_add(comp->required_interfaces, gf_strdup(ifce_type));
+               }
+
+               act = wm_xml_get_attr(ifce_node, "activateTrigger");
+               if (act) comp->activateTrigger = wm_parse_pin(act, GF_WM_ACTIVATE_TRIGGER, NULL, NULL, NULL);
+               act = wm_xml_get_attr(ifce_node, "deactivateTrigger");
+               if (act) comp->deactivateTrigger = wm_parse_pin(act, GF_WM_DEACTIVATE_TRIGGER, NULL, NULL, NULL);
+
+               gf_list_add(content->components, comp);
+       }
+
+       /*clone global prefs for this content*/
+       i=0;
+       while ((pref = gf_list_enum(global_prefs, &i))) {
+               GF_WidgetPreference *apref;
+               GF_SAFEALLOC(apref, GF_WidgetPreference);
+               apref->name = gf_strdup(pref->name);
+               if (pref->value) apref->value = gf_strdup(pref->value);
+               apref->flags = pref->flags;
+               gf_list_add(content->preferences, apref);
+       }
+
+       context = wm_xml_find(root, ns_prefix, "contextConfiguration", NULL);
+       if (context) {
+               u32 j;
+               /*get all preference elements*/
+               i=0;
+               while ((pref_node = gf_list_enum(context->content, &i))) {
+                       const char *att;
+                       if (pref_node->type != GF_XML_NODE_TYPE) continue;
+                       if (strcmp(pref_node->name, "preferenceConnect")) continue;
+                       att = wm_xml_get_attr(pref_node, "name");
+                       if (!att) continue;
+
+                       j=0;
+                       while ((pref = gf_list_enum(content->preferences, &j))) {
+                               if (!strcmp(pref->name, att) && !pref->connectTo) break;
+                       }
+
+                       if (!pref) {
+                               GF_SAFEALLOC(pref, GF_WidgetPreference);
+                               pref->name = gf_strdup(att);
+                               gf_list_add(content->preferences, pref);
+                       }
+                       att = wm_xml_get_attr(pref_node, "value");
+                       if (att) {
+                               if (pref->value) gf_free(pref->value);
+                               pref->value = gf_strdup(att);
+                       }
+                       att = wm_xml_get_attr(pref_node, "readOnly");
+                       if (att && !strcmp(att, "true")) pref->flags |= GF_WM_PREF_READONLY;
+                       att = wm_xml_get_attr(pref_node, "migratable");
+                       if (att && !strcmp(att, "saveOnly")) pref->flags |= GF_WM_PREF_SAVE;
+                       else if (att && !strcmp(att, "migrateOnly")) pref->flags |= GF_WM_PREF_MIGRATE;
+                       else pref->flags |= GF_WM_PREF_SAVE | GF_WM_PREF_MIGRATE;
+
+                       att = wm_xml_get_attr(pref_node, "connectTo");
+                       if (att) pref->connectTo = wm_parse_pin(att, GF_WM_PREF_CONNECT, NULL, NULL, NULL);
+               }
+
+               att = wm_xml_get_attr(context, "savedAction");
+               if (att) content->savedAction = wm_parse_pin(att, GF_WM_PREF_SAVEDACTION, NULL, NULL, NULL);
+               att = wm_xml_get_attr(context, "restoredAction");
+               if (att) content->restoredAction = wm_parse_pin(att, GF_WM_PREF_RESTOREDACTION, NULL, NULL, NULL);
+               att = wm_xml_get_attr(context, "saveTrigger");
+               if (att) content->saveTrigger = wm_parse_pin(att, GF_WM_PREF_SAVETRIGGER, NULL, NULL, NULL);
+               att = wm_xml_get_attr(context, "restoreTrigger");
+               if (att) content->restoreTrigger = wm_parse_pin(att, GF_WM_PREF_RESTORETRIGGER, NULL, NULL, NULL);
+       }
+}
+
+/* Implements the W3C P&C rule for getting a single attribute value
+   see http://www.w3.org/TR/widgets/#rule-for-getting-a-single-attribute-valu0
+   should be different from getting normalized text but for now it's ok
+   */
+static char *wm_get_single_attribute(const char *input) {
+       u32 i, j, len;
+       char *output;
+       Bool first_space_copied;
+
+       if (!input) return gf_strdup("");
+
+       len = strlen(input);
+       output = gf_malloc(len+1);
+
+       first_space_copied = 1;
+       j = 0;
+       for (i = 0; i<len; i++) {
+               switch (input[i]) {
+                       case ' ':
+                       case '\t':
+                       case '\r':
+                       case '\n':
+                               if (!first_space_copied) {
+                                       output[j] = ' ';
+                                       j++;
+                                       first_space_copied = 1;
+                               }
+                               break;
+                       default:
+                               output[j] = input[i];
+                               j++;
+                               first_space_copied = 0;
+               }
+       }
+       if (j && output[j-1] == ' ') output[j-1] = 0;
+       output[j] = 0;
+       return output;
+}
+
+/* Implements the W3C P&C rule for getting a single attribute value
+   see http://www.w3.org/TR/widgets/#rule-for-getting-a-single-attribute-valu0 */
+static u32 wm_parse_non_neg(const char *input) {
+       u32 result = 0;
+       if (strlen(input) && !strchr(input, '-')) {
+               if (sscanf(input, "%u", &result) != 1) result = 0;
+       }
+       return result;
+}
+
+/* returns the localized concatenated text content
+see http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-textContent
+and http://www.w3.org/TR/widgets/#rule-for-getting-text-content0
+*/
+static char *wm_get_text_content(GF_XMLNode *node, char *inherited_locale, const char *user_locale) {
+       if (node->type == GF_XML_TEXT_TYPE) {
+               if (node->name) return gf_strdup(node->name);
+               else return gf_strdup("");
+       } else {
+               char *xml_lang = (char *)wm_xml_get_attr(node, "xml:lang");
+               if (!xml_lang) xml_lang = inherited_locale;
+               /*
+               if (xml_lang && user_locale && wm_check_language(xml_lang, user_locale))
+               */
+               {
+                       u32 i, count;
+                       char *text_content;
+                       u32 text_content_len = 0;
+                       text_content = gf_strdup("");
+                       count = gf_list_count(node->content);
+                       for (i=0; i<count; i++) {
+                               GF_XMLNode *child = (GF_XMLNode *)gf_list_get(node->content, i);
+                               char *child_content = wm_get_text_content(child, xml_lang, user_locale);
+                               u32 child_content_len = strlen(child_content);
+                               text_content = gf_realloc(text_content, text_content_len+child_content_len+1);
+                               memcpy(text_content+text_content_len, child_content, child_content_len);
+                               text_content[text_content_len+child_content_len] = 0;
+                               text_content_len+=child_content_len;
+                               gf_free(child_content);
+                       }
+                       return text_content;
+               }
+               /*
+               } else {
+                       return gf_strdup("");
+               */
+       }
+}
+
+static char *wm_get_normalized_text_content(GF_XMLNode *node, char *inherited_locale, const char *user_locale) {
+       char *text_content, *result;
+       /* first aggregate text content */
+       text_content = wm_get_text_content(node, inherited_locale, user_locale);
+       /* calling normalization of text content */
+       result = wm_get_single_attribute(text_content);
+       gf_free(text_content);
+       return result;
+}
+
+/* When relocating resources over HTTP, we check if the resources for a given locale exists
+  on the server by sending a HEAD message with an Accept-Language header. */
+void wm_relocate_proc(void *usr_cbk, GF_NETIO_Parameter *parameter)
+{
+       switch (parameter->msg_type) {
+       case GF_NETIO_GET_METHOD:
+               parameter->name = "HEAD";
+               break;
+       }
+}
+
+/* relocate the given resource name (res_name) using registered relocators (e.g. locales, package folder)
+   The result is the path of the file, possibly uncompressed, possibly localized.
+   The parameter widget_path provides the path for converting relative resource paths into absolute paths.*/
+static Bool wm_relocate_url(GF_WidgetManager *wm, const char *widget_path, const char *res_name, char *relocated_name, char *localized_res_name)
+{
+       Bool ok = 0;
+       char *res_url;
+       Bool result = gf_term_relocate_url(wm->term, res_name, widget_path, relocated_name, localized_res_name);
+       if (result) return result;
+
+       res_url = gf_url_concatenate(widget_path, res_name);
+
+       /*try with HTTP HEAD */
+       if (!strnicmp(widget_path, "http", 4)) {
+               GF_Err e;
+               /*fetch the remote widget manifest synchronously and load it */
+               GF_DownloadSession *sess = gf_dm_sess_new(wm->term->downloader, (char *)res_url, GF_NETIO_SESSION_NOT_THREADED, wm_relocate_proc, NULL, &e);
+               if (sess) {
+                       e = gf_dm_sess_process(sess);
+                       gf_dm_sess_del(sess);
+                       if (e==GF_OK) {
+                               const char *opt = gf_cfg_get_key(wm->term->user->config, "Systems", "Language2CC");
+                               strcpy(relocated_name, res_url);
+                               if (opt)
+                                       sprintf(localized_res_name, "%s/%s", opt, res_name);
+                               else
+                                       strcpy(localized_res_name, res_name);
+                               ok = 1;
+                       }
+               }
+       }
+       gf_free(res_url);
+       return ok;
+}
+
+/* function that checks if the default start file exists in the widget (package or folder)
+   according to the default start files table from the W3C P&C spec.
+   The widget path attribute is used to get the associated relocator from the registered relocators */
+static void wm_set_default_start_file(GF_WidgetManager *wm, GF_WidgetContent *content, const char *widget_path) {
+       Bool result;
+       char localized_path[GF_MAX_PATH], relocated_path[GF_MAX_PATH];
+       char *mimetype = "text/html";
+       result = wm_relocate_url(wm, widget_path, "index.htm", relocated_path, localized_path);
+       if (result) {
+               mimetype = "text/html";
+       } else {
+               result = wm_relocate_url(wm, widget_path, "index.html", relocated_path, localized_path);
+               if (result) {
+                       mimetype = "text/html";
+               } else {
+                       result = wm_relocate_url(wm, widget_path, "index.svg", relocated_path, localized_path);
+                       if (result) {
+                               mimetype = "image/svg+xml";
+                       } else {
+                               result = wm_relocate_url(wm, widget_path, "index.xhtml", relocated_path, localized_path);
+                               if (result) {
+                                       mimetype = "application/xhtml+xml";
+                               } else {
+                                       result = wm_relocate_url(wm, widget_path, "index.xht", relocated_path, localized_path);
+                                       if (result) mimetype = "application/xhtml+xml";
+                               }
+                       }
+               }
+       }
+       if (content->src) gf_free(content->src);
+       content->src = gf_strdup(localized_path);
+       if (content->relocated_src) gf_free(content->relocated_src);
+       content->relocated_src = gf_strdup(relocated_path);
+       if (content->mimetype) gf_free(content->mimetype);
+       content->mimetype = gf_strdup(mimetype);
+       if (content->encoding) gf_free(content->encoding);
+       content->encoding = gf_strdup("utf-8");
+}
+
+static GF_WidgetContent *wm_add_icon(GF_Widget *widget, const char *icon_relocated_path, const char *icon_localized_path, const char *uri_fragment)
+{
+       GF_WidgetContent *icon;
+       u32 i, count;
+       Bool already_in = 0;
+
+       count = gf_list_count(widget->icons);
+       for (i =0; i<count; i++) {
+               GF_WidgetContent *in_icon = gf_list_get(widget->icons, i);
+               if (!strcmp(icon_localized_path, in_icon->src)) {
+                       already_in = 1;
+                       break;
+               }
+       }
+       if (already_in) return NULL;
+
+       GF_SAFEALLOC(icon, GF_WidgetContent);
+       if (uri_fragment) {
+               icon->src = gf_malloc(strlen(icon_localized_path) + strlen(uri_fragment) + 1);
+               strcpy(icon->src, icon_localized_path);
+               strcat(icon->src, uri_fragment);
+
+               icon->relocated_src = gf_malloc(strlen(icon_relocated_path) + strlen(uri_fragment) + 1);
+               strcpy(icon->relocated_src, icon_relocated_path);
+               strcat(icon->relocated_src, uri_fragment);
+       } else {
+               icon->src = gf_strdup(icon_localized_path);
+               icon->relocated_src = gf_strdup(icon_relocated_path);
+       }
+       icon->interfaces = gf_list_new();
+       icon->components = gf_list_new();
+       icon->preferences = gf_list_new();
+       icon->widget = widget;
+       gf_list_add(widget->icons, icon);
+       return icon;
+}
+
+/* Scans the W3C default icons table and add each icon */
+static void wm_set_default_icon_files(GF_WidgetManager *wm, const char *widget_path, GF_Widget *widget) {
+       char relocated_path[GF_MAX_PATH], localized_path[GF_MAX_PATH];
+       Bool result;
+
+       result = wm_relocate_url(wm, widget_path, "icon.svg", relocated_path, localized_path);
+       if (result) wm_add_icon(widget, relocated_path, localized_path, NULL);
+
+       result = wm_relocate_url(wm, widget_path, "icon.ico", relocated_path, localized_path);
+       if (result) wm_add_icon(widget, relocated_path, localized_path, NULL);
+
+       result = wm_relocate_url(wm, widget_path, "icon.png", relocated_path, localized_path);
+       if (result) wm_add_icon(widget, relocated_path, localized_path, NULL);
+
+       result = wm_relocate_url(wm, widget_path, "icon.gif", relocated_path, localized_path);
+       if (result) wm_add_icon(widget, relocated_path, localized_path, NULL);
+
+       result = wm_relocate_url(wm, widget_path, "icon.jpg", relocated_path, localized_path);
+       if (result) wm_add_icon(widget, relocated_path, localized_path, NULL);
+}
+
+GF_WidgetInstance *wm_load_widget(GF_WidgetManager *wm, const char *path, u32 InstanceID, Bool skip_context)
+{
+       char szName[GF_MAX_PATH];
+       u32 i, count;
+       GF_Widget *widget = NULL;
+       GF_WidgetInstance *wi = NULL;
+       GF_XMLNode *root, *icon, *nmain, *name, *xml_node;
+       GF_Err e;
+       GF_DOMParser *dom = NULL;
+       GF_WidgetPackage *wpackage = NULL;
+
+       GF_DownloadSession *sess = NULL;
+       const char *widget_ns_prefix = NULL;
+       const char *mpegu_ns_prefix = NULL;
+       const char *user_locale = gf_cfg_get_key(wm->term->user->config, "Systems", "Language2CC");
+
+       /* Try to see if this widget is already loaded */
+       e = GF_OK;
+       count = gf_list_count(wm->widgets);
+       for (i=0; i<count; i++) {
+               widget = gf_list_get(wm->widgets, i);
+               if (!strcmp(widget->url, path)) break;
+               widget = NULL;
+       }
+
+       /*not found, retrieve the widget (if http), check the package if needed and parse the configuration document/widget manifest*/
+       if (!widget) {
+               Bool isDownloadedPackage = 0;
+
+               /* path used to locate the widget (config.xml if unpackaged or zip/isoff package), potentially after download */
+               const char *szLocalPath = path;
+               /* used to locate the config document/widget manifest potentially after unzipping */
+               const char *szManifestPath = path;
+               /* */
+               const char *szWidgetPath = path;
+               const char *desc;
+               GF_WidgetPreference *pref;
+               GF_List *global_prefs;
+               GF_WidgetContent *content;
+               Bool correct_ns = 0;
+
+               if (strstr(path, "http://")) {
+                       /*fetch the remote widget manifest synchronously and load it */
+                       sess = gf_dm_sess_new(wm->term->downloader, (char *)path, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e);
+                       if (sess) {
+                               e = gf_dm_sess_process(sess);
+                               if (e==GF_OK) {
+                                       szLocalPath = gf_dm_sess_get_cache_name(sess);
+
+                                       if (gf_unzip_probe(szLocalPath)) {
+                                               isDownloadedPackage = 1;
+                                       } else {
+                                               /* TODO ISOFF-based packaged widget */
+                                       }
+                               }
+                       }
+                       if (!sess || (e!=GF_OK) || !szLocalPath) goto exit;
+               }
+
+               /* Check if the widget package is a valid package and if it contains a config.xml file */
+               szManifestPath = szLocalPath;
+
+               wpackage = widget_package_new(wm, szLocalPath);
+               if (wpackage) {
+                       count = gf_list_count(wpackage->resources);
+                       for (i=0; i<count; i++) {
+                               GF_WidgetPackageResource *wu = gf_list_get(wpackage->resources, i);
+                               /* According to W3C WPC, the config.xml file (lower case) shall only be located
+                                  at the root of the package
+                                  see http://www.w3.org/TR/widgets/#ta-dxzVDWpaWg */
+                               if (!strcmp(wu->inner_path, "config.xml")) {
+                                       szManifestPath = wu->extracted_path;
+                                       break;
+                               }
+                       }
+                       szWidgetPath = szManifestPath;
+               }
+
+
+               /* Parse the Widget Config Document as a DOM */
+               dom = gf_xml_dom_new();
+               e = gf_xml_dom_parse(dom, szManifestPath, NULL, NULL);
+               if (e) goto exit;
+
+               root = gf_xml_dom_get_root(dom);
+               if (!root) goto exit;
+
+               correct_ns = 0;
+               count = gf_list_count(root->attributes);
+               for (i=0; i<count; i++) {
+                       GF_XMLAttribute *att = gf_list_get(root->attributes, i);
+                       if (att->name) {
+                               if (!strcmp(att->name, "xmlns")) {
+                                       if (!strcmp(att->value, "http://www.w3.org/ns/widgets")) {
+                                               correct_ns = 1;
+                                       }
+                               } else if (!strnicmp(att->name, "xmlns:", 6)) {
+                                       if (!strcmp(att->value, "http://www.w3.org/ns/widgets")) {
+                                               widget_ns_prefix = att->name+6;
+                                               correct_ns = 1;
+                                       } else if (!strcmp(att->value, "urn:mpeg:mpegu:schema:widgets:manifest:2010")) {
+                                               mpegu_ns_prefix = att->name+6;
+                                       }
+                               }
+                       }
+               }
+               /* According to the spec, wrong or no namespace means invalid widget
+               see http://www.w3.org/TR/widgets/#ta-ACCJfDGwDQ */
+               if (!correct_ns) goto exit;
+
+               /* see http://www.w3.org/TR/widgets/#ta-ACCJfDGwDQ */
+               if ((root->ns && (!widget_ns_prefix || strcmp(root->ns, widget_ns_prefix) || strcmp(root->name, "widget"))) ||
+                       (!root->ns && (widget_ns_prefix || strcmp(root->name, "widget"))))
+                       goto exit;
+
+
+               /*pre-parse the root-level preference for use when parsing MPEG-U elements */
+               global_prefs = gf_list_new();
+               i=0;
+               while ((nmain = gf_list_enum(root->content, &i))) {
+                       const char *pname, *pvalue;
+                       /* 'normalized' preference name and readonly*/
+                       char *npname, *npro;
+                       u32 i, count;
+                       Bool pref_exists = 0;
+                       Bool readOnly = 0;
+                       if (nmain->type != GF_XML_NODE_TYPE) continue;
+                       if (strcmp(nmain->name, "preference")) continue;
+                       pname = wm_xml_get_attr(nmain, "name");
+                       npname = wm_get_single_attribute(pname);
+                       if (!npname || !strlen(npname)) continue;
+
+                       count = gf_list_count(global_prefs);
+                       for (i = 0; i < count; i++) {
+                               GF_WidgetPreference *tmp_pref = gf_list_get(global_prefs, i);
+                               if (!strcmp(tmp_pref->name, npname)) {
+                                       pref_exists = 1;
+                                       break;
+                               }
+                       }
+                       if (pref_exists) continue;
+
+                       pvalue = wm_xml_get_attr(nmain, "readonly");
+                       npro = wm_get_single_attribute(pvalue);
+                       if (npro && strlen(npro) && !strcmp(npro, "true")) readOnly=1;
+                       if (npro) gf_free(npro);
+
+                       pvalue = wm_xml_get_attr(nmain, "value");
+
+                       GF_SAFEALLOC(pref, GF_WidgetPreference);
+                       pref->name = npname;
+                       if (pvalue) pref->value = wm_get_single_attribute(pvalue);
+                       /*global preferences are save and migratable*/
+                       pref->flags = GF_WM_PREF_SAVE | GF_WM_PREF_MIGRATE;
+                       if (readOnly) pref->flags |= GF_WM_PREF_READONLY;
+                       gf_list_add(global_prefs, pref);
+               }
+
+               /* get the content element from the XML Config document */
+               GF_SAFEALLOC(content, GF_WidgetContent);
+               content->interfaces = gf_list_new();
+               content->components = gf_list_new();
+               content->preferences = gf_list_new();
+               nmain = wm_xml_find(root, widget_ns_prefix, "content", NULL);
+               if (!nmain) {
+                       /* if not found, use the default table of start files */
+                       wm_set_default_start_file(wm, content, szWidgetPath);
+               } else {
+                       const char *src, *encoding, *mimetype;
+                       src = wm_xml_get_attr(nmain, "src");
+
+                       /*check the resource exists*/
+                       if (src) {
+                               Bool result;
+                               char relocated_path[GF_MAX_PATH], localized_path[GF_MAX_PATH];
+                               /*remove any existing fragment*/
+                               char *sep = strchr(src, '#');
+                               if (sep) sep[0] = 0;
+                               result = wm_relocate_url(wm, szWidgetPath, src, relocated_path, localized_path);
+                               if (sep) sep[0] = '#';
+                               if (result) {
+                                       content->relocated_src = gf_strdup(relocated_path);
+                                       content->src = gf_strdup(localized_path);
+                               }
+                       }
+
+                       encoding = wm_xml_get_attr(nmain, "encoding");
+                       if (encoding && strlen(encoding)) content->encoding = wm_get_single_attribute(encoding);
+                       else content->encoding = gf_strdup("utf-8");
+
+                       mimetype = wm_xml_get_attr(nmain, "type");
+                       if (mimetype && strlen(mimetype)) {
+                               char *sep = strchr(mimetype, ';');
+                               if (sep) sep[0] = 0;
+                               content->mimetype = wm_get_single_attribute(mimetype);
+                               if (sep) sep[0] = ';';
+                       }
+                       else content->mimetype = gf_strdup("text/html");
+
+                       if (!content->relocated_src) wm_set_default_start_file(wm, content, szWidgetPath);
+               }
+               if (strlen(content->relocated_src) == 0) {
+                       gf_list_del(content->interfaces);
+                       gf_list_del(content->components);
+                       gf_list_del(content->preferences);
+                       gf_free(content);
+                       content = NULL;
+                       goto exit;
+               }
+               /* We need to call the parse of the MPEG-U elements to clone the global preferences into widget preferences,
+                  this should probably be changed to extract the clone from that function */
+               wm_parse_mpegu_content_element(content, nmain, mpegu_ns_prefix, global_prefs);
+
+               GF_SAFEALLOC(widget, GF_Widget);
+               widget->url = gf_strdup(path);
+               widget->manifest_path = gf_strdup(szManifestPath);
+               if (isDownloadedPackage) widget->local_path = gf_strdup(szLocalPath);
+               widget->wm = wm;
+               widget->main = content;
+               content->widget = widget;
+               widget->icons = gf_list_new();
+               widget->features = gf_list_new();
+               if (wpackage) {
+                       widget->wpack = wpackage;
+                       wpackage->widget = widget;
+                       /*attach downloader to our package to avoid destroying the cache file*/
+                       wpackage->sess = sess;
+                       sess = NULL;
+               }
+
+               /*check for icon - can be optional*/
+               i=0;
+               while ((icon = gf_list_enum(root->content, &i))) {
+                       if (icon->type==GF_XML_NODE_TYPE &&
+                                       icon->name && !strcmp(icon->name, "icon") &&
+                                       ((!widget_ns_prefix && !icon->ns) || !strcmp(widget_ns_prefix, icon->ns))) {
+                               char *sep;
+                               char relocated[GF_MAX_PATH], localized_path[GF_MAX_PATH];
+                               char *icon_width, *icon_height;
+                               GF_WidgetContent *iconic;
+                               Bool result;
+
+                               char *pname = (char *)wm_xml_get_attr(icon, "src");
+                               if (!pname || !strlen(pname)) continue;
+
+                               /*remove any existing fragment*/
+                               sep = strchr(pname, '#');
+                               if (sep) sep[0] = 0;
+                               result = wm_relocate_url(wm, szWidgetPath, pname, relocated, localized_path);
+                               if (sep) sep[0] = '#';
+                               if (!result) continue;
+
+                               iconic = wm_add_icon(widget, relocated, localized_path, sep);
+                               if (iconic) {
+                                       wm_parse_mpegu_content_element(iconic, icon, mpegu_ns_prefix, global_prefs);
+                                       icon_width = (char *)wm_xml_get_attr(icon, "width");
+                                       if (icon_width) iconic->width = wm_parse_non_neg(icon_width);
+                                       icon_height = (char *)wm_xml_get_attr(icon, "height");
+                                       if (icon_height) iconic->height = wm_parse_non_neg(icon_height);
+                               }
+                       }
+               }
+               /* after processing the icon elements (wether there are valid icons or not), we use the default icon table
+                 see http://dev.w3.org/2006/waf/widgets/test-suite/test-cases/ta-FAFYMEGELU/004/ */
+               wm_set_default_icon_files(wm, szWidgetPath, widget);
+
+               /*delete the root-level preference*/
+               i=0;
+               while ((pref = gf_list_enum(global_prefs , &i))) {
+                       if (pref->value) gf_free(pref->value);
+                       gf_free(pref->name);
+                       gf_free(pref);
+               }
+               gf_list_del(global_prefs);
+
+               /*check for optionnal meta data*/
+               name = wm_xml_find(root, widget_ns_prefix, "name", user_locale);
+               if (name) {
+                       const char *shortname = wm_xml_get_attr(name, "short");
+                       widget->shortname = wm_get_single_attribute(shortname);
+
+                       widget->name = wm_get_normalized_text_content(name, NULL, user_locale);
+               }
+
+               desc = wm_xml_get_attr(root, "id");
+               if (desc) {
+                       /* TODO check if this is a valid IRI, for the moment, just hack to pass the test, check for ':'
+                         see http://dev.w3.org/2006/waf/widgets/test-suite/test-cases/ta-RawAIWHoMs/ */
+                       if (strchr(desc, ':'))
+                               widget->identifier = wm_get_single_attribute(desc);
+               }
+
+               desc = wm_xml_get_attr(root, "width");
+               if (desc) {
+                       widget->width = wm_parse_non_neg(desc);
+               }
+               desc = wm_xml_get_attr(root, "height");
+               if (desc) {
+                       widget->height = wm_parse_non_neg(desc);
+               }
+
+               name = wm_xml_find(root, widget_ns_prefix, "description", user_locale);
+               if (name) {
+                       widget->description = wm_get_normalized_text_content(name, NULL, user_locale);
+               }
+
+               name = wm_xml_find(root, widget_ns_prefix, "license", user_locale);
+               if (name) {
+                       const char *href = wm_xml_get_attr(name, "href");
+                       widget->licenseHref = wm_get_single_attribute(href);
+
+                       /* Warning the license text content should not be normalized */
+                       widget->license = wm_get_text_content(name, NULL, user_locale);
+               }
+
+               desc = wm_xml_get_attr(root, "version");
+               if (desc) widget->version = wm_get_single_attribute(desc);
+
+               desc = wm_xml_get_attr(root, "uuid");
+               if (desc) widget->uuid = gf_strdup(desc);
+
+               desc = wm_xml_get_attr(root, "discardable");
+               if (desc) widget->discardable = !strcmp(desc, "true") ? 1 : 0;
+
+               desc = wm_xml_get_attr(root, "multipleInstances");
+               if (desc) widget->multipleInstance = !strcmp(desc, "true") ? 1 : 0;
+
+               name = wm_xml_find(root, widget_ns_prefix, "author", NULL);
+               if (name) {
+                       desc = wm_xml_get_attr(name, "href");
+                       if (desc && strchr(desc, ':')) widget->authorHref = wm_get_single_attribute(desc);
+
+                       desc = wm_xml_get_attr(name, "email");
+                       widget->authorEmail = wm_get_single_attribute(desc);
+
+                       widget->authorName = wm_get_normalized_text_content(name, NULL, user_locale);
+               }
+
+               i=0;
+               while ((xml_node = gf_list_enum(root->content, &i))) {
+                       if (xml_node->type==GF_XML_NODE_TYPE &&
+                                       xml_node->name && !strcmp(xml_node->name, "feature") &&
+                                       ((!widget_ns_prefix && !xml_node->ns) || !strcmp(widget_ns_prefix, xml_node->ns))) {
+
+                               u32 i, count;
+                               Bool already_in = 0;
+                               GF_WidgetFeature *feat;
+                               const char *feature_name, *req_att;
+                               char *nfname;
+                               Bool required = 1;
+                               u32 j;
+                               GF_XMLNode *param_node;
+
+                               feature_name = (char *)wm_xml_get_attr(xml_node, "name");
+                               if (!feature_name || !strlen(feature_name) || !strchr(feature_name, ':')) continue;
+                               nfname = wm_get_single_attribute(feature_name);
+
+                               req_att = (char *)wm_xml_get_attr(xml_node, "required");
+                               if (req_att && !strcmp(req_att, "false")) required = 0;
+
+                               count = gf_list_count(widget->features);
+                               for (i = 0; i<count; i++) {
+                                       GF_WidgetFeature *tmp = gf_list_get(widget->features, i);
+                                       if (!strcmp(nfname, tmp->name)) {
+                                               already_in = 1;
+                                               break;
+                                       }
+                               }
+                               if (already_in) continue;
+
+                               GF_SAFEALLOC(feat, GF_WidgetFeature);
+                               feat->name = nfname;
+                               feat->required = required;
+                               feat->params = gf_list_new();
+                               gf_list_add(widget->features, feat);
+
+                               j = 0;
+                               while ((param_node = gf_list_enum(xml_node->content, &j))) {
+                                       if (param_node->type==GF_XML_NODE_TYPE &&
+                                                       param_node->name && !strcmp(param_node->name, "param") &&
+                                                       ((!widget_ns_prefix && !param_node->ns) || !strcmp(widget_ns_prefix, param_node->ns))) {
+                                               GF_WidgetFeatureParam *wfp;
+                                               const char *param_name, *param_value;
+                                               char *npname, *npvalue;
+
+                                               param_name = (char *)wm_xml_get_attr(param_node, "name");
+                                               npname = wm_get_single_attribute(param_name);
+                                               if (!strlen(npname)) continue;
+
+                                               param_value = (char *)wm_xml_get_attr(param_node, "value");
+                                               npvalue = wm_get_single_attribute(param_value);
+                                               if (!strlen(npvalue)) {
+                                                       gf_free(npname);
+                                                       continue;
+                                               }
+
+                                               GF_SAFEALLOC(wfp, GF_WidgetFeatureParam);
+                                               wfp->name = npname;
+                                               wfp->value = npvalue;
+                                               gf_list_add(feat->params, wfp);
+
+                                       }
+                               }
+
+                       }
+               }
+
+               gf_list_add(wm->widgets, widget);
+       }
+
+       GF_SAFEALLOC(wi, GF_WidgetInstance);
+       wi->widget = widget;
+       wi->bound_ifces = gf_list_new();
+       wi->output_triggers = gf_list_new();
+       wi->components = gf_list_new();
+       widget->nb_instances++;
+       wi->instance_id = InstanceID;
+       wi->permanent = 1;
+
+       if (!InstanceID) {
+               char szInst[20];
+
+               count = gf_list_count(wm->widget_instances);
+               for (i=0; i<count; i++) {
+                       GF_WidgetInstance *awi = gf_list_get(wm->widget_instances, i);
+                       if (awi->widget == wi->widget)
+                               wi->instance_id = awi->instance_id;
+               }
+               wi->instance_id ++;
+
+               sprintf(szName, "%s#%s#Instance%d", path, wi->widget->name, wi->instance_id);
+               sprintf(wi->secname, "Widget#%08X", gf_crc_32(szName, strlen(szName)));
+
+               /*create section*/
+               gf_cfg_set_key(wm->term->user->config, "Widgets", wi->secname, " ");
+               gf_cfg_set_key(wm->term->user->config, wi->secname, "WM:Manifest", wi->widget->url);
+               sprintf(szInst, "%d", wi->instance_id);
+               gf_cfg_set_key(wm->term->user->config, wi->secname, "WM:InstanceID", szInst);
+       }
+       gf_list_add(wm->widget_instances, wi);
+
+
+       if (!skip_context && strstr(path, "http://")) {
+               GF_XMLNode *context;
+               GF_DownloadSession *ctx_sess = NULL;
+               char *ctxPath;
+               context = NULL;
+
+               /*fetch the remote widget context synchronously and load it */
+               ctxPath = gf_malloc(sizeof(char) * (strlen(path) + 1 + 15/*?mpeg-u-context*/));
+               strcpy(ctxPath, path);
+               if ((strchr(path, '?') == NULL) && (strstr(path, "%3f")==NULL) && (strstr(path, "%3F")==NULL) ) {
+                       strcat(ctxPath, "?mpeg-u-context");
+               } else {
+                       strcat(ctxPath, "&mpeg-u-context");
+               }
+
+               /*try to fetch the associated context*/
+               ctx_sess = gf_dm_sess_new(wm->term->downloader, (char *)ctxPath, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e);
+               if (ctx_sess) {
+                       e = gf_dm_sess_process(ctx_sess);
+                       if (e==GF_OK) {
+                               wi->mpegu_context = gf_xml_dom_new();
+                               e = gf_xml_dom_parse(wi->mpegu_context , gf_dm_sess_get_cache_name(ctx_sess), NULL, NULL);
+                               if (!e) {
+                                       context = gf_xml_dom_get_root(wi->mpegu_context);
+                                       if (strcmp(context->name, "contextInformation")) context = NULL;
+                               }
+                       }
+                       gf_dm_sess_del(ctx_sess);
+                       e = GF_OK;
+               }
+               gf_free(ctxPath);
+               ctxPath = NULL;
+
+               if (!context && wi->mpegu_context) {
+                       gf_xml_dom_del(wi->mpegu_context);
+                       wi->mpegu_context = NULL;
+               }
+
+       }
+
+exit:
+       if (dom) gf_xml_dom_del(dom);
+       if (sess) gf_dm_sess_del(sess);
+       if (e || !wi) {
+               if (wi) wm_delete_widget_instance(wm, wi);
+               else {
+                       if (wpackage) widget_package_del(wm, wpackage);
+               }
+               return NULL;
+       }
+       return wi;
+}
+
+
+static Bool wm_enum_widget(void *cbk, char *file_name, char *file_path)
+{
+       GF_WidgetInstance *wid;
+       GF_WidgetManager *wm = (GF_WidgetManager *)cbk;
+       wid = wm_load_widget(wm, file_path, 0, 0);
+       if (wid) {
+               wm_widget_jsbind(wm, wid);
+               /*remove section info*/
+               gf_cfg_del_section(wm->term->user->config, wid->secname);
+               gf_cfg_set_key(wm->term->user->config, "Widgets", wid->secname, NULL);
+       }
+       return 0;
+}
+
+static Bool wm_enum_dir(void *cbk, char *file_name, char *file_path)
+{
+       return gf_enum_directory(file_path, 0, wm_enum_widget, cbk, "mgt");
+}
+
+
+static JSBool SMJS_FUNCTION(wm_initialize)
+{
+       u32 i, count;
+       const char*opt;
+       SMJS_OBJ
+       //SMJS_ARGS
+       GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj);
+
+       count = gf_cfg_get_key_count(wm->term->user->config, "Widgets");
+       for (i=0; i<count; i++) {
+               const char *name = gf_cfg_get_key_name(wm->term->user->config, "Widgets", i);
+               /*this is a previously loaded widgets - reload it*/
+               if (!strnicmp(name, "Widget#", 7)) {
+                       const char *manifest = gf_cfg_get_key(wm->term->user->config, name, "WM:Manifest");
+                       if (manifest) {
+                               const char *ID = gf_cfg_get_key(wm->term->user->config, name, "WM:InstanceID");
+                               u32 instID = ID ? atoi(ID) : 0;
+                               GF_WidgetInstance *wi = wm_load_widget(wm, manifest, instID, 0);
+                               if (wi) {
+                                       strcpy(wi->secname, name);
+                                       wm_widget_jsbind(wm, wi);
+                               }
+                       }
+               }
+       }
+
+       opt = gf_cfg_get_key(wm->term->user->config, "Widgets", "WidgetStore");
+       if (opt) gf_enum_directory(opt, 1, wm_enum_dir, wm, NULL);
+
+       return JS_TRUE;
+}
+
+static void widgetmanager_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload)
+{
+       GF_WidgetManager *wm;
+
+       GF_JSAPIParam par;
+       JSPropertySpec wmClassProps[] = {
+               {0, 0, 0, 0, 0}
+       };
+       JSFunctionSpec wmClassFuncs[] = {
+               SMJS_FUNCTION_SPEC("initialize", wm_initialize, 0),
+               SMJS_FUNCTION_SPEC("load", wm_load, 2),
+               SMJS_FUNCTION_SPEC("unload", wm_unload, 1),
+               SMJS_FUNCTION_SPEC("get", wm_get, 1),
+               SMJS_FUNCTION_SPEC("findByInterface", wm_find_interface, 1),
+               SMJS_FUNCTION_SPEC(0, 0, 0)
+       };
+
+       wm = jsext->udta;
+       /*widget manager is only loaded once*/
+       if (wm->ctx && (wm->ctx != c)) {
+               /*load the 'Widget' object in the global scope*/
+               widget_load(wm, scene, c, global, unload);
+               return;
+       }
+
+       /*unload widgets*/
+       if (unload) {
+               if (wm->obj) {
+                       gf_js_remove_root(wm->ctx, &wm->obj, GF_JSGC_OBJECT);
+                       wm->obj = NULL;
+               }
+
+               while (gf_list_count(wm->widget_instances)) {
+                       GF_WidgetInstance *widg = gf_list_get(wm->widget_instances, 0);
+                       wm_delete_widget_instance(wm, widg);
+               }
+               wm->ctx = NULL;
+               return;
+       }
+       wm->ctx = c;
+
+       if (!scene) return;
+
+       /*setup JS bindings*/
+       JS_SETUP_CLASS(wm->widmanClass, "WIDGETMANAGER", JSCLASS_HAS_PRIVATE, wm_getProperty, wm_setProperty, JS_FinalizeStub);
+
+       JS_InitClass(c, global, 0, &wm->widmanClass, 0, 0, wmClassProps, wmClassFuncs, 0, 0);
+       wm->obj = JS_DefineObject(c, global, "WidgetManager", &wm->widmanClass, 0, 0);
+       JS_SetPrivate(c, wm->obj, wm);
+       gf_js_add_root(c, &wm->obj, GF_JSGC_OBJECT);
+
+
+       {
+       JSPropertySpec wmWidgetClassProps[] = {
+               {0, 0, 0, 0, 0}
+       };
+       JSFunctionSpec wmWidgetClassFuncs[] = {
+               SMJS_FUNCTION_SPEC("activate", wm_widget_activate, 1),
+               SMJS_FUNCTION_SPEC("deactivate", wm_widget_deactivate, 0),
+               SMJS_FUNCTION_SPEC("get_interface", wm_widget_get_interface, 1),
+               SMJS_FUNCTION_SPEC("bind_output_trigger", wm_widget_bind_output_trigger, 2),
+               SMJS_FUNCTION_SPEC("set_input", wm_widget_set_input, 2),
+               SMJS_FUNCTION_SPEC("bind_interface", wm_widget_bind_interface, 2),
+               SMJS_FUNCTION_SPEC("unbind_interface", wm_widget_unbind_interface, 1),
+               SMJS_FUNCTION_SPEC("call_input_action", wm_widget_call_input_action, 1),
+               SMJS_FUNCTION_SPEC("call_input_script", wm_widget_call_input_script, 2),
+               SMJS_FUNCTION_SPEC("is_interface_bound", wm_widget_is_interface_bound, 1),
+               SMJS_FUNCTION_SPEC("get_param_value", wm_widget_get_param_value, 1),
+               SMJS_FUNCTION_SPEC("get_context", wm_widget_get_context, 0),
+               SMJS_FUNCTION_SPEC("get_component", wm_widget_get_component, 2),
+
+               SMJS_FUNCTION_SPEC(0, 0, 0)
+       };
+       /*setup JS bindings*/
+       JS_SETUP_CLASS(wm->wmWidgetClass, "WMWIDGET", JSCLASS_HAS_PRIVATE, wm_widget_getProperty, wm_widget_setProperty, JS_FinalizeStub);
+       JS_InitClass(c, global, 0, &wm->wmWidgetClass, 0, 0, wmWidgetClassProps, wmWidgetClassFuncs, 0, 0);
+
+       JS_SETUP_CLASS(wm->widgetAnyClass, "WIDGETANY", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub);
+       JS_InitClass(c, global, 0, &wm->widgetAnyClass, 0, 0, 0, 0, 0, 0);
+       }
+
+       JS_SETUP_CLASS(wm->widgetClass, "MPEGWidget", JSCLASS_HAS_PRIVATE, widget_getProperty, widget_setProperty, JS_FinalizeStub);
+
+       if (scene->script_action) {
+               if (!scene->script_action(scene->script_action_cbck, GF_JSAPI_OP_GET_TERM, scene->RootNode, &par))
+                       return;
+               wm->term = par.term;
+       }
+
+}
+
+
+static GF_JSUserExtension *gwm_new()
+{
+       GF_JSUserExtension *dr;
+       GF_WidgetManager *wm;
+       dr = gf_malloc(sizeof(GF_JSUserExtension));
+       memset(dr, 0, sizeof(GF_JSUserExtension));
+       GF_REGISTER_MODULE_INTERFACE(dr, GF_JS_USER_EXT_INTERFACE, "WidgetManager JavaScript Bindings", "gpac distribution");
+
+       GF_SAFEALLOC(wm, GF_WidgetManager);
+       wm->widget_instances = gf_list_new();
+       wm->widgets = gf_list_new();
+       dr->load = widgetmanager_load;
+       dr->udta = wm;
+       return dr;
+}
+
+
+static void gwm_delete(GF_BaseInterface *ifce)
+{
+        GF_WidgetManager *wm;
+       GF_JSUserExtension *dr = (GF_JSUserExtension *) ifce;
+        if (!dr)
+          return;
+        wm = dr->udta;
+        if (!wm)
+          return;
+        if (wm->widget_instances)
+          gf_list_del(wm->widget_instances);
+        wm->widget_instances = NULL;
+        if (wm->widgets)
+          gf_list_del(wm->widgets);
+        wm->widgets = NULL;
+       gf_free(wm);
+        dr->udta = NULL;
+       gf_free(dr);
+}
+#endif
+
+
+GF_EXPORT
+const u32 *QueryInterfaces()
+{
+       static u32 si [] = {
+#ifdef GPAC_HAS_SPIDERMONKEY
+               GF_JS_USER_EXT_INTERFACE,
+               GF_SCENE_DECODER_INTERFACE,
+#endif
+               0
+       };
+       return si;
+}
+
+GF_EXPORT
+GF_BaseInterface *LoadInterface(u32 InterfaceType)
+{
+#ifdef GPAC_HAS_SPIDERMONKEY
+       if (InterfaceType == GF_JS_USER_EXT_INTERFACE) return (GF_BaseInterface *)gwm_new();
+       else if (InterfaceType == GF_SCENE_DECODER_INTERFACE) return (GF_BaseInterface *)LoadWidgetReader();
+#endif
+       return NULL;
+}
+
+GF_EXPORT
+void ShutdownInterface(GF_BaseInterface *ifce)
+{
+       switch (ifce->InterfaceType) {
+#ifdef GPAC_HAS_SPIDERMONKEY
+       case GF_JS_USER_EXT_INTERFACE:
+               gwm_delete(ifce);
+               break;
+       case GF_SCENE_DECODER_INTERFACE:
+               ShutdownWidgetReader(ifce);
+               break;
+#endif
+       }
+}
+
diff --git a/modules/widgetman/widgetman.h b/modules/widgetman/widgetman.h
new file mode 100644 (file)
index 0000000..879cf8b
--- /dev/null
@@ -0,0 +1,360 @@
+//This software module was originally developed by TelecomParisTech in the
+//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard.
+//
+//This software module is an implementation of a part of one or 
+//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets
+//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets
+//(ISO/IEC 23007-1) free license to this software module or modifications
+//thereof for use in hardware or software products claiming conformance to
+//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software
+//module in hardware or software products are advised that its use may
+//infringe existing patents.
+//The original developer of this software module and his/her company, the
+//subsequent editors and their companies, and ISO/IEC have no liability 
+//for use of this software module or modifications thereof in an implementation. 
+//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming 
+//products. 
+//Telecom ParisTech retains full right to use the code for his/her own purpose, 
+//assign or donate the code to a third party and to inhibit third parties from 
+//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. 
+//
+//This copyright notice must be included in all copies or derivative works.
+//
+//Copyright (c) 2009.
+//
+// Alternatively, this software module may be redistributed and/or modified
+//  it under the terms of the GNU Lesser General Public License as published by
+//  the Free Software Foundation; either version 2, or (at your option)
+//  any later version.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+//     Authors:        
+//                                     Jean Le Feuvre, Telecom ParisTech
+//                                     Cyril Concolato, Telecom ParisTech
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WIDGETMAN_H_
+#define _WIDGETMAN_H_
+
+#include "unzip.h"
+
+/*base SVG type*/
+#include <gpac/modules/js_usr.h>
+
+#ifdef GPAC_HAS_SPIDERMONKEY
+
+#include <gpac/nodes_mpeg4.h>
+#include <gpac/nodes_x3d.h>
+#include <gpac/nodes_svg.h>
+/*dom events*/
+#include <gpac/events.h>
+
+#include <gpac/download.h>
+#include <gpac/crypt.h>
+#include <gpac/network.h>
+#include <gpac/xml.h>
+#include <gpac/internal/scenegraph_dev.h>
+
+
+#include <gpac/isomedia.h>
+
+#include <gpac/internal/smjs_api.h>
+
+#include <gpac/internal/terminal_dev.h>
+#include <gpac/internal/compositor_dev.h>
+
+
+JSBool gf_sg_js_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node);
+JSBool gf_sg_js_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node);
+
+typedef struct _widget_manager
+{
+       JSContext *ctx;
+       /*widget manager class*/
+       JSClass widmanClass;
+       /*widget class used by the widget manager*/
+       JSClass wmWidgetClass;
+
+       /*widget class used by the widget scripts*/
+       JSClass widgetClass;
+
+       JSClass widgetAnyClass;
+
+       JSObject *obj;
+       GF_Terminal *term;
+       GF_List *widget_instances;
+       /*list of loaded prototypes (eg 1 per all instances of the same widget*/
+       GF_List *widgets;
+} GF_WidgetManager;
+
+
+
+enum
+{
+       GF_WPIN_STRING, 
+       GF_WPIN_INTEGER, 
+       GF_WPIN_NUMBER, 
+};
+
+typedef struct
+{
+       char *inner_path;
+       char *extracted_path;
+       Bool extracted;
+} GF_WidgetPackageResource;
+
+typedef struct _widget_package_relocator
+{
+       GF_TERM_URI_RELOCATOR
+       GF_List *resources;
+       struct _widget *widget;
+       GF_WidgetManager *wm;
+       Bool is_zip;
+       char root_extracted_path[GF_MAX_PATH];
+       char archive_id[14];
+       char *package_path;
+       GF_DownloadSession *sess;
+} GF_WidgetPackage;
+
+
+enum
+{
+       GF_WM_PARAM_OUTPUT, 
+       GF_WM_PARAM_INPUT,
+       GF_WM_INPUT_ACTION,
+       GF_WM_OUTPUT_TRIGGER,
+       GF_WM_BIND_ACTION,
+       GF_WM_UNBIND_ACTION,
+       GF_WM_PREF_CONNECT,
+       GF_WM_ACTIVATE_TRIGGER,
+       GF_WM_DEACTIVATE_TRIGGER,
+       GF_WM_PREF_SAVEDACTION,
+       GF_WM_PREF_RESTOREDACTION,
+       GF_WM_PREF_SAVETRIGGER,
+       GF_WM_PREF_RESTORETRIGGER,
+};
+
+#define GF_WM_PARAM_SCRIPT_STRING      (u16) 0
+#define GF_WM_PARAM_SCRIPT_BOOL                (u16) 1
+#define GF_WM_PARAM_SCRIPT_NUMBER      (u16) 2
+
+typedef struct 
+{
+       struct __widget_message *msg;
+
+       u16 type;
+       u16 script_type;
+       Bool in_action;
+
+       char *name;
+       char *node;
+       char *attribute;
+       char *default_value;
+} GF_WidgetPin;
+
+typedef struct __widget_message
+{
+       struct _widget_interface *ifce;
+
+       char *name;
+       Bool is_output;
+       GF_List *params;
+
+       GF_WidgetPin *input_action;
+       GF_WidgetPin *output_trigger;
+
+} GF_WidgetMessage;
+
+typedef struct _widget_interface
+{
+       struct __widget_content *content;
+       char *type;
+       GF_List *messages;
+
+       GF_WidgetPin *bind_action;
+       GF_WidgetPin *unbind_action;
+       Bool provider, multiple_binding, required;
+       char *connectTo;
+
+       JSObject *obj;
+} GF_WidgetInterface;
+
+typedef struct _widget_component
+{
+       struct __widget_content *content;
+       char *id;       /*may be NULL*/
+       char *src;      /*may be NULL*/
+       GF_List *required_interfaces;   /*may be empty*/
+       GF_WidgetPin *activateTrigger;
+       GF_WidgetPin *deactivateTrigger;
+       GF_WidgetPin *activatedAction;
+       GF_WidgetPin *deactivatedAction;
+} GF_WidgetComponent;
+
+enum
+{
+       GF_WM_PREF_READONLY = 1,
+       GF_WM_PREF_SAVE = 1<<1,
+       GF_WM_PREF_MIGRATE = 1<<2,
+};
+
+typedef struct 
+{
+       char *name, *value;
+       u32 flags;
+       GF_WidgetPin *connectTo;
+} GF_WidgetPreference;
+
+typedef struct 
+{
+       char *name, *value;
+} GF_WidgetFeatureParam;
+
+typedef struct 
+{
+       char *name;
+       Bool required;
+       GF_List *params;
+} GF_WidgetFeature;
+
+typedef struct __widget_content
+{
+       struct _widget *widget;
+
+       char *src;
+       char *relocated_src;
+       u32 width, height;
+
+       char *encoding, *mimetype;
+
+       GF_List *interfaces;
+       GF_List *components;
+       /*list of preferences for the widget content*/
+       GF_List *preferences;
+
+       GF_WidgetPin *savedAction;
+       GF_WidgetPin *restoredAction;
+       GF_WidgetPin *saveTrigger;
+       GF_WidgetPin *restoreTrigger;
+} GF_WidgetContent;
+
+typedef struct _widget
+{
+       GF_WidgetManager *wm;
+
+       u32 nb_instances;
+
+       /* url to the file.wgt file when zip packaged or to the config.xml file when unpackaged */
+       char *url;
+       /* path to the manifest/config document */
+       char *manifest_path;
+
+       GF_List *icons;
+/*
+       GF_WidgetContent *simple;
+       char *icon_url;
+*/
+       GF_WidgetContent *main;
+
+       GF_WidgetPackage *wpack;
+
+       /*misc metadata for W3C Widgets API*/
+       char *name, *shortname, *identifier, 
+               *authorName, *authorEmail, *authorHref, 
+               *description, *version, 
+               *uuid, *license, *licenseHref, *viewmodes;
+       
+       u32 width, height;
+
+       GF_List *features;
+
+       Bool discardable, multipleInstance;
+
+       /*when a widget is being received from a remote peer, 
+       we remember where we locally store it to be able to further remote it
+       This is only supported for packaged widgets*/
+       char *local_path;
+} GF_Widget;
+
+typedef struct _widget_instance
+{
+       GF_Widget *widget;
+
+       u32 instance_id;
+       JSObject *obj;
+       u8 secname[18];
+       GF_SceneGraph *scene;
+       /*node in the widget manager which holds the widget: Inline {} , <animation>, ...*/
+       GF_Node *anchor;
+
+       Bool activated, permanent;
+
+       GF_List *output_triggers;
+       GF_List *bound_ifces;
+       /*list of components for a parent widget*/
+       GF_List *components;
+       /*parent of the widget for a component widget*/
+       struct _widget_instance *parent;
+
+       GF_DOMParser *mpegu_context;
+
+
+       /*scripting context of the widget scene*/
+       JSContext *scene_context;
+       JSObject *scene_global;
+       /*"Widget" object in the scene*/
+       JSObject *scene_obj;
+} GF_WidgetInstance;
+
+
+typedef struct 
+{
+       GF_WidgetInterface *ifce;
+       GF_WidgetInstance *wid;
+       char *hostname;
+       JSObject *obj;
+       JSObject *cookie;
+} GF_WidgetInterfaceInstance;
+
+typedef struct 
+{
+       GF_WidgetComponent *comp;
+       GF_WidgetInstance *wid;
+} GF_WidgetComponentInstance;
+
+
+GF_WidgetInstance *wm_load_widget(GF_WidgetManager *wm, const char *path, u32 InstanceID, Bool skip_context);
+
+
+JSBool SMJS_FUNCTION(widget_has_feature);
+JSBool SMJS_FUNCTION(widget_open_url);
+JSBool SMJS_FUNCTION(widget_get_attention);
+JSBool SMJS_FUNCTION(widget_show_notification);
+JSBool SMJS_FUNCTION(widget_get_interface);
+JSBool widget_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp);
+JSBool widget_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, jsval *vp);
+
+void widget_on_interface_bind(GF_WidgetInterfaceInstance *ifce, Bool unbind);
+
+void widget_load(GF_WidgetManager *wm, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload);
+
+GF_WidgetComponentInstance *wm_activate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, Bool skip_wm_notification);
+
+void wm_deactivate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, GF_WidgetComponentInstance *comp_inst);
+
+
+
+const char *wm_xml_get_attr(GF_XMLNode *root, const char *name);
+
+GF_BaseInterface *LoadWidgetReader();
+void ShutdownWidgetReader(GF_BaseInterface *ifce);
+
+
+#endif /*GPAC_HAS_SPIDERMONKEY*/
+
+#endif
index 0c1e0d36719530037b0aa43d76912e2d05d5fb32..cf47d9dcd3e92d129d4fbcc2c4caf518aa111d5a 100644 (file)
@@ -15,7 +15,6 @@ LDFLAGS+=-pg
 endif
 
 CFLAGS+=-I"$(SRC_PATH)/include"
-# -I/usr/local/arm/3.3.2/include
 
 
 ifeq ($(X11_INC_PATH), )
@@ -64,7 +63,7 @@ all: $(LIB)
 
 
 $(LIB): $(OBJS)
-       $(CC) $(SHFLAGS) $(LDFLAGS) -lX11 -L../../bin/gcc -lgpac -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS)
+       $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -lX11 -L../../bin/gcc -lgpac $(EXTRALIBS)
 ifeq ($(STATICBUILD),yes)
        $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.$(DYN_LIB_SUFFIX) $(OBJS) -lX11 -L../../bin/gcc -lgpac_static $(EXTRALIBS)
 endif
index 06c8800587d49a2977a713f11b46483fcfa9c8b6..3bdad5b6d01e4020964aba16994748f12ed5df2a 100644 (file)
@@ -168,7 +168,7 @@ endif
 EXTRALIBS+=$(GPAC_SH_FLAGS)
 endif
 
-LD_SONAME="-Wl,-soname,$(LIB)"
+LD_SONAME="-Wl,-soname,libgpac.so.$(VERSION_MAJOR)"
 ifeq ($(CONFIG_DARWIN), yes)
 LD_SONAME=
 endif
@@ -210,6 +210,11 @@ else
        ar cr ../bin/gcc/libgpac_static.a $(OBJS)
        ranlib ../bin/gcc/libgpac_static.a
        $(CC) $(SHFLAGS) $(LD_SONAME) $(LDFLAGS) -o ../bin/gcc/$@ $(OBJS) $(EXTRALIBS)
+ifeq (,$(findstring yes, $(CONFIG_WIN32)))
+       mv ../bin/gcc/$@ ../bin/gcc/$@.$(VERSION_SONAME)
+       ln -sf $@.$(VERSION_SONAME) ../bin/gcc/$@.$(VERSION_MAJOR)
+       ln -sf $@.$(VERSION_SONAME) ../bin/gcc/$@
+endif
 endif
 
 dep: depend
@@ -220,7 +225,9 @@ depend:
 
 clean: 
        rm -f $(OBJS) ../bin/gcc/$(LIB)
-       rm -rf ../bin/gcc/libgpac_static.a
+       rm -rf ../bin/gcc/libgpac_static.a ../bin/gcc/libgpac.so \
+               ../bin/gcc/libgpac.so.$(VERSION_MAJOR) \
+               ../bin/gcc/libgpac.so.$(VERSION_SONAME)
 
 distclean: clean
        rm -f Makefile.bak .depend
index 77960875a54184546820281f5e9d7848a01cff3c..b305c887479acfb8a03ba5855af8453858f56da9 100644 (file)
@@ -102,7 +102,9 @@ enum
 };
 
 GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n);
+#ifndef GPAC_DISABLE_BIFS_ENC
 GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n);
+#endif
 
 #endif /* !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) */
 
index c6733e5798f02a71cfeefd227ca1002d60d875a8..77c09fe99780be77904d23705db7fa8c24f81dfa 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <gpac/internal/scenegraph_dev.h>
 
-#if !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY)
+#if !defined(GPAC_DISABLE_BIFS) && !defined(GPAC_DISABLE_BIFS_ENC) && defined(GPAC_HAS_SPIDERMONKEY)
 
 typedef struct 
 {
@@ -1773,4 +1773,4 @@ void SFE_Params(ScriptEnc *sc_enc, u32 start, u32 end)
        }
 }
 
-#endif /* !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) */
+#endif /* !defined(GPAC_DISABLE_BIFS) && !defined(GPAC_DISABLE_BIFS_ENC) && defined(GPAC_HAS_SPIDERMONKEY) */
index 7bdfb702b6bf5b4b7c1d44abb6ec288c294861aa..8672579365fb98696b232091f2c117bca91577bd 100644 (file)
@@ -2339,7 +2339,7 @@ void gf_sc_traverse_subscene_ex(GF_Compositor *compositor, GF_Node *inline_paren
                                new_tag = TAG_MPEG4_Layer3D;
                        }
                }
-#ifndef GPAC_DISABLE_3D
+#if !defined(GPAC_DISABLE_X3D) && !defined(GPAC_DISABLE_3D)
                /*if the inlined root node is a 3D one except Layer3D and we are not in a 3D context, insert 
                a Layer3D at the root*/
                else if (!tr_state->visual->type_3d && ((tag==TAG_MPEG4_Group) || (tag==TAG_X3D_Group))) {
index df401c7d4eba871441dc36d2d27de28ed8f8a17e..89146088d8e42fb198d892e8ecd46c4bf755c9a1 100644 (file)
@@ -255,7 +255,7 @@ void mesh_recompute_normals(GF_Mesh *mesh)
        }
 }
 
-#ifndef GPAC_DISABLE_VRML
+#if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_X3D)
 void mesh_generate_tex_coords(GF_Mesh *mesh, GF_Node *__texCoords)
 {
        u32 i;
@@ -797,7 +797,7 @@ void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node
 {
        u32 i, n, count, c_count, col_count;
        u32 index;
-       u32 first_idx, last_idx;
+       u32 first_idx, last_idx; 
        Bool move_to;
        SFVec3f pt;
        SFColorRGBA colRGBA;
@@ -805,7 +805,9 @@ void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node
        M_Coordinate2D *coord2D = (M_Coordinate2D*) __coord;
        M_Coordinate *coord = (M_Coordinate*) __coord;
        M_Color *colorRGB = (M_Color *) __color;
+#ifndef GPAC_DISABLE_X3D
        X_ColorRGBA *colorRGBA = (X_ColorRGBA *) __color;
+#endif
 
        if (__coord && (gf_node_get_tag(__coord) == TAG_MPEG4_Coordinate2D)) {
                coord = NULL;
@@ -832,11 +834,16 @@ void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node
        }
        has_color = 0;
        if (__color) {
+#ifndef GPAC_DISABLE_X3D
                if (gf_node_get_tag(__color)==TAG_X3D_ColorRGBA) {
                        colorRGB = NULL;
                        has_color = (colorRGBA->color.count) ? 1 : 0;
-               } else {
-                       colorRGBA = NULL;
+               } else
+#endif
+               {
+#ifndef GPAC_DISABLE_X3D
+                       colorRGBA = NULL;
+#endif
                        has_color = (colorRGB->color.count) ? 1 : 0;
                }
        }
@@ -848,7 +855,9 @@ void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node
        n = 0;
        if (has_color && !colorPerVertex) {
                index = colorIndex->count ? colorIndex->vals[0] : 0;
+#ifndef GPAC_DISABLE_X3D
                if ((u32) index < col_count) MESH_GET_COL(colRGBA, index);
+#endif
        }
        move_to = 1;
 
@@ -865,14 +874,18 @@ void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node
                                if (n<colorIndex->count) index = colorIndex->vals[n];
                                else if (n<col_count) index = n;
                                else index = 0;
+#ifndef GPAC_DISABLE_X3D
                                MESH_GET_COL(colRGBA, index);
+#endif
                        }
                } else {
                        if (has_color && colorPerVertex) {
                                if (i<colorIndex->count) index = colorIndex->vals[i];
                                else if (i<col_count) index = i;
                                else index=0;
+#ifndef GPAC_DISABLE_X3D
                                MESH_GET_COL(colRGBA, index);
+#endif
                        }
                        if (has_coord) index = coordIndex->vals[i];
                        else index = i;
@@ -900,7 +913,9 @@ void mesh_new_ils(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, GF_Node
                mesh_set_line(mesh, last_idx, first_idx);
        }
        if (coord2D) mesh->flags |= MESH_IS_2D;
+#ifndef GPAC_DISABLE_X3D
        if (colorRGBA) mesh->flags |= MESH_HAS_ALPHA;
+#endif
        mesh_update_bounds(mesh);
 }
 
@@ -913,7 +928,9 @@ void mesh_new_ps(GF_Mesh *mesh, GF_Node *__coord, GF_Node *__color)
        M_Coordinate2D *coord2D = (M_Coordinate2D*) __coord;
        M_Coordinate *coord = (M_Coordinate*) __coord;
        M_Color *colorRGB = (M_Color *) __color;
+#ifndef GPAC_DISABLE_X3D
        X_ColorRGBA *colorRGBA = (X_ColorRGBA *) __color;
+#endif
 
        if (__coord && (gf_node_get_tag(__coord) == TAG_MPEG4_Coordinate2D)) {
                coord = NULL;
@@ -930,11 +947,16 @@ void mesh_new_ps(GF_Mesh *mesh, GF_Node *__coord, GF_Node *__color)
 
        has_color = 0;
        if (__color) {
+#ifndef GPAC_DISABLE_X3D
                if (gf_node_get_tag(__color)==TAG_X3D_ColorRGBA) {
                        colorRGB = NULL;
                        has_color = (colorRGBA->color.count) ? 1 : 0;
-               } else {
+               } else 
+#endif
+               {
+#ifndef GPAC_DISABLE_X3D
                        colorRGBA = NULL;
+#endif
                        has_color = (colorRGB->color.count) ? 1 : 0;
                }
        }
@@ -943,7 +965,9 @@ void mesh_new_ps(GF_Mesh *mesh, GF_Node *__coord, GF_Node *__color)
        colRGBA.red = colRGBA.green = colRGBA.blue = colRGBA.alpha = FIX_ONE;
 
        for (i=0; i<c_count; ++i) {
+#ifndef GPAC_DISABLE_X3D
                if (has_color) MESH_GET_COL(colRGBA, i);
+#endif
                if (coord2D) {
                        pt.x = coord2D->point.vals[i].x;
                        pt.y = coord2D->point.vals[i].y;
@@ -1047,7 +1071,9 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
        M_Coordinate2D *coord2D = (M_Coordinate2D*) __coord;
        M_Coordinate *coord = (M_Coordinate*) __coord;
        M_Color *colorRGB = (M_Color *) __color;
+#ifndef GPAC_DISABLE_X3D
        X_ColorRGBA *colorRGBA = (X_ColorRGBA *) __color;
+#endif
        M_Normal *normal = (M_Normal*) __normal;
        M_TextureCoordinate *txcoord = (M_TextureCoordinate*) __texCoords;
 
@@ -1059,15 +1085,21 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
                coord = NULL;
        } else {
                coord2D = NULL;
-               if (!__coord) return;
+               if (!__coord)
+                       return;
                /*not supported yet*/
-               if (gf_node_get_tag(__coord) == TAG_X3D_CoordinateDouble) return;
+#ifndef GPAC_DISABLE_X3D
+               if (gf_node_get_tag(__coord) == TAG_X3D_CoordinateDouble)
+                       return;
+#endif
        }
        gen_tex_coords = 0;
+#ifndef GPAC_DISABLE_X3D
        if (__texCoords && (gf_node_get_tag(__texCoords)==TAG_X3D_TextureCoordinateGenerator)) {
                gen_tex_coords = 1;
                txcoord = NULL;
        }
+#endif
 
        if (!coord2D && !coord) return;
        c_count = coord2D ? coord2D->point.count : coord->point.count;
@@ -1115,11 +1147,16 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
 
        has_color = 0;
        if (__color) {
+#ifndef GPAC_DISABLE_X3D
                if (gf_node_get_tag(__color)==TAG_X3D_ColorRGBA) {
                        colorRGB = NULL;
                        has_color = (colorRGBA->color.count) ? 1 : 0;
-               } else {
+               } else
+#endif
+               {
+#ifndef GPAC_DISABLE_X3D
                        colorRGBA = NULL;
+#endif
                        has_color = (colorRGB->color.count) ? 1 : 0;
                }
        }
@@ -1127,7 +1164,9 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
        if (has_color) {
                if (!colorPerVertex) {
                        index = colorIndex->count ? colorIndex->vals[0] : 0;
+#ifndef GPAC_DISABLE_X3D
                        MESH_GET_COL(colRGBA, index);
+#endif
                } else {
                        if (!colorIndex->vals) colorIndex = coordIndex;
                }
@@ -1178,7 +1217,9 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
                        n++;
                        if (has_color && !colorPerVertex) {
                                GET_IDX(n, colorIndex);
+#ifndef GPAC_DISABLE_X3D
                                MESH_GET_COL(colRGBA, index);
+#endif
                        }
                        if (has_normal && !normalPerVertex) {
                                GET_IDX(n, normalIndex);
@@ -1205,7 +1246,9 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
                } else {
                        if (has_color && colorPerVertex) {
                                GET_IDX(i, colorIndex);
+#ifndef GPAC_DISABLE_X3D
                                MESH_GET_COL(colRGBA, index);
+#endif
                        }
                        if (has_normal && normalPerVertex) {
                                GET_IDX(i, normalIndex);
@@ -1300,8 +1343,10 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex,
 
        if (!coord2D) gf_mesh_build_aabbtree(mesh);
 
+#ifndef GPAC_DISABLE_X3D
        if (colorRGBA) mesh->flags |= MESH_HAS_ALPHA;
        if (gen_tex_coords) mesh_generate_tex_coords(mesh, __texCoords);
+#endif
 }
 
 void mesh_new_ifs2d(GF_Mesh *mesh, GF_Node *node)
@@ -1336,7 +1381,9 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node)
        M_ElevationGrid *eg = (M_ElevationGrid *) node;
        M_Normal *norm = (M_Normal *)eg->normal;
        M_Color *colorRGB = (M_Color *)eg->color;
+#ifndef GPAC_DISABLE_X3D
        X_ColorRGBA *colorRGBA = (X_ColorRGBA *)eg->color;
+#endif
        SFColorRGBA rgba;
        M_TextureCoordinate *txc = (M_TextureCoordinate *)eg->texCoord;
 
@@ -1349,11 +1396,16 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node)
        has_normal = norm ? norm->vector.count : 0;
        has_color = 0;
        if (eg->color) {
+#ifndef GPAC_DISABLE_X3D
                if (gf_node_get_tag(eg->color)==TAG_X3D_ColorRGBA) {
                        colorRGB = NULL;
                        has_color = colorRGBA->color.count ? 1 : 0;
-               } else {
+               } else 
+#endif
+               {
+#ifndef GPAC_DISABLE_X3D
                        colorRGBA = NULL;
+#endif
                        has_color = colorRGB->color.count ? 1 : 0;
                }
        }
@@ -1424,7 +1476,9 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node)
                        /*get face color*/
             if (has_color && !eg->colorPerVertex) {
                                idx = i + j * (xDimension-1);
+#ifndef GPAC_DISABLE_X3D
                                MESH_GET_COL(rgba, idx);
+#endif
                                vx.color = MESH_MAKE_COL(rgba);
             }
                        /*get face normal*/
@@ -1447,7 +1501,9 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node)
                                        /*get color per vertex*/
                                        if (has_color && eg->colorPerVertex) {
                                                idx = i+l + (j+k) * xDimension;
+#ifndef GPAC_DISABLE_X3D
                                                MESH_GET_COL(rgba, idx);
+#endif
                                                vx.color = MESH_MAKE_COL(rgba);
                                        }
                                        /*get tex coord*/
@@ -1555,7 +1611,9 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node)
        mesh_update_bounds(mesh);
        if (!eg->ccw) mesh->flags |= MESH_IS_CW;
        if (eg->solid) mesh->flags |= MESH_IS_SOLID;
+#ifndef GPAC_DISABLE_X3D
        if (colorRGBA) mesh->flags |= MESH_HAS_ALPHA;
+#endif
        gf_mesh_build_aabbtree(mesh);
 }
 
index 87b1536c8f47a07d4ac9fcd0c4ad723554cad5b4..0e67cd5f2c9e0d2f335f0a0e3c54d18e8169e136 100644 (file)
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_make_psp) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_import) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_import_chapters) )
-#pragma comment (linker, EXPORT_SYMBOL(gf_media_change_par) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_change_pl) )
-#pragma comment (linker, EXPORT_SYMBOL(gf_media_fragment_file) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_avc_rewrite_samples) )
 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
 
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_change_par) )
+
 
 #ifndef GPAC_DISABLE_AV_PARSERS
 #pragma comment (linker, EXPORT_SYMBOL(gf_avc_get_sps_info) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_sm_load_bt_from_string) )
 #endif
 
-#ifndef GPAC_DISABLE_SCENE_ENCODER
+#if !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_ISOM_WRITE)
 #pragma comment (linker, EXPORT_SYMBOL(gf_sm_encode_to_file) )
 #endif
 
 #pragma comment (linker, EXPORT_SYMBOL(gf_sm_dump) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_sm_dump_command_list) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_sm_dump_graph) )
+#ifndef GPAC_DISABLE_OD_DUMP
 #pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_au) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_com) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_desc) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_com_list) )
+#ifndef GPAC_MINIMAL_ODF
 #pragma comment (linker, EXPORT_SYMBOL(gf_oci_dump_event) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_oci_dump_au) )
 #endif
+#endif
+#endif
 
 #ifndef GPAC_DISABLE_SENG
 /*bifsengine exports*/
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_wget) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_dm_wget_with_cache) )
 
-#ifndef GPAC_DISABLE_ISOM
+#ifndef GPAC_DISABLE_ISOM_WRITE
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_mpd_start) )
 #pragma comment (linker, EXPORT_SYMBOL(gf_media_mpd_end) )
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+#pragma comment (linker, EXPORT_SYMBOL(gf_media_fragment_file) )
+#endif
 #endif
 
 /* dvb_mpe.h */
index be74f8f93725bf636543213cc8182ab763ae8fb6..850af4b784c9313bf84fd0df4dc13f1d5a3083b2 100644 (file)
@@ -31,7 +31,7 @@
 #endif
 #include <gpac/internal/ietf_dev.h>
 
-#ifndef GPAC_DISABLE_STREAMING
+#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_ISOM)
 
 struct __rtp_streamer
 {
@@ -733,5 +733,5 @@ GF_Err gf_rtp_streamer_send_rtcp(GF_RTPStreamer *streamer, Bool force_ts, u32 rt
        return gf_rtp_send_rtcp_report(streamer->channel, NULL, NULL);
 }
 
-#endif /*GPAC_DISABLE_STREAMING*/
+#endif /*GPAC_DISABLE_STREAMING && GPAC_DISABLE_ISOM*/
 
index 46a260321502c3b381b8cfb64ac513039171c5b3..ab39b6d512e9d8409da67ff6bdc01cb8ee871281 100644 (file)
@@ -5846,12 +5846,11 @@ GF_Err tfhd_Size(GF_Box *s)
        return GF_OK;
 }
 
-
-
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 #endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
+
 void tims_del(GF_Box *s)
 {
        GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s;
@@ -6092,11 +6091,9 @@ GF_Box *traf_New()
        return (GF_Box *)tmp;
 }
 
-
  
 #ifndef GPAC_DISABLE_ISOM_WRITE
 
-
 GF_Err traf_Write(GF_Box *s, GF_BitStream *bs)
 {
        GF_Err e;
@@ -7754,7 +7751,6 @@ GF_Err lsr1_Size(GF_Box *s)
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
-#ifndef        GPAC_DISABLE_ISOM_FRAGMENTS
 
 void sidx_del(GF_Box *s)
 {
@@ -7863,7 +7859,6 @@ GF_Err sidx_Size(GF_Box *s)
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
-#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
 
 GF_Box *subs_New()
@@ -7898,6 +7893,9 @@ void subs_del(GF_Box *s)
        gf_free(ptr);
 }
 
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
 GF_Err subs_Write(GF_Box *s, GF_BitStream *bs)
 {
        GF_Err e;
@@ -7959,6 +7957,7 @@ GF_Err subs_Size(GF_Box *s)
        return GF_OK;
 }
 
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
 
 GF_Err subs_Read(GF_Box *s, GF_BitStream *bs)
 {
@@ -8004,6 +8003,8 @@ GF_Err subs_Read(GF_Box *s, GF_BitStream *bs)
 }
 
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+
 GF_Box *tfdt_New()
 {
        GF_TFBaseMediaDecodeTimeBox *tmp;
@@ -8071,7 +8072,7 @@ GF_Err tfdt_Size(GF_Box *s)
 
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
-
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
 
 GF_Box *rvcc_New()
index 4af3783634a3a170f09cda7f1c582f4d14ceb9d5..bad1efcc23ed18f1f822302df28de34a51510e35 100644 (file)
@@ -3500,6 +3500,7 @@ GF_Err lsr1_dump(GF_Box *a, FILE * trace)
        return GF_OK;
 }
 
+
 GF_Err sidx_dump(GF_Box *a, FILE * trace)
 {
        u32 i;
@@ -3547,7 +3548,7 @@ GF_Err subs_dump(GF_Box *a, FILE * trace)
        return GF_OK;
 }
 
-
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
 GF_Err tfdt_dump(GF_Box *a, FILE * trace)
 {
        GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox*) a;
@@ -3559,6 +3560,7 @@ GF_Err tfdt_dump(GF_Box *a, FILE * trace)
        fprintf(trace, "</TrackFragmentBaseMediaDecodeTimeBox>\n");
        return GF_OK;
 }
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
 GF_Err rvcc_dump(GF_Box *a, FILE * trace)
 {
index d17a27c0b77032610868b0a2294ca4678515cd59..c870f45c41ca141c92944750fb38595a88b0b599 100644 (file)
@@ -565,9 +565,11 @@ GF_Box *gf_isom_box_new(u32 boxType)
        case GF_ISOM_BOX_TYPE_LSRC: return lsrc_New();
        case GF_ISOM_BOX_TYPE_LSR1: return lsr1_New();
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        case GF_ISOM_BOX_TYPE_SIDX: return sidx_New();
        case GF_ISOM_BOX_TYPE_SUBS: return subs_New();
        case GF_ISOM_BOX_TYPE_TFDT: return tfdt_New();
+#endif
        case GF_ISOM_BOX_TYPE_RVCC: return rvcc_New();
 
        default:
@@ -691,6 +693,7 @@ void gf_isom_box_del(GF_Box *a)
        case GF_ISOM_BOX_TYPE_MFHD: mfhd_del(a); return;
        case GF_ISOM_BOX_TYPE_TRAF: traf_del(a); return;
        case GF_ISOM_BOX_TYPE_TFHD: tfhd_del(a); return;
+       case GF_ISOM_BOX_TYPE_TFDT: tfdt_del(a); return;
        case GF_ISOM_BOX_TYPE_TRUN: trun_del(a); return;
 #endif
 
@@ -820,7 +823,6 @@ void gf_isom_box_del(GF_Box *a)
 
        case GF_ISOM_BOX_TYPE_SIDX: sidx_del(a); return;
        case GF_ISOM_BOX_TYPE_SUBS: subs_del(a); return;
-       case GF_ISOM_BOX_TYPE_TFDT: tfdt_del(a); return;
        case GF_ISOM_BOX_TYPE_RVCC: rvcc_del(a); return;
 
        default:
@@ -830,8 +832,6 @@ void gf_isom_box_del(GF_Box *a)
 }
 
 
-
-
 GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
 {
        switch (a->type) {
@@ -932,6 +932,7 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_MFHD: return mfhd_Read(a, bs);
        case GF_ISOM_BOX_TYPE_TRAF: return traf_Read(a, bs);
        case GF_ISOM_BOX_TYPE_TFHD: return tfhd_Read(a, bs);
+       case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Read(a, bs);
        case GF_ISOM_BOX_TYPE_TRUN: return trun_Read(a, bs);
 #endif
        
@@ -1053,7 +1054,6 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs)
 
        case GF_ISOM_BOX_TYPE_SIDX: return sidx_Read(a, bs); 
        case GF_ISOM_BOX_TYPE_SUBS: return subs_Read(a, bs);
-       case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Read(a, bs);
        case GF_ISOM_BOX_TYPE_RVCC: return rvcc_Read(a, bs);
 
        default:
@@ -1166,6 +1166,7 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
        case GF_ISOM_BOX_TYPE_MFHD: return mfhd_Write(a, bs);
        case GF_ISOM_BOX_TYPE_TRAF: return traf_Write(a, bs);
        case GF_ISOM_BOX_TYPE_TFHD: return tfhd_Write(a, bs);
+       case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Write(a, bs); 
        case GF_ISOM_BOX_TYPE_TRUN: return trun_Write(a, bs);
 #endif 
 
@@ -1287,7 +1288,6 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs)
 
        case GF_ISOM_BOX_TYPE_SIDX: return sidx_Write(a, bs); 
        case GF_ISOM_BOX_TYPE_SUBS: return subs_Write(a, bs);
-       case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Write(a, bs); 
        case GF_ISOM_BOX_TYPE_RVCC: return rvcc_Write(a, bs); 
 
        default:
@@ -1399,6 +1399,7 @@ GF_Err gf_isom_box_size(GF_Box *a)
        case GF_ISOM_BOX_TYPE_MFHD: return mfhd_Size(a);
        case GF_ISOM_BOX_TYPE_TRAF: return traf_Size(a);
        case GF_ISOM_BOX_TYPE_TFHD: return tfhd_Size(a);
+       case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Size(a);
        case GF_ISOM_BOX_TYPE_TRUN: return trun_Size(a);
 #endif
        
@@ -1519,7 +1520,6 @@ GF_Err gf_isom_box_size(GF_Box *a)
 
        case GF_ISOM_BOX_TYPE_SIDX: return sidx_Size(a); 
        case GF_ISOM_BOX_TYPE_SUBS: return subs_Size(a);
-       case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Size(a);
        case GF_ISOM_BOX_TYPE_RVCC: return rvcc_Size(a);
 
        default: return defa_Size(a);
index e24ee8142d5608317843fd98f226d081b31c9204..28753542508c13a9df1db65ef0db0577a5264021 100644 (file)
@@ -430,8 +430,9 @@ void gf_isom_delete_movie(GF_ISOFile *mov)
 #endif
 
        gf_isom_box_array_del(mov->TopBoxes);
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        gf_isom_box_array_del(mov->moof_list);
-
+#endif
 
        if (mov->fileName) gf_free(mov->fileName);
        gf_free(mov);
@@ -496,7 +497,13 @@ GF_Err GetMediaTime(GF_TrackBox *trak, Bool force_non_empty, u64 movieTime, u64
        if (! trak->editBox || !trak->editBox->editList) {
                *MediaTime = movieTime;
                //check this is in our media time line
-               if (!trak->moov->mov->use_segments && (*MediaTime > lastSampleTime)) *MediaTime = lastSampleTime;
+               if ((*MediaTime > lastSampleTime)
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+                       && !trak->moov->mov->use_segments
+#endif
+                  ) {
+                       *MediaTime = lastSampleTime;
+               }
                *useEdit = 0;
                return GF_OK;
        }
index 261304cdbe3370e816ad9146cdad1f55ba46dc4c..66821b9d7ea34c225ec29f4caf45c21e3f79206f 100644 (file)
@@ -59,7 +59,9 @@ u64 gf_isom_get_file_size(GF_ISOFile *the_file)
 {
        if (!the_file) return 0;
        if (the_file->movieFileMap) return gf_bs_get_size(the_file->movieFileMap->bs);
+#ifndef GPAC_DISABLE_ISOM_WRITE
        if (the_file->editFileMap) return gf_bs_get_size(the_file->editFileMap->bs);
+#endif
        return 0;
 }
 
@@ -1023,7 +1025,11 @@ u32 gf_isom_get_sample_count(GF_ISOFile *the_file, u32 trackNumber)
        GF_TrackBox *trak;
        trak = gf_isom_get_track_from_file(the_file, trackNumber);
        if (!trak) return 0;
-       return trak->Media->information->sampleTable->SampleSize->sampleCount + trak->sample_count_at_seg_start;
+       return trak->Media->information->sampleTable->SampleSize->sampleCount
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+               + trak->sample_count_at_seg_start
+#endif
+               ;
 }
 
 u32 gf_isom_get_constant_sample_size(GF_ISOFile *the_file, u32 trackNumber)
@@ -1395,7 +1401,11 @@ GF_Err gf_isom_get_sample_for_movie_time(GF_ISOFile *the_file, u32 trackNumber,
                        return GF_EOS;
                }
        }
-       else if (!trak->dts_at_seg_start && (movieTime * trak->moov->mvhd->timeScale > trak->Header->duration * trak->Media->mediaHeader->timeScale)) {
+       else if ((movieTime * trak->moov->mvhd->timeScale > trak->Header->duration * trak->Media->mediaHeader->timeScale)
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+               && !trak->dts_at_seg_start
+#endif
+               ) {
                *sample = NULL;
                if (sampleNumber) *sampleNumber = 0;
                *StreamDescriptionIndex = 0;
@@ -2692,11 +2702,15 @@ void gf_isom_reset_fragment_info(GF_ISOFile *movie)
        if (!movie) return;
        for (i=0; i<gf_list_count(movie->moov->trackList); i++) {
                GF_TrackBox *trak = gf_list_get(movie->moov->trackList, i);
+               trak->Media->information->sampleTable->SampleSize->sampleCount = 0;
+#ifdef GPAC_DISABLE_ISOM_FRAGMENTS
+       }
+#else
                trak->dts_at_seg_start = 0;
                trak->sample_count_at_seg_start = 0;
-               trak->Media->information->sampleTable->SampleSize->sampleCount = 0;
        }
        movie->NextMoofNumber = 0;
+#endif
 }
 
 GF_Err gf_isom_get_sample_rap_roll_info(GF_ISOFile *the_file, u32 trackNumber, u32 sample_number, Bool *is_rap, Bool *has_roll, s32 *roll_distance)
index b898dc93ec103d6817063843168806ee67aca8cb..33b71605e1bcb59ef551095796560f1ae7a4e87e 100644 (file)
@@ -1953,17 +1953,18 @@ GF_Err gf_isom_use_compact_size(GF_ISOFile *movie, u32 trackNumber, u8 Compactio
 GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 MajorBrand, u32 MinorVersion)
 {
        u32 i, *p;
-       GF_Err e;
 
        if (!MajorBrand) return GF_BAD_PARAM;
        
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        if (! (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY)) {
-               e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
+               GF_Err e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
                if (e) return e;
 
                e = CheckNoData(movie);
                if (e) return e;
        }
+#endif
 
        if (!movie->brand) {
                movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP);
@@ -1997,17 +1998,18 @@ GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 MajorBrand, u32 MinorVersio
 GF_Err gf_isom_modify_alternate_brand(GF_ISOFile *movie, u32 Brand, u8 AddIt)
 {
        u32 i, k, *p;
-       GF_Err e;
        
        if (!Brand) return GF_BAD_PARAM;
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        if (! (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY)) {
-               e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
+               GF_Err e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
                if (e) return e;
        
                e = CheckNoData(movie);
                if (e) return e;
        }
+#endif
 
        if (!movie->brand && AddIt) {
                movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP);
@@ -2065,15 +2067,16 @@ found:
 GF_Err gf_isom_reset_alt_brands(GF_ISOFile *movie)
 {
        u32 *p;
-       GF_Err e;
        
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        if (! (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY)) {
-               e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
+               GF_Err e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
                if (e) return e;
                
                e = CheckNoData(movie);
                if (e) return e;
        }
+#endif
 
        if (!movie->brand) {
                movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP);
index 38f87cd53c25b2fe69fd0ce2a2274f4aec20101d..187ff4edf897d419847177bc15ed010ef304fbde 100644 (file)
@@ -39,9 +39,6 @@ GF_TrackExtendsBox *GetTrex(GF_MovieBox *moov, u32 TrackID)
        return NULL;
 }
 
-
-#ifndef GPAC_DISABLE_ISOM_WRITE
-
 GF_TrackFragmentBox *GetTraf(GF_ISOFile *mov, u32 TrackID)
 {
        u32 i;
@@ -56,6 +53,9 @@ GF_TrackFragmentBox *GetTraf(GF_ISOFile *mov, u32 TrackID)
        return NULL;
 }
 
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
 GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments)
 {
        GF_Err e;
index feaf651dc6a25cfc028b60e61bfb710ff96102d8..0bc694f06383fab2a8565230d886d22984dd394b 100644 (file)
  *
  */
 
-#include <gpac/isomedia.h>
-#include <gpac/ietf.h>
-#include <gpac/config_file.h>
-#include <gpac/base_coding.h>
 #include <gpac/internal/media_dev.h>
-#include <gpac/filestreamer.h>
-#include <gpac/rtp_streamer.h>
 #include <gpac/constants.h>
 #include <gpac/math.h>
 
 #if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING)
 
+#include <gpac/isomedia.h>
+#include <gpac/ietf.h>
+#include <gpac/config_file.h>
+#include <gpac/base_coding.h>
+#include <gpac/filestreamer.h>
+#include <gpac/rtp_streamer.h>
 
 typedef struct __tag_rtp_track
 {
index aec2100297d14043dc80f303e7d8ae42cef33ce2..acaa0dc6ab3269b1190634935aa7cc095b6c58ac 100644 (file)
@@ -560,7 +560,9 @@ GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (
        GF_IPMPPtr *ipmpdp;
        GF_IPMP_Descriptor *ipmpd;
        GF_IPMPUpdate *ipmpdU;
+#ifndef GPAC_MINIMAL_ODF
        GF_IPMPX_ISMACryp *ismac;
+#endif
        GF_Err e;
        Bool prev_sample_encryped, has_crypted_samp;
 
@@ -775,6 +777,7 @@ GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (
        /*format IPMPD*/
        ipmpd = (GF_IPMP_Descriptor*)gf_odf_desc_new(GF_ODF_IPMP_TAG);
        if (tci->ipmp_type==2) {
+#ifndef GPAC_MINIMAL_ODF
                ipmpd->IPMP_DescriptorID = 0xFF;
                ipmpd->IPMP_DescriptorIDEx = tci->ipmp_desc_id;
                ipmpd->IPMPS_Type = 0xFFFF;
@@ -788,6 +791,7 @@ GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (
                ismac->key_indicator_length = 0;
                ismac->use_selective_encryption = (tci->sel_enc_type!=0)? 1 : 0;
                gf_list_add(ipmpd->ipmpx_data, ismac);
+#endif
        } else {
                ipmpd->IPMP_DescriptorID = tci->ipmp_desc_id;
        }
index 9f3939b282a23169861432e1f013ef0fa9d9b761..3f336a154d9ca84a1b267042f185834908d478c2 100644 (file)
@@ -51,11 +51,14 @@ GF_Err gf_media_get_rfc_6381_codec_name(GF_ISOFile *movie, u32 track, char *szCo
                        }
                        break;
                case GF_STREAM_VISUAL:
+#ifndef GPAC_DISABLE_AV_PARSERS
                        if (esd->decoderConfig->decoderSpecificInfo) {
                                GF_M4VDecSpecInfo dsi;
                                gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);
                                sprintf(szCodec, "mp4v.%02x.%02x", esd->decoderConfig->objectTypeIndication, dsi.VideoPL);
-                       } else {
+                       } else
+#endif
+                       {
                                sprintf(szCodec, "mp4v.%02x", esd->decoderConfig->objectTypeIndication);
                        }
                        break;
@@ -697,6 +700,8 @@ static u64 get_next_sap_time(GF_ISOFile *input, u32 track, u32 sample_count, u32
 }
 
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
+
 GF_EXPORT
 GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const char *mpd_name, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 subsegs_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, Bool single_segment_mode, const char *dash_ctx_file, GF_ISOFile *sample_descs, u32 rep_idx)
 {
@@ -709,7 +714,6 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const
        GF_Err e;
        char sOpt[100], sKey[100];
        char szCodecs[200], szCodec[100];
-       char szComponents[1000];
        u32 cur_seg, fragment_index, nb_fragments, max_sap_type;
        GF_ISOFile *output;
        GF_ISOSample *sample, *next;
@@ -916,6 +920,7 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const
 
                                }
 
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
                                //the initialization segment is not yet setup for fragmentation
                                if (! gf_isom_is_track_fragmented(sample_descs, tf->TrackID)) {
                                        e = gf_isom_setup_track_fragment(sample_descs, sample_descs_track,
@@ -933,9 +938,8 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const
                                        e = gf_isom_change_track_fragment_defaults(output, TrackNum,
                                                                                         defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, defaultPadding, defaultDegradationPriority);
                                        if (e) goto err_exit;
-
-
                                }
+#endif
 
                                /*reset all sample desc and clone with new ones*/
                                gf_isom_clone_sample_descriptions(output, TrackNum, sample_descs, sample_descs_track, 1);
@@ -991,30 +995,6 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const
                nb_samp += count;
        }
 
-       /*format component info*/
-       szComponents[0] = 0;
-       for (i=0; i<gf_list_count(fragmenters); i++) {
-               char szComponent[100];
-               tf = gf_list_get(fragmenters, i);
-               switch (tf->MediaType) {
-               case GF_ISOM_MEDIA_TEXT:
-                       gf_isom_get_media_language(input, i+1, langCode);
-                       sprintf(szComponent, "    <ContentComponent id=\"%d\" contentType=\"text\" lang=\"%s\"/>\n", tf->TrackID, langCode);
-                       break;
-               case GF_ISOM_MEDIA_VISUAL:
-                       sprintf(szComponent, "    <ContentComponent id=\"%d\" contentType=\"video\"/>\n", tf->TrackID);
-                       break;
-               case GF_ISOM_MEDIA_SCENE:
-               case GF_ISOM_MEDIA_DIMS:
-                       sprintf(szComponent, "    <ContentComponent id=\"%d\" contentType=\"application\" lang=\"%s\"/>\n", tf->TrackID, langCode);
-                       break;
-               case GF_ISOM_MEDIA_AUDIO:
-                       sprintf(szComponent, "    <ContentComponent id=\"%d\" contentType=\"audio\" lang=\"%s\"/>\n", tf->TrackID, langCode);
-                       break;
-               }
-               strcat(szComponents, szComponent);
-       }
-
        if (!tfref) tfref = gf_list_get(fragmenters, 0);
        tfref->is_ref_track = 1;
        tfref_timescale = tfref->TimeScale;
@@ -1022,8 +1002,10 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, const char *output_file, const
        if (tfref->all_sample_raps) split_seg_at_rap = 1;
 
        //flush movie
+#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
        e = gf_isom_finalize_for_fragment(output, dash_mode ? 1 : 0);
        if (e) goto err_exit;
+#endif
 
        start_range = 0;
        file_size = gf_isom_get_file_size(output);
@@ -1485,7 +1467,6 @@ restart_fragmentation_pass:
                
                fprintf(mpd, " bandwidth=\"%d\"", bandwidth);           
                fprintf(mpd, ">\n");
-               if (strlen(szComponents)) fprintf(mpd, "%s", szComponents);
 
                if (dash_ctx) {
                        Double seg_dur;
@@ -1582,8 +1563,9 @@ err_exit:
        return e;
 }
 
+#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/
 
-GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bool single_segment, char *dash_ctx, char *init_segment, Double period_duration)
+GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bool single_segment, char *dash_ctx, GF_ISOFile *init_segment, Double period_duration)
 {
        u32 h, m;
        Double s;
@@ -1606,11 +1588,37 @@ GF_Err gf_media_mpd_start(char *mpd_name, char *title, Bool use_url_template, Bo
        fprintf(mpd, "  <AdaptationSet>\n");
 
        if (init_segment) {
+               u32 i;
+               char langCode[4];
+               langCode[3] = 0;
+
+               for (i=0; i<gf_isom_get_track_count(init_segment); i++) {
+                       u32 trackID = gf_isom_get_track_id(init_segment, i+1);
+
+                       gf_isom_get_media_language(init_segment, i+1, langCode);
+
+                       switch (gf_isom_get_media_type(init_segment, i+1) ) {
+                       case GF_ISOM_MEDIA_TEXT:
+                               fprintf(mpd, "    <ContentComponent id=\"%d\" contentType=\"text\" lang=\"%s\"/>\n", trackID, langCode);
+                               break;
+                       case GF_ISOM_MEDIA_VISUAL:
+                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"video\"/>\n", trackID);
+                               break;
+                       case GF_ISOM_MEDIA_SCENE:
+                       case GF_ISOM_MEDIA_DIMS:
+                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"application\" lang=\"%s\"/>\n", trackID, langCode);
+                               break;
+                       case GF_ISOM_MEDIA_AUDIO:
+                               fprintf(mpd, "   <ContentComponent id=\"%d\" contentType=\"audio\" lang=\"%s\"/>\n", trackID, langCode);
+                               break;
+                       }
+               }
+
                if (use_url_template) {
-                       fprintf(mpd, "   <SegmentTemplate initialization=\"%s\"/>\n", init_segment);    
+                       fprintf(mpd, "   <SegmentTemplate initialization=\"%s\"/>\n", gf_isom_get_filename(init_segment) );     
                } else if (0 && !single_segment) {
                        fprintf(mpd, "   <SegmentList>\n");     
-                       fprintf(mpd, "    <Initialization sourceURL=\"%s\"/>\n", init_segment); 
+                       fprintf(mpd, "    <Initialization sourceURL=\"%s\"/>\n", gf_isom_get_filename(init_segment) );  
                        fprintf(mpd, "   </SegmentList>\n");    
                }
        }
index 2c82391e0e3b6b98ed98649f41bef9ea67929a14..be9abf90526260638407436da11e926dfcf4722e 100644 (file)
@@ -26,7 +26,7 @@
 #include <gpac/constants.h>
 #include <gpac/media_tools.h>
 
-#ifndef GPAC_DISABLE_MPEG2TS_MUX
+#if !defined(GPAC_DISABLE_MPEG2TS_MUX) && !defined(GPAC_DISABLE_MPEG2TS)
 
 /*num ms between PCR*/
 #define PCR_UPDATE_MS  200
index f1374a0bf93f7c344e944cbbc49394bb9a98585b..32255fb0cb710c09023305d549205923164e7822 100644 (file)
@@ -1522,10 +1522,12 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper)
        } 
        /*MPEG4*/
        else {
+#ifndef GPAC_DISABLE_AV_PARSERS
                /*ignore visual size info, get it from dsi*/
                gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi);
                w = dsi.width;
                h = dsi.height;
+#endif
 
                v4CC = "XVID";
 
index ca904df9d5c1e7f7995f079b4d175675aa610994..f097a4abe57fb8e21b263c286522e7c9b0d7d773 100644 (file)
@@ -6811,6 +6811,41 @@ GF_Err gf_media_import(GF_MediaImporter *importer)
        return gf_import_message(importer, e, "Unknown input file type");
 }
 
+
+GF_EXPORT
+GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level)
+{
+       u32 i, count, stype;
+       GF_Err e;
+       GF_AVCConfig *avcc;
+
+       stype = gf_isom_get_media_subtype(file, track, 1);
+       switch (stype) {
+       case GF_ISOM_SUBTYPE_AVC_H264:
+       case GF_ISOM_SUBTYPE_AVC2_H264:
+               break;
+       default:
+               return GF_OK;
+       }
+
+       avcc = gf_isom_avc_config_get(file, track, 1);
+       if (level) avcc->AVCLevelIndication = level;
+       if (profile) avcc->AVCProfileIndication = profile;
+       count = gf_list_count(avcc->sequenceParameterSets);
+       for (i=0; i<count; i++) {
+               GF_AVCConfigSlot *slc = gf_list_get(avcc->sequenceParameterSets, i);
+               if (profile) slc->data[1] = profile;
+               if (level) slc->data[3] = level;
+       }
+       e = gf_isom_avc_config_update(file, track, 1, avcc);
+       assert (e == GF_OK);
+       gf_odf_avc_cfg_del(avcc);
+       return GF_OK;
+}
+
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
+
+
 GF_EXPORT
 GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den)
 {
@@ -6862,37 +6897,3 @@ GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den)
        }
        return gf_isom_set_track_layout_info(file, track, tk_w<<16, tk_h<<16, 0, 0, 0);
 }
-
-
-GF_EXPORT
-GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level)
-{
-       u32 i, count, stype;
-       GF_Err e;
-       GF_AVCConfig *avcc;
-
-       stype = gf_isom_get_media_subtype(file, track, 1);
-       switch (stype) {
-       case GF_ISOM_SUBTYPE_AVC_H264:
-       case GF_ISOM_SUBTYPE_AVC2_H264:
-               break;
-       default:
-               return GF_OK;
-       }
-
-       avcc = gf_isom_avc_config_get(file, track, 1);
-       if (level) avcc->AVCLevelIndication = level;
-       if (profile) avcc->AVCProfileIndication = profile;
-       count = gf_list_count(avcc->sequenceParameterSets);
-       for (i=0; i<count; i++) {
-               GF_AVCConfigSlot *slc = gf_list_get(avcc->sequenceParameterSets, i);
-               if (profile) slc->data[1] = profile;
-               if (level) slc->data[3] = level;
-       }
-       e = gf_isom_avc_config_update(file, track, 1, avcc);
-       assert (e == GF_OK);
-       gf_odf_avc_cfg_del(avcc);
-       return GF_OK;
-}
-
-#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
index c9b36b094ff8db031c494a6b8118bf299266fd88..feeed1c1d2ed74ce809b41ca1bc906224d438f3b 100644 (file)
@@ -1241,8 +1241,8 @@ GF_Err gf_m3u8_to_mpd(const char *m3u8_file, const char *base_url,
                                pe->codecs[len-2] = 0;
                        }
 
-#ifndef GPAC_DISABLE_MEDIA_IMPORT
                        width = height = samplerate = num_channels = 0;
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                        if (do_import) {
                                GF_Err e;
                                GF_MediaImporter import;
index 3d4801f0698f0b9d0358957e313d85903410bd8a..4abc7e80e19118c6c52408c68889e2a2d2300030 100644 (file)
@@ -152,6 +152,7 @@ static void gf_text_get_video_size(GF_ISOFile *dest, u32 *width, u32 *height)
 }
 
 
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
 static void gf_text_import_set_language(GF_MediaImporter *import, u32 track)
 {
        if (import->esd && import->esd->langDesc) {
@@ -163,7 +164,7 @@ static void gf_text_import_set_language(GF_MediaImporter *import, u32 track)
                gf_isom_set_media_language(import->dest, track, lang);
        }
 }
-
+#endif
 
 static char *gf_text_get_utf8_line(char *szLine, u32 lineSize, FILE *txt_in, s32 unicode_type)
 {
@@ -237,6 +238,9 @@ static char *gf_text_get_utf8_line(char *szLine, u32 lineSize, FILE *txt_in, s32
        return sOK;
 }
 
+
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
+
 static GF_Err gf_text_import_srt(GF_MediaImporter *import)
 {
        FILE *srt_in;
@@ -1702,5 +1706,7 @@ GF_Err gf_import_timed_text(GF_MediaImporter *import)
        }
 }
 
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
+
 #endif /*GPAC_DISABLE_ISOM_WRITE*/
 
index 6fbf8959498fdbdf54cbe1f57738853519c0ab69..3c708fdc9d9f1af678b34f72a27e2a1e588eccb9 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <gpac/internal/odf_dev.h>
 
-#ifndef GPAC_DISABLE_OD_DUMP
+#if !defined(GPAC_DISABLE_OD_DUMP) && !defined(GPAC_MINIMAL_ODF)
 
 #define GF_IPMPX_MAX_TREE              100
 
index 37bdda96800a7a922d502fcc3af1b58ed1d61f41..12057c61d5640ac51b739486fc49721c0288ddeb 100644 (file)
@@ -1209,6 +1209,7 @@ GF_Err gf_odf_dump_ipmp(GF_IPMP_Descriptor *ipmp, FILE *trace, u32 indent, Bool
                DumpInt(trace, "controlPointCode", ipmp->control_point, indent, XMTDump);
                if (ipmp->control_point) DumpInt(trace, "sequenceCode", ipmp->cp_sequence_code, indent, XMTDump);
                EndAttributes(trace, indent, XMTDump);
+#ifndef GPAC_MINIMAL_ODF
                /*parse IPMPX data*/
                StartElement(trace, "IPMPX_Data", indent, XMTDump, 1);
                indent++;
@@ -1219,6 +1220,7 @@ GF_Err gf_odf_dump_ipmp(GF_IPMP_Descriptor *ipmp, FILE *trace, u32 indent, Bool
                }
                indent--;
                EndElement(trace, "IPMPX_Data", indent, XMTDump, 1);
+#endif
        }
        else if (!ipmp->IPMPS_Type) {
                DumpString(trace, "URLString", ipmp->opaque_data, indent, XMTDump);
@@ -1736,7 +1738,9 @@ GF_Err gf_odf_dump_ipmp_tool(GF_IPMP_Tool*t, FILE *trace, u32 indent, Bool XMTDu
        if (t->tool_url) DumpString(trace, "ToolURL", t->tool_url, indent, XMTDump);
        if (t->toolParamDesc) {
                StartElement(trace, "toolParamDesc" , indent, XMTDump, 0);
+#ifndef GPAC_MINIMAL_ODF
                gf_ipmpx_dump_data((GF_IPMPX_Data *)t->toolParamDesc, trace, indent + (XMTDump ? 1 : 0), XMTDump);
+#endif
                EndElement(trace, "toolParamDesc" , indent, XMTDump, 0);
        }
        EndAttributes(trace, indent, XMTDump);
@@ -1887,6 +1891,8 @@ GF_Err gf_odf_dump_base_command(GF_BaseODCom *com, FILE *trace, u32 indent, Bool
 }
 
 
+#ifndef GPAC_MINIMAL_ODF
+
 GF_EXPORT
 GF_Err gf_oci_dump_event(OCIEvent *ev, FILE *trace, u32 indent, Bool XMTDump)
 {
@@ -1944,4 +1950,6 @@ GF_Err gf_oci_dump_au(u8 version, char *au, u32 au_length, FILE *trace, u32 inde
        return e;
 }
 
+#endif /*GPAC_MINIMAL_ODF*/
+
 #endif /*GPAC_DISABLE_OD_DUMP*/
index 2050b0d2191a470a419b28d187a110a004f38e68..ab93f3ec3bbb7ff72f7a9a2d68f8e1cfadaeb2bf 100644 (file)
@@ -30,8 +30,6 @@
 #include <gpac/media_tools.h>
 
 
-#if !defined(GPAC_DISABLE_LOADER_BT) && !defined(GPAC_DISABLE_LOADER_XMT)
-
 /* to complete...*/
 
 u32 gf_odf_get_field_type(GF_Descriptor *desc, char *fieldName)
@@ -695,4 +693,3 @@ Bool OD_ParseUIConfig(char *val, char **out_data, u32 *out_data_size)
        return 0;
 }
 
-#endif /* defined(GPAC_DISABLE_LOADER_BT) || defined(GPAC_DISABLE_LOADER_XMT)*/ 
index 306eba28a551c5d1bd2d4a496278d1e27d4910f1..5a04550b6776ed8d30e8f7bb54f466153609aaed 100644 (file)
@@ -52,7 +52,7 @@ static void gf_sm_remove_mux_info(GF_ESD *src)
 
 static void gf_sm_finalize_mux(GF_ISOFile *mp4, GF_ESD *src, u32 offset_ts)
 {
-#if !defined (GPAC_DISABLE_ISOM) || !defined(GPAC_DISABLE_ISOM_WRITE) 
+#if !defined (GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE) 
        u32 track, mts, ts;
        GF_MuxInfo *mux = gf_sm_get_mux_info(src);
        if (!mux && !offset_ts) return;
@@ -100,15 +100,21 @@ static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src, Bool rewrite_
        }
        if (rewrite_esd_only) return GF_OK;
 
+#ifndef GPAC_DISABLE_ISOM_WRITE
        /*what's the media type for input sensor ??*/
        len = gf_isom_new_track(mp4, src->ESID, GF_ISOM_MEDIA_SCENE, 1000);
        if (!len) return gf_isom_last_error(mp4);
        gf_isom_set_track_enabled(mp4, len, 1);
        if (!src->ESID) src->ESID = gf_isom_get_track_id(mp4, len);
        return gf_isom_new_mpeg4_description(mp4, len, src, NULL, NULL, &i);
+#else
+       return GF_NOT_SUPPORTED;
+#endif
 }
 
 
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
+
 static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD *src, Double imp_time, char *mediaSource, Bool od_sample_rap)
 {
        u32 track, di, i;
@@ -342,6 +348,9 @@ static GF_Err gf_sm_import_specials(GF_SceneManager *ctx)
        return GF_OK;
 }
 
+
+#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
+
 /*locate stream in all OD updates/ESD updates (needed for systems tracks)*/
 static GF_ESD *gf_sm_locate_esd(GF_SceneManager *ctx, u16 ES_ID)
 {
@@ -390,6 +399,9 @@ static GF_ESD *gf_sm_locate_esd(GF_SceneManager *ctx, u16 ES_ID)
        return NULL;
 }
 
+
+#ifndef GPAC_DISABLE_ISOM_WRITE
+
 static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, u32 scene_type)
 {
        char *data;
@@ -559,7 +571,11 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc
                if (!au && !esd->URLString) {
                        /*if not in IOD, the stream will be imported when encoding the OD stream*/
                        if (!is_in_iod) continue;
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                        e = gf_sm_import_stream(ctx, mp4, esd, 0, NULL, 0);
+#else
+                       e = GF_BAD_PARAM;
+#endif
                        if (e) goto exit;
                        gf_sm_finalize_mux(mp4, esd, 0);
                        gf_isom_add_track_to_root_od(mp4, gf_isom_get_track_by_id(mp4, esd->ESID));
@@ -1049,7 +1065,11 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media
 
                                                        switch (imp_esd->tag) {
                                                        case GF_ODF_ESD_TAG:
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                                                                e = gf_sm_import_stream(ctx, mp4, imp_esd, au->timing_sec, mediaSource, au->flags & GF_SM_AU_RAP);
+#else
+                                                               e = GF_BAD_PARAM;
+#endif
                                                                if (e) {
                                                                        GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] cannot import stream %d (error %s)\n", imp_esd->ESID, gf_error_to_string(e)));
                                                                        goto err_exit;
@@ -1077,7 +1097,11 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media
                                        while ((imp_esd = (GF_ESD*)gf_list_enum(esdU->ESDescriptors, &m))) {
                                                switch (imp_esd->tag) {
                                                case GF_ODF_ESD_TAG:
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
                                                        e = gf_sm_import_stream(ctx, mp4, imp_esd, au->timing_sec, mediaSource, au->flags & GF_SM_AU_RAP);
+#else
+                                                       e = GF_BAD_PARAM;
+#endif
                                                        if (e) {
                                                                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] cannot import stream %d (error %s)\n", imp_esd->ESID, gf_error_to_string(e)));
                                                                gf_odf_com_del(&com);
@@ -1261,7 +1285,11 @@ GF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOp
        gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_MP41, 1);
 
        /*import specials, that is input remapping to BIFS*/
+#ifndef GPAC_DISABLE_MEDIA_IMPORT
        e = gf_sm_import_specials(ctx);
+#else
+       e = GF_BAD_PARAM;
+#endif
        if (e) return e;
 
 
@@ -1313,4 +1341,6 @@ GF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOp
        return GF_OK;
 }
 
+#endif /*GPAC_DISABLE_ISOM_WRITE*/
+
 #endif /*GPAC_DISABLE_SCENE_ENCODER*/
index 1d0c77c382b4b334253b04abfe6d71231978cb6d..20eee00e57b9b3e4c780901da8d7258c13c694b7 100644 (file)
@@ -31,7 +31,7 @@
 
 
 
-#ifndef GPAC_DISABLE_LOADER_ISOM
+#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_LOADER_ISOM)
 
 static void UpdateODCommand(GF_ISOFile *mp4, GF_ODCom *com)
 {
@@ -406,4 +406,4 @@ GF_Err gf_sm_load_init_isom(GF_SceneLoader *load)
        return GF_OK;
 }
 
-#endif /*GPAC_DISABLE_LOADER_ISOM*/
+#endif /*GPAC_DISABLE_ISOM && GPAC_DISABLE_LOADER_ISOM*/
index 4f69376d735baa9dfa7d146649c29d441c0df317..b60a27ae24eafac50c4ec985f1455e12490a8094 100644 (file)
@@ -808,9 +808,11 @@ static void gf_dump_vrml_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInf
        case GF_SG_VRML_MFNODE:
                needs_field_container = 0;
                if (sdump->XMLDump && sdump->X3DDump) needs_field_container = gf_dump_vrml_needs_container(node, &field);
+#ifndef GPAC_DISABLE_X3D
                if (!sdump->X3DDump) {
                        if (gf_node_get_tag(node)==TAG_X3D_Switch) field.name = "choice";
                }
+#endif
                list = * ((GF_ChildNodeItem **) field.far_ptr);
                assert(list);
                if (!sdump->XMLDump || !sdump->X3DDump) StartList(sdump, field.name);
@@ -1273,12 +1275,16 @@ static Bool scene_dump_vrml_can_dump(GF_SceneDumper *sdump, GF_Node *node)
                name = gf_node_get_class_name(node);
 #ifndef GPAC_DISABLE_X3D
                tag = gf_node_x3d_type_by_class_name(name);
-#endif
                return tag ? 1 : 0;
+#else
+               return 0;
+#endif
        } else {
                if (node->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) return 1;
+#ifndef GPAC_DISABLE_X3D
                if (node->sgprivate->tag==TAG_X3D_Rectangle2D) return 1;
                if (node->sgprivate->tag==TAG_X3D_Circle2D) return 1;
+#endif
                name = gf_node_get_class_name(node);
                tag = gf_node_mpeg4_type_by_class_name(name);
                return tag ? 1 : 0;
@@ -1317,9 +1323,11 @@ static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list
        if (sdump->X3DDump) {
                if (node->sgprivate->tag == TAG_MPEG4_Circle) name = "Circle2D";
                else if (node->sgprivate->tag == TAG_MPEG4_Rectangle) name = "Rectangle2D";
+#ifndef GPAC_DISABLE_X3D
        } else if (!sdump->X3DDump) {
                if (node->sgprivate->tag == TAG_X3D_Circle2D) name = "Circle";
                else if (node->sgprivate->tag == TAG_X3D_Rectangle2D) name = "Rectangle";
+#endif
        }
 #endif
 
@@ -1361,7 +1369,9 @@ static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list
        base = NULL;
        switch (gf_node_get_tag(node)) {
 #ifndef GPAC_DISABLE_VRML
+#ifndef GPAC_DISABLE_X3D
        case TAG_X3D_Script:
+#endif
        case TAG_MPEG4_Script:
                isScript = 1;
                break;
@@ -1586,10 +1596,13 @@ static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list
                                                gf_dump_vrml_field(sdump, node, field);
                                        }
                                } else {
+#ifndef GPAC_DISABLE_X3D
                                        /*X3D script metadata, NOT DYN*/
                                        if ((i==3) && (node->sgprivate->tag==TAG_X3D_Script) ) {
                                                if (*((GF_Node **)field.far_ptr)) gf_dump_vrml_field(sdump, node, field);
-                                       } else {
+                                       } else 
+#endif
+                                       {
                                                gf_dump_vrml_dyn_field(sdump, node, field, 0);
                                        }
                                }
index 3147182c245b9b5563e6ca85f6fda2ddfed5517c..02210336311d0ddc4d9ac446475bfe799e7b7150 100644 (file)
@@ -288,8 +288,10 @@ GF_Err gf_seng_enable_aggregation(GF_SceneEngine *seng, u16 ESID, u16 onESID)
 
 static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *commands, char **data, u32 *size)
 {
-       GF_Err e;
+#ifndef GPAC_DISABLE_SCENE_DUMP
        GF_SceneDumper *dumper = NULL;
+#endif
+       GF_Err e;
        char rad_name[4096];
        char file_name[4096];
        FILE *file = NULL;
@@ -335,16 +337,18 @@ start:
 #endif
        }
 
+#ifndef GPAC_DISABLE_SCENE_DUMP
        dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, ' ', GF_SM_DUMP_SVG);
        if (!dumper) {
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); 
                e = GF_IO_ERR;
                goto exit;
-       }    
+       }
 
        if (commands && gf_list_count(commands)) {
                e = gf_sm_dump_command_list(dumper, commands, 0, 0);
-       } else {
+       }
+       else {
                e = gf_sm_dump_graph(dumper, 0, 0);
        }
        gf_sm_dumper_del(dumper);
@@ -368,6 +372,8 @@ start:
                GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot dump DIMS Commands\n")); 
                goto exit;
        }
+#endif
+
 #ifdef DUMP_DIMS_LOG_WITH_TIME
     if (do_dump_with_time) {
         do_dump_with_time = 0;
@@ -546,7 +552,7 @@ static GF_Err gf_sm_live_encode_scene_au(GF_SceneEngine *seng, gf_seng_callback
                                break;
 #endif
 
-#ifndef GPAC_DISABLE_BIFS_ENC
+#ifndef GPAC_DISABLE_LASER
                        case GPAC_OTI_SCENE_LASER:
                                e = gf_laser_encode_au(seng->lsrenc, sc->ESID, au->commands, 0, &data, &size);
                                break;
@@ -584,6 +590,9 @@ GF_Err gf_seng_dump_rap_on(GF_SceneEngine *seng, Bool dump_rap)
 GF_EXPORT
 GF_Err gf_seng_save_context(GF_SceneEngine *seng, char *ctxFileName)
 {
+#ifdef GPAC_DISABLE_SCENE_DUMP
+       return GF_NOT_SUPPORTED;
+#else
        u32     d_mode, do_enc;
        char szF[GF_MAX_PATH], *ext;
        GF_Err  e;
@@ -617,6 +626,7 @@ GF_Err gf_seng_save_context(GF_SceneEngine *seng, char *ctxFileName)
                e = gf_sm_dump(seng->ctx, ctxFileName ? szF : NULL, d_mode);
        }
        return e;
+#endif
 }
 
 static GF_AUContext *gf_seng_create_new_au(GF_StreamContext *sc, u32 time) 
@@ -723,7 +733,7 @@ GF_Err gf_seng_encode_from_commands(GF_SceneEngine *seng, u16 ESID, Bool disable
                        break;
 #endif
 
-#ifndef GPAC_DISABLE_BIFS_ENC
+#ifndef GPAC_DISABLE_LASER
                case GPAC_OTI_SCENE_LASER:
                        e = gf_laser_encode_au(seng->lsrenc, ESID, new_au->commands, 0, &data, &size);
                        break;
@@ -806,7 +816,7 @@ void gf_seng_terminate(GF_SceneEngine *seng)
        if (seng->bifsenc) gf_bifs_encoder_del(seng->bifsenc);
 #endif
 
-#ifndef GPAC_DISABLE_BIFS_ENC
+#ifndef GPAC_DISABLE_LASER
        if (seng->lsrenc) gf_laser_encoder_del(seng->lsrenc);
 #endif
 
index b0ee905bbe9b82ee3c1019a37592487321c6a681..8b4ec65f1de08decc53d91b51c89f81e32a9e11a 100644 (file)
@@ -182,7 +182,7 @@ static void define_dom_exception(JSContext *c, JSObject *global)
        DEF_EXC(TYPE_MISMATCH_ERR);
 #undef  DEF_EXC
 
-       JS_AliasProperty(c, global, "DOMException", "e");
+       //JS_AliasProperty(c, global, "DOMException", "e");
        obj = JS_DefineObject(c, global, "EventException", NULL, 0, 0);
        JS_DefineProperty(c, obj, "UNSPECIFIED_EVENT_TYPE_ERR", INT_TO_JSVAL(0), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
        JS_DefineProperty(c, obj, "DISPATCH_REQUEST_ERR", INT_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT);
@@ -523,7 +523,7 @@ JSBool SMJS_FUNCTION_EXT(gf_sg_js_event_add_listener, GF_Node *on_node)
        GF_SceneGraph *sg = NULL;
        JSFunction*fun = NULL;
        GF_Node *n = NULL;
-       jsval funval = 0;
+       jsval funval = JSVAL_NULL;
        JSObject *evt_handler;
        SMJS_OBJ
        SMJS_ARGS
@@ -597,7 +597,7 @@ JSBool SMJS_FUNCTION_EXT(gf_sg_js_event_add_listener, GF_Node *on_node)
 
                if (!callback) {
                        handler->js_fun = fun;
-                       handler->js_fun_val = funval;
+                       handler->js_fun_val = *(u64 *) &funval;
                        if (handler->js_fun_val) {
                                handler->js_context = c;
                                /*protect the function - we don't know how it was passed to us, so prevent it from being GCed*/
@@ -665,7 +665,7 @@ JSBool SMJS_FUNCTION_EXT(gf_sg_js_event_remove_listener, GF_Node *vrml_node)
        u32 evtType, i, count;
        char *inNS = NULL;
        GF_Node *node = NULL;
-       jsval funval = 0;
+       jsval funval = JSVAL_NULL;
        GF_SceneGraph *sg = NULL;
        GF_DOMEventTarget *target = NULL;
        SMJS_OBJ
@@ -712,7 +712,7 @@ JSBool SMJS_FUNCTION_EXT(gf_sg_js_event_remove_listener, GF_Node *vrml_node)
                        funval = argv[of+1];
                }
        }
-       if (!callback && !funval) goto err_exit;
+       if (!callback && JSVAL_IS_NULL(funval) ) goto err_exit;
 
        evtType = gf_dom_event_type_by_name(type);
        if (evtType==GF_EVENT_UNKNOWN) goto err_exit;
@@ -732,8 +732,8 @@ JSBool SMJS_FUNCTION_EXT(gf_sg_js_event_remove_listener, GF_Node *vrml_node)
                if (!info.far_ptr) continue;
                hdl = (SVG_handlerElement *) ((XMLRI*)info.far_ptr)->target;
                if (!hdl) continue;
-               if (funval) {
-                       if (funval != (jsval) hdl->js_fun_val) continue;
+               if (! JSVAL_IS_NULL(funval) ) {
+                       if (*(u64 *) &funval != hdl->js_fun_val) continue;
                } else if (hdl->children) {
                        txt = (GF_DOMText *) hdl->children->node;
                        if (txt->sgprivate->tag != TAG_DOMText) continue;
@@ -3915,7 +3915,7 @@ void dom_js_define_document(JSContext *c, JSObject *global, GF_SceneGraph *doc)
 JSObject *dom_js_define_event(JSContext *c, JSObject *global)
 {
        JSObject *obj = JS_DefineObject(c, global, "evt", &dom_rt->domEventClass, 0, 0 );
-       JS_AliasProperty(c, global, "evt", "event");
+       //JS_AliasProperty(c, global, "evt", "event");
        return obj;
 }
 
index ee4a0e10ec7dbe4b0c536fc37c7f84f5585e2e33..e7961c390cf3df79afa1a697ba5984e99fc70b5f 100644 (file)
@@ -185,7 +185,6 @@ typedef struct
        JSContext *ctx;
 
        GF_Mutex *mx;
-       
        JSClass SFNodeClass;
 
 #ifndef GPAC_DISABLE_VRML
@@ -287,6 +286,16 @@ static void gf_sg_unload_script_modules()
 }
 
 
+#ifdef NO_JS_RUNTIMETHREAD
+void JS_SetRuntimeThread(JSRuntime *jsr)
+{
+}
+void JS_ClearRuntimeThread(JSRuntime *jsr)
+{
+}
+#endif
+
+
 #ifdef __SYMBIAN32__
 const long MAX_HEAP_BYTES = 256 * 1024L;
 #else
@@ -311,14 +320,25 @@ JSContext *gf_sg_ecmascript_new(GF_SceneGraph *sg)
        }
        js_rt->nb_inst++;
        ctx = JS_NewContext(js_rt->js_runtime, STACK_CHUNK_BYTES);
+       JS_SetOptions(ctx, JS_GetOptions(ctx) | JSOPTION_WERROR);
+
+#ifdef JS_THREADSAFE
+#if (JS_VERSION>=185)
+       JS_ClearContextThread(ctx);
+       JS_ClearRuntimeThread(js_rt->js_runtime);
+#endif
+#endif
        return ctx;
 }
 
 void gf_sg_ecmascript_del(JSContext *ctx)
 {
 #ifdef JS_THREADSAFE
-       JS_ClearContextThread(ctx);
+#if (JS_VERSION>=185)
+       assert(js_rt);
+       JS_SetRuntimeThread(js_rt->js_runtime);
        JS_SetContextThread(ctx); 
+#endif
 #endif
 
        JS_DestroyContext(ctx);
@@ -700,9 +720,9 @@ static void on_route_to_object(GF_Node *node, GF_Route *_r)
 //                     gf_js_remove_root(priv->js_ctx, &r->obj);
                        r->obj=NULL;
                }
-               if (r->fun) {
+               if ( ! JSVAL_IS_VOID(r->fun)) {
 //                     gf_js_remove_root(priv->js_ctx, &r->fun);
-                       r->fun=0;
+                       r->fun=JSVAL_NULL;
                }
                return;
        }
@@ -865,7 +885,7 @@ static JSBool SMJS_FUNCTION(deleteRoute)
 
        if (!JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFNodeClass, NULL) ) return JS_FALSE;
        
-       if (JSVAL_IS_STRING(argv[1]) && (argv[2]==JSVAL_NULL) && (argv[3]==JSVAL_NULL)) {
+       if (JSVAL_IS_STRING(argv[1]) && JSVAL_IS_NULL(argv[2]) && JSVAL_IS_NULL(argv[3])) {
                ptr = (GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]));
                assert(ptr->field.fieldType==GF_SG_VRML_SFNODE);
                n1 = * ((GF_Node **)ptr->field.far_ptr);
@@ -1143,7 +1163,11 @@ JSBool gf_sg_script_eventout_set_prop(JSContext *c, JSObject *obj, SMJS_PROP_SET
        GF_Node *n;
        GF_ScriptField *sf;
        GF_FieldInfo info;
-       JSString *str = JS_ValueToString(c, id);
+       jsval idval;
+       JSString *str;
+       JS_IdToValue(c, id, &idval);
+       if (! SMJS_ID_IS_STRING(id)) return JS_FALSE;
+       str = SMJS_ID_TO_STRING(id);
        if (!str) return JS_FALSE;
 
        script = JS_GetScriptStack(c);
@@ -3752,6 +3776,7 @@ static void gf_sg_script_update_cached_object(GF_ScriptPriv *priv, JSObject *obj
                if(parent) gf_node_get_field(parent, field->fieldIndex, &jsf->field);   \
 
 #define SETUP_MF_FIELD \
+               if (!obj) return JSVAL_NULL; \
                jsf = (GF_JSField *) JS_GetPrivate(priv->js_ctx, obj);  \
                jsf->owner = parent;            \
                if (parent) gf_node_get_field(parent, field->fieldIndex, &jsf->field);  \
@@ -4761,25 +4786,36 @@ Bool gf_sg_javascript_initialized()
 
 #ifdef GPAC_HAS_SPIDERMONKEY
 
+/*
+ * locking/try-locking the JS context
+ * we need to test whether the calling thread already has the lock on the script context
+ * if this is not the case (i.e. first lock on mutex), we switch JS context threads and
+ * call begin/end requests. Nesting begin/end request in a reentrant way crashes JS
+ * (mozilla doc is wrong here)
+ *
+ * */
 void gf_sg_lock_javascript(struct JSContext *cx, Bool LockIt)
 {
        if (!js_rt) return;
+       assert(cx);
        if (LockIt) {
                gf_mx_p(js_rt->mx);
 #ifdef JS_THREADSAFE
-               if (cx) {
+               if (gf_mx_get_num_locks(js_rt->mx)==1) {
 #if (JS_VERSION>=185)
-                       JS_SetContextThread(cx); 
+                       JS_SetRuntimeThread(js_rt->js_runtime);
+                       JS_SetContextThread(cx);
 #endif
                        JS_BeginRequest(cx);
                }
 #endif
        } else {
 #ifdef JS_THREADSAFE
-               if (cx) {
+               if (gf_mx_get_num_locks(js_rt->mx)==1) {
                        JS_EndRequest(cx);
 #if (JS_VERSION>=185)
-                       JS_ClearContextThread(cx); 
+                       JS_ClearContextThread(cx);
+                       JS_ClearRuntimeThread(js_rt->js_runtime);
 #endif
                }
 #endif
@@ -4789,11 +4825,13 @@ void gf_sg_lock_javascript(struct JSContext *cx, Bool LockIt)
 
 Bool gf_sg_try_lock_javascript(struct JSContext *cx)
 {
+       assert(cx);
        if (gf_mx_try_lock(js_rt->mx)) {
 #ifdef JS_THREADSAFE
-               if (cx) {
+               if (gf_mx_get_num_locks(js_rt->mx)==1) {
 #if (JS_VERSION>=185)
-                       JS_SetContextThread(cx); 
+                       JS_SetRuntimeThread(js_rt->js_runtime);
+                       JS_SetContextThread(cx);
 #endif
                        JS_BeginRequest(cx);
                }
index 3504752e4b8dc7aa6194e31d99eb72ed3b5ddd8b..4487c7661d7bcc189f9924ad6da764103d6ba215 100644 (file)
@@ -854,6 +854,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds
        s32 src_row;
        u32 i, yuv_planar_type = 0;
        Bool no_memcpy;
+       Bool force_load_odd_yuv_lines = 0;
        Bool yuv_init = 0;
        Bool has_alpha = (alpha!=0xFF) ? 1 : 0;
        u32 dst_bpp, dst_w_size;
@@ -988,6 +989,8 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds
        tmp = (u8 *) gf_malloc(sizeof(u8) * src_w * (yuv_planar_type ? 8 : 4) );
        rows = tmp;
 
+       if ( (src_h / dst_h) * dst_h != src_h) force_load_odd_yuv_lines = 1;
+
        dst_bits = (u8 *) dst->video_buffer;
 
        pos_y = 0x10000;
@@ -1031,8 +1034,8 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds
                if (prev_row != src_row) {
                        u32 the_row = src_row - 1;
                        if (yuv_planar_type) {
-                               if ( the_row % 2) {
-                                       if (!yuv_init) {
+                               if (the_row % 2) {
+                                       if (!yuv_init || force_load_odd_yuv_lines) {
                                                yuv_init = 1;
                                                the_row --;
                                                if (flip) the_row = src->height-2 - the_row;
@@ -1091,12 +1094,18 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds
                                if (key) {
                                        for (i=0; i<src_w; i++) {
                                                u32 idx = 4*i;
-                                               s32 thres;
-                                               thres = (255 + (tmp[idx]-kr)) % 255;
-                                               thres += (255 + (tmp[idx+1]-kg)) % 255;
-                                               thres += (255 + (tmp[idx+2]-kb)) % 255;
-                                               if (thres > 3*0xFE) tmp[idx+3] = ka;
-//                                             if ( (tmp[idx]==kr) && (tmp[idx+1]==kg) && (tmp[idx+2]==kb)) tmp[idx+3] = ka;
+                                               s32 thres, v;
+                                               v = tmp[idx]-kr; thres = ABS(v);
+                                               v = tmp[idx+1]-kg; thres += ABS(v);
+                                               v = tmp[idx+2]-kb; thres += ABS(v);
+                                               thres/=3;
+#if 0
+                                               if (thres < kl) tmp[idx+3] = 0;
+                                               else if (thres <= kh) tmp[idx+3] = (thres-kl)*ka / (kh-kl);
+#else
+                                               if (thres < kh) tmp[idx+3] = 0;
+#endif
+                                               else tmp[idx+3] = ka;
                                        }
                                }
                        }