CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/11/30 11:26:05
Modified files: . : ChangeLog gui : gui.cpp server : character.cpp movie_root.cpp movie_root.h sprite_instance.cpp testsuite/misc-mtasc.all: level5.as level99.as testsuite/swfdec: PASSING Log message: Add support for swapping and unloading levels. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5026&r2=1.5027 http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gui.cpp?cvsroot=gnash&r1=1.116&r2=1.117 http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.cpp?cvsroot=gnash&r1=1.66&r2=1.67 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.131&r2=1.132 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.93&r2=1.94 http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.400&r2=1.401 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-mtasc.all/level5.as?cvsroot=gnash&r1=1.7&r2=1.8 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-mtasc.all/level99.as?cvsroot=gnash&r1=1.7&r2=1.8 http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/swfdec/PASSING?cvsroot=gnash&r1=1.67&r2=1.68 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.5026 retrieving revision 1.5027 diff -u -b -r1.5026 -r1.5027 --- ChangeLog 30 Nov 2007 11:13:32 -0000 1.5026 +++ ChangeLog 30 Nov 2007 11:26:04 -0000 1.5027 @@ -1,5 +1,19 @@ 2007-11-30 Sandro Santilli <[EMAIL PROTECTED]> + * server/movie_root.{cpp,h}: support swapping and removing levels, + add a pointer to originally loaded movie for methods still needing + that. + * gui/gui.cpp: use movie_root::getRootMovie() instead of getLevel(0) + as we can't assume _level0 is present (I think). + * server/character.cpp (computeTargetPath): for _level# movies != + original root movie return '_level#' string, not '/'. + * server/sprite_instance.cpp: allow removing and swapping levels. + * testsuite/misc-mtasc.all/: level5.as, level99.as: test swapping + and removing levels. + * testsuite/swfdec/PASSING: movieclip-swap-depths tests succeed. + +2007-11-30 Sandro Santilli <[EMAIL PROTECTED]> + * server/parser/shape_character_def.cpp (computeBounds): don't choke on glyph shapes with m_line set to 1. Fixes bug #21674. Index: gui/gui.cpp =================================================================== RCS file: /sources/gnash/gnash/gui/gui.cpp,v retrieving revision 1.116 retrieving revision 1.117 diff -u -b -r1.116 -r1.117 --- gui/gui.cpp 28 Nov 2007 16:59:36 -0000 1.116 +++ gui/gui.cpp 30 Nov 2007 11:26:05 -0000 1.117 @@ -833,7 +833,7 @@ // Print info about levels (only level0 for now, then will be extended) movie_root& stage = vm.getRoot(); - boost::intrusive_ptr<movie_instance> level0 = stage.getLevel(0); + boost::intrusive_ptr<movie_instance> level0 = stage.getRootMovie(); movie_definition* def0 = level0->get_movie_definition(); assert(def0); snprintf(buf, 16, "SWF%d", def0->get_version()); buf[15] = '\0'; Index: server/character.cpp =================================================================== RCS file: /sources/gnash/gnash/server/character.cpp,v retrieving revision 1.66 retrieving revision 1.67 diff -u -b -r1.66 -r1.67 --- server/character.cpp 29 Nov 2007 09:31:02 -0000 1.66 +++ server/character.cpp 30 Nov 2007 11:26:05 -0000 1.67 @@ -17,7 +17,7 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // -/* $Id: character.cpp,v 1.66 2007/11/29 09:31:02 strk Exp $ */ +/* $Id: character.cpp,v 1.67 2007/11/30 11:26:05 strk Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -748,7 +748,13 @@ ch = parent; } - if ( path.empty() ) return "/"; + if ( path.empty() ) + { + if ( _vm.getRoot().getRootMovie() == this ) return "/"; + std::stringstream ss; + ss << "_level" << m_depth-character::staticDepthOffset; + return ss.str(); + } // Build the target string from the parents stack std::string target; Index: server/movie_root.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.cpp,v retrieving revision 1.131 retrieving revision 1.132 diff -u -b -r1.131 -r1.132 --- server/movie_root.cpp 29 Nov 2007 09:31:03 -0000 1.131 +++ server/movie_root.cpp 30 Nov 2007 11:26:05 -0000 1.132 @@ -82,6 +82,8 @@ m_active_input_text(NULL), m_time_remainder(0.0f), m_drag_state(), + _movies(), + _rootMovie(), _allowRescale(true), _invalidated(true), _disableScripts(false), @@ -134,6 +136,8 @@ void movie_root::setRootMovie(movie_instance* movie) { + _rootMovie = movie; + m_viewport_x0 = 0; m_viewport_y0 = 0; m_viewport_width = (int)movie->get_movie_definition()->get_width_pixels(); @@ -171,7 +175,7 @@ //movie->set_name(ss.str().c_str()); //if ( _movies.size() < num+1 ) _movies.resize(num+1); - _movies[num] = movie; // [num] = movie; + _movies[movie->get_depth()] = movie; // [num] = movie; movie->set_invalidated(); @@ -181,6 +185,110 @@ assert(testInvariant()); } +void +movie_root::swapLevels(boost::intrusive_ptr<sprite_instance> movie, int depth) +{ + assert(movie); + +//#define GNASH_DEBUG_LEVELS_SWAPPING 1 + + int oldDepth = movie->get_depth(); + +#ifdef GNASH_DEBUG_LEVELS_SWAPPING + log_debug("Before swapLevels (source depth %d, target depth %d) levels are: ", oldDepth, depth); + for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) + { + log_debug(" %d: %p (%s @ depth %d)", i->first, (void*)(i->second.get()), i->second->getTarget().c_str(), i->second->get_depth()); + } +#endif + + if ( oldDepth < character::staticDepthOffset ) // should include _level0 ! + { + IF_VERBOSE_ASCODING_ERRORS( + log_aserror(_("%s.swapDepth(%d): movie has a depth (%d) below static depth zone (%d), won't swap it's depth"), + movie->getTarget().c_str(), depth, oldDepth, character::staticDepthOffset); + ); + return; + } + + if ( oldDepth >= 0 ) + { + IF_VERBOSE_ASCODING_ERRORS( + log_aserror(_("%s.swapDepth(%d): movie has a depth (%d) below static depth zone (%d), won't swap it's depth"), + movie->getTarget().c_str(), depth, oldDepth, character::staticDepthOffset); + ); + return; + } + + int oldNum = oldDepth; // -character::staticDepthOffset; + Levels::iterator oldIt = _movies.find(oldNum); + if ( oldIt == _movies.end() ) + { + log_debug("%s.swapDepth(%d): target depth (%d) contains no movie", + movie->getTarget().c_str(), depth, oldNum); + return; + } + + int newNum = depth; // -character::staticDepthOffset; + movie->set_depth(depth); + Levels::iterator targetIt = _movies.find(newNum); + if ( targetIt == _movies.end() ) + { + _movies.erase(oldIt); + _movies[newNum] = movie; + } + else + { + boost::intrusive_ptr<sprite_instance> otherMovie = targetIt->second; + otherMovie->set_depth(oldDepth); + oldIt->second = otherMovie; + targetIt->second = movie; + } + +#ifdef GNASH_DEBUG_LEVELS_SWAPPING + log_debug("After swapLevels levels are: "); + for (Levels::iterator i=_movies.begin(), e=_movies.end(); i!=e; ++i) + { + log_debug(" %d: %p (%s @ depth %d)", i->first, (void*)(i->second.get()), i->second->getTarget().c_str(), i->second->get_depth()); + } +#endif + + // TODO: invalidate self, not the movie + movie->set_invalidated(); + + assert(testInvariant()); +} + +void +movie_root::dropLevel(int depth) +{ + // should be checked by caller + assert ( depth >= 0 && depth <= 1048575 ); + + Levels::iterator it = _movies.find(depth); + if ( it == _movies.end() ) + { + log_error("movie_root::dropLevel called against a movie not found in the levels container"); + return; + } + + sprite_instance* mo = it->second.get(); + if ( mo == getRootMovie() ) + { + IF_VERBOSE_ASCODING_ERRORS( + log_aserror(_("Original root movie can't be removed")); + ); + return; + } + + // TOCHECK: safe to erase here ? + mo->unload(); + mo->destroy(); + _movies.erase(it); + + assert(testInvariant()); +} + bool movie_root::loadLevel(unsigned int num, const URL& url) { @@ -219,7 +327,7 @@ boost::intrusive_ptr<movie_instance> movie_root::getLevel(unsigned int num) const { - Levels::const_iterator i = _movies.find(num); + Levels::const_iterator i = _movies.find(num+character::staticDepthOffset); if ( i == _movies.end() ) return 0; assert(boost::dynamic_pointer_cast<movie_instance>(i->second)); @@ -279,7 +387,8 @@ //log_msg("Rescaling allowed"); // should we cache this ? it's immutable after all ! - const rect& frame_size = _movies[0]->get_frame_size(); + // WARNING: don't allow swapping depth of the root movie !! + const rect& frame_size = _rootMovie->get_frame_size(); float scale_x = m_viewport_width / TWIPS_TO_PIXELS(frame_size.width()); float scale_y = m_viewport_height / TWIPS_TO_PIXELS(frame_size.height()); @@ -852,7 +961,7 @@ assert(testInvariant()); // should we cache this ? it's immutable after all ! - const rect& frame_size = getLevel(0)->get_frame_size(); + const rect& frame_size = getRootMovie()->get_frame_size(); clearInvalidated(); @@ -897,7 +1006,7 @@ va_list args; va_start(args, method_arg_fmt); - const char* result = getLevel(0)->call_method_args(method_name, + const char* result = getRootMovie()->call_method_args(method_name, method_arg_fmt, args); va_end(args); @@ -909,7 +1018,7 @@ const char* method_arg_fmt, va_list args) { assert(testInvariant()); - return getLevel(0)->call_method_args(method_name, method_arg_fmt, args); + return getRootMovie()->call_method_args(method_name, method_arg_fmt, args); } void movie_root::cleanupUnloadedListeners(CharacterList& ll) @@ -1274,6 +1383,10 @@ i->second->setReachable(); } + // Mark original top-level movie + // This should always be in _movies, but better make sure + _rootMovie->setReachable(); + // Mark mouse entities m_mouse_button_state.markReachableResources(); Index: server/movie_root.h =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.h,v retrieving revision 1.93 retrieving revision 1.94 diff -u -b -r1.93 -r1.94 --- server/movie_root.h 27 Nov 2007 20:37:53 -0000 1.93 +++ server/movie_root.h 30 Nov 2007 11:26:05 -0000 1.94 @@ -15,7 +15,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -/* $Id: movie_root.h,v 1.93 2007/11/27 20:37:53 strk Exp $ */ +/* $Id: movie_root.h,v 1.94 2007/11/30 11:26:05 strk Exp $ */ /// \page events_handling Handling of user events /// @@ -173,6 +173,33 @@ /// bool loadLevel(unsigned int num, const URL& url); + /// Swap depth of a level (or two) + // + /// Character's depths are updated. + /// + /// @param sp + /// The level to change depth/level of. A pointer to it is expected + /// to be found in the _level# container, or an error will be printed + /// and the call would result in a no-op. + /// + /// @param depth + /// New depth to assign to the character. If another level exists at + /// the target depth the latter is moved in place of the former, with + /// its depth also updated. + /// + void swapLevels(boost::intrusive_ptr<sprite_instance> sp, int depth); + + /// Drop level at given depth. + // + /// @param depth + /// Depth of the level to drop. Note that this is -character::staticDepthOffset for + /// the root movie. Must be >=0 and <= 1048575 or an assertion will fail. + /// Note that if the depth evaluates to the original root movie nothing happens + /// (not allowed to remove that). It is not tested if it's allowed to remove + /// _level0 after loading into it. + /// + void dropLevel(int depth); + /// @@ should this delegate to _level0? probably ! void set_member( const std::string& /*name*/, @@ -276,11 +303,16 @@ void set_drag_state(const drag_state& st); + // just an alias to getRootMovie + sprite_instance* get_root_movie() const + { + return getRootMovie(); + } + /// @return current top-level root sprite (_level0) - sprite_instance* get_root_movie() + movie_instance* getRootMovie() const { - if ( _movies.empty() ) return NULL; - return getLevel(0).get(); + return _rootMovie.get(); } void stop_drag() @@ -294,8 +326,7 @@ /// movie_definition* get_movie_definition() const { - assert(!_movies.empty()); - return getLevel(0)->get_movie_definition(); + return getRootMovie()->get_movie_definition(); } /// Add an interval timer @@ -320,18 +351,19 @@ /// Return 0-based frame index of _level0 // - /// TODO: drop this function + /// TODO: drop this function (currently used by gprocessor) /// size_t get_current_frame() const { - assert(!_movies.empty()); - return getLevel(0)->get_current_frame(); + return getRootMovie()->get_current_frame(); } +#if 0 // @@ should this be in movie_instance ? float get_frame_rate() const { return get_movie_definition()->get_frame_rate(); } +#endif /// \brief /// Return the size of a logical movie pixel as @@ -342,14 +374,15 @@ return m_pixel_scale; } +#if 0 // @@ Is this one necessary? // // TODO: drop this character* get_character(int character_id) { - assert(!_movies.empty()); - return getLevel(0)->get_character(character_id); + return getRootMovie()->get_character(character_id); } +#endif void set_background_color(const rgba& color); @@ -375,19 +408,22 @@ /// 0-based!! delegates to _level0 // - /// TODO: drop this method ? + /// TODO: drop this method. currently used by gprocessor. /// void goto_frame(size_t target_frame_number) { - getLevel(0)->goto_frame(target_frame_number); + getRootMovie()->goto_frame(target_frame_number); } void display(); /// Delegate to _level0 + // + /// TODO: drop ? + /// void set_play_state(sprite_instance::play_state s) { - getLevel(0)->set_play_state(s); + getRootMovie()->set_play_state(s); } /// For ActionScript interfacing convenience. @@ -510,6 +546,7 @@ /// Resources reachable from movie_root are: /// /// - All _level# movies (_movies) + /// - The original root movie (_rootMovie) /// - Mouse entities (m_mouse_button_state) /// - Timer targets (_intervalTimers) /// - Resources reachable by ActionQueue code (_actionQueue) @@ -699,9 +736,13 @@ /// Appropriate container could be list, set or map (order is important) /// typedef boost::intrusive_ptr<sprite_instance> LevelMovie; - typedef std::map<unsigned int, LevelMovie> Levels; + typedef std::map<int, LevelMovie> Levels; Levels _movies; + /// The root movie. This is initially the same as getLevel(0) but might + /// change during the run. It will be used to setup and retrive initial stage size + boost::intrusive_ptr<movie_instance> _rootMovie; + /// This function should return TRUE iff any action triggered /// by the event requires redraw, see \ref events_handling for /// more info. @@ -752,7 +793,7 @@ /// @param movie /// The movie_instance to store at the given level. /// Will be stored in an intrusive_ptr. - /// It's depth will be set to <num> and it's name to + /// It's depth will be set to <num>+character::staticDepthOffset and it's name to /// _level<num> /// void setLevel(unsigned int num, boost::intrusive_ptr<movie_instance> movie); Index: server/sprite_instance.cpp =================================================================== RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v retrieving revision 1.400 retrieving revision 1.401 diff -u -b -r1.400 -r1.401 --- server/sprite_instance.cpp 27 Nov 2007 16:03:20 -0000 1.400 +++ server/sprite_instance.cpp 30 Nov 2007 11:26:05 -0000 1.401 @@ -371,18 +371,6 @@ SpritePtr this_parent = dynamic_cast<sprite_instance*>(sprite->get_parent()); - if ( ! this_parent ) - { - IF_VERBOSE_ASCODING_ERRORS( - stringstream ss; fn.dump_args(ss); - log_aserror(_("%s.swapDepths(%s): this sprite has no parent, " - "swapping depth of root?"), - sprite->getTarget().c_str(), - ss.str().c_str()); - ); - return rv; - } - //CharPtr target = NULL; int target_depth = 0; @@ -452,7 +440,16 @@ } + if ( this_parent ) + { this_parent->swapDepths(sprite.get(), target_depth); + } + else + { + movie_root& root = VM::get().getRoot(); + root.swapLevels(sprite, target_depth); + return rv; + } return rv; @@ -1886,7 +1883,7 @@ } if (name.compare(0, 6, "_level") == 0 && name.find_first_not_of("0123456789", 7) == string::npos ) { - unsigned int levelno = atoi(name.c_str()+6); + unsigned int levelno = atoi(name.c_str()+6); // getting 0 here for "_level" is intentional movie_instance* mo = VM::get().getRoot().getLevel(levelno).get(); if ( mo ) { @@ -3812,8 +3809,10 @@ } else { + // removing _level# + _vm.getRoot().dropLevel(depth); // I guess this can only happen if someone uses _root.swapDepth([0..1048575]) - log_error(_("Can't remove sprite %s as it has no parent"), getTarget().c_str()); + //log_error(_("Can't remove sprite %s as it has no parent"), getTarget().c_str()); } } Index: testsuite/misc-mtasc.all/level5.as =================================================================== RCS file: /sources/gnash/gnash/testsuite/misc-mtasc.all/level5.as,v retrieving revision 1.7 retrieving revision 1.8 diff -u -b -r1.7 -r1.8 --- testsuite/misc-mtasc.all/level5.as 29 Nov 2007 10:47:00 -0000 1.7 +++ testsuite/misc-mtasc.all/level5.as 30 Nov 2007 11:26:05 -0000 1.8 @@ -34,6 +34,9 @@ // The ""+ is there to force conversion to a string check_equals(""+mc, "_level5"); + // Mc level is _level0 ? why ? + check_equals(mc._level, _level0); + // check that we can acess back to _level0 check_equals(_level0.testvar, 1239); @@ -53,6 +56,23 @@ note("Unloading "+this); } + mc.createEmptyMovieClip("ch", 1); + with(mc.ch) + { + lineStyle(1, 0x00000); + beginFill(0xFF0000, 80); + var x=200; + var y=200; + var width=100; + var height=100; + moveTo(x, y); + lineTo(x+width, y); + lineTo(x+width, y+height); + lineTo(x, y+height); + lineTo(x, y); + endFill(); + }; + // load yet another swf getURL("level99.swf","_level"+99); } Index: testsuite/misc-mtasc.all/level99.as =================================================================== RCS file: /sources/gnash/gnash/testsuite/misc-mtasc.all/level99.as,v retrieving revision 1.7 retrieving revision 1.8 diff -u -b -r1.7 -r1.8 --- testsuite/misc-mtasc.all/level99.as 29 Nov 2007 10:47:01 -0000 1.7 +++ testsuite/misc-mtasc.all/level99.as 30 Nov 2007 11:26:05 -0000 1.8 @@ -26,6 +26,23 @@ { static function main(mc) { + mc.createEmptyMovieClip("ch", 1); + with(mc.ch) + { + lineStyle(1, 0x00000); + beginFill(0x00FF00, 80); + var x=250; + var y=250; + var width=100; + var height=100; + moveTo(x, y); + lineTo(x+width, y); + lineTo(x+width, y+height); + lineTo(x, y+height); + lineTo(x, y); + endFill(); + }; + check_equals(mc._currentframe, 1); // Check our depth @@ -34,6 +51,9 @@ // The ""+ is there to force conversion to a string check_equals(""+mc, "_level99"); + // Mc level is _level0 ? why ? + check_equals(mc._level, _level0); + // check that we can acess back to _level0 check_equals(_level0.testvar, 1239); check_equals(_level0.testvar2, true); @@ -53,22 +73,60 @@ check_equals(typeof(_level5), 'movieclip'); var level5ref = _level5; + check_equals(_level5.getDepth(), -16379); _level5.swapDepths(10); - xcheck_equals(typeof(_level5), 'undefined'); + check_equals(typeof(_level5), 'undefined'); check_equals(typeof(level5ref), 'movieclip'); - xcheck_equals(level5ref.getDepth(), '10'); - xcheck_equals(level5ref._target, '_level16394'); - xcheck_equals(typeof(_level16394), 'movieclip'); + check_equals(level5ref.getDepth(), '10'); + check_equals(level5ref._target, '_level16394'); + check_equals(typeof(_level16394), 'movieclip'); + level5ref.swapDepths(20); // swapDepth doesn't work now because level5ref is out of the static depth zone + check_equals(level5ref.getDepth(), '10'); + check_equals(level5ref._target, '_level16394'); + xcheck_equals(""+level5ref, '_level5'); + + var level99ref = _level99; + _level99.swapDepths(30); + check_equals(level99ref.getDepth(), '30'); + check_equals(level99ref._target, '_level16414'); + level99ref.swapDepths(40); // swapDepth doesn't work now because level99ref is out of the static depth zone + check_equals(level99ref.getDepth(), '30'); + check_equals(level99ref._target, '_level16414'); + xcheck_equals(""+level99ref, '_level99'); + + note("Setting up onEnterFrame for "+mc.ch); + mc.ch.count = 0; + mc.ch.l5ref = level5ref; + mc.ch.l99ref = level99ref; + mc.ch.onEnterFrame = function() + { + note(this+".enterFrame -- l5ref is "+this.l5ref+" -- l99ref is "+this.l99ref); + if ( this.count > 4 ) + { + check_equals(this.l5ref._target, '_level16394'); + check_equals(this.l99ref._target, '_level16414'); _level16394.removeMovieClip(); - check_equals(typeof(level5ref), 'movieclip'); - xcheck_equals(typeof(level5ref)._target, 'undefined'); - xcheck_equals(typeof(level5ref.getDepth), 'undefined'); - + check_equals(typeof(this.l5ref), 'movieclip'); + check_equals(typeof(this.l5ref)._target, 'undefined'); + check_equals(typeof(this.l5ref.getDepth), 'undefined'); check_equals(typeof(_level16364), 'undefined') - check_totals(30); + // END OF TEST HERE + // TODO: add tests for: + // - sane swapping between to levels, + // - swapping & removing _level0 + // + check_totals(43); Dejagnu.done(); + delete this.onEnterFrame; + } + else + { + ++this.count; + this.l5ref.swapDepths(this.l99ref); + } + } } } Index: testsuite/swfdec/PASSING =================================================================== RCS file: /sources/gnash/gnash/testsuite/swfdec/PASSING,v retrieving revision 1.67 retrieving revision 1.68 diff -u -b -r1.67 -r1.68 --- testsuite/swfdec/PASSING 26 Nov 2007 17:04:50 -0000 1.67 +++ testsuite/swfdec/PASSING 30 Nov 2007 11:26:05 -0000 1.68 @@ -257,6 +257,9 @@ movieclip-set-prototype-7.swf:f147fff166cc46cdcda77d5012faddb0 movieclip-set-prototype-8.swf:9fbacb2c3107d434b585978d18ec25bb movieclip-swap-depths-5.swf:4c337a1aaa285b1e7d000acc06b6a5d7 +movieclip-swap-depths-6.swf:fdb57e8db6df99d66d93f6fd2d39b0c7 +movieclip-swap-depths-7.swf:fb8d472e5da28d95684ce067fccae829 +movieclip-swap-depths-8.swf:a02edb0c644d0a47fee7c3ca5135d748 moviecliploader-constructor-5.swf:fd0fb9a785017456810f06b61c109d35 moviecliploader-constructor-6.swf:e50f068ebde835d503c43ae1fcaf4371 moviecliploader-getprogress-5.swf:0d58d1e3762e678c27f38309c34906ec _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit